@abtnode/core 1.16.45-beta-20250625-103530-e1f5b0b8 → 1.16.45-beta-20250626-115702-00b49b4c

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 CHANGED
@@ -9,6 +9,7 @@ const getFolderSize = require('@abtnode/util/lib/get-folder-size');
9
9
  const canPackageReadWrite = require('@abtnode/util/lib/can-pkg-rw');
10
10
  const { toDelegateAddress } = require('@arcblock/did-util');
11
11
  const { MONITOR_RECORD_INTERVAL_SEC, NODE_MODES } = require('@abtnode/constant');
12
+ const { getLauncherInfo } = require('@abtnode/auth/lib/launcher');
12
13
 
13
14
  const logger = require('@abtnode/logger')('@abtnode/core:api:node');
14
15
 
@@ -48,6 +49,12 @@ class NodeAPI {
48
49
  }
49
50
 
50
51
  try {
52
+ if (entity.registerUrl) {
53
+ const launcherInfo = await getLauncherInfo(entity.registerUrl);
54
+ entity.registerInfo = launcherInfo;
55
+ logger.info(`Updated launcher info from ${entity.registerUrl}`, launcherInfo);
56
+ }
57
+
51
58
  const updateResult = await this.state.updateNodeInfo(entity);
52
59
  return updateResult;
53
60
  } catch (error) {
@@ -35,6 +35,11 @@ class ConfigSynchronizer {
35
35
  async syncAppConfig(did, { serverVersion: inputServerVersion } = {}) {
36
36
  try {
37
37
  const app = isAppObj(did) ? did : await this.manager.getBlocklet(did);
38
+ const dataDir = getValueFromEnvironments(app.environments, 'BLOCKLET_DATA_DIR');
39
+ if (!dataDir) {
40
+ return;
41
+ }
42
+
38
43
  const serverVersion = inputServerVersion || (await this.states.node.read()).version;
39
44
  const env = {
40
45
  appId: app.appDid,
@@ -58,8 +63,6 @@ class ConfigSynchronizer {
58
63
 
59
64
  const config = { env, components };
60
65
 
61
- const dataDir = getValueFromEnvironments(app.environments, 'BLOCKLET_DATA_DIR');
62
-
63
66
  await fs.outputFile(path.join(dataDir, APP_CONFIG_FILE_PATH), JSON.stringify(config));
64
67
  } catch (error) {
65
68
  logger.error('sync app config failed', { error });
@@ -69,6 +72,11 @@ class ConfigSynchronizer {
69
72
  async syncComponentConfig(did, rootDid, { serverSk }) {
70
73
  try {
71
74
  const app = await this.manager.getBlocklet(rootDid);
75
+ const dataDir = getValueFromEnvironments(app.environments, 'BLOCKLET_DATA_DIR');
76
+ if (!dataDir) {
77
+ return;
78
+ }
79
+
72
80
  const component = findComponentByIdV2(app, did);
73
81
 
74
82
  const hasResources = !!component.meta.resource?.bundles?.length;
@@ -84,8 +92,6 @@ class ConfigSynchronizer {
84
92
  component,
85
93
  });
86
94
 
87
- const dataDir = getValueFromEnvironments(app.environments, 'BLOCKLET_DATA_DIR');
88
-
89
95
  await fs.outputFile(
90
96
  path.join(dataDir, APP_CONFIG_DIR, component.meta.did, COMPONENT_ENV_FILE_NAME),
91
97
  encrypt(JSON.stringify(env), componentApiKey, component.meta.did)
@@ -258,7 +258,7 @@ const RBAC_CONFIG = {
258
258
 
259
259
  // external user
260
260
  [SERVER_ROLES.EXTERNAL_BLOCKLET_CONTROLLER]: ['query_blocklets', 'mutate_blocklets'],
261
- [SERVER_ROLES.EXTERNAL_BLOCKLETS_MANAGER]: ['query_blocklets', 'mutate_blocklets'],
261
+ [SERVER_ROLES.EXTERNAL_BLOCKLETS_MANAGER]: ['query_blocklets', 'mutate_blocklets', 'query_node'],
262
262
  }),
263
263
  };
264
264
 
@@ -485,7 +485,7 @@ module.exports = Object.freeze({
485
485
  PROCESS_NAME_LOG_ROTATE: 'abt-node-log-rotate',
486
486
  PROCESS_NAME_EVENT_HUB: 'abt-node-event-hub',
487
487
 
488
- NODE_REGISTER_URL: 'https://install.arcblock.io/',
488
+ BLOCKLET_LAUNCHER_URL: 'https://launcher.arcblock.io/',
489
489
  WEB_WALLET_URL: 'https://web.abtwallet.io',
490
490
  TEST_STORE_URL,
491
491
  BLOCKLET_STORE_URL,
@@ -3,7 +3,7 @@ const yaml = require('js-yaml');
3
3
  const get = require('lodash/get');
4
4
  const set = require('lodash/set');
5
5
 
6
- const { NODE_REGISTER_URL, NODE_COMMAND_NAME, NODE_PACKAGE_NAME } = require('@abtnode/constant');
6
+ const { BLOCKLET_LAUNCHER_URL, NODE_COMMAND_NAME, NODE_PACKAGE_NAME } = require('@abtnode/constant');
7
7
  const canPackageReadWrite = require('@abtnode/util/lib/can-pkg-rw');
8
8
 
9
9
  module.exports = async ({ states, config, configFile, printInfo }) => {
@@ -14,7 +14,7 @@ module.exports = async ({ states, config, configFile, printInfo }) => {
14
14
  const info = await states.node.read();
15
15
 
16
16
  const updates = [
17
- { key: 'registerUrl', value: NODE_REGISTER_URL },
17
+ { key: 'registerUrl', value: BLOCKLET_LAUNCHER_URL },
18
18
  { key: 'autoUpgrade', value: canPackageReadWrite(NODE_COMMAND_NAME, NODE_PACKAGE_NAME) },
19
19
  ];
20
20
  updates.forEach(({ key, value }) => {
@@ -103,7 +103,6 @@ class AccessKeyState extends BaseState {
103
103
 
104
104
  // eslint-disable-next-line no-unused-vars
105
105
  async detail({ accessKeyId } = {}, context) {
106
- logger.info('get access key', { accessKeyId });
107
106
  if (!accessKeyId) {
108
107
  throw new CustomError(400, 'accessKeyId should not be empty');
109
108
  }
@@ -143,7 +142,7 @@ class AccessKeyState extends BaseState {
143
142
  }
144
143
 
145
144
  async refreshLastUsed(accessKeyId) {
146
- logger.info('update lastUsed', { accessKeyId });
145
+ logger.debug('update lastUsed', { accessKeyId });
147
146
  if (!accessKeyId) {
148
147
  throw new CustomError(400, 'accessKeyId should not be empty');
149
148
  }
@@ -454,6 +454,7 @@ const getComponentSystemEnvironments = (blocklet) => {
454
454
  BLOCKLET_REAL_DID: blocklet.env.id, // <appDid>/componentDid> e.g. xxxxx/xxxxx
455
455
  BLOCKLET_REAL_NAME: blocklet.env.name,
456
456
  BLOCKLET_COMPONENT_DID: blocklet.meta.did, // component meta did e.g. xxxxxx
457
+ BLOCKLET_COMPONENT_VERSION: blocklet.meta.version,
457
458
  BLOCKLET_DATA_DIR: blocklet.env.dataDir,
458
459
  BLOCKLET_LOG_DIR: blocklet.env.logsDir,
459
460
  BLOCKLET_CACHE_DIR: blocklet.env.cacheDir,
@@ -1520,6 +1521,54 @@ const needBlockletDownload = (blocklet, oldBlocklet) => {
1520
1521
  return get(oldBlocklet, 'meta.dist.integrity') !== get(blocklet, 'meta.dist.integrity');
1521
1522
  };
1522
1523
 
1524
+ const formatBlockletTheme = (rawTheme) => {
1525
+ let themeConfig = {};
1526
+
1527
+ if (rawTheme) {
1528
+ if (Array.isArray(rawTheme.concepts) && rawTheme.currentConceptId) {
1529
+ const concept = rawTheme.concepts.find((x) => x.id === rawTheme.currentConceptId);
1530
+ themeConfig = {
1531
+ ...concept.themeConfig,
1532
+ prefer: concept.prefer,
1533
+ };
1534
+ } else {
1535
+ // 兼容旧数据
1536
+ themeConfig = {
1537
+ light: rawTheme.light || {},
1538
+ dark: rawTheme.dark || {},
1539
+ common: rawTheme.common || {},
1540
+ prefer: rawTheme.prefer || 'system',
1541
+ };
1542
+ }
1543
+ }
1544
+
1545
+ const result = mergeWith(
1546
+ // 至少提供 palette 色板值(客户端会使用)
1547
+ cloneDeep({
1548
+ light: { palette: BLOCKLET_THEME_LIGHT.palette },
1549
+ dark: { palette: BLOCKLET_THEME_DARK.palette },
1550
+ prefer: 'system',
1551
+ }),
1552
+ themeConfig,
1553
+ // 数组值直接替换
1554
+ (_, srcValue) => {
1555
+ if (Array.isArray(srcValue)) {
1556
+ return srcValue;
1557
+ }
1558
+ return undefined;
1559
+ }
1560
+ );
1561
+
1562
+ // 保留原始数据,用于 settings 保存
1563
+ Object.defineProperty(result, 'raw', {
1564
+ value: rawTheme,
1565
+ enumerable: false,
1566
+ writable: false,
1567
+ });
1568
+
1569
+ return result;
1570
+ };
1571
+
1523
1572
  const _getBlocklet = async ({
1524
1573
  did,
1525
1574
  dataDirs,
@@ -1575,22 +1624,7 @@ const _getBlocklet = async ({
1575
1624
  }
1576
1625
 
1577
1626
  blocklet.settings.storeList = blocklet.settings.storeList || [];
1578
- blocklet.settings.theme = mergeWith(
1579
- cloneDeep({
1580
- light: { palette: BLOCKLET_THEME_LIGHT.palette },
1581
- dark: { palette: BLOCKLET_THEME_DARK.palette },
1582
- prefer: 'light',
1583
- }),
1584
- blocklet.settings.theme,
1585
- // 数组值直接替换
1586
- (_, srcValue) => {
1587
- if (Array.isArray(srcValue)) {
1588
- return srcValue;
1589
- }
1590
- return undefined;
1591
- }
1592
- );
1593
-
1627
+ blocklet.settings.theme = formatBlockletTheme(blocklet.settings.theme);
1594
1628
  blocklet.settings.languages = blocklet.settings.languages || [];
1595
1629
 
1596
1630
  // 移除第一个版本中 from 为 tmpl 的导航
@@ -1,4 +1,4 @@
1
- const { NODE_REGISTER_URL, BLOCKLET_STORE, BLOCKLET_STORE_DEV } = require('@abtnode/constant');
1
+ const { BLOCKLET_LAUNCHER_URL, BLOCKLET_STORE, BLOCKLET_STORE_DEV } = require('@abtnode/constant');
2
2
  const canPackageReadWrite = require('@abtnode/util/lib/can-pkg-rw');
3
3
 
4
4
  const getDefaultAutoUpgrade = () => {
@@ -25,7 +25,7 @@ const defaultNodeConfigs = {
25
25
  },
26
26
  ],
27
27
  },
28
- registerUrl: { getDefaultValue: () => NODE_REGISTER_URL },
28
+ registerUrl: { getDefaultValue: () => BLOCKLET_LAUNCHER_URL },
29
29
  };
30
30
 
31
31
  const lib = {
@@ -188,6 +188,7 @@ const consumeLauncherSession = async ({ params, blocklet }) => {
188
188
  * @param {object} param.node node instance
189
189
  * @param {string} param.sessionId blocklet setup session id
190
190
  * @param {boolean} param.justCreate just create owner, not set owner
191
+ * @param {boolean} param.autoStart auto initialize the blocklet, skip setup process
191
192
  * @param {string} [param.provider=LOGIN_PROVIDER.WALLET] provider
192
193
  * @param {object} param.context context
193
194
  * @param {string} param.context.visitorId visitorId
@@ -200,7 +201,14 @@ const consumeLauncherSession = async ({ params, blocklet }) => {
200
201
  * @param {string} param.context.device.clientName deviceClientName
201
202
  * @returns
202
203
  */
203
- const setupAppOwner = async ({ node, sessionId, justCreate = false, context, provider = LOGIN_PROVIDER.WALLET }) => {
204
+ const setupAppOwner = async ({
205
+ node,
206
+ sessionId,
207
+ justCreate = false,
208
+ autoStart = false,
209
+ context,
210
+ provider = LOGIN_PROVIDER.WALLET,
211
+ }) => {
204
212
  const session = await node.getSession({ id: sessionId });
205
213
  if (!session) {
206
214
  throw new Error(`Blocklet setup session not found in server: ${sessionId}`);
@@ -345,7 +353,7 @@ const setupAppOwner = async ({ node, sessionId, justCreate = false, context, pro
345
353
  elevated: true,
346
354
  });
347
355
 
348
- if (justCreate) {
356
+ if (justCreate || autoStart) {
349
357
  await node.setBlockletInitialized({ did: appDid, owner: { did: ownerDid, pk: ownerPk } });
350
358
  } else {
351
359
  await node.setBlockletOwner({ did: appDid, owner: { did: ownerDid, pk: ownerPk } });
@@ -377,6 +385,20 @@ const setupAppOwner = async ({ node, sessionId, justCreate = false, context, pro
377
385
 
378
386
  logger.info('created user session', { appDid, ownerDid, userSession });
379
387
 
388
+ // FIXME: this always throw error
389
+ // if (autoStart) {
390
+ // node
391
+ // .startBlocklet({
392
+ // did: appDid,
393
+ // checkHealthImmediately: false,
394
+ // throwOnError: true,
395
+ // atomic: false,
396
+ // })
397
+ // .catch((error) => {
398
+ // logger.error('blocklet auto start failed', { error, appDid });
399
+ // });
400
+ // }
401
+
380
402
  return {
381
403
  session,
382
404
  blocklet,
@@ -21,7 +21,7 @@ const nodeInfoSchema = Joi.object({
21
21
  .messages({ zh: { 'string.empty': '描述不能为空' }, en: { 'string.empty': 'Description cannot be empty' } }),
22
22
  registerUrl: Joi.string()
23
23
  .uri({ scheme: [/https?/] })
24
- .label('register url')
24
+ .label('launcher url')
25
25
  .allow('')
26
26
  .optional()
27
27
  .messages({
@@ -147,11 +147,49 @@ const muiThemeSchema = Joi.object({
147
147
  components: componentsSchema.optional(),
148
148
  }).options({ allowUnknown: true, stripUnknown: true });
149
149
 
150
+ const editorStateSchema = Joi.object({
151
+ colors: Joi.object()
152
+ .pattern(
153
+ Joi.string(),
154
+ Joi.object({
155
+ isLocked: Joi.boolean().required(),
156
+ })
157
+ )
158
+ .optional(),
159
+ typography: Joi.object()
160
+ .pattern(
161
+ Joi.string(),
162
+ Joi.object({
163
+ isLocked: Joi.boolean().required(),
164
+ })
165
+ )
166
+ .optional(),
167
+ styles: Joi.object()
168
+ .pattern(
169
+ Joi.string(),
170
+ Joi.object({
171
+ isLocked: Joi.boolean().required(),
172
+ })
173
+ )
174
+ .optional(),
175
+ }).options({ allowUnknown: true, stripUnknown: true });
176
+
177
+ const conceptSchema = Joi.object({
178
+ id: Joi.string().required(),
179
+ name: Joi.string().required(),
180
+ mode: Joi.string().valid('light', 'dark').required(),
181
+ prefer: Joi.string().valid('light', 'dark', 'system').required(),
182
+ themeConfig: Joi.object({
183
+ light: muiThemeSchema.required(),
184
+ dark: muiThemeSchema.required(),
185
+ common: muiThemeSchema.required(),
186
+ }).required(),
187
+ editor: editorStateSchema.required(),
188
+ }).options({ allowUnknown: true, stripUnknown: true });
189
+
150
190
  const blockletThemeSchema = Joi.object({
151
- common: muiThemeSchema.required(),
152
- light: muiThemeSchema.required(),
153
- dark: muiThemeSchema.required(),
154
- prefer: Joi.string().valid('light', 'dark', 'system').default('light'),
191
+ concepts: Joi.array().items(conceptSchema).required(),
192
+ currentConceptId: Joi.string().required(),
155
193
  }).options({ allowUnknown: true, stripUnknown: true });
156
194
 
157
195
  module.exports = {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.16.45-beta-20250625-103530-e1f5b0b8",
6
+ "version": "1.16.45-beta-20250626-115702-00b49b4c",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,22 +19,22 @@
19
19
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
20
20
  "license": "Apache-2.0",
21
21
  "dependencies": {
22
- "@abtnode/analytics": "1.16.45-beta-20250625-103530-e1f5b0b8",
23
- "@abtnode/auth": "1.16.45-beta-20250625-103530-e1f5b0b8",
24
- "@abtnode/certificate-manager": "1.16.45-beta-20250625-103530-e1f5b0b8",
25
- "@abtnode/client": "1.16.45-beta-20250625-103530-e1f5b0b8",
26
- "@abtnode/constant": "1.16.45-beta-20250625-103530-e1f5b0b8",
27
- "@abtnode/cron": "1.16.45-beta-20250625-103530-e1f5b0b8",
28
- "@abtnode/db-cache": "1.16.45-beta-20250625-103530-e1f5b0b8",
29
- "@abtnode/docker-utils": "1.16.45-beta-20250625-103530-e1f5b0b8",
30
- "@abtnode/logger": "1.16.45-beta-20250625-103530-e1f5b0b8",
31
- "@abtnode/models": "1.16.45-beta-20250625-103530-e1f5b0b8",
32
- "@abtnode/queue": "1.16.45-beta-20250625-103530-e1f5b0b8",
33
- "@abtnode/rbac": "1.16.45-beta-20250625-103530-e1f5b0b8",
34
- "@abtnode/router-provider": "1.16.45-beta-20250625-103530-e1f5b0b8",
35
- "@abtnode/static-server": "1.16.45-beta-20250625-103530-e1f5b0b8",
36
- "@abtnode/timemachine": "1.16.45-beta-20250625-103530-e1f5b0b8",
37
- "@abtnode/util": "1.16.45-beta-20250625-103530-e1f5b0b8",
22
+ "@abtnode/analytics": "1.16.45-beta-20250626-115702-00b49b4c",
23
+ "@abtnode/auth": "1.16.45-beta-20250626-115702-00b49b4c",
24
+ "@abtnode/certificate-manager": "1.16.45-beta-20250626-115702-00b49b4c",
25
+ "@abtnode/client": "1.16.45-beta-20250626-115702-00b49b4c",
26
+ "@abtnode/constant": "1.16.45-beta-20250626-115702-00b49b4c",
27
+ "@abtnode/cron": "1.16.45-beta-20250626-115702-00b49b4c",
28
+ "@abtnode/db-cache": "1.16.45-beta-20250626-115702-00b49b4c",
29
+ "@abtnode/docker-utils": "1.16.45-beta-20250626-115702-00b49b4c",
30
+ "@abtnode/logger": "1.16.45-beta-20250626-115702-00b49b4c",
31
+ "@abtnode/models": "1.16.45-beta-20250626-115702-00b49b4c",
32
+ "@abtnode/queue": "1.16.45-beta-20250626-115702-00b49b4c",
33
+ "@abtnode/rbac": "1.16.45-beta-20250626-115702-00b49b4c",
34
+ "@abtnode/router-provider": "1.16.45-beta-20250626-115702-00b49b4c",
35
+ "@abtnode/static-server": "1.16.45-beta-20250626-115702-00b49b4c",
36
+ "@abtnode/timemachine": "1.16.45-beta-20250626-115702-00b49b4c",
37
+ "@abtnode/util": "1.16.45-beta-20250626-115702-00b49b4c",
38
38
  "@arcblock/did": "1.20.14",
39
39
  "@arcblock/did-auth": "1.20.14",
40
40
  "@arcblock/did-ext": "1.20.14",
@@ -45,14 +45,14 @@
45
45
  "@arcblock/pm2-events": "^0.0.5",
46
46
  "@arcblock/validator": "1.20.14",
47
47
  "@arcblock/vc": "1.20.14",
48
- "@blocklet/constant": "1.16.45-beta-20250625-103530-e1f5b0b8",
48
+ "@blocklet/constant": "1.16.45-beta-20250626-115702-00b49b4c",
49
49
  "@blocklet/did-space-js": "^1.0.62",
50
- "@blocklet/env": "1.16.45-beta-20250625-103530-e1f5b0b8",
50
+ "@blocklet/env": "1.16.45-beta-20250626-115702-00b49b4c",
51
51
  "@blocklet/error": "^0.2.5",
52
- "@blocklet/meta": "1.16.45-beta-20250625-103530-e1f5b0b8",
53
- "@blocklet/resolver": "1.16.45-beta-20250625-103530-e1f5b0b8",
54
- "@blocklet/sdk": "1.16.45-beta-20250625-103530-e1f5b0b8",
55
- "@blocklet/store": "1.16.45-beta-20250625-103530-e1f5b0b8",
52
+ "@blocklet/meta": "1.16.45-beta-20250626-115702-00b49b4c",
53
+ "@blocklet/resolver": "1.16.45-beta-20250626-115702-00b49b4c",
54
+ "@blocklet/sdk": "1.16.45-beta-20250626-115702-00b49b4c",
55
+ "@blocklet/store": "1.16.45-beta-20250626-115702-00b49b4c",
56
56
  "@blocklet/theme": "^2.13.70",
57
57
  "@fidm/x509": "^1.2.1",
58
58
  "@ocap/mcrypto": "1.20.14",
@@ -116,5 +116,5 @@
116
116
  "jest": "^29.7.0",
117
117
  "unzipper": "^0.10.11"
118
118
  },
119
- "gitHead": "68ba563213161265ceb38eaec06d43454a341f48"
119
+ "gitHead": "8a70f88f034e2926185d4d0b9503ab8430a772a1"
120
120
  }