@abtnode/core 1.16.0-beta-b16cb035 → 1.16.0-beta-1d6c582e

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.
@@ -4,6 +4,7 @@ const fs = require('fs-extra');
4
4
  const path = require('path');
5
5
  const flat = require('flat');
6
6
  const get = require('lodash/get');
7
+ const uniq = require('lodash/uniq');
7
8
  const merge = require('lodash/merge');
8
9
  const pick = require('lodash/pick');
9
10
  const cloneDeep = require('lodash/cloneDeep');
@@ -989,7 +990,7 @@ class BlockletManager extends BaseBlockletManager {
989
990
  throw new Error('configs list is not an array');
990
991
  }
991
992
 
992
- const dids = Array.isArray(did) ? did : [did];
993
+ const dids = Array.isArray(did) ? uniq(did) : [did];
993
994
  const [rootDid, ...childDids] = dids;
994
995
  logger.info('config blocklet', { dids });
995
996
 
@@ -138,7 +138,7 @@ const diff = async ({ did, hashFiles: clientFiles, rootDid: inputRootDid, states
138
138
 
139
139
  const rootBlocklet = await states.blocklet.getBlocklet(rootDid);
140
140
  if (childDid && !rootBlocklet) {
141
- throw new Error('Root blocklet does not exist');
141
+ throw new Error(`Root blocklet does not exist: ${rootDid}`);
142
142
  }
143
143
 
144
144
  const state = childDid ? await (rootBlocklet.children || []).find((x) => x.meta.did === childDid) : rootBlocklet;
@@ -250,7 +250,7 @@ const migrateApplicationToStructV2 = async ({ did, appSk: newAppSk, context = {}
250
250
  // add root component to blockletData
251
251
  const { source, deployedFrom } = component;
252
252
  let bundleSource;
253
- if (source === BlockletSource.store) {
253
+ if (source === BlockletSource.registry && deployedFrom && component.meta.bundleName) {
254
254
  bundleSource = {
255
255
  store: component.deployedFrom,
256
256
  name: component.meta.bundleName,
@@ -325,16 +325,16 @@ const migrateApplicationToStructV2 = async ({ did, appSk: newAppSk, context = {}
325
325
  Object.entries(sharedConfigObj).forEach(([key, value]) => {
326
326
  if (!extraData.configs.some((x) => x.key === key)) {
327
327
  logger.info('add shared config to container configs', { did, key, value });
328
- extraData.configs.push({ key, value });
328
+ extraData.configs.push({ key, value, secure: false, shared: true });
329
329
  }
330
330
  });
331
331
  }
332
332
 
333
333
  // move component data dir
334
334
  const src = component.env.dataDir;
335
- const dist = path.join(dataDirSrc, component.meta.bundleName);
336
- if (src !== dist) {
337
- dataMoveList.push({ src: component.env.dataDir, dist: path.join(dataDirDist, component.meta.bundleName) });
335
+ const dist = path.join(dataDirDist, component.meta.bundleName);
336
+ if (fs.existsSync(src)) {
337
+ dataMoveList.push({ src, dist });
338
338
  }
339
339
  });
340
340
 
@@ -13,6 +13,7 @@ const {
13
13
  checkStructVersion,
14
14
  checkVersionCompatibility,
15
15
  validateBlocklet,
16
+ getFixedBundleSource,
16
17
  } = require('../../../util/blocklet');
17
18
 
18
19
  const check = async ({ did, states }) => {
@@ -24,7 +25,10 @@ const check = async ({ did, states }) => {
24
25
  const newChildren = [];
25
26
 
26
27
  for (const child of newBlocklet.children || []) {
27
- if (child.bundleSource) {
28
+ // There may be dirty data without bundleSource but with source and deployedFrom
29
+ const bundleSource = getFixedBundleSource(child);
30
+
31
+ if (bundleSource) {
28
32
  const {
29
33
  staticComponents: [newChild],
30
34
  dynamicComponents,
@@ -32,7 +36,7 @@ const check = async ({ did, states }) => {
32
36
  meta: {
33
37
  staticComponents: [
34
38
  {
35
- source: child.bundleSource,
39
+ source: bundleSource,
36
40
  name: child.meta.name,
37
41
  title: child.meta.title,
38
42
  mountPoint: child.mountPoint,
@@ -1,6 +1,12 @@
1
- const { removeSync, outputJsonSync } = require('fs-extra');
1
+ const { removeSync, outputJsonSync, createWriteStream, createReadStream } = require('fs-extra');
2
2
  const { cloneDeep } = require('lodash');
3
- const { join } = require('path');
3
+ const { join, basename } = require('path');
4
+ const { BLOCKLET_CONFIGURABLE_KEY } = require('@blocklet/constant');
5
+ const isEmpty = require('lodash/isEmpty');
6
+ const streamToPromise = require('stream-to-promise');
7
+ const axios = require('@abtnode/util/lib/axios');
8
+ const isUrl = require('is-url');
9
+ const { getLogoUrl } = require('@abtnode/util/lib/logo');
4
10
  const { BaseBackup } = require('./base');
5
11
 
6
12
  class BlockletBackup extends BaseBackup {
@@ -8,6 +14,10 @@ class BlockletBackup extends BaseBackup {
8
14
 
9
15
  async export() {
10
16
  const blocklet = await this.cleanData();
17
+
18
+ const targetLogoPath = await this.writeLogoFile();
19
+ blocklet.meta.appLogo = basename(targetLogoPath);
20
+
11
21
  removeSync(join(this.backupDir, this.filename));
12
22
  outputJsonSync(join(this.backupDir, this.filename), blocklet);
13
23
  }
@@ -65,6 +75,57 @@ class BlockletBackup extends BaseBackup {
65
75
 
66
76
  return info;
67
77
  }
78
+
79
+ /**
80
+ *
81
+ *
82
+ * @param {string} target
83
+ * @returns {Promise<string>}
84
+ * @memberof DataBackup
85
+ */
86
+ async writeLogoFile() {
87
+ const customLogoSquareUrl = this.blocklet.environments.find(
88
+ (e) => e.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_LOGO_SQUARE
89
+ )?.value;
90
+ const appDir = this.blocklet.environments.find((e) => e.key === 'BLOCKLET_APP_DIR')?.value;
91
+ const logo = this.blocklet?.meta?.logo;
92
+ const defaultLogoPath = join(this.serverDir, 'data', this.blocklet.meta.name, 'logo.svg');
93
+
94
+ const logoUrl = await getLogoUrl({
95
+ customLogoSquareUrl,
96
+ appDir,
97
+ logo,
98
+ defaultLogoPath,
99
+ });
100
+
101
+ const logoStream = await this.getLogoStream(logoUrl);
102
+ const targetLogoPath = join(this.backupDir, 'data', basename(logoUrl));
103
+ await streamToPromise(logoStream.pipe(createWriteStream(targetLogoPath)));
104
+
105
+ return targetLogoPath;
106
+ }
107
+
108
+ /**
109
+ *
110
+ *
111
+ * @param {string} logoUrl
112
+ * @returns {Promise<NodeJS.ReadStream>}
113
+ * @memberof DataBackup
114
+ */
115
+ async getLogoStream(logoUrl) {
116
+ if (isEmpty(logoUrl)) {
117
+ throw new Error(`logoUrl(${logoUrl}) cannot be empty`);
118
+ }
119
+
120
+ if (isUrl(logoUrl)) {
121
+ const res = await axios.get(logoUrl, {
122
+ responseType: 'stream',
123
+ });
124
+ return res.data;
125
+ }
126
+
127
+ return createReadStream(logoUrl);
128
+ }
68
129
  }
69
130
 
70
131
  module.exports = { BlockletBackup };
@@ -98,7 +98,6 @@ class SpacesBackup {
98
98
  new BlockletsBackup(this.input),
99
99
  new BlockletExtrasBackup(this.input),
100
100
  new RoutingRuleBackup(this.input),
101
- new DataBackup(this.input),
102
101
  ];
103
102
  }
104
103
 
@@ -151,12 +150,19 @@ class SpacesBackup {
151
150
  progress: 15,
152
151
  completed: false,
153
152
  });
153
+
154
+ // @note: dataBackup 需要先于 blockletBackup 执行,并且 blockletBackup 与其他 backup的执行可以是无序的
155
+ const dataBackup = new DataBackup(this.input);
156
+ dataBackup.ensureParams(this);
157
+ await dataBackup.export();
158
+
154
159
  await Promise.all(
155
160
  this.storages.map((storage) => {
156
161
  storage.ensureParams(this);
157
162
  return storage.export();
158
163
  })
159
164
  );
165
+
160
166
  this.input.event.emit(BlockletEvents.backupProgress, {
161
167
  appDid: this.input.appDid,
162
168
  message: 'Data ready, start backup...',
@@ -201,7 +207,7 @@ class SpacesBackup {
201
207
  const percent = (data.completed * 100) / data.total;
202
208
  this.input.event.emit(BlockletEvents.backupProgress, {
203
209
  appDid: this.input.appDid,
204
- message: `Uploaded file ${basename(data.key)} (${data.completed}/${data.total})`,
210
+ message: `Uploading file ${basename(data.key)} (${data.completed}/${data.total})`,
205
211
  // 0.8 是因为上传文件到 spaces 占进度的 80%,+ 20 是因为需要累加之前的进度
206
212
  progress: +Math.ceil(percent * 0.8).toFixed(2) + 20,
207
213
  completed: false,
@@ -120,7 +120,7 @@ class SpacesRestore {
120
120
  logger.info('restore progress', { appDid: this.input.appDid, data });
121
121
  this.input.event.emit(BlockletEvents.restoreProgress, {
122
122
  appDid: this.input.appDid,
123
- message: `Downloaded file ${basename(data.key)} (${data.completed}/${data.total})`,
123
+ message: `Downloading file ${basename(data.key)} (${data.completed}/${data.total})`,
124
124
  });
125
125
  },
126
126
 
@@ -204,6 +204,7 @@ const ensureLatestNodeInfo = async (sites = [], { withDefaultCors = true } = {})
204
204
  * set rule.to.target by interface.path and interface.prefix
205
205
  */
206
206
  const ensureLatestInterfaceInfo = async (sites = []) => {
207
+ // FIXME @linchen groupAllInterfaces() may have performance issue
207
208
  const interfaces = await states.blocklet.groupAllInterfaces();
208
209
  return sites.map((site) => {
209
210
  if (!Array.isArray(site.rules)) {
@@ -223,10 +224,10 @@ const ensureLatestInterfaceInfo = async (sites = []) => {
223
224
  return rule;
224
225
  }
225
226
 
226
- const { did, interfaceName } = rule.to;
227
- if (interfaces[did] && interfaces[did][interfaceName]) {
227
+ const { componentId, interfaceName } = rule.to;
228
+ if (interfaces[componentId] && interfaces[componentId][interfaceName]) {
228
229
  // eslint-disable-next-line no-shadow
229
- const { path, prefix } = interfaces[did][interfaceName];
230
+ const { path, prefix } = interfaces[componentId][interfaceName];
230
231
  if (prefix === BLOCKLET_DYNAMIC_PATH_PREFIX) {
231
232
  rule.to.target = path;
232
233
  } else {
@@ -5,6 +5,7 @@ const logger = require('@abtnode/logger')('state-blocklet-extras');
5
5
  const { EXPIRED_BLOCKLET_DATA_RETENTION_DAYS } = require('@abtnode/constant');
6
6
  const camelCase = require('lodash/camelCase');
7
7
  const get = require('lodash/get');
8
+ const uniq = require('lodash/uniq');
8
9
  const dayjs = require('dayjs');
9
10
 
10
11
  const BaseState = require('./base');
@@ -127,7 +128,7 @@ class BlockletExtrasState extends BaseState {
127
128
  generateGetFn(extra) {
128
129
  return async (dids, path, defaultValue) => {
129
130
  // eslint-disable-next-line no-param-reassign
130
- dids = [].concat(dids);
131
+ dids = uniq([].concat(dids));
131
132
  const [rootDid, ...childDids] = dids;
132
133
  const { dek } = this.config;
133
134
  const { name, afterGet = noop('data') } = extra;
@@ -149,7 +150,7 @@ class BlockletExtrasState extends BaseState {
149
150
  generateSetFn(extra) {
150
151
  return async (dids, data) => {
151
152
  // eslint-disable-next-line no-param-reassign
152
- dids = [].concat(dids);
153
+ dids = uniq([].concat(dids));
153
154
  const [rootDid, ...childDids] = dids;
154
155
  const { dek } = this.config;
155
156
  const { name, beforeSet = noop('cur') } = extra;
@@ -189,7 +190,7 @@ class BlockletExtrasState extends BaseState {
189
190
  generateDelFn(extra) {
190
191
  return async (dids) => {
191
192
  // eslint-disable-next-line no-param-reassign
192
- dids = [].concat(dids);
193
+ dids = uniq([].concat(dids));
193
194
  const [rootDid, ...childDids] = dids;
194
195
  const { name } = extra;
195
196
  const item = await this.findOne({ did: rootDid });
@@ -509,17 +509,21 @@ class BlockletState extends BaseState {
509
509
  * @return {Object} { <did> : { interfaceName } }
510
510
  */
511
511
  async groupAllInterfaces() {
512
- const blocklets = await this.getBlocklets({}, { meta: 1 });
512
+ const blocklets = await this.getBlocklets({}, { meta: 1, children: 1 });
513
513
  const result = {};
514
- blocklets.forEach((blocklet) => {
515
- const { did, interfaces } = blocklet.meta;
516
- if (typeof result[did] === 'undefined') {
517
- result[did] = {};
514
+ const fillResult = (component, { id }) => {
515
+ const { interfaces } = component.meta;
516
+ if (typeof result[id] === 'undefined') {
517
+ result[id] = {};
518
518
  }
519
519
 
520
520
  (interfaces || []).forEach((x) => {
521
- result[did][x.name] = x;
521
+ result[id][x.name] = x;
522
522
  });
523
+ };
524
+
525
+ blocklets.forEach((blocklet) => {
526
+ forEachBlockletSync(blocklet, fillResult);
523
527
  });
524
528
 
525
529
  return result;
@@ -1825,6 +1825,38 @@ const getBlockletKnownAs = (blocklet) => {
1825
1825
  return alsoKnownAs.filter(Boolean).map(toDid);
1826
1826
  };
1827
1827
 
1828
+ const getFixedBundleSource = (component) => {
1829
+ if (!component) {
1830
+ return null;
1831
+ }
1832
+
1833
+ if (component.bundleSource) {
1834
+ return component.bundleSource;
1835
+ }
1836
+
1837
+ const { source, deployedFrom, meta: { bundleName } = {} } = component;
1838
+
1839
+ if (!deployedFrom) {
1840
+ return null;
1841
+ }
1842
+
1843
+ if (source === BlockletSource.registry && bundleName) {
1844
+ return {
1845
+ store: deployedFrom,
1846
+ name: bundleName,
1847
+ version: 'latest',
1848
+ };
1849
+ }
1850
+
1851
+ if (source === BlockletSource.url) {
1852
+ return {
1853
+ url: deployedFrom,
1854
+ };
1855
+ }
1856
+
1857
+ return null;
1858
+ };
1859
+
1828
1860
  module.exports = {
1829
1861
  consumeServerlessNFT,
1830
1862
  forEachBlocklet,
@@ -1879,4 +1911,5 @@ module.exports = {
1879
1911
  checkVersionCompatibility,
1880
1912
  validateBlockletMeta,
1881
1913
  getBlockletKnownAs,
1914
+ getFixedBundleSource,
1882
1915
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.16.0-beta-b16cb035",
6
+ "version": "1.16.0-beta-1d6c582e",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,34 +19,34 @@
19
19
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "@abtnode/auth": "1.16.0-beta-b16cb035",
23
- "@abtnode/certificate-manager": "1.16.0-beta-b16cb035",
24
- "@abtnode/constant": "1.16.0-beta-b16cb035",
25
- "@abtnode/cron": "1.16.0-beta-b16cb035",
26
- "@abtnode/db": "1.16.0-beta-b16cb035",
27
- "@abtnode/logger": "1.16.0-beta-b16cb035",
28
- "@abtnode/queue": "1.16.0-beta-b16cb035",
29
- "@abtnode/rbac": "1.16.0-beta-b16cb035",
30
- "@abtnode/router-provider": "1.16.0-beta-b16cb035",
31
- "@abtnode/static-server": "1.16.0-beta-b16cb035",
32
- "@abtnode/timemachine": "1.16.0-beta-b16cb035",
33
- "@abtnode/util": "1.16.0-beta-b16cb035",
34
- "@arcblock/did": "1.18.59",
22
+ "@abtnode/auth": "1.16.0-beta-1d6c582e",
23
+ "@abtnode/certificate-manager": "1.16.0-beta-1d6c582e",
24
+ "@abtnode/constant": "1.16.0-beta-1d6c582e",
25
+ "@abtnode/cron": "1.16.0-beta-1d6c582e",
26
+ "@abtnode/db": "1.16.0-beta-1d6c582e",
27
+ "@abtnode/logger": "1.16.0-beta-1d6c582e",
28
+ "@abtnode/queue": "1.16.0-beta-1d6c582e",
29
+ "@abtnode/rbac": "1.16.0-beta-1d6c582e",
30
+ "@abtnode/router-provider": "1.16.0-beta-1d6c582e",
31
+ "@abtnode/static-server": "1.16.0-beta-1d6c582e",
32
+ "@abtnode/timemachine": "1.16.0-beta-1d6c582e",
33
+ "@abtnode/util": "1.16.0-beta-1d6c582e",
34
+ "@arcblock/did": "1.18.62",
35
35
  "@arcblock/did-motif": "^1.1.10",
36
- "@arcblock/did-util": "1.18.59",
37
- "@arcblock/event-hub": "1.18.59",
38
- "@arcblock/jwt": "^1.18.59",
36
+ "@arcblock/did-util": "1.18.62",
37
+ "@arcblock/event-hub": "1.18.62",
38
+ "@arcblock/jwt": "^1.18.62",
39
39
  "@arcblock/pm2-events": "^0.0.5",
40
- "@arcblock/vc": "1.18.59",
41
- "@blocklet/constant": "1.16.0-beta-b16cb035",
42
- "@blocklet/meta": "1.16.0-beta-b16cb035",
43
- "@blocklet/sdk": "1.16.0-beta-b16cb035",
44
- "@did-space/client": "^0.2.33",
40
+ "@arcblock/vc": "1.18.62",
41
+ "@blocklet/constant": "1.16.0-beta-1d6c582e",
42
+ "@blocklet/meta": "1.16.0-beta-1d6c582e",
43
+ "@blocklet/sdk": "1.16.0-beta-1d6c582e",
44
+ "@did-space/client": "^0.2.40",
45
45
  "@fidm/x509": "^1.2.1",
46
- "@ocap/client": "1.18.59",
47
- "@ocap/mcrypto": "1.18.59",
48
- "@ocap/util": "1.18.59",
49
- "@ocap/wallet": "1.18.59",
46
+ "@ocap/client": "1.18.62",
47
+ "@ocap/mcrypto": "1.18.62",
48
+ "@ocap/util": "1.18.62",
49
+ "@ocap/wallet": "1.18.62",
50
50
  "@slack/webhook": "^5.0.4",
51
51
  "archiver": "^5.3.1",
52
52
  "axios": "^0.27.2",
@@ -91,5 +91,5 @@
91
91
  "express": "^4.18.2",
92
92
  "jest": "^27.5.1"
93
93
  },
94
- "gitHead": "138bd91aee5a35b28c2de4e1e924c44932efaf3a"
94
+ "gitHead": "209fa1413ae05d8961942b2c21f2d83df66f4b68"
95
95
  }