@abtnode/core 1.16.16-beta-e038cde7 → 1.16.16-beta-d6c5ed65

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/team.js CHANGED
@@ -278,6 +278,7 @@ class TeamAPI extends EventEmitter {
278
278
  'tags',
279
279
  // oauth relate fields
280
280
  'sourceProvider',
281
+ 'sourceAppPid',
281
282
  'connectedAccounts',
282
283
  ])
283
284
  // eslint-disable-next-line function-paren-newline
@@ -6,15 +6,26 @@ const { BLOCKLET_CONFIGURABLE_KEY } = require('@blocklet/constant');
6
6
  const removeDeletedMetaConfigs = (oldConfigs, newConfigs) =>
7
7
  oldConfigs.filter((old) => newConfigs.some(({ key, name }) => [key, name].includes(old.key)));
8
8
 
9
+ /**
10
+ * 从 blocklet.yml:environment 中导入配置:配置项字段是 name
11
+ * 主动配置:配置项字段是 key
12
+ *
13
+ * 自定义配置(customConfigs): 配置项的 custom 为 true
14
+ * 系统配置(appConfigs): 系统保留的配置项名,且 custom 为 false
15
+ * 组件配置(metaConfigs): 配置项的 custom 为 false, 且不是系统保留的配置项名
16
+ * 如果从 blocklet.yml 中导入组件配置,会删除已经删除的配置项
17
+ */
9
18
  const mergeConfigs = ({ old: oldConfigs, cur: newConfigs = [], did = '', dek = '' }) => {
10
19
  const enableSecurity = dek && did;
11
- const isUpdatingCustomConfig = newConfigs.every((x) => x.key);
20
+
21
+ const isConfigFromMeta = newConfigs.every((x) => x.key);
12
22
 
13
23
  const customConfigs = (oldConfigs || []).filter((x) => x.custom);
14
24
  const appConfigs = (oldConfigs || []).filter((x) => !x.custom && !!BLOCKLET_CONFIGURABLE_KEY[x.key]);
15
25
 
16
26
  const allMetaConfigs = (oldConfigs || []).filter((x) => !x.custom && !BLOCKLET_CONFIGURABLE_KEY[x.key]);
17
- const metaConfigs = isUpdatingCustomConfig ? allMetaConfigs : removeDeletedMetaConfigs(allMetaConfigs, newConfigs);
27
+
28
+ const metaConfigs = isConfigFromMeta ? allMetaConfigs : removeDeletedMetaConfigs(allMetaConfigs, newConfigs);
18
29
 
19
30
  // oldConfig 表示从数据库中可以用的字段
20
31
  const oldConfig = [...metaConfigs, ...appConfigs, ...customConfigs].reduce((acc, x) => {
@@ -64,7 +64,7 @@ class ConfigSynchronizer {
64
64
  const component = findComponentByIdV2(app, did);
65
65
  const env = {
66
66
  ...component.configObj,
67
- ...getSharedConfigObj(component, [app]),
67
+ ...getSharedConfigObj(app, component),
68
68
  };
69
69
 
70
70
  const componentApiKey = getComponentApiKey({
@@ -115,7 +115,6 @@ const {
115
115
  filterDuplicateComponents,
116
116
  getBundleDir,
117
117
  getBlocklet,
118
- ensureEnvDefault,
119
118
  getConfigFromPreferences,
120
119
  validateAppConfig,
121
120
  checkDuplicateMountPoint,
@@ -132,6 +131,9 @@ const {
132
131
  ensureAppPortsNotOccupied,
133
132
  getComponentNamesWithVersion,
134
133
  updateDidDocument: updateBlockletDocument,
134
+ getAppConfigsFromComponent,
135
+ removeAppConfigsFromComponent,
136
+ getConfigsFromInput,
135
137
  } = require('../../util/blocklet');
136
138
  const { getDidDomainForBlocklet } = require('../../util/get-domain-for-blocklet');
137
139
  const states = require('../../states');
@@ -472,7 +474,7 @@ class DiskBlockletManager extends BaseBlockletManager {
472
474
  // check required config
473
475
  for (const component of blocklet1.children) {
474
476
  if (!shouldSkipComponent(component.meta.did, componentDids)) {
475
- const missingProps = getComponentMissingConfigs(component, [blocklet1]);
477
+ const missingProps = getComponentMissingConfigs(component, blocklet1);
476
478
  if (missingProps.length) {
477
479
  throw new Error(
478
480
  `Missing required configuration to start ${component.meta.title}: ${missingProps
@@ -931,7 +933,13 @@ class DiskBlockletManager extends BaseBlockletManager {
931
933
  fs.removeSync(path.join(app.env.dataDir, APP_CONFIG_DIR, child.meta.did, COMPONENT_ENV_FILE_NAME));
932
934
  if (keepData === false) {
933
935
  fs.removeSync(dataDir);
936
+
937
+ const componentEnvs = await states.blockletExtras.getConfigs([app.meta.did, child.meta.did]);
934
938
  await states.blockletExtras.delConfigs([app.meta.did, child.meta.did]);
939
+
940
+ // remove app configs if no component use it
941
+ const tmpApp = await this.getBlocklet(rootDid);
942
+ await removeAppConfigsFromComponent(componentEnvs, tmpApp, states.blockletExtras);
935
943
  }
936
944
 
937
945
  const newBlocklet = await this.getBlocklet(rootDid);
@@ -1149,9 +1157,17 @@ class DiskBlockletManager extends BaseBlockletManager {
1149
1157
  }
1150
1158
  await validateAppConfig(x, states);
1151
1159
  } else if (!BLOCKLET_CONFIGURABLE_KEY[x.key] && !isPreferenceKey(x)) {
1152
- if (!(blocklet.meta.environments || []).some((y) => y.name === x.key)) {
1160
+ const hasEnvInMeta = (b) => (b.meta.environments || []).some((y) => y.name === x.key);
1161
+ if (!hasEnvInMeta(blocklet)) {
1153
1162
  // forbid unknown format key
1154
- throw new Error(`unknown format key: ${x.key}`);
1163
+ if (
1164
+ // config should in component.meta.environments
1165
+ childDid ||
1166
+ // config should in app.meta.environments and or in one of component.meta.environments
1167
+ !(blocklet.children || []).some(hasEnvInMeta)
1168
+ ) {
1169
+ throw new Error(`unknown format key: ${x.key}`);
1170
+ }
1155
1171
  }
1156
1172
  }
1157
1173
 
@@ -1183,7 +1199,18 @@ class DiskBlockletManager extends BaseBlockletManager {
1183
1199
  Object.assign(blocklet.configObj, configObj);
1184
1200
 
1185
1201
  // update db
1186
- await states.blockletExtras.setConfigs([rootMetaDid, childDid].filter(Boolean), newConfigs);
1202
+ if (childDid) {
1203
+ const { sharedConfigs, selfConfigs } = getConfigsFromInput(newConfigs, blocklet.configs);
1204
+
1205
+ if (sharedConfigs.length) {
1206
+ await states.blockletExtras.setConfigs([rootMetaDid], sharedConfigs);
1207
+ }
1208
+ if (selfConfigs.length) {
1209
+ await states.blockletExtras.setConfigs([rootMetaDid, childDid], selfConfigs);
1210
+ }
1211
+ } else {
1212
+ await states.blockletExtras.setConfigs([rootMetaDid], newConfigs);
1213
+ }
1187
1214
 
1188
1215
  if (willAppSkChange) {
1189
1216
  const info = await states.node.read();
@@ -2693,17 +2720,19 @@ class DiskBlockletManager extends BaseBlockletManager {
2693
2720
  logger.info('start migration on upgrading', { did, componentDids });
2694
2721
  {
2695
2722
  const oldVersions = {};
2696
- forEachBlockletSync(oldBlocklet, (b, { id }) => {
2697
- oldVersions[id] = b.meta.version;
2723
+ forEachComponentV2Sync(oldBlocklet, (b) => {
2724
+ if (componentDids.includes(b.meta.did)) {
2725
+ oldVersions[b.meta.did] = b.meta.version;
2726
+ }
2698
2727
  });
2699
2728
  const nodeEnvironments = await states.node.getEnvironments();
2700
- const runMigration = async (b, { id, ancestors }) => {
2729
+ const runMigration = async (b) => {
2701
2730
  try {
2702
2731
  await runMigrationScripts({
2703
2732
  blocklet: b,
2704
2733
  appDir: b.env.appDir,
2705
- env: getRuntimeEnvironments(b, nodeEnvironments, ancestors),
2706
- oldVersion: oldVersions[id],
2734
+ env: getRuntimeEnvironments(b, nodeEnvironments, [blocklet]),
2735
+ oldVersion: oldVersions[b.meta.did],
2707
2736
  newVersion: b.meta.version,
2708
2737
  ...getHooksOutputFiles(b),
2709
2738
  });
@@ -2713,7 +2742,7 @@ class DiskBlockletManager extends BaseBlockletManager {
2713
2742
  throw error;
2714
2743
  }
2715
2744
  };
2716
- await forEachBlocklet(blocklet, runMigration, { parallel: true, concurrencyLimit: 2 });
2745
+ await forEachComponentV2(blocklet, runMigration, { parallel: true, concurrencyLimit: 2 });
2717
2746
  }
2718
2747
  logger.info('done migration on upgrading', { did, componentDids });
2719
2748
 
@@ -2994,38 +3023,40 @@ class DiskBlockletManager extends BaseBlockletManager {
2994
3023
  async _setConfigsFromMeta(did, childDid) {
2995
3024
  const blocklet = await getBlocklet({ states, dataDirs: this.dataDirs, did });
2996
3025
 
2997
- if (!childDid) {
2998
- await forEachBlocklet(blocklet, async (b, { ancestors }) => {
2999
- const environments = [...get(b.meta, 'environments', []), ...getConfigFromPreferences(b)];
3026
+ const setConfig = async (app, component) => {
3027
+ const b = component || app;
3028
+ const environments = [...get(b.meta, 'environments', []), ...getConfigFromPreferences(b)];
3000
3029
 
3001
- // remove default if ancestors has a value
3002
- ensureEnvDefault(environments, ancestors);
3030
+ // write configs to db
3031
+ await states.blockletExtras.setConfigs([app.meta.did, component?.meta?.did].filter(Boolean), environments);
3003
3032
 
3004
- // write configs to db
3005
- await states.blockletExtras.setConfigs([...ancestors.map((x) => x.meta.did), b.meta.did], environments);
3033
+ if (component) {
3034
+ const envsInApp = await states.blockletExtras.getConfigs([app.appPid]);
3035
+ const envsInComponent = await states.blockletExtras.getConfigs([app.meta.did, component.meta.did]);
3006
3036
 
3007
- // chain config
3008
- await this._ensureAppChainConfig(
3009
- blocklet.meta.did,
3010
- environments.map((x) => ({ key: x.name, value: x.default })),
3011
- { force: false }
3012
- );
3037
+ const configs = getAppConfigsFromComponent({ environments }, envsInApp, envsInComponent);
3038
+ if (configs.length) {
3039
+ await states.blockletExtras.setConfigs(app.meta.did, configs);
3040
+ }
3041
+ }
3042
+
3043
+ // chain config
3044
+ await this._ensureAppChainConfig(
3045
+ blocklet.appPid,
3046
+ environments.map((x) => ({ key: x.name, value: x.default })),
3047
+ { force: false }
3048
+ );
3049
+ };
3050
+
3051
+ if (!childDid) {
3052
+ await setConfig(blocklet);
3053
+ await forEachComponentV2(blocklet, async (component) => {
3054
+ await setConfig(blocklet, component);
3013
3055
  });
3014
3056
  } else {
3015
- const child = blocklet.children.find((x) => x.meta.did === childDid);
3016
- await forEachBlocklet(child, async (b, { ancestors }) => {
3017
- await states.blockletExtras.setConfigs(
3018
- [blocklet.meta.did, ...ancestors.map((x) => x.meta.did), b.meta.did],
3019
- [...get(b.meta, 'environments', []), ...getConfigFromPreferences(child)]
3020
- );
3057
+ const component = blocklet.children.find((x) => x.meta.did === childDid);
3021
3058
 
3022
- // chain config
3023
- await this._ensureAppChainConfig(
3024
- blocklet.meta.did,
3025
- get(b.meta, 'environments', []).map((x) => ({ key: x.name, value: x.default })),
3026
- { force: false }
3027
- );
3028
- });
3059
+ await setConfig(blocklet, component);
3029
3060
  }
3030
3061
  }
3031
3062
 
@@ -3859,28 +3890,79 @@ class FederatedBlockletManager extends DiskBlockletManager {
3859
3890
  logger.error('Failed to post audit res to member-site', { error, did, url: postUrl });
3860
3891
  throw error;
3861
3892
  }
3893
+ await this.syncFederated({
3894
+ did,
3895
+ data: {
3896
+ sites: federated.sites,
3897
+ },
3898
+ });
3899
+ return newState;
3900
+ }
3901
+
3902
+ async syncFederated({ did, data = {} } = {}) {
3903
+ const blocklet = await this.getBlocklet(did);
3904
+
3905
+ const federated = defaults(cloneDeep(blocklet.settings.federated || {}), {
3906
+ config: {},
3907
+ sites: [],
3908
+ });
3909
+
3910
+ const safeData = {};
3911
+ const { users, sites } = data;
3912
+ if (users && Array.isArray(users)) {
3913
+ safeData.users = users.map((item) =>
3914
+ pick(item, ['did', 'pk', 'fullName', 'avatar', 'email', 'connectedAccount', 'action'])
3915
+ );
3916
+ }
3917
+
3918
+ if (sites && Array.isArray(sites)) {
3919
+ safeData.sites = sites.map((item) =>
3920
+ pick(item, [
3921
+ 'appId',
3922
+ 'appPid',
3923
+ 'aliasDid',
3924
+ 'appName',
3925
+ 'appDescription',
3926
+ 'appUrl',
3927
+ 'aliasDomain',
3928
+ 'appLogo',
3929
+ 'appLogoRect',
3930
+ 'appliedAt',
3931
+ 'did',
3932
+ 'pk',
3933
+ 'serverId',
3934
+ 'serverVersion',
3935
+ 'version',
3936
+ 'isMaster',
3937
+ 'status',
3938
+ ])
3939
+ );
3940
+ }
3941
+
3942
+ const nodeInfo = await states.node.read();
3943
+ const { permanentWallet } = getBlockletInfo(blocklet, nodeInfo.sk);
3944
+
3862
3945
  const waitingList = federated.sites
3863
3946
  .filter((item) => item.appId !== federated.config.appId)
3864
3947
  .map((item) => {
3865
3948
  return limitSync(async () => {
3866
- const url = `${item.appUrl}/${WELLKNOWN_SERVICE_PATH_PREFIX}/api/federated/sync`;
3949
+ const url = `${item.appUrl}${WELLKNOWN_SERVICE_PATH_PREFIX}/api/federated/sync`;
3867
3950
  try {
3868
- // NOTICE: 即使通知某个 member 失败了,也不影响其他 member 接收同步结果
3951
+ // NOTICE: 即使通知某个站点失败了,也不影响其他站点接收同步结果
3869
3952
  await pRetry(
3870
3953
  () =>
3871
3954
  request.post(url, {
3872
3955
  signer: permanentWallet.address,
3873
- data: signV2(permanentWallet.address, permanentWallet.secretKey, { sites: federated.sites }),
3956
+ data: signV2(permanentWallet.address, permanentWallet.secretKey, safeData),
3874
3957
  }),
3875
3958
  { retries: 3 }
3876
3959
  );
3877
3960
  } catch (error) {
3878
- logger.warn('Failed to sync federated sites', { error, did, url, action: 'audit' });
3961
+ logger.warn('Failed to sync federated sites', { error, did, url, action: 'sync' });
3879
3962
  }
3880
3963
  });
3881
3964
  });
3882
3965
  await Promise.all(waitingList);
3883
- return newState;
3884
3966
  }
3885
3967
  }
3886
3968
 
@@ -1,6 +1,7 @@
1
1
  const path = require('path');
2
2
  const fs = require('fs-extra');
3
3
  const pick = require('lodash/pick');
4
+ const get = require('lodash/get');
4
5
  const pRetry = require('p-retry');
5
6
  const urlPathFriendly = require('@blocklet/meta/lib/url-path-friendly').default;
6
7
  const { slugify } = require('transliteration');
@@ -9,12 +10,7 @@ const { getChainClient } = require('@abtnode/util/lib/get-chain-client');
9
10
 
10
11
  const logger = require('@abtnode/logger')('@abtnode/core:migrate-application-to-struct-v2');
11
12
 
12
- const {
13
- forEachBlockletSync,
14
- getSharedConfigObj,
15
- getBlockletChainInfo,
16
- isInProgress,
17
- } = require('@blocklet/meta/lib/util');
13
+ const { forEachBlockletSync, getBlockletChainInfo, isInProgress } = require('@blocklet/meta/lib/util');
18
14
  const { SLOT_FOR_IP_DNS_SITE, MAIN_CHAIN_ENDPOINT } = require('@abtnode/constant');
19
15
 
20
16
  const {
@@ -33,6 +29,7 @@ const {
33
29
  BLOCKLET_CONFIGURABLE_KEY,
34
30
  BLOCKLET_META_FILE,
35
31
  BLOCKLET_UPLOADS_DIR,
32
+ CHAIN_PROP_MAP,
36
33
  } = require('@blocklet/constant');
37
34
  const { update: updateMetaFile } = require('@blocklet/meta/lib/file');
38
35
  const getBlockletWallet = require('@blocklet/meta/lib/wallet');
@@ -363,7 +360,55 @@ const migrateApplicationToStructV2 = async ({ did, appSk: newAppSk, context = {}
363
360
  configs: component.configs || [],
364
361
  });
365
362
 
366
- const sharedConfigObj = getSharedConfigObj(component, ancestors);
363
+ const getSharedConfigObj = () => {
364
+ const res = {};
365
+
366
+ if (!ancestors || !ancestors.length) {
367
+ return res;
368
+ }
369
+
370
+ for (let i = ancestors.length - 1; i >= 0; i--) {
371
+ const ancestor = ancestors[i];
372
+
373
+ if (Array.isArray(ancestor.configs)) {
374
+ // eslint-disable-next-line no-loop-func
375
+ ancestor.configs.forEach(({ key, value, secure, shared }) => {
376
+ if (res[key]) {
377
+ return;
378
+ }
379
+ if (!value || secure !== false || shared === false || BLOCKLET_CONFIGURABLE_KEY[key]) {
380
+ return;
381
+ }
382
+ const config = (component.configs || []).find((x) => x.key === key);
383
+
384
+ if (config && config.value) {
385
+ return;
386
+ }
387
+ res[key] = get(ancestor, `configObj.${key}`) || value;
388
+ });
389
+ }
390
+ }
391
+
392
+ // share blocklet app chain config
393
+ const ancestor = ancestors[0];
394
+ (ancestor.configs || []).forEach(({ key, value }) => {
395
+ if (
396
+ ![
397
+ BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_CHAIN_HOST,
398
+ BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_CHAIN_ID,
399
+ BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_CHAIN_TYPE,
400
+ ].includes(key)
401
+ ) {
402
+ return;
403
+ }
404
+
405
+ res[CHAIN_PROP_MAP[key]] = value;
406
+ });
407
+
408
+ return res;
409
+ };
410
+
411
+ const sharedConfigObj = getSharedConfigObj();
367
412
  if (sharedConfigObj) {
368
413
  Object.entries(sharedConfigObj).forEach(([key, value]) => {
369
414
  if (!extraData.configs.some((x) => x.key === key)) {
package/lib/index.js CHANGED
@@ -267,6 +267,7 @@ function ABTNode(options) {
267
267
  auditFederatedLogin: blockletManager.auditFederatedLogin.bind(blockletManager),
268
268
  configFederated: blockletManager.configFederated.bind(blockletManager),
269
269
  setFederated: blockletManager.setFederated.bind(blockletManager),
270
+ syncFederated: blockletManager.syncFederated.bind(blockletManager),
270
271
  configNotification: blockletManager.configNotification.bind(blockletManager),
271
272
  updateWhoCanAccess: blockletManager.updateWhoCanAccess.bind(blockletManager),
272
273
  updateAppSessionConfig: blockletManager.updateAppSessionConfig.bind(blockletManager),
@@ -344,7 +344,17 @@ class User extends ExtendBase {
344
344
  const exist = await this.getUser(user.did, { enableConnectedAccount: true });
345
345
 
346
346
  const updates = {
347
- ...pick(user, ['fullName', 'email', 'avatar', 'role', 'locale', 'extra', 'lastLoginIp', 'remark']),
347
+ ...pick(user, [
348
+ 'fullName',
349
+ 'email',
350
+ 'avatar',
351
+ 'role',
352
+ 'locale',
353
+ 'extra',
354
+ 'lastLoginIp',
355
+ 'remark',
356
+ 'sourceAppPid',
357
+ ]),
348
358
  lastLoginAt: now,
349
359
  passports: user.passport ? [{ ...user.passport, lastLoginAt: now }] : [],
350
360
  };
@@ -85,12 +85,12 @@ const {
85
85
  forEachComponentV2Sync,
86
86
  getSharedConfigObj,
87
87
  getComponentName,
88
- isEnvShareable,
89
88
  getBlockletAppIdList,
90
89
  getChainInfo,
91
90
  isInProgress,
92
91
  isRunning,
93
92
  hasStartEngine,
93
+ isEnvShareable,
94
94
  } = require('@blocklet/meta/lib/util');
95
95
  const { getComponentsInternalInfo } = require('@blocklet/meta/lib/blocklet');
96
96
  const { titleSchema, descriptionSchema, logoSchema } = require('@blocklet/meta/lib/schema');
@@ -419,7 +419,7 @@ const getRuntimeEnvironments = (blocklet, nodeEnvironments, ancestors) => {
419
419
 
420
420
  const env = {
421
421
  ...blocklet.configObj,
422
- ...getSharedConfigObj(blocklet, ancestors),
422
+ ...getSharedConfigObj((ancestors || [])[0], blocklet),
423
423
  ...blocklet.environmentObj,
424
424
  ...devEnvironments,
425
425
  BLOCKLET_WEB_PORTS: JSON.stringify(ports),
@@ -1293,35 +1293,6 @@ const getBlocklet = async ({
1293
1293
  return blocklet;
1294
1294
  };
1295
1295
 
1296
- /**
1297
- * this function has side effect on environments
1298
- */
1299
- const ensureEnvDefault = (environments, ancestors) => {
1300
- // remove default if ancestors has a value
1301
- const envMap = environments.reduce((o, env) => {
1302
- o[env.name] = env;
1303
- return o;
1304
- }, {});
1305
-
1306
- for (let i = ancestors.length - 1; i >= 0; i--) {
1307
- const ancestor = ancestors[i];
1308
- const aEnvironments = get(ancestor.meta, 'environments', []);
1309
- const aEnv = aEnvironments.find((x) => envMap[x.name]);
1310
-
1311
- if (!isEnvShareable(aEnv)) {
1312
- break;
1313
- }
1314
-
1315
- const env = envMap[aEnv.name];
1316
- if (isEnvShareable(env) && aEnv.default) {
1317
- env.default = '';
1318
- break;
1319
- }
1320
- }
1321
-
1322
- return environments;
1323
- };
1324
-
1325
1296
  const fromProperty2Config = (properties = {}, result) => {
1326
1297
  Object.keys(properties).forEach((key) => {
1327
1298
  const prop = properties[key];
@@ -1335,7 +1306,7 @@ const fromProperty2Config = (properties = {}, result) => {
1335
1306
  name: `${BLOCKLET_PREFERENCE_PREFIX}${key}`,
1336
1307
  required: prop.required || false,
1337
1308
  secure,
1338
- shared: !secure,
1309
+ shared: secure ? false : prop.shared,
1339
1310
  });
1340
1311
  }
1341
1312
  });
@@ -1876,6 +1847,61 @@ const updateDidDocument = async ({ blocklet, nodeInfo }) => {
1876
1847
  });
1877
1848
  };
1878
1849
 
1850
+ const getAppConfigsFromComponent = (meta, configsInApp = [], configsInComponent = []) => {
1851
+ const configs = [];
1852
+ for (const configInMeta of meta?.environments || []) {
1853
+ if (isEnvShareable(configInMeta)) {
1854
+ const configInApp = (configsInApp || []).find((x) => x.key === configInMeta.name);
1855
+ if (!configInApp) {
1856
+ const configInComponent = configsInComponent.find((y) => y.key === configInMeta.name);
1857
+ if (configInComponent && isEnvShareable(configInComponent)) {
1858
+ configs.push(configInComponent);
1859
+ }
1860
+ }
1861
+ }
1862
+ }
1863
+ return configs;
1864
+ };
1865
+
1866
+ const getConfigsFromInput = (configs = [], oldConfigs = []) => {
1867
+ const sharedConfigs = [];
1868
+ const selfConfigs = [];
1869
+
1870
+ configs.forEach((config) => {
1871
+ const oldConfig = oldConfigs.find((y) => y.key === config.key);
1872
+ if (isEnvShareable(config) || isEnvShareable(oldConfig)) {
1873
+ sharedConfigs.push(config);
1874
+ } else {
1875
+ selfConfigs.push(config);
1876
+ }
1877
+ });
1878
+
1879
+ return { sharedConfigs, selfConfigs };
1880
+ };
1881
+
1882
+ // remove app configs if no component use it
1883
+ const removeAppConfigsFromComponent = async (componentConfigs, app, blockletExtraState) => {
1884
+ const appConfigs = app.configs || [];
1885
+ const remainedConfigs = [].concat(...(app.children || []).map((x) => x.configs || []));
1886
+ const removedAppConfigs = [];
1887
+
1888
+ componentConfigs.forEach((config) => {
1889
+ const appConfig = appConfigs.find((x) => x.key === config.key);
1890
+ if (
1891
+ appConfig &&
1892
+ !appConfig.custom &&
1893
+ !(app.meta.environments || []).find((x) => x.name === config.key) &&
1894
+ !remainedConfigs.find((x) => x.key === config.key && isEnvShareable(x))
1895
+ ) {
1896
+ removedAppConfigs.push({ key: appConfig.key, value: undefined });
1897
+ }
1898
+ });
1899
+
1900
+ if (removedAppConfigs.length) {
1901
+ await blockletExtraState.setConfigs(app.meta.did, removedAppConfigs);
1902
+ }
1903
+ };
1904
+
1879
1905
  module.exports = {
1880
1906
  updateBlockletFallbackLogo,
1881
1907
  forEachBlocklet,
@@ -1914,7 +1940,6 @@ module.exports = {
1914
1940
  needBlockletDownload,
1915
1941
  ensureMeta,
1916
1942
  getBlocklet,
1917
- ensureEnvDefault,
1918
1943
  getConfigFromPreferences,
1919
1944
  createDataArchive,
1920
1945
  validateAppConfig,
@@ -1941,4 +1966,7 @@ module.exports = {
1941
1966
  updateDidDocument,
1942
1967
  getSlpDid,
1943
1968
  shouldEnableSlpDomain,
1969
+ getAppConfigsFromComponent,
1970
+ removeAppConfigsFromComponent,
1971
+ getConfigsFromInput,
1944
1972
  };
@@ -35,6 +35,7 @@ const loginSchema = Joi.object({
35
35
  remark: Joi.string().empty(''),
36
36
  lastLoginIp: Joi.string().empty(''),
37
37
  passport: passportSchema.optional(),
38
+ sourceAppPid: Joi.string().empty(null),
38
39
  connectedAccount: Joi.alternatives()
39
40
  .try(connectedAccountSchema.required(), Joi.array().items(connectedAccountSchema).min(1).sparse(true))
40
41
  .required(),
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.16.16-beta-e038cde7",
6
+ "version": "1.16.16-beta-d6c5ed65",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,19 +19,19 @@
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.16-beta-e038cde7",
23
- "@abtnode/auth": "1.16.16-beta-e038cde7",
24
- "@abtnode/certificate-manager": "1.16.16-beta-e038cde7",
25
- "@abtnode/constant": "1.16.16-beta-e038cde7",
26
- "@abtnode/cron": "1.16.16-beta-e038cde7",
27
- "@abtnode/logger": "1.16.16-beta-e038cde7",
28
- "@abtnode/models": "1.16.16-beta-e038cde7",
29
- "@abtnode/queue": "1.16.16-beta-e038cde7",
30
- "@abtnode/rbac": "1.16.16-beta-e038cde7",
31
- "@abtnode/router-provider": "1.16.16-beta-e038cde7",
32
- "@abtnode/static-server": "1.16.16-beta-e038cde7",
33
- "@abtnode/timemachine": "1.16.16-beta-e038cde7",
34
- "@abtnode/util": "1.16.16-beta-e038cde7",
22
+ "@abtnode/analytics": "1.16.16-beta-d6c5ed65",
23
+ "@abtnode/auth": "1.16.16-beta-d6c5ed65",
24
+ "@abtnode/certificate-manager": "1.16.16-beta-d6c5ed65",
25
+ "@abtnode/constant": "1.16.16-beta-d6c5ed65",
26
+ "@abtnode/cron": "1.16.16-beta-d6c5ed65",
27
+ "@abtnode/logger": "1.16.16-beta-d6c5ed65",
28
+ "@abtnode/models": "1.16.16-beta-d6c5ed65",
29
+ "@abtnode/queue": "1.16.16-beta-d6c5ed65",
30
+ "@abtnode/rbac": "1.16.16-beta-d6c5ed65",
31
+ "@abtnode/router-provider": "1.16.16-beta-d6c5ed65",
32
+ "@abtnode/static-server": "1.16.16-beta-d6c5ed65",
33
+ "@abtnode/timemachine": "1.16.16-beta-d6c5ed65",
34
+ "@abtnode/util": "1.16.16-beta-d6c5ed65",
35
35
  "@arcblock/did": "1.18.89",
36
36
  "@arcblock/did-auth": "1.18.89",
37
37
  "@arcblock/did-ext": "^1.18.89",
@@ -42,12 +42,12 @@
42
42
  "@arcblock/pm2-events": "^0.0.5",
43
43
  "@arcblock/validator": "^1.18.89",
44
44
  "@arcblock/vc": "1.18.89",
45
- "@blocklet/constant": "1.16.16-beta-e038cde7",
46
- "@blocklet/env": "1.16.16-beta-e038cde7",
47
- "@blocklet/meta": "1.16.16-beta-e038cde7",
48
- "@blocklet/resolver": "1.16.16-beta-e038cde7",
49
- "@blocklet/sdk": "1.16.16-beta-e038cde7",
50
- "@did-space/client": "^0.2.170",
45
+ "@blocklet/constant": "1.16.16-beta-d6c5ed65",
46
+ "@blocklet/env": "1.16.16-beta-d6c5ed65",
47
+ "@blocklet/meta": "1.16.16-beta-d6c5ed65",
48
+ "@blocklet/resolver": "1.16.16-beta-d6c5ed65",
49
+ "@blocklet/sdk": "1.16.16-beta-d6c5ed65",
50
+ "@did-space/client": "^0.2.171",
51
51
  "@fidm/x509": "^1.2.1",
52
52
  "@ocap/mcrypto": "1.18.89",
53
53
  "@ocap/util": "1.18.89",
@@ -100,5 +100,5 @@
100
100
  "jest": "^27.5.1",
101
101
  "unzipper": "^0.10.11"
102
102
  },
103
- "gitHead": "688b1c7ae0f6652094100c101f5d218266dd86ac"
103
+ "gitHead": "16f5632a7b86283381fa49acc4d2553c65cd2aa3"
104
104
  }