starlight-server 1.7.0 → 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,8 +1,11 @@
1
1
  import { type Definition as ValidatorDefinition } from '@anjianshi/utils/validators/index.js';
2
- import { type BasicContext } from './index.js';
3
- export declare class Helpers {
4
- readonly context: BasicContext;
5
- 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);
6
9
  validatePathParameters<Definition extends Record<string, ValidatorDefinition>>(struct: Definition): import("@anjianshi/utils/validators/base.js").Validated<{
7
10
  readonly type: "struct";
8
11
  readonly struct: Definition;
@@ -54,7 +57,16 @@ export declare class Helpers {
54
57
  } : T_1 extends import("@anjianshi/utils/validators/factory.js").RecordDefinition ? Omit<T_1, "record"> & {
55
58
  record: import("@anjianshi/utils/validators/factory.js").ValidatorForDefinition<T_1["record"]>;
56
59
  } : T_1 : never : never>>;
60
+ }
61
+ export type RequestWithHelpers = Request & RequestHelpers;
62
+ export declare function getRequestWithHelpers(request: Request, pathParameters: PathParameters): RequestWithHelpers;
63
+ declare class ResponseUtilsHelpers {
64
+ readonly response: ResponseUtils;
65
+ constructor(response: ResponseUtils);
57
66
  success(data?: unknown): void;
58
67
  failed(message: string, code?: string | number): void;
59
68
  failed<T>(message: string, code: string | number | undefined, data: T): void;
60
69
  }
70
+ export type ResponseUtilsWithHelpers = ResponseUtils & ResponseUtilsHelpers;
71
+ export declare function getResponseUtilsWithHelpers(response: ResponseUtils): ResponseUtilsWithHelpers;
72
+ export {};
@@ -1,25 +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
- export class Helpers {
5
- context;
6
- constructor(context) {
7
- this.context = context;
4
+ class RequestHelpers {
5
+ request;
6
+ pathParameters;
7
+ constructor(request, pathParameters) {
8
+ this.request = request;
9
+ this.pathParameters = pathParameters;
8
10
  }
9
11
  validatePathParameters(struct) {
10
- const result = getValidator({ type: 'struct', struct })('path', this.context.pathParameters);
12
+ const result = getValidator({ type: 'struct', struct })('path', this.pathParameters);
11
13
  if (result.success)
12
14
  return result.data;
13
15
  throw new HTTPError(400, result.message);
14
16
  }
15
17
  validateQuery(struct) {
16
- const result = getValidator({ type: 'struct', struct })('query', this.context.request.query);
18
+ const result = getValidator({ type: 'struct', struct })('query', this.request.query);
17
19
  if (result.success)
18
20
  return result.data;
19
21
  throw new HTTPError(400, result.message);
20
22
  }
21
23
  async validateBody(struct) {
22
- const body = await this.context.request.body.json();
24
+ const body = await this.request.body.json();
23
25
  if (typeof body !== 'object' || body === null || Array.isArray(body))
24
26
  throw new HTTPError(400, 'Invalid JSON body, should be an object.');
25
27
  const result = getValidator({ type: 'struct', struct })('body', body);
@@ -27,10 +29,37 @@ export class Helpers {
27
29
  return result.data;
28
30
  throw new HTTPError(400, result.message);
29
31
  }
32
+ }
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;
46
+ constructor(response) {
47
+ this.response = response;
48
+ }
30
49
  success(data) {
31
- this.context.response.json(success(data));
50
+ this.response.json(success(data));
32
51
  }
33
52
  failed(message, code, data) {
34
- this.context.response.json(failed(message, code, data));
53
+ this.response.json(failed(message, code, data));
35
54
  }
36
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,18 +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 } 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: ResponseUtils;
11
8
  pathParameters: PathParameters;
12
- validatePathParameters: HelpersInst['validatePathParameters'];
13
- validateQuery: HelpersInst['validateQuery'];
14
- validateBody: HelpersInst['validateBody'];
15
- success: HelpersInst['success'];
16
- failed: HelpersInst['failed'];
9
+ request: RequestWithHelpers;
10
+ response: ResponseUtilsWithHelpers;
17
11
  }
18
12
  /** 使用者可自行补充 Context 定义 */
19
13
  export interface Context extends BasicContext {
@@ -69,4 +63,3 @@ export declare class Router {
69
63
  */
70
64
  readonly handle: (request: Request, response: ResponseUtils) => Promise<void>;
71
65
  }
72
- 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 } 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
  /**
@@ -99,17 +99,12 @@ export class Router {
99
99
  const corsRule = matched.route.cors ?? this.cors;
100
100
  handleCORS(request, response, typeof corsRule === 'function' ? corsRule(request) : corsRule);
101
101
  }
102
+ const requestWithHelpers = getRequestWithHelpers(request, matched.parameters);
103
+ const responseWithHelpers = getResponseUtilsWithHelpers(response);
102
104
  const basicContext = {};
103
- const helpers = new Helpers(basicContext);
104
105
  Object.assign(basicContext, {
105
- request,
106
- response,
107
- pathParameters: matched.parameters,
108
- validatePathParameters: helpers.validatePathParameters.bind(helpers),
109
- validateQuery: helpers.validateQuery.bind(helpers),
110
- validateBody: helpers.validateBody.bind(helpers),
111
- success: helpers.success.bind(helpers),
112
- failed: helpers.failed.bind(helpers),
106
+ request: requestWithHelpers,
107
+ response: responseWithHelpers,
113
108
  });
114
109
  const result = await this.executor(basicContext, matched.route);
115
110
  if (result !== undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-server",
3
- "version": "1.7.0",
3
+ "version": "1.7.2",
4
4
  "description": "Simple But Powerful Node.js HTTP Server",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -4,30 +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'
7
+ import { type Request } from '@/http/request.js'
8
+ import { type ResponseUtils } from '@/http/response.js'
9
+ import { type PathParameters } from './match-path.js'
8
10
 
9
- export class Helpers {
10
- constructor(readonly context: BasicContext) {}
11
+ class RequestHelpers {
12
+ constructor(
13
+ readonly request: Request,
14
+ readonly pathParameters: PathParameters,
15
+ ) {}
11
16
 
12
17
  validatePathParameters<Definition extends Record<string, ValidatorDefinition>>(
13
18
  struct: Definition,
14
19
  ) {
15
20
  const result = getValidator({ type: 'struct', struct })(
16
21
  'path',
17
- this.context.pathParameters as Record<string, string>,
22
+ this.pathParameters as Record<string, string>,
18
23
  )
19
24
  if (result.success) return result.data
20
25
  throw new HTTPError(400, result.message)
21
26
  }
22
27
 
23
28
  validateQuery<Definition extends Record<string, ValidatorDefinition>>(struct: Definition) {
24
- const result = getValidator({ type: 'struct', struct })('query', this.context.request.query)
29
+ const result = getValidator({ type: 'struct', struct })('query', this.request.query)
25
30
  if (result.success) return result.data
26
31
  throw new HTTPError(400, result.message)
27
32
  }
28
33
 
29
34
  async validateBody<Definition extends Record<string, ValidatorDefinition>>(struct: Definition) {
30
- const body = await this.context.request.body.json()
35
+ const body = await this.request.body.json()
31
36
  if (typeof body !== 'object' || body === null || Array.isArray(body))
32
37
  throw new HTTPError(400, 'Invalid JSON body, should be an object.')
33
38
 
@@ -35,14 +40,44 @@ export class Helpers {
35
40
  if (result.success) return result.data
36
41
  throw new HTTPError(400, result.message)
37
42
  }
43
+ }
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) {}
38
61
 
39
62
  success(data?: unknown) {
40
- this.context.response.json(success(data))
63
+ this.response.json(success(data))
41
64
  }
42
65
 
43
66
  failed(message: string, code?: string | number): void
44
67
  failed<T>(message: string, code: string | number | undefined, data: T): void
45
68
  failed<T>(message: string, code?: string | number, data?: T) {
46
- this.context.response.json(failed(message, code, data))
69
+ this.response.json(failed(message, code, data))
47
70
  }
48
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,19 +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 } 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: ResponseUtils
12
14
  pathParameters: PathParameters
13
- validatePathParameters: HelpersInst['validatePathParameters']
14
- validateQuery: HelpersInst['validateQuery']
15
- validateBody: HelpersInst['validateBody']
16
- success: HelpersInst['success']
17
- failed: HelpersInst['failed']
15
+ request: RequestWithHelpers
16
+ response: ResponseUtilsWithHelpers
18
17
  }
19
18
 
20
19
  /** 使用者可自行补充 Context 定义 */
@@ -135,17 +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),
147
- success: helpers.success.bind(helpers),
148
- failed: helpers.failed.bind(helpers),
142
+ request: requestWithHelpers,
143
+ response: responseWithHelpers,
149
144
  })
150
145
 
151
146
  const result = await (this.executor(basicContext, matched.route) as Promise<unknown>)