dcp-client 5.1.8 → 5.1.9
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/bin/dcp-config-value +5 -2
- package/dist/dcp-client-bundle.js +1 -1
- package/dist/dcp-client-bundle.js.map +1 -1
- package/index.js +105 -46
- package/libexec/sandbox/access-lists.js +1 -0
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -304,9 +304,13 @@ KVIN.userCtors.dcpEth$$Address = require('dcp/wallet').Address;
|
|
|
304
304
|
* existing object, so that own properties specified in the existing object graph overwrite, but
|
|
305
305
|
* unspecified edges are left alone.
|
|
306
306
|
*
|
|
307
|
-
* Instances of URL and dcpUrl::
|
|
308
|
-
*
|
|
309
|
-
* the entire value.
|
|
307
|
+
* Instances of Address, URL and dcpUrl::DcpURL receive special treatment: if they are being overwritten
|
|
308
|
+
* by another type, that value is used as the argument to the constructor to create a new object that
|
|
309
|
+
* replaces the entire value. This allows us, for example, to replace a URL with a registry string and
|
|
310
|
+
* still have the correct type once the program loads.
|
|
311
|
+
*
|
|
312
|
+
* URL types are always copied by value, not by reference.
|
|
313
|
+
*
|
|
310
314
|
*
|
|
311
315
|
* Arrays are concatenated together when merging. In the case where an Array and an Object are merged,
|
|
312
316
|
* the result will be an Array and it will be merged with the object's values.
|
|
@@ -318,7 +322,7 @@ KVIN.userCtors.dcpEth$$Address = require('dcp/wallet').Address;
|
|
|
318
322
|
* It is possible to "merge" Objects with Arrays. We basically decide that the Array indicies have no
|
|
319
323
|
* special meaning and neither do the own property names.
|
|
320
324
|
*
|
|
321
|
-
* {} -> {} => leaf merge
|
|
325
|
+
* {} -> {} => ~leaf merge
|
|
322
326
|
* [] -> [] => concat except it leaves out duplicate elements
|
|
323
327
|
* {} -> [] => Object.entries({}) -> [] => concat except it leaves out duplicate elements onto array
|
|
324
328
|
* [] -> {} => [] -> Object with dynamic keys => merge into object
|
|
@@ -333,6 +337,11 @@ function addConfig (existing, neo, dotPath)
|
|
|
333
337
|
|
|
334
338
|
if (neo === undefined || neo === existing)
|
|
335
339
|
return;
|
|
340
|
+
|
|
341
|
+
/* Caveat debuggor: the "adding" output will only show changes from config files where they return
|
|
342
|
+
* objects. Any changes which are the result of the config file directly mutating properties of
|
|
343
|
+
* dcpConfig might not be displayed. See "magicView" for info about those.
|
|
344
|
+
*/
|
|
336
345
|
debug('dcp-client:config-verbose')('adding', neo);
|
|
337
346
|
if (typeof neo !== 'object')
|
|
338
347
|
throw new TypeError(`Unable to merge ${typeof neo} value '${neo}' into ${nodeName()}`);
|
|
@@ -351,7 +360,7 @@ function addConfig (existing, neo, dotPath)
|
|
|
351
360
|
}
|
|
352
361
|
|
|
353
362
|
/** Make an object from an array so that it can be merged into another object without key collision */
|
|
354
|
-
function objFromArrForObj(arr
|
|
363
|
+
function objFromArrForObj(arr)
|
|
355
364
|
{
|
|
356
365
|
const numericKeys = Object.keys(arr).map(key => Number(key)).filter(key => !isNaN(key))
|
|
357
366
|
const maxNumericKey = numericKeys.length ? numericKeys[numericKeys.length - 1] : NaN;
|
|
@@ -367,15 +376,28 @@ function addConfig (existing, neo, dotPath)
|
|
|
367
376
|
|
|
368
377
|
for (const prop of Object.getOwnPropertyNames(neo))
|
|
369
378
|
{
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
+
/* When existing prop is URL and new prop isn't, use new prop to build a URL.
|
|
380
|
+
* Higher precedence than neo[prop] being intrinsic, convert 'http://example.com' to a URL if the existing is a URL
|
|
381
|
+
*/
|
|
382
|
+
if (DcpURL.isURL(existing?.[prop]))
|
|
383
|
+
{
|
|
384
|
+
existing[prop] = new existing[prop].constructor(neo[prop]);
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if (isIntrinsic(neo[prop]))
|
|
389
|
+
{
|
|
390
|
+
existing[prop] = neo[prop];
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (neo[prop].constructor === RegExp) /* Regexps are unmergeable and must be cloned */
|
|
395
|
+
{
|
|
396
|
+
existing[prop] = new RegExp(neo[prop].source, neo[prop].flags);
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
if (neo[prop].constructor === Promise)
|
|
379
401
|
{
|
|
380
402
|
existing[prop] = neo[prop];
|
|
381
403
|
continue;
|
|
@@ -383,36 +405,64 @@ function addConfig (existing, neo, dotPath)
|
|
|
383
405
|
|
|
384
406
|
if (typeof neo[prop] !== 'object')
|
|
385
407
|
throw new TypeError(`Unable to merge ${typeof neo[prop]} value into ${nodeName(prop)}`);
|
|
386
|
-
|
|
408
|
+
|
|
409
|
+
/* When new prop is URL, copy it by value instead of merging */
|
|
410
|
+
if (DcpURL.isURL(neo[prop]))
|
|
387
411
|
{
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
case bootstrapClasses.DcpURL: case bootstrapClasses.Address:
|
|
392
|
-
break;
|
|
393
|
-
case Function: /* previously supported: do we really need this? /wg May 2025 */
|
|
394
|
-
default:
|
|
395
|
-
throw new TypeError(`Unable to merge ${neo[prop].constructor.name} object into ${nodeName(prop)}`);
|
|
396
|
-
}
|
|
412
|
+
const neoUrl = neo[prop];
|
|
413
|
+
existing[prop] = new neoUrl.constructor(neoUrl.href);
|
|
414
|
+
continue;
|
|
397
415
|
}
|
|
398
416
|
|
|
399
|
-
|
|
417
|
+
/* When existing prop is Address and new prop isn't, use new prop to build an Address */
|
|
418
|
+
if (existing[prop]?.constructor === bootstrapClasses.Address &&
|
|
419
|
+
neo [prop] .constructor !== bootstrapClasses.Address)
|
|
420
|
+
{
|
|
421
|
+
existing[prop] = new bootstrapClasses.Address(neo[prop]);
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
400
424
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
425
|
+
switch(neo[prop].constructor)
|
|
426
|
+
{
|
|
427
|
+
case RegExp: case bootstrapClasses.DcpURL: case DcpURL: case URL:
|
|
428
|
+
throw new TypeError(`Unexpected URL type merging ${neo[prop].constructor.name} object into ${nodeName(prop)}`);
|
|
429
|
+
case Object:
|
|
430
|
+
case Array:
|
|
431
|
+
case bootstrapClasses.Address:
|
|
432
|
+
break;
|
|
433
|
+
case Function: /* previously supported: do we really need this? /wg May 2025 */
|
|
434
|
+
default:
|
|
435
|
+
throw new TypeError(`Unable to merge ${neo[prop].constructor.name} object into ${nodeName(prop)}`);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
if (!existing.hasOwnProperty(prop) || isIntrinsic(existing[prop])) /* clone by merging into empty */
|
|
439
|
+
existing[prop] = Array.isArray(neo[prop]) ? [] : {};
|
|
440
|
+
|
|
441
|
+
const neoPropIsArray = Array.isArray(neo [prop]);
|
|
442
|
+
const existingPropIsArray = Array.isArray(existing?.[prop]);
|
|
443
|
+
|
|
444
|
+
const isNotMergeable = (obj) => {
|
|
445
|
+
return false
|
|
446
|
+
|| typeof obj[prop] !== 'object'
|
|
447
|
+
|| (obj[prop].constructor !== Object && obj[prop].constructor !== Array);
|
|
448
|
+
};
|
|
449
|
+
if (isNotMergeable(existing, prop))
|
|
450
|
+
throw new TypeError(`Unable to merge into ${existing?.[prop].constructor?.name || typeof existing} value of ${nodeName(prop)}`);
|
|
451
|
+
if (isNotMergeable(neo, prop))
|
|
452
|
+
throw new TypeError(`Unable to merge ${neo[prop].constructor?.name || typeof neo[prop]} value into ${nodeName(prop)}`);
|
|
453
|
+
|
|
454
|
+
let neoOfProp = neo[prop]; /* !!! do not use neo[prop] below here !!! */
|
|
405
455
|
|
|
406
456
|
/* When one of the objects is an array and the other is a plain object, we transform the new one to
|
|
407
457
|
* match the existing one.
|
|
408
458
|
*/
|
|
409
|
-
if (!
|
|
459
|
+
if (!neoPropIsArray && existingPropIsArray) /* {} -> [] - merge object onto an array? make an array from the object and merge that. */
|
|
410
460
|
neoOfProp = Object.entries(neoOfProp);
|
|
411
|
-
else if (
|
|
461
|
+
else if (neoPropIsArray && !existingPropIsArray) /* [] -> {} - merge array onto an object? make an object from the array and merge that. */
|
|
412
462
|
neoOfProp = objFromArrForObj(neoOfProp, existing[prop]);
|
|
413
463
|
|
|
414
464
|
/* Either merge objects or arrays. Objects collide props, Arrays collide exactly equal values. */
|
|
415
|
-
if (!
|
|
465
|
+
if (!existingPropIsArray)
|
|
416
466
|
addConfig(existing[prop], neoOfProp, nodeName(prop));
|
|
417
467
|
else
|
|
418
468
|
{
|
|
@@ -436,6 +486,10 @@ function addConfig (existing, neo, dotPath)
|
|
|
436
486
|
* @param {object} seen internal use only
|
|
437
487
|
*
|
|
438
488
|
* @returns {object}
|
|
489
|
+
*
|
|
490
|
+
* @todo inherited objects should actually be read-only Proxies or similar, to prevent users from
|
|
491
|
+
* accidentally mutating the internal contents of the underlying object; eg setting the href
|
|
492
|
+
* property of a URL inside the default config, when they meant to set the URL itself.
|
|
439
493
|
*/
|
|
440
494
|
function magicView(node, seen)
|
|
441
495
|
{
|
|
@@ -542,7 +596,7 @@ function addConfigFile(existing /*, file path components ... */) {
|
|
|
542
596
|
const fpSnap = fullPath;
|
|
543
597
|
|
|
544
598
|
/**
|
|
545
|
-
* Make a
|
|
599
|
+
* Make a global object for this context for this config file's evaluation.
|
|
546
600
|
* - Top-level keys from dcpConfig become properties of this object, so that we can write statements
|
|
547
601
|
* like scheduler.location='XXX' in the file.
|
|
548
602
|
* - A variable named `dcpConfig` is also added, so that we could replace nodes wholesale, eg
|
|
@@ -553,11 +607,12 @@ function addConfigFile(existing /*, file path components ... */) {
|
|
|
553
607
|
function makeConfigFileSymbols()
|
|
554
608
|
{
|
|
555
609
|
var configFileScope = Object.assign({}, bundleScope, {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
610
|
+
__filename: fullPath,
|
|
611
|
+
dcpConfig: existing,
|
|
612
|
+
require: moduleSystem.createRequire(fullPath),
|
|
613
|
+
url: (href) => new (require('dcp/dcp-url').DcpURL)(href),
|
|
614
|
+
env: process.env,
|
|
615
|
+
dcp: { 'dcp-env': require('dcp/dcp-env') }, /* used for web-compat confs */
|
|
561
616
|
});
|
|
562
617
|
|
|
563
618
|
for (let key in existing)
|
|
@@ -867,8 +922,7 @@ function initTail(configFrags, options, finalBundleCode, finalBundleURL)
|
|
|
867
922
|
addConfig(workingDcpConfig, configFrags.localConfig);
|
|
868
923
|
addConfig(workingDcpConfig, originalDcpConfig);
|
|
869
924
|
|
|
870
|
-
bundleScope.dcpConfig = workingDcpConfig;
|
|
871
|
-
globalThis.dcpConfig = workingDcpConfig;
|
|
925
|
+
globalThis.dcpConfig = bundleScope.dcpConfig = workingDcpConfig;
|
|
872
926
|
bundleScope.dcpConfig.build = require('dcp/build').config.build; /* dcpConfig.build deprecated mar 2023 /wg */
|
|
873
927
|
|
|
874
928
|
/* 4 */
|
|
@@ -1179,13 +1233,20 @@ exports.createConfigFragments = async function dcpClient$$createConfigFragments(
|
|
|
1179
1233
|
resourceDir = path.resolve(os.homedir(), '.dcp');
|
|
1180
1234
|
let programName = options.programName;
|
|
1181
1235
|
const progDir = process.mainModule ? path.dirname(process.mainModule.filename) : process.cwd();
|
|
1236
|
+
var bin = require.main?.filename && path.dirname(require.main.filename);
|
|
1182
1237
|
var remoteConfig, remoteConfigKVIN;
|
|
1183
1238
|
const internalConfig = require('dcp/dcp-config');
|
|
1184
|
-
const defaultConfig =
|
|
1239
|
+
const defaultConfig = {};
|
|
1240
|
+
addConfig(defaultConfig, bootstrapConfig);
|
|
1241
|
+
assert(defaultConfig.__bootstrapConfig);
|
|
1242
|
+
defaultConfig.__bootstrapConfig = false;
|
|
1185
1243
|
addConfig(defaultConfig, internalConfig);
|
|
1186
1244
|
addConfig(defaultConfig, KVIN.unmarshal(require('dcp/internal/dcp-default-config')));
|
|
1187
1245
|
defaultConfig.scheduler = { location: new URL('https://scheduler.distributed.computer/') };
|
|
1188
1246
|
|
|
1247
|
+
if (bin && !bin.endsWith('/bin'))
|
|
1248
|
+
bin = false;
|
|
1249
|
+
|
|
1189
1250
|
/* localConfig eventually overrides remoteConfig, and is the dcpConfig variable that is modified by
|
|
1190
1251
|
* local include files. Pre-populating the graph edges with config nodes that always exist allows
|
|
1191
1252
|
* config file writers to add properties to leaf nodes without having to construct the entire graph;
|
|
@@ -1237,10 +1298,10 @@ exports.createConfigFragments = async function dcpClient$$createConfigFragments(
|
|
|
1237
1298
|
* any intelligent user can always change the source code to do whatever they please, but it does
|
|
1238
1299
|
* make sense for campus configurations where sysadmins believe the machines are locked down, etc.
|
|
1239
1300
|
*/
|
|
1240
|
-
let cn;
|
|
1241
1301
|
addConfigFile(localConfig, etc, 'dcp/dcp-config');
|
|
1242
1302
|
await addConfigRKey(localConfig, 'HKLM', 'dcp/dcp-config');
|
|
1243
|
-
|
|
1303
|
+
addConfigFile(localConfig, bin, '../etc/dcp/dcp-config');
|
|
1304
|
+
addConfigFile(localConfig, options.configName && path.resolve(progDir, options.configName));
|
|
1244
1305
|
addConfigFile(localConfig, resourceDir, 'dcp-config');
|
|
1245
1306
|
await addConfigRKey(localConfig, 'HKCU', 'dcp/dcp-config');
|
|
1246
1307
|
addConfigFile(localConfig, resourceDir, `${programName}/dcp-config`);
|
|
@@ -1255,8 +1316,6 @@ exports.createConfigFragments = async function dcpClient$$createConfigFragments(
|
|
|
1255
1316
|
await addConfigRKey(localConfig, 'HKLM', 'dcp/override-dcp-config');
|
|
1256
1317
|
await addConfigRKey(localConfig, 'HKLM', 'dcp-client/dcp-config'); /* legacy - used by screen saver, /wg sep'22 */
|
|
1257
1318
|
|
|
1258
|
-
exports.__cn = cn; /* memoize for use by dcp-worker etc who need to know where local conf came from */
|
|
1259
|
-
|
|
1260
1319
|
/* 5. Use the aggregate of the default and local configs to figure out where the scheduler is. Use
|
|
1261
1320
|
* this to figure where the web config is and where an auto-update bundle would be if auto-update
|
|
1262
1321
|
* were enabled.
|
|
@@ -1434,7 +1493,7 @@ function consumeArg(ckArg, bool)
|
|
|
1434
1493
|
var ret;
|
|
1435
1494
|
ckArg = '--dcp-' + ckArg;
|
|
1436
1495
|
|
|
1437
|
-
for (let
|
|
1496
|
+
for (let i=2; i < process.argv.length; i++)
|
|
1438
1497
|
{
|
|
1439
1498
|
const arg = process.argv[i];
|
|
1440
1499
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dcp-client",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.9",
|
|
4
4
|
"dcp": {
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "40f188481ecd4b4ddabfe62bf127572f1b734c01",
|
|
6
6
|
"repository": "git@gitlab.com:Distributed-Compute-Protocol/dcp.git"
|
|
7
7
|
},
|
|
8
8
|
"description": "Core libraries for accessing DCP network",
|