@blocklet/meta 1.8.33 → 1.8.35

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 (58) hide show
  1. package/lib/channel.d.ts +27 -0
  2. package/lib/channel.js +32 -32
  3. package/lib/constants.d.ts +2 -0
  4. package/lib/constants.js +6 -3
  5. package/lib/did.d.ts +10 -0
  6. package/lib/did.js +18 -24
  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 +10 -0
  12. package/lib/extension.js +78 -77
  13. package/lib/file.d.ts +21 -0
  14. package/lib/file.js +44 -39
  15. package/lib/fix.d.ts +33 -0
  16. package/lib/fix.js +218 -208
  17. package/lib/get-component-process-id.d.ts +5 -0
  18. package/lib/get-component-process-id.js +13 -14
  19. package/lib/has-reserved-key.d.ts +3 -0
  20. package/lib/has-reserved-key.js +10 -9
  21. package/lib/index.d.ts +82 -0
  22. package/lib/index.js +51 -34
  23. package/lib/info.d.ts +13 -0
  24. package/lib/info.js +58 -60
  25. package/lib/name.d.ts +5 -0
  26. package/lib/name.js +14 -7
  27. package/lib/nft-templates.d.ts +86 -0
  28. package/lib/nft-templates.js +47 -42
  29. package/lib/parse-navigation.d.ts +3 -0
  30. package/lib/parse-navigation.js +168 -209
  31. package/lib/parse.d.ts +22 -0
  32. package/lib/parse.js +71 -82
  33. package/lib/payment/index.d.ts +254 -0
  34. package/lib/payment/index.js +13 -6
  35. package/lib/payment/v1.d.ts +185 -0
  36. package/lib/payment/v1.js +80 -81
  37. package/lib/payment/v2.d.ts +242 -0
  38. package/lib/payment/v2.js +453 -531
  39. package/lib/schema.d.ts +50 -0
  40. package/lib/schema.js +405 -397
  41. package/lib/service-configs/auth.json +61 -61
  42. package/lib/service.d.ts +26 -0
  43. package/lib/service.js +69 -85
  44. package/lib/types/index.d.ts +1 -0
  45. package/lib/types/index.js +18 -0
  46. package/lib/types/schema.d.ts +241 -0
  47. package/lib/types/schema.js +3 -0
  48. package/lib/util-meta.d.ts +42 -0
  49. package/lib/util-meta.js +138 -158
  50. package/lib/util.d.ts +185 -0
  51. package/lib/util.js +359 -414
  52. package/lib/validate.d.ts +10 -0
  53. package/lib/validate.js +28 -34
  54. package/lib/verify-multi-sig.d.ts +3 -0
  55. package/lib/verify-multi-sig.js +94 -101
  56. package/lib/wallet.d.ts +9 -0
  57. package/lib/wallet.js +17 -27
  58. package/package.json +41 -18
package/lib/schema.js CHANGED
@@ -1,526 +1,534 @@
1
- /* eslint-disable newline-per-chained-call */
2
- const fs = require('fs');
3
- const JOI = require('joi');
4
- const cjkLength = require('cjk-length').default;
5
- const isGlob = require('is-glob');
6
- const { semver, semverRange } = require('joi-extension-semver');
7
-
8
- const { fileExtension, didExtension } = require('./extension');
9
- const { validateName } = require('./name');
10
- const {
11
- BLOCKLET_GROUPS,
12
- BLOCKLET_PLATFORMS,
13
- BLOCKLET_ARCHITECTURES,
14
- BLOCKLET_INTERFACE_TYPES,
15
- BLOCKLET_INTERFACE_PROTOCOLS,
16
- BLOCKLET_ENTRY_FILE,
17
- BLOCKLET_BUNDLE_FILE,
18
- BLOCKLET_DEFAULT_PORT_NAME,
19
- BLOCKLET_DYNAMIC_PATH_PREFIX,
20
- BlockletGroup,
21
- BLOCKLET_LATEST_REQUIREMENT_SERVER,
22
- BLOCKLET_INTERFACE_TYPE_WEB,
23
- BLOCKLET_INTERFACE_TYPE_WELLKNOWN,
24
- } = require('./constants');
25
-
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.statsSchema = exports.titleSchema = exports.themeSchema = exports.signatureSchema = exports.serviceSchema = exports.scriptsSchema = exports.personSchema = exports.navigationSchema = exports.navigationItemSchema = exports.mountPointSchema = exports.logoSchema = exports.interfaceSchema = exports.environmentSchema = exports.engineSchema = exports.endpointSchema = exports.distSchema = exports.descriptionSchema = exports.createBlockletSchema = exports.componentSchema = exports.blockletNameSchema = exports.blockletMetaSchema = void 0;
18
+ const fs_1 = __importDefault(require("fs"));
19
+ const joi_1 = __importDefault(require("joi"));
20
+ // eslint-disable-next-line import/no-named-default
21
+ const cjk_length_1 = __importDefault(require("cjk-length"));
22
+ const is_glob_1 = __importDefault(require("is-glob"));
23
+ const joi_extension_semver_1 = require("joi-extension-semver");
24
+ const extension_1 = require("./extension");
25
+ const name_1 = require("./name");
26
+ const constants_1 = __importDefault(require("./constants"));
27
+ const cjkLength = cjk_length_1.default.default;
28
+ 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_STORAGE_ENDPOINTS, } = constants_1.default;
26
29
  const WELLKNOWN_PATH_PREFIX = '/.well-known';
27
30
  const MAX_TITLE_LENGTH = 24;
28
31
  const MAX_NAME_LENGTH = 32;
29
-
30
- const Joi = JOI.extend(semver).extend(semverRange).extend(fileExtension).extend(didExtension);
31
-
32
+ const Joi = joi_1.default.extend(joi_extension_semver_1.semver)
33
+ .extend(joi_extension_semver_1.semverRange)
34
+ .extend(extension_1.fileExtension)
35
+ .extend(extension_1.didExtension);
32
36
  const titleSchema = Joi.string()
33
- .trim()
34
- .min(1)
35
- .custom((value) => {
37
+ .trim()
38
+ .min(1)
39
+ .custom((value) => {
36
40
  if (cjkLength(value) > MAX_TITLE_LENGTH) {
37
- throw new Error(
38
- `title length should not exceed ${MAX_TITLE_LENGTH} (see: https://www.npmjs.com/package/cjk-length)`
39
- );
41
+ throw new Error(`title length should not exceed ${MAX_TITLE_LENGTH} (see: https://www.npmjs.com/package/cjk-length)`);
40
42
  }
41
-
42
43
  return value;
43
- });
44
- const descriptionSchema = Joi.string().trim().min(3).max(160);
44
+ })
45
+ .meta({ className: 'TTitle' });
46
+ exports.titleSchema = titleSchema;
47
+ const descriptionSchema = Joi.string().trim().min(3).max(160).meta({ className: 'TDescription' });
48
+ exports.descriptionSchema = descriptionSchema;
45
49
  const logoSchema = Joi.string()
46
- .uri({ scheme: ['http', 'https'], allowRelative: true })
47
- .allow('');
48
- const mountPointSchema = Joi.string().trim().min(1);
49
-
50
+ .uri({ scheme: ['http', 'https'], allowRelative: true })
51
+ .allow('')
52
+ .meta({ className: 'TLogo' });
53
+ exports.logoSchema = logoSchema;
54
+ const mountPointSchema = Joi.string().trim().min(1).meta({ className: 'TMountPoint' });
55
+ exports.mountPointSchema = mountPointSchema;
50
56
  const blockletNameSchema = Joi.string()
51
- .custom((value) => {
52
- validateName(value);
57
+ .custom((value) => {
58
+ (0, name_1.validateName)(value);
53
59
  return value;
54
- })
55
- .max(MAX_NAME_LENGTH);
56
-
60
+ })
61
+ .max(MAX_NAME_LENGTH)
62
+ .meta({ className: 'TBlockletName' });
63
+ exports.blockletNameSchema = blockletNameSchema;
57
64
  const environmentSchema = Joi.object({
58
- name: Joi.string().trim().required(),
59
- description: Joi.string().trim().required(),
60
- default: Joi.string().optional().allow('').default(''),
61
- required: Joi.boolean().default(false),
62
- secure: Joi.boolean().default(false),
63
- validation: Joi.string().optional(),
64
- shared: Joi.boolean().default((parent) => !parent.secure),
65
- }).custom((x, helper) => {
66
- if (x.secure && x.default) {
67
- return helper.message(`Cannot declare default value for secure env ${x.name}`);
68
- }
69
-
70
- return x;
65
+ name: Joi.string().trim().required(),
66
+ description: Joi.string().trim().required(),
67
+ default: Joi.string().optional().allow('').default(''),
68
+ required: Joi.boolean().default(false),
69
+ secure: Joi.boolean().default(false),
70
+ validation: Joi.string().optional(),
71
+ shared: Joi.boolean().default((parent) => !parent.secure),
72
+ })
73
+ .custom((x, helper) => {
74
+ if (x.secure && x.default) {
75
+ // @ts-expect-error
76
+ return helper.message(`Cannot declare default value for secure env ${x.name}`);
77
+ }
78
+ return x;
79
+ })
80
+ .meta({
81
+ className: 'TEnvironment',
82
+ unknownType: 'any',
71
83
  });
72
-
84
+ exports.environmentSchema = environmentSchema;
73
85
  const scriptsSchema = Joi.object({
74
- dev: Joi.string().trim().min(1),
75
- e2eDev: Joi.string().trim().min(1),
76
- preInstall: Joi.string().trim().min(1),
77
- postInstall: Joi.string().trim().min(1),
78
- preStart: Joi.string().trim().min(1),
79
- postStart: Joi.string().trim().min(1),
80
- preStop: Joi.string().trim().min(1),
81
- preUninstall: Joi.string().trim().min(1),
82
- preConfig: Joi.string().trim().min(1),
86
+ dev: Joi.string().trim().min(1),
87
+ e2eDev: Joi.string().trim().min(1),
88
+ preInstall: Joi.string().trim().min(1),
89
+ postInstall: Joi.string().trim().min(1),
90
+ preStart: Joi.string().trim().min(1),
91
+ postStart: Joi.string().trim().min(1),
92
+ preStop: Joi.string().trim().min(1),
93
+ preUninstall: Joi.string().trim().min(1),
94
+ preConfig: Joi.string().trim().min(1),
83
95
  })
84
- .rename('pre-install', 'preInstall')
85
- .rename('post-install', 'postInstall')
86
- .rename('pre-start', 'preStart')
87
- .rename('post-start', 'postStart')
88
- .rename('pre-stop', 'preStop')
89
- .rename('pre-uninstall', 'preUninstall')
90
- .rename('pre-config', 'preConfig')
91
- .optional();
92
-
96
+ .rename('pre-install', 'preInstall')
97
+ .rename('post-install', 'postInstall')
98
+ .rename('pre-start', 'preStart')
99
+ .rename('post-start', 'postStart')
100
+ .rename('pre-stop', 'preStop')
101
+ .rename('pre-uninstall', 'preUninstall')
102
+ .rename('pre-config', 'preConfig')
103
+ .optional()
104
+ .meta({
105
+ className: 'TScripts',
106
+ unknownType: 'any',
107
+ });
108
+ exports.scriptsSchema = scriptsSchema;
93
109
  // Different services have different config schema
94
110
  // - Auth: https://github.com/ArcBlock/abtnode-docs/blob/master/src/developer/auth-service/index.md
95
111
  const serviceSchema = Joi.object({
96
- name: Joi.string().required().trim(),
97
- config: Joi.object().optional().default({}),
98
- }).unknown(true);
99
-
112
+ name: Joi.string().required().trim(),
113
+ config: Joi.object().optional().default({}),
114
+ })
115
+ .unknown(true)
116
+ .meta({
117
+ className: 'TService',
118
+ unknownType: 'any',
119
+ });
120
+ exports.serviceSchema = serviceSchema;
100
121
  const endpointSchema = Joi.object({
101
- type: Joi.string().trim(true).min(1).required(),
102
- path: Joi.string().required(),
103
- meta: Joi.object({
104
- vcType: Joi.string(),
105
- payable: Joi.boolean(),
106
- params: Joi.array().items({
107
- name: Joi.string().required().trim(),
108
- description: Joi.string().required().trim(),
122
+ type: Joi.string().trim(true).min(1).required(),
123
+ path: Joi.string().required(),
124
+ meta: Joi.object({
125
+ vcType: Joi.string(),
126
+ payable: Joi.boolean(),
127
+ params: Joi.array().items({
128
+ name: Joi.string().required().trim(),
129
+ description: Joi.string().required().trim(),
130
+ }),
109
131
  }),
110
- }),
132
+ }).meta({
133
+ className: 'TEndpoint',
134
+ unknownType: 'any',
111
135
  });
112
-
136
+ exports.endpointSchema = endpointSchema;
113
137
  const interfaceSchema = Joi.object({
114
- type: Joi.string()
115
- .lowercase()
116
- .valid(...BLOCKLET_INTERFACE_TYPES)
117
- .required(),
118
-
119
- // Human readable name of the interface, such as `public_url`
120
- name: Joi.string().trim().required(),
121
-
122
- // The path where the interface is served from the blocklet
123
- path: Joi.string().trim().default('/'),
124
-
125
- // `*` means the interface can be mounted at any path prefix
126
- prefix: Joi.string().trim().min(1).default(BLOCKLET_DYNAMIC_PATH_PREFIX),
127
-
128
- protocol: Joi.string()
129
- .lowercase()
130
- .valid(...BLOCKLET_INTERFACE_PROTOCOLS)
131
- .default('http'),
132
-
133
- // Can be a string or an object
134
- port: Joi.alternatives()
135
- .try(
136
- Joi.string().uppercase().default(BLOCKLET_DEFAULT_PORT_NAME),
137
- Joi.object({
138
+ type: Joi.string()
139
+ .lowercase()
140
+ .valid(...BLOCKLET_INTERFACE_TYPES)
141
+ .required(),
142
+ // Human readable name of the interface, such as `public_url`
143
+ name: Joi.string().trim().required(),
144
+ // The path where the interface is served from the blocklet
145
+ path: Joi.string().trim().default('/'),
146
+ // `*` means the interface can be mounted at any path prefix
147
+ prefix: Joi.string().trim().min(1).default(BLOCKLET_DYNAMIC_PATH_PREFIX),
148
+ protocol: Joi.string()
149
+ .lowercase()
150
+ .valid(...BLOCKLET_INTERFACE_PROTOCOLS)
151
+ .default('http'),
152
+ // Can be a string or an object
153
+ port: Joi.alternatives()
154
+ .try(Joi.string().uppercase().default(BLOCKLET_DEFAULT_PORT_NAME), Joi.object({
138
155
  internal: Joi.string().uppercase().required(),
139
156
  external: Joi.number().port().required(),
140
- })
141
- )
142
- .default(BLOCKLET_DEFAULT_PORT_NAME),
143
-
144
- services: Joi.array().items(serviceSchema).unique('name'),
145
- endpoints: Joi.array().items(endpointSchema).unique('type'),
157
+ }))
158
+ .default(BLOCKLET_DEFAULT_PORT_NAME),
159
+ services: Joi.array().items(serviceSchema).unique('name'),
160
+ endpoints: Joi.array().items(endpointSchema).unique('type'),
161
+ }).meta({
162
+ className: 'TInterface',
163
+ unknownType: 'any',
146
164
  });
147
-
165
+ exports.interfaceSchema = interfaceSchema;
148
166
  const engineSchema = Joi.object({
149
- platform: Joi.string()
150
- .valid(...BLOCKLET_PLATFORMS)
151
- .optional(),
152
- interpreter: Joi.string().valid('binary', 'node').default('node'),
153
- script: Joi.string().required(),
154
- args: Joi.array().items(Joi.string()).optional().default([]),
167
+ platform: Joi.string()
168
+ .valid(...BLOCKLET_PLATFORMS)
169
+ .optional(),
170
+ interpreter: Joi.string().valid('binary', 'node').default('node'),
171
+ script: Joi.string().required(),
172
+ args: Joi.array().items(Joi.string()).optional().default([]),
173
+ }).meta({
174
+ className: 'TEngine',
175
+ unknownType: 'any',
155
176
  });
156
-
177
+ exports.engineSchema = engineSchema;
157
178
  const personSchema = Joi.object({
158
- name: Joi.string().min(1).required(),
159
- email: Joi.string().email().optional(),
160
- url: Joi.string().uri().optional(),
179
+ name: Joi.string().min(1).required(),
180
+ email: Joi.string().email().optional(),
181
+ url: Joi.string().uri().optional(),
182
+ }).meta({
183
+ className: 'TPerson',
184
+ unknownType: 'any',
161
185
  });
162
-
186
+ exports.personSchema = personSchema;
163
187
  const distSchema = Joi.object({
164
- tarball: Joi.alternatives().try(Joi.string().uri(), Joi.string()).required(),
165
- integrity: Joi.string().required(),
166
- size: Joi.number().optional(),
188
+ tarball: Joi.alternatives().try(Joi.string().uri(), Joi.string()).required(),
189
+ integrity: Joi.string().required(),
190
+ size: Joi.number().optional(),
191
+ }).meta({
192
+ className: 'TDist',
193
+ unknownType: 'any',
167
194
  });
168
-
195
+ exports.distSchema = distSchema;
169
196
  const statsSchema = Joi.object({
170
- downloads: Joi.number().integer().greater(-1),
171
- star: Joi.number().default(0),
172
- purchases: Joi.number().default(0),
197
+ downloads: Joi.number().integer().greater(-1),
198
+ star: Joi.number().default(0),
199
+ purchases: Joi.number().default(0),
200
+ }).meta({
201
+ className: 'TStats',
202
+ unknownType: 'any',
173
203
  });
174
-
175
- const childrenSchema = Joi.object({
176
- name: blockletNameSchema.required(),
177
- title: titleSchema,
178
- description: descriptionSchema,
179
- mountPoint: mountPointSchema, // added in 1.2.3
180
- services: Joi.array().items(serviceSchema).unique('name'), // added in 1.2.3
181
- source: Joi.alternatives().try(
182
- Joi.object({
183
- url: Joi.alternatives().try(Joi.string().uri(), Joi.array().items(Joi.string().uri()).min(1)).required(),
184
- }),
185
- Joi.object({
186
- store: Joi.alternatives().try(Joi.string().uri(), Joi.array().items(Joi.string().uri()).min(1)).required(),
187
- name: blockletNameSchema.required(),
188
- // TODO 目前只能支持锁死的版本号,接下载需要支持自适应的版本号,比如 4.x
189
- version: Joi.alternatives().try(Joi.string().valid('latest'), Joi.semver().valid()).default('latest'),
190
- })
191
- ),
192
- resolved: Joi.alternatives().try(Joi.string().uri(), Joi.string()), // deprecated
193
- mountPoints: Joi.array() // deprecated
194
- .items(
195
- Joi.object({
204
+ exports.statsSchema = statsSchema;
205
+ const componentSchema = Joi.object({
206
+ name: blockletNameSchema.required(),
207
+ title: titleSchema,
208
+ description: descriptionSchema,
209
+ mountPoint: mountPointSchema,
210
+ services: Joi.array().items(serviceSchema).unique('name'),
211
+ source: Joi.alternatives().try(Joi.object({
212
+ url: Joi.alternatives().try(Joi.string().uri(), Joi.array().items(Joi.string().uri()).min(1)).required(),
213
+ }), Joi.object({
214
+ store: Joi.alternatives().try(Joi.string().uri(), Joi.array().items(Joi.string().uri()).min(1)).required(),
215
+ name: blockletNameSchema.required(),
216
+ // TODO 目前只能支持锁死的版本号,接下载需要支持自适应的版本号,比如 4.x
217
+ version: Joi.alternatives().try(Joi.string().valid('latest'), Joi.semver().valid()).default('latest'),
218
+ })),
219
+ resolved: Joi.alternatives().try(Joi.string().uri(), Joi.string()),
220
+ mountPoints: Joi.array() // deprecated
221
+ .items(Joi.object({
196
222
  root: Joi.object({
197
- interfaceName: Joi.string().trim().required(),
198
- prefix: Joi.string().trim().min(1).required(),
223
+ interfaceName: Joi.string().trim().required(),
224
+ prefix: Joi.string().trim().min(1).required(),
199
225
  }).required(),
200
226
  child: Joi.object({
201
- interfaceName: Joi.string().trim().required(),
227
+ interfaceName: Joi.string().trim().required(),
202
228
  }).required(),
203
229
  services: Joi.array().items(serviceSchema).unique('name'),
204
- })
205
- )
206
- .optional(),
207
- }).custom((value, helper) => {
208
- if (!value.mountPoint && (!value.mountPoints || !value.mountPoints.length)) {
209
- return helper.message('child mountPoint is required');
210
- }
211
-
212
- if (!value.source && !value.resolved) {
213
- return helper.message('child source is required');
214
- }
215
-
216
- return value;
230
+ }))
231
+ .optional(),
232
+ })
233
+ .custom((value, helper) => {
234
+ if (!value.mountPoint && (!value.mountPoints || !value.mountPoints.length)) {
235
+ // @ts-expect-error
236
+ return helper.message('child mountPoint is required');
237
+ }
238
+ if (!value.source && !value.resolved) {
239
+ // @ts-expect-error
240
+ return helper.message('child source is required');
241
+ }
242
+ return value;
243
+ })
244
+ .meta({
245
+ className: 'TComponent',
246
+ unknownType: 'any',
217
247
  });
218
-
248
+ exports.componentSchema = componentSchema;
219
249
  const signatureSchema = Joi.object({
220
- type: Joi.string().required(),
221
- name: Joi.string().required(),
222
- signer: Joi.string().required(),
223
- pk: Joi.string().required(),
224
- created: Joi.string().isoDate().required(),
225
- sig: Joi.string().required(),
226
- excludes: Joi.array().items(Joi.string()).optional(),
227
- appended: Joi.array().items(Joi.string()).optional(),
228
- // delegation token 校验所需字段
229
- delegatee: Joi.string(),
230
- delegateePk: Joi.string(),
231
- delegation: Joi.string(),
250
+ type: Joi.string().required(),
251
+ name: Joi.string().required(),
252
+ signer: Joi.string().required(),
253
+ pk: Joi.string().required(),
254
+ created: Joi.string().isoDate().required(),
255
+ sig: Joi.string().required(),
256
+ excludes: Joi.array().items(Joi.string()).optional(),
257
+ appended: Joi.array().items(Joi.string()).optional(),
258
+ // delegation token 校验所需字段
259
+ delegatee: Joi.string(),
260
+ delegateePk: Joi.string(),
261
+ delegation: Joi.string(),
262
+ }).meta({
263
+ className: 'TSignature',
264
+ unknownType: 'any',
232
265
  });
233
-
234
- const navigationItemSchema = Joi.object({
235
- title: Joi.alternatives()
236
- .try(
237
- Joi.string(),
238
- Joi.object({
266
+ exports.signatureSchema = signatureSchema;
267
+ const navigationItemProps = {
268
+ title: Joi.alternatives()
269
+ .try(Joi.string(), Joi.object({
270
+ zh: Joi.string(),
271
+ en: Joi.string(),
272
+ }).min(1))
273
+ .required(),
274
+ link: Joi.alternatives().try(Joi.string(), Joi.object({
239
275
  zh: Joi.string(),
240
276
  en: Joi.string(),
241
- }).min(1)
242
- )
243
- .required(),
244
- link: Joi.alternatives().try(
245
- Joi.string(),
246
- Joi.object({
247
- zh: Joi.string(),
248
- en: Joi.string(),
249
- }).min(1)
250
- ),
251
- component: Joi.string().min(1), // child name or child did
252
- section: Joi.array().items(Joi.string().min(1)).single(),
253
- role: Joi.array().items(Joi.string().min(1)).single(),
254
- icon: Joi.string().min(1),
255
- }).rename('child', 'component');
256
-
257
- const navigationSchema = Joi.array().items(
258
- navigationItemSchema.append({
259
- items: Joi.array().items(navigationItemSchema),
260
- })
261
- );
262
-
277
+ }).min(1)),
278
+ component: Joi.string().min(1),
279
+ section: Joi.array().items(Joi.string().min(1)).single(),
280
+ role: Joi.array().items(Joi.string().min(1)).single(),
281
+ icon: Joi.string().min(1),
282
+ };
283
+ const navigationItemSchema = Joi.object(Object.assign(Object.assign({}, navigationItemProps), { items: Joi.array().items(Joi.object(Object.assign({}, navigationItemProps)).rename('child', 'component')) }))
284
+ .rename('child', 'component')
285
+ .meta({
286
+ className: 'TNavigationItem',
287
+ unknownType: 'any',
288
+ });
289
+ exports.navigationItemSchema = navigationItemSchema;
290
+ const navigationSchema = Joi.array().items(navigationItemSchema).meta({
291
+ className: 'TNavigation',
292
+ unknownType: 'any',
293
+ });
294
+ exports.navigationSchema = navigationSchema;
263
295
  const themeSchema = Joi.object({
264
- background: Joi.alternatives().try(
265
- Joi.string().min(1),
266
- Joi.object({
267
- header: Joi.string().min(1),
268
- footer: Joi.string().min(1),
269
- default: Joi.string().min(1),
270
- }).min(1)
271
- ),
296
+ background: Joi.alternatives().try(Joi.string().min(1), Joi.object({
297
+ header: Joi.string().min(1),
298
+ footer: Joi.string().min(1),
299
+ default: Joi.string().min(1),
300
+ }).min(1)),
301
+ }).meta({
302
+ className: 'TTheme',
303
+ unknownType: 'any',
272
304
  });
273
-
274
- const createBlockletSchema = (
275
- baseDir,
276
- { ensureMain = false, ensureFiles = false, ensureDist = false, ...schemaOptions } = {}
277
- ) => {
278
- if (!baseDir || !fs.existsSync(baseDir)) {
279
- // eslint-disable-next-line no-param-reassign
280
- ensureFiles = false;
281
- }
282
-
283
- return Joi.object({
305
+ exports.themeSchema = themeSchema;
306
+ const blockletMetaProps = {
284
307
  did: Joi.DID().trim().required(),
285
308
  version: Joi.semver().valid().required(),
286
309
  name: blockletNameSchema.required(),
287
310
  description: descriptionSchema.required(),
288
- group: Joi.string().valid(...BLOCKLET_GROUPS).required(), // prettier-ignore
289
- main: Joi.when('group', {
290
- is: Joi.valid(BlockletGroup.gateway),
291
- then: Joi.forbidden(),
292
- otherwise: ensureMain ? Joi.file().exists({ baseDir }).required() : Joi.string().trim().required(),
293
- }),
311
+ group: Joi.string()
312
+ .valid(...BLOCKLET_GROUPS)
313
+ .required(),
314
+ main: Joi.string().trim().required(),
294
315
  title: titleSchema.optional().allow(''),
295
- logo: ensureFiles ? Joi.file().trim().exists({ baseDir }).optional() : Joi.string().trim().optional(),
316
+ logo: Joi.string().trim().optional(),
296
317
  specVersion: Joi.semver().valid().gte('1.0.0').optional(),
297
-
298
318
  author: personSchema.optional(),
299
319
  contributors: Joi.array().items(personSchema).optional(),
300
320
  maintainers: Joi.array().items(personSchema).optional(),
301
-
302
321
  community: Joi.string().uri().optional().allow('').default(''),
303
322
  documentation: Joi.string().uri().optional().allow('').default(''),
304
323
  homepage: Joi.string().uri().optional().allow('').default(''),
305
324
  license: Joi.string().optional().allow('').default(''),
306
325
  support: Joi.alternatives().try(Joi.string().uri(), Joi.string().email()).optional(),
307
-
308
326
  // which asset factory to mint blocklet purchase nft
309
327
  // This is usually created and maintained by `blocklet publish` command
310
328
  nftFactory: Joi.DID().optional().allow('').default(''),
311
-
312
329
  // Set the price and share of the blocklet
313
330
  payment: Joi.object({
314
- // Currently only supports 1 token
315
- price: Joi.array()
316
- .max(1)
317
- .items(
318
- Joi.object({
331
+ // Currently only supports 1 token
332
+ price: Joi.array()
333
+ .max(1)
334
+ .items(Joi.object({
319
335
  value: Joi.number().greater(0).required(),
320
336
  address: Joi.DID().required(), // token address
321
- })
322
- )
323
- .default([]),
324
- // List of beneficiaries that share the token earns from blocklet purchase
325
- // If left empty, blocklet publish workflow will enforce both the developer and the registry account
326
- // If not, the blocklet publish workflow will enforce the registry account
327
- // In theory, the developer can split as many share as he wants
328
- // Such as, some developers coauthored the blocklet, and their income get instant settlement on blocklet purchase
329
- // For performance reasons, we need to set a hard limit for share count
330
- share: Joi.array()
331
- .max(4)
332
- .items(
333
- Joi.object({
337
+ }))
338
+ .default([]),
339
+ // List of beneficiaries that share the token earns from blocklet purchase
340
+ // If left empty, blocklet publish workflow will enforce both the developer and the registry account
341
+ // If not, the blocklet publish workflow will enforce the registry account
342
+ // In theory, the developer can split as many share as he wants
343
+ // Such as, some developers coauthored the blocklet, and their income get instant settlement on blocklet purchase
344
+ // For performance reasons, we need to set a hard limit for share count
345
+ share: Joi.array()
346
+ .max(4)
347
+ .items(Joi.object({
334
348
  name: Joi.string().required(),
335
349
  address: Joi.DID().required(),
336
350
  value: Joi.number().greater(0).max(1).required(),
337
- })
338
- )
339
- .default([])
340
- .custom((value) => {
341
- // If share is not empty, the total value should be 1
342
- if (value.length === 0) {
351
+ }))
352
+ .default([])
353
+ .custom((value) => {
354
+ // If share is not empty, the total value should be 1
355
+ if (value.length === 0) {
356
+ return value;
357
+ }
358
+ const total = value.reduce((acc, cur) => acc + cur.value, 0);
359
+ if (total !== 1) {
360
+ throw new Error(`Invalid blocklet payment share config: total share must be 1, got ${total}`);
361
+ }
343
362
  return value;
344
- }
345
- const total = value.reduce((acc, cur) => acc + cur.value, 0);
346
- if (total !== 1) {
347
- throw new Error(`Invalid blocklet payment share config: total share must be 1, got ${total}`);
348
- }
349
- return value;
350
363
  }, 'invalid blocklet share'),
351
- componentPrice: Joi.array()
352
- .items(
353
- Joi.object({
364
+ componentPrice: Joi.array()
365
+ .items(Joi.object({
354
366
  parentPriceRange: Joi.array()
355
- .items(Joi.number())
356
- // FIXME
357
- // 1. 有重叠的区间时
358
- // 2. 区间不连续时
359
- // 3. 区间边界
360
- .custom((value, helper) => {
367
+ .items(Joi.number())
368
+ // FIXME
369
+ // 1. 有重叠的区间时
370
+ // 2. 区间不连续时
371
+ // 3. 区间边界
372
+ .custom((value, helper) => {
361
373
  if (value.length !== 2) {
362
- return helper.message('length of range should be 2');
374
+ // @ts-expect-error
375
+ return helper.message('length of range should be 2');
363
376
  }
364
-
365
377
  if (value[0] < 0) {
366
- return helper.message('the first value should not less than 0 in range');
378
+ // @ts-expect-error
379
+ return helper.message('the first value should not less than 0 in range');
367
380
  }
368
-
369
381
  if (value[1] <= value[0]) {
370
- return helper.message('the second value should greater than the first value in range');
382
+ // @ts-expect-error
383
+ return helper.message('the second value should greater than the first value in range');
371
384
  }
372
-
373
385
  return value;
374
- }),
386
+ }),
375
387
  type: Joi.string().valid('fixed', 'percentage').required(),
376
388
  value: Joi.number().greater(0).required(),
377
- })
378
- )
379
- .single(),
389
+ }))
390
+ .single(),
380
391
  }).default({ price: [], share: [] }),
381
-
382
392
  keywords: Joi.alternatives()
383
- .try(Joi.string().trim().min(1), Joi.array().items(Joi.string().min(1)))
384
- .optional(),
393
+ .try(Joi.string().trim().min(1), Joi.array().items(Joi.string().min(1)))
394
+ .optional(),
385
395
  tags: Joi.alternatives()
386
- .try(Joi.string().trim().min(1), Joi.array().items(Joi.string().min(1)))
387
- .optional(),
388
-
396
+ .try(Joi.string().trim().min(1), Joi.array().items(Joi.string().min(1)))
397
+ .optional(),
389
398
  gitHash: Joi.string().optional().allow(''),
390
399
  repository: Joi.alternatives()
391
- .try(
392
- Joi.string().min(1),
393
- Joi.object({
394
- type: Joi.string().valid('git', 'https', 'svn').required(),
395
- url: Joi.string().uri().required(),
396
- directory: Joi.string(),
397
- })
398
- )
399
- .optional(),
400
-
400
+ .try(Joi.string().min(1), Joi.object({
401
+ type: Joi.string().valid('git', 'https', 'svn').required(),
402
+ url: Joi.string().uri().required(),
403
+ directory: Joi.string(),
404
+ }))
405
+ .optional(),
401
406
  timeout: Joi.object({
402
- start: Joi.number().min(10).max(600), // start check timeout, 10 seconds ~ 10 minutes
407
+ start: Joi.number().min(10).max(600), // start check timeout, 10 seconds ~ 10 minutes
403
408
  }).default({ start: 60 }),
404
-
405
409
  requirements: Joi.object({
406
- abtnode: Joi.semverRange().valid(), // deprecated in v1.6.1
407
- server: Joi.semverRange().valid(),
408
- os: Joi.alternatives().try(
409
- Joi.string().valid('*', ...BLOCKLET_PLATFORMS),
410
- Joi.array()
411
- .items(Joi.string().valid(...BLOCKLET_PLATFORMS))
412
- .min(1)
413
- ),
414
- cpu: Joi.alternatives().try(
415
- Joi.string().valid('*', ...BLOCKLET_ARCHITECTURES),
416
- Joi.array()
417
- .items(Joi.string().valid(...BLOCKLET_ARCHITECTURES))
418
- .min(1)
419
- ),
420
- fuels: Joi.array().items(
421
- Joi.object({
422
- endpoint: Joi.string().trim().required(),
423
- address: Joi.string().trim(),
424
- value: Joi.string().trim().required(),
425
- reason: Joi.string().trim().required(),
426
- })
427
- ),
428
- nodejs: Joi.semverRange().valid(),
410
+ abtnode: Joi.semverRange().valid(),
411
+ server: Joi.semverRange().valid(),
412
+ os: Joi.alternatives().try(Joi.string().valid('*', ...BLOCKLET_PLATFORMS), Joi.array()
413
+ .items(Joi.string().valid(...BLOCKLET_PLATFORMS))
414
+ .min(1)),
415
+ cpu: Joi.alternatives().try(Joi.string().valid('*', ...BLOCKLET_ARCHITECTURES), Joi.array()
416
+ .items(Joi.string().valid(...BLOCKLET_ARCHITECTURES))
417
+ .min(1)),
418
+ fuels: Joi.array().items(Joi.object({
419
+ endpoint: Joi.string().trim().required(),
420
+ address: Joi.string().trim(),
421
+ value: Joi.string().trim().required(),
422
+ reason: Joi.string().trim().required(),
423
+ })),
424
+ nodejs: Joi.semverRange().valid(),
429
425
  }).default({ server: BLOCKLET_LATEST_REQUIREMENT_SERVER, os: '*', cpu: '*', nodejs: '*' }),
430
-
431
426
  // interfaces: https://github.com/blocklet/blocklet-specification/issues/2
432
427
  interfaces: Joi.array()
433
- .items(interfaceSchema)
434
- .unique('name')
435
- .min(1)
436
- .custom((value, helper) => {
428
+ .items(interfaceSchema)
429
+ .unique('name')
430
+ .min(1)
431
+ .custom((value, helper) => {
437
432
  const webItems = value.filter((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB);
438
433
  if (webItems.length > 1) {
439
- return helper.message(`Only one ${BLOCKLET_INTERFACE_TYPE_WEB} interface can be declared`);
434
+ // @ts-expect-error
435
+ return helper.message(`Only one ${BLOCKLET_INTERFACE_TYPE_WEB} interface can be declared`);
440
436
  }
441
-
442
437
  const wellknownItems = value.filter((x) => x.type === BLOCKLET_INTERFACE_TYPE_WELLKNOWN);
443
438
  for (const x of wellknownItems) {
444
- if (!x.prefix.startsWith(WELLKNOWN_PATH_PREFIX)) {
445
- return helper.message(`Wellknown path prefix must start with: ${WELLKNOWN_PATH_PREFIX}`);
446
- }
439
+ if (!x.prefix.startsWith(WELLKNOWN_PATH_PREFIX)) {
440
+ // @ts-expect-error
441
+ return helper.message(`Wellknown path prefix must start with: ${WELLKNOWN_PATH_PREFIX}`);
442
+ }
447
443
  }
448
-
449
444
  return value;
450
- })
451
- .default([]),
452
-
445
+ })
446
+ .default([]),
453
447
  // environments
454
448
  environments: Joi.array().items(environmentSchema).default([]).optional(),
455
-
456
449
  // scripts & hooks
457
450
  scripts: scriptsSchema,
458
-
459
451
  // capabilities
460
452
  capabilities: Joi.object({
461
- clusterMode: Joi.boolean().default(false), // Can blocklet be started in cluster mode
462
-
463
- // added in 1.2.2
464
- component: Joi.boolean().default(true), // Can blocklet become a component and be composed by other blocklets
453
+ clusterMode: Joi.boolean().default(false),
454
+ // added in 1.2.2
455
+ component: Joi.boolean().default(true),
456
+ didStorage: Joi.string()
457
+ .valid(...Object.values(BLOCKLET_APP_STORAGE_ENDPOINTS))
458
+ .optional(),
465
459
  }).default({
466
- clusterMode: false,
467
- component: true,
460
+ clusterMode: false,
461
+ component: true,
468
462
  }),
469
-
470
463
  // Other contents to be included in the bundle
471
- files: Joi.array()
472
- .items(
473
- ensureFiles
474
- ? // eslint-disable-next-line
475
- Joi.file().exists({ baseDir, canSkip: (dir, name) => [BLOCKLET_ENTRY_FILE, BLOCKLET_BUNDLE_FILE].includes(name) || isGlob(name) }) // prettier-ignore
476
- : Joi.string().trim()
477
- )
478
- .optional(),
479
-
464
+ files: Joi.array().items(Joi.string().trim()).optional(),
480
465
  // TODO: this field should be refactored in future version
481
466
  engine: Joi.alternatives().try(engineSchema, Joi.array().items(engineSchema)).optional(),
482
-
483
467
  // NOTE: following fields are appended by registry or bundling process
484
468
  screenshots: Joi.array().items(Joi.string().min(1)).optional().default([]),
485
469
  logoUrl: Joi.string().optional().allow(''),
486
- dist: ensureDist ? distSchema.required() : distSchema.optional(),
470
+ dist: distSchema.optional(),
487
471
  stats: statsSchema.optional(),
488
472
  htmlAst: Joi.any().optional(),
489
473
  path: Joi.string().optional(),
490
474
  signatures: Joi.array().items(signatureSchema).optional(),
491
475
  lastPublishedAt: Joi.string().isoDate().optional(),
492
-
493
476
  // blocklet component support
494
- components: Joi.array().items(childrenSchema).unique('name').optional().default([]),
495
-
477
+ components: Joi.array().items(componentSchema).unique('name').optional().default([]),
496
478
  // navigation & theme
497
479
  navigation: navigationSchema,
498
480
  theme: themeSchema,
499
481
  copyright: Joi.object({
500
- owner: Joi.string().min(1),
501
- year: Joi.alternatives().try(Joi.string(), Joi.number()),
482
+ owner: Joi.string().min(1),
483
+ year: Joi.alternatives().try(Joi.string(), Joi.number()),
502
484
  }),
503
-
504
485
  // NOTE: following fields only exist in blocklet server and cannot be set manually
505
486
  bundleName: Joi.string(),
506
487
  bundleDid: Joi.DID().trim(),
507
488
  storeId: Joi.string(),
508
- })
509
- .options({ stripUnknown: true, noDefaults: false, ...schemaOptions })
510
- .rename('children', 'components');
511
489
  };
512
-
513
- module.exports = {
514
- createBlockletSchema,
515
- interfaceSchema,
516
- environmentSchema,
517
- scriptsSchema,
518
- personSchema,
519
- distSchema,
520
- titleSchema,
521
- descriptionSchema,
522
- logoSchema,
523
- navigationSchema,
524
- themeSchema,
525
- mountPointSchema,
490
+ const blockletMetaSchema = Joi.object(blockletMetaProps).options({ stripUnknown: true, noDefaults: false }).meta({
491
+ className: 'TBlockletMeta',
492
+ unknownType: 'any',
493
+ });
494
+ exports.blockletMetaSchema = blockletMetaSchema;
495
+ const createBlockletSchema = (baseDir, _a = {}) => {
496
+ var { ensureMain = false, ensureFiles = false, ensureDist = false } = _a, schemaOptions = __rest(_a, ["ensureMain", "ensureFiles", "ensureDist"]);
497
+ if (!baseDir || !fs_1.default.existsSync(baseDir)) {
498
+ // eslint-disable-next-line no-param-reassign
499
+ ensureFiles = false;
500
+ }
501
+ return Joi.object(Object.assign(Object.assign({}, blockletMetaProps), { main: Joi.when('group', {
502
+ is: Joi.valid(BlockletGroup.gateway),
503
+ then: Joi.forbidden(),
504
+ otherwise: ensureMain ? Joi.file().exists({ baseDir }).required() : Joi.string().trim().required(),
505
+ }), logo: ensureFiles ? Joi.file().trim().exists({ baseDir }).optional() : Joi.string().trim().optional(),
506
+ // Other contents to be included in the bundle
507
+ files: Joi.array()
508
+ .items(ensureFiles
509
+ ? // eslint-disable-next-line
510
+ Joi.file().exists({ baseDir, canSkip: (dir, name) => [BLOCKLET_ENTRY_FILE, BLOCKLET_BUNDLE_FILE].includes(name) || (0, is_glob_1.default)(name) }) // prettier-ignore
511
+ : Joi.string().trim())
512
+ .optional(), dist: ensureDist ? distSchema.required() : distSchema.optional() }))
513
+ .options(Object.assign({ stripUnknown: true, noDefaults: false }, schemaOptions))
514
+ .rename('children', 'components');
515
+ };
516
+ exports.createBlockletSchema = createBlockletSchema;
517
+ exports.default = {
518
+ blockletNameSchema,
519
+ componentSchema,
520
+ endpointSchema,
521
+ serviceSchema,
522
+ createBlockletSchema,
523
+ interfaceSchema,
524
+ environmentSchema,
525
+ scriptsSchema,
526
+ personSchema,
527
+ distSchema,
528
+ titleSchema,
529
+ descriptionSchema,
530
+ logoSchema,
531
+ navigationSchema,
532
+ themeSchema,
533
+ mountPointSchema,
526
534
  };