@abtnode/core 1.7.18 → 1.7.21
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 +20 -0
- package/lib/api/team.js +40 -5
- package/lib/blocklet/extras.js +1 -5
- package/lib/blocklet/hooks.js +9 -9
- package/lib/blocklet/manager/disk.js +284 -215
- package/lib/blocklet/migration.js +1 -1
- package/lib/index.js +5 -2
- package/lib/migrations/1.7.20-blocklet-component.js +41 -0
- package/lib/router/helper.js +1 -1
- package/lib/router/index.js +1 -1
- package/lib/router/manager.js +24 -21
- package/lib/states/audit-log.js +26 -4
- package/lib/states/blocklet-extras.js +66 -159
- package/lib/states/blocklet.js +65 -62
- package/lib/states/node.js +23 -13
- package/lib/util/blocklet.js +160 -127
- package/lib/util/index.js +29 -0
- package/lib/validators/router.js +1 -2
- package/package.json +23 -22
|
@@ -53,7 +53,7 @@ async function runScripts({
|
|
|
53
53
|
const { script: scriptPath } = pendingScripts[i];
|
|
54
54
|
try {
|
|
55
55
|
printInfo(`Migration script started: ${scriptPath}`);
|
|
56
|
-
await runScript(`node ${path.join(scriptsDir, scriptPath)}`, [blocklet.env.
|
|
56
|
+
await runScript(`node ${path.join(scriptsDir, scriptPath)}`, [blocklet.env.processId, 'migration'].join(':'), {
|
|
57
57
|
cwd: appDir,
|
|
58
58
|
env: getSafeEnv(env),
|
|
59
59
|
silent: false,
|
package/lib/index.js
CHANGED
|
@@ -247,9 +247,10 @@ function ABTNode(options) {
|
|
|
247
247
|
addBlockletStore: nodeAPI.addRegistry.bind(nodeAPI),
|
|
248
248
|
deleteBlockletStore: nodeAPI.deleteRegistry.bind(nodeAPI),
|
|
249
249
|
selectBlockletStore: nodeAPI.selectRegistry.bind(nodeAPI),
|
|
250
|
+
getDelegationState: nodeAPI.getDelegationState.bind(nodeAPI),
|
|
250
251
|
cleanupDirtyUpgradeState: states.node.cleanupDirtyUpgradeState.bind(states.node),
|
|
251
|
-
addNodeOwner: states.node.addNodeOwner.bind(states.node),
|
|
252
252
|
updateNodeOwner: states.node.updateNodeOwner.bind(states.node),
|
|
253
|
+
updateNftHolder: states.node.updateNftHolder.bind(states.node),
|
|
253
254
|
updateNodeRouting,
|
|
254
255
|
isInitialized,
|
|
255
256
|
resetNode: (params, context) =>
|
|
@@ -261,7 +262,9 @@ function ABTNode(options) {
|
|
|
261
262
|
// Team && Access control
|
|
262
263
|
|
|
263
264
|
// Invitation
|
|
264
|
-
|
|
265
|
+
createMemberInvitation: teamAPI.createMemberInvitation.bind(teamAPI),
|
|
266
|
+
createTransferInvitation: teamAPI.createTransferInvitation.bind(teamAPI),
|
|
267
|
+
getInvitation: teamAPI.getInvitation.bind(teamAPI),
|
|
265
268
|
getInvitations: teamAPI.getInvitations.bind(teamAPI),
|
|
266
269
|
processInvitation: teamAPI.processInvitation.bind(teamAPI),
|
|
267
270
|
deleteInvitation: teamAPI.deleteInvitation.bind(teamAPI),
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/* eslint-disable no-await-in-loop */
|
|
2
|
+
/* eslint-disable no-continue */
|
|
3
|
+
|
|
4
|
+
module.exports = async ({ states, printInfo }) => {
|
|
5
|
+
printInfo('Try to delete realDid, realInterface and add componentId in db...');
|
|
6
|
+
|
|
7
|
+
const sites = await states.site.find({});
|
|
8
|
+
|
|
9
|
+
for (const site of sites) {
|
|
10
|
+
let changed = false;
|
|
11
|
+
for (const rule of site.rules || []) {
|
|
12
|
+
if (!rule.to) {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (rule.to.type !== 'blocklet') {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (rule.to.componentId) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!rule.to.realDid || rule.to.did === rule.to.realDid) {
|
|
25
|
+
rule.to.componentId = rule.to.did;
|
|
26
|
+
} else {
|
|
27
|
+
rule.to.componentId = `${rule.to.did}/${rule.to.realDid}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
delete rule.to.realDid;
|
|
31
|
+
delete rule.to.realInterfaceName;
|
|
32
|
+
|
|
33
|
+
changed = true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (changed) {
|
|
37
|
+
await states.site.update({ _id: site._id }, site);
|
|
38
|
+
printInfo(`site ${site.domain} has been updated`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
package/lib/router/helper.js
CHANGED
|
@@ -334,7 +334,7 @@ const ensureWellknownRule = async (sites) => {
|
|
|
334
334
|
.sort((a, b) => (a.from.pathPrefix.length > b.from.pathPrefix.length ? 1 : -1));
|
|
335
335
|
if (blockletRules.length) {
|
|
336
336
|
// get pathPrefix for blocklet-service
|
|
337
|
-
const rootBlockletRule = blockletRules.find((x) => x.to.did === x.to.
|
|
337
|
+
const rootBlockletRule = blockletRules.find((x) => x.to.did === x.to.componentId);
|
|
338
338
|
const pathPrefix = joinUrl(rootBlockletRule?.from?.pathPrefix || '/', WELLKNOWN_SERVICE_PATH_PREFIX);
|
|
339
339
|
|
|
340
340
|
// requests for /.well-known/service will stay in blocklet-service and never proxy back to blocklet
|
package/lib/router/index.js
CHANGED
package/lib/router/manager.js
CHANGED
|
@@ -29,6 +29,7 @@ const {
|
|
|
29
29
|
BLOCKLET_INTERFACE_TYPE_WEB,
|
|
30
30
|
BlockletGroup,
|
|
31
31
|
} = require('@blocklet/meta/lib/constants');
|
|
32
|
+
const { forEachChildSync } = require('@blocklet/meta/lib/util');
|
|
32
33
|
|
|
33
34
|
const {
|
|
34
35
|
validateAddSite,
|
|
@@ -112,7 +113,7 @@ class RouterManager extends EventEmitter {
|
|
|
112
113
|
for (const rule of newSite.rules) {
|
|
113
114
|
this.fixRootBlockletRule(rule);
|
|
114
115
|
checkPathPrefixInBlackList(rule.from.pathPrefix, dynamicPathBlackList);
|
|
115
|
-
rules.push(...(await this.
|
|
116
|
+
rules.push(...(await this.getRulesForMutation(rule)));
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
119
|
newSite.rules = rules;
|
|
@@ -281,7 +282,7 @@ class RouterManager extends EventEmitter {
|
|
|
281
282
|
await this.validateRouterConfig('addRoutingRule', { id, rule });
|
|
282
283
|
|
|
283
284
|
// add child blocklet rules
|
|
284
|
-
for (const x of await this.
|
|
285
|
+
for (const x of await this.getRulesForMutation(rule)) {
|
|
285
286
|
await states.site.addRuleToSite(id, x);
|
|
286
287
|
}
|
|
287
288
|
|
|
@@ -323,7 +324,7 @@ class RouterManager extends EventEmitter {
|
|
|
323
324
|
// update rules
|
|
324
325
|
const newRules = [
|
|
325
326
|
...dbSite.rules.filter((x) => (x.groupId && x.groupId !== rule.id) || x.id !== rule.id), // 有些路由没有 rule.groupId
|
|
326
|
-
...(await this.
|
|
327
|
+
...(await this.getRulesForMutation(rule)),
|
|
327
328
|
];
|
|
328
329
|
|
|
329
330
|
const updateResult = await states.site.update({ _id: id }, { $set: { rules: newRules } });
|
|
@@ -604,8 +605,7 @@ class RouterManager extends EventEmitter {
|
|
|
604
605
|
rule.from.pathPrefix = normalizePathPrefix(rule.from.pathPrefix);
|
|
605
606
|
if (rule.to.type === ROUTING_RULE_TYPES.BLOCKLET) {
|
|
606
607
|
rule.from.groupPathPrefix = rule.from.pathPrefix;
|
|
607
|
-
rule.to.
|
|
608
|
-
rule.to.realInterfaceName = rule.to.interfaceName;
|
|
608
|
+
rule.to.componentId = rule.to.did;
|
|
609
609
|
}
|
|
610
610
|
if (rule.to.url) {
|
|
611
611
|
rule.to.url = normalizeRedirectUrl(rule.to.url);
|
|
@@ -616,7 +616,7 @@ class RouterManager extends EventEmitter {
|
|
|
616
616
|
* get all rules to be add or update to site from root rule
|
|
617
617
|
* @param {*} rule
|
|
618
618
|
*/
|
|
619
|
-
async
|
|
619
|
+
async getRulesForMutation(rule) {
|
|
620
620
|
if (rule.to.type !== ROUTING_RULE_TYPES.BLOCKLET) {
|
|
621
621
|
return [rule];
|
|
622
622
|
}
|
|
@@ -626,23 +626,27 @@ class RouterManager extends EventEmitter {
|
|
|
626
626
|
|
|
627
627
|
// get child rules
|
|
628
628
|
const blocklet = await states.blocklet.getBlocklet(rule.to.did);
|
|
629
|
-
|
|
630
|
-
|
|
629
|
+
forEachChildSync(blocklet, (component, { id, ancestors }) => {
|
|
630
|
+
if (component.meta.group === BlockletGroup.gateway) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
const { mountPoint } = component;
|
|
631
635
|
if (!mountPoint) {
|
|
632
|
-
logger.error(`mountPoint of child ${
|
|
636
|
+
logger.error(`mountPoint of child ${component.meta.name} does not exist`);
|
|
633
637
|
// eslint-disable-next-line no-continue
|
|
634
|
-
|
|
638
|
+
return;
|
|
635
639
|
}
|
|
636
640
|
|
|
637
|
-
const childWebInterface = findWebInterface(
|
|
641
|
+
const childWebInterface = findWebInterface(component);
|
|
638
642
|
if (!childWebInterface) {
|
|
639
|
-
logger.error(`web interface of child ${
|
|
643
|
+
logger.error(`web interface of child ${component.meta.name} does not exist`);
|
|
640
644
|
// eslint-disable-next-line no-continue
|
|
641
|
-
|
|
645
|
+
return;
|
|
642
646
|
}
|
|
643
647
|
|
|
644
|
-
const pathPrefix = path.join(rule.from.pathPrefix, mountPoint);
|
|
645
|
-
const isRootPath = pathPrefix === rule.from.pathPrefix;
|
|
648
|
+
const pathPrefix = path.join(rule.from.pathPrefix, ...ancestors.map((x) => x.mountPoint || ''), mountPoint);
|
|
649
|
+
const isRootPath = normalizePathPrefix(pathPrefix) === normalizePathPrefix(rule.from.pathPrefix);
|
|
646
650
|
if (isRootPath) {
|
|
647
651
|
occupied = true;
|
|
648
652
|
}
|
|
@@ -657,17 +661,16 @@ class RouterManager extends EventEmitter {
|
|
|
657
661
|
},
|
|
658
662
|
to: {
|
|
659
663
|
type: ROUTING_RULE_TYPES.BLOCKLET,
|
|
660
|
-
port: findInterfacePortByName(
|
|
661
|
-
did: rule.to.did, // root
|
|
662
|
-
interfaceName: rule.to.interfaceName, // root
|
|
663
|
-
|
|
664
|
-
realInterfaceName: childWebInterface.name,
|
|
664
|
+
port: findInterfacePortByName(component, childWebInterface.name),
|
|
665
|
+
did: rule.to.did, // root component did
|
|
666
|
+
interfaceName: rule.to.interfaceName, // root component interface
|
|
667
|
+
componentId: id,
|
|
665
668
|
},
|
|
666
669
|
isProtected: isRootPath ? rule.isProtected : true,
|
|
667
670
|
};
|
|
668
671
|
|
|
669
672
|
rules.push(childRule);
|
|
670
|
-
}
|
|
673
|
+
});
|
|
671
674
|
|
|
672
675
|
// get root rule
|
|
673
676
|
if (!occupied && blocklet.meta.group !== BlockletGroup.gateway) {
|
package/lib/states/audit-log.js
CHANGED
|
@@ -110,7 +110,7 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
110
110
|
case 'deleteComponent':
|
|
111
111
|
return `removed component ${args.did} from blocklet ${getBlockletInfo(result, info)}`;
|
|
112
112
|
case 'configBlocklet':
|
|
113
|
-
return `updated following
|
|
113
|
+
return `updated following config for blocklet ${getBlockletInfo(result, info)}:\n${args.configs.map(x => `- ${x.key}: ${x.value}\n`)}`; // prettier-ignore
|
|
114
114
|
case 'upgradeBlocklet':
|
|
115
115
|
return `upgraded blocklet ${getBlockletInfo(result, info)} to v${result.meta.version}`;
|
|
116
116
|
case 'updateChildBlocklets':
|
|
@@ -154,7 +154,7 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
154
154
|
return `${args.user.approved ? 'enabled' : 'disabled'} user ${user} for ${team}`;
|
|
155
155
|
case 'deletePassportIssuance':
|
|
156
156
|
return `removed passport issuance ${args.sessionId} from ${team}`;
|
|
157
|
-
case '
|
|
157
|
+
case 'createMemberInvitation':
|
|
158
158
|
return `created member invitation(${result.inviteId}: ${args.remark}) with **${args.role}** passport for ${team}`; // prettier-ignore
|
|
159
159
|
case 'deleteInvitation':
|
|
160
160
|
return `removed unused member invitation(${args.inviteId}) from ${team}`;
|
|
@@ -169,6 +169,8 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
169
169
|
return `removed all trusted passport issuers for ${team}`;
|
|
170
170
|
}
|
|
171
171
|
return `updated trusted passport issuers to following for ${team}: \n${args.trustedPassports.map(x => `- ${x.remark}: ${x.issuerDid}`).join('\n')}`; // prettier-ignore
|
|
172
|
+
case 'delegateTransferNFT':
|
|
173
|
+
return `${args.owner} ${args.reason}`;
|
|
172
174
|
|
|
173
175
|
// accessKeys
|
|
174
176
|
case 'createAccessKey':
|
|
@@ -258,12 +260,13 @@ const getLogCategory = (action) => {
|
|
|
258
260
|
case 'revokeUserPassport':
|
|
259
261
|
case 'enableUserPassport':
|
|
260
262
|
case 'updateUserApproval':
|
|
261
|
-
case '
|
|
263
|
+
case 'createMemberInvitation':
|
|
262
264
|
case 'deleteInvitation':
|
|
263
265
|
case 'createRole':
|
|
264
266
|
case 'updateRole':
|
|
265
267
|
case 'updatePermissionsForRole':
|
|
266
268
|
case 'configTrustedPassports':
|
|
269
|
+
case 'delegateTransferNFT':
|
|
267
270
|
return 'team';
|
|
268
271
|
|
|
269
272
|
// accessKeys
|
|
@@ -299,6 +302,25 @@ const getLogCategory = (action) => {
|
|
|
299
302
|
}
|
|
300
303
|
};
|
|
301
304
|
|
|
305
|
+
const getScope = (args = {}) => {
|
|
306
|
+
// this param usually means mutating an application (server or blocklet)
|
|
307
|
+
if (args.teamDid) {
|
|
308
|
+
return args.teamDid;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// this param usually means mutating a child component
|
|
312
|
+
if (args.rootDid) {
|
|
313
|
+
return args.rootDid;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// this param usually means mutating a nested child component
|
|
317
|
+
if (Array.isArray(args.did)) {
|
|
318
|
+
return args.did[0];
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return null;
|
|
322
|
+
};
|
|
323
|
+
|
|
302
324
|
class AuditLogState extends BaseState {
|
|
303
325
|
constructor(baseDir, options = {}) {
|
|
304
326
|
super(baseDir, { filename: 'audit-log.db', ...options });
|
|
@@ -355,7 +377,7 @@ class AuditLogState extends BaseState {
|
|
|
355
377
|
const [info, geoInfo, uaInfo] = await Promise.all([node.states.node.read(), lookup(ip), parse(ua)]);
|
|
356
378
|
|
|
357
379
|
const data = await this.asyncDB.insert({
|
|
358
|
-
scope: args
|
|
380
|
+
scope: getScope(args) || info.did, // server or blocklet did
|
|
359
381
|
action,
|
|
360
382
|
category: await getLogCategory(action, args, context, result, info, node),
|
|
361
383
|
content: (await getLogContent(action, args, context, result, info, node)).trim(),
|
|
@@ -52,22 +52,14 @@ class BlockletExtrasState extends BaseState {
|
|
|
52
52
|
methods.forEach((method) => {
|
|
53
53
|
this.extras.forEach((extra) => {
|
|
54
54
|
const fn = camelCase(`${method} ${extra.name}`); // getConfigs, getRules
|
|
55
|
-
this[fn] = this.
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
const childMethods = ['get', 'set', 'del'];
|
|
60
|
-
childMethods.forEach((method) => {
|
|
61
|
-
this.childExtras.forEach((extra) => {
|
|
62
|
-
const childFn = camelCase(`${method} child ${extra.name}`); // getChildConfigs, getChildRules
|
|
63
|
-
this[childFn] = this.generateExtraChildFn(method, extra);
|
|
55
|
+
this[fn] = this.generateFn(method, extra);
|
|
64
56
|
});
|
|
65
57
|
});
|
|
66
58
|
}
|
|
67
59
|
|
|
68
|
-
// generate
|
|
60
|
+
// generate functions
|
|
69
61
|
|
|
70
|
-
|
|
62
|
+
generateFn(method, extra) {
|
|
71
63
|
if (method === 'get') {
|
|
72
64
|
return this.generateGetFn(extra);
|
|
73
65
|
}
|
|
@@ -86,11 +78,20 @@ class BlockletExtrasState extends BaseState {
|
|
|
86
78
|
}
|
|
87
79
|
|
|
88
80
|
generateGetFn(extra) {
|
|
89
|
-
return async (
|
|
81
|
+
return async (dids, path, defaultValue) => {
|
|
82
|
+
// eslint-disable-next-line no-param-reassign
|
|
83
|
+
dids = [].concat(dids);
|
|
84
|
+
const [rootDid, ...childDids] = dids;
|
|
90
85
|
const { dek } = this.options;
|
|
91
86
|
const { name, afterGet = noop('data') } = extra;
|
|
92
|
-
|
|
93
|
-
|
|
87
|
+
|
|
88
|
+
let item = await this.asyncDB.findOne({ did: rootDid });
|
|
89
|
+
while (item && childDids.length) {
|
|
90
|
+
const did = childDids.shift();
|
|
91
|
+
item = (item.children || []).find((x) => x.did === did);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const data = afterGet({ data: item ? item[name] : item, did: rootDid, dek });
|
|
94
95
|
if (!path) {
|
|
95
96
|
return data;
|
|
96
97
|
}
|
|
@@ -99,43 +100,71 @@ class BlockletExtrasState extends BaseState {
|
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
generateSetFn(extra) {
|
|
102
|
-
return async (
|
|
103
|
+
return async (dids, data) => {
|
|
104
|
+
// eslint-disable-next-line no-param-reassign
|
|
105
|
+
dids = [].concat(dids);
|
|
106
|
+
const [rootDid, ...childDids] = dids;
|
|
103
107
|
const { dek } = this.options;
|
|
104
108
|
const { name, beforeSet = noop('cur') } = extra;
|
|
105
|
-
const
|
|
109
|
+
const exist = await this.asyncDB.findOne({ did: rootDid });
|
|
110
|
+
|
|
111
|
+
const item = exist || { did: rootDid };
|
|
112
|
+
let component = item;
|
|
113
|
+
while (childDids.length) {
|
|
114
|
+
const did = childDids.shift();
|
|
115
|
+
component.children = component.children || [];
|
|
116
|
+
let child = component.children.find((x) => x.did === did);
|
|
117
|
+
if (!child) {
|
|
118
|
+
child = { did };
|
|
119
|
+
component.children.push(child);
|
|
120
|
+
}
|
|
121
|
+
component = child;
|
|
122
|
+
}
|
|
106
123
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
124
|
+
const old = component[name];
|
|
125
|
+
const newData = beforeSet({ old, cur: data, did: rootDid, dek });
|
|
126
|
+
component[name] = newData;
|
|
127
|
+
|
|
128
|
+
if (!exist) {
|
|
129
|
+
await this.asyncDB.insert(item);
|
|
130
|
+
logger.info('create extra success', { name, dids });
|
|
131
|
+
} else {
|
|
132
|
+
await this.update(item._id, item);
|
|
133
|
+
logger.info('update extra success', { name, dids });
|
|
116
134
|
}
|
|
117
135
|
|
|
118
|
-
|
|
119
|
-
const updated = await this.update(item._id, {
|
|
120
|
-
$set: {
|
|
121
|
-
[name]: beforeSet({ old: itemNameValue, cur: data, did, dek }),
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
return updated[name];
|
|
136
|
+
return newData;
|
|
125
137
|
};
|
|
126
138
|
}
|
|
127
139
|
|
|
128
140
|
generateDelFn(extra) {
|
|
129
|
-
return async (
|
|
141
|
+
return async (dids) => {
|
|
142
|
+
// eslint-disable-next-line no-param-reassign
|
|
143
|
+
dids = [].concat(dids);
|
|
144
|
+
const [rootDid, ...childDids] = dids;
|
|
130
145
|
const { name } = extra;
|
|
131
|
-
const item = await this.asyncDB.findOne({ did });
|
|
146
|
+
const item = await this.asyncDB.findOne({ did: rootDid });
|
|
132
147
|
|
|
133
148
|
if (!item) {
|
|
134
|
-
return
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
let component = item;
|
|
153
|
+
while (component && childDids.length) {
|
|
154
|
+
const did = childDids.shift();
|
|
155
|
+
component = (component.children || []).find((x) => x.did === did);
|
|
135
156
|
}
|
|
136
157
|
|
|
137
|
-
|
|
138
|
-
|
|
158
|
+
if (!component) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const updated = component[name];
|
|
163
|
+
component[name] = null;
|
|
164
|
+
|
|
165
|
+
await this.update(item._id, item);
|
|
166
|
+
|
|
167
|
+
return updated;
|
|
139
168
|
};
|
|
140
169
|
}
|
|
141
170
|
|
|
@@ -153,128 +182,6 @@ class BlockletExtrasState extends BaseState {
|
|
|
153
182
|
return list;
|
|
154
183
|
};
|
|
155
184
|
}
|
|
156
|
-
|
|
157
|
-
// generate extra child functions
|
|
158
|
-
|
|
159
|
-
generateExtraChildFn(method, extra) {
|
|
160
|
-
if (method === 'get') {
|
|
161
|
-
return this.generateGetChildFn(extra);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (method === 'set') {
|
|
165
|
-
return this.generateSetChildFn(extra);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (method === 'del') {
|
|
169
|
-
return this.generateDelChildFn(extra);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
generateGetChildFn(extra) {
|
|
174
|
-
return async (did, childDid) => {
|
|
175
|
-
const { dek } = this.options;
|
|
176
|
-
const { name, afterGet = noop('data') } = extra;
|
|
177
|
-
const item = await this.asyncDB.findOne({ did });
|
|
178
|
-
const children = (item || {}).children || [];
|
|
179
|
-
const subItem = (children || []).find((x) => x.did === childDid);
|
|
180
|
-
return afterGet({ data: subItem ? subItem[name] : null, did, dek });
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
generateSetChildFn(extra) {
|
|
185
|
-
return async (did, childDid, data) => {
|
|
186
|
-
const { dek } = this.options;
|
|
187
|
-
const { name, beforeSet = noop('cur') } = extra;
|
|
188
|
-
const item = await this.asyncDB.findOne({ did });
|
|
189
|
-
|
|
190
|
-
if (!item) {
|
|
191
|
-
const newData = beforeSet({ old: undefined, cur: data, did, dek });
|
|
192
|
-
const insertData = {
|
|
193
|
-
did,
|
|
194
|
-
children: [
|
|
195
|
-
{
|
|
196
|
-
did: childDid,
|
|
197
|
-
[name]: newData,
|
|
198
|
-
},
|
|
199
|
-
],
|
|
200
|
-
};
|
|
201
|
-
await this.asyncDB.insert(insertData);
|
|
202
|
-
|
|
203
|
-
logger.info('create info success; insert child info success');
|
|
204
|
-
|
|
205
|
-
return newData;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const children = (item || {}).children || [];
|
|
209
|
-
const subItem = (children || []).find((x) => x.did === childDid);
|
|
210
|
-
|
|
211
|
-
if (!subItem) {
|
|
212
|
-
const newData = beforeSet({ old: undefined, cur: data, did, dek });
|
|
213
|
-
await this.update(item._id, {
|
|
214
|
-
$addToSet: {
|
|
215
|
-
children: {
|
|
216
|
-
did: childDid,
|
|
217
|
-
[name]: newData,
|
|
218
|
-
},
|
|
219
|
-
},
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
logger.info('insert child info success');
|
|
223
|
-
return newData;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const newData = beforeSet({ old: subItem[name], cur: data, did, dek });
|
|
227
|
-
|
|
228
|
-
children.forEach((x) => {
|
|
229
|
-
if (x.did === childDid) {
|
|
230
|
-
x[name] = newData;
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
await this.update(item._id, {
|
|
235
|
-
$set: {
|
|
236
|
-
children,
|
|
237
|
-
},
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
return newData;
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
generateDelChildFn(extra) {
|
|
245
|
-
return async (did, childDid) => {
|
|
246
|
-
const { name } = extra;
|
|
247
|
-
const item = await this.asyncDB.findOne({ did });
|
|
248
|
-
|
|
249
|
-
if (!item) {
|
|
250
|
-
return null;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const children = (item || {}).children || [];
|
|
254
|
-
const subItem = (children || []).find((x) => x.did === childDid);
|
|
255
|
-
|
|
256
|
-
if (!subItem) {
|
|
257
|
-
return null;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
let updated = null;
|
|
261
|
-
|
|
262
|
-
children.forEach((x) => {
|
|
263
|
-
if (x.did === childDid) {
|
|
264
|
-
updated = x[name];
|
|
265
|
-
x[name] = null;
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
await this.update(item._id, {
|
|
270
|
-
$set: {
|
|
271
|
-
children,
|
|
272
|
-
},
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
return updated;
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
185
|
}
|
|
279
186
|
|
|
280
187
|
module.exports = BlockletExtrasState;
|