@forklaunch/core 0.10.2 → 0.10.4

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.
@@ -3,23 +3,24 @@ import { Collection } from '@mikro-orm/core';
3
3
 
4
4
  declare function getEnvVar(name: string): string;
5
5
 
6
- declare enum Lifetime {
7
- Singleton = 0,
8
- Transient = 1,
9
- Scoped = 2
10
- }
6
+ declare const Lifetime: {
7
+ readonly Singleton: 0;
8
+ readonly Transient: 1;
9
+ readonly Scoped: 2;
10
+ };
11
+ type Lifetime = (typeof Lifetime)[keyof typeof Lifetime];
11
12
  type Singleton<Type, Args, Value> = {
12
- lifetime: Lifetime.Singleton;
13
+ lifetime: typeof Lifetime.Singleton;
13
14
  type: Type;
14
15
  value: Value;
15
16
  } | ConstructedSingleton<Type, Args, Value>;
16
17
  type ConstructedSingleton<Type, Args, Return> = {
17
- lifetime: Lifetime.Singleton;
18
+ lifetime: typeof Lifetime.Singleton;
18
19
  type: Type;
19
20
  factory: (args: Args, resolve: <T extends keyof Args>(token: T, context?: Record<string, unknown>) => Args[T], context: Record<string, unknown>) => Return;
20
21
  };
21
22
  type Constructed<Type, Args, Return> = {
22
- lifetime: Lifetime.Transient | Lifetime.Scoped;
23
+ lifetime: typeof Lifetime.Transient | typeof Lifetime.Scoped;
23
24
  type: Type;
24
25
  factory: (args: Args, resolve: <T extends keyof Args>(token: T, context?: Record<string, unknown>) => Args[T], context: Record<string, unknown>) => Return;
25
26
  };
@@ -3,23 +3,24 @@ import { Collection } from '@mikro-orm/core';
3
3
 
4
4
  declare function getEnvVar(name: string): string;
5
5
 
6
- declare enum Lifetime {
7
- Singleton = 0,
8
- Transient = 1,
9
- Scoped = 2
10
- }
6
+ declare const Lifetime: {
7
+ readonly Singleton: 0;
8
+ readonly Transient: 1;
9
+ readonly Scoped: 2;
10
+ };
11
+ type Lifetime = (typeof Lifetime)[keyof typeof Lifetime];
11
12
  type Singleton<Type, Args, Value> = {
12
- lifetime: Lifetime.Singleton;
13
+ lifetime: typeof Lifetime.Singleton;
13
14
  type: Type;
14
15
  value: Value;
15
16
  } | ConstructedSingleton<Type, Args, Value>;
16
17
  type ConstructedSingleton<Type, Args, Return> = {
17
- lifetime: Lifetime.Singleton;
18
+ lifetime: typeof Lifetime.Singleton;
18
19
  type: Type;
19
20
  factory: (args: Args, resolve: <T extends keyof Args>(token: T, context?: Record<string, unknown>) => Args[T], context: Record<string, unknown>) => Return;
20
21
  };
21
22
  type Constructed<Type, Args, Return> = {
22
- lifetime: Lifetime.Transient | Lifetime.Scoped;
23
+ lifetime: typeof Lifetime.Transient | typeof Lifetime.Scoped;
23
24
  type: Type;
24
25
  factory: (args: Args, resolve: <T extends keyof Args>(token: T, context?: Record<string, unknown>) => Args[T], context: Record<string, unknown>) => Return;
25
26
  };
@@ -42,16 +42,15 @@ function isConstructed(value) {
42
42
  }
43
43
 
44
44
  // src/services/types/configInjector.types.ts
45
- var Lifetime = /* @__PURE__ */ ((Lifetime2) => {
46
- Lifetime2[Lifetime2["Singleton"] = 0] = "Singleton";
47
- Lifetime2[Lifetime2["Transient"] = 1] = "Transient";
48
- Lifetime2[Lifetime2["Scoped"] = 2] = "Scoped";
49
- return Lifetime2;
50
- })(Lifetime || {});
45
+ var Lifetime = {
46
+ Singleton: 0,
47
+ Transient: 1,
48
+ Scoped: 2
49
+ };
51
50
 
52
51
  // src/services/guards/isConstructedSingleton.ts
53
52
  function isConstructedSingleton(value) {
54
- return typeof value === "object" && value != null && "lifetime" in value && value.lifetime === 0 /* Singleton */ && "factory" in value;
53
+ return typeof value === "object" && value != null && "lifetime" in value && value.lifetime === Lifetime.Singleton && "factory" in value;
55
54
  }
56
55
 
57
56
  // src/services/guards/isConstructor.ts
@@ -86,7 +85,7 @@ var ConfigInjector = class _ConfigInjector {
86
85
  }
87
86
  for (const token in this.dependenciesDefinition) {
88
87
  const definition = this.dependenciesDefinition[token];
89
- if (definition.lifetime === 0 /* Singleton */ && !this.instances[token]) {
88
+ if (definition.lifetime === Lifetime.Singleton && !this.instances[token]) {
90
89
  if (isConstructedSingleton(definition)) {
91
90
  this.instances[token] = this.resolveInstance(
92
91
  token,
@@ -138,7 +137,7 @@ var ConfigInjector = class _ConfigInjector {
138
137
  safeValidateConfigSingletons() {
139
138
  const validNonSchemaSingletons = Object.entries(this.configShapes).reduce(
140
139
  (acc, [key, value]) => {
141
- if (this.dependenciesDefinition[key].lifetime === 0 /* Singleton */ && !this.schemaValidator.isSchema(value) && isConstructor(value)) {
140
+ if (this.dependenciesDefinition[key].lifetime === Lifetime.Singleton && !this.schemaValidator.isSchema(value) && isConstructor(value)) {
142
141
  if (!(this.instances[key] instanceof value)) {
143
142
  const expected = value.name;
144
143
  const receivedValue = this.instances[key];
@@ -175,7 +174,7 @@ var ConfigInjector = class _ConfigInjector {
175
174
  );
176
175
  const singletons = Object.fromEntries(
177
176
  Object.entries(this.configShapes).filter(
178
- ([key, value]) => this.dependenciesDefinition[key].lifetime === 0 /* Singleton */ && this.schemaValidator.isSchema(value)
177
+ ([key, value]) => this.dependenciesDefinition[key].lifetime === Lifetime.Singleton && this.schemaValidator.isSchema(value)
179
178
  )
180
179
  );
181
180
  const schemaSingletonParseResult = this.schemaValidator.parse(
@@ -185,7 +184,7 @@ var ConfigInjector = class _ConfigInjector {
185
184
  const dependency = this.dependenciesDefinition[key];
186
185
  return [
187
186
  key,
188
- dependency.lifetime === 0 /* Singleton */ ? this.instances[key] : void 0
187
+ dependency.lifetime === Lifetime.Singleton ? this.instances[key] : void 0
189
188
  ];
190
189
  })
191
190
  )
@@ -224,7 +223,7 @@ var ConfigInjector = class _ConfigInjector {
224
223
  throw new Error(`Unable to resolve dependency ${String(token)}`);
225
224
  }
226
225
  switch (definition.lifetime) {
227
- case 0 /* Singleton */: {
226
+ case Lifetime.Singleton: {
228
227
  if (isConstructedSingleton(definition) && !this.instances[token]) {
229
228
  this.instances[token] = this.resolveInstance(
230
229
  token,
@@ -235,7 +234,7 @@ var ConfigInjector = class _ConfigInjector {
235
234
  }
236
235
  return this.instances[token];
237
236
  }
238
- case 2 /* Scoped */: {
237
+ case Lifetime.Scoped: {
239
238
  if (!isConstructed(definition)) {
240
239
  throw new Error(
241
240
  `Invalid dependency definition for ${String(token)}`
@@ -250,7 +249,7 @@ var ConfigInjector = class _ConfigInjector {
250
249
  this.instances[token] = scopedInstance;
251
250
  return scopedInstance;
252
251
  }
253
- case 1 /* Transient */: {
252
+ case Lifetime.Transient: {
254
253
  if (!isConstructed(definition)) {
255
254
  throw new Error(
256
255
  `Invalid dependency definition for ${String(token)}`
@@ -282,7 +281,7 @@ var ConfigInjector = class _ConfigInjector {
282
281
  createScope() {
283
282
  const singletons = {};
284
283
  for (const dependency in this.dependenciesDefinition) {
285
- if (this.dependenciesDefinition[dependency].lifetime === 0 /* Singleton */) {
284
+ if (this.dependenciesDefinition[dependency].lifetime === Lifetime.Singleton) {
286
285
  singletons[dependency] = this.instances[dependency];
287
286
  }
288
287
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/services/index.ts","../../../common/src/getEnvVar.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"],"sourcesContent":["export * from '../../../common/src/getEnvVar';\nexport { createConfigInjector } from './configInjector';\nexport type { ConfigInjector, ValidConfigInjector } from './configInjector';\nexport * from './types/configInjector.types';\nexport * from './types/entityManager.types';\nexport * from './types/service.types';\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","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>(\n schemaValidator,\n dependenciesDefinition\n ).load();\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\n for (const token in this.dependenciesDefinition) {\n const definition = this.dependenciesDefinition[token];\n if (\n definition.lifetime === Lifetime.Singleton &&\n !this.instances[token]\n ) {\n 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 }\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 ).load({ ...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 const singletons: Record<string, unknown> = {};\n for (const dependency in this.dependenciesDefinition) {\n if (\n this.dependenciesDefinition[dependency].lifetime === Lifetime.Singleton\n ) {\n singletons[dependency] = this.instances[dependency];\n }\n }\n return new ConfigInjector<SV, CV>(\n this.schemaValidator,\n this.dependenciesDefinition\n ).load(singletons as ResolvedConfigValidator<SV, CV>);\n }\n\n dispose(): void {\n this.instances = {};\n this.load();\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 FunctionToConstructor = (\n ...args: never[]\n) => new (...args: never[]) => unknown;\nexport type SchemaFunction<SV extends AnySchemaValidator> = (\n args: unknown\n) => IdiomaticSchema<SV>;\n\nexport type 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 ? (...args: Parameters<T>) => Schema<ReturnType<T>, SV>\n : T extends FunctionToConstructor\n ? (...args: Parameters<T>) => InstanceType<ReturnType<T>>\n : T extends Function\n ? (...args: Parameters<T>) => ReturnType<T>\n : T extends Constructor\n ? InstanceType<T>\n : T extends IdiomaticSchema<SV>\n ? Schema<T, SV>\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"],"mappings":"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","names":["Lifetime"]}
1
+ {"version":3,"sources":["../../src/services/index.ts","../../../common/src/getEnvVar.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"],"sourcesContent":["export * from '../../../common/src/getEnvVar';\nexport { createConfigInjector } from './configInjector';\nexport type { ConfigInjector, ValidConfigInjector } from './configInjector';\nexport * from './types/configInjector.types';\nexport * from './types/entityManager.types';\nexport * from './types/service.types';\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","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>(\n schemaValidator,\n dependenciesDefinition\n ).load();\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\n for (const token in this.dependenciesDefinition) {\n const definition = this.dependenciesDefinition[token];\n if (\n definition.lifetime === Lifetime.Singleton &&\n !this.instances[token]\n ) {\n 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 }\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 ).load({ ...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 const singletons: Record<string, unknown> = {};\n for (const dependency in this.dependenciesDefinition) {\n if (\n this.dependenciesDefinition[dependency].lifetime === Lifetime.Singleton\n ) {\n singletons[dependency] = this.instances[dependency];\n }\n }\n return new ConfigInjector<SV, CV>(\n this.schemaValidator,\n this.dependenciesDefinition\n ).load(singletons as ResolvedConfigValidator<SV, CV>);\n }\n\n dispose(): void {\n this.instances = {};\n this.load();\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 const Lifetime = {\n Singleton: 0,\n Transient: 1,\n Scoped: 2\n} as const;\nexport type Lifetime = (typeof Lifetime)[keyof typeof Lifetime];\n\nexport type Singleton<Type, Args, Value> =\n | {\n lifetime: typeof Lifetime.Singleton;\n type: Type;\n value: Value;\n }\n | ConstructedSingleton<Type, Args, Value>;\n\nexport type ConstructedSingleton<Type, Args, Return> = {\n lifetime: typeof 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: typeof Lifetime.Transient | typeof 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 FunctionToConstructor = (\n ...args: never[]\n) => new (...args: never[]) => unknown;\nexport type SchemaFunction<SV extends AnySchemaValidator> = (\n args: unknown\n) => IdiomaticSchema<SV>;\n\nexport type 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 ? (...args: Parameters<T>) => Schema<ReturnType<T>, SV>\n : T extends FunctionToConstructor\n ? (...args: Parameters<T>) => InstanceType<ReturnType<T>>\n : T extends Function\n ? (...args: Parameters<T>) => ReturnType<T>\n : T extends Constructor\n ? InstanceType<T>\n : T extends IdiomaticSchema<SV>\n ? Schema<T, SV>\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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGO,SAAS,UAAU,MAAsB;AAC9C,QAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,SAAO;AACT;;;ACNA,oBAA8C;AAC9C,uBAMO;;;ACLA,SAAS,cACd,OAC0C;AAC1C,SACE,OAAO,UAAU,YACjB,SAAS,QACT,iBAAiB,SACjB,MAAM,eAAe;AAEzB;;;ACJO,IAAM,WAAW;AAAA,EACtB,WAAW;AAAA,EACX,WAAW;AAAA,EACX,QAAQ;AACV;;;ACTO,SAAS,uBACd,OACmD;AACnD,SACE,OAAO,UAAU,YACjB,SAAS,QACT,cAAc,SACd,MAAM,aAAa,SAAS,aAC5B,aAAa;AAEjB;;;ACVO,SAAS,cAAc,OAAsC;AAClE,SACE,OAAO,UAAU,cACjB,MAAM,eAAe,QACrB,MAAM,aAAa;AAEvB;;;AJcO,SAAS,qBAId,iBACA,wBAaA;AACA,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,EACF,EAAE,KAAK;AACT;AAEO,IAAM,iBAAN,MAAM,gBAGX;AAAA,EAkGA,YACU,iBACA,wBAgBR;AAjBQ;AACA;AAiBR,SAAK,eAAe,OAAO,QAAQ,KAAK,sBAAsB,EAAE;AAAA,MAC9D,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO;AAAA,QACzB,GAAG;AAAA,QACH,CAAC,GAAG,GAAG;AAAA,MACT;AAAA,MACA,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EA3HA,YAEI,CAAC;AAAA,EAEI;AAAA,EAET,KAAK,yBAEI;AACP,eAAW,SAAS,yBAAyB;AAC3C,WAAK,UAAU,KAAK,IAAI,wBAAwB,KAAK;AAAA,IACvD;AAEA,eAAW,SAAS,KAAK,wBAAwB;AAC/C,YAAM,aAAa,KAAK,uBAAuB,KAAK;AACpD,UACE,WAAW,aAAa,SAAS,aACjC,CAAC,KAAK,UAAU,KAAK,GACrB;AACA,YACE,uBAIE,UAAU,GACZ;AACA,eAAK,UAAU,KAAK,IAAI,KAAK;AAAA,YAC3B;AAAA,YACA;AAAA,UACF;AAAA,QACF,OAAO;AACL,eAAK,UAAU,KAAK,IAAI,WAAW;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,gBACN,OACA,YAWA,SACA,iBAA+B,CAAC,GACI;AACpC,UAAM,uBAAmB,oCAAqB,WAAW,OAAO,EAAE,CAAC;AAEnE,QAAI,CAAC,oBAAoB,qBAAqB,SAAS;AACrD,aAAO,WAAW;AAAA,QAChB,CAAC;AAAA,QACD,KAAK,QAAQ,KAAK,IAAI;AAAA,QACtB,WAAY,CAAC;AAAA,MACf;AAAA,IACF;AAEA,QAAI,CAAC,iBAAiB,WAAW,GAAG,KAAK,CAAC,iBAAiB,SAAS,GAAG,GAAG;AACxE,YAAM,IAAI;AAAA,QACR,iCAAiC;AAAA,UAC/B;AAAA,QACF,CAAC,KAAK,gBAAgB;AAAA,MACxB;AAAA,IACF;AACA,UAAM,oBAAoB,OAAO;AAAA,MAC/B,iBACG,QAAQ,KAAK,EAAE,EACf,QAAQ,KAAK,EAAE,EACf,MAAM,GAAG,EACT,IAAI,CAAC,QAAQ,IAAI,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,EACrC,IAAI,CAAC,QAAQ;AACZ,cAAM,oBAAoB,CAAC,GAAG,gBAAgB,KAAK;AACnD,YAAI,eAAe,SAAS,GAAG,GAAG;AAChC,gBAAM,IAAI;AAAA,YACR,iCAAiC,kBAAkB;AAAA,cACjD;AAAA,YACF,CAAC,OAAO,GAAG;AAAA,UACb;AAAA,QACF;AACA,cAAM,cAAc,KAAK,QAAQ,KAAK,SAAS,iBAAiB;AAChE,eAAO,CAAC,KAAK,WAAW;AAAA,MAC1B,CAAC;AAAA,IACL;AACA,WAAO,WAAW;AAAA,MAChB;AAAA,MACA,KAAK,QAAQ,KAAK,IAAI;AAAA,MACtB,WAAY,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EA8BA,+BAAyE;AACvE,UAAM,2BAA2B,OAAO,QAAQ,KAAK,YAAY,EAAE;AAAA,MAGjE,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AACrB,YACE,KAAK,uBAAuB,GAAG,EAAE,aAAa,SAAS,aACvD,CAAE,KAAK,gBAAoC,SAEzC,KAAK,KACP,cAAc,KAAK,GACnB;AACA,cAAI,EAAE,KAAK,UAAU,GAAG,aAAa,QAAQ;AAC3C,kBAAM,WAAW,MAAM;AACvB,kBAAM,gBAAyB,KAAK,UAAU,GAAG;AACjD,kBAAM,WAAW,cAAc,aAAa,IACxC,cAAc,YAAY,OAC1B,OAAO;AAEX,gBAAI,IAAI,IAAI;AACV,oBAAM;AAAA,gBACJ,IAAI;AAAA,gBACJ,QAAQ,CAAC;AAAA,cACX;AAAA,YACF;AACA,gBAAI,QAAQ,KAAK;AAAA,cACf,SAAS,YAAY,QAAQ,cAAc,QAAQ;AAAA,cACnD,MAAM,CAAC,GAAG;AAAA,YACZ,CAAC;AAAA,UACH,OAAO;AACL,gBAAI,IAAI,IAAI;AACV,oBAAM;AAAA,gBACJ,IAAI;AAAA,gBACJ,OAAO;AAAA,kBACL,GAAG,IAAI;AAAA,kBACP,CAAC,GAAG,GAAG,KAAK,UAAU,GAAG;AAAA,gBAC3B;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO,CAAC;AAAA,MACV;AAAA,IACF;AAEA,UAAM,aAAa,OAAO;AAAA,MACxB,OAAO,QAAQ,KAAK,YAAY,EAAE;AAAA,QAChC,CAAC,CAAC,KAAK,KAAK,MACV,KAAK,uBAAuB,GAAG,EAAE,aAAa,SAAS,aACtD,KAAK,gBAAoC,SAAS,KAAK;AAAA,MAC5D;AAAA,IACF;AACA,UAAM,6BACJ,KAAK,gBACL;AAAA,MACC,KAAK,gBAAoC,SAAS,UAAU;AAAA,MAC7D,OAAO;AAAA,QACL,OAAO,KAAK,UAAU,EAAE,IAAI,CAAC,QAAQ;AACnC,gBAAM,aAAa,KAAK,uBAAuB,GAAG;AAClD,iBAAO;AAAA,YACL;AAAA,YACA,WAAW,aAAa,SAAS,YAC7B,KAAK,UAAU,GAAG,IAClB;AAAA,UACN;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,aAAa,OAAO,KAAK,KAAK,YAAY;AAEhD,WAAO,yBAAyB,MAAM,2BAA2B,KAC7D;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,IAAI;AAAA,QACT,KAAK;AAAA,QACL,KAAK;AAAA,MACP,EAAE,KAAK,EAAE,GAAG,KAAK,UAAU,CAAC;AAAA,IAC9B,IACA;AAAA,MACE,IAAI;AAAA,MACJ,QAAQ;AAAA,QACN,GAAI,CAAC,yBAAyB,MAAM,yBAAyB,SACzD,yBAAyB,SACzB,CAAC;AAAA,QACL,GAAI,CAAC,2BAA2B,MAChC,2BAA2B,SACvB,2BAA2B,SAC3B,CAAC;AAAA,MACP,EAAE;AAAA,QACA,CAAC,GAAG,MACF,WAAW,QAAQ,EAAE,KAAK,CAAC,CAAC,IAAI,WAAW,QAAQ,EAAE,KAAK,CAAC,CAAC;AAAA,MAChE;AAAA,IACF;AAAA,EACN;AAAA,EAEA,yBAAyB,YAAiD;AACxE,UAAM,qBAAqB,KAAK,6BAA6B;AAE7D,QAAI,mBAAmB,IAAI;AACzB,aAAO,mBAAmB;AAAA,IAC5B;AAEA,UAAM,IAAI;AAAA,UACR,yCAAuB,mBAAmB,QAAQ,UAAU;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,QACE,OACA,SACA,iBAA+B,CAAC,GACI;AACpC,UAAM,WAAW,KAAK,UAAU,KAAK;AACrC,QAAI,CAAC,UAAU;AACb,YAAM,aAAa,KAAK,uBAAuB,KAAK;AAEpD,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,MAAM,gCAAgC,OAAO,KAAK,CAAC,EAAE;AAAA,MACjE;AAEA,cAAQ,WAAW,UAAU;AAAA,QAC3B,KAAK,SAAS,WAAW;AACvB,cACE,uBAIE,UAAU,KACZ,CAAC,KAAK,UAAU,KAAK,GACrB;AACA,iBAAK,UAAU,KAAK,IAAI,KAAK;AAAA,cAC3B;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AACA,iBAAO,KAAK,UAAU,KAAK;AAAA,QAC7B;AAAA,QACA,KAAK,SAAS,QAAQ;AACpB,cACE,CAAC,cAIC,UAAU,GACZ;AACA,kBAAM,IAAI;AAAA,cACR,qCAAqC,OAAO,KAAK,CAAC;AAAA,YACpD;AAAA,UACF;AAEA,gBAAM,iBAAiB,KAAK;AAAA,YAC1B;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AACA,eAAK,UAAU,KAAK,IAAI;AACxB,iBAAO;AAAA,QACT;AAAA,QACA,KAAK,SAAS,WAAW;AACvB,cACE,CAAC,cAIC,UAAU,GACZ;AACA,kBAAM,IAAI;AAAA,cACR,qCAAqC,OAAO,KAAK,CAAC;AAAA,YACpD;AAAA,UACF;AAEA,iBAAO,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,QACA,SAAS;AACP,qCAAQ,UAAU;AAClB,gBAAM,IAAI;AAAA,YACR,6CAA6C;AAAA,cAC3C;AAAA,YACF,CAAC,KAAK,cAAc;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,eACE,OACA,SACA,iBAA+B,CAAC,GACwC;AACxE,WAAO,CAAC,WACL,SAAS,KAAK,YAAY,GAAG,QAAW,OAAO,SAAS,cAAc;AAAA,EAC3E;AAAA,EAEA,cAAsC;AACpC,UAAM,aAAsC,CAAC;AAC7C,eAAW,cAAc,KAAK,wBAAwB;AACpD,UACE,KAAK,uBAAuB,UAAU,EAAE,aAAa,SAAS,WAC9D;AACA,mBAAW,UAAU,IAAI,KAAK,UAAU,UAAU;AAAA,MACpD;AAAA,IACF;AACA,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,IACP,EAAE,KAAK,UAA6C;AAAA,EACtD;AAAA,EAEA,UAAgB;AACd,SAAK,YAAY,CAAC;AAClB,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,MAA6C,wBAeN;AACrC,WAAO,IAAI,gBAAuB,KAAK,iBAAiB;AAAA,MACtD,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,IACL,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,UAAU,CAAC;AAAA,EAI/B;AAAA,EAEA,SAEE;AACA,WAAO,OAAO;AAAA,MACZ,OAAO,KAAK,KAAK,sBAAsB,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC;AAAA,IAClE;AAAA,EAGF;AACF;AAEO,IAAM,sBAAN,cAGG,eAAuB;AAAA,EAC/B;AACF;","names":[]}
@@ -16,16 +16,15 @@ function isConstructed(value) {
16
16
  }
17
17
 
18
18
  // src/services/types/configInjector.types.ts
19
- var Lifetime = /* @__PURE__ */ ((Lifetime2) => {
20
- Lifetime2[Lifetime2["Singleton"] = 0] = "Singleton";
21
- Lifetime2[Lifetime2["Transient"] = 1] = "Transient";
22
- Lifetime2[Lifetime2["Scoped"] = 2] = "Scoped";
23
- return Lifetime2;
24
- })(Lifetime || {});
19
+ var Lifetime = {
20
+ Singleton: 0,
21
+ Transient: 1,
22
+ Scoped: 2
23
+ };
25
24
 
26
25
  // src/services/guards/isConstructedSingleton.ts
27
26
  function isConstructedSingleton(value) {
28
- return typeof value === "object" && value != null && "lifetime" in value && value.lifetime === 0 /* Singleton */ && "factory" in value;
27
+ return typeof value === "object" && value != null && "lifetime" in value && value.lifetime === Lifetime.Singleton && "factory" in value;
29
28
  }
30
29
 
31
30
  // src/services/guards/isConstructor.ts
@@ -60,7 +59,7 @@ var ConfigInjector = class _ConfigInjector {
60
59
  }
61
60
  for (const token in this.dependenciesDefinition) {
62
61
  const definition = this.dependenciesDefinition[token];
63
- if (definition.lifetime === 0 /* Singleton */ && !this.instances[token]) {
62
+ if (definition.lifetime === Lifetime.Singleton && !this.instances[token]) {
64
63
  if (isConstructedSingleton(definition)) {
65
64
  this.instances[token] = this.resolveInstance(
66
65
  token,
@@ -112,7 +111,7 @@ var ConfigInjector = class _ConfigInjector {
112
111
  safeValidateConfigSingletons() {
113
112
  const validNonSchemaSingletons = Object.entries(this.configShapes).reduce(
114
113
  (acc, [key, value]) => {
115
- if (this.dependenciesDefinition[key].lifetime === 0 /* Singleton */ && !this.schemaValidator.isSchema(value) && isConstructor(value)) {
114
+ if (this.dependenciesDefinition[key].lifetime === Lifetime.Singleton && !this.schemaValidator.isSchema(value) && isConstructor(value)) {
116
115
  if (!(this.instances[key] instanceof value)) {
117
116
  const expected = value.name;
118
117
  const receivedValue = this.instances[key];
@@ -149,7 +148,7 @@ var ConfigInjector = class _ConfigInjector {
149
148
  );
150
149
  const singletons = Object.fromEntries(
151
150
  Object.entries(this.configShapes).filter(
152
- ([key, value]) => this.dependenciesDefinition[key].lifetime === 0 /* Singleton */ && this.schemaValidator.isSchema(value)
151
+ ([key, value]) => this.dependenciesDefinition[key].lifetime === Lifetime.Singleton && this.schemaValidator.isSchema(value)
153
152
  )
154
153
  );
155
154
  const schemaSingletonParseResult = this.schemaValidator.parse(
@@ -159,7 +158,7 @@ var ConfigInjector = class _ConfigInjector {
159
158
  const dependency = this.dependenciesDefinition[key];
160
159
  return [
161
160
  key,
162
- dependency.lifetime === 0 /* Singleton */ ? this.instances[key] : void 0
161
+ dependency.lifetime === Lifetime.Singleton ? this.instances[key] : void 0
163
162
  ];
164
163
  })
165
164
  )
@@ -198,7 +197,7 @@ var ConfigInjector = class _ConfigInjector {
198
197
  throw new Error(`Unable to resolve dependency ${String(token)}`);
199
198
  }
200
199
  switch (definition.lifetime) {
201
- case 0 /* Singleton */: {
200
+ case Lifetime.Singleton: {
202
201
  if (isConstructedSingleton(definition) && !this.instances[token]) {
203
202
  this.instances[token] = this.resolveInstance(
204
203
  token,
@@ -209,7 +208,7 @@ var ConfigInjector = class _ConfigInjector {
209
208
  }
210
209
  return this.instances[token];
211
210
  }
212
- case 2 /* Scoped */: {
211
+ case Lifetime.Scoped: {
213
212
  if (!isConstructed(definition)) {
214
213
  throw new Error(
215
214
  `Invalid dependency definition for ${String(token)}`
@@ -224,7 +223,7 @@ var ConfigInjector = class _ConfigInjector {
224
223
  this.instances[token] = scopedInstance;
225
224
  return scopedInstance;
226
225
  }
227
- case 1 /* Transient */: {
226
+ case Lifetime.Transient: {
228
227
  if (!isConstructed(definition)) {
229
228
  throw new Error(
230
229
  `Invalid dependency definition for ${String(token)}`
@@ -256,7 +255,7 @@ var ConfigInjector = class _ConfigInjector {
256
255
  createScope() {
257
256
  const singletons = {};
258
257
  for (const dependency in this.dependenciesDefinition) {
259
- if (this.dependenciesDefinition[dependency].lifetime === 0 /* Singleton */) {
258
+ if (this.dependenciesDefinition[dependency].lifetime === Lifetime.Singleton) {
260
259
  singletons[dependency] = this.instances[dependency];
261
260
  }
262
261
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../common/src/getEnvVar.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"],"sourcesContent":["// 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","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>(\n schemaValidator,\n dependenciesDefinition\n ).load();\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\n for (const token in this.dependenciesDefinition) {\n const definition = this.dependenciesDefinition[token];\n if (\n definition.lifetime === Lifetime.Singleton &&\n !this.instances[token]\n ) {\n 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 }\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 ).load({ ...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 const singletons: Record<string, unknown> = {};\n for (const dependency in this.dependenciesDefinition) {\n if (\n this.dependenciesDefinition[dependency].lifetime === Lifetime.Singleton\n ) {\n singletons[dependency] = this.instances[dependency];\n }\n }\n return new ConfigInjector<SV, CV>(\n this.schemaValidator,\n this.dependenciesDefinition\n ).load(singletons as ResolvedConfigValidator<SV, CV>);\n }\n\n dispose(): void {\n this.instances = {};\n this.load();\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 FunctionToConstructor = (\n ...args: never[]\n) => new (...args: never[]) => unknown;\nexport type SchemaFunction<SV extends AnySchemaValidator> = (\n args: unknown\n) => IdiomaticSchema<SV>;\n\nexport type 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 ? (...args: Parameters<T>) => Schema<ReturnType<T>, SV>\n : T extends FunctionToConstructor\n ? (...args: Parameters<T>) => InstanceType<ReturnType<T>>\n : T extends Function\n ? (...args: Parameters<T>) => ReturnType<T>\n : T extends Constructor\n ? InstanceType<T>\n : T extends IdiomaticSchema<SV>\n ? Schema<T, SV>\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"],"mappings":"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","names":["Lifetime"]}
1
+ {"version":3,"sources":["../../../common/src/getEnvVar.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"],"sourcesContent":["// 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","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>(\n schemaValidator,\n dependenciesDefinition\n ).load();\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\n for (const token in this.dependenciesDefinition) {\n const definition = this.dependenciesDefinition[token];\n if (\n definition.lifetime === Lifetime.Singleton &&\n !this.instances[token]\n ) {\n 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 }\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 ).load({ ...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 const singletons: Record<string, unknown> = {};\n for (const dependency in this.dependenciesDefinition) {\n if (\n this.dependenciesDefinition[dependency].lifetime === Lifetime.Singleton\n ) {\n singletons[dependency] = this.instances[dependency];\n }\n }\n return new ConfigInjector<SV, CV>(\n this.schemaValidator,\n this.dependenciesDefinition\n ).load(singletons as ResolvedConfigValidator<SV, CV>);\n }\n\n dispose(): void {\n this.instances = {};\n this.load();\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 const Lifetime = {\n Singleton: 0,\n Transient: 1,\n Scoped: 2\n} as const;\nexport type Lifetime = (typeof Lifetime)[keyof typeof Lifetime];\n\nexport type Singleton<Type, Args, Value> =\n | {\n lifetime: typeof Lifetime.Singleton;\n type: Type;\n value: Value;\n }\n | ConstructedSingleton<Type, Args, Value>;\n\nexport type ConstructedSingleton<Type, Args, Return> = {\n lifetime: typeof 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: typeof Lifetime.Transient | typeof 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 FunctionToConstructor = (\n ...args: never[]\n) => new (...args: never[]) => unknown;\nexport type SchemaFunction<SV extends AnySchemaValidator> = (\n args: unknown\n) => IdiomaticSchema<SV>;\n\nexport type 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 ? (...args: Parameters<T>) => Schema<ReturnType<T>, SV>\n : T extends FunctionToConstructor\n ? (...args: Parameters<T>) => InstanceType<ReturnType<T>>\n : T extends Function\n ? (...args: Parameters<T>) => ReturnType<T>\n : T extends Constructor\n ? InstanceType<T>\n : T extends IdiomaticSchema<SV>\n ? Schema<T, SV>\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"],"mappings":";AAGO,SAAS,UAAU,MAAsB;AAC9C,QAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,SAAO;AACT;;;ACNA,SAAS,sBAAsB,eAAe;AAC9C;AAAA,EAIE;AAAA,OAEK;;;ACLA,SAAS,cACd,OAC0C;AAC1C,SACE,OAAO,UAAU,YACjB,SAAS,QACT,iBAAiB,SACjB,MAAM,eAAe;AAEzB;;;ACJO,IAAM,WAAW;AAAA,EACtB,WAAW;AAAA,EACX,WAAW;AAAA,EACX,QAAQ;AACV;;;ACTO,SAAS,uBACd,OACmD;AACnD,SACE,OAAO,UAAU,YACjB,SAAS,QACT,cAAc,SACd,MAAM,aAAa,SAAS,aAC5B,aAAa;AAEjB;;;ACVO,SAAS,cAAc,OAAsC;AAClE,SACE,OAAO,UAAU,cACjB,MAAM,eAAe,QACrB,MAAM,aAAa;AAEvB;;;AJcO,SAAS,qBAId,iBACA,wBAaA;AACA,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,EACF,EAAE,KAAK;AACT;AAEO,IAAM,iBAAN,MAAM,gBAGX;AAAA,EAkGA,YACU,iBACA,wBAgBR;AAjBQ;AACA;AAiBR,SAAK,eAAe,OAAO,QAAQ,KAAK,sBAAsB,EAAE;AAAA,MAC9D,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO;AAAA,QACzB,GAAG;AAAA,QACH,CAAC,GAAG,GAAG;AAAA,MACT;AAAA,MACA,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EA3HA,YAEI,CAAC;AAAA,EAEI;AAAA,EAET,KAAK,yBAEI;AACP,eAAW,SAAS,yBAAyB;AAC3C,WAAK,UAAU,KAAK,IAAI,wBAAwB,KAAK;AAAA,IACvD;AAEA,eAAW,SAAS,KAAK,wBAAwB;AAC/C,YAAM,aAAa,KAAK,uBAAuB,KAAK;AACpD,UACE,WAAW,aAAa,SAAS,aACjC,CAAC,KAAK,UAAU,KAAK,GACrB;AACA,YACE,uBAIE,UAAU,GACZ;AACA,eAAK,UAAU,KAAK,IAAI,KAAK;AAAA,YAC3B;AAAA,YACA;AAAA,UACF;AAAA,QACF,OAAO;AACL,eAAK,UAAU,KAAK,IAAI,WAAW;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,gBACN,OACA,YAWA,SACA,iBAA+B,CAAC,GACI;AACpC,UAAM,mBAAmB,qBAAqB,WAAW,OAAO,EAAE,CAAC;AAEnE,QAAI,CAAC,oBAAoB,qBAAqB,SAAS;AACrD,aAAO,WAAW;AAAA,QAChB,CAAC;AAAA,QACD,KAAK,QAAQ,KAAK,IAAI;AAAA,QACtB,WAAY,CAAC;AAAA,MACf;AAAA,IACF;AAEA,QAAI,CAAC,iBAAiB,WAAW,GAAG,KAAK,CAAC,iBAAiB,SAAS,GAAG,GAAG;AACxE,YAAM,IAAI;AAAA,QACR,iCAAiC;AAAA,UAC/B;AAAA,QACF,CAAC,KAAK,gBAAgB;AAAA,MACxB;AAAA,IACF;AACA,UAAM,oBAAoB,OAAO;AAAA,MAC/B,iBACG,QAAQ,KAAK,EAAE,EACf,QAAQ,KAAK,EAAE,EACf,MAAM,GAAG,EACT,IAAI,CAAC,QAAQ,IAAI,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,EACrC,IAAI,CAAC,QAAQ;AACZ,cAAM,oBAAoB,CAAC,GAAG,gBAAgB,KAAK;AACnD,YAAI,eAAe,SAAS,GAAG,GAAG;AAChC,gBAAM,IAAI;AAAA,YACR,iCAAiC,kBAAkB;AAAA,cACjD;AAAA,YACF,CAAC,OAAO,GAAG;AAAA,UACb;AAAA,QACF;AACA,cAAM,cAAc,KAAK,QAAQ,KAAK,SAAS,iBAAiB;AAChE,eAAO,CAAC,KAAK,WAAW;AAAA,MAC1B,CAAC;AAAA,IACL;AACA,WAAO,WAAW;AAAA,MAChB;AAAA,MACA,KAAK,QAAQ,KAAK,IAAI;AAAA,MACtB,WAAY,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EA8BA,+BAAyE;AACvE,UAAM,2BAA2B,OAAO,QAAQ,KAAK,YAAY,EAAE;AAAA,MAGjE,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AACrB,YACE,KAAK,uBAAuB,GAAG,EAAE,aAAa,SAAS,aACvD,CAAE,KAAK,gBAAoC,SAEzC,KAAK,KACP,cAAc,KAAK,GACnB;AACA,cAAI,EAAE,KAAK,UAAU,GAAG,aAAa,QAAQ;AAC3C,kBAAM,WAAW,MAAM;AACvB,kBAAM,gBAAyB,KAAK,UAAU,GAAG;AACjD,kBAAM,WAAW,cAAc,aAAa,IACxC,cAAc,YAAY,OAC1B,OAAO;AAEX,gBAAI,IAAI,IAAI;AACV,oBAAM;AAAA,gBACJ,IAAI;AAAA,gBACJ,QAAQ,CAAC;AAAA,cACX;AAAA,YACF;AACA,gBAAI,QAAQ,KAAK;AAAA,cACf,SAAS,YAAY,QAAQ,cAAc,QAAQ;AAAA,cACnD,MAAM,CAAC,GAAG;AAAA,YACZ,CAAC;AAAA,UACH,OAAO;AACL,gBAAI,IAAI,IAAI;AACV,oBAAM;AAAA,gBACJ,IAAI;AAAA,gBACJ,OAAO;AAAA,kBACL,GAAG,IAAI;AAAA,kBACP,CAAC,GAAG,GAAG,KAAK,UAAU,GAAG;AAAA,gBAC3B;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO,CAAC;AAAA,MACV;AAAA,IACF;AAEA,UAAM,aAAa,OAAO;AAAA,MACxB,OAAO,QAAQ,KAAK,YAAY,EAAE;AAAA,QAChC,CAAC,CAAC,KAAK,KAAK,MACV,KAAK,uBAAuB,GAAG,EAAE,aAAa,SAAS,aACtD,KAAK,gBAAoC,SAAS,KAAK;AAAA,MAC5D;AAAA,IACF;AACA,UAAM,6BACJ,KAAK,gBACL;AAAA,MACC,KAAK,gBAAoC,SAAS,UAAU;AAAA,MAC7D,OAAO;AAAA,QACL,OAAO,KAAK,UAAU,EAAE,IAAI,CAAC,QAAQ;AACnC,gBAAM,aAAa,KAAK,uBAAuB,GAAG;AAClD,iBAAO;AAAA,YACL;AAAA,YACA,WAAW,aAAa,SAAS,YAC7B,KAAK,UAAU,GAAG,IAClB;AAAA,UACN;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,aAAa,OAAO,KAAK,KAAK,YAAY;AAEhD,WAAO,yBAAyB,MAAM,2BAA2B,KAC7D;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,IAAI;AAAA,QACT,KAAK;AAAA,QACL,KAAK;AAAA,MACP,EAAE,KAAK,EAAE,GAAG,KAAK,UAAU,CAAC;AAAA,IAC9B,IACA;AAAA,MACE,IAAI;AAAA,MACJ,QAAQ;AAAA,QACN,GAAI,CAAC,yBAAyB,MAAM,yBAAyB,SACzD,yBAAyB,SACzB,CAAC;AAAA,QACL,GAAI,CAAC,2BAA2B,MAChC,2BAA2B,SACvB,2BAA2B,SAC3B,CAAC;AAAA,MACP,EAAE;AAAA,QACA,CAAC,GAAG,MACF,WAAW,QAAQ,EAAE,KAAK,CAAC,CAAC,IAAI,WAAW,QAAQ,EAAE,KAAK,CAAC,CAAC;AAAA,MAChE;AAAA,IACF;AAAA,EACN;AAAA,EAEA,yBAAyB,YAAiD;AACxE,UAAM,qBAAqB,KAAK,6BAA6B;AAE7D,QAAI,mBAAmB,IAAI;AACzB,aAAO,mBAAmB;AAAA,IAC5B;AAEA,UAAM,IAAI;AAAA,MACR,uBAAuB,mBAAmB,QAAQ,UAAU;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,QACE,OACA,SACA,iBAA+B,CAAC,GACI;AACpC,UAAM,WAAW,KAAK,UAAU,KAAK;AACrC,QAAI,CAAC,UAAU;AACb,YAAM,aAAa,KAAK,uBAAuB,KAAK;AAEpD,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,MAAM,gCAAgC,OAAO,KAAK,CAAC,EAAE;AAAA,MACjE;AAEA,cAAQ,WAAW,UAAU;AAAA,QAC3B,KAAK,SAAS,WAAW;AACvB,cACE,uBAIE,UAAU,KACZ,CAAC,KAAK,UAAU,KAAK,GACrB;AACA,iBAAK,UAAU,KAAK,IAAI,KAAK;AAAA,cAC3B;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AACA,iBAAO,KAAK,UAAU,KAAK;AAAA,QAC7B;AAAA,QACA,KAAK,SAAS,QAAQ;AACpB,cACE,CAAC,cAIC,UAAU,GACZ;AACA,kBAAM,IAAI;AAAA,cACR,qCAAqC,OAAO,KAAK,CAAC;AAAA,YACpD;AAAA,UACF;AAEA,gBAAM,iBAAiB,KAAK;AAAA,YAC1B;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AACA,eAAK,UAAU,KAAK,IAAI;AACxB,iBAAO;AAAA,QACT;AAAA,QACA,KAAK,SAAS,WAAW;AACvB,cACE,CAAC,cAIC,UAAU,GACZ;AACA,kBAAM,IAAI;AAAA,cACR,qCAAqC,OAAO,KAAK,CAAC;AAAA,YACpD;AAAA,UACF;AAEA,iBAAO,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,QACA,SAAS;AACP,kBAAQ,UAAU;AAClB,gBAAM,IAAI;AAAA,YACR,6CAA6C;AAAA,cAC3C;AAAA,YACF,CAAC,KAAK,cAAc;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,eACE,OACA,SACA,iBAA+B,CAAC,GACwC;AACxE,WAAO,CAAC,WACL,SAAS,KAAK,YAAY,GAAG,QAAW,OAAO,SAAS,cAAc;AAAA,EAC3E;AAAA,EAEA,cAAsC;AACpC,UAAM,aAAsC,CAAC;AAC7C,eAAW,cAAc,KAAK,wBAAwB;AACpD,UACE,KAAK,uBAAuB,UAAU,EAAE,aAAa,SAAS,WAC9D;AACA,mBAAW,UAAU,IAAI,KAAK,UAAU,UAAU;AAAA,MACpD;AAAA,IACF;AACA,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,IACP,EAAE,KAAK,UAA6C;AAAA,EACtD;AAAA,EAEA,UAAgB;AACd,SAAK,YAAY,CAAC;AAClB,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,MAA6C,wBAeN;AACrC,WAAO,IAAI,gBAAuB,KAAK,iBAAiB;AAAA,MACtD,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,IACL,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,UAAU,CAAC;AAAA,EAI/B;AAAA,EAEA,SAEE;AACA,WAAO,OAAO;AAAA,MACZ,OAAO,KAAK,KAAK,sBAAsB,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC;AAAA,IAClE;AAAA,EAGF;AACF;AAEO,IAAM,sBAAN,cAGG,eAAuB;AAAA,EAC/B;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forklaunch/core",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
4
4
  "description": "forklaunch-js core package. Contains useful building blocks.",
5
5
  "homepage": "https://github.com/forklaunch/forklaunch-js#readme",
6
6
  "bugs": {
@@ -67,7 +67,7 @@
67
67
  "@forklaunch/opentelemetry-instrumentation-hyper-express": "0.0.5",
68
68
  "@mikro-orm/core": "^6.4.16",
69
69
  "@mikro-orm/mongodb": "^6.4.16",
70
- "@modelcontextprotocol/sdk": "^1.13.3",
70
+ "@modelcontextprotocol/sdk": "^1.14.0",
71
71
  "@opentelemetry/api": "^1.9.0",
72
72
  "@opentelemetry/api-logs": "^0.202.0",
73
73
  "@opentelemetry/exporter-logs-otlp-http": "^0.202.0",
@@ -91,8 +91,8 @@
91
91
  "pino-pretty": "^13.0.0",
92
92
  "redis": "^5.5.6",
93
93
  "uuid": "^11.1.0",
94
- "@forklaunch/common": "0.4.1",
95
- "@forklaunch/validator": "0.7.2"
94
+ "@forklaunch/common": "0.4.2",
95
+ "@forklaunch/validator": "0.7.4"
96
96
  },
97
97
  "devDependencies": {
98
98
  "@eslint/js": "^9.30.1",
@@ -101,9 +101,9 @@
101
101
  "@types/jest": "^30.0.0",
102
102
  "@types/qs": "^6.14.0",
103
103
  "@types/uuid": "^10.0.0",
104
- "@typescript/native-preview": "7.0.0-dev.20250702.1",
104
+ "@typescript/native-preview": "7.0.0-dev.20250703.1",
105
105
  "globals": "^16.3.0",
106
- "jest": "^30.0.3",
106
+ "jest": "^30.0.4",
107
107
  "prettier": "^3.6.2",
108
108
  "testcontainers": "^11.0.3",
109
109
  "ts-jest": "^29.4.0",