@kanjijs/openapi 0.2.0-beta.14 → 0.2.0-beta.16
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/dist/contracts/src/index.d.ts +27 -0
- package/dist/core/src/context.d.ts +7 -0
- package/dist/core/src/decorators.d.ts +34 -0
- package/dist/core/src/di/container.d.ts +26 -0
- package/dist/core/src/di/module-compiler.d.ts +12 -0
- package/dist/core/src/exceptions/exception.filter.d.ts +3 -0
- package/dist/core/src/exceptions/http.exception.d.ts +7 -0
- package/dist/core/src/index.d.ts +9 -0
- package/dist/core/src/metadata.d.ts +64 -0
- package/dist/index.js +105 -46
- package/dist/openapi/src/index.d.ts +14 -0
- package/package.json +2 -2
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type SchemaLike = unknown;
|
|
2
|
+
export interface ContractRequestSpec<T = SchemaLike> {
|
|
3
|
+
params?: T;
|
|
4
|
+
query?: T;
|
|
5
|
+
headers?: T;
|
|
6
|
+
cookies?: T;
|
|
7
|
+
body?: T;
|
|
8
|
+
}
|
|
9
|
+
export interface ContractResponseSpec<T = SchemaLike> {
|
|
10
|
+
[status: number]: T;
|
|
11
|
+
}
|
|
12
|
+
export interface ContractSpec<T = SchemaLike> {
|
|
13
|
+
request?: ContractRequestSpec<T>;
|
|
14
|
+
response?: ContractResponseSpec<T>;
|
|
15
|
+
}
|
|
16
|
+
export interface ValidatorAdapter<S = SchemaLike> {
|
|
17
|
+
parse<O = unknown>(schema: S, data: unknown): Promise<{
|
|
18
|
+
success: true;
|
|
19
|
+
data: O;
|
|
20
|
+
} | {
|
|
21
|
+
success: false;
|
|
22
|
+
issues: unknown[];
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
export declare class Contract {
|
|
26
|
+
static json<T = SchemaLike>(spec: ContractRequestSpec<T>): ContractSpec<T>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
export interface RequestContext {
|
|
3
|
+
requestId: string;
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}
|
|
6
|
+
export declare const kanjijsContext: AsyncLocalStorage<RequestContext>;
|
|
7
|
+
export declare function getRequestId(): string | undefined;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ContractSpec } from "@kanjijs/contracts";
|
|
2
|
+
import { type ModuleMetadata, type Token } from "./metadata";
|
|
3
|
+
/**
|
|
4
|
+
* @Module({ controllers: [...] })
|
|
5
|
+
*/
|
|
6
|
+
export declare function Module(metadata: ModuleMetadata): ClassDecorator;
|
|
7
|
+
/**
|
|
8
|
+
* @Contract({ ... })
|
|
9
|
+
*/
|
|
10
|
+
export declare function Contract(spec: ContractSpec): MethodDecorator;
|
|
11
|
+
/**
|
|
12
|
+
* @Controller('/users')
|
|
13
|
+
*/
|
|
14
|
+
export declare function Controller(prefix?: string): ClassDecorator;
|
|
15
|
+
export declare function Injectable(): ClassDecorator;
|
|
16
|
+
export declare const Get: (path?: string) => MethodDecorator;
|
|
17
|
+
export declare const Post: (path?: string) => MethodDecorator;
|
|
18
|
+
export declare const Put: (path?: string) => MethodDecorator;
|
|
19
|
+
export declare const Delete: (path?: string) => MethodDecorator;
|
|
20
|
+
export declare const Patch: (path?: string) => MethodDecorator;
|
|
21
|
+
/**
|
|
22
|
+
* @Inject("DATABASE_CLIENT")
|
|
23
|
+
*/
|
|
24
|
+
export declare function Inject(token: Token<unknown>): ParameterDecorator;
|
|
25
|
+
/**
|
|
26
|
+
* @Use(middleware1, middleware2)
|
|
27
|
+
* Attaches middlewares to a controller or method.
|
|
28
|
+
*/
|
|
29
|
+
export declare function Use(...middlewares: unknown[]): MethodDecorator & ClassDecorator;
|
|
30
|
+
export declare const Body: (data?: string) => ParameterDecorator;
|
|
31
|
+
export declare const Query: (data?: string) => ParameterDecorator;
|
|
32
|
+
export declare const Param: (data?: string) => ParameterDecorator;
|
|
33
|
+
export declare const Headers: (data?: string) => ParameterDecorator;
|
|
34
|
+
export declare const Ctx: (data?: string) => ParameterDecorator;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type Constructor, type Token } from "../metadata";
|
|
2
|
+
import "reflect-metadata";
|
|
3
|
+
export declare class KanjijsIoC {
|
|
4
|
+
private static providers;
|
|
5
|
+
static register<T>(target: Constructor<T>): void;
|
|
6
|
+
static register<T>(token: Token<T>, provider: {
|
|
7
|
+
useValue?: T;
|
|
8
|
+
useClass?: Constructor<T>;
|
|
9
|
+
}): void;
|
|
10
|
+
static resolve<T>(target: Token<T>): T;
|
|
11
|
+
static clear(): void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* V2 STRICT CONTAINER
|
|
15
|
+
* Instance-based, no auto-registration, explicit visibility.
|
|
16
|
+
*/
|
|
17
|
+
export declare class Container {
|
|
18
|
+
private providers;
|
|
19
|
+
register<T>(token: Token<T>, provider: {
|
|
20
|
+
useValue?: T;
|
|
21
|
+
useClass?: Constructor<T>;
|
|
22
|
+
useFactory?: (...args: unknown[]) => T;
|
|
23
|
+
inject?: Array<Token<unknown>>;
|
|
24
|
+
}): void;
|
|
25
|
+
resolve<T>(token: Token<T>): T;
|
|
26
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Constructor } from "../metadata";
|
|
2
|
+
import { Container } from "./container";
|
|
3
|
+
export declare class ModuleCompiler {
|
|
4
|
+
private nodes;
|
|
5
|
+
private globalExportedTokens;
|
|
6
|
+
compile(rootModule: Constructor): Container;
|
|
7
|
+
private scan;
|
|
8
|
+
private processProviders;
|
|
9
|
+
private validate;
|
|
10
|
+
private checkDependencies;
|
|
11
|
+
private registerProviders;
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type { ContractRequestSpec, ContractResponseSpec, ContractSpec, SchemaLike, ValidatorAdapter, } from "@kanjijs/contracts";
|
|
2
|
+
export * from "./context";
|
|
3
|
+
export * from "./decorators";
|
|
4
|
+
export * from "./di/container";
|
|
5
|
+
export * from "./di/module-compiler";
|
|
6
|
+
export * from "./exceptions/exception.filter";
|
|
7
|
+
export * from "./exceptions/http.exception";
|
|
8
|
+
export * from "./metadata";
|
|
9
|
+
export declare const GLOBAL_MIDDLEWARE_TOKEN: unique symbol;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ContractSpec } from "@kanjijs/contracts";
|
|
2
|
+
import "reflect-metadata";
|
|
3
|
+
export type Constructor<T = unknown> = new (...args: unknown[]) => T;
|
|
4
|
+
export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
5
|
+
export type RouteParamType = "BODY" | "QUERY" | "PARAM" | "HEADERS" | "CONTEXT";
|
|
6
|
+
export interface RouteParamMetadata {
|
|
7
|
+
index: number;
|
|
8
|
+
type: RouteParamType;
|
|
9
|
+
data?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface RouteMetadata {
|
|
12
|
+
method: HttpMethod;
|
|
13
|
+
path: string;
|
|
14
|
+
contract?: ContractSpec;
|
|
15
|
+
middlewares?: unknown[];
|
|
16
|
+
params?: RouteParamMetadata[];
|
|
17
|
+
}
|
|
18
|
+
export interface ControllerMetadata {
|
|
19
|
+
prefix: string;
|
|
20
|
+
middlewares?: unknown[];
|
|
21
|
+
}
|
|
22
|
+
export type Token<T = unknown> = string | symbol | Constructor<T>;
|
|
23
|
+
export type Provider<T = unknown> = Constructor<T> | {
|
|
24
|
+
provide: Token<T>;
|
|
25
|
+
useValue: T;
|
|
26
|
+
} | {
|
|
27
|
+
provide: Token<T>;
|
|
28
|
+
useClass: Constructor<T>;
|
|
29
|
+
} | {
|
|
30
|
+
provide: Token<T>;
|
|
31
|
+
useFactory: (...args: unknown[]) => T | Promise<T>;
|
|
32
|
+
inject?: Token[];
|
|
33
|
+
};
|
|
34
|
+
export interface DynamicModule {
|
|
35
|
+
module: Constructor;
|
|
36
|
+
providers?: Provider[];
|
|
37
|
+
imports?: Array<Constructor | DynamicModule>;
|
|
38
|
+
exports?: Token[];
|
|
39
|
+
global?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface ModuleMetadata {
|
|
42
|
+
controllers?: Constructor[];
|
|
43
|
+
providers?: Provider[];
|
|
44
|
+
imports?: Array<Constructor | DynamicModule>;
|
|
45
|
+
exports?: Token[];
|
|
46
|
+
global?: boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface IMetadataStorage {
|
|
49
|
+
addRoute(target: object, methodName: string, meta: RouteMetadata): void;
|
|
50
|
+
addContract(target: object, methodName: string, contract: ContractSpec): void;
|
|
51
|
+
addMiddleware(target: object, middleware: unknown, methodName?: string): void;
|
|
52
|
+
getRoutes(target: object): Map<string, RouteMetadata> | undefined;
|
|
53
|
+
setController(target: object, meta: ControllerMetadata): void;
|
|
54
|
+
getController(target: object): ControllerMetadata | undefined;
|
|
55
|
+
defineModule(target: object, meta: ModuleMetadata): void;
|
|
56
|
+
getModule(target: object): ModuleMetadata | undefined;
|
|
57
|
+
addInjection(target: object, index: number, token: Token<unknown>): void;
|
|
58
|
+
getInjections(target: object): Map<number, Token<unknown>> | undefined;
|
|
59
|
+
addRouteParam(target: object, methodName: string, param: RouteParamMetadata): void;
|
|
60
|
+
}
|
|
61
|
+
declare global {
|
|
62
|
+
var KANJI_METADATA_STORAGE: IMetadataStorage | undefined;
|
|
63
|
+
}
|
|
64
|
+
export declare const MetadataStorage: IMetadataStorage;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// ../core/dist/index.js
|
|
3
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
4
2
|
var __create = Object.create;
|
|
5
3
|
var __getProtoOf = Object.getPrototypeOf;
|
|
6
4
|
var __defProp = Object.defineProperty;
|
|
@@ -18,21 +16,23 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
18
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
19
|
+
|
|
20
|
+
// ../../node_modules/.bun/reflect-metadata@0.2.2/node_modules/reflect-metadata/Reflect.js
|
|
21
21
|
var require_Reflect = __commonJS(() => {
|
|
22
22
|
/*! *****************************************************************************
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
23
|
+
Copyright (C) Microsoft. All rights reserved.
|
|
24
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
25
|
+
this file except in compliance with the License. You may obtain a copy of the
|
|
26
|
+
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
27
|
+
|
|
28
|
+
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
29
|
+
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
30
|
+
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
31
|
+
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
32
|
+
|
|
33
|
+
See the Apache Version 2.0 License for specific language governing permissions
|
|
34
|
+
and limitations under the License.
|
|
35
|
+
***************************************************************************** */
|
|
36
36
|
var Reflect2;
|
|
37
37
|
(function(Reflect3) {
|
|
38
38
|
(function(factory) {
|
|
@@ -1012,6 +1012,11 @@ var require_Reflect = __commonJS(() => {
|
|
|
1012
1012
|
});
|
|
1013
1013
|
})(Reflect2 || (Reflect2 = {}));
|
|
1014
1014
|
});
|
|
1015
|
+
|
|
1016
|
+
// ../core/src/context.ts
|
|
1017
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
1018
|
+
var kanjijsContext = new AsyncLocalStorage;
|
|
1019
|
+
// ../core/src/metadata.ts
|
|
1015
1020
|
var import_reflect_metadata = __toESM(require_Reflect(), 1);
|
|
1016
1021
|
var methodMetadataStore = new WeakMap;
|
|
1017
1022
|
var controllerMetadataStore = new WeakMap;
|
|
@@ -1039,6 +1044,16 @@ if (!globalStore.KANJI_METADATA_STORAGE) {
|
|
|
1039
1044
|
existing.contract = contract;
|
|
1040
1045
|
methods.set(methodName, existing);
|
|
1041
1046
|
},
|
|
1047
|
+
addRouteParam(target, methodName, param) {
|
|
1048
|
+
let methods = methodMetadataStore.get(target);
|
|
1049
|
+
if (!methods) {
|
|
1050
|
+
methods = new Map;
|
|
1051
|
+
methodMetadataStore.set(target, methods);
|
|
1052
|
+
}
|
|
1053
|
+
const existing = methods.get(methodName) || {};
|
|
1054
|
+
existing.params = [...existing.params || [], param];
|
|
1055
|
+
methods.set(methodName, existing);
|
|
1056
|
+
},
|
|
1042
1057
|
addMiddleware(target, middleware, methodName) {
|
|
1043
1058
|
if (methodName) {
|
|
1044
1059
|
let methods = methodMetadataStore.get(target);
|
|
@@ -1084,6 +1099,8 @@ if (!globalStore.KANJI_METADATA_STORAGE) {
|
|
|
1084
1099
|
};
|
|
1085
1100
|
}
|
|
1086
1101
|
var MetadataStorage = globalStore.KANJI_METADATA_STORAGE;
|
|
1102
|
+
|
|
1103
|
+
// ../core/src/decorators.ts
|
|
1087
1104
|
function createMethodDecorator(method) {
|
|
1088
1105
|
return (path = "/") => {
|
|
1089
1106
|
return (target, propertyKey) => {
|
|
@@ -1099,6 +1116,25 @@ var Post = createMethodDecorator("POST");
|
|
|
1099
1116
|
var Put = createMethodDecorator("PUT");
|
|
1100
1117
|
var Delete = createMethodDecorator("DELETE");
|
|
1101
1118
|
var Patch = createMethodDecorator("PATCH");
|
|
1119
|
+
function createParamDecorator(type) {
|
|
1120
|
+
return (data) => {
|
|
1121
|
+
return (target, propertyKey, parameterIndex) => {
|
|
1122
|
+
if (propertyKey) {
|
|
1123
|
+
MetadataStorage.addRouteParam(target, propertyKey, {
|
|
1124
|
+
index: parameterIndex,
|
|
1125
|
+
type,
|
|
1126
|
+
data
|
|
1127
|
+
});
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
var Body = createParamDecorator("BODY");
|
|
1133
|
+
var Query = createParamDecorator("QUERY");
|
|
1134
|
+
var Param = createParamDecorator("PARAM");
|
|
1135
|
+
var Headers = createParamDecorator("HEADERS");
|
|
1136
|
+
var Ctx = createParamDecorator("CONTEXT");
|
|
1137
|
+
// ../core/src/di/container.ts
|
|
1102
1138
|
var import_reflect_metadata2 = __toESM(require_Reflect(), 1);
|
|
1103
1139
|
|
|
1104
1140
|
class KanjijsIoC {
|
|
@@ -1106,43 +1142,48 @@ class KanjijsIoC {
|
|
|
1106
1142
|
static register(tokenOrTarget, provider) {
|
|
1107
1143
|
if (provider) {
|
|
1108
1144
|
if ("useValue" in provider) {
|
|
1109
|
-
|
|
1145
|
+
KanjijsIoC.providers.set(tokenOrTarget, { useValue: provider.useValue });
|
|
1110
1146
|
} else if ("useClass" in provider) {
|
|
1111
|
-
|
|
1147
|
+
KanjijsIoC.providers.set(tokenOrTarget, { useClass: provider.useClass });
|
|
1112
1148
|
}
|
|
1113
1149
|
} else {
|
|
1114
|
-
|
|
1150
|
+
KanjijsIoC.providers.set(tokenOrTarget, {
|
|
1151
|
+
useClass: tokenOrTarget
|
|
1152
|
+
});
|
|
1115
1153
|
}
|
|
1116
1154
|
}
|
|
1117
1155
|
static resolve(target) {
|
|
1118
|
-
let provider =
|
|
1156
|
+
let provider = KanjijsIoC.providers.get(target);
|
|
1119
1157
|
if (!provider && typeof target === "function") {
|
|
1120
1158
|
provider = { useClass: target };
|
|
1121
|
-
|
|
1159
|
+
KanjijsIoC.providers.set(target, provider);
|
|
1122
1160
|
}
|
|
1123
1161
|
if (!provider) {
|
|
1124
|
-
|
|
1162
|
+
const targetName2 = typeof target === "function" ? target.name ?? "anonymous" : String(target);
|
|
1163
|
+
throw new Error(`Provider not found for token: ${targetName2}`);
|
|
1125
1164
|
}
|
|
1126
1165
|
if (provider.instance) {
|
|
1127
1166
|
return provider.instance;
|
|
1128
1167
|
}
|
|
1129
|
-
|
|
1168
|
+
const targetName = typeof target === "function" ? target.name ?? "anonymous" : String(target);
|
|
1169
|
+
console.log(`[DI] Creating NEW instance for ${targetName}`);
|
|
1130
1170
|
if (provider.useValue !== undefined) {
|
|
1131
1171
|
provider.instance = provider.useValue;
|
|
1132
1172
|
} else if (provider.useClass) {
|
|
1133
1173
|
const ConcreteClass = provider.useClass;
|
|
1134
1174
|
const paramTypes = Reflect.getMetadata("design:paramtypes", ConcreteClass) || [];
|
|
1135
1175
|
const injectionTokens = MetadataStorage.getInjections(ConcreteClass) || new Map;
|
|
1136
|
-
const injections = paramTypes.map((
|
|
1176
|
+
const injections = paramTypes.map((paramToken, index) => {
|
|
1137
1177
|
const overrideToken = injectionTokens.get(index);
|
|
1138
|
-
|
|
1178
|
+
const resolvedToken = overrideToken || paramToken;
|
|
1179
|
+
return KanjijsIoC.resolve(resolvedToken);
|
|
1139
1180
|
});
|
|
1140
1181
|
provider.instance = new ConcreteClass(...injections);
|
|
1141
1182
|
}
|
|
1142
1183
|
return provider.instance;
|
|
1143
1184
|
}
|
|
1144
1185
|
static clear() {
|
|
1145
|
-
|
|
1186
|
+
KanjijsIoC.providers.clear();
|
|
1146
1187
|
}
|
|
1147
1188
|
}
|
|
1148
1189
|
|
|
@@ -1154,7 +1195,8 @@ class Container {
|
|
|
1154
1195
|
resolve(token) {
|
|
1155
1196
|
const provider = this.providers.get(token);
|
|
1156
1197
|
if (!provider) {
|
|
1157
|
-
|
|
1198
|
+
const tokenName = typeof token === "function" ? token.name ?? "anonymous" : String(token);
|
|
1199
|
+
throw new Error(`[DI] Provider not found for token: ${tokenName}`);
|
|
1158
1200
|
}
|
|
1159
1201
|
if (provider.instance) {
|
|
1160
1202
|
return provider.instance;
|
|
@@ -1167,7 +1209,8 @@ class Container {
|
|
|
1167
1209
|
const injectionTokens = MetadataStorage.getInjections(ConcreteClass) || new Map;
|
|
1168
1210
|
const injections = paramTypes.map((paramToken, index) => {
|
|
1169
1211
|
const overrideToken = injectionTokens.get(index);
|
|
1170
|
-
|
|
1212
|
+
const resolvedToken = overrideToken || paramToken;
|
|
1213
|
+
return this.resolve(resolvedToken);
|
|
1171
1214
|
});
|
|
1172
1215
|
provider.instance = new ConcreteClass(...injections);
|
|
1173
1216
|
} else if (provider.useFactory) {
|
|
@@ -1177,7 +1220,7 @@ class Container {
|
|
|
1177
1220
|
return provider.instance;
|
|
1178
1221
|
}
|
|
1179
1222
|
}
|
|
1180
|
-
|
|
1223
|
+
// ../core/src/di/module-compiler.ts
|
|
1181
1224
|
class ModuleCompiler {
|
|
1182
1225
|
nodes = new Map;
|
|
1183
1226
|
globalExportedTokens = new Set;
|
|
@@ -1185,11 +1228,11 @@ class ModuleCompiler {
|
|
|
1185
1228
|
this.scan(rootModule);
|
|
1186
1229
|
this.validate();
|
|
1187
1230
|
const container = new Container;
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
}
|
|
1231
|
+
const rootNode = this.nodes.get(rootModule);
|
|
1232
|
+
if (!rootNode) {
|
|
1233
|
+
return container;
|
|
1192
1234
|
}
|
|
1235
|
+
this.registerProviders(rootNode, container, new Set);
|
|
1193
1236
|
return container;
|
|
1194
1237
|
}
|
|
1195
1238
|
scan(target) {
|
|
@@ -1206,20 +1249,20 @@ class ModuleCompiler {
|
|
|
1206
1249
|
};
|
|
1207
1250
|
this.nodes.set(moduleClass, node);
|
|
1208
1251
|
const meta = MetadataStorage.getModule(moduleClass) || {};
|
|
1209
|
-
const dynamicMeta = "module" in target ? target :
|
|
1210
|
-
const allProviders = [...meta.providers || [], ...dynamicMeta
|
|
1252
|
+
const dynamicMeta = "module" in target ? target : undefined;
|
|
1253
|
+
const allProviders = [...meta.providers || [], ...dynamicMeta?.providers || []];
|
|
1211
1254
|
this.processProviders(node, allProviders);
|
|
1212
|
-
const allExports = [...meta.exports || [], ...dynamicMeta
|
|
1255
|
+
const allExports = [...meta.exports || [], ...dynamicMeta?.exports || []];
|
|
1213
1256
|
for (const token of allExports) {
|
|
1214
1257
|
node.exports.add(token);
|
|
1215
1258
|
}
|
|
1216
|
-
if (meta.global || dynamicMeta
|
|
1259
|
+
if (meta.global || dynamicMeta?.global) {
|
|
1217
1260
|
node.isGlobal = true;
|
|
1218
1261
|
for (const token of node.exports) {
|
|
1219
1262
|
this.globalExportedTokens.add(token);
|
|
1220
1263
|
}
|
|
1221
1264
|
}
|
|
1222
|
-
const allImports = [...meta.imports || [], ...dynamicMeta
|
|
1265
|
+
const allImports = [...meta.imports || [], ...dynamicMeta?.imports || []];
|
|
1223
1266
|
for (const imp of allImports) {
|
|
1224
1267
|
const importedNode = this.scan(imp);
|
|
1225
1268
|
node.imports.add(importedNode);
|
|
@@ -1258,7 +1301,7 @@ class ModuleCompiler {
|
|
|
1258
1301
|
for (const globalToken of this.globalExportedTokens) {
|
|
1259
1302
|
visibleTokens.add(globalToken);
|
|
1260
1303
|
}
|
|
1261
|
-
for (const [
|
|
1304
|
+
for (const [_token, provider] of node.providers) {
|
|
1262
1305
|
this.checkDependencies(provider, visibleTokens, node.module.name);
|
|
1263
1306
|
}
|
|
1264
1307
|
}
|
|
@@ -1271,19 +1314,36 @@ class ModuleCompiler {
|
|
|
1271
1314
|
targetName = clazz.name;
|
|
1272
1315
|
const paramTypes = Reflect.getMetadata("design:paramtypes", clazz) || [];
|
|
1273
1316
|
const injectionTokens = MetadataStorage.getInjections(clazz) || new Map;
|
|
1274
|
-
dependencies = paramTypes.map((
|
|
1317
|
+
dependencies = paramTypes.map((paramType, index) => {
|
|
1318
|
+
const overrideToken = injectionTokens.get(index);
|
|
1319
|
+
return overrideToken || paramType;
|
|
1320
|
+
});
|
|
1275
1321
|
} else if ("useFactory" in provider) {
|
|
1276
|
-
targetName = provider.provide
|
|
1322
|
+
targetName = typeof provider.provide === "function" ? provider.provide.name ?? "anonymous" : String(provider.provide);
|
|
1277
1323
|
dependencies = provider.inject || [];
|
|
1278
1324
|
}
|
|
1279
1325
|
for (const dep of dependencies) {
|
|
1280
1326
|
if (!visibleTokens.has(dep)) {
|
|
1281
|
-
const depName = dep
|
|
1327
|
+
const depName = typeof dep === "function" ? dep.name ?? "anonymous" : String(dep);
|
|
1282
1328
|
throw new Error(`[Kanjijs] strict-di-error: Provider '${targetName}' in Module '${moduleName}' ` + `depends on '${depName}', but it is not visible. ` + `Make sure it is imported and exported by the source module.`);
|
|
1283
1329
|
}
|
|
1284
1330
|
}
|
|
1285
1331
|
}
|
|
1332
|
+
registerProviders(node, container, visited) {
|
|
1333
|
+
if (visited.has(node))
|
|
1334
|
+
return;
|
|
1335
|
+
visited.add(node);
|
|
1336
|
+
for (const imp of node.imports) {
|
|
1337
|
+
this.registerProviders(imp, container, visited);
|
|
1338
|
+
}
|
|
1339
|
+
for (const [token, provider] of node.providers) {
|
|
1340
|
+
const { provide: _provide, ...definition } = provider;
|
|
1341
|
+
container.register(token, definition);
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1286
1344
|
}
|
|
1345
|
+
|
|
1346
|
+
// ../core/src/index.ts
|
|
1287
1347
|
var GLOBAL_MIDDLEWARE_TOKEN = Symbol("GLOBAL_MIDDLEWARE_TOKEN");
|
|
1288
1348
|
|
|
1289
1349
|
// ../../node_modules/.bun/zod-to-json-schema@3.25.1+27912429049419a2/node_modules/zod-to-json-schema/dist/esm/Options.js
|
|
@@ -6337,11 +6397,10 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
6337
6397
|
class OpenApiGenerator {
|
|
6338
6398
|
static generate(rootModule) {
|
|
6339
6399
|
const paths = {};
|
|
6340
|
-
const schemas = {};
|
|
6341
6400
|
const rootMeta = MetadataStorage.getModule(rootModule);
|
|
6342
6401
|
if (!rootMeta)
|
|
6343
6402
|
throw new Error("Root module metadata not found.");
|
|
6344
|
-
const controllers =
|
|
6403
|
+
const controllers = OpenApiGenerator.getAllControllers(rootMeta);
|
|
6345
6404
|
for (const ControllerClass of controllers) {
|
|
6346
6405
|
const ctrlMeta = MetadataStorage.getController(ControllerClass);
|
|
6347
6406
|
if (!ctrlMeta)
|
|
@@ -6351,7 +6410,7 @@ class OpenApiGenerator {
|
|
|
6351
6410
|
if (!routesMap)
|
|
6352
6411
|
continue;
|
|
6353
6412
|
for (const [methodName, route] of routesMap) {
|
|
6354
|
-
const path =
|
|
6413
|
+
const path = OpenApiGenerator.normalizePath(prefix + route.path);
|
|
6355
6414
|
if (!paths[path])
|
|
6356
6415
|
paths[path] = {};
|
|
6357
6416
|
const method = route.method.toLowerCase();
|
|
@@ -6362,7 +6421,7 @@ class OpenApiGenerator {
|
|
|
6362
6421
|
responses: {
|
|
6363
6422
|
"200": { description: "Success" }
|
|
6364
6423
|
},
|
|
6365
|
-
...
|
|
6424
|
+
...OpenApiGenerator.buildParameters(contract)
|
|
6366
6425
|
};
|
|
6367
6426
|
}
|
|
6368
6427
|
}
|
|
@@ -6381,7 +6440,7 @@ class OpenApiGenerator {
|
|
|
6381
6440
|
for (const imp of meta.imports) {
|
|
6382
6441
|
const impMeta = MetadataStorage.getModule(imp);
|
|
6383
6442
|
if (impMeta) {
|
|
6384
|
-
controllers = [...controllers, ...
|
|
6443
|
+
controllers = [...controllers, ...OpenApiGenerator.getAllControllers(impMeta)];
|
|
6385
6444
|
}
|
|
6386
6445
|
}
|
|
6387
6446
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Constructor } from "@kanjijs/core";
|
|
2
|
+
export declare class OpenApiGenerator {
|
|
3
|
+
static generate(rootModule: Constructor): {
|
|
4
|
+
openapi: string;
|
|
5
|
+
info: {
|
|
6
|
+
title: string;
|
|
7
|
+
version: string;
|
|
8
|
+
};
|
|
9
|
+
paths: Record<string, Record<string, unknown>>;
|
|
10
|
+
};
|
|
11
|
+
private static getAllControllers;
|
|
12
|
+
private static normalizePath;
|
|
13
|
+
private static buildParameters;
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanjijs/openapi",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.16",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"build": "bun build src/index.ts --outdir dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@kanjijs/core": "^0.2.0-beta.
|
|
16
|
+
"@kanjijs/core": "^0.2.0-beta.16",
|
|
17
17
|
"zod-to-json-schema": "^3.22.0",
|
|
18
18
|
"zod": "^3.0.0",
|
|
19
19
|
"reflect-metadata": "^0.2.0"
|