@lumjs/core 1.26.0 → 1.30.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/README.md +14 -0
- package/lib/console.js +54 -0
- package/lib/enum.js +27 -6
- package/lib/index.js +12 -16
- package/lib/meta.js +68 -88
- package/lib/obj/clone.js +1 -1
- package/lib/obj/copyprops.js +1 -1
- package/lib/obj/merge.js +1 -1
- package/lib/obj/ns.js +1 -1
- package/lib/objectid.js +34 -13
- package/lib/observable.js +1 -1
- package/lib/old/abstractclass.js +82 -0
- package/lib/opt/args.js +50 -0
- package/lib/opt/getpath.js +70 -0
- package/lib/opt/getval.js +61 -0
- package/lib/opt/index.js +21 -0
- package/lib/opt/val.js +63 -0
- package/lib/strings.js +1 -1
- package/lib/types/basics.js +43 -16
- package/lib/types/def.js +49 -36
- package/lib/types/dt.js +147 -18
- package/lib/types/index.js +35 -59
- package/lib/types/isa.js +4 -0
- package/lib/types/js.js +29 -12
- package/lib/types/lazy.js +3 -2
- package/lib/types/needs.js +0 -1
- package/package.json +7 -3
- package/lib/opt.js +0 -664
package/lib/opt.js
DELETED
|
@@ -1,664 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Functions for working with options and default values.
|
|
3
|
-
* @module @lumjs/core/opt
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
{
|
|
8
|
-
U,F,S,N,B,
|
|
9
|
-
isObj,isComplex,isArray,isNil,needObj,needType
|
|
10
|
-
} = require('./types');
|
|
11
|
-
const {insert} = require('./arrays/add');
|
|
12
|
-
const {getObjectPath} = require('./obj/ns');
|
|
13
|
-
|
|
14
|
-
// Aliases for Opts#get() and Opts#find()
|
|
15
|
-
const OPTS_ALIASES =
|
|
16
|
-
{
|
|
17
|
-
'null': 'allowNull',
|
|
18
|
-
'lazy': 'isLazy',
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* A helper to support both positional arguments and named
|
|
23
|
-
* options in the same method signature.
|
|
24
|
-
*
|
|
25
|
-
* @param {object} opts - Options built from positional arguments
|
|
26
|
-
*
|
|
27
|
-
* Keep in mind that this object **WILL** be modified!
|
|
28
|
-
*
|
|
29
|
-
* @param {string} optArg - The option that may contain named options
|
|
30
|
-
*
|
|
31
|
-
* Generally the name of the first positional argument that may be
|
|
32
|
-
* an `object` full of options or a different positional argument value.
|
|
33
|
-
*
|
|
34
|
-
* The biggest limitation is that it cannot be an `object` value when used
|
|
35
|
-
* as a positional argument, as that will always be seen as the _options_.
|
|
36
|
-
*
|
|
37
|
-
* @param {*} optDef - A default value for `opts[optArg]`
|
|
38
|
-
*
|
|
39
|
-
* If `opts[optArg]` was an `object`, we'll compose its properties
|
|
40
|
-
* into `opts` directly. If after that `opts[optArg]` is still the
|
|
41
|
-
* options `object` then this value will be used instead.
|
|
42
|
-
*
|
|
43
|
-
* @param {boolean} [validate=true] Ensure `opts` is an object?
|
|
44
|
-
*
|
|
45
|
-
* Should only be disabled if you know for certain it is.
|
|
46
|
-
*
|
|
47
|
-
* @example <caption>Example usage</caption>
|
|
48
|
-
*
|
|
49
|
-
* function example(first=true, second=null, third="test")
|
|
50
|
-
* {
|
|
51
|
-
* const opts = argOpts({first, second, third}, 'first', true);
|
|
52
|
-
* }
|
|
53
|
-
*
|
|
54
|
-
* @alias module:@lumjs/core/opt.argOpts
|
|
55
|
-
*/
|
|
56
|
-
function argOpts(opts, optArg, optDef, validate=true)
|
|
57
|
-
{
|
|
58
|
-
if (validate) needObj(opts, false, 'invalid opts object');
|
|
59
|
-
|
|
60
|
-
if (isObj(opts[optArg]))
|
|
61
|
-
{ // Merge the named options.
|
|
62
|
-
const specOpts = opts[optArg];
|
|
63
|
-
Object.assign(opts, specOpts);
|
|
64
|
-
if (opts[optArg] === specOpts)
|
|
65
|
-
{ // specOpts didn't override the real option.
|
|
66
|
-
opts[optArg] = optDef;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
} // argOpts()
|
|
71
|
-
|
|
72
|
-
exports.argOpts = argOpts;
|
|
73
|
-
|
|
74
|
-
// Private helper for `val()` and `get()` to support new-style options.
|
|
75
|
-
function _opts(opts, defNull)
|
|
76
|
-
{
|
|
77
|
-
return argOpts(opts, 'allowNull', defNull, false);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* See if a value is *set*, and if not, return a default value.
|
|
82
|
-
*
|
|
83
|
-
* This function used to use all positional arguments, but it now
|
|
84
|
-
* supports named options if an `object` is passed as the third argument.
|
|
85
|
-
* If both named options and the corresponding positional arguments are
|
|
86
|
-
* specified, the named options will take precedence.
|
|
87
|
-
*
|
|
88
|
-
* @param {*} optvalue - The value we are testing.
|
|
89
|
-
* @param {*} defvalue - The default value if opt was null or undefined.
|
|
90
|
-
*
|
|
91
|
-
* @param {(object|boolean)} opts - Options
|
|
92
|
-
*
|
|
93
|
-
* If this is a `boolean` it is used as the `allowNull` option.
|
|
94
|
-
*
|
|
95
|
-
* @param {boolean} [opts.allowNull=false] If true, allow null to count as *set*.
|
|
96
|
-
* @param {boolean} [opts.isLazy=false] If true, and `defvalue` is a function,
|
|
97
|
-
* use the value from the function as
|
|
98
|
-
* the default.
|
|
99
|
-
* @param {object} [opts.lazyThis=null] If `isLazy` is true, this object will
|
|
100
|
-
* be used as `this` for the function.
|
|
101
|
-
* @param {Array} [opts.lazyArgs] If `isLazy` is true, this may be used
|
|
102
|
-
* as a list of arguments to pass.
|
|
103
|
-
*
|
|
104
|
-
* @param {boolean} [isLazy=false] Same as `opts.isLazy`
|
|
105
|
-
* @param {object} [lazyThis=null] Same as `opts.lazyThis`
|
|
106
|
-
* @param {Array} [lazyArgs] Same as `opts.lazyArgs`
|
|
107
|
-
*
|
|
108
|
-
* @return {*} Either `optvalue` or `defvalue` depending on the test.
|
|
109
|
-
* @alias module:@lumjs/core/opt.val
|
|
110
|
-
*/
|
|
111
|
-
function val(optvalue, defvalue,
|
|
112
|
-
allowNull=false,
|
|
113
|
-
isLazy=false,
|
|
114
|
-
lazyThis=null,
|
|
115
|
-
lazyArgs=[])
|
|
116
|
-
{
|
|
117
|
-
const opts = _opts({allowNull,isLazy,lazyThis,lazyArgs}, false);
|
|
118
|
-
|
|
119
|
-
if (typeof optvalue === U || (!opts.allowNull && optvalue === null))
|
|
120
|
-
{ // The defined value was not "set" as per our rules.
|
|
121
|
-
if (opts.isLazy && typeof defvalue === F)
|
|
122
|
-
{ // Get the default value from a passed in function.
|
|
123
|
-
return defvalue.apply(opts.lazyThis, opts.lazyArgs);
|
|
124
|
-
}
|
|
125
|
-
return defvalue;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return optvalue;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
exports.val = val;
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* See if a property in an object is set.
|
|
135
|
-
*
|
|
136
|
-
* If it is, return the property, otherwise return a default value.
|
|
137
|
-
* This uses the `val()` method, and as such supports the same arguments.
|
|
138
|
-
* However read the descriptions, as defaults may be quite different!
|
|
139
|
-
*
|
|
140
|
-
* @param {object} obj - An object to test for a property in.
|
|
141
|
-
* @param {string} optname - The property name we're checking for.
|
|
142
|
-
* @param {*} defvalue - The default value.
|
|
143
|
-
*
|
|
144
|
-
* @param {(object|boolean)} [opts] Options
|
|
145
|
-
*
|
|
146
|
-
* If this is a `boolean` it is used as the `allowNull` option.
|
|
147
|
-
*
|
|
148
|
-
* @param {boolean} [opts.allowNull=true] Passed to `val()`;
|
|
149
|
-
* default is `true`, which differs from `val()`.
|
|
150
|
-
* @param {boolean} [opts.isLazy=false] Passed to `val()`;
|
|
151
|
-
* default is `false`, the same as `val()`.
|
|
152
|
-
* @param {object} [opts.lazyThis=obj] Passed to `val()`;
|
|
153
|
-
* default is `obj`, which differs from `val()`.
|
|
154
|
-
* @param {Array} [opts.lazyArgs] Passed to `val()`
|
|
155
|
-
* @param {boolean} [opts.allowFun=false] Allow `obj` to be a `function` ?
|
|
156
|
-
*
|
|
157
|
-
* By default only `object` values are valid for `obj`; this can be set to
|
|
158
|
-
* `true` to allow `function` values to be used.
|
|
159
|
-
*
|
|
160
|
-
* @param {boolean} [isLazy=false] Same as `opts.isLazy`
|
|
161
|
-
* @param {object} [lazyThis=opts] Same as `opts.lazyThis`
|
|
162
|
-
* @param {Array} [lazyArgs] Same as `opts.lazyArgs`
|
|
163
|
-
* @param {boolean} [allowFun] Same as `opts.allowFun`
|
|
164
|
-
*
|
|
165
|
-
* @returns {*} Either the property value, or the default value.
|
|
166
|
-
* @see module:@lumjs/core/opt.val
|
|
167
|
-
* @alias module:@lumjs/core/opt.get
|
|
168
|
-
*/
|
|
169
|
-
function get(obj, optname, defvalue,
|
|
170
|
-
allowNull=true,
|
|
171
|
-
isLazy=false,
|
|
172
|
-
lazyThis=obj,
|
|
173
|
-
lazyArgs=[],
|
|
174
|
-
allowFun=false)
|
|
175
|
-
{
|
|
176
|
-
const opts = _opts({allowNull,isLazy,lazyThis,lazyArgs,allowFun}, true);
|
|
177
|
-
|
|
178
|
-
needObj(obj, opts.allowFun);
|
|
179
|
-
needType(S, optname);
|
|
180
|
-
|
|
181
|
-
return val(obj[optname], defvalue,
|
|
182
|
-
opts.allowNull,
|
|
183
|
-
opts.isLazy,
|
|
184
|
-
opts.lazyThis,
|
|
185
|
-
opts.lazyArgs);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
exports.get = get;
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* An alternative to `get()` that uses `getObjectPath()`
|
|
192
|
-
* to look for a specific nested property value.
|
|
193
|
-
*
|
|
194
|
-
* While `get()` supports positional arguments like `val()`,
|
|
195
|
-
* this function _only_ supports named options.
|
|
196
|
-
*
|
|
197
|
-
* @param {object} obj - Object we're looking for properties in
|
|
198
|
-
* @param {(string|Array)} path - Path for `getObjectPath()`
|
|
199
|
-
* @param {object} [opts] Options
|
|
200
|
-
*
|
|
201
|
-
* This supports all of the same options as `get()`, plus all of the
|
|
202
|
-
* options supported by `getObjectPath()`. See the docs for both those
|
|
203
|
-
* functions to see what all is supported. If the same option is supported
|
|
204
|
-
* by *both* functions (e.g. `allowFun`) then the default value
|
|
205
|
-
* will be the one from `getObjectPath()` rather than `get()`.
|
|
206
|
-
*
|
|
207
|
-
* @param {boolean} [opts.ro=false] Should `opts` be read-only?
|
|
208
|
-
*
|
|
209
|
-
* If `true`, a copy of the `opts` will be made before any changes
|
|
210
|
-
* are performed, ensuring the original options aren't modified.
|
|
211
|
-
*
|
|
212
|
-
* @returns {*} The property if found, or `opts.default` if not.
|
|
213
|
-
*
|
|
214
|
-
* @see module:@lumjs/core/opt.get
|
|
215
|
-
* @see module:@lumjs/core/obj.getObjectPath
|
|
216
|
-
* @alias module:@lumjs/core/opt.getPath
|
|
217
|
-
*/
|
|
218
|
-
function getPath(obj, path, opts={})
|
|
219
|
-
{
|
|
220
|
-
const defvalue = opts.default;
|
|
221
|
-
if (opts.ro)
|
|
222
|
-
{
|
|
223
|
-
opts = Object.assign({}, opts);
|
|
224
|
-
}
|
|
225
|
-
delete opts.default;
|
|
226
|
-
|
|
227
|
-
return val(getObjectPath(obj, path, opts), defvalue,
|
|
228
|
-
(opts.allowNull ?? true),
|
|
229
|
-
opts.isLazy,
|
|
230
|
-
(opts.lazyThis ?? obj),
|
|
231
|
-
opts.lazyArgs);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
exports.getPath = getPath;
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* A class for handling options with multiple sources.
|
|
238
|
-
* @alias module:@lumjs/core/opt.Opts
|
|
239
|
-
*/
|
|
240
|
-
class Opts
|
|
241
|
-
{
|
|
242
|
-
/**
|
|
243
|
-
* Build an Opts instance.
|
|
244
|
-
*
|
|
245
|
-
* @param {...object} sources - Initial sources of options.
|
|
246
|
-
*
|
|
247
|
-
* The order of sources matters, as the ones added later will override
|
|
248
|
-
* the ones added earlier. Keep that in mind when adding sources.
|
|
249
|
-
*/
|
|
250
|
-
constructor(...sources)
|
|
251
|
-
{
|
|
252
|
-
this.$sources = [];
|
|
253
|
-
this.$curPos = -1;
|
|
254
|
-
this.$curSrc = null;
|
|
255
|
-
|
|
256
|
-
this.$fatalErrors = false;
|
|
257
|
-
this.$strictProps = false;
|
|
258
|
-
|
|
259
|
-
this.add(...sources);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
static isPath(value)
|
|
263
|
-
{
|
|
264
|
-
return (Array.isArray(value)
|
|
265
|
-
|| (typeof value === S && value.includes('.')));
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Compile current sources into a data object.
|
|
270
|
-
*
|
|
271
|
-
* @returns {object} `this`
|
|
272
|
-
* @private
|
|
273
|
-
*/
|
|
274
|
-
_compile()
|
|
275
|
-
{
|
|
276
|
-
this.$data = Object.assign({}, ...this.$sources);
|
|
277
|
-
return this;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Handle an error
|
|
282
|
-
*
|
|
283
|
-
* @param {string} msg - A summary of the error.
|
|
284
|
-
* @param {object} info - Debugging information for the logs.
|
|
285
|
-
* @param {function} [errClass=TypeError] Constructor for an `Error` class.
|
|
286
|
-
* Used if fatal errors are enabled.
|
|
287
|
-
*
|
|
288
|
-
* @returns {object} `this`
|
|
289
|
-
* @throws {Error} An error of `errClass` class, if fatal mode is enabled.
|
|
290
|
-
* @private
|
|
291
|
-
*/
|
|
292
|
-
_err(msg, info={}, errClass=TypeError)
|
|
293
|
-
{
|
|
294
|
-
const args = this.$fatalErrors ? [info] : [msg, info];
|
|
295
|
-
|
|
296
|
-
info.instance = this;
|
|
297
|
-
console.error(...args);
|
|
298
|
-
|
|
299
|
-
if (this.$fatalErrors)
|
|
300
|
-
{
|
|
301
|
-
throw new errClass(msg);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* Normalize options.
|
|
307
|
-
*
|
|
308
|
-
* Auto-sets `isLazy` if it wasn't specified.
|
|
309
|
-
* Applies any known aliases.
|
|
310
|
-
*
|
|
311
|
-
* @param {object} opts - Options to normalize
|
|
312
|
-
* @returns {object} Usually `opts`, but might be a copy.
|
|
313
|
-
* @private
|
|
314
|
-
*/
|
|
315
|
-
_opts(opts)
|
|
316
|
-
{
|
|
317
|
-
if (opts._opts_compiled)
|
|
318
|
-
{ // Already done.
|
|
319
|
-
return opts;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (opts.ro)
|
|
323
|
-
{
|
|
324
|
-
opts = Object.assign({}, opts);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (isNil(opts.isLazy)
|
|
328
|
-
&& (isComplex(opts.lazyThis)
|
|
329
|
-
|| isArray(opts.lazyArgs)))
|
|
330
|
-
{
|
|
331
|
-
opts.isLazy = true;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
for (const akey in OPTS_ALIASES)
|
|
335
|
-
{
|
|
336
|
-
const okey = OPTS_ALIASES[akey];
|
|
337
|
-
if (opts[okey] === undefined && opts[akey] !== undefined)
|
|
338
|
-
{ // An alias was found.
|
|
339
|
-
opts[okey] = opts[akey];
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// Now remember that we've processed these options.
|
|
344
|
-
opts._opts_compiled = true;
|
|
345
|
-
return opts;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* Set the fatal error handling setting.
|
|
350
|
-
*
|
|
351
|
-
* Default is `false`, so errors will be logged, but not thrown.
|
|
352
|
-
*
|
|
353
|
-
* @param {boolean} val - Should errors be fatal?
|
|
354
|
-
* @returns {object} `this`
|
|
355
|
-
*/
|
|
356
|
-
fatal(val)
|
|
357
|
-
{
|
|
358
|
-
if (typeof val === B)
|
|
359
|
-
{
|
|
360
|
-
this.$fatalErrors = val;
|
|
361
|
-
}
|
|
362
|
-
else
|
|
363
|
-
{
|
|
364
|
-
this._err('invalid fatal value', {val});
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
return this;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Set the strict property check setting.
|
|
372
|
-
*
|
|
373
|
-
* Default is `false`, we don't care about non-existent properties.
|
|
374
|
-
*
|
|
375
|
-
* @param {boolean} val - Should non-existant properties be an error?
|
|
376
|
-
* @returns {object} `this`
|
|
377
|
-
*/
|
|
378
|
-
strict(val)
|
|
379
|
-
{
|
|
380
|
-
if (typeof val === B)
|
|
381
|
-
{
|
|
382
|
-
this.$strictProps = val;
|
|
383
|
-
}
|
|
384
|
-
else
|
|
385
|
-
{
|
|
386
|
-
this._err('invalid strict value', {val});
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
return this;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
/**
|
|
393
|
-
* Set the position/offset to add new sources at.
|
|
394
|
-
*
|
|
395
|
-
* This will affect subsequent calls to the `add()` method.
|
|
396
|
-
*
|
|
397
|
-
* @param {number} pos - The position/offset value.
|
|
398
|
-
*
|
|
399
|
-
* - A value of `-1` uses `Array#push(src))`; end of array.
|
|
400
|
-
* - A value of `0` uses `Array#unshift(src)`; start of array.
|
|
401
|
-
* - Any value `> 0` uses `Array#splice(pos, 0, src)`; offset from start.
|
|
402
|
-
* - Any value `< -1` uses `Array#splice(pos+1, 0, src)`; offset from end.
|
|
403
|
-
*
|
|
404
|
-
* The default value if none is specified is `-1`.
|
|
405
|
-
*
|
|
406
|
-
* @returns {object} `this`
|
|
407
|
-
* @throws {TypeError} An invalid value was passed while `fatal` was true.
|
|
408
|
-
*/
|
|
409
|
-
at(pos)
|
|
410
|
-
{
|
|
411
|
-
if (typeof pos === N)
|
|
412
|
-
{
|
|
413
|
-
this.$curPos = pos;
|
|
414
|
-
}
|
|
415
|
-
else
|
|
416
|
-
{
|
|
417
|
-
this._err("Invalid pos value", {pos});
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
return this;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Set the object to look for nested properties in.
|
|
425
|
-
*
|
|
426
|
-
* This will affect subsequent calls to the `add()` method.
|
|
427
|
-
*
|
|
428
|
-
* @param {(object|number|boolean)} source - Source definition
|
|
429
|
-
*
|
|
430
|
-
* - If this is an `object` it will be used as the object directly.
|
|
431
|
-
* - If this is a `number` it is the position of one of our data sources.
|
|
432
|
-
* Negative numbers count from the end of the list of sources.
|
|
433
|
-
* - If this is `true` then the compiled options data at the time of the
|
|
434
|
-
* call to this method will be used.
|
|
435
|
-
* - If this is `false` then the next time a `string` value is passed to
|
|
436
|
-
* `add()` the options will be compiled on demand, and that object will
|
|
437
|
-
* be used until the next call to `from()`.
|
|
438
|
-
*
|
|
439
|
-
* If this is not specified, then it defaults to `false`.
|
|
440
|
-
*
|
|
441
|
-
* @returns {object} `this`
|
|
442
|
-
* @throws {TypeError} An invalid value was passed while `fatal` was true.
|
|
443
|
-
*/
|
|
444
|
-
from(source)
|
|
445
|
-
{
|
|
446
|
-
if (source === true)
|
|
447
|
-
{ // Use existing data as the source.
|
|
448
|
-
this.$curSrc = this.$data;
|
|
449
|
-
}
|
|
450
|
-
else if (source === false)
|
|
451
|
-
{ // Auto-generate the source the next time.
|
|
452
|
-
this.$curSrc = null;
|
|
453
|
-
}
|
|
454
|
-
else if (typeof source === N)
|
|
455
|
-
{ // A number will be the position of an existing source.
|
|
456
|
-
const offset
|
|
457
|
-
= (source < 0)
|
|
458
|
-
? this.$sources.length + source
|
|
459
|
-
: source;
|
|
460
|
-
|
|
461
|
-
if (isObj(this.$sources[offset]))
|
|
462
|
-
{
|
|
463
|
-
this.$curSrc = this.$sources[offset];
|
|
464
|
-
}
|
|
465
|
-
else
|
|
466
|
-
{
|
|
467
|
-
this._err("Invalid source offset", {offset, source});
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
else if (isObj(source))
|
|
471
|
-
{ // An object or function will be used as the source.
|
|
472
|
-
this.$curSrc = source;
|
|
473
|
-
}
|
|
474
|
-
else
|
|
475
|
-
{
|
|
476
|
-
this._err("Invalid source", {source});
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
return this;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
/**
|
|
483
|
-
* Add new sources of options.
|
|
484
|
-
*
|
|
485
|
-
* @param {...(object|string)} sources - Sources and positions.
|
|
486
|
-
*
|
|
487
|
-
* If this is an `object` then it's a source of options to add.
|
|
488
|
-
* This is the most common way of using this.
|
|
489
|
-
*
|
|
490
|
-
* If this is a `string` then it's assumed to be nested property
|
|
491
|
-
* of the current `from()` source, and if that property exists and
|
|
492
|
-
* is an object, it will be used as the source to add. If it does
|
|
493
|
-
* not exist, then the behaviour will depend on the values of the
|
|
494
|
-
* `strict()` and `fatal()` modifiers.
|
|
495
|
-
*
|
|
496
|
-
* @returns {object} `this`
|
|
497
|
-
*/
|
|
498
|
-
add(...sources)
|
|
499
|
-
{
|
|
500
|
-
for (let source of sources)
|
|
501
|
-
{
|
|
502
|
-
if (source === undefined || source === null)
|
|
503
|
-
{ // Skip undefined or null values.
|
|
504
|
-
continue;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
if (typeof source === S)
|
|
508
|
-
{ // Try to find a nested property to include.
|
|
509
|
-
if (this.$curSrc === null)
|
|
510
|
-
{ // Has not been initialized, let's do that now.
|
|
511
|
-
this._compile();
|
|
512
|
-
this.$curSrc = this.$data;
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
if (isObj(this.$curSrc[source]))
|
|
516
|
-
{ // Found a property, use it.
|
|
517
|
-
source = this.$curSrc[source];
|
|
518
|
-
}
|
|
519
|
-
else
|
|
520
|
-
{ // No such property.
|
|
521
|
-
if (this.$strictProps)
|
|
522
|
-
{
|
|
523
|
-
this._err('Property not found', {source});
|
|
524
|
-
}
|
|
525
|
-
continue;
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
if (isObj(source))
|
|
530
|
-
{ // It's a source to add.
|
|
531
|
-
insert(this.$sources, source, this.$curPos);
|
|
532
|
-
}
|
|
533
|
-
else
|
|
534
|
-
{ // That's not valid.
|
|
535
|
-
this._err('invalid source value', {source, sources});
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
return this._compile();
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
/**
|
|
543
|
-
* Remove existing sources of options.
|
|
544
|
-
*
|
|
545
|
-
* @param {...object} sources - Sources to remove.
|
|
546
|
-
*
|
|
547
|
-
* @returns {object} `this`
|
|
548
|
-
*/
|
|
549
|
-
remove(...sources)
|
|
550
|
-
{
|
|
551
|
-
for (const source of sources)
|
|
552
|
-
{
|
|
553
|
-
const index = this.$sources.indexOf(source);
|
|
554
|
-
if (index !== -1)
|
|
555
|
-
{
|
|
556
|
-
this.$sources.splice(index, 1);
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
return this._compile();
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
/**
|
|
564
|
-
* Remove all current sources. Resets compiled options data.
|
|
565
|
-
*
|
|
566
|
-
* @returns {object} `this`
|
|
567
|
-
*/
|
|
568
|
-
clear()
|
|
569
|
-
{
|
|
570
|
-
this.$sources = [];
|
|
571
|
-
return this._compile();
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Get an option value from our compiled data sources.
|
|
576
|
-
*
|
|
577
|
-
* This uses either `get()` or `getPath()` depending on
|
|
578
|
-
* the specified arguments.
|
|
579
|
-
*
|
|
580
|
-
* @param {(string|Array)} opt - The name or path of the option to get.
|
|
581
|
-
*
|
|
582
|
-
* @param {object} [opts] Options
|
|
583
|
-
*
|
|
584
|
-
* I will only list the options that are specific to this method,
|
|
585
|
-
* as the rest are already documented in `getPath()` and related functions.
|
|
586
|
-
*
|
|
587
|
-
* Note that some options like `opts.ro` and `opts.default` which are
|
|
588
|
-
* supported by `getPath()` but not `get()` are usable here regardless
|
|
589
|
-
* of which of those functions will end up being called. The method
|
|
590
|
-
* will do the right thing to make those options work in every context.
|
|
591
|
-
*
|
|
592
|
-
* @param {boolean} [opts.path] Use `getPath()` instead of `get()` ?
|
|
593
|
-
*
|
|
594
|
-
* If not specified, this will be auto-determined based on the `opt`;
|
|
595
|
-
* if `opt` is an `Array` or contains the `'.'` character the default
|
|
596
|
-
* will be `true`, otherwise it will be `false`.
|
|
597
|
-
*
|
|
598
|
-
* @returns {*} The output of the `get()` function.
|
|
599
|
-
* @see module:@lumjs/core/opt.getPath
|
|
600
|
-
*/
|
|
601
|
-
get(opt, opts={})
|
|
602
|
-
{
|
|
603
|
-
opts = this._opts(opts);
|
|
604
|
-
|
|
605
|
-
const isPath = this.constructor.isPath;
|
|
606
|
-
const usePath = opts.path ?? isPath(opt);
|
|
607
|
-
|
|
608
|
-
if (usePath)
|
|
609
|
-
{
|
|
610
|
-
return getPath(this.$data, opt, opts);
|
|
611
|
-
}
|
|
612
|
-
else
|
|
613
|
-
{
|
|
614
|
-
return get(this.$data, opt, opts.default, opts);
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
/**
|
|
619
|
-
* A wrapper around the `get()` method that can check for
|
|
620
|
-
* multiple possible properties or namespaces, and will
|
|
621
|
-
* return the first one that has a defined value.
|
|
622
|
-
*
|
|
623
|
-
* @param {object} opts - Options
|
|
624
|
-
*
|
|
625
|
-
* The same options as the `get()` instance method, which includes all
|
|
626
|
-
* of the options of the `getPath()`, `get()`, and `getObjectPath()`
|
|
627
|
-
* utility functions. So there's a lot of options supported here.
|
|
628
|
-
*
|
|
629
|
-
* Unlike every other method and function that uses options,
|
|
630
|
-
* this is a mandatory argument. You cannot skip it. If you want
|
|
631
|
-
* to use all default options, just pass `{}` and presto, defaults.
|
|
632
|
-
*
|
|
633
|
-
* @param {...(string|Array)} paths - All the properties/paths to try.
|
|
634
|
-
*
|
|
635
|
-
* At least one path must be specified (although if you were only
|
|
636
|
-
* going to specify one, you may as well use the `get()` method
|
|
637
|
-
* directly rather than this...)
|
|
638
|
-
*
|
|
639
|
-
* @returns {*} Could be anything!
|
|
640
|
-
*/
|
|
641
|
-
find(opts, ...paths)
|
|
642
|
-
{
|
|
643
|
-
opts = this._opts(opts);
|
|
644
|
-
|
|
645
|
-
const defvalue = opts.default;
|
|
646
|
-
delete opts.default;
|
|
647
|
-
delete opts.ro;
|
|
648
|
-
|
|
649
|
-
for (const path of paths)
|
|
650
|
-
{
|
|
651
|
-
const value = this.get(path, opts);
|
|
652
|
-
if (value !== undefined)
|
|
653
|
-
{ // Found a value.
|
|
654
|
-
return value;
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
// No matches found, use the default.
|
|
659
|
-
return val(undefined, defvalue, opts);
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
} // Opts
|
|
663
|
-
|
|
664
|
-
exports.Opts = Opts;
|