@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.
@@ -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,3 @@
1
+ export interface ExceptionFilter<T = any, C = any> {
2
+ catch(exception: T, context: C): void | Promise<void> | any;
3
+ }
@@ -0,0 +1,7 @@
1
+ export declare class HttpException extends Error {
2
+ readonly response: string | object;
3
+ readonly status: number;
4
+ constructor(response: string | object, status: number);
5
+ getResponse(): string | object;
6
+ getStatus(): number;
7
+ }
@@ -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;
@@ -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
- 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
- ***************************************************************************** */
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 MetadataStorage = {
1021
- addRoute(target, methodName, meta) {
1022
- let methods = methodMetadataStore.get(target);
1023
- if (!methods) {
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
- existing.middlewares = [...existing.middlewares || [], middleware];
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
- } else {
1051
- const existing = controllerMetadataStore.get(target) || { prefix: "/" };
1052
- existing.middlewares = [...existing.middlewares || [], middleware];
1053
- controllerMetadataStore.set(target, existing);
1054
- }
1055
- },
1056
- getRoutes(target) {
1057
- return methodMetadataStore.get(target);
1058
- },
1059
- setController(target, meta) {
1060
- controllerMetadataStore.set(target, meta);
1061
- },
1062
- getController(target) {
1063
- return controllerMetadataStore.get(target);
1064
- },
1065
- defineModule(target, meta) {
1066
- moduleMetadataStore.set(target, meta);
1067
- },
1068
- getModule(target) {
1069
- return moduleMetadataStore.get(target);
1070
- },
1071
- addInjection(target, index, token) {
1072
- let injections = injectionMetadataStore.get(target);
1073
- if (!injections) {
1074
- injections = new Map;
1075
- injectionMetadataStore.set(target, injections);
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
- injections.set(index, token);
1078
- },
1079
- getInjections(target) {
1080
- return injectionMetadataStore.get(target);
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
- this.providers.set(tokenOrTarget, { useValue: provider.useValue });
1145
+ KanjijsIoC.providers.set(tokenOrTarget, { useValue: provider.useValue });
1106
1146
  } else if ("useClass" in provider) {
1107
- this.providers.set(tokenOrTarget, { useClass: provider.useClass });
1147
+ KanjijsIoC.providers.set(tokenOrTarget, { useClass: provider.useClass });
1108
1148
  }
1109
1149
  } else {
1110
- this.providers.set(tokenOrTarget, { useClass: tokenOrTarget });
1150
+ KanjijsIoC.providers.set(tokenOrTarget, {
1151
+ useClass: tokenOrTarget
1152
+ });
1111
1153
  }
1112
1154
  }
1113
1155
  static resolve(target) {
1114
- let provider = this.providers.get(target);
1156
+ let provider = KanjijsIoC.providers.get(target);
1115
1157
  if (!provider && typeof target === "function") {
1116
1158
  provider = { useClass: target };
1117
- this.providers.set(target, provider);
1159
+ KanjijsIoC.providers.set(target, provider);
1118
1160
  }
1119
1161
  if (!provider) {
1120
- throw new Error(`Provider not found for token: ${target?.name || target}`);
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
- console.log(`[DI] Creating NEW instance for ${target?.name || String(target)}`);
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((token, index) => {
1176
+ const injections = paramTypes.map((paramToken, index) => {
1133
1177
  const overrideToken = injectionTokens.get(index);
1134
- return KanjijsIoC.resolve(overrideToken || token);
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
- this.providers.clear();
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
- throw new Error(`[DI] Provider not found for token: ${token?.name || String(token)}`);
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
- return this.resolve(overrideToken || paramToken);
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
- var kanjijsContext = new AsyncLocalStorage;
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
- for (const node of this.nodes.values()) {
1185
- for (const [token, provider] of node.providers) {
1186
- container.register(token, provider);
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.providers || []];
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.exports || []];
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.global) {
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.imports || []];
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 [token, provider] of node.providers) {
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((t, i) => injectionTokens.get(i) || t);
1271
- } else if ("useFactory" in provider && provider.useFactory) {
1272
- targetName = provider.provide?.name || String(provider.provide);
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?.name || String(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 = this.getAllControllers(rootMeta);
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 = this.normalizePath(prefix + route.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
- ...this.buildParameters(contract)
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, ...this.getAllControllers(impMeta)];
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.2",
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.2",
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"