@abtnode/core 1.7.12 → 1.7.15
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/lib/blocklet/manager/disk.js +149 -71
- package/lib/blocklet/registry.js +2 -2
- package/lib/index.js +2 -1
- package/lib/migrations/1.7.15-blocklet-bundle-source.js +42 -0
- package/lib/router/helper.js +15 -25
- package/lib/states/README.md +4 -2
- package/lib/states/audit-log.js +17 -7
- package/lib/states/blocklet.js +2 -2
- package/lib/states/node.js +34 -18
- package/lib/util/blocklet.js +57 -4
- package/lib/util/default-node-config.js +1 -2
- package/lib/util/index.js +4 -8
- package/lib/util/requirement.js +3 -1
- package/lib/util/upgrade.js +1 -1
- package/package.json +21 -20
|
@@ -491,12 +491,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
491
491
|
}
|
|
492
492
|
}
|
|
493
493
|
|
|
494
|
-
async reset({ did }, context = {}) {
|
|
495
|
-
logger.info('reset blocklet', { did });
|
|
494
|
+
async reset({ did, childDid }, context = {}) {
|
|
495
|
+
logger.info('reset blocklet', { did, childDid });
|
|
496
496
|
|
|
497
497
|
const blocklet = await this.ensureBlocklet(did);
|
|
498
498
|
|
|
499
|
-
if (isInProgress(blocklet.status)) {
|
|
499
|
+
if (isInProgress(blocklet.status || blocklet.status === BlockletStatus.running)) {
|
|
500
500
|
throw new Error('Cannot reset when blocklet is in progress');
|
|
501
501
|
}
|
|
502
502
|
|
|
@@ -506,27 +506,43 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
506
506
|
// do nothing
|
|
507
507
|
}
|
|
508
508
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
fs.removeSync(dataDir);
|
|
516
|
-
fs.removeSync(logsDir);
|
|
509
|
+
if (!childDid) {
|
|
510
|
+
// Cleanup disk storage
|
|
511
|
+
const { cacheDir, logsDir, dataDir } = blocklet.env;
|
|
512
|
+
fs.removeSync(cacheDir);
|
|
513
|
+
fs.removeSync(dataDir);
|
|
514
|
+
fs.removeSync(logsDir);
|
|
517
515
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
516
|
+
// Reset config in db
|
|
517
|
+
await states.blockletExtras.remove({ did: blocklet.meta.did });
|
|
518
|
+
await this._setConfigs(did);
|
|
519
|
+
await this.updateBlockletEnvironment(did);
|
|
520
|
+
await this.resetSiteByDid(did, context);
|
|
521
|
+
} else {
|
|
522
|
+
const child = blocklet.children.find((x) => x.meta.did === childDid);
|
|
523
523
|
|
|
524
|
-
|
|
524
|
+
if (!child) {
|
|
525
|
+
throw new Error('Child does not exist');
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Cleanup disk storage
|
|
529
|
+
const { cacheDir, logsDir, dataDir } = child.env;
|
|
530
|
+
fs.removeSync(cacheDir);
|
|
531
|
+
fs.removeSync(dataDir);
|
|
532
|
+
fs.removeSync(logsDir);
|
|
533
|
+
|
|
534
|
+
// Reset config in db
|
|
535
|
+
await states.blockletExtras.delChildConfigs(blocklet.meta.did, child.meta.did);
|
|
536
|
+
await this._setConfigs(blocklet.meta.did, child.meta.did);
|
|
537
|
+
await this.updateBlockletEnvironment(did);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
logger.info('blocklet reset', { did, childDid });
|
|
525
541
|
return blocklet;
|
|
526
542
|
}
|
|
527
543
|
|
|
528
|
-
async deleteComponent({ did, rootDid }, context) {
|
|
529
|
-
logger.info('delete blocklet component', { did, rootDid });
|
|
544
|
+
async deleteComponent({ did, rootDid, keepData, keepState }, context) {
|
|
545
|
+
logger.info('delete blocklet component', { did, rootDid, keepData });
|
|
530
546
|
|
|
531
547
|
const blocklet = await this.ensureBlocklet(rootDid);
|
|
532
548
|
const doc = await states.blocklet.getBlocklet(rootDid);
|
|
@@ -538,22 +554,36 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
538
554
|
}
|
|
539
555
|
|
|
540
556
|
doc.children = doc.children.filter((x) => x.meta.did !== did);
|
|
541
|
-
const children = (await this._getDynamicChildrenFromSettings(
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
557
|
+
const children = (await this._getDynamicChildrenFromSettings(blocklet.meta.did)).filter((x) => x.meta.did !== did);
|
|
558
|
+
if (keepState !== false) {
|
|
559
|
+
children.push({
|
|
560
|
+
meta: pick(child.meta, ['did', 'name', 'bundleDid', 'bundleName', 'version', 'title', 'description']),
|
|
561
|
+
mountPoint: child.mountPoint,
|
|
562
|
+
status: BlockletStatus.deleted,
|
|
563
|
+
deletedAt: new Date(),
|
|
564
|
+
});
|
|
565
|
+
}
|
|
548
566
|
|
|
549
567
|
await states.blocklet.updateBlocklet(rootDid, doc);
|
|
550
|
-
states.blockletExtras.setSettings(
|
|
568
|
+
states.blockletExtras.setSettings(blocklet.meta.did, { children });
|
|
569
|
+
|
|
570
|
+
// delete navigation
|
|
571
|
+
const navigation = await states.blockletExtras.getSettings(blocklet.meta.did, 'navigation', []);
|
|
572
|
+
await states.blockletExtras.setSettings(
|
|
573
|
+
blocklet.meta.did,
|
|
574
|
+
'navigation',
|
|
575
|
+
navigation.filter((x) => x.child !== blocklet.meta.name)
|
|
576
|
+
);
|
|
551
577
|
|
|
552
578
|
// delete storage
|
|
553
579
|
const childBlocklet = blocklet.children.find((x) => x.meta.did === did);
|
|
554
|
-
const { cacheDir, logsDir } = childBlocklet.env;
|
|
580
|
+
const { cacheDir, logsDir, dataDir } = childBlocklet.env;
|
|
555
581
|
fs.removeSync(cacheDir);
|
|
556
582
|
fs.removeSync(logsDir);
|
|
583
|
+
if (keepData === false) {
|
|
584
|
+
fs.removeSync(dataDir);
|
|
585
|
+
await states.blockletExtras.delChildConfigs(blocklet.meta.did, child.meta.did);
|
|
586
|
+
}
|
|
557
587
|
|
|
558
588
|
const newBlocklet = await this.ensureBlocklet(rootDid);
|
|
559
589
|
this.emit(BlockletEvents.upgraded, { blocklet: newBlocklet, context }); // trigger router refresh
|
|
@@ -887,13 +917,13 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
887
917
|
const blocklet = await states.blocklet.getBlocklet(did);
|
|
888
918
|
const newStaticChildren = await parseChildrenFromMeta(blocklet.meta);
|
|
889
919
|
|
|
890
|
-
const oldDynamicChildren = await this._getDynamicChildrenFromSettings(did, { skipDeleted: true });
|
|
891
|
-
const
|
|
920
|
+
const oldDynamicChildren = await this._getDynamicChildrenFromSettings(blocklet.meta.did, { skipDeleted: true });
|
|
921
|
+
const noneBundleSourceChildren = oldDynamicChildren.filter((x) => !x.bundleSource);
|
|
892
922
|
const dynamicConfig = oldDynamicChildren
|
|
893
|
-
.filter((x) => x.
|
|
894
|
-
.map((x) => ({
|
|
923
|
+
.filter((x) => x.bundleSource)
|
|
924
|
+
.map((x) => ({ source: x.bundleSource, name: x.meta.name, title: x.meta.title, mountPoint: x.mountPoint }));
|
|
895
925
|
const newDynamicChildren = [
|
|
896
|
-
...
|
|
926
|
+
...noneBundleSourceChildren,
|
|
897
927
|
...(await parseChildrenFromMeta(dynamicConfig, { dynamic: true })),
|
|
898
928
|
];
|
|
899
929
|
|
|
@@ -934,7 +964,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
934
964
|
did = sessionData.did;
|
|
935
965
|
const { staticChildren = [], dynamicChildren = [] } = sessionData;
|
|
936
966
|
children = [...staticChildren, ...dynamicChildren.map((x) => ({ ...x, dynamic: true }))];
|
|
937
|
-
oldBlocklet = await
|
|
967
|
+
oldBlocklet = await this._getBlockletForInstallation(did);
|
|
938
968
|
}
|
|
939
969
|
|
|
940
970
|
// get old blocklet
|
|
@@ -1041,6 +1071,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1041
1071
|
}
|
|
1042
1072
|
|
|
1043
1073
|
const children = await this._getChildren(meta);
|
|
1074
|
+
await validateBlocklet({ meta, children });
|
|
1044
1075
|
const added = await states.blocklet.addBlocklet({
|
|
1045
1076
|
meta,
|
|
1046
1077
|
source: BlockletSource.local,
|
|
@@ -1101,7 +1132,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1101
1132
|
dynamic: true,
|
|
1102
1133
|
},
|
|
1103
1134
|
]);
|
|
1135
|
+
await validateBlocklet(children[0]);
|
|
1104
1136
|
await states.blocklet.addChildren(rootDid, children);
|
|
1137
|
+
await this._upsertDynamicNavigation(existRoot.meta.did, children[0]);
|
|
1105
1138
|
|
|
1106
1139
|
logger.info('add blocklet component for dev', { did, version, meta });
|
|
1107
1140
|
|
|
@@ -1395,7 +1428,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1395
1428
|
try {
|
|
1396
1429
|
// install blocklet
|
|
1397
1430
|
if (postAction === 'install') {
|
|
1398
|
-
await this.onInstall({ blocklet, context });
|
|
1431
|
+
await this.onInstall({ blocklet, context, oldBlocklet });
|
|
1399
1432
|
return;
|
|
1400
1433
|
}
|
|
1401
1434
|
|
|
@@ -1410,7 +1443,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1410
1443
|
}
|
|
1411
1444
|
}
|
|
1412
1445
|
|
|
1413
|
-
async onInstall({ blocklet, context }) {
|
|
1446
|
+
async onInstall({ blocklet, context, oldBlocklet }) {
|
|
1414
1447
|
const { meta } = blocklet;
|
|
1415
1448
|
const { did, version } = meta;
|
|
1416
1449
|
logger.info('do install blocklet', { did, version });
|
|
@@ -1422,6 +1455,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1422
1455
|
const installedBlocklet = await this._installBlocklet({
|
|
1423
1456
|
did,
|
|
1424
1457
|
context,
|
|
1458
|
+
oldBlocklet,
|
|
1425
1459
|
});
|
|
1426
1460
|
|
|
1427
1461
|
if (context.startImmediately) {
|
|
@@ -1612,7 +1646,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1612
1646
|
}
|
|
1613
1647
|
|
|
1614
1648
|
async _installComponentFromUrl({ rootDid, mountPoint, url, context, title, name: inputName, did: inputDid }) {
|
|
1615
|
-
const blocklet = await
|
|
1649
|
+
const blocklet = await this._getBlockletForInstallation(rootDid);
|
|
1616
1650
|
if (!blocklet) {
|
|
1617
1651
|
throw new Error('Root blocklet does not exist');
|
|
1618
1652
|
}
|
|
@@ -1638,7 +1672,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1638
1672
|
if (!inputName && !inputDid) {
|
|
1639
1673
|
const found = findAvailableDid(meta, [
|
|
1640
1674
|
...blocklet.children.map((x) => x.meta),
|
|
1641
|
-
...(await states.blockletExtras.getSettings(
|
|
1675
|
+
...(await states.blockletExtras.getSettings(blocklet.meta.did, 'children', [])).map((x) => x.meta),
|
|
1642
1676
|
]);
|
|
1643
1677
|
name = found.name;
|
|
1644
1678
|
did = found.did;
|
|
@@ -1648,7 +1682,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1648
1682
|
{
|
|
1649
1683
|
meta: ensureMeta(meta, { did, name }),
|
|
1650
1684
|
mountPoint,
|
|
1651
|
-
|
|
1685
|
+
bundleSource: { url },
|
|
1652
1686
|
dynamic: true,
|
|
1653
1687
|
},
|
|
1654
1688
|
]);
|
|
@@ -1657,6 +1691,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1657
1691
|
|
|
1658
1692
|
// add component to db
|
|
1659
1693
|
await states.blocklet.addChildren(rootDid, newChildren);
|
|
1694
|
+
await this._upsertDynamicNavigation(blocklet.meta.did, newChildren[0]);
|
|
1660
1695
|
|
|
1661
1696
|
return this.updateChildren(
|
|
1662
1697
|
{
|
|
@@ -1743,7 +1778,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1743
1778
|
|
|
1744
1779
|
// diff deploy
|
|
1745
1780
|
if (did && diffVersion) {
|
|
1746
|
-
const oldBlocklet = await
|
|
1781
|
+
const oldBlocklet = await this._getBlockletForInstallation(did);
|
|
1747
1782
|
if (!oldBlocklet) {
|
|
1748
1783
|
throw new Error(`Blocklet ${did} not found when diff deploying`);
|
|
1749
1784
|
}
|
|
@@ -1779,7 +1814,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1779
1814
|
|
|
1780
1815
|
// full deploy
|
|
1781
1816
|
const { meta } = await this._resolveDownload(cwd, tarFile);
|
|
1782
|
-
const oldBlocklet = await
|
|
1817
|
+
const oldBlocklet = await this._getBlockletForInstallation(meta.did);
|
|
1783
1818
|
|
|
1784
1819
|
// full deploy - upgrade
|
|
1785
1820
|
if (oldBlocklet) {
|
|
@@ -1805,6 +1840,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1805
1840
|
}
|
|
1806
1841
|
|
|
1807
1842
|
// full deploy - install
|
|
1843
|
+
const oldExtraState = await states.blockletExtras.findOne({ did: meta.did });
|
|
1808
1844
|
const children = await this._getChildren(meta);
|
|
1809
1845
|
const blocklet = await states.blocklet.addBlocklet({
|
|
1810
1846
|
meta,
|
|
@@ -1826,6 +1862,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1826
1862
|
return this._installBlocklet({
|
|
1827
1863
|
did: meta.did,
|
|
1828
1864
|
context,
|
|
1865
|
+
oldBlocklet: { extraState: oldExtraState },
|
|
1829
1866
|
});
|
|
1830
1867
|
}
|
|
1831
1868
|
|
|
@@ -1834,7 +1871,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1834
1871
|
// download
|
|
1835
1872
|
const { cwd, tarFile } = await this._downloadFromUpload(file);
|
|
1836
1873
|
|
|
1837
|
-
const oldBlocklet = await
|
|
1874
|
+
const oldBlocklet = await this._getBlockletForInstallation(rootDid);
|
|
1838
1875
|
if (!oldBlocklet) {
|
|
1839
1876
|
throw new Error('Root blocklet does not exist');
|
|
1840
1877
|
}
|
|
@@ -1883,7 +1920,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1883
1920
|
mountPoint,
|
|
1884
1921
|
source: BlockletSource.upload,
|
|
1885
1922
|
deployedFrom: `Upload by ${context.user.fullName}`,
|
|
1886
|
-
|
|
1923
|
+
bundleSource: null,
|
|
1887
1924
|
dynamic: true,
|
|
1888
1925
|
};
|
|
1889
1926
|
const index = newBlocklet.children.findIndex((child) => child.meta.did === meta.did);
|
|
@@ -1892,6 +1929,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1892
1929
|
} else {
|
|
1893
1930
|
newBlocklet.children.push(newChild);
|
|
1894
1931
|
}
|
|
1932
|
+
await this._upsertDynamicNavigation(newBlocklet.meta.did, newChild);
|
|
1895
1933
|
|
|
1896
1934
|
await validateBlocklet(newBlocklet);
|
|
1897
1935
|
|
|
@@ -2046,6 +2084,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2046
2084
|
|
|
2047
2085
|
const { name, did, version } = meta;
|
|
2048
2086
|
|
|
2087
|
+
const oldExtraState = await states.blockletExtras.findOne({ did: meta.did });
|
|
2088
|
+
|
|
2049
2089
|
const children = await this._getChildren(meta);
|
|
2050
2090
|
try {
|
|
2051
2091
|
const blocklet = await states.blocklet.addBlocklet({
|
|
@@ -2067,7 +2107,10 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2067
2107
|
// download
|
|
2068
2108
|
const downloadParams = {
|
|
2069
2109
|
blocklet: { ...blocklet1 },
|
|
2070
|
-
oldBlocklet: {
|
|
2110
|
+
oldBlocklet: {
|
|
2111
|
+
children: children.filter((x) => x.dynamic), // let downloader skip re-downloading dynamic blocklet
|
|
2112
|
+
extraState: oldExtraState,
|
|
2113
|
+
},
|
|
2071
2114
|
context,
|
|
2072
2115
|
postAction: 'install',
|
|
2073
2116
|
};
|
|
@@ -2089,8 +2132,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2089
2132
|
ticket.on('failed', async (err) => {
|
|
2090
2133
|
logger.error('failed to install blocklet', { name, did, version, error: err });
|
|
2091
2134
|
try {
|
|
2092
|
-
await this.
|
|
2093
|
-
await states.blocklet.deleteBlocklet(did);
|
|
2135
|
+
await this._rollback('install', did, { extraState: oldExtraState });
|
|
2094
2136
|
} catch (e) {
|
|
2095
2137
|
logger.error('failed to remove blocklet on install error', { did: meta.did, error: e });
|
|
2096
2138
|
}
|
|
@@ -2116,7 +2158,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2116
2158
|
});
|
|
2117
2159
|
|
|
2118
2160
|
try {
|
|
2119
|
-
await this._rollback('install', did);
|
|
2161
|
+
await this._rollback('install', did, { extraState: oldExtraState });
|
|
2120
2162
|
} catch (e) {
|
|
2121
2163
|
logger.error('failed to remove blocklet on install error', { did: meta.did, error: e });
|
|
2122
2164
|
}
|
|
@@ -2130,7 +2172,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2130
2172
|
|
|
2131
2173
|
const { name, version, did } = meta;
|
|
2132
2174
|
|
|
2133
|
-
const oldBlocklet = await
|
|
2175
|
+
const oldBlocklet = await this._getBlockletForInstallation(did);
|
|
2134
2176
|
|
|
2135
2177
|
// NOTE: 目前的版本移除了降级通道,所以不需要考虑降级通道的情况
|
|
2136
2178
|
const action = semver.gt(oldBlocklet.meta.version, version) ? 'downgrade' : 'upgrade';
|
|
@@ -2248,9 +2290,10 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2248
2290
|
if (fs.existsSync(installDir)) {
|
|
2249
2291
|
fs.removeSync(installDir);
|
|
2250
2292
|
logger.info('cleanup blocklet upgrade dir', { name, version, installDir });
|
|
2251
|
-
} else {
|
|
2252
|
-
fs.mkdirSync(installDir, { recursive: true });
|
|
2253
2293
|
}
|
|
2294
|
+
|
|
2295
|
+
fs.mkdirSync(installDir, { recursive: true });
|
|
2296
|
+
|
|
2254
2297
|
await fs.move(downloadDir, installDir, { overwrite: true });
|
|
2255
2298
|
} catch (error) {
|
|
2256
2299
|
fs.removeSync(downloadDir);
|
|
@@ -2303,6 +2346,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2303
2346
|
|
|
2304
2347
|
await ensureBlockletExpanded(meta, downloadDir);
|
|
2305
2348
|
|
|
2349
|
+
// move to installDir
|
|
2306
2350
|
const bundleDir = getBundleDir(this.installDir, meta);
|
|
2307
2351
|
logger.info('Move downloadDir to installDir', { downloadDir, bundleDir });
|
|
2308
2352
|
await fs.move(downloadDir, bundleDir, { overwrite: true });
|
|
@@ -2319,7 +2363,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2319
2363
|
* @param {string} opt.did
|
|
2320
2364
|
* @param {object} opt.context
|
|
2321
2365
|
*/
|
|
2322
|
-
async _installBlocklet({ did, context }) {
|
|
2366
|
+
async _installBlocklet({ did, oldBlocklet, context }) {
|
|
2323
2367
|
try {
|
|
2324
2368
|
let blocklet = await this.ensureBlocklet(did);
|
|
2325
2369
|
const { meta, source, deployedFrom } = blocklet;
|
|
@@ -2388,7 +2432,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2388
2432
|
const { name, version } = meta;
|
|
2389
2433
|
logger.error('failed to install blocklet', { name, did, version, error: err });
|
|
2390
2434
|
try {
|
|
2391
|
-
await this._rollback('install', did);
|
|
2435
|
+
await this._rollback('install', did, oldBlocklet);
|
|
2392
2436
|
this.emit(BlockletEvents.installFailed, { meta: { did } });
|
|
2393
2437
|
states.notification.create({
|
|
2394
2438
|
title: 'Blocklet Install Failed',
|
|
@@ -2544,7 +2588,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2544
2588
|
const { did } = blocklet.meta;
|
|
2545
2589
|
const dynamicChildren = blocklet.children
|
|
2546
2590
|
.filter((x) => x.dynamic)
|
|
2547
|
-
.map((x) => pick(x, ['meta', 'mountPoint', '
|
|
2591
|
+
.map((x) => pick(x, ['meta', 'mountPoint', 'bundleSource', 'source']));
|
|
2548
2592
|
|
|
2549
2593
|
// deleted blocklet
|
|
2550
2594
|
let deletes = await states.blockletExtras.getSettings(did, 'children', []);
|
|
@@ -2822,14 +2866,27 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2822
2866
|
*/
|
|
2823
2867
|
async _rollback(action, did, oldBlocklet) {
|
|
2824
2868
|
if (action === 'install') {
|
|
2825
|
-
|
|
2869
|
+
const extraState = oldBlocklet?.extraState;
|
|
2870
|
+
|
|
2871
|
+
// rollback blocklet extra state
|
|
2872
|
+
if (extraState) {
|
|
2873
|
+
await states.blockletExtras.update({ did }, extraState);
|
|
2874
|
+
} else {
|
|
2875
|
+
await states.blockletExtras.remove({ did });
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
// remove blocklet state
|
|
2826
2879
|
return this._deleteBlocklet({ did, keepData: true });
|
|
2827
2880
|
}
|
|
2828
2881
|
|
|
2829
2882
|
if (['upgrade', 'downgrade'].includes(action)) {
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
await
|
|
2883
|
+
const { extraState, ...blocklet } = oldBlocklet;
|
|
2884
|
+
// rollback blocklet state
|
|
2885
|
+
const result = await states.blocklet.updateBlocklet(did, blocklet);
|
|
2886
|
+
|
|
2887
|
+
// rollback blocklet extra state
|
|
2888
|
+
await states.blockletExtras.update({ did: blocklet.meta.did }, extraState);
|
|
2889
|
+
|
|
2833
2890
|
logger.info('blocklet rollback successfully', { did });
|
|
2834
2891
|
this.emit(BlockletEvents.updated, result);
|
|
2835
2892
|
return result;
|
|
@@ -2851,14 +2908,14 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2851
2908
|
if (keepData === false) {
|
|
2852
2909
|
fs.removeSync(dataDir);
|
|
2853
2910
|
fs.removeSync(logsDir);
|
|
2854
|
-
await
|
|
2911
|
+
await states.blockletExtras.remove({ did: blocklet.meta.did });
|
|
2855
2912
|
} else {
|
|
2856
2913
|
if (keepLogsDir === false) {
|
|
2857
2914
|
fs.removeSync(logsDir);
|
|
2858
2915
|
}
|
|
2859
2916
|
|
|
2860
2917
|
if (keepConfigs === false) {
|
|
2861
|
-
await
|
|
2918
|
+
await states.blockletExtras.remove({ did: blocklet.meta.did });
|
|
2862
2919
|
}
|
|
2863
2920
|
}
|
|
2864
2921
|
|
|
@@ -2880,21 +2937,18 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2880
2937
|
return blocklet;
|
|
2881
2938
|
}
|
|
2882
2939
|
|
|
2883
|
-
async _setConfigs(did) {
|
|
2940
|
+
async _setConfigs(did, childDid) {
|
|
2884
2941
|
const blocklet = await states.blocklet.getBlocklet(did);
|
|
2885
2942
|
const { meta } = blocklet;
|
|
2886
|
-
await states.blockletExtras.setConfigs(did, get(meta, 'environments', []));
|
|
2887
|
-
for (const child of blocklet.children) {
|
|
2888
|
-
await states.blockletExtras.setChildConfigs(did, child.meta.did, get(child.meta, 'environments'));
|
|
2889
|
-
}
|
|
2890
|
-
}
|
|
2891
2943
|
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2944
|
+
if (!childDid) {
|
|
2945
|
+
await states.blockletExtras.setConfigs(blocklet.meta.did, get(meta, 'environments', []));
|
|
2946
|
+
for (const child of blocklet.children) {
|
|
2947
|
+
await states.blockletExtras.setChildConfigs(blocklet.meta.did, child.meta.did, get(child.meta, 'environments'));
|
|
2948
|
+
}
|
|
2949
|
+
} else {
|
|
2950
|
+
const child = blocklet.children.find((x) => x.meta.did === childDid);
|
|
2951
|
+
await states.blockletExtras.setChildConfigs(blocklet.meta.did, child.meta.did, get(child.meta, 'environments'));
|
|
2898
2952
|
}
|
|
2899
2953
|
}
|
|
2900
2954
|
|
|
@@ -2911,6 +2965,30 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2911
2965
|
}
|
|
2912
2966
|
return { did, name };
|
|
2913
2967
|
}
|
|
2968
|
+
|
|
2969
|
+
async _upsertDynamicNavigation(did, child) {
|
|
2970
|
+
const navigation = await states.blockletExtras.getSettings(did, 'navigation', []);
|
|
2971
|
+
const item = { title: child.meta.title, child: child.meta.name };
|
|
2972
|
+
const index = navigation.findIndex((x) => x.child === item.child);
|
|
2973
|
+
if (index > -1) {
|
|
2974
|
+
navigation.splice(index, 1, item);
|
|
2975
|
+
} else {
|
|
2976
|
+
navigation.push(item);
|
|
2977
|
+
}
|
|
2978
|
+
await states.blockletExtras.setSettings(did, { navigation });
|
|
2979
|
+
}
|
|
2980
|
+
|
|
2981
|
+
async _getBlockletForInstallation(did) {
|
|
2982
|
+
const blocklet = await states.blocklet.getBlocklet(did);
|
|
2983
|
+
if (!blocklet) {
|
|
2984
|
+
return null;
|
|
2985
|
+
}
|
|
2986
|
+
|
|
2987
|
+
const extraState = await states.blockletExtras.findOne({ did: blocklet.meta.did });
|
|
2988
|
+
blocklet.extraState = extraState;
|
|
2989
|
+
|
|
2990
|
+
return blocklet;
|
|
2991
|
+
}
|
|
2914
2992
|
}
|
|
2915
2993
|
|
|
2916
2994
|
module.exports = BlockletManager;
|
package/lib/blocklet/registry.js
CHANGED
|
@@ -123,7 +123,7 @@ class BlockletRegistry {
|
|
|
123
123
|
|
|
124
124
|
if (res.status === 304 && this.blocklets.length > 0) {
|
|
125
125
|
logger.debug('use cached data', { etag: res.headers.etag, registryUrl });
|
|
126
|
-
return this.blocklets;
|
|
126
|
+
return this.blocklets.filter((x) => isRequirementsSatisfied(x.requirements, false));
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
if (res.status === 304) {
|
|
@@ -144,7 +144,7 @@ class BlockletRegistry {
|
|
|
144
144
|
const blocklets = res.data.filter((x) => BlockletGroup[x.group]);
|
|
145
145
|
logger.debug('blocklets loaded', { url, blocklets: blocklets.map((x) => ({ did: x.did, name: x.name })) });
|
|
146
146
|
this.cacheId = res.headers.etag;
|
|
147
|
-
this.blocklets = blocklets;
|
|
147
|
+
this.blocklets = blocklets.filter((x) => isRequirementsSatisfied(x.requirements, false));
|
|
148
148
|
} catch (error) {
|
|
149
149
|
logger.error('refresh blocklet registry failed', { error, registryUrl });
|
|
150
150
|
this.cacheId = '';
|
package/lib/index.js
CHANGED
|
@@ -249,6 +249,7 @@ function ABTNode(options) {
|
|
|
249
249
|
selectBlockletStore: nodeAPI.selectRegistry.bind(nodeAPI),
|
|
250
250
|
cleanupDirtyUpgradeState: states.node.cleanupDirtyUpgradeState.bind(states.node),
|
|
251
251
|
addNodeOwner: states.node.addNodeOwner.bind(states.node),
|
|
252
|
+
updateNodeOwner: states.node.updateNodeOwner.bind(states.node),
|
|
252
253
|
updateNodeRouting,
|
|
253
254
|
isInitialized,
|
|
254
255
|
resetNode: (params, context) =>
|
|
@@ -426,7 +427,7 @@ function ABTNode(options) {
|
|
|
426
427
|
action,
|
|
427
428
|
args: {},
|
|
428
429
|
context: formatContext({
|
|
429
|
-
user: { fullName: 'CLI', role: '
|
|
430
|
+
user: { fullName: 'CLI', role: 'admin', did: options.nodeDid },
|
|
430
431
|
headers: { 'user-agent': 'CLI' },
|
|
431
432
|
}),
|
|
432
433
|
result: null,
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/* eslint-disable no-continue */
|
|
2
|
+
/* eslint-disable no-await-in-loop */
|
|
3
|
+
/* eslint-disable no-underscore-dangle */
|
|
4
|
+
|
|
5
|
+
module.exports = async ({ states, printInfo }) => {
|
|
6
|
+
printInfo('Try to update blocklet server to 1.7.15...');
|
|
7
|
+
|
|
8
|
+
const blocklets = await states.blocklet.getBlocklets();
|
|
9
|
+
|
|
10
|
+
for (const blocklet of blocklets) {
|
|
11
|
+
(blocklet.children || []).forEach((child) => {
|
|
12
|
+
const { sourceUrl } = child;
|
|
13
|
+
delete child.sourceUrl;
|
|
14
|
+
if (sourceUrl && !child.bundleSource) {
|
|
15
|
+
child.bundleSource = {
|
|
16
|
+
url: sourceUrl,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
await states.blocklet.updateBlocklet(blocklet.meta.did, { children: blocklet.children });
|
|
22
|
+
printInfo(`Blocklet children in blocklet.db updated: ${blocklet.meta.did}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const blockletExtras = await states.blockletExtras.find({});
|
|
26
|
+
|
|
27
|
+
for (const extra of blockletExtras) {
|
|
28
|
+
const children = await states.blockletExtras.getSettings(extra.did, 'children', []);
|
|
29
|
+
(children || []).forEach((child) => {
|
|
30
|
+
const { sourceUrl } = child;
|
|
31
|
+
delete child.sourceUrl;
|
|
32
|
+
if (sourceUrl && !child.bundleSource) {
|
|
33
|
+
child.bundleSource = {
|
|
34
|
+
url: sourceUrl,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
await states.blockletExtras.setSettings(extra.did, { children });
|
|
40
|
+
printInfo(`Blocklet dynamic component in blocklet_extra.db updated: ${extra.did}`);
|
|
41
|
+
}
|
|
42
|
+
};
|
package/lib/router/helper.js
CHANGED
|
@@ -311,8 +311,8 @@ const ensureWellknownRule = async (sites) => {
|
|
|
311
311
|
for (const site of tempSites) {
|
|
312
312
|
// 不向 default site & ip site & wellknown site 添加 wellknown rule
|
|
313
313
|
if (![DOMAIN_FOR_INTERNAL_SITE, DOMAIN_FOR_IP_SITE, DOMAIN_FOR_DEFAULT_SITE].includes(site.domain)) {
|
|
314
|
+
// add /.well-known for blocklet
|
|
314
315
|
const isExists = site.rules.find((x) => x.from.pathPrefix === WELLKNOWN_PATH_PREFIX);
|
|
315
|
-
|
|
316
316
|
if (!isExists) {
|
|
317
317
|
site.rules.push({
|
|
318
318
|
from: { pathPrefix: WELLKNOWN_PATH_PREFIX },
|
|
@@ -326,31 +326,21 @@ const ensureWellknownRule = async (sites) => {
|
|
|
326
326
|
}
|
|
327
327
|
|
|
328
328
|
// add /.well-known/service for blocklet
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
329
|
+
const blockletRules = site.rules.filter((x) => x.to.type === ROUTING_RULE_TYPES.BLOCKLET);
|
|
330
|
+
if (blockletRules.length) {
|
|
331
|
+
// get pathPrefix for blocklet-service
|
|
332
|
+
const rootBlockletRule = blockletRules.find((x) => x.to.did === x.to.realDid);
|
|
333
|
+
const pathPrefix = joinUrl(rootBlockletRule?.from?.pathPrefix || '/', WELLKNOWN_SERVICE_PATH_PREFIX);
|
|
334
|
+
|
|
335
|
+
// requests for /.well-known/service will stay in blocklet-service and never proxy back to blocklet
|
|
336
|
+
// so any rule is ok to be cloned
|
|
337
|
+
if (!site.rules.some((x) => x.from.pathPrefix === pathPrefix)) {
|
|
338
|
+
const rule = cloneDeep(rootBlockletRule || blockletRules[0]);
|
|
339
|
+
rule.from.pathPrefix = pathPrefix;
|
|
340
|
+
rule.isProtected = true;
|
|
341
|
+
site.rules.push(rule);
|
|
336
342
|
}
|
|
337
|
-
|
|
338
|
-
// already exists
|
|
339
|
-
if (rule.from.pathPrefix.endsWith(WELLKNOWN_SERVICE_PATH_PREFIX)) {
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
const pathPrefix = joinUrl(rule.from.pathPrefix, WELLKNOWN_SERVICE_PATH_PREFIX);
|
|
344
|
-
|
|
345
|
-
// already exists
|
|
346
|
-
if (site.rules.some((x) => x.from.pathPrefix === pathPrefix)) {
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
rule.from.pathPrefix = pathPrefix;
|
|
351
|
-
rule.isProtected = true;
|
|
352
|
-
site.rules.push(rule);
|
|
353
|
-
});
|
|
343
|
+
}
|
|
354
344
|
}
|
|
355
345
|
}
|
|
356
346
|
|
package/lib/states/README.md
CHANGED
|
@@ -17,9 +17,11 @@ All Blocklet Server states are managed by files in this folder.
|
|
|
17
17
|
- `scripts`: for hook of component lifecycle
|
|
18
18
|
- `engine`, `timeout`, `group`, `main`: related to process startup
|
|
19
19
|
- `dist`: bundle source
|
|
20
|
+
- `theme`: app theme
|
|
21
|
+
- `navigation`: app navigation`
|
|
20
22
|
- `source`: type of bundle source
|
|
21
|
-
- `
|
|
22
|
-
- `
|
|
23
|
+
- `bundleSource`: download infomation of bundle srouce
|
|
24
|
+
- `deployedFrom`: extra information of bundle source
|
|
23
25
|
- `appDid`: app instance id _app only_
|
|
24
26
|
- `status`, `startedAt`, `installedAt`, `stoppedAt` app status
|
|
25
27
|
- `deletedAt` _component only_
|
package/lib/states/audit-log.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-async-promise-executor */
|
|
2
2
|
const pick = require('lodash/pick');
|
|
3
3
|
const get = require('lodash/get');
|
|
4
|
+
const joinUrl = require('url-join');
|
|
4
5
|
const { getDisplayName } = require('@blocklet/meta/lib/util');
|
|
5
6
|
const { BLOCKLET_SITE_GROUP_SUFFIX } = require('@abtnode/constant');
|
|
6
7
|
const logger = require('@abtnode/logger')('@abtnode/core:states:audit-log');
|
|
@@ -10,8 +11,8 @@ const BaseState = require('./base');
|
|
|
10
11
|
const { parse } = require('../util/ua');
|
|
11
12
|
const { lookup } = require('../util/ip');
|
|
12
13
|
|
|
13
|
-
const getServerInfo = (info) => `[${info.name}](${info.routing.adminPath
|
|
14
|
-
const getBlockletInfo = (blocklet, info) => `[${getDisplayName(blocklet)} v${blocklet.meta.version}](${info.routing.adminPath
|
|
14
|
+
const getServerInfo = (info) => `[${info.name}](${joinUrl(info.routing.adminPath, '/settings/about')})`;
|
|
15
|
+
const getBlockletInfo = (blocklet, info) => `[${getDisplayName(blocklet)} v${blocklet.meta.version}](${joinUrl(info.routing.adminPath, '/blocklets/', blocklet.meta.did, '/overview')})`; // prettier-ignore
|
|
15
16
|
const expandTeam = async (teamDid, info, node) => {
|
|
16
17
|
if (!teamDid) {
|
|
17
18
|
return '';
|
|
@@ -64,10 +65,10 @@ const expandUser = async (teamDid, userDid, passportId, info, node) => {
|
|
|
64
65
|
const passport = user.passports.find((x) => x.id === passportId);
|
|
65
66
|
|
|
66
67
|
if (teamDid === info.did) {
|
|
67
|
-
return [`[${user.fullName}](${info.routing.adminPath
|
|
68
|
+
return [`[${user.fullName}](${joinUrl(info.routing.adminPath, '/team/members')})`, passport ? passport.name : ''];
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
return [`[${user.fullName}](${info.routing.adminPath
|
|
71
|
+
return [`[${user.fullName}](${joinUrl(info.routing.adminPath, '/blocklets/', teamDid, '/members')})`, passport ? passport.name : '']; // prettier-ignore
|
|
71
72
|
};
|
|
72
73
|
|
|
73
74
|
/**
|
|
@@ -93,7 +94,7 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
93
94
|
case 'installBlocklet':
|
|
94
95
|
return `installed blocklet ${getBlockletInfo(result, info)} from ${result.deployedFrom}`;
|
|
95
96
|
case 'startBlocklet':
|
|
96
|
-
return `started blocklet ${getBlockletInfo(result, info)}`;
|
|
97
|
+
return `started blocklet ${getBlockletInfo(result, info)} ${args.reason || ''}`;
|
|
97
98
|
case 'restartBlocklet':
|
|
98
99
|
return `restarted blocklet ${getBlockletInfo(result, info)}`;
|
|
99
100
|
case 'reloadBlocklet':
|
|
@@ -131,6 +132,12 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
131
132
|
return `joined team ${team} by ${args.reason}`;
|
|
132
133
|
case 'updateUser':
|
|
133
134
|
return `${args.reason} and received **${args.passport.name}** passport from ${team}`;
|
|
135
|
+
case 'switchProfile':
|
|
136
|
+
return `switched profile to ${args.profile.fullName} for ${team}`;
|
|
137
|
+
case 'switchPassport':
|
|
138
|
+
return `switched passport to ${args.passport.role} for ${team}`;
|
|
139
|
+
case 'login':
|
|
140
|
+
return `${user} logged in to ${team} with passport ${args.passport.name}`;
|
|
134
141
|
case 'configWhoCanAccess':
|
|
135
142
|
return `updated access control policy to **${args.value}** for ${team} when ${args.reason}`;
|
|
136
143
|
case 'configPassportIssuance':
|
|
@@ -181,7 +188,7 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
181
188
|
case 'updateNodeInfo':
|
|
182
189
|
return `updated basic server settings: \n${Object.keys(args).map(x => `- ${x}: ${args[x]}`).join('\n')}`; // prettier-ignore
|
|
183
190
|
case 'upgradeNodeVersion':
|
|
184
|
-
return `
|
|
191
|
+
return `upgrade server to ${info.nextVersion}`;
|
|
185
192
|
case 'startServer':
|
|
186
193
|
return 'server was started';
|
|
187
194
|
case 'stopServer':
|
|
@@ -240,6 +247,9 @@ const getLogCategory = (action) => {
|
|
|
240
247
|
// teams: members/passports
|
|
241
248
|
case 'addUser':
|
|
242
249
|
case 'updateUser':
|
|
250
|
+
case 'switchProfile':
|
|
251
|
+
case 'switchPassport':
|
|
252
|
+
case 'login':
|
|
243
253
|
case 'configWhoCanAccess':
|
|
244
254
|
case 'processPassportIssuance':
|
|
245
255
|
case 'configPassportIssuance':
|
|
@@ -329,7 +339,7 @@ class AuditLogState extends BaseState {
|
|
|
329
339
|
}
|
|
330
340
|
* @return {object} new doc
|
|
331
341
|
*/
|
|
332
|
-
create({ action, args, context, result }, node) {
|
|
342
|
+
create({ action, args = {}, context = {}, result = {} }, node) {
|
|
333
343
|
return new Promise(async (resolve) => {
|
|
334
344
|
// Do not store secure configs in audit log
|
|
335
345
|
if (Array.isArray(args.configs)) {
|
package/lib/states/blocklet.js
CHANGED
|
@@ -522,7 +522,7 @@ class BlockletState extends BaseState {
|
|
|
522
522
|
|
|
523
523
|
const newChildren = [...oldChildren];
|
|
524
524
|
for (const child of children) {
|
|
525
|
-
const { meta, mountPoint,
|
|
525
|
+
const { meta, mountPoint, bundleSource = null, source = '', deployedFrom = '', mode } = child;
|
|
526
526
|
|
|
527
527
|
if (!mountPoint) {
|
|
528
528
|
throw new Error(`mountPoint is required when adding component ${getDisplayName(child, true)}`);
|
|
@@ -537,7 +537,7 @@ class BlockletState extends BaseState {
|
|
|
537
537
|
newChildren.push({
|
|
538
538
|
mountPoint,
|
|
539
539
|
meta,
|
|
540
|
-
|
|
540
|
+
bundleSource,
|
|
541
541
|
source,
|
|
542
542
|
deployedFrom,
|
|
543
543
|
mode,
|
package/lib/states/node.js
CHANGED
|
@@ -97,6 +97,7 @@ class NodeState extends BaseState {
|
|
|
97
97
|
didDomain,
|
|
98
98
|
enablePassportIssuance = true,
|
|
99
99
|
trustedPassports = [],
|
|
100
|
+
webWalletUrl,
|
|
100
101
|
} = this.options;
|
|
101
102
|
|
|
102
103
|
if (nodeOwner && !validateOwner(nodeOwner)) {
|
|
@@ -134,6 +135,7 @@ class NodeState extends BaseState {
|
|
|
134
135
|
enablePassportIssuance,
|
|
135
136
|
trustedPassports,
|
|
136
137
|
customBlockletNumber: 0,
|
|
138
|
+
webWalletUrl,
|
|
137
139
|
},
|
|
138
140
|
async (e, data) => {
|
|
139
141
|
if (e) {
|
|
@@ -197,34 +199,48 @@ class NodeState extends BaseState {
|
|
|
197
199
|
});
|
|
198
200
|
}
|
|
199
201
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
+
async addOwner(owner, doc) {
|
|
203
|
+
const initialized = this.isInitialized({ nodeOwner: owner });
|
|
204
|
+
|
|
205
|
+
if (this.notification && typeof this.notification.setDefaultReceiver === 'function') {
|
|
206
|
+
this.notification.setDefaultReceiver(owner.did);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const updateResult = await this.update(doc._id, {
|
|
210
|
+
$set: { nodeOwner: owner, initialized, initializedAt: initialized ? new Date() : null },
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
this.emit(EVENTS.NODE_ADDED_OWNER, updateResult);
|
|
214
|
+
|
|
215
|
+
return updateResult;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async addNodeOwner(owner) {
|
|
219
|
+
if (!validateOwner(owner)) {
|
|
202
220
|
throw new Error('Node owner is invalid');
|
|
203
221
|
}
|
|
204
222
|
|
|
205
|
-
|
|
206
|
-
if (doc.nodeOwner) {
|
|
207
|
-
if (isEqual(owner, doc.nodeOwner)) {
|
|
208
|
-
return doc;
|
|
209
|
-
}
|
|
223
|
+
const doc = await this.read();
|
|
210
224
|
|
|
211
|
-
|
|
225
|
+
if (doc.nodeOwner) {
|
|
226
|
+
if (isEqual(owner, doc.nodeOwner)) {
|
|
227
|
+
return doc;
|
|
212
228
|
}
|
|
213
229
|
|
|
214
|
-
|
|
230
|
+
throw new Error('Cannot set owner because owner already exists');
|
|
231
|
+
}
|
|
215
232
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
233
|
+
return this.addOwner(owner, doc);
|
|
234
|
+
}
|
|
219
235
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
236
|
+
async updateNodeOwner(owner) {
|
|
237
|
+
if (!validateOwner(owner)) {
|
|
238
|
+
throw new Error('Node owner is invalid');
|
|
239
|
+
}
|
|
223
240
|
|
|
224
|
-
|
|
241
|
+
const doc = await this.read();
|
|
225
242
|
|
|
226
|
-
|
|
227
|
-
});
|
|
243
|
+
return this.addOwner(owner, doc);
|
|
228
244
|
}
|
|
229
245
|
|
|
230
246
|
async enterMode(mode) {
|
package/lib/util/blocklet.js
CHANGED
|
@@ -10,6 +10,8 @@ const streamToPromise = require('stream-to-promise');
|
|
|
10
10
|
const { Throttle } = require('stream-throttle');
|
|
11
11
|
const ssri = require('ssri');
|
|
12
12
|
const diff = require('deep-diff');
|
|
13
|
+
const any = require('promise.any');
|
|
14
|
+
const joinUrl = require('url-join');
|
|
13
15
|
|
|
14
16
|
const { toHex } = require('@ocap/util');
|
|
15
17
|
const logger = require('@abtnode/logger')('@abtnode/core:util:blocklet');
|
|
@@ -20,7 +22,7 @@ const CustomError = require('@abtnode/util/lib/custom-error');
|
|
|
20
22
|
const getFolderSize = require('@abtnode/util/lib/get-folder-size');
|
|
21
23
|
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
22
24
|
const hashFiles = require('@abtnode/util/lib/hash-files');
|
|
23
|
-
const { BLOCKLET_MAX_MEM_LIMIT_IN_MB } = require('@abtnode/constant');
|
|
25
|
+
const { BLOCKLET_MAX_MEM_LIMIT_IN_MB, BLOCKLET_STORE_API_BLOCKLET_PREFIX } = require('@abtnode/constant');
|
|
24
26
|
|
|
25
27
|
const {
|
|
26
28
|
BlockletStatus,
|
|
@@ -411,12 +413,24 @@ const getBlockletMetaFromUrl = async (url) => {
|
|
|
411
413
|
|
|
412
414
|
meta.dist.tarball = tarball;
|
|
413
415
|
} catch (err) {
|
|
414
|
-
|
|
416
|
+
const msg = `Invalid blocklet meta: dist.tarball is not a valid url ${err.message}`;
|
|
417
|
+
logger.error(msg);
|
|
418
|
+
throw new Error(msg);
|
|
415
419
|
}
|
|
416
420
|
|
|
417
421
|
return meta;
|
|
418
422
|
};
|
|
419
423
|
|
|
424
|
+
const getBlockletMetaFromUrls = async (urls) => {
|
|
425
|
+
try {
|
|
426
|
+
const meta = await any(urls.map(getBlockletMetaFromUrl));
|
|
427
|
+
return meta;
|
|
428
|
+
} catch (err) {
|
|
429
|
+
logger.error('failed get blocklet meta', { urls });
|
|
430
|
+
throw new Error('Failed get blocklet meta');
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
|
|
420
434
|
/**
|
|
421
435
|
* Start all precesses of a blocklet
|
|
422
436
|
* @param {*} blocklet should contain env props
|
|
@@ -649,6 +663,36 @@ const parseChildren = (children, parentMeta = {}, { dynamic } = {}) => {
|
|
|
649
663
|
return children;
|
|
650
664
|
};
|
|
651
665
|
|
|
666
|
+
/**
|
|
667
|
+
* @param {*} config defined in childrenSchema in blocklet meta schema
|
|
668
|
+
*/
|
|
669
|
+
const getSourceUrlsFromConfig = (config) => {
|
|
670
|
+
if (config.source) {
|
|
671
|
+
if (config.source.url) {
|
|
672
|
+
return [config.source.url].flat();
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
const { store, version, name } = config.source;
|
|
676
|
+
return [store]
|
|
677
|
+
.flat()
|
|
678
|
+
.map((x) =>
|
|
679
|
+
joinUrl(
|
|
680
|
+
x,
|
|
681
|
+
BLOCKLET_STORE_API_BLOCKLET_PREFIX,
|
|
682
|
+
toBlockletDid(name),
|
|
683
|
+
!version || version === 'latest' ? '' : version,
|
|
684
|
+
'blocklet.json'
|
|
685
|
+
)
|
|
686
|
+
);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
if (config.resolved) {
|
|
690
|
+
return [config.resolved];
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
throw new Error('Invalid child config');
|
|
694
|
+
};
|
|
695
|
+
|
|
652
696
|
/**
|
|
653
697
|
* this function has side effect on children
|
|
654
698
|
*/
|
|
@@ -667,7 +711,15 @@ const parseChildrenFromMeta = async (src, { dynamic } = {}) => {
|
|
|
667
711
|
throw new Error(`MountPoint does not found in child ${config.name}`);
|
|
668
712
|
}
|
|
669
713
|
|
|
670
|
-
const
|
|
714
|
+
const urls = getSourceUrlsFromConfig(config);
|
|
715
|
+
|
|
716
|
+
let m;
|
|
717
|
+
try {
|
|
718
|
+
m = await getBlockletMetaFromUrls(urls);
|
|
719
|
+
} catch {
|
|
720
|
+
throw new Error('Failed get component meta');
|
|
721
|
+
}
|
|
722
|
+
|
|
671
723
|
validateBlockletMeta(m, { ensureDist: true });
|
|
672
724
|
|
|
673
725
|
const webInterface = findWebInterface(m);
|
|
@@ -691,7 +743,7 @@ const parseChildrenFromMeta = async (src, { dynamic } = {}) => {
|
|
|
691
743
|
const child = {
|
|
692
744
|
mountPoint,
|
|
693
745
|
meta,
|
|
694
|
-
|
|
746
|
+
bundleSource: config.source || { url: config.resolved },
|
|
695
747
|
};
|
|
696
748
|
|
|
697
749
|
children.push(child);
|
|
@@ -1234,4 +1286,5 @@ module.exports = {
|
|
|
1234
1286
|
verifyPurchase,
|
|
1235
1287
|
findAvailableDid,
|
|
1236
1288
|
ensureMeta,
|
|
1289
|
+
getSourceUrlsFromConfig,
|
|
1237
1290
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { NODE_REGISTER_URL, BLOCKLET_STORE_URL, BLOCKLET_STORE_URL_DEV
|
|
1
|
+
const { NODE_REGISTER_URL, BLOCKLET_STORE_URL, BLOCKLET_STORE_URL_DEV } = require('@abtnode/constant');
|
|
2
2
|
const canPackageReadWrite = require('@abtnode/util/lib/can-pkg-rw');
|
|
3
3
|
|
|
4
4
|
const getDefaultAutoUpgrade = () => {
|
|
@@ -36,7 +36,6 @@ const defaultNodeConfigs = {
|
|
|
36
36
|
],
|
|
37
37
|
},
|
|
38
38
|
registerUrl: { getDefaultValue: () => NODE_REGISTER_URL },
|
|
39
|
-
webWalletUrl: { getDefaultValue: () => WEB_WALLET_URL },
|
|
40
39
|
};
|
|
41
40
|
|
|
42
41
|
const lib = {
|
package/lib/util/index.js
CHANGED
|
@@ -358,15 +358,11 @@ const getBlockletMetaByUrl = async (url) => {
|
|
|
358
358
|
}
|
|
359
359
|
|
|
360
360
|
if (protocol.startsWith('http')) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
throw new Error('Url is not valid');
|
|
365
|
-
}
|
|
366
|
-
return meta;
|
|
367
|
-
} catch (err) {
|
|
368
|
-
throw new Error(`Failed to get blocklet meta from ${url}: ${err.message}`);
|
|
361
|
+
const { data: meta } = await request({ url, method: 'GET', timeout: 1000 * 20 });
|
|
362
|
+
if (Object.prototype.toString.call(meta) !== '[object Object]') {
|
|
363
|
+
throw new Error('Url is not valid');
|
|
369
364
|
}
|
|
365
|
+
return meta;
|
|
370
366
|
}
|
|
371
367
|
|
|
372
368
|
throw new Error(`Invalid url protocol: ${protocol.replace(/:$/, '')}`);
|
package/lib/util/requirement.js
CHANGED
|
@@ -28,7 +28,9 @@ const isSatisfied = (requirements, throwOnUnsatisfied = true) => {
|
|
|
28
28
|
throw new Error(`Your blocklet is not supported on architecture ${actualCpu}`);
|
|
29
29
|
}
|
|
30
30
|
if (isVersionSatisfied === false) {
|
|
31
|
-
throw new Error(
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Expected server version for the blocklet is ${expectedVersion}, but your server version is ${actualVersion}, please upgrade or downgrade your server to continue.`
|
|
33
|
+
);
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
|
package/lib/util/upgrade.js
CHANGED
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.7.
|
|
6
|
+
"version": "1.7.15",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,29 +19,29 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/certificate-manager": "1.7.
|
|
23
|
-
"@abtnode/constant": "1.7.
|
|
24
|
-
"@abtnode/cron": "1.7.
|
|
25
|
-
"@abtnode/db": "1.7.
|
|
26
|
-
"@abtnode/logger": "1.7.
|
|
27
|
-
"@abtnode/queue": "1.7.
|
|
28
|
-
"@abtnode/rbac": "1.7.
|
|
29
|
-
"@abtnode/router-provider": "1.7.
|
|
30
|
-
"@abtnode/static-server": "1.7.
|
|
31
|
-
"@abtnode/timemachine": "1.7.
|
|
32
|
-
"@abtnode/util": "1.7.
|
|
33
|
-
"@arcblock/did": "^1.16.
|
|
22
|
+
"@abtnode/certificate-manager": "1.7.15",
|
|
23
|
+
"@abtnode/constant": "1.7.15",
|
|
24
|
+
"@abtnode/cron": "1.7.15",
|
|
25
|
+
"@abtnode/db": "1.7.15",
|
|
26
|
+
"@abtnode/logger": "1.7.15",
|
|
27
|
+
"@abtnode/queue": "1.7.15",
|
|
28
|
+
"@abtnode/rbac": "1.7.15",
|
|
29
|
+
"@abtnode/router-provider": "1.7.15",
|
|
30
|
+
"@abtnode/static-server": "1.7.15",
|
|
31
|
+
"@abtnode/timemachine": "1.7.15",
|
|
32
|
+
"@abtnode/util": "1.7.15",
|
|
33
|
+
"@arcblock/did": "^1.16.8",
|
|
34
34
|
"@arcblock/did-motif": "^1.1.5",
|
|
35
|
-
"@arcblock/event-hub": "1.16.
|
|
35
|
+
"@arcblock/event-hub": "1.16.8",
|
|
36
36
|
"@arcblock/pm2-events": "^0.0.5",
|
|
37
|
-
"@arcblock/vc": "^1.16.
|
|
38
|
-
"@blocklet/meta": "1.7.
|
|
37
|
+
"@arcblock/vc": "^1.16.8",
|
|
38
|
+
"@blocklet/meta": "1.7.15",
|
|
39
39
|
"@fidm/x509": "^1.2.1",
|
|
40
40
|
"@nedb/core": "^1.2.2",
|
|
41
41
|
"@nedb/multi": "^1.2.2",
|
|
42
|
-
"@ocap/mcrypto": "^1.16.
|
|
43
|
-
"@ocap/util": "^1.16.
|
|
44
|
-
"@ocap/wallet": "^1.16.
|
|
42
|
+
"@ocap/mcrypto": "^1.16.8",
|
|
43
|
+
"@ocap/util": "^1.16.8",
|
|
44
|
+
"@ocap/wallet": "^1.16.8",
|
|
45
45
|
"@slack/webhook": "^5.0.3",
|
|
46
46
|
"axios": "^0.26.1",
|
|
47
47
|
"axon": "^2.0.3",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"lodash": "^4.17.21",
|
|
60
60
|
"lru-cache": "^6.0.0",
|
|
61
61
|
"pm2": "^5.1.2",
|
|
62
|
+
"promise.any": "^2.0.4",
|
|
62
63
|
"semver": "^7.3.2",
|
|
63
64
|
"shelljs": "^0.8.4",
|
|
64
65
|
"slugify": "^1.4.6",
|
|
@@ -78,5 +79,5 @@
|
|
|
78
79
|
"express": "^4.17.1",
|
|
79
80
|
"jest": "^27.4.5"
|
|
80
81
|
},
|
|
81
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "d95421b38c281ed41fa7490a707f149aa737f3d3"
|
|
82
83
|
}
|