@nejs/basic-extensions 2.6.0 → 2.8.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/.vscode/settings.json +5 -0
- package/README.md +6129 -1574
- package/dist/@nejs/basic-extensions.bundle.2.7.0.js +19 -0
- package/dist/@nejs/basic-extensions.bundle.2.7.0.js.map +7 -0
- package/dist/cjs/array.extensions.d.ts +39 -0
- package/dist/cjs/array.extensions.js +303 -0
- package/dist/cjs/array.extensions.js.map +1 -0
- package/dist/cjs/big.int.extension.d.ts +31 -0
- package/dist/cjs/big.int.extension.js +164 -0
- package/dist/cjs/big.int.extension.js.map +1 -0
- package/dist/cjs/{newClasses → classes}/asyncIterable.js +32 -44
- package/dist/cjs/classes/asyncIterable.js.map +1 -0
- package/dist/cjs/{newClasses → classes}/deferred.js +66 -138
- package/dist/cjs/classes/deferred.js.map +1 -0
- package/dist/cjs/{newClasses → classes}/descriptor.js +56 -90
- package/dist/cjs/classes/descriptor.js.map +1 -0
- package/dist/cjs/classes/index.d.ts +13 -0
- package/dist/cjs/classes/index.js +57 -0
- package/dist/cjs/classes/index.js.map +1 -0
- package/dist/cjs/classes/introspector.d.ts +20 -0
- package/dist/cjs/classes/introspector.js +130 -0
- package/dist/cjs/classes/introspector.js.map +1 -0
- package/dist/cjs/{newClasses → classes}/iterable.js +42 -63
- package/dist/cjs/classes/iterable.js.map +1 -0
- package/dist/cjs/classes/param.parser.d.ts +227 -0
- package/dist/cjs/classes/param.parser.js +242 -0
- package/dist/cjs/classes/param.parser.js.map +1 -0
- package/dist/cjs/classes/pluggable.proxy.d.ts +152 -0
- package/dist/cjs/classes/pluggable.proxy.js +444 -0
- package/dist/cjs/classes/pluggable.proxy.js.map +1 -0
- package/dist/cjs/{newClasses → classes}/refmap.js +18 -30
- package/dist/cjs/classes/refmap.js.map +1 -0
- package/dist/cjs/{newClasses → classes}/refset.js +28 -47
- package/dist/cjs/classes/refset.js.map +1 -0
- package/dist/cjs/classes/symkeys.d.ts +292 -0
- package/dist/cjs/classes/symkeys.js +424 -0
- package/dist/cjs/classes/symkeys.js.map +1 -0
- package/dist/cjs/classes/type.d.ts +56 -0
- package/dist/cjs/classes/type.js +405 -0
- package/dist/cjs/classes/type.js.map +1 -0
- package/dist/cjs/function.extensions.js +757 -0
- package/dist/cjs/function.extensions.js.map +1 -0
- package/dist/cjs/global.this.js +261 -0
- package/dist/cjs/global.this.js.map +1 -0
- package/dist/cjs/index.d.ts +4 -3
- package/dist/cjs/index.js +62 -32
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/json.extensions.d.ts +2 -0
- package/dist/cjs/json.extensions.js +107 -0
- package/dist/cjs/json.extensions.js.map +1 -0
- package/dist/{mjs/mapextensions.d.ts → cjs/map.extensions.d.ts} +1 -0
- package/dist/cjs/map.extensions.js +142 -0
- package/dist/cjs/map.extensions.js.map +1 -0
- package/dist/cjs/number.extension.d.ts +44 -0
- package/dist/cjs/number.extension.js +260 -0
- package/dist/cjs/number.extension.js.map +1 -0
- package/dist/cjs/object.extensions.d.ts +62 -0
- package/dist/cjs/object.extensions.js +1116 -0
- package/dist/cjs/object.extensions.js.map +1 -0
- package/dist/cjs/proxy.extensions.d.ts +2 -0
- package/dist/cjs/proxy.extensions.js +207 -0
- package/dist/cjs/proxy.extensions.js.map +1 -0
- package/dist/cjs/reflect.extensions.js +316 -0
- package/dist/cjs/reflect.extensions.js.map +1 -0
- package/dist/cjs/regular.expression.extensions.d.ts +2 -0
- package/dist/cjs/regular.expression.extensions.js +423 -0
- package/dist/cjs/regular.expression.extensions.js.map +1 -0
- package/dist/cjs/set.extensions.d.ts +40 -0
- package/dist/cjs/{setextensions.js → set.extensions.js} +150 -2
- package/dist/cjs/set.extensions.js.map +1 -0
- package/dist/cjs/string.extensions.js +471 -0
- package/dist/cjs/string.extensions.js.map +1 -0
- package/dist/{mjs/symbolextensions.d.ts → cjs/symbol.extensions.d.ts} +1 -0
- package/dist/cjs/symbol.extensions.js +259 -0
- package/dist/cjs/symbol.extensions.js.map +1 -0
- package/dist/cjs/{weakrefextensions.js → weakref.extensions.js} +1 -1
- package/dist/cjs/weakref.extensions.js.map +1 -0
- package/dist/mjs/array.extensions.d.ts +39 -0
- package/dist/mjs/array.extensions.js +300 -0
- package/dist/mjs/array.extensions.js.map +1 -0
- package/dist/mjs/big.int.extension.d.ts +31 -0
- package/dist/mjs/big.int.extension.js +161 -0
- package/dist/mjs/big.int.extension.js.map +1 -0
- package/dist/mjs/classes/asyncIterable.js.map +1 -0
- package/dist/mjs/classes/deferred.js.map +1 -0
- package/dist/mjs/{newClasses → classes}/descriptor.js +7 -4
- package/dist/mjs/classes/descriptor.js.map +1 -0
- package/dist/mjs/classes/index.d.ts +13 -0
- package/dist/mjs/classes/index.js +40 -0
- package/dist/mjs/classes/index.js.map +1 -0
- package/dist/mjs/classes/introspector.d.ts +20 -0
- package/dist/mjs/classes/introspector.js +126 -0
- package/dist/mjs/classes/introspector.js.map +1 -0
- package/dist/mjs/classes/iterable.js.map +1 -0
- package/dist/mjs/classes/param.parser.d.ts +227 -0
- package/dist/mjs/classes/param.parser.js +238 -0
- package/dist/mjs/classes/param.parser.js.map +1 -0
- package/dist/mjs/classes/pluggable.proxy.d.ts +152 -0
- package/dist/mjs/classes/pluggable.proxy.js +438 -0
- package/dist/mjs/classes/pluggable.proxy.js.map +1 -0
- package/dist/mjs/{newClasses → classes}/refmap.js +3 -3
- package/dist/mjs/classes/refmap.js.map +1 -0
- package/dist/mjs/classes/refset.js.map +1 -0
- package/dist/mjs/classes/symkeys.d.ts +292 -0
- package/dist/mjs/classes/symkeys.js +420 -0
- package/dist/mjs/classes/symkeys.js.map +1 -0
- package/dist/mjs/classes/type.d.ts +56 -0
- package/dist/mjs/classes/type.js +401 -0
- package/dist/mjs/classes/type.js.map +1 -0
- package/dist/mjs/function.extensions.js +754 -0
- package/dist/mjs/function.extensions.js.map +1 -0
- package/dist/mjs/global.this.js +258 -0
- package/dist/mjs/global.this.js.map +1 -0
- package/dist/mjs/index.d.ts +4 -3
- package/dist/mjs/index.js +49 -19
- package/dist/mjs/index.js.map +1 -1
- package/dist/mjs/json.extensions.d.ts +2 -0
- package/dist/mjs/json.extensions.js +104 -0
- package/dist/mjs/json.extensions.js.map +1 -0
- package/dist/{cjs/mapextensions.d.ts → mjs/map.extensions.d.ts} +1 -0
- package/dist/mjs/map.extensions.js +139 -0
- package/dist/mjs/map.extensions.js.map +1 -0
- package/dist/mjs/number.extension.d.ts +44 -0
- package/dist/mjs/number.extension.js +257 -0
- package/dist/mjs/number.extension.js.map +1 -0
- package/dist/mjs/object.extensions.d.ts +62 -0
- package/dist/mjs/object.extensions.js +1112 -0
- package/dist/mjs/object.extensions.js.map +1 -0
- package/dist/mjs/proxy.extensions.d.ts +2 -0
- package/dist/mjs/proxy.extensions.js +204 -0
- package/dist/mjs/proxy.extensions.js.map +1 -0
- package/dist/mjs/reflect.extensions.js +313 -0
- package/dist/mjs/reflect.extensions.js.map +1 -0
- package/dist/mjs/regular.expression.extensions.d.ts +2 -0
- package/dist/mjs/regular.expression.extensions.js +420 -0
- package/dist/mjs/regular.expression.extensions.js.map +1 -0
- package/dist/mjs/set.extensions.d.ts +40 -0
- package/dist/mjs/{setextensions.js → set.extensions.js} +149 -1
- package/dist/mjs/set.extensions.js.map +1 -0
- package/dist/mjs/string.extensions.js +468 -0
- package/dist/mjs/string.extensions.js.map +1 -0
- package/dist/{cjs/symbolextensions.d.ts → mjs/symbol.extensions.d.ts} +1 -0
- package/dist/mjs/symbol.extensions.js +256 -0
- package/dist/mjs/symbol.extensions.js.map +1 -0
- package/dist/mjs/{weakrefextensions.js → weakref.extensions.js} +1 -1
- package/dist/mjs/weakref.extensions.js.map +1 -0
- package/docs/index.html +24045 -5805
- package/package.json +6 -4
- package/repl.bootstrap.js +21 -0
- package/src/array.extensions.js +322 -0
- package/src/big.int.extension.js +163 -0
- package/src/{newClasses → classes}/descriptor.js +16 -12
- package/src/classes/index.js +51 -0
- package/src/classes/introspector.js +167 -0
- package/src/classes/param.parser.js +253 -0
- package/src/classes/pluggable.proxy.js +485 -0
- package/src/{newClasses → classes}/refmap.js +5 -3
- package/src/classes/symkeys.js +464 -0
- package/src/classes/type.js +427 -0
- package/src/function.extensions.js +818 -0
- package/src/global.this.js +304 -0
- package/src/index.js +56 -23
- package/src/json.extensions.js +108 -0
- package/src/map.extensions.js +144 -0
- package/src/number.extension.js +273 -0
- package/src/object.extensions.js +1222 -0
- package/src/proxy.extensions.js +229 -0
- package/src/reflect.extensions.js +346 -0
- package/src/regular.expression.extensions.js +451 -0
- package/src/{setextensions.js → set.extensions.js} +151 -2
- package/src/string.extensions.js +515 -0
- package/src/symbol.extensions.js +268 -0
- package/tests/newClasses/refmap.test.js +3 -2
- package/tsconfig.base.json +5 -3
- package/tsconfig.cjs.json +2 -2
- package/tsconfig.esm.json +2 -2
- package/dist/@nejs/basic-extensions.bundle.2.5.0.js +0 -8
- package/dist/@nejs/basic-extensions.bundle.2.5.0.js.map +0 -7
- package/dist/cjs/arrayextensions.d.ts +0 -10
- package/dist/cjs/arrayextensions.js +0 -73
- package/dist/cjs/arrayextensions.js.map +0 -1
- package/dist/cjs/functionextensions.js +0 -202
- package/dist/cjs/functionextensions.js.map +0 -1
- package/dist/cjs/globals.js +0 -166
- package/dist/cjs/globals.js.map +0 -1
- package/dist/cjs/mapextensions.js +0 -32
- package/dist/cjs/mapextensions.js.map +0 -1
- package/dist/cjs/newClasses/asyncIterable.js.map +0 -1
- package/dist/cjs/newClasses/deferred.js.map +0 -1
- package/dist/cjs/newClasses/descriptor.js.map +0 -1
- package/dist/cjs/newClasses/iterable.js.map +0 -1
- package/dist/cjs/newClasses/refmap.js.map +0 -1
- package/dist/cjs/newClasses/refset.js.map +0 -1
- package/dist/cjs/objectextensions.d.ts +0 -11
- package/dist/cjs/objectextensions.js +0 -232
- package/dist/cjs/objectextensions.js.map +0 -1
- package/dist/cjs/reflectextensions.js +0 -111
- package/dist/cjs/reflectextensions.js.map +0 -1
- package/dist/cjs/setextensions.d.ts +0 -2
- package/dist/cjs/setextensions.js.map +0 -1
- package/dist/cjs/stringextensions.js +0 -158
- package/dist/cjs/stringextensions.js.map +0 -1
- package/dist/cjs/symbolextensions.js +0 -69
- package/dist/cjs/symbolextensions.js.map +0 -1
- package/dist/cjs/weakrefextensions.js.map +0 -1
- package/dist/mjs/arrayextensions.d.ts +0 -10
- package/dist/mjs/arrayextensions.js +0 -70
- package/dist/mjs/arrayextensions.js.map +0 -1
- package/dist/mjs/functionextensions.js +0 -199
- package/dist/mjs/functionextensions.js.map +0 -1
- package/dist/mjs/globals.js +0 -163
- package/dist/mjs/globals.js.map +0 -1
- package/dist/mjs/mapextensions.js +0 -29
- package/dist/mjs/mapextensions.js.map +0 -1
- package/dist/mjs/newClasses/asyncIterable.js.map +0 -1
- package/dist/mjs/newClasses/deferred.js.map +0 -1
- package/dist/mjs/newClasses/descriptor.js.map +0 -1
- package/dist/mjs/newClasses/iterable.js.map +0 -1
- package/dist/mjs/newClasses/refmap.js.map +0 -1
- package/dist/mjs/newClasses/refset.js.map +0 -1
- package/dist/mjs/objectextensions.d.ts +0 -11
- package/dist/mjs/objectextensions.js +0 -229
- package/dist/mjs/objectextensions.js.map +0 -1
- package/dist/mjs/reflectextensions.js +0 -108
- package/dist/mjs/reflectextensions.js.map +0 -1
- package/dist/mjs/setextensions.d.ts +0 -2
- package/dist/mjs/setextensions.js.map +0 -1
- package/dist/mjs/stringextensions.js +0 -155
- package/dist/mjs/stringextensions.js.map +0 -1
- package/dist/mjs/symbolextensions.js +0 -66
- package/dist/mjs/symbolextensions.js.map +0 -1
- package/dist/mjs/weakrefextensions.js.map +0 -1
- package/src/arrayextensions.js +0 -75
- package/src/functionextensions.js +0 -225
- package/src/globals.js +0 -196
- package/src/mapextensions.js +0 -32
- package/src/objectextensions.js +0 -256
- package/src/reflectextensions.js +0 -118
- package/src/stringextensions.js +0 -166
- package/src/symbolextensions.js +0 -69
- /package/dist/cjs/{newClasses → classes}/asyncIterable.d.ts +0 -0
- /package/dist/cjs/{newClasses → classes}/deferred.d.ts +0 -0
- /package/dist/cjs/{newClasses → classes}/descriptor.d.ts +0 -0
- /package/dist/cjs/{newClasses → classes}/iterable.d.ts +0 -0
- /package/dist/cjs/{newClasses → classes}/refmap.d.ts +0 -0
- /package/dist/cjs/{newClasses → classes}/refset.d.ts +0 -0
- /package/dist/cjs/{functionextensions.d.ts → function.extensions.d.ts} +0 -0
- /package/dist/cjs/{globals.d.ts → global.this.d.ts} +0 -0
- /package/dist/cjs/{reflectextensions.d.ts → reflect.extensions.d.ts} +0 -0
- /package/dist/cjs/{stringextensions.d.ts → string.extensions.d.ts} +0 -0
- /package/dist/cjs/{weakrefextensions.d.ts → weakref.extensions.d.ts} +0 -0
- /package/dist/mjs/{newClasses → classes}/asyncIterable.d.ts +0 -0
- /package/dist/mjs/{newClasses → classes}/asyncIterable.js +0 -0
- /package/dist/mjs/{newClasses → classes}/deferred.d.ts +0 -0
- /package/dist/mjs/{newClasses → classes}/deferred.js +0 -0
- /package/dist/mjs/{newClasses → classes}/descriptor.d.ts +0 -0
- /package/dist/mjs/{newClasses → classes}/iterable.d.ts +0 -0
- /package/dist/mjs/{newClasses → classes}/iterable.js +0 -0
- /package/dist/mjs/{newClasses → classes}/refmap.d.ts +0 -0
- /package/dist/mjs/{newClasses → classes}/refset.d.ts +0 -0
- /package/dist/mjs/{newClasses → classes}/refset.js +0 -0
- /package/dist/mjs/{functionextensions.d.ts → function.extensions.d.ts} +0 -0
- /package/dist/mjs/{globals.d.ts → global.this.d.ts} +0 -0
- /package/dist/mjs/{reflectextensions.d.ts → reflect.extensions.d.ts} +0 -0
- /package/dist/mjs/{stringextensions.d.ts → string.extensions.d.ts} +0 -0
- /package/dist/mjs/{weakrefextensions.d.ts → weakref.extensions.d.ts} +0 -0
- /package/src/{newClasses → classes}/asyncIterable.js +0 -0
- /package/src/{newClasses → classes}/deferred.js +0 -0
- /package/src/{newClasses → classes}/iterable.js +0 -0
- /package/src/{newClasses → classes}/refset.js +0 -0
- /package/src/{weakrefextensions.js → weakref.extensions.js} +0 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { Extension } from '@nejs/extension'
|
|
2
|
+
|
|
3
|
+
export class Introspector {
|
|
4
|
+
static addExpansion(array) {
|
|
5
|
+
const toEntriesFrom = (owner = globalThis) => {
|
|
6
|
+
return (accumulator, key) => {
|
|
7
|
+
const count = accumulator.length;
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
const value = owner[key]
|
|
11
|
+
accumulator.splice(count, 0, [key, value], [value, key])
|
|
12
|
+
}
|
|
13
|
+
catch (error) { accumulator.splice(count, 0, [key, error]) }
|
|
14
|
+
|
|
15
|
+
return accumulator
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return Object.defineProperty(array, 'expand', {
|
|
20
|
+
get() {
|
|
21
|
+
return new Map(
|
|
22
|
+
this.reduce(toEntriesFrom(globalThis), [])
|
|
23
|
+
)
|
|
24
|
+
},
|
|
25
|
+
configurable: true,
|
|
26
|
+
enumerable: true,
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static accessors(owner = globalThis, keys = []) {
|
|
31
|
+
const entries = []
|
|
32
|
+
|
|
33
|
+
for (const key of keys) {
|
|
34
|
+
try {
|
|
35
|
+
const metadata = this.metadata(owner, key)
|
|
36
|
+
if (metadata.get || metadata.set) {
|
|
37
|
+
entries.push([key, metadata])
|
|
38
|
+
}
|
|
39
|
+
continue
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
entries.push([key, error])
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return new Map(entries)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static classes(owner = globalThis) {
|
|
50
|
+
return this.fetcher(
|
|
51
|
+
'function', /^[A-Z]/, Object, 'getOwnPropertyNames', owner
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static functions(owner = globalThis) {
|
|
56
|
+
return this.fetcher(
|
|
57
|
+
'function', /^[a-z]/, Object, 'getOwnPropertyNames', owner
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static objects(owner = globalThis) {
|
|
62
|
+
return this.fetcher('object', null, Object, 'getOwnPropertyNames', owner)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static properties(owner = globalThis) {
|
|
66
|
+
return this.fetcher(
|
|
67
|
+
(v,t,d) => t !== 'object' && t !== 'function',
|
|
68
|
+
null, Object, 'getOwnPropertyNames', owner
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static symbols(owner = globalThis) {
|
|
73
|
+
return this.addExpansion(Object.getOwnPropertySymbols(owner))
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static metadata(owner, key) {
|
|
77
|
+
const metadata = {
|
|
78
|
+
owner, key,
|
|
79
|
+
descriptor: undefined,
|
|
80
|
+
value: undefined,
|
|
81
|
+
get type() { return typeof this.value },
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try { metadata.descriptor = Object.getOwnPropertyDescriptor(owner, key) }
|
|
85
|
+
catch(error) { metadata.descriptor = error }
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
metadata.value = (
|
|
89
|
+
metadata.descriptor?.value ??
|
|
90
|
+
metadata.descriptor?.get?.bind(owner)?.() ??
|
|
91
|
+
owner[key]
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
catch(error) { metadata.value = error }
|
|
95
|
+
|
|
96
|
+
return metadata
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static fetcher(
|
|
100
|
+
typeNameOrTyperFn,
|
|
101
|
+
regExp = undefined,
|
|
102
|
+
searchClass = Object,
|
|
103
|
+
searchFunction = 'getOwnPropertyNames',
|
|
104
|
+
owner = globalThis
|
|
105
|
+
) {
|
|
106
|
+
let typer = typeNameOrTyperFn
|
|
107
|
+
|
|
108
|
+
if (typeof typeNameOrTyperFn !== 'function') {
|
|
109
|
+
const type = String(typeNameOrTyperFn)
|
|
110
|
+
typer = (function(value, typeName, descriptor) {
|
|
111
|
+
return typeName === type
|
|
112
|
+
}).bind(this)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return this.addExpansion(
|
|
116
|
+
searchClass[searchFunction](owner).filter(key => {
|
|
117
|
+
const metadata = this.metadata(owner, key)
|
|
118
|
+
return (
|
|
119
|
+
(!regExp || regExp.exec(String(key))) &&
|
|
120
|
+
typer(metadata.value, metadata.type, metadata.descriptor)
|
|
121
|
+
)
|
|
122
|
+
}).toSorted()
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
static makeReport(owner = globalThis) {
|
|
127
|
+
let names = [
|
|
128
|
+
'classes', 'functions', 'objects', 'properties', 'symbols', 'accessors'
|
|
129
|
+
];
|
|
130
|
+
let bound = names.reduce(
|
|
131
|
+
(a,n) => { a[n] = this[n].bind(this); return a },
|
|
132
|
+
{}
|
|
133
|
+
)
|
|
134
|
+
const { classes, functions, objects, properties, symbols, accessors } = bound
|
|
135
|
+
const result = { }
|
|
136
|
+
|
|
137
|
+
Object.assign(result, {
|
|
138
|
+
accessors: {
|
|
139
|
+
classes: undefined,
|
|
140
|
+
functions: undefined,
|
|
141
|
+
objects: undefined,
|
|
142
|
+
properties: undefined,
|
|
143
|
+
symbols: undefined,
|
|
144
|
+
},
|
|
145
|
+
classes: this[classes.name](),
|
|
146
|
+
functions: this[functions.name](),
|
|
147
|
+
objects: this[objects.name](),
|
|
148
|
+
properties: this[properties.name](),
|
|
149
|
+
symbols: this[symbols.name](),
|
|
150
|
+
expandAll() {
|
|
151
|
+
names.forEach(reportName => {
|
|
152
|
+
result[reportName] = result?.[reportName]?.expand
|
|
153
|
+
})
|
|
154
|
+
},
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
(names.forEach(type => {
|
|
158
|
+
debugger
|
|
159
|
+
result.accessors[type] = accessors(globalThis, result[type])
|
|
160
|
+
})
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
return result
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export const IntrospectorExtensions = new Extension(Introspector);
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { Extension } from '@nejs/extension'
|
|
2
|
+
|
|
3
|
+
export class ParamParser {
|
|
4
|
+
/**
|
|
5
|
+
* Constructs an instance of ParamParser. It takes in parameters, an optional
|
|
6
|
+
* validator function, and an optional parser function. The parameters are
|
|
7
|
+
* validated and if successful, parsed.
|
|
8
|
+
*
|
|
9
|
+
* @param {any[]} parameters - Arguments passed in by the process.
|
|
10
|
+
* @param {((any[]) => boolean)?} [validator=() => {}] - An optional function
|
|
11
|
+
* to specify a validator without subclassing ParamParser. It should return
|
|
12
|
+
* a boolean indicating the validity of the parameters.
|
|
13
|
+
* @param {((any[]) => object)?} [parser=() => {}] - An optional function to
|
|
14
|
+
* specify a parser without subclassing ParamParser. It should return an
|
|
15
|
+
* object after parsing the input parameters.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* const parameters = ['param1', 'param2']
|
|
19
|
+
* const validator = params => params.every(param => typeof param === 'string')
|
|
20
|
+
* const parser = params => ({ params })
|
|
21
|
+
* const paramParser = new ParamParser(parameters, validator, parser)
|
|
22
|
+
* if (paramParser.success) {
|
|
23
|
+
* console.log('Parsing successful:', paramParser.results)
|
|
24
|
+
* } else {
|
|
25
|
+
* console.error('Parsing failed.')
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
constructor(parameters, validator = () => {}, parser = () => {}) {
|
|
29
|
+
this.args = parameters
|
|
30
|
+
this.parser = parser
|
|
31
|
+
this.validator = validator
|
|
32
|
+
this.result = undefined
|
|
33
|
+
this.success = this.validate(this.args)
|
|
34
|
+
|
|
35
|
+
if (this.success) {
|
|
36
|
+
this.results = this.parse(this.args)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {object} args arguments that were previously validated
|
|
42
|
+
* by either the overloaded validate() method or the supplied
|
|
43
|
+
* validator closure.
|
|
44
|
+
* @returns {object} returns the output object, or an empty
|
|
45
|
+
* object, after parsing the input arguments or parameters.
|
|
46
|
+
*/
|
|
47
|
+
parse(args) {
|
|
48
|
+
return this.parser?.(args);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Walk the arguments and determine if the supplied input is
|
|
53
|
+
* a valid parsing.
|
|
54
|
+
*
|
|
55
|
+
* @param {any[]} args arguments supplied by the process.
|
|
56
|
+
* @returns {boolean} `true` if the validation is successful,
|
|
57
|
+
* `false` otherwise.
|
|
58
|
+
*/
|
|
59
|
+
validate(args) {
|
|
60
|
+
return this.validator?.(args);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Attempts to parse the given parameters using the provided parsers, throwing an
|
|
65
|
+
* error if no valid parser is found. This method serves as a convenience wrapper
|
|
66
|
+
* around `safeTryParsers`, enforcing strict parsing by automatically enabling
|
|
67
|
+
* error throwing on failure.
|
|
68
|
+
*
|
|
69
|
+
* @param {any[]} parameters - The parameters to be parsed.
|
|
70
|
+
* @param {Function[]} parsers - An array of `ParamParser` subclasses to attempt
|
|
71
|
+
* parsing with.
|
|
72
|
+
* @returns {Object} An object containing the parsing result, with a `success`
|
|
73
|
+
* property indicating if parsing was successful, and a `data` property containing
|
|
74
|
+
* the parsed data if successful.
|
|
75
|
+
* @example
|
|
76
|
+
* const parameters = ['param1', 'param2'];
|
|
77
|
+
* const parsers = [Parser1, Parser2];
|
|
78
|
+
* const result = ParamParser.tryParsers(parameters, parsers);
|
|
79
|
+
* if (result.success) {
|
|
80
|
+
* console.log('Parsing successful:', result.data);
|
|
81
|
+
* } else {
|
|
82
|
+
* console.error('Parsing failed.');
|
|
83
|
+
* }
|
|
84
|
+
*/
|
|
85
|
+
static tryParsers(parameters, parsers) {
|
|
86
|
+
return this.safeTryParsers(parameters, parsers, true)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Tries parsing `parameters` with each parser in `parsers`. If
|
|
91
|
+
* `throwOnFail` is true, throws an error when validation fails or
|
|
92
|
+
* no valid parser is found.
|
|
93
|
+
*
|
|
94
|
+
* This method attempts to parse the given parameters using the
|
|
95
|
+
* provided list of parsers. It validates the input to ensure both
|
|
96
|
+
* `parameters` and `parsers` are arrays and that `parsers`
|
|
97
|
+
* contains at least one valid `ParamParser` subclass. If
|
|
98
|
+
* `throwOnFail` is set to true, it will throw specific errors for
|
|
99
|
+
* invalid inputs or when no parser succeeds. Otherwise, it returns
|
|
100
|
+
* an object indicating the success status and the result of
|
|
101
|
+
* parsing, if successful.
|
|
102
|
+
*
|
|
103
|
+
* @param {any[]} parameters - The parameters to be parsed.
|
|
104
|
+
* @param {Function[]} parsers - An array of `ParamParser`
|
|
105
|
+
* subclasses to attempt parsing with.
|
|
106
|
+
* @param {boolean} [throwOnFail=false] - Whether to throw an
|
|
107
|
+
* error on failure.
|
|
108
|
+
* @returns {{success: boolean, data: any}} An object with a
|
|
109
|
+
* `success` flag and `data` containing the parsing result, if
|
|
110
|
+
* successful.
|
|
111
|
+
* @throws {ParametersMustBeArrayError} If `parameters` or
|
|
112
|
+
* `parsers` are not arrays when `throwOnFail` is true.
|
|
113
|
+
* @throws {ParsersArrayMustContainParsersError} If `parsers`
|
|
114
|
+
* does not contain at least one valid `ParamParser` subclass
|
|
115
|
+
* when `throwOnFail` is true.
|
|
116
|
+
* @throws {NoValidParsersFound} If no valid parser is found
|
|
117
|
+
* and `throwOnFail` is true.
|
|
118
|
+
* @example
|
|
119
|
+
* const parameters = ['param1', 'param2'];
|
|
120
|
+
* const parsers = [Parser1, Parser2];
|
|
121
|
+
* const result = ParamParser.safeTryParsers(
|
|
122
|
+
* parameters, parsers, true
|
|
123
|
+
* );
|
|
124
|
+
*
|
|
125
|
+
* if (result.success) {
|
|
126
|
+
* console.log('Parsing successful:', result.data);
|
|
127
|
+
* } else {
|
|
128
|
+
* console.error('Parsing failed.');
|
|
129
|
+
* }
|
|
130
|
+
*/
|
|
131
|
+
static safeTryParsers(parameters, parsers, throwOnFail = false) {
|
|
132
|
+
if (!Array.isArray(parameters) || !Array.isArray(parsers)) {
|
|
133
|
+
if (throwOnFail) {
|
|
134
|
+
throw new this.ParametersMustBeArrayError(
|
|
135
|
+
`${this.name}.tryParsers must receive two arrays as args`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (!parsers.some(parser => parser?.prototype instanceof ParamParser &&
|
|
141
|
+
typeof parser === 'function')) {
|
|
142
|
+
if (throwOnFail) {
|
|
143
|
+
throw new this.ParsersArrayMustContainParsersError(
|
|
144
|
+
`${this.name}.tryParsers parsers argument must contain at least one ` +
|
|
145
|
+
`ParamParser derived class`
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
let success = false;
|
|
151
|
+
let result = undefined;
|
|
152
|
+
|
|
153
|
+
for (let Parser of parsers) {
|
|
154
|
+
const parser = new Parser(parameters);
|
|
155
|
+
if (parser.success) {
|
|
156
|
+
success = true;
|
|
157
|
+
result = parser.result;
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!success && throwOnFail) {
|
|
163
|
+
throw new this.NoValidParsersFound('No valid parsers found');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return { success, data: result };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* A custom error class that signifies no valid parsers were found
|
|
171
|
+
* during the parsing process. This error is thrown when all
|
|
172
|
+
* parsers fail to parse the given parameters and the `throwOnFail`
|
|
173
|
+
* flag is set to true in the `safeTryParsers` method.
|
|
174
|
+
*
|
|
175
|
+
* @returns {Function} A class extending Error, representing a
|
|
176
|
+
* specific error when no valid parsers are found.ound.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* try {
|
|
180
|
+
* const result = ParamParser.safeTryParsers(
|
|
181
|
+
* parameters, parsers, true
|
|
182
|
+
* );
|
|
183
|
+
* } catch (error) {
|
|
184
|
+
* if (error instanceof ParamParser.NoValidParsersFound) {
|
|
185
|
+
* console.error(
|
|
186
|
+
* 'No valid parsers could process the parameters.'
|
|
187
|
+
* );
|
|
188
|
+
* }
|
|
189
|
+
* }
|
|
190
|
+
*/
|
|
191
|
+
static get NoValidParsersFound() {
|
|
192
|
+
return class NoValidParsersFound extends Error { }
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Represents an error thrown when the parameters provided to a method
|
|
197
|
+
* are not in an array format as expected. This class extends the
|
|
198
|
+
* native JavaScript `Error` class, allowing for instances of this
|
|
199
|
+
* error to be thrown and caught using standard error handling
|
|
200
|
+
* mechanisms in JavaScript.
|
|
201
|
+
*
|
|
202
|
+
* This error is specifically used in scenarios where a method
|
|
203
|
+
* expects its arguments to be provided as an array, and the
|
|
204
|
+
* validation of those arguments fails because they were not
|
|
205
|
+
* provided in an array format. It serves as a clear indicator
|
|
206
|
+
* of the nature of the error to developers, enabling them to
|
|
207
|
+
* quickly identify and rectify the issue in their code.
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* try {
|
|
211
|
+
* ParamParser.safeTryParsers(nonArrayParameters, parsers, true);
|
|
212
|
+
* } catch (error) {
|
|
213
|
+
* if (error instanceof ParamParser.ParametersMustBeArrayError) {
|
|
214
|
+
* console.error('Parameters must be provided as an array.');
|
|
215
|
+
* }
|
|
216
|
+
* }
|
|
217
|
+
*/
|
|
218
|
+
static get ParametersMustBeArrayError() {
|
|
219
|
+
return class ParametersMustBeArrayError extends Error { }
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* A custom error class indicating that the parsers array does not
|
|
224
|
+
* contain valid parser functions. This error is thrown when the
|
|
225
|
+
* validation of parsers within `ParamParser.safeTryParsers` fails
|
|
226
|
+
* to find any instance that is a subclass of `ParamParser`. It
|
|
227
|
+
* extends the native JavaScript `Error` class, allowing it to be
|
|
228
|
+
* thrown and caught using standard error handling mechanisms.
|
|
229
|
+
*
|
|
230
|
+
* This error serves as a clear indicator to developers that the
|
|
231
|
+
* provided array of parsers does not meet the expected criteria,
|
|
232
|
+
* specifically that it must contain at least one valid parser
|
|
233
|
+
* that extends `ParamParser`. This ensures that the parsing
|
|
234
|
+
* process can be executed with at least one valid parser function.
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* try {
|
|
238
|
+
* ParamParser.safeTryParsers(parameters, [], true);
|
|
239
|
+
* } catch (error) {
|
|
240
|
+
* const { ParsersArrayMustContainParsersError } = ParamParser
|
|
241
|
+
* if (error instanceof ParsersArrayMustContainParsersError) {
|
|
242
|
+
* console.error(
|
|
243
|
+
* 'The parsers array must contain at least one valid parser.'
|
|
244
|
+
* );
|
|
245
|
+
* }
|
|
246
|
+
* }
|
|
247
|
+
*/
|
|
248
|
+
static get ParsersArrayMustContainParsersError() {
|
|
249
|
+
return class ParsersArrayMustContainParsersError extends Error { }
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export const ParamParserExtensions = new Extension(ParamParser);
|