@abtnode/core 1.6.16 → 1.6.20
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 +1 -1
- package/lib/blocklet/hooks.js +16 -63
- package/lib/blocklet/manager/disk.js +425 -151
- package/lib/blocklet/migration.js +16 -52
- package/lib/event.js +3 -2
- package/lib/index.js +2 -1
- package/lib/migrations/1.6.17-blocklet-children.js +48 -0
- package/lib/router/helper.js +11 -9
- package/lib/router/manager.js +45 -41
- package/lib/states/blocklet-extras.js +39 -3
- package/lib/states/blocklet.js +84 -12
- package/lib/states/node.js +17 -2
- package/lib/util/blocklet.js +284 -68
- package/lib/util/get-domain-for-blocklet.js +2 -2
- package/lib/util/upgrade.js +8 -4
- package/package.json +23 -23
|
@@ -1,67 +1,25 @@
|
|
|
1
1
|
/* eslint-disable no-await-in-loop */
|
|
2
|
-
const childProcess = require('child_process');
|
|
3
2
|
const fs = require('fs-extra');
|
|
4
3
|
const path = require('path');
|
|
5
4
|
const semver = require('semver');
|
|
5
|
+
const runScript = require('@abtnode/util/lib/run-script');
|
|
6
6
|
|
|
7
7
|
const { getMigrationScripts: getScripts } = require('../migrations');
|
|
8
8
|
const { getSafeEnv } = require('../util');
|
|
9
9
|
const { name } = require('../../package.json');
|
|
10
10
|
const logger = require('@abtnode/logger')(`${name}:blocklet:migration`); // eslint-disable-line
|
|
11
11
|
|
|
12
|
-
const _runScript = ({ appDir, env, migrationScript, progress = false }) => {
|
|
13
|
-
const safeEnv = getSafeEnv(env);
|
|
14
|
-
|
|
15
|
-
const child = childProcess.exec(`node ${migrationScript}`, {
|
|
16
|
-
cwd: appDir,
|
|
17
|
-
env: safeEnv,
|
|
18
|
-
stdio: 'inherit',
|
|
19
|
-
});
|
|
20
|
-
let hasUnhandledRejection = false;
|
|
21
|
-
|
|
22
|
-
if (progress) {
|
|
23
|
-
child.stdout.pipe(process.stdout);
|
|
24
|
-
child.stderr.pipe(process.stderr);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return new Promise((resolve, reject) => {
|
|
28
|
-
const errorMessages = [];
|
|
29
|
-
|
|
30
|
-
child.stderr.on('data', (err) => {
|
|
31
|
-
// Check if has unhandledRejection in childProcess
|
|
32
|
-
// https://stackoverflow.com/questions/32784649/gracefully-handle-errors-in-child-processes-in-nodejs
|
|
33
|
-
if (err.includes('UnhandledPromiseRejectionWarning')) {
|
|
34
|
-
hasUnhandledRejection = true;
|
|
35
|
-
}
|
|
36
|
-
errorMessages.push(err);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
child.on('exit', (code) => {
|
|
40
|
-
if (errorMessages.length > 0) {
|
|
41
|
-
if (code !== 0 || hasUnhandledRejection) {
|
|
42
|
-
return reject(new Error(errorMessages.join('\r\n')));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (!progress) {
|
|
46
|
-
errorMessages.forEach((message) => process.stderr.write(message));
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return resolve();
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
};
|
|
54
|
-
|
|
55
12
|
async function runScripts({
|
|
13
|
+
blocklet,
|
|
14
|
+
appDir,
|
|
15
|
+
env,
|
|
16
|
+
oldVersion,
|
|
56
17
|
dbDir,
|
|
57
18
|
backupDir,
|
|
58
19
|
scriptsDir,
|
|
59
20
|
printInfo,
|
|
60
21
|
printSuccess,
|
|
61
22
|
printError,
|
|
62
|
-
appDir,
|
|
63
|
-
env,
|
|
64
|
-
oldVersion,
|
|
65
23
|
}) {
|
|
66
24
|
let scripts = [];
|
|
67
25
|
try {
|
|
@@ -90,7 +48,11 @@ async function runScripts({
|
|
|
90
48
|
const { script: scriptPath } = pendingScripts[i];
|
|
91
49
|
try {
|
|
92
50
|
printInfo(`Migration script started: ${scriptPath}`);
|
|
93
|
-
await
|
|
51
|
+
await runScript(`node ${path.join(scriptsDir, scriptPath)}`, [blocklet.env.appId, 'migration'].join(':'), {
|
|
52
|
+
cwd: appDir,
|
|
53
|
+
env: getSafeEnv(env),
|
|
54
|
+
silent: false,
|
|
55
|
+
});
|
|
94
56
|
printInfo(`Migration script executed: ${scriptPath}`);
|
|
95
57
|
} catch (migrationErr) {
|
|
96
58
|
printError(`Failed to execute migration script: ${scriptPath}, error: ${migrationErr.message}`);
|
|
@@ -123,6 +85,7 @@ async function doRestore({ dbDir, backupDir, printInfo, printSuccess }) {
|
|
|
123
85
|
}
|
|
124
86
|
|
|
125
87
|
module.exports = async ({
|
|
88
|
+
blocklet,
|
|
126
89
|
appDir,
|
|
127
90
|
env,
|
|
128
91
|
oldVersion,
|
|
@@ -142,15 +105,16 @@ module.exports = async ({
|
|
|
142
105
|
fs.ensureDirSync(backupDir);
|
|
143
106
|
|
|
144
107
|
await runScripts({
|
|
108
|
+
blocklet,
|
|
109
|
+
appDir,
|
|
110
|
+
env,
|
|
111
|
+
oldVersion,
|
|
112
|
+
newVersion,
|
|
145
113
|
dbDir,
|
|
146
114
|
backupDir,
|
|
147
115
|
scriptsDir,
|
|
148
116
|
printError,
|
|
149
117
|
printInfo,
|
|
150
118
|
printSuccess,
|
|
151
|
-
appDir,
|
|
152
|
-
env,
|
|
153
|
-
oldVersion,
|
|
154
|
-
newVersion,
|
|
155
119
|
});
|
|
156
120
|
};
|
package/lib/event.js
CHANGED
|
@@ -132,7 +132,7 @@ module.exports = ({
|
|
|
132
132
|
onEvent(name, blocklet);
|
|
133
133
|
};
|
|
134
134
|
|
|
135
|
-
const
|
|
135
|
+
const handleServerEvent = (eventName) => {
|
|
136
136
|
const [, status] = eventName.split('.');
|
|
137
137
|
onEvent(eventName, {
|
|
138
138
|
title: `Blocklet Server ${status}`,
|
|
@@ -209,7 +209,8 @@ module.exports = ({
|
|
|
209
209
|
|
|
210
210
|
events.handleBlockletAdd = handleBlockletAdd;
|
|
211
211
|
events.handleBlockletRemove = handleBlockletRemove;
|
|
212
|
-
events.
|
|
212
|
+
events.handleServerEvent = handleServerEvent;
|
|
213
|
+
events.onEvent = onEvent;
|
|
213
214
|
|
|
214
215
|
return events;
|
|
215
216
|
};
|
package/lib/index.js
CHANGED
|
@@ -197,16 +197,17 @@ function ABTNode(options) {
|
|
|
197
197
|
// Blocklet manager
|
|
198
198
|
installBlocklet: blockletManager.install.bind(blockletManager),
|
|
199
199
|
installBlockletFromVc: blockletManager.installBlockletFromVc.bind(blockletManager),
|
|
200
|
+
installComponent: blockletManager.installComponent.bind(blockletManager),
|
|
200
201
|
startBlocklet: blockletManager.start.bind(blockletManager),
|
|
201
202
|
stopBlocklet: blockletManager.stop.bind(blockletManager),
|
|
202
203
|
reloadBlocklet: blockletManager.reload.bind(blockletManager),
|
|
203
204
|
restartBlocklet: blockletManager.restart.bind(blockletManager),
|
|
204
205
|
deleteBlocklet: blockletManager.delete.bind(blockletManager),
|
|
206
|
+
deleteComponent: blockletManager.deleteComponent.bind(blockletManager),
|
|
205
207
|
cancelDownloadBlocklet: blockletManager.cancelDownload.bind(blockletManager),
|
|
206
208
|
upgradeBlocklet: blockletManager.upgrade.bind(blockletManager),
|
|
207
209
|
configBlocklet: blockletManager.config.bind(blockletManager),
|
|
208
210
|
devBlocklet: blockletManager.dev.bind(blockletManager),
|
|
209
|
-
getBlockletStatus: blockletManager.getStatus.bind(blockletManager),
|
|
210
211
|
checkChildBlockletsForUpdates: blockletManager.checkChildrenForUpdates.bind(blockletManager),
|
|
211
212
|
updateChildBlocklets: blockletManager.updateChildren.bind(blockletManager),
|
|
212
213
|
getLatestBlockletVersion: blockletManager.getLatestBlockletVersion.bind(blockletManager),
|
|
@@ -0,0 +1,48 @@
|
|
|
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 to 1.6.17...');
|
|
7
|
+
const blockletState = states.blocklet;
|
|
8
|
+
|
|
9
|
+
const blocklets = await blockletState.getBlocklets();
|
|
10
|
+
for (const blocklet of blocklets) {
|
|
11
|
+
if (!blocklet) {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (!blocklet.children || !blocklet.children.length) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const meta = blocklet.meta || {};
|
|
20
|
+
const { did } = meta;
|
|
21
|
+
if (!did) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const children = (blocklet.children || []).map((child) => {
|
|
26
|
+
if (child.mountPoint) {
|
|
27
|
+
return child;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const config = (meta.children || []).find((x) => x.name === child.meta.name);
|
|
31
|
+
|
|
32
|
+
if (
|
|
33
|
+
config &&
|
|
34
|
+
config.mountPoints &&
|
|
35
|
+
config.mountPoints[0] &&
|
|
36
|
+
config.mountPoints[0].root &&
|
|
37
|
+
config.mountPoints[0].root.prefix
|
|
38
|
+
) {
|
|
39
|
+
child.mountPoint = config.mountPoints[0].root.prefix;
|
|
40
|
+
}
|
|
41
|
+
printInfo(`Set mountPoint: ${child.mountPoint} to child ${child.meta.name} in ${blocklet.meta.name}`);
|
|
42
|
+
|
|
43
|
+
return child;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
await blockletState.update(blocklet._id, { $set: { children } });
|
|
47
|
+
}
|
|
48
|
+
};
|
package/lib/router/helper.js
CHANGED
|
@@ -317,7 +317,7 @@ const ensureWellknownRule = async (sites) => {
|
|
|
317
317
|
rules.forEach((rule) => {
|
|
318
318
|
if (
|
|
319
319
|
rule.to.type !== ROUTING_RULE_TYPES.BLOCKLET || // is not blocklet
|
|
320
|
-
rule.to.did !== rule.to.realDid // is a component endpoint
|
|
320
|
+
(rule.to.did !== rule.to.realDid && rule.from.pathPrefix !== '/') // is a component endpoint in sub path
|
|
321
321
|
) {
|
|
322
322
|
return;
|
|
323
323
|
}
|
|
@@ -660,7 +660,9 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
660
660
|
|
|
661
661
|
const dashboardDomain = get(info, 'routing.dashboardDomain', '');
|
|
662
662
|
const didDomain = `${info.did.toLowerCase()}.${info.didDomain}`;
|
|
663
|
-
|
|
663
|
+
let dashboardAliasDomains = [dashboardDomain, didDomain];
|
|
664
|
+
|
|
665
|
+
dashboardAliasDomains = dashboardAliasDomains
|
|
664
666
|
.filter((item) => item && !isExistsInAlias(item))
|
|
665
667
|
.map((item) => ({ value: item, isProtected: true }));
|
|
666
668
|
|
|
@@ -746,18 +748,18 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
746
748
|
|
|
747
749
|
const existSite = await states.site.findOne({ domain: domainGroup });
|
|
748
750
|
if (!existSite) {
|
|
749
|
-
const
|
|
750
|
-
const appIdEnv = blocklet.environments.find((e) => e.key === 'BLOCKLET_APP_ID');
|
|
751
|
-
const domainAliases = [{ value: ipEchoDnsDomain, isProtected: true }];
|
|
751
|
+
const domainAliases = [];
|
|
752
752
|
|
|
753
753
|
const didDomain = getDidDomainForBlocklet({
|
|
754
|
-
|
|
754
|
+
name: blocklet.meta.name,
|
|
755
|
+
daemonDid: nodeInfo.did,
|
|
755
756
|
didDomain: nodeInfo.didDomain,
|
|
756
757
|
});
|
|
757
758
|
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
759
|
+
const ipEchoDnsDomain = getIpDnsDomainForBlocklet(blocklet, webInterface, nodeInfo.did);
|
|
760
|
+
|
|
761
|
+
// let didDomain in front of ipEchoDnsDomain
|
|
762
|
+
domainAliases.push({ value: didDomain, isProtected: true }, { value: ipEchoDnsDomain, isProtected: true });
|
|
761
763
|
|
|
762
764
|
await routerManager.addRoutingSite(
|
|
763
765
|
{
|
package/lib/router/manager.js
CHANGED
|
@@ -27,6 +27,7 @@ const {
|
|
|
27
27
|
BLOCKLET_BUNDLE_FOLDER,
|
|
28
28
|
BLOCKLET_DYNAMIC_PATH_PREFIX,
|
|
29
29
|
BLOCKLET_INTERFACE_TYPE_WEB,
|
|
30
|
+
BlockletGroup,
|
|
30
31
|
} = require('@blocklet/meta/lib/constants');
|
|
31
32
|
|
|
32
33
|
const {
|
|
@@ -37,6 +38,7 @@ const {
|
|
|
37
38
|
validateUpdateSite,
|
|
38
39
|
} = require('../validators/router');
|
|
39
40
|
const { getProviderFromNodeInfo, findInterfaceByName, isCLI, findInterfacePortByName } = require('../util');
|
|
41
|
+
const { findWebInterface } = require('../util/blocklet');
|
|
40
42
|
const { attachInterfaceUrls, ensureLatestInfo } = require('./helper');
|
|
41
43
|
const Router = require('./index');
|
|
42
44
|
const states = require('../states');
|
|
@@ -219,10 +221,10 @@ class RouterManager extends EventEmitter {
|
|
|
219
221
|
}
|
|
220
222
|
}
|
|
221
223
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
);
|
|
224
|
+
// let custom domain in front of protected domain
|
|
225
|
+
const domainAliases = [{ value: domainAlias, isProtected: false }, ...dbSite.domainAliases];
|
|
226
|
+
|
|
227
|
+
const updateResult = await states.site.update({ _id: id }, { $set: { domainAliases } });
|
|
226
228
|
logger.debug('add domain alias update result', { id, updateResult, domainAlias });
|
|
227
229
|
|
|
228
230
|
const newSite = await states.site.findOne({ _id: id });
|
|
@@ -679,49 +681,51 @@ class RouterManager extends EventEmitter {
|
|
|
679
681
|
|
|
680
682
|
// get child rules
|
|
681
683
|
const blocklet = await states.blocklet.getBlocklet(rule.to.did);
|
|
682
|
-
for (const
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
continue;
|
|
690
|
-
}
|
|
684
|
+
for (const child of blocklet.children || []) {
|
|
685
|
+
const { mountPoint } = child;
|
|
686
|
+
if (!mountPoint) {
|
|
687
|
+
logger.error(`mountPoint of child ${child.meta.name} does not exist`);
|
|
688
|
+
// eslint-disable-next-line no-continue
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
691
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
692
|
+
const childWebInterface = findWebInterface(child);
|
|
693
|
+
if (!childWebInterface) {
|
|
694
|
+
logger.error(`web interface of child ${child.meta.name} does not exist`);
|
|
695
|
+
// eslint-disable-next-line no-continue
|
|
696
|
+
continue;
|
|
697
|
+
}
|
|
698
698
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
from: {
|
|
704
|
-
pathPrefix: normalizePathPrefix(pathPrefix),
|
|
705
|
-
groupPathPrefix: rule.from.pathPrefix,
|
|
706
|
-
},
|
|
707
|
-
to: {
|
|
708
|
-
type: ROUTING_RULE_TYPES.BLOCKLET,
|
|
709
|
-
port: findInterfacePortByName(child, mountPoint.child.interfaceName),
|
|
710
|
-
did: rule.to.did, // root blocklet did
|
|
711
|
-
interfaceName: rule.to.interfaceName, // root blocklet interface
|
|
712
|
-
realDid: child.meta.did, // child blocklet did
|
|
713
|
-
realInterfaceName: mountPoint.child.interfaceName,
|
|
714
|
-
},
|
|
715
|
-
isProtected: isRootPath ? rule.isProtected : true,
|
|
716
|
-
};
|
|
717
|
-
|
|
718
|
-
rules.push(childRule);
|
|
719
|
-
}
|
|
699
|
+
const pathPrefix = path.join(rule.from.pathPrefix, mountPoint);
|
|
700
|
+
const isRootPath = pathPrefix === rule.from.pathPrefix;
|
|
701
|
+
if (isRootPath) {
|
|
702
|
+
occupied = true;
|
|
720
703
|
}
|
|
704
|
+
|
|
705
|
+
// if is root path, child rule become root rule
|
|
706
|
+
const childRule = {
|
|
707
|
+
id: isRootPath ? rule.id : uuid.v4(),
|
|
708
|
+
groupId: rule.id,
|
|
709
|
+
from: {
|
|
710
|
+
pathPrefix: normalizePathPrefix(pathPrefix),
|
|
711
|
+
groupPathPrefix: rule.from.pathPrefix,
|
|
712
|
+
},
|
|
713
|
+
to: {
|
|
714
|
+
type: ROUTING_RULE_TYPES.BLOCKLET,
|
|
715
|
+
port: findInterfacePortByName(child, childWebInterface.name),
|
|
716
|
+
did: rule.to.did, // root blocklet did
|
|
717
|
+
interfaceName: rule.to.interfaceName, // root blocklet interface
|
|
718
|
+
realDid: child.meta.did, // child blocklet did
|
|
719
|
+
realInterfaceName: childWebInterface.name,
|
|
720
|
+
},
|
|
721
|
+
isProtected: isRootPath ? rule.isProtected : true,
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
rules.push(childRule);
|
|
721
725
|
}
|
|
722
726
|
|
|
723
727
|
// get root rule
|
|
724
|
-
if (!occupied) {
|
|
728
|
+
if (!occupied && blocklet.meta.group !== BlockletGroup.gateway) {
|
|
725
729
|
rules.push(rule);
|
|
726
730
|
}
|
|
727
731
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
/* eslint-disable consistent-return */
|
|
4
4
|
const logger = require('@abtnode/logger')('state-blocklet-extras');
|
|
5
5
|
const camelCase = require('lodash/camelCase');
|
|
6
|
+
const get = require('lodash/get');
|
|
6
7
|
|
|
7
8
|
const BaseState = require('./base');
|
|
8
9
|
|
|
@@ -36,16 +37,28 @@ class BlockletExtrasState extends BaseState {
|
|
|
36
37
|
},
|
|
37
38
|
},
|
|
38
39
|
];
|
|
40
|
+
|
|
41
|
+
this.childExtras = this.extras.filter((x) => ['configs'].includes(x.name));
|
|
42
|
+
|
|
39
43
|
this.generateExtraFns();
|
|
40
44
|
}
|
|
41
45
|
|
|
46
|
+
delete(did) {
|
|
47
|
+
return this.remove({ did });
|
|
48
|
+
}
|
|
49
|
+
|
|
42
50
|
generateExtraFns() {
|
|
43
|
-
const methods = ['get', 'set', 'del'];
|
|
51
|
+
const methods = ['get', 'set', 'del', 'list'];
|
|
44
52
|
methods.forEach((method) => {
|
|
45
53
|
this.extras.forEach((extra) => {
|
|
46
54
|
const fn = camelCase(`${method} ${extra.name}`); // getConfigs, getRules
|
|
47
55
|
this[fn] = this.generateExtraFn(method, extra);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
48
58
|
|
|
59
|
+
const childMethods = ['get', 'set', 'del'];
|
|
60
|
+
childMethods.forEach((method) => {
|
|
61
|
+
this.childExtras.forEach((extra) => {
|
|
49
62
|
const childFn = camelCase(`${method} child ${extra.name}`); // getChildConfigs, getChildRules
|
|
50
63
|
this[childFn] = this.generateExtraChildFn(method, extra);
|
|
51
64
|
});
|
|
@@ -66,14 +79,22 @@ class BlockletExtrasState extends BaseState {
|
|
|
66
79
|
if (method === 'del') {
|
|
67
80
|
return this.generateDelFn(extra);
|
|
68
81
|
}
|
|
82
|
+
|
|
83
|
+
if (method === 'list') {
|
|
84
|
+
return this.generateListFn(extra);
|
|
85
|
+
}
|
|
69
86
|
}
|
|
70
87
|
|
|
71
88
|
generateGetFn(extra) {
|
|
72
|
-
return async (did) => {
|
|
89
|
+
return async (did, path, defaultValue) => {
|
|
73
90
|
const { dek } = this.options;
|
|
74
91
|
const { name, afterGet = noop('data') } = extra;
|
|
75
92
|
const item = await this.asyncDB.findOne({ did });
|
|
76
|
-
|
|
93
|
+
const data = afterGet({ data: item ? item[name] : item, did, dek });
|
|
94
|
+
if (!path) {
|
|
95
|
+
return data;
|
|
96
|
+
}
|
|
97
|
+
return get(data, path, defaultValue);
|
|
77
98
|
};
|
|
78
99
|
}
|
|
79
100
|
|
|
@@ -118,6 +139,21 @@ class BlockletExtrasState extends BaseState {
|
|
|
118
139
|
};
|
|
119
140
|
}
|
|
120
141
|
|
|
142
|
+
generateListFn(extra) {
|
|
143
|
+
return async () => {
|
|
144
|
+
const { dek } = this.options;
|
|
145
|
+
const { name, afterGet = noop('data') } = extra;
|
|
146
|
+
const docs = await this.asyncDB.find({});
|
|
147
|
+
const list = docs
|
|
148
|
+
.filter((x) => x[name])
|
|
149
|
+
.map((x) => ({
|
|
150
|
+
did: x.did,
|
|
151
|
+
[name]: afterGet({ data: x[name], did: x.did, dek }),
|
|
152
|
+
}));
|
|
153
|
+
return list;
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
121
157
|
// generate extra child functions
|
|
122
158
|
|
|
123
159
|
generateExtraChildFn(method, extra) {
|
package/lib/states/blocklet.js
CHANGED
|
@@ -20,7 +20,7 @@ const {
|
|
|
20
20
|
const logger = require('@abtnode/logger')('state-blocklet');
|
|
21
21
|
|
|
22
22
|
const BaseState = require('./base');
|
|
23
|
-
const { forEachBlocklet } = require('../util/blocklet');
|
|
23
|
+
const { forEachBlocklet, checkDuplicateComponents } = require('../util/blocklet');
|
|
24
24
|
const { validateBlockletMeta } = require('../util');
|
|
25
25
|
|
|
26
26
|
const lock = new Lock('blocklet-port-assign-lock');
|
|
@@ -80,7 +80,11 @@ class BlockletState extends BaseState {
|
|
|
80
80
|
|
|
81
81
|
getBlocklet(did) {
|
|
82
82
|
return new Promise((resolve, reject) => {
|
|
83
|
-
|
|
83
|
+
if (!did) {
|
|
84
|
+
resolve(null);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this.db.findOne({ $or: [{ 'meta.did': did }, { appDid: did }] }, (err, doc) => {
|
|
84
88
|
if (err) {
|
|
85
89
|
return reject(err);
|
|
86
90
|
}
|
|
@@ -131,9 +135,9 @@ class BlockletState extends BaseState {
|
|
|
131
135
|
meta,
|
|
132
136
|
source = BlockletSource.registry,
|
|
133
137
|
status = BlockletStatus.added,
|
|
134
|
-
deployedFrom,
|
|
138
|
+
deployedFrom = '',
|
|
135
139
|
mode = BLOCKLET_MODES.PRODUCTION,
|
|
136
|
-
|
|
140
|
+
children: rawChildren = [],
|
|
137
141
|
} = {}) {
|
|
138
142
|
return this.getBlocklet(did).then(
|
|
139
143
|
(doc) =>
|
|
@@ -153,13 +157,14 @@ class BlockletState extends BaseState {
|
|
|
153
157
|
|
|
154
158
|
const ports = await this.getBlockletPorts({ interfaces: sanitized.interfaces || [] });
|
|
155
159
|
|
|
156
|
-
const children = await this.fillChildrenPorts(
|
|
160
|
+
const children = await this.fillChildrenPorts(rawChildren, {
|
|
157
161
|
defaultPort: getMaxPort(ports),
|
|
158
162
|
});
|
|
159
163
|
|
|
160
164
|
// add to db
|
|
161
165
|
this.db.insert(
|
|
162
166
|
{
|
|
167
|
+
appDid: null, // will updated later when updating blocklet environments
|
|
163
168
|
mode,
|
|
164
169
|
meta: omit(sanitized, ['htmlAst']),
|
|
165
170
|
status,
|
|
@@ -207,7 +212,7 @@ class BlockletState extends BaseState {
|
|
|
207
212
|
);
|
|
208
213
|
}
|
|
209
214
|
|
|
210
|
-
upgradeBlocklet({ meta, source, deployedFrom, children } = {}) {
|
|
215
|
+
upgradeBlocklet({ meta, source, deployedFrom = '', children } = {}) {
|
|
211
216
|
return this.getBlocklet(meta.did).then(
|
|
212
217
|
(doc) =>
|
|
213
218
|
// eslint-disable-next-line no-async-promise-executor
|
|
@@ -391,13 +396,20 @@ class BlockletState extends BaseState {
|
|
|
391
396
|
return result;
|
|
392
397
|
}
|
|
393
398
|
|
|
394
|
-
|
|
399
|
+
/**
|
|
400
|
+
* @param {String} did blocklet did
|
|
401
|
+
* @param {BlockletStatus} status blocklet status
|
|
402
|
+
*
|
|
403
|
+
* children status only different with parent before blocklet installation
|
|
404
|
+
* @param {Array<{did}>} children
|
|
405
|
+
*/
|
|
406
|
+
async setBlockletStatus(did, status, { children } = {}) {
|
|
395
407
|
if (typeof status === 'undefined') {
|
|
396
408
|
throw new Error('Unsupported blocklet status');
|
|
397
409
|
}
|
|
398
410
|
|
|
399
411
|
const doc = await this.getBlocklet(did);
|
|
400
|
-
if (doc.status === status) {
|
|
412
|
+
if (doc.status === status && !children) {
|
|
401
413
|
return formatBlocklet(doc, 'onRead', this.options.dek);
|
|
402
414
|
}
|
|
403
415
|
|
|
@@ -412,14 +424,32 @@ class BlockletState extends BaseState {
|
|
|
412
424
|
updates.stoppedAt = new Date();
|
|
413
425
|
}
|
|
414
426
|
|
|
427
|
+
// update children status
|
|
428
|
+
updates.children = doc.children.map((child) => {
|
|
429
|
+
if (children === 'all') {
|
|
430
|
+
child.status = status;
|
|
431
|
+
return child;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (!children) {
|
|
435
|
+
if (![BlockletStatus.waiting, BlockletStatus.upgrading, BlockletStatus.installing].includes(status)) {
|
|
436
|
+
child.status = status;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
return child;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
const inputChild = children.find((x) => x.did === child.meta.did);
|
|
443
|
+
if (inputChild) {
|
|
444
|
+
child.status = status;
|
|
445
|
+
}
|
|
446
|
+
return child;
|
|
447
|
+
});
|
|
448
|
+
|
|
415
449
|
await this.update(doc._id, { $set: updates });
|
|
416
450
|
return formatBlocklet({ ...doc, ...updates }, 'onRead', this.options.dek);
|
|
417
451
|
}
|
|
418
452
|
|
|
419
|
-
getChildrenFromMetas(childrenMeta) {
|
|
420
|
-
return childrenMeta.map((x) => ({ meta: x }));
|
|
421
|
-
}
|
|
422
|
-
|
|
423
453
|
async fillChildrenPorts(children, { defaultPort = 0, oldChildren } = {}) {
|
|
424
454
|
let _maxPort = defaultPort;
|
|
425
455
|
for (const child of children || []) {
|
|
@@ -467,6 +497,48 @@ class BlockletState extends BaseState {
|
|
|
467
497
|
|
|
468
498
|
return children;
|
|
469
499
|
}
|
|
500
|
+
|
|
501
|
+
async addChildren(did, children) {
|
|
502
|
+
const parent = await this.getBlocklet(did);
|
|
503
|
+
if (!parent) {
|
|
504
|
+
throw new Error('Blocklet does not exist');
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const oldChildren = parent.children || [];
|
|
508
|
+
|
|
509
|
+
const newChildren = [...oldChildren];
|
|
510
|
+
for (const child of children) {
|
|
511
|
+
const { meta, mountPoint, sourceUrl = '', source = '', deployedFrom = '' } = child;
|
|
512
|
+
|
|
513
|
+
if (!mountPoint) {
|
|
514
|
+
throw new Error(`mountPoint is required when adding component ${meta.title || meta.name}`);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
if (meta.did === parent.meta.did) {
|
|
518
|
+
throw new Error('Cannot add self as a component');
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
checkDuplicateComponents([child], newChildren);
|
|
522
|
+
|
|
523
|
+
newChildren.push({
|
|
524
|
+
mountPoint,
|
|
525
|
+
meta,
|
|
526
|
+
sourceUrl,
|
|
527
|
+
source,
|
|
528
|
+
deployedFrom,
|
|
529
|
+
dynamic: true,
|
|
530
|
+
status: BlockletStatus.added,
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// use upgradeBlocklet to assign ports to children and write new data to db
|
|
535
|
+
return this.upgradeBlocklet({
|
|
536
|
+
meta: parent.meta,
|
|
537
|
+
source: parent.source,
|
|
538
|
+
deployedFrom: parent.deployedFrom,
|
|
539
|
+
children: newChildren,
|
|
540
|
+
});
|
|
541
|
+
}
|
|
470
542
|
}
|
|
471
543
|
|
|
472
544
|
BlockletState.BlockletStatus = BlockletStatus;
|
package/lib/states/node.js
CHANGED
|
@@ -49,7 +49,10 @@ class NodeState extends BaseState {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
isInitialized(doc) {
|
|
52
|
-
|
|
52
|
+
const isOwnerConnected = !!doc.nodeOwner;
|
|
53
|
+
const isControlledBy3rdParty =
|
|
54
|
+
!doc.enablePassportIssuance && Array.isArray(doc.trustedPassports) && doc.trustedPassports.length > 0;
|
|
55
|
+
return isOwnerConnected || isControlledBy3rdParty;
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
/**
|
|
@@ -92,13 +95,15 @@ class NodeState extends BaseState {
|
|
|
92
95
|
launcherInfo,
|
|
93
96
|
didRegistry,
|
|
94
97
|
didDomain,
|
|
98
|
+
enablePassportIssuance = true,
|
|
99
|
+
trustedPassports = [],
|
|
95
100
|
} = this.options;
|
|
96
101
|
|
|
97
102
|
if (nodeOwner && !validateOwner(nodeOwner)) {
|
|
98
103
|
return reject(new Error('Node owner is invalid'));
|
|
99
104
|
}
|
|
100
105
|
|
|
101
|
-
const initialized = this.isInitialized({ nodeOwner });
|
|
106
|
+
const initialized = this.isInitialized({ nodeOwner, enablePassportIssuance, trustedPassports });
|
|
102
107
|
|
|
103
108
|
return getDefaultConfigs()
|
|
104
109
|
.then((defaultConfigs) =>
|
|
@@ -126,6 +131,9 @@ class NodeState extends BaseState {
|
|
|
126
131
|
launcherInfo: launcherInfo || undefined,
|
|
127
132
|
didRegistry,
|
|
128
133
|
didDomain,
|
|
134
|
+
enablePassportIssuance,
|
|
135
|
+
trustedPassports,
|
|
136
|
+
customBlockletNumber: 0,
|
|
129
137
|
},
|
|
130
138
|
async (e, data) => {
|
|
131
139
|
if (e) {
|
|
@@ -262,6 +270,13 @@ class NodeState extends BaseState {
|
|
|
262
270
|
getBlockletRegistry() {
|
|
263
271
|
return this.read().then((info) => info.blockletRegistryList.find((item) => item.selected).url);
|
|
264
272
|
}
|
|
273
|
+
|
|
274
|
+
async increaseCustomBlockletNumber() {
|
|
275
|
+
const { _id, customBlockletNumber = 0 } = await this.read();
|
|
276
|
+
const num = customBlockletNumber + 1;
|
|
277
|
+
await this.update(_id, { $set: { customBlockletNumber: num } });
|
|
278
|
+
return num;
|
|
279
|
+
}
|
|
265
280
|
}
|
|
266
281
|
|
|
267
282
|
module.exports = NodeState;
|