@blocklet/meta 1.15.17 → 1.16.0-beta-8ee536d7

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.
Files changed (62) hide show
  1. package/lib/channel.d.ts +32 -0
  2. package/lib/channel.js +54 -0
  3. package/lib/constants.d.ts +2 -0
  4. package/lib/constants.js +5 -152
  5. package/lib/did.d.ts +3 -0
  6. package/lib/did.js +9 -9
  7. package/lib/engine.d.ts +7 -0
  8. package/lib/engine.js +21 -25
  9. package/lib/entry.d.ts +3 -0
  10. package/lib/entry.js +51 -64
  11. package/lib/extension.d.ts +14 -0
  12. package/lib/extension.js +82 -77
  13. package/lib/file.d.ts +23 -0
  14. package/lib/file.js +51 -36
  15. package/lib/fix.d.ts +36 -0
  16. package/lib/fix.js +231 -228
  17. package/lib/get-component-process-id.d.ts +5 -0
  18. package/lib/get-component-process-id.js +16 -0
  19. package/lib/has-reserved-key.d.ts +3 -0
  20. package/lib/has-reserved-key.js +15 -0
  21. package/lib/index.d.ts +86 -0
  22. package/lib/index.js +55 -34
  23. package/lib/info.d.ts +15 -0
  24. package/lib/info.js +70 -38
  25. package/lib/name.d.ts +15 -0
  26. package/lib/name.js +41 -8
  27. package/lib/nft-templates.d.ts +86 -0
  28. package/lib/nft-templates.js +52 -0
  29. package/lib/parse-navigation-from-blocklet.d.ts +92 -0
  30. package/lib/parse-navigation-from-blocklet.js +539 -0
  31. package/lib/parse-navigation.d.ts +3 -0
  32. package/lib/parse-navigation.js +197 -0
  33. package/lib/parse.d.ts +22 -0
  34. package/lib/parse.js +100 -89
  35. package/lib/payment/index.d.ts +254 -0
  36. package/lib/payment/index.js +14 -0
  37. package/lib/payment/v1.d.ts +185 -0
  38. package/lib/payment/v1.js +84 -0
  39. package/lib/payment/v2.d.ts +242 -0
  40. package/lib/payment/v2.js +576 -0
  41. package/lib/schema.d.ts +63 -0
  42. package/lib/schema.js +669 -283
  43. package/lib/service.d.ts +27 -0
  44. package/lib/service.js +71 -0
  45. package/lib/types/index.d.ts +1 -0
  46. package/lib/types/index.js +18 -0
  47. package/lib/types/schema.d.ts +284 -0
  48. package/lib/types/schema.js +3 -0
  49. package/lib/url-friendly.d.ts +6 -0
  50. package/lib/url-friendly.js +20 -0
  51. package/lib/util-meta.d.ts +42 -0
  52. package/lib/util-meta.js +146 -0
  53. package/lib/util.d.ts +201 -0
  54. package/lib/util.js +501 -82
  55. package/lib/validate.d.ts +13 -0
  56. package/lib/validate.js +37 -61
  57. package/lib/verify-multi-sig.d.ts +3 -0
  58. package/lib/verify-multi-sig.js +86 -59
  59. package/lib/wallet.d.ts +9 -0
  60. package/lib/wallet.js +19 -30
  61. package/package.json +59 -20
  62. package/lib/payment.js +0 -114
package/lib/schema.js CHANGED
@@ -1,363 +1,749 @@
1
- /* eslint-disable newline-per-chained-call */
2
- const fs = require('fs');
3
- const JOI = require('joi');
4
- const { semver, semverRange } = require('joi-extension-semver');
5
- const isGlob = require('is-glob');
6
-
7
- const { fileExtension, didExtension } = require('./extension');
8
- const { validateName } = require('./name');
9
- const {
10
- BLOCKLET_GROUPS,
11
- BLOCKLET_PLATFORMS,
12
- BLOCKLET_ARCHITECTURES,
13
- BLOCKLET_INTERFACE_TYPES,
14
- BLOCKLET_INTERFACE_PROTOCOLS,
15
- BLOCKLET_ENTRY_FILE,
16
- BLOCKLET_BUNDLE_FILE,
17
- BLOCKLET_DEFAULT_PORT_NAME,
18
- BLOCKLET_DYNAMIC_PATH_PREFIX,
19
- BlockletGroup,
20
- BLOCKLET_LATEST_REQUIREMENT_ABTNODE,
21
- BLOCKLET_INTERFACE_TYPE_WEB,
22
- BLOCKLET_INTERFACE_TYPE_WELLKNOWN,
23
- } = require('./constants');
24
-
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.authConfigSchema = exports.cacheableSchema = exports.statsSchema = exports.titleSchema = exports.themeSchema = exports.signatureSchema = exports.serviceSchema = exports.scriptsSchema = exports.personSchema = exports.navigationSchema = exports.navigationItemSchema = exports.updateMountPointSchema = exports.mountPointSchema = exports.logoSchema = exports.interfaceSchema = exports.environmentNameSchema = exports.environmentSchema = exports.engineSchema = exports.endpointSchema = exports.distSchema = exports.descriptionSchema = exports.createBlockletSchema = exports.componentSchema = exports.blockletNameSchema = exports.blockletMetaSchema = void 0;
30
+ const fs_1 = __importDefault(require("fs"));
31
+ const joi_1 = __importDefault(require("joi"));
32
+ const cjk_length_1 = __importDefault(require("cjk-length"));
33
+ const is_glob_1 = __importDefault(require("is-glob"));
34
+ const joi_extension_semver_1 = require("joi-extension-semver");
35
+ const is_var_name_1 = __importDefault(require("is-var-name"));
36
+ const constant_1 = require("@abtnode/constant");
37
+ const did_1 = require("@arcblock/did");
38
+ const did_2 = __importDefault(require("./did"));
39
+ const extension_1 = require("./extension");
40
+ const name_1 = require("./name");
41
+ const constants_1 = __importDefault(require("./constants"));
42
+ const parse_navigation_from_blocklet_1 = require("./parse-navigation-from-blocklet");
43
+ const url_friendly_1 = __importStar(require("./url-friendly"));
44
+ const cjkLength = cjk_length_1.default.default;
45
+ const { BLOCKLET_GROUPS, BLOCKLET_PLATFORMS, BLOCKLET_ARCHITECTURES, BLOCKLET_INTERFACE_TYPES, BLOCKLET_INTERFACE_PROTOCOLS, BLOCKLET_ENTRY_FILE, BLOCKLET_BUNDLE_FILE, BLOCKLET_DEFAULT_PORT_NAME, BLOCKLET_DYNAMIC_PATH_PREFIX, BlockletGroup, BLOCKLET_LATEST_REQUIREMENT_SERVER, BLOCKLET_INTERFACE_TYPE_WEB, BLOCKLET_INTERFACE_TYPE_WELLKNOWN, BLOCKLET_APP_SPACE_ENDPOINTS, BLOCKLET_CONFIGURABLE_KEY, } = constants_1.default;
25
46
  const WELLKNOWN_PATH_PREFIX = '/.well-known';
47
+ const MAX_TITLE_LENGTH = 24;
48
+ const Joi = joi_1.default.extend(joi_extension_semver_1.semver)
49
+ .extend(joi_extension_semver_1.semverRange)
50
+ .extend(extension_1.fileExtension)
51
+ .extend(extension_1.didExtension);
52
+ const checkLinkHelper = (value, helper) => {
53
+ if ((0, parse_navigation_from_blocklet_1.checkLink)(value)) {
54
+ return value;
55
+ }
56
+ // @ts-expect-error
57
+ return helper.message(`Invalid navigation link: ${value}
58
+
59
+ A valid navigation link should be a relative url which start with '/' or a absolute url, such as:
60
+ - /en/home
61
+ - /zh/home
62
+ - https://www.arcblock.io`);
63
+ };
64
+ const checkId = (value, helper) => {
65
+ if (!value || (0, is_var_name_1.default)(value)) {
66
+ return value;
67
+ }
68
+ // @ts-expect-error
69
+ return helper.message(`Invalid navigation id: ${value}
26
70
 
27
- const Joi = JOI.extend(semver).extend(semverRange).extend(fileExtension).extend(didExtension);
71
+ A valid navigation id is should follow the rules of javascript variables, such as:
72
+ - foo
73
+ - fooBar
74
+ - foo123
28
75
 
76
+ see detail in https://www.npmjs.com/package/is-var-name`);
77
+ };
78
+ const titleSchema = Joi.string()
79
+ .trim()
80
+ .min(1)
81
+ .custom((value) => {
82
+ if (cjkLength(value) > MAX_TITLE_LENGTH) {
83
+ throw new Error(`title length should not exceed ${MAX_TITLE_LENGTH} (see: https://www.npmjs.com/package/cjk-length)`);
84
+ }
85
+ return value;
86
+ })
87
+ .meta({ className: 'TTitle' });
88
+ exports.titleSchema = titleSchema;
89
+ const descriptionSchema = Joi.string().trim().min(3).max(160).meta({ className: 'TDescription' });
90
+ exports.descriptionSchema = descriptionSchema;
91
+ const logoSchema = Joi.string()
92
+ .uri({ scheme: ['http', 'https'], allowRelative: true })
93
+ .allow('')
94
+ .custom((value, helper) => {
95
+ if (value.includes(constant_1.WELLKNOWN_BLOCKLET_LOGO_PATH)) {
96
+ // @ts-expect-error
97
+ return helper.message(`logo url should not include ${constant_1.WELLKNOWN_BLOCKLET_LOGO_PATH}`);
98
+ }
99
+ return value;
100
+ })
101
+ .meta({ className: 'TLogo' });
102
+ exports.logoSchema = logoSchema;
103
+ const baseMountPointSchema = Joi.string().trim().min(1);
104
+ const mountPointSchema = baseMountPointSchema
105
+ .meta({ className: 'TMountPoint' })
106
+ .custom((value, helper) => {
107
+ if ((0, url_friendly_1.isValidUrl)(value)) {
108
+ return value;
109
+ }
110
+ // @ts-expect-error
111
+ return helper.message('mountPoint cannot contain such characters space $*_+~.()\'"!:@\\');
112
+ });
113
+ exports.mountPointSchema = mountPointSchema;
114
+ const updateMountPointSchema = baseMountPointSchema
115
+ .meta({ className: 'TUpdateMountPoint' })
116
+ .custom((value) => (0, url_friendly_1.default)(value));
117
+ exports.updateMountPointSchema = updateMountPointSchema;
118
+ const blockletNameSchema = Joi.string()
119
+ .custom((value) => {
120
+ (0, name_1.validateName)(value);
121
+ return value;
122
+ })
123
+ .meta({ className: 'TBlockletName' });
124
+ exports.blockletNameSchema = blockletNameSchema;
125
+ const ENV_NAME_WHITE_LIST = [BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_WALLET_TYPE];
126
+ const environmentNameSchema = Joi.string()
127
+ .trim()
128
+ .min(1)
129
+ .max(50)
130
+ .required()
131
+ .custom((name, helper) => {
132
+ if (name.startsWith('BLOCKLET')) {
133
+ if (!ENV_NAME_WHITE_LIST.includes(name)) {
134
+ // @ts-expect-error
135
+ return helper.message('Env name can not start with BLOCKLET_');
136
+ }
137
+ }
138
+ if (name.startsWith('COMPONENT')) {
139
+ // @ts-expect-error
140
+ return helper.message('Env name can not start with COMPONENT_');
141
+ }
142
+ if (name.startsWith('ABTNODE')) {
143
+ // @ts-expect-error
144
+ return helper.message('Env name can not start with ABTNODE_');
145
+ }
146
+ if (/[^\w]/.test(name)) {
147
+ // @ts-expect-error
148
+ return helper.message('Env name can include only numbers or letters or "_"');
149
+ }
150
+ return name;
151
+ })
152
+ .meta({
153
+ className: 'TEnvironmentName',
154
+ unknownType: 'any',
155
+ });
156
+ exports.environmentNameSchema = environmentNameSchema;
29
157
  const environmentSchema = Joi.object({
30
- name: Joi.string().trim().required(),
31
- description: Joi.string().trim().required(),
32
- default: Joi.string().optional().allow('').default(''),
33
- required: Joi.boolean().default(false),
34
- secure: Joi.boolean().default(false),
35
- validation: Joi.string().optional(),
158
+ name: environmentNameSchema.required(),
159
+ description: Joi.string().trim().required(),
160
+ default: Joi.string().optional().allow('').default(''),
161
+ required: Joi.boolean().default(false),
162
+ secure: Joi.boolean().default(false),
163
+ validation: Joi.string().optional(),
164
+ shared: Joi.boolean().default((parent) => !parent.secure),
165
+ })
166
+ .custom((x, helper) => {
167
+ if (x.secure && x.default) {
168
+ // @ts-expect-error
169
+ return helper.message(`Cannot declare default value for secure env ${x.name}`);
170
+ }
171
+ return x;
172
+ })
173
+ .meta({
174
+ className: 'TEnvironment',
175
+ unknownType: 'any',
36
176
  });
37
-
177
+ exports.environmentSchema = environmentSchema;
38
178
  const scriptsSchema = Joi.object({
39
- dev: Joi.string().trim().min(1),
40
- preInstall: Joi.string().trim().min(1),
41
- postInstall: Joi.string().trim().min(1),
42
- preDeploy: Joi.string().trim().min(1),
43
- preStart: Joi.string().trim().min(1),
44
- preStop: Joi.string().trim().min(1),
45
- preUninstall: Joi.string().trim().min(1),
46
- preConfig: Joi.string().trim().min(1),
179
+ dev: Joi.string().trim().min(1),
180
+ e2eDev: Joi.string().trim().min(1),
181
+ preInstall: Joi.string().trim().min(1),
182
+ postInstall: Joi.string().trim().min(1),
183
+ preStart: Joi.string().trim().min(1),
184
+ postStart: Joi.string().trim().min(1),
185
+ preStop: Joi.string().trim().min(1),
186
+ preUninstall: Joi.string().trim().min(1),
187
+ preConfig: Joi.string().trim().min(1),
47
188
  })
48
- .rename('pre-install', 'preInstall')
49
- .rename('post-install', 'postInstall')
50
- .rename('pre-deploy', 'preDeploy')
51
- .rename('pre-start', 'preStart')
52
- .rename('pre-stop', 'preStop')
53
- .rename('pre-uninstall', 'preUninstall')
54
- .rename('pre-config', 'preConfig')
55
- .optional();
56
-
189
+ .rename('pre-install', 'preInstall')
190
+ .rename('post-install', 'postInstall')
191
+ .rename('pre-start', 'preStart')
192
+ .rename('post-start', 'postStart')
193
+ .rename('pre-stop', 'preStop')
194
+ .rename('pre-uninstall', 'preUninstall')
195
+ .rename('pre-config', 'preConfig')
196
+ .optional()
197
+ .meta({
198
+ className: 'TScripts',
199
+ unknownType: 'any',
200
+ });
201
+ exports.scriptsSchema = scriptsSchema;
57
202
  // Different services have different config schema
58
203
  // - Auth: https://github.com/ArcBlock/abtnode-docs/blob/master/src/developer/auth-service/index.md
59
204
  const serviceSchema = Joi.object({
60
- name: Joi.string().required().trim(),
61
- config: Joi.object().optional().default({}),
62
- }).unknown(true);
63
-
205
+ name: Joi.string().required().trim(),
206
+ config: Joi.object().optional().default({}),
207
+ })
208
+ .unknown(true)
209
+ .meta({
210
+ className: 'TService',
211
+ unknownType: 'any',
212
+ });
213
+ exports.serviceSchema = serviceSchema;
64
214
  const endpointSchema = Joi.object({
65
- type: Joi.string().trim(true).min(1).required(),
66
- path: Joi.string().required(),
67
- meta: Joi.object({
68
- vcType: Joi.string(),
69
- payable: Joi.boolean(),
70
- params: Joi.array().items({
71
- name: Joi.string().required().trim(),
72
- description: Joi.string().required().trim(),
215
+ type: Joi.string().trim(true).min(1).required(),
216
+ path: Joi.string().required(),
217
+ meta: Joi.object({
218
+ vcType: Joi.string(),
219
+ payable: Joi.boolean(),
220
+ params: Joi.array().items({
221
+ name: Joi.string().required().trim(),
222
+ description: Joi.string().required().trim(),
223
+ }),
73
224
  }),
74
- }),
225
+ }).meta({
226
+ className: 'TEndpoint',
227
+ unknownType: 'any',
75
228
  });
76
-
229
+ exports.endpointSchema = endpointSchema;
230
+ const cacheableSchema = Joi.string()
231
+ .trim()
232
+ .custom((value, helpers) => {
233
+ const parts = value.split('/').filter(Boolean);
234
+ if (parts.length === 0) {
235
+ // @ts-ignore
236
+ return helpers.message('cacheable path must be a valid pathname that is not /');
237
+ }
238
+ return `/${parts.join('/')}`;
239
+ })
240
+ .meta({
241
+ className: 'TPathPrefix',
242
+ unknownType: 'any',
243
+ });
244
+ exports.cacheableSchema = cacheableSchema;
77
245
  const interfaceSchema = Joi.object({
78
- type: Joi.string()
79
- .lowercase()
80
- .valid(...BLOCKLET_INTERFACE_TYPES)
81
- .required(),
82
-
83
- // Human readable name of the interface, such as `public_url`
84
- name: Joi.string().trim().required(),
85
-
86
- // The path where the interface is served from the blocklet
87
- path: Joi.string().trim().default('/'),
88
-
89
- // `*` means the interface can be mounted at any path prefix
90
- prefix: Joi.string().trim().min(1).default(BLOCKLET_DYNAMIC_PATH_PREFIX),
91
-
92
- protocol: Joi.string()
93
- .lowercase()
94
- .valid(...BLOCKLET_INTERFACE_PROTOCOLS)
95
- .default('http'),
96
-
97
- // Can be a string or an object
98
- port: Joi.alternatives()
99
- .try(
100
- Joi.string().uppercase().default(BLOCKLET_DEFAULT_PORT_NAME),
101
- Joi.object({
246
+ type: Joi.string()
247
+ .lowercase()
248
+ .valid(...BLOCKLET_INTERFACE_TYPES)
249
+ .required(),
250
+ // Human readable name of the interface, such as `public_url`
251
+ name: Joi.string().trim().required(),
252
+ // The path where the interface is served from the blocklet
253
+ path: Joi.string().trim().default('/'),
254
+ // `*` means the interface can be mounted at any path prefix
255
+ prefix: Joi.string().trim().min(1).default(BLOCKLET_DYNAMIC_PATH_PREFIX),
256
+ protocol: Joi.string()
257
+ .lowercase()
258
+ .valid(...BLOCKLET_INTERFACE_PROTOCOLS)
259
+ .default('http'),
260
+ // Can be a string or an object
261
+ port: Joi.alternatives()
262
+ .try(Joi.string().uppercase().default(BLOCKLET_DEFAULT_PORT_NAME), Joi.object({
102
263
  internal: Joi.string().uppercase().required(),
103
264
  external: Joi.number().port().required(),
104
- })
105
- )
106
- .default(BLOCKLET_DEFAULT_PORT_NAME),
107
-
108
- services: Joi.array().items(serviceSchema).unique('name'),
109
- endpoints: Joi.array().items(endpointSchema).unique('type'),
265
+ }))
266
+ .default(BLOCKLET_DEFAULT_PORT_NAME),
267
+ cacheable: Joi.array().items(cacheableSchema).unique(),
268
+ services: Joi.array().items(serviceSchema).unique('name'),
269
+ endpoints: Joi.array().items(endpointSchema).unique('type'),
270
+ }).meta({
271
+ className: 'TInterface',
272
+ unknownType: 'any',
110
273
  });
111
-
274
+ exports.interfaceSchema = interfaceSchema;
112
275
  const engineSchema = Joi.object({
113
- platform: Joi.string()
114
- .valid(...BLOCKLET_PLATFORMS)
115
- .optional(),
116
- interpreter: Joi.string().valid('binary', 'node').default('node'),
117
- script: Joi.string().required(),
118
- args: Joi.array().items(Joi.string()).optional().default([]),
276
+ platform: Joi.string()
277
+ .valid(...BLOCKLET_PLATFORMS)
278
+ .optional(),
279
+ interpreter: Joi.string().valid('binary', 'node').default('node'),
280
+ script: Joi.string().required(),
281
+ args: Joi.array().items(Joi.string()).optional().default([]),
282
+ }).meta({
283
+ className: 'TEngine',
284
+ unknownType: 'any',
119
285
  });
120
-
286
+ exports.engineSchema = engineSchema;
121
287
  const personSchema = Joi.object({
122
- name: Joi.string().min(1).required(),
123
- email: Joi.string().email().optional(),
124
- url: Joi.string().uri().optional(),
288
+ name: Joi.string().min(1).required(),
289
+ email: Joi.string().email().optional(),
290
+ url: Joi.string().uri().optional(),
291
+ }).meta({
292
+ className: 'TPerson',
293
+ unknownType: 'any',
125
294
  });
126
-
295
+ exports.personSchema = personSchema;
127
296
  const distSchema = Joi.object({
128
- tarball: Joi.alternatives().try(Joi.string().uri(), Joi.string()).required(),
129
- integrity: Joi.string().required(),
297
+ tarball: Joi.alternatives().try(Joi.string().uri(), Joi.string()).required(),
298
+ integrity: Joi.string().required(),
299
+ size: Joi.number().optional(),
300
+ }).meta({
301
+ className: 'TDist',
302
+ unknownType: 'any',
130
303
  });
131
-
304
+ exports.distSchema = distSchema;
132
305
  const statsSchema = Joi.object({
133
- downloads: Joi.number().integer().greater(-1),
134
- star: Joi.number().default(0),
135
- purchases: Joi.number().default(0),
306
+ downloads: Joi.number().integer().greater(-1),
307
+ star: Joi.number().default(0),
308
+ purchases: Joi.number().default(0),
309
+ }).meta({
310
+ className: 'TStats',
311
+ unknownType: 'any',
136
312
  });
137
-
138
- const childrenSchema = Joi.object({
139
- name: Joi.string().min(1).required(),
140
- resolved: Joi.alternatives().try(Joi.string().uri(), Joi.string()).required(),
141
- mountPoints: Joi.array()
142
- .items(
143
- Joi.object({
144
- root: Joi.object({
145
- interfaceName: Joi.string().trim().required(),
146
- prefix: Joi.string().trim().min(1).required(),
147
- }).required(),
148
- child: Joi.object({
149
- interfaceName: Joi.string().trim().required(),
150
- }).required(),
151
- services: Joi.array().items(serviceSchema).unique('name'),
152
- })
153
- )
154
- .optional()
155
- .default([]),
313
+ exports.statsSchema = statsSchema;
314
+ const urlListSchema = Joi.alternatives().try(Joi.string().uri(), Joi.array().items(Joi.string().uri()).min(1));
315
+ const componentSourceSchema = Joi.alternatives().try(Joi.object({
316
+ url: urlListSchema.required(),
317
+ // 虽然 url 无法像 store 一样根据 version 获取指定版本的 component, 但是 version 仍然可以用于限制 component 版本
318
+ version: Joi.alternatives().try(Joi.string().valid('latest'), Joi.semverRange().valid()),
319
+ }), Joi.object({
320
+ store: urlListSchema,
321
+ name: blockletNameSchema.required(),
322
+ // TODO 目前只能支持锁死的版本号,接下载需要支持自适应的版本号,比如 4.x
323
+ version: Joi.alternatives().try(Joi.string().valid('latest'), Joi.semverRange().valid()).default('latest'),
324
+ }));
325
+ const componentSchemaProps = {
326
+ source: componentSourceSchema.required(),
327
+ // Can the dynamic component be deleted before I delete myself
328
+ required: Joi.boolean(),
329
+ // These props in dynamic component is for suggestion only and can be changed by user or other dynamic component
330
+ title: titleSchema,
331
+ description: descriptionSchema,
332
+ mountPoint: mountPointSchema,
333
+ // backward compatible, useless
334
+ name: blockletNameSchema,
335
+ };
336
+ const staticComponentSchemaProps = {
337
+ source: componentSourceSchema.required(),
338
+ name: blockletNameSchema.required(),
339
+ title: titleSchema,
340
+ description: descriptionSchema,
341
+ mountPoint: mountPointSchema.required(),
342
+ };
343
+ const createComponentSchema = (schema, allowEmptyStore) => Joi.object(schema).custom((value, helper) => {
344
+ if (!allowEmptyStore && value.source && value.source.name && !value.source.store) {
345
+ // @ts-expect-error
346
+ return helper.message(`missing 'store' in source of component ${value.name}`);
347
+ }
348
+ return value;
156
349
  });
157
-
350
+ const componentSchema = createComponentSchema(componentSchemaProps).meta({
351
+ className: 'TComponent',
352
+ unknownType: 'any',
353
+ });
354
+ exports.componentSchema = componentSchema;
355
+ const staticComponentSchema = createComponentSchema(staticComponentSchemaProps).meta({
356
+ className: 'TStaticComponent',
357
+ unknownType: 'any',
358
+ });
359
+ const componentSchemaWithoutStoreCheck = createComponentSchema(componentSchemaProps, true);
360
+ const staticComponentSchemaWithoutStoreCheck = createComponentSchema(staticComponentSchemaProps, true);
361
+ const componentsSchema = ({ isStatic, checkStore } = {}) => {
362
+ const arr = isStatic
363
+ ? [staticComponentSchema, staticComponentSchemaWithoutStoreCheck]
364
+ : [componentSchema, componentSchemaWithoutStoreCheck];
365
+ let schema = Joi.array()
366
+ .items(checkStore ? arr[0] : arr[1])
367
+ .optional()
368
+ .custom((value, helper) => {
369
+ if (isStatic) {
370
+ const names = value.map((x) => x.name);
371
+ const duplicateName = names.find((x, i) => names.indexOf(x) !== i);
372
+ if (duplicateName) {
373
+ // @ts-expect-error
374
+ return helper.message(`find duplicate name "${duplicateName}" in components`);
375
+ }
376
+ }
377
+ return value;
378
+ });
379
+ if (!isStatic) {
380
+ schema = schema.default([]);
381
+ }
382
+ return schema;
383
+ };
158
384
  const signatureSchema = Joi.object({
159
- type: Joi.string().required(),
160
- name: Joi.string().required(),
161
- signer: Joi.string().required(),
162
- pk: Joi.string().required(),
163
- created: Joi.string().isoDate().required(),
164
- sig: Joi.string().required(),
165
- excludes: Joi.array().items(Joi.string()).optional(),
166
- appended: Joi.array().items(Joi.string()).optional(),
385
+ type: Joi.string().required(),
386
+ name: Joi.string().required(),
387
+ signer: Joi.string().required(),
388
+ pk: Joi.string().required(),
389
+ created: Joi.string().isoDate().required(),
390
+ sig: Joi.string().required(),
391
+ excludes: Joi.array().items(Joi.string()).optional(),
392
+ appended: Joi.array().items(Joi.string()).optional(),
393
+ // delegation token 校验所需字段
394
+ delegatee: Joi.string(),
395
+ delegateePk: Joi.string(),
396
+ delegation: Joi.string(),
397
+ }).meta({
398
+ className: 'TSignature',
399
+ unknownType: 'any',
167
400
  });
168
-
169
- const createBlockletSchema = (
170
- baseDir,
171
- { ensureMain = false, ensureFiles = false, ensureDist = false, ...schemaOptions } = {}
172
- ) => {
173
- if (!baseDir || !fs.existsSync(baseDir)) {
174
- // eslint-disable-next-line no-param-reassign
175
- ensureFiles = false;
176
- }
177
-
178
- return Joi.object({
401
+ exports.signatureSchema = signatureSchema;
402
+ const localeList = ['en', 'zh', 'fr', 'ru', 'ar', 'es', 'de', 'pt', 'ja', 'hi'];
403
+ const navigationItemProps = {
404
+ id: Joi.string().custom(checkId),
405
+ title: Joi.alternatives()
406
+ .try(Joi.string().min(1).max(MAX_TITLE_LENGTH), Joi.object()
407
+ .min(1)
408
+ .pattern(Joi.string().valid(...localeList), Joi.string().min(1).max(MAX_TITLE_LENGTH)))
409
+ .required(),
410
+ link: Joi.alternatives().try(Joi.string().custom(checkLinkHelper), Joi.object()
411
+ .min(1)
412
+ .pattern(Joi.string().valid(...localeList), Joi.string().custom(checkLinkHelper))),
413
+ component: Joi.string().min(1),
414
+ section: Joi.array().items(Joi.string().min(1)).single(),
415
+ role: Joi.array().items(Joi.string().min(1)).single(),
416
+ icon: Joi.string().min(1),
417
+ visible: Joi.boolean(),
418
+ };
419
+ const navigationItemSchema = Joi.object({
420
+ ...navigationItemProps,
421
+ items: Joi.array().items(Joi.object({ ...navigationItemProps }).rename('child', 'component')),
422
+ })
423
+ .rename('child', 'component')
424
+ .meta({
425
+ className: 'TNavigationItem',
426
+ unknownType: 'any',
427
+ });
428
+ exports.navigationItemSchema = navigationItemSchema;
429
+ const navigationSchema = Joi.array()
430
+ .items(navigationItemSchema)
431
+ .unique((a, b) => {
432
+ if (a.id && b.id) {
433
+ return a.id === b.id;
434
+ }
435
+ return false;
436
+ })
437
+ .meta({
438
+ className: 'TNavigation',
439
+ unknownType: 'any',
440
+ });
441
+ exports.navigationSchema = navigationSchema;
442
+ const themeSchema = Joi.object({
443
+ background: Joi.alternatives().try(Joi.string().min(1), Joi.object({
444
+ header: Joi.string().min(1),
445
+ footer: Joi.string().min(1),
446
+ default: Joi.string().min(1),
447
+ }).min(1)),
448
+ }).meta({
449
+ className: 'TTheme',
450
+ unknownType: 'any',
451
+ });
452
+ exports.themeSchema = themeSchema;
453
+ const authConfigSchema = Joi.object({
454
+ whoCanAccess: Joi.string().valid('owner', 'invited', 'all'),
455
+ profileFields: Joi.array().items(Joi.string().valid('fullName', 'email', 'avatar', 'phone')).unique(),
456
+ ignoreUrls: Joi.array().items(Joi.string().min(1)),
457
+ allowSwitchProfile: Joi.boolean(),
458
+ blockUnauthenticated: Joi.boolean(),
459
+ blockUnauthorized: Joi.boolean(),
460
+ })
461
+ .options({ stripUnknown: true })
462
+ .meta({
463
+ className: 'TAuthConfig',
464
+ unknownType: 'any',
465
+ });
466
+ exports.authConfigSchema = authConfigSchema;
467
+ const blockletMetaProps = {
179
468
  did: Joi.DID().trim().required(),
180
469
  version: Joi.semver().valid().required(),
181
- name: Joi.string()
182
- .custom((value) => {
183
- validateName(value);
184
- return value;
185
- })
186
- .required(),
187
- description: Joi.string().trim().required(),
188
- group: Joi.string().valid(...BLOCKLET_GROUPS).required(), // prettier-ignore
189
- main: Joi.when('group', {
190
- is: Joi.valid(BlockletGroup.gateway),
191
- then: Joi.forbidden(),
192
- otherwise: ensureMain ? Joi.file().exists({ baseDir }).required() : Joi.string().trim().required(),
193
- }),
194
- title: Joi.string().trim().optional().allow(''),
195
- logo: ensureFiles ? Joi.file().trim().exists({ baseDir }).optional() : Joi.string().trim().optional(),
470
+ name: Joi.string().optional(),
471
+ description: descriptionSchema.required(),
472
+ group: Joi.string()
473
+ .valid(...BLOCKLET_GROUPS)
474
+ .required(),
475
+ main: Joi.string().trim().required(),
476
+ title: titleSchema.optional().allow(''),
477
+ logo: Joi.string().trim().optional(),
196
478
  specVersion: Joi.semver().valid().gte('1.0.0').optional(),
197
-
198
479
  author: personSchema.optional(),
199
480
  contributors: Joi.array().items(personSchema).optional(),
200
481
  maintainers: Joi.array().items(personSchema).optional(),
201
-
202
482
  community: Joi.string().uri().optional().allow('').default(''),
203
483
  documentation: Joi.string().uri().optional().allow('').default(''),
204
484
  homepage: Joi.string().uri().optional().allow('').default(''),
205
485
  license: Joi.string().optional().allow('').default(''),
206
486
  support: Joi.alternatives().try(Joi.string().uri(), Joi.string().email()).optional(),
207
-
208
487
  // which asset factory to mint blocklet purchase nft
209
488
  // This is usually created and maintained by `blocklet publish` command
210
489
  nftFactory: Joi.DID().optional().allow('').default(''),
211
-
212
- // Set the price and shares of the blocklet
213
- charging: Joi.object({
214
- // How much primary tokens required to purchase this blocklet
215
- price: Joi.number(),
216
- // How much secondary tokens required to purchase this block
217
- tokens: Joi.array()
218
- .max(4)
219
- .items(
220
- Joi.object({
221
- price: Joi.number().required(),
490
+ // Set the price and share of the blocklet
491
+ payment: Joi.object({
492
+ // Currently only supports 1 token
493
+ price: Joi.array()
494
+ .max(1)
495
+ .items(Joi.object({
496
+ value: Joi.number().greater(0).required(),
222
497
  address: Joi.DID().required(), // token address
223
- })
224
- ),
225
- // List of beneficiaries that shares the token earns from blocklet purchase
226
- // If left empty, blocklet publish workflow will enforce both the developer and the registry account
227
- // If not, the blocklet publish workflow will enforce the registry account
228
- // In theory, the developer can split as many shares as he wants
229
- // Such as, some developers coauthored the blocklet, and their income get instant settlement on blocklet purchase
230
- // For performance reasons, we need to set a hard limit for shares count
231
- shares: Joi.array()
232
- .max(4)
233
- .items(
234
- Joi.object({
498
+ }))
499
+ .default([]),
500
+ // List of beneficiaries that share the token earns from blocklet purchase
501
+ // If left empty, blocklet publish workflow will enforce both the developer and the registry account
502
+ // If not, the blocklet publish workflow will enforce the registry account
503
+ // In theory, the developer can split as many share as he wants
504
+ // Such as, some developers coauthored the blocklet, and their income get instant settlement on blocklet purchase
505
+ // For performance reasons, we need to set a hard limit for share count
506
+ share: Joi.array()
507
+ .max(4)
508
+ .items(Joi.object({
235
509
  name: Joi.string().required(),
236
510
  address: Joi.DID().required(),
237
- share: Joi.number().min(0).max(1).required(),
238
- })
239
- ),
240
- })
241
- .default({ price: 0, tokens: [], shares: [] })
242
- .optional(),
243
-
511
+ value: Joi.number().greater(0).max(1).required(),
512
+ }))
513
+ .default([])
514
+ .custom((value) => {
515
+ // If share is not empty, the total value should be 1
516
+ if (value.length === 0) {
517
+ return value;
518
+ }
519
+ const total = value.reduce((acc, cur) => acc + cur.value, 0);
520
+ if (total !== 1) {
521
+ throw new Error(`Invalid blocklet payment share config: total share must be 1, got ${total}`);
522
+ }
523
+ return value;
524
+ }, 'invalid blocklet share'),
525
+ componentPrice: Joi.array()
526
+ .items(Joi.object({
527
+ parentPriceRange: Joi.array()
528
+ .items(Joi.number())
529
+ // FIXME
530
+ // 1. 有重叠的区间时
531
+ // 2. 区间不连续时
532
+ // 3. 区间边界
533
+ .custom((value, helper) => {
534
+ if (value.length !== 2) {
535
+ // @ts-ignore
536
+ return helper.message('length of range should be 2');
537
+ }
538
+ if (value[0] < 0) {
539
+ // @ts-ignore
540
+ return helper.message('the first value should not less than 0 in range');
541
+ }
542
+ if (value[1] <= value[0]) {
543
+ // @ts-ignore
544
+ return helper.message('the second value should greater than the first value in range');
545
+ }
546
+ return value;
547
+ }),
548
+ type: Joi.string().valid('fixed', 'percentage').required(),
549
+ value: Joi.number().greater(0).required(),
550
+ }))
551
+ .single(),
552
+ }).default({ price: [], share: [] }),
244
553
  keywords: Joi.alternatives()
245
- .try(Joi.string().trim().min(1), Joi.array().items(Joi.string().min(1)))
246
- .optional(),
554
+ .try(Joi.string().trim().min(1), Joi.array().items(Joi.string().min(1)))
555
+ .optional(),
247
556
  tags: Joi.alternatives()
248
- .try(Joi.string().trim().min(1), Joi.array().items(Joi.string().min(1)))
249
- .optional(),
250
-
557
+ .try(Joi.string().trim().min(1), Joi.array().items(Joi.string().min(1)))
558
+ .optional(),
251
559
  gitHash: Joi.string().optional().allow(''),
252
560
  repository: Joi.alternatives()
253
- .try(
254
- Joi.string().min(1),
255
- Joi.object({
256
- type: Joi.string().valid('git', 'https', 'svn').required(),
257
- url: Joi.string().uri().required(),
258
- directory: Joi.string(),
259
- })
260
- )
261
- .optional(),
262
-
561
+ .try(Joi.string().min(1), Joi.object({
562
+ type: Joi.string().valid('git', 'https', 'svn').required(),
563
+ url: Joi.string().uri().required(),
564
+ directory: Joi.string(),
565
+ }))
566
+ .optional(),
263
567
  timeout: Joi.object({
264
- start: Joi.number().min(10).max(600), // start check timeout, 10 seconds ~ 10 minutes
568
+ start: Joi.number().min(10).max(600), // start check timeout, 10 seconds ~ 10 minutes
265
569
  }).default({ start: 60 }),
266
-
267
570
  requirements: Joi.object({
268
- abtnode: Joi.semverRange().valid(),
269
- os: Joi.alternatives().try(
270
- Joi.string().valid('*', ...BLOCKLET_PLATFORMS),
271
- Joi.array()
272
- .items(Joi.string().valid(...BLOCKLET_PLATFORMS))
273
- .min(1)
274
- ),
275
- cpu: Joi.alternatives().try(
276
- Joi.string().valid('*', ...BLOCKLET_ARCHITECTURES),
277
- Joi.array()
278
- .items(Joi.string().valid(...BLOCKLET_ARCHITECTURES))
279
- .min(1)
280
- ),
281
- }).default({ abtnode: BLOCKLET_LATEST_REQUIREMENT_ABTNODE, os: '*', cpu: '*' }),
282
-
571
+ abtnode: Joi.semverRange().valid(),
572
+ server: Joi.semverRange().valid(),
573
+ os: Joi.alternatives().try(Joi.string().valid('*', ...BLOCKLET_PLATFORMS), Joi.array()
574
+ .items(Joi.string().valid(...BLOCKLET_PLATFORMS))
575
+ .min(1)),
576
+ cpu: Joi.alternatives().try(Joi.string().valid('*', ...BLOCKLET_ARCHITECTURES), Joi.array()
577
+ .items(Joi.string().valid(...BLOCKLET_ARCHITECTURES))
578
+ .min(1)),
579
+ fuels: Joi.array().items(Joi.object({
580
+ endpoint: Joi.string().trim().required(),
581
+ address: Joi.string().trim(),
582
+ value: Joi.string().trim().required(),
583
+ reason: Joi.string().trim().required(),
584
+ })),
585
+ nodejs: Joi.semverRange().valid(),
586
+ }).default({ server: BLOCKLET_LATEST_REQUIREMENT_SERVER, os: '*', cpu: '*', nodejs: '*' }),
283
587
  // interfaces: https://github.com/blocklet/blocklet-specification/issues/2
284
588
  interfaces: Joi.array()
285
- .items(interfaceSchema)
286
- .unique('name')
287
- .min(1)
288
- .custom((value, helper) => {
589
+ .items(interfaceSchema)
590
+ .unique('name')
591
+ .min(1)
592
+ .custom((value, helper) => {
289
593
  const webItems = value.filter((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB);
290
594
  if (webItems.length > 1) {
291
- return helper.message(`Only one ${BLOCKLET_INTERFACE_TYPE_WEB} interface can be declared`);
595
+ // @ts-expect-error
596
+ return helper.message(`Only one ${BLOCKLET_INTERFACE_TYPE_WEB} interface can be declared`);
292
597
  }
293
-
294
598
  const wellknownItems = value.filter((x) => x.type === BLOCKLET_INTERFACE_TYPE_WELLKNOWN);
295
599
  for (const x of wellknownItems) {
296
- if (!x.prefix.startsWith(WELLKNOWN_PATH_PREFIX)) {
297
- return helper.message(`Wellknown path prefix must start with: ${WELLKNOWN_PATH_PREFIX}`);
298
- }
600
+ if (!x.prefix.startsWith(WELLKNOWN_PATH_PREFIX)) {
601
+ // @ts-expect-error
602
+ return helper.message(`Wellknown path prefix must start with: ${WELLKNOWN_PATH_PREFIX}`);
603
+ }
299
604
  }
300
-
301
605
  return value;
302
- })
303
- .default([]),
304
-
606
+ })
607
+ .default([]),
305
608
  // environments
306
- environments: Joi.array().items(environmentSchema).default([]).optional(),
307
-
609
+ environments: Joi.array()
610
+ .items(environmentSchema)
611
+ .default([])
612
+ .optional()
613
+ .custom((data, helper) => {
614
+ if (data && data.length) {
615
+ const duplicates = data.filter((x, index) => data.findIndex((y) => y.name === x.name) !== index);
616
+ if (duplicates.length) {
617
+ // @ts-expect-error
618
+ return helper.message(`find duplicate environment names ${duplicates.map((x) => x.name).join(', ')}`);
619
+ }
620
+ }
621
+ return data;
622
+ }),
308
623
  // scripts & hooks
309
624
  scripts: scriptsSchema,
310
-
311
625
  // capabilities
312
626
  capabilities: Joi.object({
313
- clusterMode: Joi.boolean().default(false), // Can blocklet be started in cluster mode
314
- }).default({}),
315
-
627
+ clusterMode: Joi.boolean().default(false),
628
+ // added in 1.2.2
629
+ component: Joi.boolean().default(true),
630
+ didSpace: Joi.string()
631
+ .valid(...Object.values(BLOCKLET_APP_SPACE_ENDPOINTS))
632
+ .optional(),
633
+ navigation: Joi.boolean().default(true), // Should blocklet join navigation auto-merge process
634
+ }).default({
635
+ clusterMode: false,
636
+ component: true,
637
+ }),
316
638
  // Other contents to be included in the bundle
317
- files: Joi.array()
318
- .items(
319
- ensureFiles
320
- ? // eslint-disable-next-line
321
- Joi.file().exists({ baseDir, canSkip: (dir, name) => [BLOCKLET_ENTRY_FILE, BLOCKLET_BUNDLE_FILE].includes(name) || isGlob(name) }) // prettier-ignore
322
- : Joi.string().trim()
323
- )
324
- .optional(),
325
-
639
+ files: Joi.array().items(Joi.string().trim()).optional(),
326
640
  // TODO: this field should be refactored in future version
327
641
  engine: Joi.alternatives().try(engineSchema, Joi.array().items(engineSchema)).optional(),
328
-
329
- // TODO: following fields only exist for backward compatibility
330
- publicUrl: Joi.string().optional().allow(''),
331
- adminUrl: Joi.string().optional().allow(''),
332
- configUrl: Joi.string().optional().allow(''),
333
- docUrl: Joi.string().optional().allow(''),
334
-
335
642
  // NOTE: following fields are appended by registry or bundling process
336
643
  screenshots: Joi.array().items(Joi.string().min(1)).optional().default([]),
337
644
  logoUrl: Joi.string().optional().allow(''),
338
- dist: ensureDist ? distSchema.required() : distSchema.optional(),
645
+ dist: distSchema.optional(),
339
646
  stats: statsSchema.optional(),
340
647
  htmlAst: Joi.any().optional(),
341
648
  path: Joi.string().optional(),
342
649
  signatures: Joi.array().items(signatureSchema).optional(),
343
650
  lastPublishedAt: Joi.string().isoDate().optional(),
344
-
345
651
  // blocklet component support
346
- children: Joi.array().items(childrenSchema).optional().default([]),
347
- })
348
- .rename('public_url', 'publicUrl', { ignoreUndefined: true, override: true })
349
- .rename('admin_url', 'adminUrl', { ignoreUndefined: true, override: true })
350
- .rename('config_url', 'configUrl', { ignoreUndefined: true, override: true })
351
- .rename('tags', 'keywords', { ignoreUndefined: true, override: true })
352
- .rename('requiredEnvironments', 'environments', { ignoreUndefined: true, override: true })
353
- .options({ stripUnknown: true, noDefaults: false, ...schemaOptions });
652
+ components: componentsSchema(),
653
+ staticComponents: componentsSchema({ isStatic: true }),
654
+ // navigation & theme
655
+ navigation: navigationSchema,
656
+ theme: themeSchema,
657
+ copyright: Joi.object({
658
+ owner: Joi.string().min(1),
659
+ year: Joi.alternatives().try(Joi.string(), Joi.number()),
660
+ }),
661
+ // NOTE: following fields only exist in blocklet server and cannot be set manually
662
+ bundleName: Joi.string(),
663
+ bundleDid: Joi.DID().trim(),
664
+ storeId: Joi.string(),
354
665
  };
355
-
356
- module.exports = {
357
- createBlockletSchema,
358
- interfaceSchema,
359
- environmentSchema,
360
- scriptsSchema,
361
- personSchema,
362
- distSchema,
666
+ const blockletMetaSchema = Joi.object(blockletMetaProps).options({ stripUnknown: true, noDefaults: false }).meta({
667
+ className: 'TBlockletMeta',
668
+ unknownType: 'any',
669
+ });
670
+ exports.blockletMetaSchema = blockletMetaSchema;
671
+ const createBlockletSchema = (baseDir, { ensureMain = false, ensureFiles = false, ensureDist = false, ensureComponentStore = true, ensureName = false, skipValidateDidName = false, ...schemaOptions } = {}) => {
672
+ if (!baseDir || !fs_1.default.existsSync(baseDir)) {
673
+ // eslint-disable-next-line no-param-reassign
674
+ ensureFiles = false;
675
+ }
676
+ return Joi.object({
677
+ ...blockletMetaProps,
678
+ main: Joi.when('group', {
679
+ is: Joi.valid(BlockletGroup.gateway),
680
+ then: Joi.forbidden(),
681
+ otherwise: ensureMain ? Joi.file().exists({ baseDir }).required() : Joi.string().trim().required(),
682
+ }),
683
+ logo: ensureFiles ? Joi.file().trim().exists({ baseDir }).optional() : Joi.string().trim().optional(),
684
+ // Other contents to be included in the bundle
685
+ files: Joi.array()
686
+ .items(ensureFiles
687
+ ? // eslint-disable-next-line
688
+ Joi.file().exists({ baseDir, canSkip: (dir, name) => [BLOCKLET_ENTRY_FILE, BLOCKLET_BUNDLE_FILE].includes(name) || (0, is_glob_1.default)(name) }) // prettier-ignore
689
+ : Joi.string().trim())
690
+ .optional(),
691
+ dist: ensureDist ? distSchema.required() : distSchema.optional(),
692
+ components: componentsSchema({ checkStore: ensureComponentStore }),
693
+ staticComponents: componentsSchema({ isStatic: true, checkStore: ensureComponentStore }),
694
+ name: ensureName ? Joi.string().optional() : Joi.string().required(),
695
+ })
696
+ .options({ stripUnknown: true, noDefaults: false, ...schemaOptions })
697
+ .rename('children', 'components')
698
+ .custom((data, helper) => {
699
+ const { did, name } = data;
700
+ let cacheError;
701
+ if ((0, did_1.isValid)(did)) {
702
+ try {
703
+ (0, name_1.validateNewDid)(did);
704
+ return data;
705
+ }
706
+ catch (e) {
707
+ cacheError = e;
708
+ }
709
+ }
710
+ /* ------------- 兼容旧的逻辑,旧逻辑使用 name 生成一个 did ------------- */
711
+ // 此时 name 必须存在
712
+ if (name) {
713
+ (0, name_1.validateName)(name, { checkDid: !skipValidateDidName });
714
+ const expectDid = (0, did_2.default)(name);
715
+ if (expectDid !== did) {
716
+ // @ts-ignore
717
+ return helper.message(`The did of name "${name}" should be "${expectDid}"`);
718
+ }
719
+ return data;
720
+ /* ------------------------------------------------------ */
721
+ }
722
+ if (cacheError) {
723
+ return helper.message(cacheError.message);
724
+ }
725
+ return data;
726
+ });
727
+ };
728
+ exports.createBlockletSchema = createBlockletSchema;
729
+ exports.default = {
730
+ blockletNameSchema,
731
+ componentSchema,
732
+ endpointSchema,
733
+ serviceSchema,
734
+ createBlockletSchema,
735
+ interfaceSchema,
736
+ environmentSchema,
737
+ environmentNameSchema,
738
+ scriptsSchema,
739
+ personSchema,
740
+ distSchema,
741
+ titleSchema,
742
+ descriptionSchema,
743
+ logoSchema,
744
+ navigationSchema,
745
+ themeSchema,
746
+ mountPointSchema,
747
+ updateMountPointSchema,
748
+ authConfigSchema,
363
749
  };