starlight-server 1.5.0 → 1.6.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,15 +1,18 @@
1
+ import { type validators } from '@anjianshi/utils/validators/index.js';
1
2
  import { type CORSRule } from '../http/cors.js';
2
3
  import { type Request, type ResponseUtils } from '../http/index.js';
3
4
  import { Swagger, type Method } from '../swagger/index.js';
4
5
  import * as helpers from './helpers.js';
5
6
  import { type PathParameters } from './match-path.js';
7
+ type WithoutThis<T extends (...args: any[]) => unknown> = (...args: Parameters<T>) => ReturnType<T>;
6
8
  export interface BasicContext {
7
9
  request: Request;
8
10
  response: ResponseUtils;
9
11
  pathParameters: PathParameters;
10
- validatePathParameters: typeof helpers.validatePathParameters;
11
- validateQuery: typeof helpers.validateQuery;
12
- validateBody: typeof helpers.validateBody;
12
+ validatePathParameters: WithoutThis<typeof helpers.validatePathParameters>;
13
+ validateQuery: WithoutThis<typeof helpers.validateQuery>;
14
+ validateBody: WithoutThis<typeof helpers.validateBody>;
15
+ validators: typeof validators;
13
16
  }
14
17
  /** 使用者可自行补充 Context 定义 */
15
18
  export interface Context extends BasicContext {
@@ -65,3 +68,4 @@ export declare class Router {
65
68
  */
66
69
  readonly handle: (request: Request, response: ResponseUtils) => Promise<void>;
67
70
  }
71
+ export {};
@@ -99,6 +99,7 @@ export class Router {
99
99
  request,
100
100
  response,
101
101
  pathParameters: matched.parameters,
102
+ validatePathParameters: helpers.validatePathParameters.bind(basicContext),
102
103
  validateQuery: helpers.validateQuery.bind(basicContext),
103
104
  validateBody: helpers.validateBody.bind(basicContext),
104
105
  });
@@ -22,7 +22,10 @@ export function makeOperation(options = {}) {
22
22
  ? query
23
23
  : query
24
24
  ? Object.entries(query).reduce((result, [name, options]) => {
25
- const query = makeQuery({ name, ...('schema' in options ? options : { schema: options }) });
25
+ const query = makeQuery({
26
+ name,
27
+ ...('schema' in options ? options : { schema: options }),
28
+ });
26
29
  return [...result, query];
27
30
  }, [])
28
31
  : undefined;
package/package.json CHANGED
@@ -1,13 +1,8 @@
1
1
  {
2
2
  "name": "starlight-server",
3
- "version": "1.5.0",
3
+ "version": "1.6.2",
4
4
  "description": "Simple But Powerful Node.js HTTP Server",
5
5
  "type": "module",
6
- "scripts": {
7
- "dev": "rimraf dist && (concurrently --raw \"tsc -w\" \"sleep 5 && tsc-alias -w\" \"sleep 6 && nodemon dist/demo/index.js\")",
8
- "build": "rimraf dist && tsc && tsc-alias",
9
- "prepublishOnly": "npm run build"
10
- },
11
6
  "keywords": [
12
7
  "web",
13
8
  "app",
@@ -29,26 +24,35 @@
29
24
  "publishConfig": {
30
25
  "registry": "https://registry.npmjs.org/"
31
26
  },
27
+ "main": "dist/index.js",
32
28
  "dependencies": {
33
- "@anjianshi/utils": "^1.3.1",
29
+ "@anjianshi/utils": "^2.0.7",
34
30
  "chalk": "^5.3.0",
31
+ "dayjs": "^1.11.10",
35
32
  "debug": "^4.3.4",
36
- "swagger-ui-dist": "^5.11.10"
33
+ "lodash": "^4.17.21",
34
+ "swagger-ui-dist": "^5.15.1"
37
35
  },
38
36
  "devDependencies": {
39
- "@anjianshi/presets-eslint-node": "^1.0.3",
40
- "@anjianshi/presets-eslint-typescript": "^1.0.3",
41
- "@anjianshi/presets-prettier": "^1.0.0",
42
- "@anjianshi/presets-typescript": "^1.0.1",
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",
43
41
  "@types/debug": "^4.1.9",
44
42
  "@types/lodash": "^4.14.199",
45
43
  "@types/node": "^20.8.6",
46
44
  "@types/swagger-ui-dist": "^3.30.4",
47
45
  "concurrently": "^8.2.1",
48
46
  "nodemon": "^3.0.2",
49
- "rimraf": "^4.3.0",
50
- "tsc-alias": "^1.8.8"
47
+ "rimraf": "^5.0.5",
48
+ "tsc-alias": "^1.8.8",
49
+ "typescript": "^5.4.5"
51
50
  },
52
51
  "eslintIgnore": [],
53
- "prettier": "@anjianshi/presets-prettier/prettierrc"
54
- }
52
+ "prettier": "@anjianshi/presets-prettier/prettierrc",
53
+ "scripts": {
54
+ "dev": "rimraf dist && (concurrently --raw \"tsc-with-alias --watch\" \"nodemon dist/demo/index.js\")",
55
+ "build": "rimraf dist && tsc-with-alias",
56
+ "lint": "tsc --noEmit && eslint './src/**/*'"
57
+ }
58
+ }
package/src/demo/index.ts CHANGED
@@ -31,7 +31,7 @@ swagger.registerResponse(
31
31
  'hello',
32
32
  swagger.response({
33
33
  hello: swagger.string(),
34
- })
34
+ }),
35
35
  )
36
36
 
37
37
  router.register({
@@ -1,17 +1,20 @@
1
1
  import { joinPath } from '@anjianshi/utils'
2
+ import { type validators } from '@anjianshi/utils/validators/index.js'
2
3
  import { getPreflightRequestMethod, handleCORS, type CORSRule } from '@/http/cors.js'
3
4
  import { HTTPError, type Request, type ResponseUtils } from '@/http/index.js'
4
5
  import { Swagger, type Method } from '@/swagger/index.js'
5
6
  import * as helpers from './helpers.js'
6
7
  import { matchPath, type PathParameters } from './match-path.js'
7
8
 
9
+ type WithoutThis<T extends (...args: any[]) => unknown> = (...args: Parameters<T>) => ReturnType<T>
8
10
  export interface BasicContext {
9
11
  request: Request
10
12
  response: ResponseUtils
11
13
  pathParameters: PathParameters
12
- validatePathParameters: typeof helpers.validatePathParameters
13
- validateQuery: typeof helpers.validateQuery
14
- validateBody: typeof helpers.validateBody
14
+ validatePathParameters: WithoutThis<typeof helpers.validatePathParameters>
15
+ validateQuery: WithoutThis<typeof helpers.validateQuery>
16
+ validateBody: WithoutThis<typeof helpers.validateBody>
17
+ validators: typeof validators
15
18
  }
16
19
 
17
20
  /** 使用者可自行补充 Context 定义 */
@@ -108,7 +111,7 @@ export class Router {
108
111
  readonly handle = async (request: Request, response: ResponseUtils) => {
109
112
  const pathMatchedRoutes = matchPath(
110
113
  this.routes.map(route => route.path),
111
- request.path
114
+ request.path,
112
115
  ).map(result => ({ route: this.routes[result.index]!, parameters: result.parameters }))
113
116
  if (!pathMatchedRoutes.length) throw new HTTPError(404) // 没有路径匹配的路由
114
117
 
@@ -117,7 +120,7 @@ export class Router {
117
120
  if (!matched) {
118
121
  const preflightTargetMethod = getPreflightRequestMethod(request) // 对于 CORS Preflight 请求,此为客户端原本希望请求的 method
119
122
  const preflightMatched = pathMatchedRoutes.find(
120
- match => match.route.method === preflightTargetMethod
123
+ match => match.route.method === preflightTargetMethod,
121
124
  )
122
125
  if (preflightMatched) {
123
126
  const corsRule = preflightMatched.route.cors ?? this.cors
@@ -133,6 +136,7 @@ export class Router {
133
136
  request,
134
137
  response,
135
138
  pathParameters: matched.parameters,
139
+ validatePathParameters: helpers.validatePathParameters.bind(basicContext),
136
140
  validateQuery: helpers.validateQuery.bind(basicContext),
137
141
  validateBody: helpers.validateBody.bind(basicContext),
138
142
  })
@@ -13,7 +13,6 @@ import type {
13
13
  Reference,
14
14
  Parameter,
15
15
  RequestBody,
16
- Components,
17
16
  } from './specification.js'
18
17
 
19
18
  type SchemaOrRef = Schema | Reference
@@ -45,11 +44,14 @@ export function makeOperation(options: OperationOptions = {}): Operation {
45
44
  const parameters = Array.isArray(query)
46
45
  ? query
47
46
  : query
48
- ? Object.entries(query).reduce<Parameter[]>((result, [name, options]) => {
49
- const query = makeQuery({ name, ...('schema' in options ? options : { schema: options }) })
50
- return [...result, query]
51
- }, [])
52
- : undefined
47
+ ? Object.entries(query).reduce<Parameter[]>((result, [name, options]) => {
48
+ const query = makeQuery({
49
+ name,
50
+ ...('schema' in options ? options : { schema: options }),
51
+ })
52
+ return [...result, query]
53
+ }, [])
54
+ : undefined
53
55
  const requestBody = body ? ('$ref' in body ? (body as Reference) : makeBody(body)) : undefined
54
56
  const responses = response
55
57
  ? '$ref' in response
@@ -79,7 +81,7 @@ export function isOperationOptions(value: unknown): value is OperationOptions {
79
81
  if (typeof value !== 'object' || value === null) return false
80
82
  return (
81
83
  ['category', 'query', 'body', 'response'].find(key =>
82
- truthy((value as Record<string, unknown>)[key])
84
+ truthy((value as Record<string, unknown>)[key]),
83
85
  ) !== undefined
84
86
  )
85
87
  }
@@ -116,7 +118,7 @@ export function makeHeader(options: ParameterOptions): Parameter {
116
118
  */
117
119
  export function makeBody(
118
120
  input: Record<string, SchemaOrRef> | ObjectOptions | Schema,
119
- description?: string
121
+ description?: string,
120
122
  ): RequestBody {
121
123
  return {
122
124
  description,
@@ -152,7 +154,7 @@ export function makeResponsesBy(response: Response | Reference): Responses {
152
154
  /** 生成 Response 定义 */
153
155
  export function makeResponse(
154
156
  schema: Schema | Record<string, SchemaOrRef>,
155
- description?: string
157
+ description?: string,
156
158
  ): Response {
157
159
  return {
158
160
  description,
@@ -175,7 +177,7 @@ export function isSchema(value: unknown): value is Schema {
175
177
  if (typeof value !== 'object' || value === null) return false
176
178
  return (
177
179
  ['type', 'allOf', 'anyOf', 'oneOf', 'not'].find(key =>
178
- truthy((value as Record<string, unknown>)[key])
180
+ truthy((value as Record<string, unknown>)[key]),
179
181
  ) !== undefined
180
182
  )
181
183
  }