提交 9c6d7531 作者: 方治民

feat: springboot v3 + openapi v3 等相关适配完成

上级 ccb648b8
...@@ -30,11 +30,11 @@ dependencies { ...@@ -30,11 +30,11 @@ dependencies {
// Optional: Doc // Optional: Doc
implementation project(":basic-common:doc") implementation project(":basic-common:doc")
implementation "com.github.xiaoymin:knife4j-spring-boot-starter:${knife4jVersion}" implementation "com.github.xiaoymin:knife4j-openapi3-jakarta-spring-boot-starter:${knife4jOpen3Version}"
// Optional: Auth // Optional: Auth
implementation project(":basic-auth") implementation project(":basic-auth")
implementation "cn.dev33:sa-token-spring-boot-starter:${saTokenVersion}" implementation "cn.dev33:sa-token-spring-boot3-starter:${saTokenVersion}"
// Optional: WebSocket && STOMP 依赖 Auth + Redis 模块 // Optional: WebSocket && STOMP 依赖 Auth + Redis 模块
implementation project(":basic-websocket") implementation project(":basic-websocket")
...@@ -59,6 +59,6 @@ dependencies { ...@@ -59,6 +59,6 @@ dependencies {
implementation "cn.hutool:hutool-core:${hutoolVersion}" implementation "cn.hutool:hutool-core:${hutoolVersion}"
implementation "cn.hutool:hutool-extra:${hutoolVersion}" implementation "cn.hutool:hutool-extra:${hutoolVersion}"
// https://github.com/vladmihalcea/hibernate-types // https://github.com/vladmihalcea/hypersistence-utils
implementation "com.vladmihalcea:hibernate-types-55:${hibernateTypesVersion}" implementation "io.hypersistence:hypersistence-utils-hibernate-60:${hibernateTypesVersion}"
} }
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.app.config; package com.yiring.app.config;
import cn.dev33.satoken.exception.*;
import com.yiring.common.core.I18n; import com.yiring.common.core.I18n;
import com.yiring.common.core.Result; import com.yiring.common.core.Result;
import com.yiring.common.core.Status; import com.yiring.common.core.Status;
import com.yiring.common.exception.BusinessException;
import com.yiring.common.exception.FailStatusException;
import javax.validation.ConstraintViolationException;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.ClientAbortException; import org.springframework.core.annotation.Order;
import org.aspectj.bridge.AbortException;
import org.hibernate.validator.internal.engine.ConstraintViolationImpl;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/** /**
* 全局错误处理 * 全局错误处理
...@@ -33,130 +19,14 @@ import org.springframework.web.bind.annotation.ResponseStatus; ...@@ -33,130 +19,14 @@ import org.springframework.web.bind.annotation.ResponseStatus;
* 2017年11月30日 上午11:36:31 * 2017年11月30日 上午11:36:31
*/ */
@Slf4j @Slf4j
@ControllerAdvice @Order
@ResponseBody @RestControllerAdvice
@RequiredArgsConstructor @RequiredArgsConstructor
public class GlobalExceptionHandler { public class GlobalExceptionHandler {
final I18n i18n; final I18n i18n;
/** /**
* 参数校验异常
*
* @param e 异常信息
* @return 统一的校验失败信息 {@link Status#EXPECTATION_FAILED
*/
@ExceptionHandler(
{ BindException.class, MethodArgumentNotValidException.class, ConstraintViolationException.class }
)
public Result<String> validFailHandler(Exception e) {
String details = null;
if (e instanceof ConstraintViolationException) {
details = ((ConstraintViolationException) e).getConstraintViolations().iterator().next().getMessage();
} else {
BindingResult result = null;
if (e instanceof MethodArgumentNotValidException) {
result = ((MethodArgumentNotValidException) e).getBindingResult();
} else if (e instanceof BindException) {
result = ((BindException) e).getBindingResult();
}
if (result != null) {
ObjectError error = result.getAllErrors().iterator().next();
if (error instanceof FieldError fieldError) {
// TODO: 可以优化成提取 @ApiModelProperty value 中文描述
// 构建明确的字段错误提示, 例如: id 不能为 null, 如果自己填写了 message 则不追加 field 字段前缀
ConstraintViolationImpl<?> violation = error.unwrap(ConstraintViolationImpl.class);
String template = violation.getMessageTemplate();
String prefix = "";
// 如果是模板字符串, 则在消息前添加字段提示
if (template.contains("{") && template.contains("}")) {
prefix = fieldError.getField() + " ";
}
details = prefix + i18n.get(fieldError);
} else {
details = i18n.get(error);
}
}
}
return Result.no(Status.EXPECTATION_FAILED, details);
}
/**
* 不支持的HttpMethod异常
*
* @param e 异常信息
* @return 异常信息反馈 {@link Status#METHOD_NOT_ALLOWED
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public Result<String> httpRequestMethodNotSupportedErrorHandler(Exception e) {
return Result.no(Status.METHOD_NOT_ALLOWED, e.getMessage());
}
/**
* 未登录异常(鉴权失败)
*
* @return 异常信息反馈 {@link Status#UNAUTHORIZED
*/
@ExceptionHandler(NotLoginException.class)
public Result<String> unauthorizedErrorHandler() {
return Result.no(Status.UNAUTHORIZED);
}
/**
* 1. 二级认证失败异常
* 2. 角色条件不满足
* 3. 权限条件不满足
* 4. HTTP Basic 验证不通过
* 5. 用户被禁止访问该服务
* 6. API 被禁用
*
* @return 异常信息反馈 {@link Status#FORBIDDEN
*/
@ExceptionHandler(
{
// https://sa-token.dev33.cn/doc.html#/up/safe-auth
NotSafeException.class,
// https://sa-token.dev33.cn/doc.html#/use/at-check
NotRoleException.class,
NotPermissionException.class,
// https://sa-token.dev33.cn/doc.html#/up/basic-auth
NotBasicAuthException.class,
// https://sa-token.dev33.cn/doc.html#/up/disable
DisableServiceException.class,
ApiDisabledException.class,
}
)
public Result<String> forbiddenHandler() {
return Result.no(Status.FORBIDDEN);
}
/**
* 自定义业务异常
*/
@ExceptionHandler(BusinessException.class)
public Result<String> businessExceptionHandler(BusinessException e) {
return Result.no(Status.BAD_REQUEST, e.getCode(), e.getMessage(), null);
}
/**
* 失败状态异常
*/
@ExceptionHandler(FailStatusException.class)
public Result<String> failStatusExceptionHandler(FailStatusException e) {
return Result.no(e.getStatus(), e.getMessage());
}
/**
* 取消请求异常(忽略)
*/
@ExceptionHandler({ ClientAbortException.class, AbortException.class, HttpMessageNotWritableException.class })
public void ignoreExceptionHandler() {}
/**
* 其他异常 * 其他异常
* *
* @param e 异常信息 * @param e 异常信息
......
...@@ -3,12 +3,12 @@ package com.yiring.app.domain.user; ...@@ -3,12 +3,12 @@ package com.yiring.app.domain.user;
import com.yiring.auth.domain.user.User; import com.yiring.auth.domain.user.User;
import com.yiring.common.domain.BasicEntity; import com.yiring.common.domain.BasicEntity;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
......
...@@ -2,11 +2,13 @@ ...@@ -2,11 +2,13 @@
package com.yiring.app.vo.user; package com.yiring.app.vo.user;
import com.yiring.common.jackson.MappingSerialize; import com.yiring.common.jackson.MappingSerialize;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import lombok.*; import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
/** /**
...@@ -15,9 +17,8 @@ import lombok.experimental.FieldDefaults; ...@@ -15,9 +17,8 @@ import lombok.experimental.FieldDefaults;
* 2022/7/13 11:36 * 2022/7/13 11:36
*/ */
@ApiModel("UserExtensionVo") @Schema(name = "UserExtensionVo", description = "用户扩展信息")
@Data @Data
@Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
...@@ -26,10 +27,13 @@ public class UserExtensionVo implements Serializable { ...@@ -26,10 +27,13 @@ public class UserExtensionVo implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -2251567849918281906L; private static final long serialVersionUID = -2251567849918281906L;
@ApiModelProperty(value = "性别", example = "男") @Schema(description = "性别", example = "男", allowableValues = { "男", "女" }, type = "string")
@MappingSerialize(mapping = "0:女,1:男") @MappingSerialize(mapping = "0:女,1:男")
Integer gender; Integer gender;
@ApiModelProperty(value = "年龄", example = "18") @Schema(description = "年龄", example = "18")
Integer age; Integer age;
@Schema(description = "简介", example = "Hi")
String introduction;
} }
...@@ -10,6 +10,7 @@ import com.yiring.app.domain.user.UserExtensionRepository; ...@@ -10,6 +10,7 @@ import com.yiring.app.domain.user.UserExtensionRepository;
import com.yiring.app.vo.user.UserExtensionVo; import com.yiring.app.vo.user.UserExtensionVo;
import com.yiring.auth.domain.user.User; import com.yiring.auth.domain.user.User;
import com.yiring.auth.util.Auths; import com.yiring.auth.util.Auths;
import com.yiring.common.annotation.DownloadResponse;
import com.yiring.common.core.I18n; import com.yiring.common.core.I18n;
import com.yiring.common.core.Result; import com.yiring.common.core.Result;
import com.yiring.common.core.Status; import com.yiring.common.core.Status;
...@@ -19,16 +20,17 @@ import com.yiring.common.util.Commons; ...@@ -19,16 +20,17 @@ import com.yiring.common.util.Commons;
import com.yiring.common.util.FileUtils; import com.yiring.common.util.FileUtils;
import com.yiring.common.validation.group.Group; import com.yiring.common.validation.group.Group;
import com.yiring.common.vo.PageVo; import com.yiring.common.vo.PageVo;
import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import javax.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.data.domain.Example; import org.springframework.data.domain.Example;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
...@@ -43,9 +45,8 @@ import org.springframework.web.bind.annotation.*; ...@@ -43,9 +45,8 @@ import org.springframework.web.bind.annotation.*;
@Slf4j @Slf4j
@Validated @Validated
@SuppressWarnings({ "deprecation" })
@ApiSupport(order = 0) @ApiSupport(order = 0)
@Api(tags = "示例", description = "Example") @Tag(name = "示例", description = "Example")
@RequestMapping("/example/") @RequestMapping("/example/")
@RestController @RestController
@RequiredArgsConstructor @RequiredArgsConstructor
...@@ -55,7 +56,7 @@ public class ExampleController { ...@@ -55,7 +56,7 @@ public class ExampleController {
final Auths auths; final Auths auths;
final UserExtensionRepository userExtensionRepository; final UserExtensionRepository userExtensionRepository;
@ApiOperation("Hello World") @Operation(summary = "Hello World")
@GetMapping @GetMapping
public Result<String> hello() { public Result<String> hello() {
return Result.ok("example.hello"); return Result.ok("example.hello");
...@@ -64,16 +65,16 @@ public class ExampleController { ...@@ -64,16 +65,16 @@ public class ExampleController {
/** /**
* 测试失败自定义状态信息输出 * 测试失败自定义状态信息输出
*/ */
@ApiOperation("测试失败") @Operation(summary = "测试失败")
@GetMapping("fail") @GetMapping("fail")
public Result<String> fail() { public Result<String> fail() {
throw BusinessException.i18n("Code.1"); throw BusinessException.i18n("Code.1");
} }
@SaCheckLogin @SaCheckLogin
@ApiOperation("分页条件查询") @Operation(summary = "分页条件查询")
@GetMapping("page") @GetMapping("page")
public Result<PageVo<String>> page(@Validated PageParam param) { public Result<PageVo<String>> page(@ParameterObject @Validated PageParam param) {
log.debug("PageParam: {}", param); log.debug("PageParam: {}", param);
String text = i18n.get("example.hello"); String text = i18n.get("example.hello");
...@@ -82,7 +83,7 @@ public class ExampleController { ...@@ -82,7 +83,7 @@ public class ExampleController {
return Result.ok(vo); return Result.ok(vo);
} }
@ApiOperation(value = "JSON 传参") @Operation(summary = "JSON 传参")
@PostMapping("json") @PostMapping("json")
public Result<PageVo<String>> json( public Result<PageVo<String>> json(
@RequestBody(required = false) @Validated(Group.Optional.class) PageParam param @RequestBody(required = false) @Validated(Group.Optional.class) PageParam param
...@@ -91,9 +92,10 @@ public class ExampleController { ...@@ -91,9 +92,10 @@ public class ExampleController {
} }
@SaIgnore @SaIgnore
@DownloadResponse
@SneakyThrows(IOException.class) @SneakyThrows(IOException.class)
@ApiOperation(value = "文件下载", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) @Operation(summary = "文件下载")
@GetMapping("download") @GetMapping(value = "download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public void download(HttpServletResponse response) { public void download(HttpServletResponse response) {
ClassPathResource resource = new ClassPathResource("static/cat.jpg"); ClassPathResource resource = new ClassPathResource("static/cat.jpg");
FileUtils.download(response, resource.getFile()); FileUtils.download(response, resource.getFile());
...@@ -101,7 +103,7 @@ public class ExampleController { ...@@ -101,7 +103,7 @@ public class ExampleController {
@SaCheckSafe @SaCheckSafe
@SaCheckLogin @SaCheckLogin
@ApiOperation("查询用户属性") @Operation(summary = "查询用户属性")
@GetMapping("findUserExtensionInfo") @GetMapping("findUserExtensionInfo")
public Result<UserExtensionVo> findUserExtensionInfo() { public Result<UserExtensionVo> findUserExtensionInfo() {
User user = auths.getLoginUser(); User user = auths.getLoginUser();
......
...@@ -19,3 +19,5 @@ logging: ...@@ -19,3 +19,5 @@ logging:
springfox.documentation.spring.web.readers.operation.CachingOperationNameGenerator: WARN springfox.documentation.spring.web.readers.operation.CachingOperationNameGenerator: WARN
# 关闭接口扫描 ApiListingReferenceScanner 日志 # 关闭接口扫描 ApiListingReferenceScanner 日志
springfox.documentation.spring.web.scanners.ApiListingReferenceScanner: WARN springfox.documentation.spring.web.scanners.ApiListingReferenceScanner: WARN
# https://github.com/spring-projects/spring-framework/issues/29612
org.springframework.core.LocalVariableTableParameterNameDiscoverer: ERROR
...@@ -12,19 +12,34 @@ spring: ...@@ -12,19 +12,34 @@ spring:
username: ${env.extra.username} username: ${env.extra.username}
password: ${env.extra.password} password: ${env.extra.password}
jpa: jpa:
database-platform: org.hibernate.dialect.PostgreSQL10Dialect database-platform: org.hibernate.dialect.PostgreSQLDialect
open-in-view: true open-in-view: true
hibernate: hibernate:
ddl-auto: update ddl-auto: update
show-sql: true show-sql: false
properties: properties:
hibernate: hibernate:
format_sql: true format_sql: true
redis: # https://github.com/spring-projects/spring-data-jpa/issues/2717
database: 5 # https://hibernate.atlassian.net/browse/HHH-15827
host: ${env.host} jakarta:
port: 6379 persistence:
password: ${env.extra.password} sharedCache:
mode: UNSPECIFIED
data:
redis:
database: 5
port: 6379
host: ${env.host}
password: ${env.extra.password}
springdoc:
default-consumes-media-type: "application/x-www-form-urlencoded"
default-produces-media-type: "application/json"
default-flat-param-object: true
override-with-generic-response: false
api-docs:
resolve-schema-properties: true
# knife4j # knife4j
knife4j: knife4j:
......
...@@ -3,3 +3,16 @@ ...@@ -3,3 +3,16 @@
example.hello=\uD83D\uDE0E Hello World example.hello=\uD83D\uDE0E Hello World
# \u4E1A\u52A1\u72B6\u6001\u7801\u9519\u8BEF\u6D88\u606F # \u4E1A\u52A1\u72B6\u6001\u7801\u9519\u8BEF\u6D88\u606F
Code.1=\u5931\u8D25 Code.1=\u5931\u8D25
Code.1000=\u7528\u6237\u4E0D\u5B58\u5728
Code.1001=\u6743\u9650\u6807\u8BC6\u91CD\u590D
Code.1002=\u89D2\u8272\u6807\u8BC6\u91CD\u590D
Code.10000=\u4E8C\u7EA7\u8BA4\u8BC1\u6821\u9A8C\u5931\u8D25
Code.10001=\u89D2\u8272\u6743\u9650\u4E0D\u8DB3
Code.10002=\u6743\u9650\u4E0D\u8DB3
Code.10003=\u672A\u6388\u6743
Code.100000=\u7528\u6237\u540D\u5DF2\u5B58\u5728
Code.100001=\u624B\u673A\u53F7\u5DF2\u5B58\u5728
Code.100002=\u90AE\u7BB1\u5DF2\u5B58\u5728
Code.100003=\u8D26\u53F7\u5BC6\u7801\u9519\u8BEF
Code.100004=\u7528\u6237\u88AB\u7981\u7528, \u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
Code.100005=\u7528\u6237\u88AB\u7981\u6B62\u767B\u5F55, \u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
...@@ -3,3 +3,16 @@ ...@@ -3,3 +3,16 @@
example.hello=\uD83D\uDE0E Hello World example.hello=\uD83D\uDE0E Hello World
# \u4E1A\u52A1\u72B6\u6001\u7801\u9519\u8BEF\u6D88\u606F # \u4E1A\u52A1\u72B6\u6001\u7801\u9519\u8BEF\u6D88\u606F
Code.1=\u5931\u8D25 Code.1=\u5931\u8D25
Code.1000=\u7528\u6237\u4E0D\u5B58\u5728
Code.1001=\u6743\u9650\u6807\u8BC6\u91CD\u590D
Code.1002=\u89D2\u8272\u6807\u8BC6\u91CD\u590D
Code.10000=\u4E8C\u7EA7\u8BA4\u8BC1\u6821\u9A8C\u5931\u8D25
Code.10001=\u89D2\u8272\u6743\u9650\u4E0D\u8DB3
Code.10002=\u6743\u9650\u4E0D\u8DB3
Code.10003=\u672A\u6388\u6743
Code.100000=\u7528\u6237\u540D\u5DF2\u5B58\u5728
Code.100001=\u624B\u673A\u53F7\u5DF2\u5B58\u5728
Code.100002=\u90AE\u7BB1\u5DF2\u5B58\u5728
Code.100003=\u8D26\u53F7\u5BC6\u7801\u9519\u8BEF
Code.100004=\u7528\u6237\u88AB\u7981\u7528, \u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
Code.100005=\u7528\u6237\u88AB\u7981\u6B62\u767B\u5F55, \u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
javax.validation.constraints.AssertFalse.message=\u53EA\u80FD\u4E3A false jakarta.validation.constraints.AssertFalse.message=\u53EA\u80FD\u4E3Afalse
javax.validation.constraints.AssertTrue.message=\u53EA\u80FD\u4E3A true jakarta.validation.constraints.AssertTrue.message=\u53EA\u80FD\u4E3Atrue
javax.validation.constraints.DecimalMax.message=\u5FC5\u987B\u5C0F\u4E8E${inclusive == true ? '\u6216\u7B49\u4E8E' : ''}{value} jakarta.validation.constraints.DecimalMax.message=\u5FC5\u987B\u5C0F\u4E8E${inclusive == true ? '\u6216\u7B49\u4E8E' : ''}{value}
javax.validation.constraints.DecimalMin.message=\u5FC5\u987B\u5927\u4E8E${inclusive == true ? '\u6216\u7B49\u4E8E' : ''}{value} jakarta.validation.constraints.DecimalMin.message=\u5FC5\u987B\u5927\u4E8E${inclusive == true ? '\u6216\u7B49\u4E8E' : ''}{value}
javax.validation.constraints.Digits.message=\u6570\u5B57\u7684\u503C\u8D85\u51FA\u4E86\u5141\u8BB8\u8303\u56F4(\u53EA\u5141\u8BB8\u5728{integer}\u4F4D\u6574\u6570\u548C{fraction}\u4F4D\u5C0F\u6570\u8303\u56F4\u5185) jakarta.validation.constraints.Digits.message=\u6570\u5B57\u7684\u503C\u8D85\u51FA\u4E86\u5141\u8BB8\u8303\u56F4(\u53EA\u5141\u8BB8\u5728{integer}\u4F4D\u6574\u6570\u548C{fraction}\u4F4D\u5C0F\u6570\u8303\u56F4\u5185)
javax.validation.constraints.Email.message=\u4E0D\u662F\u4E00\u4E2A\u5408\u6CD5\u7684\u7535\u5B50\u90AE\u4EF6\u5730\u5740 jakarta.validation.constraints.Email.message=\u4E0D\u662F\u4E00\u4E2A\u5408\u6CD5\u7684\u7535\u5B50\u90AE\u4EF6\u5730\u5740
javax.validation.constraints.Future.message=\u9700\u8981\u662F\u4E00\u4E2A\u5C06\u6765\u7684\u65F6\u95F4 jakarta.validation.constraints.Future.message=\u9700\u8981\u662F\u4E00\u4E2A\u5C06\u6765\u7684\u65F6\u95F4
javax.validation.constraints.FutureOrPresent.message=\u9700\u8981\u662F\u4E00\u4E2A\u5C06\u6765\u6216\u73B0\u5728\u7684\u65F6\u95F4 jakarta.validation.constraints.FutureOrPresent.message=\u9700\u8981\u662F\u4E00\u4E2A\u5C06\u6765\u6216\u73B0\u5728\u7684\u65F6\u95F4
javax.validation.constraints.Max.message=\u6700\u5927\u4E0D\u80FD\u8D85\u8FC7{value} jakarta.validation.constraints.Max.message=\u6700\u5927\u4E0D\u80FD\u8D85\u8FC7{value}
javax.validation.constraints.Min.message=\u6700\u5C0F\u4E0D\u80FD\u5C0F\u4E8E{value} jakarta.validation.constraints.Min.message=\u6700\u5C0F\u4E0D\u80FD\u5C0F\u4E8E{value}
javax.validation.constraints.Negative.message=\u5FC5\u987B\u662F\u8D1F\u6570 jakarta.validation.constraints.Negative.message=\u5FC5\u987B\u662F\u8D1F\u6570
javax.validation.constraints.NegativeOrZero.message=\u5FC5\u987B\u662F\u8D1F\u6570\u6216\u96F6 jakarta.validation.constraints.NegativeOrZero.message=\u5FC5\u987B\u662F\u8D1F\u6570\u6216\u96F6
javax.validation.constraints.NotBlank.message=\u4E0D\u80FD\u4E3A\u7A7A jakarta.validation.constraints.NotBlank.message=\u4E0D\u80FD\u4E3A\u7A7A
javax.validation.constraints.NotEmpty.message=\u4E0D\u80FD\u4E3A\u7A7A jakarta.validation.constraints.NotEmpty.message=\u4E0D\u80FD\u4E3A\u7A7A
javax.validation.constraints.NotNull.message=\u4E0D\u80FD\u4E3A null jakarta.validation.constraints.NotNull.message=\u4E0D\u80FD\u4E3Anull
javax.validation.constraints.Null.message=\u5FC5\u987B\u4E3A null jakarta.validation.constraints.Null.message=\u5FC5\u987B\u4E3Anull
javax.validation.constraints.Past.message=\u9700\u8981\u662F\u4E00\u4E2A\u8FC7\u53BB\u7684\u65F6\u95F4 jakarta.validation.constraints.Past.message=\u9700\u8981\u662F\u4E00\u4E2A\u8FC7\u53BB\u7684\u65F6\u95F4
javax.validation.constraints.PastOrPresent.message=\u9700\u8981\u662F\u4E00\u4E2A\u8FC7\u53BB\u6216\u73B0\u5728\u7684\u65F6\u95F4 jakarta.validation.constraints.PastOrPresent.message=\u9700\u8981\u662F\u4E00\u4E2A\u8FC7\u53BB\u6216\u73B0\u5728\u7684\u65F6\u95F4
javax.validation.constraints.Pattern.message=\u9700\u8981\u5339\u914D\u6B63\u5219\u8868\u8FBE\u5F0F"{regexp}" jakarta.validation.constraints.Pattern.message=\u9700\u8981\u5339\u914D\u6B63\u5219\u8868\u8FBE\u5F0F"{regexp}"
javax.validation.constraints.Positive.message=\u5FC5\u987B\u662F\u6B63\u6570 jakarta.validation.constraints.Positive.message=\u5FC5\u987B\u662F\u6B63\u6570
javax.validation.constraints.PositiveOrZero.message=\u5FC5\u987B\u662F\u6B63\u6570\u6216\u96F6 jakarta.validation.constraints.PositiveOrZero.message=\u5FC5\u987B\u662F\u6B63\u6570\u6216\u96F6
javax.validation.constraints.Size.message=\u4E2A\u6570\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 jakarta.validation.constraints.Size.message=\u4E2A\u6570\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4
org.hibernate.validator.constraints.CreditCardNumber.message=\u4E0D\u5408\u6CD5\u7684\u4FE1\u7528\u5361\u53F7\u7801 org.hibernate.validator.constraints.CreditCardNumber.message=\u4E0D\u5408\u6CD5\u7684\u4FE1\u7528\u5361\u53F7\u7801
org.hibernate.validator.constraints.Currency.message=\u4E0D\u5408\u6CD5\u7684\u8D27\u5E01 (\u5FC5\u987B\u662F{value}\u5176\u4E2D\u4E4B\u4E00) org.hibernate.validator.constraints.Currency.message=\u4E0D\u5408\u6CD5\u7684\u8D27\u5E01 (\u5FC5\u987B\u662F{value}\u5176\u4E2D\u4E4B\u4E00)
org.hibernate.validator.constraints.EAN.message=\u4E0D\u5408\u6CD5\u7684{type}\u6761\u5F62\u7801 org.hibernate.validator.constraints.EAN.message=\u4E0D\u5408\u6CD5\u7684{type}\u6761\u5F62\u7801
......
...@@ -9,11 +9,13 @@ dependencies { ...@@ -9,11 +9,13 @@ dependencies {
implementation fileTree(dir: project.rootDir.getPath() + '\\libs', includes: ['*jar']) implementation fileTree(dir: project.rootDir.getPath() + '\\libs', includes: ['*jar'])
// swagger(knife4j) // swagger(knife4j)
implementation "com.github.xiaoymin:knife4j-spring-boot-starter:${knife4jVersion}" implementation "com.github.xiaoymin:knife4j-openapi3-jakarta-spring-boot-starter:${knife4jOpen3Version}"
// sa-token // sa-token
implementation "cn.dev33:sa-token-spring-boot-starter:${saTokenVersion}" implementation "cn.dev33:sa-token-spring-boot3-starter:${saTokenVersion}"
implementation "cn.dev33:sa-token-dao-redis-jackson:${saTokenVersion}" implementation "cn.dev33:sa-token-dao-redis-jackson:${saTokenVersion}"
// Sa-Token 整合 Redis (使用 jackson 序列化方式)
implementation 'org.apache.commons:commons-pool2'
// fastjson // fastjson
implementation "com.alibaba.fastjson2:fastjson2:${fastJsonVersion}" implementation "com.alibaba.fastjson2:fastjson2:${fastJsonVersion}"
...@@ -21,8 +23,11 @@ dependencies { ...@@ -21,8 +23,11 @@ dependencies {
// hutool-core // hutool-core
implementation "cn.hutool:hutool-core:${hutoolVersion}" implementation "cn.hutool:hutool-core:${hutoolVersion}"
// https://github.com/vladmihalcea/hibernate-types // https://github.com/vladmihalcea/hypersistence-utils
// hibernate-types-55 // hypersistence-utils-hibernate-60
implementation "com.vladmihalcea:hibernate-types-55:${hibernateTypesVersion}" implementation "io.hypersistence:hypersistence-utils-hibernate-60:${hibernateTypesVersion}"
// https://mvnrepository.com/artifact/org.jetbrains/annotations
implementation "org.jetbrains:annotations:${jetbrainsAnnotationsVersion}"
} }
/* (C) 2022 YiRing, Inc. */
package com.yiring.auth.annotation;
import cn.dev33.satoken.annotation.SaIgnore;
import java.lang.annotation.*;
/**
* 忽略登录校验
* 与 @SaCheckLogin 相对
*
* @author Jim
* @version 0.1
* 2022/4/7 15:21
* @deprecated 已过期,请使用 @SaIgnore
*/
@SuppressWarnings({ "unused" })
@Deprecated
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@SaIgnore
public @interface AuthIgnore {
}
/* (C) 2021 YiRing, Inc. */
package com.yiring.auth.config;
import cn.dev33.satoken.exception.*;
import com.yiring.common.core.Result;
import com.yiring.common.core.Status;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 授权异常拦截处理
*
* @author Jim
* @version 0.1
* 2023/1/12 14:06
*/
@Slf4j
@Order(0)
@RestControllerAdvice
@RequiredArgsConstructor
public class AuthExceptionHandler {
/**
* 未登录异常(鉴权失败)
*
* @return 异常信息反馈 {@link Status#UNAUTHORIZED
*/
@ExceptionHandler(NotLoginException.class)
public Result<String> unauthorizedErrorHandler() {
return Result.no(Status.UNAUTHORIZED);
}
/**
* 1. 二级认证失败异常
* 2. 角色条件不满足
* 3. 权限条件不满足
* 4. HTTP Basic 验证不通过
* 5. 用户被禁止访问该服务
* 6. API 被禁用
*
* @return 异常信息反馈 {@link Status#FORBIDDEN
*/
@ExceptionHandler(
{
// https://sa-token.dev33.cn/doc.html#/up/safe-auth
NotSafeException.class,
// https://sa-token.dev33.cn/doc.html#/use/at-check
NotRoleException.class,
NotPermissionException.class,
// https://sa-token.dev33.cn/doc.html#/up/basic-auth
NotBasicAuthException.class,
// https://sa-token.dev33.cn/doc.html#/up/disable
DisableServiceException.class,
ApiDisabledException.class,
}
)
public Result<String> forbiddenHandler(Exception e) {
if (e instanceof NotSafeException) {
return Result.no(Status.FORBIDDEN, "Code.10000");
}
if (e instanceof NotRoleException) {
return Result.no(Status.FORBIDDEN, "Code.10001");
}
if (e instanceof NotPermissionException) {
return Result.no(Status.FORBIDDEN, "Code.10002");
}
if (e instanceof NotBasicAuthException) {
return Result.no(Status.FORBIDDEN, "Code.10003");
}
log.warn(e.getMessage(), e);
return Result.no(Status.FORBIDDEN);
}
}
...@@ -12,7 +12,7 @@ import java.util.Objects; ...@@ -12,7 +12,7 @@ import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Resource; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
...@@ -24,10 +24,10 @@ import org.springframework.stereotype.Component; ...@@ -24,10 +24,10 @@ import org.springframework.stereotype.Component;
*/ */
@Component @Component
@RequiredArgsConstructor
public class StpInterfaceImpl implements StpInterface { public class StpInterfaceImpl implements StpInterface {
@Resource final UserRepository userRepository;
UserRepository userRepository;
@Override @Override
public List<String> getPermissionList(Object loginId, String loginType) { public List<String> getPermissionList(Object loginId, String loginType) {
...@@ -50,6 +50,7 @@ public class StpInterfaceImpl implements StpInterface { ...@@ -50,6 +50,7 @@ public class StpInterfaceImpl implements StpInterface {
/** /**
* 根据 id 获取用户信息 * 根据 id 获取用户信息
*
* @param loginId 登录 ID * @param loginId 登录 ID
* @return 用户信息 * @return 用户信息
*/ */
...@@ -57,7 +58,7 @@ public class StpInterfaceImpl implements StpInterface { ...@@ -57,7 +58,7 @@ public class StpInterfaceImpl implements StpInterface {
String id = Objects.toString(loginId); String id = Objects.toString(loginId);
Optional<User> optional = userRepository.findById(id); Optional<User> optional = userRepository.findById(id);
if (optional.isEmpty()) { if (optional.isEmpty()) {
throw Status.NOT_FOUND.exception("用户不存在"); throw Status.NOT_FOUND.exception("Code.1000");
} }
return optional.get(); return optional.get();
......
...@@ -6,9 +6,10 @@ import static com.yiring.auth.domain.permission.Permission.TABLE_NAME; ...@@ -6,9 +6,10 @@ import static com.yiring.auth.domain.permission.Permission.TABLE_NAME;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yiring.common.domain.BasicEntity; import com.yiring.common.domain.BasicEntity;
import io.hypersistence.utils.hibernate.type.json.JsonType;
import jakarta.persistence.*;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import javax.persistence.*;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
...@@ -99,7 +100,7 @@ public class Permission extends BasicEntity implements Serializable { ...@@ -99,7 +100,7 @@ public class Permission extends BasicEntity implements Serializable {
* 可用于扩展一些前端可能用到的路由参数 * 可用于扩展一些前端可能用到的路由参数
*/ */
@Comment("扩展元数据信息") @Comment("扩展元数据信息")
@org.hibernate.annotations.Type(type = "json") @org.hibernate.annotations.Type(JsonType.class)
@Column(columnDefinition = "json") @Column(columnDefinition = "json")
JSONObject meta; JSONObject meta;
...@@ -123,6 +124,7 @@ public class Permission extends BasicEntity implements Serializable { ...@@ -123,6 +124,7 @@ public class Permission extends BasicEntity implements Serializable {
/** /**
* 获取权限的元数据信息,通常是根据前端所需来输出,可自定义调整 * 获取权限的元数据信息,通常是根据前端所需来输出,可自定义调整
*
* @return JSON 格式 Meta 元数据 * @return JSON 格式 Meta 元数据
*/ */
public JSONObject getMetaJson() { public JSONObject getMetaJson() {
......
...@@ -8,11 +8,11 @@ import com.fasterxml.jackson.annotation.JsonIgnore; ...@@ -8,11 +8,11 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.yiring.auth.domain.permission.Permission; import com.yiring.auth.domain.permission.Permission;
import com.yiring.auth.domain.user.User; import com.yiring.auth.domain.user.User;
import com.yiring.common.domain.BasicEntity; import com.yiring.common.domain.BasicEntity;
import jakarta.persistence.*;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.persistence.*;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
......
...@@ -4,12 +4,12 @@ package com.yiring.auth.domain.user; ...@@ -4,12 +4,12 @@ package com.yiring.auth.domain.user;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.yiring.auth.domain.role.Role; import com.yiring.auth.domain.role.Role;
import com.yiring.common.domain.BasicEntity; import com.yiring.common.domain.BasicEntity;
import jakarta.persistence.*;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.persistence.*;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
......
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.auth.param.auth; package com.yiring.auth.param.auth;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.annotations.ApiModelProperty; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import javax.validation.constraints.NotEmpty;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
...@@ -16,7 +16,7 @@ import lombok.experimental.FieldDefaults; ...@@ -16,7 +16,7 @@ import lombok.experimental.FieldDefaults;
* @version 0.1 * @version 0.1
* 2019/5/28 22:11 * 2019/5/28 22:11
*/ */
@ApiModel("LoginParam") @Schema(name = "LoginParam")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -27,11 +27,11 @@ public class LoginParam implements Serializable { ...@@ -27,11 +27,11 @@ public class LoginParam implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -8690942241103456895L; private static final long serialVersionUID = -8690942241103456895L;
@ApiModelProperty(value = "账号(支持用户名/手机号/邮箱)", example = "admin", required = true) @Parameter(description = "账号(支持用户名/手机号/邮箱)", example = "admin")
@NotEmpty(message = "账号不能为空") @NotEmpty(message = "账号不能为空")
String account; String account;
@ApiModelProperty(value = "密码", example = "123456", required = true) @Parameter(description = "密码", example = "123456")
@NotEmpty(message = "密码不能为空") @NotEmpty(message = "密码不能为空")
String password; String password;
} }
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.auth.param.auth; package com.yiring.auth.param.auth;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.annotations.ApiModelProperty; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Pattern;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
...@@ -17,7 +17,7 @@ import lombok.experimental.FieldDefaults; ...@@ -17,7 +17,7 @@ import lombok.experimental.FieldDefaults;
* @version 0.1 * @version 0.1
* 2019/5/28 22:11 * 2019/5/28 22:11
*/ */
@ApiModel("RegisterParam") @Schema(name = "RegisterParam")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -28,32 +28,32 @@ public class RegisterParam implements Serializable { ...@@ -28,32 +28,32 @@ public class RegisterParam implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -8690942241103456895L; private static final long serialVersionUID = -8690942241103456895L;
@ApiModelProperty(value = "用户名", example = "admin", required = true) @Parameter(description = "用户名", example = "admin")
@NotEmpty(message = "用户名不能为空") @NotEmpty(message = "用户名不能为空")
String username; String username;
@ApiModelProperty(value = "密码", example = "123456", required = true) @Parameter(description = "密码", example = "123456")
@NotEmpty(message = "密码不能为空") @NotEmpty(message = "密码不能为空")
String password; String password;
@ApiModelProperty(value = "真实姓名", example = "管理员", required = true) @Parameter(description = "真实姓名", example = "管理员")
@NotEmpty(message = "真实姓名不能为空") @NotEmpty(message = "真实姓名不能为空")
String realName; String realName;
@ApiModelProperty(value = "手机号", example = "13012345678", required = true) @Parameter(description = "手机号", example = "13012345678")
@NotEmpty(message = "手机号不能为空") @NotEmpty(message = "手机号不能为空")
@Pattern(regexp = "^1\\d{10}$", message = "手机号码格式不正确") @Pattern(regexp = "^1\\d{10}$", message = "手机号码格式不正确")
String mobile; String mobile;
@ApiModelProperty(value = "头像", example = "https://s1.ax1x.com/2022/03/30/qggJH0.jpg") @Parameter(description = "头像", example = "https://s1.ax1x.com/2022/03/30/qggJH0.jpg")
String avatar; String avatar;
@ApiModelProperty(value = "邮箱", example = "developer@yiring.com") @Parameter(description = "邮箱", example = "developer@yiring.com")
String email; String email;
@ApiModelProperty(value = "简介", example = "平台管理员") @Parameter(description = "简介", example = "平台管理员")
String introduction; String introduction;
@ApiModelProperty(value = "是否启用", example = "true") @Parameter(description = "是否启用", example = "true")
Boolean enable; Boolean enable;
} }
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.auth.param.auth; package com.yiring.auth.param.auth;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.annotations.ApiModelProperty; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import javax.validation.constraints.NotEmpty;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
...@@ -16,7 +16,7 @@ import lombok.experimental.FieldDefaults; ...@@ -16,7 +16,7 @@ import lombok.experimental.FieldDefaults;
* @version 0.1 * @version 0.1
* 2019/5/28 22:11 * 2019/5/28 22:11
*/ */
@ApiModel("SafeParam") @Schema(name = "SafeParam")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -27,7 +27,7 @@ public class SafeParam implements Serializable { ...@@ -27,7 +27,7 @@ public class SafeParam implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 9106494470582579138L; private static final long serialVersionUID = 9106494470582579138L;
@ApiModelProperty(value = "密码", example = "123456", required = true) @Parameter(description = "密码", example = "123456")
@NotEmpty(message = "密码不能为空") @NotEmpty(message = "密码不能为空")
String password; String password;
} }
...@@ -4,13 +4,13 @@ package com.yiring.auth.param.permission; ...@@ -4,13 +4,13 @@ package com.yiring.auth.param.permission;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.yiring.auth.domain.permission.Permission; import com.yiring.auth.domain.permission.Permission;
import com.yiring.common.validation.group.Group; import com.yiring.common.validation.group.Group;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.annotations.ApiModelProperty; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
...@@ -23,7 +23,7 @@ import lombok.experimental.FieldDefaults; ...@@ -23,7 +23,7 @@ import lombok.experimental.FieldDefaults;
*/ */
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@ApiModel("PermissionParam") @Schema(name = "PermissionParam")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -34,47 +34,47 @@ public class PermissionParam implements Serializable { ...@@ -34,47 +34,47 @@ public class PermissionParam implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -6781934969837655538L; private static final long serialVersionUID = -6781934969837655538L;
@ApiModelProperty(value = "id", example = "1") @Parameter(description = "id", example = "1")
@NotBlank(groups = { Group.Edit.class }) @NotBlank(groups = { Group.Edit.class })
String id; String id;
@ApiModelProperty(value = "权限类型", example = "MENU", required = true) @Parameter(description = "权限类型", example = "MENU")
@NotNull(message = "权限类型不能为空") @NotNull(message = "权限类型不能为空")
Permission.Type type; Permission.Type type;
@ApiModelProperty(value = "序号", example = "1") @Parameter(description = "序号", example = "1")
Integer serial; Integer serial;
@ApiModelProperty(value = "标识", example = "Dashboard", required = true) @Parameter(description = "标识", example = "Dashboard")
@NotEmpty(message = "权限标识不能为空") @NotEmpty(message = "权限标识不能为空")
String uid; String uid;
@ApiModelProperty(value = "名称", example = "Dashboard", required = true) @Parameter(description = "名称", example = "Dashboard")
@NotEmpty(message = "权限名称不能为空") @NotEmpty(message = "权限名称不能为空")
String name; String name;
@ApiModelProperty(value = "路径", example = "/dashboard") @Parameter(description = "路径", example = "/dashboard")
String path; String path;
@ApiModelProperty(value = "重定向", example = "/dashboard/workbench") @Parameter(description = "重定向", example = "/dashboard/workbench")
String redirect; String redirect;
@ApiModelProperty(value = "组件", example = "LAYOUT") @Parameter(description = "组件", example = "LAYOUT")
String component; String component;
@ApiModelProperty(value = "图标", example = "ion:grid-outline") @Parameter(description = "图标", example = "ion:grid-outline")
String icon; String icon;
@ApiModelProperty(value = "是否隐藏", example = "false") @Parameter(description = "是否隐藏", example = "false")
Boolean hidden; Boolean hidden;
@ApiModelProperty(value = "是否启用", example = "true") @Parameter(description = "是否启用", example = "true")
Boolean enable; Boolean enable;
@ApiModelProperty(value = "父级ID", example = "0") @Parameter(description = "父级ID", example = "0")
@Builder.Default @Builder.Default
String pid = "0"; String pid = "0";
@ApiModelProperty(value = "元数据", example = "{\"title\": \"routes.dashboard.dashboard\"}") @Parameter(description = "元数据", example = "{\"title\": \"routes.dashboard.dashboard\"}")
String meta; String meta;
} }
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
package com.yiring.auth.param.role; package com.yiring.auth.param.role;
import com.yiring.common.validation.group.Group; import com.yiring.common.validation.group.Group;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.annotations.ApiModelProperty; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
...@@ -19,7 +19,7 @@ import lombok.experimental.FieldDefaults; ...@@ -19,7 +19,7 @@ import lombok.experimental.FieldDefaults;
* 2022/3/25 17:09 * 2022/3/25 17:09
*/ */
@ApiModel("RoleParam") @Schema(name = "RoleParam")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -30,15 +30,15 @@ public class RoleParam implements Serializable { ...@@ -30,15 +30,15 @@ public class RoleParam implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 6572751635422870217L; private static final long serialVersionUID = 6572751635422870217L;
@ApiModelProperty(value = "id", example = "1") @Parameter(description = "id", example = "1")
@NotBlank(groups = { Group.Edit.class }) @NotBlank(groups = { Group.Edit.class })
String id; String id;
@ApiModelProperty(value = "标识", example = "admin", required = true) @Parameter(description = "标识", example = "admin")
@NotEmpty(message = "角色标识不能为空") @NotEmpty(message = "角色标识不能为空")
String uid; String uid;
@ApiModelProperty(value = "名称", example = "管理员", required = true) @Parameter(description = "名称", example = "管理员")
@NotEmpty(message = "角色名称不能为空") @NotEmpty(message = "角色名称不能为空")
String name; String name;
} }
...@@ -9,8 +9,8 @@ import com.yiring.common.core.Status; ...@@ -9,8 +9,8 @@ import com.yiring.common.core.Status;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Resource;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
...@@ -23,10 +23,10 @@ import org.springframework.stereotype.Component; ...@@ -23,10 +23,10 @@ import org.springframework.stereotype.Component;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Component @Component
@RequiredArgsConstructor
public class Auths { public class Auths {
@Resource final UserRepository userRepository;
UserRepository userRepository;
/** /**
* 管理员角色标识 * 管理员角色标识
...@@ -36,6 +36,7 @@ public class Auths { ...@@ -36,6 +36,7 @@ public class Auths {
/** /**
* 根据 Token 获取用户信息 * 根据 Token 获取用户信息
* 如果用户未登录或校验失败会抛出 NotLoginException {@link Status#UNAUTHORIZED} * 如果用户未登录或校验失败会抛出 NotLoginException {@link Status#UNAUTHORIZED}
*
* @param token token * @param token token
* @return 用户信息 * @return 用户信息
*/ */
...@@ -70,6 +71,7 @@ public class Auths { ...@@ -70,6 +71,7 @@ public class Auths {
/** /**
* 踢出这个用户 id 所有登录状态(可能有多人重复登录了一个账号的情况) * 踢出这个用户 id 所有登录状态(可能有多人重复登录了一个账号的情况)
*
* @param userId 用户 id * @param userId 用户 id
*/ */
public void logoutAll(String userId) { public void logoutAll(String userId) {
...@@ -81,6 +83,7 @@ public class Auths { ...@@ -81,6 +83,7 @@ public class Auths {
/** /**
* 判断用户是否为超级管理员 * 判断用户是否为超级管理员
*
* @param userId 用户 ID * @param userId 用户 ID
* @return 是否为管理员 * @return 是否为管理员
*/ */
...@@ -91,6 +94,7 @@ public class Auths { ...@@ -91,6 +94,7 @@ public class Auths {
/** /**
* 检查用户是否为管理员(检查用户是否拥有包含 admin 字符的角色) * 检查用户是否为管理员(检查用户是否拥有包含 admin 字符的角色)
*
* @param user 用户 * @param user 用户
* @return 是否为管理员 * @return 是否为管理员
*/ */
...@@ -104,6 +108,7 @@ public class Auths { ...@@ -104,6 +108,7 @@ public class Auths {
/** /**
* 检查当前登录用户是否为管理员 * 检查当前登录用户是否为管理员
* {@link this.isAdmin} * {@link this.isAdmin}
*
* @return 是否为管理员 * @return 是否为管理员
*/ */
public boolean checkLoginUserIsAdmin() { public boolean checkLoginUserIsAdmin() {
......
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.auth.util; package com.yiring.auth.util;
import com.sun.istack.Nullable;
import com.yiring.auth.domain.permission.Permission; import com.yiring.auth.domain.permission.Permission;
import com.yiring.auth.domain.role.Role; import com.yiring.auth.domain.role.Role;
import com.yiring.auth.vo.permission.MenuVo; import com.yiring.auth.vo.permission.MenuVo;
import com.yiring.auth.vo.permission.PermissionVo; import com.yiring.auth.vo.permission.PermissionVo;
import com.yiring.auth.vo.role.RoleVo; import com.yiring.auth.vo.role.RoleVo;
import com.yiring.common.util.Commons; import com.yiring.common.util.Commons;
import jakarta.annotation.Nullable;
import java.util.*; import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -28,6 +28,7 @@ public class Permissions { ...@@ -28,6 +28,7 @@ public class Permissions {
/** /**
* 将角色集合转换成 Vo 集合 * 将角色集合转换成 Vo 集合
*
* @param roles 角色集合 * @param roles 角色集合
* @return vos * @return vos
*/ */
...@@ -40,6 +41,7 @@ public class Permissions { ...@@ -40,6 +41,7 @@ public class Permissions {
/** /**
* 将权限集合转换成菜单树 * 将权限集合转换成菜单树
*
* @param permissions 权限集合 * @param permissions 权限集合
* @return 菜单树 * @return 菜单树
*/ */
...@@ -75,6 +77,7 @@ public class Permissions { ...@@ -75,6 +77,7 @@ public class Permissions {
/** /**
* 菜单树递归排序 * 菜单树递归排序
*
* @param menus 菜单集合 * @param menus 菜单集合
* @return 排序后的菜单集合 * @return 排序后的菜单集合
*/ */
...@@ -88,7 +91,7 @@ public class Permissions { ...@@ -88,7 +91,7 @@ public class Permissions {
) )
) )
.peek(item -> { .peek(item -> {
if (!Commons.isNullOrEmpty(item.getChildren())) { if (Commons.notEmpty(item.getChildren())) {
item.setChildren(sortMenuTreeVo(item.getChildren())); item.setChildren(sortMenuTreeVo(item.getChildren()));
} }
}) })
...@@ -97,6 +100,7 @@ public class Permissions { ...@@ -97,6 +100,7 @@ public class Permissions {
/** /**
* 将权限集合转换成 Vo 集合 * 将权限集合转换成 Vo 集合
*
* @param permissions 权限集合 * @param permissions 权限集合
* @return vos * @return vos
*/ */
...@@ -114,6 +118,7 @@ public class Permissions { ...@@ -114,6 +118,7 @@ public class Permissions {
/** /**
* 提取角色集合含有的权限去重结果 * 提取角色集合含有的权限去重结果
*
* @param roles 角色集合 * @param roles 角色集合
* @return 权限集合 * @return 权限集合
*/ */
...@@ -130,8 +135,9 @@ public class Permissions { ...@@ -130,8 +135,9 @@ public class Permissions {
/** /**
* 根据 pid 构建树状权限集合 * 根据 pid 构建树状权限集合
*
* @param permissions 权限集合 * @param permissions 权限集合
* @param pid 权限父级 ID * @param pid 权限父级 ID
* @return 树状权限集合 * @return 树状权限集合
*/ */
public List<PermissionVo> toTree(List<Permission> permissions, @NonNull String pid) { public List<PermissionVo> toTree(List<Permission> permissions, @NonNull String pid) {
......
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.auth.vo.auth; package com.yiring.auth.vo.auth;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import lombok.*; import lombok.*;
...@@ -16,7 +15,7 @@ import lombok.experimental.FieldDefaults; ...@@ -16,7 +15,7 @@ import lombok.experimental.FieldDefaults;
* 2019/5/28 22:11 * 2019/5/28 22:11
*/ */
@ApiModel("LoginVo") @Schema(name = "LoginVo")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -27,9 +26,9 @@ public class LoginVo implements Serializable { ...@@ -27,9 +26,9 @@ public class LoginVo implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -8690942241103456896L; private static final long serialVersionUID = -8690942241103456896L;
@ApiModelProperty(value = "用户 ID", example = "1") @Schema(description = "用户 ID", example = "1")
String userId; String userId;
@ApiModelProperty(value = "token", example = "c68ca9c8c04b4a59afeafd2fb7c04741") @Schema(description = "token", example = "c68ca9c8c04b4a59afeafd2fb7c04741")
String token; String token;
} }
...@@ -4,8 +4,7 @@ package com.yiring.auth.vo.permission; ...@@ -4,8 +4,7 @@ package com.yiring.auth.vo.permission;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
...@@ -21,7 +20,7 @@ import lombok.experimental.FieldDefaults; ...@@ -21,7 +20,7 @@ import lombok.experimental.FieldDefaults;
*/ */
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@ApiModel("MenuVo") @Schema(name = "MenuVo")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -38,24 +37,24 @@ public class MenuVo implements Serializable { ...@@ -38,24 +37,24 @@ public class MenuVo implements Serializable {
@JsonIgnore @JsonIgnore
String pid; String pid;
@ApiModelProperty(value = "唯一标识", example = "Dashboard") @Schema(description = "唯一标识", example = "Dashboard")
String uid; String uid;
@ApiModelProperty(value = "名称", example = "Dashboard") @Schema(description = "名称", example = "Dashboard")
String name; String name;
@ApiModelProperty(value = "路径", example = "/dashboard") @Schema(description = "路径", example = "/dashboard")
String path; String path;
@ApiModelProperty(value = "重定向", example = "/dashboard/workbench") @Schema(description = "重定向", example = "/dashboard/workbench")
String redirect; String redirect;
@ApiModelProperty(value = "组件", example = "LAYOUT") @Schema(description = "组件", example = "LAYOUT")
String component; String component;
@ApiModelProperty(value = "元数据", example = "{\"title\": \"routes.dashboard.dashboard\"}") @Schema(description = "元数据", example = "{\"title\": \"routes.dashboard.dashboard\"}")
JSONObject meta; JSONObject meta;
@ApiModelProperty(value = "子权限") @Schema(description = "子权限")
List<MenuVo> children; List<MenuVo> children;
} }
...@@ -4,8 +4,8 @@ package com.yiring.auth.vo.permission; ...@@ -4,8 +4,8 @@ package com.yiring.auth.vo.permission;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.yiring.auth.domain.permission.Permission; import com.yiring.auth.domain.permission.Permission;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.annotations.ApiModelProperty; import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
...@@ -14,13 +14,14 @@ import lombok.experimental.FieldDefaults; ...@@ -14,13 +14,14 @@ import lombok.experimental.FieldDefaults;
/** /**
* 权限输出类 * 权限输出类
*
* @author Jim * @author Jim
* @version 0.1 * @version 0.1
* 2022/3/25 17:09 * 2022/3/25 17:09
*/ */
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@ApiModel("PermissionVo") @Schema(name = "PermissionVo")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -31,42 +32,42 @@ public class PermissionVo implements Serializable { ...@@ -31,42 +32,42 @@ public class PermissionVo implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -9139328772148985141L; private static final long serialVersionUID = -9139328772148985141L;
@ApiModelProperty(value = "主键", example = "1") @Parameter(description = "主键", example = "1")
String id; String id;
@ApiModelProperty(value = "权限类型", example = "MENU") @Parameter(description = "权限类型", example = "MENU")
Permission.Type type; Permission.Type type;
@ApiModelProperty(value = "序号", example = "1") @Parameter(description = "序号", example = "1")
Integer serial; Integer serial;
@ApiModelProperty(value = "标识", example = "home") @Parameter(description = "标识", example = "home")
String uid; String uid;
@ApiModelProperty(value = "名称", example = "主页") @Parameter(description = "名称", example = "主页")
String name; String name;
@ApiModelProperty(value = "路径", example = "/") @Parameter(description = "路径", example = "/")
String path; String path;
@ApiModelProperty(value = "组件", example = "/home") @Parameter(description = "组件", example = "/home")
String component; String component;
@ApiModelProperty(value = "图标", example = "menu") @Parameter(description = "图标", example = "menu")
String icon; String icon;
@ApiModelProperty(value = "是否隐藏", example = "false") @Parameter(description = "是否隐藏", example = "false")
Boolean hidden; Boolean hidden;
@ApiModelProperty(value = "是否启用", example = "true") @Parameter(description = "是否启用", example = "true")
Boolean enable; Boolean enable;
@ApiModelProperty(value = "父级ID", example = "0") @Parameter(description = "父级ID", example = "0")
String pid; String pid;
@ApiModelProperty(value = "元数据", example = "{\"title\": \"routes.dashboard.dashboard\"}") @Parameter(description = "元数据", example = "{\"title\": \"routes.dashboard.dashboard\"}")
JSONObject meta; JSONObject meta;
@ApiModelProperty(value = "子权限") @Parameter(description = "子权限")
List<PermissionVo> children; List<PermissionVo> children;
} }
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
package com.yiring.auth.vo.role; package com.yiring.auth.vo.role;
import com.yiring.auth.vo.permission.PermissionVo; import com.yiring.auth.vo.permission.PermissionVo;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
...@@ -12,12 +11,13 @@ import lombok.experimental.FieldDefaults; ...@@ -12,12 +11,13 @@ import lombok.experimental.FieldDefaults;
/** /**
* 角色响应类 * 角色响应类
*
* @author Jim * @author Jim
* @version 0.1 * @version 0.1
* 2022/3/25 17:09 * 2022/3/25 17:09
*/ */
@ApiModel("RoleVo") @Schema(name = "RoleVo")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -28,15 +28,15 @@ public class RoleVo implements Serializable { ...@@ -28,15 +28,15 @@ public class RoleVo implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -9154497137563970840L; private static final long serialVersionUID = -9154497137563970840L;
@ApiModelProperty(value = "主键", example = "1") @Schema(description = "主键", example = "1")
String id; String id;
@ApiModelProperty(value = "标识", example = "admin") @Schema(description = "标识", example = "admin")
String uid; String uid;
@ApiModelProperty(value = "名称", example = "系统管理员") @Schema(description = "名称", example = "系统管理员")
String name; String name;
@ApiModelProperty("权限") @Schema(description = "权限")
List<PermissionVo> permissions; List<PermissionVo> permissions;
} }
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
package com.yiring.auth.vo.user; package com.yiring.auth.vo.user;
import com.yiring.auth.vo.role.RoleVo; import com.yiring.auth.vo.role.RoleVo;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -13,11 +12,12 @@ import lombok.experimental.FieldDefaults; ...@@ -13,11 +12,12 @@ import lombok.experimental.FieldDefaults;
/** /**
* 用户信息 * 用户信息
*
* @author ifzm * @author ifzm
* 2022/03/03 10:35 * 2022/03/03 10:35
**/ **/
@ApiModel("UserInfo") @Schema(name = "UserInfo")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -28,28 +28,28 @@ public class UserInfoVo implements Serializable { ...@@ -28,28 +28,28 @@ public class UserInfoVo implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -5319037883240327088L; private static final long serialVersionUID = -5319037883240327088L;
@ApiModelProperty(value = "主键", example = "1") @Schema(description = "主键", example = "1")
String userId; String userId;
@ApiModelProperty(value = "手机号", example = "15616260195") @Schema(description = "手机号", example = "15616260195")
String mobile; String mobile;
@ApiModelProperty(value = "真实姓名", example = "超级用户") @Schema(description = "真实姓名", example = "超级用户")
String realName; String realName;
@ApiModelProperty(value = "用户名", example = "admin") @Schema(description = "用户名", example = "admin")
String username; String username;
@ApiModelProperty(value = "介绍", example = "系统管理员") @Schema(description = "介绍", example = "系统管理员")
String desc; String desc;
@ApiModelProperty(value = "头像", example = "https://s1.ax1x.com/2022/03/30/qggJH0.jpg") @Schema(description = "头像", example = "https://s1.ax1x.com/2022/03/30/qggJH0.jpg")
String avatar; String avatar;
@ApiModelProperty("角色") @Schema(description = "角色")
@Builder.Default @Builder.Default
List<RoleVo> roles = new ArrayList<>(0); List<RoleVo> roles = new ArrayList<>(0);
@ApiModelProperty(value = "用户主页", example = "/dashboard/workbench") @Schema(description = "用户主页", example = "/dashboard/workbench")
String homePath; String homePath;
} }
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
package com.yiring.auth.vo.user; package com.yiring.auth.vo.user;
import com.yiring.auth.vo.role.RoleVo; import com.yiring.auth.vo.role.RoleVo;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -13,11 +12,12 @@ import lombok.experimental.FieldDefaults; ...@@ -13,11 +12,12 @@ import lombok.experimental.FieldDefaults;
/** /**
* 用户信息 * 用户信息
*
* @author ifzm * @author ifzm
* 2022/03/03 10:35 * 2022/03/03 10:35
**/ **/
@ApiModel("UserInfo") @Schema(name = "UserInfo")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -28,25 +28,25 @@ public class UserMenuListVo implements Serializable { ...@@ -28,25 +28,25 @@ public class UserMenuListVo implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -5319037883240327088L; private static final long serialVersionUID = -5319037883240327088L;
@ApiModelProperty(value = "主键", example = "1") @Schema(description = "主键", example = "1")
String userId; String userId;
@ApiModelProperty(value = "真实姓名", example = "超级用户") @Schema(description = "真实姓名", example = "超级用户")
String realName; String realName;
@ApiModelProperty(value = "用户名", example = "admin") @Schema(description = "用户名", example = "admin")
String username; String username;
@ApiModelProperty(value = "介绍", example = "系统管理员") @Schema(description = "介绍", example = "系统管理员")
String desc; String desc;
@ApiModelProperty(value = "头像", example = "https://s1.ax1x.com/2022/03/30/qggJH0.jpg") @Schema(description = "头像", example = "https://s1.ax1x.com/2022/03/30/qggJH0.jpg")
String avatar; String avatar;
@ApiModelProperty("角色") @Schema(description = "角色")
@Builder.Default @Builder.Default
List<RoleVo> roles = new ArrayList<>(0); List<RoleVo> roles = new ArrayList<>(0);
@ApiModelProperty(value = "用户主页", example = "/dashboard/workbench") @Schema(description = "用户主页", example = "/dashboard/workbench")
String homePath; String homePath;
} }
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.auth.vo.user; package com.yiring.auth.vo.user;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
...@@ -11,11 +10,12 @@ import lombok.experimental.FieldDefaults; ...@@ -11,11 +10,12 @@ import lombok.experimental.FieldDefaults;
/** /**
* 用户信息 * 用户信息
*
* @author ifzm * @author ifzm
* 2022/03/03 10:35 * 2022/03/03 10:35
**/ **/
@ApiModel("UserVo") @Schema(name = "UserVo")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -26,39 +26,39 @@ public class UserVo implements Serializable { ...@@ -26,39 +26,39 @@ public class UserVo implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -2184378273450466835L; private static final long serialVersionUID = -2184378273450466835L;
@ApiModelProperty(value = "主键", example = "1") @Schema(description = "主键", example = "1")
String id; String id;
@ApiModelProperty(value = "真实姓名", example = "超级用户") @Schema(description = "真实姓名", example = "超级用户")
String realName; String realName;
@ApiModelProperty(value = "用户名", example = "admin") @Schema(description = "用户名", example = "admin")
String username; String username;
@ApiModelProperty(value = "手机号", example = "13012345678") @Schema(description = "手机号", example = "13012345678")
String mobile; String mobile;
@ApiModelProperty(value = "邮箱", example = "developer@yiring.com") @Schema(description = "邮箱", example = "developer@yiring.com")
String email; String email;
@ApiModelProperty(value = "职称", example = "系统管理员") @Schema(description = "职称", example = "系统管理员")
String title; String title;
@ApiModelProperty(value = "头像", example = "https://s1.ax1x.com/2022/03/30/qggJH0.jpg") @Schema(description = "头像", example = "https://s1.ax1x.com/2022/03/30/qggJH0.jpg")
String avatar; String avatar;
@ApiModelProperty(value = "是否启用", example = "true") @Schema(description = "是否启用", example = "true")
Boolean enabled; Boolean enabled;
@ApiModelProperty(value = "是否删除", example = "false") @Schema(description = "是否删除", example = "false")
Boolean deleted; Boolean deleted;
@ApiModelProperty(value = "最后登录IP地址", example = "127.0.0.1") @Schema(description = "最后登录IP地址", example = "127.0.0.1")
String lastLoginIp; String lastLoginIp;
@ApiModelProperty(value = "最后登录时间", example = "2022-10-24 10:24:00") @Schema(description = "最后登录时间", example = "2022-10-24 10:24:00")
LocalDateTime lastLoginTime; LocalDateTime lastLoginTime;
@ApiModelProperty(value = "最后登录时间", example = "2022-01-01 00:00:00") @Schema(description = "最后登录时间", example = "2022-01-01 00:00:00")
LocalDateTime createTime; LocalDateTime createTime;
} }
...@@ -5,7 +5,6 @@ import cn.dev33.satoken.annotation.SaCheckLogin; ...@@ -5,7 +5,6 @@ import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.secure.SaSecureUtil; import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.yiring.auth.domain.user.User; import com.yiring.auth.domain.user.User;
import com.yiring.auth.domain.user.UserRepository; import com.yiring.auth.domain.user.UserRepository;
import com.yiring.auth.param.auth.LoginParam; import com.yiring.auth.param.auth.LoginParam;
...@@ -16,12 +15,15 @@ import com.yiring.auth.vo.auth.LoginVo; ...@@ -16,12 +15,15 @@ import com.yiring.auth.vo.auth.LoginVo;
import com.yiring.common.core.Result; import com.yiring.common.core.Result;
import com.yiring.common.exception.BusinessException; import com.yiring.common.exception.BusinessException;
import com.yiring.common.util.Commons; import com.yiring.common.util.Commons;
import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.extensions.Extension;
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import javax.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.data.domain.Example; import org.springframework.data.domain.Example;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
...@@ -39,9 +41,11 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -39,9 +41,11 @@ import org.springframework.web.bind.annotation.RestController;
@Slf4j @Slf4j
@Validated @Validated
@SuppressWarnings({ "all" }) @Tag(
@ApiSupport(order = -99) name = "Auth",
@Api(tags = "身份认证", description = "Auth") description = "身份认证",
extensions = { @Extension(properties = { @ExtensionProperty(name = "x-order", value = "-9999") }) }
)
@RestController @RestController
@RequestMapping("/auth/") @RequestMapping("/auth/")
@RequiredArgsConstructor @RequiredArgsConstructor
...@@ -50,9 +54,9 @@ public class AuthController { ...@@ -50,9 +54,9 @@ public class AuthController {
final Auths auths; final Auths auths;
final UserRepository userRepository; final UserRepository userRepository;
@ApiOperation(value = "注册") @Operation(summary = "注册")
@PostMapping("register") @PostMapping(value = "register")
public Result<String> register(@Validated RegisterParam param) { public Result<String> register(@ParameterObject @Validated RegisterParam param) {
// 检查用户名是否存在 // 检查用户名是否存在
long count = userRepository.count(Example.of(User.builder().username(param.getUsername()).build())); long count = userRepository.count(Example.of(User.builder().username(param.getUsername()).build()));
if (count > 0) { if (count > 0) {
...@@ -88,9 +92,9 @@ public class AuthController { ...@@ -88,9 +92,9 @@ public class AuthController {
return Result.ok(); return Result.ok();
} }
@ApiOperation(value = "登录") @Operation(summary = "登录")
@PostMapping("login") @PostMapping("login")
public Result<LoginVo> login(@Validated LoginParam param, HttpServletRequest request) { public Result<LoginVo> login(@ParameterObject @Validated LoginParam param, HttpServletRequest request) {
// 查询用户信息是否匹配 // 查询用户信息是否匹配
User user = userRepository.findByAccount(param.getAccount()); User user = userRepository.findByAccount(param.getAccount());
if (user == null) { if (user == null) {
...@@ -126,13 +130,13 @@ public class AuthController { ...@@ -126,13 +130,13 @@ public class AuthController {
return Result.ok(vo); return Result.ok(vo);
} }
@ApiOperation(value = "检查登录") @Operation(summary = "检查登录")
@GetMapping("valid") @GetMapping("valid")
public Result<Boolean> valid() { public Result<Boolean> valid() {
return Result.ok(StpUtil.isLogin()); return Result.ok(StpUtil.isLogin());
} }
@ApiOperation(value = "登出") @Operation(summary = "登出")
@GetMapping("logout") @GetMapping("logout")
public Result<String> logout() { public Result<String> logout() {
StpUtil.logout(); StpUtil.logout();
...@@ -144,13 +148,12 @@ public class AuthController { ...@@ -144,13 +148,12 @@ public class AuthController {
* 默认安全时间: 120s * 默认安全时间: 120s
* *
* @param param 用户密码 * @param param 用户密码
* @return * @link { <a href="https://sa-token.dev33.cn/doc.html#/up/safe-auth">...</a> }
* @link { https://sa-token.dev33.cn/doc.html#/up/safe-auth }
*/ */
@SaCheckLogin @SaCheckLogin
@ApiOperation(value = "安全校验") @Operation(summary = "安全验证")
@GetMapping("safe") @GetMapping("safe")
public Result<String> safe(@Validated SafeParam param) { public Result<String> safe(@ParameterObject @Validated SafeParam param) {
User user = auths.getLoginUser(); User user = auths.getLoginUser();
if (SaSecureUtil.sha256(param.getPassword()).equals(user.getPassword())) { if (SaSecureUtil.sha256(param.getPassword()).equals(user.getPassword())) {
StpUtil.openSafe(120); StpUtil.openSafe(120);
......
...@@ -4,7 +4,6 @@ package com.yiring.auth.web.sys.permission; ...@@ -4,7 +4,6 @@ package com.yiring.auth.web.sys.permission;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONValidator; import com.alibaba.fastjson2.JSONValidator;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.yiring.auth.domain.permission.Permission; import com.yiring.auth.domain.permission.Permission;
import com.yiring.auth.domain.permission.PermissionRepository; import com.yiring.auth.domain.permission.PermissionRepository;
import com.yiring.auth.param.permission.PermissionParam; import com.yiring.auth.param.permission.PermissionParam;
...@@ -18,13 +17,16 @@ import com.yiring.common.param.PageParam; ...@@ -18,13 +17,16 @@ import com.yiring.common.param.PageParam;
import com.yiring.common.param.PidParam; import com.yiring.common.param.PidParam;
import com.yiring.common.validation.group.Group; import com.yiring.common.validation.group.Group;
import com.yiring.common.vo.PageVo; import com.yiring.common.vo.PageVo;
import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.extensions.Extension;
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Example; import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
...@@ -44,9 +46,11 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -44,9 +46,11 @@ import org.springframework.web.bind.annotation.RestController;
@Slf4j @Slf4j
@Validated @Validated
@SuppressWarnings({ "deprecation" }) @Tag(
@ApiSupport(order = -97) name = "权限管理",
@Api(tags = "权限管理", description = "Permission") description = "Permission",
extensions = { @Extension(properties = { @ExtensionProperty(name = "x-order", value = "-99") }) }
)
@RestController @RestController
@RequestMapping("/sys/permission/") @RequestMapping("/sys/permission/")
@RequiredArgsConstructor @RequiredArgsConstructor
...@@ -54,9 +58,9 @@ public class PermissionController { ...@@ -54,9 +58,9 @@ public class PermissionController {
final PermissionRepository permissionRepository; final PermissionRepository permissionRepository;
@ApiOperation(value = "新增") @Operation(summary = "新增")
@PostMapping("add") @PostMapping("add")
public Result<String> add(@Validated({ Group.Add.class }) PermissionParam param) { public Result<String> add(@ParameterObject @Validated({ Group.Add.class }) PermissionParam param) {
if (has(param.getUid())) { if (has(param.getUid())) {
throw BusinessException.i18n("Code.1001"); throw BusinessException.i18n("Code.1001");
} }
...@@ -66,9 +70,9 @@ public class PermissionController { ...@@ -66,9 +70,9 @@ public class PermissionController {
return Result.ok(); return Result.ok();
} }
@ApiOperation(value = "修改") @Operation(summary = "修改")
@PostMapping("modify") @PostMapping("modify")
public Result<String> modify(@Validated({ Group.Edit.class }) PermissionParam param) { public Result<String> modify(@ParameterObject @Validated({ Group.Edit.class }) PermissionParam param) {
Optional<Permission> optional = permissionRepository.findById(param.getId()); Optional<Permission> optional = permissionRepository.findById(param.getId());
if (optional.isEmpty()) { if (optional.isEmpty()) {
throw Status.NOT_FOUND.exception(); throw Status.NOT_FOUND.exception();
...@@ -86,9 +90,9 @@ public class PermissionController { ...@@ -86,9 +90,9 @@ public class PermissionController {
return Result.ok(); return Result.ok();
} }
@ApiOperation(value = "删除") @Operation(summary = "删除")
@PostMapping("deleted") @PostMapping("deleted")
public Result<String> deleted(@Validated IdParam param) { public Result<String> deleted(@ParameterObject @Validated IdParam param) {
Optional<Permission> optional = permissionRepository.findById(param.getId()); Optional<Permission> optional = permissionRepository.findById(param.getId());
if (optional.isEmpty()) { if (optional.isEmpty()) {
throw Status.NOT_FOUND.exception(); throw Status.NOT_FOUND.exception();
...@@ -99,9 +103,9 @@ public class PermissionController { ...@@ -99,9 +103,9 @@ public class PermissionController {
return Result.ok(); return Result.ok();
} }
@ApiOperation(value = "查询") @Operation(summary = "查询")
@GetMapping("find") @GetMapping("find")
public Result<PermissionVo> find(@Validated IdParam param) { public Result<PermissionVo> find(@ParameterObject @Validated IdParam param) {
Optional<Permission> optional = permissionRepository.findById(param.getId()); Optional<Permission> optional = permissionRepository.findById(param.getId());
if (optional.isEmpty()) { if (optional.isEmpty()) {
throw Status.NOT_FOUND.exception(); throw Status.NOT_FOUND.exception();
...@@ -114,18 +118,18 @@ public class PermissionController { ...@@ -114,18 +118,18 @@ public class PermissionController {
return Result.ok(vo); return Result.ok(vo);
} }
@ApiOperation(value = "分页查询") @Operation(summary = "分页查询")
@GetMapping("page") @GetMapping("page")
public Result<PageVo<PermissionVo>> page(@Validated PageParam param) { public Result<PageVo<PermissionVo>> page(@ParameterObject @Validated PageParam param) {
Page<Permission> page = permissionRepository.findAll(PageParam.toPageable(param)); Page<Permission> page = permissionRepository.findAll(PageParam.toPageable(param));
List<PermissionVo> data = Permissions.toPermissionVos(page.toList()); List<PermissionVo> data = Permissions.toPermissionVos(page.toList());
PageVo<PermissionVo> vo = PageVo.build(data, page.getTotalElements()); PageVo<PermissionVo> vo = PageVo.build(data, page.getTotalElements());
return Result.ok(vo); return Result.ok(vo);
} }
@ApiOperation(value = "树结构查询") @Operation(summary = "树结构查询")
@GetMapping(value = "tree") @GetMapping(value = "tree")
public Result<ArrayList<PermissionVo>> tree(@Validated(Group.Optional.class) PidParam param) { public Result<ArrayList<PermissionVo>> tree(@ParameterObject @Validated(Group.Optional.class) PidParam param) {
List<Permission> permissions = permissionRepository.findAll(); List<Permission> permissions = permissionRepository.findAll();
List<PermissionVo> vos = Permissions.toTree( List<PermissionVo> vos = Permissions.toTree(
permissions, permissions,
......
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.auth.web.sys.role; package com.yiring.auth.web.sys.role;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.yiring.auth.domain.permission.Permission; import com.yiring.auth.domain.permission.Permission;
import com.yiring.auth.domain.permission.PermissionRepository; import com.yiring.auth.domain.permission.PermissionRepository;
import com.yiring.auth.domain.role.Role; import com.yiring.auth.domain.role.Role;
...@@ -17,12 +16,15 @@ import com.yiring.common.param.IdsParam; ...@@ -17,12 +16,15 @@ import com.yiring.common.param.IdsParam;
import com.yiring.common.param.PageParam; import com.yiring.common.param.PageParam;
import com.yiring.common.validation.group.Group; import com.yiring.common.validation.group.Group;
import com.yiring.common.vo.PageVo; import com.yiring.common.vo.PageVo;
import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.extensions.Extension;
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.io.Serializable; import java.io.Serializable;
import java.util.*; import java.util.*;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Example; import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
...@@ -42,9 +44,11 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -42,9 +44,11 @@ import org.springframework.web.bind.annotation.RestController;
@Slf4j @Slf4j
@Validated @Validated
@SuppressWarnings({ "deprecation" }) @Tag(
@ApiSupport(order = -96) name = "角色管理",
@Api(tags = "角色管理", description = "Role") description = "Role",
extensions = { @Extension(properties = { @ExtensionProperty(name = "x-order", value = "-98") }) }
)
@RestController @RestController
@RequestMapping("/sys/role/") @RequestMapping("/sys/role/")
@RequiredArgsConstructor @RequiredArgsConstructor
...@@ -53,9 +57,9 @@ public class RoleController { ...@@ -53,9 +57,9 @@ public class RoleController {
final RoleRepository roleRepository; final RoleRepository roleRepository;
final PermissionRepository permissionRepository; final PermissionRepository permissionRepository;
@ApiOperation(value = "新增") @Operation(summary = "新增")
@PostMapping("add") @PostMapping("add")
public Result<String> add(@Validated({ Group.Add.class }) RoleParam param) { public Result<String> add(@ParameterObject @Validated({ Group.Add.class }) RoleParam param) {
if (has(param.getUid())) { if (has(param.getUid())) {
throw BusinessException.i18n("Code.1002"); throw BusinessException.i18n("Code.1002");
} }
...@@ -66,9 +70,9 @@ public class RoleController { ...@@ -66,9 +70,9 @@ public class RoleController {
return Result.ok(); return Result.ok();
} }
@ApiOperation(value = "修改") @Operation(summary = "修改")
@PostMapping("modify") @PostMapping("modify")
public Result<String> modify(@Validated({ Group.Edit.class }) RoleParam param) { public Result<String> modify(@ParameterObject @Validated({ Group.Edit.class }) RoleParam param) {
Optional<Role> optional = roleRepository.findById(param.getId()); Optional<Role> optional = roleRepository.findById(param.getId());
if (optional.isEmpty()) { if (optional.isEmpty()) {
throw Status.NOT_FOUND.exception(); throw Status.NOT_FOUND.exception();
...@@ -87,9 +91,12 @@ public class RoleController { ...@@ -87,9 +91,12 @@ public class RoleController {
return Result.ok(); return Result.ok();
} }
@ApiOperation(value = "分配权限") @Operation(summary = "分配权限")
@PostMapping("assign") @PostMapping("assign")
public Result<String> assign(@Validated IdParam idParam, @Validated IdsParam idsParam) { public Result<String> assign(
@ParameterObject @Validated IdParam idParam,
@ParameterObject @Validated IdsParam idsParam
) {
Optional<Role> optional = roleRepository.findById(idParam.getId()); Optional<Role> optional = roleRepository.findById(idParam.getId());
if (optional.isEmpty()) { if (optional.isEmpty()) {
throw Status.NOT_FOUND.exception(); throw Status.NOT_FOUND.exception();
...@@ -105,17 +112,17 @@ public class RoleController { ...@@ -105,17 +112,17 @@ public class RoleController {
return Result.ok(); return Result.ok();
} }
@ApiOperation(value = "删除") @Operation(summary = "删除")
@PostMapping("deleted") @PostMapping("deleted")
public Result<String> deleted(@Validated IdsParam param) { public Result<String> deleted(@ParameterObject @Validated IdsParam param) {
List<Role> roles = roleRepository.findAllById(param.toIds()); List<Role> roles = roleRepository.findAllById(param.toIds());
roleRepository.deleteAll(roles); roleRepository.deleteAll(roles);
return Result.ok(); return Result.ok();
} }
@ApiOperation(value = "查询") @Operation(summary = "查询")
@GetMapping("find") @GetMapping("find")
public Result<RoleVo> find(@Validated IdParam param) { public Result<RoleVo> find(@ParameterObject @Validated IdParam param) {
Optional<Role> optional = roleRepository.findById(param.getId()); Optional<Role> optional = roleRepository.findById(param.getId());
if (optional.isEmpty()) { if (optional.isEmpty()) {
throw Status.NOT_FOUND.exception(); throw Status.NOT_FOUND.exception();
...@@ -128,16 +135,16 @@ public class RoleController { ...@@ -128,16 +135,16 @@ public class RoleController {
return Result.ok(vo); return Result.ok(vo);
} }
@ApiOperation(value = "分页查询") @Operation(summary = "分页查询")
@GetMapping("page") @GetMapping("page")
public Result<PageVo<RoleVo>> page(@Validated PageParam param) { public Result<PageVo<RoleVo>> page(@ParameterObject @Validated PageParam param) {
Page<Role> page = roleRepository.findAll(PageParam.toPageable(param)); Page<Role> page = roleRepository.findAll(PageParam.toPageable(param));
List<RoleVo> data = new ArrayList<>(Permissions.toRoleVos(page.toSet())); List<RoleVo> data = new ArrayList<>(Permissions.toRoleVos(page.toSet()));
PageVo<RoleVo> vo = PageVo.build(data, page.getTotalElements()); PageVo<RoleVo> vo = PageVo.build(data, page.getTotalElements());
return Result.ok(vo); return Result.ok(vo);
} }
@ApiOperation(value = "选项查询") @Operation(summary = "选项查询")
@GetMapping("selector") @GetMapping("selector")
public Result<ArrayList<RoleVo>> selector() { public Result<ArrayList<RoleVo>> selector() {
List<Role> roles = roleRepository.findAll(); List<Role> roles = roleRepository.findAll();
......
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.auth.web.sys.user; package com.yiring.auth.web.sys.user;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.yiring.auth.domain.role.Role; import com.yiring.auth.domain.role.Role;
import com.yiring.auth.domain.role.RoleRepository; import com.yiring.auth.domain.role.RoleRepository;
import com.yiring.auth.domain.user.User; import com.yiring.auth.domain.user.User;
...@@ -14,13 +13,16 @@ import com.yiring.common.param.IdsParam; ...@@ -14,13 +13,16 @@ import com.yiring.common.param.IdsParam;
import com.yiring.common.param.PageParam; import com.yiring.common.param.PageParam;
import com.yiring.common.util.Commons; import com.yiring.common.util.Commons;
import com.yiring.common.vo.PageVo; import com.yiring.common.vo.PageVo;
import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.extensions.Extension;
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.io.Serializable; import java.io.Serializable;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
...@@ -38,9 +40,11 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -38,9 +40,11 @@ import org.springframework.web.bind.annotation.RestController;
@Slf4j @Slf4j
@Validated @Validated
@SuppressWarnings({ "deprecation" }) @Tag(
@ApiSupport(order = -95) name = "用户管理",
@Api(tags = "用户管理", description = "User") description = "User",
extensions = { @Extension(properties = { @ExtensionProperty(name = "x-order", value = "-97") }) }
)
@RestController @RestController
@RequestMapping("/sys/user/") @RequestMapping("/sys/user/")
@RequiredArgsConstructor @RequiredArgsConstructor
...@@ -49,9 +53,12 @@ public class UserController { ...@@ -49,9 +53,12 @@ public class UserController {
final UserRepository userRepository; final UserRepository userRepository;
final RoleRepository roleRepository; final RoleRepository roleRepository;
@ApiOperation(value = "分配角色") @Operation(summary = "分配角色")
@PostMapping("assign") @PostMapping("assign")
public Result<String> assign(@Validated IdParam idParam, @Validated IdsParam idsParam) { public Result<String> assign(
@ParameterObject @Validated IdParam idParam,
@ParameterObject @Validated IdsParam idsParam
) {
Optional<User> optional = userRepository.findById(idParam.getId()); Optional<User> optional = userRepository.findById(idParam.getId());
if (optional.isEmpty()) { if (optional.isEmpty()) {
throw Status.NOT_FOUND.exception(); throw Status.NOT_FOUND.exception();
...@@ -67,9 +74,9 @@ public class UserController { ...@@ -67,9 +74,9 @@ public class UserController {
return Result.ok(); return Result.ok();
} }
@ApiOperation(value = "分页查询") @Operation(summary = "分页查询")
@GetMapping("page") @GetMapping("page")
public Result<PageVo<UserVo>> page(@Validated PageParam param) { public Result<PageVo<UserVo>> page(@ParameterObject @Validated PageParam param) {
Page<User> page = userRepository.findAll(PageParam.toPageable(param)); Page<User> page = userRepository.findAll(PageParam.toPageable(param));
List<UserVo> data = page.get().map(user -> Commons.transform(user, UserVo.class)).collect(Collectors.toList()); List<UserVo> data = page.get().map(user -> Commons.transform(user, UserVo.class)).collect(Collectors.toList());
......
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.auth.web.user; package com.yiring.auth.web.user;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.yiring.auth.domain.permission.Permission; import com.yiring.auth.domain.permission.Permission;
import com.yiring.auth.domain.user.User; import com.yiring.auth.domain.user.User;
import com.yiring.auth.util.Auths; import com.yiring.auth.util.Auths;
...@@ -9,8 +8,10 @@ import com.yiring.auth.util.Permissions; ...@@ -9,8 +8,10 @@ import com.yiring.auth.util.Permissions;
import com.yiring.auth.vo.permission.MenuVo; import com.yiring.auth.vo.permission.MenuVo;
import com.yiring.auth.vo.user.UserInfoVo; import com.yiring.auth.vo.user.UserInfoVo;
import com.yiring.common.core.Result; import com.yiring.common.core.Result;
import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.extensions.Extension;
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -31,9 +32,11 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -31,9 +32,11 @@ import org.springframework.web.bind.annotation.RestController;
@Slf4j @Slf4j
@Validated @Validated
@SuppressWarnings({ "deprecation" }) @Tag(
@ApiSupport(order = -95) name = "用户信息",
@Api(tags = "用户信息", description = "UserView") description = "UserView",
extensions = { @Extension(properties = { @ExtensionProperty(name = "x-order", value = "-9998") }) }
)
@RestController @RestController
@RequestMapping("/user/") @RequestMapping("/user/")
@RequiredArgsConstructor @RequiredArgsConstructor
...@@ -41,7 +44,7 @@ public class UserViewController { ...@@ -41,7 +44,7 @@ public class UserViewController {
final Auths auths; final Auths auths;
@ApiOperation(value = "获取登录用户信息") @Operation(summary = "获取登录用户信息")
@GetMapping("getUserInfo") @GetMapping("getUserInfo")
public Result<UserInfoVo> getUserInfo() { public Result<UserInfoVo> getUserInfo() {
User user = auths.getLoginUser(); User user = auths.getLoginUser();
...@@ -57,7 +60,7 @@ public class UserViewController { ...@@ -57,7 +60,7 @@ public class UserViewController {
return Result.ok(userInfoVo); return Result.ok(userInfoVo);
} }
@ApiOperation(value = "获取用户菜单") @Operation(summary = "获取用户菜单")
@GetMapping("getMenuList") @GetMapping("getMenuList")
public Result<ArrayList<MenuVo>> getMenuList() { public Result<ArrayList<MenuVo>> getMenuList() {
User user = auths.getLoginUser(); User user = auths.getLoginUser();
...@@ -70,7 +73,7 @@ public class UserViewController { ...@@ -70,7 +73,7 @@ public class UserViewController {
return Result.ok((ArrayList<MenuVo>) vos); return Result.ok((ArrayList<MenuVo>) vos);
} }
@ApiOperation(value = "获取用户权限") @Operation(summary = "获取用户权限")
@GetMapping("getPermCode") @GetMapping("getPermCode")
public Result<ArrayList<String>> getPermCode() { public Result<ArrayList<String>> getPermCode() {
User user = auths.getLoginUser(); User user = auths.getLoginUser();
......
# Sa-Token配置 # Sa-Token配置
sa-token: sa-token:
# token名称 (同时也是cookie名称) # token名称 (同时也是cookie名称)
token-name: Authorization token-name: App-Token
# token有效期,单位s 默认30天, -1代表永不过期 # token有效期,单位s 默认30天, -1代表永不过期
timeout: 2592000 timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
......
Code.1000=\u7528\u6237\u4E0D\u5B58\u5728
Code.1001=\u6743\u9650\u6807\u8BC6\u91CD\u590D Code.1001=\u6743\u9650\u6807\u8BC6\u91CD\u590D
Code.1002=\u89D2\u8272\u6807\u8BC6\u91CD\u590D Code.1002=\u89D2\u8272\u6807\u8BC6\u91CD\u590D
Code.10000=\u4E8C\u7EA7\u8BA4\u8BC1\u6821\u9A8C\u5931\u8D25
Code.10001=\u89D2\u8272\u6743\u9650\u4E0D\u8DB3
Code.10002=\u6743\u9650\u4E0D\u8DB3
Code.10003=\u672A\u6388\u6743
Code.100000=\u7528\u6237\u540D\u5DF2\u5B58\u5728 Code.100000=\u7528\u6237\u540D\u5DF2\u5B58\u5728
Code.100001=\u624B\u673A\u53F7\u5DF2\u5B58\u5728 Code.100001=\u624B\u673A\u53F7\u5DF2\u5B58\u5728
Code.100002=\u90AE\u7BB1\u5DF2\u5B58\u5728 Code.100002=\u90AE\u7BB1\u5DF2\u5B58\u5728
......
Code.1000=\u7528\u6237\u4E0D\u5B58\u5728
Code.1001=\u6743\u9650\u6807\u8BC6\u91CD\u590D Code.1001=\u6743\u9650\u6807\u8BC6\u91CD\u590D
Code.1002=\u89D2\u8272\u6807\u8BC6\u91CD\u590D Code.1002=\u89D2\u8272\u6807\u8BC6\u91CD\u590D
Code.10000=\u4E8C\u7EA7\u8BA4\u8BC1\u6821\u9A8C\u5931\u8D25
Code.10001=\u89D2\u8272\u6743\u9650\u4E0D\u8DB3
Code.10002=\u6743\u9650\u4E0D\u8DB3
Code.10003=\u672A\u6388\u6743
Code.100000=\u7528\u6237\u540D\u5DF2\u5B58\u5728 Code.100000=\u7528\u6237\u540D\u5DF2\u5B58\u5728
Code.100001=\u624B\u673A\u53F7\u5DF2\u5B58\u5728 Code.100001=\u624B\u673A\u53F7\u5DF2\u5B58\u5728
Code.100002=\u90AE\u7BB1\u5DF2\u5B58\u5728 Code.100002=\u90AE\u7BB1\u5DF2\u5B58\u5728
......
Status.OK=OK Status.OK=\u6210\u529F
Status.NON_AUTHORITATIVE_INFORMATION=\u8BA4\u8BC1\u5931\u8D25 Status.NON_AUTHORITATIVE_INFORMATION=\u8BA4\u8BC1\u5931\u8D25
Status.BAD_REQUEST=\u8BF7\u6C42\u5931\u8D25 Status.BAD_REQUEST=\u8BF7\u6C42\u5931\u8D25
Status.UNAUTHORIZED=\u51ED\u8BC1\u8FC7\u671F Status.UNAUTHORIZED=\u51ED\u8BC1\u8FC7\u671F
......
...@@ -11,7 +11,7 @@ dependencies { ...@@ -11,7 +11,7 @@ dependencies {
implementation fileTree(dir: project.rootDir.getPath() + '\\libs', includes: ['*jar']) implementation fileTree(dir: project.rootDir.getPath() + '\\libs', includes: ['*jar'])
// swagger(knife4j) // swagger(knife4j)
implementation "com.github.xiaoymin:knife4j-spring-boot-starter:${knife4jVersion}" implementation "com.github.xiaoymin:knife4j-openapi3-jakarta-spring-boot-starter:${knife4jOpen3Version}"
// hutool-extra // hutool-extra
implementation "cn.hutool:hutool-extra:${hutoolVersion}" implementation "cn.hutool:hutool-extra:${hutoolVersion}"
...@@ -22,9 +22,9 @@ dependencies { ...@@ -22,9 +22,9 @@ dependencies {
// JTS 几何对象操作库 // JTS 几何对象操作库
implementation "org.locationtech.jts:jts-core:${jtsVersion}" implementation "org.locationtech.jts:jts-core:${jtsVersion}"
// https://github.com/vladmihalcea/hibernate-types // https://github.com/vladmihalcea/hypersistence-utils
// hibernate-types-55 // hypersistence-utils-hibernate-60
implementation "com.vladmihalcea:hibernate-types-55:${hibernateTypesVersion}" implementation "io.hypersistence:hypersistence-utils-hibernate-60:${hibernateTypesVersion}"
// https://mvnrepository.com/artifact/org.n52.jackson/jackson-datatype-jts/1.2.10 // https://mvnrepository.com/artifact/org.n52.jackson/jackson-datatype-jts/1.2.10
implementation("org.n52.jackson:jackson-datatype-jts:1.2.10") { implementation("org.n52.jackson:jackson-datatype-jts:1.2.10") {
......
/* (C) 2023 YiRing, Inc. */
package com.yiring.common.annotation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import java.lang.annotation.*;
import org.springframework.core.annotation.AliasFor;
import org.springframework.http.MediaType;
/**
* 下载响应注解
*
* @author Jim
* @version 0.1
* 2023/1/12 11:22
*/
@SuppressWarnings({ "unused" })
@Target({ ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@ApiResponse
public @interface DownloadResponse {
@AliasFor(annotation = ApiResponse.class)
String responseCode() default "200";
@AliasFor(annotation = ApiResponse.class)
String description() default "OK";
@AliasFor(annotation = ApiResponse.class)
Content content() default @Content(
schema = @Schema(type = "string", format = "binary"),
mediaType = MediaType.APPLICATION_OCTET_STREAM_VALUE
);
}
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.common.aspect; package com.yiring.common.aspect;
import cn.hutool.extra.servlet.ServletUtil; import cn.hutool.extra.servlet.JakartaServletUtil;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter; import com.alibaba.fastjson2.JSONWriter;
import com.yiring.common.constant.DateFormatter; import com.yiring.common.constant.DateFormatter;
import com.yiring.common.core.Result; import com.yiring.common.core.Result;
import com.yiring.common.util.Commons; import com.yiring.common.util.Commons;
import jakarta.servlet.http.HttpServletRequest;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
...@@ -36,9 +36,9 @@ public class RequestAspect { ...@@ -36,9 +36,9 @@ public class RequestAspect {
Boolean debug; Boolean debug;
/** /**
* 白名单 * 白名单(忽略)
*/ */
List<String> WHITE_LIST = List.of("/swagger-resources", "/error"); List<String> IGNORE_LIST = List.of("/swagger-resources", "/error", "/v3/api-docs");
@Pointcut( @Pointcut(
"@annotation(org.springframework.web.bind.annotation.RequestMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping) || @annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PutMapping) || @annotation(org.springframework.web.bind.annotation.DeleteMapping) || @annotation(org.springframework.web.bind.annotation.PatchMapping) || @annotation(org.springframework.web.bind.annotation.ExceptionHandler)" "@annotation(org.springframework.web.bind.annotation.RequestMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping) || @annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PutMapping) || @annotation(org.springframework.web.bind.annotation.DeleteMapping) || @annotation(org.springframework.web.bind.annotation.PatchMapping) || @annotation(org.springframework.web.bind.annotation.ExceptionHandler)"
...@@ -49,8 +49,10 @@ public class RequestAspect { ...@@ -49,8 +49,10 @@ public class RequestAspect {
public Object around(ProceedingJoinPoint point) throws Throwable { public Object around(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request = getRequest(); HttpServletRequest request = getRequest();
// 放行白名单 // 放行白名单
if (WHITE_LIST.contains(request.getServletPath())) { for (String path : IGNORE_LIST) {
return point.proceed(); if (request.getServletPath().startsWith(path)) {
return point.proceed();
}
} }
// 计算接口执行耗时 // 计算接口执行耗时
...@@ -66,10 +68,13 @@ public class RequestAspect { ...@@ -66,10 +68,13 @@ public class RequestAspect {
String extra = ""; String extra = "";
if (Boolean.TRUE.equals(debug)) { if (Boolean.TRUE.equals(debug)) {
String headers = JSONObject.toJSONString( String headers = JSONObject.toJSONString(
ServletUtil.getHeaderMap(request), JakartaServletUtil.getHeaderMap(request),
JSONWriter.Feature.PrettyFormat
);
String params = JSONObject.toJSONString(
JakartaServletUtil.getParamMap(request),
JSONWriter.Feature.PrettyFormat JSONWriter.Feature.PrettyFormat
); );
String params = JSONObject.toJSONString(ServletUtil.getParamMap(request), JSONWriter.Feature.PrettyFormat);
extra += String.format("\nHeaders: %s", headers); extra += String.format("\nHeaders: %s", headers);
extra += String.format("\nParams: %s", params); extra += String.format("\nParams: %s", params);
if (result instanceof Result) { if (result instanceof Result) {
......
/* (C) 2023 YiRing, Inc. */
package com.yiring.common.config;
import com.yiring.common.core.I18n;
import com.yiring.common.core.Result;
import com.yiring.common.core.Status;
import com.yiring.common.exception.BusinessException;
import com.yiring.common.exception.FailStatusException;
import jakarta.validation.ConstraintViolationException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.ClientAbortException;
import org.aspectj.bridge.AbortException;
import org.hibernate.validator.internal.engine.ConstraintViolationImpl;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 核心异常拦截处理
*
* @author Jim
* @version 0.1
* 2023/1/12 14:06
*/
@Slf4j
@Order(0)
@RestControllerAdvice
@RequiredArgsConstructor
public class CoreExceptionHandler {
final I18n i18n;
/**
* 参数校验异常
*
* @param e 异常信息
* @return 统一的校验失败信息 {@link Status#EXPECTATION_FAILED
*/
@ExceptionHandler(
{ BindException.class, MethodArgumentNotValidException.class, ConstraintViolationException.class }
)
public Result<String> validFailHandler(Exception e) {
String details = null;
if (e instanceof ConstraintViolationException) {
details = ((ConstraintViolationException) e).getConstraintViolations().iterator().next().getMessage();
} else {
BindingResult result = null;
if (e instanceof MethodArgumentNotValidException) {
result = ((MethodArgumentNotValidException) e).getBindingResult();
} else if (e instanceof BindException) {
result = ((BindException) e).getBindingResult();
}
if (result != null) {
ObjectError error = result.getAllErrors().iterator().next();
if (error instanceof FieldError fieldError) {
// 构建明确的字段错误提示, 例如: id 不能为 null, 如果自己填写了 message 则不追加 field 字段前缀
ConstraintViolationImpl<?> violation = error.unwrap(ConstraintViolationImpl.class);
String template = violation.getMessageTemplate();
String prefix = "";
// 如果是模板字符串, 则在消息前添加字段提示
if (template.contains("{") && template.contains("}")) {
prefix = "参数" + fieldError.getField();
}
details = prefix + i18n.get(fieldError);
} else {
details = i18n.get(error);
}
}
}
return Result.no(Status.EXPECTATION_FAILED, details);
}
/**
* 参数读取解析失败异常
* eg: 例如参数使用 RequestBody 接收,但是传了个空字符串,导致解析失败
*
* @param e 异常
* @return 校验失败信息 {@link Status#EXPECTATION_FAILED
*/
@ExceptionHandler(HttpMessageNotReadableException.class)
public Result<String> httpMessageNotReadableExceptionHandler(Exception e) {
log.warn(e.getMessage(), e);
return Result.no(Status.EXPECTATION_FAILED);
}
/**
* 不支持的HttpMethod异常
*
* @param e 异常信息
* @return 异常信息反馈 {@link Status#METHOD_NOT_ALLOWED
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public Result<String> httpRequestMethodNotSupportedErrorHandler(Exception e) {
return Result.no(Status.METHOD_NOT_ALLOWED, e.getMessage());
}
/**
* 自定义业务异常
*/
@ExceptionHandler(BusinessException.class)
public Result<String> businessExceptionHandler(BusinessException e) {
return Result.no(e.getStatus(), e.getMessage());
}
/**
* 失败状态异常
*/
@ExceptionHandler(FailStatusException.class)
public Result<String> failStatusExceptionHandler(FailStatusException e) {
return Result.no(e.getStatus(), e.getMessage());
}
/**
* 取消请求异常(忽略)
*/
@ExceptionHandler({ ClientAbortException.class, AbortException.class, HttpMessageNotWritableException.class })
public void ignoreExceptionHandler() {}
}
...@@ -4,7 +4,7 @@ package com.yiring.common.config; ...@@ -4,7 +4,7 @@ package com.yiring.common.config;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import javax.annotation.Resource; import lombok.RequiredArgsConstructor;
import org.n52.jackson.datatype.jts.JtsModule; import org.n52.jackson.datatype.jts.JtsModule;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -18,10 +18,10 @@ import org.springframework.context.annotation.Configuration; ...@@ -18,10 +18,10 @@ import org.springframework.context.annotation.Configuration;
*/ */
@Configuration @Configuration
@RequiredArgsConstructor
public class JacksonConfig { public class JacksonConfig {
@Resource final JavaTimeModule javaTimeModule;
JavaTimeModule javaTimeModule;
@Bean @Bean
public ObjectMapper objectMapper() { public ObjectMapper objectMapper() {
......
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.common.core; package com.yiring.common.core;
import cn.hutool.core.convert.Convert;
import cn.hutool.extra.spring.SpringUtil; import cn.hutool.extra.spring.SpringUtil;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.PropertyKey; import org.jetbrains.annotations.PropertyKey;
/** /**
...@@ -23,13 +23,11 @@ import org.jetbrains.annotations.PropertyKey; ...@@ -23,13 +23,11 @@ import org.jetbrains.annotations.PropertyKey;
*/ */
@SuppressWarnings({ "unchecked", "unused" }) @SuppressWarnings({ "unchecked", "unused" })
@ApiModel("Result")
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Slf4j
@Data @Data
@Builder @Builder
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class Result<T extends Serializable> implements Serializable { public class Result<T> implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -4802543396830024571L; private static final long serialVersionUID = -4802543396830024571L;
...@@ -46,49 +44,49 @@ public class Result<T extends Serializable> implements Serializable { ...@@ -46,49 +44,49 @@ public class Result<T extends Serializable> implements Serializable {
/** /**
* 接口响应时间 * 接口响应时间
*/ */
@ApiModelProperty(value = "响应时间", example = "2021-01-01 00:00:00") @Schema(description = "响应时间", example = "2021-01-01 00:00:00")
String timestamp; String timestamp;
/** /**
* 接口耗时(单位:秒)通常在调试阶段出现 * 接口耗时(单位:秒)通常在调试阶段出现
*/ */
@ApiModelProperty(value = "耗时", example = "0.001s") @Schema(description = "耗时", example = "0.001s")
String times; String times;
/** /**
* 响应状态码 * 响应状态码
*/ */
@ApiModelProperty(value = "状态码", example = "200") @Schema(description = "状态码", example = "200", defaultValue = "200")
Integer status; Integer status;
/** /**
* 业务标识码 * 响应消息
*/ */
@ApiModelProperty(value = "业务标识码", example = "0") @Schema(description = "消息", example = "OK", defaultValue = "OK")
Integer code; String message;
/** /**
* 响应消息 * 业务标识码
*/ */
@ApiModelProperty(value = "消息", example = "OK") @Schema(description = "业务标识码", example = "0", nullable = true)
String message; Integer code;
/** /**
* 详细信息,通常为参数校验结果或自定义消息 * 详细信息,通常为参数校验结果或自定义消息
*/ */
@ApiModelProperty(value = "详细信息", example = "Details message") @Schema(description = "详细信息", nullable = true)
String details; String details;
/** /**
* 异常信息,通常在出现服务器错误时会出现该异常 * 异常信息,通常在出现服务器错误时会出现该异常
*/ */
@ApiModelProperty(value = "异常信息", notes = "出现错误时会出现该字段", example = "Error message") @Schema(description = "异常信息", nullable = true)
String error; String error;
/** /**
* 响应内容 * 响应内容
*/ */
@ApiModelProperty("内容") @Schema(description = "内容")
T body; T body;
/** /**
...@@ -97,7 +95,7 @@ public class Result<T extends Serializable> implements Serializable { ...@@ -97,7 +95,7 @@ public class Result<T extends Serializable> implements Serializable {
* @return Result * @return Result
* @see com.yiring.common.core.Status * @see com.yiring.common.core.Status
*/ */
public static <T extends Serializable> Result<T> ok() { public static <T> Result<T> ok() {
return (Result<T>) Result.builder().status(Status.OK.value()).message(t(Status.OK.getReasonPhrase())).build(); return (Result<T>) Result.builder().status(Status.OK.value()).message(t(Status.OK.getReasonPhrase())).build();
} }
...@@ -108,9 +106,7 @@ public class Result<T extends Serializable> implements Serializable { ...@@ -108,9 +106,7 @@ public class Result<T extends Serializable> implements Serializable {
* @return Result * @return Result
* @see com.yiring.common.core.Status * @see com.yiring.common.core.Status
*/ */
public static <T extends Serializable> Result<T> ok( public static <T> Result<T> ok(@PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String body) {
@PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String body
) {
return (Result<T>) Result return (Result<T>) Result
.builder() .builder()
.status(Status.OK.value()) .status(Status.OK.value())
...@@ -125,7 +121,7 @@ public class Result<T extends Serializable> implements Serializable { ...@@ -125,7 +121,7 @@ public class Result<T extends Serializable> implements Serializable {
* @param body {@link Object} * @param body {@link Object}
* @return Result * @return Result
*/ */
public static <T extends Serializable> Result<T> ok(T body) { public static <T> Result<T> ok(T body) {
return (Result<T>) Result return (Result<T>) Result
.builder() .builder()
.status(Status.OK.value()) .status(Status.OK.value())
...@@ -140,7 +136,7 @@ public class Result<T extends Serializable> implements Serializable { ...@@ -140,7 +136,7 @@ public class Result<T extends Serializable> implements Serializable {
* @return Result * @return Result
* @see Status#BAD_REQUEST * @see Status#BAD_REQUEST
*/ */
public static <T extends Serializable> Result<T> no() { public static <T> Result<T> no() {
return no(Status.BAD_REQUEST); return no(Status.BAD_REQUEST);
} }
...@@ -150,9 +146,7 @@ public class Result<T extends Serializable> implements Serializable { ...@@ -150,9 +146,7 @@ public class Result<T extends Serializable> implements Serializable {
* @return Result * @return Result
* @see Status#BAD_REQUEST * @see Status#BAD_REQUEST
*/ */
public static <T extends Serializable> Result<T> no( public static <T> Result<T> no(@PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String details) {
@PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String details
) {
return no(Status.BAD_REQUEST, details); return no(Status.BAD_REQUEST, details);
} }
...@@ -162,7 +156,7 @@ public class Result<T extends Serializable> implements Serializable { ...@@ -162,7 +156,7 @@ public class Result<T extends Serializable> implements Serializable {
* @return Result * @return Result
* @see Status#BAD_REQUEST * @see Status#BAD_REQUEST
*/ */
public static <T extends Serializable> Result<T> no(Status status) { public static <T> Result<T> no(Status status) {
return no(status, null, null, null); return no(status, null, null, null);
} }
...@@ -172,10 +166,7 @@ public class Result<T extends Serializable> implements Serializable { ...@@ -172,10 +166,7 @@ public class Result<T extends Serializable> implements Serializable {
* @return Result * @return Result
* @see Status * @see Status
*/ */
public static <T extends Serializable> Result<T> no( public static <T> Result<T> no(Status status, @PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String details) {
Status status,
@PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String details
) {
return no(status, null, details, null); return no(status, null, details, null);
} }
...@@ -185,7 +176,7 @@ public class Result<T extends Serializable> implements Serializable { ...@@ -185,7 +176,7 @@ public class Result<T extends Serializable> implements Serializable {
* @return Result * @return Result
* @see Status * @see Status
*/ */
public static <T extends Serializable> Result<T> no(Status status, Throwable error) { public static <T> Result<T> no(Status status, Throwable error) {
return no(status, null, null, error); return no(status, null, null, error);
} }
...@@ -195,12 +186,22 @@ public class Result<T extends Serializable> implements Serializable { ...@@ -195,12 +186,22 @@ public class Result<T extends Serializable> implements Serializable {
* @return Result * @return Result
* @see Status * @see Status
*/ */
public static <T extends Serializable> Result<T> no( public static <T> Result<T> no(
Status status, Status status,
Integer code, Integer code,
@PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String details, @PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String details,
Throwable error Throwable error
) { ) {
if (Objects.isNull(code)) {
String prefix = "Code.";
if (details.startsWith(prefix)) {
String codeText = details.replace(prefix, "");
code = Convert.toInt(codeText);
} else {
code = -1;
}
}
Result<T> result = (Result<T>) Result Result<T> result = (Result<T>) Result
.builder() .builder()
.status(status.value()) .status(status.value())
......
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.common.domain; package com.yiring.common.domain;
import com.vladmihalcea.hibernate.type.json.JsonBinaryType; import com.yiring.common.snowflake.SnowflakeId;
import com.vladmihalcea.hibernate.type.json.JsonType; import jakarta.persistence.*;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import javax.persistence.*;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.*; import org.hibernate.annotations.Comment;
import org.hibernate.snowflake.SnowflakeId; import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.UpdateTimestamp;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/** /**
* 基础表抽象类 * 基础表抽象类
...@@ -28,12 +30,8 @@ import org.hibernate.snowflake.SnowflakeId; ...@@ -28,12 +30,8 @@ import org.hibernate.snowflake.SnowflakeId;
@FieldNameConstants @FieldNameConstants
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
@SuperBuilder(toBuilder = true) @SuperBuilder(toBuilder = true)
@TypeDefs(
value = {
@TypeDef(name = "json", typeClass = JsonType.class), @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class),
}
)
@MappedSuperclass @MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BasicEntity { public abstract class BasicEntity {
@Comment("主键") @Comment("主键")
......
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.common.exception; package com.yiring.common.exception;
import cn.hutool.core.convert.Convert;
import com.yiring.common.core.I18n; import com.yiring.common.core.I18n;
import com.yiring.common.core.Status;
import java.io.Serial; import java.io.Serial;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import org.jetbrains.annotations.PropertyKey; import org.jetbrains.annotations.PropertyKey;
...@@ -22,7 +22,6 @@ import org.jetbrains.annotations.PropertyKey; ...@@ -22,7 +22,6 @@ import org.jetbrains.annotations.PropertyKey;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data @Data
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class BusinessException extends RuntimeException { public class BusinessException extends RuntimeException {
...@@ -30,33 +29,28 @@ public class BusinessException extends RuntimeException { ...@@ -30,33 +29,28 @@ public class BusinessException extends RuntimeException {
private static final long serialVersionUID = -4226669531686389671L; private static final long serialVersionUID = -4226669531686389671L;
/** /**
* 业务状态 * 状态码
*/ */
Integer code; Status status;
/** /**
* 业务状态异常消息 * 业务状态异常消息
*/ */
String message; String message;
public BusinessException(@PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String message) { public BusinessException(Status status, @PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String message) {
String prefix = "Code."; this.status = status;
if (message.startsWith(prefix)) {
String code = message.replaceAll(".*(\\d+).*", "$1");
this.code = Convert.toInt(code);
this.message = message;
} else {
this.code = -1;
this.message = "Unknown Error";
}
}
public BusinessException(int code, @PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String message) {
this.code = code;
this.message = message; this.message = message;
} }
public static BusinessException i18n(@PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String message) { public static BusinessException i18n(@PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String message) {
return new BusinessException(message); return new BusinessException(Status.BAD_REQUEST, message);
}
public static BusinessException i18n(
@NonNull Status status,
@PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String message
) {
return new BusinessException(status, message);
} }
} }
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.common.param; package com.yiring.common.param;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.annotations.ApiModelProperty; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
...@@ -16,7 +16,7 @@ import lombok.experimental.FieldDefaults; ...@@ -16,7 +16,7 @@ import lombok.experimental.FieldDefaults;
* @version 0.1 * @version 0.1
* 2019/5/28 22:11 * 2019/5/28 22:11
*/ */
@ApiModel(value = "IdParam", description = "公共的 ID 查询参数") @Schema(name = "IdParam", description = "公共的 ID 查询参数")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -27,7 +27,7 @@ public class IdParam implements Serializable { ...@@ -27,7 +27,7 @@ public class IdParam implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -8690942241103456893L; private static final long serialVersionUID = -8690942241103456893L;
@ApiModelProperty(value = "id", example = "1", required = true) @Parameter(description = "id", example = "1")
@NotBlank @NotBlank
String id; String id;
} }
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.common.param; package com.yiring.common.param;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.annotations.ApiModelProperty; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.validation.constraints.NotBlank;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
...@@ -19,7 +19,7 @@ import lombok.experimental.FieldDefaults; ...@@ -19,7 +19,7 @@ import lombok.experimental.FieldDefaults;
* @version 0.1 * @version 0.1
* 2019/5/28 22:11 * 2019/5/28 22:11
*/ */
@ApiModel("IdsParam") @Schema(name = "IdsParam")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -30,7 +30,7 @@ public class IdsParam implements Serializable { ...@@ -30,7 +30,7 @@ public class IdsParam implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -8379896695668632733L; private static final long serialVersionUID = -8379896695668632733L;
@ApiModelProperty(value = "ids 多个以逗号分割", example = "1,2", required = true) @Parameter(description = "ids 多个以逗号分割", example = "1,2")
@NotBlank @NotBlank
String ids; String ids;
......
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.common.param; package com.yiring.common.param;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.annotations.ApiModelProperty; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
...@@ -16,7 +16,7 @@ import lombok.experimental.FieldDefaults; ...@@ -16,7 +16,7 @@ import lombok.experimental.FieldDefaults;
* @version 0.1 * @version 0.1
* 2022/4/27 08:53 * 2022/4/27 08:53
*/ */
@ApiModel(value = "KeywordParam", description = "公共的关键字查询参数") @Schema(name = "KeywordParam", description = "公共的关键字查询参数")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -27,7 +27,7 @@ public class KeywordParam implements Serializable { ...@@ -27,7 +27,7 @@ public class KeywordParam implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -8690942241103456894L; private static final long serialVersionUID = -8690942241103456894L;
@ApiModelProperty(value = "关键字", example = "hi") @Parameter(description = "关键字", example = "hi")
@NotBlank @NotBlank
String keyword; String keyword;
} }
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.common.param; package com.yiring.common.param;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.annotations.ApiModelProperty; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
...@@ -26,7 +26,7 @@ import org.springframework.data.domain.Sort; ...@@ -26,7 +26,7 @@ import org.springframework.data.domain.Sort;
* @author ifzm * @author ifzm
* @version 0.1 2019/3/10 16:29 * @version 0.1 2019/3/10 16:29
*/ */
@ApiModel(value = "PageParam", description = "公共的分页排序查询参数") @Schema(name = "PageParam", description = "公共的分页排序查询参数")
@Data @Data
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
...@@ -37,20 +37,22 @@ public class PageParam implements Serializable { ...@@ -37,20 +37,22 @@ public class PageParam implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 6103761701912769946L; private static final long serialVersionUID = 6103761701912769946L;
@ApiModelProperty(value = "分页条数", example = "10") @Parameter
@Schema(description = "分页条数", defaultValue = "10", example = "10", type = "integer")
@NotNull @NotNull
@Range(min = 1, max = 100) @Range(min = 1, max = 100)
Integer pageSize; Integer pageSize;
@ApiModelProperty(value = "当前页数", example = "1") @Parameter
@Schema(description = "当前页数", defaultValue = "1", example = "1", type = "integer")
@NotNull @NotNull
@Min(1) @Min(1)
Integer pageNo; Integer pageNo;
@ApiModelProperty(value = "排序字段", example = "id") @Schema(description = "排序字段", defaultValue = "id", example = "id")
String sortField; String sortField;
@ApiModelProperty(value = "排序方向(ASC|DESC)", example = "DESC") @Schema(description = "排序方向(ASC|DESC)", defaultValue = "DESC", example = "DESC")
Sort.Direction sortOrder; Sort.Direction sortOrder;
/** /**
......
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.common.param; package com.yiring.common.param;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.annotations.ApiModelProperty; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
...@@ -16,7 +16,7 @@ import lombok.experimental.FieldDefaults; ...@@ -16,7 +16,7 @@ import lombok.experimental.FieldDefaults;
* @version 0.1 * @version 0.1
* 2019/5/28 22:11 * 2019/5/28 22:11
*/ */
@ApiModel(value = "PidParam", description = "公共的父级 ID 查询参数") @Schema(name = "PidParam", description = "公共的父级 ID 查询参数")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -27,7 +27,7 @@ public class PidParam implements Serializable { ...@@ -27,7 +27,7 @@ public class PidParam implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -8690942241103456893L; private static final long serialVersionUID = -8690942241103456893L;
@ApiModelProperty(value = "pid", example = "0", required = true) @Parameter(description = "pid", example = "0")
@NotBlank @NotBlank
String pid; String pid;
} }
/* (C) 2023 YiRing, Inc. */
package com.yiring.common.snowflake;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import java.io.Serializable;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import org.springframework.stereotype.Component;
/**
* 基于雪花算法的 ID 生成器
* 生成 Long 类型
*
* @author ifzm
* @version 0.1
* 2020/1/14 16:18
*/
@Component
public class GenerateLongId implements IdentifierGenerator {
private Snowflake snowflake;
@Override
public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
return snowflake.nextId();
}
@Override
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
snowflake = IdUtil.getSnowflake();
}
}
/* (C) 2023 YiRing, Inc. */
package com.yiring.common.snowflake;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import java.io.Serializable;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import org.springframework.stereotype.Component;
/**
* 基于雪花算法的 ID 生成器
* 生成 String 类型
*
* @author ifzm
* @version 0.1
* 2020/1/14 16:18
*/
@Component
public class GenerateStringId implements IdentifierGenerator {
private Snowflake snowflake;
@Override
public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
return snowflake.nextIdStr();
}
@Override
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
snowflake = IdUtil.getSnowflake();
}
}
/* (C) 2023 YiRing, Inc. */
package com.yiring.common.snowflake;
import lombok.experimental.UtilityClass;
/**
* 雪花 ID 生成器常量
*
* @author ifzm
* @version 0.1
* 2020/8/10 15:35
*/
@UtilityClass
public class SnowflakeId {
public final String GENERATOR = "snowflake";
public class Strategy {
public static final String STRING = "com.yiring.common.snowflake.GenerateStringId";
public static final String LONG = "com.yiring.common.snowflake.GenerateLongId";
}
}
...@@ -4,11 +4,11 @@ package com.yiring.common.validation; ...@@ -4,11 +4,11 @@ package com.yiring.common.validation;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
/** /**
* 枚举参数校验 * 枚举参数校验
......
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.common.validation; package com.yiring.common.validation;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/** /**
* 枚举参数校验器 * 枚举参数校验器
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
package com.yiring.common.validation; package com.yiring.common.validation;
import com.yiring.common.util.Commons; import com.yiring.common.util.Commons;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validation;
import jakarta.validation.ValidatorFactory;
import java.util.Set; import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import lombok.Cleanup; import lombok.Cleanup;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
...@@ -34,7 +34,7 @@ public class ValidateUtil { ...@@ -34,7 +34,7 @@ public class ValidateUtil {
@Cleanup @Cleanup
ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Set<ConstraintViolation<T>> constraintViolations = factory.getValidator().validate(t, groups); Set<ConstraintViolation<T>> constraintViolations = factory.getValidator().validate(t, groups);
if (!Commons.isNullOrEmpty(constraintViolations)) { if (Commons.notEmpty(constraintViolations)) {
throw new ConstraintViolationException(constraintViolations); throw new ConstraintViolationException(constraintViolations);
} }
} }
......
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.common.validation.group; package com.yiring.common.validation.group;
import javax.validation.groups.Default; import jakarta.validation.groups.Default;
/** /**
* validate group * validate group
......
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.common.vo; package com.yiring.common.vo;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import lombok.*; import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
/** /**
...@@ -16,7 +18,7 @@ import lombok.experimental.FieldDefaults; ...@@ -16,7 +18,7 @@ import lombok.experimental.FieldDefaults;
* @version 0.1 * @version 0.1
* 2022/3/23 16:47 * 2022/3/23 16:47
*/ */
@ApiModel(value = "DataVo", description = "公共数据响应输出") @Schema(name = "DataVo", description = "公共数据响应输出")
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
...@@ -26,17 +28,18 @@ public class DataVo<T extends Serializable> implements Serializable { ...@@ -26,17 +28,18 @@ public class DataVo<T extends Serializable> implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 2472779197432240431L; private static final long serialVersionUID = 2472779197432240431L;
@ApiModelProperty(value = "数据") @Schema(description = "数据")
T data; T data;
/** /**
* 通常在带有时效性的数据查询时有用途(可选参数) * 通常在带有时效性的数据查询时有用途(可选参数)
*/ */
@ApiModelProperty(value = "数据最新时间") @Schema(description = "数据最新时间")
LocalDateTime latest; LocalDateTime latest;
/** /**
* 构建一个 DataVo * 构建一个 DataVo
*
* @param data 数据 * @param data 数据
* @return DataVo * @return DataVo
*/ */
...@@ -47,7 +50,8 @@ public class DataVo<T extends Serializable> implements Serializable { ...@@ -47,7 +50,8 @@ public class DataVo<T extends Serializable> implements Serializable {
/** /**
* 构建一个 DataVo * 构建一个 DataVo
* @param data 数据 *
* @param data 数据
* @param latest 数据最新时间 * @param latest 数据最新时间
* @return DataVo * @return DataVo
*/ */
......
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.common.vo; package com.yiring.common.vo;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import lombok.*; import lombok.*;
...@@ -16,7 +15,7 @@ import lombok.experimental.FieldDefaults; ...@@ -16,7 +15,7 @@ import lombok.experimental.FieldDefaults;
* 2022/3/24 17:29 * 2022/3/24 17:29
*/ */
@ApiModel(value = "KeyValueVo", description = "键值对响应输出") @Schema(name = "KeyValueVo", description = "键值对响应输出")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -27,15 +26,15 @@ public class KeyValueVo implements Serializable { ...@@ -27,15 +26,15 @@ public class KeyValueVo implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -5238793972067296346L; private static final long serialVersionUID = -5238793972067296346L;
@ApiModelProperty(value = "key", example = "key") @Schema(description = "key", example = "key")
String key; String key;
@ApiModelProperty(value = "value", example = "value") @Schema(description = "value", example = "value")
String value; String value;
/** /**
* 扩展字段,可用于文本输出 * 扩展字段,可用于文本输出
*/ */
@ApiModelProperty(value = "label", example = "label") @Schema(description = "label", example = "label")
String label; String label;
} }
...@@ -2,14 +2,16 @@ ...@@ -2,14 +2,16 @@
package com.yiring.common.vo; package com.yiring.common.vo;
import com.yiring.common.util.Commons; import com.yiring.common.util.Commons;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import lombok.*; import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
...@@ -19,7 +21,7 @@ import org.springframework.data.domain.Page; ...@@ -19,7 +21,7 @@ import org.springframework.data.domain.Page;
* @author ifzm * @author ifzm
* @version 0.1 2019/3/10 16:29 * @version 0.1 2019/3/10 16:29
*/ */
@ApiModel(value = "PageVo", description = "公共分页查询响应输出") @Schema(name = "PageVo", description = "公共分页查询响应输出")
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
...@@ -29,16 +31,16 @@ public class PageVo<T extends Serializable> implements Serializable { ...@@ -29,16 +31,16 @@ public class PageVo<T extends Serializable> implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 6103761701912769946L; private static final long serialVersionUID = 6103761701912769946L;
@ApiModelProperty(value = "数据", required = true) @Schema(description = "数据")
List<T> data; List<T> data;
@ApiModelProperty(value = "数据总数", example = "100", required = true) @Schema(description = "数据总数", example = "100")
Long total; Long total;
/** /**
* 通常在带有时效性的数据查询时有用途(可选参数) * 通常在带有时效性的数据查询时有用途(可选参数)
*/ */
@ApiModelProperty(value = "数据最新时间") @Schema(description = "数据最新时间")
LocalDateTime latest; LocalDateTime latest;
/** /**
......
dependencies { dependencies {
implementation project(":basic-common:core") implementation project(":basic-common:core")
implementation project(":basic-common:i18n")
implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-validation'
// swagger(knife4j) // swagger(knife4j)
implementation "com.github.xiaoymin:knife4j-spring-boot-starter:${knife4jVersion}" implementation "com.github.xiaoymin:knife4j-openapi3-jakarta-spring-boot-starter:${knife4jOpen3Version}"
// hutool-core // hutool-core
implementation "cn.hutool:hutool-core:${hutoolVersion}" implementation "cn.hutool:hutool-core:${hutoolVersion}"
......
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.common.swagger; package com.yiring.common.swagger;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Console; import cn.hutool.core.lang.Console;
import cn.hutool.core.net.NetUtil; import cn.hutool.core.net.NetUtil;
import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver; import com.yiring.common.core.I18n;
import com.yiring.common.core.Status; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.annotations.Api; import io.swagger.v3.oas.models.ExternalDocumentation;
import java.util.Arrays; import io.swagger.v3.oas.models.OpenAPI;
import java.util.List; import io.swagger.v3.oas.models.info.Contact;
import java.util.function.Predicate; import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.tags.Tag;
import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Resource; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.customizers.OpenApiCustomizer;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
import org.springframework.web.bind.annotation.RequestMethod;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseMessageBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.ResponseMessage;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
/** /**
* Swagger Config * Swagger Config
...@@ -42,9 +33,8 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc; ...@@ -42,9 +33,8 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
@Slf4j @Slf4j
@Profile("!prod") @Profile("!prod")
@EnableSwagger2WebMvc
@Configuration @Configuration
@Import(BeanValidatorPluginsConfiguration.class) @RequiredArgsConstructor
public class SwaggerConfig implements CommandLineRunner { public class SwaggerConfig implements CommandLineRunner {
@Value("${spring.application.name}") @Value("${spring.application.name}")
...@@ -56,78 +46,110 @@ public class SwaggerConfig implements CommandLineRunner { ...@@ -56,78 +46,110 @@ public class SwaggerConfig implements CommandLineRunner {
@Value("${server.servlet.context-path}") @Value("${server.servlet.context-path}")
String path; String path;
@Resource final I18n i18n;
OpenApiExtensionResolver openApiExtensionResolver;
@Bean
public OpenAPI openAPI() {
Info info = new Info()
.title("API Doc")
.description(applicationName)
.version("1.0")
.contact(new Contact().name("© YiRing").url("https://yiring.com").email("developer@yiring.com"));
return new OpenAPI().info(info).externalDocs(new ExternalDocumentation());
}
@Bean(name = "api.any") @Bean(name = "api.any")
public Docket any() { public GroupedOpenApi any() {
return api("default", List.of(""), PathSelectors.any()); return api("default", List.of("com.yiring"), List.of("/**"), Collections.emptyList());
} }
@Bean(name = "api.auth") @Bean(name = "api.auth")
public Docket auth() { public GroupedOpenApi auth() {
return api("① Auth", List.of("com.yiring.auth.web"), Predicate.not(PathSelectors.ant(path + "/sys/**"))); return api("① Auth", List.of("com.yiring.auth.web"), List.of("/**"), List.of("/sys/**"));
} }
@Bean(name = "api.common") @Bean(name = "api.common")
public Docket common() { public GroupedOpenApi common() {
return api("② 公共", List.of("com.yiring.common.web", "com.yiring.app.web.common"), PathSelectors.any()); return api(
"② 公共",
List.of("com.yiring.common.web", "com.yiring.app.web.common"),
List.of("/**"),
Collections.emptyList()
);
} }
@Bean(name = "api.manage") @Bean(name = "api.manage")
public Docket manage() { public GroupedOpenApi manage() {
return api("③ 系统管理", List.of("com.yiring.auth.web.sys"), PathSelectors.any()); return api("③ 系统管理", List.of("com.yiring.auth.web.sys"), List.of("/**"), Collections.emptyList());
} }
@Bean(name = "api.example") @Bean(name = "api.example")
public Docket example() { public GroupedOpenApi example() {
return api("④ 示例", List.of("com.yiring.app.web.example"), PathSelectors.any()); return api("④ 示例", List.of("com.yiring.app.web.example"), List.of("/**"), Collections.emptyList());
} }
private Docket api(String group, List<String> basePackages, Predicate<String> paths) { @Bean
// 扫描多个包 public OpenApiCustomizer sortTagCustom() {
Predicate<RequestHandler> predicate = basePackages String order = "x-order";
.stream() return api -> {
.map(RequestHandlerSelectors::basePackage) List<Tag> tags = api
.reduce(Predicate::or) .getTags()
.orElse(RequestHandlerSelectors.none()); .stream()
.sorted(
return new Docket(DocumentationType.SWAGGER_2) Comparator.comparing(tag ->
.groupName(group) Convert.toInt(
.apiInfo(apiInfo()) Optional.ofNullable(tag.getExtensions()).orElseGet(HashMap::new).get(order),
.useDefaultResponseMessages(false) Integer.MAX_VALUE
.globalResponseMessage(RequestMethod.GET, buildGlobalResponseMessage()) )
.globalResponseMessage(RequestMethod.POST, buildGlobalResponseMessage()) )
.globalResponseMessage(RequestMethod.DELETE, buildGlobalResponseMessage()) )
.globalResponseMessage(RequestMethod.PUT, buildGlobalResponseMessage()) .peek(tag -> {
.select() Map<String, Object> extensions = tag.getExtensions();
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class).and(predicate)) if (Objects.nonNull(extensions) && extensions.containsKey(order)) {
.paths(paths) extensions.put(order, Convert.toInt(extensions.get(order)));
.build() }
.extensions(openApiExtensionResolver.buildExtensions(group)); })
.toList();
api.setTags(tags);
};
} }
private ApiInfo apiInfo() { // @Bean
return new ApiInfoBuilder() // public OperationCustomizer addGlobalStatusResponse() {
.title("API Doc") // return (operation, handlerMethod) -> {
.description(applicationName) // ApiResponses responses = operation.getResponses();
.version("1.0") // for (Status status : Status.values()) {
.contact(new Contact("© YiRing", "https://yiring.com", "developer@yiring.com")) // if (Status.OK.equals(status)) {
// continue;
// }
//
// ApiResponse response = new ApiResponse()
// .description(i18n.get(status.getReasonPhrase()))
// .$ref("Response");
// responses.addApiResponse(String.valueOf(status.value()), response);
// }
//
// return operation;
// };
// }
private GroupedOpenApi api(
String group,
List<String> basePackages,
List<String> pathsToMatch,
List<String> pathsToExclude
) {
return GroupedOpenApi
.builder()
.group(group)
.packagesToScan(basePackages.toArray(new String[0]))
.addOpenApiMethodFilter(method -> method.isAnnotationPresent(Operation.class))
.pathsToMatch(pathsToMatch.toArray(new String[0]))
.pathsToExclude(pathsToExclude.toArray(new String[0]))
.build(); .build();
} }
/**
* 构建全局响应消息
*
* @return 所有自定义状态码消息
*/
private List<ResponseMessage> buildGlobalResponseMessage() {
return Arrays
.stream(Status.values())
.map(status -> new ResponseMessageBuilder().code(status.value()).message(status.getReasonPhrase()).build())
.collect(Collectors.toList());
}
@Override @Override
public void run(String... args) { public void run(String... args) {
String link = NetUtil String link = NetUtil
...@@ -135,6 +157,6 @@ public class SwaggerConfig implements CommandLineRunner { ...@@ -135,6 +157,6 @@ public class SwaggerConfig implements CommandLineRunner {
.stream() .stream()
.map(host -> "> http://" + host + ":" + port + path + "/doc.html") .map(host -> "> http://" + host + ":" + port + path + "/doc.html")
.collect(Collectors.joining("\n\t\t")); .collect(Collectors.joining("\n\t\t"));
Console.log("\n\t📖 API Doc (Swagger2): \n\t\t{}\n", link); Console.log("\n\t📖 API Doc (OpenAPI3): \n\t\t{}\n", link);
} }
} }
...@@ -7,6 +7,8 @@ import org.jetbrains.annotations.PropertyKey; ...@@ -7,6 +7,8 @@ import org.jetbrains.annotations.PropertyKey;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceResolvable; import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
...@@ -18,6 +20,7 @@ import org.springframework.stereotype.Component; ...@@ -18,6 +20,7 @@ import org.springframework.stereotype.Component;
*/ */
@Slf4j @Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
public class I18n { public class I18n {
......
Status.OK=OK Status.OK=\u6210\u529F
Status.NON_AUTHORITATIVE_INFORMATION=\u8BA4\u8BC1\u5931\u8D25 Status.NON_AUTHORITATIVE_INFORMATION=\u8BA4\u8BC1\u5931\u8D25
Status.BAD_REQUEST=\u8BF7\u6C42\u5931\u8D25 Status.BAD_REQUEST=\u8BF7\u6C42\u5931\u8D25
Status.UNAUTHORIZED=\u51ED\u8BC1\u8FC7\u671F Status.UNAUTHORIZED=\u51ED\u8BC1\u8FC7\u671F
......
...@@ -6,7 +6,7 @@ dependencies { ...@@ -6,7 +6,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-validation'
// swagger(knife4j) // swagger(knife4j)
implementation "com.github.xiaoymin:knife4j-spring-boot-starter:${knife4jVersion}" implementation "com.github.xiaoymin:knife4j-openapi3-jakarta-spring-boot-starter:${knife4jOpen3Version}"
// minio // minio
implementation "io.minio:minio:${minioVersion}" implementation "io.minio:minio:${minioVersion}"
......
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.common.param; package com.yiring.common.param;
import io.swagger.annotations.ApiModel; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiModelProperty; import jakarta.validation.constraints.NotEmpty;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import javax.validation.constraints.NotEmpty;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
...@@ -17,7 +16,7 @@ import lombok.experimental.FieldDefaults; ...@@ -17,7 +16,7 @@ import lombok.experimental.FieldDefaults;
* 2022/7/5 15:29 * 2022/7/5 15:29
*/ */
@ApiModel(value = "DownloadParam", description = "文件下载请求参数") @Schema(name = "DownloadParam", description = "文件下载请求参数")
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
...@@ -28,11 +27,11 @@ public class DownloadParam implements Serializable { ...@@ -28,11 +27,11 @@ public class DownloadParam implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -8690942241103456899L; private static final long serialVersionUID = -8690942241103456899L;
@ApiModelProperty(value = "bucket", example = "public", required = true) @Schema(name = "bucket", example = "public")
@NotEmpty(message = "存储桶不能为空") @NotEmpty(message = "存储桶不能为空")
String bucket; String bucket;
@ApiModelProperty(value = "object", example = "cat.jpg", required = true) @Schema(name = "object", example = "cat.jpg")
@NotEmpty(message = "文件对象不能为空") @NotEmpty(message = "文件对象不能为空")
String object; String object;
} }
...@@ -3,7 +3,7 @@ package com.yiring.common.web; ...@@ -3,7 +3,7 @@ package com.yiring.common.web;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.github.xiaoymin.knife4j.annotations.ApiSupport; import com.yiring.common.annotation.DownloadResponse;
import com.yiring.common.core.Minio; import com.yiring.common.core.Minio;
import com.yiring.common.core.Result; import com.yiring.common.core.Result;
import com.yiring.common.core.Status; import com.yiring.common.core.Status;
...@@ -13,16 +13,18 @@ import com.yiring.common.util.FileUtils; ...@@ -13,16 +13,18 @@ import com.yiring.common.util.FileUtils;
import com.yiring.common.vo.ImageInfo; import com.yiring.common.vo.ImageInfo;
import io.minio.GetObjectResponse; import io.minio.GetObjectResponse;
import io.minio.StatObjectResponse; import io.minio.StatObjectResponse;
import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.annotations.ApiParam; import io.swagger.v3.oas.annotations.extensions.Extension;
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import java.sql.Timestamp; import java.sql.Timestamp;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders; import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
...@@ -36,9 +38,11 @@ import org.springframework.web.multipart.MultipartFile; ...@@ -36,9 +38,11 @@ import org.springframework.web.multipart.MultipartFile;
@Slf4j @Slf4j
@Validated @Validated
@SuppressWarnings({ "deprecation" }) @Tag(
@ApiSupport(order = -98) name = "文件管理",
@Api(tags = "文件管理", description = "file") description = "file",
extensions = { @Extension(properties = { @ExtensionProperty(name = "x-order", value = "-9997") }) }
)
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@RequestMapping("/common/file/") @RequestMapping("/common/file/")
...@@ -50,9 +54,9 @@ public class MinioController { ...@@ -50,9 +54,9 @@ public class MinioController {
/** /**
* minio 上传文件,成功返回文件 url * minio 上传文件,成功返回文件 url
*/ */
@ApiOperation(value = "文件上传", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @Operation(summary = "文件上传")
@PostMapping(value = "upload", headers = HttpHeaders.CONTENT_TYPE + "=" + MediaType.MULTIPART_FORM_DATA_VALUE) @PostMapping(value = "upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Result<String> upload(@ApiParam(value = "文件", required = true) @RequestPart("file") MultipartFile file) { public Result<String> upload(@Parameter(name = "文件", required = true) @RequestPart("file") MultipartFile file) {
try { try {
// 获取文件名信息 // 获取文件名信息
String filename = file.getOriginalFilename(); String filename = file.getOriginalFilename();
...@@ -76,13 +80,13 @@ public class MinioController { ...@@ -76,13 +80,13 @@ public class MinioController {
} }
} }
@ApiOperation(value = "Base64 图片上传") @Operation(summary = "Base64 图片上传")
@ApiImplicitParam( @Parameter(
name = "base64Image", name = "base64Image",
value = "Base64 图片信息", description = "Base64 图片信息",
example = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAALCAYAAABYpyyrAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAATSURBVBhXYzAwNP6PjIeKgPF/ABj+RUX4hZfVAAAAAElFTkSuQmCC", example = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAALCAYAAABYpyyrAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAATSURBVBhXYzAwNP6PjIeKgPF/ABj+RUX4hZfVAAAAAElFTkSuQmCC",
required = true, required = true,
paramType = "query" in = ParameterIn.QUERY
) )
@PostMapping(value = "uploadBase64Image") @PostMapping(value = "uploadBase64Image")
public Result<String> uploadBase64Image(@NotBlank(message = "图片 Base64 信息不能为空") String base64Image) { public Result<String> uploadBase64Image(@NotBlank(message = "图片 Base64 信息不能为空") String base64Image) {
...@@ -112,9 +116,10 @@ public class MinioController { ...@@ -112,9 +116,10 @@ public class MinioController {
* @param response HttpServletResponse * @param response HttpServletResponse
* @param param 请求参数 * @param param 请求参数
*/ */
@ApiOperation(value = "文件下载", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) @DownloadResponse
@GetMapping("download") @Operation(summary = "文件下载")
public void download(HttpServletResponse response, @Validated DownloadParam param) { @GetMapping(value = "download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public void download(HttpServletResponse response, @ParameterObject @Validated DownloadParam param) {
try { try {
StatObjectResponse statObject = minio.objectStat(param.getBucket(), param.getObject()); StatObjectResponse statObject = minio.objectStat(param.getBucket(), param.getObject());
GetObjectResponse object = minio.getObject(param.getBucket(), param.getObject()); GetObjectResponse object = minio.getObject(param.getBucket(), param.getObject());
......
...@@ -3,7 +3,7 @@ package com.yiring.common.config; ...@@ -3,7 +3,7 @@ package com.yiring.common.config;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Duration; import java.time.Duration;
import javax.annotation.Resource; import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -25,10 +25,10 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; ...@@ -25,10 +25,10 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
@EnableCaching @EnableCaching
@Configuration @Configuration
@RequiredArgsConstructor
public class RedisConfig { public class RedisConfig {
@Resource final ObjectMapper objectMapper;
ObjectMapper objectMapper;
@Bean @Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
......
...@@ -3,7 +3,7 @@ package com.yiring.common.core; ...@@ -3,7 +3,7 @@ package com.yiring.common.core;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Resource; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
...@@ -18,10 +18,10 @@ import org.springframework.stereotype.Component; ...@@ -18,10 +18,10 @@ import org.springframework.stereotype.Component;
@SuppressWarnings({ "unused" }) @SuppressWarnings({ "unused" })
@Slf4j @Slf4j
@Component @Component
@RequiredArgsConstructor
public final class Redis { public final class Redis {
@Resource final RedisTemplate<String, Object> redisTemplate;
RedisTemplate<String, Object> redisTemplate;
/** /**
* 指定缓存失效时间 * 指定缓存失效时间
...@@ -83,7 +83,7 @@ public final class Redis { ...@@ -83,7 +83,7 @@ public final class Redis {
/** /**
* 普通缓存获取 * 普通缓存获取
* *
* @param key 键 * @param key
* @param type 类型 * @param type 类型
* @return 值 * @return 值
*/ */
...@@ -459,6 +459,7 @@ public final class Redis { ...@@ -459,6 +459,7 @@ public final class Redis {
/** /**
* 获取所有 key * 获取所有 key
*
* @param pattern 查询规则 * @param pattern 查询规则
* @return 所有匹配的 Key 集合 * @return 所有匹配的 Key 集合
*/ */
......
/* (C) 2021 YiRing, Inc. */ /* (C) 2021 YiRing, Inc. */
package com.yiring.common.util; package com.yiring.common.util;
import jakarta.servlet.http.HttpServletRequest;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.*; import java.util.*;
import javax.servlet.http.HttpServletRequest;
import lombok.NonNull; import lombok.NonNull;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -21,7 +21,9 @@ import org.springframework.beans.BeanUtils; ...@@ -21,7 +21,9 @@ import org.springframework.beans.BeanUtils;
@UtilityClass @UtilityClass
public class Commons { public class Commons {
/** 代理 IP 请求头 */ /**
* 代理 IP 请求头
*/
private static final String[] HEADERS_TO_TRY = { private static final String[] HEADERS_TO_TRY = {
"X-Forwarded-For", "X-Forwarded-For",
"Proxy-Client-IP", "Proxy-Client-IP",
...@@ -69,8 +71,8 @@ public class Commons { ...@@ -69,8 +71,8 @@ public class Commons {
* @param collection 集合 * @param collection 集合
* @return 是否为空 * @return 是否为空
*/ */
public boolean isNullOrEmpty(Collection<?> collection) { public boolean notEmpty(Collection<?> collection) {
return collection == null || collection.isEmpty(); return collection != null && !collection.isEmpty();
} }
/** /**
...@@ -85,11 +87,12 @@ public class Commons { ...@@ -85,11 +87,12 @@ public class Commons {
/** /**
* 对象 Copy * 对象 Copy
* @param source 源对象 *
* @param type 目标类型 * @param source 源对象
* @param type 目标类型
* @param ignoreProperties 忽略属性 * @param ignoreProperties 忽略属性
* @param <T> 目标类型
* @return 目标对象 * @return 目标对象
* @param <T> 目标类型
*/ */
public <T> T transform(Object source, Class<T> type, String... ignoreProperties) { public <T> T transform(Object source, Class<T> type, String... ignoreProperties) {
try { try {
...@@ -106,11 +109,12 @@ public class Commons { ...@@ -106,11 +109,12 @@ public class Commons {
/** /**
* 将集合通过 BeanUtils 反射转换成指定类型集合 * 将集合通过 BeanUtils 反射转换成指定类型集合
* @param list 原始数据集合 *
* @param type 目标类型 * @param list 原始数据集合
* @param type 目标类型
* @param ignoreProperties 忽略属性 * @param ignoreProperties 忽略属性
* @param <T> 目标类型集合 * @param <T> 目标类型集合
* @param <S> 原类型集合 * @param <S> 原类型集合
* @return 目标集合 * @return 目标集合
*/ */
public <T, S> List<T> transform(@NonNull List<S> list, Class<T> type, String... ignoreProperties) { public <T, S> List<T> transform(@NonNull List<S> list, Class<T> type, String... ignoreProperties) {
...@@ -119,12 +123,13 @@ public class Commons { ...@@ -119,12 +123,13 @@ public class Commons {
/** /**
* 将集合通过 BeanUtils 反射转换成指定类型集合 * 将集合通过 BeanUtils 反射转换成指定类型集合
* @param list 原始数据集合 *
* @param type 目标类型 * @param list 原始数据集合
* @param fn 自定义处理函数 * @param type 目标类型
* @param fn 自定义处理函数
* @param ignoreProperties 忽略属性 * @param ignoreProperties 忽略属性
* @param <T> 目标类型集合 * @param <T> 目标类型集合
* @param <S> 原类型集合 * @param <S> 原类型集合
* @return 目标集合 * @return 目标集合
*/ */
public <T, S> List<T> transform( public <T, S> List<T> transform(
...@@ -162,6 +167,7 @@ public class Commons { ...@@ -162,6 +167,7 @@ public class Commons {
public interface CallbackFunction<S, T> { public interface CallbackFunction<S, T> {
/** /**
* 执行方法 * 执行方法
*
* @param s 源对象 * @param s 源对象
* @param t 目标对象 * @param t 目标对象
*/ */
......
...@@ -5,6 +5,7 @@ import cn.hutool.core.codec.Base64; ...@@ -5,6 +5,7 @@ import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader; import cn.hutool.core.io.file.FileReader;
import com.yiring.common.vo.ImageInfo; import com.yiring.common.vo.ImageInfo;
import jakarta.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
...@@ -15,7 +16,6 @@ import java.nio.charset.StandardCharsets; ...@@ -15,7 +16,6 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.apache.tomcat.util.http.fileupload.IOUtils; import org.apache.tomcat.util.http.fileupload.IOUtils;
......
plugins { plugins {
id 'java' id 'java'
// https://start.spring.io // https://start.spring.io
id 'org.springframework.boot' version '2.7.7' id 'org.springframework.boot' version '3.0.1'
id 'org.graalvm.buildtools.native' version '0.9.18'
// https://plugins.gradle.org/plugin/io.spring.dependency-management // https://plugins.gradle.org/plugin/io.spring.dependency-management
id 'io.spring.dependency-management' version '1.0.13.RELEASE' id 'io.spring.dependency-management' version '1.1.0'
// https://plugins.gradle.org/plugin/com.diffplug.spotless // https://plugins.gradle.org/plugin/com.diffplug.spotless
id "com.diffplug.spotless" version "6.3.0" id "com.diffplug.spotless" version "6.12.1"
} }
ext { ext {
// Spotless // Spotless
// https://www.npmjs.com/package/prettier // https://www.npmjs.com/package/prettier
prettierVersion = '2.8.1' prettierVersion = '2.8.2'
// https://www.npmjs.com/package/prettier-plugin-java // https://www.npmjs.com/package/prettier-plugin-java
prettierJavaVersion = '2.0.0' prettierJavaVersion = '2.0.0'
// SpringCloud // SpringCloud
// https://start.spring.io/ // https://start.spring.io/
springCloudVersion = '2021.0.4' springCloudVersion = '2022.0.0'
// Dependencies // Dependencies
// https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-spring-boot-starter // // https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-openapi3-jakarta-spring-boot-starter
knife4jVersion = '2.0.9' knife4jOpen3Version = '4.0.0'
// https://mvnrepository.com/artifact/io.swagger/swagger-annotations // https://mvnrepository.com/artifact/io.swagger/swagger-annotations
swaggerAnnotationsVersion = '1.6.9' swaggerAnnotationsVersion = '1.6.9'
// https://mvnrepository.com/artifact/cn.dev33/sa-token-spring-boot-starter // https://mvnrepository.com/artifact/cn.dev33/sa-token-spring-boot3-starter
saTokenVersion = '1.33.0' saTokenVersion = '1.34.0'
// https://mvnrepository.com/artifact/cn.hutool/hutool-all // https://mvnrepository.com/artifact/cn.hutool/hutool-all
hutoolVersion = '5.8.11' hutoolVersion = '5.8.11'
// https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 // https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2
...@@ -35,11 +36,11 @@ ext { ...@@ -35,11 +36,11 @@ ext {
// https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp // https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
okhttpVersion = '4.10.0' okhttpVersion = '4.10.0'
// https://mvnrepository.com/artifact/io.minio/minio // https://mvnrepository.com/artifact/io.minio/minio
minioVersion = '8.4.6' minioVersion = '8.5.1'
// https://mvnrepository.com/artifact/com.vladmihalcea/hibernate-types-55 // https://mvnrepository.com/artifact/io.hypersistence/hypersistence-utils-hibernate-60
hibernateTypesVersion = '2.21.1' hibernateTypesVersion = '3.0.1'
// https://mvnrepository.com/artifact/org.hibernate/hibernate-spatial // https://mvnrepository.com/artifact/org.hibernate/hibernate-spatial
hibernateSpatialVersion = '5.6.14.Final' hibernateSpatialVersion = '6.1.6.Final'
// https://mvnrepository.com/artifact/org.locationtech.jts/jts-core // https://mvnrepository.com/artifact/org.locationtech.jts/jts-core
jtsVersion = '1.19.0' jtsVersion = '1.19.0'
// https://mvnrepository.com/artifact/com.github.liaochong/myexcel // https://mvnrepository.com/artifact/com.github.liaochong/myexcel
...@@ -55,6 +56,7 @@ allprojects { ...@@ -55,6 +56,7 @@ allprojects {
mavenLocal() mavenLocal()
// Nexus // Nexus
// maven { url 'http://10.111.102.83:8081/repository/aliyun-maven/' } // maven { url 'http://10.111.102.83:8081/repository/aliyun-maven/' }
maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/maven-public/' }
maven { url 'https://maven.aliyun.com/repository/public' } maven { url 'https://maven.aliyun.com/repository/public' }
mavenCentral() mavenCentral()
} }
......
const fs = require('fs')
const path = require('path')
const { execSync } = require('child_process')
const scopes = fs
.readdirSync(path.resolve(__dirname, 'src'), { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map((dirent) => dirent.name.replace(/s$/, ''))
// precomputed scope
const scopeComplete = execSync('git status --porcelain || true')
.toString()
.trim()
.split('\n')
.find((r) => ~r.indexOf('M src'))
?.replace(/(\/)/g, '%%')
?.match(/src%%((\w|-)*)/)?.[1]
?.replace(/s$/, '')
/** @type {import('cz-git').UserConfig} */
module.exports = {
ignores: [(commit) => commit.includes('init')],
extends: ['@commitlint/config-conventional'],
rules: {
'body-leading-blank': [2, 'always'],
'footer-leading-blank': [1, 'always'],
'header-max-length': [2, 'always', 108],
'subject-empty': [2, 'never'],
'type-empty': [2, 'never'],
'subject-case': [0],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
'style',
'docs',
'test',
'refactor',
'build',
'ci',
'chore',
'revert',
'wip',
'workflow',
'types',
'release',
],
],
},
prompt: {
/** @use `yarn commit :f` */
alias: {
f: 'docs: fix typos',
r: 'docs: update README',
s: 'style: update code format',
b: 'build: bump dependencies',
c: 'chore: update config',
},
customScopesAlign: !scopeComplete ? 'top' : 'bottom',
defaultScope: scopeComplete,
scopes: [...scopes, 'mock'],
allowEmptyIssuePrefixs: false,
allowCustomIssuePrefixs: false,
// English
typesAppend: [
{ value: 'wip', name: 'wip: work in process' },
{ value: 'workflow', name: 'workflow: workflow improvements' },
{ value: 'types', name: 'types: type definition file changes' },
],
// 中英文对照版
// messages: {
// type: '选择你要提交的类型 :',
// scope: '选择一个提交范围 (可选):',
// customScope: '请输入自定义的提交范围 :',
// subject: '填写简短精炼的变更描述 :\n',
// body: '填写更加详细的变更描述 (可选)。使用 "|" 换行 :\n',
// breaking: '列举非兼容性重大的变更 (可选)。使用 "|" 换行 :\n',
// footerPrefixsSelect: '选择关联issue前缀 (可选):',
// customFooterPrefixs: '输入自定义issue前缀 :',
// footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
// confirmCommit: '是否提交或修改commit ?',
// },
// types: [
// { value: 'feat', name: 'feat: 新增功能' },
// { value: 'fix', name: 'fix: 修复缺陷' },
// { value: 'docs', name: 'docs: 文档变更' },
// { value: 'style', name: 'style: 代码格式' },
// { value: 'refactor', name: 'refactor: 代码重构' },
// { value: 'perf', name: 'perf: 性能优化' },
// { value: 'test', name: 'test: 添加疏漏测试或已有测试改动' },
// { value: 'build', name: 'build: 构建流程、外部依赖变更 (如升级 npm 包、修改打包配置等)' },
// { value: 'ci', name: 'ci: 修改 CI 配置、脚本' },
// { value: 'revert', name: 'revert: 回滚 commit' },
// { value: 'chore', name: 'chore: 对构建过程或辅助工具和库的更改 (不影响源文件、测试用例)' },
// { value: 'wip', name: 'wip: 正在开发中' },
// { value: 'workflow', name: 'workflow: 工作流程改进' },
// { value: 'types', name: 'types: 类型定义文件修改' },
// ],
// emptyScopesAlias: 'empty: 不填写',
// customScopesAlias: 'custom: 自定义',
},
}
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<!-- prettier-ignore --> <!-- prettier-ignore -->
- [SpringBoot v2.7.x](https://spring.io/projects/spring-boot) - [SpringBoot v3.0.x](https://spring.io/projects/spring-boot)
- [Lombok](https://projectlombok.org/) - [Lombok](https://projectlombok.org/)
- [Spring Web](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html) - [Spring Web](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html)
- [Spring Data Jpa](https://spring.io/projects/spring-data-jpa) - [Spring Data Jpa](https://spring.io/projects/spring-data-jpa)
......
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
{ {
"name": "basic-api-project", "name": "basic-api-boot",
"version": "0.0.1", "version": "0.0.1",
"scripts": { "scripts": {
"log": "conventional-changelog -p angular -i CHANGELOG.md -s" "log": "conventional-changelog -p angular -i CHANGELOG.md -s"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^17.4.0",
"@commitlint/config-conventional": "^17.4.0",
"commitizen": "^4.2.6",
"conventional-changelog-cli": "^2.2.2",
"cz-conventional-changelog": "^3.3.0", "cz-conventional-changelog": "^3.3.0",
"conventional-changelog-cli": "^2.2.2" "cz-customizable": "^7.0.0",
"cz-git": "^1.4.1"
}, },
"config": { "config": {
"commitizen": { "commitizen": {
"path": "./node_modules/cz-conventional-changelog" "path": "node_modules/cz-git"
} }
} }
} }
lockfileVersion: 5.3 lockfileVersion: 5.4
specifiers: specifiers:
'@commitlint/cli': ^17.4.0
'@commitlint/config-conventional': ^17.4.0
commitizen: ^4.2.6
conventional-changelog-cli: ^2.2.2 conventional-changelog-cli: ^2.2.2
cz-conventional-changelog: ^3.3.0 cz-conventional-changelog: ^3.3.0
cz-customizable: ^7.0.0
cz-git: ^1.4.1
devDependencies: devDependencies:
'@commitlint/cli': 17.4.1
'@commitlint/config-conventional': 17.4.0
commitizen: 4.2.6
conventional-changelog-cli: 2.2.2 conventional-changelog-cli: 2.2.2
cz-conventional-changelog: 3.3.0 cz-conventional-changelog: 3.3.0
cz-customizable: 7.0.0
cz-git: 1.4.1
packages: packages:
...@@ -31,6 +41,33 @@ packages: ...@@ -31,6 +41,33 @@ packages:
js-tokens: 4.0.0 js-tokens: 4.0.0
dev: true dev: true
/@commitlint/cli/17.4.1:
resolution: {integrity: sha512-W8OJwz+izY+fVwyUt1HveCDmABMZNRVZHSVPw/Bh9Y62tp11SmmQaycgbsYLMiMy7JGn4mAJqEGlSHS9Uti9ZQ==}
engines: {node: '>=v14'}
hasBin: true
dependencies:
'@commitlint/format': 17.4.0
'@commitlint/lint': 17.4.0
'@commitlint/load': 17.4.1
'@commitlint/read': 17.4.0
'@commitlint/types': 17.4.0
execa: 5.1.1
lodash.isfunction: 3.0.9
resolve-from: 5.0.0
resolve-global: 1.0.0
yargs: 17.6.2
transitivePeerDependencies:
- '@swc/core'
- '@swc/wasm'
dev: true
/@commitlint/config-conventional/17.4.0:
resolution: {integrity: sha512-G4XBf45J4ZMspO4NwBFzY3g/1Kb+B42BcIxeikF8wucQxcyxcmhRdjeQpRpS1XEcBq5pdtEEQFipuB9IuiNFhw==}
engines: {node: '>=v14'}
dependencies:
conventional-changelog-conventionalcommits: 5.0.0
dev: true
/@commitlint/config-validator/16.2.1: /@commitlint/config-validator/16.2.1:
resolution: {integrity: sha512-hogSe0WGg7CKmp4IfNbdNES3Rq3UEI4XRPB8JL4EPgo/ORq5nrGTVzxJh78omibNuB8Ho4501Czb1Er1MoDWpw==} resolution: {integrity: sha512-hogSe0WGg7CKmp4IfNbdNES3Rq3UEI4XRPB8JL4EPgo/ORq5nrGTVzxJh78omibNuB8Ho4501Czb1Er1MoDWpw==}
engines: {node: '>=v12'} engines: {node: '>=v12'}
...@@ -40,12 +77,63 @@ packages: ...@@ -40,12 +77,63 @@ packages:
dev: true dev: true
optional: true optional: true
/@commitlint/config-validator/17.4.0:
resolution: {integrity: sha512-Sa/+8KNpDXz4zT4bVbz2fpFjvgkPO6u2V2fP4TKgt6FjmOw2z3eEX859vtfeaTav/ukBw0/0jr+5ZTZp9zCBhA==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/types': 17.4.0
ajv: 8.12.0
dev: true
/@commitlint/ensure/17.4.0:
resolution: {integrity: sha512-7oAxt25je0jeQ/E0O/M8L3ADb1Cvweu/5lc/kYF8g/kXatI0wxGE5La52onnAUAWeWlsuvBNar15WcrmDmr5Mw==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/types': 17.4.0
lodash.camelcase: 4.3.0
lodash.kebabcase: 4.1.1
lodash.snakecase: 4.1.1
lodash.startcase: 4.4.0
lodash.upperfirst: 4.3.1
dev: true
/@commitlint/execute-rule/16.2.1: /@commitlint/execute-rule/16.2.1:
resolution: {integrity: sha512-oSls82fmUTLM6cl5V3epdVo4gHhbmBFvCvQGHBRdQ50H/690Uq1Dyd7hXMuKITCIdcnr9umyDkr8r5C6HZDF3g==} resolution: {integrity: sha512-oSls82fmUTLM6cl5V3epdVo4gHhbmBFvCvQGHBRdQ50H/690Uq1Dyd7hXMuKITCIdcnr9umyDkr8r5C6HZDF3g==}
engines: {node: '>=v12'} engines: {node: '>=v12'}
dev: true dev: true
optional: true optional: true
/@commitlint/execute-rule/17.4.0:
resolution: {integrity: sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==}
engines: {node: '>=v14'}
dev: true
/@commitlint/format/17.4.0:
resolution: {integrity: sha512-Z2bWAU5+f1YZh9W76c84J8iLIWIvvm+mzqogTz0Nsc1x6EHW0Z2gI38g5HAjB0r0I3ZjR15IDEJKhsxyblcyhA==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/types': 17.4.0
chalk: 4.1.2
dev: true
/@commitlint/is-ignored/17.4.0:
resolution: {integrity: sha512-mkRuBlPUaBimvSvJyIHEHEW1/jP1SqEI7NOoaO9/eyJkMbsaiv5b1QgDYL4ZXlHdS64RMV7Y21MVVzuIceImDA==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/types': 17.4.0
semver: 7.3.8
dev: true
/@commitlint/lint/17.4.0:
resolution: {integrity: sha512-HG2YT4TUbQKs9v8QvpQjJ6OK+fhflsDB8M+D5tLrY79hbQOWA9mDKdRkABsW/AAhpNI9+zeGUWF3jj245jSHKw==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/is-ignored': 17.4.0
'@commitlint/parse': 17.4.0
'@commitlint/rules': 17.4.0
'@commitlint/types': 17.4.0
dev: true
/@commitlint/load/16.2.3: /@commitlint/load/16.2.3:
resolution: {integrity: sha512-Hb4OUlMnBUK6UxJEZ/VJ5k0LocIS7PtEMbRXEAA7eSpOgORIFexC4K/RaRpVd5UTtu3M0ST3ddPPijF9rdW6nw==} resolution: {integrity: sha512-Hb4OUlMnBUK6UxJEZ/VJ5k0LocIS7PtEMbRXEAA7eSpOgORIFexC4K/RaRpVd5UTtu3M0ST3ddPPijF9rdW6nw==}
engines: {node: '>=v12'} engines: {node: '>=v12'}
...@@ -58,7 +146,7 @@ packages: ...@@ -58,7 +146,7 @@ packages:
'@types/node': 17.0.29 '@types/node': 17.0.29
chalk: 4.1.2 chalk: 4.1.2
cosmiconfig: 7.0.1 cosmiconfig: 7.0.1
cosmiconfig-typescript-loader: 1.0.9_5281fe59fc32158e106b8b5e2bebb315 cosmiconfig-typescript-loader: 1.0.9_kka74wp4giky4edlrnpcx25tcu
lodash: 4.17.21 lodash: 4.17.21
resolve-from: 5.0.0 resolve-from: 5.0.0
typescript: 4.6.3 typescript: 4.6.3
...@@ -68,6 +156,54 @@ packages: ...@@ -68,6 +156,54 @@ packages:
dev: true dev: true
optional: true optional: true
/@commitlint/load/17.4.1:
resolution: {integrity: sha512-6A7/LhIaQpL4ieciIDcVvK2d5z/UI1GBrtDaHm6sQSCL0265clB2/F7XKQNTJHXv9yG4LByT2r+QCpM4GugIfw==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/config-validator': 17.4.0
'@commitlint/execute-rule': 17.4.0
'@commitlint/resolve-extends': 17.4.0
'@commitlint/types': 17.4.0
'@types/node': 17.0.29
chalk: 4.1.2
cosmiconfig: 8.0.0
cosmiconfig-typescript-loader: 4.3.0_asoaktcvsaefgrgziobsocgewq
lodash.isplainobject: 4.0.6
lodash.merge: 4.6.2
lodash.uniq: 4.5.0
resolve-from: 5.0.0
ts-node: 10.9.1_u3h3q7xqdg7nitfvwf64wuo7zy
typescript: 4.9.4
transitivePeerDependencies:
- '@swc/core'
- '@swc/wasm'
dev: true
/@commitlint/message/17.4.0:
resolution: {integrity: sha512-USGJDU9PPxcgQjKXCzvPUal65KAhxWq3hp+MrU1pNCN2itWM654CLIoY2LMIQ7rScTli9B5dTLH3vXhzbItmzA==}
engines: {node: '>=v14'}
dev: true
/@commitlint/parse/17.4.0:
resolution: {integrity: sha512-x8opKc5p+Hgs+CrMbq3VAnW2L2foPAX6arW8u9c8nTzksldGgFsENT+XVyPmpSMLlVBswZ1tndcz1xyKiY9TJA==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/types': 17.4.0
conventional-changelog-angular: 5.0.13
conventional-commits-parser: 3.2.4
dev: true
/@commitlint/read/17.4.0:
resolution: {integrity: sha512-pGDeZpbkyvhxK8ZoCDUacPPRpauKPWF3n2XpDBEnuGreqUF2clq2PVJpwMMaNN5cHW8iFKCbcoOjXhD01sln0A==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/top-level': 17.4.0
'@commitlint/types': 17.4.0
fs-extra: 11.1.0
git-raw-commits: 2.0.11
minimist: 1.2.6
dev: true
/@commitlint/resolve-extends/16.2.1: /@commitlint/resolve-extends/16.2.1:
resolution: {integrity: sha512-NbbCMPKTFf2J805kwfP9EO+vV+XvnaHRcBy6ud5dF35dxMsvdJqke54W3XazXF1ZAxC4a3LBy4i/GNVBAthsEg==} resolution: {integrity: sha512-NbbCMPKTFf2J805kwfP9EO+vV+XvnaHRcBy6ud5dF35dxMsvdJqke54W3XazXF1ZAxC4a3LBy4i/GNVBAthsEg==}
engines: {node: '>=v12'} engines: {node: '>=v12'}
...@@ -81,6 +217,41 @@ packages: ...@@ -81,6 +217,41 @@ packages:
dev: true dev: true
optional: true optional: true
/@commitlint/resolve-extends/17.4.0:
resolution: {integrity: sha512-3JsmwkrCzoK8sO22AzLBvNEvC1Pmdn/65RKXzEtQMy6oYMl0Snrq97a5bQQEFETF0VsvbtUuKttLqqgn99OXRQ==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/config-validator': 17.4.0
'@commitlint/types': 17.4.0
import-fresh: 3.3.0
lodash.mergewith: 4.6.2
resolve-from: 5.0.0
resolve-global: 1.0.0
dev: true
/@commitlint/rules/17.4.0:
resolution: {integrity: sha512-lz3i1jet2NNjTWpAMwjjQjMZCPWBIHK1Kkja9o09UmUtMjRdALTb8uMLe8gCyeq3DiiZ5lLYOhbsoPK56xGQKA==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/ensure': 17.4.0
'@commitlint/message': 17.4.0
'@commitlint/to-lines': 17.4.0
'@commitlint/types': 17.4.0
execa: 5.1.1
dev: true
/@commitlint/to-lines/17.4.0:
resolution: {integrity: sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==}
engines: {node: '>=v14'}
dev: true
/@commitlint/top-level/17.4.0:
resolution: {integrity: sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==}
engines: {node: '>=v14'}
dependencies:
find-up: 5.0.0
dev: true
/@commitlint/types/16.2.1: /@commitlint/types/16.2.1:
resolution: {integrity: sha512-7/z7pA7BM0i8XvMSBynO7xsB3mVQPUZbVn6zMIlp/a091XJ3qAXRXc+HwLYhiIdzzS5fuxxNIHZMGHVD4HJxdA==} resolution: {integrity: sha512-7/z7pA7BM0i8XvMSBynO7xsB3mVQPUZbVn6zMIlp/a091XJ3qAXRXc+HwLYhiIdzzS5fuxxNIHZMGHVD4HJxdA==}
engines: {node: '>=v12'} engines: {node: '>=v12'}
...@@ -89,44 +260,56 @@ packages: ...@@ -89,44 +260,56 @@ packages:
dev: true dev: true
optional: true optional: true
/@cspotcode/source-map-consumer/0.8.0: /@commitlint/types/17.4.0:
resolution: {integrity: sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==} resolution: {integrity: sha512-2NjAnq5IcxY9kXtUeO2Ac0aPpvkuOmwbH/BxIm36XXK5LtWFObWJWjXOA+kcaABMrthjWu6la+FUpyYFMHRvbA==}
engines: {node: '>= 12'} engines: {node: '>=v14'}
dependencies:
chalk: 4.1.2
dev: true dev: true
optional: true
/@cspotcode/source-map-support/0.7.0: /@cspotcode/source-map-support/0.8.1:
resolution: {integrity: sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==} resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'} engines: {node: '>=12'}
dependencies: dependencies:
'@cspotcode/source-map-consumer': 0.8.0 '@jridgewell/trace-mapping': 0.3.9
dev: true dev: true
optional: true
/@hutson/parse-repository-url/3.0.2: /@hutson/parse-repository-url/3.0.2:
resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dev: true dev: true
/@jridgewell/resolve-uri/3.1.0:
resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
engines: {node: '>=6.0.0'}
dev: true
/@jridgewell/sourcemap-codec/1.4.14:
resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
dev: true
/@jridgewell/trace-mapping/0.3.9:
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
dependencies:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.14
dev: true
/@tsconfig/node10/1.0.8: /@tsconfig/node10/1.0.8:
resolution: {integrity: sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==} resolution: {integrity: sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==}
dev: true dev: true
optional: true
/@tsconfig/node12/1.0.9: /@tsconfig/node12/1.0.9:
resolution: {integrity: sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==} resolution: {integrity: sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==}
dev: true dev: true
optional: true
/@tsconfig/node14/1.0.1: /@tsconfig/node14/1.0.1:
resolution: {integrity: sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==} resolution: {integrity: sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==}
dev: true dev: true
optional: true
/@tsconfig/node16/1.0.2: /@tsconfig/node16/1.0.2:
resolution: {integrity: sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==} resolution: {integrity: sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==}
dev: true dev: true
optional: true
/@types/minimist/1.2.2: /@types/minimist/1.2.2:
resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==}
...@@ -135,7 +318,6 @@ packages: ...@@ -135,7 +318,6 @@ packages:
/@types/node/17.0.29: /@types/node/17.0.29:
resolution: {integrity: sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA==} resolution: {integrity: sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA==}
dev: true dev: true
optional: true
/@types/normalize-package-data/2.4.1: /@types/normalize-package-data/2.4.1:
resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
...@@ -158,14 +340,12 @@ packages: ...@@ -158,14 +340,12 @@ packages:
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
dev: true dev: true
optional: true
/acorn/8.7.1: /acorn/8.7.1:
resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==} resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
hasBin: true hasBin: true
dev: true dev: true
optional: true
/add-stream/1.0.0: /add-stream/1.0.0:
resolution: {integrity: sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=} resolution: {integrity: sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=}
...@@ -181,11 +361,27 @@ packages: ...@@ -181,11 +361,27 @@ packages:
dev: true dev: true
optional: true optional: true
/ajv/8.12.0:
resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==}
dependencies:
fast-deep-equal: 3.1.3
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
uri-js: 4.4.1
dev: true
/ansi-escapes/3.2.0: /ansi-escapes/3.2.0:
resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==}
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: true
/ansi-escapes/4.3.2:
resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
engines: {node: '>=8'}
dependencies:
type-fest: 0.21.3
dev: true
/ansi-regex/3.0.1: /ansi-regex/3.0.1:
resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==}
engines: {node: '>=4'} engines: {node: '>=4'}
...@@ -218,21 +414,41 @@ packages: ...@@ -218,21 +414,41 @@ packages:
/arg/4.1.3: /arg/4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
dev: true dev: true
optional: true
/argparse/2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: true
/array-ify/1.0.0: /array-ify/1.0.0:
resolution: {integrity: sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=} resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==}
dev: true dev: true
/arrify/1.0.1: /arrify/1.0.1:
resolution: {integrity: sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=} resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/at-least-node/1.0.0:
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
engines: {node: '>= 4.0.0'}
dev: true
/balanced-match/1.0.2: /balanced-match/1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: true dev: true
/base64-js/1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
dev: true
/bl/4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
dependencies:
buffer: 5.7.1
inherits: 2.0.4
readable-stream: 3.6.0
dev: true
/brace-expansion/1.1.11: /brace-expansion/1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies: dependencies:
...@@ -247,8 +463,15 @@ packages: ...@@ -247,8 +463,15 @@ packages:
fill-range: 7.0.1 fill-range: 7.0.1
dev: true dev: true
/cachedir/2.2.0: /buffer/5.7.1:
resolution: {integrity: sha512-VvxA0xhNqIIfg0V9AmJkDg91DaJwryutH5rVEZAhcNi4iJFj9f+QxmAjgK1LT9I8OgToX27fypX6/MeCXVbBjQ==} resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
dev: true
/cachedir/2.3.0:
resolution: {integrity: sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==}
engines: {node: '>=6'} engines: {node: '>=6'}
dev: true dev: true
...@@ -256,7 +479,6 @@ packages: ...@@ -256,7 +479,6 @@ packages:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
dev: true dev: true
optional: true
/camelcase-keys/6.2.2: /camelcase-keys/6.2.2:
resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==}
...@@ -288,23 +510,39 @@ packages: ...@@ -288,23 +510,39 @@ packages:
ansi-styles: 4.3.0 ansi-styles: 4.3.0
supports-color: 7.2.0 supports-color: 7.2.0
dev: true dev: true
optional: true
/chardet/0.7.0: /chardet/0.7.0:
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
dev: true dev: true
/cli-cursor/2.1.0: /cli-cursor/2.1.0:
resolution: {integrity: sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=} resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
restore-cursor: 2.0.0 restore-cursor: 2.0.0
dev: true dev: true
/cli-cursor/3.1.0:
resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
engines: {node: '>=8'}
dependencies:
restore-cursor: 3.1.0
dev: true
/cli-spinners/2.7.0:
resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==}
engines: {node: '>=6'}
dev: true
/cli-width/2.2.1: /cli-width/2.2.1:
resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==} resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==}
dev: true dev: true
/cli-width/3.0.0:
resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==}
engines: {node: '>= 10'}
dev: true
/cliui/7.0.4: /cliui/7.0.4:
resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
dependencies: dependencies:
...@@ -313,6 +551,20 @@ packages: ...@@ -313,6 +551,20 @@ packages:
wrap-ansi: 7.0.0 wrap-ansi: 7.0.0
dev: true dev: true
/cliui/8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 7.0.0
dev: true
/clone/1.0.4:
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
engines: {node: '>=0.8'}
dev: true
/color-convert/1.9.3: /color-convert/1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies: dependencies:
...@@ -327,32 +579,32 @@ packages: ...@@ -327,32 +579,32 @@ packages:
dev: true dev: true
/color-name/1.1.3: /color-name/1.1.3:
resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=} resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
dev: true dev: true
/color-name/1.1.4: /color-name/1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
dev: true dev: true
/commitizen/4.2.4: /commitizen/4.2.6:
resolution: {integrity: sha512-LlZChbDzg3Ir3O2S7jSo/cgWp5/QwylQVr59K4xayVq8S4/RdKzSyJkghAiZZHfhh5t4pxunUoyeg0ml1q/7aw==} resolution: {integrity: sha512-RyTM+EiD9GO01DJUn9MRRAet3XUHGfoUZoksLfr+1ym1Xt2q5EYJs9Fg2BtKSb5Mo53i0BtMBmWMHQXVlZ/L9w==}
engines: {node: '>= 10'} engines: {node: '>= 12'}
hasBin: true hasBin: true
dependencies: dependencies:
cachedir: 2.2.0 cachedir: 2.3.0
cz-conventional-changelog: 3.2.0 cz-conventional-changelog: 3.3.0
dedent: 0.7.0 dedent: 0.7.0
detect-indent: 6.0.0 detect-indent: 6.1.0
find-node-modules: 2.1.3 find-node-modules: 2.1.3
find-root: 1.1.0 find-root: 1.1.0
fs-extra: 8.1.0 fs-extra: 9.1.0
glob: 7.1.4 glob: 7.2.3
inquirer: 6.5.2 inquirer: 8.2.4
is-utf8: 0.2.1 is-utf8: 0.2.1
lodash: 4.17.21 lodash: 4.17.21
minimist: 1.2.5 minimist: 1.2.6
strip-bom: 4.0.0 strip-bom: 4.0.0
strip-json-comments: 3.0.1 strip-json-comments: 3.1.1
transitivePeerDependencies: transitivePeerDependencies:
- '@swc/core' - '@swc/core'
- '@swc/wasm' - '@swc/wasm'
...@@ -366,7 +618,7 @@ packages: ...@@ -366,7 +618,7 @@ packages:
dev: true dev: true
/concat-map/0.0.1: /concat-map/0.0.1:
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: true dev: true
/conventional-changelog-angular/5.0.13: /conventional-changelog-angular/5.0.13:
...@@ -412,6 +664,15 @@ packages: ...@@ -412,6 +664,15 @@ packages:
q: 1.5.1 q: 1.5.1
dev: true dev: true
/conventional-changelog-conventionalcommits/5.0.0:
resolution: {integrity: sha512-lCDbA+ZqVFQGUj7h9QBKoIpLhl8iihkO0nCTyRNzuXtcd7ubODpYB04IFy31JloiJgG0Uovu8ot8oxRzn7Nwtw==}
engines: {node: '>=10'}
dependencies:
compare-func: 2.0.0
lodash: 4.17.21
q: 1.5.1
dev: true
/conventional-changelog-core/4.2.4: /conventional-changelog-core/4.2.4:
resolution: {integrity: sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==} resolution: {integrity: sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==}
engines: {node: '>=10'} engines: {node: '>=10'}
...@@ -523,8 +784,8 @@ packages: ...@@ -523,8 +784,8 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
hasBin: true hasBin: true
dependencies: dependencies:
is-text-path: 1.0.1
JSONStream: 1.3.5 JSONStream: 1.3.5
is-text-path: 1.0.1
lodash: 4.17.21 lodash: 4.17.21
meow: 8.1.2 meow: 8.1.2
split2: 3.2.2 split2: 3.2.2
...@@ -535,7 +796,7 @@ packages: ...@@ -535,7 +796,7 @@ packages:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
dev: true dev: true
/cosmiconfig-typescript-loader/1.0.9_5281fe59fc32158e106b8b5e2bebb315: /cosmiconfig-typescript-loader/1.0.9_kka74wp4giky4edlrnpcx25tcu:
resolution: {integrity: sha512-tRuMRhxN4m1Y8hP9SNYfz7jRwt8lZdWxdjg/ohg5esKmsndJIn4yT96oJVcf5x0eA11taXl+sIp+ielu529k6g==} resolution: {integrity: sha512-tRuMRhxN4m1Y8hP9SNYfz7jRwt8lZdWxdjg/ohg5esKmsndJIn4yT96oJVcf5x0eA11taXl+sIp+ielu529k6g==}
engines: {node: '>=12', npm: '>=6'} engines: {node: '>=12', npm: '>=6'}
peerDependencies: peerDependencies:
...@@ -544,7 +805,7 @@ packages: ...@@ -544,7 +805,7 @@ packages:
dependencies: dependencies:
'@types/node': 17.0.29 '@types/node': 17.0.29
cosmiconfig: 7.0.1 cosmiconfig: 7.0.1
ts-node: 10.7.0_5281fe59fc32158e106b8b5e2bebb315 ts-node: 10.9.1_kka74wp4giky4edlrnpcx25tcu
typescript: 4.6.3 typescript: 4.6.3
transitivePeerDependencies: transitivePeerDependencies:
- '@swc/core' - '@swc/core'
...@@ -552,6 +813,21 @@ packages: ...@@ -552,6 +813,21 @@ packages:
dev: true dev: true
optional: true optional: true
/cosmiconfig-typescript-loader/4.3.0_asoaktcvsaefgrgziobsocgewq:
resolution: {integrity: sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==}
engines: {node: '>=12', npm: '>=6'}
peerDependencies:
'@types/node': '*'
cosmiconfig: '>=7'
ts-node: '>=10'
typescript: '>=3'
dependencies:
'@types/node': 17.0.29
cosmiconfig: 8.0.0
ts-node: 10.9.1_u3h3q7xqdg7nitfvwf64wuo7zy
typescript: 4.9.4
dev: true
/cosmiconfig/7.0.1: /cosmiconfig/7.0.1:
resolution: {integrity: sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==} resolution: {integrity: sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
...@@ -564,26 +840,27 @@ packages: ...@@ -564,26 +840,27 @@ packages:
dev: true dev: true
optional: true optional: true
/cosmiconfig/8.0.0:
resolution: {integrity: sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ==}
engines: {node: '>=14'}
dependencies:
import-fresh: 3.3.0
js-yaml: 4.1.0
parse-json: 5.2.0
path-type: 4.0.0
dev: true
/create-require/1.1.1: /create-require/1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
dev: true dev: true
optional: true
/cz-conventional-changelog/3.2.0: /cross-spawn/7.0.3:
resolution: {integrity: sha512-yAYxeGpVi27hqIilG1nh4A9Bnx4J3Ov+eXy4koL3drrR+IO9GaWPsKjik20ht608Asqi8TQPf0mczhEeyAtMzg==} resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 10'} engines: {node: '>= 8'}
dependencies: dependencies:
chalk: 2.4.2 path-key: 3.1.1
commitizen: 4.2.4 shebang-command: 2.0.0
conventional-commit-types: 3.0.0 which: 2.0.2
lodash.map: 4.6.0
longest: 2.0.1
word-wrap: 1.2.3
optionalDependencies:
'@commitlint/load': 16.2.3
transitivePeerDependencies:
- '@swc/core'
- '@swc/wasm'
dev: true dev: true
/cz-conventional-changelog/3.3.0: /cz-conventional-changelog/3.3.0:
...@@ -591,7 +868,7 @@ packages: ...@@ -591,7 +868,7 @@ packages:
engines: {node: '>= 10'} engines: {node: '>= 10'}
dependencies: dependencies:
chalk: 2.4.2 chalk: 2.4.2
commitizen: 4.2.4 commitizen: 4.2.6
conventional-commit-types: 3.0.0 conventional-commit-types: 3.0.0
lodash.map: 4.6.0 lodash.map: 4.6.0
longest: 2.0.1 longest: 2.0.1
...@@ -603,6 +880,22 @@ packages: ...@@ -603,6 +880,22 @@ packages:
- '@swc/wasm' - '@swc/wasm'
dev: true dev: true
/cz-customizable/7.0.0:
resolution: {integrity: sha512-pQKkGSm+8SY9VY/yeJqDOla1MjrGaG7WG4EYLLEV4VNctGO7WdzdGtWEr2ydKSkrpmTs7f8fmBksg/FaTrUAyw==}
hasBin: true
dependencies:
editor: 1.0.0
find-config: 1.0.0
inquirer: 6.5.2
lodash: 4.17.21
temp: 0.9.4
word-wrap: 1.2.3
dev: true
/cz-git/1.4.1:
resolution: {integrity: sha512-EOtuitcnfxde8t3NNTKh2YxEJhLXGiVlKSVaZipK3+DVo135rEUifAfqxkslM66Nf6ZO7a+3JR+XAOLhMXUAjQ==}
dev: true
/dargs/7.0.0: /dargs/7.0.0:
resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==}
engines: {node: '>=8'} engines: {node: '>=8'}
...@@ -613,7 +906,7 @@ packages: ...@@ -613,7 +906,7 @@ packages:
dev: true dev: true
/decamelize-keys/1.1.0: /decamelize-keys/1.1.0:
resolution: {integrity: sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=} resolution: {integrity: sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dependencies: dependencies:
decamelize: 1.2.0 decamelize: 1.2.0
...@@ -621,21 +914,27 @@ packages: ...@@ -621,21 +914,27 @@ packages:
dev: true dev: true
/decamelize/1.2.0: /decamelize/1.2.0:
resolution: {integrity: sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=} resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/dedent/0.7.0: /dedent/0.7.0:
resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=} resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==}
dev: true
/defaults/1.0.4:
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
dependencies:
clone: 1.0.4
dev: true dev: true
/detect-file/1.0.0: /detect-file/1.0.0:
resolution: {integrity: sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=} resolution: {integrity: sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/detect-indent/6.0.0: /detect-indent/6.1.0:
resolution: {integrity: sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==} resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==}
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
...@@ -643,7 +942,6 @@ packages: ...@@ -643,7 +942,6 @@ packages:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
engines: {node: '>=0.3.1'} engines: {node: '>=0.3.1'}
dev: true dev: true
optional: true
/dot-prop/5.3.0: /dot-prop/5.3.0:
resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
...@@ -652,6 +950,10 @@ packages: ...@@ -652,6 +950,10 @@ packages:
is-obj: 2.0.0 is-obj: 2.0.0
dev: true dev: true
/editor/1.0.0:
resolution: {integrity: sha512-SoRmbGStwNYHgKfjOrX2L0mUvp9bUVv0uPppZSOMAntEbcFtoC3MKF5b3T6HQPXKIV+QGY3xPO3JK5it5lVkuw==}
dev: true
/emoji-regex/8.0.0: /emoji-regex/8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
dev: true dev: true
...@@ -668,12 +970,27 @@ packages: ...@@ -668,12 +970,27 @@ packages:
dev: true dev: true
/escape-string-regexp/1.0.5: /escape-string-regexp/1.0.5:
resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
engines: {node: '>=0.8.0'} engines: {node: '>=0.8.0'}
dev: true dev: true
/execa/5.1.1:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
dependencies:
cross-spawn: 7.0.3
get-stream: 6.0.1
human-signals: 2.1.0
is-stream: 2.0.1
merge-stream: 2.0.0
npm-run-path: 4.0.1
onetime: 5.1.2
signal-exit: 3.0.7
strip-final-newline: 2.0.0
dev: true
/expand-tilde/2.0.2: /expand-tilde/2.0.2:
resolution: {integrity: sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=} resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dependencies: dependencies:
homedir-polyfill: 1.0.3 homedir-polyfill: 1.0.3
...@@ -691,7 +1008,6 @@ packages: ...@@ -691,7 +1008,6 @@ packages:
/fast-deep-equal/3.1.3: /fast-deep-equal/3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
dev: true dev: true
optional: true
/fast-json-stable-stringify/2.1.0: /fast-json-stable-stringify/2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
...@@ -699,12 +1015,19 @@ packages: ...@@ -699,12 +1015,19 @@ packages:
optional: true optional: true
/figures/2.0.0: /figures/2.0.0:
resolution: {integrity: sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=} resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
escape-string-regexp: 1.0.5 escape-string-regexp: 1.0.5
dev: true dev: true
/figures/3.2.0:
resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==}
engines: {node: '>=8'}
dependencies:
escape-string-regexp: 1.0.5
dev: true
/fill-range/7.0.1: /fill-range/7.0.1:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'} engines: {node: '>=8'}
...@@ -712,6 +1035,13 @@ packages: ...@@ -712,6 +1035,13 @@ packages:
to-regex-range: 5.0.1 to-regex-range: 5.0.1
dev: true dev: true
/find-config/1.0.0:
resolution: {integrity: sha512-Z+suHH+7LSE40WfUeZPIxSxypCWvrzdVc60xAjUShZeT5eMWM0/FQUduq3HjluyfAHWvC/aOBkT1pTZktyF/jg==}
engines: {node: '>= 0.12'}
dependencies:
user-home: 2.0.0
dev: true
/find-node-modules/2.1.3: /find-node-modules/2.1.3:
resolution: {integrity: sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==} resolution: {integrity: sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==}
dependencies: dependencies:
...@@ -724,7 +1054,7 @@ packages: ...@@ -724,7 +1054,7 @@ packages:
dev: true dev: true
/find-up/2.1.0: /find-up/2.1.0:
resolution: {integrity: sha1-RdG35QbHF93UgndaK3eSCjwMV6c=} resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
locate-path: 2.0.0 locate-path: 2.0.0
...@@ -738,6 +1068,14 @@ packages: ...@@ -738,6 +1068,14 @@ packages:
path-exists: 4.0.0 path-exists: 4.0.0
dev: true dev: true
/find-up/5.0.0:
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'}
dependencies:
locate-path: 6.0.0
path-exists: 4.0.0
dev: true
/findup-sync/4.0.0: /findup-sync/4.0.0:
resolution: {integrity: sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==} resolution: {integrity: sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
...@@ -748,17 +1086,27 @@ packages: ...@@ -748,17 +1086,27 @@ packages:
resolve-dir: 1.0.1 resolve-dir: 1.0.1
dev: true dev: true
/fs-extra/8.1.0: /fs-extra/11.1.0:
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==}
engines: {node: '>=6 <7 || >=8'} engines: {node: '>=14.14'}
dependencies: dependencies:
graceful-fs: 4.2.10 graceful-fs: 4.2.10
jsonfile: 4.0.0 jsonfile: 6.1.0
universalify: 0.1.2 universalify: 2.0.0
dev: true
/fs-extra/9.1.0:
resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==}
engines: {node: '>=10'}
dependencies:
at-least-node: 1.0.0
graceful-fs: 4.2.10
jsonfile: 6.1.0
universalify: 2.0.0
dev: true dev: true
/fs.realpath/1.0.0: /fs.realpath/1.0.0:
resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
dev: true dev: true
/function-bind/1.1.1: /function-bind/1.1.1:
...@@ -781,6 +1129,11 @@ packages: ...@@ -781,6 +1129,11 @@ packages:
yargs: 16.2.0 yargs: 16.2.0
dev: true dev: true
/get-stream/6.0.1:
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
engines: {node: '>=10'}
dev: true
/git-raw-commits/2.0.11: /git-raw-commits/2.0.11:
resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==}
engines: {node: '>=10'} engines: {node: '>=10'}
...@@ -816,8 +1169,8 @@ packages: ...@@ -816,8 +1169,8 @@ packages:
ini: 1.3.8 ini: 1.3.8
dev: true dev: true
/glob/7.1.4: /glob/7.2.3:
resolution: {integrity: sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==} resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
dependencies: dependencies:
fs.realpath: 1.0.0 fs.realpath: 1.0.0
inflight: 1.0.6 inflight: 1.0.6
...@@ -828,12 +1181,11 @@ packages: ...@@ -828,12 +1181,11 @@ packages:
dev: true dev: true
/global-dirs/0.1.1: /global-dirs/0.1.1:
resolution: {integrity: sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=} resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
ini: 1.3.8 ini: 1.3.8
dev: true dev: true
optional: true
/global-modules/1.0.0: /global-modules/1.0.0:
resolution: {integrity: sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==} resolution: {integrity: sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==}
...@@ -845,7 +1197,7 @@ packages: ...@@ -845,7 +1197,7 @@ packages:
dev: true dev: true
/global-prefix/1.0.2: /global-prefix/1.0.2:
resolution: {integrity: sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=} resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dependencies: dependencies:
expand-tilde: 2.0.2 expand-tilde: 2.0.2
...@@ -878,7 +1230,7 @@ packages: ...@@ -878,7 +1230,7 @@ packages:
dev: true dev: true
/has-flag/3.0.0: /has-flag/3.0.0:
resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: true
...@@ -886,7 +1238,6 @@ packages: ...@@ -886,7 +1238,6 @@ packages:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
optional: true
/has/1.0.3: /has/1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
...@@ -913,6 +1264,11 @@ packages: ...@@ -913,6 +1264,11 @@ packages:
lru-cache: 6.0.0 lru-cache: 6.0.0
dev: true dev: true
/human-signals/2.1.0:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
dev: true
/iconv-lite/0.4.24: /iconv-lite/0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
...@@ -920,6 +1276,10 @@ packages: ...@@ -920,6 +1276,10 @@ packages:
safer-buffer: 2.1.2 safer-buffer: 2.1.2
dev: true dev: true
/ieee754/1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
dev: true
/import-fresh/3.3.0: /import-fresh/3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'} engines: {node: '>=6'}
...@@ -927,7 +1287,6 @@ packages: ...@@ -927,7 +1287,6 @@ packages:
parent-module: 1.0.1 parent-module: 1.0.1
resolve-from: 4.0.0 resolve-from: 4.0.0
dev: true dev: true
optional: true
/indent-string/4.0.0: /indent-string/4.0.0:
resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
...@@ -935,7 +1294,7 @@ packages: ...@@ -935,7 +1294,7 @@ packages:
dev: true dev: true
/inflight/1.0.6: /inflight/1.0.6:
resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=} resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
dependencies: dependencies:
once: 1.4.0 once: 1.4.0
wrappy: 1.0.2 wrappy: 1.0.2
...@@ -968,8 +1327,29 @@ packages: ...@@ -968,8 +1327,29 @@ packages:
through: 2.3.8 through: 2.3.8
dev: true dev: true
/inquirer/8.2.4:
resolution: {integrity: sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==}
engines: {node: '>=12.0.0'}
dependencies:
ansi-escapes: 4.3.2
chalk: 4.1.2
cli-cursor: 3.1.0
cli-width: 3.0.0
external-editor: 3.1.0
figures: 3.2.0
lodash: 4.17.21
mute-stream: 0.0.8
ora: 5.4.1
run-async: 2.4.1
rxjs: 7.8.0
string-width: 4.2.3
strip-ansi: 6.0.1
through: 2.3.8
wrap-ansi: 7.0.0
dev: true
/is-arrayish/0.2.1: /is-arrayish/0.2.1:
resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=} resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
dev: true dev: true
/is-core-module/2.9.0: /is-core-module/2.9.0:
...@@ -979,12 +1359,12 @@ packages: ...@@ -979,12 +1359,12 @@ packages:
dev: true dev: true
/is-extglob/2.1.1: /is-extglob/2.1.1:
resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=} resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/is-fullwidth-code-point/2.0.0: /is-fullwidth-code-point/2.0.0:
resolution: {integrity: sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=} resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==}
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: true
...@@ -1000,6 +1380,11 @@ packages: ...@@ -1000,6 +1380,11 @@ packages:
is-extglob: 2.1.1 is-extglob: 2.1.1
dev: true dev: true
/is-interactive/1.0.0:
resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
engines: {node: '>=8'}
dev: true
/is-number/7.0.0: /is-number/7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'} engines: {node: '>=0.12.0'}
...@@ -1011,19 +1396,29 @@ packages: ...@@ -1011,19 +1396,29 @@ packages:
dev: true dev: true
/is-plain-obj/1.1.0: /is-plain-obj/1.1.0:
resolution: {integrity: sha1-caUMhCnfync8kqOQpKA7OfzVHT4=} resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/is-stream/2.0.1:
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
engines: {node: '>=8'}
dev: true
/is-text-path/1.0.1: /is-text-path/1.0.1:
resolution: {integrity: sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=} resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dependencies: dependencies:
text-extensions: 1.9.0 text-extensions: 1.9.0
dev: true dev: true
/is-unicode-supported/0.1.0:
resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
engines: {node: '>=10'}
dev: true
/is-utf8/0.2.1: /is-utf8/0.2.1:
resolution: {integrity: sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=} resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==}
dev: true dev: true
/is-windows/1.0.2: /is-windows/1.0.2:
...@@ -1036,13 +1431,20 @@ packages: ...@@ -1036,13 +1431,20 @@ packages:
dev: true dev: true
/isexe/2.0.0: /isexe/2.0.0:
resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
dev: true dev: true
/js-tokens/4.0.0: /js-tokens/4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
dev: true dev: true
/js-yaml/4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
dependencies:
argparse: 2.0.1
dev: true
/json-parse-better-errors/1.0.2: /json-parse-better-errors/1.0.2:
resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==}
dev: true dev: true
...@@ -1056,18 +1458,24 @@ packages: ...@@ -1056,18 +1458,24 @@ packages:
dev: true dev: true
optional: true optional: true
/json-schema-traverse/1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
dev: true
/json-stringify-safe/5.0.1: /json-stringify-safe/5.0.1:
resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=} resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=}
dev: true dev: true
/jsonfile/4.0.0: /jsonfile/6.1.0:
resolution: {integrity: sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=} resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
dependencies:
universalify: 2.0.0
optionalDependencies: optionalDependencies:
graceful-fs: 4.2.10 graceful-fs: 4.2.10
dev: true dev: true
/jsonparse/1.3.1: /jsonparse/1.3.1:
resolution: {integrity: sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=} resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
engines: {'0': node >= 0.2.0} engines: {'0': node >= 0.2.0}
dev: true dev: true
...@@ -1091,7 +1499,7 @@ packages: ...@@ -1091,7 +1499,7 @@ packages:
dev: true dev: true
/locate-path/2.0.0: /locate-path/2.0.0:
resolution: {integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=} resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
p-locate: 2.0.0 p-locate: 2.0.0
...@@ -1105,18 +1513,73 @@ packages: ...@@ -1105,18 +1513,73 @@ packages:
p-locate: 4.1.0 p-locate: 4.1.0
dev: true dev: true
/locate-path/6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
dependencies:
p-locate: 5.0.0
dev: true
/lodash.camelcase/4.3.0:
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
dev: true
/lodash.isfunction/3.0.9:
resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==}
dev: true
/lodash.ismatch/4.4.0: /lodash.ismatch/4.4.0:
resolution: {integrity: sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=} resolution: {integrity: sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=}
dev: true dev: true
/lodash.isplainobject/4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
dev: true
/lodash.kebabcase/4.1.1:
resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==}
dev: true
/lodash.map/4.6.0: /lodash.map/4.6.0:
resolution: {integrity: sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=} resolution: {integrity: sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=}
dev: true dev: true
/lodash.merge/4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
dev: true
/lodash.mergewith/4.6.2:
resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==}
dev: true
/lodash.snakecase/4.1.1:
resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==}
dev: true
/lodash.startcase/4.4.0:
resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==}
dev: true
/lodash.uniq/4.5.0:
resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==}
dev: true
/lodash.upperfirst/4.3.1:
resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==}
dev: true
/lodash/4.17.21: /lodash/4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
dev: true dev: true
/log-symbols/4.1.0:
resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
engines: {node: '>=10'}
dependencies:
chalk: 4.1.2
is-unicode-supported: 0.1.0
dev: true
/longest/2.0.1: /longest/2.0.1:
resolution: {integrity: sha1-eB4YMpaqlPbU2RbcM10NF676I/g=} resolution: {integrity: sha1-eB4YMpaqlPbU2RbcM10NF676I/g=}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
...@@ -1132,10 +1595,9 @@ packages: ...@@ -1132,10 +1595,9 @@ packages:
/make-error/1.3.6: /make-error/1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
dev: true dev: true
optional: true
/map-obj/1.0.1: /map-obj/1.0.1:
resolution: {integrity: sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=} resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
...@@ -1161,6 +1623,10 @@ packages: ...@@ -1161,6 +1623,10 @@ packages:
yargs-parser: 20.2.9 yargs-parser: 20.2.9
dev: true dev: true
/merge-stream/2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
dev: true
/merge/2.1.1: /merge/2.1.1:
resolution: {integrity: sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==} resolution: {integrity: sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==}
dev: true dev: true
...@@ -1178,6 +1644,11 @@ packages: ...@@ -1178,6 +1644,11 @@ packages:
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: true
/mimic-fn/2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
dev: true
/min-indent/1.0.1: /min-indent/1.0.1:
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
engines: {node: '>=4'} engines: {node: '>=4'}
...@@ -1198,21 +1669,28 @@ packages: ...@@ -1198,21 +1669,28 @@ packages:
kind-of: 6.0.3 kind-of: 6.0.3
dev: true dev: true
/minimist/1.2.5:
resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==}
dev: true
/minimist/1.2.6: /minimist/1.2.6:
resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==}
dev: true dev: true
/mkdirp/0.5.6:
resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
hasBin: true
dependencies:
minimist: 1.2.6
dev: true
/modify-values/1.0.1: /modify-values/1.0.1:
resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==} resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/mute-stream/0.0.7: /mute-stream/0.0.7:
resolution: {integrity: sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=} resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==}
dev: true
/mute-stream/0.0.8:
resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
dev: true dev: true
/neo-async/2.6.2: /neo-async/2.6.2:
...@@ -1234,25 +1712,59 @@ packages: ...@@ -1234,25 +1712,59 @@ packages:
dependencies: dependencies:
hosted-git-info: 4.1.0 hosted-git-info: 4.1.0
is-core-module: 2.9.0 is-core-module: 2.9.0
semver: 7.3.7 semver: 7.3.8
validate-npm-package-license: 3.0.4 validate-npm-package-license: 3.0.4
dev: true dev: true
/npm-run-path/4.0.1:
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
engines: {node: '>=8'}
dependencies:
path-key: 3.1.1
dev: true
/once/1.4.0: /once/1.4.0:
resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies: dependencies:
wrappy: 1.0.2 wrappy: 1.0.2
dev: true dev: true
/onetime/2.0.1: /onetime/2.0.1:
resolution: {integrity: sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=} resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
mimic-fn: 1.2.0 mimic-fn: 1.2.0
dev: true dev: true
/onetime/5.1.2:
resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
engines: {node: '>=6'}
dependencies:
mimic-fn: 2.1.0
dev: true
/ora/5.4.1:
resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
engines: {node: '>=10'}
dependencies:
bl: 4.1.0
chalk: 4.1.2
cli-cursor: 3.1.0
cli-spinners: 2.7.0
is-interactive: 1.0.0
is-unicode-supported: 0.1.0
log-symbols: 4.1.0
strip-ansi: 6.0.1
wcwidth: 1.0.1
dev: true
/os-homedir/1.0.2:
resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==}
engines: {node: '>=0.10.0'}
dev: true
/os-tmpdir/1.0.2: /os-tmpdir/1.0.2:
resolution: {integrity: sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=} resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
...@@ -1270,8 +1782,15 @@ packages: ...@@ -1270,8 +1782,15 @@ packages:
p-try: 2.2.0 p-try: 2.2.0
dev: true dev: true
/p-limit/3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
dependencies:
yocto-queue: 0.1.0
dev: true
/p-locate/2.0.0: /p-locate/2.0.0:
resolution: {integrity: sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=} resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
p-limit: 1.3.0 p-limit: 1.3.0
...@@ -1284,8 +1803,15 @@ packages: ...@@ -1284,8 +1803,15 @@ packages:
p-limit: 2.3.0 p-limit: 2.3.0
dev: true dev: true
/p-locate/5.0.0:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
dependencies:
p-limit: 3.1.0
dev: true
/p-try/1.0.0: /p-try/1.0.0:
resolution: {integrity: sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=} resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==}
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: true
...@@ -1300,10 +1826,9 @@ packages: ...@@ -1300,10 +1826,9 @@ packages:
dependencies: dependencies:
callsites: 3.1.0 callsites: 3.1.0
dev: true dev: true
optional: true
/parse-json/4.0.0: /parse-json/4.0.0:
resolution: {integrity: sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=} resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
error-ex: 1.3.2 error-ex: 1.3.2
...@@ -1321,12 +1846,12 @@ packages: ...@@ -1321,12 +1846,12 @@ packages:
dev: true dev: true
/parse-passwd/1.0.0: /parse-passwd/1.0.0:
resolution: {integrity: sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=} resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/path-exists/3.0.0: /path-exists/3.0.0:
resolution: {integrity: sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=} resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: true
...@@ -1336,10 +1861,15 @@ packages: ...@@ -1336,10 +1861,15 @@ packages:
dev: true dev: true
/path-is-absolute/1.0.1: /path-is-absolute/1.0.1:
resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/path-key/3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
dev: true
/path-parse/1.0.7: /path-parse/1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: true dev: true
...@@ -1355,7 +1885,6 @@ packages: ...@@ -1355,7 +1885,6 @@ packages:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
optional: true
/picomatch/2.3.1: /picomatch/2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
...@@ -1380,10 +1909,9 @@ packages: ...@@ -1380,10 +1909,9 @@ packages:
resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
engines: {node: '>=6'} engines: {node: '>=6'}
dev: true dev: true
optional: true
/q/1.5.1: /q/1.5.1:
resolution: {integrity: sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=} resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==}
engines: {node: '>=0.6.0', teleport: '>=0.2.0'} engines: {node: '>=0.6.0', teleport: '>=0.2.0'}
dev: true dev: true
...@@ -1393,7 +1921,7 @@ packages: ...@@ -1393,7 +1921,7 @@ packages:
dev: true dev: true
/read-pkg-up/3.0.0: /read-pkg-up/3.0.0:
resolution: {integrity: sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=} resolution: {integrity: sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
find-up: 2.1.0 find-up: 2.1.0
...@@ -1410,7 +1938,7 @@ packages: ...@@ -1410,7 +1938,7 @@ packages:
dev: true dev: true
/read-pkg/3.0.0: /read-pkg/3.0.0:
resolution: {integrity: sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=} resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
load-json-file: 4.0.0 load-json-file: 4.0.0
...@@ -1458,12 +1986,17 @@ packages: ...@@ -1458,12 +1986,17 @@ packages:
dev: true dev: true
/require-directory/2.1.1: /require-directory/2.1.1:
resolution: {integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=} resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
dev: true
/require-from-string/2.0.2:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/resolve-dir/1.0.1: /resolve-dir/1.0.1:
resolution: {integrity: sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=} resolution: {integrity: sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dependencies: dependencies:
expand-tilde: 2.0.2 expand-tilde: 2.0.2
...@@ -1474,13 +2007,11 @@ packages: ...@@ -1474,13 +2007,11 @@ packages:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: true
optional: true
/resolve-from/5.0.0: /resolve-from/5.0.0:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
optional: true
/resolve-global/1.0.0: /resolve-global/1.0.0:
resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==} resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==}
...@@ -1488,7 +2019,6 @@ packages: ...@@ -1488,7 +2019,6 @@ packages:
dependencies: dependencies:
global-dirs: 0.1.1 global-dirs: 0.1.1
dev: true dev: true
optional: true
/resolve/1.22.0: /resolve/1.22.0:
resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==} resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==}
...@@ -1500,13 +2030,28 @@ packages: ...@@ -1500,13 +2030,28 @@ packages:
dev: true dev: true
/restore-cursor/2.0.0: /restore-cursor/2.0.0:
resolution: {integrity: sha1-n37ih/gv0ybU/RYpI9YhKe7g368=} resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
onetime: 2.0.1 onetime: 2.0.1
signal-exit: 3.0.7 signal-exit: 3.0.7
dev: true dev: true
/restore-cursor/3.1.0:
resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
engines: {node: '>=8'}
dependencies:
onetime: 5.1.2
signal-exit: 3.0.7
dev: true
/rimraf/2.6.3:
resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==}
hasBin: true
dependencies:
glob: 7.2.3
dev: true
/run-async/2.4.1: /run-async/2.4.1:
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
engines: {node: '>=0.12.0'} engines: {node: '>=0.12.0'}
...@@ -1519,6 +2064,12 @@ packages: ...@@ -1519,6 +2064,12 @@ packages:
tslib: 1.14.1 tslib: 1.14.1
dev: true dev: true
/rxjs/7.8.0:
resolution: {integrity: sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==}
dependencies:
tslib: 2.4.1
dev: true
/safe-buffer/5.1.2: /safe-buffer/5.1.2:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
dev: true dev: true
...@@ -1541,14 +2092,26 @@ packages: ...@@ -1541,14 +2092,26 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/semver/7.3.7: /semver/7.3.8:
resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==} resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==}
engines: {node: '>=10'} engines: {node: '>=10'}
hasBin: true hasBin: true
dependencies: dependencies:
lru-cache: 6.0.0 lru-cache: 6.0.0
dev: true dev: true
/shebang-command/2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
dependencies:
shebang-regex: 3.0.0
dev: true
/shebang-regex/3.0.0:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
dev: true
/signal-exit/3.0.7: /signal-exit/3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: true dev: true
...@@ -1622,7 +2185,7 @@ packages: ...@@ -1622,7 +2185,7 @@ packages:
dev: true dev: true
/strip-ansi/4.0.0: /strip-ansi/4.0.0:
resolution: {integrity: sha1-qEeQIusaw2iocTibY1JixQXuNo8=} resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
ansi-regex: 3.0.1 ansi-regex: 3.0.1
...@@ -1643,7 +2206,7 @@ packages: ...@@ -1643,7 +2206,7 @@ packages:
dev: true dev: true
/strip-bom/3.0.0: /strip-bom/3.0.0:
resolution: {integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=} resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: true
...@@ -1652,6 +2215,11 @@ packages: ...@@ -1652,6 +2215,11 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/strip-final-newline/2.0.0:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
dev: true
/strip-indent/3.0.0: /strip-indent/3.0.0:
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
engines: {node: '>=8'} engines: {node: '>=8'}
...@@ -1659,8 +2227,8 @@ packages: ...@@ -1659,8 +2227,8 @@ packages:
min-indent: 1.0.1 min-indent: 1.0.1
dev: true dev: true
/strip-json-comments/3.0.1: /strip-json-comments/3.1.1:
resolution: {integrity: sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==} resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
...@@ -1677,7 +2245,6 @@ packages: ...@@ -1677,7 +2245,6 @@ packages:
dependencies: dependencies:
has-flag: 4.0.0 has-flag: 4.0.0
dev: true dev: true
optional: true
/supports-preserve-symlinks-flag/1.0.0: /supports-preserve-symlinks-flag/1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
...@@ -1689,6 +2256,14 @@ packages: ...@@ -1689,6 +2256,14 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/temp/0.9.4:
resolution: {integrity: sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==}
engines: {node: '>=6.0.0'}
dependencies:
mkdirp: 0.5.6
rimraf: 2.6.3
dev: true
/tempfile/3.0.0: /tempfile/3.0.0:
resolution: {integrity: sha512-uNFCg478XovRi85iD42egu+eSFUmmka750Jy7L5tfHI5hQKKtbPnxaSaXAbBqCDYrw3wx4tXjKwci4/QmsZJxw==} resolution: {integrity: sha512-uNFCg478XovRi85iD42egu+eSFUmmka750Jy7L5tfHI5hQKKtbPnxaSaXAbBqCDYrw3wx4tXjKwci4/QmsZJxw==}
engines: {node: '>=8'} engines: {node: '>=8'}
...@@ -1703,7 +2278,7 @@ packages: ...@@ -1703,7 +2278,7 @@ packages:
dev: true dev: true
/through/2.3.8: /through/2.3.8:
resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=} resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
dev: true dev: true
/through2/2.0.5: /through2/2.0.5:
...@@ -1738,8 +2313,8 @@ packages: ...@@ -1738,8 +2313,8 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/ts-node/10.7.0_5281fe59fc32158e106b8b5e2bebb315: /ts-node/10.9.1_kka74wp4giky4edlrnpcx25tcu:
resolution: {integrity: sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==} resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
'@swc/core': '>=1.2.50' '@swc/core': '>=1.2.50'
...@@ -1752,7 +2327,7 @@ packages: ...@@ -1752,7 +2327,7 @@ packages:
'@swc/wasm': '@swc/wasm':
optional: true optional: true
dependencies: dependencies:
'@cspotcode/source-map-support': 0.7.0 '@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.8 '@tsconfig/node10': 1.0.8
'@tsconfig/node12': 1.0.9 '@tsconfig/node12': 1.0.9
'@tsconfig/node14': 1.0.1 '@tsconfig/node14': 1.0.1
...@@ -1770,15 +2345,55 @@ packages: ...@@ -1770,15 +2345,55 @@ packages:
dev: true dev: true
optional: true optional: true
/ts-node/10.9.1_u3h3q7xqdg7nitfvwf64wuo7zy:
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
'@swc/core': '>=1.2.50'
'@swc/wasm': '>=1.2.50'
'@types/node': '*'
typescript: '>=2.7'
peerDependenciesMeta:
'@swc/core':
optional: true
'@swc/wasm':
optional: true
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.8
'@tsconfig/node12': 1.0.9
'@tsconfig/node14': 1.0.1
'@tsconfig/node16': 1.0.2
'@types/node': 17.0.29
acorn: 8.7.1
acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
typescript: 4.9.4
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
dev: true
/tslib/1.14.1: /tslib/1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
dev: true dev: true
/tslib/2.4.1:
resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==}
dev: true
/type-fest/0.18.1: /type-fest/0.18.1:
resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==}
engines: {node: '>=10'} engines: {node: '>=10'}
dev: true dev: true
/type-fest/0.21.3:
resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
engines: {node: '>=10'}
dev: true
/type-fest/0.6.0: /type-fest/0.6.0:
resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==}
engines: {node: '>=8'} engines: {node: '>=8'}
...@@ -1796,6 +2411,12 @@ packages: ...@@ -1796,6 +2411,12 @@ packages:
dev: true dev: true
optional: true optional: true
/typescript/4.9.4:
resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==}
engines: {node: '>=4.2.0'}
hasBin: true
dev: true
/uglify-js/3.15.4: /uglify-js/3.15.4:
resolution: {integrity: sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA==} resolution: {integrity: sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA==}
engines: {node: '>=0.8.0'} engines: {node: '>=0.8.0'}
...@@ -1804,9 +2425,9 @@ packages: ...@@ -1804,9 +2425,9 @@ packages:
dev: true dev: true
optional: true optional: true
/universalify/0.1.2: /universalify/2.0.0:
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
engines: {node: '>= 4.0.0'} engines: {node: '>= 10.0.0'}
dev: true dev: true
/uri-js/4.4.1: /uri-js/4.4.1:
...@@ -1814,10 +2435,16 @@ packages: ...@@ -1814,10 +2435,16 @@ packages:
dependencies: dependencies:
punycode: 2.1.1 punycode: 2.1.1
dev: true dev: true
optional: true
/user-home/2.0.0:
resolution: {integrity: sha512-KMWqdlOcjCYdtIJpicDSFBQ8nFwS2i9sslAd6f4+CBGcU4gist2REnr2fxj2YocvJFxSF3ZOHLYLVZnUxv4BZQ==}
engines: {node: '>=0.10.0'}
dependencies:
os-homedir: 1.0.2
dev: true
/util-deprecate/1.0.2: /util-deprecate/1.0.2:
resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
dev: true dev: true
/uuid/3.4.0: /uuid/3.4.0:
...@@ -1829,7 +2456,6 @@ packages: ...@@ -1829,7 +2456,6 @@ packages:
/v8-compile-cache-lib/3.0.1: /v8-compile-cache-lib/3.0.1:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
dev: true dev: true
optional: true
/validate-npm-package-license/3.0.4: /validate-npm-package-license/3.0.4:
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
...@@ -1838,6 +2464,12 @@ packages: ...@@ -1838,6 +2464,12 @@ packages:
spdx-expression-parse: 3.0.1 spdx-expression-parse: 3.0.1
dev: true dev: true
/wcwidth/1.0.1:
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
dependencies:
defaults: 1.0.4
dev: true
/which/1.3.1: /which/1.3.1:
resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
hasBin: true hasBin: true
...@@ -1845,6 +2477,14 @@ packages: ...@@ -1845,6 +2477,14 @@ packages:
isexe: 2.0.0 isexe: 2.0.0
dev: true dev: true
/which/2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
hasBin: true
dependencies:
isexe: 2.0.0
dev: true
/word-wrap/1.2.3: /word-wrap/1.2.3:
resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
...@@ -1864,7 +2504,7 @@ packages: ...@@ -1864,7 +2504,7 @@ packages:
dev: true dev: true
/wrappy/1.0.2: /wrappy/1.0.2:
resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: true dev: true
/xtend/4.0.2: /xtend/4.0.2:
...@@ -1892,6 +2532,11 @@ packages: ...@@ -1892,6 +2532,11 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
dev: true dev: true
/yargs-parser/21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
dev: true
/yargs/16.2.0: /yargs/16.2.0:
resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==}
engines: {node: '>=10'} engines: {node: '>=10'}
...@@ -1905,8 +2550,25 @@ packages: ...@@ -1905,8 +2550,25 @@ packages:
yargs-parser: 20.2.9 yargs-parser: 20.2.9
dev: true dev: true
/yargs/17.6.2:
resolution: {integrity: sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==}
engines: {node: '>=12'}
dependencies:
cliui: 8.0.1
escalade: 3.1.1
get-caller-file: 2.0.5
require-directory: 2.1.1
string-width: 4.2.3
y18n: 5.0.8
yargs-parser: 21.1.1
dev: true
/yn/3.1.1: /yn/3.1.1:
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
engines: {node: '>=6'} engines: {node: '>=6'}
dev: true dev: true
optional: true
/yocto-queue/0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
dev: true
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论