@bool-ts/core 1.9.1 → 1.9.2
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/__test/_constants.ts +1 -0
- package/__test/container.ts +28 -0
- package/__test/controller.ts +1 -1
- package/__test/{module.ts → firstModule.ts} +4 -6
- package/__test/index.ts +2 -4
- package/__test/secondModule.ts +29 -0
- package/__test/tsconfig.json +1 -1
- package/dist/decorators/arguments.d.ts +5 -1
- package/dist/decorators/container.d.ts +10 -10
- package/dist/decorators/index.d.ts +4 -2
- package/dist/decorators/module.d.ts +6 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -5
- package/dist/interfaces/context.d.ts +8 -2
- package/dist/interfaces/index.d.ts +1 -1
- package/dist/keys/index.d.ts +2 -0
- package/dist/producers/context.d.ts +13 -0
- package/dist/{hooks → producers}/factory.d.ts +3 -2
- package/dist/{hooks → producers}/injector.d.ts +7 -1
- package/package.json +3 -3
- package/src/decorators/arguments.ts +27 -0
- package/src/decorators/container.ts +45 -30
- package/src/decorators/index.ts +4 -1
- package/src/decorators/module.ts +16 -2
- package/src/index.ts +1 -1
- package/src/interfaces/context.ts +9 -2
- package/src/interfaces/index.ts +1 -1
- package/src/keys/index.ts +2 -0
- package/src/producers/context.ts +63 -0
- package/src/producers/factory.ts +2013 -0
- package/src/{hooks → producers}/injector.ts +41 -6
- package/src/hooks/factory.ts +0 -1703
- /package/dist/{hooks → producers}/index.d.ts +0 -0
- /package/src/{hooks → producers}/index.ts +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bool-ts/core",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
"@bool-ts/date-time": "^1.0.0",
|
|
22
22
|
"qs": "^6.14.0",
|
|
23
23
|
"reflect-metadata": "^0.2.2",
|
|
24
|
-
"zod": "^3.24.
|
|
24
|
+
"zod": "^3.24.2"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/bun": "latest",
|
|
28
28
|
"@types/qs": "^6.9.18",
|
|
29
|
-
"typescript": "^5.
|
|
29
|
+
"typescript": "^5.8.2"
|
|
30
30
|
},
|
|
31
31
|
"private": "false"
|
|
32
32
|
}
|
|
@@ -2,6 +2,7 @@ import * as Zod from "zod";
|
|
|
2
2
|
import {
|
|
3
3
|
argumentsKey,
|
|
4
4
|
contextArgsKey,
|
|
5
|
+
httpServerArgsKey,
|
|
5
6
|
paramArgsKey,
|
|
6
7
|
paramsArgsKey,
|
|
7
8
|
queryArgsKey,
|
|
@@ -64,6 +65,10 @@ export type TArgumentsMetadata =
|
|
|
64
65
|
| {
|
|
65
66
|
index: number;
|
|
66
67
|
type: typeof routeModelArgsKey;
|
|
68
|
+
}
|
|
69
|
+
| {
|
|
70
|
+
index: number;
|
|
71
|
+
type: typeof httpServerArgsKey;
|
|
67
72
|
};
|
|
68
73
|
|
|
69
74
|
export type TArgumentsMetadataCollection = Record<`argumentIndexes.${number}`, TArgumentsMetadata>;
|
|
@@ -306,3 +311,25 @@ export const RouteModel =
|
|
|
306
311
|
|
|
307
312
|
Reflect.defineMetadata(argumentsKey, metadata, target.constructor, methodName);
|
|
308
313
|
};
|
|
314
|
+
|
|
315
|
+
export const HttpServer =
|
|
316
|
+
() => (target: Object, methodName: string | symbol | undefined, parameterIndex: number) => {
|
|
317
|
+
if (!methodName) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const metadata: TArgumentsMetadataCollection =
|
|
322
|
+
Reflect.getOwnMetadata(argumentsKey, target.constructor, methodName) || {};
|
|
323
|
+
|
|
324
|
+
metadata[`argumentIndexes.${parameterIndex}`] = {
|
|
325
|
+
index: parameterIndex,
|
|
326
|
+
type: httpServerArgsKey
|
|
327
|
+
} satisfies Extract<
|
|
328
|
+
TArgumentsMetadata,
|
|
329
|
+
{
|
|
330
|
+
type: typeof httpServerArgsKey;
|
|
331
|
+
}
|
|
332
|
+
>;
|
|
333
|
+
|
|
334
|
+
Reflect.defineMetadata(argumentsKey, metadata, target.constructor, methodName);
|
|
335
|
+
};
|
|
@@ -1,45 +1,60 @@
|
|
|
1
1
|
import type { IModule } from "../interfaces";
|
|
2
2
|
|
|
3
|
-
import { containerKey,
|
|
3
|
+
import { containerKey, guardKey, injectableKey, middlewareKey, moduleKey } from "../keys";
|
|
4
4
|
|
|
5
5
|
type TInstances = Array<new (...args: any[]) => any>;
|
|
6
6
|
type TLoaders<TConfig extends {} = {}> = Record<
|
|
7
7
|
string | symbol,
|
|
8
8
|
(args: { config: TConfig }) => [string | symbol, any] | Promise<[string | symbol, any]>
|
|
9
9
|
>;
|
|
10
|
+
export type TContainerConfig<TConfig> =
|
|
11
|
+
| TConfig
|
|
12
|
+
| (() => TConfig | Promise<TConfig>)
|
|
13
|
+
| Readonly<{
|
|
14
|
+
key: symbol;
|
|
15
|
+
value: TConfig | (() => TConfig | Promise<TConfig>);
|
|
16
|
+
}>;
|
|
10
17
|
|
|
11
18
|
export type TContainerOptions<TConfig extends {} = {}> =
|
|
12
|
-
|
|
|
19
|
+
| Partial<{
|
|
20
|
+
config: TContainerConfig<TConfig>;
|
|
13
21
|
modules: TInstances;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
middlewares: TInstances;
|
|
20
|
-
guards: TInstances;
|
|
21
|
-
dispatchers: TInstances;
|
|
22
|
-
}>)
|
|
22
|
+
dependencies: TInstances;
|
|
23
|
+
loaders: TLoaders<TConfig>;
|
|
24
|
+
middlewares: TInstances;
|
|
25
|
+
guards: TInstances;
|
|
26
|
+
}>
|
|
23
27
|
| undefined;
|
|
24
28
|
|
|
25
29
|
export type TContainerMetadata<TConfig extends {} = {}> =
|
|
26
|
-
|
|
|
30
|
+
| Partial<{
|
|
27
31
|
modules: TInstances;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
guards: TInstances;
|
|
35
|
-
dispatchers: TInstances;
|
|
36
|
-
}>)
|
|
32
|
+
config: TContainerConfig<TConfig>;
|
|
33
|
+
dependencies: TInstances;
|
|
34
|
+
loaders: TLoaders<TConfig>;
|
|
35
|
+
middlewares: TInstances;
|
|
36
|
+
guards: TInstances;
|
|
37
|
+
}>
|
|
37
38
|
| undefined;
|
|
38
39
|
|
|
39
40
|
export const Container =
|
|
40
41
|
<TConfig extends {} = {}>(args?: TContainerOptions<TConfig>) =>
|
|
41
42
|
<T extends { new (...args: any[]): IModule }>(target: T) => {
|
|
42
|
-
const { middlewares, guards,
|
|
43
|
+
const { modules, middlewares, guards, dependencies } = args || {};
|
|
44
|
+
|
|
45
|
+
if (Reflect.hasOwnMetadata(moduleKey, target)) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
`Conflict detected! ${target.name} class cannot be both a Module and a Container.`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (modules) {
|
|
52
|
+
for (let i = 0; i < modules.length; i++) {
|
|
53
|
+
if (!Reflect.getOwnMetadataKeys(modules[i]).includes(moduleKey)) {
|
|
54
|
+
throw Error(`${modules[i].name} is not a module.`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
43
58
|
|
|
44
59
|
if (middlewares) {
|
|
45
60
|
for (let i = 0; i < middlewares.length; i++) {
|
|
@@ -49,18 +64,18 @@ export const Container =
|
|
|
49
64
|
}
|
|
50
65
|
}
|
|
51
66
|
|
|
52
|
-
if (
|
|
53
|
-
for (let i = 0; i <
|
|
54
|
-
if (!Reflect.getOwnMetadataKeys(
|
|
55
|
-
throw Error(`${
|
|
67
|
+
if (middlewares) {
|
|
68
|
+
for (let i = 0; i < middlewares.length; i++) {
|
|
69
|
+
if (!Reflect.getOwnMetadataKeys(middlewares[i]).includes(middlewareKey)) {
|
|
70
|
+
throw Error(`${middlewares[i].name} is not a middleware.`);
|
|
56
71
|
}
|
|
57
72
|
}
|
|
58
73
|
}
|
|
59
74
|
|
|
60
|
-
if (
|
|
61
|
-
for (let i = 0; i <
|
|
62
|
-
if (!Reflect.getOwnMetadataKeys(
|
|
63
|
-
throw Error(`${
|
|
75
|
+
if (guards) {
|
|
76
|
+
for (let i = 0; i < guards.length; i++) {
|
|
77
|
+
if (!Reflect.getOwnMetadataKeys(guards[i]).includes(guardKey)) {
|
|
78
|
+
throw Error(`${guards[i].name} is not a guard.`);
|
|
64
79
|
}
|
|
65
80
|
}
|
|
66
81
|
}
|
package/src/decorators/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export {
|
|
2
2
|
Context,
|
|
3
|
+
HttpServer,
|
|
3
4
|
Param,
|
|
4
5
|
Params,
|
|
5
6
|
Query,
|
|
@@ -10,6 +11,7 @@ export {
|
|
|
10
11
|
ResponseHeaders,
|
|
11
12
|
RouteModel
|
|
12
13
|
} from "./arguments";
|
|
14
|
+
export { Container } from "./container";
|
|
13
15
|
export { Controller } from "./controller";
|
|
14
16
|
export { Dispatcher } from "./dispatcher";
|
|
15
17
|
export { Guard } from "./guard";
|
|
@@ -29,11 +31,12 @@ export { WebSocketEvent } from "./webSocketEvent";
|
|
|
29
31
|
export { ZodSchema } from "./zodSchema";
|
|
30
32
|
|
|
31
33
|
export type { TArgumentsMetadata } from "./arguments";
|
|
34
|
+
export type { TContainerConfig, TContainerMetadata, TContainerOptions } from "./container";
|
|
32
35
|
export type { TControllerMetadata } from "./controller";
|
|
33
36
|
export type { TDispatcherMetadata } from "./dispatcher";
|
|
34
37
|
export type { TGuardMetadata } from "./guard";
|
|
35
38
|
export type { THttpMetadata } from "./http";
|
|
36
39
|
export type { TMiddlewareMetadata } from "./middleware";
|
|
37
|
-
export type { TModuleMetadata, TModuleOptions } from "./module";
|
|
40
|
+
export type { TModuleConfig, TModuleMetadata, TModuleOptions } from "./module";
|
|
38
41
|
export type { TWebSocketMetadata } from "./webSocket";
|
|
39
42
|
export type { TWebSocketEventHandlerMetadata, TWebSocketEventMetadata } from "./webSocketEvent";
|
package/src/decorators/module.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { IModule } from "../interfaces";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
containerKey,
|
|
4
5
|
controllerKey,
|
|
5
6
|
dispatcherKey,
|
|
6
7
|
guardKey,
|
|
@@ -15,10 +16,17 @@ type TLoaders<TConfig extends {} = {}> = Record<
|
|
|
15
16
|
string | symbol,
|
|
16
17
|
(args: { config: TConfig }) => [string | symbol, any] | Promise<[string | symbol, any]>
|
|
17
18
|
>;
|
|
19
|
+
export type TModuleConfig<TConfig> =
|
|
20
|
+
| TConfig
|
|
21
|
+
| (() => TConfig | Promise<TConfig>)
|
|
22
|
+
| Readonly<{
|
|
23
|
+
key: symbol;
|
|
24
|
+
value: TConfig | (() => TConfig | Promise<TConfig>);
|
|
25
|
+
}>;
|
|
18
26
|
|
|
19
27
|
export type TModuleOptions<TConfig extends {} = {}> =
|
|
20
28
|
| Partial<{
|
|
21
|
-
config:
|
|
29
|
+
config: TModuleConfig<TConfig>;
|
|
22
30
|
prefix: string;
|
|
23
31
|
dependencies: TInstances;
|
|
24
32
|
loaders: TLoaders<TConfig>;
|
|
@@ -32,7 +40,7 @@ export type TModuleOptions<TConfig extends {} = {}> =
|
|
|
32
40
|
|
|
33
41
|
export type TModuleMetadata<TConfig extends {} = {}> =
|
|
34
42
|
| Partial<{
|
|
35
|
-
config:
|
|
43
|
+
config: TModuleConfig<TConfig>;
|
|
36
44
|
prefix: string;
|
|
37
45
|
dependencies: TInstances;
|
|
38
46
|
loaders: TLoaders<TConfig>;
|
|
@@ -47,6 +55,12 @@ export type TModuleMetadata<TConfig extends {} = {}> =
|
|
|
47
55
|
export const Module =
|
|
48
56
|
<TConfig extends {} = {}>(args?: TModuleOptions<TConfig>) =>
|
|
49
57
|
<T extends { new (...args: any[]): IModule }>(target: T) => {
|
|
58
|
+
if (Reflect.hasOwnMetadata(containerKey, target)) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`Conflict detected! ${target.name} class cannot be both a Module and a Container.`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
50
64
|
const { middlewares, guards, dispatchers, controllers, dependencies, webSockets } =
|
|
51
65
|
args || {};
|
|
52
66
|
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
export type TContextOptions = Partial<{
|
|
2
|
+
isStatic: boolean;
|
|
3
|
+
isPassthrough: boolean;
|
|
4
|
+
}>;
|
|
5
|
+
|
|
1
6
|
export interface IContext {
|
|
2
|
-
get: (key: symbol) =>
|
|
3
|
-
|
|
7
|
+
get: <T = unknown>(key: symbol, options?: TContextOptions) => T;
|
|
8
|
+
has: (key: symbol, options?: TContextOptions) => boolean;
|
|
9
|
+
set: <T = unknown>(key: symbol, value: T, options?: TContextOptions) => ThisType<IContext>;
|
|
10
|
+
setOptions: (options: TContextOptions) => ThisType<IContext>;
|
|
4
11
|
}
|
package/src/interfaces/index.ts
CHANGED
package/src/keys/index.ts
CHANGED
|
@@ -32,3 +32,5 @@ export const responseHeadersArgsKey = Symbol("__bool:httpArguments:responseHeade
|
|
|
32
32
|
export const contextArgsKey = Symbol("__bool:httpArguments:context__");
|
|
33
33
|
export const routeModelArgsKey = Symbol("__bool:httpArguments:routeModel__");
|
|
34
34
|
export const responseBodyArgsKey = Symbol("__bool:httpArguments:responseBody__");
|
|
35
|
+
export const responseStatusArgsKey = Symbol("__bool:httpArguments:responseStatus__");
|
|
36
|
+
export const responseStatusTextArgsKey = Symbol("__bool:httpArguments:responseStatusText__");
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { IContext, TContextOptions } from "../interfaces";
|
|
2
|
+
|
|
3
|
+
export class Context implements IContext {
|
|
4
|
+
private readonly _staticMap = new Map<symbol, any>();
|
|
5
|
+
private readonly _dynamicMap = new Map<symbol, any>();
|
|
6
|
+
|
|
7
|
+
private _options?: TContextOptions = undefined;
|
|
8
|
+
|
|
9
|
+
constructor(...contexts: Array<Context>) {
|
|
10
|
+
contexts.forEach((context) => {
|
|
11
|
+
context.staticEntries.forEach(([key, value]) =>
|
|
12
|
+
this.set(key, value, { isStatic: true, isPassthrough: true })
|
|
13
|
+
);
|
|
14
|
+
context.dynamicEntries.forEach(([key, value]) =>
|
|
15
|
+
this.set(key, value, { isStatic: false })
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get<T = unknown>(key: symbol, options?: TContextOptions) {
|
|
21
|
+
const temporaryOptions = options || this._options;
|
|
22
|
+
|
|
23
|
+
return !temporaryOptions?.isStatic
|
|
24
|
+
? (this._dynamicMap.get(key) as T)
|
|
25
|
+
: (this._staticMap.get(key) as T);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
has(key: symbol, options?: TContextOptions) {
|
|
29
|
+
const temporaryOptions = options || this._options;
|
|
30
|
+
|
|
31
|
+
return !temporaryOptions?.isStatic ? this._dynamicMap.has(key) : this._staticMap.has(key);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
set(key: symbol, value: any, options?: TContextOptions) {
|
|
35
|
+
const temporaryOptions = options || this._options;
|
|
36
|
+
|
|
37
|
+
if (!temporaryOptions?.isStatic) {
|
|
38
|
+
this._dynamicMap.set(key, value);
|
|
39
|
+
} else {
|
|
40
|
+
if (!this._staticMap.has(key)) {
|
|
41
|
+
this._staticMap.set(key, value);
|
|
42
|
+
} else if (!temporaryOptions.isPassthrough) {
|
|
43
|
+
throw Error(`${String(key)} already exists in context static collection.`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
setOptions(options: TContextOptions) {
|
|
51
|
+
this._options = options;
|
|
52
|
+
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get staticEntries() {
|
|
57
|
+
return [...this._staticMap.entries()];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get dynamicEntries() {
|
|
61
|
+
return [...this._dynamicMap.entries()];
|
|
62
|
+
}
|
|
63
|
+
}
|