UNPKG

lakutata

Version:

An IoC-based universal application framework.

371 lines (305 loc) 9.42 kB
import * as e from "util"; import { DependencyInjectionRegistrationError as t, DependencyInjectionResolutionError as r, DependencyInjectionTypeError as o } from "./Errors.mjs"; import { InjectionMode as n } from "./InjectionMode.mjs"; import { Lifetime as s, isLifetimeLonger as i } from "./Lifetime.mjs"; import { listModules as c } from "./ListModules.mjs"; import { loadModules as a } from "./LoadModules.mjs"; import { asClass as m, asFunction as p } from "./Resolvers.mjs"; import { last as l, nameValueToObject as u, isClass as f } from "./Utils.mjs"; import { GetObjectLifetime as d } from "../base/internal/ObjectLifetime.mjs"; import { As as j } from "../helpers/As.mjs"; import { AppendObjectWeakRefs as g } from "../base/internal/ObjectWeakRefs.mjs"; import "../../exceptions/di/DependencyInjectionException.mjs"; import "../base/abstracts/Exception.mjs"; import "../base/internal/BasicInfo.mjs"; import "../../../vendor/Package.6.mjs"; import "../../../vendor/Package.5.mjs"; import "../../../vendor/Package.7.mjs"; import "../base/internal/ThrowWarning.mjs"; import "../helpers/Templating.mjs"; import "../base/internal/CamelCase.mjs"; import "../helpers/NoCase.mjs"; import "../base/internal/ConstructorSymbol.mjs"; import "../../constants/DIMetadataKey.mjs"; import "../../../vendor/Package.4.mjs"; import "node:crypto"; import "../../../vendor/Package.2.mjs"; import "../../../vendor/Package.1.mjs"; import "../base/internal/DataValidator.mjs"; import "node:util/types"; import "../validation/VLD.mjs"; import "../../../vendor/Package.11.mjs"; import "url"; import "../../../vendor/Package.10.mjs"; import "../../exceptions/dto/InvalidValueException.mjs"; import "../../../vendor/Package.9.mjs"; import "../helpers/IsHtml.mjs"; import "../helpers/IsXML.mjs"; import "../../constants/DTOMetadataKey.mjs"; import "../helpers/ObjectConstructor.mjs"; import "../helpers/ObjectParentConstructors.mjs"; import "../helpers/ObjectParentConstructor.mjs"; import "../helpers/ObjectPrototype.mjs"; import "../../../vendor/Package.8.mjs"; import "os"; import "path"; import "stream"; import "events"; import "fs"; import "./ParamParser.mjs"; import "./FunctionTokenizer.mjs"; import "../../exceptions/di/LifetimeLockedException.mjs"; // -- Shims -- import cjsUrl from 'node:url'; import cjsPath from 'node:path'; import cjsModule from 'node:module'; const __filename = cjsUrl.fileURLToPath(import.meta.url); const __dirname = cjsPath.dirname(__filename); const require = cjsModule.createRequire(import.meta.url); function h(e) { return import(e); } const b = Symbol("familyTree"); const v = Symbol("rollUpRegistrations"); const y = "DependencyInjectionContainerCradle"; function w(e = {}) { return P(e); } function P(O, k, S) { O = { injectionMode: n.PROXY, strict: false, ...O }; const I = S ?? []; const N = {}; const T = new Proxy({ [e.inspect.custom]: $ }, { get: (e, t) => q(t), set: (e, t) => { throw new Error(`Attempted setting property "${t}" on container cradle - this is not allowed.`); }, ownKeys() { return Array.from(T); }, getOwnPropertyDescriptor(e, t) { const r = M(); if (Object.getOwnPropertyDescriptor(r, t)) { return { enumerable: true, configurable: true }; } return undefined; } }); const E = { options: O, cradle: T, inspect: D, cache: new Map, loadModules: V, createScope: x, register: A, build: K, resolve: q, hasRegistration: G, dispose: W, getRegistration: U, [e.inspect.custom]: D, [v]: M, get registrations() { return M(); } }; const L = k ? [ E ].concat(j(k)[b]) : [ E ]; E[b] = L; const C = l(L); return E; function D() { return `[DependencyInjectionContainer (${k ? "scoped, " : ""}registrations: ${Object.keys(E.registrations).length})]`; } function M() { return { ...k && k[v](), ...N }; } function* R() { const e = M(); for (const t in e) { yield t; } } function x() { return P(O, E, I); } function A(e, r) { const o = u(e, r); const n = [ ...Object.keys(o), ...Object.getOwnPropertySymbols(o) ]; for (const e of n) { const r = o[e]; if (O.strict && r.lifetime === s.SINGLETON) { if (k) { throw new t(e, "Cannot register a singleton on a scoped container."); } } N[e] = r; } return E; } function $() { return Object.prototype.toString.call(T); } function U(e) { const t = N[e]; if (t) { return t; } if (k) { return k.getRegistration(e); } return null; } function q(t, o) { o = o || {}; try { const n = U(t); if (I.some((({name: e}) => e === t))) { throw new r(t, I, "Cyclic dependencies detected."); } if (t === "toJSON") { return $; } if (t === "constructor") { return w; } if (!n) { switch (t) { case e.inspect.custom: case "inspect": case "toString": return $; case Symbol.toStringTag: return y; case "then": return undefined; case Symbol.iterator: return R; } if (o.allowUnregistered) { return undefined; } throw new r(t, I); } const c = n.lifetime || s.TRANSIENT; if (O.strict && !n.isLeakSafe) { const e = I.findIndex((({lifetime: e}) => i(e, c))); if (e > -1) { throw new r(t, I, `Dependency '${t.toString()}' has a shorter lifetime than its ancestor: '${I[e].name.toString()}'`); } } I.push({ name: t, lifetime: c }); let a; let m; switch (c) { case s.TRANSIENT: m = n.resolve(E); break; case s.APPLICATION_SINGLETON: a = C.cache.get(t); if (!a) { m = n.resolve(O.strict ? C : E); C.cache.set(t, { resolver: n, value: m }); } else { m = a.value; } break; case s.MODULE_SINGLETON: case s.SINGLETON: a = E.cache.get(t); if (a !== undefined) { m = a.value; break; } m = n.resolve(E); E.cache.set(t, { resolver: n, value: m }); break; case s.SCOPED: a = E.cache.get(t); if (a !== undefined) { m = a.value; break; } m = n.resolve(E); E.cache.set(t, { resolver: n, value: m }); break; default: throw new r(t, I, `Unknown lifetime "${n.lifetime}"`); } I.pop(); if (d(m.constructor) === s.TRANSIENT) g(this, m); return m; } catch (e) { I.length = 0; throw e; } } function G(e) { return !!U(e); } function K(e, t) { if (e && e.resolve) { return e.resolve(E); } const r = "build"; const n = "targetOrResolver"; o.assert(e, r, n, "a registration, function or class", e); o.assert(typeof e === "function", r, n, "a function or class", e); const s = f(e) ? m(e, t) : p(e, t); return s.resolve(E); } function V(e, t) { const r = { require: O.require || function(e) { return require(e); }, listModules: c, container: E }; if (t?.esModules) { r.require = h; return a(r, e, t).then((() => E)); } else { a(r, e, t); return E; } } async function W() { const e = Array.from(E.cache.entries()); E.cache.clear(); return Promise.all(e.map((async ([, e]) => { const {resolver: t, value: r} = e; const o = t; if (o.dispose) { await Promise.resolve(); return o.dispose(r); } return Promise.resolve(); }))).then((() => undefined)); } } export { w as createContainer };