@zenofolio/hyper-decor 1.0.72 → 1.0.73
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/.agent/rules/philosophy.md +103 -0
- package/.agent/rules/writing.md +32 -0
- package/README.md +125 -136
- package/dist/__internals/constants.d.ts +1 -62
- package/dist/__internals/constants.js +3 -69
- package/dist/__internals/helpers/merge-metadata.d.ts +2 -3
- package/dist/__internals/helpers/merge-metadata.js +31 -7
- package/dist/__internals/helpers/prepare.helper.d.ts +4 -10
- package/dist/__internals/helpers/prepare.helper.js +316 -271
- package/dist/__internals/stores/hyper.store.d.ts +5 -0
- package/dist/__internals/stores/hyper.store.js +5 -0
- package/dist/__internals/stores/index.d.ts +4 -0
- package/dist/__internals/stores/index.js +20 -0
- package/dist/__internals/stores/meta.store.d.ts +34 -0
- package/dist/__internals/stores/meta.store.js +107 -0
- package/dist/__internals/stores/scope.store.d.ts +14 -0
- package/dist/__internals/stores/scope.store.js +29 -0
- package/dist/__internals/stores/serivces.store.d.ts +1 -0
- package/dist/__internals/stores/serivces.store.js +4 -0
- package/dist/__internals/transform/middleware.transform.d.ts +1 -1
- package/dist/__internals/transform/middleware.transform.js +1 -1
- package/dist/__internals/transform/role.transform.d.ts +1 -1
- package/dist/__internals/transform/role.transform.js +4 -4
- package/dist/__internals/transform/scope.transfrom.d.ts +1 -1
- package/dist/__internals/transform/scope.transfrom.js +2 -2
- package/dist/__internals/types.d.ts +53 -4
- package/dist/common/bootstrap.d.ts +6 -2
- package/dist/common/bootstrap.js +44 -10
- package/dist/common/transport.d.ts +1 -0
- package/dist/common/transport.js +27 -14
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +2 -1
- package/dist/decorators.d.ts +1 -0
- package/dist/decorators.js +17 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.js +6 -5
- package/dist/lib/event/meta.store.d.ts +4 -0
- package/dist/lib/event/meta.store.js +5 -0
- package/dist/lib/openapi/collectors/class.collector.d.ts +5 -9
- package/dist/lib/openapi/collectors/class.collector.js +6 -63
- package/dist/lib/openapi/collectors/index.d.ts +3 -4
- package/dist/lib/openapi/collectors/index.js +0 -1
- package/dist/lib/openapi/collectors/method.collector.d.ts +6 -1
- package/dist/lib/openapi/collectors/method.collector.js +92 -59
- package/dist/lib/openapi/collectors/schema.collector.d.ts +3 -8
- package/dist/lib/openapi/collectors/schema.collector.js +17 -25
- package/dist/lib/openapi/constants.d.ts +1 -0
- package/dist/lib/openapi/constants.js +2 -2
- package/dist/lib/openapi/decorators.d.ts +16 -0
- package/dist/lib/openapi/decorators.js +93 -0
- package/dist/lib/openapi/index.d.ts +29 -5
- package/dist/lib/openapi/index.js +119 -5
- package/dist/lib/openapi/metadata.d.ts +7 -0
- package/dist/lib/openapi/metadata.js +8 -0
- package/dist/lib/openapi/metadata.registry.d.ts +1 -1
- package/dist/lib/server/decorators/File.d.ts +37 -0
- package/dist/lib/server/decorators/File.js +167 -0
- package/dist/lib/server/decorators/Http.d.ts +12 -0
- package/dist/lib/server/decorators/Http.js +56 -0
- package/dist/lib/server/decorators/HyperApp.d.ts +7 -0
- package/dist/lib/server/decorators/HyperApp.js +14 -0
- package/dist/lib/server/decorators/HyperController.d.ts +6 -0
- package/dist/lib/server/decorators/HyperController.js +27 -0
- package/dist/lib/server/decorators/HyperModule.d.ts +6 -0
- package/dist/lib/server/decorators/HyperModule.js +13 -0
- package/dist/lib/server/decorators/HyperService.d.ts +11 -0
- package/dist/lib/server/decorators/HyperService.js +30 -0
- package/dist/lib/server/decorators/Messaging.d.ts +8 -0
- package/dist/lib/server/decorators/Messaging.js +19 -0
- package/dist/lib/server/decorators/Middleware.d.ts +18 -0
- package/dist/lib/server/decorators/Middleware.js +52 -0
- package/dist/lib/server/decorators/Output.d.ts +6 -0
- package/dist/lib/server/decorators/Output.js +14 -0
- package/dist/lib/server/decorators/Pass.d.ts +10 -0
- package/dist/lib/server/decorators/Pass.js +13 -0
- package/dist/lib/server/decorators/Role.d.ts +7 -0
- package/dist/lib/server/decorators/Role.js +14 -0
- package/dist/lib/server/decorators/Routes.d.ts +14 -0
- package/dist/lib/server/decorators/Routes.js +39 -0
- package/dist/lib/server/decorators/Scope.d.ts +7 -0
- package/dist/lib/server/decorators/Scope.js +14 -0
- package/dist/lib/server/decorators/index.d.ts +16 -0
- package/dist/lib/server/decorators/index.js +32 -0
- package/dist/lib/server/decorators/metadata.d.ts +1 -0
- package/dist/lib/server/decorators/metadata.js +5 -0
- package/dist/lib/server/decorators/types.d.ts +125 -0
- package/dist/lib/server/decorators/types.js +6 -0
- package/dist/lib/server/exeptions/DuplicateControllerPathException.d.ts +14 -0
- package/dist/lib/server/exeptions/DuplicateControllerPathException.js +12 -0
- package/dist/lib/server/exeptions/DuplicatedException.d.ts +8 -0
- package/dist/lib/server/exeptions/DuplicatedException.js +12 -0
- package/dist/lib/server/exeptions/DuplicatedHandlerException.d.ts +4 -0
- package/dist/lib/server/exeptions/DuplicatedHandlerException.js +12 -0
- package/dist/lib/server/exeptions/HyperException.d.ts +8 -0
- package/dist/lib/server/exeptions/HyperException.js +14 -0
- package/dist/lib/server/exeptions/HyperFileException.d.ts +4 -0
- package/dist/lib/server/exeptions/HyperFileException.js +12 -0
- package/dist/lib/server/exeptions/MethodNotFountException.d.ts +4 -0
- package/dist/lib/server/exeptions/MethodNotFountException.js +12 -0
- package/dist/lib/server/exeptions/NotPropertyException.d.ts +6 -0
- package/dist/lib/server/exeptions/NotPropertyException.js +16 -0
- package/dist/lib/server/exeptions/NotRoleException.d.ts +6 -0
- package/dist/lib/server/exeptions/NotRoleException.js +17 -0
- package/dist/lib/server/exeptions/NotScopeException.d.ts +7 -0
- package/dist/lib/server/exeptions/NotScopeException.js +18 -0
- package/dist/lib/server/exeptions/WrongPlaceException.d.ts +8 -0
- package/dist/lib/server/exeptions/WrongPlaceException.js +21 -0
- package/dist/lib/server/exeptions/index.d.ts +8 -0
- package/dist/lib/server/exeptions/index.js +18 -0
- package/dist/lib/server/exeptions/types.d.ts +1 -0
- package/dist/lib/server/exeptions/types.js +2 -0
- package/dist/lib/tree/tree.d.ts +36 -0
- package/dist/lib/tree/tree.js +106 -0
- package/package.json +1 -1
- package/scripts/clean.js +55 -55
- package/scripts/test-server.ts +85 -85
- package/vitest.config.mjs +33 -30
- package/vitest.json +0 -0
|
@@ -1,67 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.collectClassMetadata = collectClassMetadata;
|
|
4
|
-
require("
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
var _a;
|
|
11
|
-
const prototype = Reflect.getPrototypeOf(target);
|
|
12
|
-
const constructor = prototype === null || prototype === void 0 ? void 0 : prototype.constructor;
|
|
13
|
-
const name = target.name || (constructor === null || constructor === void 0 ? void 0 : constructor.name) || ((_a = target === null || target === void 0 ? void 0 : target.constructor) === null || _a === void 0 ? void 0 : _a.name);
|
|
14
|
-
// Extraemos las metadata de la clase
|
|
15
|
-
let tags = Reflect.getMetadata(constants_1.TAGS, target) || [];
|
|
16
|
-
let security = Reflect.getMetadata(constants_1.SECURITY, target) || [];
|
|
17
|
-
// Invoke custom class collectors
|
|
18
|
-
metadata_registry_1.openApiRegistry.getCollectors("class").forEach(collector => {
|
|
19
|
-
const data = collector(target);
|
|
20
|
-
if (data === null || data === void 0 ? void 0 : data.tags)
|
|
21
|
-
tags = [...tags, ...data.tags];
|
|
22
|
-
if (data === null || data === void 0 ? void 0 : data.security)
|
|
23
|
-
security = [...security, ...data.security];
|
|
24
|
-
});
|
|
25
|
-
// Si no tenemos tags, intentamos inferirlos
|
|
26
|
-
if (tags.length === 0) {
|
|
27
|
-
tags.push({ name });
|
|
28
|
-
}
|
|
29
|
-
// Si no tenemos seguridad, intentamos asignar un valor predeterminado
|
|
30
|
-
if (security.length === 0) {
|
|
31
|
-
security.push({ bearerAuth: [] });
|
|
32
|
-
}
|
|
33
|
-
// Obtenemos todos los métodos de la clase
|
|
34
|
-
const methodNames = Object.getOwnPropertyNames(target.prototype || {}).filter((method) => method !== "constructor");
|
|
35
|
-
// Creamos una lista con la metadata de cada uno de los métodos
|
|
36
|
-
const methods = {};
|
|
37
|
-
methodNames.forEach((methodName) => {
|
|
38
|
-
let methodMetadata = (0, method_collector_1.collectMethodMetadata)(target.prototype, methodName);
|
|
39
|
-
// Invoke custom method collectors
|
|
40
|
-
metadata_registry_1.openApiRegistry.getCollectors("method").forEach(collector => {
|
|
41
|
-
const data = collector(target.prototype, methodName);
|
|
42
|
-
methodMetadata = Object.assign(Object.assign({}, methodMetadata), data);
|
|
43
|
-
});
|
|
44
|
-
// Si el método no tiene parámetros definidos, intentamos inferirlos
|
|
45
|
-
if (!methodMetadata.parameters || methodMetadata.parameters.length === 0) {
|
|
46
|
-
const methodParams = (0, function_util_1.extractArgsNames)(target.prototype[methodName]);
|
|
47
|
-
methodParams === null || methodParams === void 0 ? void 0 : methodParams.forEach((paramName, index) => {
|
|
48
|
-
const inferredParam = {
|
|
49
|
-
name: paramName || `param${index}`,
|
|
50
|
-
in: "query",
|
|
51
|
-
required: true,
|
|
52
|
-
schema: {
|
|
53
|
-
type: "string",
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
methodMetadata.parameters || (methodMetadata.parameters = []);
|
|
57
|
-
methodMetadata.parameters.push(inferredParam);
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
methods[methodName] = methodMetadata;
|
|
61
|
-
});
|
|
62
|
-
return {
|
|
63
|
-
tags,
|
|
64
|
-
security,
|
|
65
|
-
methods,
|
|
66
|
-
};
|
|
4
|
+
const metadata_1 = require("../metadata");
|
|
5
|
+
/**
|
|
6
|
+
* 🏢 Extracts class-level OpenAPI metadata (Tags, Security, etc.)
|
|
7
|
+
*/
|
|
8
|
+
function collectClassMetadata(Target) {
|
|
9
|
+
return metadata_1.SwaggerMeta.get(Target);
|
|
67
10
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from "./schema.collector";
|
|
1
|
+
export * from './class.collector';
|
|
2
|
+
export * from './method.collector';
|
|
3
|
+
export * from './schema.collector';
|
|
@@ -16,5 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./class.collector"), exports);
|
|
18
18
|
__exportStar(require("./method.collector"), exports);
|
|
19
|
-
__exportStar(require("./param.collector"), exports);
|
|
20
19
|
__exportStar(require("./schema.collector"), exports);
|
|
@@ -1,2 +1,7 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
1
2
|
import { Operation } from '../types';
|
|
2
|
-
|
|
3
|
+
import { Constructor } from '../../server/decorators/types';
|
|
4
|
+
/**
|
|
5
|
+
* 🛠️ Consolidates framework metadata and OpenAPI decorators into a single Operation object.
|
|
6
|
+
*/
|
|
7
|
+
export declare function collectMethodMetadata(target: Constructor, propertyKey?: string): Operation | undefined;
|
|
@@ -1,68 +1,101 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.collectMethodMetadata = collectMethodMetadata;
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
4
|
+
require("reflect-metadata");
|
|
5
|
+
const metadata_1 = require("../metadata");
|
|
6
|
+
const metadata_2 = require("../../server/decorators/metadata");
|
|
7
7
|
const transform_registry_1 = require("../../../__internals/transform/transform.registry");
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
//
|
|
18
|
-
const
|
|
19
|
-
//
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
8
|
+
const constants_1 = require("../../../__internals/constants");
|
|
9
|
+
const schema_collector_1 = require("./schema.collector");
|
|
10
|
+
/**
|
|
11
|
+
* 🛠️ Consolidates framework metadata and OpenAPI decorators into a single Operation object.
|
|
12
|
+
*/
|
|
13
|
+
function collectMethodMetadata(target, propertyKey) {
|
|
14
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
15
|
+
if (!propertyKey)
|
|
16
|
+
return undefined;
|
|
17
|
+
// 1. Get user-defined OpenAPI metadata from decorators
|
|
18
|
+
const baseOperation = metadata_1.SwaggerMeta.get(target, propertyKey);
|
|
19
|
+
// 2. Get framework metadata (params, route, etc.)
|
|
20
|
+
const hyperMeta = metadata_2.HyperMeta.get(target, propertyKey);
|
|
21
|
+
const operation = Object.assign(Object.assign({}, baseOperation), { parameters: [...(baseOperation.parameters || [])], responses: Object.assign({}, (baseOperation.responses || {})) });
|
|
22
|
+
// 3. Bridge Parameters (@Query, @Param, @Headers)
|
|
23
|
+
if ((_a = hyperMeta.params) === null || _a === void 0 ? void 0 : _a.params) {
|
|
24
|
+
hyperMeta.params.params.forEach((param) => {
|
|
25
|
+
const inType = mapParamIn(param.decorator);
|
|
26
|
+
if (!inType)
|
|
27
|
+
return; // Skip 'body' or unknown
|
|
28
|
+
const name = param.picker || param.name || param.decorator || 'param';
|
|
29
|
+
const schema = param.schema
|
|
30
|
+
? (transform_registry_1.transformRegistry.getOpenApiSchema(param.schema) || (0, schema_collector_1.collectSchema)(param.schema))
|
|
31
|
+
: { type: 'string' };
|
|
32
|
+
// If it's an object, we might want to explode it (if it's Query/Headers)
|
|
33
|
+
// Or if it's a DTO (whole source)
|
|
34
|
+
if (schema.type === 'object' && schema.properties && (inType === 'query' || inType === 'header')) {
|
|
35
|
+
Object.entries(schema.properties).forEach(([propName, prop]) => {
|
|
36
|
+
operation.parameters.push({
|
|
37
|
+
name: propName,
|
|
38
|
+
in: inType,
|
|
39
|
+
required: true,
|
|
40
|
+
schema: prop
|
|
41
|
+
});
|
|
42
|
+
});
|
|
38
43
|
}
|
|
39
|
-
|
|
44
|
+
else {
|
|
45
|
+
operation.parameters.push({
|
|
46
|
+
name,
|
|
47
|
+
in: inType,
|
|
48
|
+
required: inType === 'path' ? true : undefined,
|
|
49
|
+
schema
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
});
|
|
40
53
|
}
|
|
41
|
-
//
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
// 4. Bridge Request Body (@Body)
|
|
55
|
+
const bodyParam = (_c = (_b = hyperMeta.params) === null || _b === void 0 ? void 0 : _b.params) === null || _c === void 0 ? void 0 : _c.find((p) => p.decorator === 'Body');
|
|
56
|
+
if (bodyParam && !operation.requestBody) {
|
|
57
|
+
let schema = bodyParam.schema
|
|
58
|
+
? (transform_registry_1.transformRegistry.getOpenApiSchema(bodyParam.schema) || (0, schema_collector_1.collectSchema)(bodyParam.schema))
|
|
59
|
+
: { type: 'object' };
|
|
60
|
+
// If a specific picker was requested, wrap the schema in an object
|
|
61
|
+
if (bodyParam.picker && bodyParam.picker !== 'body') {
|
|
62
|
+
schema = {
|
|
63
|
+
type: 'object',
|
|
64
|
+
properties: {
|
|
65
|
+
[bodyParam.picker]: schema
|
|
66
|
+
},
|
|
67
|
+
required: [bodyParam.picker]
|
|
68
|
+
};
|
|
50
69
|
}
|
|
70
|
+
operation.requestBody = {
|
|
71
|
+
content: {
|
|
72
|
+
"application/json": { schema }
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// 5. Bridge Responses (@Output)
|
|
77
|
+
const outputSchema = ((_g = (_f = (_e = (_d = baseOperation.responses) === null || _d === void 0 ? void 0 : _d["200"]) === null || _e === void 0 ? void 0 : _e.content) === null || _f === void 0 ? void 0 : _f["application/json"]) === null || _g === void 0 ? void 0 : _g.schema)
|
|
78
|
+
|| hyperMeta[constants_1.KEY_OUTPUT_SCHEMA]
|
|
79
|
+
|| hyperMeta.output;
|
|
80
|
+
if (outputSchema && !operation.responses["200"]) {
|
|
81
|
+
const schema = transform_registry_1.transformRegistry.getOpenApiSchema(outputSchema) || (0, schema_collector_1.collectSchema)(outputSchema);
|
|
82
|
+
operation.responses["200"] = {
|
|
83
|
+
description: "OK",
|
|
84
|
+
content: {
|
|
85
|
+
"application/json": { schema }
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
else if (Object.keys(operation.responses).length === 0) {
|
|
90
|
+
operation.responses["200"] = { description: "OK" };
|
|
91
|
+
}
|
|
92
|
+
return operation;
|
|
93
|
+
}
|
|
94
|
+
function mapParamIn(decorator) {
|
|
95
|
+
switch (decorator.toLowerCase()) {
|
|
96
|
+
case 'query': return 'query';
|
|
97
|
+
case 'param': return 'path';
|
|
98
|
+
case 'headers': return 'header';
|
|
99
|
+
default: return undefined;
|
|
51
100
|
}
|
|
52
|
-
// Asignamos las propiedades al objeto de metadata solo si existen
|
|
53
|
-
if (summary)
|
|
54
|
-
methodMetadata.summary = summary;
|
|
55
|
-
if (operationId)
|
|
56
|
-
methodMetadata.operationId = operationId;
|
|
57
|
-
if (tags)
|
|
58
|
-
methodMetadata.tags = tags;
|
|
59
|
-
if (security)
|
|
60
|
-
methodMetadata.security = security;
|
|
61
|
-
if (responses && Object.keys(responses).length > 0)
|
|
62
|
-
methodMetadata.responses = responses;
|
|
63
|
-
if (parameters.length > 0)
|
|
64
|
-
methodMetadata.parameters = parameters;
|
|
65
|
-
if (requestBody.content)
|
|
66
|
-
methodMetadata.requestBody = requestBody;
|
|
67
|
-
return methodMetadata;
|
|
68
101
|
}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Schema } from "../types";
|
|
1
|
+
import { Schema } from '../types';
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* 🔍 Extracts a basic OpenAPI schema from a DTO class.
|
|
4
|
+
* This is a fallback when no specific transformer (Zod, etc.) is registered.
|
|
6
5
|
*/
|
|
7
6
|
export declare function collectSchema(Target: any): Schema;
|
|
8
|
-
/**
|
|
9
|
-
* Infer OpenAPI type from JavaScript constructor names.
|
|
10
|
-
*/
|
|
11
|
-
export declare function inferType(constructorName: string): string;
|
|
@@ -1,37 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.collectSchema = collectSchema;
|
|
4
|
-
exports.inferType = inferType;
|
|
5
|
-
require("reflect-metadata");
|
|
6
4
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* 🔍 Extracts a basic OpenAPI schema from a DTO class.
|
|
6
|
+
* This is a fallback when no specific transformer (Zod, etc.) is registered.
|
|
9
7
|
*/
|
|
10
8
|
function collectSchema(Target) {
|
|
11
|
-
if (
|
|
12
|
-
return { type:
|
|
9
|
+
if (typeof Target !== 'function') {
|
|
10
|
+
return { type: 'string' };
|
|
13
11
|
}
|
|
14
12
|
const schema = {
|
|
15
|
-
type:
|
|
13
|
+
type: 'object',
|
|
16
14
|
properties: {},
|
|
17
15
|
};
|
|
18
|
-
// Note: Standard
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
16
|
+
// Note: Standard TS reflection doesn't expose fields without decorators.
|
|
17
|
+
// However, we can try to instantiate or use metadata if available.
|
|
18
|
+
// For now, we provide a placeholder that can be extended.
|
|
19
|
+
// If it's a primitive constructor
|
|
20
|
+
if (Target === String)
|
|
21
|
+
return { type: 'string' };
|
|
22
|
+
if (Target === Number)
|
|
23
|
+
return { type: 'number' };
|
|
24
|
+
if (Target === Boolean)
|
|
25
|
+
return { type: 'boolean' };
|
|
26
|
+
if (Target === Date)
|
|
27
|
+
return { type: 'string', format: 'date-time' };
|
|
22
28
|
return schema;
|
|
23
29
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Infer OpenAPI type from JavaScript constructor names.
|
|
26
|
-
*/
|
|
27
|
-
function inferType(constructorName) {
|
|
28
|
-
const map = {
|
|
29
|
-
String: "string",
|
|
30
|
-
Number: "number",
|
|
31
|
-
Boolean: "boolean",
|
|
32
|
-
Array: "array",
|
|
33
|
-
Object: "object",
|
|
34
|
-
Date: "string", // Dates are strings in OpenAPI
|
|
35
|
-
};
|
|
36
|
-
return map[constructorName] || "string";
|
|
37
|
-
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// constants.ts
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.SECURITY_OIDC = exports.SECURITY_OAUTH2 = exports.SECURITY_API_KEY = exports.COMPONENTS_SECURITY_SCHEMES = exports.COMPONENTS_PARAMETERS = exports.COMPONENTS_RESPONSES = exports.COMPONENTS_SCHEMAS = exports.COMPONENTS = exports.METHOD_TAGS = exports.METHOD_OPERATION_ID = exports.METHOD_SUMMARY = exports.METHOD_METADATA = exports.TAG_DESCRIPTION = exports.TAG_NAME = exports.TAGS = exports.SECURITY_SCHEME = exports.SECURITY = exports.RESPONSE_SCHEMA = exports.RESPONSE_CONTENT = exports.RESPONSE_DESCRIPTION = exports.RESPONSES = exports.REQUEST_BODY_CONTENT = exports.REQUEST_BODY_DESCRIPTION = exports.REQUEST_BODY = exports.PARAM_SCHEMA = exports.PARAM_DESCRIPTION = exports.PARAM_REQUIRED = exports.PARAM_IN = exports.PARAM_NAME = exports.PARAMETERS = exports.METHOD_TRACE = exports.METHOD_OPTIONS = exports.METHOD_HEAD = exports.METHOD_PATCH = exports.METHOD_DELETE = exports.METHOD_PUT = exports.METHOD_POST = exports.METHOD_GET = exports.PATHS = exports.INFO_LICENSE = exports.INFO_CONTACT = exports.INFO_TERMS_OF_SERVICE = exports.INFO_VERSION = exports.INFO_DESCRIPTION = exports.INFO_TITLE = exports.OPENAPI_VERSION = void 0;
|
|
3
|
+
exports.SECURITY_OIDC = exports.SECURITY_OAUTH2 = exports.SECURITY_API_KEY = exports.COMPONENTS_SECURITY_SCHEMES = exports.COMPONENTS_PARAMETERS = exports.COMPONENTS_RESPONSES = exports.COMPONENTS_SCHEMAS = exports.COMPONENTS = exports.METHOD_TAGS = exports.METHOD_OPERATION_ID = exports.METHOD_SUMMARY = exports.METHOD_METADATA = exports.TAG_DESCRIPTION = exports.TAG_NAME = exports.TAGS = exports.SECURITY_SCHEME = exports.SECURITY = exports.RESPONSE_SCHEMA = exports.RESPONSE_CONTENT = exports.RESPONSE_DESCRIPTION = exports.RESPONSES = exports.REQUEST_BODY_CONTENT = exports.REQUEST_BODY_DESCRIPTION = exports.REQUEST_BODY = exports.PARAM_SCHEMA = exports.PARAM_DESCRIPTION = exports.PARAM_REQUIRED = exports.PARAM_IN = exports.PARAM_NAME = exports.PARAMETERS = exports.METHOD_TRACE = exports.METHOD_OPTIONS = exports.METHOD_HEAD = exports.METHOD_PATCH = exports.METHOD_DELETE = exports.METHOD_PUT = exports.METHOD_POST = exports.METHOD_GET = exports.PATHS = exports.INFO_LICENSE = exports.INFO_CONTACT = exports.INFO_TERMS_OF_SERVICE = exports.INFO_VERSION = exports.INFO_DESCRIPTION = exports.INFO_TITLE = exports.OPENAPI_VERSION = exports.KEY_OPENAPI = void 0;
|
|
4
|
+
exports.KEY_OPENAPI = "hyper:openapi";
|
|
5
5
|
// OpenAPI Version
|
|
6
6
|
exports.OPENAPI_VERSION = "3.0.0";
|
|
7
7
|
// Info Metadata (Información general sobre la API)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Tag, OpenApiResponses, OpenApiParameter, RequestBody, SecurityRequirement, Operation } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* 📝 OpenAPI Decorators consolidated for better performance and clean imports.
|
|
4
|
+
*/
|
|
5
|
+
export declare function ApiSummary(summary: string): (target: any, propertyKey: any) => void;
|
|
6
|
+
export declare function ApiDescription(description: string): (target: any, propertyKey: any) => void;
|
|
7
|
+
export declare function ApiOperationId(operationId: string): (target: any, propertyKey: any) => void;
|
|
8
|
+
export declare function ApiTag(options: Tag | string): (target: any, propertyKey?: any) => void;
|
|
9
|
+
export declare function ApiResponse(options: OpenApiResponses): (target: any, propertyKey?: any) => void;
|
|
10
|
+
export declare function ApiParameter(options: OpenApiParameter): (target: any, propertyKey: any) => void;
|
|
11
|
+
export declare function ApiRequestBody(options: RequestBody): (target: any, propertyKey: any) => void;
|
|
12
|
+
export declare function ApiSecurity(options: SecurityRequirement): (target: any, propertyKey?: any) => void;
|
|
13
|
+
export declare function ApiBearerAuth(name?: string): (target: any, propertyKey?: any) => void;
|
|
14
|
+
export declare function ApiMethod(options: Partial<Operation>): (target: any, propertyKey: any) => void;
|
|
15
|
+
export declare function ApiNamespace(name: string): (target: any, propertyKey?: any) => void;
|
|
16
|
+
export declare function ApiIgnore(): (target: any, propertyKey?: any) => void;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiSummary = ApiSummary;
|
|
4
|
+
exports.ApiDescription = ApiDescription;
|
|
5
|
+
exports.ApiOperationId = ApiOperationId;
|
|
6
|
+
exports.ApiTag = ApiTag;
|
|
7
|
+
exports.ApiResponse = ApiResponse;
|
|
8
|
+
exports.ApiParameter = ApiParameter;
|
|
9
|
+
exports.ApiRequestBody = ApiRequestBody;
|
|
10
|
+
exports.ApiSecurity = ApiSecurity;
|
|
11
|
+
exports.ApiBearerAuth = ApiBearerAuth;
|
|
12
|
+
exports.ApiMethod = ApiMethod;
|
|
13
|
+
exports.ApiNamespace = ApiNamespace;
|
|
14
|
+
exports.ApiIgnore = ApiIgnore;
|
|
15
|
+
const metadata_1 = require("./metadata");
|
|
16
|
+
/**
|
|
17
|
+
* 📝 OpenAPI Decorators consolidated for better performance and clean imports.
|
|
18
|
+
*/
|
|
19
|
+
function ApiSummary(summary) {
|
|
20
|
+
return (target, propertyKey) => {
|
|
21
|
+
metadata_1.SwaggerMeta.set(target, propertyKey, { summary });
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function ApiDescription(description) {
|
|
25
|
+
return (target, propertyKey) => {
|
|
26
|
+
metadata_1.SwaggerMeta.set(target, propertyKey, { description });
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function ApiOperationId(operationId) {
|
|
30
|
+
return (target, propertyKey) => {
|
|
31
|
+
metadata_1.SwaggerMeta.set(target, propertyKey, { operationId });
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function ApiTag(options) {
|
|
35
|
+
const tag = typeof options === 'string' ? { name: options } : options;
|
|
36
|
+
return (target, propertyKey) => {
|
|
37
|
+
if (propertyKey) {
|
|
38
|
+
const current = metadata_1.SwaggerMeta.get(target, propertyKey);
|
|
39
|
+
const tags = [...(current.tags || []), tag];
|
|
40
|
+
// Use Map to deduplicate by name
|
|
41
|
+
const uniqueTags = Array.from(new Map(tags.map(t => [t.name, t])).values());
|
|
42
|
+
metadata_1.SwaggerMeta.set(target, propertyKey, { tags: uniqueTags });
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const current = metadata_1.SwaggerMeta.get(target);
|
|
46
|
+
const tags = [...(current.tags || []), tag];
|
|
47
|
+
const uniqueTags = Array.from(new Map(tags.map(t => [t.name, t])).values());
|
|
48
|
+
metadata_1.SwaggerMeta.set(target, undefined, { tags: uniqueTags });
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function ApiResponse(options) {
|
|
53
|
+
return (target, propertyKey) => {
|
|
54
|
+
metadata_1.SwaggerMeta.set(target, propertyKey, { responses: options });
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function ApiParameter(options) {
|
|
58
|
+
return (target, propertyKey) => {
|
|
59
|
+
const current = metadata_1.SwaggerMeta.get(target, propertyKey);
|
|
60
|
+
const parameters = [...(current.parameters || []), options];
|
|
61
|
+
metadata_1.SwaggerMeta.set(target, propertyKey, { parameters });
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function ApiRequestBody(options) {
|
|
65
|
+
return (target, propertyKey) => {
|
|
66
|
+
metadata_1.SwaggerMeta.set(target, propertyKey, { requestBody: options });
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function ApiSecurity(options) {
|
|
70
|
+
return (target, propertyKey) => {
|
|
71
|
+
const current = metadata_1.SwaggerMeta.get(target, propertyKey);
|
|
72
|
+
const security = [...(current.security || []), options];
|
|
73
|
+
metadata_1.SwaggerMeta.set(target, propertyKey, { security });
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function ApiBearerAuth(name = 'bearerAuth') {
|
|
77
|
+
return ApiSecurity({ [name]: [] });
|
|
78
|
+
}
|
|
79
|
+
function ApiMethod(options) {
|
|
80
|
+
return (target, propertyKey) => {
|
|
81
|
+
metadata_1.SwaggerMeta.set(target, propertyKey, options);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function ApiNamespace(name) {
|
|
85
|
+
return (target, propertyKey) => {
|
|
86
|
+
metadata_1.SwaggerMeta.set(target, propertyKey, { namespace: name });
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function ApiIgnore() {
|
|
90
|
+
return (target, propertyKey) => {
|
|
91
|
+
metadata_1.SwaggerMeta.set(target, propertyKey, { ignore: true });
|
|
92
|
+
};
|
|
93
|
+
}
|
|
@@ -1,6 +1,30 @@
|
|
|
1
|
-
export * from "./metadata.registry";
|
|
2
|
-
export * from "./constants";
|
|
3
|
-
export * from "./collectors";
|
|
4
|
-
export * from "./decorators";
|
|
5
|
-
export * from "./helpers";
|
|
6
1
|
export * from "./types";
|
|
2
|
+
import { ApiBearerAuth, ApiDescription, ApiOperationId, ApiParameter, ApiRequestBody, ApiResponse, ApiSecurity, ApiSummary, ApiTag, ApiMethod, ApiNamespace, ApiIgnore } from "./decorators";
|
|
3
|
+
export declare const OpenApi: {
|
|
4
|
+
Summary: typeof ApiSummary;
|
|
5
|
+
Description: typeof ApiDescription;
|
|
6
|
+
OperationId: typeof ApiOperationId;
|
|
7
|
+
Tag: typeof ApiTag;
|
|
8
|
+
Response: typeof ApiResponse;
|
|
9
|
+
Parameter: typeof ApiParameter;
|
|
10
|
+
RequestBody: typeof ApiRequestBody;
|
|
11
|
+
Security: typeof ApiSecurity;
|
|
12
|
+
BearerAuth: typeof ApiBearerAuth;
|
|
13
|
+
Method: typeof ApiMethod;
|
|
14
|
+
Namespace: typeof ApiNamespace;
|
|
15
|
+
Ignore: typeof ApiIgnore;
|
|
16
|
+
};
|
|
17
|
+
export { ApiBearerAuth, ApiDescription, ApiOperationId, ApiParameter, ApiRequestBody, ApiResponse, ApiSecurity, ApiSummary, ApiTag, ApiMethod, ApiNamespace, ApiIgnore, };
|
|
18
|
+
import { Constructor } from "../server/decorators/types";
|
|
19
|
+
import { OpenAPIDocument } from "./types";
|
|
20
|
+
/**
|
|
21
|
+
* Generates an OpenAPI specification object from a HyperApp class.
|
|
22
|
+
*
|
|
23
|
+
* @param App The Root Application Class
|
|
24
|
+
* @param options Generator options
|
|
25
|
+
* @returns OpenAPI Spec Object
|
|
26
|
+
*/
|
|
27
|
+
export declare function getOpenAPI(App: Constructor, options?: {
|
|
28
|
+
includeNamespaces?: string[];
|
|
29
|
+
excludeNamespaces?: string[];
|
|
30
|
+
}): OpenAPIDocument;
|
|
@@ -14,9 +14,123 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
__exportStar(require("./collectors"), exports);
|
|
20
|
-
__exportStar(require("./decorators"), exports);
|
|
21
|
-
__exportStar(require("./helpers"), exports);
|
|
17
|
+
exports.ApiIgnore = exports.ApiNamespace = exports.ApiMethod = exports.ApiTag = exports.ApiSummary = exports.ApiSecurity = exports.ApiResponse = exports.ApiRequestBody = exports.ApiParameter = exports.ApiOperationId = exports.ApiDescription = exports.ApiBearerAuth = exports.OpenApi = void 0;
|
|
18
|
+
exports.getOpenAPI = getOpenAPI;
|
|
22
19
|
__exportStar(require("./types"), exports);
|
|
20
|
+
const decorators_1 = require("./decorators");
|
|
21
|
+
Object.defineProperty(exports, "ApiBearerAuth", { enumerable: true, get: function () { return decorators_1.ApiBearerAuth; } });
|
|
22
|
+
Object.defineProperty(exports, "ApiDescription", { enumerable: true, get: function () { return decorators_1.ApiDescription; } });
|
|
23
|
+
Object.defineProperty(exports, "ApiOperationId", { enumerable: true, get: function () { return decorators_1.ApiOperationId; } });
|
|
24
|
+
Object.defineProperty(exports, "ApiParameter", { enumerable: true, get: function () { return decorators_1.ApiParameter; } });
|
|
25
|
+
Object.defineProperty(exports, "ApiRequestBody", { enumerable: true, get: function () { return decorators_1.ApiRequestBody; } });
|
|
26
|
+
Object.defineProperty(exports, "ApiResponse", { enumerable: true, get: function () { return decorators_1.ApiResponse; } });
|
|
27
|
+
Object.defineProperty(exports, "ApiSecurity", { enumerable: true, get: function () { return decorators_1.ApiSecurity; } });
|
|
28
|
+
Object.defineProperty(exports, "ApiSummary", { enumerable: true, get: function () { return decorators_1.ApiSummary; } });
|
|
29
|
+
Object.defineProperty(exports, "ApiTag", { enumerable: true, get: function () { return decorators_1.ApiTag; } });
|
|
30
|
+
Object.defineProperty(exports, "ApiMethod", { enumerable: true, get: function () { return decorators_1.ApiMethod; } });
|
|
31
|
+
Object.defineProperty(exports, "ApiNamespace", { enumerable: true, get: function () { return decorators_1.ApiNamespace; } });
|
|
32
|
+
Object.defineProperty(exports, "ApiIgnore", { enumerable: true, get: function () { return decorators_1.ApiIgnore; } });
|
|
33
|
+
exports.OpenApi = {
|
|
34
|
+
Summary: decorators_1.ApiSummary,
|
|
35
|
+
Description: decorators_1.ApiDescription,
|
|
36
|
+
OperationId: decorators_1.ApiOperationId,
|
|
37
|
+
Tag: decorators_1.ApiTag,
|
|
38
|
+
Response: decorators_1.ApiResponse,
|
|
39
|
+
Parameter: decorators_1.ApiParameter,
|
|
40
|
+
RequestBody: decorators_1.ApiRequestBody,
|
|
41
|
+
Security: decorators_1.ApiSecurity,
|
|
42
|
+
BearerAuth: decorators_1.ApiBearerAuth,
|
|
43
|
+
Method: decorators_1.ApiMethod,
|
|
44
|
+
Namespace: decorators_1.ApiNamespace,
|
|
45
|
+
Ignore: decorators_1.ApiIgnore,
|
|
46
|
+
};
|
|
47
|
+
const tree_1 = require("../tree/tree");
|
|
48
|
+
const metadata_registry_1 = require("./metadata.registry");
|
|
49
|
+
// --- Registration ---
|
|
50
|
+
const collectors_1 = require("./collectors");
|
|
51
|
+
metadata_registry_1.openApiRegistry.registerCollector("class", collectors_1.collectClassMetadata);
|
|
52
|
+
metadata_registry_1.openApiRegistry.registerCollector("method", collectors_1.collectMethodMetadata);
|
|
53
|
+
/**
|
|
54
|
+
* Generates an OpenAPI specification object from a HyperApp class.
|
|
55
|
+
*
|
|
56
|
+
* @param App The Root Application Class
|
|
57
|
+
* @param options Generator options
|
|
58
|
+
* @returns OpenAPI Spec Object
|
|
59
|
+
*/
|
|
60
|
+
function getOpenAPI(App, options = {}) {
|
|
61
|
+
const tree = (0, tree_1.getAppTree)(App);
|
|
62
|
+
const spec = {
|
|
63
|
+
openapi: "3.0.0",
|
|
64
|
+
info: {
|
|
65
|
+
title: tree.app.name || "HyperApp API",
|
|
66
|
+
version: tree.app.version || "1.0.0",
|
|
67
|
+
},
|
|
68
|
+
paths: {},
|
|
69
|
+
};
|
|
70
|
+
const processController = (ctrl, parentNamespace) => {
|
|
71
|
+
const ctrlOpenApi = ctrl.openapi;
|
|
72
|
+
if (ctrlOpenApi === null || ctrlOpenApi === void 0 ? void 0 : ctrlOpenApi.ignore)
|
|
73
|
+
return;
|
|
74
|
+
const ctrlNamespace = (ctrlOpenApi === null || ctrlOpenApi === void 0 ? void 0 : ctrlOpenApi.namespace) || parentNamespace;
|
|
75
|
+
ctrl.routes.forEach((route) => {
|
|
76
|
+
var _a, _b;
|
|
77
|
+
const routeOpenApi = route.openapi;
|
|
78
|
+
if (!routeOpenApi || routeOpenApi.ignore)
|
|
79
|
+
return;
|
|
80
|
+
const path = normalizePath(route.fullPath);
|
|
81
|
+
if (!spec.paths[path])
|
|
82
|
+
spec.paths[path] = {};
|
|
83
|
+
const methodNamespace = routeOpenApi.namespace || ctrlNamespace;
|
|
84
|
+
// Filtering logic
|
|
85
|
+
if (options.includeNamespaces && options.includeNamespaces.length > 0) {
|
|
86
|
+
if (!methodNamespace || !options.includeNamespaces.includes(methodNamespace))
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (options.excludeNamespaces && options.excludeNamespaces.length > 0) {
|
|
90
|
+
if (methodNamespace && options.excludeNamespaces.includes(methodNamespace))
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// --- Merge Metadata Inheritance ---
|
|
94
|
+
const ctrlData = (ctrl.openapi || {});
|
|
95
|
+
const finalOperation = Object.assign(Object.assign(Object.assign({ responses: {} }, ctrlData), routeOpenApi), {
|
|
96
|
+
// Merge Tags (unique by name)
|
|
97
|
+
tags: Array.from(new Map([
|
|
98
|
+
...(ctrlData.tags || []).map(t => [t.name, t]),
|
|
99
|
+
...(routeOpenApi.tags || []).map(t => [t.name, t])
|
|
100
|
+
]).values()),
|
|
101
|
+
// Merge Security (additive)
|
|
102
|
+
security: [
|
|
103
|
+
...(ctrlData.security || []),
|
|
104
|
+
...(routeOpenApi.security || [])
|
|
105
|
+
] });
|
|
106
|
+
// Remove empty fields to keep spec clean
|
|
107
|
+
if (((_a = finalOperation.tags) === null || _a === void 0 ? void 0 : _a.length) === 0)
|
|
108
|
+
delete finalOperation.tags;
|
|
109
|
+
if (((_b = finalOperation.security) === null || _b === void 0 ? void 0 : _b.length) === 0)
|
|
110
|
+
delete finalOperation.security;
|
|
111
|
+
spec.paths[path] = Object.assign(Object.assign({}, spec.paths[path]), { [route.method.toLowerCase()]: finalOperation });
|
|
112
|
+
});
|
|
113
|
+
// Clean up empty paths if all methods were filtered out
|
|
114
|
+
Object.keys(spec.paths).forEach(path => {
|
|
115
|
+
if (Object.keys(spec.paths[path]).length === 0) {
|
|
116
|
+
delete spec.paths[path];
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
function normalizePath(path) {
|
|
121
|
+
let normalized = path.replace(/:([a-zA-Z0-9_]+)/g, '{$1}');
|
|
122
|
+
// Remove trailing slash if it's not the root path
|
|
123
|
+
if (normalized.length > 1 && normalized.endsWith('/')) {
|
|
124
|
+
normalized = normalized.slice(0, -1);
|
|
125
|
+
}
|
|
126
|
+
return normalized;
|
|
127
|
+
}
|
|
128
|
+
const processModule = (mod) => {
|
|
129
|
+
var _a;
|
|
130
|
+
const modNamespace = (_a = mod.openapi) === null || _a === void 0 ? void 0 : _a.namespace;
|
|
131
|
+
Object.values(mod.controllers).forEach(ctrl => processController(ctrl, modNamespace));
|
|
132
|
+
Object.values(mod.modules).forEach(processModule);
|
|
133
|
+
};
|
|
134
|
+
Object.values(tree.modules).forEach(processModule);
|
|
135
|
+
return spec;
|
|
136
|
+
}
|