@lumjs/core 1.38.3 → 1.38.5

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.
@@ -1,14 +1,9 @@
1
-
2
- // Get some constants
3
- const {S,B,N,F,isObj,isArray,needObj,def} = require('../types');
4
- const {copyAll, duplicateOne: clone} = require('./copyall');
5
-
6
- const RECURSE_NONE = 0;
7
- const RECURSE_ALL = -1;
8
- const RECURSE_LIST = -2;
9
-
10
1
  /**
11
2
  * Copy properties from one object to another.
3
+ *
4
+ * NOTE: As of v1.38.5 this is an alias of @lumjs/cp/fun.copyProps
5
+ *
6
+ * @function module:@lumjs/core/obj.copyProps
12
7
  *
13
8
  * @param {(object|function)} source - The object to copy properties from.
14
9
  * @param {(object|function)} target - The target to copy properties to.
@@ -72,382 +67,7 @@ const RECURSE_LIST = -2;
72
67
  * in `opts.recurseOpts` will be recursed. The rest will simply be copied.
73
68
  *
74
69
  * @returns {object} The `target` object.
75
- * @alias module:@lumjs/core/obj.copyProps
70
+ * @deprecated Moved to @lumjs/cp package.
76
71
  */
77
- function copyProps(source, target, opts={})
78
- {
79
- //console.debug("copyProps", source, target, propOpts);
80
- needObj(source, true, 'source must be an object or function');
81
- needObj(target, true, 'target must be an object or function');
82
- needObj(opts, false, 'opts must be an object');
83
-
84
- const useDefaults = opts.default ?? true;
85
- const overrides = opts.overrides ?? {};
86
-
87
- let recursive;
88
- if (typeof opts.recursive === N)
89
- {
90
- recursive = opts.recursive;
91
- }
92
- else if (typeof opts.recursive === B)
93
- {
94
- recursive = opts.recursive ? RECURSE_ALL : RECURSE_NONE;
95
- }
96
- else
97
- {
98
- recursive = RECURSE_NONE;
99
- }
100
-
101
- let recurseCache, recurseOpts;
102
- if (recursive !== RECURSE_NONE)
103
- {
104
- recurseCache = opts.recurseCache ?? [];
105
- recurseOpts = opts.recurseOpts ?? {};
106
- }
107
-
108
- let overwrites;
109
- if (typeof opts.overwrite === F)
110
- { // A custom function.
111
- overwrites = opts.overwrite;
112
- }
113
- else if (isObj(opts.overwrite))
114
- { // An object may be an array or a map.
115
- if (isArray(opts.overwrite))
116
- { // A flat array of properties to overwrite.
117
- overwrites = prop => opts.overwrite.includes(prop);
118
- }
119
- else
120
- { // A map of properties to overwrite.
121
- overwrites = prop => opts.overwrite[prop] ?? false;
122
- }
123
- }
124
- else
125
- { // The only other values should be boolean.
126
- overwrites = () => opts.overwrite ?? false;
127
- }
128
-
129
- const exclude = isArray(opts.exclude) ? opts.exclude : null;
130
-
131
- let propDefs;
132
-
133
- if (isArray(opts.props))
134
- {
135
- propDefs = opts.props;
136
- }
137
- else if (opts.all)
138
- {
139
- propDefs = Object.getOwnPropertyNames(source);
140
- }
141
- else if (useDefaults)
142
- {
143
- propDefs = Object.keys(source);
144
- }
145
- else
146
- {
147
- propDefs = Object.keys(overrides);
148
- }
149
-
150
- if (!propDefs)
151
- {
152
- console.error("Could not determine properties to copy", opts);
153
- return;
154
- }
155
-
156
- // For each propDef found, add it to the target.
157
- for (const prop of propDefs)
158
- {
159
- //console.debug(" @prop:", prop);
160
- if (exclude && exclude.indexOf(prop) !== -1)
161
- { // Excluded property.
162
- continue;
163
- }
164
-
165
- let desc = Object.getOwnPropertyDescriptor(source, prop);
166
- //console.debug(" @desc:", def);
167
- if (desc === undefined)
168
- { // A non-existent property.
169
- continue; // Invalid property.
170
- }
171
-
172
- if (isObj(overrides[prop]))
173
- { // Overriding descriptor properties.
174
- desc = clone(desc);
175
- for (const key in overrides[prop])
176
- {
177
- const val = overrides[prop][key];
178
- desc[key] = val;
179
- }
180
- }
181
-
182
- let overwrite = overwrites(prop);
183
-
184
- if (recursive !== 0
185
- && (recursive !== RECURSE_LIST || isObj(recurseOpts[prop]))
186
- && isObj(desc.value)
187
- && isObj(target[prop])
188
- && !recurseCache.includes(desc.value)
189
- && !recurseCache.includes(target[prop]))
190
- { // Recursive mode is enabled, so we're going to go deeper.
191
- recurseCache.push(decs.value);
192
- if (desc.value !== target[prop])
193
- { // They're not the same literal object already.
194
- recurseCache.push(target[prop]);
195
- const ropts
196
- = isObj(recurseOpts[prop])
197
- ? clone(recurseOpts[prop])
198
- : {overwrite};
199
- // Always set the cache.
200
- ropts.recurseCache = recurseCache;
201
- if (typeof ropts.recursive !== N)
202
- { // Set the recursive option.
203
- ropts.recursive = (recursive > 0) ? recursive - 1 : recursive;
204
- }
205
- // Okay, we're ready, let's recurse now!
206
- copyProps(desc.value, target[prop], ropts);
207
- }
208
- }
209
- else if (overwrite || target[prop] === undefined)
210
- { // Property doesn't already exist, let's add it.
211
- def(target, prop, desc);
212
- }
213
- }
214
-
215
- //console.debug("copyProps:done", target);
216
-
217
- return target;
218
- } // copyProps()
219
-
220
- def(copyProps, 'RECURSE_NONE', RECURSE_NONE);
221
- def(copyProps, 'RECURSE_ALL', RECURSE_ALL);
222
- def(copyProps, 'RECURSE_LIST', RECURSE_LIST);
223
-
224
- /**
225
- * A class providing a declarative `copyProps()` API,
226
- * which makes it easy to copy one or more sources,
227
- * into one or more targets.
228
- *
229
- * This class is not directly accessible, and instead is available
230
- * via some special sub-methods of `copyProps`; examples:
231
- *
232
- * ```js
233
- * // Get a copy of the `copyProps` function.
234
- * const cp = require('@lumjs/core').obj.copyProps;
235
- *
236
- * // Starting with the target(s):
237
- * cp.into(targetObj).given({all: true}).from(source1, source2);
238
- *
239
- * // Starting with the source(s):
240
- * cp.from(sourceObj).given({exclude: ['dontCopy']}).into(target1, target2);
241
- *
242
- * // Starting with the options:
243
- * cp.given({recursive: cp.RECURSE_ALL}).from(source1, source2).into(target1, target2);
244
- *
245
- * // Call `cp.into()` and cache the instance in a `Map`.
246
- * // Future calls with the same `targetObj` will return the cached instance.
247
- * // Unlike `cp.into()`, only supports a single `targetObj`.
248
- * cp.cache.into(targetObj);
249
- *
250
- * // Call `cp.from()` and cache the instance in a `Map`.
251
- * // Future calls with the same `sourceObj` will return the cached instance.
252
- * // Unlike `cp.from()`, only supports a single `sourceObj`.
253
- * cp.cache.from(sourceObj);
254
- *
255
- * // Clear the `Map` instances for `cp.cache.into` and `cp.cache.from`
256
- * cp.cache.clear();
257
- *
258
- * ```
259
- *
260
- * @alias module:@lumjs/core/obj~CopyProps
261
- */
262
- class $CopyProps
263
- {
264
- // Constructor is private so we won't document it.
265
- constructor(opts={})
266
- {
267
- this.opts = opts;
268
- this.sources = [];
269
- this.targets = [];
270
- }
271
-
272
- /**
273
- * Set options.
274
- *
275
- * @param {(string|object)} opt - Option(s) to set.
276
- *
277
- * If this is a `string` it's the name of an option to set.
278
- * If this is an `object`, it's map of options to set with `copyAll`.
279
- *
280
- * @param {*} value - The option value.
281
- *
282
- * Only used if `option` is a `string`.
283
- *
284
- * @returns {object} `this`
285
- */
286
- set(opt, value)
287
- {
288
- //console.debug("CopyProps.set(", opt, value, ')');
289
- if (typeof opt === S)
290
- { // Set a single option.
291
- this.opts[opt] = value;
292
- }
293
- else if (isObj(opt))
294
- { // Set a bunch of options.
295
- copyAll(this.opts, opt);
296
- }
297
- else
298
- { // That's not supported
299
- console.error("invalid opt", {opt, value, cp: this});
300
- }
301
- //console.debug("CopyProps.set:after", this);
302
- return this;
303
- }
304
-
305
- /**
306
- * Set all options.
307
- *
308
- * This replaces any existing options entirely.
309
- *
310
- * @param {object} opts - The options to set.
311
- * @returns {object} `this`
312
- */
313
- given(opts)
314
- {
315
- needObj(opts);
316
- this.opts = opts;
317
- return this;
318
- }
319
-
320
- /**
321
- * Specify the `targets` to copy properties into.
322
- *
323
- * @param {...object} [targets] The target objects
324
- *
325
- * If `this.sources` has objects in it already,
326
- * then we'll run `copyProps()` for each of the
327
- * sources into each of the `targets`.
328
- *
329
- * If `this.sources` is empty, then this will set
330
- * `this.target` to the specified value.
331
- *
332
- * You can specify no sources at all to clear the
333
- * currently set `this.targets` value.
334
- *
335
- * @returns {object} `this`
336
- */
337
- into(...targets)
338
- {
339
- if (this.sources.length > 0 && targets.length > 0)
340
- {
341
- this.$run(this.sources, targets);
342
- }
343
- else
344
- {
345
- this.targets = targets;
346
- }
347
- return this;
348
- }
349
-
350
- /**
351
- * Specify the `sources` to copy properties from.
352
- *
353
- * @param {...object} [sources] The source objects.
354
- *
355
- * If `this.targets` has objects in it already,
356
- * then we'll run `copyProps()` for each of the
357
- * `sources` into each of the targets.
358
- *
359
- * If `this.targets` is empty, then this will set
360
- * `this.sources` to the specified value.
361
- *
362
- * You can specify no sources at all to clear the
363
- * currently set `this.sources` value.
364
- *
365
- * @returns {object} `this`
366
- */
367
- from(...sources)
368
- {
369
- if (this.targets.length > 0 && sources.length > 0)
370
- {
371
- this.$run(sources, this.targets);
372
- }
373
- else
374
- {
375
- this.sources = sources;
376
- }
377
- return this;
378
- }
379
-
380
- // Protected method doesn't need to be documented.
381
- $run(sources, targets)
382
- {
383
- for (const source of sources)
384
- {
385
- for (const target of targets)
386
- {
387
- copyProps(source, target, this.opts);
388
- }
389
- }
390
- }
391
-
392
- }
393
-
394
- copyProps.given = function(opts)
395
- {
396
- return new $CopyProps(opts);
397
- }
398
-
399
- copyProps.into = function(...targets)
400
- {
401
- return ((new $CopyProps()).into(...targets));
402
- }
403
-
404
- copyProps.from = function(...sources)
405
- {
406
- return ((new $CopyProps()).from(...sources));
407
- }
408
-
409
- copyProps.cache =
410
- {
411
- into(target)
412
- {
413
- if (this.intoCache === undefined)
414
- this.intoCache = new Map();
415
- const cache = this.intoCache;
416
- if (cache.has(target))
417
- {
418
- return cache.get(target);
419
- }
420
- else
421
- {
422
- const cp = copyProps.into(target);
423
- cache.set(target, cp);
424
- return cp;
425
- }
426
- },
427
- from(source)
428
- {
429
- if (this.fromCache === undefined)
430
- this.fromCache = new Map();
431
- const cache = this.fromCache;
432
- if (cache.has(source))
433
- {
434
- return cache.get(source);
435
- }
436
- else
437
- {
438
- const cp = copyProps.from(source);
439
- cache.set(source, cp);
440
- return cp;
441
- }
442
- },
443
- clear()
444
- {
445
- if (this.intoCache)
446
- this.intoCache.clear();
447
- if (this.fromCache)
448
- this.fromCache.clear();
449
- return this;
450
- },
451
- };
452
72
 
453
- module.exports = copyProps;
73
+ module.exports = require('@lumjs/cp/fun').copyProps;