@abtnode/core 1.17.6-beta-20251216-223535-283b9ffe → 1.17.6-beta-20251217-144034-62fafb94
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 +4 -2
- package/lib/event/index.js +54 -2
- package/lib/router/helper.js +29 -10
- package/lib/states/blocklet-child.js +26 -0
- package/lib/states/blocklet.js +45 -27
- package/lib/util/blocklet.js +119 -2
- package/package.json +24 -24
|
@@ -2832,7 +2832,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2832
2832
|
{
|
|
2833
2833
|
name: 'send-serverless-heartbeat',
|
|
2834
2834
|
time: process.env.ABT_NODE_SERVERLESS_HEARTBEAT_INTERVAL || '*/5 * * * *', // default every 5 minutes
|
|
2835
|
-
options: { runOnInit:
|
|
2835
|
+
options: { runOnInit: true },
|
|
2836
2836
|
fn: () => launcher.sendServerlessHeartbeat(),
|
|
2837
2837
|
},
|
|
2838
2838
|
];
|
|
@@ -5433,8 +5433,10 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
5433
5433
|
this.emit(BlockletEvents.appDidChanged, blocklet);
|
|
5434
5434
|
|
|
5435
5435
|
await updateBlockletDocument({
|
|
5436
|
-
blocklet,
|
|
5436
|
+
did: blocklet.appPid,
|
|
5437
5437
|
nodeInfo,
|
|
5438
|
+
states,
|
|
5439
|
+
teamManager: this.teamManager,
|
|
5438
5440
|
})
|
|
5439
5441
|
.then(() => {
|
|
5440
5442
|
logger.info('updated blocklet dns document', { appPid: blocklet.appPid, appDid: blocklet.appDid });
|
package/lib/event/index.js
CHANGED
|
@@ -37,7 +37,12 @@ const { getBackupEndpoint, getBackupFilesUrlFromEndpoint, getDIDSpacesUrlFromEnd
|
|
|
37
37
|
const { autoBackupHandlerFactory, autoBackupHandler } = require('./auto-backup-handler');
|
|
38
38
|
|
|
39
39
|
const eventBusHandler = require('../blocklet/webhook/event-bus');
|
|
40
|
-
const {
|
|
40
|
+
const {
|
|
41
|
+
isDevelopmentMode,
|
|
42
|
+
deleteBlockletCache,
|
|
43
|
+
updateDidDocument,
|
|
44
|
+
updateDidDocumentStateOnly,
|
|
45
|
+
} = require('../util/blocklet');
|
|
41
46
|
const {
|
|
42
47
|
backupBlockletSites,
|
|
43
48
|
cleanBlockletSitesBackup,
|
|
@@ -229,6 +234,14 @@ module.exports = ({
|
|
|
229
234
|
|
|
230
235
|
await teamAPI.refreshBlockletInterfacePermissions(blocklet.meta);
|
|
231
236
|
logger.info('refreshed blocklet interface permissions after installed', { did: blocklet.meta.did });
|
|
237
|
+
|
|
238
|
+
try {
|
|
239
|
+
const nodeInfo = await node.getNodeInfo();
|
|
240
|
+
await updateDidDocument({ did: blocklet.appPid, nodeInfo, teamManager, states });
|
|
241
|
+
logger.info('updated blocklet DID document after install', { did: blocklet.meta.did });
|
|
242
|
+
} catch (error) {
|
|
243
|
+
logger.error('update blocklet DID document failed after install', { did: blocklet.meta.did, error });
|
|
244
|
+
}
|
|
232
245
|
} catch (error) {
|
|
233
246
|
logger.error('create.url.mapping.error', { event: name, error });
|
|
234
247
|
teamManager.createNotification({
|
|
@@ -261,6 +274,19 @@ module.exports = ({
|
|
|
261
274
|
logger.error('remove blocklet routing rules error', { event: name, error });
|
|
262
275
|
}
|
|
263
276
|
|
|
277
|
+
try {
|
|
278
|
+
const nodeInfo = await node.getNodeInfo();
|
|
279
|
+
await updateDidDocumentStateOnly({
|
|
280
|
+
did: blocklet.appPid,
|
|
281
|
+
blocklet,
|
|
282
|
+
state: 'deleted',
|
|
283
|
+
nodeInfo,
|
|
284
|
+
});
|
|
285
|
+
logger.info('updated blocklet DID document state to deleted', { did: blocklet.meta.did });
|
|
286
|
+
} catch (error) {
|
|
287
|
+
logger.error('update blocklet DID document failed after remove', { did: blocklet.meta.did, error });
|
|
288
|
+
}
|
|
289
|
+
|
|
264
290
|
try {
|
|
265
291
|
await blockletManager.prune();
|
|
266
292
|
} catch (error) {
|
|
@@ -503,6 +529,23 @@ module.exports = ({
|
|
|
503
529
|
} catch (error) {
|
|
504
530
|
logger.error('monit runtime info failed', { eventName, error });
|
|
505
531
|
}
|
|
532
|
+
|
|
533
|
+
if ([BlockletEvents.started, BlockletEvents.stopped].includes(eventName)) {
|
|
534
|
+
try {
|
|
535
|
+
const nodeInfo = await node.getNodeInfo();
|
|
536
|
+
await updateDidDocument({ did: blocklet.appPid, nodeInfo, teamManager, states });
|
|
537
|
+
logger.info('updated blocklet DID document after state change', {
|
|
538
|
+
did: blocklet.meta.did,
|
|
539
|
+
event: eventName,
|
|
540
|
+
});
|
|
541
|
+
} catch (error) {
|
|
542
|
+
logger.error('update blocklet DID document failed after state change', {
|
|
543
|
+
did: blocklet.meta.did,
|
|
544
|
+
event: eventName,
|
|
545
|
+
error,
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
}
|
|
506
549
|
}
|
|
507
550
|
|
|
508
551
|
if ([BlockletEvents.statusChange].includes(eventName) && isDevelopmentMode(blocklet)) {
|
|
@@ -704,8 +747,17 @@ module.exports = ({
|
|
|
704
747
|
});
|
|
705
748
|
});
|
|
706
749
|
|
|
707
|
-
routerManager.on(EVENTS.UPDATE_DOMAIN_ALIAS, (did) => {
|
|
750
|
+
routerManager.on(EVENTS.UPDATE_DOMAIN_ALIAS, async (did) => {
|
|
708
751
|
if (did) {
|
|
752
|
+
const nodeInfo = await node.getNodeInfo();
|
|
753
|
+
updateDidDocument({ did, nodeInfo, teamManager, states })
|
|
754
|
+
.then(() => {
|
|
755
|
+
logger.info('Update did document successfully on update domain alias', { did });
|
|
756
|
+
})
|
|
757
|
+
.catch((err) => {
|
|
758
|
+
logger.error('Update did document failed on update domain alias', { did, error: err });
|
|
759
|
+
});
|
|
760
|
+
|
|
709
761
|
blockletManager
|
|
710
762
|
.detail({ did })
|
|
711
763
|
.then((blocklet) => {
|
package/lib/router/helper.js
CHANGED
|
@@ -29,6 +29,7 @@ const axios = require('@abtnode/util/lib/axios');
|
|
|
29
29
|
const { getIpDnsDomainForBlocklet } = require('@abtnode/util/lib/get-domain-for-blocklet');
|
|
30
30
|
const { forEachBlockletSync } = require('@blocklet/meta/lib/util');
|
|
31
31
|
const { processLogByDate } = require('@abtnode/analytics');
|
|
32
|
+
const { DBCache, getAbtNodeRedisAndSQLiteUrl } = require('@abtnode/db-cache');
|
|
32
33
|
const pRetry = require('p-retry');
|
|
33
34
|
const { buildLauncherUrl, buildRequestHeaders } = require('@abtnode/auth/lib/launcher');
|
|
34
35
|
const {
|
|
@@ -105,6 +106,13 @@ const { get: getIp } = require('../util/ip');
|
|
|
105
106
|
|
|
106
107
|
const isServiceFeDevelopment = process.env.ABT_NODE_SERVICE_FE_PORT;
|
|
107
108
|
|
|
109
|
+
// 使用 DBCache 实现分布式锁,防止同一个 blocklet 的路由操作并发执行
|
|
110
|
+
const ensureBlockletRoutingLock = new DBCache(() => ({
|
|
111
|
+
prefix: 'ensure-blocklet-routing-lock',
|
|
112
|
+
ttl: 1000 * 60, // 60 seconds timeout
|
|
113
|
+
...getAbtNodeRedisAndSQLiteUrl(),
|
|
114
|
+
}));
|
|
115
|
+
|
|
108
116
|
const hasRuleByPrefix = (site, value) => site.rules.find((x) => x.isProtected && get(x, 'from.pathPrefix') === value);
|
|
109
117
|
|
|
110
118
|
const pingWellknownRule = {
|
|
@@ -1311,19 +1319,22 @@ module.exports = function getRouterHelpers({
|
|
|
1311
1319
|
|
|
1312
1320
|
const existSite = await states.site.findOne({ domain: domainGroup });
|
|
1313
1321
|
updateBlockletDocument({
|
|
1314
|
-
blocklet,
|
|
1322
|
+
did: blocklet.appPid,
|
|
1315
1323
|
nodeInfo,
|
|
1324
|
+
teamManager,
|
|
1325
|
+
states,
|
|
1316
1326
|
})
|
|
1317
1327
|
.then(() => {
|
|
1318
|
-
logger.info(
|
|
1328
|
+
logger.info('updated blocklet dns document', {
|
|
1329
|
+
did: blocklet.appPid,
|
|
1330
|
+
});
|
|
1319
1331
|
})
|
|
1320
1332
|
.catch((err) => {
|
|
1321
|
-
logger.error(
|
|
1333
|
+
logger.error('update blocklet dns document failed', { did: blocklet.meta.did, error: err });
|
|
1322
1334
|
});
|
|
1323
1335
|
|
|
1324
1336
|
if (!existSite) {
|
|
1325
1337
|
const domainAliases = getBlockletDidDomainList(blocklet, nodeInfo);
|
|
1326
|
-
|
|
1327
1338
|
// let didDomain in front of ipEchoDnsDomain
|
|
1328
1339
|
domainAliases.push({ value: getIpDnsDomainForBlocklet(blocklet), isProtected: true });
|
|
1329
1340
|
|
|
@@ -1496,13 +1507,21 @@ module.exports = function getRouterHelpers({
|
|
|
1496
1507
|
* @returns {Promise<boolean>} if routing changed
|
|
1497
1508
|
*/
|
|
1498
1509
|
const ensureBlockletRouting = async (blocklet, context = {}) => {
|
|
1499
|
-
const
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
return false;
|
|
1503
|
-
}
|
|
1510
|
+
const lockName = `ensure-blocklet-routing-${blocklet.meta.did}`;
|
|
1511
|
+
|
|
1512
|
+
await ensureBlockletRoutingLock.acquire(lockName);
|
|
1504
1513
|
|
|
1505
|
-
|
|
1514
|
+
try {
|
|
1515
|
+
const nodeInfo = await nodeState.read();
|
|
1516
|
+
const hasWebInterface = (blocklet.meta.interfaces || []).some((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB);
|
|
1517
|
+
if (!hasWebInterface) {
|
|
1518
|
+
return false;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
return await _ensureBlockletSites(blocklet, nodeInfo, context);
|
|
1522
|
+
} finally {
|
|
1523
|
+
await ensureBlockletRoutingLock.releaseLock(lockName);
|
|
1524
|
+
}
|
|
1506
1525
|
};
|
|
1507
1526
|
|
|
1508
1527
|
/**
|
|
@@ -56,6 +56,32 @@ class BlockletChildState extends BaseState {
|
|
|
56
56
|
return (children || []).map(ensureDeployedFrom);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Get children by multiple parent blocklet IDs (batch query)
|
|
61
|
+
* @param {string[]} parentBlockletIds - Array of parent blocklet IDs
|
|
62
|
+
* @returns {Promise<Map<string, Array>>} - Map of parentBlockletId -> children array
|
|
63
|
+
*/
|
|
64
|
+
async getChildrenByParentIds(parentBlockletIds) {
|
|
65
|
+
if (!Array.isArray(parentBlockletIds) || parentBlockletIds.length === 0) {
|
|
66
|
+
return new Map();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const children = await this.find({ parentBlockletId: { $in: parentBlockletIds } }, {}, { createdAt: 1 });
|
|
70
|
+
|
|
71
|
+
// Group children by parentBlockletId
|
|
72
|
+
const childrenMap = new Map();
|
|
73
|
+
parentBlockletIds.forEach((id) => childrenMap.set(id, []));
|
|
74
|
+
|
|
75
|
+
(children || []).forEach((child) => {
|
|
76
|
+
const processedChild = ensureDeployedFrom(child);
|
|
77
|
+
if (childrenMap.has(child.parentBlockletId)) {
|
|
78
|
+
childrenMap.get(child.parentBlockletId).push(processedChild);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return childrenMap;
|
|
83
|
+
}
|
|
84
|
+
|
|
59
85
|
/**
|
|
60
86
|
* Delete children by parent blocklet ID
|
|
61
87
|
* @param {string} parentBlockletId - The parent blocklet ID
|
package/lib/states/blocklet.js
CHANGED
|
@@ -265,13 +265,13 @@ class BlockletState extends BaseState {
|
|
|
265
265
|
* @param {string} blockletId - The blocklet ID
|
|
266
266
|
* @returns {Promise<Array>} - Array of children
|
|
267
267
|
*/
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
268
|
+
/**
|
|
269
|
+
* Process raw children records into structured format
|
|
270
|
+
* @param {Array} children - Raw children records from database
|
|
271
|
+
* @param {string} parentBlockletId - The parent blocklet ID (for logging)
|
|
272
|
+
* @returns {Array} - Processed children array
|
|
273
|
+
*/
|
|
274
|
+
_processLoadedChildren(children, parentBlockletId) {
|
|
275
275
|
if (!Array.isArray(children)) {
|
|
276
276
|
return [];
|
|
277
277
|
}
|
|
@@ -280,17 +280,17 @@ class BlockletState extends BaseState {
|
|
|
280
280
|
// Ensure meta is an object and has required fields
|
|
281
281
|
const meta = child.meta || {};
|
|
282
282
|
if (!meta.did) {
|
|
283
|
-
logger.warn('loadChildren: child missing meta.did', { childId: child.id, parentBlockletId
|
|
283
|
+
logger.warn('loadChildren: child missing meta.did', { childId: child.id, parentBlockletId });
|
|
284
284
|
}
|
|
285
285
|
if (!meta.name && !meta.bundleName) {
|
|
286
286
|
logger.warn('loadChildren: child missing meta.name and meta.bundleName', {
|
|
287
287
|
childId: child.id,
|
|
288
288
|
childDid: meta.did,
|
|
289
|
-
parentBlockletId
|
|
289
|
+
parentBlockletId,
|
|
290
290
|
});
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
-
|
|
293
|
+
return {
|
|
294
294
|
id: child.id,
|
|
295
295
|
mountPoint: child.mountPoint,
|
|
296
296
|
meta,
|
|
@@ -312,15 +312,16 @@ class BlockletState extends BaseState {
|
|
|
312
312
|
greenStatus: child.greenStatus,
|
|
313
313
|
greenPorts: child.greenPorts,
|
|
314
314
|
};
|
|
315
|
+
});
|
|
316
|
+
}
|
|
315
317
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
318
|
+
async loadChildren(blockletId) {
|
|
319
|
+
if (!this.BlockletChildState || !blockletId) {
|
|
320
|
+
return [];
|
|
321
|
+
}
|
|
321
322
|
|
|
322
|
-
|
|
323
|
-
|
|
323
|
+
const children = await this.BlockletChildState.getChildrenByParentId(blockletId);
|
|
324
|
+
return this._processLoadedChildren(children, blockletId);
|
|
324
325
|
}
|
|
325
326
|
|
|
326
327
|
/**
|
|
@@ -525,16 +526,23 @@ class BlockletState extends BaseState {
|
|
|
525
526
|
|
|
526
527
|
async getBlocklets(query = {}, projection = {}, sort = { createdAt: -1 }) {
|
|
527
528
|
const docs = await this.find(query, projection, sort);
|
|
528
|
-
const
|
|
529
|
+
const validDocs = docs.filter(Boolean);
|
|
529
530
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
const children = await this.loadChildren(doc.id);
|
|
533
|
-
doc.children = children;
|
|
534
|
-
result.push(formatBlocklet(doc, 'onRead', this.config.dek));
|
|
531
|
+
if (validDocs.length === 0) {
|
|
532
|
+
return [];
|
|
535
533
|
}
|
|
536
534
|
|
|
537
|
-
|
|
535
|
+
// Batch load all children in a single query (instead of N+1 queries)
|
|
536
|
+
let childrenMap = new Map();
|
|
537
|
+
if (this.BlockletChildState) {
|
|
538
|
+
const blockletIds = validDocs.map((doc) => doc.id);
|
|
539
|
+
childrenMap = await this.BlockletChildState.getChildrenByParentIds(blockletIds);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
return validDocs.map((doc) => {
|
|
543
|
+
doc.children = this._processLoadedChildren(childrenMap.get(doc.id) || [], doc.id);
|
|
544
|
+
return formatBlocklet(doc, 'onRead', this.config.dek);
|
|
545
|
+
});
|
|
538
546
|
}
|
|
539
547
|
|
|
540
548
|
async deleteBlocklet(did) {
|
|
@@ -903,12 +911,22 @@ class BlockletState extends BaseState {
|
|
|
903
911
|
}
|
|
904
912
|
|
|
905
913
|
async getServices() {
|
|
906
|
-
const blocklets = await this.getBlocklets({}, { meta: 1, ports: 1 });
|
|
914
|
+
const blocklets = await this.getBlocklets({}, { id: 1, meta: 1, ports: 1 });
|
|
907
915
|
const services = [];
|
|
908
916
|
|
|
909
917
|
blocklets.forEach((blocklet) => {
|
|
910
918
|
const list = getBlockletServices(blocklet);
|
|
911
919
|
list.forEach((x) => {
|
|
920
|
+
// 如果本地 53 端口被系统占用,调试可以配置: export ABT_NODE_REDIRECTION_SERVICE_PORTS="53:10053,553:101553" 等多个 Service 端口重定向
|
|
921
|
+
if (process.env.ABT_NODE_REDIRECTION_SERVICE_PORTS) {
|
|
922
|
+
const redirectionPorts = process.env.ABT_NODE_REDIRECTION_SERVICE_PORTS.split(',');
|
|
923
|
+
redirectionPorts.forEach((portString) => {
|
|
924
|
+
const [portA, portB] = portString.split(':');
|
|
925
|
+
if (x.port === +portA) {
|
|
926
|
+
x.port = +portB;
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
}
|
|
912
930
|
if (!x.port) {
|
|
913
931
|
logger.error('Missing service port', { appId: blocklet.meta.did, x });
|
|
914
932
|
return;
|
|
@@ -941,7 +959,7 @@ class BlockletState extends BaseState {
|
|
|
941
959
|
* @return {Object} { <did> : { interfaceName } }
|
|
942
960
|
*/
|
|
943
961
|
async groupAllInterfaces() {
|
|
944
|
-
const blocklets = await this.getBlocklets({}, { meta: 1 });
|
|
962
|
+
const blocklets = await this.getBlocklets({}, { id: 1, meta: 1 });
|
|
945
963
|
const result = {};
|
|
946
964
|
const fillResult = (component, { id }) => {
|
|
947
965
|
const { interfaces } = component.meta;
|
|
@@ -1201,7 +1219,7 @@ class BlockletState extends BaseState {
|
|
|
1201
1219
|
}
|
|
1202
1220
|
|
|
1203
1221
|
async _getOccupiedPorts() {
|
|
1204
|
-
const blocklets = await this.getBlocklets({}, { port: 1, ports: 1, meta: 1 });
|
|
1222
|
+
const blocklets = await this.getBlocklets({}, { id: 1, port: 1, ports: 1, meta: 1 });
|
|
1205
1223
|
|
|
1206
1224
|
const occupiedExternalPorts = new Map();
|
|
1207
1225
|
const occupiedInternalPorts = new Map();
|
package/lib/util/blocklet.js
CHANGED
|
@@ -31,6 +31,7 @@ const { isValid: isValidDid, isEthereumDid } = require('@arcblock/did');
|
|
|
31
31
|
const logger = require('@abtnode/logger')('@abtnode/core:util:blocklet');
|
|
32
32
|
const pm2 = require('@abtnode/util/lib/pm2/async-pm2');
|
|
33
33
|
const sleep = require('@abtnode/util/lib/sleep');
|
|
34
|
+
const { isCustomDomain } = require('@abtnode/util/lib/url-evaluation');
|
|
34
35
|
const getPm2ProcessInfo = require('@abtnode/util/lib/get-pm2-process-info');
|
|
35
36
|
const { formatEnv, getSecurityNodeOptions, decrypt } = require('@abtnode/util/lib/security');
|
|
36
37
|
const ensureEndpointHealthy = require('@abtnode/util/lib/ensure-endpoint-healthy');
|
|
@@ -45,6 +46,7 @@ const {
|
|
|
45
46
|
APP_STRUCT_VERSION,
|
|
46
47
|
BLOCKLET_CACHE_TTL,
|
|
47
48
|
AIGNE_CONFIG_ENCRYPT_SALT,
|
|
49
|
+
SLOT_FOR_IP_DNS_SITE,
|
|
48
50
|
} = require('@abtnode/constant');
|
|
49
51
|
const { BLOCKLET_THEME_LIGHT, BLOCKLET_THEME_DARK } = require('@blocklet/theme');
|
|
50
52
|
const {
|
|
@@ -127,6 +129,7 @@ const {
|
|
|
127
129
|
templateReplace,
|
|
128
130
|
getServerDidDomain,
|
|
129
131
|
APP_CONFIG_IMAGE_KEYS,
|
|
132
|
+
replaceDomainSlot,
|
|
130
133
|
} = require('./index');
|
|
131
134
|
const { installExternalDependencies } = require('./install-external-dependencies');
|
|
132
135
|
const parseDockerOptionsFromPm2 = require('./docker/parse-docker-options-from-pm2');
|
|
@@ -135,6 +138,7 @@ const getDockerRuntimeInfo = require('./docker/get-docker-runtime-info');
|
|
|
135
138
|
const parseDockerName = require('./docker/parse-docker-name');
|
|
136
139
|
const { createDockerNetwork } = require('./docker/docker-network');
|
|
137
140
|
const { ensureBun } = require('./ensure-bun');
|
|
141
|
+
const { getFromCache: getAccessibleExternalNodeIp } = require('./get-accessible-external-node-ip');
|
|
138
142
|
|
|
139
143
|
/**
|
|
140
144
|
* Get actual listening port from Docker container or process
|
|
@@ -2402,9 +2406,16 @@ const validateStore = (nodeInfo, storeUrl) => {
|
|
|
2402
2406
|
return;
|
|
2403
2407
|
}
|
|
2404
2408
|
|
|
2409
|
+
const storeUrlObj = new URL(storeUrl);
|
|
2410
|
+
const registerUrlObj = new URL(nodeInfo.registerUrl);
|
|
2411
|
+
|
|
2412
|
+
// 信任 Launcher 打包的应用
|
|
2413
|
+
if (registerUrlObj.host === storeUrlObj.host) {
|
|
2414
|
+
return;
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2405
2417
|
const inStoreList = nodeInfo.blockletRegistryList.find((item) => {
|
|
2406
2418
|
const itemURLObj = new URL(item.url);
|
|
2407
|
-
const storeUrlObj = new URL(storeUrl);
|
|
2408
2419
|
|
|
2409
2420
|
return itemURLObj.host === storeUrlObj.host;
|
|
2410
2421
|
});
|
|
@@ -2736,8 +2747,10 @@ const getSlpDid = (serverDid, appPid) => {
|
|
|
2736
2747
|
};
|
|
2737
2748
|
|
|
2738
2749
|
// eslint-disable-next-line require-await
|
|
2739
|
-
const
|
|
2750
|
+
const publishDidDocument = async ({ blocklet, ownerInfo, nodeInfo }) => {
|
|
2740
2751
|
const alsoKnownAs = getBlockletKnownAs(blocklet);
|
|
2752
|
+
logger.debug('updateDidDocument blocklet info', { blocklet });
|
|
2753
|
+
|
|
2741
2754
|
const { wallet } = getBlockletInfo(blocklet, nodeInfo.sk);
|
|
2742
2755
|
const { mode, did: serverDid } = nodeInfo;
|
|
2743
2756
|
|
|
@@ -2761,6 +2774,58 @@ const updateDidDocument = async ({ blocklet, nodeInfo }) => {
|
|
|
2761
2774
|
slpDomain: nodeInfo.slpDomain,
|
|
2762
2775
|
});
|
|
2763
2776
|
|
|
2777
|
+
const name = blocklet.meta?.title || blocklet.meta?.name;
|
|
2778
|
+
const state = fromBlockletStatus(blocklet.status || BlockletStatus.stopped);
|
|
2779
|
+
|
|
2780
|
+
let launcher = null;
|
|
2781
|
+
if (!isEmpty(blocklet.controller)) {
|
|
2782
|
+
launcher = {
|
|
2783
|
+
did: toDid(blocklet.controller.did || nodeInfo.registerInfo.appPid), // 目前 controller 没有 launcher 的元信息, 默认在 nodeInfo 中存储
|
|
2784
|
+
name: blocklet.controller.launcherName || nodeInfo.registerInfo.appName || '',
|
|
2785
|
+
url: blocklet.controller.launcherUrl || nodeInfo.registerInfo.appUrl || '',
|
|
2786
|
+
userDid: toDid(blocklet.controller.nftOwner),
|
|
2787
|
+
};
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2790
|
+
const isPrimaryDomain = (d) => {
|
|
2791
|
+
const appUrl = blocklet.environments.find((x) => x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_URL)?.value;
|
|
2792
|
+
try {
|
|
2793
|
+
const url = new URL(appUrl);
|
|
2794
|
+
return url.hostname === d;
|
|
2795
|
+
} catch (error) {
|
|
2796
|
+
logger.error('failed to get primary domain', { error, domain: d, appUrl });
|
|
2797
|
+
return false;
|
|
2798
|
+
}
|
|
2799
|
+
};
|
|
2800
|
+
|
|
2801
|
+
const domains = await Promise.all(
|
|
2802
|
+
blocklet.site.domainAliases.map(async (item) => {
|
|
2803
|
+
let type = isCustomDomain(item.value) ? 'custom' : 'internal';
|
|
2804
|
+
// 如果域名是 appUrl,则设置为 primary
|
|
2805
|
+
if (isPrimaryDomain(item.value)) {
|
|
2806
|
+
type = 'primary';
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
if (item.value.includes(SLOT_FOR_IP_DNS_SITE)) {
|
|
2810
|
+
const nodeIp = await getAccessibleExternalNodeIp();
|
|
2811
|
+
item.value = replaceDomainSlot({ domain: item.value, nodeIp });
|
|
2812
|
+
}
|
|
2813
|
+
|
|
2814
|
+
return {
|
|
2815
|
+
type,
|
|
2816
|
+
host: item.value,
|
|
2817
|
+
url: `https://${item.value}`,
|
|
2818
|
+
source: 'dnsRecords', // 固定为 dnsRecords
|
|
2819
|
+
};
|
|
2820
|
+
})
|
|
2821
|
+
);
|
|
2822
|
+
|
|
2823
|
+
const owner = {
|
|
2824
|
+
did: toDid(ownerInfo.did),
|
|
2825
|
+
name: ownerInfo.fullName,
|
|
2826
|
+
avatar: ownerInfo.avatar,
|
|
2827
|
+
};
|
|
2828
|
+
|
|
2764
2829
|
return didDocument.updateBlockletDocument({
|
|
2765
2830
|
blocklet,
|
|
2766
2831
|
wallet,
|
|
@@ -2772,6 +2837,56 @@ const updateDidDocument = async ({ blocklet, nodeInfo }) => {
|
|
|
2772
2837
|
slpDomain: nodeInfo.slpDomain,
|
|
2773
2838
|
serverDid,
|
|
2774
2839
|
blockletServerVersion: nodeInfo.version,
|
|
2840
|
+
name,
|
|
2841
|
+
state,
|
|
2842
|
+
owner,
|
|
2843
|
+
launcher,
|
|
2844
|
+
domains,
|
|
2845
|
+
});
|
|
2846
|
+
};
|
|
2847
|
+
|
|
2848
|
+
const updateDidDocument = async ({ did, status, nodeInfo, teamManager, states }) => {
|
|
2849
|
+
const blocklet = await states.blocklet.getBlocklet(did);
|
|
2850
|
+
const blockletExtra = await states.blockletExtras.findOne({ did });
|
|
2851
|
+
|
|
2852
|
+
blocklet.site = await states.site.findOneByBlocklet(did);
|
|
2853
|
+
blocklet.settings = await states.blockletExtras.getSettings(did);
|
|
2854
|
+
blocklet.controller = blockletExtra.controller;
|
|
2855
|
+
|
|
2856
|
+
logger.debug('update did document', { blocklet });
|
|
2857
|
+
|
|
2858
|
+
if (isEmpty(blocklet.status)) {
|
|
2859
|
+
blocklet.status = status;
|
|
2860
|
+
}
|
|
2861
|
+
|
|
2862
|
+
const ownerDid = blocklet.settings.owner.did;
|
|
2863
|
+
logger.info('get owner info', { ownerDid, teamDid: blocklet.appPid });
|
|
2864
|
+
const userState = await teamManager.getUserState(blocklet.appPid);
|
|
2865
|
+
const ownerInfo = await userState.getUser(ownerDid);
|
|
2866
|
+
|
|
2867
|
+
logger.info('got user info', {
|
|
2868
|
+
owner: ownerInfo,
|
|
2869
|
+
blockletDid: blocklet.meta.did,
|
|
2870
|
+
ownerDid,
|
|
2871
|
+
teamDid: blocklet.appPid,
|
|
2872
|
+
});
|
|
2873
|
+
|
|
2874
|
+
return publishDidDocument({ blocklet, ownerInfo, nodeInfo });
|
|
2875
|
+
};
|
|
2876
|
+
|
|
2877
|
+
// Update DID document state only (e.g., to 'deleted') without fetching from database
|
|
2878
|
+
// Used when blocklet is being removed and database data may not be available
|
|
2879
|
+
const updateDidDocumentStateOnly = ({ did, blocklet, state, nodeInfo }) => {
|
|
2880
|
+
logger.debug('update did document state only', { did, state });
|
|
2881
|
+
|
|
2882
|
+
const { wallet } = getBlockletInfo(blocklet, nodeInfo.sk);
|
|
2883
|
+
|
|
2884
|
+
return didDocument.updateBlockletStateOnly({
|
|
2885
|
+
did,
|
|
2886
|
+
state,
|
|
2887
|
+
didRegistryUrl: nodeInfo.didRegistry,
|
|
2888
|
+
wallet,
|
|
2889
|
+
blockletServerVersion: nodeInfo.version,
|
|
2775
2890
|
});
|
|
2776
2891
|
};
|
|
2777
2892
|
|
|
@@ -2983,7 +3098,9 @@ module.exports = {
|
|
|
2983
3098
|
getBlockletURLForLauncher,
|
|
2984
3099
|
ensureAppPortsNotOccupied,
|
|
2985
3100
|
getComponentNamesWithVersion,
|
|
3101
|
+
publishDidDocument,
|
|
2986
3102
|
updateDidDocument,
|
|
3103
|
+
updateDidDocumentStateOnly,
|
|
2987
3104
|
getSlpDid,
|
|
2988
3105
|
shouldEnableSlpDomain,
|
|
2989
3106
|
getAppConfigsFromComponent,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.17.6-beta-
|
|
6
|
+
"version": "1.17.6-beta-20251217-144034-62fafb94",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -17,21 +17,21 @@
|
|
|
17
17
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
18
18
|
"license": "Apache-2.0",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@abtnode/analytics": "1.17.6-beta-
|
|
21
|
-
"@abtnode/auth": "1.17.6-beta-
|
|
22
|
-
"@abtnode/certificate-manager": "1.17.6-beta-
|
|
23
|
-
"@abtnode/constant": "1.17.6-beta-
|
|
24
|
-
"@abtnode/cron": "1.17.6-beta-
|
|
25
|
-
"@abtnode/db-cache": "1.17.6-beta-
|
|
26
|
-
"@abtnode/docker-utils": "1.17.6-beta-
|
|
27
|
-
"@abtnode/logger": "1.17.6-beta-
|
|
28
|
-
"@abtnode/models": "1.17.6-beta-
|
|
29
|
-
"@abtnode/queue": "1.17.6-beta-
|
|
30
|
-
"@abtnode/rbac": "1.17.6-beta-
|
|
31
|
-
"@abtnode/router-provider": "1.17.6-beta-
|
|
32
|
-
"@abtnode/static-server": "1.17.6-beta-
|
|
33
|
-
"@abtnode/timemachine": "1.17.6-beta-
|
|
34
|
-
"@abtnode/util": "1.17.6-beta-
|
|
20
|
+
"@abtnode/analytics": "1.17.6-beta-20251217-144034-62fafb94",
|
|
21
|
+
"@abtnode/auth": "1.17.6-beta-20251217-144034-62fafb94",
|
|
22
|
+
"@abtnode/certificate-manager": "1.17.6-beta-20251217-144034-62fafb94",
|
|
23
|
+
"@abtnode/constant": "1.17.6-beta-20251217-144034-62fafb94",
|
|
24
|
+
"@abtnode/cron": "1.17.6-beta-20251217-144034-62fafb94",
|
|
25
|
+
"@abtnode/db-cache": "1.17.6-beta-20251217-144034-62fafb94",
|
|
26
|
+
"@abtnode/docker-utils": "1.17.6-beta-20251217-144034-62fafb94",
|
|
27
|
+
"@abtnode/logger": "1.17.6-beta-20251217-144034-62fafb94",
|
|
28
|
+
"@abtnode/models": "1.17.6-beta-20251217-144034-62fafb94",
|
|
29
|
+
"@abtnode/queue": "1.17.6-beta-20251217-144034-62fafb94",
|
|
30
|
+
"@abtnode/rbac": "1.17.6-beta-20251217-144034-62fafb94",
|
|
31
|
+
"@abtnode/router-provider": "1.17.6-beta-20251217-144034-62fafb94",
|
|
32
|
+
"@abtnode/static-server": "1.17.6-beta-20251217-144034-62fafb94",
|
|
33
|
+
"@abtnode/timemachine": "1.17.6-beta-20251217-144034-62fafb94",
|
|
34
|
+
"@abtnode/util": "1.17.6-beta-20251217-144034-62fafb94",
|
|
35
35
|
"@aigne/aigne-hub": "^0.10.15",
|
|
36
36
|
"@arcblock/did": "^1.27.15",
|
|
37
37
|
"@arcblock/did-connect-js": "^1.27.15",
|
|
@@ -43,15 +43,15 @@
|
|
|
43
43
|
"@arcblock/pm2-events": "^0.0.5",
|
|
44
44
|
"@arcblock/validator": "^1.27.15",
|
|
45
45
|
"@arcblock/vc": "^1.27.15",
|
|
46
|
-
"@blocklet/constant": "1.17.6-beta-
|
|
46
|
+
"@blocklet/constant": "1.17.6-beta-20251217-144034-62fafb94",
|
|
47
47
|
"@blocklet/did-space-js": "^1.2.10",
|
|
48
|
-
"@blocklet/env": "1.17.6-beta-
|
|
48
|
+
"@blocklet/env": "1.17.6-beta-20251217-144034-62fafb94",
|
|
49
49
|
"@blocklet/error": "^0.3.5",
|
|
50
|
-
"@blocklet/meta": "1.17.6-beta-
|
|
51
|
-
"@blocklet/resolver": "1.17.6-beta-
|
|
52
|
-
"@blocklet/sdk": "1.17.6-beta-
|
|
53
|
-
"@blocklet/server-js": "1.17.6-beta-
|
|
54
|
-
"@blocklet/store": "1.17.6-beta-
|
|
50
|
+
"@blocklet/meta": "1.17.6-beta-20251217-144034-62fafb94",
|
|
51
|
+
"@blocklet/resolver": "1.17.6-beta-20251217-144034-62fafb94",
|
|
52
|
+
"@blocklet/sdk": "1.17.6-beta-20251217-144034-62fafb94",
|
|
53
|
+
"@blocklet/server-js": "1.17.6-beta-20251217-144034-62fafb94",
|
|
54
|
+
"@blocklet/store": "1.17.6-beta-20251217-144034-62fafb94",
|
|
55
55
|
"@blocklet/theme": "^3.2.14",
|
|
56
56
|
"@fidm/x509": "^1.2.1",
|
|
57
57
|
"@ocap/mcrypto": "^1.27.15",
|
|
@@ -116,5 +116,5 @@
|
|
|
116
116
|
"express": "^4.18.2",
|
|
117
117
|
"unzipper": "^0.10.11"
|
|
118
118
|
},
|
|
119
|
-
"gitHead": "
|
|
119
|
+
"gitHead": "9f47bf4e66af87c562f846e5470f45491506ab36"
|
|
120
120
|
}
|