@blocklet/meta 1.6.17 → 1.6.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/constants.js CHANGED
@@ -173,7 +173,7 @@ module.exports = Object.freeze({
173
173
 
174
174
  BLOCKLET_DEFAULT_VERSION: '1.0.0',
175
175
 
176
- BLOCKLET_LATEST_SPEC_VERSION: '1.2.1',
176
+ BLOCKLET_LATEST_SPEC_VERSION: '1.2.3',
177
177
  BLOCKLET_LATEST_REQUIREMENT_SERVER: '>=1.6.2',
178
178
  BLOCKLET_LATEST_REQUIREMENT_ABTNODE: '>=1.5.15', // Deprecated
179
179
 
package/lib/info.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const get = require('lodash/get');
2
2
  const getBlockletWallet = require('./wallet');
3
+ const { getDisplayName } = require('./util');
3
4
 
4
5
  module.exports = (state, nodeSk, { returnWallet = true } = {}) => {
5
6
  if (!state || typeof state !== 'object' || !Array.isArray(state.environments) || !get(state, 'meta.did')) {
@@ -9,12 +10,11 @@ module.exports = (state, nodeSk, { returnWallet = true } = {}) => {
9
10
  const { environments, configs = [] } = state;
10
11
  const envs = [...configs, ...environments];
11
12
 
12
- const customName = envs.find((x) => x.key === 'BLOCKLET_APP_NAME');
13
13
  const customDescription = envs.find((x) => x.key === 'BLOCKLET_APP_DESCRIPTION');
14
14
  const customPassportColor = envs.find((x) => x.key === 'BLOCKLET_PASSPORT_COLOR');
15
15
 
16
16
  const { did } = state.meta;
17
- const name = get(customName, 'value', state.meta.title || state.meta.name);
17
+ const name = getDisplayName(state);
18
18
  const description = get(customDescription, 'value', state.meta.description);
19
19
  const passportColor = get(customPassportColor, 'value', 'auto');
20
20
 
package/lib/schema.js CHANGED
@@ -1,8 +1,9 @@
1
1
  /* eslint-disable newline-per-chained-call */
2
2
  const fs = require('fs');
3
3
  const JOI = require('joi');
4
- const { semver, semverRange } = require('joi-extension-semver');
4
+ const cjkLength = require('cjk-length').default;
5
5
  const isGlob = require('is-glob');
6
+ const { semver, semverRange } = require('joi-extension-semver');
6
7
 
7
8
  const { fileExtension, didExtension } = require('./extension');
8
9
  const { validateName } = require('./name');
@@ -23,6 +24,7 @@ const {
23
24
  } = require('./constants');
24
25
 
25
26
  const WELLKNOWN_PATH_PREFIX = '/.well-known';
27
+ const MAX_TITLE_LENGTH = 48;
26
28
 
27
29
  const Joi = JOI.extend(semver).extend(semverRange).extend(fileExtension).extend(didExtension);
28
30
 
@@ -138,7 +140,7 @@ const statsSchema = Joi.object({
138
140
  const childrenSchema = Joi.object({
139
141
  name: Joi.string().min(1).required(),
140
142
  resolved: Joi.alternatives().try(Joi.string().uri(), Joi.string()).required(),
141
- mountPoints: Joi.array()
143
+ mountPoints: Joi.array() // deprecated
142
144
  .items(
143
145
  Joi.object({
144
146
  root: Joi.object({
@@ -153,6 +155,14 @@ const childrenSchema = Joi.object({
153
155
  )
154
156
  .optional()
155
157
  .default([]),
158
+ mountPoint: Joi.string().trim().min(1), // added in 1.2.3
159
+ services: Joi.array().items(serviceSchema).unique('name'), // added in 1.2.3
160
+ }).custom((value) => {
161
+ if (!value.mountPoint && (!value.mountPoints || !value.mountPoints.length)) {
162
+ throw new Error('mountPoint is required');
163
+ }
164
+
165
+ return value;
156
166
  });
157
167
 
158
168
  const signatureSchema = Joi.object({
@@ -184,14 +194,25 @@ const createBlockletSchema = (
184
194
  return value;
185
195
  })
186
196
  .required(),
187
- description: Joi.string().trim().required(),
197
+ description: Joi.string().trim().min(3).max(512).required(),
188
198
  group: Joi.string().valid(...BLOCKLET_GROUPS).required(), // prettier-ignore
189
199
  main: Joi.when('group', {
190
200
  is: Joi.valid(BlockletGroup.gateway),
191
201
  then: Joi.forbidden(),
192
202
  otherwise: ensureMain ? Joi.file().exists({ baseDir }).required() : Joi.string().trim().required(),
193
203
  }),
194
- title: Joi.string().trim().optional().allow(''),
204
+ title: Joi.string()
205
+ .trim()
206
+ .min(3)
207
+ .custom((value) => {
208
+ if (cjkLength(value) > MAX_TITLE_LENGTH) {
209
+ throw new Error(`Blocklet title is too long. Max length is ${MAX_TITLE_LENGTH}`);
210
+ }
211
+
212
+ return value;
213
+ })
214
+ .optional()
215
+ .allow(''),
195
216
  logo: ensureFiles ? Joi.file().trim().exists({ baseDir }).optional() : Joi.string().trim().optional(),
196
217
  specVersion: Joi.semver().valid().gte('1.0.0').optional(),
197
218
 
@@ -216,7 +237,7 @@ const createBlockletSchema = (
216
237
  .max(4)
217
238
  .items(
218
239
  Joi.object({
219
- value: Joi.number().required(),
240
+ value: Joi.number().greater(0).required(),
220
241
  address: Joi.DID().required(), // token address
221
242
  })
222
243
  ),
@@ -232,7 +253,7 @@ const createBlockletSchema = (
232
253
  Joi.object({
233
254
  name: Joi.string().required(),
234
255
  address: Joi.DID().required(),
235
- value: Joi.number().min(0).max(1).required(),
256
+ value: Joi.number().greater(0).max(1).required(),
236
257
  })
237
258
  )
238
259
  .custom((value) => {
@@ -242,13 +263,11 @@ const createBlockletSchema = (
242
263
  }
243
264
  const total = value.reduce((acc, cur) => acc + cur.value, 0);
244
265
  if (total !== 1) {
245
- throw new Error(`invalid share: ${JSON.stringify(value)}`);
266
+ throw new Error(`Invalid blocklet payment share config: total share must be 1, got ${total}`);
246
267
  }
247
268
  return value;
248
- }, 'share invalid'),
249
- })
250
- .default({ price: [], share: [] })
251
- .optional(),
269
+ }, 'invalid blocklet share'),
270
+ }).default({ price: [], share: [] }),
252
271
 
253
272
  keywords: Joi.alternatives()
254
273
  .try(Joi.string().trim().min(1), Joi.array().items(Joi.string().min(1)))
@@ -321,7 +340,13 @@ const createBlockletSchema = (
321
340
  // capabilities
322
341
  capabilities: Joi.object({
323
342
  clusterMode: Joi.boolean().default(false), // Can blocklet be started in cluster mode
324
- }).default({}),
343
+
344
+ // added in 1.2.2
345
+ component: Joi.boolean().default(true), // Can blocklet become a component and be composed by other blocklets
346
+ }).default({
347
+ clusterMode: false,
348
+ component: true,
349
+ }),
325
350
 
326
351
  // Other contents to be included in the bundle
327
352
  files: Joi.array()
package/lib/util.js CHANGED
@@ -101,6 +101,10 @@ const isFreeBlocklet = (meta) => {
101
101
  return priceList.every((x) => x === 0);
102
102
  };
103
103
 
104
+ const isComponentBlocklet = (meta) => {
105
+ return get(meta, 'capabilities.component') !== false;
106
+ };
107
+
104
108
  const wipeSensitiveData = (blocklet) => {
105
109
  if (!blocklet) {
106
110
  return blocklet;
@@ -153,8 +157,28 @@ const hasRunnableComponent = (blocklet) => {
153
157
  return has;
154
158
  };
155
159
 
160
+ /**
161
+ * 获取 blocklet 的 name
162
+ * @param {Object} blocklet 应用数据
163
+ * @param {Boolean} onlyUseMeta 优先使用应用元数据的name
164
+ * @returns blocklet display name
165
+ */
166
+ const getDisplayName = (blocklet, onlyUseMeta = false) => {
167
+ const { meta } = blocklet;
168
+ let displayName;
169
+
170
+ if (!onlyUseMeta && blocklet.environments) {
171
+ const target = blocklet.environments.find((e) => e.key === 'BLOCKLET_APP_NAME');
172
+ if (target && target.value) {
173
+ displayName = target.value;
174
+ }
175
+ }
176
+ return displayName || meta.title || meta.name;
177
+ };
178
+
156
179
  module.exports = {
157
180
  isFreeBlocklet,
181
+ isComponentBlocklet,
158
182
  forEachBlockletSync,
159
183
  isDeletableBlocklet,
160
184
  forEachBlocklet,
@@ -162,4 +186,5 @@ module.exports = {
162
186
  getRequiredMissingConfigs,
163
187
  wipeSensitiveData,
164
188
  hasRunnableComponent,
189
+ getDisplayName,
165
190
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.6.17",
6
+ "version": "1.6.21",
7
7
  "description": "Library to parse/validate/fix blocklet meta",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -18,20 +18,21 @@
18
18
  "author": "wangshijun <wangshijun2020@gmail.com> (http://github.com/wangshijun)",
19
19
  "license": "MIT",
20
20
  "dependencies": {
21
- "@arcblock/did": "^1.14.8",
22
- "@arcblock/did-ext": "^1.14.8",
23
- "@arcblock/did-util": "^1.14.8",
24
- "@arcblock/nft": "^1.14.8",
25
- "@ocap/asset": "^1.14.8",
26
- "@ocap/mcrypto": "^1.14.8",
27
- "@ocap/util": "^1.14.8",
28
- "@ocap/wallet": "^1.14.8",
21
+ "@arcblock/did": "^1.14.13",
22
+ "@arcblock/did-ext": "^1.14.13",
23
+ "@arcblock/did-util": "^1.14.13",
24
+ "@arcblock/nft": "^1.14.13",
25
+ "@ocap/asset": "^1.14.13",
26
+ "@ocap/mcrypto": "^1.14.13",
27
+ "@ocap/util": "^1.14.13",
28
+ "@ocap/wallet": "^1.14.13",
29
29
  "ajv": "^7.0.3",
30
+ "cjk-length": "^1.0.0",
30
31
  "debug": "^4.3.3",
31
32
  "fs-extra": "^10.0.0",
32
33
  "hosted-git-info": "3.0.8",
33
34
  "is-glob": "^4.0.3",
34
- "joi": "^17.5.0",
35
+ "joi": "^17.6.0",
35
36
  "joi-extension-semver": "^5.0.0",
36
37
  "js-yaml": "^3.14.0",
37
38
  "json-stable-stringify": "^1.0.1",
@@ -42,5 +43,5 @@
42
43
  "devDependencies": {
43
44
  "jest": "^27.4.5"
44
45
  },
45
- "gitHead": "d567a622a779eba43c95eaeb4633cb2b276bb7b9"
46
+ "gitHead": "864ae21711c119948475057a1f634fd7d16ae91a"
46
47
  }