@andrew_l/ioc 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,21 +1,19 @@
1
1
  'use strict';
2
2
 
3
- const glob = require('glob');
4
3
  const crypto = require('node:crypto');
4
+ const node_fs = require('node:fs');
5
5
  const fs = require('node:fs/promises');
6
6
  const path = require('node:path');
7
7
  const toolkit = require('@andrew_l/toolkit');
8
8
 
9
- var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
10
9
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
11
10
 
12
- const glob__default = /*#__PURE__*/_interopDefaultCompat(glob);
13
11
  const crypto__default = /*#__PURE__*/_interopDefaultCompat(crypto);
14
12
  const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
15
13
  const path__default = /*#__PURE__*/_interopDefaultCompat(path);
16
14
 
17
15
  const storage = /* @__PURE__ */ new Map();
18
- const log = toolkit.logger(({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }), "IOC");
16
+ const log = toolkit.logger("IOC");
19
17
  const ServiceContainer = {
20
18
  get(id) {
21
19
  const service = storage.get(id);
@@ -34,9 +32,7 @@ const ServiceContainer = {
34
32
  }
35
33
  let constructorPath;
36
34
  try {
37
- constructorPath = new URL(
38
- toolkit.captureStackTrace(this.set).split("\n")[0].slice(7)
39
- ).pathname.split(":")[0];
35
+ constructorPath = extractFilePathFromStack(toolkit.captureStackTrace(this.set));
40
36
  } catch (_) {
41
37
  }
42
38
  this.override(id, factoryOrClassReference, buildInstantly, constructorPath);
@@ -82,7 +78,7 @@ const ServiceContainer = {
82
78
  },
83
79
  async importServices(autoImportPatterns) {
84
80
  for (const pattern of autoImportPatterns) {
85
- for (const filePath of glob__default.sync(pattern)) {
81
+ for (const filePath of node_fs.globSync(pattern)) {
86
82
  await import(filePath);
87
83
  }
88
84
  }
@@ -94,8 +90,7 @@ const ServiceContainer = {
94
90
  key,
95
91
  { constructorName, constructorPath }
96
92
  ] of storage.entries()) {
97
- if (!constructorName) continue;
98
- if (!constructorPath) continue;
93
+ if (!constructorName || !constructorPath) continue;
99
94
  typesDefinitions.push(
100
95
  `"${key}": import('./${path__default.relative(
101
96
  outputFolderPath,
@@ -130,6 +125,23 @@ ${typesContent}
130
125
  }
131
126
  }
132
127
  };
128
+ function extractFilePathFromStack(stack) {
129
+ let result = stack.split("\n")[0].slice(7).replace("<anonymous>", "").trim();
130
+ if (result.startsWith("(")) {
131
+ result = result.slice(1);
132
+ }
133
+ if (result.endsWith(")")) {
134
+ result = result.slice(0, -1);
135
+ }
136
+ if (!result.startsWith("file://")) {
137
+ result = "file://" + result;
138
+ }
139
+ result = new URL(result).pathname.split(":")[0];
140
+ if (result.endsWith(".ts")) {
141
+ result = result.slice(0, -3) + ".js";
142
+ }
143
+ return result;
144
+ }
133
145
  function isConstructable(obj) {
134
146
  return !!obj.prototype && !!obj.prototype.constructor.name;
135
147
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/ServiceContainer.ts","../src/ioc.ts"],"sourcesContent":["import glob from 'glob';\n\nimport crypto from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { type AnyFunction, captureStackTrace, logger } from '@andrew_l/toolkit';\n\nexport type Factory = any;\n\nexport type Service = {\n factory?: Factory;\n constructorName?: string;\n constructorPath?: string;\n instance: any;\n};\n\nexport interface SetupOptions {\n pathRoot?: string;\n\n /**\n * Absolute or relative path where generated type file will be saved\n */\n typeOutput?: string;\n\n /**\n * Absolute or relative glob patterns to auto-import service files\n */\n autoImportPatterns?: string[];\n\n /**\n * Should generate type file\n */\n generateTypes?: boolean;\n}\n\nconst storage = new Map<string, Service>();\n\nconst log = logger(import.meta, 'IOC');\n\nexport default {\n get<T>(id: string): T {\n const service = storage.get(id);\n\n if (!service) {\n throw new Error(`No service is registered for [${id}]`);\n }\n\n if (!service.instance) {\n service.instance = service.factory?.();\n service.factory = undefined;\n }\n\n return service.instance;\n },\n\n set(\n id: string,\n factoryOrClassReference: Factory | AnyFunction,\n buildInstantly: boolean = false,\n ) {\n if (this.isSet(id)) {\n throw new Error(`Service [${id}] is already registered`);\n }\n\n let constructorPath: string | undefined;\n\n try {\n constructorPath = new URL(\n captureStackTrace(this.set).split('\\n')[0].slice(7),\n ).pathname.split(':')[0];\n } catch (_) {}\n\n this.override(id, factoryOrClassReference, buildInstantly, constructorPath);\n },\n\n override(\n id: string,\n factoryOrClassReference: Factory | AnyFunction,\n buildInstantly: boolean = false,\n constructorPath?: string,\n ) {\n const factory: Factory = getFactory(factoryOrClassReference);\n\n storage.set(id, {\n factory: buildInstantly ? undefined : factory,\n instance: buildInstantly ? factory() : undefined,\n constructorName: getConstructorName(factoryOrClassReference),\n constructorPath,\n });\n },\n\n isSet(id: string): boolean {\n return storage.has(id);\n },\n\n clear() {\n storage.clear();\n },\n\n async setup({\n pathRoot = process.cwd(),\n generateTypes = false,\n autoImportPatterns = ['./services/*/**/*.service.{js,mjs,ts,mts,cts}'],\n typeOutput = './ioc.d.ts',\n }: SetupOptions | undefined = {}) {\n typeOutput = path.isAbsolute(typeOutput)\n ? typeOutput\n : path.join(pathRoot, typeOutput);\n\n if (!typeOutput.endsWith('.d.ts')) {\n typeOutput = path.join(typeOutput, 'ioc.d.ts');\n }\n\n autoImportPatterns = autoImportPatterns.map(servicePath => {\n return path.isAbsolute(servicePath)\n ? servicePath\n : path.join(pathRoot, servicePath);\n });\n\n log.debug('Setup', {\n pathRoot,\n generateTypes,\n autoImportPatterns,\n typeOutput,\n });\n\n await this.importServices(autoImportPatterns);\n\n if (generateTypes) {\n await this.writeTypes(typeOutput);\n }\n },\n\n async importServices(autoImportPatterns: string[]) {\n for (const pattern of autoImportPatterns) {\n for (const filePath of glob.sync(pattern)) {\n await import(filePath);\n }\n }\n },\n\n async writeTypes(outputFilePath: string) {\n const typesDefinitions: string[] = [];\n const outputFolderPath = path.dirname(outputFilePath);\n\n for (const [\n key,\n { constructorName, constructorPath },\n ] of storage.entries()) {\n if (!constructorName) continue;\n if (!constructorPath) continue;\n\n typesDefinitions.push(\n `\"${key}\": import('./${path.relative(\n outputFolderPath,\n constructorPath,\n )}').${constructorName};`,\n );\n }\n\n const typesContent = `/* eslint-disable */\n/* prettier-ignore */\n// @ts-nocheck\n// Generated by @andrew_l/ioc\n\nexport {};\n\ndeclare module '@andrew_l/ioc' {\n\tinterface IocMap {\n\t\t${typesDefinitions.sort().join('\\n\\t\\t')}\n\t}\n\n\tfunction ioc<Key extends keyof IocMap>(id: Key): IocMap[Key];\n}`;\n\n const newHash = crypto\n .createHmac('sha256', '')\n .update(typesContent)\n .digest('hex');\n\n const oldHash = await getHashFromTypeFile(outputFilePath);\n\n if (newHash !== oldHash) {\n log.warn('Types file has been updated.');\n\n await fs.writeFile(\n outputFilePath,\n `// hash:${newHash}\\n${typesContent}\\n`,\n );\n }\n },\n};\n\nfunction isConstructable(obj: any): obj is Function {\n // https://stackoverflow.com/a/46320004\n return !!obj.prototype && !!obj.prototype.constructor.name;\n}\n\nfunction getFactory(factoryOrClassReference: Factory | AnyFunction): Factory {\n return isConstructable(factoryOrClassReference)\n ? () => new factoryOrClassReference()\n : factoryOrClassReference;\n}\n\nfunction getConstructorName(\n factoryOrClassReference: Factory | AnyFunction,\n): string {\n return isConstructable(factoryOrClassReference)\n ? factoryOrClassReference.prototype.constructor.name\n : String(factoryOrClassReference).match(/new\\s(\\w+)\\(/)?.[1] || '';\n}\n\nasync function getHashFromTypeFile(filePath: string): Promise<string | null> {\n try {\n const content = await fs.readFile(filePath, { encoding: 'utf8' });\n const lastLine = content.split('\\n').at(0);\n\n return lastLine?.split('hash:')[1] || null;\n } catch (_) {\n return null;\n }\n}\n","import ServiceContainer from './ServiceContainer';\n\n/**\n * This interface can be augmented by users to add types to ioc\n */\ninterface IocMap {}\n\n/**\n * Get instance of service\n * @example\n * const userService ioc('UserService');\n *\n * @group Main\n */\nexport function ioc<Key extends keyof IocMap>(id: Key): IocMap[Key] {\n return ServiceContainer.get(id as any) as any;\n}\nexport type { IocMap };\n"],"names":["logger","captureStackTrace","path","glob","crypto","fs"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/ServiceContainer.ts","../src/ioc.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport { globSync } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { type AnyFunction, captureStackTrace, logger } from '@andrew_l/toolkit';\n\nexport type Factory = any;\n\nexport type Service = {\n factory?: Factory;\n constructorName?: string;\n constructorPath?: string;\n instance: any;\n};\n\nexport interface SetupOptions {\n pathRoot?: string;\n\n /**\n * Absolute or relative path where generated type file will be saved\n */\n typeOutput?: string;\n\n /**\n * Absolute or relative glob patterns to auto-import service files\n */\n autoImportPatterns?: string[];\n\n /**\n * Should generate type file\n */\n generateTypes?: boolean;\n}\n\nconst storage = new Map<string, Service>();\n\nconst log = logger('IOC');\n\nexport default {\n get<T>(id: string): T {\n const service = storage.get(id);\n\n if (!service) {\n throw new Error(`No service is registered for [${id}]`);\n }\n\n if (!service.instance) {\n service.instance = service.factory?.();\n service.factory = undefined;\n }\n\n return service.instance;\n },\n\n set(\n id: string,\n factoryOrClassReference: Factory | AnyFunction,\n buildInstantly: boolean = false,\n ) {\n if (this.isSet(id)) {\n throw new Error(`Service [${id}] is already registered`);\n }\n\n let constructorPath: string | undefined;\n\n try {\n constructorPath = extractFilePathFromStack(captureStackTrace(this.set));\n } catch (_) {}\n\n this.override(id, factoryOrClassReference, buildInstantly, constructorPath);\n },\n\n override(\n id: string,\n factoryOrClassReference: Factory | AnyFunction,\n buildInstantly: boolean = false,\n constructorPath?: string,\n ) {\n const factory: Factory = getFactory(factoryOrClassReference);\n\n storage.set(id, {\n factory: buildInstantly ? undefined : factory,\n instance: buildInstantly ? factory() : undefined,\n constructorName: getConstructorName(factoryOrClassReference),\n constructorPath,\n });\n },\n\n isSet(id: string): boolean {\n return storage.has(id);\n },\n\n clear() {\n storage.clear();\n },\n\n async setup({\n pathRoot = process.cwd(),\n generateTypes = false,\n autoImportPatterns = ['./services/*/**/*.service.{js,mjs,ts,mts,cts}'],\n typeOutput = './ioc.d.ts',\n }: SetupOptions | undefined = {}) {\n typeOutput = path.isAbsolute(typeOutput)\n ? typeOutput\n : path.join(pathRoot, typeOutput);\n\n if (!typeOutput.endsWith('.d.ts')) {\n typeOutput = path.join(typeOutput, 'ioc.d.ts');\n }\n\n autoImportPatterns = autoImportPatterns.map(servicePath => {\n return path.isAbsolute(servicePath)\n ? servicePath\n : path.join(pathRoot, servicePath);\n });\n\n log.debug('Setup', {\n pathRoot,\n generateTypes,\n autoImportPatterns,\n typeOutput,\n });\n\n await this.importServices(autoImportPatterns);\n\n if (generateTypes) {\n await this.writeTypes(typeOutput);\n }\n },\n\n async importServices(autoImportPatterns: string[]) {\n for (const pattern of autoImportPatterns) {\n for (const filePath of globSync(pattern)) {\n await import(filePath);\n }\n }\n },\n\n async writeTypes(outputFilePath: string) {\n const typesDefinitions: string[] = [];\n const outputFolderPath = path.dirname(outputFilePath);\n\n for (const [\n key,\n { constructorName, constructorPath },\n ] of storage.entries()) {\n if (!constructorName || !constructorPath) continue;\n\n typesDefinitions.push(\n `\"${key}\": import('./${path.relative(\n outputFolderPath,\n constructorPath,\n )}').${constructorName};`,\n );\n }\n\n const typesContent = `/* eslint-disable */\n/* prettier-ignore */\n// @ts-nocheck\n// Generated by @andrew_l/ioc\n\nexport {};\n\ndeclare module '@andrew_l/ioc' {\n\tinterface IocMap {\n\t\t${typesDefinitions.sort().join('\\n\\t\\t')}\n\t}\n\n\tfunction ioc<Key extends keyof IocMap>(id: Key): IocMap[Key];\n}`;\n\n const newHash = crypto\n .createHmac('sha256', '')\n .update(typesContent)\n .digest('hex');\n\n const oldHash = await getHashFromTypeFile(outputFilePath);\n\n if (newHash !== oldHash) {\n log.warn('Types file has been updated.');\n\n await fs.writeFile(\n outputFilePath,\n `// hash:${newHash}\\n${typesContent}\\n`,\n );\n }\n },\n};\n\nfunction extractFilePathFromStack(stack: string): string {\n let result = stack.split('\\n')[0].slice(7).replace('<anonymous>', '').trim();\n\n if (result.startsWith('(')) {\n result = result.slice(1);\n }\n\n if (result.endsWith(')')) {\n result = result.slice(0, -1);\n }\n\n if (!result.startsWith('file://')) {\n result = 'file://' + result;\n }\n\n result = new URL(result).pathname.split(':')[0];\n\n if (result.endsWith('.ts')) {\n result = result.slice(0, -3) + '.js';\n }\n return result;\n}\n\nfunction isConstructable(obj: any): obj is Function {\n // https://stackoverflow.com/a/46320004\n return !!obj.prototype && !!obj.prototype.constructor.name;\n}\n\nfunction getFactory(factoryOrClassReference: Factory | AnyFunction): Factory {\n return isConstructable(factoryOrClassReference)\n ? () => new factoryOrClassReference()\n : factoryOrClassReference;\n}\n\nfunction getConstructorName(\n factoryOrClassReference: Factory | AnyFunction,\n): string {\n return isConstructable(factoryOrClassReference)\n ? factoryOrClassReference.prototype.constructor.name\n : String(factoryOrClassReference).match(/new\\s(\\w+)\\(/)?.[1] || '';\n}\n\nasync function getHashFromTypeFile(filePath: string): Promise<string | null> {\n try {\n const content = await fs.readFile(filePath, { encoding: 'utf8' });\n const lastLine = content.split('\\n').at(0);\n\n return lastLine?.split('hash:')[1] || null;\n } catch (_) {\n return null;\n }\n}\n","import ServiceContainer from './ServiceContainer';\n\n/**\n * This interface can be augmented by users to add types to ioc\n */\ninterface IocMap {}\n\n/**\n * Get instance of service\n * @example\n * const userService ioc('UserService');\n *\n * @group Main\n */\nexport function ioc<Key extends keyof IocMap>(id: Key): IocMap[Key] {\n return ServiceContainer.get(id as any) as any;\n}\nexport type { IocMap };\n"],"names":["logger","captureStackTrace","path","globSync","crypto","fs"],"mappings":";;;;;;;;;;;;;;AAmCA,MAAM,OAAA,uBAAc,GAAqB,EAAA,CAAA;AAEzC,MAAM,GAAA,GAAMA,eAAO,KAAK,CAAA,CAAA;AAExB,yBAAe;AAAA,EACb,IAAO,EAAe,EAAA;AACpB,IAAM,MAAA,OAAA,GAAU,OAAQ,CAAA,GAAA,CAAI,EAAE,CAAA,CAAA;AAE9B,IAAA,IAAI,CAAC,OAAS,EAAA;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,CAAiC,8BAAA,EAAA,EAAE,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,KACxD;AAEA,IAAI,IAAA,CAAC,QAAQ,QAAU,EAAA;AACrB,MAAQ,OAAA,CAAA,QAAA,GAAW,QAAQ,OAAU,IAAA,CAAA;AACrC,MAAA,OAAA,CAAQ,OAAU,GAAA,KAAA,CAAA,CAAA;AAAA,KACpB;AAEA,IAAA,OAAO,OAAQ,CAAA,QAAA,CAAA;AAAA,GACjB;AAAA,EAEA,GACE,CAAA,EAAA,EACA,uBACA,EAAA,cAAA,GAA0B,KAC1B,EAAA;AACA,IAAI,IAAA,IAAA,CAAK,KAAM,CAAA,EAAE,CAAG,EAAA;AAClB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAY,SAAA,EAAA,EAAE,CAAyB,uBAAA,CAAA,CAAA,CAAA;AAAA,KACzD;AAEA,IAAI,IAAA,eAAA,CAAA;AAEJ,IAAI,IAAA;AACF,MAAA,eAAA,GAAkB,wBAAyB,CAAAC,yBAAA,CAAkB,IAAK,CAAA,GAAG,CAAC,CAAA,CAAA;AAAA,aAC/D,CAAG,EAAA;AAAA,KAAC;AAEb,IAAA,IAAA,CAAK,QAAS,CAAA,EAAA,EAAI,uBAAyB,EAAA,cAAA,EAAgB,eAAe,CAAA,CAAA;AAAA,GAC5E;AAAA,EAEA,QACE,CAAA,EAAA,EACA,uBACA,EAAA,cAAA,GAA0B,OAC1B,eACA,EAAA;AACA,IAAM,MAAA,OAAA,GAAmB,WAAW,uBAAuB,CAAA,CAAA;AAE3D,IAAA,OAAA,CAAQ,IAAI,EAAI,EAAA;AAAA,MACd,OAAA,EAAS,iBAAiB,KAAY,CAAA,GAAA,OAAA;AAAA,MACtC,QAAA,EAAU,cAAiB,GAAA,OAAA,EAAY,GAAA,KAAA,CAAA;AAAA,MACvC,eAAA,EAAiB,mBAAmB,uBAAuB,CAAA;AAAA,MAC3D,eAAA;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AAAA,EAEA,MAAM,EAAqB,EAAA;AACzB,IAAO,OAAA,OAAA,CAAQ,IAAI,EAAE,CAAA,CAAA;AAAA,GACvB;AAAA,EAEA,KAAQ,GAAA;AACN,IAAA,OAAA,CAAQ,KAAM,EAAA,CAAA;AAAA,GAChB;AAAA,EAEA,MAAM,KAAM,CAAA;AAAA,IACV,QAAA,GAAW,QAAQ,GAAI,EAAA;AAAA,IACvB,aAAgB,GAAA,KAAA;AAAA,IAChB,kBAAA,GAAqB,CAAC,+CAA+C,CAAA;AAAA,IACrE,UAAa,GAAA,YAAA;AAAA,GACf,GAA8B,EAAI,EAAA;AAChC,IAAa,UAAA,GAAAC,aAAA,CAAK,WAAW,UAAU,CAAA,GACnC,aACAA,aAAK,CAAA,IAAA,CAAK,UAAU,UAAU,CAAA,CAAA;AAElC,IAAA,IAAI,CAAC,UAAA,CAAW,QAAS,CAAA,OAAO,CAAG,EAAA;AACjC,MAAa,UAAA,GAAAA,aAAA,CAAK,IAAK,CAAA,UAAA,EAAY,UAAU,CAAA,CAAA;AAAA,KAC/C;AAEA,IAAqB,kBAAA,GAAA,kBAAA,CAAmB,IAAI,CAAe,WAAA,KAAA;AACzD,MAAO,OAAAA,aAAA,CAAK,WAAW,WAAW,CAAA,GAC9B,cACAA,aAAK,CAAA,IAAA,CAAK,UAAU,WAAW,CAAA,CAAA;AAAA,KACpC,CAAA,CAAA;AAED,IAAA,GAAA,CAAI,MAAM,OAAS,EAAA;AAAA,MACjB,QAAA;AAAA,MACA,aAAA;AAAA,MACA,kBAAA;AAAA,MACA,UAAA;AAAA,KACD,CAAA,CAAA;AAED,IAAM,MAAA,IAAA,CAAK,eAAe,kBAAkB,CAAA,CAAA;AAE5C,IAAA,IAAI,aAAe,EAAA;AACjB,MAAM,MAAA,IAAA,CAAK,WAAW,UAAU,CAAA,CAAA;AAAA,KAClC;AAAA,GACF;AAAA,EAEA,MAAM,eAAe,kBAA8B,EAAA;AACjD,IAAA,KAAA,MAAW,WAAW,kBAAoB,EAAA;AACxC,MAAW,KAAA,MAAA,QAAA,IAAYC,gBAAS,CAAA,OAAO,CAAG,EAAA;AACxC,QAAA,MAAM,OAAO,QAAA,CAAA,CAAA;AAAA,OACf;AAAA,KACF;AAAA,GACF;AAAA,EAEA,MAAM,WAAW,cAAwB,EAAA;AACvC,IAAA,MAAM,mBAA6B,EAAC,CAAA;AACpC,IAAM,MAAA,gBAAA,GAAmBD,aAAK,CAAA,OAAA,CAAQ,cAAc,CAAA,CAAA;AAEpD,IAAW,KAAA,MAAA;AAAA,MACT,GAAA;AAAA,MACA,EAAE,iBAAiB,eAAgB,EAAA;AAAA,KACrC,IAAK,OAAQ,CAAA,OAAA,EAAW,EAAA;AACtB,MAAI,IAAA,CAAC,eAAmB,IAAA,CAAC,eAAiB,EAAA,SAAA;AAE1C,MAAiB,gBAAA,CAAA,IAAA;AAAA,QACf,CAAA,CAAA,EAAI,GAAG,CAAA,aAAA,EAAgBA,aAAK,CAAA,QAAA;AAAA,UAC1B,gBAAA;AAAA,UACA,eAAA;AAAA,SACD,MAAM,eAAe,CAAA,CAAA,CAAA;AAAA,OACxB,CAAA;AAAA,KACF;AAEA,IAAA,MAAM,YAAe,GAAA,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,EASrB,gBAAiB,CAAA,IAAA,EAAO,CAAA,IAAA,CAAK,MAAQ,CAAC,CAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA,CAAA;AAMtC,IAAM,MAAA,OAAA,GAAUE,eACb,CAAA,UAAA,CAAW,QAAU,EAAA,EAAE,EACvB,MAAO,CAAA,YAAY,CACnB,CAAA,MAAA,CAAO,KAAK,CAAA,CAAA;AAEf,IAAM,MAAA,OAAA,GAAU,MAAM,mBAAA,CAAoB,cAAc,CAAA,CAAA;AAExD,IAAA,IAAI,YAAY,OAAS,EAAA;AACvB,MAAA,GAAA,CAAI,KAAK,8BAA8B,CAAA,CAAA;AAEvC,MAAA,MAAMC,WAAG,CAAA,SAAA;AAAA,QACP,cAAA;AAAA,QACA,WAAW,OAAO,CAAA;AAAA,EAAK,YAAY,CAAA;AAAA,CAAA;AAAA,OACrC,CAAA;AAAA,KACF;AAAA,GACF;AACF,CAAA,CAAA;AAEA,SAAS,yBAAyB,KAAuB,EAAA;AACvD,EAAA,IAAI,MAAS,GAAA,KAAA,CAAM,KAAM,CAAA,IAAI,EAAE,CAAC,CAAA,CAAE,KAAM,CAAA,CAAC,CAAE,CAAA,OAAA,CAAQ,aAAe,EAAA,EAAE,EAAE,IAAK,EAAA,CAAA;AAE3E,EAAI,IAAA,MAAA,CAAO,UAAW,CAAA,GAAG,CAAG,EAAA;AAC1B,IAAS,MAAA,GAAA,MAAA,CAAO,MAAM,CAAC,CAAA,CAAA;AAAA,GACzB;AAEA,EAAI,IAAA,MAAA,CAAO,QAAS,CAAA,GAAG,CAAG,EAAA;AACxB,IAAS,MAAA,GAAA,MAAA,CAAO,KAAM,CAAA,CAAA,EAAG,CAAE,CAAA,CAAA,CAAA;AAAA,GAC7B;AAEA,EAAA,IAAI,CAAC,MAAA,CAAO,UAAW,CAAA,SAAS,CAAG,EAAA;AACjC,IAAA,MAAA,GAAS,SAAY,GAAA,MAAA,CAAA;AAAA,GACvB;AAEA,EAAS,MAAA,GAAA,IAAI,IAAI,MAAM,CAAA,CAAE,SAAS,KAAM,CAAA,GAAG,EAAE,CAAC,CAAA,CAAA;AAE9C,EAAI,IAAA,MAAA,CAAO,QAAS,CAAA,KAAK,CAAG,EAAA;AAC1B,IAAA,MAAA,GAAS,MAAO,CAAA,KAAA,CAAM,CAAG,EAAA,CAAA,CAAE,CAAI,GAAA,KAAA,CAAA;AAAA,GACjC;AACA,EAAO,OAAA,MAAA,CAAA;AACT,CAAA;AAEA,SAAS,gBAAgB,GAA2B,EAAA;AAElD,EAAO,OAAA,CAAC,CAAC,GAAI,CAAA,SAAA,IAAa,CAAC,CAAC,GAAA,CAAI,UAAU,WAAY,CAAA,IAAA,CAAA;AACxD,CAAA;AAEA,SAAS,WAAW,uBAAyD,EAAA;AAC3E,EAAA,OAAO,gBAAgB,uBAAuB,CAAA,GAC1C,MAAM,IAAI,yBACV,GAAA,uBAAA,CAAA;AACN,CAAA;AAEA,SAAS,mBACP,uBACQ,EAAA;AACR,EAAA,OAAO,eAAgB,CAAA,uBAAuB,CAC1C,GAAA,uBAAA,CAAwB,UAAU,WAAY,CAAA,IAAA,GAC9C,MAAO,CAAA,uBAAuB,CAAE,CAAA,KAAA,CAAM,cAAc,CAAA,GAAI,CAAC,CAAK,IAAA,EAAA,CAAA;AACpE,CAAA;AAEA,eAAe,oBAAoB,QAA0C,EAAA;AAC3E,EAAI,IAAA;AACF,IAAM,MAAA,OAAA,GAAU,MAAMA,WAAG,CAAA,QAAA,CAAS,UAAU,EAAE,QAAA,EAAU,QAAQ,CAAA,CAAA;AAChE,IAAA,MAAM,WAAW,OAAQ,CAAA,KAAA,CAAM,IAAI,CAAA,CAAE,GAAG,CAAC,CAAA,CAAA;AAEzC,IAAA,OAAO,QAAU,EAAA,KAAA,CAAM,OAAO,CAAA,CAAE,CAAC,CAAK,IAAA,IAAA,CAAA;AAAA,WAC/B,CAAG,EAAA;AACV,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AACF;;ACnOO,SAAS,IAA8B,EAAsB,EAAA;AAClE,EAAO,OAAA,gBAAA,CAAiB,IAAI,EAAS,CAAA,CAAA;AACvC;;;;;"}
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
- import glob from 'glob';
2
1
  import crypto from 'node:crypto';
2
+ import { globSync } from 'node:fs';
3
3
  import fs from 'node:fs/promises';
4
4
  import path from 'node:path';
5
5
  import { logger, captureStackTrace } from '@andrew_l/toolkit';
6
6
 
7
7
  const storage = /* @__PURE__ */ new Map();
8
- const log = logger(import.meta, "IOC");
8
+ const log = logger("IOC");
9
9
  const ServiceContainer = {
10
10
  get(id) {
11
11
  const service = storage.get(id);
@@ -24,9 +24,7 @@ const ServiceContainer = {
24
24
  }
25
25
  let constructorPath;
26
26
  try {
27
- constructorPath = new URL(
28
- captureStackTrace(this.set).split("\n")[0].slice(7)
29
- ).pathname.split(":")[0];
27
+ constructorPath = extractFilePathFromStack(captureStackTrace(this.set));
30
28
  } catch (_) {
31
29
  }
32
30
  this.override(id, factoryOrClassReference, buildInstantly, constructorPath);
@@ -72,7 +70,7 @@ const ServiceContainer = {
72
70
  },
73
71
  async importServices(autoImportPatterns) {
74
72
  for (const pattern of autoImportPatterns) {
75
- for (const filePath of glob.sync(pattern)) {
73
+ for (const filePath of globSync(pattern)) {
76
74
  await import(filePath);
77
75
  }
78
76
  }
@@ -84,8 +82,7 @@ const ServiceContainer = {
84
82
  key,
85
83
  { constructorName, constructorPath }
86
84
  ] of storage.entries()) {
87
- if (!constructorName) continue;
88
- if (!constructorPath) continue;
85
+ if (!constructorName || !constructorPath) continue;
89
86
  typesDefinitions.push(
90
87
  `"${key}": import('./${path.relative(
91
88
  outputFolderPath,
@@ -120,6 +117,23 @@ ${typesContent}
120
117
  }
121
118
  }
122
119
  };
120
+ function extractFilePathFromStack(stack) {
121
+ let result = stack.split("\n")[0].slice(7).replace("<anonymous>", "").trim();
122
+ if (result.startsWith("(")) {
123
+ result = result.slice(1);
124
+ }
125
+ if (result.endsWith(")")) {
126
+ result = result.slice(0, -1);
127
+ }
128
+ if (!result.startsWith("file://")) {
129
+ result = "file://" + result;
130
+ }
131
+ result = new URL(result).pathname.split(":")[0];
132
+ if (result.endsWith(".ts")) {
133
+ result = result.slice(0, -3) + ".js";
134
+ }
135
+ return result;
136
+ }
123
137
  function isConstructable(obj) {
124
138
  return !!obj.prototype && !!obj.prototype.constructor.name;
125
139
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/ServiceContainer.ts","../src/ioc.ts"],"sourcesContent":["import glob from 'glob';\n\nimport crypto from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { type AnyFunction, captureStackTrace, logger } from '@andrew_l/toolkit';\n\nexport type Factory = any;\n\nexport type Service = {\n factory?: Factory;\n constructorName?: string;\n constructorPath?: string;\n instance: any;\n};\n\nexport interface SetupOptions {\n pathRoot?: string;\n\n /**\n * Absolute or relative path where generated type file will be saved\n */\n typeOutput?: string;\n\n /**\n * Absolute or relative glob patterns to auto-import service files\n */\n autoImportPatterns?: string[];\n\n /**\n * Should generate type file\n */\n generateTypes?: boolean;\n}\n\nconst storage = new Map<string, Service>();\n\nconst log = logger(import.meta, 'IOC');\n\nexport default {\n get<T>(id: string): T {\n const service = storage.get(id);\n\n if (!service) {\n throw new Error(`No service is registered for [${id}]`);\n }\n\n if (!service.instance) {\n service.instance = service.factory?.();\n service.factory = undefined;\n }\n\n return service.instance;\n },\n\n set(\n id: string,\n factoryOrClassReference: Factory | AnyFunction,\n buildInstantly: boolean = false,\n ) {\n if (this.isSet(id)) {\n throw new Error(`Service [${id}] is already registered`);\n }\n\n let constructorPath: string | undefined;\n\n try {\n constructorPath = new URL(\n captureStackTrace(this.set).split('\\n')[0].slice(7),\n ).pathname.split(':')[0];\n } catch (_) {}\n\n this.override(id, factoryOrClassReference, buildInstantly, constructorPath);\n },\n\n override(\n id: string,\n factoryOrClassReference: Factory | AnyFunction,\n buildInstantly: boolean = false,\n constructorPath?: string,\n ) {\n const factory: Factory = getFactory(factoryOrClassReference);\n\n storage.set(id, {\n factory: buildInstantly ? undefined : factory,\n instance: buildInstantly ? factory() : undefined,\n constructorName: getConstructorName(factoryOrClassReference),\n constructorPath,\n });\n },\n\n isSet(id: string): boolean {\n return storage.has(id);\n },\n\n clear() {\n storage.clear();\n },\n\n async setup({\n pathRoot = process.cwd(),\n generateTypes = false,\n autoImportPatterns = ['./services/*/**/*.service.{js,mjs,ts,mts,cts}'],\n typeOutput = './ioc.d.ts',\n }: SetupOptions | undefined = {}) {\n typeOutput = path.isAbsolute(typeOutput)\n ? typeOutput\n : path.join(pathRoot, typeOutput);\n\n if (!typeOutput.endsWith('.d.ts')) {\n typeOutput = path.join(typeOutput, 'ioc.d.ts');\n }\n\n autoImportPatterns = autoImportPatterns.map(servicePath => {\n return path.isAbsolute(servicePath)\n ? servicePath\n : path.join(pathRoot, servicePath);\n });\n\n log.debug('Setup', {\n pathRoot,\n generateTypes,\n autoImportPatterns,\n typeOutput,\n });\n\n await this.importServices(autoImportPatterns);\n\n if (generateTypes) {\n await this.writeTypes(typeOutput);\n }\n },\n\n async importServices(autoImportPatterns: string[]) {\n for (const pattern of autoImportPatterns) {\n for (const filePath of glob.sync(pattern)) {\n await import(filePath);\n }\n }\n },\n\n async writeTypes(outputFilePath: string) {\n const typesDefinitions: string[] = [];\n const outputFolderPath = path.dirname(outputFilePath);\n\n for (const [\n key,\n { constructorName, constructorPath },\n ] of storage.entries()) {\n if (!constructorName) continue;\n if (!constructorPath) continue;\n\n typesDefinitions.push(\n `\"${key}\": import('./${path.relative(\n outputFolderPath,\n constructorPath,\n )}').${constructorName};`,\n );\n }\n\n const typesContent = `/* eslint-disable */\n/* prettier-ignore */\n// @ts-nocheck\n// Generated by @andrew_l/ioc\n\nexport {};\n\ndeclare module '@andrew_l/ioc' {\n\tinterface IocMap {\n\t\t${typesDefinitions.sort().join('\\n\\t\\t')}\n\t}\n\n\tfunction ioc<Key extends keyof IocMap>(id: Key): IocMap[Key];\n}`;\n\n const newHash = crypto\n .createHmac('sha256', '')\n .update(typesContent)\n .digest('hex');\n\n const oldHash = await getHashFromTypeFile(outputFilePath);\n\n if (newHash !== oldHash) {\n log.warn('Types file has been updated.');\n\n await fs.writeFile(\n outputFilePath,\n `// hash:${newHash}\\n${typesContent}\\n`,\n );\n }\n },\n};\n\nfunction isConstructable(obj: any): obj is Function {\n // https://stackoverflow.com/a/46320004\n return !!obj.prototype && !!obj.prototype.constructor.name;\n}\n\nfunction getFactory(factoryOrClassReference: Factory | AnyFunction): Factory {\n return isConstructable(factoryOrClassReference)\n ? () => new factoryOrClassReference()\n : factoryOrClassReference;\n}\n\nfunction getConstructorName(\n factoryOrClassReference: Factory | AnyFunction,\n): string {\n return isConstructable(factoryOrClassReference)\n ? factoryOrClassReference.prototype.constructor.name\n : String(factoryOrClassReference).match(/new\\s(\\w+)\\(/)?.[1] || '';\n}\n\nasync function getHashFromTypeFile(filePath: string): Promise<string | null> {\n try {\n const content = await fs.readFile(filePath, { encoding: 'utf8' });\n const lastLine = content.split('\\n').at(0);\n\n return lastLine?.split('hash:')[1] || null;\n } catch (_) {\n return null;\n }\n}\n","import ServiceContainer from './ServiceContainer';\n\n/**\n * This interface can be augmented by users to add types to ioc\n */\ninterface IocMap {}\n\n/**\n * Get instance of service\n * @example\n * const userService ioc('UserService');\n *\n * @group Main\n */\nexport function ioc<Key extends keyof IocMap>(id: Key): IocMap[Key] {\n return ServiceContainer.get(id as any) as any;\n}\nexport type { IocMap };\n"],"names":[],"mappings":";;;;;;AAoCA,MAAM,OAAA,uBAAc,GAAqB,EAAA,CAAA;AAEzC,MAAM,GAAA,GAAM,MAAO,CAAA,MAAA,CAAA,IAAA,EAAa,KAAK,CAAA,CAAA;AAErC,yBAAe;AAAA,EACb,IAAO,EAAe,EAAA;AACpB,IAAM,MAAA,OAAA,GAAU,OAAQ,CAAA,GAAA,CAAI,EAAE,CAAA,CAAA;AAE9B,IAAA,IAAI,CAAC,OAAS,EAAA;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,CAAiC,8BAAA,EAAA,EAAE,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,KACxD;AAEA,IAAI,IAAA,CAAC,QAAQ,QAAU,EAAA;AACrB,MAAQ,OAAA,CAAA,QAAA,GAAW,QAAQ,OAAU,IAAA,CAAA;AACrC,MAAA,OAAA,CAAQ,OAAU,GAAA,KAAA,CAAA,CAAA;AAAA,KACpB;AAEA,IAAA,OAAO,OAAQ,CAAA,QAAA,CAAA;AAAA,GACjB;AAAA,EAEA,GACE,CAAA,EAAA,EACA,uBACA,EAAA,cAAA,GAA0B,KAC1B,EAAA;AACA,IAAI,IAAA,IAAA,CAAK,KAAM,CAAA,EAAE,CAAG,EAAA;AAClB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAY,SAAA,EAAA,EAAE,CAAyB,uBAAA,CAAA,CAAA,CAAA;AAAA,KACzD;AAEA,IAAI,IAAA,eAAA,CAAA;AAEJ,IAAI,IAAA;AACF,MAAA,eAAA,GAAkB,IAAI,GAAA;AAAA,QACpB,iBAAA,CAAkB,IAAK,CAAA,GAAG,CAAE,CAAA,KAAA,CAAM,IAAI,CAAE,CAAA,CAAC,CAAE,CAAA,KAAA,CAAM,CAAC,CAAA;AAAA,OAClD,CAAA,QAAA,CAAS,KAAM,CAAA,GAAG,EAAE,CAAC,CAAA,CAAA;AAAA,aAChB,CAAG,EAAA;AAAA,KAAC;AAEb,IAAA,IAAA,CAAK,QAAS,CAAA,EAAA,EAAI,uBAAyB,EAAA,cAAA,EAAgB,eAAe,CAAA,CAAA;AAAA,GAC5E;AAAA,EAEA,QACE,CAAA,EAAA,EACA,uBACA,EAAA,cAAA,GAA0B,OAC1B,eACA,EAAA;AACA,IAAM,MAAA,OAAA,GAAmB,WAAW,uBAAuB,CAAA,CAAA;AAE3D,IAAA,OAAA,CAAQ,IAAI,EAAI,EAAA;AAAA,MACd,OAAA,EAAS,iBAAiB,KAAY,CAAA,GAAA,OAAA;AAAA,MACtC,QAAA,EAAU,cAAiB,GAAA,OAAA,EAAY,GAAA,KAAA,CAAA;AAAA,MACvC,eAAA,EAAiB,mBAAmB,uBAAuB,CAAA;AAAA,MAC3D,eAAA;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AAAA,EAEA,MAAM,EAAqB,EAAA;AACzB,IAAO,OAAA,OAAA,CAAQ,IAAI,EAAE,CAAA,CAAA;AAAA,GACvB;AAAA,EAEA,KAAQ,GAAA;AACN,IAAA,OAAA,CAAQ,KAAM,EAAA,CAAA;AAAA,GAChB;AAAA,EAEA,MAAM,KAAM,CAAA;AAAA,IACV,QAAA,GAAW,QAAQ,GAAI,EAAA;AAAA,IACvB,aAAgB,GAAA,KAAA;AAAA,IAChB,kBAAA,GAAqB,CAAC,+CAA+C,CAAA;AAAA,IACrE,UAAa,GAAA,YAAA;AAAA,GACf,GAA8B,EAAI,EAAA;AAChC,IAAa,UAAA,GAAA,IAAA,CAAK,WAAW,UAAU,CAAA,GACnC,aACA,IAAK,CAAA,IAAA,CAAK,UAAU,UAAU,CAAA,CAAA;AAElC,IAAA,IAAI,CAAC,UAAA,CAAW,QAAS,CAAA,OAAO,CAAG,EAAA;AACjC,MAAa,UAAA,GAAA,IAAA,CAAK,IAAK,CAAA,UAAA,EAAY,UAAU,CAAA,CAAA;AAAA,KAC/C;AAEA,IAAqB,kBAAA,GAAA,kBAAA,CAAmB,IAAI,CAAe,WAAA,KAAA;AACzD,MAAO,OAAA,IAAA,CAAK,WAAW,WAAW,CAAA,GAC9B,cACA,IAAK,CAAA,IAAA,CAAK,UAAU,WAAW,CAAA,CAAA;AAAA,KACpC,CAAA,CAAA;AAED,IAAA,GAAA,CAAI,MAAM,OAAS,EAAA;AAAA,MACjB,QAAA;AAAA,MACA,aAAA;AAAA,MACA,kBAAA;AAAA,MACA,UAAA;AAAA,KACD,CAAA,CAAA;AAED,IAAM,MAAA,IAAA,CAAK,eAAe,kBAAkB,CAAA,CAAA;AAE5C,IAAA,IAAI,aAAe,EAAA;AACjB,MAAM,MAAA,IAAA,CAAK,WAAW,UAAU,CAAA,CAAA;AAAA,KAClC;AAAA,GACF;AAAA,EAEA,MAAM,eAAe,kBAA8B,EAAA;AACjD,IAAA,KAAA,MAAW,WAAW,kBAAoB,EAAA;AACxC,MAAA,KAAA,MAAW,QAAY,IAAA,IAAA,CAAK,IAAK,CAAA,OAAO,CAAG,EAAA;AACzC,QAAA,MAAM,OAAO,QAAA,CAAA,CAAA;AAAA,OACf;AAAA,KACF;AAAA,GACF;AAAA,EAEA,MAAM,WAAW,cAAwB,EAAA;AACvC,IAAA,MAAM,mBAA6B,EAAC,CAAA;AACpC,IAAM,MAAA,gBAAA,GAAmB,IAAK,CAAA,OAAA,CAAQ,cAAc,CAAA,CAAA;AAEpD,IAAW,KAAA,MAAA;AAAA,MACT,GAAA;AAAA,MACA,EAAE,iBAAiB,eAAgB,EAAA;AAAA,KACrC,IAAK,OAAQ,CAAA,OAAA,EAAW,EAAA;AACtB,MAAA,IAAI,CAAC,eAAiB,EAAA,SAAA;AACtB,MAAA,IAAI,CAAC,eAAiB,EAAA,SAAA;AAEtB,MAAiB,gBAAA,CAAA,IAAA;AAAA,QACf,CAAA,CAAA,EAAI,GAAG,CAAA,aAAA,EAAgB,IAAK,CAAA,QAAA;AAAA,UAC1B,gBAAA;AAAA,UACA,eAAA;AAAA,SACD,MAAM,eAAe,CAAA,CAAA,CAAA;AAAA,OACxB,CAAA;AAAA,KACF;AAEA,IAAA,MAAM,YAAe,GAAA,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,EASrB,gBAAiB,CAAA,IAAA,EAAO,CAAA,IAAA,CAAK,MAAQ,CAAC,CAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA,CAAA;AAMtC,IAAM,MAAA,OAAA,GAAU,MACb,CAAA,UAAA,CAAW,QAAU,EAAA,EAAE,EACvB,MAAO,CAAA,YAAY,CACnB,CAAA,MAAA,CAAO,KAAK,CAAA,CAAA;AAEf,IAAM,MAAA,OAAA,GAAU,MAAM,mBAAA,CAAoB,cAAc,CAAA,CAAA;AAExD,IAAA,IAAI,YAAY,OAAS,EAAA;AACvB,MAAA,GAAA,CAAI,KAAK,8BAA8B,CAAA,CAAA;AAEvC,MAAA,MAAM,EAAG,CAAA,SAAA;AAAA,QACP,cAAA;AAAA,QACA,WAAW,OAAO,CAAA;AAAA,EAAK,YAAY,CAAA;AAAA,CAAA;AAAA,OACrC,CAAA;AAAA,KACF;AAAA,GACF;AACF,CAAA,CAAA;AAEA,SAAS,gBAAgB,GAA2B,EAAA;AAElD,EAAO,OAAA,CAAC,CAAC,GAAI,CAAA,SAAA,IAAa,CAAC,CAAC,GAAA,CAAI,UAAU,WAAY,CAAA,IAAA,CAAA;AACxD,CAAA;AAEA,SAAS,WAAW,uBAAyD,EAAA;AAC3E,EAAA,OAAO,gBAAgB,uBAAuB,CAAA,GAC1C,MAAM,IAAI,yBACV,GAAA,uBAAA,CAAA;AACN,CAAA;AAEA,SAAS,mBACP,uBACQ,EAAA;AACR,EAAA,OAAO,eAAgB,CAAA,uBAAuB,CAC1C,GAAA,uBAAA,CAAwB,UAAU,WAAY,CAAA,IAAA,GAC9C,MAAO,CAAA,uBAAuB,CAAE,CAAA,KAAA,CAAM,cAAc,CAAA,GAAI,CAAC,CAAK,IAAA,EAAA,CAAA;AACpE,CAAA;AAEA,eAAe,oBAAoB,QAA0C,EAAA;AAC3E,EAAI,IAAA;AACF,IAAM,MAAA,OAAA,GAAU,MAAM,EAAG,CAAA,QAAA,CAAS,UAAU,EAAE,QAAA,EAAU,QAAQ,CAAA,CAAA;AAChE,IAAA,MAAM,WAAW,OAAQ,CAAA,KAAA,CAAM,IAAI,CAAA,CAAE,GAAG,CAAC,CAAA,CAAA;AAEzC,IAAA,OAAO,QAAU,EAAA,KAAA,CAAM,OAAO,CAAA,CAAE,CAAC,CAAK,IAAA,IAAA,CAAA;AAAA,WAC/B,CAAG,EAAA;AACV,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AACF;;AChNO,SAAS,IAA8B,EAAsB,EAAA;AAClE,EAAO,OAAA,gBAAA,CAAiB,IAAI,EAAS,CAAA,CAAA;AACvC;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/ServiceContainer.ts","../src/ioc.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport { globSync } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { type AnyFunction, captureStackTrace, logger } from '@andrew_l/toolkit';\n\nexport type Factory = any;\n\nexport type Service = {\n factory?: Factory;\n constructorName?: string;\n constructorPath?: string;\n instance: any;\n};\n\nexport interface SetupOptions {\n pathRoot?: string;\n\n /**\n * Absolute or relative path where generated type file will be saved\n */\n typeOutput?: string;\n\n /**\n * Absolute or relative glob patterns to auto-import service files\n */\n autoImportPatterns?: string[];\n\n /**\n * Should generate type file\n */\n generateTypes?: boolean;\n}\n\nconst storage = new Map<string, Service>();\n\nconst log = logger('IOC');\n\nexport default {\n get<T>(id: string): T {\n const service = storage.get(id);\n\n if (!service) {\n throw new Error(`No service is registered for [${id}]`);\n }\n\n if (!service.instance) {\n service.instance = service.factory?.();\n service.factory = undefined;\n }\n\n return service.instance;\n },\n\n set(\n id: string,\n factoryOrClassReference: Factory | AnyFunction,\n buildInstantly: boolean = false,\n ) {\n if (this.isSet(id)) {\n throw new Error(`Service [${id}] is already registered`);\n }\n\n let constructorPath: string | undefined;\n\n try {\n constructorPath = extractFilePathFromStack(captureStackTrace(this.set));\n } catch (_) {}\n\n this.override(id, factoryOrClassReference, buildInstantly, constructorPath);\n },\n\n override(\n id: string,\n factoryOrClassReference: Factory | AnyFunction,\n buildInstantly: boolean = false,\n constructorPath?: string,\n ) {\n const factory: Factory = getFactory(factoryOrClassReference);\n\n storage.set(id, {\n factory: buildInstantly ? undefined : factory,\n instance: buildInstantly ? factory() : undefined,\n constructorName: getConstructorName(factoryOrClassReference),\n constructorPath,\n });\n },\n\n isSet(id: string): boolean {\n return storage.has(id);\n },\n\n clear() {\n storage.clear();\n },\n\n async setup({\n pathRoot = process.cwd(),\n generateTypes = false,\n autoImportPatterns = ['./services/*/**/*.service.{js,mjs,ts,mts,cts}'],\n typeOutput = './ioc.d.ts',\n }: SetupOptions | undefined = {}) {\n typeOutput = path.isAbsolute(typeOutput)\n ? typeOutput\n : path.join(pathRoot, typeOutput);\n\n if (!typeOutput.endsWith('.d.ts')) {\n typeOutput = path.join(typeOutput, 'ioc.d.ts');\n }\n\n autoImportPatterns = autoImportPatterns.map(servicePath => {\n return path.isAbsolute(servicePath)\n ? servicePath\n : path.join(pathRoot, servicePath);\n });\n\n log.debug('Setup', {\n pathRoot,\n generateTypes,\n autoImportPatterns,\n typeOutput,\n });\n\n await this.importServices(autoImportPatterns);\n\n if (generateTypes) {\n await this.writeTypes(typeOutput);\n }\n },\n\n async importServices(autoImportPatterns: string[]) {\n for (const pattern of autoImportPatterns) {\n for (const filePath of globSync(pattern)) {\n await import(filePath);\n }\n }\n },\n\n async writeTypes(outputFilePath: string) {\n const typesDefinitions: string[] = [];\n const outputFolderPath = path.dirname(outputFilePath);\n\n for (const [\n key,\n { constructorName, constructorPath },\n ] of storage.entries()) {\n if (!constructorName || !constructorPath) continue;\n\n typesDefinitions.push(\n `\"${key}\": import('./${path.relative(\n outputFolderPath,\n constructorPath,\n )}').${constructorName};`,\n );\n }\n\n const typesContent = `/* eslint-disable */\n/* prettier-ignore */\n// @ts-nocheck\n// Generated by @andrew_l/ioc\n\nexport {};\n\ndeclare module '@andrew_l/ioc' {\n\tinterface IocMap {\n\t\t${typesDefinitions.sort().join('\\n\\t\\t')}\n\t}\n\n\tfunction ioc<Key extends keyof IocMap>(id: Key): IocMap[Key];\n}`;\n\n const newHash = crypto\n .createHmac('sha256', '')\n .update(typesContent)\n .digest('hex');\n\n const oldHash = await getHashFromTypeFile(outputFilePath);\n\n if (newHash !== oldHash) {\n log.warn('Types file has been updated.');\n\n await fs.writeFile(\n outputFilePath,\n `// hash:${newHash}\\n${typesContent}\\n`,\n );\n }\n },\n};\n\nfunction extractFilePathFromStack(stack: string): string {\n let result = stack.split('\\n')[0].slice(7).replace('<anonymous>', '').trim();\n\n if (result.startsWith('(')) {\n result = result.slice(1);\n }\n\n if (result.endsWith(')')) {\n result = result.slice(0, -1);\n }\n\n if (!result.startsWith('file://')) {\n result = 'file://' + result;\n }\n\n result = new URL(result).pathname.split(':')[0];\n\n if (result.endsWith('.ts')) {\n result = result.slice(0, -3) + '.js';\n }\n return result;\n}\n\nfunction isConstructable(obj: any): obj is Function {\n // https://stackoverflow.com/a/46320004\n return !!obj.prototype && !!obj.prototype.constructor.name;\n}\n\nfunction getFactory(factoryOrClassReference: Factory | AnyFunction): Factory {\n return isConstructable(factoryOrClassReference)\n ? () => new factoryOrClassReference()\n : factoryOrClassReference;\n}\n\nfunction getConstructorName(\n factoryOrClassReference: Factory | AnyFunction,\n): string {\n return isConstructable(factoryOrClassReference)\n ? factoryOrClassReference.prototype.constructor.name\n : String(factoryOrClassReference).match(/new\\s(\\w+)\\(/)?.[1] || '';\n}\n\nasync function getHashFromTypeFile(filePath: string): Promise<string | null> {\n try {\n const content = await fs.readFile(filePath, { encoding: 'utf8' });\n const lastLine = content.split('\\n').at(0);\n\n return lastLine?.split('hash:')[1] || null;\n } catch (_) {\n return null;\n }\n}\n","import ServiceContainer from './ServiceContainer';\n\n/**\n * This interface can be augmented by users to add types to ioc\n */\ninterface IocMap {}\n\n/**\n * Get instance of service\n * @example\n * const userService ioc('UserService');\n *\n * @group Main\n */\nexport function ioc<Key extends keyof IocMap>(id: Key): IocMap[Key] {\n return ServiceContainer.get(id as any) as any;\n}\nexport type { IocMap };\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andrew_l/ioc",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -27,15 +27,13 @@
27
27
  "dist"
28
28
  ],
29
29
  "devDependencies": {
30
- "@types/glob": "^8.1.0",
31
- "@types/node": "^20.16.10",
30
+ "@types/node": "22.10.5",
32
31
  "typescript": "~5.6.2",
33
32
  "unbuild": "3.0.0-rc.11",
34
33
  "vitest": "^2.1.3"
35
34
  },
36
35
  "dependencies": {
37
- "glob": "^11.0.0",
38
- "@andrew_l/toolkit": "0.2.5"
36
+ "@andrew_l/toolkit": "0.2.7"
39
37
  },
40
38
  "scripts": {
41
39
  "build": "unbuild",