@abtnode/core 1.7.10 → 1.7.13
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/api/node.js +7 -1
- package/lib/api/team.js +2 -2
- package/lib/blocklet/manager/disk.js +141 -81
- package/lib/blocklet/registry.js +6 -2
- package/lib/event.js +5 -0
- package/lib/index.js +39 -7
- package/lib/migrations/1.7.12-blocklet-meta.js +51 -0
- package/lib/router/index.js +7 -0
- package/lib/states/README.md +31 -1
- package/lib/states/audit-log.js +382 -0
- package/lib/states/blocklet.js +9 -7
- package/lib/states/index.js +3 -0
- package/lib/states/node.js +8 -0
- package/lib/util/blocklet.js +102 -43
- package/lib/util/index.js +35 -0
- package/lib/util/ip.js +6 -0
- package/lib/util/rpc.js +16 -0
- package/lib/util/ua.js +54 -0
- package/lib/util/upgrade.js +3 -15
- package/lib/validators/node.js +13 -0
- package/package.json +21 -20
package/lib/api/node.js
CHANGED
|
@@ -10,7 +10,7 @@ const canPackageReadWrite = require('@abtnode/util/lib/can-pkg-rw');
|
|
|
10
10
|
const logger = require('@abtnode/logger')('@abtnode/core:api:node');
|
|
11
11
|
|
|
12
12
|
const IP = require('../util/ip');
|
|
13
|
-
const { validateNodeInfo } = require('../validators/node');
|
|
13
|
+
const { validateNodeInfo, validateUpdateGateway } = require('../validators/node');
|
|
14
14
|
const BlockletRegistry = require('../blocklet/registry');
|
|
15
15
|
const { getAll } = require('../blocklet/manager/engine');
|
|
16
16
|
|
|
@@ -154,6 +154,12 @@ class NodeAPI {
|
|
|
154
154
|
|
|
155
155
|
return res;
|
|
156
156
|
}
|
|
157
|
+
|
|
158
|
+
async updateGateway(entity, context) {
|
|
159
|
+
const data = await validateUpdateGateway(entity, context);
|
|
160
|
+
|
|
161
|
+
return this.state.updateGateway(data);
|
|
162
|
+
}
|
|
157
163
|
}
|
|
158
164
|
|
|
159
165
|
module.exports = NodeAPI;
|
package/lib/api/team.js
CHANGED
|
@@ -54,9 +54,9 @@ class TeamAPI extends EventEmitter {
|
|
|
54
54
|
if (teamDid === nodeInfo.did && nodeInfo.nodeOwner && user.did !== nodeInfo.nodeOwner.did) {
|
|
55
55
|
await this.notification.create({
|
|
56
56
|
title: 'New member join',
|
|
57
|
-
description: `User with Name (${user.fullName}) and DID (${user.did}) has joined this
|
|
57
|
+
description: `User with Name (${user.fullName}) and DID (${user.did}) has joined this server`,
|
|
58
58
|
entityType: 'node',
|
|
59
|
-
action: '/
|
|
59
|
+
action: '/team/members',
|
|
60
60
|
entityId: user.did,
|
|
61
61
|
severity: 'success',
|
|
62
62
|
});
|
|
@@ -31,6 +31,7 @@ const {
|
|
|
31
31
|
isDeletableBlocklet,
|
|
32
32
|
getRequiredMissingConfigs,
|
|
33
33
|
hasRunnableComponent,
|
|
34
|
+
forEachBlocklet,
|
|
34
35
|
} = require('@blocklet/meta/lib/util');
|
|
35
36
|
const validateBlockletEntry = require('@blocklet/meta/lib/entry');
|
|
36
37
|
const toBlockletDid = require('@blocklet/meta/lib/did');
|
|
@@ -63,7 +64,6 @@ const {
|
|
|
63
64
|
getFromCache: getAccessibleExternalNodeIp,
|
|
64
65
|
} = require('../../util/get-accessible-external-node-ip');
|
|
65
66
|
const {
|
|
66
|
-
forEachBlocklet,
|
|
67
67
|
getBlockletDirs,
|
|
68
68
|
getBlockletMetaFromUrl,
|
|
69
69
|
fillBlockletConfigs,
|
|
@@ -88,12 +88,15 @@ const {
|
|
|
88
88
|
getUpdateMetaList,
|
|
89
89
|
getRuntimeEnvironments,
|
|
90
90
|
getSourceFromInstallParams,
|
|
91
|
+
parseChildrenFromMeta,
|
|
91
92
|
parseChildren,
|
|
92
93
|
checkDuplicateComponents,
|
|
93
94
|
getDiffFiles,
|
|
94
95
|
getBundleDir,
|
|
95
96
|
needBlockletDownload,
|
|
96
97
|
verifyPurchase,
|
|
98
|
+
findAvailableDid,
|
|
99
|
+
ensureMeta,
|
|
97
100
|
} = require('../../util/blocklet');
|
|
98
101
|
const { parseSourceUrl } = require('../../util/registry');
|
|
99
102
|
const states = require('../../states');
|
|
@@ -217,11 +220,15 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
217
220
|
*
|
|
218
221
|
* InstallFromUpload
|
|
219
222
|
* @param {Object} file
|
|
220
|
-
* @param {String} did for diff upload
|
|
223
|
+
* @param {String} did for diff upload or custom component did
|
|
221
224
|
* @param {String} diffVersion for diff upload
|
|
222
225
|
* @param {Array} deleteSet for diff upload
|
|
226
|
+
*
|
|
227
|
+
* Custom info
|
|
228
|
+
* @param {String} title custom component title
|
|
229
|
+
* @param {String} name custom component name
|
|
223
230
|
*/
|
|
224
|
-
async installComponent({ rootDid, mountPoint, url, file, did, diffVersion, deleteSet }, context = {}) {
|
|
231
|
+
async installComponent({ rootDid, mountPoint, url, file, did, diffVersion, deleteSet, title, name }, context = {}) {
|
|
225
232
|
logger.debug('start install component', { rootDid, mountPoint, url });
|
|
226
233
|
|
|
227
234
|
if (file) {
|
|
@@ -229,7 +236,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
229
236
|
}
|
|
230
237
|
|
|
231
238
|
if (url) {
|
|
232
|
-
return this._installComponentFromUrl({ rootDid, mountPoint, url, context });
|
|
239
|
+
return this._installComponentFromUrl({ rootDid, mountPoint, url, context, title, did, name });
|
|
233
240
|
}
|
|
234
241
|
|
|
235
242
|
// should not be here
|
|
@@ -283,7 +290,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
283
290
|
|
|
284
291
|
async start({ did, throwOnError, checkHealthImmediately = false, e2eMode = false }, context) {
|
|
285
292
|
logger.info('start blocklet', { did });
|
|
286
|
-
const blocklet = await this.ensureBlocklet(did, e2eMode);
|
|
293
|
+
const blocklet = await this.ensureBlocklet(did, { e2eMode });
|
|
287
294
|
|
|
288
295
|
try {
|
|
289
296
|
if (!hasRunnableComponent(blocklet)) {
|
|
@@ -452,7 +459,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
452
459
|
logger.info('delete blocklet', { did, keepData });
|
|
453
460
|
|
|
454
461
|
try {
|
|
455
|
-
const blocklet = await this.ensureBlocklet(did);
|
|
462
|
+
const blocklet = await this.ensureBlocklet(did, { validateEnv: false });
|
|
456
463
|
if (isDeletableBlocklet(blocklet) === false) {
|
|
457
464
|
throw new Error('Blocklet is protected from accidental deletion');
|
|
458
465
|
}
|
|
@@ -521,14 +528,33 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
521
528
|
async deleteComponent({ did, rootDid }, context) {
|
|
522
529
|
logger.info('delete blocklet component', { did, rootDid });
|
|
523
530
|
|
|
531
|
+
const blocklet = await this.ensureBlocklet(rootDid);
|
|
524
532
|
const doc = await states.blocklet.getBlocklet(rootDid);
|
|
525
533
|
|
|
534
|
+
const child = doc.children.find((x) => x.meta.did === did);
|
|
535
|
+
|
|
536
|
+
if (!child) {
|
|
537
|
+
throw new Error('Component does not exist');
|
|
538
|
+
}
|
|
539
|
+
|
|
526
540
|
doc.children = doc.children.filter((x) => x.meta.did !== did);
|
|
527
541
|
const children = (await this._getDynamicChildrenFromSettings(rootDid)).filter((x) => x.meta.did !== did);
|
|
542
|
+
children.push({
|
|
543
|
+
meta: pick(child.meta, ['did', 'name', 'bundleDid', 'bundleName', 'version', 'title', 'description']),
|
|
544
|
+
mountPoint: child.mountPoint,
|
|
545
|
+
status: BlockletStatus.deleted,
|
|
546
|
+
deletedAt: new Date(),
|
|
547
|
+
});
|
|
528
548
|
|
|
529
549
|
await states.blocklet.updateBlocklet(rootDid, doc);
|
|
530
550
|
states.blockletExtras.setSettings(rootDid, { children });
|
|
531
551
|
|
|
552
|
+
// delete storage
|
|
553
|
+
const childBlocklet = blocklet.children.find((x) => x.meta.did === did);
|
|
554
|
+
const { cacheDir, logsDir } = childBlocklet.env;
|
|
555
|
+
fs.removeSync(cacheDir);
|
|
556
|
+
fs.removeSync(logsDir);
|
|
557
|
+
|
|
532
558
|
const newBlocklet = await this.ensureBlocklet(rootDid);
|
|
533
559
|
this.emit(BlockletEvents.upgraded, { blocklet: newBlocklet, context }); // trigger router refresh
|
|
534
560
|
return newBlocklet;
|
|
@@ -738,9 +764,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
738
764
|
|
|
739
765
|
const upgradeFromRegistry = registryUrl || blocklet.deployedFrom;
|
|
740
766
|
|
|
741
|
-
const
|
|
767
|
+
const newVersionMeta = await this.registry.getBlockletMeta(
|
|
742
768
|
{
|
|
743
|
-
did,
|
|
769
|
+
did: blocklet.meta.bundleDid,
|
|
744
770
|
registryUrl: upgradeFromRegistry,
|
|
745
771
|
},
|
|
746
772
|
context
|
|
@@ -767,7 +793,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
767
793
|
}
|
|
768
794
|
|
|
769
795
|
const currentDeveloperSignature = getSignature(blocklet.meta.signatures);
|
|
770
|
-
const newVersionDeveloperSignature = getSignature(
|
|
796
|
+
const newVersionDeveloperSignature = getSignature(newVersionMeta.signatures, blocklet.meta.signatures);
|
|
771
797
|
|
|
772
798
|
if (!newVersionDeveloperSignature) {
|
|
773
799
|
throw new Error('Invalid upgrade blocklet signature');
|
|
@@ -783,15 +809,15 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
783
809
|
throw new Error('Invalid developer signature');
|
|
784
810
|
}
|
|
785
811
|
|
|
786
|
-
if (blocklet.meta.version ===
|
|
812
|
+
if (blocklet.meta.version === newVersionMeta.version) {
|
|
787
813
|
throw new Error('Upgrade/downgrade blocklet to same version is noop');
|
|
788
814
|
}
|
|
789
815
|
|
|
790
|
-
const action = semver.gt(blocklet.meta.version,
|
|
816
|
+
const action = semver.gt(blocklet.meta.version, newVersionMeta.version) ? 'downgrade' : 'upgrade';
|
|
791
817
|
logger.info(`${action} blocklet`, { did });
|
|
792
818
|
|
|
793
819
|
return this._upgrade({
|
|
794
|
-
meta:
|
|
820
|
+
meta: newVersionMeta,
|
|
795
821
|
source: BlockletSource.registry,
|
|
796
822
|
deployedFrom: upgradeFromRegistry,
|
|
797
823
|
context,
|
|
@@ -859,16 +885,19 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
859
885
|
|
|
860
886
|
async checkChildrenForUpdates({ did }) {
|
|
861
887
|
const blocklet = await states.blocklet.getBlocklet(did);
|
|
862
|
-
const newStaticChildren = await
|
|
888
|
+
const newStaticChildren = await parseChildrenFromMeta(blocklet.meta);
|
|
863
889
|
|
|
864
|
-
const oldDynamicChildren = await this._getDynamicChildrenFromSettings(did);
|
|
890
|
+
const oldDynamicChildren = await this._getDynamicChildrenFromSettings(did, { skipDeleted: true });
|
|
865
891
|
const noneSourceUrlChildren = oldDynamicChildren.filter((x) => !x.sourceUrl);
|
|
866
892
|
const dynamicConfig = oldDynamicChildren
|
|
867
893
|
.filter((x) => x.sourceUrl)
|
|
868
894
|
.map((x) => ({ resolved: x.sourceUrl, name: x.meta.name, mountPoint: x.mountPoint }));
|
|
869
|
-
const newDynamicChildren = [
|
|
895
|
+
const newDynamicChildren = [
|
|
896
|
+
...noneSourceUrlChildren,
|
|
897
|
+
...(await parseChildrenFromMeta(dynamicConfig, { dynamic: true })),
|
|
898
|
+
];
|
|
870
899
|
|
|
871
|
-
checkDuplicateComponents(newDynamicChildren, newStaticChildren);
|
|
900
|
+
checkDuplicateComponents([...newDynamicChildren, ...newStaticChildren]);
|
|
872
901
|
|
|
873
902
|
const updateList = getUpdateMetaList(
|
|
874
903
|
[...blocklet.children.map((x) => x.meta), ...oldDynamicChildren.map((x) => x.meta)],
|
|
@@ -1013,7 +1042,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1013
1042
|
|
|
1014
1043
|
const children = await this._getChildren(meta);
|
|
1015
1044
|
const added = await states.blocklet.addBlocklet({
|
|
1016
|
-
did,
|
|
1017
1045
|
meta,
|
|
1018
1046
|
source: BlockletSource.local,
|
|
1019
1047
|
deployedFrom: folder,
|
|
@@ -1062,19 +1090,17 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1062
1090
|
}
|
|
1063
1091
|
|
|
1064
1092
|
const defaultPath = formatName(meta.name);
|
|
1065
|
-
const children = await parseChildren(
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
dynamic: true,
|
|
1077
|
-
});
|
|
1093
|
+
const children = await parseChildren([
|
|
1094
|
+
{
|
|
1095
|
+
meta: ensureMeta(meta),
|
|
1096
|
+
mountPoint: mountPoint || `/${defaultPath}`,
|
|
1097
|
+
source: BlockletSource.local,
|
|
1098
|
+
deployedFrom: folder,
|
|
1099
|
+
status: BlockletStatus.installed,
|
|
1100
|
+
mode: BLOCKLET_MODES.DEVELOPMENT,
|
|
1101
|
+
dynamic: true,
|
|
1102
|
+
},
|
|
1103
|
+
]);
|
|
1078
1104
|
await states.blocklet.addChildren(rootDid, children);
|
|
1079
1105
|
|
|
1080
1106
|
logger.info('add blocklet component for dev', { did, version, meta });
|
|
@@ -1088,7 +1114,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1088
1114
|
return rootBlocklet;
|
|
1089
1115
|
}
|
|
1090
1116
|
|
|
1091
|
-
async ensureBlocklet(did, e2eMode = false) {
|
|
1117
|
+
async ensureBlocklet(did, { e2eMode = false, validateEnv = true } = {}) {
|
|
1092
1118
|
if (!isValidDid(did)) {
|
|
1093
1119
|
throw new Error(`Blocklet did is invalid: ${did}`);
|
|
1094
1120
|
}
|
|
@@ -1098,6 +1124,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1098
1124
|
throw new Error(`Can not find blocklet in database by did ${did}`);
|
|
1099
1125
|
}
|
|
1100
1126
|
|
|
1127
|
+
// env
|
|
1101
1128
|
blocklet.env = {
|
|
1102
1129
|
appId: blocklet.meta.name,
|
|
1103
1130
|
// dataDir is /dataDir.data/blocklet.meta.name
|
|
@@ -1107,18 +1134,23 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1107
1134
|
dataDirs: this.dataDirs,
|
|
1108
1135
|
ensure: true,
|
|
1109
1136
|
e2eMode,
|
|
1137
|
+
validate: validateEnv,
|
|
1110
1138
|
}),
|
|
1111
1139
|
};
|
|
1112
1140
|
|
|
1141
|
+
// configs
|
|
1113
1142
|
const configs = await states.blockletExtras.getConfigs(blocklet.meta.did);
|
|
1114
1143
|
fillBlockletConfigs(blocklet, configs);
|
|
1115
1144
|
|
|
1116
|
-
//
|
|
1145
|
+
// settings
|
|
1117
1146
|
const settings = await states.blockletExtras.getSettings(blocklet.meta.did);
|
|
1118
1147
|
blocklet.trustedPassports = get(settings, 'trustedPassports') || [];
|
|
1119
1148
|
blocklet.enablePassportIssuance = get(settings, 'enablePassportIssuance', true);
|
|
1120
1149
|
blocklet.settings = settings || {};
|
|
1121
1150
|
|
|
1151
|
+
// site
|
|
1152
|
+
blocklet.site = await this.getSiteByDid(blocklet.meta.did);
|
|
1153
|
+
|
|
1122
1154
|
// handle child env
|
|
1123
1155
|
for (const child of blocklet.children) {
|
|
1124
1156
|
const {
|
|
@@ -1128,11 +1160,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1128
1160
|
meta: { name },
|
|
1129
1161
|
} = blocklet;
|
|
1130
1162
|
|
|
1163
|
+
// child env
|
|
1131
1164
|
child.env = {
|
|
1132
1165
|
appId: `${encodeURIComponent(name)}/${encodeURIComponent(childName)}`,
|
|
1133
|
-
// dataDir is /dataDir.data/blocklet.meta.name/child.meta.name
|
|
1134
|
-
// cacheDir is /dataDirs.cache/blocklet.meta.name/child.meta.name
|
|
1135
|
-
// logDir is /dataDirs.log/blocklet.meta.name
|
|
1136
1166
|
...getBlockletDirs(child, {
|
|
1137
1167
|
dataDirs: this.dataDirs,
|
|
1138
1168
|
ensure: true,
|
|
@@ -1140,13 +1170,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1140
1170
|
}),
|
|
1141
1171
|
};
|
|
1142
1172
|
|
|
1173
|
+
// child configs
|
|
1143
1174
|
const childConfigs = await states.blockletExtras.getChildConfigs(blocklet.meta.did, childDid);
|
|
1144
1175
|
fillBlockletConfigs(child, childConfigs, blocklet);
|
|
1145
1176
|
}
|
|
1146
1177
|
|
|
1147
|
-
// site
|
|
1148
|
-
blocklet.site = await this.getSiteByDid(blocklet.meta.did);
|
|
1149
|
-
|
|
1150
1178
|
return blocklet;
|
|
1151
1179
|
}
|
|
1152
1180
|
|
|
@@ -1583,7 +1611,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1583
1611
|
});
|
|
1584
1612
|
}
|
|
1585
1613
|
|
|
1586
|
-
async _installComponentFromUrl({ rootDid, mountPoint, url, context }) {
|
|
1614
|
+
async _installComponentFromUrl({ rootDid, mountPoint, url, context, title, name: inputName, did: inputDid }) {
|
|
1587
1615
|
const blocklet = await states.blocklet.getBlocklet(rootDid);
|
|
1588
1616
|
if (!blocklet) {
|
|
1589
1617
|
throw new Error('Root blocklet does not exist');
|
|
@@ -1601,18 +1629,31 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1601
1629
|
|
|
1602
1630
|
verifyPurchase(meta, context);
|
|
1603
1631
|
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1632
|
+
if (title) {
|
|
1633
|
+
meta.title = await titleSchema.validateAsync(title);
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
let name = inputName;
|
|
1637
|
+
let did = inputDid;
|
|
1638
|
+
if (!inputName && !inputDid) {
|
|
1639
|
+
const found = findAvailableDid(meta, [
|
|
1640
|
+
...blocklet.children.map((x) => x.meta),
|
|
1641
|
+
...(await states.blockletExtras.getSettings(rootDid, 'children', [])).map((x) => x.meta),
|
|
1642
|
+
]);
|
|
1643
|
+
name = found.name;
|
|
1644
|
+
did = found.did;
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
const newChildren = await parseChildren([
|
|
1648
|
+
{
|
|
1649
|
+
meta: ensureMeta(meta, { did, name }),
|
|
1650
|
+
mountPoint,
|
|
1651
|
+
sourceUrl: url,
|
|
1652
|
+
dynamic: true,
|
|
1653
|
+
},
|
|
1654
|
+
]);
|
|
1614
1655
|
|
|
1615
|
-
checkDuplicateComponents(blocklet.children, newChildren);
|
|
1656
|
+
checkDuplicateComponents([...blocklet.children, ...newChildren]);
|
|
1616
1657
|
|
|
1617
1658
|
// add component to db
|
|
1618
1659
|
await states.blocklet.addChildren(rootDid, newChildren);
|
|
@@ -1656,7 +1697,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1656
1697
|
const meta = validateMeta(rawMeta);
|
|
1657
1698
|
|
|
1658
1699
|
await states.blocklet.addBlocklet({
|
|
1659
|
-
did: meta.did,
|
|
1660
1700
|
meta,
|
|
1661
1701
|
source: BlockletSource.custom,
|
|
1662
1702
|
});
|
|
@@ -1723,7 +1763,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1723
1763
|
|
|
1724
1764
|
const { meta } = await this._resolveDiffDownload(cwd, tarFile, deleteSet, oldBlocklet.meta);
|
|
1725
1765
|
const newBlocklet = await states.blocklet.getBlocklet(did);
|
|
1726
|
-
newBlocklet.meta = meta;
|
|
1766
|
+
newBlocklet.meta = ensureMeta(meta);
|
|
1727
1767
|
newBlocklet.source = BlockletSource.upload;
|
|
1728
1768
|
newBlocklet.deployedFrom = `Upload by ${context.user.fullName}`;
|
|
1729
1769
|
newBlocklet.children = await this._getChildren(meta);
|
|
@@ -1749,7 +1789,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1749
1789
|
}
|
|
1750
1790
|
|
|
1751
1791
|
const newBlocklet = await states.blocklet.getBlocklet(meta.did);
|
|
1752
|
-
newBlocklet.meta = meta;
|
|
1792
|
+
newBlocklet.meta = ensureMeta(meta);
|
|
1753
1793
|
newBlocklet.source = BlockletSource.upload;
|
|
1754
1794
|
newBlocklet.deployedFrom = `Upload by ${context.user.fullName}`;
|
|
1755
1795
|
newBlocklet.children = await this._getChildren(meta);
|
|
@@ -1767,7 +1807,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1767
1807
|
// full deploy - install
|
|
1768
1808
|
const children = await this._getChildren(meta);
|
|
1769
1809
|
const blocklet = await states.blocklet.addBlocklet({
|
|
1770
|
-
did: meta.did,
|
|
1771
1810
|
meta,
|
|
1772
1811
|
source: BlockletSource.upload,
|
|
1773
1812
|
deployedFrom: `Upload by ${context.user.fullName}`,
|
|
@@ -1834,28 +1873,26 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1834
1873
|
}
|
|
1835
1874
|
|
|
1836
1875
|
const newBlocklet = await states.blocklet.getBlocklet(rootDid);
|
|
1837
|
-
|
|
1876
|
+
|
|
1877
|
+
if (newBlocklet.children.some((x) => !x.dynamic && x.meta.did === meta.did)) {
|
|
1878
|
+
throw new Error('Cannot add duplicate component defined in app meta');
|
|
1879
|
+
}
|
|
1838
1880
|
|
|
1839
1881
|
const newChild = {
|
|
1840
|
-
meta,
|
|
1882
|
+
meta: ensureMeta(meta),
|
|
1841
1883
|
mountPoint,
|
|
1842
1884
|
source: BlockletSource.upload,
|
|
1843
1885
|
deployedFrom: `Upload by ${context.user.fullName}`,
|
|
1844
1886
|
sourceUrl: '',
|
|
1845
1887
|
dynamic: true,
|
|
1846
1888
|
};
|
|
1847
|
-
const index =
|
|
1889
|
+
const index = newBlocklet.children.findIndex((child) => child.meta.did === meta.did);
|
|
1848
1890
|
if (index >= 0) {
|
|
1849
|
-
|
|
1891
|
+
newBlocklet.children.splice(index, 1, newChild);
|
|
1850
1892
|
} else {
|
|
1851
|
-
|
|
1893
|
+
newBlocklet.children.push(newChild);
|
|
1852
1894
|
}
|
|
1853
1895
|
|
|
1854
|
-
const staticChildren = newBlocklet.children.filter((x) => !x.dynamic);
|
|
1855
|
-
checkDuplicateComponents(dynamicChildren, staticChildren);
|
|
1856
|
-
|
|
1857
|
-
newBlocklet.children = [...staticChildren, ...dynamicChildren.map((x) => ({ ...x, dynamic: true }))];
|
|
1858
|
-
|
|
1859
1896
|
await validateBlocklet(newBlocklet);
|
|
1860
1897
|
|
|
1861
1898
|
return this._upgradeBlocklet({
|
|
@@ -1902,13 +1939,15 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1902
1939
|
throw new Error('the blocklet is not installed');
|
|
1903
1940
|
}
|
|
1904
1941
|
|
|
1942
|
+
const { bundleDid } = blocklet.meta;
|
|
1943
|
+
|
|
1905
1944
|
let versions = this.cachedBlockletVersions.get(did);
|
|
1906
1945
|
|
|
1907
1946
|
if (!versions) {
|
|
1908
1947
|
const { blockletRegistryList } = await states.node.read();
|
|
1909
1948
|
const tasks = blockletRegistryList.map((registry) =>
|
|
1910
1949
|
this.registry
|
|
1911
|
-
.getBlockletMeta({ did, registryUrl: registry.url })
|
|
1950
|
+
.getBlockletMeta({ did: bundleDid, registryUrl: registry.url })
|
|
1912
1951
|
.then((item) => ({ did, version: item.version, registryUrl: registry.url }))
|
|
1913
1952
|
.catch((error) => {
|
|
1914
1953
|
if (error.response && error.response.status === 404) {
|
|
@@ -1982,19 +2021,24 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1982
2021
|
}
|
|
1983
2022
|
|
|
1984
2023
|
async _getChildren(meta) {
|
|
1985
|
-
const staticChildren = await
|
|
1986
|
-
const dynamicChildren = await parseChildren(
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
2024
|
+
const staticChildren = await parseChildrenFromMeta(meta);
|
|
2025
|
+
const dynamicChildren = await parseChildren(
|
|
2026
|
+
await this._getDynamicChildrenFromSettings(meta.did, { skipDeleted: true }),
|
|
2027
|
+
meta,
|
|
2028
|
+
{
|
|
2029
|
+
dynamic: true,
|
|
2030
|
+
}
|
|
2031
|
+
);
|
|
2032
|
+
checkDuplicateComponents([...dynamicChildren, ...staticChildren]);
|
|
1991
2033
|
|
|
1992
2034
|
return [...staticChildren, ...dynamicChildren];
|
|
1993
2035
|
}
|
|
1994
2036
|
|
|
1995
|
-
async _getDynamicChildrenFromSettings(did) {
|
|
2037
|
+
async _getDynamicChildrenFromSettings(did, { skipDeleted } = {}) {
|
|
1996
2038
|
const children = await states.blockletExtras.getSettings(did, 'children', []);
|
|
1997
|
-
return children
|
|
2039
|
+
return children
|
|
2040
|
+
.map((x) => ({ ...x, dynamic: true }))
|
|
2041
|
+
.filter((x) => (skipDeleted ? x.status !== BlockletStatus.deleted : true));
|
|
1998
2042
|
}
|
|
1999
2043
|
|
|
2000
2044
|
async _install({ meta, source, deployedFrom, context, sync }) {
|
|
@@ -2005,7 +2049,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2005
2049
|
const children = await this._getChildren(meta);
|
|
2006
2050
|
try {
|
|
2007
2051
|
const blocklet = await states.blocklet.addBlocklet({
|
|
2008
|
-
did: meta.did,
|
|
2009
2052
|
meta,
|
|
2010
2053
|
source,
|
|
2011
2054
|
deployedFrom,
|
|
@@ -2091,11 +2134,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2091
2134
|
|
|
2092
2135
|
// NOTE: 目前的版本移除了降级通道,所以不需要考虑降级通道的情况
|
|
2093
2136
|
const action = semver.gt(oldBlocklet.meta.version, version) ? 'downgrade' : 'upgrade';
|
|
2094
|
-
logger.info(`${action} blocklet`, { did, version });
|
|
2137
|
+
logger.info(`${action} blocklet`, { did, name, version });
|
|
2095
2138
|
|
|
2096
2139
|
const newBlocklet = await states.blocklet.setBlockletStatus(did, BlockletStatus.waiting);
|
|
2097
2140
|
|
|
2098
|
-
newBlocklet.meta = meta;
|
|
2141
|
+
newBlocklet.meta = ensureMeta(meta);
|
|
2099
2142
|
newBlocklet.source = source;
|
|
2100
2143
|
newBlocklet.deployedFrom = deployedFrom;
|
|
2101
2144
|
newBlocklet.children = await this._getChildren(meta);
|
|
@@ -2326,6 +2369,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2326
2369
|
|
|
2327
2370
|
this.emit(BlockletEvents.installed, { blocklet, context });
|
|
2328
2371
|
|
|
2372
|
+
// Update dynamic component meta in blocklet settings
|
|
2373
|
+
await this._ensureDynamicChildrenInSettings(blocklet);
|
|
2374
|
+
|
|
2329
2375
|
states.notification.create({
|
|
2330
2376
|
title: 'Blocklet Installed',
|
|
2331
2377
|
description: `Blocklet ${meta.name}@${meta.version} is installed successfully. (Source: ${
|
|
@@ -2475,10 +2521,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2475
2521
|
}
|
|
2476
2522
|
|
|
2477
2523
|
// Update dynamic component meta in blocklet settings
|
|
2478
|
-
|
|
2479
|
-
.filter((x) => x.dynamic)
|
|
2480
|
-
.map((x) => pick(x, ['meta', 'mountPoint', 'sourceUrl', 'source']));
|
|
2481
|
-
await states.blockletExtras.setSettings(did, { children: dynamicChildren });
|
|
2524
|
+
await this._ensureDynamicChildrenInSettings(blocklet);
|
|
2482
2525
|
|
|
2483
2526
|
return blocklet;
|
|
2484
2527
|
} catch (err) {
|
|
@@ -2496,6 +2539,23 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2496
2539
|
}
|
|
2497
2540
|
}
|
|
2498
2541
|
|
|
2542
|
+
// Update dynamic component meta in blocklet settings
|
|
2543
|
+
async _ensureDynamicChildrenInSettings(blocklet) {
|
|
2544
|
+
const { did } = blocklet.meta;
|
|
2545
|
+
const dynamicChildren = blocklet.children
|
|
2546
|
+
.filter((x) => x.dynamic)
|
|
2547
|
+
.map((x) => pick(x, ['meta', 'mountPoint', 'sourceUrl', 'source']));
|
|
2548
|
+
|
|
2549
|
+
// deleted blocklet
|
|
2550
|
+
let deletes = await states.blockletExtras.getSettings(did, 'children', []);
|
|
2551
|
+
deletes = deletes.filter(
|
|
2552
|
+
(x) => x.status === BlockletStatus.deleted && !blocklet.children.some((y) => y.meta.did === x.meta.did)
|
|
2553
|
+
);
|
|
2554
|
+
dynamicChildren.push(...deletes);
|
|
2555
|
+
|
|
2556
|
+
await states.blockletExtras.setSettings(did, { children: dynamicChildren });
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2499
2559
|
/**
|
|
2500
2560
|
* for download: cwd, tarball, did
|
|
2501
2561
|
* for verify: verify, integrity
|
|
@@ -2619,7 +2679,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2619
2679
|
* @return {object} { isCancelled: Boolean }
|
|
2620
2680
|
*/
|
|
2621
2681
|
async _downloadBundle(meta, rootDid, url) {
|
|
2622
|
-
const { name, did, version, dist = {} } = meta;
|
|
2682
|
+
const { bundleName: name, bundleDid: did, version, dist = {} } = meta;
|
|
2623
2683
|
const { tarball, integrity } = dist;
|
|
2624
2684
|
|
|
2625
2685
|
const lockName = `download-${did}-${version}`;
|
package/lib/blocklet/registry.js
CHANGED
|
@@ -11,7 +11,7 @@ const request = require('../util/request');
|
|
|
11
11
|
|
|
12
12
|
const states = require('../states');
|
|
13
13
|
const isRequirementsSatisfied = require('../util/requirement');
|
|
14
|
-
const {
|
|
14
|
+
const { fixAndVerifyMetaFromStore } = require('../util/blocklet');
|
|
15
15
|
const { translate } = require('../locales');
|
|
16
16
|
const { validateRegistryURL, getRegistryMeta } = require('../util/registry');
|
|
17
17
|
|
|
@@ -68,7 +68,11 @@ class BlockletRegistry {
|
|
|
68
68
|
|
|
69
69
|
const { data } = await request.get(url);
|
|
70
70
|
try {
|
|
71
|
-
|
|
71
|
+
if (data.did !== did) {
|
|
72
|
+
throw new Error('Invalid blocklet meta: did does not match');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return fixAndVerifyMetaFromStore(data);
|
|
72
76
|
} catch (err) {
|
|
73
77
|
logger.error('failed to get blocklet meta', { did, data, error: err });
|
|
74
78
|
throw err;
|
package/lib/event.js
CHANGED
|
@@ -210,6 +210,11 @@ module.exports = ({
|
|
|
210
210
|
}
|
|
211
211
|
});
|
|
212
212
|
nodeState.on(EVENTS.NODE_UPGRADE_PROGRESS, (session) => onEvent(EVENTS.NODE_UPGRADE_PROGRESS, session));
|
|
213
|
+
nodeState.on(EVENTS.RELOAD_GATEWAY, (nodeInfo) => {
|
|
214
|
+
handleRouting(nodeInfo).catch((err) => {
|
|
215
|
+
logger.error('Handle routing failed on node.updated', { error: err });
|
|
216
|
+
});
|
|
217
|
+
});
|
|
213
218
|
|
|
214
219
|
domainStatus.on(EVENTS.DOMAIN_STATUS, (data) => {
|
|
215
220
|
if (data) {
|