@kanjijs/openapi 0.2.0-beta.2 → 0.2.0-beta.20
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.d.ts +14 -0
- package/dist/index.js +165 -102
- package/dist/openapi/src/index.d.ts +14 -0
- package/package.json +3 -3
|
@@ -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.d.ts
ADDED
|
@@ -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, any>;
|
|
10
|
+
};
|
|
11
|
+
private static getAllControllers;
|
|
12
|
+
private static normalizePath;
|
|
13
|
+
private static buildParameters;
|
|
14
|
+
}
|
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,74 +1012,95 @@ 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;
|
|
1018
1023
|
var moduleMetadataStore = new WeakMap;
|
|
1019
1024
|
var injectionMetadataStore = new WeakMap;
|
|
1020
|
-
var
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
methods = new Map;
|
|
1025
|
-
methodMetadataStore.set(target, methods);
|
|
1026
|
-
}
|
|
1027
|
-
const existing = methods.get(methodName) || {};
|
|
1028
|
-
methods.set(methodName, { ...existing, ...meta });
|
|
1029
|
-
},
|
|
1030
|
-
addContract(target, methodName, contract) {
|
|
1031
|
-
let methods = methodMetadataStore.get(target);
|
|
1032
|
-
if (!methods) {
|
|
1033
|
-
methods = new Map;
|
|
1034
|
-
methodMetadataStore.set(target, methods);
|
|
1035
|
-
}
|
|
1036
|
-
const existing = methods.get(methodName) || {};
|
|
1037
|
-
existing.contract = contract;
|
|
1038
|
-
methods.set(methodName, existing);
|
|
1039
|
-
},
|
|
1040
|
-
addMiddleware(target, middleware, methodName) {
|
|
1041
|
-
if (methodName) {
|
|
1025
|
+
var globalStore = globalThis;
|
|
1026
|
+
if (!globalStore.KANJI_METADATA_STORAGE) {
|
|
1027
|
+
globalStore.KANJI_METADATA_STORAGE = {
|
|
1028
|
+
addRoute(target, methodName, meta) {
|
|
1042
1029
|
let methods = methodMetadataStore.get(target);
|
|
1043
1030
|
if (!methods) {
|
|
1044
1031
|
methods = new Map;
|
|
1045
1032
|
methodMetadataStore.set(target, methods);
|
|
1046
1033
|
}
|
|
1047
1034
|
const existing = methods.get(methodName) || {};
|
|
1048
|
-
|
|
1035
|
+
methods.set(methodName, { ...existing, ...meta });
|
|
1036
|
+
},
|
|
1037
|
+
addContract(target, methodName, contract) {
|
|
1038
|
+
let methods = methodMetadataStore.get(target);
|
|
1039
|
+
if (!methods) {
|
|
1040
|
+
methods = new Map;
|
|
1041
|
+
methodMetadataStore.set(target, methods);
|
|
1042
|
+
}
|
|
1043
|
+
const existing = methods.get(methodName) || {};
|
|
1044
|
+
existing.contract = contract;
|
|
1049
1045
|
methods.set(methodName, existing);
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
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
|
+
},
|
|
1057
|
+
addMiddleware(target, middleware, methodName) {
|
|
1058
|
+
if (methodName) {
|
|
1059
|
+
let methods = methodMetadataStore.get(target);
|
|
1060
|
+
if (!methods) {
|
|
1061
|
+
methods = new Map;
|
|
1062
|
+
methodMetadataStore.set(target, methods);
|
|
1063
|
+
}
|
|
1064
|
+
const existing = methods.get(methodName) || {};
|
|
1065
|
+
existing.middlewares = [...existing.middlewares || [], middleware];
|
|
1066
|
+
methods.set(methodName, existing);
|
|
1067
|
+
} else {
|
|
1068
|
+
const existing = controllerMetadataStore.get(target) || { prefix: "/" };
|
|
1069
|
+
existing.middlewares = [...existing.middlewares || [], middleware];
|
|
1070
|
+
controllerMetadataStore.set(target, existing);
|
|
1071
|
+
}
|
|
1072
|
+
},
|
|
1073
|
+
getRoutes(target) {
|
|
1074
|
+
return methodMetadataStore.get(target);
|
|
1075
|
+
},
|
|
1076
|
+
setController(target, meta) {
|
|
1077
|
+
controllerMetadataStore.set(target, meta);
|
|
1078
|
+
},
|
|
1079
|
+
getController(target) {
|
|
1080
|
+
return controllerMetadataStore.get(target);
|
|
1081
|
+
},
|
|
1082
|
+
defineModule(target, meta) {
|
|
1083
|
+
moduleMetadataStore.set(target, meta);
|
|
1084
|
+
},
|
|
1085
|
+
getModule(target) {
|
|
1086
|
+
return moduleMetadataStore.get(target);
|
|
1087
|
+
},
|
|
1088
|
+
addInjection(target, index, token) {
|
|
1089
|
+
let injections = injectionMetadataStore.get(target);
|
|
1090
|
+
if (!injections) {
|
|
1091
|
+
injections = new Map;
|
|
1092
|
+
injectionMetadataStore.set(target, injections);
|
|
1093
|
+
}
|
|
1094
|
+
injections.set(index, token);
|
|
1095
|
+
},
|
|
1096
|
+
getInjections(target) {
|
|
1097
|
+
return injectionMetadataStore.get(target);
|
|
1076
1098
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
};
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
var MetadataStorage = globalStore.KANJI_METADATA_STORAGE;
|
|
1102
|
+
|
|
1103
|
+
// ../core/src/decorators.ts
|
|
1083
1104
|
function createMethodDecorator(method) {
|
|
1084
1105
|
return (path = "/") => {
|
|
1085
1106
|
return (target, propertyKey) => {
|
|
@@ -1095,6 +1116,25 @@ var Post = createMethodDecorator("POST");
|
|
|
1095
1116
|
var Put = createMethodDecorator("PUT");
|
|
1096
1117
|
var Delete = createMethodDecorator("DELETE");
|
|
1097
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
|
|
1098
1138
|
var import_reflect_metadata2 = __toESM(require_Reflect(), 1);
|
|
1099
1139
|
|
|
1100
1140
|
class KanjijsIoC {
|
|
@@ -1102,43 +1142,48 @@ class KanjijsIoC {
|
|
|
1102
1142
|
static register(tokenOrTarget, provider) {
|
|
1103
1143
|
if (provider) {
|
|
1104
1144
|
if ("useValue" in provider) {
|
|
1105
|
-
|
|
1145
|
+
KanjijsIoC.providers.set(tokenOrTarget, { useValue: provider.useValue });
|
|
1106
1146
|
} else if ("useClass" in provider) {
|
|
1107
|
-
|
|
1147
|
+
KanjijsIoC.providers.set(tokenOrTarget, { useClass: provider.useClass });
|
|
1108
1148
|
}
|
|
1109
1149
|
} else {
|
|
1110
|
-
|
|
1150
|
+
KanjijsIoC.providers.set(tokenOrTarget, {
|
|
1151
|
+
useClass: tokenOrTarget
|
|
1152
|
+
});
|
|
1111
1153
|
}
|
|
1112
1154
|
}
|
|
1113
1155
|
static resolve(target) {
|
|
1114
|
-
let provider =
|
|
1156
|
+
let provider = KanjijsIoC.providers.get(target);
|
|
1115
1157
|
if (!provider && typeof target === "function") {
|
|
1116
1158
|
provider = { useClass: target };
|
|
1117
|
-
|
|
1159
|
+
KanjijsIoC.providers.set(target, provider);
|
|
1118
1160
|
}
|
|
1119
1161
|
if (!provider) {
|
|
1120
|
-
|
|
1162
|
+
const targetName2 = typeof target === "function" ? target.name ?? "anonymous" : String(target);
|
|
1163
|
+
throw new Error(`Provider not found for token: ${targetName2}`);
|
|
1121
1164
|
}
|
|
1122
1165
|
if (provider.instance) {
|
|
1123
1166
|
return provider.instance;
|
|
1124
1167
|
}
|
|
1125
|
-
|
|
1168
|
+
const targetName = typeof target === "function" ? target.name ?? "anonymous" : String(target);
|
|
1169
|
+
console.log(`[DI] Creating NEW instance for ${targetName}`);
|
|
1126
1170
|
if (provider.useValue !== undefined) {
|
|
1127
1171
|
provider.instance = provider.useValue;
|
|
1128
1172
|
} else if (provider.useClass) {
|
|
1129
1173
|
const ConcreteClass = provider.useClass;
|
|
1130
1174
|
const paramTypes = Reflect.getMetadata("design:paramtypes", ConcreteClass) || [];
|
|
1131
1175
|
const injectionTokens = MetadataStorage.getInjections(ConcreteClass) || new Map;
|
|
1132
|
-
const injections = paramTypes.map((
|
|
1176
|
+
const injections = paramTypes.map((paramToken, index) => {
|
|
1133
1177
|
const overrideToken = injectionTokens.get(index);
|
|
1134
|
-
|
|
1178
|
+
const resolvedToken = overrideToken || paramToken;
|
|
1179
|
+
return KanjijsIoC.resolve(resolvedToken);
|
|
1135
1180
|
});
|
|
1136
1181
|
provider.instance = new ConcreteClass(...injections);
|
|
1137
1182
|
}
|
|
1138
1183
|
return provider.instance;
|
|
1139
1184
|
}
|
|
1140
1185
|
static clear() {
|
|
1141
|
-
|
|
1186
|
+
KanjijsIoC.providers.clear();
|
|
1142
1187
|
}
|
|
1143
1188
|
}
|
|
1144
1189
|
|
|
@@ -1150,7 +1195,8 @@ class Container {
|
|
|
1150
1195
|
resolve(token) {
|
|
1151
1196
|
const provider = this.providers.get(token);
|
|
1152
1197
|
if (!provider) {
|
|
1153
|
-
|
|
1198
|
+
const tokenName = typeof token === "function" ? token.name ?? "anonymous" : String(token);
|
|
1199
|
+
throw new Error(`[DI] Provider not found for token: ${tokenName}`);
|
|
1154
1200
|
}
|
|
1155
1201
|
if (provider.instance) {
|
|
1156
1202
|
return provider.instance;
|
|
@@ -1163,7 +1209,8 @@ class Container {
|
|
|
1163
1209
|
const injectionTokens = MetadataStorage.getInjections(ConcreteClass) || new Map;
|
|
1164
1210
|
const injections = paramTypes.map((paramToken, index) => {
|
|
1165
1211
|
const overrideToken = injectionTokens.get(index);
|
|
1166
|
-
|
|
1212
|
+
const resolvedToken = overrideToken || paramToken;
|
|
1213
|
+
return this.resolve(resolvedToken);
|
|
1167
1214
|
});
|
|
1168
1215
|
provider.instance = new ConcreteClass(...injections);
|
|
1169
1216
|
} else if (provider.useFactory) {
|
|
@@ -1173,7 +1220,7 @@ class Container {
|
|
|
1173
1220
|
return provider.instance;
|
|
1174
1221
|
}
|
|
1175
1222
|
}
|
|
1176
|
-
|
|
1223
|
+
// ../core/src/di/module-compiler.ts
|
|
1177
1224
|
class ModuleCompiler {
|
|
1178
1225
|
nodes = new Map;
|
|
1179
1226
|
globalExportedTokens = new Set;
|
|
@@ -1181,11 +1228,11 @@ class ModuleCompiler {
|
|
|
1181
1228
|
this.scan(rootModule);
|
|
1182
1229
|
this.validate();
|
|
1183
1230
|
const container = new Container;
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
}
|
|
1231
|
+
const rootNode = this.nodes.get(rootModule);
|
|
1232
|
+
if (!rootNode) {
|
|
1233
|
+
return container;
|
|
1188
1234
|
}
|
|
1235
|
+
this.registerProviders(rootNode, container, new Set);
|
|
1189
1236
|
return container;
|
|
1190
1237
|
}
|
|
1191
1238
|
scan(target) {
|
|
@@ -1202,20 +1249,20 @@ class ModuleCompiler {
|
|
|
1202
1249
|
};
|
|
1203
1250
|
this.nodes.set(moduleClass, node);
|
|
1204
1251
|
const meta = MetadataStorage.getModule(moduleClass) || {};
|
|
1205
|
-
const dynamicMeta = "module" in target ? target :
|
|
1206
|
-
const allProviders = [...meta.providers || [], ...dynamicMeta
|
|
1252
|
+
const dynamicMeta = "module" in target ? target : undefined;
|
|
1253
|
+
const allProviders = [...meta.providers || [], ...dynamicMeta?.providers || []];
|
|
1207
1254
|
this.processProviders(node, allProviders);
|
|
1208
|
-
const allExports = [...meta.exports || [], ...dynamicMeta
|
|
1255
|
+
const allExports = [...meta.exports || [], ...dynamicMeta?.exports || []];
|
|
1209
1256
|
for (const token of allExports) {
|
|
1210
1257
|
node.exports.add(token);
|
|
1211
1258
|
}
|
|
1212
|
-
if (meta.global || dynamicMeta
|
|
1259
|
+
if (meta.global || dynamicMeta?.global) {
|
|
1213
1260
|
node.isGlobal = true;
|
|
1214
1261
|
for (const token of node.exports) {
|
|
1215
1262
|
this.globalExportedTokens.add(token);
|
|
1216
1263
|
}
|
|
1217
1264
|
}
|
|
1218
|
-
const allImports = [...meta.imports || [], ...dynamicMeta
|
|
1265
|
+
const allImports = [...meta.imports || [], ...dynamicMeta?.imports || []];
|
|
1219
1266
|
for (const imp of allImports) {
|
|
1220
1267
|
const importedNode = this.scan(imp);
|
|
1221
1268
|
node.imports.add(importedNode);
|
|
@@ -1254,7 +1301,7 @@ class ModuleCompiler {
|
|
|
1254
1301
|
for (const globalToken of this.globalExportedTokens) {
|
|
1255
1302
|
visibleTokens.add(globalToken);
|
|
1256
1303
|
}
|
|
1257
|
-
for (const [
|
|
1304
|
+
for (const [_token, provider] of node.providers) {
|
|
1258
1305
|
this.checkDependencies(provider, visibleTokens, node.module.name);
|
|
1259
1306
|
}
|
|
1260
1307
|
}
|
|
@@ -1267,19 +1314,36 @@ class ModuleCompiler {
|
|
|
1267
1314
|
targetName = clazz.name;
|
|
1268
1315
|
const paramTypes = Reflect.getMetadata("design:paramtypes", clazz) || [];
|
|
1269
1316
|
const injectionTokens = MetadataStorage.getInjections(clazz) || new Map;
|
|
1270
|
-
dependencies = paramTypes.map((
|
|
1271
|
-
|
|
1272
|
-
|
|
1317
|
+
dependencies = paramTypes.map((paramType, index) => {
|
|
1318
|
+
const overrideToken = injectionTokens.get(index);
|
|
1319
|
+
return overrideToken || paramType;
|
|
1320
|
+
});
|
|
1321
|
+
} else if ("useFactory" in provider) {
|
|
1322
|
+
targetName = typeof provider.provide === "function" ? provider.provide.name ?? "anonymous" : String(provider.provide);
|
|
1273
1323
|
dependencies = provider.inject || [];
|
|
1274
1324
|
}
|
|
1275
1325
|
for (const dep of dependencies) {
|
|
1276
1326
|
if (!visibleTokens.has(dep)) {
|
|
1277
|
-
const depName = dep
|
|
1327
|
+
const depName = typeof dep === "function" ? dep.name ?? "anonymous" : String(dep);
|
|
1278
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.`);
|
|
1279
1329
|
}
|
|
1280
1330
|
}
|
|
1281
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
|
+
}
|
|
1282
1344
|
}
|
|
1345
|
+
|
|
1346
|
+
// ../core/src/index.ts
|
|
1283
1347
|
var GLOBAL_MIDDLEWARE_TOKEN = Symbol("GLOBAL_MIDDLEWARE_TOKEN");
|
|
1284
1348
|
|
|
1285
1349
|
// ../../node_modules/.bun/zod-to-json-schema@3.25.1+27912429049419a2/node_modules/zod-to-json-schema/dist/esm/Options.js
|
|
@@ -6333,11 +6397,10 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
6333
6397
|
class OpenApiGenerator {
|
|
6334
6398
|
static generate(rootModule) {
|
|
6335
6399
|
const paths = {};
|
|
6336
|
-
const schemas = {};
|
|
6337
6400
|
const rootMeta = MetadataStorage.getModule(rootModule);
|
|
6338
6401
|
if (!rootMeta)
|
|
6339
6402
|
throw new Error("Root module metadata not found.");
|
|
6340
|
-
const controllers =
|
|
6403
|
+
const controllers = OpenApiGenerator.getAllControllers(rootMeta);
|
|
6341
6404
|
for (const ControllerClass of controllers) {
|
|
6342
6405
|
const ctrlMeta = MetadataStorage.getController(ControllerClass);
|
|
6343
6406
|
if (!ctrlMeta)
|
|
@@ -6347,7 +6410,7 @@ class OpenApiGenerator {
|
|
|
6347
6410
|
if (!routesMap)
|
|
6348
6411
|
continue;
|
|
6349
6412
|
for (const [methodName, route] of routesMap) {
|
|
6350
|
-
const path =
|
|
6413
|
+
const path = OpenApiGenerator.normalizePath(prefix + route.path);
|
|
6351
6414
|
if (!paths[path])
|
|
6352
6415
|
paths[path] = {};
|
|
6353
6416
|
const method = route.method.toLowerCase();
|
|
@@ -6358,7 +6421,7 @@ class OpenApiGenerator {
|
|
|
6358
6421
|
responses: {
|
|
6359
6422
|
"200": { description: "Success" }
|
|
6360
6423
|
},
|
|
6361
|
-
...
|
|
6424
|
+
...OpenApiGenerator.buildParameters(contract)
|
|
6362
6425
|
};
|
|
6363
6426
|
}
|
|
6364
6427
|
}
|
|
@@ -6377,7 +6440,7 @@ class OpenApiGenerator {
|
|
|
6377
6440
|
for (const imp of meta.imports) {
|
|
6378
6441
|
const impMeta = MetadataStorage.getModule(imp);
|
|
6379
6442
|
if (impMeta) {
|
|
6380
|
-
controllers = [...controllers, ...
|
|
6443
|
+
controllers = [...controllers, ...OpenApiGenerator.getAllControllers(impMeta)];
|
|
6381
6444
|
}
|
|
6382
6445
|
}
|
|
6383
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.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
"LICENSE"
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build": "bun build src/index.ts --outdir dist --target bun"
|
|
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.20",
|
|
17
17
|
"zod-to-json-schema": "^3.22.0",
|
|
18
18
|
"zod": "^3.0.0",
|
|
19
19
|
"reflect-metadata": "^0.2.0"
|