@teqfw/di 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/RELEASE.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @teqfw/di releases
2
2
 
3
+ ## 0.33.0 – Cleanup and Enhancements
4
+
5
+ - Removed deprecated documentation.
6
+ - Updated ESLint rules for consistency with current platform practices.
7
+ - Introduced `#` as a separator (in addition to `.`) between namespace and export names.
8
+
9
+ ## 0.32.0 - added support for the `node:` prefix
10
+
11
+ - **Added ability** to manually register objects in the container (`register`).
12
+ - **Optimized dependency parsing**, added support for the `node:` prefix.
13
+ - **Updated singleton handling**, fixed issues with `Defs.LS`.
14
+ - **Added protection against object modification**, freezing objects when possible (`Object.freeze`).
15
+ - **Updated dependencies** (Mocha, Rollup, Rollup plugins).
16
+
3
17
  ## 0.31.0
4
18
 
5
19
  * Added optional `stack` parameter to the `get` method for improved dependency tracking and debugging.
@@ -9,5 +9,6 @@ rm -fr "${DIR_ROOT}/doc/"
9
9
  rm -fr "${DIR_ROOT}/docs/"
10
10
  rm -fr "${DIR_ROOT}/example/"
11
11
  rm -fr "${DIR_ROOT}/node_modules/"
12
+ rm -fr "${DIR_ROOT}/package-lock.json"
12
13
  rm -fr "${DIR_ROOT}/test/"
13
14
  rm -fr "${DIR_ROOT}/tmp/"
package/dist/esm.js CHANGED
@@ -1 +1 @@
1
- var e={COMP_A:"A",COMP_F:"F",ID:"container",ID_FQN:"TeqFw_Di_Container$",LIFE_I:"I",LIFE_S:"S",isClass(e){const t=Object.getOwnPropertyDescriptor(e,"prototype");return t&&!t.writable}};const t=/(function)*\s*\w*\s*\(\s*\{([^\}]*)\}/s,o=/constructor\s*\(\s*\{([^\}]*)\}/s;function s(e){const t=[];try{const o=new Function(`{${e}}`,"return");o(new Proxy({},{get:(e,o)=>t.push(o)}))}catch(t){throw new Error(`Cannot analyze the deps specification:${e}\n\nPlease, be sure that spec does not contain extra ')' in a comments.\n\nError: ${t}`)}return t}function n(n){return"function"==typeof n?e.isClass(n)?function(e){const t=[],n=e.toString(),r=o.exec(n);return r&&t.push(...s(r[1])),t}(n):function(e){const o=[],n=e.toString(),r=t.exec(n);return r&&o.push(...s(r[2])),o}(n):[]}class r{constructor(){let t=!1;this.create=async function(o,s,r,i){if(r.includes(o.value))throw new Error(`Circular dependency for '${o.value}'. Parents are: ${JSON.stringify(r)}`);if(o.exportName){const a=[...r,o.value],{[o.exportName]:u}=s;if(o.composition===e.COMP_F){if("function"==typeof u){const s=n(u);s.length&&(c=`Deps for object '${o.value}' are: ${JSON.stringify(s)}`,t&&console.log(c));const r={};for(const e of s)r[e]=await i.compose(e,a);const l=e.isClass(u)?new u(r):u(r);return l instanceof Promise?await l:l}return Object.assign({},u)}return u}return s;var c},this.setDebug=function(e){t=e}}}class i{exportName;composition;life;moduleName;value;wrappers=[]}const c=/^((([A-Z])[A-Za-z0-9_]*)((\.)?([A-Za-z0-9_]*)((\$)?(\$)?)?)?(\(([A-Za-z0-9_,]*)\))?)$/;class a{canParse(e){return!0}parse(t){const o=new i;o.value=t;const s=c.exec(t);if(s&&(o.moduleName=s[2],"."===s[5]?"$"===s[7]||"$$"===s[7]?(o.composition=e.COMP_F,o.exportName=s[6],o.life="$"===s[7]?e.LIFE_S:e.LIFE_I):(o.composition=e.COMP_A,o.life=e.LIFE_S,o.exportName=""!==s[6]?s[6]:"default"):"$"===s[7]||"$$"===s[7]?(o.composition=e.COMP_F,o.exportName="default",o.life="$"===s[7]?e.LIFE_S:e.LIFE_I):(o.composition=void 0,o.exportName=void 0,o.life=void 0),s[11]&&(o.wrappers=s[11].split(","))),o.composition===e.COMP_A&&o.life===e.LIFE_I)throw new Error(`Export is not a function and should be used as a singleton only: '${o.value}'.`);return o}}class u{constructor(){let e=new a;const t=[];this.addChunk=function(e){t.push(e)},this.parse=function(o){let s;for(const e of t)if(e.canParse(o)){s=e.parse(o);break}return s||(s=e?.parse(o)),s},this.setDefaultChunk=function(t){e=t}}}class l{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=function(t,o){let s=t;for(const n of e)s=n.modify(s,t,o);return s}}}class f{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=async function(t,o,s){let n=t;for(const t of e)n=t.modify(n,o,s),n instanceof Promise&&(n=await n);return n}}}const p="root";class m{constructor(){const e={};let t=!1,o=[],s="/";this.addNamespaceRoot=function(s,n,r){const i=(t?n.replace(/^\\/,""):n).replace(/\\/g,"/"),c=t?`file://${i}`:i;e[s]={ext:r??"js",ns:s,[p]:c},o=Object.keys(e).sort(((e,t)=>t.localeCompare(e)))},this.resolve=function(t){let n,r,i;for(i of o)if(t.startsWith(i)){n=e[i][p],r=e[i].ext;break}if(n&&r){let e=t.replace(i,"");0===e.indexOf("_")&&(e=e.replace("_",""));const o=e.replaceAll("_",s);return`${n}${s}${o}.${r}`}return t},this.setWindowsEnv=function(e=!0){t=e,s=e?"\\":"/"}}}function d(e){return`${e.moduleName}#${e.exportName}`}class h{constructor(){let t=new r,o=!1,s=new u,n=new l,i=new f;const c={},a={};let p=new m;function h(){o&&console.log(...arguments)}this.get=async function(e,t=[]){return this.compose(e,t)},this.compose=async function(o,r=[]){if(h(`Object '${o}' is requested.`),o===e.ID||o===e.ID_FQN)return h("Container itself is returned."),a[e.ID];const u=s.parse(o),l=n.modify(u,r);if(l.life===e.LIFE_S){const e=d(l);if(a[e])return h(`Existing singleton '${e}' is returned.`),a[e]}let f;c[l.moduleName]||(h(`ES6 module '${l.moduleName}' is not resolved yet`),c[l.moduleName]=p.resolve(l.moduleName));const m=c[l.moduleName];try{f=await import(m),h(`ES6 module '${l.moduleName}' is loaded from '${m}'.`)}catch(e){throw console.error(e?.message,`Object key: "${o}".`,`Path: "${m}".`,`Stack: ${JSON.stringify(r)}`),e}let $=await t.create(l,f,r,this);if($=await i.modify($,l,r),h(`Object '${o}' is created.`),l.life===e.LIFE_S){const e=d(l);a[e]=$,h(`Object '${o}' is saved as singleton.`)}return $},this.getParser=()=>s,this.getPreProcessor=()=>n,this.getPostProcessor=()=>i,this.getResolver=()=>p,this.setDebug=function(e){o=e,t.setDebug(e)},this.setParser=e=>s=e,this.setPreProcessor=e=>n=e,this.setPostProcessor=e=>i=e,this.setResolver=e=>p=e,a[e.ID]=this}}export{h as default};
1
+ var e={CA:"A",CF:"F",ID:"container",ID_FQN:"TeqFw_Di_Container$",LI:"I",LS:"S",isClass(e){const t=Object.getOwnPropertyDescriptor(e,"prototype");return t&&!t.writable}};const t=/(function)*\s*\w*\s*\(\s*\{([^}]*)}/s,o=/constructor\s*\(\s*\{([^}]*)}/s;function n(e){const t=[];try{const o=new Function(`{${e}}`,"return");o(new Proxy({},{get:(e,o)=>t.push(o)}))}catch(t){throw new Error(`Cannot analyze the deps specification:${e}\n\nPlease, be sure that spec does not contain extra ')' in a comments.\n\nError: ${t}`)}return t}function s(s){return"function"==typeof s?e.isClass(s)?function(e){const t=[],s=e.toString(),r=o.exec(s);return r&&t.push(...n(r[1])),t}(s):function(e){const o=[],s=e.toString(),r=t.exec(s);return r&&o.push(...n(r[2])),o}(s):[]}class r{constructor(){let t=!1;this.create=async function(o,n,r,i){if(r.includes(o.origin))throw new Error(`Circular dependency for '${o.origin}'. Parents are: ${JSON.stringify(r)}`);if(o.exportName){const a=[...r,o.origin],{[o.exportName]:u}=n;if(o.composition===e.CF){if("function"==typeof u){const n=s(u);n.length&&(c=`Deps for object '${o.origin}' are: ${JSON.stringify(n)}`,t&&console.log(c));const r={};for(const e of n)r[e]=await i.compose(e,a);const l=e.isClass(u)?new u(r):u(r);return l instanceof Promise?await l:l}return Object.assign({},u)}return u}return n;var c},this.setDebug=function(e){t=e}}}class i{exportName;composition;life;moduleName;origin;wrappers=[]}const c=/^(node:)?(@?[A-Za-z0-9_-]+\/?[A-Za-z0-9_-]*)(([.#])?([A-Za-z0-9_]*)((\$)?(\$)?)?)?(\(([A-Za-z0-9_,]*)\))?$/;class a{canParse(){return!0}parse(t){const o=new i;o.origin=t;const n=c.exec(t);if(n&&(o.isNodeModule=Boolean(n[1]),o.moduleName=n[2].replace(/^node:/,""),"."===n[4]||"#"===n[4]?"$"===n[6]||"$$"===n[6]?(o.composition=e.CF,o.exportName=n[5],o.life="$"===n[6]?e.LS:e.LI):(o.composition=e.CA,o.life=e.LS,o.exportName=""!==n[5]?n[5]:"default"):"$"===n[6]||"$$"===n[6]?(o.composition=e.CF,o.exportName="default",o.life="$"===n[6]?e.LS:e.LI):(o.composition=void 0,o.exportName=void 0,o.life=void 0),n[10]&&(o.wrappers=n[10].split(","))),o.composition===e.CA&&o.life===e.LI)throw new Error(`Export is not a function and should be used as a singleton only: '${o.origin}'.`);return o}}class u{constructor(){let e=new a;const t=[];this.addChunk=function(e){t.push(e)},this.parse=function(o){let n;for(const e of t)if(e.canParse(o)){n=e.parse(o);break}return n||(n=e?.parse(o)),n},this.setDefaultChunk=function(t){e=t}}}class l{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=function(t,o){let n=t;for(const s of e)n=s.modify(n,t,o);return n}}}class f{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=async function(t,o,n){let s=t;for(const t of e)s=t.modify(s,o,n),s instanceof Promise&&(s=await s);return s}}}const p="root";class d{constructor(){const e={};let t=!1,o=[],n="/";this.addNamespaceRoot=function(n,s,r){const i=(t?s.replace(/^\\/,""):s).replace(/\\/g,"/"),c=t?`file://${i}`:i;e[n]={ext:r??"js",ns:n,[p]:c},o=Object.keys(e).sort(((e,t)=>t.localeCompare(e)))},this.resolve=function(t){let s,r,i;for(i of o)if(t.startsWith(i)){s=e[i][p],r=e[i].ext;break}if(s&&r){let e=t.replace(i,"");0===e.indexOf("_")&&(e=e.replace("_",""));const o=e.replaceAll("_",n);return`${s}${n}${o}.${r}`}return t},this.setWindowsEnv=function(e=!0){t=e,n=e?"\\":"/"}}}function m(e){return`${e.moduleName}#${e.exportName}`}class h{constructor(){let t=new r,o=!1,n=new u,s=new l,i=new f;const c={},a={};let p=new d;function h(){o&&console.log(...arguments)}this.get=async function(e,t=[]){return this.compose(e,t)},this.compose=async function(o,r=[]){if(h(`Object '${o}' is requested.`),o===e.ID||o===e.ID_FQN)return h("Container itself is returned."),a[e.ID];const u=n.parse(o),l=s.modify(u,r);if(l.life===e.LS){const e=m(l);if(a[e])return h(`Existing singleton '${e}' is returned.`),a[e]}let f;c[l.moduleName]||(h(`ES6 module '${l.moduleName}' is not resolved yet`),c[l.moduleName]=p.resolve(l.moduleName));const d=c[l.moduleName];try{f=await import(d),h(`ES6 module '${l.moduleName}' is loaded from '${d}'.`)}catch(e){throw console.error(e?.message,`Object key: "${o}".`,`Path: "${d}".`,`Stack: ${JSON.stringify(r)}`),e}let $=await t.create(l,f,r,this);var g;if(null===(g=$)||"object"!=typeof g&&"function"!=typeof g||"[object Module]"===Object.prototype.toString.call(g)||Object.isFrozen(g)||Object.freeze($),$=await i.modify($,l,r),h(`Object '${o}' is created.`),l.life===e.LS){const e=m(l);a[e]=$,h(`Object '${o}' is saved as singleton.`)}return $},this.getParser=()=>n,this.getPreProcessor=()=>s,this.getPostProcessor=()=>i,this.getResolver=()=>p,this.register=function(t,o){if(!t||!o)throw new Error("depId and object are required");const s=n.parse(t);if(s.life!==e.LS)throw new Error(`Only singletons can be registered manually. Given: ${t}`);{const e=m(s);a[e]=o,h(`Object '${t}' is registered manually as singleton.`)}},this.setDebug=function(e){o=e,t.setDebug(e)},this.setParser=e=>n=e,this.setPreProcessor=e=>s=e,this.setPostProcessor=e=>i=e,this.setResolver=e=>p=e,a[e.ID]=this}}export{h as default};
package/dist/umd.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).TeqFw_Di_Container=t()}(this,(function(){"use strict";var e={COMP_A:"A",COMP_F:"F",ID:"container",ID_FQN:"TeqFw_Di_Container$",LIFE_I:"I",LIFE_S:"S",isClass(e){const t=Object.getOwnPropertyDescriptor(e,"prototype");return t&&!t.writable}};const t=/(function)*\s*\w*\s*\(\s*\{([^\}]*)\}/s,o=/constructor\s*\(\s*\{([^\}]*)\}/s;function n(e){const t=[];try{const o=new Function(`{${e}}`,"return");o(new Proxy({},{get:(e,o)=>t.push(o)}))}catch(t){throw new Error(`Cannot analyze the deps specification:${e}\n\nPlease, be sure that spec does not contain extra ')' in a comments.\n\nError: ${t}`)}return t}function s(s){return"function"==typeof s?e.isClass(s)?function(e){const t=[],s=e.toString(),r=o.exec(s);return r&&t.push(...n(r[1])),t}(s):function(e){const o=[],s=e.toString(),r=t.exec(s);return r&&o.push(...n(r[2])),o}(s):[]}class r{constructor(){let t=!1;this.create=async function(o,n,r,i){if(r.includes(o.value))throw new Error(`Circular dependency for '${o.value}'. Parents are: ${JSON.stringify(r)}`);if(o.exportName){const a=[...r,o.value],{[o.exportName]:u}=n;if(o.composition===e.COMP_F){if("function"==typeof u){const n=s(u);n.length&&(c=`Deps for object '${o.value}' are: ${JSON.stringify(n)}`,t&&console.log(c));const r={};for(const e of n)r[e]=await i.compose(e,a);const l=e.isClass(u)?new u(r):u(r);return l instanceof Promise?await l:l}return Object.assign({},u)}return u}return n;var c},this.setDebug=function(e){t=e}}}class i{exportName;composition;life;moduleName;value;wrappers=[]}const c=/^((([A-Z])[A-Za-z0-9_]*)((\.)?([A-Za-z0-9_]*)((\$)?(\$)?)?)?(\(([A-Za-z0-9_,]*)\))?)$/;class a{canParse(e){return!0}parse(t){const o=new i;o.value=t;const n=c.exec(t);if(n&&(o.moduleName=n[2],"."===n[5]?"$"===n[7]||"$$"===n[7]?(o.composition=e.COMP_F,o.exportName=n[6],o.life="$"===n[7]?e.LIFE_S:e.LIFE_I):(o.composition=e.COMP_A,o.life=e.LIFE_S,o.exportName=""!==n[6]?n[6]:"default"):"$"===n[7]||"$$"===n[7]?(o.composition=e.COMP_F,o.exportName="default",o.life="$"===n[7]?e.LIFE_S:e.LIFE_I):(o.composition=void 0,o.exportName=void 0,o.life=void 0),n[11]&&(o.wrappers=n[11].split(","))),o.composition===e.COMP_A&&o.life===e.LIFE_I)throw new Error(`Export is not a function and should be used as a singleton only: '${o.value}'.`);return o}}class u{constructor(){let e=new a;const t=[];this.addChunk=function(e){t.push(e)},this.parse=function(o){let n;for(const e of t)if(e.canParse(o)){n=e.parse(o);break}return n||(n=e?.parse(o)),n},this.setDefaultChunk=function(t){e=t}}}class l{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=function(t,o){let n=t;for(const s of e)n=s.modify(n,t,o);return n}}}class f{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=async function(t,o,n){let s=t;for(const t of e)s=t.modify(s,o,n),s instanceof Promise&&(s=await s);return s}}}const p="root";class d{constructor(){const e={};let t=!1,o=[],n="/";this.addNamespaceRoot=function(n,s,r){const i=(t?s.replace(/^\\/,""):s).replace(/\\/g,"/"),c=t?`file://${i}`:i;e[n]={ext:r??"js",ns:n,[p]:c},o=Object.keys(e).sort(((e,t)=>t.localeCompare(e)))},this.resolve=function(t){let s,r,i;for(i of o)if(t.startsWith(i)){s=e[i][p],r=e[i].ext;break}if(s&&r){let e=t.replace(i,"");0===e.indexOf("_")&&(e=e.replace("_",""));const o=e.replaceAll("_",n);return`${s}${n}${o}.${r}`}return t},this.setWindowsEnv=function(e=!0){t=e,n=e?"\\":"/"}}}function m(e){return`${e.moduleName}#${e.exportName}`}return class{constructor(){let t=new r,o=!1,n=new u,s=new l,i=new f;const c={},a={};let p=new d;function h(){o&&console.log(...arguments)}this.get=async function(e,t=[]){return this.compose(e,t)},this.compose=async function(o,r=[]){if(h(`Object '${o}' is requested.`),o===e.ID||o===e.ID_FQN)return h("Container itself is returned."),a[e.ID];const u=n.parse(o),l=s.modify(u,r);if(l.life===e.LIFE_S){const e=m(l);if(a[e])return h(`Existing singleton '${e}' is returned.`),a[e]}let f;c[l.moduleName]||(h(`ES6 module '${l.moduleName}' is not resolved yet`),c[l.moduleName]=p.resolve(l.moduleName));const d=c[l.moduleName];try{f=await import(d),h(`ES6 module '${l.moduleName}' is loaded from '${d}'.`)}catch(e){throw console.error(e?.message,`Object key: "${o}".`,`Path: "${d}".`,`Stack: ${JSON.stringify(r)}`),e}let $=await t.create(l,f,r,this);if($=await i.modify($,l,r),h(`Object '${o}' is created.`),l.life===e.LIFE_S){const e=m(l);a[e]=$,h(`Object '${o}' is saved as singleton.`)}return $},this.getParser=()=>n,this.getPreProcessor=()=>s,this.getPostProcessor=()=>i,this.getResolver=()=>p,this.setDebug=function(e){o=e,t.setDebug(e)},this.setParser=e=>n=e,this.setPreProcessor=e=>s=e,this.setPostProcessor=e=>i=e,this.setResolver=e=>p=e,a[e.ID]=this}}}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).TeqFw_Di_Container=t()}(this,(function(){"use strict";var e={CA:"A",CF:"F",ID:"container",ID_FQN:"TeqFw_Di_Container$",LI:"I",LS:"S",isClass(e){const t=Object.getOwnPropertyDescriptor(e,"prototype");return t&&!t.writable}};const t=/(function)*\s*\w*\s*\(\s*\{([^}]*)}/s,o=/constructor\s*\(\s*\{([^}]*)}/s;function n(e){const t=[];try{const o=new Function(`{${e}}`,"return");o(new Proxy({},{get:(e,o)=>t.push(o)}))}catch(t){throw new Error(`Cannot analyze the deps specification:${e}\n\nPlease, be sure that spec does not contain extra ')' in a comments.\n\nError: ${t}`)}return t}function s(s){return"function"==typeof s?e.isClass(s)?function(e){const t=[],s=e.toString(),r=o.exec(s);return r&&t.push(...n(r[1])),t}(s):function(e){const o=[],s=e.toString(),r=t.exec(s);return r&&o.push(...n(r[2])),o}(s):[]}class r{constructor(){let t=!1;this.create=async function(o,n,r,i){if(r.includes(o.origin))throw new Error(`Circular dependency for '${o.origin}'. Parents are: ${JSON.stringify(r)}`);if(o.exportName){const a=[...r,o.origin],{[o.exportName]:u}=n;if(o.composition===e.CF){if("function"==typeof u){const n=s(u);n.length&&(c=`Deps for object '${o.origin}' are: ${JSON.stringify(n)}`,t&&console.log(c));const r={};for(const e of n)r[e]=await i.compose(e,a);const l=e.isClass(u)?new u(r):u(r);return l instanceof Promise?await l:l}return Object.assign({},u)}return u}return n;var c},this.setDebug=function(e){t=e}}}class i{exportName;composition;life;moduleName;origin;wrappers=[]}const c=/^(node:)?(@?[A-Za-z0-9_-]+\/?[A-Za-z0-9_-]*)(([.#])?([A-Za-z0-9_]*)((\$)?(\$)?)?)?(\(([A-Za-z0-9_,]*)\))?$/;class a{canParse(){return!0}parse(t){const o=new i;o.origin=t;const n=c.exec(t);if(n&&(o.isNodeModule=Boolean(n[1]),o.moduleName=n[2].replace(/^node:/,""),"."===n[4]||"#"===n[4]?"$"===n[6]||"$$"===n[6]?(o.composition=e.CF,o.exportName=n[5],o.life="$"===n[6]?e.LS:e.LI):(o.composition=e.CA,o.life=e.LS,o.exportName=""!==n[5]?n[5]:"default"):"$"===n[6]||"$$"===n[6]?(o.composition=e.CF,o.exportName="default",o.life="$"===n[6]?e.LS:e.LI):(o.composition=void 0,o.exportName=void 0,o.life=void 0),n[10]&&(o.wrappers=n[10].split(","))),o.composition===e.CA&&o.life===e.LI)throw new Error(`Export is not a function and should be used as a singleton only: '${o.origin}'.`);return o}}class u{constructor(){let e=new a;const t=[];this.addChunk=function(e){t.push(e)},this.parse=function(o){let n;for(const e of t)if(e.canParse(o)){n=e.parse(o);break}return n||(n=e?.parse(o)),n},this.setDefaultChunk=function(t){e=t}}}class l{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=function(t,o){let n=t;for(const s of e)n=s.modify(n,t,o);return n}}}class f{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=async function(t,o,n){let s=t;for(const t of e)s=t.modify(s,o,n),s instanceof Promise&&(s=await s);return s}}}const d="root";class p{constructor(){const e={};let t=!1,o=[],n="/";this.addNamespaceRoot=function(n,s,r){const i=(t?s.replace(/^\\/,""):s).replace(/\\/g,"/"),c=t?`file://${i}`:i;e[n]={ext:r??"js",ns:n,[d]:c},o=Object.keys(e).sort(((e,t)=>t.localeCompare(e)))},this.resolve=function(t){let s,r,i;for(i of o)if(t.startsWith(i)){s=e[i][d],r=e[i].ext;break}if(s&&r){let e=t.replace(i,"");0===e.indexOf("_")&&(e=e.replace("_",""));const o=e.replaceAll("_",n);return`${s}${n}${o}.${r}`}return t},this.setWindowsEnv=function(e=!0){t=e,n=e?"\\":"/"}}}function m(e){return`${e.moduleName}#${e.exportName}`}return class{constructor(){let t=new r,o=!1,n=new u,s=new l,i=new f;const c={},a={};let d=new p;function h(){o&&console.log(...arguments)}this.get=async function(e,t=[]){return this.compose(e,t)},this.compose=async function(o,r=[]){if(h(`Object '${o}' is requested.`),o===e.ID||o===e.ID_FQN)return h("Container itself is returned."),a[e.ID];const u=n.parse(o),l=s.modify(u,r);if(l.life===e.LS){const e=m(l);if(a[e])return h(`Existing singleton '${e}' is returned.`),a[e]}let f;c[l.moduleName]||(h(`ES6 module '${l.moduleName}' is not resolved yet`),c[l.moduleName]=d.resolve(l.moduleName));const p=c[l.moduleName];try{f=await import(p),h(`ES6 module '${l.moduleName}' is loaded from '${p}'.`)}catch(e){throw console.error(e?.message,`Object key: "${o}".`,`Path: "${p}".`,`Stack: ${JSON.stringify(r)}`),e}let g=await t.create(l,f,r,this);var $;if(null===($=g)||"object"!=typeof $&&"function"!=typeof $||"[object Module]"===Object.prototype.toString.call($)||Object.isFrozen($)||Object.freeze(g),g=await i.modify(g,l,r),h(`Object '${o}' is created.`),l.life===e.LS){const e=m(l);a[e]=g,h(`Object '${o}' is saved as singleton.`)}return g},this.getParser=()=>n,this.getPreProcessor=()=>s,this.getPostProcessor=()=>i,this.getResolver=()=>d,this.register=function(t,o){if(!t||!o)throw new Error("depId and object are required");const s=n.parse(t);if(s.life!==e.LS)throw new Error(`Only singletons can be registered manually. Given: ${t}`);{const e=m(s);a[e]=o,h(`Object '${t}' is registered manually as singleton.`)}},this.setDebug=function(e){o=e,t.setDebug(e)},this.setParser=e=>n=e,this.setPreProcessor=e=>s=e,this.setPostProcessor=e=>i=e,this.setResolver=e=>d=e,a[e.ID]=this}}}));
@@ -0,0 +1,37 @@
1
+ // eslint.config.js
2
+ import js from '@eslint/js';
3
+
4
+ /** @type {import('eslint').Linter.FlatConfig[]} */
5
+ export default [
6
+ js.configs.recommended,
7
+ {
8
+ languageOptions: {
9
+ ecmaVersion: 2022, // required for public class fields
10
+ sourceType: 'module',
11
+ globals: {
12
+ console: 'readonly',
13
+ },
14
+ },
15
+ rules: {
16
+ 'camelcase': [
17
+ 'warn',
18
+ {
19
+ properties: 'never',
20
+ ignoreDestructuring: true,
21
+ allow: ['^([A-Z][a-zA-Z0-9]*_)+[A-Z][a-zA-Z0-9]*$'],
22
+ },
23
+ ],
24
+ 'indent': ['error', 4],
25
+ 'linebreak-style': ['error', 'unix'],
26
+ 'quotes': ['error', 'single'],
27
+ 'semi': ['error', 'always'],
28
+ },
29
+ },
30
+ // Special rule override for interface declarations
31
+ {
32
+ files: ['./src/Api/**/*.js'],
33
+ rules: {
34
+ 'no-unused-vars': 'off',
35
+ },
36
+ },
37
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teqfw/di",
3
- "version": "0.31.0",
3
+ "version": "0.33.0",
4
4
  "description": "Dependency Injection container for ES6 modules that works in both browser and Node.js apps.",
5
5
  "keywords": [
6
6
  "dependency injection",
@@ -28,13 +28,16 @@
28
28
  },
29
29
  "scripts": {
30
30
  "rollup": "rollup -c",
31
+ "eslint": "eslint './src/**/*.js'",
31
32
  "test": "mocha --recursive './test/**/*.test.mjs'"
32
33
  },
33
34
  "devDependencies": {
34
- "@rollup/plugin-node-resolve": "^15.2.3",
35
- "mocha": "^10.7.0",
36
- "rollup": "^2.79.1",
37
- "rollup-plugin-terser": "^7.0.2"
35
+ "@eslint/js": "^9.25.0",
36
+ "@rollup/plugin-node-resolve": "^16.0.1",
37
+ "@rollup/plugin-terser": "^0.4.4",
38
+ "eslint": "^9.25.0",
39
+ "mocha": "^11.1.0",
40
+ "rollup": "^4.36.0"
38
41
  },
39
42
  "mocha": {
40
43
  "spec": "./test/**/*.test.mjs",
package/rollup.config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import resolve from '@rollup/plugin-node-resolve';
2
- import {terser} from 'rollup-plugin-terser';
2
+ import terser from '@rollup/plugin-terser';
3
3
 
4
4
  export default {
5
5
  input: 'src/Container.js',
@@ -34,6 +34,13 @@ export default class TeqFw_Di_Api_Container {
34
34
  */
35
35
  getResolver() {};
36
36
 
37
+ /**
38
+ * Registers an object (module, singleton, factory, or prototype) by dependency ID.
39
+ * @param {string} depId
40
+ * @param {Object} obj
41
+ */
42
+ register(depId, obj) {};
43
+
37
44
  /**
38
45
  * Enable disable debug output for the object composition process.
39
46
  * @param {boolean} data
@@ -8,8 +8,8 @@
8
8
  import Defs from '../../../../Defs.js';
9
9
 
10
10
  // VARS
11
- const FUNC = /(function)*\s*\w*\s*\(\s*\{([^\}]*)\}/s;
12
- const CLASS = /constructor\s*\(\s*\{([^\}]*)\}/s;
11
+ const FUNC = /(function)*\s*\w*\s*\(\s*\{([^}]*)}/s;
12
+ const CLASS = /constructor\s*\(\s*\{([^}]*)}/s;
13
13
 
14
14
  // FUNCS
15
15
 
@@ -32,7 +32,7 @@ function _analyze(params) {
32
32
  fn(spec);
33
33
  } catch (e) {
34
34
  const msg = `Cannot analyze the deps specification:${params}\n`
35
- + `\nPlease, be sure that spec does not contain extra ')' in a comments.`
35
+ + '\nPlease, be sure that spec does not contain extra \')\' in a comments.'
36
36
  + `\n\nError: ${e}`;
37
37
  throw new Error(msg);
38
38
  }
@@ -29,17 +29,17 @@ export default class TeqFw_Di_Container_A_Composer {
29
29
  * @returns {Promise<*>}
30
30
  */
31
31
  this.create = async function (depId, module, stack, container) {
32
- if (stack.includes(depId.value))
33
- throw new Error(`Circular dependency for '${depId.value}'. Parents are: ${JSON.stringify(stack)}`);
32
+ if (stack.includes(depId.origin))
33
+ throw new Error(`Circular dependency for '${depId.origin}'. Parents are: ${JSON.stringify(stack)}`);
34
34
  if (depId.exportName) {
35
35
  // use export from the es6-module
36
- const stackNew = [...stack, depId.value];
36
+ const stackNew = [...stack, depId.origin];
37
37
  const {[depId.exportName]: exp} = module;
38
- if (depId.composition === Defs.COMP_F) {
38
+ if (depId.composition === Defs.CF) {
39
39
  if (typeof exp === 'function') {
40
40
  // create deps for factory function
41
41
  const deps = specParser(exp);
42
- if (deps.length) log(`Deps for object '${depId.value}' are: ${JSON.stringify(deps)}`);
42
+ if (deps.length) log(`Deps for object '${depId.origin}' are: ${JSON.stringify(deps)}`);
43
43
  const spec = {};
44
44
  for (const dep of deps)
45
45
  spec[dep] = await container.compose(dep, stackNew);
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * Default parser for object keys in format:
3
3
  * - Ns_Module.export$$(post)
4
+ * - node:package.export$$(post)
5
+ * - node:@scope/package.export$$(post)
4
6
  *
5
7
  * @namespace TeqFw_Di_Container_A_Parser_Chunk_Def
6
8
  */
@@ -8,58 +10,60 @@ import Dto from '../../../../DepId.js';
8
10
  import Defs from '../../../../Defs.js';
9
11
 
10
12
  // VARS
11
- /** @type {RegExp} expression for default object key (Ns_Module.export$$(post)) */
12
- const REGEXP = /^((([A-Z])[A-Za-z0-9_]*)((\.)?([A-Za-z0-9_]*)((\$)?(\$)?)?)?(\(([A-Za-z0-9_,]*)\))?)$/;
13
+ /** @type {RegExp} expression for a default object key */
14
+ const REGEXP = /^(node:)?(@?[A-Za-z0-9_-]+\/?[A-Za-z0-9_-]*)(([.#])?([A-Za-z0-9_]*)((\$)?(\$)?)?)?(\(([A-Za-z0-9_,]*)\))?$/;
13
15
 
14
16
  /**
15
17
  * @implements TeqFw_Di_Api_Container_Parser_Chunk
16
18
  */
17
19
  export default class TeqFw_Di_Container_A_Parser_Chunk_Def {
18
20
 
19
- canParse(depId) {
20
- // default parser always trys to parse the depId
21
+ canParse() {
22
+ // the default parser always tries to parse the depId
21
23
  return true;
22
24
  }
23
25
 
24
26
  parse(objectKey) {
25
27
  const res = new Dto();
26
- res.value = objectKey;
28
+ res.origin = objectKey;
27
29
  const parts = REGEXP.exec(objectKey);
28
30
  if (parts) {
29
- res.moduleName = parts[2];
30
- if (parts[5] === '.') {
31
- // Ns_Module.export...
32
- if ((parts[7] === '$') || (parts[7] === '$$')) {
33
- // Ns_Module.export$...
34
- res.composition = Defs.COMP_F;
35
- res.exportName = parts[6];
36
- res.life = (parts[7] === '$') ? Defs.LIFE_S : Defs.LIFE_I;
31
+ res.isNodeModule = Boolean(parts[1]); // Detect 'node:' prefix
32
+ res.moduleName = parts[2].replace(/^node:/, ''); // Remove 'node:' prefix
33
+
34
+ if ((parts[4] === '.') || (parts[4] === '#')) {
35
+ // Ns_Module.export or node:package.export
36
+ if ((parts[6] === '$') || (parts[6] === '$$')) {
37
+ res.composition = Defs.CF;
38
+ res.exportName = parts[5];
39
+ res.life = (parts[6] === '$') ? Defs.LS : Defs.LI;
37
40
  } else {
38
- res.composition = Defs.COMP_A;
39
- res.life = Defs.LIFE_S;
40
- // res.exportName = (parts[6]) ? parts[6] : 'default';
41
- res.exportName = (parts[6] !== '') ? parts[6] : 'default';
41
+ res.composition = Defs.CA;
42
+ res.life = Defs.LS;
43
+ res.exportName = (parts[5] !== '') ? parts[5] : 'default';
42
44
  }
43
- } else if ((parts[7] === '$') || parts[7] === '$$') {
44
- // Ns_Module$$
45
- res.composition = Defs.COMP_F;
45
+ } else if ((parts[6] === '$') || parts[6] === '$$') {
46
+ // Ns_Module$$ or node:package$$
47
+ res.composition = Defs.CF;
46
48
  res.exportName = 'default';
47
- res.life = (parts[7] === '$') ? Defs.LIFE_S : Defs.LIFE_I;
49
+ res.life = (parts[6] === '$') ? Defs.LS : Defs.LI;
48
50
  } else {
49
- // Ns_Module (es6 module)
51
+ // Ns_Module or node:package (ES6 module)
50
52
  res.composition = undefined;
51
53
  res.exportName = undefined;
52
54
  res.life = undefined;
53
55
  }
54
- // wrappers
55
- if (parts[11]) {
56
- res.wrappers = parts[11].split(',');
56
+
57
+ // Wrappers handling
58
+ if (parts[10]) {
59
+ res.wrappers = parts[10].split(',');
57
60
  }
58
61
  }
59
62
 
60
- // we should always use singletons for as-is exports
61
- if ((res.composition === Defs.COMP_A) && (res.life === Defs.LIFE_I))
62
- throw new Error(`Export is not a function and should be used as a singleton only: '${res.value}'.`);
63
+ // Ensure singletons for non-factory exports
64
+ if ((res.composition === Defs.CA) && (res.life === Defs.LI))
65
+ throw new Error(`Export is not a function and should be used as a singleton only: '${res.origin}'.`);
66
+
63
67
  return res;
64
68
  }
65
- }
69
+ }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Default parser for object keys in format:
3
3
  * - Ns_Module[.|#]export$[F|A][S|I]
4
+ * - node:package[.|#]export$[F|A][S|I]
4
5
  *
5
6
  * @namespace TeqFw_Di_Container_A_Parser_Chunk_V02X
6
7
  */
@@ -8,63 +9,58 @@ import Dto from '../../../../DepId.js';
8
9
  import Defs from '../../../../Defs.js';
9
10
 
10
11
  // VARS
11
- /** @type {RegExp} expression for default object key (Ns_Module[.|#]export$[F|A][S|I]) */
12
- const REGEXP = /^((([A-Z])[A-Za-z0-9_]*)((#|\.)?([A-Za-z0-9_]*)((\$)([F|A])?([S|I])?)?)?)$/;
12
+ /** @type {RegExp} expression for a default object key */
13
+ const REGEXP = /^(node:)?(([A-Z])[A-Za-z0-9_]*|[a-z][a-z0-9-]*)(([#.])?([A-Za-z0-9_]*)((\$)([F|A])?([S|I])?)?)?$/;
13
14
 
14
15
  /**
15
16
  * @implements TeqFw_Di_Api_Container_Parser_Chunk
16
17
  */
17
18
  export default class TeqFw_Di_Container_A_Parser_Chunk_V02X {
18
19
 
19
- canParse(depId) {
20
- // default parser always trys to parse the depId
20
+ canParse() {
21
+ // the default parser always tries to parse the depId
21
22
  return true;
22
23
  }
23
24
 
24
25
  parse(objectKey) {
25
26
  const res = new Dto();
26
- res.value = objectKey;
27
+ res.origin = objectKey;
27
28
  const parts = REGEXP.exec(objectKey);
28
29
  if (parts) {
29
- res.moduleName = parts[2];
30
+ res.isNodeModule = Boolean(parts[1]); // Check if it starts with 'node:'
31
+ res.moduleName = parts[2].replace(/^node:/, ''); // Remove 'node:' if present
32
+
30
33
  if (parts[5] === '.') {
31
- // App_Service.export...
34
+ // App_Service.export or node:package.export
32
35
  if (parts[8] === '$') {
33
- // App_Service.export$...
34
- res.composition = Defs.COMP_F;
36
+ // App_Service.export$ or node:package.export$
37
+ res.composition = Defs.CF;
35
38
  res.exportName = parts[6];
36
- res.life = (parts[10] === Defs.LIFE_I)
37
- ? Defs.LIFE_I : Defs.LIFE_S;
39
+ res.life = (parts[10] === Defs.LI) ? Defs.LI : Defs.LS;
38
40
  } else {
39
- res.composition = ((parts[8] === undefined) || (parts[8] === Defs.COMP_A))
40
- ? Defs.COMP_A : Defs.COMP_F;
41
+ res.composition = (!parts[8] || parts[8] === Defs.CA) ? Defs.CA : Defs.CF;
41
42
  res.exportName = parts[6];
42
- res.life = ((parts[8] === undefined) || (parts[10] === Defs.LIFE_S))
43
- ? Defs.LIFE_S : Defs.LIFE_I;
43
+ res.life = (!parts[8] || parts[10] === Defs.LS) ? Defs.LS : Defs.LI;
44
44
  }
45
-
46
-
47
45
  } else if (parts[8] === '$') {
48
- // App_Logger$FS
49
- res.composition = ((parts[9] === undefined) || (parts[9] === Defs.COMP_F))
50
- ? Defs.COMP_F : Defs.COMP_A;
46
+ // App_Logger$FS or node:package$
47
+ res.composition = (!parts[9] || parts[9] === Defs.CF) ? Defs.CF : Defs.CA;
51
48
  res.exportName = 'default';
52
- if (parts[10]) {
53
- res.life = (parts[10] === Defs.LIFE_S) ? Defs.LIFE_S : Defs.LIFE_I;
54
- } else {
55
- res.life = (res.composition === Defs.COMP_F) ? Defs.LIFE_S : Defs.LIFE_I;
56
- }
49
+ res.life = parts[10] ? (parts[10] === Defs.LS ? Defs.LS : Defs.LI) : (res.composition === Defs.CF ? Defs.LS : Defs.LI);
57
50
  } else {
58
- // App_Service (es6 module)
51
+ // App_Service or node:package (ES6 module)
59
52
  res.composition = undefined;
60
53
  res.exportName = undefined;
61
54
  res.life = undefined;
62
55
  }
56
+
57
+ }
58
+
59
+ // Enforce singleton for non-factory exports
60
+ if (res.composition === Defs.CA && res.life === Defs.LI) {
61
+ throw new Error(`Export is not a function and should be used as a singleton only: '${res.origin}'.`);
63
62
  }
64
63
 
65
- // we should always use singletons for as-is exports
66
- if ((res.composition === Defs.COMP_A) && (res.life === Defs.LIFE_I))
67
- throw new Error(`Export is not a function and should be used as a singleton only: '${res.value}'.`);
68
64
  return res;
69
65
  }
70
- }
66
+ }
package/src/Container.js CHANGED
@@ -19,6 +19,21 @@ function getSingletonId(key) {
19
19
  return `${key.moduleName}#${key.exportName}`;
20
20
  }
21
21
 
22
+ /**
23
+ * Determines if an object, function, or primitive can be safely frozen.
24
+ * @param {*} value - The value to check.
25
+ * @returns {boolean} - Returns true if the value can be safely frozen.
26
+ */
27
+ function canBeFrozen(value) {
28
+ // Primitives (except objects and functions) cannot be frozen
29
+ if (value === null || typeof value !== 'object' && typeof value !== 'function') return false;
30
+ // // ES modules cannot be frozen
31
+ if (Object.prototype.toString.call(value) === '[object Module]') return false;
32
+ // check is Object is already frozen
33
+ return !Object.isFrozen(value);
34
+ }
35
+
36
+
22
37
  // MAIN
23
38
  /**
24
39
  * @implements TeqFw_Di_Api_Container
@@ -72,7 +87,7 @@ export default class TeqFw_Di_Container {
72
87
  (depId === Defs.ID) ||
73
88
  (depId === Defs.ID_FQN)
74
89
  ) {
75
- log(`Container itself is returned.`);
90
+ log('Container itself is returned.');
76
91
  return _regSingles[Defs.ID];
77
92
  }
78
93
  // parse the `objectKey` and get the structured DTO
@@ -80,7 +95,7 @@ export default class TeqFw_Di_Container {
80
95
  // modify original key according to some rules (replacements, etc.)
81
96
  const key = _preProcessor.modify(parsed, stack);
82
97
  // return existing singleton
83
- if (key.life === Defs.LIFE_S) {
98
+ if (key.life === Defs.LS) {
84
99
  const singleId = getSingletonId(key);
85
100
  if (_regSingles[singleId]) {
86
101
  log(`Existing singleton '${singleId}' is returned.`);
@@ -111,11 +126,13 @@ export default class TeqFw_Di_Container {
111
126
  }
112
127
  // create object using the composer then modify it in post-processor
113
128
  let res = await _composer.create(key, module, stack, this);
129
+ // freeze the result to prevent modifications (TODO: should we have configuration for the feature?)
130
+ if (canBeFrozen(res)) Object.freeze(res);
114
131
  res = await _postProcessor.modify(res, key, stack);
115
132
  log(`Object '${depId}' is created.`);
116
133
 
117
134
  // save singletons
118
- if (key.life === Defs.LIFE_S) {
135
+ if (key.life === Defs.LS) {
119
136
  const singleId = getSingletonId(key);
120
137
  _regSingles[singleId] = res;
121
138
  log(`Object '${depId}' is saved as singleton.`);
@@ -128,8 +145,27 @@ export default class TeqFw_Di_Container {
128
145
  this.getPreProcessor = () => _preProcessor;
129
146
 
130
147
  this.getPostProcessor = () => _postProcessor;
148
+
131
149
  this.getResolver = () => _resolver;
132
150
 
151
+ /**
152
+ * Register new object in the Container.
153
+ * @param {string} depId
154
+ * @param {Object} obj
155
+ */
156
+ this.register = function (depId, obj) {
157
+ if (!depId || !obj) throw new Error('depId and object are required');
158
+ const key = _parser.parse(depId);
159
+ if (key.life === Defs.LS) {
160
+ const singleId = getSingletonId(key);
161
+ _regSingles[singleId] = obj;
162
+ log(`Object '${depId}' is registered manually as singleton.`);
163
+ } else {
164
+ // TODO: factory function also should be added manually
165
+ throw new Error(`Only singletons can be registered manually. Given: ${depId}`);
166
+ }
167
+ };
168
+
133
169
  this.setDebug = function (data) {
134
170
  _debug = data;
135
171
  _composer.setDebug(data);
package/src/Defs.js CHANGED
@@ -3,12 +3,13 @@
3
3
  * @namespace TeqFw_Di_Defs
4
4
  */
5
5
  export default {
6
- COMP_A: 'A', // composition: as-is
7
- COMP_F: 'F', // composition: factory
6
+ CA: 'A', // composition: as-is
7
+ CF: 'F', // composition: factory
8
+ // TODO: we don't need an access to the container itself.
8
9
  ID: 'container', // default ID for container itself
9
10
  ID_FQN: 'TeqFw_Di_Container$', // default Full Qualified Name for container itself
10
- LIFE_I: 'I', // lifestyle: instance
11
- LIFE_S: 'S', // lifestyle: singleton
11
+ LI: 'I', // lifestyle: instance
12
+ LS: 'S', // lifestyle: singleton
12
13
 
13
14
  /**
14
15
  * Return 'true' if function is a class definition.
package/src/DepId.js CHANGED
@@ -1,33 +1,44 @@
1
1
  /**
2
- * This is a DTO that represents the structure of an ID for a runtime dependency.
2
+ * DTO representing a dependency identifier in the container.
3
3
  * @namespace TeqFw_Di_DepId
4
4
  */
5
5
  export default class TeqFw_Di_DepId {
6
6
  /**
7
- * The name of an export of the module.
7
+ * The name of an export from the module.
8
+ * Example: 'default', 'logger', 'DbClient'.
8
9
  * @type {string}
9
10
  */
10
11
  exportName;
11
12
  /**
12
- * Composition type (see Defs.COMPOSE_): use the export as Factory (F) or return as-is (A).
13
+ * Defines how the export should be used:
14
+ * - 'F' (Factory): The export is a factory function, call it to get an instance.
15
+ * - 'A' (As-Is): The export is returned as-is, without calling.
16
+ * Example: 'F', 'A'.
13
17
  * @type {string}
14
18
  */
15
19
  composition;
16
20
  /**
17
- * Lifestyle type (see Defs.LIFE_): singleton (S) or instance (I).
21
+ * Defines the lifecycle of the resolved dependency:
22
+ * - 'S' (Singleton): A single instance is created and reused.
23
+ * - 'I' (Instance): A new instance is created on each request.
24
+ * Example: 'S', 'I'.
18
25
  * @type {string}
19
26
  */
20
27
  life;
21
28
  /**
22
- * The code for ES6 module that can be converted to the path to this es6 module.
29
+ * ES6 module identifier, which can be transformed into a file path.
30
+ * This value is processed by the Resolver to determine the module's location.
31
+ * Example: 'TeqFw_Core_Shared_Api_Logger'.
23
32
  * @type {string}
24
33
  */
25
34
  moduleName;
26
35
  /**
27
- * Object key value.
36
+ * The original identifier string provided to the container.
37
+ * This is the unprocessed dependency key.
38
+ * Example: 'TeqFw_Core_Shared_Api_Logger$$'.
28
39
  * @type {string}
29
40
  */
30
- value;
41
+ origin;
31
42
  /**
32
43
  * List of wrappers to decorate the result.
33
44
  * @type {string[]}
package/.eslintrc.mjs DELETED
File without changes