@abtnode/core 1.16.28-next-5a717317 → 1.16.28
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/api/team.js +3 -3
- package/lib/blocklet/hooks.js +9 -1
- package/lib/blocklet/manager/disk.js +6 -5
- package/lib/blocklet/manager/helper/install-component-from-url.js +3 -1
- package/lib/blocklet/project/create-pack-release.js +2 -2
- package/lib/blocklet/project/index.js +56 -22
- package/lib/blocklet/project/util.js +35 -0
- package/lib/monitor/blocklet-runtime-monitor.js +1 -1
- package/lib/monitor/node-runtime-monitor.js +1 -1
- package/lib/router/helper.js +8 -8
- package/lib/router/manager.js +2 -2
- package/lib/states/audit-log.js +5 -5
- package/lib/states/release.js +1 -0
- package/lib/states/user.js +3 -0
- package/lib/util/blocklet.js +29 -10
- package/lib/util/get-accessible-external-node-ip.js +2 -2
- package/lib/util/index.js +3 -3
- package/lib/util/launcher.js +3 -3
- package/lib/util/spaces.js +4 -2
- package/lib/util/store.js +8 -6
- package/lib/validators/node.js +1 -0
- package/lib/validators/project.js +3 -0
- package/package.json +24 -24
package/lib/api/team.js
CHANGED
|
@@ -2,7 +2,7 @@ const { EventEmitter } = require('events');
|
|
|
2
2
|
const pick = require('lodash/pick');
|
|
3
3
|
const defaults = require('lodash/defaults');
|
|
4
4
|
const cloneDeep = require('lodash/cloneDeep');
|
|
5
|
-
const
|
|
5
|
+
const { joinURL } = require('ufo');
|
|
6
6
|
|
|
7
7
|
const logger = require('@abtnode/logger')('@abtnode/core:api:team');
|
|
8
8
|
const {
|
|
@@ -511,7 +511,7 @@ class TeamAPI extends EventEmitter {
|
|
|
511
511
|
role,
|
|
512
512
|
}),
|
|
513
513
|
endpoint: getPassportStatusEndpoint({
|
|
514
|
-
baseUrl:
|
|
514
|
+
baseUrl: joinURL(appUrl, WELLKNOWN_SERVICE_PATH_PREFIX),
|
|
515
515
|
userDid,
|
|
516
516
|
teamDid,
|
|
517
517
|
}),
|
|
@@ -966,7 +966,7 @@ class TeamAPI extends EventEmitter {
|
|
|
966
966
|
role,
|
|
967
967
|
}),
|
|
968
968
|
endpoint: getPassportStatusEndpoint({
|
|
969
|
-
baseUrl:
|
|
969
|
+
baseUrl: joinURL(appUrl, WELLKNOWN_SERVICE_PATH_PREFIX),
|
|
970
970
|
userDid,
|
|
971
971
|
teamDid,
|
|
972
972
|
}),
|
package/lib/blocklet/hooks.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const get = require('lodash/get');
|
|
2
2
|
const camelCase = require('lodash/camelCase');
|
|
3
3
|
const runScript = require('@abtnode/util/lib/run-script');
|
|
4
|
+
const { getSecurityNodeOptions } = require('@abtnode/util/lib/security');
|
|
4
5
|
|
|
5
6
|
// eslint-disable-next-line global-require
|
|
6
7
|
const logger = require('@abtnode/logger')(`${require('../../package.json').name}:blocklet:hooks`);
|
|
7
8
|
|
|
8
9
|
const { getSafeEnv } = require('../util');
|
|
10
|
+
const states = require('../states');
|
|
9
11
|
|
|
10
12
|
const runUserHook = async (label, hookName, args) => {
|
|
11
13
|
const {
|
|
@@ -27,10 +29,16 @@ const runUserHook = async (label, hookName, args) => {
|
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
logger.info(`run hook:${hookName}:`, { label, hook });
|
|
32
|
+
|
|
33
|
+
const nodeInfo = await states.node.read();
|
|
30
34
|
// FIXME @linchen timeout 应该动态设置或不设置
|
|
31
35
|
await runScript(hook, [label, hookName].join(':'), {
|
|
32
36
|
cwd: appDir,
|
|
33
|
-
env: {
|
|
37
|
+
env: {
|
|
38
|
+
...getSafeEnv(env),
|
|
39
|
+
BLOCKLET_HOOK_NAME: hookName,
|
|
40
|
+
NODE_OPTIONS: getSecurityNodeOptions({ environmentObj: env, ...args }, nodeInfo.enableFileSystemIsolation),
|
|
41
|
+
},
|
|
34
42
|
silent,
|
|
35
43
|
output: outputFile,
|
|
36
44
|
error: errorFile,
|
|
@@ -16,7 +16,7 @@ const { sign } = require('@arcblock/jwt');
|
|
|
16
16
|
const { isInServerlessMode } = require('@abtnode/util/lib/serverless');
|
|
17
17
|
const sleep = require('@abtnode/util/lib/sleep');
|
|
18
18
|
const getBlockletInfo = require('@blocklet/meta/lib/info');
|
|
19
|
-
const
|
|
19
|
+
const { joinURL } = require('ufo');
|
|
20
20
|
const { sendToUser } = require('@blocklet/sdk/lib/util/send-notification');
|
|
21
21
|
|
|
22
22
|
const logger = require('@abtnode/logger')('@abtnode/core:blocklet:manager');
|
|
@@ -2799,7 +2799,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2799
2799
|
* @type {import('@abtnode/client').NodeState}
|
|
2800
2800
|
*/
|
|
2801
2801
|
const node = await states.node.read();
|
|
2802
|
-
referrer =
|
|
2802
|
+
referrer = joinURL(
|
|
2803
2803
|
`https://${encode(node.did)}.${DEFAULT_DID_DOMAIN}`,
|
|
2804
2804
|
node.routing.adminPath,
|
|
2805
2805
|
`/blocklets/${did}/storage`
|
|
@@ -3253,7 +3253,8 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3253
3253
|
logo: '',
|
|
3254
3254
|
};
|
|
3255
3255
|
} else {
|
|
3256
|
-
|
|
3256
|
+
// Note: the component maybe in dev mode or removed
|
|
3257
|
+
logger.warn(`engine component ${engineId} not found for ${did}`);
|
|
3257
3258
|
}
|
|
3258
3259
|
} else {
|
|
3259
3260
|
component.engine = getEngine(engine.interpreter)?.describe();
|
|
@@ -4486,7 +4487,7 @@ class FederatedBlockletManager extends DiskBlockletManager {
|
|
|
4486
4487
|
async joinFederatedLogin({ appUrl, did }, context) {
|
|
4487
4488
|
const url = new URL(appUrl);
|
|
4488
4489
|
// master service api 的地址
|
|
4489
|
-
url.pathname =
|
|
4490
|
+
url.pathname = joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, '/api/federated/join');
|
|
4490
4491
|
|
|
4491
4492
|
const blocklet = await this.getBlocklet(did);
|
|
4492
4493
|
const nodeInfo = await states.node.read();
|
|
@@ -4503,7 +4504,7 @@ class FederatedBlockletManager extends DiskBlockletManager {
|
|
|
4503
4504
|
aliasDomain: domainAliases.map((x) => x.value),
|
|
4504
4505
|
appLogo:
|
|
4505
4506
|
blocklet.environmentObj.BLOCKLET_APP_LOGO ||
|
|
4506
|
-
normalizePathPrefix(
|
|
4507
|
+
normalizePathPrefix(joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, '/blocklet/logo')) ||
|
|
4507
4508
|
'/',
|
|
4508
4509
|
appLogoRect: blocklet.environmentObj.BLOCKLET_APP_LOGO_RECT,
|
|
4509
4510
|
did: permanentWallet.address,
|
|
@@ -95,9 +95,11 @@ const installComponentFromUrl = async ({
|
|
|
95
95
|
const { dynamicComponents } = await parseComponents(newChild);
|
|
96
96
|
|
|
97
97
|
const index = blocklet.children.findIndex((child) => child.meta.did === meta.did);
|
|
98
|
+
|
|
98
99
|
if (index >= 0) {
|
|
99
100
|
// if upgrade, do not update mountPoint and title
|
|
100
|
-
newChild.mountPoint =
|
|
101
|
+
newChild.mountPoint =
|
|
102
|
+
blocklet.children[index].mountPoint || formatName(newChildMeta.title) || formatName(newChildMeta.name);
|
|
101
103
|
// 更新版本时, title 应该更新
|
|
102
104
|
// newChild.meta.title = blocklet.children[index].meta.title;
|
|
103
105
|
newChild.installedAt = blocklet.children[index].installedAt;
|
|
@@ -13,7 +13,7 @@ const { createRelease: createBlockletRelease } = require('@abtnode/util/lib/crea
|
|
|
13
13
|
const urlPathFriendly = require('@blocklet/meta/lib/url-path-friendly').default;
|
|
14
14
|
const { hasStartEngine } = require('@blocklet/meta/lib/util');
|
|
15
15
|
|
|
16
|
-
const logger = require('@abtnode/logger')('
|
|
16
|
+
const logger = require('@abtnode/logger')('blocklet-studio-pack');
|
|
17
17
|
|
|
18
18
|
const { createReleaseSchema } = require('../../validators/project');
|
|
19
19
|
|
|
@@ -228,7 +228,7 @@ const createPackRelease = async ({
|
|
|
228
228
|
if (fs.existsSync(extendedMetaFile)) {
|
|
229
229
|
const extendedMeta = readMetaFile(extendedMetaFile);
|
|
230
230
|
logger.info('merge extended blocklet.yml', extendedMeta);
|
|
231
|
-
Object.assign(meta, pick(extendedMeta, ['environments', 'engine']));
|
|
231
|
+
Object.assign(meta, pick(extendedMeta, ['environments', 'engine', 'capabilities']));
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
// Reset group for blocklets with engine specified
|
|
@@ -10,7 +10,7 @@ const { titleSchema } = require('@blocklet/meta/lib/schema');
|
|
|
10
10
|
const { validateNewDid } = require('@blocklet/meta/lib/name');
|
|
11
11
|
const urlPathFriendly = require('@blocklet/meta/lib/url-path-friendly').default;
|
|
12
12
|
|
|
13
|
-
const logger = require('@abtnode/logger')('
|
|
13
|
+
const logger = require('@abtnode/logger')('blocklet-studio');
|
|
14
14
|
|
|
15
15
|
const { createReleaseSchema } = require('../../validators/project');
|
|
16
16
|
const getIsMultipleTenant = require('./get-is-multiple-tenant');
|
|
@@ -19,8 +19,10 @@ const {
|
|
|
19
19
|
getLogoFile,
|
|
20
20
|
exportBlockletResources,
|
|
21
21
|
getResourceList,
|
|
22
|
+
checkUploadExists,
|
|
22
23
|
checkResourceExists,
|
|
23
24
|
getExtendedMetaFile,
|
|
25
|
+
exportUploadedResources,
|
|
24
26
|
} = require('./util');
|
|
25
27
|
const createPackRelease = require('./create-pack-release');
|
|
26
28
|
const connectToStore = require('./connect-to-store');
|
|
@@ -172,6 +174,7 @@ const createRelease = async ({
|
|
|
172
174
|
blockletIntroduction,
|
|
173
175
|
blockletLogo,
|
|
174
176
|
blockletScreenshots,
|
|
177
|
+
uploadedResource,
|
|
175
178
|
blockletComponents,
|
|
176
179
|
note,
|
|
177
180
|
manager,
|
|
@@ -196,6 +199,7 @@ const createRelease = async ({
|
|
|
196
199
|
blockletLogo,
|
|
197
200
|
blockletIntroduction,
|
|
198
201
|
blockletScreenshots,
|
|
202
|
+
uploadedResource,
|
|
199
203
|
note,
|
|
200
204
|
};
|
|
201
205
|
|
|
@@ -235,16 +239,16 @@ const createRelease = async ({
|
|
|
235
239
|
if (action === 'update') {
|
|
236
240
|
const release = await releaseState.findOne({ projectId, id: releaseId });
|
|
237
241
|
if (!release) {
|
|
238
|
-
throw new Error(
|
|
242
|
+
throw new Error(`Blocklet release ${releaseId} not found for project ${projectId}`);
|
|
239
243
|
}
|
|
240
244
|
if (release.status !== 'draft') {
|
|
241
|
-
throw new Error(
|
|
245
|
+
throw new Error(`Can not update a published release: ${releaseId}`);
|
|
242
246
|
}
|
|
243
247
|
}
|
|
244
248
|
|
|
245
249
|
const existVersion = await releaseState.findOne({ projectId, blockletVersion });
|
|
246
250
|
if (existVersion && (action === 'create' || existVersion.id !== releaseId)) {
|
|
247
|
-
throw new Error(`
|
|
251
|
+
throw new Error(`Release version ${blockletVersion} already exists`);
|
|
248
252
|
}
|
|
249
253
|
|
|
250
254
|
const { blockletDid } = project0;
|
|
@@ -253,8 +257,14 @@ const createRelease = async ({
|
|
|
253
257
|
|
|
254
258
|
const projectDir = path.join(blocklet.env.dataDir, PROJECT.DIR, `${projectId}`);
|
|
255
259
|
|
|
260
|
+
// validate resources
|
|
261
|
+
const isResourceFromUpload = !!uploadedResource;
|
|
256
262
|
if (status !== PROJECT.RELEASE_STATUS.draft) {
|
|
257
|
-
|
|
263
|
+
if (isResourceFromUpload) {
|
|
264
|
+
await checkUploadExists(projectDir, action, releaseId, uploadedResource);
|
|
265
|
+
} else {
|
|
266
|
+
await checkResourceExists(projectDir, action, releaseId);
|
|
267
|
+
}
|
|
258
268
|
}
|
|
259
269
|
|
|
260
270
|
const release = await releaseState.upsertRelease({
|
|
@@ -264,6 +274,7 @@ const createRelease = async ({
|
|
|
264
274
|
releaseId,
|
|
265
275
|
status,
|
|
266
276
|
});
|
|
277
|
+
logger.info('release upsert done', release);
|
|
267
278
|
|
|
268
279
|
const _releaseId = release.id;
|
|
269
280
|
const releaseDir = path.join(projectDir, PROJECT.RELEASE_DIR, `${_releaseId}`);
|
|
@@ -301,7 +312,7 @@ const createRelease = async ({
|
|
|
301
312
|
}
|
|
302
313
|
|
|
303
314
|
if (fs.existsSync(releaseFile)) {
|
|
304
|
-
logger.
|
|
315
|
+
logger.warn('release file exists, remove it', releaseFile);
|
|
305
316
|
await fs.remove(releaseFile);
|
|
306
317
|
}
|
|
307
318
|
|
|
@@ -338,17 +349,7 @@ const createRelease = async ({
|
|
|
338
349
|
});
|
|
339
350
|
await fs.outputFile(changelogDistFile, changelog.join('\n\n'));
|
|
340
351
|
|
|
341
|
-
// create resource
|
|
342
|
-
await exportBlockletResources({
|
|
343
|
-
app: blocklet,
|
|
344
|
-
projectId,
|
|
345
|
-
releaseId: _releaseId,
|
|
346
|
-
exportDir: releaseBundleDir,
|
|
347
|
-
blockletDid,
|
|
348
|
-
});
|
|
349
|
-
|
|
350
352
|
// create blocklet.yml
|
|
351
|
-
const resourceList = await getResourceList(resourceDir);
|
|
352
353
|
const meta = {
|
|
353
354
|
did: blockletDid,
|
|
354
355
|
name: blockletDid,
|
|
@@ -356,20 +357,53 @@ const createRelease = async ({
|
|
|
356
357
|
description: blockletDescription,
|
|
357
358
|
version: blockletVersion,
|
|
358
359
|
logo: logoFileName,
|
|
359
|
-
resource: {
|
|
360
|
-
bundles: resourceList.length ? resourceList : undefined,
|
|
361
|
-
},
|
|
362
360
|
components: [],
|
|
363
361
|
files: project.blockletScreenshots?.length ? ['screenshots'] : [],
|
|
364
362
|
screenshots: project.blockletScreenshots || [],
|
|
365
363
|
};
|
|
366
364
|
|
|
365
|
+
// create resource
|
|
366
|
+
if (isResourceFromUpload) {
|
|
367
|
+
await exportUploadedResources({
|
|
368
|
+
app: blocklet,
|
|
369
|
+
projectId,
|
|
370
|
+
releaseId: _releaseId,
|
|
371
|
+
exportDir: releaseBundleDir,
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
meta.main = PROJECT.MAIN_DIR;
|
|
375
|
+
meta.engine = {
|
|
376
|
+
interpreter: 'blocklet',
|
|
377
|
+
source: {
|
|
378
|
+
// FIXME: @wangshijun publish this to production store
|
|
379
|
+
store: 'https://test.store.blocklet.dev',
|
|
380
|
+
name: 'z2qa2dGC9EmsjB2WJtUcmuRWx43zTwPUZQF7g',
|
|
381
|
+
version: 'latest',
|
|
382
|
+
},
|
|
383
|
+
};
|
|
384
|
+
} else {
|
|
385
|
+
await exportBlockletResources({
|
|
386
|
+
app: blocklet,
|
|
387
|
+
projectId,
|
|
388
|
+
releaseId: _releaseId,
|
|
389
|
+
exportDir: releaseBundleDir,
|
|
390
|
+
blockletDid,
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
const resourceList = await getResourceList(resourceDir);
|
|
394
|
+
if (resourceList) {
|
|
395
|
+
meta.resource = {
|
|
396
|
+
bundles: resourceList.length ? resourceList : undefined,
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
367
401
|
// merge extended blocklet.yml
|
|
368
402
|
const extendedMetaFile = getExtendedMetaFile({ app: blocklet, projectId, releaseId });
|
|
369
403
|
if (fs.existsSync(extendedMetaFile)) {
|
|
370
404
|
const extendedMeta = readMetaFile(extendedMetaFile);
|
|
371
|
-
logger.info('
|
|
372
|
-
Object.assign(meta, pick(extendedMeta, ['environments', 'engine']));
|
|
405
|
+
logger.info('release extended blocklet.yml', extendedMeta);
|
|
406
|
+
Object.assign(meta, pick(extendedMeta, ['environments', 'engine', 'capabilities']));
|
|
373
407
|
}
|
|
374
408
|
|
|
375
409
|
// Enable mountPoint for blocklets with engine specified
|
|
@@ -411,7 +445,7 @@ const createRelease = async ({
|
|
|
411
445
|
files: [releaseFileName],
|
|
412
446
|
});
|
|
413
447
|
|
|
414
|
-
logger.info('
|
|
448
|
+
logger.info('release finalized', res2);
|
|
415
449
|
|
|
416
450
|
return res2;
|
|
417
451
|
} catch (error) {
|
|
@@ -3,6 +3,7 @@ const fs = require('fs-extra');
|
|
|
3
3
|
const fg = require('fast-glob');
|
|
4
4
|
const { isValid: isValidDid } = require('@arcblock/did');
|
|
5
5
|
const { PROJECT, BLOCKLET_RESOURCE_DIR, BLOCKLET_META_FILE } = require('@blocklet/constant');
|
|
6
|
+
const { expandBundle } = require('../../util');
|
|
6
7
|
|
|
7
8
|
const COMPONENT_CONFIG_MAP_DIR = '.component_config';
|
|
8
9
|
|
|
@@ -77,6 +78,15 @@ const exportBlockletResources = async ({
|
|
|
77
78
|
}
|
|
78
79
|
};
|
|
79
80
|
|
|
81
|
+
const exportUploadedResources = async ({ app, projectId, releaseId, exportDir }) => {
|
|
82
|
+
const projectDir = path.join(app.env.dataDir, PROJECT.DIR, `${projectId}`);
|
|
83
|
+
const releaseDir = path.join(projectDir, PROJECT.RELEASE_DIR, `${releaseId}`);
|
|
84
|
+
const sourceDir = path.join(releaseDir, PROJECT.RESOURCE_DIR, PROJECT.MAIN_DIR);
|
|
85
|
+
const destDir = path.join(exportDir, PROJECT.MAIN_DIR);
|
|
86
|
+
await fs.ensureDir(destDir);
|
|
87
|
+
await fs.copy(sourceDir, destDir);
|
|
88
|
+
};
|
|
89
|
+
|
|
80
90
|
async function checkIfDirectory(file) {
|
|
81
91
|
try {
|
|
82
92
|
const stats = await fs.promises.stat(file);
|
|
@@ -135,6 +145,29 @@ const checkResourceExists = async (projectDir, action, releaseId) => {
|
|
|
135
145
|
}
|
|
136
146
|
};
|
|
137
147
|
|
|
148
|
+
const checkUploadExists = async (projectDir, action, releaseId, uploadedResource) => {
|
|
149
|
+
const uploadedFile = path.join(projectDir, PROJECT.ASSET_DIR, uploadedResource);
|
|
150
|
+
if (!fs.existsSync(uploadedFile)) {
|
|
151
|
+
throw new Error(`Uploaded resource does not exist: ${uploadedResource}`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const resourceDir =
|
|
155
|
+
action === 'create'
|
|
156
|
+
? path.join(projectDir, PROJECT.RESOURCE_DIR, PROJECT.MAIN_DIR)
|
|
157
|
+
: path.join(projectDir, PROJECT.RELEASE_DIR, `${releaseId}`, PROJECT.RESOURCE_DIR, PROJECT.MAIN_DIR);
|
|
158
|
+
|
|
159
|
+
if (fs.existsSync(resourceDir)) {
|
|
160
|
+
fs.rmSync(resourceDir, { recursive: true });
|
|
161
|
+
}
|
|
162
|
+
fs.ensureDirSync(resourceDir);
|
|
163
|
+
|
|
164
|
+
await expandBundle(uploadedFile, resourceDir);
|
|
165
|
+
const files = ['index.html', 'index.htm'];
|
|
166
|
+
if (files.every((file) => fs.existsSync(path.join(resourceDir, file)) === false)) {
|
|
167
|
+
throw new Error(`Uploaded resource does not contain index.html or index.htm: ${uploadedResource}`);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
138
171
|
const getExtendedMetaFile = ({ app, projectId, releaseId }) => {
|
|
139
172
|
const { dataDir } = app.env;
|
|
140
173
|
const dirArr = [dataDir, PROJECT.DIR, projectId || '/'];
|
|
@@ -148,7 +181,9 @@ const getExtendedMetaFile = ({ app, projectId, releaseId }) => {
|
|
|
148
181
|
module.exports = {
|
|
149
182
|
getLogoFile,
|
|
150
183
|
exportBlockletResources,
|
|
184
|
+
exportUploadedResources,
|
|
151
185
|
getResourceList,
|
|
186
|
+
checkUploadExists,
|
|
152
187
|
checkResourceExists,
|
|
153
188
|
getExtendedMetaFile,
|
|
154
189
|
};
|
package/lib/router/helper.js
CHANGED
|
@@ -10,7 +10,7 @@ const get = require('lodash/get');
|
|
|
10
10
|
const cloneDeep = require('lodash/cloneDeep');
|
|
11
11
|
const groupBy = require('lodash/groupBy');
|
|
12
12
|
const isEqual = require('lodash/isEqual');
|
|
13
|
-
const
|
|
13
|
+
const { joinURL } = require('ufo');
|
|
14
14
|
const {
|
|
15
15
|
replaceSlotToIp,
|
|
16
16
|
findComponentById,
|
|
@@ -288,7 +288,7 @@ const ensureLatestInterfaceInfo = async (sites = []) => {
|
|
|
288
288
|
if (rule.isProtected && rule.to.target === WELLKNOWN_SERVICE_PATH_PREFIX) {
|
|
289
289
|
return rule;
|
|
290
290
|
}
|
|
291
|
-
if (rule.isProtected && rule.to.target ===
|
|
291
|
+
if (rule.isProtected && rule.to.target === joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, USER_AVATAR_PATH_PREFIX)) {
|
|
292
292
|
return rule;
|
|
293
293
|
}
|
|
294
294
|
|
|
@@ -359,7 +359,7 @@ const ensureWellknownRule = async (sites = []) => {
|
|
|
359
359
|
const rule = grouped[groupPathPrefix][0];
|
|
360
360
|
|
|
361
361
|
// Serve blocklet service always
|
|
362
|
-
const servicePathPrefix =
|
|
362
|
+
const servicePathPrefix = joinURL(groupPathPrefix, WELLKNOWN_SERVICE_PATH_PREFIX);
|
|
363
363
|
if (!site.rules.some((x) => x.from.pathPrefix === servicePathPrefix)) {
|
|
364
364
|
site.rules.push({
|
|
365
365
|
id: rule.id,
|
|
@@ -380,7 +380,7 @@ const ensureWellknownRule = async (sites = []) => {
|
|
|
380
380
|
}
|
|
381
381
|
|
|
382
382
|
// Cache user avatar from gateway
|
|
383
|
-
const avatarPathPrefix =
|
|
383
|
+
const avatarPathPrefix = joinURL(servicePathPrefix, USER_AVATAR_PATH_PREFIX);
|
|
384
384
|
if (!site.rules.some((x) => x.from.pathPrefix === avatarPathPrefix)) {
|
|
385
385
|
site.rules.push({
|
|
386
386
|
id: rule.id,
|
|
@@ -492,7 +492,7 @@ const ensureBlockletWellknownRules = (sites, blocklets) => {
|
|
|
492
492
|
|
|
493
493
|
const tmpMountPoint = mountPoint || blocklet.mountPoint;
|
|
494
494
|
if (tmpMountPoint) {
|
|
495
|
-
pathPrefix =
|
|
495
|
+
pathPrefix = joinURL(tmpMountPoint, pathPrefix);
|
|
496
496
|
}
|
|
497
497
|
|
|
498
498
|
const port = findInterfacePortByName(blocklet, tmpInterface.name);
|
|
@@ -585,7 +585,7 @@ const expandComponentRules = (sites = [], blocklets) => {
|
|
|
585
585
|
newRule.from.pathPrefix = baseRule.from.pathPrefix;
|
|
586
586
|
newRule.to.pageGroup = baseRule.to.pageGroup;
|
|
587
587
|
} else {
|
|
588
|
-
newRule.from.pathPrefix =
|
|
588
|
+
newRule.from.pathPrefix = joinURL(baseRule.from.pathPrefix, x.mountPoint);
|
|
589
589
|
}
|
|
590
590
|
|
|
591
591
|
expandedRules.push(newRule);
|
|
@@ -633,7 +633,7 @@ const ensureBlockletCache = (sites = [], blocklets) => {
|
|
|
633
633
|
const cacheable = get(findWebInterface(component), 'cacheable', []);
|
|
634
634
|
cacheable.forEach((cachePrefix) => {
|
|
635
635
|
const clone = cloneDeep(rule);
|
|
636
|
-
clone.from.pathPrefix =
|
|
636
|
+
clone.from.pathPrefix = joinURL(rule.from.pathPrefix, cachePrefix);
|
|
637
637
|
clone.to.cacheGroup = isServiceFeDevelopment ? '' : 'blockletProxy';
|
|
638
638
|
clone.to.targetPrefix = cachePrefix;
|
|
639
639
|
clone.dynamic = true; // mark as dynamic to avoid redundant generated rules
|
|
@@ -674,7 +674,7 @@ const decompressCertificates = async (source, dest) => {
|
|
|
674
674
|
return dest;
|
|
675
675
|
};
|
|
676
676
|
|
|
677
|
-
const joinCertDownUrl = (baseUrl, name) =>
|
|
677
|
+
const joinCertDownUrl = (baseUrl, name) => joinURL(baseUrl, '/certs', name);
|
|
678
678
|
|
|
679
679
|
const getIpEchoCertDownloadUrl = (baseUrl) => joinCertDownUrl(baseUrl, 'ip-abtnet-io.tar.gz');
|
|
680
680
|
const getDidDomainCertDownloadUrl = (baseUrl) => joinCertDownUrl(baseUrl, 'did-abtnet-io.tar.gz');
|
package/lib/router/manager.js
CHANGED
|
@@ -13,7 +13,7 @@ const toLower = require('lodash/toLower');
|
|
|
13
13
|
const { EventEmitter } = require('events');
|
|
14
14
|
const uuid = require('uuid');
|
|
15
15
|
const isUrl = require('is-url');
|
|
16
|
-
const
|
|
16
|
+
const { joinURL } = require('ufo');
|
|
17
17
|
const cloneDeep = require('lodash/cloneDeep');
|
|
18
18
|
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
19
19
|
const logger = require('@abtnode/logger')('@abtnode/core:router:manager');
|
|
@@ -704,7 +704,7 @@ class RouterManager extends EventEmitter {
|
|
|
704
704
|
const blockletPrefix = normalizePathPrefix(rawRule.from.pathPrefix);
|
|
705
705
|
|
|
706
706
|
// root component's mountPoint may not be '/'
|
|
707
|
-
const rootComponentPrefix =
|
|
707
|
+
const rootComponentPrefix = joinURL(blockletPrefix, blocklet.mountPoint || '/');
|
|
708
708
|
rawRule.from.pathPrefix = normalizePathPrefix(rootComponentPrefix);
|
|
709
709
|
|
|
710
710
|
const isOccupiable = isGatewayBlocklet(blocklet.meta);
|
package/lib/states/audit-log.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const pick = require('lodash/pick');
|
|
4
4
|
const get = require('lodash/get');
|
|
5
5
|
const uniq = require('lodash/uniq');
|
|
6
|
-
const
|
|
6
|
+
const { joinURL } = require('ufo');
|
|
7
7
|
const { getDisplayName } = require('@blocklet/meta/lib/util');
|
|
8
8
|
const { BLOCKLET_SITE_GROUP_SUFFIX, NODE_SERVICES } = require('@abtnode/constant');
|
|
9
9
|
const logger = require('@abtnode/logger')('@abtnode/core:states:audit-log');
|
|
@@ -12,7 +12,7 @@ const BaseState = require('./base');
|
|
|
12
12
|
|
|
13
13
|
const { parse } = require('../util/ua');
|
|
14
14
|
|
|
15
|
-
const getServerInfo = (info) => `[${info.name}](${
|
|
15
|
+
const getServerInfo = (info) => `[${info.name}](${joinURL(info.routing.adminPath, '/settings/about')})`;
|
|
16
16
|
/**
|
|
17
17
|
* @description
|
|
18
18
|
* @param {import('@abtnode/client').BlockletState} blocklet
|
|
@@ -21,7 +21,7 @@ const getServerInfo = (info) => `[${info.name}](${joinUrl(info.routing.adminPath
|
|
|
21
21
|
* }} info
|
|
22
22
|
* @returns {string}
|
|
23
23
|
*/
|
|
24
|
-
const getBlockletInfo = (blocklet, info) => `[${getDisplayName(blocklet)}](${
|
|
24
|
+
const getBlockletInfo = (blocklet, info) => `[${getDisplayName(blocklet)}](${joinURL(info.routing.adminPath, '/blocklets/', blocklet.meta.did, '/overview')})`; // prettier-ignore
|
|
25
25
|
const componentOrApplication = (componentDids) => (componentDids?.length ? 'component' : 'application');
|
|
26
26
|
const getComponentNames = (blocklet, componentDids, withVersion) =>
|
|
27
27
|
uniq(componentDids || [])
|
|
@@ -82,10 +82,10 @@ const expandUser = async (teamDid, userDid, passportId, info, node) => {
|
|
|
82
82
|
const passport = user.passports.find((x) => x.id === passportId);
|
|
83
83
|
|
|
84
84
|
if (teamDid === info.did) {
|
|
85
|
-
return [`[${user.fullName}](${
|
|
85
|
+
return [`[${user.fullName}](${joinURL(info.routing.adminPath, '/team/members')})`, passport ? passport.name : ''];
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
return [`[${user.fullName}](${
|
|
88
|
+
return [`[${user.fullName}](${joinURL(info.routing.adminPath, '/blocklets/', teamDid, '/members')})`, passport ? passport.name : '']; // prettier-ignore
|
|
89
89
|
};
|
|
90
90
|
|
|
91
91
|
/**
|
package/lib/states/release.js
CHANGED
package/lib/states/user.js
CHANGED
|
@@ -393,6 +393,7 @@ class User extends ExtendBase {
|
|
|
393
393
|
'email',
|
|
394
394
|
'avatar',
|
|
395
395
|
'role',
|
|
396
|
+
|
|
396
397
|
'locale',
|
|
397
398
|
'extra',
|
|
398
399
|
'lastLoginIp',
|
|
@@ -413,6 +414,8 @@ class User extends ExtendBase {
|
|
|
413
414
|
if (updates.sourceAppPid) {
|
|
414
415
|
delete updates.sourceAppPid;
|
|
415
416
|
}
|
|
417
|
+
// 登录不再更新 locale
|
|
418
|
+
delete updates.locale;
|
|
416
419
|
// update user, connectedAccount, passport
|
|
417
420
|
updates.connectedAccounts = updateConnectedAccount(exist.connectedAccounts, user.connectedAccount);
|
|
418
421
|
updated = await this.updateUser(exist.did, updates);
|
package/lib/util/blocklet.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable camelcase */
|
|
1
2
|
/* eslint-disable no-await-in-loop */
|
|
2
3
|
|
|
3
4
|
const fs = require('fs-extra');
|
|
@@ -27,7 +28,7 @@ const logger = require('@abtnode/logger')('@abtnode/core:util:blocklet');
|
|
|
27
28
|
const pm2 = require('@abtnode/util/lib/async-pm2');
|
|
28
29
|
const sleep = require('@abtnode/util/lib/sleep');
|
|
29
30
|
const getPm2ProcessInfo = require('@abtnode/util/lib/get-pm2-process-info');
|
|
30
|
-
const { formatEnv } = require('@abtnode/util/lib/security');
|
|
31
|
+
const { formatEnv, getSecurityNodeOptions } = require('@abtnode/util/lib/security');
|
|
31
32
|
const ensureEndpointHealthy = require('@abtnode/util/lib/ensure-endpoint-healthy');
|
|
32
33
|
const getFolderSize = require('@abtnode/util/lib/get-folder-size');
|
|
33
34
|
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
@@ -180,7 +181,9 @@ const getComponentDirs = (component, { dataDirs, ensure = false, ancestors = []
|
|
|
180
181
|
};
|
|
181
182
|
|
|
182
183
|
/**
|
|
183
|
-
* @
|
|
184
|
+
* @param component {import('@abtnode/client').ComponentState & { environmentObj: {[key: string]: string } } }
|
|
185
|
+
* @returns {{cwd, script, args, environmentObj, interpreter, interpreterArgs}: { args: []}}
|
|
186
|
+
* @return {*}
|
|
184
187
|
*/
|
|
185
188
|
const getComponentStartEngine = (component, { e2eMode = false } = {}) => {
|
|
186
189
|
if (!hasStartEngine(component.meta)) {
|
|
@@ -208,8 +211,8 @@ const getComponentStartEngine = (component, { e2eMode = false } = {}) => {
|
|
|
208
211
|
}
|
|
209
212
|
|
|
210
213
|
let script = null;
|
|
211
|
-
let interpreter
|
|
212
|
-
let interpreterArgs =
|
|
214
|
+
let interpreter;
|
|
215
|
+
let interpreterArgs = [];
|
|
213
216
|
const environmentObj = {};
|
|
214
217
|
let args = [];
|
|
215
218
|
|
|
@@ -226,11 +229,18 @@ const getComponentStartEngine = (component, { e2eMode = false } = {}) => {
|
|
|
226
229
|
|
|
227
230
|
if (component.mode !== BLOCKLET_MODES.DEVELOPMENT) {
|
|
228
231
|
const engine = getEngine(blockletEngineInfo.interpreter);
|
|
229
|
-
interpreter = engine.interpreter === 'node' ?
|
|
230
|
-
interpreterArgs = engine.args
|
|
232
|
+
interpreter = engine.interpreter === 'node' ? undefined : engine.interpreter;
|
|
233
|
+
interpreterArgs = interpreterArgs.concat(engine.args ? [engine.args] : []);
|
|
231
234
|
}
|
|
232
235
|
|
|
233
|
-
return {
|
|
236
|
+
return {
|
|
237
|
+
cwd,
|
|
238
|
+
script,
|
|
239
|
+
args,
|
|
240
|
+
environmentObj,
|
|
241
|
+
interpreter,
|
|
242
|
+
interpreterArgs: interpreterArgs.join(' ').trim(),
|
|
243
|
+
};
|
|
234
244
|
};
|
|
235
245
|
|
|
236
246
|
const getBlockletConfigObj = (blocklet, { excludeSecure } = {}) => {
|
|
@@ -248,7 +258,6 @@ const getBlockletConfigObj = (blocklet, { excludeSecure } = {}) => {
|
|
|
248
258
|
|
|
249
259
|
return obj;
|
|
250
260
|
};
|
|
251
|
-
|
|
252
261
|
/**
|
|
253
262
|
* set 'configs', configObj', 'environmentObj' to blocklet TODO
|
|
254
263
|
* @param {*} blocklet
|
|
@@ -531,6 +540,12 @@ const startBlockletProcess = async (
|
|
|
531
540
|
|
|
532
541
|
await forEachBlocklet(
|
|
533
542
|
blocklet,
|
|
543
|
+
/**
|
|
544
|
+
*
|
|
545
|
+
* @param {import('@abtnode/client').BlockletState} b
|
|
546
|
+
* @param {*} param1
|
|
547
|
+
* @returns
|
|
548
|
+
*/
|
|
534
549
|
async (b, { ancestors }) => {
|
|
535
550
|
if (b.meta.group === BlockletGroup.gateway) {
|
|
536
551
|
return;
|
|
@@ -572,10 +587,10 @@ const startBlockletProcess = async (
|
|
|
572
587
|
await installExternalDependencies({ appDir: env?.BLOCKLET_APP_DIR });
|
|
573
588
|
|
|
574
589
|
// run hook
|
|
575
|
-
await preFlight(b, { env });
|
|
590
|
+
await preFlight(b, { env: { ...env } });
|
|
576
591
|
|
|
577
592
|
// run hook
|
|
578
|
-
await preStart(b, { env });
|
|
593
|
+
await preStart(b, { env: { ...env } });
|
|
579
594
|
|
|
580
595
|
// kill process if port is occupied
|
|
581
596
|
try {
|
|
@@ -588,6 +603,9 @@ const startBlockletProcess = async (
|
|
|
588
603
|
// start process
|
|
589
604
|
const maxMemoryRestart = get(nodeInfo, 'runtimeConfig.blockletMaxMemoryLimit', BLOCKLET_MAX_MEM_LIMIT_IN_MB);
|
|
590
605
|
|
|
606
|
+
/**
|
|
607
|
+
* @type {pm2.StartOptions}
|
|
608
|
+
*/
|
|
591
609
|
const options = {
|
|
592
610
|
namespace: 'blocklets',
|
|
593
611
|
name: processId,
|
|
@@ -606,6 +624,7 @@ const startBlockletProcess = async (
|
|
|
606
624
|
...env,
|
|
607
625
|
NODE_ENV: 'production',
|
|
608
626
|
BLOCKLET_START_AT: now,
|
|
627
|
+
NODE_OPTIONS: getSecurityNodeOptions(b, nodeInfo.enableFileSystemIsolation),
|
|
609
628
|
},
|
|
610
629
|
script,
|
|
611
630
|
args,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { joinURL } = require('ufo');
|
|
2
2
|
const axios = require('@abtnode/util/lib/axios');
|
|
3
3
|
const { DEFAULT_IP_DOMAIN, WELLKNOWN_SERVER_ADMIN_PATH } = require('@abtnode/constant');
|
|
4
4
|
const logger = require('@abtnode/logger')('@abtnode/core:util:get-accessible-external-node-ip');
|
|
@@ -15,7 +15,7 @@ const timeout = process.env.NODE_ENV === 'test' ? 500 : 5000;
|
|
|
15
15
|
const checkConnected = async ({ ip, info }) => {
|
|
16
16
|
const { adminPath = WELLKNOWN_SERVER_ADMIN_PATH } = info.routing || {};
|
|
17
17
|
const origin = `https://${getNodeDomain(ip)}`;
|
|
18
|
-
const endpoint =
|
|
18
|
+
const endpoint = joinURL(origin, adminPath);
|
|
19
19
|
await axios.get(endpoint, { timeout });
|
|
20
20
|
};
|
|
21
21
|
|
package/lib/util/index.js
CHANGED
|
@@ -8,7 +8,7 @@ const camelCase = require('lodash/camelCase');
|
|
|
8
8
|
const get = require('lodash/get');
|
|
9
9
|
const pickBy = require('lodash/pickBy');
|
|
10
10
|
const { isFromPublicKey } = require('@arcblock/did');
|
|
11
|
-
const
|
|
11
|
+
const { joinURL } = require('ufo');
|
|
12
12
|
const { Certificate } = require('@fidm/x509');
|
|
13
13
|
const getPortLib = require('get-port');
|
|
14
14
|
const v8 = require('v8');
|
|
@@ -362,7 +362,7 @@ const getStateCrons = (states) => [
|
|
|
362
362
|
|
|
363
363
|
const getDelegateState = async (chainHost, address) => {
|
|
364
364
|
const result = await axios.post(
|
|
365
|
-
|
|
365
|
+
joinURL(chainHost, '/gql/'),
|
|
366
366
|
JSON.stringify({
|
|
367
367
|
query: `{
|
|
368
368
|
getDelegateState(address: "${address}") {
|
|
@@ -388,7 +388,7 @@ const getDelegateState = async (chainHost, address) => {
|
|
|
388
388
|
};
|
|
389
389
|
|
|
390
390
|
const getNFTState = async (chainHost, nftId) => {
|
|
391
|
-
const url =
|
|
391
|
+
const url = joinURL(new URL(chainHost).origin, '/api/gql/');
|
|
392
392
|
|
|
393
393
|
const result = await axios.post(
|
|
394
394
|
url,
|
package/lib/util/launcher.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs-extra');
|
|
3
|
-
const
|
|
3
|
+
const { joinURL } = require('ufo');
|
|
4
4
|
const dayjs = require('@abtnode/util/lib/dayjs');
|
|
5
5
|
const pick = require('lodash/pick');
|
|
6
6
|
const uniq = require('lodash/uniq');
|
|
@@ -206,7 +206,7 @@ const setupAppOwner = async (node, sessionId) => {
|
|
|
206
206
|
throw new Error(`Owner user not found from launcher: ${launcherUrl}`);
|
|
207
207
|
}
|
|
208
208
|
appOwnerProfile = pick(user, ['fullName', 'email', 'avatar']);
|
|
209
|
-
const avatarBase64 = await getAvatarByUrl(
|
|
209
|
+
const avatarBase64 = await getAvatarByUrl(joinURL(launcherUrl, user.avatar));
|
|
210
210
|
appOwnerProfile.avatar = await extractUserAvatar(avatarBase64, { dataDir });
|
|
211
211
|
logger.info('Create owner from launcher for blocklet', { appDid, ownerDid, ownerPk, sessionId, appOwnerProfile });
|
|
212
212
|
} else {
|
|
@@ -242,7 +242,7 @@ const setupAppOwner = async (node, sessionId) => {
|
|
|
242
242
|
endpoint: appUrl,
|
|
243
243
|
}),
|
|
244
244
|
endpoint: getPassportStatusEndpoint({
|
|
245
|
-
baseUrl:
|
|
245
|
+
baseUrl: joinURL(appUrl, WELLKNOWN_SERVICE_PATH_PREFIX),
|
|
246
246
|
userDid: ownerDid,
|
|
247
247
|
teamDid: appDid,
|
|
248
248
|
}),
|
package/lib/util/spaces.js
CHANGED
|
@@ -3,7 +3,7 @@ const { default: axios } = require('axios');
|
|
|
3
3
|
const isUrl = require('is-url');
|
|
4
4
|
const isArray = require('lodash/isArray');
|
|
5
5
|
const isEmpty = require('lodash/isEmpty');
|
|
6
|
-
const
|
|
6
|
+
const { joinURL, withQuery } = require('ufo');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @description
|
|
@@ -35,7 +35,9 @@ function getBackupFilesUrlFromEndpoint(endpoint) {
|
|
|
35
35
|
const spaceDid = strArray.at(-4);
|
|
36
36
|
const appDid = strArray.at(-2);
|
|
37
37
|
|
|
38
|
-
return
|
|
38
|
+
return withQuery(joinURL(prefix, 'space', spaceDid, 'apps', appDid, 'explorer'), {
|
|
39
|
+
key: `/apps/${appDid}/.did-objects/${appDid}/`,
|
|
40
|
+
});
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
function getDIDSpacesUrlFromEndpoint(endpoint) {
|
package/lib/util/store.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { joinURL, withQuery } = require('ufo');
|
|
2
2
|
const pick = require('lodash/pick');
|
|
3
3
|
const isBase64 = require('is-base64');
|
|
4
4
|
|
|
@@ -48,7 +48,9 @@ const fixAndVerifyMetaFromStore = (meta) => {
|
|
|
48
48
|
|
|
49
49
|
const getStoreMeta = async (registry) => {
|
|
50
50
|
try {
|
|
51
|
-
const url =
|
|
51
|
+
const url = withQuery(joinURL(registry, BLOCKLET_STORE_META_PATH), {
|
|
52
|
+
__t__: Date.now(),
|
|
53
|
+
});
|
|
52
54
|
const { data } = await request.get(url);
|
|
53
55
|
|
|
54
56
|
if (!data) {
|
|
@@ -69,7 +71,7 @@ const getStoreMeta = async (registry) => {
|
|
|
69
71
|
} else if (isBase64(logoUrl, { allowMime: true })) {
|
|
70
72
|
result.logoUrl = logoUrl;
|
|
71
73
|
} else {
|
|
72
|
-
result.logoUrl =
|
|
74
|
+
result.logoUrl = joinURL(registry, logoUrl);
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
77
|
|
|
@@ -124,14 +126,14 @@ const resolveTarballURL = ({ did, tarball = '', storeUrl = '' }) => {
|
|
|
124
126
|
return '';
|
|
125
127
|
}
|
|
126
128
|
|
|
127
|
-
return
|
|
129
|
+
return joinURL(storeUrl, 'api', 'blocklets', did, tarball);
|
|
128
130
|
};
|
|
129
131
|
|
|
130
132
|
const getBlockletMetaUrl = ({ did, storeUrl }) =>
|
|
131
|
-
|
|
133
|
+
joinURL(storeUrl, BLOCKLET_STORE_API_PREFIX, `/blocklets/${did}/blocklet.json`);
|
|
132
134
|
|
|
133
135
|
const getBlockletMeta = async ({ did, storeUrl }) => {
|
|
134
|
-
const url =
|
|
136
|
+
const url = joinURL(storeUrl, BLOCKLET_STORE_API_PREFIX, `/blocklets/${did}/blocklet.json?__t__=${Date.now()}`);
|
|
135
137
|
|
|
136
138
|
const { data } = await request.get(url);
|
|
137
139
|
try {
|
package/lib/validators/node.js
CHANGED
|
@@ -5,6 +5,7 @@ const note = Joi.string().min(1).max(PROJECT.MAX_NOTE_LENGTH);
|
|
|
5
5
|
const blockletIntroduction = Joi.string().max(PROJECT.MAX_INTRO_LENGTH).allow('').allow(null);
|
|
6
6
|
const blockletScreenshots = Joi.array().items(Joi.string().min(1).max(200));
|
|
7
7
|
const blockletLogo = Joi.string().max(200).allow(null).allow('');
|
|
8
|
+
const uploadedResource = Joi.string().max(255).allow(null).allow('');
|
|
8
9
|
|
|
9
10
|
const createReleaseSchema = (status) =>
|
|
10
11
|
Joi.object({
|
|
@@ -24,6 +25,7 @@ const createReleaseSchema = (status) =>
|
|
|
24
25
|
required: Joi.boolean().allow(null),
|
|
25
26
|
})
|
|
26
27
|
),
|
|
28
|
+
uploadedResource,
|
|
27
29
|
});
|
|
28
30
|
|
|
29
31
|
module.exports = {
|
|
@@ -31,5 +33,6 @@ module.exports = {
|
|
|
31
33
|
blockletIntroduction,
|
|
32
34
|
blockletScreenshots,
|
|
33
35
|
blockletLogo,
|
|
36
|
+
uploadedResource,
|
|
34
37
|
createReleaseSchema,
|
|
35
38
|
};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.28
|
|
6
|
+
"version": "1.16.28",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,19 +19,19 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/analytics": "1.16.28
|
|
23
|
-
"@abtnode/auth": "1.16.28
|
|
24
|
-
"@abtnode/certificate-manager": "1.16.28
|
|
25
|
-
"@abtnode/constant": "1.16.28
|
|
26
|
-
"@abtnode/cron": "1.16.28
|
|
27
|
-
"@abtnode/logger": "1.16.28
|
|
28
|
-
"@abtnode/models": "1.16.28
|
|
29
|
-
"@abtnode/queue": "1.16.28
|
|
30
|
-
"@abtnode/rbac": "1.16.28
|
|
31
|
-
"@abtnode/router-provider": "1.16.28
|
|
32
|
-
"@abtnode/static-server": "1.16.28
|
|
33
|
-
"@abtnode/timemachine": "1.16.28
|
|
34
|
-
"@abtnode/util": "1.16.28
|
|
22
|
+
"@abtnode/analytics": "1.16.28",
|
|
23
|
+
"@abtnode/auth": "1.16.28",
|
|
24
|
+
"@abtnode/certificate-manager": "1.16.28",
|
|
25
|
+
"@abtnode/constant": "1.16.28",
|
|
26
|
+
"@abtnode/cron": "1.16.28",
|
|
27
|
+
"@abtnode/logger": "1.16.28",
|
|
28
|
+
"@abtnode/models": "1.16.28",
|
|
29
|
+
"@abtnode/queue": "1.16.28",
|
|
30
|
+
"@abtnode/rbac": "1.16.28",
|
|
31
|
+
"@abtnode/router-provider": "1.16.28",
|
|
32
|
+
"@abtnode/static-server": "1.16.28",
|
|
33
|
+
"@abtnode/timemachine": "1.16.28",
|
|
34
|
+
"@abtnode/util": "1.16.28",
|
|
35
35
|
"@arcblock/did": "1.18.123",
|
|
36
36
|
"@arcblock/did-auth": "1.18.123",
|
|
37
37
|
"@arcblock/did-ext": "^1.18.123",
|
|
@@ -42,20 +42,20 @@
|
|
|
42
42
|
"@arcblock/pm2-events": "^0.0.5",
|
|
43
43
|
"@arcblock/validator": "^1.18.123",
|
|
44
44
|
"@arcblock/vc": "1.18.123",
|
|
45
|
-
"@blocklet/constant": "1.16.28
|
|
46
|
-
"@blocklet/env": "1.16.28
|
|
47
|
-
"@blocklet/meta": "1.16.28
|
|
48
|
-
"@blocklet/resolver": "1.16.28
|
|
49
|
-
"@blocklet/sdk": "1.16.28
|
|
50
|
-
"@blocklet/store": "1.16.28
|
|
51
|
-
"@did-space/client": "^0.
|
|
45
|
+
"@blocklet/constant": "1.16.28",
|
|
46
|
+
"@blocklet/env": "1.16.28",
|
|
47
|
+
"@blocklet/meta": "1.16.28",
|
|
48
|
+
"@blocklet/resolver": "1.16.28",
|
|
49
|
+
"@blocklet/sdk": "1.16.28",
|
|
50
|
+
"@blocklet/store": "1.16.28",
|
|
51
|
+
"@did-space/client": "^0.5.1",
|
|
52
52
|
"@fidm/x509": "^1.2.1",
|
|
53
53
|
"@ocap/mcrypto": "1.18.123",
|
|
54
54
|
"@ocap/util": "1.18.123",
|
|
55
55
|
"@ocap/wallet": "1.18.123",
|
|
56
56
|
"@slack/webhook": "^5.0.4",
|
|
57
57
|
"archiver": "^7.0.1",
|
|
58
|
-
"axios": "^
|
|
58
|
+
"axios": "^1.7.2",
|
|
59
59
|
"axon": "^2.0.3",
|
|
60
60
|
"chalk": "^4.1.2",
|
|
61
61
|
"cross-spawn": "^7.0.3",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"tar": "^6.1.11",
|
|
93
93
|
"transliteration": "^2.3.5",
|
|
94
94
|
"ua-parser-js": "^1.0.2",
|
|
95
|
-
"
|
|
95
|
+
"ufo": "^1.5.3",
|
|
96
96
|
"uuid": "^9.0.1",
|
|
97
97
|
"valid-url": "^1.0.9",
|
|
98
98
|
"xbytes": "^1.8.0"
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"jest": "^29.7.0",
|
|
104
104
|
"unzipper": "^0.10.11"
|
|
105
105
|
},
|
|
106
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "54db076a7e520bbc260f8cbf0af31dd50b86aef1"
|
|
107
107
|
}
|