@teqfw/di 0.20.0 → 0.21.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/src/Parser/Def.js DELETED
@@ -1,63 +0,0 @@
1
- /**
2
- * Default parser for object keys in format:
3
- * - Vnd_Pkg_Prj_Mod$FA
4
- */
5
- import Dto from '../Api/ObjectKey.js';
6
- import Defs from '../Defs.js';
7
-
8
- // VARS
9
- /** @type {RegExp} expression for default object key (Ns_Module[.|#]export$[F|A][S|I]) */
10
- const REGEXP = /^((([A-Z])[A-Za-z0-9_]*)((#|\.)?([A-Za-z0-9]*)((\$)([F|A])?([S|I])?)?)?)$/;
11
-
12
-
13
- // MAIN
14
- /**
15
- * @param {string} objectKey
16
- * @return {TeqFw_Di_Api_ObjectKey}
17
- */
18
- export default function TeqFw_Di_Parser_Def(objectKey) {
19
- const res = new Dto();
20
- res.value = objectKey;
21
- const parts = REGEXP.exec(objectKey);
22
- if (parts) {
23
- res.moduleName = parts[2];
24
- if (parts[5] === '.') {
25
- // App_Service.export...
26
- if (parts[8] === '$') {
27
- // App_Service.export$...
28
- res.composition = Defs.COMPOSE_FACTORY;
29
- res.exportName = parts[6];
30
- res.life = (parts[10] === Defs.LIFE_INSTANCE)
31
- ? Defs.LIFE_INSTANCE : Defs.LIFE_SINGLETON;
32
- } else {
33
- res.composition = ((parts[8] === undefined) || (parts[8] === Defs.COMPOSE_AS_IS))
34
- ? Defs.COMPOSE_AS_IS : Defs.COMPOSE_FACTORY;
35
- res.exportName = parts[6];
36
- res.life = ((parts[8] === undefined) || (parts[10] === Defs.LIFE_SINGLETON))
37
- ? Defs.LIFE_SINGLETON : Defs.LIFE_INSTANCE;
38
- }
39
-
40
-
41
- } else if (parts[8] === '$') {
42
- // App_Logger$FS
43
- res.composition = ((parts[9] === undefined) || (parts[9] === Defs.COMPOSE_FACTORY))
44
- ? Defs.COMPOSE_FACTORY : Defs.COMPOSE_AS_IS;
45
- res.exportName = 'default';
46
- if (parts[10]) {
47
- res.life = (parts[10] === Defs.LIFE_SINGLETON) ? Defs.LIFE_SINGLETON : Defs.LIFE_INSTANCE;
48
- } else {
49
- res.life = (res.composition === Defs.COMPOSE_FACTORY) ? Defs.LIFE_SINGLETON : Defs.LIFE_INSTANCE;
50
- }
51
- } else {
52
- // App_Service
53
- res.composition = Defs.COMPOSE_AS_IS;
54
- res.exportName = 'default';
55
- res.life = Defs.LIFE_SINGLETON;
56
- }
57
- }
58
-
59
- // we should always use singletons for as-is exports
60
- if ((res.composition === Defs.COMPOSE_AS_IS) && (res.life === Defs.LIFE_INSTANCE))
61
- throw new Error(`Export is not a function and should be used as a singleton only: '${res.value}'.`);
62
- return res;
63
- }
package/src/Parser/Old.js DELETED
@@ -1,108 +0,0 @@
1
- /**
2
- * Parser for object keys in old format:
3
- * - Vnd_Pkg_Prj_Mod[.|#]export$$
4
- */
5
- import Dto from '../Api/ObjectKey.js';
6
- import Defs from '../Defs.js';
7
-
8
- // VARS
9
- /** @type {string} default export keyword */
10
- const DEF_EXP = 'default';
11
- /** @type {string} logical namespace export mark (Ns_Mod.export) */
12
- const EXP = '.';
13
- /** @type {string} filesystem export mark (@vendor/package!module#export$$) and old logical export mark */
14
- const EXP_OLD = '#';
15
- /** @type {string} new instance mark (Ns_Mod.export$$) */
16
- const INST = '$$';
17
- /** @type {RegExp} expression for logical namespace IDs (Ns_Module[.|#]export$$@@) */
18
- const REGEXP = /^((([A-Z])[A-Za-z0-9_]*)((#|.)?([A-Za-z0-9_]*)(\${1,2}|@{1,2})?)?)$/;
19
- /** @type {RegExp} expression for objects that manually added to DI container (singleton, namedFactory$$) */
20
- const MANUAL = /^((([a-z])[A-Za-z0-9_]*)(\$\$)?)$/s;
21
- /** @type {string} new instance proxy mark (Ns_Mod.export@@) */
22
- const P_INST = '@@';
23
- /** @type {string} singleton proxy mark (Ns_Mod.export@) */
24
- const P_SNGLT = '@';
25
- /** @type {string} singleton mark (Ns_Mod.export$) */
26
- const SNGLT = '$';
27
-
28
- // MAIN
29
- export default function TeqFw_Di_Parser_Old(objectKey) {
30
- const res = new Dto();
31
- res.value = objectKey;
32
- const parts = REGEXP.exec(objectKey);
33
- if (parts) {
34
- res.moduleName = parts[2];
35
- // Ns_Module.name$$[@@] - named instance [proxy]
36
- if (
37
- ((parts[5] === EXP) || (parts[5] === EXP_OLD))
38
- && ((parts[7] === INST) || (parts[7] === P_INST))
39
- ) {
40
- if (parts[7] === P_INST)
41
- res.wrappers.push(Defs.WRAP_PROXY);
42
- res.composition = Defs.COMPOSE_FACTORY;
43
- res.life = Defs.LIFE_INSTANCE;
44
- res.exportName = parts[6];
45
- }
46
- // Ns_Module.name$[@] - named singleton [proxy]
47
- else if (
48
- ((parts[5] === EXP) || (parts[5] === EXP_OLD))
49
- && ((parts[7] === SNGLT) || (parts[7] === P_SNGLT))
50
- ) {
51
- if (parts[7] === P_SNGLT)
52
- res.wrappers.push(Defs.WRAP_PROXY);
53
- res.composition = Defs.COMPOSE_FACTORY;
54
- res.life = Defs.LIFE_SINGLETON;
55
- res.exportName = parts[6];
56
- }
57
- // Ns_Module.name - named export
58
- else if (
59
- ((parts[5] === EXP) || (parts[5] === EXP_OLD))
60
- && ((parts[6] !== undefined) && (parts[6] !== ''))
61
- ) {
62
- res.composition = Defs.COMPOSE_AS_IS;
63
- res.exportName = parts[6];
64
- res.life = Defs.LIFE_SINGLETON;
65
- }
66
- // Ns_Module$$[@@]- default instance [proxy]
67
- else if ((parts[4] === INST) || (parts[4] === P_INST)) {
68
- if (parts[4] === P_INST)
69
- res.wrappers.push(Defs.WRAP_PROXY);
70
- res.composition = Defs.COMPOSE_FACTORY;
71
- res.life = Defs.LIFE_INSTANCE;
72
- res.exportName = DEF_EXP;
73
- }
74
- // Ns_Module$[@] - default singleton [proxy]
75
- else if ((parts[4] === SNGLT) || (parts[4] === P_SNGLT)) {
76
- if (parts[4] === P_SNGLT)
77
- res.wrappers.push(Defs.WRAP_PROXY);
78
- res.composition = Defs.COMPOSE_FACTORY;
79
- res.life = Defs.LIFE_SINGLETON;
80
- res.exportName = DEF_EXP;
81
- }
82
- // Ns_Module#[.] - default export
83
- else if (
84
- ((parts[5] === EXP) || (parts[5] === EXP_OLD))
85
- && (parts[7] === undefined)
86
- ) {
87
- res.composition = Defs.COMPOSE_AS_IS;
88
- res.life = Defs.LIFE_SINGLETON;
89
- res.exportName = DEF_EXP;
90
- } else {
91
- // just a es6-module (deprecated)
92
-
93
- }
94
- } else {
95
- const manual = MANUAL.exec(objectKey);
96
- if (manual) {
97
- if (manual[4] === '$$') {
98
- res.composition = Defs.COMPOSE_FACTORY;
99
- res.life = Defs.LIFE_INSTANCE;
100
- } else {
101
- res.life = Defs.LIFE_SINGLETON;
102
- }
103
- } else {
104
- // TODO: add exception
105
- }
106
- }
107
- return res;
108
- }
package/src/Parser.js DELETED
@@ -1,65 +0,0 @@
1
- /**
2
- * The root parser for `objectKeys` contains all other parsers.
3
- * It calls the other parser one by one to parse the object key as a structure.
4
- * Every npm package can have its own format for an `objectKey`.
5
- */
6
- import defaultParser from './Parser/Def.js';
7
-
8
- // VARS
9
- const KEY_PARSER = 'parser';
10
- const KEY_VALIDATOR = 'validator';
11
-
12
- // MAIN
13
- export default class TeqFw_Di_Parser {
14
-
15
- constructor() {
16
- // VARS
17
- /**
18
- * Default parsing function.
19
- * @type {(function(string): TeqFw_Di_Api_ObjectKey)}
20
- */
21
- let _defaultParser = defaultParser;
22
- /**
23
- * The array of the pairs {validator, parser} to parse objectKeys.
24
- * @type {Object<validator:function, parser:function>[]}
25
- */
26
- const _parsers = [];
27
-
28
- // INSTANCE METHODS
29
-
30
- /**
31
- *
32
- * @param {function(string):boolean} validator
33
- * @param {function(string):TeqFw_Di_Api_ObjectKey} parser
34
- */
35
- this.addParser = function (validator, parser) {
36
- _parsers.push({[KEY_VALIDATOR]: validator, [KEY_PARSER]: parser});
37
- };
38
-
39
- /**
40
- * @param {string} objectKey
41
- * @return {TeqFw_Di_Api_ObjectKey}
42
- */
43
- this.parse = function (objectKey) {
44
- let res;
45
- for (const one of _parsers) {
46
- if (one[KEY_VALIDATOR](objectKey)) {
47
- res = one[KEY_PARSER](objectKey);
48
- break;
49
- }
50
- }
51
- if (!res)
52
- res = _defaultParser(objectKey);
53
- return res;
54
- };
55
-
56
- /**
57
- * @param {function(string):TeqFw_Di_Api_ObjectKey} parser
58
- */
59
- this.setDefaultParser = function (parser) {
60
- _defaultParser = parser;
61
- };
62
-
63
- // MAIN
64
- }
65
- };
@@ -1,48 +0,0 @@
1
- /**
2
- * Pre-processor handler to replace one object key with another.
3
- */
4
-
5
- /**
6
- * Factory function to create pre-processor handler.
7
- * @return {function(*): *}
8
- */
9
- export default function () {
10
- // VARS
11
- /**
12
- * Storage for ES modules replacements (interface => implementation).
13
- * Sample: {['Vnd_Plug_Interface']:'Vnd_Plug_Impl', ...}
14
- * @type {Object<string, string>}
15
- */
16
- const replacements = {};
17
-
18
- // FUNCS
19
- /**
20
- * @param {TeqFw_Di_Api_ObjectKey} objectKey
21
- * @param {TeqFw_Di_Api_ObjectKey} originalKey
22
- * @return {TeqFw_Di_Api_ObjectKey}
23
- * @namespace
24
- */
25
- function TeqFw_Di_PreProcessor_Replace(objectKey, originalKey) {
26
- let module = objectKey.moduleName;
27
- while (replacements[module]) module = replacements[module];
28
- if (module !== objectKey.moduleName) {
29
- const res = Object.assign({}, objectKey);
30
- res.moduleName = module;
31
- return res;
32
- } else
33
- return objectKey;
34
- }
35
-
36
- /**
37
- * Add replacement for ES6 modules.
38
- *
39
- * @param {string} orig ('Vnd_Plug_Interface')
40
- * @param {string} alter ('Vnd_Plug_Impl')
41
- */
42
- TeqFw_Di_PreProcessor_Replace.add = function (orig, alter) {
43
- replacements[orig] = alter;
44
- };
45
-
46
- // MAIN
47
- return TeqFw_Di_PreProcessor_Replace;
48
- }
@@ -1,45 +0,0 @@
1
- /**
2
- * The preprocessor handles object keys after the parsing but before creating any objects.
3
- * A replacement rules can be implemented here.
4
- * Every handler is a function with 2 arguments:
5
- * - objectKey: current key after processing with other handlers;
6
- * - originalKey: the key before any processing;
7
- */
8
- export default class TeqFw_Di_PreProcessor {
9
-
10
- constructor() {
11
- // VARS
12
- /**
13
- * The array of handlers in the dependency order (from the basic (di) up to the app).
14
- * @type {Array<function(TeqFw_Di_Api_ObjectKey, TeqFw_Di_Api_ObjectKey):TeqFw_Di_Api_ObjectKey>}
15
- */
16
- const _handlers = [];
17
-
18
- // INSTANCE METHODS
19
-
20
- /**
21
- *
22
- * @param {function(TeqFw_Di_Api_ObjectKey, TeqFw_Di_Api_ObjectKey):TeqFw_Di_Api_ObjectKey} hndl
23
- */
24
- this.addHandler = function (hndl) {
25
- _handlers.push(hndl);
26
- };
27
-
28
- /**
29
- * Get all pre-processing handlers.
30
- * @return {Array<function(TeqFw_Di_Api_ObjectKey, TeqFw_Di_Api_ObjectKey): TeqFw_Di_Api_ObjectKey>}
31
- */
32
- this.getHandlers = () => _handlers;
33
-
34
- /**
35
- * @param {TeqFw_Di_Api_ObjectKey} objectKey
36
- * @return {TeqFw_Di_Api_ObjectKey}
37
- */
38
- this.process = function (objectKey) {
39
- let res = objectKey;
40
- for (const one of _handlers)
41
- res = one(res, objectKey);
42
- return res;
43
- };
44
- }
45
- };
@@ -1,101 +0,0 @@
1
- /**
2
- * This is default parser that converts dependencies specification into array of depIds.
3
- * @namespace Spec.Parser
4
- */
5
- // IMPORTS
6
-
7
- // VARS
8
- const FN_ARW = /^.*\((\{[^}]*}|[^)]*)\)\s* =>.*$/s;
9
- const FN_CLASS = /class.*constructor.*\((.*)\).*/s;
10
- const FN_REG = /^function.*\((\{[^}]*}|[^)]*)\)\s*\{[^}]*}$/s;
11
-
12
- // FUNCS
13
-
14
- /**
15
- * Extract spec arguments from the class constructor '({...}=>{})
16
- * @param {string} spec
17
- * @return {null|string}
18
- */
19
- function specClass(spec) {
20
- const parts = FN_CLASS.exec(spec);
21
- if (parts?.[1]) {
22
- return parts[1].replace('{', '')
23
- .replace('}', '')
24
- .replace(/\n/g, ' ');
25
- }
26
- return null;
27
- }
28
-
29
- /**
30
- * Extract spec arguments from the arrow '({...}=>{})
31
- * @param {string} spec
32
- * @return {null|string}
33
- */
34
- function specFnArrow(spec) {
35
- const parts = FN_ARW.exec(spec);
36
- if (parts?.[1]) {
37
- return parts[1].replace('{', '')
38
- .replace('}', '')
39
- .replace(/\n/g, ' ');
40
- }
41
- return null;
42
- }
43
-
44
- /**
45
- * Extract spec arguments from the regular 'function({...})
46
- * @param {string} spec
47
- * @return {null|string}
48
- */
49
- function specFnRegular(spec) {
50
- const parts = FN_REG.exec(spec);
51
- if (parts?.[1]) {
52
- return parts[1].replace('{', '')
53
- .replace('}', '')
54
- .replace(/\n/g, ' ');
55
- }
56
- return null;
57
- }
58
-
59
- function argsComplex(args) {
60
- const res = [];
61
- /** @type {string[]} */
62
- const all = args.split(',');
63
- for (const one of all) {
64
- let arg = one.trim();
65
- if (arg.includes('[')) {
66
- // ['Vendor_App_Mod.arg1$$#adp']: arg1,
67
- const norm = arg.replaceAll('\'', '')
68
- .replaceAll('"', '')
69
- .replace('[', '')
70
- .replace(']', '');
71
- const parts = norm.split(':');
72
- res.push(parts[0]);
73
- } else if (arg.includes(':')) {
74
- // Vendor_App_Mod$$: arg1,
75
- const parts = arg.split(':');
76
- res.push(parts[0]);
77
- } else if (arg.length) {
78
- // Vendor_App_Mod$$
79
- res.push(arg);
80
- }
81
- }
82
- return res;
83
- }
84
-
85
- /**
86
- * @param {Object} factory
87
- * @return {string[]}
88
- */
89
- export default function (factory) {
90
- const res = [];
91
- if (typeof factory === 'function') {
92
- const def = factory.toString();
93
- let spec = specFnRegular(def);
94
- if (spec) return argsComplex(spec);
95
- spec = specFnArrow(def);
96
- if (spec) return argsComplex(spec);
97
- spec = specClass(def);
98
- if (spec) return argsComplex(spec);
99
- }
100
- return res;
101
- }