@kanjijs/core 0.2.0-beta.13 → 0.2.0-beta.15
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/context.d.ts +2 -1
- 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 +11 -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/decorators.d.ts +9 -2
- package/dist/di/container.d.ts +10 -5
- package/dist/index.js +90 -49
- package/dist/metadata.d.ts +20 -6
- package/package.json +4 -4
package/dist/context.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
export interface RequestContext {
|
|
3
3
|
requestId: string;
|
|
4
|
-
[key: string]:
|
|
4
|
+
[key: string]// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
5
|
+
: any;
|
|
5
6
|
}
|
|
6
7
|
export declare const kanjijsContext: AsyncLocalStorage<RequestContext>;
|
|
7
8
|
export declare function getRequestId(): string | undefined;
|
|
@@ -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,11 @@
|
|
|
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
|
+
}
|
|
@@ -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/decorators.d.ts
CHANGED
|
@@ -21,9 +21,16 @@ export declare const Patch: (path?: string) => MethodDecorator;
|
|
|
21
21
|
/**
|
|
22
22
|
* @Inject("DATABASE_CLIENT")
|
|
23
23
|
*/
|
|
24
|
-
export declare function Inject(token
|
|
24
|
+
export declare function Inject(token// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
25
|
+
: any): ParameterDecorator;
|
|
25
26
|
/**
|
|
26
27
|
* @Use(middleware1, middleware2)
|
|
27
28
|
* Attaches middlewares to a controller or method.
|
|
28
29
|
*/
|
|
29
|
-
export declare function Use(...middlewares
|
|
30
|
+
export declare function Use(...middlewares// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
31
|
+
: any[]): MethodDecorator & ClassDecorator;
|
|
32
|
+
export declare const Body: (data?: string) => ParameterDecorator;
|
|
33
|
+
export declare const Query: (data?: string) => ParameterDecorator;
|
|
34
|
+
export declare const Param: (data?: string) => ParameterDecorator;
|
|
35
|
+
export declare const Headers: (data?: string) => ParameterDecorator;
|
|
36
|
+
export declare const Ctx: (data?: string) => ParameterDecorator;
|
package/dist/di/container.d.ts
CHANGED
|
@@ -3,8 +3,10 @@ import "reflect-metadata";
|
|
|
3
3
|
export declare class KanjijsIoC {
|
|
4
4
|
private static providers;
|
|
5
5
|
static register<T>(target: Constructor<T>): void;
|
|
6
|
-
static register(token
|
|
7
|
-
|
|
6
|
+
static register(token// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
7
|
+
: any, provider: {
|
|
8
|
+
useValue?// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
9
|
+
: any;
|
|
8
10
|
useClass?: Constructor;
|
|
9
11
|
}): void;
|
|
10
12
|
static resolve<T>(target: Constructor<T> | any): T;
|
|
@@ -16,11 +18,14 @@ export declare class KanjijsIoC {
|
|
|
16
18
|
*/
|
|
17
19
|
export declare class Container {
|
|
18
20
|
private providers;
|
|
19
|
-
register(token
|
|
20
|
-
|
|
21
|
+
register(token// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
22
|
+
: any, provider: {
|
|
23
|
+
useValue?// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
24
|
+
: any;
|
|
21
25
|
useClass?: Constructor;
|
|
22
26
|
useFactory?: Function;
|
|
23
|
-
inject
|
|
27
|
+
inject?// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
28
|
+
: any[];
|
|
24
29
|
}): void;
|
|
25
30
|
resolve<T>(token: Constructor<T> | any): T;
|
|
26
31
|
}
|
package/dist/index.js
CHANGED
|
@@ -1013,6 +1013,12 @@ var require_Reflect = __commonJS(() => {
|
|
|
1013
1013
|
})(Reflect2 || (Reflect2 = {}));
|
|
1014
1014
|
});
|
|
1015
1015
|
|
|
1016
|
+
// src/context.ts
|
|
1017
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
1018
|
+
var kanjijsContext = new AsyncLocalStorage;
|
|
1019
|
+
function getRequestId() {
|
|
1020
|
+
return kanjijsContext.getStore()?.requestId;
|
|
1021
|
+
}
|
|
1016
1022
|
// src/metadata.ts
|
|
1017
1023
|
var import_reflect_metadata = __toESM(require_Reflect(), 1);
|
|
1018
1024
|
var methodMetadataStore = new WeakMap;
|
|
@@ -1041,6 +1047,16 @@ if (!globalStore.KANJI_METADATA_STORAGE) {
|
|
|
1041
1047
|
existing.contract = contract;
|
|
1042
1048
|
methods.set(methodName, existing);
|
|
1043
1049
|
},
|
|
1050
|
+
addRouteParam(target, methodName, param) {
|
|
1051
|
+
let methods = methodMetadataStore.get(target);
|
|
1052
|
+
if (!methods) {
|
|
1053
|
+
methods = new Map;
|
|
1054
|
+
methodMetadataStore.set(target, methods);
|
|
1055
|
+
}
|
|
1056
|
+
const existing = methods.get(methodName) || {};
|
|
1057
|
+
existing.params = [...existing.params || [], param];
|
|
1058
|
+
methods.set(methodName, existing);
|
|
1059
|
+
},
|
|
1044
1060
|
addMiddleware(target, middleware, methodName) {
|
|
1045
1061
|
if (methodName) {
|
|
1046
1062
|
let methods = methodMetadataStore.get(target);
|
|
@@ -1104,7 +1120,7 @@ function Controller(prefix = "") {
|
|
|
1104
1120
|
};
|
|
1105
1121
|
}
|
|
1106
1122
|
function Injectable() {
|
|
1107
|
-
return (
|
|
1123
|
+
return (_target) => {};
|
|
1108
1124
|
}
|
|
1109
1125
|
function createMethodDecorator(method) {
|
|
1110
1126
|
return (path = "/") => {
|
|
@@ -1122,12 +1138,12 @@ var Put = createMethodDecorator("PUT");
|
|
|
1122
1138
|
var Delete = createMethodDecorator("DELETE");
|
|
1123
1139
|
var Patch = createMethodDecorator("PATCH");
|
|
1124
1140
|
function Inject(token) {
|
|
1125
|
-
return (target,
|
|
1141
|
+
return (target, _propertyKey, parameterIndex) => {
|
|
1126
1142
|
MetadataStorage.addInjection(target, parameterIndex, token);
|
|
1127
1143
|
};
|
|
1128
1144
|
}
|
|
1129
1145
|
function Use(...middlewares) {
|
|
1130
|
-
return (target, propertyKey,
|
|
1146
|
+
return (target, propertyKey, _descriptor) => {
|
|
1131
1147
|
if (propertyKey) {
|
|
1132
1148
|
for (const m of middlewares) {
|
|
1133
1149
|
MetadataStorage.addMiddleware(target, m, propertyKey);
|
|
@@ -1139,6 +1155,24 @@ function Use(...middlewares) {
|
|
|
1139
1155
|
}
|
|
1140
1156
|
};
|
|
1141
1157
|
}
|
|
1158
|
+
function createParamDecorator(type) {
|
|
1159
|
+
return (data) => {
|
|
1160
|
+
return (target, propertyKey, parameterIndex) => {
|
|
1161
|
+
if (propertyKey) {
|
|
1162
|
+
MetadataStorage.addRouteParam(target, propertyKey, {
|
|
1163
|
+
index: parameterIndex,
|
|
1164
|
+
type,
|
|
1165
|
+
data
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
};
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
1171
|
+
var Body = createParamDecorator("BODY");
|
|
1172
|
+
var Query = createParamDecorator("QUERY");
|
|
1173
|
+
var Param = createParamDecorator("PARAM");
|
|
1174
|
+
var Headers = createParamDecorator("HEADERS");
|
|
1175
|
+
var Ctx = createParamDecorator("CONTEXT");
|
|
1142
1176
|
// src/di/container.ts
|
|
1143
1177
|
var import_reflect_metadata2 = __toESM(require_Reflect(), 1);
|
|
1144
1178
|
|
|
@@ -1147,43 +1181,46 @@ class KanjijsIoC {
|
|
|
1147
1181
|
static register(tokenOrTarget, provider) {
|
|
1148
1182
|
if (provider) {
|
|
1149
1183
|
if ("useValue" in provider) {
|
|
1150
|
-
|
|
1184
|
+
KanjijsIoC.providers.set(tokenOrTarget, { useValue: provider.useValue });
|
|
1151
1185
|
} else if ("useClass" in provider) {
|
|
1152
|
-
|
|
1186
|
+
KanjijsIoC.providers.set(tokenOrTarget, { useClass: provider.useClass });
|
|
1153
1187
|
}
|
|
1154
1188
|
} else {
|
|
1155
|
-
|
|
1189
|
+
KanjijsIoC.providers.set(tokenOrTarget, {
|
|
1190
|
+
useClass: tokenOrTarget
|
|
1191
|
+
});
|
|
1156
1192
|
}
|
|
1157
1193
|
}
|
|
1158
1194
|
static resolve(target) {
|
|
1159
|
-
let provider =
|
|
1195
|
+
let provider = KanjijsIoC.providers.get(target);
|
|
1160
1196
|
if (!provider && typeof target === "function") {
|
|
1161
1197
|
provider = { useClass: target };
|
|
1162
|
-
|
|
1198
|
+
KanjijsIoC.providers.set(target, provider);
|
|
1163
1199
|
}
|
|
1164
1200
|
if (!provider) {
|
|
1165
|
-
throw new Error(`Provider not found for token: ${target
|
|
1201
|
+
throw new Error(`Provider not found for token: ${typeof target === "function" ? target.name : String(target)}`);
|
|
1166
1202
|
}
|
|
1167
1203
|
if (provider.instance) {
|
|
1168
1204
|
return provider.instance;
|
|
1169
1205
|
}
|
|
1170
|
-
console.log(`[DI] Creating NEW instance for ${target
|
|
1206
|
+
console.log(`[DI] Creating NEW instance for ${typeof target === "function" ? target.name : String(target)}`);
|
|
1171
1207
|
if (provider.useValue !== undefined) {
|
|
1172
1208
|
provider.instance = provider.useValue;
|
|
1173
1209
|
} else if (provider.useClass) {
|
|
1174
1210
|
const ConcreteClass = provider.useClass;
|
|
1175
1211
|
const paramTypes = Reflect.getMetadata("design:paramtypes", ConcreteClass) || [];
|
|
1176
1212
|
const injectionTokens = MetadataStorage.getInjections(ConcreteClass) || new Map;
|
|
1177
|
-
const injections = paramTypes.map((
|
|
1213
|
+
const injections = paramTypes.map((paramToken, index) => {
|
|
1178
1214
|
const overrideToken = injectionTokens.get(index);
|
|
1179
|
-
|
|
1215
|
+
const resolvedToken = overrideToken || paramToken;
|
|
1216
|
+
return KanjijsIoC.resolve(resolvedToken);
|
|
1180
1217
|
});
|
|
1181
1218
|
provider.instance = new ConcreteClass(...injections);
|
|
1182
1219
|
}
|
|
1183
1220
|
return provider.instance;
|
|
1184
1221
|
}
|
|
1185
1222
|
static clear() {
|
|
1186
|
-
|
|
1223
|
+
KanjijsIoC.providers.clear();
|
|
1187
1224
|
}
|
|
1188
1225
|
}
|
|
1189
1226
|
|
|
@@ -1195,7 +1232,7 @@ class Container {
|
|
|
1195
1232
|
resolve(token) {
|
|
1196
1233
|
const provider = this.providers.get(token);
|
|
1197
1234
|
if (!provider) {
|
|
1198
|
-
throw new Error(`[DI] Provider not found for token: ${token
|
|
1235
|
+
throw new Error(`[DI] Provider not found for token: ${typeof token === "function" ? token.name : String(token)}`);
|
|
1199
1236
|
}
|
|
1200
1237
|
if (provider.instance) {
|
|
1201
1238
|
return provider.instance;
|
|
@@ -1208,7 +1245,8 @@ class Container {
|
|
|
1208
1245
|
const injectionTokens = MetadataStorage.getInjections(ConcreteClass) || new Map;
|
|
1209
1246
|
const injections = paramTypes.map((paramToken, index) => {
|
|
1210
1247
|
const overrideToken = injectionTokens.get(index);
|
|
1211
|
-
|
|
1248
|
+
const resolvedToken = overrideToken || paramToken;
|
|
1249
|
+
return this.resolve(resolvedToken);
|
|
1212
1250
|
});
|
|
1213
1251
|
provider.instance = new ConcreteClass(...injections);
|
|
1214
1252
|
} else if (provider.useFactory) {
|
|
@@ -1218,29 +1256,6 @@ class Container {
|
|
|
1218
1256
|
return provider.instance;
|
|
1219
1257
|
}
|
|
1220
1258
|
}
|
|
1221
|
-
// src/context.ts
|
|
1222
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
1223
|
-
var kanjijsContext = new AsyncLocalStorage;
|
|
1224
|
-
function getRequestId() {
|
|
1225
|
-
return kanjijsContext.getStore()?.requestId;
|
|
1226
|
-
}
|
|
1227
|
-
// src/exceptions/http.exception.ts
|
|
1228
|
-
class HttpException extends Error {
|
|
1229
|
-
response;
|
|
1230
|
-
status;
|
|
1231
|
-
constructor(response, status) {
|
|
1232
|
-
super(typeof response === "string" ? response : JSON.stringify(response));
|
|
1233
|
-
this.response = response;
|
|
1234
|
-
this.status = status;
|
|
1235
|
-
this.name = "HttpException";
|
|
1236
|
-
}
|
|
1237
|
-
getResponse() {
|
|
1238
|
-
return this.response;
|
|
1239
|
-
}
|
|
1240
|
-
getStatus() {
|
|
1241
|
-
return this.status;
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
1259
|
// src/di/module-compiler.ts
|
|
1245
1260
|
class ModuleCompiler {
|
|
1246
1261
|
nodes = new Map;
|
|
@@ -1251,7 +1266,8 @@ class ModuleCompiler {
|
|
|
1251
1266
|
const container = new Container;
|
|
1252
1267
|
for (const node of this.nodes.values()) {
|
|
1253
1268
|
for (const [token, provider] of node.providers) {
|
|
1254
|
-
|
|
1269
|
+
const { provide: _provide, ...definition } = provider;
|
|
1270
|
+
container.register(token, definition);
|
|
1255
1271
|
}
|
|
1256
1272
|
}
|
|
1257
1273
|
return container;
|
|
@@ -1270,20 +1286,20 @@ class ModuleCompiler {
|
|
|
1270
1286
|
};
|
|
1271
1287
|
this.nodes.set(moduleClass, node);
|
|
1272
1288
|
const meta = MetadataStorage.getModule(moduleClass) || {};
|
|
1273
|
-
const dynamicMeta = "module" in target ? target :
|
|
1274
|
-
const allProviders = [...meta.providers || [], ...dynamicMeta
|
|
1289
|
+
const dynamicMeta = "module" in target ? target : undefined;
|
|
1290
|
+
const allProviders = [...meta.providers || [], ...dynamicMeta?.providers || []];
|
|
1275
1291
|
this.processProviders(node, allProviders);
|
|
1276
|
-
const allExports = [...meta.exports || [], ...dynamicMeta
|
|
1292
|
+
const allExports = [...meta.exports || [], ...dynamicMeta?.exports || []];
|
|
1277
1293
|
for (const token of allExports) {
|
|
1278
1294
|
node.exports.add(token);
|
|
1279
1295
|
}
|
|
1280
|
-
if (meta.global || dynamicMeta
|
|
1296
|
+
if (meta.global || dynamicMeta?.global) {
|
|
1281
1297
|
node.isGlobal = true;
|
|
1282
1298
|
for (const token of node.exports) {
|
|
1283
1299
|
this.globalExportedTokens.add(token);
|
|
1284
1300
|
}
|
|
1285
1301
|
}
|
|
1286
|
-
const allImports = [...meta.imports || [], ...dynamicMeta
|
|
1302
|
+
const allImports = [...meta.imports || [], ...dynamicMeta?.imports || []];
|
|
1287
1303
|
for (const imp of allImports) {
|
|
1288
1304
|
const importedNode = this.scan(imp);
|
|
1289
1305
|
node.imports.add(importedNode);
|
|
@@ -1322,7 +1338,7 @@ class ModuleCompiler {
|
|
|
1322
1338
|
for (const globalToken of this.globalExportedTokens) {
|
|
1323
1339
|
visibleTokens.add(globalToken);
|
|
1324
1340
|
}
|
|
1325
|
-
for (const [
|
|
1341
|
+
for (const [_token, provider] of node.providers) {
|
|
1326
1342
|
this.checkDependencies(provider, visibleTokens, node.module.name);
|
|
1327
1343
|
}
|
|
1328
1344
|
}
|
|
@@ -1335,19 +1351,39 @@ class ModuleCompiler {
|
|
|
1335
1351
|
targetName = clazz.name;
|
|
1336
1352
|
const paramTypes = Reflect.getMetadata("design:paramtypes", clazz) || [];
|
|
1337
1353
|
const injectionTokens = MetadataStorage.getInjections(clazz) || new Map;
|
|
1338
|
-
dependencies = paramTypes.map((
|
|
1354
|
+
dependencies = paramTypes.map((paramType, index) => {
|
|
1355
|
+
const overrideToken = injectionTokens.get(index);
|
|
1356
|
+
return overrideToken || paramType;
|
|
1357
|
+
});
|
|
1339
1358
|
} else if ("useFactory" in provider) {
|
|
1340
|
-
targetName = provider.provide
|
|
1359
|
+
targetName = typeof provider.provide === "function" ? provider.provide.name : String(provider.provide);
|
|
1341
1360
|
dependencies = provider.inject || [];
|
|
1342
1361
|
}
|
|
1343
1362
|
for (const dep of dependencies) {
|
|
1344
1363
|
if (!visibleTokens.has(dep)) {
|
|
1345
|
-
const depName = dep
|
|
1364
|
+
const depName = typeof dep === "function" ? dep.name : String(dep);
|
|
1346
1365
|
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.`);
|
|
1347
1366
|
}
|
|
1348
1367
|
}
|
|
1349
1368
|
}
|
|
1350
1369
|
}
|
|
1370
|
+
// src/exceptions/http.exception.ts
|
|
1371
|
+
class HttpException extends Error {
|
|
1372
|
+
response;
|
|
1373
|
+
status;
|
|
1374
|
+
constructor(response, status) {
|
|
1375
|
+
super(typeof response === "string" ? response : JSON.stringify(response));
|
|
1376
|
+
this.response = response;
|
|
1377
|
+
this.status = status;
|
|
1378
|
+
this.name = "HttpException";
|
|
1379
|
+
}
|
|
1380
|
+
getResponse() {
|
|
1381
|
+
return this.response;
|
|
1382
|
+
}
|
|
1383
|
+
getStatus() {
|
|
1384
|
+
return this.status;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1351
1387
|
|
|
1352
1388
|
// src/index.ts
|
|
1353
1389
|
var GLOBAL_MIDDLEWARE_TOKEN = Symbol("GLOBAL_MIDDLEWARE_TOKEN");
|
|
@@ -1355,9 +1391,11 @@ export {
|
|
|
1355
1391
|
kanjijsContext,
|
|
1356
1392
|
getRequestId,
|
|
1357
1393
|
Use,
|
|
1394
|
+
Query,
|
|
1358
1395
|
Put,
|
|
1359
1396
|
Post,
|
|
1360
1397
|
Patch,
|
|
1398
|
+
Param,
|
|
1361
1399
|
ModuleCompiler,
|
|
1362
1400
|
Module,
|
|
1363
1401
|
MetadataStorage,
|
|
@@ -1365,10 +1403,13 @@ export {
|
|
|
1365
1403
|
Injectable,
|
|
1366
1404
|
Inject,
|
|
1367
1405
|
HttpException,
|
|
1406
|
+
Headers,
|
|
1368
1407
|
Get,
|
|
1369
1408
|
GLOBAL_MIDDLEWARE_TOKEN,
|
|
1370
1409
|
Delete,
|
|
1410
|
+
Ctx,
|
|
1371
1411
|
Controller,
|
|
1372
1412
|
Contract,
|
|
1373
|
-
Container
|
|
1413
|
+
Container,
|
|
1414
|
+
Body
|
|
1374
1415
|
};
|
package/dist/metadata.d.ts
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import type { ContractSpec } from "@kanjijs/contracts";
|
|
2
2
|
import "reflect-metadata";
|
|
3
|
-
export type Constructor<T = any> = new (...args
|
|
3
|
+
export type Constructor<T = any> = new (...args// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
4
|
+
: any[]) => T;
|
|
4
5
|
export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
6
|
+
export type RouteParamType = "BODY" | "QUERY" | "PARAM" | "HEADERS" | "CONTEXT";
|
|
7
|
+
export interface RouteParamMetadata {
|
|
8
|
+
index: number;
|
|
9
|
+
type: RouteParamType;
|
|
10
|
+
data?: string;
|
|
11
|
+
}
|
|
5
12
|
export interface RouteMetadata {
|
|
6
13
|
method: HttpMethod;
|
|
7
14
|
path: string;
|
|
8
15
|
contract?: ContractSpec;
|
|
9
|
-
middlewares
|
|
16
|
+
middlewares?// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
17
|
+
: any[];
|
|
18
|
+
params?: RouteParamMetadata[];
|
|
10
19
|
}
|
|
11
20
|
export interface ControllerMetadata {
|
|
12
21
|
prefix: string;
|
|
13
|
-
middlewares
|
|
22
|
+
middlewares?// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
23
|
+
: any[];
|
|
14
24
|
}
|
|
15
25
|
export type Token<T = any> = string | symbol | Constructor<T>;
|
|
16
26
|
export type Provider<T = any> = Constructor<T> | {
|
|
@@ -21,7 +31,8 @@ export type Provider<T = any> = Constructor<T> | {
|
|
|
21
31
|
useClass: Constructor<T>;
|
|
22
32
|
} | {
|
|
23
33
|
provide: Token<T>;
|
|
24
|
-
useFactory: (...args
|
|
34
|
+
useFactory: (...args// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
35
|
+
: any[]) => T | Promise<T>;
|
|
25
36
|
inject?: Token[];
|
|
26
37
|
};
|
|
27
38
|
export interface DynamicModule {
|
|
@@ -41,14 +52,17 @@ export interface ModuleMetadata {
|
|
|
41
52
|
export interface IMetadataStorage {
|
|
42
53
|
addRoute(target: object, methodName: string, meta: RouteMetadata): void;
|
|
43
54
|
addContract(target: object, methodName: string, contract: ContractSpec): void;
|
|
44
|
-
addMiddleware(target: object, middleware
|
|
55
|
+
addMiddleware(target: object, middleware// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
56
|
+
: any, methodName?: string): void;
|
|
45
57
|
getRoutes(target: object): Map<string, RouteMetadata> | undefined;
|
|
46
58
|
setController(target: object, meta: ControllerMetadata): void;
|
|
47
59
|
getController(target: object): ControllerMetadata | undefined;
|
|
48
60
|
defineModule(target: object, meta: ModuleMetadata): void;
|
|
49
61
|
getModule(target: object): ModuleMetadata | undefined;
|
|
50
|
-
addInjection(target: object, index: number, token
|
|
62
|
+
addInjection(target: object, index: number, token// biome-ignore lint/suspicious/noExplicitAny: Suppressed
|
|
63
|
+
: any): void;
|
|
51
64
|
getInjections(target: object): Map<number, any> | undefined;
|
|
65
|
+
addRouteParam(target: object, methodName: string, param: RouteParamMetadata): void;
|
|
52
66
|
}
|
|
53
67
|
declare global {
|
|
54
68
|
var KANJI_METADATA_STORAGE: IMetadataStorage | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanjijs/core",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.15",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -10,12 +10,12 @@
|
|
|
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 && bunx tsc --emitDeclarationOnly --declaration --outDir dist",
|
|
14
14
|
"test": "bun test"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@kanjijs/common": "^0.2.0-beta.
|
|
18
|
-
"@kanjijs/contracts": "^0.2.0-beta.
|
|
17
|
+
"@kanjijs/common": "^0.2.0-beta.15",
|
|
18
|
+
"@kanjijs/contracts": "^0.2.0-beta.15",
|
|
19
19
|
"reflect-metadata": "^0.2.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|