@blocklet/meta 1.6.15 → 1.6.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/constants.js +91 -56
- package/lib/did.js +1 -3
- package/lib/fix.js +4 -9
- package/lib/info.js +5 -2
- package/lib/parse.js +1 -1
- package/lib/payment.js +0 -3
- package/lib/schema.js +28 -11
- package/lib/util.js +55 -7
- package/lib/wallet.js +1 -3
- package/package.json +12 -11
package/lib/constants.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
1
|
+
const fromEntry = (entries) => (v) => {
|
|
2
|
+
const match = Object.entries(entries).find((x) => x[1] === Number(v));
|
|
3
|
+
return match ? match[0] : 'unknown';
|
|
4
|
+
};
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
//
|
|
7
|
-
const BLOCKLET_INTERFACE_TYPE_WELLKNOWN = 'wellknown';
|
|
6
|
+
const toEntry = (entries) => (v) => Object.keys(entries).find((x) => entries[x] === Number(v));
|
|
7
|
+
|
|
8
|
+
// Blocklet Status
|
|
8
9
|
|
|
9
10
|
const BlockletStatus = Object.freeze({
|
|
10
11
|
added: 0,
|
|
@@ -23,13 +24,52 @@ const BlockletStatus = Object.freeze({
|
|
|
23
24
|
waiting: 13,
|
|
24
25
|
});
|
|
25
26
|
|
|
27
|
+
const fromBlockletStatus = fromEntry(BlockletStatus);
|
|
28
|
+
const toBlockletStatus = toEntry(BlockletStatus);
|
|
29
|
+
|
|
30
|
+
// Blocklet Source
|
|
31
|
+
|
|
26
32
|
const BlockletSource = Object.freeze({
|
|
33
|
+
// Installed from Blocklet Store
|
|
27
34
|
registry: 0,
|
|
35
|
+
|
|
36
|
+
// Installed from local development source folder
|
|
28
37
|
local: 1,
|
|
38
|
+
|
|
39
|
+
// Installed from uploading bundle directly
|
|
29
40
|
upload: 2,
|
|
41
|
+
|
|
42
|
+
// Installed from a url (similar to Blocklet Store)
|
|
30
43
|
url: 3,
|
|
44
|
+
|
|
45
|
+
// Installed by custom creation
|
|
46
|
+
custom: 4,
|
|
31
47
|
});
|
|
32
48
|
|
|
49
|
+
const fromBlockletSource = fromEntry(BlockletSource);
|
|
50
|
+
const toBlockletSource = toEntry(BlockletSource);
|
|
51
|
+
|
|
52
|
+
// Blocklet Group(Type)
|
|
53
|
+
|
|
54
|
+
const BlockletGroup = Object.freeze({
|
|
55
|
+
// Only static website
|
|
56
|
+
// The website is served by by Blocklet Server at runtime
|
|
57
|
+
static: 'static',
|
|
58
|
+
|
|
59
|
+
// The runtime instance is provided by its own backend server
|
|
60
|
+
dapp: 'dapp',
|
|
61
|
+
|
|
62
|
+
starter: false, // deprecated
|
|
63
|
+
|
|
64
|
+
// This type is used to combine other component blocklets
|
|
65
|
+
// No instance will be spawned at runtime
|
|
66
|
+
gateway: 'gateway',
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const BLOCKLET_GROUPS = ['dapp', 'static', 'gateway'];
|
|
70
|
+
|
|
71
|
+
// Blocklet Events
|
|
72
|
+
|
|
33
73
|
const BlockletEvents = Object.freeze({
|
|
34
74
|
added: 'blocklet.added',
|
|
35
75
|
downloadFailed: 'blocklet.downloadFailed',
|
|
@@ -48,45 +88,52 @@ const BlockletEvents = Object.freeze({
|
|
|
48
88
|
purchaseChange: 'blocklet.purchaseChange',
|
|
49
89
|
});
|
|
50
90
|
|
|
51
|
-
|
|
52
|
-
const match = Object.entries(entries).find((x) => x[1] === Number(v));
|
|
53
|
-
return match ? match[0] : 'unknown';
|
|
54
|
-
};
|
|
91
|
+
// Blocklet Interface
|
|
55
92
|
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
const fromBlockletStatus = fromEntry(BlockletStatus);
|
|
59
|
-
const toBlockletStatus = toEntry(BlockletStatus);
|
|
93
|
+
const BLOCKLET_INTERFACE_TYPE_WEB = 'web';
|
|
94
|
+
const BLOCKLET_INTERFACE_TYPE_SERVICE = 'service';
|
|
60
95
|
|
|
61
|
-
|
|
62
|
-
|
|
96
|
+
// Wellknown interface declares an sub-interface under web interface
|
|
97
|
+
// The path of the wellknown interface must starts with /.well-known, e.g. /.well-known/acme-challenge)
|
|
98
|
+
// The wellknown interface can be mounted to every endpoint of the abtnode and all blocklets on the abtnode
|
|
99
|
+
const BLOCKLET_INTERFACE_TYPE_WELLKNOWN = 'wellknown';
|
|
100
|
+
const BLOCKLET_INTERFACE_TYPES = [
|
|
101
|
+
BLOCKLET_INTERFACE_TYPE_WEB,
|
|
102
|
+
BLOCKLET_INTERFACE_TYPE_SERVICE,
|
|
103
|
+
BLOCKLET_INTERFACE_TYPE_WELLKNOWN,
|
|
104
|
+
];
|
|
63
105
|
|
|
64
106
|
const BLOCKLET_INTERFACE_PUBLIC = 'publicUrl';
|
|
65
|
-
const BLOCKLET_INTERFACE_ADMIN = 'adminUrl';
|
|
66
|
-
const BLOCKLET_INTERFACE_CONFIG = 'configUrl';
|
|
67
|
-
const BLOCKLET_INTERFACE_DOC = 'docUrl';
|
|
68
107
|
const BLOCKLET_INTERFACE_WELLKNOWN = 'wellknownUrl'; // Deprecated
|
|
108
|
+
const BLOCKLET_UI_INTERFACES = [BLOCKLET_INTERFACE_PUBLIC];
|
|
109
|
+
const BLOCKLET_STANDARD_INTERFACES = [BLOCKLET_INTERFACE_PUBLIC, BLOCKLET_INTERFACE_WELLKNOWN];
|
|
110
|
+
|
|
111
|
+
const BLOCKLET_INTERFACE_PROTOCOL_HTTP = 'http';
|
|
112
|
+
const BLOCKLET_INTERFACE_PROTOCOL_TCP = 'tcp';
|
|
113
|
+
const BLOCKLET_INTERFACE_PROTOCOL_UDP = 'udp';
|
|
114
|
+
const BLOCKLET_INTERFACE_PROTOCOLS = [
|
|
115
|
+
BLOCKLET_INTERFACE_PROTOCOL_TCP,
|
|
116
|
+
BLOCKLET_INTERFACE_PROTOCOL_UDP,
|
|
117
|
+
BLOCKLET_INTERFACE_PROTOCOL_HTTP,
|
|
118
|
+
];
|
|
69
119
|
|
|
70
120
|
module.exports = Object.freeze({
|
|
71
121
|
BlockletStatus,
|
|
72
|
-
BlockletSource,
|
|
73
122
|
fromBlockletStatus,
|
|
74
123
|
toBlockletStatus,
|
|
124
|
+
|
|
125
|
+
BlockletSource,
|
|
75
126
|
fromBlockletSource,
|
|
76
127
|
toBlockletSource,
|
|
77
128
|
|
|
78
|
-
BlockletGroup
|
|
79
|
-
|
|
80
|
-
dapp: 'dapp',
|
|
81
|
-
starter: false,
|
|
82
|
-
gateway: 'gateway',
|
|
83
|
-
}),
|
|
84
|
-
BLOCKLET_GROUPS: ['dapp', 'static', 'gateway'],
|
|
129
|
+
BlockletGroup,
|
|
130
|
+
BLOCKLET_GROUPS,
|
|
85
131
|
|
|
86
132
|
BlockletEvents,
|
|
87
133
|
|
|
88
134
|
BLOCKLET_PLATFORMS: ['aix', 'darwin', 'freebsd', 'linux', 'openbsd', 'sunos', 'win32'],
|
|
89
135
|
BLOCKLET_ARCHITECTURES: ['arm', 'arm64', 'ia32', 'mips', 'mipsel', 'ppc', 'ppc64', 's390', 's390x', 'x32', 'x64'],
|
|
136
|
+
|
|
90
137
|
BLOCKLET_MODES: Object.freeze({
|
|
91
138
|
PRODUCTION: 'production',
|
|
92
139
|
DEVELOPMENT: 'development',
|
|
@@ -94,40 +141,27 @@ module.exports = Object.freeze({
|
|
|
94
141
|
|
|
95
142
|
BLOCKLET_FACTORY_SHARES: { developer: 0.7, store: 0.3 },
|
|
96
143
|
|
|
97
|
-
|
|
98
|
-
|
|
144
|
+
// interface
|
|
99
145
|
BLOCKLET_INTERFACE_PUBLIC,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
BLOCKLET_INTERFACE_WELLKNOWN,
|
|
104
|
-
|
|
105
|
-
BLOCKLET_UI_INTERFACES: [
|
|
106
|
-
BLOCKLET_INTERFACE_PUBLIC,
|
|
107
|
-
BLOCKLET_INTERFACE_ADMIN,
|
|
108
|
-
BLOCKLET_INTERFACE_CONFIG,
|
|
109
|
-
BLOCKLET_INTERFACE_DOC,
|
|
110
|
-
],
|
|
111
|
-
|
|
112
|
-
BLOCKLET_STANDARD_INTERFACES: [
|
|
113
|
-
BLOCKLET_INTERFACE_PUBLIC,
|
|
114
|
-
BLOCKLET_INTERFACE_ADMIN,
|
|
115
|
-
BLOCKLET_INTERFACE_CONFIG,
|
|
116
|
-
BLOCKLET_INTERFACE_DOC,
|
|
117
|
-
BLOCKLET_INTERFACE_WELLKNOWN,
|
|
118
|
-
],
|
|
146
|
+
BLOCKLET_INTERFACE_WELLKNOWN, // Deprecated
|
|
147
|
+
BLOCKLET_UI_INTERFACES,
|
|
148
|
+
BLOCKLET_STANDARD_INTERFACES,
|
|
119
149
|
|
|
120
150
|
BLOCKLET_INTERFACE_TYPE_WEB,
|
|
121
151
|
BLOCKLET_INTERFACE_TYPE_SERVICE,
|
|
122
152
|
BLOCKLET_INTERFACE_TYPE_WELLKNOWN,
|
|
123
|
-
BLOCKLET_INTERFACE_TYPES
|
|
124
|
-
BLOCKLET_INTERFACE_TYPE_WEB,
|
|
125
|
-
BLOCKLET_INTERFACE_TYPE_SERVICE,
|
|
126
|
-
BLOCKLET_INTERFACE_TYPE_WELLKNOWN,
|
|
127
|
-
],
|
|
153
|
+
BLOCKLET_INTERFACE_TYPES,
|
|
128
154
|
|
|
129
|
-
|
|
155
|
+
BLOCKLET_INTERFACE_PROTOCOL_HTTP,
|
|
156
|
+
BLOCKLET_INTERFACE_PROTOCOL_TCP,
|
|
157
|
+
BLOCKLET_INTERFACE_PROTOCOL_UDP,
|
|
158
|
+
BLOCKLET_INTERFACE_PROTOCOLS,
|
|
130
159
|
|
|
160
|
+
BLOCKLET_DYNAMIC_PATH_PREFIX: '*',
|
|
161
|
+
BLOCKLET_DEFAULT_PORT_NAME: 'BLOCKLET_PORT',
|
|
162
|
+
BLOCKLET_DEFAULT_PATH_REWRITE: '/',
|
|
163
|
+
|
|
164
|
+
// bundle
|
|
131
165
|
BLOCKLET_RELEASE_FOLDER: '.blocklet/release',
|
|
132
166
|
BLOCKLET_RELEASE_FILE: 'blocklet.json',
|
|
133
167
|
BLOCKLET_BUNDLE_FOLDER: '.blocklet/bundle',
|
|
@@ -138,9 +172,8 @@ module.exports = Object.freeze({
|
|
|
138
172
|
BLOCKLET_META_FILE_OLD: 'blocklet.json',
|
|
139
173
|
|
|
140
174
|
BLOCKLET_DEFAULT_VERSION: '1.0.0',
|
|
141
|
-
BLOCKLET_DEFAULT_PORT_NAME: 'BLOCKLET_PORT',
|
|
142
175
|
|
|
143
|
-
BLOCKLET_LATEST_SPEC_VERSION: '1.2.
|
|
176
|
+
BLOCKLET_LATEST_SPEC_VERSION: '1.2.2',
|
|
144
177
|
BLOCKLET_LATEST_REQUIREMENT_SERVER: '>=1.6.2',
|
|
145
178
|
BLOCKLET_LATEST_REQUIREMENT_ABTNODE: '>=1.5.15', // Deprecated
|
|
146
179
|
|
|
@@ -149,6 +182,8 @@ module.exports = Object.freeze({
|
|
|
149
182
|
BLOCKLET_APP_NAME: 'BLOCKLET_APP_NAME',
|
|
150
183
|
BLOCKLET_APP_DESCRIPTION: 'BLOCKLET_APP_DESCRIPTION',
|
|
151
184
|
BLOCKLET_APP_SK: 'BLOCKLET_APP_SK',
|
|
185
|
+
BLOCKLET_APP_URL: 'BLOCKLET_APP_URL',
|
|
186
|
+
BLOCKLET_PASSPORT_COLOR: 'BLOCKLET_PASSPORT_COLOR',
|
|
152
187
|
BLOCKLET_WALLET_TYPE: 'BLOCKLET_WALLET_TYPE',
|
|
153
188
|
BLOCKLET_DELETABLE: 'BLOCKLET_DELETABLE',
|
|
154
189
|
},
|
package/lib/did.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { types } = require('@ocap/mcrypto');
|
|
2
2
|
const { toHex } = require('@ocap/util');
|
|
3
3
|
const { fromPublicKey } = require('@arcblock/did');
|
|
4
4
|
|
|
5
|
-
const { types } = Mcrypto;
|
|
6
|
-
|
|
7
5
|
const toBlockletDid = (name) => {
|
|
8
6
|
const pk = toHex(name);
|
|
9
7
|
return fromPublicKey(pk, { role: types.RoleType.ROLE_ANY });
|
package/lib/fix.js
CHANGED
|
@@ -12,9 +12,6 @@ const {
|
|
|
12
12
|
BLOCKLET_DYNAMIC_PATH_PREFIX,
|
|
13
13
|
BLOCKLET_INTERFACE_TYPE_WEB,
|
|
14
14
|
BLOCKLET_INTERFACE_PUBLIC,
|
|
15
|
-
BLOCKLET_INTERFACE_ADMIN,
|
|
16
|
-
BLOCKLET_INTERFACE_CONFIG,
|
|
17
|
-
BLOCKLET_INTERFACE_DOC,
|
|
18
15
|
} = require('./constants');
|
|
19
16
|
|
|
20
17
|
// Assign sensible defaults: name/description/main/group/version/public_url
|
|
@@ -203,13 +200,11 @@ const fixInterfaces = (meta, removeMerged = true) => {
|
|
|
203
200
|
meta.interfaces.push({ type, name, path, prefix, port, protocol });
|
|
204
201
|
};
|
|
205
202
|
|
|
206
|
-
[BLOCKLET_INTERFACE_PUBLIC
|
|
207
|
-
(x)
|
|
208
|
-
|
|
209
|
-
addInterface({ name: x, path: meta[x] });
|
|
210
|
-
}
|
|
203
|
+
[BLOCKLET_INTERFACE_PUBLIC].forEach((x) => {
|
|
204
|
+
if (meta[x]) {
|
|
205
|
+
addInterface({ name: x, path: meta[x] });
|
|
211
206
|
}
|
|
212
|
-
);
|
|
207
|
+
});
|
|
213
208
|
|
|
214
209
|
if (Array.isArray(meta.exposeServices)) {
|
|
215
210
|
meta.exposeServices.forEach((x) => {
|
package/lib/info.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const get = require('lodash/get');
|
|
2
2
|
const getBlockletWallet = require('./wallet');
|
|
3
|
+
const { getDisplayName } = require('./util');
|
|
3
4
|
|
|
4
5
|
module.exports = (state, nodeSk, { returnWallet = true } = {}) => {
|
|
5
6
|
if (!state || typeof state !== 'object' || !Array.isArray(state.environments) || !get(state, 'meta.did')) {
|
|
@@ -9,12 +10,13 @@ module.exports = (state, nodeSk, { returnWallet = true } = {}) => {
|
|
|
9
10
|
const { environments, configs = [] } = state;
|
|
10
11
|
const envs = [...configs, ...environments];
|
|
11
12
|
|
|
12
|
-
const customName = envs.find((x) => x.key === 'BLOCKLET_APP_NAME');
|
|
13
13
|
const customDescription = envs.find((x) => x.key === 'BLOCKLET_APP_DESCRIPTION');
|
|
14
|
+
const customPassportColor = envs.find((x) => x.key === 'BLOCKLET_PASSPORT_COLOR');
|
|
14
15
|
|
|
15
16
|
const { did } = state.meta;
|
|
16
|
-
const name =
|
|
17
|
+
const name = getDisplayName(state);
|
|
17
18
|
const description = get(customDescription, 'value', state.meta.description);
|
|
19
|
+
const passportColor = get(customPassportColor, 'value', 'auto');
|
|
18
20
|
|
|
19
21
|
if (!returnWallet) {
|
|
20
22
|
return {
|
|
@@ -51,6 +53,7 @@ module.exports = (state, nodeSk, { returnWallet = true } = {}) => {
|
|
|
51
53
|
did,
|
|
52
54
|
name,
|
|
53
55
|
description,
|
|
56
|
+
passportColor,
|
|
54
57
|
wallet,
|
|
55
58
|
};
|
|
56
59
|
};
|
package/lib/parse.js
CHANGED
|
@@ -2,7 +2,7 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const yaml = require('js-yaml');
|
|
4
4
|
const camelCase = require('lodash/camelCase');
|
|
5
|
-
const debug = require('debug')('@blocklet/meta:
|
|
5
|
+
const debug = require('debug')('@blocklet/meta:parse');
|
|
6
6
|
|
|
7
7
|
const { BLOCKLET_META_FILE, BLOCKLET_META_FILE_ALT, BLOCKLET_META_FILE_OLD } = require('./constants');
|
|
8
8
|
|
package/lib/payment.js
CHANGED
|
@@ -5,8 +5,6 @@ const { isValidFactory } = require('@ocap/asset');
|
|
|
5
5
|
const { toFactoryAddress } = require('@arcblock/did-util');
|
|
6
6
|
const { getBlockletPurchaseTemplate } = require('@arcblock/nft/lib/templates');
|
|
7
7
|
|
|
8
|
-
const { isFreeBlocklet } = require('./util');
|
|
9
|
-
|
|
10
8
|
const createShareContract = ({ tokens = [], shares = [] }) => {
|
|
11
9
|
const zeroBN = new BN(0);
|
|
12
10
|
const decimals = 1000000; // we only support 6 decimals on share ratio
|
|
@@ -81,7 +79,6 @@ const createNftFactoryItx = ({ meta, tokens, shares, issuers, serviceUrl }) => {
|
|
|
81
79
|
};
|
|
82
80
|
|
|
83
81
|
module.exports = {
|
|
84
|
-
isFreeBlocklet,
|
|
85
82
|
createShareContract,
|
|
86
83
|
createNftFactoryItx,
|
|
87
84
|
};
|
package/lib/schema.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/* eslint-disable newline-per-chained-call */
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const JOI = require('joi');
|
|
4
|
-
const
|
|
4
|
+
const cjkLength = require('cjk-length').default;
|
|
5
5
|
const isGlob = require('is-glob');
|
|
6
|
+
const { semver, semverRange } = require('joi-extension-semver');
|
|
6
7
|
|
|
7
8
|
const { fileExtension, didExtension } = require('./extension');
|
|
8
9
|
const { validateName } = require('./name');
|
|
@@ -23,6 +24,7 @@ const {
|
|
|
23
24
|
} = require('./constants');
|
|
24
25
|
|
|
25
26
|
const WELLKNOWN_PATH_PREFIX = '/.well-known';
|
|
27
|
+
const MAX_TITLE_LENGTH = 48;
|
|
26
28
|
|
|
27
29
|
const Joi = JOI.extend(semver).extend(semverRange).extend(fileExtension).extend(didExtension);
|
|
28
30
|
|
|
@@ -184,14 +186,25 @@ const createBlockletSchema = (
|
|
|
184
186
|
return value;
|
|
185
187
|
})
|
|
186
188
|
.required(),
|
|
187
|
-
description: Joi.string().trim().required(),
|
|
189
|
+
description: Joi.string().trim().min(3).max(512).required(),
|
|
188
190
|
group: Joi.string().valid(...BLOCKLET_GROUPS).required(), // prettier-ignore
|
|
189
191
|
main: Joi.when('group', {
|
|
190
192
|
is: Joi.valid(BlockletGroup.gateway),
|
|
191
193
|
then: Joi.forbidden(),
|
|
192
194
|
otherwise: ensureMain ? Joi.file().exists({ baseDir }).required() : Joi.string().trim().required(),
|
|
193
195
|
}),
|
|
194
|
-
title: Joi.string()
|
|
196
|
+
title: Joi.string()
|
|
197
|
+
.trim()
|
|
198
|
+
.min(3)
|
|
199
|
+
.custom((value) => {
|
|
200
|
+
if (cjkLength(value) > MAX_TITLE_LENGTH) {
|
|
201
|
+
throw new Error(`Blocklet title is too long. Max length is ${MAX_TITLE_LENGTH}`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return value;
|
|
205
|
+
})
|
|
206
|
+
.optional()
|
|
207
|
+
.allow(''),
|
|
195
208
|
logo: ensureFiles ? Joi.file().trim().exists({ baseDir }).optional() : Joi.string().trim().optional(),
|
|
196
209
|
specVersion: Joi.semver().valid().gte('1.0.0').optional(),
|
|
197
210
|
|
|
@@ -216,7 +229,7 @@ const createBlockletSchema = (
|
|
|
216
229
|
.max(4)
|
|
217
230
|
.items(
|
|
218
231
|
Joi.object({
|
|
219
|
-
value: Joi.number().required(),
|
|
232
|
+
value: Joi.number().greater(0).required(),
|
|
220
233
|
address: Joi.DID().required(), // token address
|
|
221
234
|
})
|
|
222
235
|
),
|
|
@@ -232,7 +245,7 @@ const createBlockletSchema = (
|
|
|
232
245
|
Joi.object({
|
|
233
246
|
name: Joi.string().required(),
|
|
234
247
|
address: Joi.DID().required(),
|
|
235
|
-
value: Joi.number().
|
|
248
|
+
value: Joi.number().greater(0).max(1).required(),
|
|
236
249
|
})
|
|
237
250
|
)
|
|
238
251
|
.custom((value) => {
|
|
@@ -242,13 +255,11 @@ const createBlockletSchema = (
|
|
|
242
255
|
}
|
|
243
256
|
const total = value.reduce((acc, cur) => acc + cur.value, 0);
|
|
244
257
|
if (total !== 1) {
|
|
245
|
-
throw new Error(`
|
|
258
|
+
throw new Error(`Invalid blocklet payment share config: total share must be 1, got ${total}`);
|
|
246
259
|
}
|
|
247
260
|
return value;
|
|
248
|
-
}, 'share
|
|
249
|
-
})
|
|
250
|
-
.default({ price: [], share: [] })
|
|
251
|
-
.optional(),
|
|
261
|
+
}, 'invalid blocklet share'),
|
|
262
|
+
}).default({ price: [], share: [] }),
|
|
252
263
|
|
|
253
264
|
keywords: Joi.alternatives()
|
|
254
265
|
.try(Joi.string().trim().min(1), Joi.array().items(Joi.string().min(1)))
|
|
@@ -321,7 +332,13 @@ const createBlockletSchema = (
|
|
|
321
332
|
// capabilities
|
|
322
333
|
capabilities: Joi.object({
|
|
323
334
|
clusterMode: Joi.boolean().default(false), // Can blocklet be started in cluster mode
|
|
324
|
-
|
|
335
|
+
|
|
336
|
+
// added in 1.2.2
|
|
337
|
+
component: Joi.boolean().default(true), // Can blocklet become a component and be composed by other blocklets
|
|
338
|
+
}).default({
|
|
339
|
+
clusterMode: false,
|
|
340
|
+
component: true,
|
|
341
|
+
}),
|
|
325
342
|
|
|
326
343
|
// Other contents to be included in the bundle
|
|
327
344
|
files: Joi.array()
|
package/lib/util.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/* eslint-disable no-await-in-loop */
|
|
2
2
|
const get = require('lodash/get');
|
|
3
3
|
|
|
4
|
+
const { BlockletGroup } = require('./constants');
|
|
5
|
+
|
|
4
6
|
const forEachBlocklet = (blocklet, cb, { parallel = false, sync } = {}) => {
|
|
5
7
|
// sync
|
|
6
8
|
if (sync) {
|
|
@@ -15,15 +17,21 @@ const forEachBlocklet = (blocklet, cb, { parallel = false, sync } = {}) => {
|
|
|
15
17
|
|
|
16
18
|
// serial
|
|
17
19
|
if (!parallel) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
21
|
+
return new Promise(async (resolve, reject) => {
|
|
22
|
+
try {
|
|
23
|
+
await cb(blocklet);
|
|
24
|
+
if (blocklet.children) {
|
|
25
|
+
for (const child of blocklet.children) {
|
|
26
|
+
await cb(child);
|
|
27
|
+
}
|
|
23
28
|
}
|
|
29
|
+
|
|
30
|
+
resolve(null);
|
|
31
|
+
} catch (err) {
|
|
32
|
+
reject(err);
|
|
24
33
|
}
|
|
25
|
-
|
|
26
|
-
})();
|
|
34
|
+
});
|
|
27
35
|
}
|
|
28
36
|
|
|
29
37
|
// parallel
|
|
@@ -37,6 +45,8 @@ const forEachBlocklet = (blocklet, cb, { parallel = false, sync } = {}) => {
|
|
|
37
45
|
return Promise.all(tasks);
|
|
38
46
|
};
|
|
39
47
|
|
|
48
|
+
const forEachBlockletSync = (blocklet, cb) => forEachBlocklet(blocklet, cb, { sync: true });
|
|
49
|
+
|
|
40
50
|
const isAuthServiceEnabled = (blocklet) => {
|
|
41
51
|
const interfaces = get(blocklet, 'meta.interfaces') || [];
|
|
42
52
|
const isRootEnabled = interfaces.some((x) => {
|
|
@@ -91,6 +101,10 @@ const isFreeBlocklet = (meta) => {
|
|
|
91
101
|
return priceList.every((x) => x === 0);
|
|
92
102
|
};
|
|
93
103
|
|
|
104
|
+
const isComponentBlocklet = (meta) => {
|
|
105
|
+
return get(meta, 'capabilities.component') !== false;
|
|
106
|
+
};
|
|
107
|
+
|
|
94
108
|
const wipeSensitiveData = (blocklet) => {
|
|
95
109
|
if (!blocklet) {
|
|
96
110
|
return blocklet;
|
|
@@ -132,11 +146,45 @@ const isDeletableBlocklet = (blocklet) => {
|
|
|
132
146
|
return config.value === 'yes';
|
|
133
147
|
};
|
|
134
148
|
|
|
149
|
+
const hasRunnableComponent = (blocklet) => {
|
|
150
|
+
let has = false;
|
|
151
|
+
forEachBlockletSync(blocklet, (x) => {
|
|
152
|
+
if (x.meta.group !== BlockletGroup.gateway) {
|
|
153
|
+
has = true;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
return has;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* 获取 blocklet 的 name
|
|
162
|
+
* @param {Object} blocklet 应用数据
|
|
163
|
+
* @param {Boolean} onlyUseMeta 优先使用应用元数据的name
|
|
164
|
+
* @returns blocklet display name
|
|
165
|
+
*/
|
|
166
|
+
const getDisplayName = (blocklet, onlyUseMeta = false) => {
|
|
167
|
+
const { meta } = blocklet;
|
|
168
|
+
let displayName;
|
|
169
|
+
|
|
170
|
+
if (!onlyUseMeta && blocklet.environments) {
|
|
171
|
+
const target = blocklet.environments.find((e) => e.key === 'BLOCKLET_APP_NAME');
|
|
172
|
+
if (target && target.value) {
|
|
173
|
+
displayName = target.value;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return displayName || meta.title || meta.name;
|
|
177
|
+
};
|
|
178
|
+
|
|
135
179
|
module.exports = {
|
|
136
180
|
isFreeBlocklet,
|
|
181
|
+
isComponentBlocklet,
|
|
182
|
+
forEachBlockletSync,
|
|
137
183
|
isDeletableBlocklet,
|
|
138
184
|
forEachBlocklet,
|
|
139
185
|
isAuthServiceEnabled,
|
|
140
186
|
getRequiredMissingConfigs,
|
|
141
187
|
wipeSensitiveData,
|
|
188
|
+
hasRunnableComponent,
|
|
189
|
+
getDisplayName,
|
|
142
190
|
};
|
package/lib/wallet.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { types } = require('@ocap/mcrypto');
|
|
2
2
|
const { fromSecretKey } = require('@ocap/wallet');
|
|
3
3
|
const { isValid } = require('@arcblock/did');
|
|
4
4
|
const { fromAppDid } = require('@arcblock/did-ext');
|
|
5
5
|
|
|
6
|
-
const { types } = Mcrypto;
|
|
7
|
-
|
|
8
6
|
/**
|
|
9
7
|
* Gen DID from blocklet did and nodeSk
|
|
10
8
|
*
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.6.
|
|
6
|
+
"version": "1.6.19",
|
|
7
7
|
"description": "Library to parse/validate/fix blocklet meta",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -18,20 +18,21 @@
|
|
|
18
18
|
"author": "wangshijun <wangshijun2020@gmail.com> (http://github.com/wangshijun)",
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@arcblock/did": "^1.
|
|
22
|
-
"@arcblock/did-ext": "^1.
|
|
23
|
-
"@arcblock/did-util": "^1.
|
|
24
|
-
"@arcblock/nft": "^1.
|
|
25
|
-
"@ocap/asset": "^1.
|
|
26
|
-
"@ocap/mcrypto": "^1.
|
|
27
|
-
"@ocap/util": "^1.
|
|
28
|
-
"@ocap/wallet": "^1.
|
|
21
|
+
"@arcblock/did": "^1.14.11",
|
|
22
|
+
"@arcblock/did-ext": "^1.14.11",
|
|
23
|
+
"@arcblock/did-util": "^1.14.11",
|
|
24
|
+
"@arcblock/nft": "^1.14.11",
|
|
25
|
+
"@ocap/asset": "^1.14.11",
|
|
26
|
+
"@ocap/mcrypto": "^1.14.11",
|
|
27
|
+
"@ocap/util": "^1.14.11",
|
|
28
|
+
"@ocap/wallet": "^1.14.11",
|
|
29
29
|
"ajv": "^7.0.3",
|
|
30
|
+
"cjk-length": "^1.0.0",
|
|
30
31
|
"debug": "^4.3.3",
|
|
31
32
|
"fs-extra": "^10.0.0",
|
|
32
33
|
"hosted-git-info": "3.0.8",
|
|
33
34
|
"is-glob": "^4.0.3",
|
|
34
|
-
"joi": "^17.
|
|
35
|
+
"joi": "^17.6.0",
|
|
35
36
|
"joi-extension-semver": "^5.0.0",
|
|
36
37
|
"js-yaml": "^3.14.0",
|
|
37
38
|
"json-stable-stringify": "^1.0.1",
|
|
@@ -42,5 +43,5 @@
|
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"jest": "^27.4.5"
|
|
44
45
|
},
|
|
45
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "42a1290f14fca261eccafb05561eecf8683ed66a"
|
|
46
47
|
}
|