starlight-server 1.7.1 → 1.7.2

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,9 +1,11 @@
1
1
  import { type Definition as ValidatorDefinition } from '@anjianshi/utils/validators/index.js';
2
- import { type BasicContext } from './index.js';
3
- import { ResponseUtils } from '../http/response.js';
4
- export declare class Helpers {
5
- readonly context: BasicContext;
6
- constructor(context: BasicContext);
2
+ import { type Request } from '../http/request.js';
3
+ import { type ResponseUtils } from '../http/response.js';
4
+ import { type PathParameters } from './match-path.js';
5
+ declare class RequestHelpers {
6
+ readonly request: Request;
7
+ readonly pathParameters: PathParameters;
8
+ constructor(request: Request, pathParameters: PathParameters);
7
9
  validatePathParameters<Definition extends Record<string, ValidatorDefinition>>(struct: Definition): import("@anjianshi/utils/validators/base.js").Validated<{
8
10
  readonly type: "struct";
9
11
  readonly struct: Definition;
@@ -56,9 +58,15 @@ export declare class Helpers {
56
58
  record: import("@anjianshi/utils/validators/factory.js").ValidatorForDefinition<T_1["record"]>;
57
59
  } : T_1 : never : never>>;
58
60
  }
59
- export declare class ResponseUtilsWithHelpers extends ResponseUtils {
61
+ export type RequestWithHelpers = Request & RequestHelpers;
62
+ export declare function getRequestWithHelpers(request: Request, pathParameters: PathParameters): RequestWithHelpers;
63
+ declare class ResponseUtilsHelpers {
64
+ readonly response: ResponseUtils;
60
65
  constructor(response: ResponseUtils);
61
66
  success(data?: unknown): void;
62
67
  failed(message: string, code?: string | number): void;
63
68
  failed<T>(message: string, code: string | number | undefined, data: T): void;
64
69
  }
70
+ export type ResponseUtilsWithHelpers = ResponseUtils & ResponseUtilsHelpers;
71
+ export declare function getResponseUtilsWithHelpers(response: ResponseUtils): ResponseUtilsWithHelpers;
72
+ export {};
@@ -1,26 +1,27 @@
1
1
  import { success, failed } from '@anjianshi/utils';
2
2
  import { getValidator, } from '@anjianshi/utils/validators/index.js';
3
3
  import { HTTPError } from '../index.js';
4
- import { ResponseUtils } from '../http/response.js';
5
- export class Helpers {
6
- context;
7
- constructor(context) {
8
- this.context = context;
4
+ class RequestHelpers {
5
+ request;
6
+ pathParameters;
7
+ constructor(request, pathParameters) {
8
+ this.request = request;
9
+ this.pathParameters = pathParameters;
9
10
  }
10
11
  validatePathParameters(struct) {
11
- const result = getValidator({ type: 'struct', struct })('path', this.context.pathParameters);
12
+ const result = getValidator({ type: 'struct', struct })('path', this.pathParameters);
12
13
  if (result.success)
13
14
  return result.data;
14
15
  throw new HTTPError(400, result.message);
15
16
  }
16
17
  validateQuery(struct) {
17
- const result = getValidator({ type: 'struct', struct })('query', this.context.request.query);
18
+ const result = getValidator({ type: 'struct', struct })('query', this.request.query);
18
19
  if (result.success)
19
20
  return result.data;
20
21
  throw new HTTPError(400, result.message);
21
22
  }
22
23
  async validateBody(struct) {
23
- const body = await this.context.request.body.json();
24
+ const body = await this.request.body.json();
24
25
  if (typeof body !== 'object' || body === null || Array.isArray(body))
25
26
  throw new HTTPError(400, 'Invalid JSON body, should be an object.');
26
27
  const result = getValidator({ type: 'struct', struct })('body', body);
@@ -29,14 +30,36 @@ export class Helpers {
29
30
  throw new HTTPError(400, result.message);
30
31
  }
31
32
  }
32
- export class ResponseUtilsWithHelpers extends ResponseUtils {
33
+ export function getRequestWithHelpers(request, pathParameters) {
34
+ const helpers = new RequestHelpers(request, pathParameters);
35
+ return new Proxy(request, {
36
+ get(target, prop) {
37
+ if (prop in helpers)
38
+ return helpers[prop];
39
+ return request[prop];
40
+ },
41
+ });
42
+ }
43
+ // -----------------------------
44
+ class ResponseUtilsHelpers {
45
+ response;
33
46
  constructor(response) {
34
- super(response.nodeResponse, response.logger, response.jsonReplacer);
47
+ this.response = response;
35
48
  }
36
49
  success(data) {
37
- this.json(success(data));
50
+ this.response.json(success(data));
38
51
  }
39
52
  failed(message, code, data) {
40
- this.json(failed(message, code, data));
53
+ this.response.json(failed(message, code, data));
41
54
  }
42
55
  }
56
+ export function getResponseUtilsWithHelpers(response) {
57
+ const helpers = new ResponseUtilsHelpers(response);
58
+ return new Proxy(response, {
59
+ get(target, prop) {
60
+ if (prop in helpers)
61
+ return helpers[prop];
62
+ return response[prop];
63
+ },
64
+ });
65
+ }
@@ -2,16 +2,12 @@ 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, ResponseUtilsWithHelpers } from './helpers.js';
5
+ import { type RequestWithHelpers, type ResponseUtilsWithHelpers } from './helpers.js';
6
6
  import { type PathParameters } from './match-path.js';
7
- type HelpersInst = InstanceType<typeof Helpers>;
8
7
  export interface BasicContext {
9
- request: Request;
10
- response: ResponseUtilsWithHelpers;
11
8
  pathParameters: PathParameters;
12
- validatePathParameters: HelpersInst['validatePathParameters'];
13
- validateQuery: HelpersInst['validateQuery'];
14
- validateBody: HelpersInst['validateBody'];
9
+ request: RequestWithHelpers;
10
+ response: ResponseUtilsWithHelpers;
15
11
  }
16
12
  /** 使用者可自行补充 Context 定义 */
17
13
  export interface Context extends BasicContext {
@@ -65,6 +61,5 @@ export declare class Router {
65
61
  * 请求处理
66
62
  * ----------------------
67
63
  */
68
- readonly handle: (request: Request, originResponse: ResponseUtils) => Promise<void>;
64
+ readonly handle: (request: Request, response: ResponseUtils) => Promise<void>;
69
65
  }
70
- export {};
@@ -2,7 +2,7 @@ import { joinPath } from '@anjianshi/utils';
2
2
  import { getPreflightRequestMethod, handleCORS } from '../http/cors.js';
3
3
  import { HTTPError } from '../http/index.js';
4
4
  import { Swagger } from '../swagger/index.js';
5
- import { Helpers, ResponseUtilsWithHelpers } from './helpers.js';
5
+ import { getRequestWithHelpers, getResponseUtilsWithHelpers, } from './helpers.js';
6
6
  import { matchPath } from './match-path.js';
7
7
  export class Router {
8
8
  /**
@@ -78,8 +78,7 @@ export class Router {
78
78
  * 请求处理
79
79
  * ----------------------
80
80
  */
81
- handle = async (request, originResponse) => {
82
- const response = new ResponseUtilsWithHelpers(originResponse);
81
+ handle = async (request, response) => {
83
82
  const pathMatchedRoutes = matchPath(this.routes.map(route => route.path), request.path).map(result => ({ route: this.routes[result.index], parameters: result.parameters }));
84
83
  if (!pathMatchedRoutes.length)
85
84
  throw new HTTPError(404); // 没有路径匹配的路由
@@ -100,15 +99,12 @@ export class Router {
100
99
  const corsRule = matched.route.cors ?? this.cors;
101
100
  handleCORS(request, response, typeof corsRule === 'function' ? corsRule(request) : corsRule);
102
101
  }
102
+ const requestWithHelpers = getRequestWithHelpers(request, matched.parameters);
103
+ const responseWithHelpers = getResponseUtilsWithHelpers(response);
103
104
  const basicContext = {};
104
- const helpers = new Helpers(basicContext);
105
105
  Object.assign(basicContext, {
106
- request,
107
- response,
108
- pathParameters: matched.parameters,
109
- validatePathParameters: helpers.validatePathParameters.bind(helpers),
110
- validateQuery: helpers.validateQuery.bind(helpers),
111
- validateBody: helpers.validateBody.bind(helpers),
106
+ request: requestWithHelpers,
107
+ response: responseWithHelpers,
112
108
  });
113
109
  const result = await this.executor(basicContext, matched.route);
114
110
  if (result !== undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-server",
3
- "version": "1.7.1",
3
+ "version": "1.7.2",
4
4
  "description": "Simple But Powerful Node.js HTTP Server",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -4,31 +4,35 @@ import {
4
4
  type Definition as ValidatorDefinition,
5
5
  } from '@anjianshi/utils/validators/index.js'
6
6
  import { HTTPError } from '@/index.js'
7
- import { type BasicContext } from './index.js'
8
- import { ResponseUtils } from '@/http/response.js'
7
+ import { type Request } from '@/http/request.js'
8
+ import { type ResponseUtils } from '@/http/response.js'
9
+ import { type PathParameters } from './match-path.js'
9
10
 
10
- export class Helpers {
11
- constructor(readonly context: BasicContext) {}
11
+ class RequestHelpers {
12
+ constructor(
13
+ readonly request: Request,
14
+ readonly pathParameters: PathParameters,
15
+ ) {}
12
16
 
13
17
  validatePathParameters<Definition extends Record<string, ValidatorDefinition>>(
14
18
  struct: Definition,
15
19
  ) {
16
20
  const result = getValidator({ type: 'struct', struct })(
17
21
  'path',
18
- this.context.pathParameters as Record<string, string>,
22
+ this.pathParameters as Record<string, string>,
19
23
  )
20
24
  if (result.success) return result.data
21
25
  throw new HTTPError(400, result.message)
22
26
  }
23
27
 
24
28
  validateQuery<Definition extends Record<string, ValidatorDefinition>>(struct: Definition) {
25
- const result = getValidator({ type: 'struct', struct })('query', this.context.request.query)
29
+ const result = getValidator({ type: 'struct', struct })('query', this.request.query)
26
30
  if (result.success) return result.data
27
31
  throw new HTTPError(400, result.message)
28
32
  }
29
33
 
30
34
  async validateBody<Definition extends Record<string, ValidatorDefinition>>(struct: Definition) {
31
- const body = await this.context.request.body.json()
35
+ const body = await this.request.body.json()
32
36
  if (typeof body !== 'object' || body === null || Array.isArray(body))
33
37
  throw new HTTPError(400, 'Invalid JSON body, should be an object.')
34
38
 
@@ -38,18 +42,42 @@ export class Helpers {
38
42
  }
39
43
  }
40
44
 
41
- export class ResponseUtilsWithHelpers extends ResponseUtils {
42
- constructor(response: ResponseUtils) {
43
- super(response.nodeResponse, response.logger, response.jsonReplacer)
44
- }
45
+ export type RequestWithHelpers = Request & RequestHelpers
46
+
47
+ export function getRequestWithHelpers(request: Request, pathParameters: PathParameters) {
48
+ const helpers = new RequestHelpers(request, pathParameters)
49
+ return new Proxy(request, {
50
+ get(target, prop): unknown {
51
+ if (prop in helpers) return helpers[prop as keyof RequestHelpers]
52
+ return request[prop as keyof Request]
53
+ },
54
+ }) as RequestWithHelpers
55
+ }
56
+
57
+ // -----------------------------
58
+
59
+ class ResponseUtilsHelpers {
60
+ constructor(readonly response: ResponseUtils) {}
45
61
 
46
62
  success(data?: unknown) {
47
- this.json(success(data))
63
+ this.response.json(success(data))
48
64
  }
49
65
 
50
66
  failed(message: string, code?: string | number): void
51
67
  failed<T>(message: string, code: string | number | undefined, data: T): void
52
68
  failed<T>(message: string, code?: string | number, data?: T) {
53
- this.json(failed(message, code, data))
69
+ this.response.json(failed(message, code, data))
54
70
  }
55
71
  }
72
+
73
+ export type ResponseUtilsWithHelpers = ResponseUtils & ResponseUtilsHelpers
74
+
75
+ export function getResponseUtilsWithHelpers(response: ResponseUtils) {
76
+ const helpers = new ResponseUtilsHelpers(response)
77
+ return new Proxy(response, {
78
+ get(target, prop) {
79
+ if (prop in helpers) return helpers[prop as keyof ResponseUtilsHelpers]
80
+ return response[prop as keyof ResponseUtils]
81
+ },
82
+ }) as ResponseUtilsWithHelpers
83
+ }
@@ -2,17 +2,18 @@ import { type OptionalFields, joinPath } from '@anjianshi/utils'
2
2
  import { getPreflightRequestMethod, handleCORS, type CORSRule } from '@/http/cors.js'
3
3
  import { HTTPError, type Request, type ResponseUtils } from '@/http/index.js'
4
4
  import { Swagger, type Method } from '@/swagger/index.js'
5
- import { Helpers, ResponseUtilsWithHelpers } from './helpers.js'
5
+ import {
6
+ getRequestWithHelpers,
7
+ getResponseUtilsWithHelpers,
8
+ type RequestWithHelpers,
9
+ type ResponseUtilsWithHelpers,
10
+ } from './helpers.js'
6
11
  import { matchPath, type PathParameters } from './match-path.js'
7
12
 
8
- type HelpersInst = InstanceType<typeof Helpers>
9
13
  export interface BasicContext {
10
- request: Request
11
- response: ResponseUtilsWithHelpers
12
14
  pathParameters: PathParameters
13
- validatePathParameters: HelpersInst['validatePathParameters']
14
- validateQuery: HelpersInst['validateQuery']
15
- validateBody: HelpersInst['validateBody']
15
+ request: RequestWithHelpers
16
+ response: ResponseUtilsWithHelpers
16
17
  }
17
18
 
18
19
  /** 使用者可自行补充 Context 定义 */
@@ -107,9 +108,7 @@ export class Router {
107
108
  * 请求处理
108
109
  * ----------------------
109
110
  */
110
- readonly handle = async (request: Request, originResponse: ResponseUtils) => {
111
- const response = new ResponseUtilsWithHelpers(originResponse)
112
-
111
+ readonly handle = async (request: Request, response: ResponseUtils) => {
113
112
  const pathMatchedRoutes = matchPath(
114
113
  this.routes.map(route => route.path),
115
114
  request.path,
@@ -135,15 +134,13 @@ export class Router {
135
134
  handleCORS(request, response, typeof corsRule === 'function' ? corsRule(request) : corsRule)
136
135
  }
137
136
 
137
+ const requestWithHelpers = getRequestWithHelpers(request, matched.parameters)
138
+ const responseWithHelpers = getResponseUtilsWithHelpers(response)
139
+
138
140
  const basicContext = {} as BasicContext
139
- const helpers = new Helpers(basicContext)
140
141
  Object.assign(basicContext, {
141
- request,
142
- response,
143
- pathParameters: matched.parameters,
144
- validatePathParameters: helpers.validatePathParameters.bind(helpers),
145
- validateQuery: helpers.validateQuery.bind(helpers),
146
- validateBody: helpers.validateBody.bind(helpers),
142
+ request: requestWithHelpers,
143
+ response: responseWithHelpers,
147
144
  })
148
145
 
149
146
  const result = await (this.executor(basicContext, matched.route) as Promise<unknown>)