starlight-server 1.6.7 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  /**
3
2
  * 解析后的 FormData(格式参考浏览器环境中的 FormData 对象)
4
3
  * Parsed FormData (formatted like the FormData object in a browser environment)
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import { type NodeRequest } from '../types.js';
3
2
  export interface BodyOptions {
4
3
  /**
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import { type NodeRequest } from '../types.js';
3
2
  export declare function receiveBody(nodeRequest: NodeRequest,
4
3
  /**
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import type http from 'node:http';
3
2
  import { type Logger } from '../logging.js';
4
3
  import { RequestBody, type BodyOptions } from './body/index.js';
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import { type Logger } from '../logging.js';
3
2
  import { type NodeResponse } from './types.js';
4
3
  /**
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  /**
3
2
  * 重新定义 HTTP 请求相关类型
4
3
  * Redefine HTTP request-related types.
package/dist/index.d.ts CHANGED
@@ -2,4 +2,4 @@ export * from './logging.js';
2
2
  export * from './http/index.js';
3
3
  export * from './router/index.js';
4
4
  export * from './swagger/index.js';
5
- export { validators } from '@anjianshi/utils/validators/index.js';
5
+ export * from './utils.js';
package/dist/index.js CHANGED
@@ -2,4 +2,4 @@ export * from './logging.js';
2
2
  export * from './http/index.js';
3
3
  export * from './router/index.js';
4
4
  export * from './swagger/index.js';
5
- export { validators } from '@anjianshi/utils/validators/index.js';
5
+ export * from './utils.js';
@@ -1,11 +1,63 @@
1
- import { type Validator } from '@anjianshi/utils/validators/index.js';
1
+ import { type Definition as ValidatorDefinition } from '@anjianshi/utils/validators/index.js';
2
2
  import { type BasicContext } from './index.js';
3
+ import { ResponseUtils } from '../http/response.js';
3
4
  export declare class Helpers {
4
5
  readonly context: BasicContext;
5
6
  constructor(context: BasicContext);
6
- validatePathParameters<T>(struct: Record<string, Validator>): T;
7
- validateQuery<T>(struct: Record<string, Validator>): T;
8
- validateBody<T>(struct: Record<string, Validator>): Promise<T>;
7
+ validatePathParameters<Definition extends Record<string, ValidatorDefinition>>(struct: Definition): import("@anjianshi/utils/validators/base.js").Validated<{
8
+ readonly type: "struct";
9
+ readonly struct: Definition;
10
+ } extends infer T ? T extends {
11
+ readonly type: "struct";
12
+ readonly struct: Definition;
13
+ } ? T extends import("@anjianshi/utils/validators/factory.js").StructDefinition ? { [Key in keyof T["struct"]]: import("@anjianshi/utils/validators/base.js").Validated<import("@anjianshi/utils/validators/factory.js").ValueOfDefinition<T["struct"][Key]>, T["struct"][Key]>; } : T extends import("@anjianshi/utils/validators/factory.js").RecordDefinition ? Record<string, import("@anjianshi/utils/validators/base.js").Validated<import("@anjianshi/utils/validators/factory.js").ValueOfDefinition<T["record"]>, T["record"]>> : never : never : never, {
14
+ readonly type: "struct";
15
+ readonly struct: Definition;
16
+ } extends infer T_1 ? T_1 extends {
17
+ readonly type: "struct";
18
+ readonly struct: Definition;
19
+ } ? T_1 extends import("@anjianshi/utils/validators/factory.js").StructDefinition ? Omit<T_1, "struct"> & {
20
+ struct: { [Key_1 in keyof T_1["struct"]]: import("@anjianshi/utils/validators/factory.js").ValidatorForDefinition<T_1["struct"][Key_1]>; };
21
+ } : T_1 extends import("@anjianshi/utils/validators/factory.js").RecordDefinition ? Omit<T_1, "record"> & {
22
+ record: import("@anjianshi/utils/validators/factory.js").ValidatorForDefinition<T_1["record"]>;
23
+ } : T_1 : never : never>;
24
+ validateQuery<Definition extends Record<string, ValidatorDefinition>>(struct: Definition): import("@anjianshi/utils/validators/base.js").Validated<{
25
+ readonly type: "struct";
26
+ readonly struct: Definition;
27
+ } extends infer T ? T extends {
28
+ readonly type: "struct";
29
+ readonly struct: Definition;
30
+ } ? T extends import("@anjianshi/utils/validators/factory.js").StructDefinition ? { [Key in keyof T["struct"]]: import("@anjianshi/utils/validators/base.js").Validated<import("@anjianshi/utils/validators/factory.js").ValueOfDefinition<T["struct"][Key]>, T["struct"][Key]>; } : T extends import("@anjianshi/utils/validators/factory.js").RecordDefinition ? Record<string, import("@anjianshi/utils/validators/base.js").Validated<import("@anjianshi/utils/validators/factory.js").ValueOfDefinition<T["record"]>, T["record"]>> : never : never : never, {
31
+ readonly type: "struct";
32
+ readonly struct: Definition;
33
+ } extends infer T_1 ? T_1 extends {
34
+ readonly type: "struct";
35
+ readonly struct: Definition;
36
+ } ? T_1 extends import("@anjianshi/utils/validators/factory.js").StructDefinition ? Omit<T_1, "struct"> & {
37
+ struct: { [Key_1 in keyof T_1["struct"]]: import("@anjianshi/utils/validators/factory.js").ValidatorForDefinition<T_1["struct"][Key_1]>; };
38
+ } : T_1 extends import("@anjianshi/utils/validators/factory.js").RecordDefinition ? Omit<T_1, "record"> & {
39
+ record: import("@anjianshi/utils/validators/factory.js").ValidatorForDefinition<T_1["record"]>;
40
+ } : T_1 : never : never>;
41
+ validateBody<Definition extends Record<string, ValidatorDefinition>>(struct: Definition): Promise<import("@anjianshi/utils/validators/base.js").Validated<{
42
+ readonly type: "struct";
43
+ readonly struct: Definition;
44
+ } extends infer T ? T extends {
45
+ readonly type: "struct";
46
+ readonly struct: Definition;
47
+ } ? T extends import("@anjianshi/utils/validators/factory.js").StructDefinition ? { [Key in keyof T["struct"]]: import("@anjianshi/utils/validators/base.js").Validated<import("@anjianshi/utils/validators/factory.js").ValueOfDefinition<T["struct"][Key]>, T["struct"][Key]>; } : T extends import("@anjianshi/utils/validators/factory.js").RecordDefinition ? Record<string, import("@anjianshi/utils/validators/base.js").Validated<import("@anjianshi/utils/validators/factory.js").ValueOfDefinition<T["record"]>, T["record"]>> : never : never : never, {
48
+ readonly type: "struct";
49
+ readonly struct: Definition;
50
+ } extends infer T_1 ? T_1 extends {
51
+ readonly type: "struct";
52
+ readonly struct: Definition;
53
+ } ? T_1 extends import("@anjianshi/utils/validators/factory.js").StructDefinition ? Omit<T_1, "struct"> & {
54
+ struct: { [Key_1 in keyof T_1["struct"]]: import("@anjianshi/utils/validators/factory.js").ValidatorForDefinition<T_1["struct"][Key_1]>; };
55
+ } : T_1 extends import("@anjianshi/utils/validators/factory.js").RecordDefinition ? Omit<T_1, "record"> & {
56
+ record: import("@anjianshi/utils/validators/factory.js").ValidatorForDefinition<T_1["record"]>;
57
+ } : T_1 : never : never>>;
58
+ }
59
+ export declare class ResponseUtilsWithHelpers extends ResponseUtils {
60
+ constructor(response: ResponseUtils);
9
61
  success(data?: unknown): void;
10
62
  failed(message: string, code?: string | number): void;
11
63
  failed<T>(message: string, code: string | number | undefined, data: T): void;
@@ -1,19 +1,20 @@
1
1
  import { success, failed } from '@anjianshi/utils';
2
- import { validators } from '@anjianshi/utils/validators/index.js';
2
+ import { getValidator, } from '@anjianshi/utils/validators/index.js';
3
3
  import { HTTPError } from '../index.js';
4
+ import { ResponseUtils } from '../http/response.js';
4
5
  export class Helpers {
5
6
  context;
6
7
  constructor(context) {
7
8
  this.context = context;
8
9
  }
9
10
  validatePathParameters(struct) {
10
- const result = validators.struct(struct).validate('path', this.context.pathParameters);
11
+ const result = getValidator({ type: 'struct', struct })('path', this.context.pathParameters);
11
12
  if (result.success)
12
13
  return result.data;
13
14
  throw new HTTPError(400, result.message);
14
15
  }
15
16
  validateQuery(struct) {
16
- const result = validators.struct(struct).validate('query', this.context.request.query);
17
+ const result = getValidator({ type: 'struct', struct })('query', this.context.request.query);
17
18
  if (result.success)
18
19
  return result.data;
19
20
  throw new HTTPError(400, result.message);
@@ -22,15 +23,20 @@ export class Helpers {
22
23
  const body = await this.context.request.body.json();
23
24
  if (typeof body !== 'object' || body === null || Array.isArray(body))
24
25
  throw new HTTPError(400, 'Invalid JSON body, should be an object.');
25
- const result = validators.struct(struct).validate('body', body);
26
+ const result = getValidator({ type: 'struct', struct })('body', body);
26
27
  if (result.success)
27
28
  return result.data;
28
29
  throw new HTTPError(400, result.message);
29
30
  }
31
+ }
32
+ export class ResponseUtilsWithHelpers extends ResponseUtils {
33
+ constructor(response) {
34
+ super(response.nodeResponse, response.logger, response.jsonReplacer);
35
+ }
30
36
  success(data) {
31
- this.context.response.json(success(data));
37
+ this.json(success(data));
32
38
  }
33
39
  failed(message, code, data) {
34
- this.context.response.json(failed(message, code, data));
40
+ this.json(failed(message, code, data));
35
41
  }
36
42
  }
@@ -1,20 +1,17 @@
1
- import { validators } from '@anjianshi/utils/validators/index.js';
1
+ import { type OptionalFields } from '@anjianshi/utils';
2
2
  import { type CORSRule } from '../http/cors.js';
3
3
  import { type Request, type ResponseUtils } from '../http/index.js';
4
4
  import { Swagger, type Method } from '../swagger/index.js';
5
- import { Helpers } from './helpers.js';
5
+ import { Helpers, ResponseUtilsWithHelpers } from './helpers.js';
6
6
  import { type PathParameters } from './match-path.js';
7
7
  type HelpersInst = InstanceType<typeof Helpers>;
8
8
  export interface BasicContext {
9
9
  request: Request;
10
- response: ResponseUtils;
10
+ response: ResponseUtilsWithHelpers;
11
11
  pathParameters: PathParameters;
12
12
  validatePathParameters: HelpersInst['validatePathParameters'];
13
13
  validateQuery: HelpersInst['validateQuery'];
14
14
  validateBody: HelpersInst['validateBody'];
15
- validators: typeof validators;
16
- success: HelpersInst['success'];
17
- failed: HelpersInst['failed'];
18
15
  }
19
16
  /** 使用者可自行补充 Context 定义 */
20
17
  export interface Context extends BasicContext {
@@ -35,7 +32,7 @@ export declare class Router {
35
32
  * ----------------------
36
33
  */
37
34
  readonly routes: Route[];
38
- register(route: Route): void;
35
+ register(inputRoute: OptionalFields<Route, 'method'>): void;
39
36
  /**
40
37
  * ----------------------
41
38
  * 全局 CORS 配置
@@ -68,6 +65,6 @@ export declare class Router {
68
65
  * 请求处理
69
66
  * ----------------------
70
67
  */
71
- readonly handle: (request: Request, response: ResponseUtils) => Promise<void>;
68
+ readonly handle: (request: Request, originResponse: ResponseUtils) => Promise<void>;
72
69
  }
73
70
  export {};
@@ -1,9 +1,8 @@
1
1
  import { joinPath } from '@anjianshi/utils';
2
- import { validators } from '@anjianshi/utils/validators/index.js';
3
2
  import { getPreflightRequestMethod, handleCORS } from '../http/cors.js';
4
3
  import { HTTPError } from '../http/index.js';
5
4
  import { Swagger } from '../swagger/index.js';
6
- import { Helpers } from './helpers.js';
5
+ import { Helpers, ResponseUtilsWithHelpers } from './helpers.js';
7
6
  import { matchPath } from './match-path.js';
8
7
  export class Router {
9
8
  /**
@@ -12,7 +11,8 @@ export class Router {
12
11
  * ----------------------
13
12
  */
14
13
  routes = [];
15
- register(route) {
14
+ register(inputRoute) {
15
+ const route = { ...inputRoute, method: inputRoute.method ?? 'GET' };
16
16
  this.routes.push(route);
17
17
  this.registerRouteToSwagger(route);
18
18
  }
@@ -78,7 +78,8 @@ export class Router {
78
78
  * 请求处理
79
79
  * ----------------------
80
80
  */
81
- handle = async (request, response) => {
81
+ handle = async (request, originResponse) => {
82
+ const response = new ResponseUtilsWithHelpers(originResponse);
82
83
  const pathMatchedRoutes = matchPath(this.routes.map(route => route.path), request.path).map(result => ({ route: this.routes[result.index], parameters: result.parameters }));
83
84
  if (!pathMatchedRoutes.length)
84
85
  throw new HTTPError(404); // 没有路径匹配的路由
@@ -108,10 +109,9 @@ export class Router {
108
109
  validatePathParameters: helpers.validatePathParameters.bind(helpers),
109
110
  validateQuery: helpers.validateQuery.bind(helpers),
110
111
  validateBody: helpers.validateBody.bind(helpers),
111
- validators,
112
- success: helpers.success.bind(helpers),
113
- failed: helpers.failed.bind(helpers),
114
112
  });
115
- await this.executor(basicContext, matched.route);
113
+ const result = await this.executor(basicContext, matched.route);
114
+ if (result !== undefined)
115
+ throw new Error('route handler 不应该有返回值');
116
116
  };
117
117
  }
@@ -3,10 +3,10 @@ export interface MatchResult {
3
3
  pattern: string;
4
4
  parameters: PathParameters;
5
5
  }
6
- export type PathParameters = {
6
+ export interface PathParameters {
7
7
  [name: string]: string | undefined;
8
8
  '*'?: string;
9
- };
9
+ }
10
10
  /**
11
11
  * 返回与路径匹配的 pattern 及匹配得到的参数值
12
12
  */
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 把 @anjianshi/utils 包中 App 用得到的内导出来,这样用到时就不用分别引用 starlight-server 和 @anjianshi/utils 了
3
+ */
4
+ export { getValidator, type Definition as ValidatorDefinition } from '@anjianshi/utils/validators/index.js';
5
+ export * from '@anjianshi/utils/lang/may-success.js';
package/dist/utils.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 把 @anjianshi/utils 包中 App 用得到的内导出来,这样用到时就不用分别引用 starlight-server 和 @anjianshi/utils 了
3
+ */
4
+ export { getValidator } from '@anjianshi/utils/validators/index.js';
5
+ export * from '@anjianshi/utils/lang/may-success.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-server",
3
- "version": "1.6.7",
3
+ "version": "1.7.1",
4
4
  "description": "Simple But Powerful Node.js HTTP Server",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "main": "dist/index.js",
28
28
  "dependencies": {
29
- "@anjianshi/utils": "^2.1.1",
29
+ "@anjianshi/utils": "^2.2.2",
30
30
  "chalk": "^5.3.0",
31
31
  "dayjs": "^1.11.10",
32
32
  "debug": "^4.3.4",
@@ -34,10 +34,9 @@
34
34
  "swagger-ui-dist": "^5.15.1"
35
35
  },
36
36
  "devDependencies": {
37
- "@anjianshi/presets-eslint-node": "^4.0.3",
38
- "@anjianshi/presets-eslint-typescript": "^4.0.3",
39
- "@anjianshi/presets-prettier": "^3.0.0",
40
- "@anjianshi/presets-typescript": "^3.1.3",
37
+ "@anjianshi/presets-eslint-node": "^4.0.6",
38
+ "@anjianshi/presets-prettier": "^3.0.1",
39
+ "@anjianshi/presets-typescript": "^3.2.0",
41
40
  "@types/debug": "^4.1.9",
42
41
  "@types/lodash": "^4.14.199",
43
42
  "@types/node": "^20.8.6",
@@ -46,7 +45,7 @@
46
45
  "nodemon": "^3.0.2",
47
46
  "rimraf": "^5.0.5",
48
47
  "tsc-alias": "^1.8.8",
49
- "typescript": "^5.4.5"
48
+ "typescript": "^5.5.4"
50
49
  },
51
50
  "eslintIgnore": [],
52
51
  "prettier": "@anjianshi/presets-prettier/prettierrc",
package/src/index.ts CHANGED
@@ -2,4 +2,4 @@ export * from '@/logging.js'
2
2
  export * from '@/http/index.js'
3
3
  export * from '@/router/index.js'
4
4
  export * from '@/swagger/index.js'
5
- export { validators } from '@anjianshi/utils/validators/index.js'
5
+ export * from '@/utils.js'
@@ -1,40 +1,55 @@
1
1
  import { success, failed } from '@anjianshi/utils'
2
- import { type Validator, validators } from '@anjianshi/utils/validators/index.js'
2
+ import {
3
+ getValidator,
4
+ type Definition as ValidatorDefinition,
5
+ } from '@anjianshi/utils/validators/index.js'
3
6
  import { HTTPError } from '@/index.js'
4
7
  import { type BasicContext } from './index.js'
8
+ import { ResponseUtils } from '@/http/response.js'
5
9
 
6
10
  export class Helpers {
7
11
  constructor(readonly context: BasicContext) {}
8
12
 
9
- validatePathParameters<T>(struct: Record<string, Validator>) {
10
- const result = validators.struct(struct).validate('path', this.context.pathParameters)
11
- if (result.success) return result.data as T
13
+ validatePathParameters<Definition extends Record<string, ValidatorDefinition>>(
14
+ struct: Definition,
15
+ ) {
16
+ const result = getValidator({ type: 'struct', struct })(
17
+ 'path',
18
+ this.context.pathParameters as Record<string, string>,
19
+ )
20
+ if (result.success) return result.data
12
21
  throw new HTTPError(400, result.message)
13
22
  }
14
23
 
15
- validateQuery<T>(struct: Record<string, Validator>) {
16
- const result = validators.struct(struct).validate('query', this.context.request.query)
17
- if (result.success) return result.data as T
24
+ validateQuery<Definition extends Record<string, ValidatorDefinition>>(struct: Definition) {
25
+ const result = getValidator({ type: 'struct', struct })('query', this.context.request.query)
26
+ if (result.success) return result.data
18
27
  throw new HTTPError(400, result.message)
19
28
  }
20
29
 
21
- async validateBody<T>(struct: Record<string, Validator>) {
30
+ async validateBody<Definition extends Record<string, ValidatorDefinition>>(struct: Definition) {
22
31
  const body = await this.context.request.body.json()
23
32
  if (typeof body !== 'object' || body === null || Array.isArray(body))
24
33
  throw new HTTPError(400, 'Invalid JSON body, should be an object.')
25
34
 
26
- const result = validators.struct(struct).validate('body', body)
27
- if (result.success) return result.data as T
35
+ const result = getValidator({ type: 'struct', struct })('body', body as Record<string, string>)
36
+ if (result.success) return result.data
28
37
  throw new HTTPError(400, result.message)
29
38
  }
39
+ }
40
+
41
+ export class ResponseUtilsWithHelpers extends ResponseUtils {
42
+ constructor(response: ResponseUtils) {
43
+ super(response.nodeResponse, response.logger, response.jsonReplacer)
44
+ }
30
45
 
31
46
  success(data?: unknown) {
32
- this.context.response.json(success(data))
47
+ this.json(success(data))
33
48
  }
34
49
 
35
50
  failed(message: string, code?: string | number): void
36
51
  failed<T>(message: string, code: string | number | undefined, data: T): void
37
52
  failed<T>(message: string, code?: string | number, data?: T) {
38
- this.context.response.json(failed(message, code, data))
53
+ this.json(failed(message, code, data))
39
54
  }
40
55
  }
@@ -1,26 +1,22 @@
1
- import { joinPath } from '@anjianshi/utils'
2
- import { validators } from '@anjianshi/utils/validators/index.js'
1
+ import { type OptionalFields, joinPath } from '@anjianshi/utils'
3
2
  import { getPreflightRequestMethod, handleCORS, type CORSRule } from '@/http/cors.js'
4
3
  import { HTTPError, type Request, type ResponseUtils } from '@/http/index.js'
5
4
  import { Swagger, type Method } from '@/swagger/index.js'
6
- import { Helpers } from './helpers.js'
5
+ import { Helpers, ResponseUtilsWithHelpers } from './helpers.js'
7
6
  import { matchPath, type PathParameters } from './match-path.js'
8
7
 
9
8
  type HelpersInst = InstanceType<typeof Helpers>
10
9
  export interface BasicContext {
11
10
  request: Request
12
- response: ResponseUtils
11
+ response: ResponseUtilsWithHelpers
13
12
  pathParameters: PathParameters
14
13
  validatePathParameters: HelpersInst['validatePathParameters']
15
14
  validateQuery: HelpersInst['validateQuery']
16
15
  validateBody: HelpersInst['validateBody']
17
- validators: typeof validators
18
- success: HelpersInst['success']
19
- failed: HelpersInst['failed']
20
16
  }
21
17
 
22
18
  /** 使用者可自行补充 Context 定义 */
23
- export interface Context extends BasicContext {}
19
+ export interface Context extends BasicContext {} // eslint-disable-line @typescript-eslint/no-empty-object-type
24
20
 
25
21
  export interface Route {
26
22
  method: Method
@@ -40,7 +36,8 @@ export class Router {
40
36
  */
41
37
  readonly routes: Route[] = []
42
38
 
43
- register(route: Route) {
39
+ register(inputRoute: OptionalFields<Route, 'method'>) {
40
+ const route = { ...inputRoute, method: inputRoute.method ?? 'GET' }
44
41
  this.routes.push(route)
45
42
  this.registerRouteToSwagger(route)
46
43
  }
@@ -110,7 +107,9 @@ export class Router {
110
107
  * 请求处理
111
108
  * ----------------------
112
109
  */
113
- readonly handle = async (request: Request, response: ResponseUtils) => {
110
+ readonly handle = async (request: Request, originResponse: ResponseUtils) => {
111
+ const response = new ResponseUtilsWithHelpers(originResponse)
112
+
114
113
  const pathMatchedRoutes = matchPath(
115
114
  this.routes.map(route => route.path),
116
115
  request.path,
@@ -145,10 +144,9 @@ export class Router {
145
144
  validatePathParameters: helpers.validatePathParameters.bind(helpers),
146
145
  validateQuery: helpers.validateQuery.bind(helpers),
147
146
  validateBody: helpers.validateBody.bind(helpers),
148
- validators,
149
- success: helpers.success.bind(helpers),
150
- failed: helpers.failed.bind(helpers),
151
147
  })
152
- await this.executor(basicContext, matched.route)
148
+
149
+ const result = await (this.executor(basicContext, matched.route) as Promise<unknown>)
150
+ if (result !== undefined) throw new Error('route handler 不应该有返回值')
153
151
  }
154
152
  }
@@ -35,7 +35,7 @@ export interface MatchResult {
35
35
  }
36
36
 
37
37
  // 匹配得到的参数值
38
- export type PathParameters = {
38
+ export interface PathParameters {
39
39
  [name: string]: string | undefined
40
40
  '*'?: string
41
41
  }
package/src/utils.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 把 @anjianshi/utils 包中 App 用得到的内导出来,这样用到时就不用分别引用 starlight-server 和 @anjianshi/utils 了
3
+ */
4
+ export { getValidator, type Definition as ValidatorDefinition } from '@anjianshi/utils/validators/index.js'
5
+ export * from '@anjianshi/utils/lang/may-success.js'