adorn-api 1.0.1 → 1.0.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.
- package/README.md +4 -1
- package/dist/adapters/express/createApp.d.ts +149 -11
- package/dist/adapters/express/createApp.d.ts.map +1 -1
- package/dist/adapters/express/createApp.js +112 -6
- package/dist/adapters/express/createApp.js.map +1 -1
- package/dist/adapters/express/middleware/errorHandler.d.ts +193 -2
- package/dist/adapters/express/middleware/errorHandler.d.ts.map +1 -1
- package/dist/adapters/express/middleware/errorHandler.js +164 -3
- package/dist/adapters/express/middleware/errorHandler.js.map +1 -1
- package/dist/adapters/express/router.d.ts +1 -1
- package/dist/adapters/express/router.d.ts.map +1 -1
- package/dist/adapters/express/router.js +6 -4
- package/dist/adapters/express/router.js.map +1 -1
- package/dist/adapters/express/transport/request.js.map +1 -1
- package/dist/adapters/express/transport/response.d.ts +1 -1
- package/dist/adapters/express/transport/response.d.ts.map +1 -1
- package/dist/adapters/express/transport/response.js.map +1 -1
- package/dist/contracts/openapi-v3.d.ts +461 -0
- package/dist/contracts/openapi-v3.d.ts.map +1 -1
- package/dist/contracts/reply.d.ts +109 -1
- package/dist/contracts/reply.d.ts.map +1 -1
- package/dist/contracts/reply.js +40 -1
- package/dist/contracts/reply.js.map +1 -1
- package/dist/contracts/response-types.d.ts +5 -5
- package/dist/contracts/response-types.d.ts.map +1 -1
- package/dist/contracts/responses.d.ts +84 -4
- package/dist/contracts/responses.d.ts.map +1 -1
- package/dist/contracts/route-options.d.ts +134 -3
- package/dist/contracts/route-options.d.ts.map +1 -1
- package/dist/contracts/validator.d.ts +121 -0
- package/dist/contracts/validator.d.ts.map +1 -1
- package/dist/core/binding/binder.d.ts +56 -1
- package/dist/core/binding/binder.d.ts.map +1 -1
- package/dist/core/binding/binder.js +33 -0
- package/dist/core/binding/binder.js.map +1 -1
- package/dist/core/binding/coerce/primitives.d.ts +68 -1
- package/dist/core/binding/coerce/primitives.d.ts.map +1 -1
- package/dist/core/binding/coerce/primitives.js +82 -12
- package/dist/core/binding/coerce/primitives.js.map +1 -1
- package/dist/core/errors/http-error.d.ts +54 -0
- package/dist/core/errors/http-error.d.ts.map +1 -1
- package/dist/core/errors/http-error.js +54 -0
- package/dist/core/errors/http-error.js.map +1 -1
- package/dist/core/errors/validation-error.d.ts +65 -0
- package/dist/core/errors/validation-error.d.ts.map +1 -1
- package/dist/core/errors/validation-error.js +65 -0
- package/dist/core/errors/validation-error.js.map +1 -1
- package/dist/core/openapi/buildOpenApi.d.ts +65 -0
- package/dist/core/openapi/buildOpenApi.d.ts.map +1 -1
- package/dist/core/openapi/buildOpenApi.js +66 -4
- package/dist/core/openapi/buildOpenApi.js.map +1 -1
- package/dist/core/openapi/schema/registry.d.ts +1 -1
- package/dist/core/openapi/schema/registry.d.ts.map +1 -1
- package/dist/core/openapi/schema/registry.js.map +1 -1
- package/dist/core/registry/buildRegistry.d.ts.map +1 -1
- package/dist/core/registry/buildRegistry.js +49 -5
- package/dist/core/registry/buildRegistry.js.map +1 -1
- package/dist/core/registry/types.d.ts +194 -1
- package/dist/core/registry/types.d.ts.map +1 -1
- package/dist/core/reply/reply.d.ts +94 -0
- package/dist/core/reply/reply.d.ts.map +1 -1
- package/dist/core/reply/reply.js +87 -0
- package/dist/core/reply/reply.js.map +1 -1
- package/dist/core/reply/typed.d.ts +137 -3
- package/dist/core/reply/typed.d.ts.map +1 -1
- package/dist/core/reply/typed.js +137 -2
- package/dist/core/reply/typed.js.map +1 -1
- package/dist/core/responses/helpers.d.ts +1 -1
- package/dist/core/responses/helpers.d.ts.map +1 -1
- package/dist/core/responses/normalize.d.ts.map +1 -1
- package/dist/core/responses/normalize.js +2 -1
- package/dist/core/responses/normalize.js.map +1 -1
- package/dist/core/route/defineRoute.d.ts +48 -1
- package/dist/core/route/defineRoute.d.ts.map +1 -1
- package/dist/core/route/defineRoute.js +42 -1
- package/dist/core/route/defineRoute.js.map +1 -1
- package/dist/decorators/binding.d.ts +1 -1
- package/dist/decorators/binding.d.ts.map +1 -1
- package/dist/decorators/binding.js.map +1 -1
- package/dist/decorators/controller.d.ts +1 -1
- package/dist/decorators/controller.d.ts.map +1 -1
- package/dist/decorators/controller.js.map +1 -1
- package/dist/decorators/docs.d.ts +6 -0
- package/dist/decorators/docs.d.ts.map +1 -1
- package/dist/decorators/docs.js +45 -2
- package/dist/decorators/docs.js.map +1 -1
- package/dist/decorators/index.d.ts +3 -0
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js +3 -0
- package/dist/decorators/index.js.map +1 -1
- package/dist/decorators/methods.d.ts +128 -6
- package/dist/decorators/methods.d.ts.map +1 -1
- package/dist/decorators/methods.js +124 -0
- package/dist/decorators/methods.js.map +1 -1
- package/dist/decorators/responses.d.ts +5 -0
- package/dist/decorators/responses.d.ts.map +1 -1
- package/dist/decorators/responses.js +43 -2
- package/dist/decorators/responses.js.map +1 -1
- package/dist/decorators/security.d.ts +6 -0
- package/dist/decorators/security.d.ts.map +1 -1
- package/dist/decorators/security.js +38 -2
- package/dist/decorators/security.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/metal-orm/schema/column-map.d.ts +91 -0
- package/dist/integrations/metal-orm/schema/column-map.d.ts.map +1 -1
- package/dist/integrations/metal-orm/schema/column-map.js +129 -2
- package/dist/integrations/metal-orm/schema/column-map.js.map +1 -1
- package/dist/integrations/metal-orm/schema/dto.d.ts +2 -2
- package/dist/integrations/metal-orm/schema/dto.d.ts.map +1 -1
- package/dist/integrations/metal-orm/schema/dto.js.map +1 -1
- package/dist/integrations/metal-orm/schema/entity.d.ts +90 -8
- package/dist/integrations/metal-orm/schema/entity.d.ts.map +1 -1
- package/dist/integrations/metal-orm/schema/entity.js +78 -6
- package/dist/integrations/metal-orm/schema/entity.js.map +1 -1
- package/dist/integrations/metal-orm/schema/filters.d.ts +1 -1
- package/dist/integrations/metal-orm/schema/filters.d.ts.map +1 -1
- package/dist/integrations/metal-orm/schema/filters.js +2 -1
- package/dist/integrations/metal-orm/schema/filters.js.map +1 -1
- package/dist/integrations/metal-orm/schema/tabledef.d.ts +1 -1
- package/dist/integrations/metal-orm/schema/tabledef.d.ts.map +1 -1
- package/dist/metadata/bag.d.ts +2 -1
- package/dist/metadata/bag.d.ts.map +1 -1
- package/dist/metadata/bag.js +2 -1
- package/dist/metadata/bag.js.map +1 -1
- package/dist/metadata/keys.d.ts +203 -1
- package/dist/metadata/keys.d.ts.map +1 -1
- package/dist/metadata/keys.js +3 -9
- package/dist/metadata/keys.js.map +1 -1
- package/dist/metadata/merge.d.ts.map +1 -1
- package/dist/metadata/merge.js +4 -1
- package/dist/metadata/merge.js.map +1 -1
- package/dist/validation/native/schema.d.ts +2 -2
- package/dist/validation/native/schema.d.ts.map +1 -1
- package/dist/validation/native/validator.d.ts +1 -1
- package/dist/validation/native/validator.d.ts.map +1 -1
- package/package.json +6 -2
|
@@ -1,6 +1,60 @@
|
|
|
1
1
|
import { normalizeResponses } from '../responses/normalize.js';
|
|
2
2
|
import { OasSchemaRegistry } from './schema/registry.js';
|
|
3
3
|
import { irToOasSchema } from './schema/toOpenApi.js';
|
|
4
|
+
/**
|
|
5
|
+
* Builds a complete OpenAPI 3.0.3 specification document from the route registry.
|
|
6
|
+
*
|
|
7
|
+
* This function generates a comprehensive OpenAPI specification by analyzing
|
|
8
|
+
* the route registry and extracting all necessary information including paths,
|
|
9
|
+
* operations, parameters, request/response bodies, and security schemes.
|
|
10
|
+
*
|
|
11
|
+
* @param registry - Route registry containing all registered routes and metadata
|
|
12
|
+
* @param opts - OpenAPI build options including title, version, and servers
|
|
13
|
+
* @returns Complete OpenAPI 3.0.3 document ready for serving or serialization
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { buildRegistry } from './registry';
|
|
18
|
+
* import { buildOpenApi } from './openapi';
|
|
19
|
+
*
|
|
20
|
+
* // Build route registry from controllers
|
|
21
|
+
* const registry = buildRegistry([UserController, ProductController]);
|
|
22
|
+
*
|
|
23
|
+
* // Generate OpenAPI specification
|
|
24
|
+
* const openApiDoc = buildOpenApi(registry, {
|
|
25
|
+
* title: 'My API',
|
|
26
|
+
* version: '1.0.0',
|
|
27
|
+
* servers: [
|
|
28
|
+
* { url: 'https://api.example.com/v1', description: 'Production server' },
|
|
29
|
+
* { url: 'https://staging.api.example.com/v1', description: 'Staging server' }
|
|
30
|
+
* ],
|
|
31
|
+
* defaultRequestContentType: 'application/json',
|
|
32
|
+
* defaultResponseContentType: 'application/json'
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* // Serve the OpenAPI JSON
|
|
36
|
+
* app.get('/openapi.json', (req, res) => {
|
|
37
|
+
* res.json(openApiDoc);
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* // With custom content types
|
|
44
|
+
* const openApiDoc = buildOpenApi(registry, {
|
|
45
|
+
* title: 'Multi-format API',
|
|
46
|
+
* version: '2.0.0',
|
|
47
|
+
* defaultRequestContentType: 'application/json',
|
|
48
|
+
* defaultResponseContentType: 'application/problem+json'
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* // The generated spec will use application/problem+json for error responses
|
|
52
|
+
* // and application/json for successful responses by default
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @see Registry for route registry structure
|
|
56
|
+
* @see OpenApiDocument for the returned document structure
|
|
57
|
+
*/
|
|
4
58
|
export function buildOpenApi(registry, opts) {
|
|
5
59
|
const schemaReg = new OasSchemaRegistry();
|
|
6
60
|
const doc = {
|
|
@@ -8,7 +62,6 @@ export function buildOpenApi(registry, opts) {
|
|
|
8
62
|
info: { title: opts.title, version: opts.version },
|
|
9
63
|
...(opts.servers !== undefined ? { servers: opts.servers } : {}),
|
|
10
64
|
paths: {},
|
|
11
|
-
components: {},
|
|
12
65
|
};
|
|
13
66
|
for (const r of registry.routes) {
|
|
14
67
|
const pathKey = r.fullPath;
|
|
@@ -16,11 +69,12 @@ export function buildOpenApi(registry, opts) {
|
|
|
16
69
|
const method = r.method.toLowerCase();
|
|
17
70
|
const ro = (r.options ?? {});
|
|
18
71
|
const op = {
|
|
19
|
-
operationId: `${r.controller.name}.${r.handlerName}`,
|
|
72
|
+
operationId: ro.operationId ?? `${r.controller.name}.${r.handlerName}`,
|
|
20
73
|
...(ro.summary !== undefined ? { summary: ro.summary } : {}),
|
|
21
74
|
...(ro.description !== undefined ? { description: ro.description } : {}),
|
|
22
75
|
...(ro.tags !== undefined ? { tags: ro.tags } : {}),
|
|
23
76
|
...(ro.deprecated !== undefined ? { deprecated: ro.deprecated } : {}),
|
|
77
|
+
...(ro.security !== undefined ? { security: ro.security } : {}),
|
|
24
78
|
parameters: [],
|
|
25
79
|
responses: {},
|
|
26
80
|
};
|
|
@@ -28,9 +82,17 @@ export function buildOpenApi(registry, opts) {
|
|
|
28
82
|
addQueryParams(op, ro);
|
|
29
83
|
addRequestBody(op, r, ro, schemaReg, opts.defaultRequestContentType ?? 'application/json');
|
|
30
84
|
addResponses(op, r, ro, schemaReg, opts.defaultResponseContentType ?? 'application/json');
|
|
31
|
-
doc.paths[pathKey]
|
|
85
|
+
const pathItem = doc.paths[pathKey] ?? {};
|
|
86
|
+
pathItem[method] = op;
|
|
87
|
+
doc.paths[pathKey] = pathItem;
|
|
88
|
+
}
|
|
89
|
+
const components = schemaReg.getComponents();
|
|
90
|
+
if (registry.securitySchemes && Object.keys(registry.securitySchemes).length) {
|
|
91
|
+
components.securitySchemes = registry.securitySchemes;
|
|
92
|
+
}
|
|
93
|
+
if (Object.keys(components).length) {
|
|
94
|
+
doc.components = components;
|
|
32
95
|
}
|
|
33
|
-
doc.components = schemaReg.getComponents();
|
|
34
96
|
return doc;
|
|
35
97
|
}
|
|
36
98
|
function addPathParams(op, r, ro) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildOpenApi.js","sourceRoot":"","sources":["../../../src/core/openapi/buildOpenApi.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"buildOpenApi.js","sourceRoot":"","sources":["../../../src/core/openapi/buildOpenApi.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import type { Schema } from '../../../validation/native/schema.js';
|
|
|
3
3
|
export declare class OasSchemaRegistry {
|
|
4
4
|
private components;
|
|
5
5
|
private seen;
|
|
6
|
-
toSchemaRef(schema: Schema<
|
|
6
|
+
toSchemaRef(schema: Schema<unknown>): SchemaObject | ReferenceObject;
|
|
7
7
|
getComponents(): ComponentsObject;
|
|
8
8
|
}
|
|
9
9
|
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../src/core/openapi/schema/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACxG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAC;AAGnE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,IAAI,CAAiC;IAE7C,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../src/core/openapi/schema/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACxG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAC;AAGnE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,IAAI,CAAiC;IAE7C,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,YAAY,GAAG,eAAe;IAgBpE,aAAa,IAAI,gBAAgB;CAGlC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../src/core/openapi/schema/registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,OAAO,iBAAiB;IACpB,UAAU,GAAiC,EAAE,CAAC;IAC9C,IAAI,GAAG,IAAI,OAAO,EAAkB,CAAC;IAE7C,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../src/core/openapi/schema/registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,OAAO,iBAAiB;IACpB,UAAU,GAAiC,EAAE,CAAC;IAC9C,IAAI,GAAG,IAAI,OAAO,EAAkB,CAAC;IAE7C,WAAW,CAAC,MAAuB;QACjC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAgB,CAAC,CAAC;YACjD,MAAM,IAAI,GAAG,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC;YAErC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAgB,EAAE,IAAI,CAAC,CAAC;gBACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACnD,CAAC;YAED,OAAO,EAAE,IAAI,EAAE,wBAAwB,IAAI,EAAE,EAAE,CAAC;QAClD,CAAC;QAED,OAAO,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,aAAa;QACX,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACjF,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildRegistry.d.ts","sourceRoot":"","sources":["../../../src/core/registry/buildRegistry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"buildRegistry.d.ts","sourceRoot":"","sources":["../../../src/core/registry/buildRegistry.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAmB,QAAQ,EAAc,MAAM,YAAY,CAAC;AAkCxF,wBAAgB,aAAa,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,QAAQ,CAsDrE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { META } from '../../metadata/keys.js';
|
|
1
|
+
import { META, } from '../../metadata/keys.js';
|
|
2
2
|
import { bagFromClass, bagGet } from '../../metadata/bag.js';
|
|
3
3
|
import { mergeBags } from '../../metadata/merge.js';
|
|
4
4
|
import { joinPaths } from './normalize.js';
|
|
@@ -6,11 +6,12 @@ import { assertNoRouteConflicts } from './conflicts.js';
|
|
|
6
6
|
function mergedBagFromClass(ctor) {
|
|
7
7
|
const chain = [];
|
|
8
8
|
let cur = ctor;
|
|
9
|
-
while (typeof cur === 'function'
|
|
9
|
+
while (cur && typeof cur === 'function') {
|
|
10
10
|
chain.push(cur);
|
|
11
|
-
|
|
12
|
-
if (!
|
|
11
|
+
const parent = Object.getPrototypeOf(cur);
|
|
12
|
+
if (!parent || parent === Function || parent === Function.prototype)
|
|
13
13
|
break;
|
|
14
|
+
cur = parent;
|
|
14
15
|
}
|
|
15
16
|
chain.reverse();
|
|
16
17
|
let merged = {};
|
|
@@ -29,6 +30,7 @@ function requireControllerMeta(ctor, bag) {
|
|
|
29
30
|
export function buildRegistry(controllers) {
|
|
30
31
|
const controllerEntries = [];
|
|
31
32
|
const routes = [];
|
|
33
|
+
const securitySchemes = {};
|
|
32
34
|
for (const ctor of controllers) {
|
|
33
35
|
const mergedBag = mergedBagFromClass(ctor);
|
|
34
36
|
const controllerMeta = requireControllerMeta(ctor, mergedBag);
|
|
@@ -38,8 +40,16 @@ export function buildRegistry(controllers) {
|
|
|
38
40
|
throw new Error(`Invalid route metadata on ${ctor.name}: expected an array at META.routes.`);
|
|
39
41
|
}
|
|
40
42
|
const bindingsMeta = mergedBag[META.bindings];
|
|
43
|
+
const docsMeta = bagGet(mergedBag, META.docs);
|
|
44
|
+
const securityMeta = bagGet(mergedBag, META.security);
|
|
45
|
+
if (securityMeta?.schemes) {
|
|
46
|
+
Object.assign(securitySchemes, securityMeta.schemes);
|
|
47
|
+
}
|
|
41
48
|
for (const rm of routeMetas) {
|
|
42
49
|
const fullPath = joinPaths(controllerMeta.basePath, rm.path);
|
|
50
|
+
const baseDocs = docsMeta ? baseDocsToRouteOptions(docsMeta) : undefined;
|
|
51
|
+
const methodDocs = docsMeta?.byMethod?.[rm.name];
|
|
52
|
+
const mergedOptions = mergeRouteOptions(rm.options, baseDocs, methodDocs);
|
|
43
53
|
const methodBindings = bindingsMeta?.byMethod?.[rm.name];
|
|
44
54
|
routes.push({
|
|
45
55
|
method: rm.method,
|
|
@@ -47,7 +57,7 @@ export function buildRegistry(controllers) {
|
|
|
47
57
|
routePath: rm.path,
|
|
48
58
|
handlerName: rm.name,
|
|
49
59
|
controller: ctor,
|
|
50
|
-
options: rm.options,
|
|
60
|
+
...(mergedOptions ? { options: mergedOptions } : { options: rm.options }),
|
|
51
61
|
...(methodBindings ? { bindings: { byMethod: { [rm.name]: methodBindings } } } : {}),
|
|
52
62
|
});
|
|
53
63
|
}
|
|
@@ -56,6 +66,40 @@ export function buildRegistry(controllers) {
|
|
|
56
66
|
return {
|
|
57
67
|
controllers: controllerEntries,
|
|
58
68
|
routes,
|
|
69
|
+
...(Object.keys(securitySchemes).length ? { securitySchemes } : {}),
|
|
59
70
|
};
|
|
60
71
|
}
|
|
72
|
+
function baseDocsToRouteOptions(docs) {
|
|
73
|
+
const out = {};
|
|
74
|
+
if (docs.tags?.length)
|
|
75
|
+
out.tags = [...docs.tags];
|
|
76
|
+
if (docs.security !== undefined)
|
|
77
|
+
out.security = docs.security;
|
|
78
|
+
return Object.keys(out).length ? out : undefined;
|
|
79
|
+
}
|
|
80
|
+
function mergeRouteOptions(base, ...overlays) {
|
|
81
|
+
if (!base && overlays.every((o) => !o))
|
|
82
|
+
return base;
|
|
83
|
+
const out = { ...(base ?? {}) };
|
|
84
|
+
for (const overlay of overlays) {
|
|
85
|
+
if (!overlay)
|
|
86
|
+
continue;
|
|
87
|
+
if (overlay.tags?.length) {
|
|
88
|
+
out.tags = [...(out.tags ?? []), ...overlay.tags];
|
|
89
|
+
}
|
|
90
|
+
if (overlay.operationId !== undefined)
|
|
91
|
+
out.operationId = overlay.operationId;
|
|
92
|
+
if (overlay.deprecated !== undefined)
|
|
93
|
+
out.deprecated = overlay.deprecated;
|
|
94
|
+
if (overlay.security !== undefined)
|
|
95
|
+
out.security = overlay.security;
|
|
96
|
+
if (overlay.responses) {
|
|
97
|
+
out.responses = {
|
|
98
|
+
...(out.responses ?? {}),
|
|
99
|
+
...overlay.responses,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return out;
|
|
104
|
+
}
|
|
61
105
|
//# sourceMappingURL=buildRegistry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildRegistry.js","sourceRoot":"","sources":["../../../src/core/registry/buildRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"buildRegistry.js","sourceRoot":"","sources":["../../../src/core/registry/buildRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,32 +1,225 @@
|
|
|
1
1
|
import type { BindingsMeta, ControllerMeta, RouteMeta } from '../../metadata/keys.js';
|
|
2
|
-
|
|
2
|
+
import type { SecuritySchemeObject } from '../../contracts/openapi-v3.js';
|
|
3
|
+
/**
|
|
4
|
+
* Constructor type for controller classes.
|
|
5
|
+
*
|
|
6
|
+
* Represents a class constructor that can be instantiated
|
|
7
|
+
* to create controller instances for handling requests.
|
|
8
|
+
*
|
|
9
|
+
* @template T - The controller instance type
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Controller class
|
|
14
|
+
* class UserController {
|
|
15
|
+
* @Get('/users')
|
|
16
|
+
* async listUsers() {
|
|
17
|
+
* return await userService.findAll();
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* // Controller constructor type
|
|
22
|
+
* const UserControllerCtor: ControllerCtor<UserController> = UserController;
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export type ControllerCtor<T = unknown> = new (...args: never[]) => T;
|
|
26
|
+
/**
|
|
27
|
+
* Registry entry for a controller.
|
|
28
|
+
*
|
|
29
|
+
* Contains the controller constructor and its associated metadata,
|
|
30
|
+
* which is used during route registration and runtime processing.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* // Controller entry in registry
|
|
35
|
+
* const userControllerEntry: ControllerEntry = {
|
|
36
|
+
* ctor: UserController,
|
|
37
|
+
* meta: {
|
|
38
|
+
* basePath: '/api/v1/users'
|
|
39
|
+
* }
|
|
40
|
+
* };
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
3
43
|
export type ControllerEntry = {
|
|
44
|
+
/** Controller constructor function */
|
|
4
45
|
ctor: ControllerCtor;
|
|
46
|
+
/** Controller metadata including base path */
|
|
5
47
|
meta: ControllerMeta;
|
|
6
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* Registry entry for an individual route.
|
|
51
|
+
*
|
|
52
|
+
* Contains comprehensive information about a route including its HTTP method,
|
|
53
|
+
* path templates, controller association, and configuration options.
|
|
54
|
+
* This information is used for request routing, OpenAPI generation,
|
|
55
|
+
* and runtime route processing.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* // Route entry for a GET /users/:id endpoint
|
|
60
|
+
* const userRouteEntry: RouteEntry = {
|
|
61
|
+
* method: 'GET',
|
|
62
|
+
* fullPath: '/users/{id}',
|
|
63
|
+
* routePath: '/{id}',
|
|
64
|
+
* handlerName: 'getUser',
|
|
65
|
+
* controller: UserController,
|
|
66
|
+
* options: {
|
|
67
|
+
* summary: 'Get user by ID',
|
|
68
|
+
* responses: {
|
|
69
|
+
* 200: { description: 'User found' },
|
|
70
|
+
* 404: { description: 'User not found' }
|
|
71
|
+
* }
|
|
72
|
+
* },
|
|
73
|
+
* bindings: {
|
|
74
|
+
* byMethod: {
|
|
75
|
+
* getUser: {
|
|
76
|
+
* path: { id: 'uuid' }
|
|
77
|
+
* }
|
|
78
|
+
* }
|
|
79
|
+
* }
|
|
80
|
+
* };
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* // Route entry for a POST /users endpoint
|
|
86
|
+
* const createUserRouteEntry: RouteEntry = {
|
|
87
|
+
* method: 'POST',
|
|
88
|
+
* fullPath: '/users',
|
|
89
|
+
* routePath: '/',
|
|
90
|
+
* handlerName: 'createUser',
|
|
91
|
+
* controller: UserController,
|
|
92
|
+
* options: {
|
|
93
|
+
* summary: 'Create new user',
|
|
94
|
+
* responses: {
|
|
95
|
+
* 201: { description: 'User created' },
|
|
96
|
+
* 400: { description: 'Invalid user data' }
|
|
97
|
+
* }
|
|
98
|
+
* }
|
|
99
|
+
* };
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
7
102
|
export type RouteEntry = {
|
|
103
|
+
/** HTTP method for this route */
|
|
8
104
|
method: RouteMeta['method'];
|
|
9
105
|
/**
|
|
10
106
|
* Full, normalized path template, e.g. "/users/{id}"
|
|
107
|
+
*
|
|
108
|
+
* This includes the controller base path combined with the route path
|
|
11
109
|
*/
|
|
12
110
|
fullPath: string;
|
|
13
111
|
/**
|
|
14
112
|
* Raw route template as declared on the method, e.g. "/{id}"
|
|
113
|
+
*
|
|
114
|
+
* This is the path template as written in the decorator
|
|
15
115
|
*/
|
|
16
116
|
routePath: string;
|
|
17
117
|
/**
|
|
18
118
|
* The handler name on the controller, e.g. "get"
|
|
119
|
+
*
|
|
120
|
+
* This is the method name where the route is defined
|
|
19
121
|
*/
|
|
20
122
|
handlerName: string;
|
|
123
|
+
/** Controller constructor that defines this route */
|
|
21
124
|
controller: ControllerCtor;
|
|
22
125
|
/**
|
|
23
126
|
* Whatever the decorator carried (docs/security/etc). Compiler can refine later.
|
|
127
|
+
*
|
|
128
|
+
* Contains route-specific configuration including documentation,
|
|
129
|
+
* security requirements, responses, and other metadata
|
|
24
130
|
*/
|
|
25
131
|
options?: unknown;
|
|
132
|
+
/** Parameter binding configuration for this route */
|
|
26
133
|
bindings?: BindingsMeta;
|
|
27
134
|
};
|
|
135
|
+
/**
|
|
136
|
+
* Complete route registry containing all registered controllers and routes.
|
|
137
|
+
*
|
|
138
|
+
* The registry is the central data structure that contains all the metadata
|
|
139
|
+
* needed for request routing, OpenAPI documentation generation,
|
|
140
|
+
* and runtime processing. It's built during application startup
|
|
141
|
+
* by scanning controller classes and their decorators.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```typescript
|
|
145
|
+
* // Example registry with user and product controllers
|
|
146
|
+
* const appRegistry: Registry = {
|
|
147
|
+
* controllers: [
|
|
148
|
+
* {
|
|
149
|
+
* ctor: UserController,
|
|
150
|
+
* meta: { basePath: '/api/v1/users' }
|
|
151
|
+
* },
|
|
152
|
+
* {
|
|
153
|
+
* ctor: ProductController,
|
|
154
|
+
* meta: { basePath: '/api/v1/products' }
|
|
155
|
+
* }
|
|
156
|
+
* ],
|
|
157
|
+
* routes: [
|
|
158
|
+
* // UserController routes
|
|
159
|
+
* {
|
|
160
|
+
* method: 'GET',
|
|
161
|
+
* fullPath: '/api/v1/users',
|
|
162
|
+
* routePath: '/',
|
|
163
|
+
* handlerName: 'listUsers',
|
|
164
|
+
* controller: UserController,
|
|
165
|
+
* options: { summary: 'List all users' }
|
|
166
|
+
* },
|
|
167
|
+
* {
|
|
168
|
+
* method: 'GET',
|
|
169
|
+
* fullPath: '/api/v1/users/{id}',
|
|
170
|
+
* routePath: '/{id}',
|
|
171
|
+
* handlerName: 'getUser',
|
|
172
|
+
* controller: UserController,
|
|
173
|
+
* options: { summary: 'Get user by ID' }
|
|
174
|
+
* },
|
|
175
|
+
* // ProductController routes
|
|
176
|
+
* {
|
|
177
|
+
* method: 'GET',
|
|
178
|
+
* fullPath: '/api/v1/products',
|
|
179
|
+
* routePath: '/',
|
|
180
|
+
* handlerName: 'listProducts',
|
|
181
|
+
* controller: ProductController,
|
|
182
|
+
* options: { summary: 'List all products' }
|
|
183
|
+
* }
|
|
184
|
+
* ],
|
|
185
|
+
* securitySchemes: {
|
|
186
|
+
* bearerAuth: {
|
|
187
|
+
* type: 'http',
|
|
188
|
+
* scheme: 'bearer',
|
|
189
|
+
* bearerFormat: 'JWT'
|
|
190
|
+
* }
|
|
191
|
+
* }
|
|
192
|
+
* };
|
|
193
|
+
* ```
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```typescript
|
|
197
|
+
* // Using the registry for OpenAPI generation
|
|
198
|
+
* import { buildOpenApi } from './openapi';
|
|
199
|
+
*
|
|
200
|
+
* const registry = buildRegistry([UserController, ProductController]);
|
|
201
|
+
* const openApiDoc = buildOpenApi(registry, {
|
|
202
|
+
* title: 'My API',
|
|
203
|
+
* version: '1.0.0'
|
|
204
|
+
* });
|
|
205
|
+
*
|
|
206
|
+
* // Using the registry for Express routing
|
|
207
|
+
* import { applyRegistryToExpressRouter } from './express';
|
|
208
|
+
*
|
|
209
|
+
* const router = express.Router();
|
|
210
|
+
* applyRegistryToExpressRouter(router, registry);
|
|
211
|
+
* ```
|
|
212
|
+
*
|
|
213
|
+
* @see buildRegistry for creating registries from controllers
|
|
214
|
+
* @see buildOpenApi for OpenAPI documentation generation
|
|
215
|
+
* @see applyRegistryToExpressRouter for Express integration
|
|
216
|
+
*/
|
|
28
217
|
export type Registry = {
|
|
218
|
+
/** Array of all registered controllers */
|
|
29
219
|
controllers: ControllerEntry[];
|
|
220
|
+
/** Array of all registered routes */
|
|
30
221
|
routes: RouteEntry[];
|
|
222
|
+
/** Security schemes available for the API */
|
|
223
|
+
securitySchemes?: Record<string, SecuritySchemeObject>;
|
|
31
224
|
};
|
|
32
225
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/registry/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/registry/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAEtE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,sCAAsC;IACtC,IAAI,EAAE,cAAc,CAAC;IACrB,8CAA8C;IAC9C,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,iCAAiC;IACjC,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB,qDAAqD;IACrD,UAAU,EAAE,cAAc,CAAC;IAE3B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiFG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,0CAA0C;IAC1C,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,qCAAqC;IACrC,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,6CAA6C;IAC7C,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CACxD,CAAC"}
|
|
@@ -1,8 +1,102 @@
|
|
|
1
1
|
import type { Reply, ReplyHeaders } from '../../contracts/reply.js';
|
|
2
|
+
/**
|
|
3
|
+
* Initialization options for creating Reply objects.
|
|
4
|
+
*
|
|
5
|
+
* These options allow customization of response headers and content type.
|
|
6
|
+
*/
|
|
2
7
|
export type ReplyInit = {
|
|
8
|
+
/** Custom response headers */
|
|
3
9
|
headers?: ReplyHeaders;
|
|
10
|
+
/** Content type header (convenience property) */
|
|
4
11
|
contentType?: string;
|
|
5
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* Creates a typed HTTP response with body content.
|
|
15
|
+
*
|
|
16
|
+
* This function creates a Reply object with status code, body, and optional headers.
|
|
17
|
+
* It's the primary way to create successful responses with content in Adorn API.
|
|
18
|
+
*
|
|
19
|
+
* @template TBody - Type of the response body
|
|
20
|
+
* @template TStatus - HTTP status code (must be a number literal)
|
|
21
|
+
* @param status - HTTP status code
|
|
22
|
+
* @param body - Response body content
|
|
23
|
+
* @param init - Optional initialization options (headers, contentType)
|
|
24
|
+
* @returns Typed Reply object
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // Simple JSON response
|
|
29
|
+
* return reply(200, { message: 'Success', data: user });
|
|
30
|
+
*
|
|
31
|
+
* // Response with custom headers
|
|
32
|
+
* return reply(201, createdUser, {
|
|
33
|
+
* headers: { 'Location': `/users/${createdUser.id}` },
|
|
34
|
+
* contentType: 'application/json'
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* // Error response
|
|
38
|
+
* return reply(404, { error: 'User not found', code: 'USER_NOT_FOUND' });
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* // In a controller
|
|
44
|
+
* @Get('/users/:id')
|
|
45
|
+
* async getUser(id: string) {
|
|
46
|
+
* const user = await userService.findById(id);
|
|
47
|
+
* if (!user) {
|
|
48
|
+
* return reply(404, { error: 'User not found' });
|
|
49
|
+
* }
|
|
50
|
+
* return reply(200, user);
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @see Reply for the return type structure
|
|
55
|
+
* @see noContent for responses without body
|
|
56
|
+
*/
|
|
6
57
|
export declare function reply<TBody, const TStatus extends number>(status: TStatus, body: TBody, init?: ReplyInit): Reply<TBody, TStatus>;
|
|
58
|
+
/**
|
|
59
|
+
* Creates a typed HTTP response without body content.
|
|
60
|
+
*
|
|
61
|
+
* This function creates a Reply object for responses that don't include a body,
|
|
62
|
+
* such as 204 No Content responses. It's commonly used for successful DELETE operations
|
|
63
|
+
* or other operations where no response body is needed.
|
|
64
|
+
*
|
|
65
|
+
* @template TStatus - HTTP status code (default: 204, must be a number literal)
|
|
66
|
+
* @param status - Optional HTTP status code (default: 204)
|
|
67
|
+
* @param init - Optional initialization options (headers, contentType)
|
|
68
|
+
* @returns Typed Reply object without body
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* // Standard 204 No Content response
|
|
73
|
+
* return noContent();
|
|
74
|
+
*
|
|
75
|
+
* // Custom no-content status with headers
|
|
76
|
+
* return noContent(202, {
|
|
77
|
+
* headers: { 'X-Request-Processed': 'true' }
|
|
78
|
+
* });
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* // In a DELETE controller
|
|
84
|
+
* @Delete('/users/:id')
|
|
85
|
+
* async deleteUser(id: string) {
|
|
86
|
+
* await userService.delete(id);
|
|
87
|
+
* return noContent(); // 204 No Content
|
|
88
|
+
* }
|
|
89
|
+
*
|
|
90
|
+
* // Custom accepted response
|
|
91
|
+
* @Post('/users/bulk-delete')
|
|
92
|
+
* async bulkDeleteUser(ids: string[]) {
|
|
93
|
+
* await userService.bulkDelete(ids);
|
|
94
|
+
* return noContent(202); // 202 Accepted
|
|
95
|
+
* }
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* @see Reply for the return type structure
|
|
99
|
+
* @see reply for responses with body content
|
|
100
|
+
*/
|
|
7
101
|
export declare function noContent<const TStatus extends number = 204>(status?: TStatus, init?: ReplyInit): Reply<undefined, TStatus>;
|
|
8
102
|
//# sourceMappingURL=reply.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reply.d.ts","sourceRoot":"","sources":["../../../src/core/reply/reply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEpE,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,SAAS,MAAM,EACvD,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,KAAK,EACX,IAAI,GAAE,SAAc,GACnB,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAQvB;AAED,wBAAgB,SAAS,CAAC,KAAK,CAAC,OAAO,SAAS,MAAM,GAAG,GAAG,EAC1D,MAAM,CAAC,EAAE,OAAO,EAChB,IAAI,GAAE,SAAc,GACnB,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAO3B"}
|
|
1
|
+
{"version":3,"file":"reply.d.ts","sourceRoot":"","sources":["../../../src/core/reply/reply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEpE;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,SAAS,MAAM,EACvD,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,KAAK,EACX,IAAI,GAAE,SAAc,GACnB,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAQvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,SAAS,CAAC,KAAK,CAAC,OAAO,SAAS,MAAM,GAAG,GAAG,EAC1D,MAAM,CAAC,EAAE,OAAO,EAChB,IAAI,GAAE,SAAc,GACnB,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAO3B"}
|