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