@forklaunch/core 0.5.5 → 0.6.0
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/lib/__test__/index.d.mts +11 -0
- package/lib/__test__/index.d.ts +11 -0
- package/lib/__test__/index.js +54 -0
- package/lib/__test__/index.js.map +1 -0
- package/lib/__test__/index.mjs +30 -0
- package/lib/__test__/index.mjs.map +1 -0
- package/lib/{cache → src/cache}/index.d.mts +1 -1
- package/lib/{cache → src/cache}/index.d.ts +1 -1
- package/lib/src/cache/index.js.map +1 -0
- package/lib/src/cache/index.mjs.map +1 -0
- package/lib/{controllers → src/controllers}/index.d.mts +2 -0
- package/lib/{controllers → src/controllers}/index.d.ts +2 -0
- package/lib/src/controllers/index.js.map +1 -0
- package/lib/{dtoMapper → src/dtoMapper}/index.d.mts +67 -1
- package/lib/{dtoMapper → src/dtoMapper}/index.d.ts +67 -1
- package/lib/{dtoMapper → src/dtoMapper}/index.js +36 -2
- package/lib/src/dtoMapper/index.js.map +1 -0
- package/lib/{dtoMapper → src/dtoMapper}/index.mjs +33 -1
- package/lib/src/dtoMapper/index.mjs.map +1 -0
- package/lib/{http → src/http}/index.d.mts +2 -2
- package/lib/{http → src/http}/index.d.ts +2 -2
- package/lib/{http → src/http}/index.js +8 -3
- package/lib/{http → src/http}/index.js.map +1 -1
- package/lib/{http → src/http}/index.mjs +9 -4
- package/lib/src/http/index.mjs.map +1 -0
- package/lib/{services → src/services}/index.d.mts +43 -13
- package/lib/{services → src/services}/index.d.ts +43 -13
- package/lib/{services → src/services}/index.js +56 -12
- package/lib/src/services/index.js.map +1 -0
- package/lib/{services → src/services}/index.mjs +55 -12
- package/lib/src/services/index.mjs.map +1 -0
- package/package.json +52 -46
- package/lib/cache/index.js.map +0 -1
- package/lib/cache/index.mjs.map +0 -1
- package/lib/controllers/index.js.map +0 -1
- package/lib/dtoMapper/index.js.map +0 -1
- package/lib/dtoMapper/index.mjs.map +0 -1
- package/lib/http/index.mjs.map +0 -1
- package/lib/services/index.js.map +0 -1
- package/lib/services/index.mjs.map +0 -1
- /package/lib/{cache → src/cache}/index.js +0 -0
- /package/lib/{cache → src/cache}/index.mjs +0 -0
- /package/lib/{controllers → src/controllers}/index.js +0 -0
- /package/lib/{controllers → src/controllers}/index.mjs +0 -0
- /package/lib/{controllers → src/controllers}/index.mjs.map +0 -0
@@ -1,46 +1,59 @@
|
|
1
1
|
import { AnySchemaValidator, IdiomaticSchema, Schema, ParseResult } from '@forklaunch/validator';
|
2
|
-
import { EntityManager as EntityManager$1 } from '@mikro-orm/core';
|
2
|
+
import { EntityManager as EntityManager$1, Collection } from '@mikro-orm/core';
|
3
3
|
|
4
4
|
declare enum Lifetime {
|
5
5
|
Singleton = 0,
|
6
6
|
Transient = 1,
|
7
7
|
Scoped = 2
|
8
8
|
}
|
9
|
-
type Singleton<Args, Value> = {
|
9
|
+
type Singleton<Type, Args, Value> = {
|
10
10
|
lifetime: Lifetime.Singleton;
|
11
|
+
type: Type;
|
11
12
|
value: Value;
|
12
|
-
} | ConstructedSingleton<Args, Value>;
|
13
|
-
type ConstructedSingleton<Args, Return> = {
|
13
|
+
} | ConstructedSingleton<Type, Args, Value>;
|
14
|
+
type ConstructedSingleton<Type, Args, Return> = {
|
14
15
|
lifetime: Lifetime.Singleton;
|
16
|
+
type: Type;
|
15
17
|
factory: (args: Args, resolve: <T extends keyof Args>(token: T, context?: Record<string, unknown>) => Args[T], context: Record<string, unknown>) => Return;
|
16
18
|
};
|
17
|
-
type Constructed<Args, Return> = {
|
19
|
+
type Constructed<Type, Args, Return> = {
|
18
20
|
lifetime: Lifetime.Transient | Lifetime.Scoped;
|
21
|
+
type: Type;
|
19
22
|
factory: (args: Args, resolve: <T extends keyof Args>(token: T, context?: Record<string, unknown>) => Args[T], context: Record<string, unknown>) => Return;
|
20
23
|
};
|
21
24
|
type Constructor = new (...args: never[]) => unknown;
|
22
25
|
type SchemaConstructor<SV extends AnySchemaValidator> = new (...args: unknown[]) => IdiomaticSchema<SV>;
|
23
26
|
type Function = (...args: never[]) => unknown;
|
24
27
|
type SchemaFunction<SV extends AnySchemaValidator> = (args: unknown) => IdiomaticSchema<SV>;
|
25
|
-
type
|
28
|
+
type ConfigTypes<SV extends AnySchemaValidator> = Function | SchemaFunction<SV> | Constructor | SchemaConstructor<SV> | IdiomaticSchema<SV>;
|
29
|
+
type ConfigValidator<SV extends AnySchemaValidator> = Record<string, ConfigTypes<SV> | Record<string, ConfigTypes<SV>>>;
|
30
|
+
type ResolveConfigValue<SV extends AnySchemaValidator, T> = T extends SchemaConstructor<SV> ? Schema<InstanceType<T>, SV> : T extends SchemaFunction<SV> ? Schema<ReturnType<T>, SV> : T extends Function ? ReturnType<T> : T extends Constructor ? InstanceType<T> : T extends Record<string, ConfigTypes<SV>> ? {
|
31
|
+
[K in keyof T]: ResolveConfigValue<SV, T[K]>;
|
32
|
+
} : Schema<T, SV>;
|
26
33
|
type ResolvedConfigValidator<SV extends AnySchemaValidator, CV extends ConfigValidator<SV>> = {
|
27
|
-
[M in keyof CV]:
|
34
|
+
[M in keyof CV]: ResolveConfigValue<SV, CV[M]>;
|
28
35
|
};
|
29
36
|
type ScopedDependencyFactory<SV extends AnySchemaValidator, CV extends ConfigValidator<SV>, M extends keyof CV> = (scope?: ConfigInjector<SV, CV>) => ResolvedConfigValidator<SV, CV>[M];
|
30
37
|
|
38
|
+
declare function createConfigInjector<SV extends AnySchemaValidator, CV extends ConfigValidator<SV>>(schemaValidator: SV, dependenciesDefinition: {
|
39
|
+
[K in keyof CV]: Singleton<CV[K], Omit<ResolvedConfigValidator<SV, CV>, K>, ResolvedConfigValidator<SV, CV>[K]> | Constructed<CV[K], Omit<ResolvedConfigValidator<SV, CV>, K>, ResolvedConfigValidator<SV, CV>[K]>;
|
40
|
+
}): ConfigInjector<SV, CV>;
|
31
41
|
declare class ConfigInjector<SV extends AnySchemaValidator, CV extends ConfigValidator<SV>> {
|
32
42
|
private schemaValidator;
|
33
|
-
private configShapes;
|
34
43
|
private dependenciesDefinition;
|
35
44
|
instances: {
|
36
45
|
[K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];
|
37
46
|
};
|
47
|
+
readonly configShapes: CV;
|
48
|
+
load(inheritedScopeInstances?: {
|
49
|
+
[K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];
|
50
|
+
}): this;
|
38
51
|
private loadSingletons;
|
39
52
|
private resolveInstance;
|
40
|
-
constructor(schemaValidator: SV,
|
41
|
-
[K in keyof CV]: Singleton<Omit<ResolvedConfigValidator<SV, CV>, K>, ResolvedConfigValidator<SV, CV>[K]> | Constructed<Omit<ResolvedConfigValidator<SV, CV>, K>, ResolvedConfigValidator<SV, CV>[K]
|
42
|
-
|
43
|
-
|
53
|
+
constructor(schemaValidator: SV, dependenciesDefinition: {
|
54
|
+
[K in keyof CV]: (Singleton<CV[K], Omit<ResolvedConfigValidator<SV, CV>, K>, ResolvedConfigValidator<SV, CV>[K]> | Constructed<CV[K], Omit<ResolvedConfigValidator<SV, CV>, K>, ResolvedConfigValidator<SV, CV>[K]>) & {
|
55
|
+
type: CV[K];
|
56
|
+
};
|
44
57
|
});
|
45
58
|
safeValidateConfigSingletons(): ParseResult<ValidConfigInjector<SV, CV>>;
|
46
59
|
validateConfigSingletons(configName: string): ValidConfigInjector<SV, CV>;
|
@@ -48,6 +61,14 @@ declare class ConfigInjector<SV extends AnySchemaValidator, CV extends ConfigVal
|
|
48
61
|
scopedResolver<T extends keyof CV>(token: T, context?: Record<string, unknown>, resolutionPath?: (keyof CV)[]): (scope?: ConfigInjector<SV, CV>) => ResolvedConfigValidator<SV, CV>[T];
|
49
62
|
createScope(): ConfigInjector<SV, CV>;
|
50
63
|
dispose(): void;
|
64
|
+
chain<ChainedCV extends ConfigValidator<SV>>(dependenciesDefinition: {
|
65
|
+
[K in keyof ChainedCV]: {
|
66
|
+
type: ChainedCV[K];
|
67
|
+
} & (Singleton<ChainedCV[K], Omit<ResolvedConfigValidator<SV, CV & ChainedCV>, K>, ResolvedConfigValidator<SV, ChainedCV>[K]> | Constructed<ChainedCV[K], Omit<ResolvedConfigValidator<SV, CV & ChainedCV>, K>, ResolvedConfigValidator<SV, ChainedCV>[K]>);
|
68
|
+
}): ConfigInjector<SV, CV & ChainedCV>;
|
69
|
+
tokens(): {
|
70
|
+
[K in keyof CV]: K;
|
71
|
+
};
|
51
72
|
}
|
52
73
|
declare class ValidConfigInjector<SV extends AnySchemaValidator, CV extends ConfigValidator<SV>> extends ConfigInjector<SV, CV> {
|
53
74
|
validConfigInjector: void;
|
@@ -72,5 +93,14 @@ interface BaseService {
|
|
72
93
|
type EntityManager = {
|
73
94
|
fork: <Options>(options?: Options) => EntityManager;
|
74
95
|
};
|
96
|
+
type DependencyShapes<CreateDependencies extends (...args: never[]) => {
|
97
|
+
serviceDependencies: {
|
98
|
+
configShapes: unknown;
|
99
|
+
};
|
100
|
+
}> = ReturnType<CreateDependencies>['serviceDependencies']['configShapes'];
|
101
|
+
|
102
|
+
type MapNestedDtoArraysToCollections<Dto, Keys extends string> = Omit<Dto, Keys> & {
|
103
|
+
[K in Keys]: Collection<object>;
|
104
|
+
};
|
75
105
|
|
76
|
-
export { type BaseService, ConfigInjector, type ConfigValidator, type Constructed, type ConstructedSingleton, type Constructor, type EntityManager, type Function, Lifetime, type ResolvedConfigValidator, type SchemaConstructor, type SchemaFunction, type ScopedDependencyFactory, type Singleton, ValidConfigInjector, getEnvVar };
|
106
|
+
export { type BaseService, ConfigInjector, type ConfigValidator, type Constructed, type ConstructedSingleton, type Constructor, type DependencyShapes, type EntityManager, type Function, Lifetime, type MapNestedDtoArraysToCollections, type ResolvedConfigValidator, type SchemaConstructor, type SchemaFunction, type ScopedDependencyFactory, type Singleton, ValidConfigInjector, createConfigInjector, getEnvVar };
|
@@ -1,46 +1,59 @@
|
|
1
1
|
import { AnySchemaValidator, IdiomaticSchema, Schema, ParseResult } from '@forklaunch/validator';
|
2
|
-
import { EntityManager as EntityManager$1 } from '@mikro-orm/core';
|
2
|
+
import { EntityManager as EntityManager$1, Collection } from '@mikro-orm/core';
|
3
3
|
|
4
4
|
declare enum Lifetime {
|
5
5
|
Singleton = 0,
|
6
6
|
Transient = 1,
|
7
7
|
Scoped = 2
|
8
8
|
}
|
9
|
-
type Singleton<Args, Value> = {
|
9
|
+
type Singleton<Type, Args, Value> = {
|
10
10
|
lifetime: Lifetime.Singleton;
|
11
|
+
type: Type;
|
11
12
|
value: Value;
|
12
|
-
} | ConstructedSingleton<Args, Value>;
|
13
|
-
type ConstructedSingleton<Args, Return> = {
|
13
|
+
} | ConstructedSingleton<Type, Args, Value>;
|
14
|
+
type ConstructedSingleton<Type, Args, Return> = {
|
14
15
|
lifetime: Lifetime.Singleton;
|
16
|
+
type: Type;
|
15
17
|
factory: (args: Args, resolve: <T extends keyof Args>(token: T, context?: Record<string, unknown>) => Args[T], context: Record<string, unknown>) => Return;
|
16
18
|
};
|
17
|
-
type Constructed<Args, Return> = {
|
19
|
+
type Constructed<Type, Args, Return> = {
|
18
20
|
lifetime: Lifetime.Transient | Lifetime.Scoped;
|
21
|
+
type: Type;
|
19
22
|
factory: (args: Args, resolve: <T extends keyof Args>(token: T, context?: Record<string, unknown>) => Args[T], context: Record<string, unknown>) => Return;
|
20
23
|
};
|
21
24
|
type Constructor = new (...args: never[]) => unknown;
|
22
25
|
type SchemaConstructor<SV extends AnySchemaValidator> = new (...args: unknown[]) => IdiomaticSchema<SV>;
|
23
26
|
type Function = (...args: never[]) => unknown;
|
24
27
|
type SchemaFunction<SV extends AnySchemaValidator> = (args: unknown) => IdiomaticSchema<SV>;
|
25
|
-
type
|
28
|
+
type ConfigTypes<SV extends AnySchemaValidator> = Function | SchemaFunction<SV> | Constructor | SchemaConstructor<SV> | IdiomaticSchema<SV>;
|
29
|
+
type ConfigValidator<SV extends AnySchemaValidator> = Record<string, ConfigTypes<SV> | Record<string, ConfigTypes<SV>>>;
|
30
|
+
type ResolveConfigValue<SV extends AnySchemaValidator, T> = T extends SchemaConstructor<SV> ? Schema<InstanceType<T>, SV> : T extends SchemaFunction<SV> ? Schema<ReturnType<T>, SV> : T extends Function ? ReturnType<T> : T extends Constructor ? InstanceType<T> : T extends Record<string, ConfigTypes<SV>> ? {
|
31
|
+
[K in keyof T]: ResolveConfigValue<SV, T[K]>;
|
32
|
+
} : Schema<T, SV>;
|
26
33
|
type ResolvedConfigValidator<SV extends AnySchemaValidator, CV extends ConfigValidator<SV>> = {
|
27
|
-
[M in keyof CV]:
|
34
|
+
[M in keyof CV]: ResolveConfigValue<SV, CV[M]>;
|
28
35
|
};
|
29
36
|
type ScopedDependencyFactory<SV extends AnySchemaValidator, CV extends ConfigValidator<SV>, M extends keyof CV> = (scope?: ConfigInjector<SV, CV>) => ResolvedConfigValidator<SV, CV>[M];
|
30
37
|
|
38
|
+
declare function createConfigInjector<SV extends AnySchemaValidator, CV extends ConfigValidator<SV>>(schemaValidator: SV, dependenciesDefinition: {
|
39
|
+
[K in keyof CV]: Singleton<CV[K], Omit<ResolvedConfigValidator<SV, CV>, K>, ResolvedConfigValidator<SV, CV>[K]> | Constructed<CV[K], Omit<ResolvedConfigValidator<SV, CV>, K>, ResolvedConfigValidator<SV, CV>[K]>;
|
40
|
+
}): ConfigInjector<SV, CV>;
|
31
41
|
declare class ConfigInjector<SV extends AnySchemaValidator, CV extends ConfigValidator<SV>> {
|
32
42
|
private schemaValidator;
|
33
|
-
private configShapes;
|
34
43
|
private dependenciesDefinition;
|
35
44
|
instances: {
|
36
45
|
[K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];
|
37
46
|
};
|
47
|
+
readonly configShapes: CV;
|
48
|
+
load(inheritedScopeInstances?: {
|
49
|
+
[K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];
|
50
|
+
}): this;
|
38
51
|
private loadSingletons;
|
39
52
|
private resolveInstance;
|
40
|
-
constructor(schemaValidator: SV,
|
41
|
-
[K in keyof CV]: Singleton<Omit<ResolvedConfigValidator<SV, CV>, K>, ResolvedConfigValidator<SV, CV>[K]> | Constructed<Omit<ResolvedConfigValidator<SV, CV>, K>, ResolvedConfigValidator<SV, CV>[K]
|
42
|
-
|
43
|
-
|
53
|
+
constructor(schemaValidator: SV, dependenciesDefinition: {
|
54
|
+
[K in keyof CV]: (Singleton<CV[K], Omit<ResolvedConfigValidator<SV, CV>, K>, ResolvedConfigValidator<SV, CV>[K]> | Constructed<CV[K], Omit<ResolvedConfigValidator<SV, CV>, K>, ResolvedConfigValidator<SV, CV>[K]>) & {
|
55
|
+
type: CV[K];
|
56
|
+
};
|
44
57
|
});
|
45
58
|
safeValidateConfigSingletons(): ParseResult<ValidConfigInjector<SV, CV>>;
|
46
59
|
validateConfigSingletons(configName: string): ValidConfigInjector<SV, CV>;
|
@@ -48,6 +61,14 @@ declare class ConfigInjector<SV extends AnySchemaValidator, CV extends ConfigVal
|
|
48
61
|
scopedResolver<T extends keyof CV>(token: T, context?: Record<string, unknown>, resolutionPath?: (keyof CV)[]): (scope?: ConfigInjector<SV, CV>) => ResolvedConfigValidator<SV, CV>[T];
|
49
62
|
createScope(): ConfigInjector<SV, CV>;
|
50
63
|
dispose(): void;
|
64
|
+
chain<ChainedCV extends ConfigValidator<SV>>(dependenciesDefinition: {
|
65
|
+
[K in keyof ChainedCV]: {
|
66
|
+
type: ChainedCV[K];
|
67
|
+
} & (Singleton<ChainedCV[K], Omit<ResolvedConfigValidator<SV, CV & ChainedCV>, K>, ResolvedConfigValidator<SV, ChainedCV>[K]> | Constructed<ChainedCV[K], Omit<ResolvedConfigValidator<SV, CV & ChainedCV>, K>, ResolvedConfigValidator<SV, ChainedCV>[K]>);
|
68
|
+
}): ConfigInjector<SV, CV & ChainedCV>;
|
69
|
+
tokens(): {
|
70
|
+
[K in keyof CV]: K;
|
71
|
+
};
|
51
72
|
}
|
52
73
|
declare class ValidConfigInjector<SV extends AnySchemaValidator, CV extends ConfigValidator<SV>> extends ConfigInjector<SV, CV> {
|
53
74
|
validConfigInjector: void;
|
@@ -72,5 +93,14 @@ interface BaseService {
|
|
72
93
|
type EntityManager = {
|
73
94
|
fork: <Options>(options?: Options) => EntityManager;
|
74
95
|
};
|
96
|
+
type DependencyShapes<CreateDependencies extends (...args: never[]) => {
|
97
|
+
serviceDependencies: {
|
98
|
+
configShapes: unknown;
|
99
|
+
};
|
100
|
+
}> = ReturnType<CreateDependencies>['serviceDependencies']['configShapes'];
|
101
|
+
|
102
|
+
type MapNestedDtoArraysToCollections<Dto, Keys extends string> = Omit<Dto, Keys> & {
|
103
|
+
[K in Keys]: Collection<object>;
|
104
|
+
};
|
75
105
|
|
76
|
-
export { type BaseService, ConfigInjector, type ConfigValidator, type Constructed, type ConstructedSingleton, type Constructor, type EntityManager, type Function, Lifetime, type ResolvedConfigValidator, type SchemaConstructor, type SchemaFunction, type ScopedDependencyFactory, type Singleton, ValidConfigInjector, getEnvVar };
|
106
|
+
export { type BaseService, ConfigInjector, type ConfigValidator, type Constructed, type ConstructedSingleton, type Constructor, type DependencyShapes, type EntityManager, type Function, Lifetime, type MapNestedDtoArraysToCollections, type ResolvedConfigValidator, type SchemaConstructor, type SchemaFunction, type ScopedDependencyFactory, type Singleton, ValidConfigInjector, createConfigInjector, getEnvVar };
|
@@ -23,6 +23,7 @@ __export(services_exports, {
|
|
23
23
|
ConfigInjector: () => ConfigInjector,
|
24
24
|
Lifetime: () => Lifetime,
|
25
25
|
ValidConfigInjector: () => ValidConfigInjector,
|
26
|
+
createConfigInjector: () => createConfigInjector,
|
26
27
|
getEnvVar: () => getEnvVar
|
27
28
|
});
|
28
29
|
module.exports = __toCommonJS(services_exports);
|
@@ -55,14 +56,30 @@ function isConstructor(value) {
|
|
55
56
|
}
|
56
57
|
|
57
58
|
// src/services/configInjector.ts
|
59
|
+
function createConfigInjector(schemaValidator, dependenciesDefinition) {
|
60
|
+
return new ConfigInjector(schemaValidator, dependenciesDefinition);
|
61
|
+
}
|
58
62
|
var ConfigInjector = class _ConfigInjector {
|
59
|
-
constructor(schemaValidator,
|
63
|
+
constructor(schemaValidator, dependenciesDefinition) {
|
60
64
|
this.schemaValidator = schemaValidator;
|
61
|
-
this.configShapes = configShapes;
|
62
65
|
this.dependenciesDefinition = dependenciesDefinition;
|
63
|
-
this.
|
66
|
+
this.configShapes = Object.entries(this.dependenciesDefinition).reduce(
|
67
|
+
(acc, [key, { type }]) => ({
|
68
|
+
...acc,
|
69
|
+
[key]: type
|
70
|
+
}),
|
71
|
+
{}
|
72
|
+
);
|
73
|
+
this.loadSingletons();
|
64
74
|
}
|
65
75
|
instances = {};
|
76
|
+
configShapes;
|
77
|
+
load(inheritedScopeInstances) {
|
78
|
+
for (const token in inheritedScopeInstances) {
|
79
|
+
this.instances[token] = inheritedScopeInstances[token];
|
80
|
+
}
|
81
|
+
return this;
|
82
|
+
}
|
66
83
|
loadSingletons(inheritedScopeInstances) {
|
67
84
|
for (const token in this.dependenciesDefinition) {
|
68
85
|
const definition = this.dependenciesDefinition[token];
|
@@ -79,10 +96,11 @@ var ConfigInjector = class _ConfigInjector {
|
|
79
96
|
}
|
80
97
|
}
|
81
98
|
}
|
99
|
+
return this;
|
82
100
|
}
|
83
101
|
resolveInstance(token, definition, context, resolutionPath = []) {
|
84
102
|
const injectorArgument = (0, import_common.extractArgumentNames)(definition.factory)[0];
|
85
|
-
if (injectorArgument === "_args") {
|
103
|
+
if (!injectorArgument || injectorArgument === "_args") {
|
86
104
|
return definition.factory(
|
87
105
|
{},
|
88
106
|
this.resolve.bind(this),
|
@@ -176,10 +194,8 @@ var ConfigInjector = class _ConfigInjector {
|
|
176
194
|
ok: true,
|
177
195
|
value: new ValidConfigInjector(
|
178
196
|
this.schemaValidator,
|
179
|
-
this.
|
180
|
-
|
181
|
-
this.instances
|
182
|
-
)
|
197
|
+
this.dependenciesDefinition
|
198
|
+
).loadSingletons({ ...this.instances })
|
183
199
|
} : {
|
184
200
|
ok: false,
|
185
201
|
errors: [
|
@@ -208,9 +224,22 @@ var ConfigInjector = class _ConfigInjector {
|
|
208
224
|
}
|
209
225
|
switch (definition.lifetime) {
|
210
226
|
case 0 /* Singleton */: {
|
227
|
+
if (isConstructedSingleton(definition) && !this.instances[token]) {
|
228
|
+
this.instances[token] = this.resolveInstance(
|
229
|
+
token,
|
230
|
+
definition,
|
231
|
+
context,
|
232
|
+
resolutionPath
|
233
|
+
);
|
234
|
+
}
|
211
235
|
return this.instances[token];
|
212
236
|
}
|
213
237
|
case 2 /* Scoped */: {
|
238
|
+
if (!isConstructed(definition)) {
|
239
|
+
throw new Error(
|
240
|
+
`Invalid dependency definition for ${String(token)}`
|
241
|
+
);
|
242
|
+
}
|
214
243
|
const scopedInstance = this.resolveInstance(
|
215
244
|
token,
|
216
245
|
definition,
|
@@ -221,6 +250,11 @@ var ConfigInjector = class _ConfigInjector {
|
|
221
250
|
return scopedInstance;
|
222
251
|
}
|
223
252
|
case 1 /* Transient */: {
|
253
|
+
if (!isConstructed(definition)) {
|
254
|
+
throw new Error(
|
255
|
+
`Invalid dependency definition for ${String(token)}`
|
256
|
+
);
|
257
|
+
}
|
224
258
|
return this.resolveInstance(
|
225
259
|
token,
|
226
260
|
definition,
|
@@ -247,15 +281,24 @@ var ConfigInjector = class _ConfigInjector {
|
|
247
281
|
createScope() {
|
248
282
|
return new _ConfigInjector(
|
249
283
|
this.schemaValidator,
|
250
|
-
this.
|
251
|
-
|
252
|
-
this.instances
|
253
|
-
);
|
284
|
+
this.dependenciesDefinition
|
285
|
+
).loadSingletons({ ...this.instances });
|
254
286
|
}
|
255
287
|
dispose() {
|
256
288
|
this.instances = {};
|
257
289
|
this.loadSingletons();
|
258
290
|
}
|
291
|
+
chain(dependenciesDefinition) {
|
292
|
+
return new _ConfigInjector(this.schemaValidator, {
|
293
|
+
...this.dependenciesDefinition,
|
294
|
+
...dependenciesDefinition
|
295
|
+
}).load({ ...this.instances });
|
296
|
+
}
|
297
|
+
tokens() {
|
298
|
+
return Object.fromEntries(
|
299
|
+
Object.keys(this.dependenciesDefinition).map((key) => [key, key])
|
300
|
+
);
|
301
|
+
}
|
259
302
|
};
|
260
303
|
var ValidConfigInjector = class extends ConfigInjector {
|
261
304
|
validConfigInjector;
|
@@ -271,6 +314,7 @@ function getEnvVar(name) {
|
|
271
314
|
ConfigInjector,
|
272
315
|
Lifetime,
|
273
316
|
ValidConfigInjector,
|
317
|
+
createConfigInjector,
|
274
318
|
getEnvVar
|
275
319
|
});
|
276
320
|
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../../src/services/index.ts","../../../src/services/configInjector.ts","../../../src/services/guards/isConstructed.ts","../../../src/services/types/configInjector.types.ts","../../../src/services/guards/isConstructedSingleton.ts","../../../src/services/guards/isConstructor.ts","../../../src/services/getEnvVar.ts"],"sourcesContent":["export * from './configInjector';\nexport * from './getEnvVar';\nexport * from './interfaces/baseService';\nexport * from './types/configInjector.types';\nexport * from './types/entityManager.types';\nexport * from './types/service.types';\n","import { extractArgumentNames, isNever } from '@forklaunch/common';\nimport {\n AnySchemaValidator,\n IdiomaticSchema,\n ParseResult,\n prettyPrintParseErrors,\n SchemaValidator\n} from '@forklaunch/validator';\nimport { isConstructed } from './guards/isConstructed';\nimport { isConstructedSingleton } from './guards/isConstructedSingleton';\nimport { isConstructor } from './guards/isConstructor';\nimport {\n ConfigValidator,\n Constructed,\n ConstructedSingleton,\n Lifetime,\n ResolvedConfigValidator,\n SchemaConstructor,\n SchemaFunction,\n Singleton\n} from './types/configInjector.types';\n\nexport function createConfigInjector<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n>(\n schemaValidator: SV,\n dependenciesDefinition: {\n [K in keyof CV]:\n | Singleton<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >\n | Constructed<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >;\n }\n) {\n return new ConfigInjector<SV, CV>(schemaValidator, dependenciesDefinition);\n}\n\nexport class ConfigInjector<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n> {\n instances: {\n [K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];\n } = {};\n\n readonly configShapes: CV;\n\n load(inheritedScopeInstances?: {\n [K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];\n }): this {\n for (const token in inheritedScopeInstances) {\n this.instances[token] = inheritedScopeInstances[token];\n }\n return this;\n }\n\n private loadSingletons(inheritedScopeInstances?: {\n [K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];\n }): this {\n for (const token in this.dependenciesDefinition) {\n const definition = this.dependenciesDefinition[token];\n if (definition.lifetime === Lifetime.Singleton) {\n if (inheritedScopeInstances && inheritedScopeInstances[token]) {\n this.instances[token] = inheritedScopeInstances[token];\n } else if (\n isConstructedSingleton<\n CV[typeof token],\n Omit<ResolvedConfigValidator<SV, CV>, typeof token>,\n ResolvedConfigValidator<SV, CV>[typeof token]\n >(definition)\n ) {\n this.instances[token] = this.resolveInstance<typeof token>(\n token,\n definition\n );\n } else {\n this.instances[token] = definition.value;\n }\n }\n }\n return this;\n }\n\n private resolveInstance<T extends keyof CV>(\n token: T,\n definition:\n | ConstructedSingleton<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >\n | Constructed<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >,\n context?: Record<string, unknown>,\n resolutionPath: (keyof CV)[] = []\n ): ResolvedConfigValidator<SV, CV>[T] {\n const injectorArgument = extractArgumentNames(definition.factory)[0];\n // short circuit as no args\n if (!injectorArgument || injectorArgument === '_args') {\n return definition.factory(\n {} as Omit<ResolvedConfigValidator<SV, CV>, T>,\n this.resolve.bind(this),\n context ?? ({} as Record<string, unknown>)\n );\n }\n\n if (!injectorArgument.startsWith('{') || !injectorArgument.endsWith('}')) {\n throw new Error(\n `Invalid injector argument for ${String(\n token\n )}: ${injectorArgument}. Please use object destructuring syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment.`\n );\n }\n const resolvedArguments = Object.fromEntries(\n injectorArgument\n .replace('{', '')\n .replace('}', '')\n .split(',')\n .map((arg) => arg.split(':')[0].trim())\n .map((arg) => {\n const newResolutionPath = [...resolutionPath, token];\n if (resolutionPath.includes(arg)) {\n throw new Error(\n `Circular dependency detected: ${newResolutionPath.join(\n ' -> '\n )} -> ${arg}`\n );\n }\n const resolvedArg = this.resolve(arg, context, newResolutionPath);\n return [arg, resolvedArg];\n })\n ) as unknown as Omit<ResolvedConfigValidator<SV, CV>, T>;\n return definition.factory(\n resolvedArguments,\n this.resolve.bind(this),\n context ?? ({} as Record<string, unknown>)\n );\n }\n\n constructor(\n private schemaValidator: SV,\n private dependenciesDefinition: {\n [K in keyof CV]: (\n | Singleton<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >\n | Constructed<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >\n ) & {\n type: CV[K];\n };\n }\n ) {\n this.configShapes = Object.entries(this.dependenciesDefinition).reduce(\n (acc, [key, { type }]) => ({\n ...acc,\n [key]: type\n }),\n {} as Record<keyof CV, CV[keyof CV]>\n ) as CV;\n this.loadSingletons();\n }\n\n safeValidateConfigSingletons(): ParseResult<ValidConfigInjector<SV, CV>> {\n const validNonSchemaSingletons = Object.entries(this.configShapes).reduce<\n ParseResult<ResolvedConfigValidator<SV, CV>>\n >(\n (acc, [key, value]) => {\n if (\n this.dependenciesDefinition[key].lifetime === Lifetime.Singleton &&\n !(this.schemaValidator as SchemaValidator).isSchema<\n SchemaFunction<SV> | SchemaConstructor<SV> | IdiomaticSchema<SV>\n >(value) &&\n isConstructor(value)\n ) {\n if (!(this.instances[key] instanceof value)) {\n const expected = value.name;\n const receivedValue: unknown = this.instances[key];\n const received = isConstructed(receivedValue)\n ? receivedValue.constructor.name\n : typeof receivedValue;\n\n if (acc.ok) {\n acc = {\n ok: false,\n errors: []\n };\n }\n acc.errors?.push({\n message: `Expected ${expected}, received ${received}`,\n path: [key]\n });\n } else {\n if (acc.ok) {\n acc = {\n ok: true,\n value: {\n ...acc.value,\n [key]: this.instances[key]\n }\n };\n }\n }\n return acc;\n }\n return acc;\n },\n {\n ok: true,\n value: {} as ResolvedConfigValidator<SV, CV>\n }\n );\n\n const singletons = Object.fromEntries(\n Object.entries(this.configShapes).filter(\n ([key, value]) =>\n this.dependenciesDefinition[key].lifetime === Lifetime.Singleton &&\n (this.schemaValidator as SchemaValidator).isSchema(value)\n )\n );\n const schemaSingletonParseResult = (\n this.schemaValidator as SchemaValidator\n ).parse(\n (this.schemaValidator as SchemaValidator).schemify(singletons),\n Object.fromEntries(\n Object.keys(singletons).map((key) => {\n const dependency = this.dependenciesDefinition[key];\n return [\n key,\n dependency.lifetime === Lifetime.Singleton\n ? this.instances[key]\n : undefined\n ];\n })\n )\n );\n\n const configKeys = Object.keys(this.configShapes);\n\n return validNonSchemaSingletons.ok && schemaSingletonParseResult.ok\n ? {\n ok: true as const,\n value: new ValidConfigInjector<SV, CV>(\n this.schemaValidator,\n this.dependenciesDefinition\n ).loadSingletons({ ...this.instances })\n }\n : {\n ok: false as const,\n errors: [\n ...(!validNonSchemaSingletons.ok && validNonSchemaSingletons.errors\n ? validNonSchemaSingletons.errors\n : []),\n ...(!schemaSingletonParseResult.ok &&\n schemaSingletonParseResult.errors\n ? schemaSingletonParseResult.errors\n : [])\n ].sort(\n (a, b) =>\n configKeys.indexOf(a.path[0]) - configKeys.indexOf(b.path[0])\n )\n };\n }\n\n validateConfigSingletons(configName: string): ValidConfigInjector<SV, CV> {\n const safeValidateResult = this.safeValidateConfigSingletons();\n\n if (safeValidateResult.ok) {\n return safeValidateResult.value;\n }\n\n throw new Error(\n prettyPrintParseErrors(safeValidateResult.errors, configName)\n );\n }\n\n resolve<T extends keyof CV>(\n token: T,\n context?: Record<string, unknown>,\n resolutionPath: (keyof CV)[] = []\n ): ResolvedConfigValidator<SV, CV>[T] {\n const instance = this.instances[token];\n if (!instance) {\n const definition = this.dependenciesDefinition[token];\n\n if (!definition) {\n throw new Error(`Unable to resolve dependency ${String(token)}`);\n }\n\n switch (definition.lifetime) {\n case Lifetime.Singleton: {\n if (\n isConstructedSingleton<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >(definition) &&\n !this.instances[token]\n ) {\n this.instances[token] = this.resolveInstance<T>(\n token,\n definition,\n context,\n resolutionPath\n );\n }\n return this.instances[token] as ResolvedConfigValidator<SV, CV>[T];\n }\n case Lifetime.Scoped: {\n if (\n !isConstructed<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >(definition)\n ) {\n throw new Error(\n `Invalid dependency definition for ${String(token)}`\n );\n }\n\n const scopedInstance = this.resolveInstance<T>(\n token,\n definition,\n context,\n resolutionPath\n );\n this.instances[token] = scopedInstance;\n return scopedInstance;\n }\n case Lifetime.Transient: {\n if (\n !isConstructed<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >(definition)\n ) {\n throw new Error(\n `Invalid dependency definition for ${String(token)}`\n );\n }\n\n return this.resolveInstance<T>(\n token,\n definition,\n context,\n resolutionPath\n );\n }\n default: {\n isNever(definition);\n throw new Error(\n `Unable to resolve lifetime for dependency ${String(\n token\n )}, ${resolutionPath}`\n );\n }\n }\n } else {\n return instance;\n }\n }\n\n scopedResolver<T extends keyof CV>(\n token: T,\n context?: Record<string, unknown>,\n resolutionPath: (keyof CV)[] = []\n ): (scope?: ConfigInjector<SV, CV>) => ResolvedConfigValidator<SV, CV>[T] {\n return (scope) =>\n (scope ?? this.createScope()).resolve<T>(token, context, resolutionPath);\n }\n\n createScope(): ConfigInjector<SV, CV> {\n return new ConfigInjector<SV, CV>(\n this.schemaValidator,\n this.dependenciesDefinition\n ).loadSingletons({ ...this.instances });\n }\n\n dispose(): void {\n this.instances = {};\n this.loadSingletons();\n }\n\n chain<ChainedCV extends ConfigValidator<SV>>(dependenciesDefinition: {\n [K in keyof ChainedCV]: {\n type: ChainedCV[K];\n } & (\n | Singleton<\n ChainedCV[K],\n Omit<ResolvedConfigValidator<SV, CV & ChainedCV>, K>,\n ResolvedConfigValidator<SV, ChainedCV>[K]\n >\n | Constructed<\n ChainedCV[K],\n Omit<ResolvedConfigValidator<SV, CV & ChainedCV>, K>,\n ResolvedConfigValidator<SV, ChainedCV>[K]\n >\n );\n }): ConfigInjector<SV, CV & ChainedCV> {\n return new ConfigInjector<SV, CV>(this.schemaValidator, {\n ...this.dependenciesDefinition,\n ...dependenciesDefinition\n }).load({ ...this.instances }) as unknown as ConfigInjector<\n SV,\n CV & ChainedCV\n >;\n }\n\n tokens(): {\n [K in keyof CV]: K;\n } {\n return Object.fromEntries(\n Object.keys(this.dependenciesDefinition).map((key) => [key, key])\n ) as {\n [K in keyof CV]: K;\n };\n }\n}\n\nexport class ValidConfigInjector<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n> extends ConfigInjector<SV, CV> {\n validConfigInjector!: void;\n}\n","import { Constructed } from '../types/configInjector.types';\n\nexport function isConstructed<Type, Args, Return>(\n value: unknown\n): value is Constructed<Type, Args, Return> {\n return (\n typeof value === 'object' &&\n value != null &&\n 'constructor' in value &&\n value.constructor != null\n );\n}\n","import {\n AnySchemaValidator,\n IdiomaticSchema,\n Schema\n} from '@forklaunch/validator';\nimport { ConfigInjector } from '../configInjector';\n\nexport enum Lifetime {\n Singleton,\n Transient,\n Scoped\n}\n\nexport type Singleton<Type, Args, Value> =\n | {\n lifetime: Lifetime.Singleton;\n type: Type;\n value: Value;\n }\n | ConstructedSingleton<Type, Args, Value>;\n\nexport type ConstructedSingleton<Type, Args, Return> = {\n lifetime: Lifetime.Singleton;\n type: Type;\n factory: (\n args: Args,\n resolve: <T extends keyof Args>(\n token: T,\n context?: Record<string, unknown>\n ) => Args[T],\n context: Record<string, unknown>\n ) => Return;\n};\n\nexport type Constructed<Type, Args, Return> = {\n lifetime: Lifetime.Transient | Lifetime.Scoped;\n type: Type;\n factory: (\n args: Args,\n resolve: <T extends keyof Args>(\n token: T,\n context?: Record<string, unknown>\n ) => Args[T],\n context: Record<string, unknown>\n ) => Return;\n};\n\nexport type Constructor = new (...args: never[]) => unknown;\nexport type SchemaConstructor<SV extends AnySchemaValidator> = new (\n ...args: unknown[]\n) => IdiomaticSchema<SV>;\nexport type Function = (...args: never[]) => unknown;\nexport type SchemaFunction<SV extends AnySchemaValidator> = (\n args: unknown\n) => IdiomaticSchema<SV>;\n\ntype ConfigTypes<SV extends AnySchemaValidator> =\n | Function\n | SchemaFunction<SV>\n | Constructor\n | SchemaConstructor<SV>\n | IdiomaticSchema<SV>;\n\nexport type ConfigValidator<SV extends AnySchemaValidator> = Record<\n string,\n ConfigTypes<SV> | Record<string, ConfigTypes<SV>>\n>;\n\ntype ResolveConfigValue<SV extends AnySchemaValidator, T> =\n T extends SchemaConstructor<SV>\n ? Schema<InstanceType<T>, SV>\n : T extends SchemaFunction<SV>\n ? Schema<ReturnType<T>, SV>\n : T extends Function\n ? ReturnType<T>\n : T extends Constructor\n ? InstanceType<T>\n : T extends Record<string, ConfigTypes<SV>>\n ? {\n [K in keyof T]: ResolveConfigValue<SV, T[K]>;\n }\n : Schema<T, SV>;\n\nexport type ResolvedConfigValidator<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n> = {\n [M in keyof CV]: ResolveConfigValue<SV, CV[M]>;\n};\n\nexport type ScopedDependencyFactory<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>,\n M extends keyof CV\n> = (scope?: ConfigInjector<SV, CV>) => ResolvedConfigValidator<SV, CV>[M];\n","import { ConstructedSingleton, Lifetime } from '../types/configInjector.types';\n\nexport function isConstructedSingleton<Type, Args, Return>(\n value: unknown\n): value is ConstructedSingleton<Type, Args, Return> {\n return (\n typeof value === 'object' &&\n value != null &&\n 'lifetime' in value &&\n value.lifetime === Lifetime.Singleton &&\n 'factory' in value\n );\n}\n","import { Constructor } from '../types/configInjector.types';\n\nexport function isConstructor(value: unknown): value is Constructor {\n return (\n typeof value === 'function' &&\n value.constructor != null &&\n value.prototype != null\n );\n}\n","// This is a simple function that returns the value of an environment variable.\n// It casts a potentially undefined value to a string, since it will be validated in order to be bootstrapped.\n\nexport function getEnvVar(name: string): string {\n const value = process.env[name];\n return value as string;\n}\n"],"mappings":"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","names":["Lifetime"]}
|
@@ -28,14 +28,30 @@ function isConstructor(value) {
|
|
28
28
|
}
|
29
29
|
|
30
30
|
// src/services/configInjector.ts
|
31
|
+
function createConfigInjector(schemaValidator, dependenciesDefinition) {
|
32
|
+
return new ConfigInjector(schemaValidator, dependenciesDefinition);
|
33
|
+
}
|
31
34
|
var ConfigInjector = class _ConfigInjector {
|
32
|
-
constructor(schemaValidator,
|
35
|
+
constructor(schemaValidator, dependenciesDefinition) {
|
33
36
|
this.schemaValidator = schemaValidator;
|
34
|
-
this.configShapes = configShapes;
|
35
37
|
this.dependenciesDefinition = dependenciesDefinition;
|
36
|
-
this.
|
38
|
+
this.configShapes = Object.entries(this.dependenciesDefinition).reduce(
|
39
|
+
(acc, [key, { type }]) => ({
|
40
|
+
...acc,
|
41
|
+
[key]: type
|
42
|
+
}),
|
43
|
+
{}
|
44
|
+
);
|
45
|
+
this.loadSingletons();
|
37
46
|
}
|
38
47
|
instances = {};
|
48
|
+
configShapes;
|
49
|
+
load(inheritedScopeInstances) {
|
50
|
+
for (const token in inheritedScopeInstances) {
|
51
|
+
this.instances[token] = inheritedScopeInstances[token];
|
52
|
+
}
|
53
|
+
return this;
|
54
|
+
}
|
39
55
|
loadSingletons(inheritedScopeInstances) {
|
40
56
|
for (const token in this.dependenciesDefinition) {
|
41
57
|
const definition = this.dependenciesDefinition[token];
|
@@ -52,10 +68,11 @@ var ConfigInjector = class _ConfigInjector {
|
|
52
68
|
}
|
53
69
|
}
|
54
70
|
}
|
71
|
+
return this;
|
55
72
|
}
|
56
73
|
resolveInstance(token, definition, context, resolutionPath = []) {
|
57
74
|
const injectorArgument = extractArgumentNames(definition.factory)[0];
|
58
|
-
if (injectorArgument === "_args") {
|
75
|
+
if (!injectorArgument || injectorArgument === "_args") {
|
59
76
|
return definition.factory(
|
60
77
|
{},
|
61
78
|
this.resolve.bind(this),
|
@@ -149,10 +166,8 @@ var ConfigInjector = class _ConfigInjector {
|
|
149
166
|
ok: true,
|
150
167
|
value: new ValidConfigInjector(
|
151
168
|
this.schemaValidator,
|
152
|
-
this.
|
153
|
-
|
154
|
-
this.instances
|
155
|
-
)
|
169
|
+
this.dependenciesDefinition
|
170
|
+
).loadSingletons({ ...this.instances })
|
156
171
|
} : {
|
157
172
|
ok: false,
|
158
173
|
errors: [
|
@@ -181,9 +196,22 @@ var ConfigInjector = class _ConfigInjector {
|
|
181
196
|
}
|
182
197
|
switch (definition.lifetime) {
|
183
198
|
case 0 /* Singleton */: {
|
199
|
+
if (isConstructedSingleton(definition) && !this.instances[token]) {
|
200
|
+
this.instances[token] = this.resolveInstance(
|
201
|
+
token,
|
202
|
+
definition,
|
203
|
+
context,
|
204
|
+
resolutionPath
|
205
|
+
);
|
206
|
+
}
|
184
207
|
return this.instances[token];
|
185
208
|
}
|
186
209
|
case 2 /* Scoped */: {
|
210
|
+
if (!isConstructed(definition)) {
|
211
|
+
throw new Error(
|
212
|
+
`Invalid dependency definition for ${String(token)}`
|
213
|
+
);
|
214
|
+
}
|
187
215
|
const scopedInstance = this.resolveInstance(
|
188
216
|
token,
|
189
217
|
definition,
|
@@ -194,6 +222,11 @@ var ConfigInjector = class _ConfigInjector {
|
|
194
222
|
return scopedInstance;
|
195
223
|
}
|
196
224
|
case 1 /* Transient */: {
|
225
|
+
if (!isConstructed(definition)) {
|
226
|
+
throw new Error(
|
227
|
+
`Invalid dependency definition for ${String(token)}`
|
228
|
+
);
|
229
|
+
}
|
197
230
|
return this.resolveInstance(
|
198
231
|
token,
|
199
232
|
definition,
|
@@ -220,15 +253,24 @@ var ConfigInjector = class _ConfigInjector {
|
|
220
253
|
createScope() {
|
221
254
|
return new _ConfigInjector(
|
222
255
|
this.schemaValidator,
|
223
|
-
this.
|
224
|
-
|
225
|
-
this.instances
|
226
|
-
);
|
256
|
+
this.dependenciesDefinition
|
257
|
+
).loadSingletons({ ...this.instances });
|
227
258
|
}
|
228
259
|
dispose() {
|
229
260
|
this.instances = {};
|
230
261
|
this.loadSingletons();
|
231
262
|
}
|
263
|
+
chain(dependenciesDefinition) {
|
264
|
+
return new _ConfigInjector(this.schemaValidator, {
|
265
|
+
...this.dependenciesDefinition,
|
266
|
+
...dependenciesDefinition
|
267
|
+
}).load({ ...this.instances });
|
268
|
+
}
|
269
|
+
tokens() {
|
270
|
+
return Object.fromEntries(
|
271
|
+
Object.keys(this.dependenciesDefinition).map((key) => [key, key])
|
272
|
+
);
|
273
|
+
}
|
232
274
|
};
|
233
275
|
var ValidConfigInjector = class extends ConfigInjector {
|
234
276
|
validConfigInjector;
|
@@ -243,6 +285,7 @@ export {
|
|
243
285
|
ConfigInjector,
|
244
286
|
Lifetime,
|
245
287
|
ValidConfigInjector,
|
288
|
+
createConfigInjector,
|
246
289
|
getEnvVar
|
247
290
|
};
|
248
291
|
//# sourceMappingURL=index.mjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../../src/services/configInjector.ts","../../../src/services/guards/isConstructed.ts","../../../src/services/types/configInjector.types.ts","../../../src/services/guards/isConstructedSingleton.ts","../../../src/services/guards/isConstructor.ts","../../../src/services/getEnvVar.ts"],"sourcesContent":["import { extractArgumentNames, isNever } from '@forklaunch/common';\nimport {\n AnySchemaValidator,\n IdiomaticSchema,\n ParseResult,\n prettyPrintParseErrors,\n SchemaValidator\n} from '@forklaunch/validator';\nimport { isConstructed } from './guards/isConstructed';\nimport { isConstructedSingleton } from './guards/isConstructedSingleton';\nimport { isConstructor } from './guards/isConstructor';\nimport {\n ConfigValidator,\n Constructed,\n ConstructedSingleton,\n Lifetime,\n ResolvedConfigValidator,\n SchemaConstructor,\n SchemaFunction,\n Singleton\n} from './types/configInjector.types';\n\nexport function createConfigInjector<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n>(\n schemaValidator: SV,\n dependenciesDefinition: {\n [K in keyof CV]:\n | Singleton<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >\n | Constructed<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >;\n }\n) {\n return new ConfigInjector<SV, CV>(schemaValidator, dependenciesDefinition);\n}\n\nexport class ConfigInjector<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n> {\n instances: {\n [K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];\n } = {};\n\n readonly configShapes: CV;\n\n load(inheritedScopeInstances?: {\n [K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];\n }): this {\n for (const token in inheritedScopeInstances) {\n this.instances[token] = inheritedScopeInstances[token];\n }\n return this;\n }\n\n private loadSingletons(inheritedScopeInstances?: {\n [K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];\n }): this {\n for (const token in this.dependenciesDefinition) {\n const definition = this.dependenciesDefinition[token];\n if (definition.lifetime === Lifetime.Singleton) {\n if (inheritedScopeInstances && inheritedScopeInstances[token]) {\n this.instances[token] = inheritedScopeInstances[token];\n } else if (\n isConstructedSingleton<\n CV[typeof token],\n Omit<ResolvedConfigValidator<SV, CV>, typeof token>,\n ResolvedConfigValidator<SV, CV>[typeof token]\n >(definition)\n ) {\n this.instances[token] = this.resolveInstance<typeof token>(\n token,\n definition\n );\n } else {\n this.instances[token] = definition.value;\n }\n }\n }\n return this;\n }\n\n private resolveInstance<T extends keyof CV>(\n token: T,\n definition:\n | ConstructedSingleton<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >\n | Constructed<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >,\n context?: Record<string, unknown>,\n resolutionPath: (keyof CV)[] = []\n ): ResolvedConfigValidator<SV, CV>[T] {\n const injectorArgument = extractArgumentNames(definition.factory)[0];\n // short circuit as no args\n if (!injectorArgument || injectorArgument === '_args') {\n return definition.factory(\n {} as Omit<ResolvedConfigValidator<SV, CV>, T>,\n this.resolve.bind(this),\n context ?? ({} as Record<string, unknown>)\n );\n }\n\n if (!injectorArgument.startsWith('{') || !injectorArgument.endsWith('}')) {\n throw new Error(\n `Invalid injector argument for ${String(\n token\n )}: ${injectorArgument}. Please use object destructuring syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment.`\n );\n }\n const resolvedArguments = Object.fromEntries(\n injectorArgument\n .replace('{', '')\n .replace('}', '')\n .split(',')\n .map((arg) => arg.split(':')[0].trim())\n .map((arg) => {\n const newResolutionPath = [...resolutionPath, token];\n if (resolutionPath.includes(arg)) {\n throw new Error(\n `Circular dependency detected: ${newResolutionPath.join(\n ' -> '\n )} -> ${arg}`\n );\n }\n const resolvedArg = this.resolve(arg, context, newResolutionPath);\n return [arg, resolvedArg];\n })\n ) as unknown as Omit<ResolvedConfigValidator<SV, CV>, T>;\n return definition.factory(\n resolvedArguments,\n this.resolve.bind(this),\n context ?? ({} as Record<string, unknown>)\n );\n }\n\n constructor(\n private schemaValidator: SV,\n private dependenciesDefinition: {\n [K in keyof CV]: (\n | Singleton<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >\n | Constructed<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >\n ) & {\n type: CV[K];\n };\n }\n ) {\n this.configShapes = Object.entries(this.dependenciesDefinition).reduce(\n (acc, [key, { type }]) => ({\n ...acc,\n [key]: type\n }),\n {} as Record<keyof CV, CV[keyof CV]>\n ) as CV;\n this.loadSingletons();\n }\n\n safeValidateConfigSingletons(): ParseResult<ValidConfigInjector<SV, CV>> {\n const validNonSchemaSingletons = Object.entries(this.configShapes).reduce<\n ParseResult<ResolvedConfigValidator<SV, CV>>\n >(\n (acc, [key, value]) => {\n if (\n this.dependenciesDefinition[key].lifetime === Lifetime.Singleton &&\n !(this.schemaValidator as SchemaValidator).isSchema<\n SchemaFunction<SV> | SchemaConstructor<SV> | IdiomaticSchema<SV>\n >(value) &&\n isConstructor(value)\n ) {\n if (!(this.instances[key] instanceof value)) {\n const expected = value.name;\n const receivedValue: unknown = this.instances[key];\n const received = isConstructed(receivedValue)\n ? receivedValue.constructor.name\n : typeof receivedValue;\n\n if (acc.ok) {\n acc = {\n ok: false,\n errors: []\n };\n }\n acc.errors?.push({\n message: `Expected ${expected}, received ${received}`,\n path: [key]\n });\n } else {\n if (acc.ok) {\n acc = {\n ok: true,\n value: {\n ...acc.value,\n [key]: this.instances[key]\n }\n };\n }\n }\n return acc;\n }\n return acc;\n },\n {\n ok: true,\n value: {} as ResolvedConfigValidator<SV, CV>\n }\n );\n\n const singletons = Object.fromEntries(\n Object.entries(this.configShapes).filter(\n ([key, value]) =>\n this.dependenciesDefinition[key].lifetime === Lifetime.Singleton &&\n (this.schemaValidator as SchemaValidator).isSchema(value)\n )\n );\n const schemaSingletonParseResult = (\n this.schemaValidator as SchemaValidator\n ).parse(\n (this.schemaValidator as SchemaValidator).schemify(singletons),\n Object.fromEntries(\n Object.keys(singletons).map((key) => {\n const dependency = this.dependenciesDefinition[key];\n return [\n key,\n dependency.lifetime === Lifetime.Singleton\n ? this.instances[key]\n : undefined\n ];\n })\n )\n );\n\n const configKeys = Object.keys(this.configShapes);\n\n return validNonSchemaSingletons.ok && schemaSingletonParseResult.ok\n ? {\n ok: true as const,\n value: new ValidConfigInjector<SV, CV>(\n this.schemaValidator,\n this.dependenciesDefinition\n ).loadSingletons({ ...this.instances })\n }\n : {\n ok: false as const,\n errors: [\n ...(!validNonSchemaSingletons.ok && validNonSchemaSingletons.errors\n ? validNonSchemaSingletons.errors\n : []),\n ...(!schemaSingletonParseResult.ok &&\n schemaSingletonParseResult.errors\n ? schemaSingletonParseResult.errors\n : [])\n ].sort(\n (a, b) =>\n configKeys.indexOf(a.path[0]) - configKeys.indexOf(b.path[0])\n )\n };\n }\n\n validateConfigSingletons(configName: string): ValidConfigInjector<SV, CV> {\n const safeValidateResult = this.safeValidateConfigSingletons();\n\n if (safeValidateResult.ok) {\n return safeValidateResult.value;\n }\n\n throw new Error(\n prettyPrintParseErrors(safeValidateResult.errors, configName)\n );\n }\n\n resolve<T extends keyof CV>(\n token: T,\n context?: Record<string, unknown>,\n resolutionPath: (keyof CV)[] = []\n ): ResolvedConfigValidator<SV, CV>[T] {\n const instance = this.instances[token];\n if (!instance) {\n const definition = this.dependenciesDefinition[token];\n\n if (!definition) {\n throw new Error(`Unable to resolve dependency ${String(token)}`);\n }\n\n switch (definition.lifetime) {\n case Lifetime.Singleton: {\n if (\n isConstructedSingleton<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >(definition) &&\n !this.instances[token]\n ) {\n this.instances[token] = this.resolveInstance<T>(\n token,\n definition,\n context,\n resolutionPath\n );\n }\n return this.instances[token] as ResolvedConfigValidator<SV, CV>[T];\n }\n case Lifetime.Scoped: {\n if (\n !isConstructed<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >(definition)\n ) {\n throw new Error(\n `Invalid dependency definition for ${String(token)}`\n );\n }\n\n const scopedInstance = this.resolveInstance<T>(\n token,\n definition,\n context,\n resolutionPath\n );\n this.instances[token] = scopedInstance;\n return scopedInstance;\n }\n case Lifetime.Transient: {\n if (\n !isConstructed<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >(definition)\n ) {\n throw new Error(\n `Invalid dependency definition for ${String(token)}`\n );\n }\n\n return this.resolveInstance<T>(\n token,\n definition,\n context,\n resolutionPath\n );\n }\n default: {\n isNever(definition);\n throw new Error(\n `Unable to resolve lifetime for dependency ${String(\n token\n )}, ${resolutionPath}`\n );\n }\n }\n } else {\n return instance;\n }\n }\n\n scopedResolver<T extends keyof CV>(\n token: T,\n context?: Record<string, unknown>,\n resolutionPath: (keyof CV)[] = []\n ): (scope?: ConfigInjector<SV, CV>) => ResolvedConfigValidator<SV, CV>[T] {\n return (scope) =>\n (scope ?? this.createScope()).resolve<T>(token, context, resolutionPath);\n }\n\n createScope(): ConfigInjector<SV, CV> {\n return new ConfigInjector<SV, CV>(\n this.schemaValidator,\n this.dependenciesDefinition\n ).loadSingletons({ ...this.instances });\n }\n\n dispose(): void {\n this.instances = {};\n this.loadSingletons();\n }\n\n chain<ChainedCV extends ConfigValidator<SV>>(dependenciesDefinition: {\n [K in keyof ChainedCV]: {\n type: ChainedCV[K];\n } & (\n | Singleton<\n ChainedCV[K],\n Omit<ResolvedConfigValidator<SV, CV & ChainedCV>, K>,\n ResolvedConfigValidator<SV, ChainedCV>[K]\n >\n | Constructed<\n ChainedCV[K],\n Omit<ResolvedConfigValidator<SV, CV & ChainedCV>, K>,\n ResolvedConfigValidator<SV, ChainedCV>[K]\n >\n );\n }): ConfigInjector<SV, CV & ChainedCV> {\n return new ConfigInjector<SV, CV>(this.schemaValidator, {\n ...this.dependenciesDefinition,\n ...dependenciesDefinition\n }).load({ ...this.instances }) as unknown as ConfigInjector<\n SV,\n CV & ChainedCV\n >;\n }\n\n tokens(): {\n [K in keyof CV]: K;\n } {\n return Object.fromEntries(\n Object.keys(this.dependenciesDefinition).map((key) => [key, key])\n ) as {\n [K in keyof CV]: K;\n };\n }\n}\n\nexport class ValidConfigInjector<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n> extends ConfigInjector<SV, CV> {\n validConfigInjector!: void;\n}\n","import { Constructed } from '../types/configInjector.types';\n\nexport function isConstructed<Type, Args, Return>(\n value: unknown\n): value is Constructed<Type, Args, Return> {\n return (\n typeof value === 'object' &&\n value != null &&\n 'constructor' in value &&\n value.constructor != null\n );\n}\n","import {\n AnySchemaValidator,\n IdiomaticSchema,\n Schema\n} from '@forklaunch/validator';\nimport { ConfigInjector } from '../configInjector';\n\nexport enum Lifetime {\n Singleton,\n Transient,\n Scoped\n}\n\nexport type Singleton<Type, Args, Value> =\n | {\n lifetime: Lifetime.Singleton;\n type: Type;\n value: Value;\n }\n | ConstructedSingleton<Type, Args, Value>;\n\nexport type ConstructedSingleton<Type, Args, Return> = {\n lifetime: Lifetime.Singleton;\n type: Type;\n factory: (\n args: Args,\n resolve: <T extends keyof Args>(\n token: T,\n context?: Record<string, unknown>\n ) => Args[T],\n context: Record<string, unknown>\n ) => Return;\n};\n\nexport type Constructed<Type, Args, Return> = {\n lifetime: Lifetime.Transient | Lifetime.Scoped;\n type: Type;\n factory: (\n args: Args,\n resolve: <T extends keyof Args>(\n token: T,\n context?: Record<string, unknown>\n ) => Args[T],\n context: Record<string, unknown>\n ) => Return;\n};\n\nexport type Constructor = new (...args: never[]) => unknown;\nexport type SchemaConstructor<SV extends AnySchemaValidator> = new (\n ...args: unknown[]\n) => IdiomaticSchema<SV>;\nexport type Function = (...args: never[]) => unknown;\nexport type SchemaFunction<SV extends AnySchemaValidator> = (\n args: unknown\n) => IdiomaticSchema<SV>;\n\ntype ConfigTypes<SV extends AnySchemaValidator> =\n | Function\n | SchemaFunction<SV>\n | Constructor\n | SchemaConstructor<SV>\n | IdiomaticSchema<SV>;\n\nexport type ConfigValidator<SV extends AnySchemaValidator> = Record<\n string,\n ConfigTypes<SV> | Record<string, ConfigTypes<SV>>\n>;\n\ntype ResolveConfigValue<SV extends AnySchemaValidator, T> =\n T extends SchemaConstructor<SV>\n ? Schema<InstanceType<T>, SV>\n : T extends SchemaFunction<SV>\n ? Schema<ReturnType<T>, SV>\n : T extends Function\n ? ReturnType<T>\n : T extends Constructor\n ? InstanceType<T>\n : T extends Record<string, ConfigTypes<SV>>\n ? {\n [K in keyof T]: ResolveConfigValue<SV, T[K]>;\n }\n : Schema<T, SV>;\n\nexport type ResolvedConfigValidator<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n> = {\n [M in keyof CV]: ResolveConfigValue<SV, CV[M]>;\n};\n\nexport type ScopedDependencyFactory<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>,\n M extends keyof CV\n> = (scope?: ConfigInjector<SV, CV>) => ResolvedConfigValidator<SV, CV>[M];\n","import { ConstructedSingleton, Lifetime } from '../types/configInjector.types';\n\nexport function isConstructedSingleton<Type, Args, Return>(\n value: unknown\n): value is ConstructedSingleton<Type, Args, Return> {\n return (\n typeof value === 'object' &&\n value != null &&\n 'lifetime' in value &&\n value.lifetime === Lifetime.Singleton &&\n 'factory' in value\n );\n}\n","import { Constructor } from '../types/configInjector.types';\n\nexport function isConstructor(value: unknown): value is Constructor {\n return (\n typeof value === 'function' &&\n value.constructor != null &&\n value.prototype != null\n );\n}\n","// This is a simple function that returns the value of an environment variable.\n// It casts a potentially undefined value to a string, since it will be validated in order to be bootstrapped.\n\nexport function getEnvVar(name: string): string {\n const value = process.env[name];\n return value as string;\n}\n"],"mappings":"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","names":["Lifetime"]}
|