awilixify 2.2.1 → 3.0.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.
Files changed (127) hide show
  1. package/README.md +12 -6
  2. package/dist/index.d.ts +18 -0
  3. package/dist/index.js +15 -0
  4. package/dist/lib/decorators/decorator-state.d.ts +15 -0
  5. package/dist/lib/decorators/decorator-state.js +72 -0
  6. package/dist/lib/decorators/decorator-state.types.d.ts +35 -0
  7. package/dist/lib/decorators/decorator-state.types.js +1 -0
  8. package/dist/lib/di/common.types.d.ts +6 -0
  9. package/dist/lib/di/common.types.js +1 -0
  10. package/dist/lib/di/contexts/container-context-base.d.ts +53 -0
  11. package/dist/lib/di/contexts/container-context-base.js +194 -0
  12. package/dist/lib/di/contexts/context-overrides.d.ts +22 -0
  13. package/dist/lib/di/contexts/context-overrides.js +93 -0
  14. package/dist/lib/di/contexts/di-context-async.d.ts +14 -0
  15. package/dist/lib/di/contexts/di-context-async.js +112 -0
  16. package/dist/lib/di/contexts/di-context-base.d.ts +19 -0
  17. package/dist/lib/di/contexts/di-context-base.js +32 -0
  18. package/dist/lib/di/contexts/di-context.d.ts +7 -0
  19. package/dist/lib/di/contexts/di-context.js +9 -0
  20. package/dist/lib/di/contexts/module-graph-ensurer.d.ts +31 -0
  21. package/dist/lib/di/contexts/module-graph-ensurer.js +45 -0
  22. package/dist/lib/di/contexts/module-overrides.d.ts +70 -0
  23. package/dist/lib/di/contexts/module-overrides.js +3 -0
  24. package/dist/lib/di/contexts/override-value.types.d.ts +6 -0
  25. package/dist/lib/di/contexts/override-value.types.js +1 -0
  26. package/dist/lib/di/contexts/overrides-processor.d.ts +22 -0
  27. package/dist/lib/di/contexts/overrides-processor.js +93 -0
  28. package/dist/lib/di/contexts/provider-overrides.types.d.ts +19 -0
  29. package/dist/lib/di/contexts/provider-overrides.types.js +1 -0
  30. package/dist/lib/di/errors.d.ts +66 -0
  31. package/dist/lib/di/errors.js +148 -0
  32. package/dist/lib/di/modules/module-def.types.d.ts +117 -0
  33. package/dist/lib/di/modules/module-def.types.js +1 -0
  34. package/dist/lib/di/modules/module-factories.d.ts +16 -0
  35. package/dist/lib/di/modules/module-factories.js +46 -0
  36. package/dist/lib/di/modules/module-overrides.d.ts +70 -0
  37. package/dist/lib/di/modules/module-overrides.js +3 -0
  38. package/dist/lib/di/modules/module-ref.types.d.ts +13 -0
  39. package/dist/lib/di/modules/module-ref.types.js +1 -0
  40. package/dist/lib/di/modules/module.types.d.ts +178 -0
  41. package/dist/lib/di/modules/module.types.js +1 -0
  42. package/dist/lib/di/modules/provider-overrides.types.d.ts +19 -0
  43. package/dist/lib/di/modules/provider-overrides.types.js +1 -0
  44. package/dist/lib/di/modules/runtime-module.types.d.ts +25 -0
  45. package/dist/lib/di/modules/runtime-module.types.js +1 -0
  46. package/dist/lib/di/processors/controller-processor.d.ts +13 -0
  47. package/dist/lib/di/processors/controller-processor.js +76 -0
  48. package/dist/lib/di/processors/handler-processor.d.ts +15 -0
  49. package/dist/lib/di/processors/handler-processor.js +69 -0
  50. package/dist/lib/di/processors/initializer-processor.d.ts +19 -0
  51. package/dist/lib/di/processors/initializer-processor.js +91 -0
  52. package/dist/lib/di/processors/interceptor-processor.d.ts +18 -0
  53. package/dist/lib/di/processors/interceptor-processor.js +101 -0
  54. package/dist/lib/di/processors/keyed-feature-registrar.d.ts +19 -0
  55. package/dist/lib/di/processors/keyed-feature-registrar.js +112 -0
  56. package/dist/lib/di/processors/lifecycle-processor.d.ts +38 -0
  57. package/dist/lib/di/processors/lifecycle-processor.js +178 -0
  58. package/dist/lib/di/processors/overrides-processor.d.ts +24 -0
  59. package/dist/lib/di/processors/overrides-processor.js +69 -0
  60. package/dist/lib/di/providers/basic-provider-resolver.d.ts +35 -0
  61. package/dist/lib/di/providers/basic-provider-resolver.js +88 -0
  62. package/dist/lib/di/providers/provider-dependency-sorter.d.ts +9 -0
  63. package/dist/lib/di/providers/provider-dependency-sorter.js +76 -0
  64. package/dist/lib/di/providers/provider-resolver.d.ts +31 -0
  65. package/dist/lib/di/providers/provider-resolver.js +128 -0
  66. package/dist/lib/di/providers/provider.types.d.ts +1 -0
  67. package/dist/lib/di/providers/provider.types.js +1 -0
  68. package/dist/lib/di/providers/types/controller.types.d.ts +9 -0
  69. package/dist/lib/di/providers/types/controller.types.js +1 -0
  70. package/dist/lib/di/providers/types/decorator-context.types.d.ts +9 -0
  71. package/dist/lib/di/providers/types/decorator-context.types.js +1 -0
  72. package/dist/lib/di/providers/types/handler.types.d.ts +9 -0
  73. package/dist/lib/di/providers/types/handler.types.js +1 -0
  74. package/dist/lib/di/providers/types/index.d.ts +7 -0
  75. package/dist/lib/di/providers/types/index.js +7 -0
  76. package/dist/lib/di/providers/types/initializer.types.d.ts +16 -0
  77. package/dist/lib/di/providers/types/initializer.types.js +3 -0
  78. package/dist/lib/di/providers/types/interceptor.types.d.ts +18 -0
  79. package/dist/lib/di/providers/types/interceptor.types.js +1 -0
  80. package/dist/lib/di/providers/types/middleware.types.d.ts +10 -0
  81. package/dist/lib/di/providers/types/middleware.types.js +1 -0
  82. package/dist/lib/di/providers/types/provider.types.d.ts +26 -0
  83. package/dist/lib/di/providers/types/provider.types.js +1 -0
  84. package/dist/lib/di/request-scope-context.d.ts +5 -0
  85. package/dist/lib/di/request-scope-context.js +28 -0
  86. package/dist/lib/di/type-guards.d.ts +35 -0
  87. package/dist/lib/di/type-guards.js +84 -0
  88. package/dist/lib/http/decorators.d.ts +33 -0
  89. package/dist/lib/http/decorators.js +151 -0
  90. package/dist/lib/http/exceptions.d.ts +58 -0
  91. package/dist/lib/http/exceptions.js +71 -0
  92. package/dist/lib/http/http-verbs.d.ts +12 -0
  93. package/dist/lib/http/http-verbs.js +11 -0
  94. package/dist/lib/http/index.d.ts +3 -0
  95. package/dist/lib/http/index.js +3 -0
  96. package/dist/lib/http/openapi-builder.d.ts +27 -0
  97. package/dist/lib/http/openapi-builder.js +83 -0
  98. package/dist/lib/mediator/contract.types.d.ts +159 -0
  99. package/dist/lib/mediator/contract.types.js +1 -0
  100. package/dist/lib/mediator/errors.d.ts +15 -0
  101. package/dist/lib/mediator/errors.js +33 -0
  102. package/dist/lib/mediator/global-middlewares.types.d.ts +13 -0
  103. package/dist/lib/mediator/global-middlewares.types.js +1 -0
  104. package/dist/lib/mediator/handler.types.d.ts +16 -0
  105. package/dist/lib/mediator/handler.types.js +1 -0
  106. package/dist/lib/mediator/mediator.d.ts +21 -0
  107. package/dist/lib/mediator/mediator.js +123 -0
  108. package/dist/lib/mediator/mediator.types.d.ts +64 -0
  109. package/dist/lib/mediator/mediator.types.js +1 -0
  110. package/dist/lib/mediator/middleware.types.d.ts +41 -0
  111. package/dist/lib/mediator/middleware.types.js +1 -0
  112. package/dist/lib/mediator/result.d.ts +18 -0
  113. package/dist/lib/mediator/result.js +24 -0
  114. package/dist/lib/react/errors.d.ts +12 -0
  115. package/dist/lib/react/errors.js +24 -0
  116. package/dist/lib/react/react-component-processor.d.ts +10 -0
  117. package/dist/lib/react/react-component-processor.js +62 -0
  118. package/dist/lib/react/react-di-context.d.ts +21 -0
  119. package/dist/lib/react/react-di-context.js +55 -0
  120. package/dist/lib/react/react-module-factories.d.ts +6 -0
  121. package/dist/lib/react/react-module-factories.js +34 -0
  122. package/dist/lib/react/react-module.types.d.ts +183 -0
  123. package/dist/lib/react/react-module.types.js +1 -0
  124. package/dist/react.d.ts +4 -0
  125. package/dist/react.js +4 -0
  126. package/dist/tsconfig.tsbuildinfo +1 -0
  127. package/package.json +29 -3
@@ -0,0 +1,178 @@
1
+ import * as Awilix from "awilix";
2
+ import * as ERRORS from "../errors.js";
3
+ import * as GUARGS from "../type-guards.js";
4
+ export class LifecycleProcessor {
5
+ providerOptions;
6
+ eagerProviderRefs = [];
7
+ initializerTasks = [];
8
+ createdScopes = [];
9
+ initPromise;
10
+ disposePromise;
11
+ constructor(providerOptions) {
12
+ this.providerOptions = providerOptions;
13
+ }
14
+ collectEagerProviders(m, scope) {
15
+ for (const key of this.getEagerProviderKeys(m)) {
16
+ this.eagerProviderRefs.push({
17
+ module: m,
18
+ scope,
19
+ key,
20
+ });
21
+ }
22
+ }
23
+ trackScope(scope) {
24
+ this.createdScopes.push(scope);
25
+ }
26
+ addInitializerTask(task) {
27
+ if (!task)
28
+ return;
29
+ this.initializerTasks.push(task);
30
+ }
31
+ init(options) {
32
+ this.initPromise ??= this.executeInit(options);
33
+ return this.initPromise;
34
+ }
35
+ dispose() {
36
+ this.disposePromise ??= this.executeDispose();
37
+ return this.disposePromise;
38
+ }
39
+ async executeInit(options) {
40
+ const initializedProviders = [];
41
+ for (const { module, scope, key } of this.sortEagerProviderRefs()) {
42
+ this.ensureEagerProviderUsesSingletonLifetime(module, scope, key);
43
+ const instance = await this.resolveEagerProvider({
44
+ module,
45
+ scope,
46
+ key,
47
+ });
48
+ initializedProviders.push({ module, scope, key, instance });
49
+ await this.callProviderInitAsync(instance);
50
+ }
51
+ for (const initialize of this.initializerTasks) {
52
+ await initialize(options);
53
+ }
54
+ for (const { key, instance } of initializedProviders) {
55
+ if (this.shouldSkipProviderPostInit(key, options))
56
+ continue;
57
+ await this.callProviderPostInitAsync(instance);
58
+ }
59
+ }
60
+ async executeDispose() {
61
+ const uniqueScopes = Array.from(new Set(this.createdScopes)).reverse();
62
+ for (const scope of uniqueScopes) {
63
+ await scope.dispose();
64
+ }
65
+ }
66
+ shouldSkipProviderPostInit(key, options) {
67
+ if (options?.excludePostInit === true)
68
+ return true;
69
+ if (!Array.isArray(options?.excludePostInit))
70
+ return false;
71
+ return new Set(options.excludePostInit).has(key);
72
+ }
73
+ getEagerProviderKeys(m) {
74
+ return Object.entries(m.providers || {})
75
+ .filter(([, provider]) => GUARGS.isEagerProvider(provider))
76
+ .map(([key]) => key);
77
+ }
78
+ ensureEagerProviderUsesSingletonLifetime(m, scope, key) {
79
+ if (scope.registrations[key]?.lifetime !== Awilix.Lifetime.SINGLETON) {
80
+ throw new ERRORS.EagerProviderRequiresSingletonLifetimeError(m.name, key);
81
+ }
82
+ }
83
+ async resolveEagerProvider({ module, scope, key, }) {
84
+ const provider = module.providers?.[key];
85
+ if (!provider ||
86
+ !GUARGS.isFactoryProvider(provider) ||
87
+ !GUARGS.isAsyncFactoryProvider(provider)) {
88
+ return scope.resolve(key);
89
+ }
90
+ const factoryDeps = (provider.inject || []).map((dependencyKey) => scope.registrations[dependencyKey].resolve(scope));
91
+ const resolvedValue = await provider.useFactory(...factoryDeps);
92
+ const { eager, initAfter, inject, useFactory, ...providerResolverOptions } = provider;
93
+ const resolverOptions = {
94
+ ...this.providerOptions,
95
+ ...module.providerOptions,
96
+ ...providerResolverOptions,
97
+ };
98
+ scope.register({
99
+ [key]: Awilix.asFunction(() => resolvedValue, resolverOptions),
100
+ });
101
+ return scope.resolve(key);
102
+ }
103
+ async callProviderInitAsync(instance) {
104
+ if (!GUARGS.hasProviderInit(instance))
105
+ return;
106
+ await instance.init();
107
+ }
108
+ async callProviderPostInitAsync(instance) {
109
+ if (!GUARGS.hasProviderPostInit(instance))
110
+ return;
111
+ await instance.postInit();
112
+ }
113
+ sortEagerProviderRefs() {
114
+ const nodes = this.eagerProviderRefs.map((ref) => ({
115
+ ...ref,
116
+ id: LifecycleProcessor.createEagerProviderId(ref.module.name, ref.key),
117
+ initAfter: this.getProviderInitAfter(ref.module, ref.key),
118
+ }));
119
+ const nodeById = new Map(nodes.map((node) => [node.id, node]));
120
+ const nodeByKey = LifecycleProcessor.buildEagerProviderNodeKeyMap(nodes);
121
+ const graph = new Map(nodes.map((node) => [node.id, []]));
122
+ const inDegree = new Map(nodes.map((node) => [node.id, 0]));
123
+ for (const node of nodes) {
124
+ for (const dependencyKey of node.initAfter) {
125
+ const dependencyNode = nodeByKey.get(dependencyKey);
126
+ if (!dependencyNode) {
127
+ throw new ERRORS.EagerProviderInitDependencyNotFoundError(node.module.name, node.key, dependencyKey);
128
+ }
129
+ const dependencies = graph.get(dependencyNode.id);
130
+ if (!dependencies)
131
+ continue;
132
+ dependencies.push(node.id);
133
+ inDegree.set(node.id, (inDegree.get(node.id) || 0) + 1);
134
+ }
135
+ }
136
+ const sortedIds = this.sortEagerProviderIds(graph, inDegree);
137
+ if (sortedIds.length !== nodes.length) {
138
+ throw new ERRORS.CircularProviderInitDependencyError(nodes.map((node) => node.key));
139
+ }
140
+ return sortedIds.map((id) => {
141
+ const { module, scope, key } = nodeById.get(id);
142
+ return { module, scope, key };
143
+ });
144
+ }
145
+ getProviderInitAfter(module, key) {
146
+ const provider = module.providers?.[key];
147
+ if (!GUARGS.hasInitAfter(provider))
148
+ return [];
149
+ return [...provider.initAfter];
150
+ }
151
+ sortEagerProviderIds(graph, inDegree) {
152
+ const queue = Array.from(inDegree.entries())
153
+ .filter(([, degree]) => degree === 0)
154
+ .map(([id]) => id);
155
+ const sortedIds = [];
156
+ while (queue.length > 0) {
157
+ const current = queue.shift();
158
+ sortedIds.push(current);
159
+ for (const dependent of graph.get(current) || []) {
160
+ const nextDegree = (inDegree.get(dependent) || 0) - 1;
161
+ inDegree.set(dependent, nextDegree);
162
+ if (nextDegree === 0)
163
+ queue.push(dependent);
164
+ }
165
+ }
166
+ return sortedIds;
167
+ }
168
+ static buildEagerProviderNodeKeyMap(nodes) {
169
+ const nodeByKey = new Map();
170
+ for (const node of nodes) {
171
+ nodeByKey.set(node.key, node);
172
+ }
173
+ return nodeByKey;
174
+ }
175
+ static createEagerProviderId(moduleName, key) {
176
+ return `${moduleName}:${key}`;
177
+ }
178
+ }
@@ -0,0 +1,24 @@
1
+ import type { AnyModuleOverride } from "../modules/module-overrides.js";
2
+ import type { InternalModuleLike } from "../modules/runtime-module.types.js";
3
+ export type OverrideOptions = {
4
+ moduleOverrides?: readonly AnyModuleOverride[];
5
+ };
6
+ export declare const FeatureKind: {
7
+ readonly Providers: "providers";
8
+ readonly QueryPreHandlers: "queryPreHandlers";
9
+ readonly CommandPreHandlers: "commandPreHandlers";
10
+ readonly Interceptors: "interceptors";
11
+ readonly Initializers: "initializers";
12
+ };
13
+ export declare class OverridesProcessor<M extends InternalModuleLike> {
14
+ private readonly options;
15
+ private readonly effectiveModuleMap;
16
+ private readonly appliedModuleOverrides;
17
+ constructor(options: OverrideOptions);
18
+ applyModuleOverrides(module: M): M;
19
+ getModuleWithOverrides(module: M): M;
20
+ ensureAllModuleOverridesApplied(): void;
21
+ private ensureModuleOverrideKeysExist;
22
+ private remapFeatureOverrides;
23
+ private ensureFeatureOverrideKeysExist;
24
+ }
@@ -0,0 +1,69 @@
1
+ import * as ERRORS from "../errors.js";
2
+ export const FeatureKind = {
3
+ Providers: "providers",
4
+ QueryPreHandlers: "queryPreHandlers",
5
+ CommandPreHandlers: "commandPreHandlers",
6
+ Interceptors: "interceptors",
7
+ Initializers: "initializers",
8
+ };
9
+ const FEATURE_KINDS = Object.values(FeatureKind);
10
+ export class OverridesProcessor {
11
+ options;
12
+ effectiveModuleMap = new WeakMap();
13
+ appliedModuleOverrides = new WeakSet();
14
+ constructor(options) {
15
+ this.options = options;
16
+ }
17
+ applyModuleOverrides(module) {
18
+ const moduleOverride = this.options.moduleOverrides?.find((override) => override.module === module);
19
+ if (!moduleOverride) {
20
+ this.effectiveModuleMap.set(module, module);
21
+ return module;
22
+ }
23
+ this.ensureModuleOverrideKeysExist(module, moduleOverride);
24
+ this.appliedModuleOverrides.add(module);
25
+ const remappedFeatures = FEATURE_KINDS.reduce((acc, featureKind) => {
26
+ Object.assign(acc, this.remapFeatureOverrides(module, moduleOverride, featureKind));
27
+ return acc;
28
+ }, {});
29
+ const effectiveModule = {
30
+ ...module,
31
+ ...remappedFeatures,
32
+ };
33
+ this.effectiveModuleMap.set(module, effectiveModule);
34
+ return effectiveModule;
35
+ }
36
+ getModuleWithOverrides(module) {
37
+ return this.effectiveModuleMap.get(module) ?? module;
38
+ }
39
+ ensureAllModuleOverridesApplied() {
40
+ for (const override of this.options.moduleOverrides ?? []) {
41
+ if (!this.appliedModuleOverrides.has(override.module)) {
42
+ throw new ERRORS.ModuleOverrideTargetNotFoundError(override.module.name);
43
+ }
44
+ }
45
+ }
46
+ ensureModuleOverrideKeysExist(module, moduleOverride) {
47
+ for (const featureKind of FEATURE_KINDS) {
48
+ this.ensureFeatureOverrideKeysExist(module, featureKind, moduleOverride.overrides[featureKind]);
49
+ }
50
+ }
51
+ remapFeatureOverrides(module, moduleOverride, featureKind) {
52
+ return {
53
+ [featureKind]: {
54
+ ...module[featureKind],
55
+ ...moduleOverride.overrides[featureKind],
56
+ },
57
+ };
58
+ }
59
+ ensureFeatureOverrideKeysExist(module, featureKind, overrides) {
60
+ if (!overrides)
61
+ return;
62
+ const featureKeys = new Set(Object.keys(module[featureKind] || {}));
63
+ for (const key of Object.keys(overrides)) {
64
+ if (!featureKeys.has(key)) {
65
+ throw new ERRORS.ModuleFeatureOverrideNotFoundError(module.name, featureKind, key);
66
+ }
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,35 @@
1
+ import * as Awilix from "awilix";
2
+ import type { InternalModuleLike as M } from "../modules/runtime-module.types.js";
3
+ import type { AnyProvider } from "./provider.types.js";
4
+ export type ResolveProviderParams = {
5
+ key: string;
6
+ provider: AnyProvider;
7
+ resolutionScope: Awilix.AwilixContainer;
8
+ module: M;
9
+ };
10
+ export declare class BasicProviderResolver {
11
+ protected readonly providerOptions: Partial<Awilix.BuildResolverOptions<any>>;
12
+ constructor(providerOptions: Partial<Awilix.BuildResolverOptions<any>>);
13
+ static mergeResolverOptions(module: M, providerOptions: Partial<Awilix.BuildResolverOptions<any>>, options?: Partial<Awilix.BuildResolverOptions<any>>): Awilix.BuildResolverOptions<any>;
14
+ resolveProvider({ key, provider, resolutionScope, module, }: ResolveProviderParams): Awilix.Resolver<any>;
15
+ resolveProviderAsync({ key, provider, resolutionScope, module, }: ResolveProviderParams): Promise<Awilix.Resolver<any>>;
16
+ protected resolveConstructorProvider({ provider, resolverOptions, }: {
17
+ provider: Awilix.Constructor<any>;
18
+ resolverOptions: Awilix.BuildResolverOptions<any>;
19
+ module: M;
20
+ }): Awilix.Resolver<any>;
21
+ protected resolveUseClassProvider({ provider, resolverOptions, }: {
22
+ provider: Extract<AnyProvider, {
23
+ useClass: Awilix.Constructor<any>;
24
+ }>;
25
+ resolverOptions: Awilix.BuildResolverOptions<any>;
26
+ module: M;
27
+ }): Awilix.Resolver<any>;
28
+ protected resolveAsyncFactoryInSyncContext({ key, module, }: {
29
+ key: string;
30
+ provider: AnyProvider;
31
+ resolverOptions: Awilix.BuildResolverOptions<any>;
32
+ module: M;
33
+ }): Awilix.Resolver<any>;
34
+ protected extractResolverOptions(module: M, provider: AnyProvider): Awilix.BuildResolverOptions<any>;
35
+ }
@@ -0,0 +1,88 @@
1
+ import * as Awilix from "awilix";
2
+ import * as ERRORS from "../errors.js";
3
+ import * as GUARGS from "../type-guards.js";
4
+ export class BasicProviderResolver {
5
+ providerOptions;
6
+ constructor(providerOptions) {
7
+ this.providerOptions = providerOptions;
8
+ }
9
+ static mergeResolverOptions(module, providerOptions, options) {
10
+ return {
11
+ ...providerOptions,
12
+ ...module.providerOptions,
13
+ ...options,
14
+ };
15
+ }
16
+ resolveProvider({ key, provider, resolutionScope, module, }) {
17
+ if (GUARGS.isPrimitive(provider)) {
18
+ return Awilix.asValue(provider);
19
+ }
20
+ if (GUARGS.isPlainFunction(provider) &&
21
+ !GUARGS.isCostructorProvider(provider)) {
22
+ return Awilix.asValue(provider);
23
+ }
24
+ if (typeof provider === "object" &&
25
+ !GUARGS.isCostructorProvider(provider) &&
26
+ !GUARGS.isFactoryProvider(provider) &&
27
+ !GUARGS.hasUseClass(provider)) {
28
+ return Awilix.asValue(provider);
29
+ }
30
+ const resolverOptions = this.extractResolverOptions(module, provider);
31
+ if (GUARGS.isCostructorProvider(provider)) {
32
+ return this.resolveConstructorProvider({
33
+ provider,
34
+ resolverOptions,
35
+ module,
36
+ });
37
+ }
38
+ if (GUARGS.isFactoryProvider(provider)) {
39
+ if (GUARGS.isAsyncFactoryProvider(provider)) {
40
+ return this.resolveAsyncFactoryInSyncContext({
41
+ key,
42
+ provider,
43
+ resolverOptions,
44
+ module,
45
+ });
46
+ }
47
+ const factoryDeps = (provider.inject || []).map((dependencyKey) => resolutionScope.registrations[dependencyKey].resolve(resolutionScope));
48
+ return Awilix.asFunction(() => provider.useFactory(...factoryDeps), resolverOptions);
49
+ }
50
+ return this.resolveUseClassProvider({
51
+ provider,
52
+ resolverOptions,
53
+ module,
54
+ });
55
+ }
56
+ async resolveProviderAsync({ key, provider, resolutionScope, module, }) {
57
+ if (!GUARGS.isFactoryProvider(provider) ||
58
+ !GUARGS.isAsyncFactoryProvider(provider)) {
59
+ return this.resolveProvider({ provider, resolutionScope, module, key });
60
+ }
61
+ const resolverOptions = this.extractResolverOptions(module, provider);
62
+ if (resolverOptions.lifetime !== Awilix.Lifetime.SINGLETON) {
63
+ throw new ERRORS.AsyncFactoryRequiresSingletonLifetimeError(module.name, key);
64
+ }
65
+ const factoryDeps = (provider.inject || []).map((dependencyKey) => resolutionScope.registrations[dependencyKey].resolve(resolutionScope));
66
+ return Awilix.asValue(await provider.useFactory(...factoryDeps));
67
+ }
68
+ resolveConstructorProvider({ provider, resolverOptions, }) {
69
+ return Awilix.asClass(provider, resolverOptions);
70
+ }
71
+ resolveUseClassProvider({ provider, resolverOptions, }) {
72
+ return Awilix.asClass(provider.useClass, resolverOptions);
73
+ }
74
+ resolveAsyncFactoryInSyncContext({ key, module, }) {
75
+ throw new ERRORS.AsyncFactoryRequiresAsyncCreateError(module.name, key);
76
+ }
77
+ extractResolverOptions(module, provider) {
78
+ if (GUARGS.hasUseClass(provider)) {
79
+ const { useClass, allowCircular, eager, initAfter, ...options } = provider;
80
+ return BasicProviderResolver.mergeResolverOptions(module, this.providerOptions, options);
81
+ }
82
+ if (GUARGS.isFactoryProvider(provider)) {
83
+ const { eager, initAfter, inject, useFactory, ...options } = provider;
84
+ return BasicProviderResolver.mergeResolverOptions(module, this.providerOptions, options);
85
+ }
86
+ return BasicProviderResolver.mergeResolverOptions(module, this.providerOptions);
87
+ }
88
+ }
@@ -0,0 +1,9 @@
1
+ import type { InternalModuleLike as M } from "../modules/runtime-module.types.js";
2
+ export declare class ProviderDependencySorter {
3
+ sortByDependencies(m: M): NonNullable<typeof m.providers>;
4
+ private initializeDepGraph;
5
+ private buildDepGraph;
6
+ private sortTopologically;
7
+ private initializeQueue;
8
+ private ensureNoCyclicDependencies;
9
+ }
@@ -0,0 +1,76 @@
1
+ import * as ERRORS from "../errors.js";
2
+ import { isFactoryProvider, isForwardRef, isPromiseLike, } from "../type-guards.js";
3
+ export class ProviderDependencySorter {
4
+ sortByDependencies(m) {
5
+ const depsGraph = this.buildDepGraph(m, this.initializeDepGraph(m));
6
+ const initialQueue = this.initializeQueue(depsGraph.inDegree);
7
+ const sortedKeys = this.sortTopologically(depsGraph, initialQueue);
8
+ this.ensureNoCyclicDependencies(m, sortedKeys);
9
+ return sortedKeys.reduce((acc, key) => {
10
+ const provider = m.providers?.[key];
11
+ if (provider !== undefined)
12
+ acc[key] = provider;
13
+ return acc;
14
+ }, {});
15
+ }
16
+ initializeDepGraph(m) {
17
+ return Object.keys(m.providers || {}).reduce((acc, curr) => {
18
+ acc.graph.set(curr, []);
19
+ acc.inDegree.set(curr, 0);
20
+ return acc;
21
+ }, {
22
+ graph: new Map(),
23
+ inDegree: new Map(),
24
+ });
25
+ }
26
+ buildDepGraph(m, depsGraph) {
27
+ const importedProviderKeys = new Set((m.imports || []).flatMap((importItem) => {
28
+ const importedModule = isForwardRef(importItem)
29
+ ? importItem.resolve()
30
+ : importItem;
31
+ if (isPromiseLike(importedModule)) {
32
+ throw new Error(`Async module import in "${m.name}" was not resolved before provider dependency sorting.`);
33
+ }
34
+ return importedModule.exports ? [...importedModule.exports] : [];
35
+ }));
36
+ return Object.entries(m.providers || {}).reduce((acc, [key, provider]) => {
37
+ if (!isFactoryProvider(provider) || !provider.inject)
38
+ return acc;
39
+ provider.inject.forEach((dep) => {
40
+ const depList = acc.graph.get(dep);
41
+ if (depList) {
42
+ depList.push(key);
43
+ acc.inDegree.set(key, (acc.inDegree.get(key) || 0) + 1);
44
+ return;
45
+ }
46
+ if (!depList && !importedProviderKeys.has(dep)) {
47
+ throw new ERRORS.DependencyNotFoundError(dep, m.name);
48
+ }
49
+ });
50
+ return acc;
51
+ }, { ...depsGraph });
52
+ }
53
+ sortTopologically(depsGraph, queue, result = []) {
54
+ const [current, ...restQueue] = queue;
55
+ if (!current)
56
+ return result;
57
+ const deps = depsGraph.graph.get(current) || [];
58
+ const inDegree = deps.reduce((acc, curr) => {
59
+ acc.set(curr, (acc.get(curr) || 0) - 1);
60
+ return acc;
61
+ }, new Map(depsGraph.inDegree));
62
+ return this.sortTopologically({ ...depsGraph, inDegree }, [...restQueue, ...deps.filter((dep) => inDegree.get(dep) === 0)], [...result, current]);
63
+ }
64
+ initializeQueue(inDegree) {
65
+ return Array.from(inDegree.entries())
66
+ .filter(([_, degree]) => degree === 0)
67
+ .map(([key]) => key);
68
+ }
69
+ ensureNoCyclicDependencies(m, sortedKeys) {
70
+ const providerKeys = Object.keys(m.providers || {});
71
+ if (sortedKeys.length !== providerKeys.length) {
72
+ const remaining = providerKeys.filter((key) => !sortedKeys.includes(key));
73
+ throw new ERRORS.CircularDependencyError(m.name, remaining);
74
+ }
75
+ }
76
+ }
@@ -0,0 +1,31 @@
1
+ import * as Awilix from "awilix";
2
+ import type { InternalModuleLike as M } from "../modules/runtime-module.types.js";
3
+ import type { InterceptorProcessor } from "../processors/interceptor-processor.js";
4
+ import type { AnyProvider } from "./provider.types.js";
5
+ export type RequestScopeResolver = (scope: Awilix.AwilixContainer) => Awilix.AwilixContainer;
6
+ type ResolveProviderParams = {
7
+ key: string;
8
+ provider: AnyProvider;
9
+ resolutionScope: Awilix.AwilixContainer;
10
+ module: M;
11
+ };
12
+ type ResolveClassProviderParams = {
13
+ provider: unknown;
14
+ resolutionScope: Awilix.AwilixContainer;
15
+ module: M;
16
+ providerOptions?: Partial<Awilix.BuildResolverOptions<any>>;
17
+ wrapForExport?: boolean;
18
+ };
19
+ export declare class ProviderResolver {
20
+ private readonly interceptorProcessor;
21
+ private readonly providerOptions;
22
+ private readonly requestScopeResolver?;
23
+ constructor(interceptorProcessor: InterceptorProcessor | undefined, providerOptions: Partial<Awilix.BuildResolverOptions<any>>, requestScopeResolver?: RequestScopeResolver | undefined);
24
+ static mergeResolverOptions(module: M, providerOptions: Partial<Awilix.BuildResolverOptions<any>>, options?: Partial<Awilix.BuildResolverOptions<any>>): Awilix.BuildResolverOptions<any>;
25
+ resolveClassProvider({ provider, resolutionScope, module, wrapForExport, }: ResolveClassProviderParams): Awilix.Resolver<any>;
26
+ resolveProvider({ key, provider, resolutionScope, module, }: ResolveProviderParams): Awilix.Resolver<any>;
27
+ resolveProviderAsync({ key, provider, resolutionScope, module, }: ResolveProviderParams): Promise<Awilix.Resolver<any>>;
28
+ private extractResolverOptions;
29
+ private createProxyResolver;
30
+ }
31
+ export {};
@@ -0,0 +1,128 @@
1
+ import * as Awilix from "awilix";
2
+ import * as ERRORS from "../errors.js";
3
+ import * as GUARGS from "../type-guards.js";
4
+ export class ProviderResolver {
5
+ interceptorProcessor;
6
+ providerOptions;
7
+ requestScopeResolver;
8
+ constructor(interceptorProcessor, providerOptions, requestScopeResolver) {
9
+ this.interceptorProcessor = interceptorProcessor;
10
+ this.providerOptions = providerOptions;
11
+ this.requestScopeResolver = requestScopeResolver;
12
+ }
13
+ static mergeResolverOptions(module, providerOptions, options) {
14
+ return {
15
+ ...providerOptions,
16
+ ...module.providerOptions,
17
+ ...options,
18
+ };
19
+ }
20
+ resolveClassProvider({ provider, resolutionScope, module, wrapForExport, }) {
21
+ const { useClass, ...featureOptions } = GUARGS.hasUseClass(provider)
22
+ ? provider
23
+ : { useClass: provider };
24
+ const resolverOptions = {
25
+ ...this.providerOptions,
26
+ ...module.providerOptions,
27
+ ...featureOptions,
28
+ };
29
+ const resolver = Awilix.asClass(useClass, resolverOptions);
30
+ if (!wrapForExport)
31
+ return resolver;
32
+ return Awilix.asFunction(() => resolver.resolve(resolverOptions.lifetime === Awilix.Lifetime.SINGLETON
33
+ ? resolutionScope
34
+ : this.requestScopeResolver
35
+ ? this.requestScopeResolver(resolutionScope)
36
+ : resolutionScope), resolverOptions);
37
+ }
38
+ resolveProvider({ key, provider, resolutionScope, module, }) {
39
+ if (GUARGS.isPrimitive(provider)) {
40
+ return Awilix.asValue(provider);
41
+ }
42
+ if (GUARGS.isPlainFunction(provider) &&
43
+ !GUARGS.isCostructorProvider(provider)) {
44
+ return Awilix.asValue(provider);
45
+ }
46
+ if (typeof provider === "object" &&
47
+ !GUARGS.isCostructorProvider(provider) &&
48
+ !GUARGS.isFactoryProvider(provider) &&
49
+ !GUARGS.hasUseClass(provider)) {
50
+ return Awilix.asValue(provider);
51
+ }
52
+ const resolverOptions = this.extractResolverOptions(module, provider);
53
+ if (GUARGS.isCostructorProvider(provider)) {
54
+ if (!this.interceptorProcessor) {
55
+ return Awilix.asClass(provider, resolverOptions);
56
+ }
57
+ return this.interceptorProcessor.createInterceptedProviderResolver({
58
+ module,
59
+ useClass: provider,
60
+ options: resolverOptions,
61
+ });
62
+ }
63
+ if (GUARGS.isFactoryProvider(provider)) {
64
+ if (GUARGS.isAsyncFactoryProvider(provider)) {
65
+ if (GUARGS.isEagerProvider(provider)) {
66
+ return Awilix.asFunction(() => {
67
+ throw new ERRORS.AsyncEagerFactoryRequiresInitError(module.name, key ?? "unknown");
68
+ }, resolverOptions);
69
+ }
70
+ throw new ERRORS.AsyncFactoryRequiresAsyncCreateError(module.name, key ?? "unknown");
71
+ }
72
+ const factoryDeps = (provider.inject || []).map((k) => resolutionScope.registrations[k].resolve(resolutionScope));
73
+ return Awilix.asFunction(() => provider.useFactory(...factoryDeps), resolverOptions);
74
+ }
75
+ const baseResolver = Awilix.asClass(provider.useClass, resolverOptions);
76
+ const classResolver = provider.allowCircular
77
+ ? this.createProxyResolver(baseResolver, resolverOptions)
78
+ : baseResolver;
79
+ if (!this.interceptorProcessor) {
80
+ return classResolver;
81
+ }
82
+ return this.interceptorProcessor.createInterceptedProviderResolver({
83
+ module,
84
+ useClass: provider.useClass,
85
+ options: resolverOptions,
86
+ resolver: classResolver,
87
+ });
88
+ }
89
+ async resolveProviderAsync({ key, provider, resolutionScope, module, }) {
90
+ if (!GUARGS.isFactoryProvider(provider) ||
91
+ !GUARGS.isAsyncFactoryProvider(provider)) {
92
+ return this.resolveProvider({ provider, resolutionScope, module, key });
93
+ }
94
+ const resolverOptions = this.extractResolverOptions(module, provider);
95
+ if (resolverOptions.lifetime !== Awilix.Lifetime.SINGLETON) {
96
+ throw new ERRORS.AsyncFactoryRequiresSingletonLifetimeError(module.name, key);
97
+ }
98
+ const factoryDeps = (provider.inject || []).map((k) => resolutionScope.registrations[k].resolve(resolutionScope));
99
+ return Awilix.asValue(await provider.useFactory(...factoryDeps));
100
+ }
101
+ extractResolverOptions(module, provider) {
102
+ if (GUARGS.hasUseClass(provider)) {
103
+ const { useClass, allowCircular, eager, initAfter, ...options } = provider;
104
+ return ProviderResolver.mergeResolverOptions(module, this.providerOptions, options);
105
+ }
106
+ if (GUARGS.isFactoryProvider(provider)) {
107
+ const { eager, initAfter, inject, useFactory, ...options } = provider;
108
+ return ProviderResolver.mergeResolverOptions(module, this.providerOptions, options);
109
+ }
110
+ return ProviderResolver.mergeResolverOptions(module, this.providerOptions);
111
+ }
112
+ createProxyResolver(resolver, options) {
113
+ return Awilix.createBuildResolver({
114
+ ...options,
115
+ resolve(container) {
116
+ let resolved = null;
117
+ return new Proxy({}, {
118
+ get(_, name) {
119
+ if (!resolved) {
120
+ resolved = resolver.resolve(container);
121
+ }
122
+ return resolved[name];
123
+ },
124
+ });
125
+ },
126
+ });
127
+ }
128
+ }
@@ -0,0 +1 @@
1
+ export * from "./types/index.js";
@@ -0,0 +1 @@
1
+ export * from "./types/index.js";
@@ -0,0 +1,9 @@
1
+ import type { BuildResolverOptions, Constructor } from "awilix";
2
+ export type ConstructorController = Constructor<Controller>;
3
+ export type ClassController = {
4
+ useClass: ConstructorController | Constructor<any>;
5
+ } & BuildResolverOptions<any>;
6
+ export type AnyController = ConstructorController | ClassController | Constructor<any>;
7
+ export interface Controller {
8
+ registerRoutes: () => void;
9
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { DecoratorMethodState, DecoratorState, DecoratorToken, MethodName } from "../../../decorators/decorator-state.types.js";
2
+ export type AnyDecoratorToken = DecoratorToken<DecoratorState<any, any>>;
3
+ export type DecoratorExecutionContext<TToken extends AnyDecoratorToken = AnyDecoratorToken, TTarget extends object = object> = {
4
+ target: TTarget;
5
+ methodName: MethodName;
6
+ moduleName: string;
7
+ metadata: DecoratorMethodState<TToken["state"]>;
8
+ decoratorState: TToken["state"];
9
+ };