@blocklet/meta 1.8.55 → 1.8.57
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/index.d.ts +5 -3
- package/lib/parse-navigation-from-blocklet.d.ts +52 -14
- package/lib/parse-navigation-from-blocklet.js +13 -13
- package/lib/parse.d.ts +4 -4
- package/lib/parse.js +35 -10
- package/lib/schema.d.ts +4 -2
- package/lib/schema.js +35 -12
- package/lib/types/schema.d.ts +26 -2
- package/lib/validate.d.ts +2 -1
- package/lib/validate.js +5 -2
- package/package.json +6 -6
package/lib/index.d.ts
CHANGED
|
@@ -35,21 +35,23 @@ declare const _default: {
|
|
|
35
35
|
update: (file: string, meta: import("./types").TBlockletMeta, { fix }?: {
|
|
36
36
|
fix?: boolean;
|
|
37
37
|
}) => void;
|
|
38
|
-
parse: (dir: string, { ensureMain, ensureFiles, ensureDist,
|
|
38
|
+
parse: (dir: string, { ensureMain, ensureFiles, ensureDist, ensureComponentStore, extraRawAttrs, schemaOptions, defaultStoreUrl, fix, }?: {
|
|
39
39
|
ensureMain?: boolean;
|
|
40
40
|
ensureFiles?: boolean;
|
|
41
41
|
ensureDist?: boolean;
|
|
42
|
+
ensureComponentStore?: boolean;
|
|
42
43
|
extraRawAttrs?: any;
|
|
43
|
-
serviceMetas?: any;
|
|
44
44
|
schemaOptions?: any;
|
|
45
45
|
enableDefaults?: boolean;
|
|
46
46
|
extraAttrSpec?: any;
|
|
47
|
+
defaultStoreUrl?: string | ((component: import("./types").TComponent) => string);
|
|
47
48
|
fix?: boolean;
|
|
48
49
|
}) => import("./types").TBlockletMeta;
|
|
49
|
-
validateMeta: (meta: any, { ensureMain, ensureFiles, ensureDist, schemaOptions, }?: {
|
|
50
|
+
validateMeta: (meta: any, { ensureMain, ensureFiles, ensureDist, ensureComponentStore, schemaOptions, }?: {
|
|
50
51
|
ensureMain?: boolean;
|
|
51
52
|
ensureFiles?: boolean;
|
|
52
53
|
ensureDist?: boolean;
|
|
54
|
+
ensureComponentStore?: boolean;
|
|
53
55
|
schemaOptions?: any;
|
|
54
56
|
}) => import("./types").TBlockletMeta;
|
|
55
57
|
fixAndValidateService: (meta: import("./types").TBlockletMeta) => import("./types").TBlockletMeta;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
declare const checkLink: (value:
|
|
1
|
+
declare const checkLink: (value: string) => boolean;
|
|
2
|
+
interface DeepWalkCallback {
|
|
3
|
+
(current: any, parent: any, options: DeepWalkCallbackOptions): void;
|
|
4
|
+
}
|
|
5
|
+
interface DeepWalkCallbackOptions {
|
|
6
|
+
index: number;
|
|
7
|
+
level: number;
|
|
8
|
+
}
|
|
2
9
|
/**
|
|
3
10
|
*
|
|
4
11
|
* @param {object} tree 需要深度遍历的数状结构
|
|
@@ -9,17 +16,43 @@ declare const checkLink: (value: any) => boolean;
|
|
|
9
16
|
* @param {object} param.parent 当前节点的父节点
|
|
10
17
|
* @param {number} param.level 当前节点的深度
|
|
11
18
|
*/
|
|
12
|
-
|
|
13
|
-
key?:
|
|
14
|
-
|
|
19
|
+
type TreeNode<K extends string> = Record<string, any> & {
|
|
20
|
+
[key in K]?: TreeNode<K>[];
|
|
21
|
+
};
|
|
22
|
+
declare function deepWalk<K extends string>(tree: TreeNode<K>, cb: DeepWalkCallback, { key, order }: {
|
|
23
|
+
key: K;
|
|
24
|
+
order?: 'first' | 'last';
|
|
25
|
+
}): void;
|
|
26
|
+
declare function deepWalk(tree: TreeNode<'children'>, cb: DeepWalkCallback, { key, order }?: {
|
|
27
|
+
key?: 'children';
|
|
28
|
+
order?: 'first' | 'last';
|
|
15
29
|
}): void;
|
|
16
30
|
/**
|
|
17
31
|
* 判断一个传入值是否属于一个 section
|
|
18
32
|
* @param {string | array} sections 需要判断的对象
|
|
19
33
|
* @param {string} section 目标 section
|
|
20
34
|
*/
|
|
21
|
-
declare function isMatchSection(sections:
|
|
22
|
-
|
|
35
|
+
declare function isMatchSection(sections: string[] | string, section: string): boolean;
|
|
36
|
+
interface NavigationItem {
|
|
37
|
+
id: string;
|
|
38
|
+
role?: string;
|
|
39
|
+
section?: string;
|
|
40
|
+
title?: string;
|
|
41
|
+
link?: string;
|
|
42
|
+
items?: NavigationItem[];
|
|
43
|
+
component?: string;
|
|
44
|
+
child?: string;
|
|
45
|
+
[key: string]: any;
|
|
46
|
+
}
|
|
47
|
+
interface ComponentItem {
|
|
48
|
+
name: string;
|
|
49
|
+
link: string;
|
|
50
|
+
}
|
|
51
|
+
declare function joinLink(navigation: NavigationItem, components: ComponentItem[]): NavigationItem;
|
|
52
|
+
interface FlatternNavigationOption {
|
|
53
|
+
transform?: (current: any, parent?: any) => any;
|
|
54
|
+
depth?: number;
|
|
55
|
+
}
|
|
23
56
|
/**
|
|
24
57
|
* 将树状结构的导航列表进行扁平化处理
|
|
25
58
|
* @param {array} navigationList 树状结构的导航列表
|
|
@@ -28,25 +61,30 @@ declare function joinLink(navigation: any, components: any): any;
|
|
|
28
61
|
* @param {function} params.transform 当发生拍平处理时
|
|
29
62
|
* @returns 扁平化后的导航列表
|
|
30
63
|
*/
|
|
31
|
-
declare function flatternNavigation(list?:
|
|
32
|
-
depth?: number;
|
|
33
|
-
transform?: (v: any) => any;
|
|
34
|
-
}): any[];
|
|
64
|
+
declare function flatternNavigation(list?: NavigationItem[], { depth, transform }?: FlatternNavigationOption): any[];
|
|
35
65
|
/**
|
|
36
66
|
* 根据导航中每一个子菜单所属的 section,将原由的导航数据分离为多个导航数据(此时每一个导航 item 只会包含一个 section)
|
|
37
67
|
* @param {array} navigation 导航列表数据(树状结构,目前只适用于两层的树状结构)
|
|
38
68
|
* @returns
|
|
39
69
|
*/
|
|
40
|
-
declare function splitNavigationBySection(navigation:
|
|
70
|
+
declare function splitNavigationBySection(navigation: NavigationItem[]): any[];
|
|
41
71
|
/**
|
|
42
72
|
* 将导航数据进行层叠处理
|
|
43
73
|
* @param {array} list 扁平化的导航数据
|
|
44
74
|
* @returns 处理后的导航
|
|
45
75
|
*/
|
|
46
76
|
declare function nestNavigationList(list?: any[]): any[];
|
|
47
|
-
declare function filterNavigation(navigationList:
|
|
48
|
-
declare function cleanOrphanNavigation(list:
|
|
49
|
-
|
|
77
|
+
declare function filterNavigation(navigationList: NavigationItem[], components?: ComponentItem[]): any[];
|
|
78
|
+
declare function cleanOrphanNavigation(list: NavigationItem[]): NavigationItem[];
|
|
79
|
+
interface Blocklet {
|
|
80
|
+
settings?: {
|
|
81
|
+
navigations?: NavigationItem[];
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
interface ParseNavigationOption {
|
|
85
|
+
beforeProcess?: (data: any) => any;
|
|
86
|
+
}
|
|
87
|
+
declare function parseNavigation(blocklet?: Blocklet, options?: ParseNavigationOption): {
|
|
50
88
|
navigationList: any[];
|
|
51
89
|
components: any[];
|
|
52
90
|
builtinList: any[];
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// @ts-nocheck
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -36,16 +35,6 @@ const checkLink = (value) => {
|
|
|
36
35
|
return false;
|
|
37
36
|
};
|
|
38
37
|
exports.checkLink = checkLink;
|
|
39
|
-
/**
|
|
40
|
-
*
|
|
41
|
-
* @param {object} tree 需要深度遍历的数状结构
|
|
42
|
-
* @param {function} cb 每一个节点的回调函数,回调的参数:当前节点数据,父亲节点数据,{index:当前节点所属的数组中的序号,level: 当前节点所处的深度}
|
|
43
|
-
* @param {object} param 深度遍历的参数
|
|
44
|
-
* @param {string} param.key 孩子数组的 key 值
|
|
45
|
-
* @param {number} param.index 当前节点所属的数组中的序号
|
|
46
|
-
* @param {object} param.parent 当前节点的父节点
|
|
47
|
-
* @param {number} param.level 当前节点的深度
|
|
48
|
-
*/
|
|
49
38
|
function deepWalk(tree, cb = () => { }, { key = 'children', order = 'first' } = {}) {
|
|
50
39
|
function walk(current, { index = 0, parent = null, level = 0 } = {}) {
|
|
51
40
|
if (Array.isArray(current)) {
|
|
@@ -118,7 +107,7 @@ function optionalJoin(prefix = '/', url = '') {
|
|
|
118
107
|
}
|
|
119
108
|
return resultUrl;
|
|
120
109
|
}
|
|
121
|
-
function smartJoinLink(_parentLink, _childLink, { strict = true } = {}) {
|
|
110
|
+
function smartJoinLink(_parentLink, _childLink, { strict = true, } = {}) {
|
|
122
111
|
let parentLink = _parentLink;
|
|
123
112
|
let childLink = _childLink;
|
|
124
113
|
if (!strict) {
|
|
@@ -477,7 +466,18 @@ function filterNavigation(navigationList, components = []) {
|
|
|
477
466
|
}
|
|
478
467
|
}
|
|
479
468
|
}, { key: 'items' });
|
|
480
|
-
const filteredNavigation = nestedNavigation.filter((item) =>
|
|
469
|
+
const filteredNavigation = nestedNavigation.filter((item) => {
|
|
470
|
+
var _a;
|
|
471
|
+
if (item.visible === false)
|
|
472
|
+
return false;
|
|
473
|
+
// 如果某一菜单的 子菜单 均为隐藏状态,则一级菜单本身也不显示出来
|
|
474
|
+
if (item.items &&
|
|
475
|
+
Array.isArray(item.items) &&
|
|
476
|
+
item.items.length > 0 &&
|
|
477
|
+
((_a = item.items) === null || _a === void 0 ? void 0 : _a.every((v) => v.visible === false)))
|
|
478
|
+
return false;
|
|
479
|
+
return true;
|
|
480
|
+
});
|
|
481
481
|
return filteredNavigation;
|
|
482
482
|
}
|
|
483
483
|
exports.filterNavigation = filterNavigation;
|
package/lib/parse.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TBlockletMeta } from './types';
|
|
1
|
+
import { TBlockletMeta, TComponent } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* Get blocklet meta from blocklet.yml
|
|
4
4
|
* @param {string} dir blocklet directory
|
|
@@ -6,17 +6,17 @@ import { TBlockletMeta } from './types';
|
|
|
6
6
|
* @param {boolean} options.ensureMain should we verify that main exists
|
|
7
7
|
* @param {boolean} options.ensureDist should we verify that dist exists
|
|
8
8
|
* @param {boolean} options.ensureFiles should we verify that logo and files exists
|
|
9
|
-
* @param {Array} options.serviceMetas should we verify that each service is validate (using JSON Schema defined serviceMetas)
|
|
10
9
|
*/
|
|
11
|
-
declare const parse: (dir: string, { ensureMain, ensureFiles, ensureDist,
|
|
10
|
+
declare const parse: (dir: string, { ensureMain, ensureFiles, ensureDist, ensureComponentStore, extraRawAttrs, schemaOptions, defaultStoreUrl, fix, }?: {
|
|
12
11
|
ensureMain?: boolean;
|
|
13
12
|
ensureFiles?: boolean;
|
|
14
13
|
ensureDist?: boolean;
|
|
14
|
+
ensureComponentStore?: boolean;
|
|
15
15
|
extraRawAttrs?: any;
|
|
16
|
-
serviceMetas?: any;
|
|
17
16
|
schemaOptions?: any;
|
|
18
17
|
enableDefaults?: boolean;
|
|
19
18
|
extraAttrSpec?: any;
|
|
19
|
+
defaultStoreUrl?: string | ((component: TComponent) => string);
|
|
20
20
|
fix?: boolean;
|
|
21
21
|
}) => TBlockletMeta;
|
|
22
22
|
export = parse;
|
package/lib/parse.js
CHANGED
|
@@ -6,6 +6,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
6
6
|
const path_1 = __importDefault(require("path"));
|
|
7
7
|
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
8
8
|
const camelCase_1 = __importDefault(require("lodash/camelCase"));
|
|
9
|
+
const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
|
|
9
10
|
const debug_1 = __importDefault(require("debug"));
|
|
10
11
|
const constants_1 = __importDefault(require("./constants"));
|
|
11
12
|
const schema_1 = require("./schema");
|
|
@@ -19,15 +20,15 @@ const { BLOCKLET_META_FILE, BLOCKLET_META_FILE_ALT } = constants_1.default;
|
|
|
19
20
|
* @param {boolean} options.ensureMain should we verify that main exists
|
|
20
21
|
* @param {boolean} options.ensureDist should we verify that dist exists
|
|
21
22
|
* @param {boolean} options.ensureFiles should we verify that logo and files exists
|
|
22
|
-
* @param {Array} options.serviceMetas should we verify that each service is validate (using JSON Schema defined serviceMetas)
|
|
23
23
|
*/
|
|
24
|
-
const parse = (dir, { ensureMain = false, ensureFiles = false, ensureDist = false, extraRawAttrs = {},
|
|
25
|
-
|
|
24
|
+
const parse = (dir, { ensureMain = false, ensureFiles = false, ensureDist = false, ensureComponentStore = true, extraRawAttrs = {}, schemaOptions = {}, defaultStoreUrl, fix = true, } = {}) => {
|
|
25
|
+
var _a;
|
|
26
|
+
let result;
|
|
26
27
|
const blockletMetaFile = path_1.default.join(dir, BLOCKLET_META_FILE);
|
|
27
28
|
const blockletMetaFileAlt = path_1.default.join(dir, BLOCKLET_META_FILE_ALT);
|
|
28
29
|
if (fs_1.default.existsSync(blockletMetaFile)) {
|
|
29
30
|
try {
|
|
30
|
-
result =
|
|
31
|
+
result = js_yaml_1.default.load(fs_1.default.readFileSync(blockletMetaFile).toString(), { json: true });
|
|
31
32
|
debug(`parse ${blockletMetaFile}`, result);
|
|
32
33
|
}
|
|
33
34
|
catch (err) {
|
|
@@ -36,7 +37,7 @@ const parse = (dir, { ensureMain = false, ensureFiles = false, ensureDist = fals
|
|
|
36
37
|
}
|
|
37
38
|
else if (fs_1.default.existsSync(blockletMetaFileAlt)) {
|
|
38
39
|
try {
|
|
39
|
-
result = Object.assign(
|
|
40
|
+
result = Object.assign({}, js_yaml_1.default.load(fs_1.default.readFileSync(blockletMetaFileAlt).toString(), { json: true }));
|
|
40
41
|
debug(`parse ${blockletMetaFileAlt}`, result);
|
|
41
42
|
}
|
|
42
43
|
catch (err) {
|
|
@@ -61,9 +62,16 @@ const parse = (dir, { ensureMain = false, ensureFiles = false, ensureDist = fals
|
|
|
61
62
|
(0, fix_1.fixKeywords)(result);
|
|
62
63
|
(0, fix_1.fixTags)(result);
|
|
63
64
|
(0, fix_1.fixPerson)(result);
|
|
64
|
-
|
|
65
|
-
(0
|
|
66
|
-
|
|
65
|
+
(0, fix_1.fixService)(result);
|
|
66
|
+
if (defaultStoreUrl && ((_a = result.components) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
67
|
+
result.components.forEach((x) => {
|
|
68
|
+
if ('name' in x.source) {
|
|
69
|
+
if (!x.source.store) {
|
|
70
|
+
x.source.store = typeof defaultStoreUrl === 'function' ? defaultStoreUrl((0, cloneDeep_1.default)(x)) : defaultStoreUrl;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
67
75
|
// We will overwrite did anyway
|
|
68
76
|
result.path = `/${result.group}/${result.name}`;
|
|
69
77
|
// Ensure camelCase
|
|
@@ -71,11 +79,28 @@ const parse = (dir, { ensureMain = false, ensureFiles = false, ensureDist = fals
|
|
|
71
79
|
acc[(0, camelCase_1.default)(k)] = result[k];
|
|
72
80
|
return acc;
|
|
73
81
|
}, {});
|
|
82
|
+
debug('fix', result);
|
|
74
83
|
// Validate and cleanup
|
|
75
|
-
const schema = (0, schema_1.createBlockletSchema)(dir, Object.assign({ ensureMain,
|
|
84
|
+
const schema = (0, schema_1.createBlockletSchema)(dir, Object.assign({ ensureMain,
|
|
85
|
+
ensureFiles,
|
|
86
|
+
ensureDist,
|
|
87
|
+
ensureComponentStore }, schemaOptions));
|
|
76
88
|
const { value, error } = schema.validate(result);
|
|
77
89
|
if (error) {
|
|
78
|
-
throw new Error(`Invalid blocklet.yml: ${error.details
|
|
90
|
+
throw new Error(`Invalid blocklet.yml: ${error.details
|
|
91
|
+
.map((x) => {
|
|
92
|
+
try {
|
|
93
|
+
// 根据 navigation 校验规则定制特殊的错误消息显示
|
|
94
|
+
if (x.type === 'array.unique' && x.path[0] === 'navigation') {
|
|
95
|
+
return `${x.message}: ${x.context.value.id}`;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch (_a) {
|
|
99
|
+
//
|
|
100
|
+
}
|
|
101
|
+
return x.message;
|
|
102
|
+
})
|
|
103
|
+
.join(', ')}`);
|
|
79
104
|
}
|
|
80
105
|
return value;
|
|
81
106
|
};
|
package/lib/schema.d.ts
CHANGED
|
@@ -21,10 +21,11 @@ declare const navigationSchema: JOI.ArraySchema<any[]>;
|
|
|
21
21
|
declare const themeSchema: JOI.ObjectSchema<any>;
|
|
22
22
|
declare const authConfigSchema: JOI.ObjectSchema<any>;
|
|
23
23
|
declare const blockletMetaSchema: JOI.ObjectSchema<any>;
|
|
24
|
-
declare const createBlockletSchema: (baseDir: string, { ensureMain, ensureFiles, ensureDist, ...schemaOptions }?: {
|
|
24
|
+
declare const createBlockletSchema: (baseDir: string, { ensureMain, ensureFiles, ensureDist, ensureComponentStore, ...schemaOptions }?: {
|
|
25
25
|
ensureMain?: boolean;
|
|
26
26
|
ensureFiles?: boolean;
|
|
27
27
|
ensureDist?: boolean;
|
|
28
|
+
ensureComponentStore?: boolean;
|
|
28
29
|
}) => JOI.ObjectSchema;
|
|
29
30
|
export { blockletMetaSchema, blockletNameSchema, componentSchema, createBlockletSchema, descriptionSchema, distSchema, endpointSchema, engineSchema, environmentSchema, environmentNameSchema, interfaceSchema, logoSchema, mountPointSchema, navigationItemSchema, navigationSchema, personSchema, scriptsSchema, serviceSchema, signatureSchema, themeSchema, titleSchema, statsSchema, authConfigSchema, };
|
|
30
31
|
declare const _default: {
|
|
@@ -32,10 +33,11 @@ declare const _default: {
|
|
|
32
33
|
componentSchema: JOI.ObjectSchema<any>;
|
|
33
34
|
endpointSchema: JOI.ObjectSchema<any>;
|
|
34
35
|
serviceSchema: JOI.ObjectSchema<any>;
|
|
35
|
-
createBlockletSchema: (baseDir: string, { ensureMain, ensureFiles, ensureDist, ...schemaOptions }?: {
|
|
36
|
+
createBlockletSchema: (baseDir: string, { ensureMain, ensureFiles, ensureDist, ensureComponentStore, ...schemaOptions }?: {
|
|
36
37
|
ensureMain?: boolean;
|
|
37
38
|
ensureFiles?: boolean;
|
|
38
39
|
ensureDist?: boolean;
|
|
40
|
+
ensureComponentStore?: boolean;
|
|
39
41
|
}) => JOI.ObjectSchema<any>;
|
|
40
42
|
interfaceSchema: JOI.ObjectSchema<any>;
|
|
41
43
|
environmentSchema: JOI.ObjectSchema<any>;
|
package/lib/schema.js
CHANGED
|
@@ -42,14 +42,26 @@ const checkLinkHelper = (value, helper) => {
|
|
|
42
42
|
return value;
|
|
43
43
|
}
|
|
44
44
|
// @ts-expect-error
|
|
45
|
-
return helper.message(
|
|
45
|
+
return helper.message(`Invalid navigation link: ${value}
|
|
46
|
+
|
|
47
|
+
A valid navigation link should be a relative url which start with '/' or a absolute url, such as:
|
|
48
|
+
- /en/home
|
|
49
|
+
- /zh/home
|
|
50
|
+
- https://www.arcblock.io`);
|
|
46
51
|
};
|
|
47
52
|
const checkId = (value, helper) => {
|
|
48
53
|
if (!value || (0, is_var_name_1.default)(value)) {
|
|
49
54
|
return value;
|
|
50
55
|
}
|
|
51
56
|
// @ts-expect-error
|
|
52
|
-
return helper.message(
|
|
57
|
+
return helper.message(`Invalid navigation id: ${value}
|
|
58
|
+
|
|
59
|
+
A valid navigation id is should follow the rules of javascript variables, such as:
|
|
60
|
+
- foo
|
|
61
|
+
- fooBar
|
|
62
|
+
- foo123
|
|
63
|
+
|
|
64
|
+
see detail in https://www.npmjs.com/package/is-var-name`);
|
|
53
65
|
};
|
|
54
66
|
const titleSchema = Joi.string()
|
|
55
67
|
.trim()
|
|
@@ -259,16 +271,17 @@ const statsSchema = Joi.object({
|
|
|
259
271
|
unknownType: 'any',
|
|
260
272
|
});
|
|
261
273
|
exports.statsSchema = statsSchema;
|
|
262
|
-
const
|
|
274
|
+
const urlListSchema = Joi.alternatives().try(Joi.string().uri(), Joi.array().items(Joi.string().uri()).min(1));
|
|
275
|
+
const componentSchemaProps = {
|
|
263
276
|
name: blockletNameSchema.required(),
|
|
264
277
|
title: titleSchema,
|
|
265
278
|
description: descriptionSchema,
|
|
266
279
|
mountPoint: mountPointSchema,
|
|
267
280
|
services: Joi.array().items(serviceSchema).unique('name'),
|
|
268
281
|
source: Joi.alternatives().try(Joi.object({
|
|
269
|
-
url:
|
|
282
|
+
url: urlListSchema.required(),
|
|
270
283
|
}), Joi.object({
|
|
271
|
-
store:
|
|
284
|
+
store: urlListSchema,
|
|
272
285
|
name: blockletNameSchema.required(),
|
|
273
286
|
// TODO 目前只能支持锁死的版本号,接下载需要支持自适应的版本号,比如 4.x
|
|
274
287
|
version: Joi.alternatives().try(Joi.string().valid('latest'), Joi.semver().valid()).default('latest'),
|
|
@@ -286,8 +299,8 @@ const componentSchema = Joi.object({
|
|
|
286
299
|
services: Joi.array().items(serviceSchema).unique('name'),
|
|
287
300
|
}))
|
|
288
301
|
.optional(),
|
|
289
|
-
}
|
|
290
|
-
|
|
302
|
+
};
|
|
303
|
+
const createComponentSchema = (allowEmptyStore) => Joi.object(componentSchemaProps).custom((value, helper) => {
|
|
291
304
|
if (!value.mountPoint && (!value.mountPoints || !value.mountPoints.length)) {
|
|
292
305
|
// @ts-expect-error
|
|
293
306
|
return helper.message('child mountPoint is required');
|
|
@@ -296,13 +309,23 @@ const componentSchema = Joi.object({
|
|
|
296
309
|
// @ts-expect-error
|
|
297
310
|
return helper.message('child source is required');
|
|
298
311
|
}
|
|
312
|
+
if (!allowEmptyStore && value.source && value.source.name && !value.source.store) {
|
|
313
|
+
// @ts-expect-error
|
|
314
|
+
return helper.message(`missing 'store' in source of component ${value.name}`);
|
|
315
|
+
}
|
|
299
316
|
return value;
|
|
300
|
-
})
|
|
301
|
-
|
|
317
|
+
});
|
|
318
|
+
const componentSchema = createComponentSchema().meta({
|
|
302
319
|
className: 'TComponent',
|
|
303
320
|
unknownType: 'any',
|
|
304
321
|
});
|
|
305
322
|
exports.componentSchema = componentSchema;
|
|
323
|
+
const componentSchemaWithoutStoreCheck = createComponentSchema(true);
|
|
324
|
+
const componentsSchema = (checkStore) => Joi.array()
|
|
325
|
+
.items(checkStore ? componentSchema : componentSchemaWithoutStoreCheck)
|
|
326
|
+
.unique('name')
|
|
327
|
+
.optional()
|
|
328
|
+
.default([]);
|
|
306
329
|
const signatureSchema = Joi.object({
|
|
307
330
|
type: Joi.string().required(),
|
|
308
331
|
name: Joi.string().required(),
|
|
@@ -568,7 +591,7 @@ const blockletMetaProps = {
|
|
|
568
591
|
signatures: Joi.array().items(signatureSchema).optional(),
|
|
569
592
|
lastPublishedAt: Joi.string().isoDate().optional(),
|
|
570
593
|
// blocklet component support
|
|
571
|
-
components:
|
|
594
|
+
components: componentsSchema(),
|
|
572
595
|
// navigation & theme
|
|
573
596
|
navigation: navigationSchema,
|
|
574
597
|
theme: themeSchema,
|
|
@@ -587,7 +610,7 @@ const blockletMetaSchema = Joi.object(blockletMetaProps).options({ stripUnknown:
|
|
|
587
610
|
});
|
|
588
611
|
exports.blockletMetaSchema = blockletMetaSchema;
|
|
589
612
|
const createBlockletSchema = (baseDir, _a = {}) => {
|
|
590
|
-
var { ensureMain = false, ensureFiles = false, ensureDist = false } = _a, schemaOptions = __rest(_a, ["ensureMain", "ensureFiles", "ensureDist"]);
|
|
613
|
+
var { ensureMain = false, ensureFiles = false, ensureDist = false, ensureComponentStore = true } = _a, schemaOptions = __rest(_a, ["ensureMain", "ensureFiles", "ensureDist", "ensureComponentStore"]);
|
|
591
614
|
if (!baseDir || !fs_1.default.existsSync(baseDir)) {
|
|
592
615
|
// eslint-disable-next-line no-param-reassign
|
|
593
616
|
ensureFiles = false;
|
|
@@ -603,7 +626,7 @@ const createBlockletSchema = (baseDir, _a = {}) => {
|
|
|
603
626
|
? // eslint-disable-next-line
|
|
604
627
|
Joi.file().exists({ baseDir, canSkip: (dir, name) => [BLOCKLET_ENTRY_FILE, BLOCKLET_BUNDLE_FILE].includes(name) || (0, is_glob_1.default)(name) }) // prettier-ignore
|
|
605
628
|
: Joi.string().trim())
|
|
606
|
-
.optional(), dist: ensureDist ? distSchema.required() : distSchema.optional() }))
|
|
629
|
+
.optional(), dist: ensureDist ? distSchema.required() : distSchema.optional(), components: componentsSchema(ensureComponentStore) }))
|
|
607
630
|
.options(Object.assign({ stripUnknown: true, noDefaults: false }, schemaOptions))
|
|
608
631
|
.rename('children', 'components')
|
|
609
632
|
.custom((data, helper) => {
|
package/lib/types/schema.d.ts
CHANGED
|
@@ -17,7 +17,31 @@ export interface TBlockletMeta {
|
|
|
17
17
|
navigation?: boolean;
|
|
18
18
|
};
|
|
19
19
|
community?: string;
|
|
20
|
-
components?:
|
|
20
|
+
components?: {
|
|
21
|
+
description?: TDescription;
|
|
22
|
+
mountPoint?: TMountPoint;
|
|
23
|
+
mountPoints?: {
|
|
24
|
+
child: {
|
|
25
|
+
interfaceName: string;
|
|
26
|
+
};
|
|
27
|
+
root: {
|
|
28
|
+
interfaceName: string;
|
|
29
|
+
prefix: string;
|
|
30
|
+
};
|
|
31
|
+
services?: TService[];
|
|
32
|
+
}[];
|
|
33
|
+
name: TBlockletName;
|
|
34
|
+
resolved?: string | string;
|
|
35
|
+
services?: TService[];
|
|
36
|
+
source?: {
|
|
37
|
+
url: string | string[];
|
|
38
|
+
} | {
|
|
39
|
+
name: TBlockletName;
|
|
40
|
+
store?: string | string[];
|
|
41
|
+
version?: 'latest' | string;
|
|
42
|
+
};
|
|
43
|
+
title?: TTitle;
|
|
44
|
+
}[];
|
|
21
45
|
contributors?: TPerson[];
|
|
22
46
|
copyright?: {
|
|
23
47
|
owner?: string;
|
|
@@ -116,7 +140,7 @@ export interface TComponent {
|
|
|
116
140
|
url: string | string[];
|
|
117
141
|
} | {
|
|
118
142
|
name: TBlockletName;
|
|
119
|
-
store
|
|
143
|
+
store?: string | string[];
|
|
120
144
|
version?: 'latest' | string;
|
|
121
145
|
};
|
|
122
146
|
title?: TTitle;
|
package/lib/validate.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { TBlockletMeta } from './types';
|
|
2
2
|
declare const fixAndValidateService: (meta: TBlockletMeta) => TBlockletMeta;
|
|
3
|
-
declare const validateMeta: (meta: any, { ensureMain, ensureFiles, ensureDist, schemaOptions, }?: {
|
|
3
|
+
declare const validateMeta: (meta: any, { ensureMain, ensureFiles, ensureDist, ensureComponentStore, schemaOptions, }?: {
|
|
4
4
|
ensureMain?: boolean;
|
|
5
5
|
ensureFiles?: boolean;
|
|
6
6
|
ensureDist?: boolean;
|
|
7
|
+
ensureComponentStore?: boolean;
|
|
7
8
|
schemaOptions?: any;
|
|
8
9
|
}) => TBlockletMeta;
|
|
9
10
|
export default validateMeta;
|
package/lib/validate.js
CHANGED
|
@@ -20,8 +20,11 @@ const fixAndValidateService = (meta) => {
|
|
|
20
20
|
return meta;
|
|
21
21
|
};
|
|
22
22
|
exports.fixAndValidateService = fixAndValidateService;
|
|
23
|
-
const validateMeta = (meta, { ensureMain = false, ensureFiles = false, ensureDist = false, schemaOptions = {}, } = {}) => {
|
|
24
|
-
const schema = (0, schema_1.createBlockletSchema)(null, Object.assign({ ensureMain,
|
|
23
|
+
const validateMeta = (meta, { ensureMain = false, ensureFiles = false, ensureDist = false, ensureComponentStore = true, schemaOptions = {}, } = {}) => {
|
|
24
|
+
const schema = (0, schema_1.createBlockletSchema)(null, Object.assign({ ensureMain,
|
|
25
|
+
ensureFiles,
|
|
26
|
+
ensureDist,
|
|
27
|
+
ensureComponentStore }, schemaOptions));
|
|
25
28
|
const { value, error } = schema.validate(meta);
|
|
26
29
|
if (error) {
|
|
27
30
|
throw new Error(`Invalid blocklet meta: ${error.details.map((x) => x.message).join(', ')}`);
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.8.
|
|
6
|
+
"version": "1.8.57",
|
|
7
7
|
"description": "Library to parse/validate/fix blocklet meta",
|
|
8
8
|
"main": "./lib/index.js",
|
|
9
9
|
"typings": "./lib/index.d.ts",
|
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
"author": "wangshijun <wangshijun2020@gmail.com> (http://github.com/wangshijun)",
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@abtnode/client": "1.8.
|
|
28
|
-
"@abtnode/constant": "1.8.
|
|
29
|
-
"@abtnode/util": "1.8.
|
|
27
|
+
"@abtnode/client": "1.8.57",
|
|
28
|
+
"@abtnode/constant": "1.8.57",
|
|
29
|
+
"@abtnode/util": "1.8.57",
|
|
30
30
|
"@arcblock/did": "1.18.34",
|
|
31
31
|
"@arcblock/did-ext": "1.18.34",
|
|
32
32
|
"@arcblock/did-util": "1.18.34",
|
|
33
33
|
"@arcblock/jwt": "1.18.34",
|
|
34
|
-
"@blocklet/constant": "1.8.
|
|
34
|
+
"@blocklet/constant": "1.8.57",
|
|
35
35
|
"@ocap/asset": "1.18.34",
|
|
36
36
|
"@ocap/mcrypto": "1.18.34",
|
|
37
37
|
"@ocap/types": "1.18.34",
|
|
@@ -80,5 +80,5 @@
|
|
|
80
80
|
"ts-node": "^10.9.1",
|
|
81
81
|
"typescript": "^4.8.4"
|
|
82
82
|
},
|
|
83
|
-
"gitHead": "
|
|
83
|
+
"gitHead": "2573eb9370c79853cba88cba418a964fb1cc8949"
|
|
84
84
|
}
|