vector-framework 1.2.2 → 1.2.3

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.
Files changed (189) hide show
  1. package/README.md +18 -6
  2. package/dist/auth/protected.d.ts +4 -4
  3. package/dist/auth/protected.d.ts.map +1 -1
  4. package/dist/auth/protected.js +10 -7
  5. package/dist/auth/protected.js.map +1 -1
  6. package/dist/cache/manager.d.ts +2 -0
  7. package/dist/cache/manager.d.ts.map +1 -1
  8. package/dist/cache/manager.js +21 -4
  9. package/dist/cache/manager.js.map +1 -1
  10. package/dist/checkpoint/artifacts/compressor.d.ts +5 -0
  11. package/dist/checkpoint/artifacts/compressor.d.ts.map +1 -0
  12. package/dist/checkpoint/artifacts/compressor.js +24 -0
  13. package/dist/checkpoint/artifacts/compressor.js.map +1 -0
  14. package/dist/checkpoint/artifacts/decompress-worker.d.ts +2 -0
  15. package/dist/checkpoint/artifacts/decompress-worker.d.ts.map +1 -0
  16. package/dist/checkpoint/artifacts/decompress-worker.js +31 -0
  17. package/dist/checkpoint/artifacts/decompress-worker.js.map +1 -0
  18. package/dist/checkpoint/artifacts/hasher.d.ts +2 -0
  19. package/dist/checkpoint/artifacts/hasher.d.ts.map +1 -0
  20. package/dist/checkpoint/artifacts/hasher.js +7 -0
  21. package/dist/checkpoint/artifacts/hasher.js.map +1 -0
  22. package/dist/checkpoint/artifacts/manifest.d.ts +6 -0
  23. package/dist/checkpoint/artifacts/manifest.d.ts.map +1 -0
  24. package/dist/checkpoint/artifacts/manifest.js +55 -0
  25. package/dist/checkpoint/artifacts/manifest.js.map +1 -0
  26. package/dist/checkpoint/artifacts/materializer.d.ts +16 -0
  27. package/dist/checkpoint/artifacts/materializer.d.ts.map +1 -0
  28. package/dist/checkpoint/artifacts/materializer.js +168 -0
  29. package/dist/checkpoint/artifacts/materializer.js.map +1 -0
  30. package/dist/checkpoint/artifacts/packager.d.ts +12 -0
  31. package/dist/checkpoint/artifacts/packager.d.ts.map +1 -0
  32. package/dist/checkpoint/artifacts/packager.js +82 -0
  33. package/dist/checkpoint/artifacts/packager.js.map +1 -0
  34. package/dist/checkpoint/artifacts/repository.d.ts +11 -0
  35. package/dist/checkpoint/artifacts/repository.d.ts.map +1 -0
  36. package/dist/checkpoint/artifacts/repository.js +29 -0
  37. package/dist/checkpoint/artifacts/repository.js.map +1 -0
  38. package/dist/checkpoint/artifacts/store.d.ts +13 -0
  39. package/dist/checkpoint/artifacts/store.d.ts.map +1 -0
  40. package/dist/checkpoint/artifacts/store.js +85 -0
  41. package/dist/checkpoint/artifacts/store.js.map +1 -0
  42. package/dist/checkpoint/artifacts/types.d.ts +21 -0
  43. package/dist/checkpoint/artifacts/types.d.ts.map +1 -0
  44. package/dist/checkpoint/artifacts/types.js +2 -0
  45. package/dist/checkpoint/artifacts/types.js.map +1 -0
  46. package/dist/checkpoint/artifacts/worker-decompressor.d.ts +17 -0
  47. package/dist/checkpoint/artifacts/worker-decompressor.d.ts.map +1 -0
  48. package/dist/checkpoint/artifacts/worker-decompressor.js +148 -0
  49. package/dist/checkpoint/artifacts/worker-decompressor.js.map +1 -0
  50. package/dist/checkpoint/asset-store.d.ts +10 -0
  51. package/dist/checkpoint/asset-store.d.ts.map +1 -0
  52. package/dist/checkpoint/asset-store.js +46 -0
  53. package/dist/checkpoint/asset-store.js.map +1 -0
  54. package/dist/checkpoint/bundler.d.ts +15 -0
  55. package/dist/checkpoint/bundler.d.ts.map +1 -0
  56. package/dist/checkpoint/bundler.js +45 -0
  57. package/dist/checkpoint/bundler.js.map +1 -0
  58. package/dist/checkpoint/cli.d.ts +2 -0
  59. package/dist/checkpoint/cli.d.ts.map +1 -0
  60. package/dist/checkpoint/cli.js +157 -0
  61. package/dist/checkpoint/cli.js.map +1 -0
  62. package/dist/checkpoint/entrypoint-generator.d.ts +17 -0
  63. package/dist/checkpoint/entrypoint-generator.d.ts.map +1 -0
  64. package/dist/checkpoint/entrypoint-generator.js +251 -0
  65. package/dist/checkpoint/entrypoint-generator.js.map +1 -0
  66. package/dist/checkpoint/forwarder.d.ts +6 -0
  67. package/dist/checkpoint/forwarder.d.ts.map +1 -0
  68. package/dist/checkpoint/forwarder.js +74 -0
  69. package/dist/checkpoint/forwarder.js.map +1 -0
  70. package/dist/checkpoint/gateway.d.ts +11 -0
  71. package/dist/checkpoint/gateway.d.ts.map +1 -0
  72. package/dist/checkpoint/gateway.js +30 -0
  73. package/dist/checkpoint/gateway.js.map +1 -0
  74. package/dist/checkpoint/ipc.d.ts +12 -0
  75. package/dist/checkpoint/ipc.d.ts.map +1 -0
  76. package/dist/checkpoint/ipc.js +96 -0
  77. package/dist/checkpoint/ipc.js.map +1 -0
  78. package/dist/checkpoint/manager.d.ts +20 -0
  79. package/dist/checkpoint/manager.d.ts.map +1 -0
  80. package/dist/checkpoint/manager.js +214 -0
  81. package/dist/checkpoint/manager.js.map +1 -0
  82. package/dist/checkpoint/process-manager.d.ts +35 -0
  83. package/dist/checkpoint/process-manager.d.ts.map +1 -0
  84. package/dist/checkpoint/process-manager.js +203 -0
  85. package/dist/checkpoint/process-manager.js.map +1 -0
  86. package/dist/checkpoint/resolver.d.ts +25 -0
  87. package/dist/checkpoint/resolver.d.ts.map +1 -0
  88. package/dist/checkpoint/resolver.js +95 -0
  89. package/dist/checkpoint/resolver.js.map +1 -0
  90. package/dist/checkpoint/socket-path.d.ts +2 -0
  91. package/dist/checkpoint/socket-path.d.ts.map +1 -0
  92. package/dist/checkpoint/socket-path.js +51 -0
  93. package/dist/checkpoint/socket-path.js.map +1 -0
  94. package/dist/checkpoint/types.d.ts +54 -0
  95. package/dist/checkpoint/types.d.ts.map +1 -0
  96. package/dist/checkpoint/types.js +2 -0
  97. package/dist/checkpoint/types.js.map +1 -0
  98. package/dist/cli/index.js +10 -2
  99. package/dist/cli/index.js.map +1 -1
  100. package/dist/cli/option-resolution.d.ts +1 -1
  101. package/dist/cli/option-resolution.d.ts.map +1 -1
  102. package/dist/cli/option-resolution.js.map +1 -1
  103. package/dist/cli.js +3709 -328
  104. package/dist/core/config-loader.d.ts +1 -0
  105. package/dist/core/config-loader.d.ts.map +1 -1
  106. package/dist/core/config-loader.js +10 -2
  107. package/dist/core/config-loader.js.map +1 -1
  108. package/dist/core/router.d.ts +24 -3
  109. package/dist/core/router.d.ts.map +1 -1
  110. package/dist/core/router.js +398 -249
  111. package/dist/core/router.js.map +1 -1
  112. package/dist/core/server.d.ts +2 -0
  113. package/dist/core/server.d.ts.map +1 -1
  114. package/dist/core/server.js +22 -8
  115. package/dist/core/server.js.map +1 -1
  116. package/dist/core/vector.d.ts +3 -0
  117. package/dist/core/vector.d.ts.map +1 -1
  118. package/dist/core/vector.js +51 -1
  119. package/dist/core/vector.js.map +1 -1
  120. package/dist/dev/route-scanner.d.ts.map +1 -1
  121. package/dist/dev/route-scanner.js +2 -1
  122. package/dist/dev/route-scanner.js.map +1 -1
  123. package/dist/http.d.ts +32 -7
  124. package/dist/http.d.ts.map +1 -1
  125. package/dist/http.js +144 -13
  126. package/dist/http.js.map +1 -1
  127. package/dist/index.cjs +1297 -74
  128. package/dist/index.d.ts +3 -2
  129. package/dist/index.d.ts.map +1 -1
  130. package/dist/index.js +2 -2
  131. package/dist/index.js.map +1 -1
  132. package/dist/index.mjs +1296 -73
  133. package/dist/middleware/manager.d.ts +3 -3
  134. package/dist/middleware/manager.d.ts.map +1 -1
  135. package/dist/middleware/manager.js +9 -8
  136. package/dist/middleware/manager.js.map +1 -1
  137. package/dist/openapi/docs-ui.d.ts.map +1 -1
  138. package/dist/openapi/docs-ui.js +1097 -61
  139. package/dist/openapi/docs-ui.js.map +1 -1
  140. package/dist/openapi/generator.d.ts +2 -1
  141. package/dist/openapi/generator.d.ts.map +1 -1
  142. package/dist/openapi/generator.js +240 -7
  143. package/dist/openapi/generator.js.map +1 -1
  144. package/dist/types/index.d.ts +71 -28
  145. package/dist/types/index.d.ts.map +1 -1
  146. package/dist/types/index.js +24 -1
  147. package/dist/types/index.js.map +1 -1
  148. package/dist/utils/validation.d.ts.map +1 -1
  149. package/dist/utils/validation.js +3 -2
  150. package/dist/utils/validation.js.map +1 -1
  151. package/package.json +2 -1
  152. package/src/auth/protected.ts +11 -8
  153. package/src/cache/manager.ts +23 -4
  154. package/src/checkpoint/artifacts/compressor.ts +30 -0
  155. package/src/checkpoint/artifacts/decompress-worker.ts +49 -0
  156. package/src/checkpoint/artifacts/hasher.ts +6 -0
  157. package/src/checkpoint/artifacts/manifest.ts +72 -0
  158. package/src/checkpoint/artifacts/materializer.ts +211 -0
  159. package/src/checkpoint/artifacts/packager.ts +100 -0
  160. package/src/checkpoint/artifacts/repository.ts +36 -0
  161. package/src/checkpoint/artifacts/store.ts +102 -0
  162. package/src/checkpoint/artifacts/types.ts +24 -0
  163. package/src/checkpoint/artifacts/worker-decompressor.ts +192 -0
  164. package/src/checkpoint/asset-store.ts +61 -0
  165. package/src/checkpoint/bundler.ts +64 -0
  166. package/src/checkpoint/cli.ts +177 -0
  167. package/src/checkpoint/entrypoint-generator.ts +275 -0
  168. package/src/checkpoint/forwarder.ts +84 -0
  169. package/src/checkpoint/gateway.ts +40 -0
  170. package/src/checkpoint/ipc.ts +107 -0
  171. package/src/checkpoint/manager.ts +254 -0
  172. package/src/checkpoint/process-manager.ts +250 -0
  173. package/src/checkpoint/resolver.ts +124 -0
  174. package/src/checkpoint/socket-path.ts +61 -0
  175. package/src/checkpoint/types.ts +63 -0
  176. package/src/cli/index.ts +11 -2
  177. package/src/cli/option-resolution.ts +5 -1
  178. package/src/core/config-loader.ts +11 -2
  179. package/src/core/router.ts +505 -264
  180. package/src/core/server.ts +36 -9
  181. package/src/core/vector.ts +60 -1
  182. package/src/dev/route-scanner.ts +2 -1
  183. package/src/http.ts +219 -19
  184. package/src/index.ts +3 -2
  185. package/src/middleware/manager.ts +10 -10
  186. package/src/openapi/docs-ui.ts +1097 -61
  187. package/src/openapi/generator.ts +265 -6
  188. package/src/types/index.ts +83 -30
  189. package/src/utils/validation.ts +5 -3
@@ -1,11 +1,19 @@
1
1
  import type { RegisteredRouteDefinition } from '../core/router';
2
- import type { OpenAPIInfoOptions, RouteSchemaDefinition, StandardJSONSchemaCapable } from '../types';
2
+ import { AuthKind, HttpAuthScheme, OpenApiSecuritySchemeType } from '../types';
3
+ import type {
4
+ OpenAPIAuthOptions,
5
+ OpenAPIInfoOptions,
6
+ OpenAPISecurityScheme,
7
+ RouteSchemaDefinition,
8
+ StandardJSONSchemaCapable,
9
+ } from '../types';
3
10
 
4
11
  type JsonSchema = Record<string, unknown>;
5
12
 
6
13
  export interface OpenAPIGenerationOptions {
7
14
  target: string;
8
15
  info?: OpenAPIInfoOptions;
16
+ auth?: OpenAPIAuthOptions;
9
17
  }
10
18
 
11
19
  export interface OpenAPIGenerationResult {
@@ -13,6 +21,119 @@ export interface OpenAPIGenerationResult {
13
21
  warnings: string[];
14
22
  }
15
23
 
24
+ const AUTH_KIND_VALUES = new Set<string>(Object.values(AuthKind));
25
+ const DEFAULT_SECURITY_SCHEME_NAMES: Record<AuthKind, string> = {
26
+ [AuthKind.ApiKey]: 'apiKeyAuth',
27
+ [AuthKind.HttpBasic]: 'basicAuth',
28
+ [AuthKind.HttpBearer]: 'bearerAuth',
29
+ [AuthKind.HttpDigest]: 'digestAuth',
30
+ [AuthKind.OAuth2]: 'oauth2Auth',
31
+ [AuthKind.OpenIdConnect]: 'openIdConnectAuth',
32
+ [AuthKind.MutualTls]: 'mutualTlsAuth',
33
+ };
34
+
35
+ function isAuthKind(value: unknown): value is AuthKind {
36
+ return typeof value === 'string' && AUTH_KIND_VALUES.has(value);
37
+ }
38
+
39
+ function resolveRouteAuthKind(routeAuth: unknown, defaultAuthKind: AuthKind): AuthKind | null {
40
+ if (routeAuth === undefined || routeAuth === false || routeAuth === null) {
41
+ return null;
42
+ }
43
+
44
+ if (routeAuth === true) {
45
+ return defaultAuthKind;
46
+ }
47
+
48
+ if (isAuthKind(routeAuth)) {
49
+ return routeAuth;
50
+ }
51
+
52
+ // Preserve runtime behavior for unexpected truthy auth values.
53
+ return defaultAuthKind;
54
+ }
55
+
56
+ function resolveSecuritySchemeName(kind: AuthKind, authOptions?: OpenAPIAuthOptions): string {
57
+ const configuredName = authOptions?.securitySchemeNames?.[kind];
58
+ if (typeof configuredName === 'string' && configuredName.trim().length > 0) {
59
+ return configuredName.trim();
60
+ }
61
+ return DEFAULT_SECURITY_SCHEME_NAMES[kind];
62
+ }
63
+
64
+ function toOpenApiSecurityScheme(kind: AuthKind): OpenAPISecurityScheme {
65
+ switch (kind) {
66
+ case AuthKind.ApiKey:
67
+ return {
68
+ type: OpenApiSecuritySchemeType.ApiKey,
69
+ name: 'X-API-Key',
70
+ in: 'header',
71
+ };
72
+ case AuthKind.HttpBasic:
73
+ return {
74
+ type: OpenApiSecuritySchemeType.Http,
75
+ scheme: HttpAuthScheme.Basic,
76
+ };
77
+ case AuthKind.HttpBearer:
78
+ return {
79
+ type: OpenApiSecuritySchemeType.Http,
80
+ scheme: HttpAuthScheme.Bearer,
81
+ bearerFormat: 'JWT',
82
+ };
83
+ case AuthKind.HttpDigest:
84
+ return {
85
+ type: OpenApiSecuritySchemeType.Http,
86
+ scheme: HttpAuthScheme.Digest,
87
+ };
88
+ case AuthKind.OAuth2:
89
+ return {
90
+ type: OpenApiSecuritySchemeType.OAuth2,
91
+ flows: {
92
+ authorizationCode: {
93
+ authorizationUrl: 'https://example.com/oauth/authorize',
94
+ tokenUrl: 'https://example.com/oauth/token',
95
+ scopes: {},
96
+ },
97
+ },
98
+ };
99
+ case AuthKind.OpenIdConnect:
100
+ return {
101
+ type: OpenApiSecuritySchemeType.OpenIdConnect,
102
+ openIdConnectUrl: 'https://example.com/.well-known/openid-configuration',
103
+ };
104
+ case AuthKind.MutualTls:
105
+ return {
106
+ type: OpenApiSecuritySchemeType.MutualTls,
107
+ };
108
+ default: {
109
+ const exhaustiveCheck: never = kind;
110
+ return exhaustiveCheck;
111
+ }
112
+ }
113
+ }
114
+
115
+ function resolveSecurityScheme(kind: AuthKind, authOptions?: OpenAPIAuthOptions): OpenAPISecurityScheme {
116
+ const defaultScheme = toOpenApiSecurityScheme(kind);
117
+ const override = authOptions?.securitySchemes?.[kind];
118
+ if (!override) {
119
+ return defaultScheme;
120
+ }
121
+
122
+ const merged: OpenAPISecurityScheme = {
123
+ ...defaultScheme,
124
+ ...override,
125
+ };
126
+
127
+ if (isRecord(defaultScheme.flows) && isRecord(override.flows)) {
128
+ merged.flows = {
129
+ ...defaultScheme.flows,
130
+ ...override.flows,
131
+ };
132
+ }
133
+
134
+ return merged;
135
+ }
136
+
16
137
  function isJSONSchemaCapable(schema: unknown): schema is StandardJSONSchemaCapable {
17
138
  const standard = (schema as any)?.['~standard'];
18
139
  const converter = standard?.jsonSchema;
@@ -114,12 +235,89 @@ function isNoBodyResponseStatus(status: string): boolean {
114
235
  }
115
236
 
116
237
  function getResponseDescription(status: string): string {
117
- if (status === '204') return 'No Content';
118
- if (status === '205') return 'Reset Content';
119
- if (status === '304') return 'Not Modified';
238
+ const knownDescriptions: Record<string, string> = {
239
+ '100': 'Continue',
240
+ '101': 'Switching Protocols',
241
+ '102': 'Processing',
242
+ '103': 'Early Hints',
243
+ '200': 'OK',
244
+ '201': 'Created',
245
+ '202': 'Accepted',
246
+ '203': 'Non-Authoritative Information',
247
+ '204': 'No Content',
248
+ '205': 'Reset Content',
249
+ '206': 'Partial Content',
250
+ '207': 'Multi-Status',
251
+ '208': 'Already Reported',
252
+ '226': 'IM Used',
253
+ '300': 'Multiple Choices',
254
+ '301': 'Moved Permanently',
255
+ '302': 'Found',
256
+ '303': 'See Other',
257
+ '304': 'Not Modified',
258
+ '305': 'Use Proxy',
259
+ '307': 'Temporary Redirect',
260
+ '308': 'Permanent Redirect',
261
+ '400': 'Bad Request',
262
+ '401': 'Unauthorized',
263
+ '402': 'Payment Required',
264
+ '403': 'Forbidden',
265
+ '404': 'Not Found',
266
+ '405': 'Method Not Allowed',
267
+ '406': 'Not Acceptable',
268
+ '407': 'Proxy Authentication Required',
269
+ '408': 'Request Timeout',
270
+ '409': 'Conflict',
271
+ '410': 'Gone',
272
+ '411': 'Length Required',
273
+ '412': 'Precondition Failed',
274
+ '413': 'Payload Too Large',
275
+ '414': 'URI Too Long',
276
+ '415': 'Unsupported Media Type',
277
+ '416': 'Range Not Satisfiable',
278
+ '417': 'Expectation Failed',
279
+ '418': "I'm a teapot",
280
+ '421': 'Misdirected Request',
281
+ '422': 'Unprocessable Content',
282
+ '423': 'Locked',
283
+ '424': 'Failed Dependency',
284
+ '425': 'Too Early',
285
+ '426': 'Upgrade Required',
286
+ '428': 'Precondition Required',
287
+ '429': 'Too Many Requests',
288
+ '431': 'Request Header Fields Too Large',
289
+ '451': 'Unavailable For Legal Reasons',
290
+ '500': 'Internal Server Error',
291
+ '501': 'Not Implemented',
292
+ '502': 'Bad Gateway',
293
+ '503': 'Service Unavailable',
294
+ '504': 'Gateway Timeout',
295
+ '505': 'HTTP Version Not Supported',
296
+ '506': 'Variant Also Negotiates',
297
+ '507': 'Insufficient Storage',
298
+ '508': 'Loop Detected',
299
+ '510': 'Not Extended',
300
+ '511': 'Network Authentication Required',
301
+ };
302
+ if (knownDescriptions[status]) {
303
+ return knownDescriptions[status];
304
+ }
305
+
120
306
  const numericStatus = Number(status);
121
307
  if (Number.isInteger(numericStatus) && numericStatus >= 100 && numericStatus < 200) {
122
- return 'Informational';
308
+ return 'Informational Response';
309
+ }
310
+ if (Number.isInteger(numericStatus) && numericStatus >= 200 && numericStatus < 300) {
311
+ return 'Successful Response';
312
+ }
313
+ if (Number.isInteger(numericStatus) && numericStatus >= 300 && numericStatus < 400) {
314
+ return 'Redirection';
315
+ }
316
+ if (Number.isInteger(numericStatus) && numericStatus >= 400 && numericStatus < 500) {
317
+ return 'Client Error';
318
+ }
319
+ if (Number.isInteger(numericStatus) && numericStatus >= 500 && numericStatus < 600) {
320
+ return 'Server Error';
123
321
  }
124
322
  return 'OK';
125
323
  }
@@ -648,6 +846,8 @@ export function generateOpenAPIDocument(
648
846
  ): OpenAPIGenerationResult {
649
847
  const warnings: string[] = [];
650
848
  const paths: Record<string, Record<string, unknown>> = {};
849
+ const defaultAuthKind = AuthKind.HttpBearer;
850
+ const usedAuthKinds = new Set<AuthKind>();
651
851
 
652
852
  for (const route of routes) {
653
853
  if (route.options.expose === false) continue;
@@ -661,15 +861,64 @@ export function generateOpenAPIDocument(
661
861
  operationId: createOperationId(method, openapiPath),
662
862
  tags: [route.options.schema?.tag || inferTagFromPath(route.path)],
663
863
  };
864
+ if (typeof route.options.schema?.summary === 'string' && route.options.schema.summary.trim()) {
865
+ operation.summary = route.options.schema.summary.trim();
866
+ }
867
+ const routeSchemaDescription =
868
+ typeof route.options.schema?.description === 'string' && route.options.schema.description.trim()
869
+ ? route.options.schema.description.trim()
870
+ : typeof route.options.schema?.descrition === 'string' && route.options.schema.descrition.trim()
871
+ ? route.options.schema.descrition.trim()
872
+ : undefined;
873
+ if (routeSchemaDescription) {
874
+ operation.description = routeSchemaDescription;
875
+ }
876
+ if (route.options.deprecated === true) {
877
+ operation.deprecated = true;
878
+ }
879
+ const routeAuthKind = resolveRouteAuthKind(route.options.auth, defaultAuthKind);
880
+ if (routeAuthKind) {
881
+ usedAuthKinds.add(routeAuthKind);
882
+ const securitySchemeName = resolveSecuritySchemeName(routeAuthKind, options.auth);
883
+ operation.security = [{ [securitySchemeName]: [] }];
884
+ }
664
885
 
665
886
  const inputJSONSchema = convertInputSchema(route.path, route.options.schema?.input, options.target, warnings);
666
887
 
667
888
  if (inputJSONSchema) {
889
+ if (!operation.summary && typeof inputJSONSchema.title === 'string' && inputJSONSchema.title.trim()) {
890
+ operation.summary = inputJSONSchema.title.trim();
891
+ }
892
+ if (
893
+ !operation.description &&
894
+ typeof inputJSONSchema.description === 'string' &&
895
+ inputJSONSchema.description.trim()
896
+ ) {
897
+ operation.description = inputJSONSchema.description.trim();
898
+ }
668
899
  addStructuredInputToOperation(operation, inputJSONSchema);
669
900
  }
670
901
  addMissingPathParameters(operation, route.path);
671
902
 
672
903
  addOutputSchemasToOperation(operation, route.path, route.options.schema || {}, options.target, warnings);
904
+ if (!operation.summary || !operation.description) {
905
+ const responseEntries = Object.values(operation.responses || {}) as any[];
906
+ for (const response of responseEntries) {
907
+ const responseSchema = response?.content?.['application/json']?.schema;
908
+ if (!responseSchema || typeof responseSchema !== 'object') continue;
909
+ if (!operation.summary && typeof responseSchema.title === 'string' && responseSchema.title.trim()) {
910
+ operation.summary = responseSchema.title.trim();
911
+ }
912
+ if (
913
+ !operation.description &&
914
+ typeof responseSchema.description === 'string' &&
915
+ responseSchema.description.trim()
916
+ ) {
917
+ operation.description = responseSchema.description.trim();
918
+ }
919
+ if (operation.summary && operation.description) break;
920
+ }
921
+ }
673
922
 
674
923
  paths[openapiPath] ||= {};
675
924
  paths[openapiPath][method] = operation;
@@ -677,7 +926,7 @@ export function generateOpenAPIDocument(
677
926
 
678
927
  const openapiVersion = options.target === 'openapi-3.0' ? '3.0.3' : '3.1.0';
679
928
 
680
- const document = {
929
+ const document: Record<string, unknown> = {
681
930
  openapi: openapiVersion,
682
931
  info: {
683
932
  title: options.info?.title || 'Vector API',
@@ -686,6 +935,16 @@ export function generateOpenAPIDocument(
686
935
  },
687
936
  paths,
688
937
  };
938
+ if (usedAuthKinds.size > 0) {
939
+ const securitySchemes: Record<string, OpenAPISecurityScheme> = {};
940
+ for (const authKind of usedAuthKinds) {
941
+ const name = resolveSecuritySchemeName(authKind, options.auth);
942
+ securitySchemes[name] = resolveSecurityScheme(authKind, options.auth);
943
+ }
944
+ document.components = {
945
+ securitySchemes,
946
+ };
947
+ }
689
948
 
690
949
  return {
691
950
  document,
@@ -1,5 +1,6 @@
1
1
  import type { StandardJSONSchemaV1, StandardSchemaV1, StandardTypedV1 } from './standard-schema';
2
2
  import type { Server } from 'bun';
3
+ import type { CheckpointConfig } from '../checkpoint/types';
3
4
 
4
5
  // Default AuthUser type - users can override this with their own type
5
6
  export interface DefaultAuthUser {
@@ -14,7 +15,6 @@ export interface DefaultAuthUser {
14
15
  // Users can override any of these types without breaking changes
15
16
  export interface VectorTypes {
16
17
  auth?: any; // Custom auth user type
17
- context?: any; // Custom request context (future)
18
18
  cache?: any; // Custom cache value type (future)
19
19
  metadata?: any; // Custom metadata type (future)
20
20
  }
@@ -22,7 +22,6 @@ export interface VectorTypes {
22
22
  // Default types
23
23
  export interface DefaultVectorTypes extends VectorTypes {
24
24
  auth: DefaultAuthUser;
25
- context: Record<string, any>;
26
25
  cache: any;
27
26
  metadata: Record<string, any>;
28
27
  }
@@ -30,8 +29,6 @@ export interface DefaultVectorTypes extends VectorTypes {
30
29
  // Type helpers
31
30
  export type GetAuthType<T extends VectorTypes> = T['auth'] extends undefined ? DefaultAuthUser : T['auth'];
32
31
 
33
- export type GetContextType<T extends VectorTypes> = T['context'] extends undefined ? Record<string, any> : T['context'];
34
-
35
32
  export type GetCacheType<T extends VectorTypes> = T['cache'] extends undefined ? any : T['cache'];
36
33
 
37
34
  export type GetMetadataType<T extends VectorTypes> = T['metadata'] extends undefined
@@ -41,11 +38,7 @@ export type GetMetadataType<T extends VectorTypes> = T['metadata'] extends undef
41
38
  // Legacy support - keep AuthUser for backward compatibility
42
39
  export type AuthUser = DefaultAuthUser;
43
40
 
44
- type DefaultQueryShape = { [key: string]: string | string[] | undefined };
45
- type DefaultParamsShape = Record<string, string>;
46
- type DefaultCookiesShape = Record<string, string>;
47
-
48
- type BaseVectorRequest = Omit<Request, 'body' | 'json' | 'text' | 'formData' | 'arrayBuffer' | 'blob'>;
41
+ type BaseVectorRequest = Request;
49
42
 
50
43
  type InferValidatedSection<TValidatedInput, TKey extends string, TFallback> = [TValidatedInput] extends [undefined]
51
44
  ? TFallback
@@ -56,27 +49,35 @@ type InferValidatedSection<TValidatedInput, TKey extends string, TFallback> = [T
56
49
  : TFallback;
57
50
 
58
51
  type InferValidatedInputValue<TValidatedInput> = [TValidatedInput] extends [undefined] ? unknown : TValidatedInput;
52
+ type ValidatedInputField<TValidatedInput> = [TValidatedInput] extends [undefined]
53
+ ? { validatedInput?: InferValidatedInputValue<TValidatedInput> }
54
+ : { validatedInput: InferValidatedInputValue<TValidatedInput> };
59
55
 
60
56
  export type BunRouteHandler = (req: Request) => Response | Promise<Response>;
61
57
  export type BunMethodMap = Record<string, BunRouteHandler>;
62
58
  export type BunRouteTable = Record<string, BunMethodMap | Response>;
63
59
  export type LegacyRouteEntry = [string, RegExp, [BunRouteHandler, ...BunRouteHandler[]], string?];
64
60
 
65
- export interface VectorRequest<TTypes extends VectorTypes = DefaultVectorTypes, TValidatedInput = undefined>
66
- extends BaseVectorRequest {
61
+ type VectorRequestTypeBrand<TTypes extends VectorTypes, TValidatedInput> = {
62
+ readonly __vectorTypesBrand__?: TTypes;
63
+ readonly __validatedInputBrand__?: TValidatedInput;
64
+ };
65
+
66
+ export type VectorRequest<
67
+ TTypes extends VectorTypes = DefaultVectorTypes,
68
+ TValidatedInput = undefined,
69
+ > = BaseVectorRequest & VectorRequestTypeBrand<TTypes, TValidatedInput>;
70
+
71
+ export type VectorContext<TTypes extends VectorTypes = DefaultVectorTypes, TValidatedInput = undefined> = {
72
+ request: VectorRequest<TTypes, TValidatedInput>;
67
73
  authUser?: GetAuthType<TTypes>;
68
- context: GetContextType<TTypes>;
69
- metadata?: GetMetadataType<TTypes>;
74
+ metadata: GetMetadataType<TTypes>;
75
+ params: InferValidatedSection<TValidatedInput, 'params', Record<string, string>>;
76
+ query: InferValidatedSection<TValidatedInput, 'query', Record<string, string | string[]>>;
77
+ cookies: InferValidatedSection<TValidatedInput, 'cookies', Record<string, string>>;
70
78
  content?: InferValidatedSection<TValidatedInput, 'body', any>;
71
- body?: InferValidatedSection<TValidatedInput, 'body', any>;
72
- params?: InferValidatedSection<TValidatedInput, 'params', DefaultParamsShape>;
73
- query: InferValidatedSection<TValidatedInput, 'query', DefaultQueryShape>;
74
- headers: Headers;
75
- cookies?: InferValidatedSection<TValidatedInput, 'cookies', DefaultCookiesShape>;
76
- validatedInput?: InferValidatedInputValue<TValidatedInput>;
77
- startTime?: number;
78
79
  [key: string]: any;
79
- }
80
+ } & ValidatedInputField<TValidatedInput>;
80
81
 
81
82
  export interface CacheOptions {
82
83
  key?: string;
@@ -97,6 +98,52 @@ export interface RouteSchemaDefinition<
97
98
  input?: TInput;
98
99
  output?: TOutput;
99
100
  tag?: string;
101
+ summary?: string;
102
+ description?: string;
103
+ descrition?: string;
104
+ }
105
+
106
+ export enum OpenApiSecuritySchemeType {
107
+ ApiKey = 'apiKey',
108
+ Http = 'http',
109
+ MutualTls = 'mutualTLS',
110
+ OAuth2 = 'oauth2',
111
+ OpenIdConnect = 'openIdConnect',
112
+ }
113
+
114
+ export enum HttpAuthScheme {
115
+ Basic = 'basic',
116
+ Bearer = 'bearer',
117
+ Digest = 'digest',
118
+ }
119
+
120
+ export enum AuthKind {
121
+ ApiKey = 'ApiKey',
122
+ HttpBasic = 'HttpBasic',
123
+ HttpBearer = 'HttpBearer',
124
+ HttpDigest = 'HttpDigest',
125
+ OAuth2 = 'OAuth2',
126
+ OpenIdConnect = 'OpenIdConnect',
127
+ MutualTls = 'MutualTls',
128
+ }
129
+
130
+ export type RouteAuthOption = boolean | AuthKind;
131
+
132
+ export interface OpenAPISecurityScheme {
133
+ type: OpenApiSecuritySchemeType | ({} & string);
134
+ description?: string;
135
+ name?: string;
136
+ in?: 'query' | 'header' | 'cookie';
137
+ scheme?: string;
138
+ bearerFormat?: string;
139
+ flows?: Record<string, unknown>;
140
+ openIdConnectUrl?: string;
141
+ [key: string]: unknown;
142
+ }
143
+
144
+ export interface OpenAPIAuthOptions {
145
+ securitySchemeNames?: Partial<Record<AuthKind, string>>;
146
+ securitySchemes?: Partial<Record<AuthKind, OpenAPISecurityScheme>>;
100
147
  }
101
148
 
102
149
  export type InferStandardSchemaInput<TSchema extends StandardRouteSchema> = StandardSchemaV1.InferInput<TSchema>;
@@ -113,8 +160,9 @@ export type InferRouteInputFromSchemaDefinition<TSchemaDef extends RouteSchemaDe
113
160
  export interface RouteOptions<TTypes extends VectorTypes = DefaultVectorTypes> {
114
161
  method: string;
115
162
  path: string;
116
- auth?: boolean;
163
+ auth?: RouteAuthOption;
117
164
  expose?: boolean; // defaults to true
165
+ deprecated?: boolean; // OpenAPI operation.deprecated flag
118
166
  cache?: CacheOptions | number;
119
167
  rawRequest?: boolean;
120
168
  validate?: boolean; // defaults to validating schema.input unless false
@@ -125,7 +173,7 @@ export interface RouteOptions<TTypes extends VectorTypes = DefaultVectorTypes> {
125
173
  }
126
174
 
127
175
  export interface RouteBooleanDefaults {
128
- auth?: boolean;
176
+ auth?: RouteAuthOption;
129
177
  expose?: boolean;
130
178
  rawRequest?: boolean;
131
179
  validate?: boolean;
@@ -138,7 +186,7 @@ export interface VectorDefaults {
138
186
 
139
187
  // Legacy config interface - will be deprecated
140
188
  export interface VectorConfig<TTypes extends VectorTypes = DefaultVectorTypes> {
141
- port?: number;
189
+ port?: number | string;
142
190
  hostname?: string;
143
191
  reusePort?: boolean;
144
192
  development?: boolean;
@@ -153,6 +201,7 @@ export interface VectorConfig<TTypes extends VectorTypes = DefaultVectorTypes> {
153
201
  openapi?: OpenAPIOptions | boolean;
154
202
  startup?: StartupHandler;
155
203
  shutdown?: ShutdownHandler;
204
+ checkpoint?: CheckpointConfig;
156
205
  }
157
206
 
158
207
  export interface StartVectorContext {
@@ -181,7 +230,7 @@ export interface StartedVectorApp<TTypes extends VectorTypes = DefaultVectorType
181
230
  // New config-driven schema - flat structure
182
231
  export interface VectorConfigSchema<TTypes extends VectorTypes = DefaultVectorTypes> {
183
232
  // Server configuration
184
- port?: number;
233
+ port?: number | string;
185
234
  hostname?: string;
186
235
  reusePort?: boolean;
187
236
  development?: boolean;
@@ -208,6 +257,9 @@ export interface VectorConfigSchema<TTypes extends VectorTypes = DefaultVectorTy
208
257
  startup?: StartupHandler;
209
258
  shutdown?: ShutdownHandler;
210
259
 
260
+ // Checkpoints
261
+ checkpoint?: CheckpointConfig;
262
+
211
263
  // Custom types for TypeScript
212
264
  types?: VectorTypes;
213
265
  }
@@ -239,15 +291,16 @@ export interface OpenAPIOptions {
239
291
  target?: 'openapi-3.0' | 'draft-2020-12' | 'draft-07' | ({} & string);
240
292
  docs?: boolean | OpenAPIDocsOptions;
241
293
  info?: OpenAPIInfoOptions;
294
+ auth?: OpenAPIAuthOptions;
242
295
  }
243
296
 
244
297
  export type BeforeMiddlewareHandler<TTypes extends VectorTypes = DefaultVectorTypes> = (
245
- request: VectorRequest<TTypes>
246
- ) => Promise<VectorRequest<TTypes> | Response> | VectorRequest<TTypes> | Response;
298
+ context: VectorContext<TTypes>
299
+ ) => Promise<void | Response> | void | Response;
247
300
 
248
301
  export type AfterMiddlewareHandler<TTypes extends VectorTypes = DefaultVectorTypes> = (
249
302
  response: Response,
250
- request: VectorRequest<TTypes>
303
+ context: VectorContext<TTypes>
251
304
  ) => Promise<Response> | Response;
252
305
  export type MiddlewareHandler = BeforeMiddlewareHandler | AfterMiddlewareHandler;
253
306
 
@@ -255,11 +308,11 @@ export type StartupHandler = () => Promise<void> | void;
255
308
  export type ShutdownHandler = () => Promise<void> | void;
256
309
 
257
310
  export type RouteHandler<TTypes extends VectorTypes = DefaultVectorTypes, TValidatedInput = undefined> = (
258
- request: VectorRequest<TTypes, TValidatedInput>
311
+ context: VectorContext<TTypes, TValidatedInput>
259
312
  ) => Promise<any> | any;
260
313
 
261
314
  export type ProtectedHandler<TTypes extends VectorTypes = DefaultVectorTypes> = (
262
- request: VectorRequest<TTypes>
315
+ context: VectorContext<TTypes>
263
316
  ) => Promise<GetAuthType<TTypes>> | GetAuthType<TTypes>;
264
317
 
265
318
  export type CacheHandler = (key: string, factory: () => Promise<any>, ttl: number) => Promise<any>;
@@ -20,16 +20,18 @@ export function validateConfig(config: VectorConfig): VectorConfig {
20
20
  return validatedConfig;
21
21
  }
22
22
 
23
- function validatePort(port?: number): number {
23
+ function validatePort(port?: number | string): number {
24
24
  if (port === undefined) {
25
25
  return DEFAULT_CONFIG.PORT;
26
26
  }
27
27
 
28
- if (!Number.isInteger(port) || port < 1 || port > 65535) {
28
+ const normalizedPort = Number(port);
29
+
30
+ if (!Number.isInteger(normalizedPort) || normalizedPort < 1 || normalizedPort > 65535) {
29
31
  throw new Error(`Invalid port: ${port}. Port must be between 1 and 65535.`);
30
32
  }
31
33
 
32
- return port;
34
+ return normalizedPort;
33
35
  }
34
36
 
35
37
  function validateCorsOptions(cors: CorsOptions | boolean): CorsOptions | undefined {