@giteeteam/apps-manifest 0.2.1 → 0.3.0

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/manifest.d.ts CHANGED
@@ -43,4 +43,18 @@ export declare class Manifest {
43
43
  * @returns
44
44
  */
45
45
  getFunctionFiles(): string[];
46
+ /**
47
+ * 校验manifest
48
+ * @returns
49
+ */
50
+ validate(): {
51
+ pass: boolean;
52
+ errors: any[];
53
+ } | {
54
+ pass: false | undefined;
55
+ errors: {
56
+ path: string;
57
+ message: string | undefined;
58
+ }[] | null;
59
+ };
46
60
  }
package/lib/manifest.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Manifest = void 0;
4
4
  const yaml_1 = require("yaml");
5
+ const validate_1 = require("./validate");
5
6
  class Manifest {
6
7
  constructor(manifestString) {
7
8
  this.manifest = (0, yaml_1.parse)(manifestString);
@@ -102,5 +103,12 @@ class Manifest {
102
103
  });
103
104
  return [...fileNames];
104
105
  }
106
+ /**
107
+ * 校验manifest
108
+ * @returns
109
+ */
110
+ validate() {
111
+ return (0, validate_1.validateAll)(this.getManifest());
112
+ }
105
113
  }
106
114
  exports.Manifest = Manifest;
@@ -0,0 +1,25 @@
1
+ {
2
+ "$id": "http://proxima.com/schemas/all.json",
3
+ "type": "object",
4
+ "properties": {
5
+ "app": {
6
+ "$ref": "app.json"
7
+ },
8
+ "modules": {
9
+ "$ref": "modules/index.json"
10
+ },
11
+ "resources": {
12
+ "$ref": "resources.json"
13
+ },
14
+ "tables": {
15
+ "$ref": "tables.json"
16
+ },
17
+ "locales": {
18
+ "$ref": "locales.json"
19
+ }
20
+ },
21
+ "required": [
22
+ "app"
23
+ ],
24
+ "additionalProperties": false
25
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "$id": "http://proxima.com/schemas/app.json",
3
+ "type": "object",
4
+ "required": [
5
+ "name",
6
+ "key",
7
+ "version"
8
+ ],
9
+ "properties": {
10
+ "key": {
11
+ "type": "string",
12
+ "regexp": "/^[a-z][a-z0-9_]*$/gi"
13
+ },
14
+ "name": {
15
+ "type": "string"
16
+ },
17
+ "version": {
18
+ "type": "string"
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "$id": "http://proxima.com/schemas/locales.json",
3
+ "type": "object",
4
+ "patternProperties": {
5
+ "^(en-US|zh-CN)$": {
6
+ "type": "object",
7
+ "additionalProperties": true
8
+ }
9
+ },
10
+ "additionalProperties": true,
11
+ "minProperties": 1
12
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "type": "object",
3
+ "$id": "http://proxima.com/schemas/modules/custom-field/field.json",
4
+ "additionalProperties": true,
5
+ "properties": {
6
+ "key": {
7
+ "type": "string"
8
+ },
9
+ "name": {
10
+ "type": "string"
11
+ },
12
+ "type": {
13
+ "type": "string"
14
+ }
15
+ },
16
+ "required": [
17
+ "key", "name", "type"
18
+ ]
19
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "type": "object",
3
+ "$id": "http://proxima.com/schemas/modules/custom-field/type.json",
4
+ "properties": {
5
+ "key": {
6
+ "type": "string"
7
+ },
8
+ "name": {
9
+ "type": "string"
10
+ },
11
+ "resource": {
12
+ "type": "string"
13
+ }
14
+ },
15
+ "required": [
16
+ "key", "name"
17
+ ]
18
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "type": "object",
3
+ "$id": "http://proxima.com/schemas/modules/frontend/base.json",
4
+ "additionalProperties": true,
5
+ "properties": {
6
+ "key": {
7
+ "type": "string"
8
+ },
9
+ "resource": {
10
+ "type": "string"
11
+ },
12
+ "title": {
13
+ "type": "string"
14
+ },
15
+ "loadType": {
16
+ "type": "string"
17
+ },
18
+ "route": {
19
+ "type": "string"
20
+ }
21
+ },
22
+ "required": [
23
+ "key", "resource", "title"
24
+ ]
25
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "type": "object",
3
+ "$id": "http://proxima.com/schemas/modules/function/base.json",
4
+ "properties": {
5
+ "key": {
6
+ "type": "string"
7
+ },
8
+ "handler": {
9
+ "type": "string"
10
+ }
11
+ },
12
+ "required": [
13
+ "key", "handler"
14
+ ]
15
+ }
@@ -0,0 +1,92 @@
1
+ {
2
+ "$id": "http://proxima.com/schemas/modules/index.json",
3
+ "type": "object",
4
+ "patternProperties": {
5
+ "^(adminPage|itemPanel|itemActivity|appPage|viewAction)$": {
6
+ "type": "array",
7
+ "uniqueItems": true,
8
+ "uniqueItemProperties": [
9
+ "key"
10
+ ],
11
+ "minItems": 1,
12
+ "additionalItems": true,
13
+ "items": [
14
+ {
15
+ "$ref": "frontend/base.json"
16
+ }
17
+ ]
18
+ },
19
+ "^(webtrigger)$": {
20
+ "type": "array",
21
+ "uniqueItems": true,
22
+ "uniqueItemProperties": [
23
+ "key"
24
+ ],
25
+ "minItems": 1,
26
+ "additionalItems": true,
27
+ "items": [
28
+ {
29
+ "$ref": "trigger/webtrigger.json"
30
+ }
31
+ ]
32
+ },
33
+ "^(trigger)$": {
34
+ "type": "array",
35
+ "uniqueItems": true,
36
+ "uniqueItemProperties": [
37
+ "key"
38
+ ],
39
+ "minItems": 1,
40
+ "additionalItems": true,
41
+ "items": [
42
+ {
43
+ "$ref": "trigger/base.json"
44
+ }
45
+ ]
46
+ },
47
+ "^(function)$": {
48
+ "type": "array",
49
+ "uniqueItems": true,
50
+ "uniqueItemProperties": [
51
+ "key"
52
+ ],
53
+ "minItems": 1,
54
+ "additionalItems": true,
55
+ "items": [
56
+ {
57
+ "$ref": "function/base.json"
58
+ }
59
+ ]
60
+ },
61
+ "^(customFieldType)$": {
62
+ "type": "array",
63
+ "uniqueItems": true,
64
+ "uniqueItemProperties": [
65
+ "key"
66
+ ],
67
+ "minItems": 1,
68
+ "additionalItems": true,
69
+ "items": [
70
+ {
71
+ "$ref": "custom-field/type.json"
72
+ }
73
+ ]
74
+ },
75
+ "^(customField)$": {
76
+ "type": "array",
77
+ "uniqueItems": true,
78
+ "uniqueItemProperties": [
79
+ "key"
80
+ ],
81
+ "minItems": 1,
82
+ "additionalItems": true,
83
+ "items": [
84
+ {
85
+ "$ref": "custom-field/field.json"
86
+ }
87
+ ]
88
+ }
89
+ },
90
+ "additionalProperties": true,
91
+ "minProperties": 1
92
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "type": "object",
3
+ "$id": "http://proxima.com/schemas/modules/trigger/base.json",
4
+ "properties": {
5
+ "key": {
6
+ "type": "string"
7
+ },
8
+ "events": {
9
+ "type": "array",
10
+ "uniqueItems": true,
11
+ "minItems": 1,
12
+ "additionalItems": true,
13
+ "items": [
14
+ {
15
+ "type": "string"
16
+ }
17
+ ]
18
+ },
19
+ "function": {
20
+ "type": "string"
21
+ }
22
+ },
23
+ "required": [
24
+ "key", "events", "function"
25
+ ]
26
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "type": "object",
3
+ "$id": "http://proxima.com/schemas/modules/trigger/webtrigger.json",
4
+ "properties": {
5
+ "key": {
6
+ "type": "string"
7
+ },
8
+ "function": {
9
+ "type": "string"
10
+ }
11
+ },
12
+ "required": [
13
+ "key", "function"
14
+ ]
15
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "$id": "http://proxima.com/schemas/resources.json",
3
+ "type": "array",
4
+ "minItems": 1,
5
+ "uniqueItems": true,
6
+ "uniqueItemProperties": [
7
+ "key"
8
+ ],
9
+ "items": {
10
+ "type": "object",
11
+ "properties": {
12
+ "key": {
13
+ "type": "string"
14
+ },
15
+ "path": {
16
+ "type": "string"
17
+ }
18
+ },
19
+ "required": [
20
+ "key",
21
+ "path"
22
+ ]
23
+ }
24
+ }
@@ -0,0 +1,151 @@
1
+ {
2
+ "$id": "http://proxima.com/schemas/tables.json",
3
+ "type": "array",
4
+ "minItems": 1,
5
+ "uniqueItems": true,
6
+ "uniqueItemProperties": [
7
+ "className"
8
+ ],
9
+ "items": {
10
+ "type": "object",
11
+ "properties": {
12
+ "className": {
13
+ "type": "string",
14
+ "regexp": {
15
+ "pattern": "(^_([a-zA-Z0-9]_?)*$)|(^[a-zA-Z](_?[a-zA-Z0-9])*_?$)",
16
+ "flags": "i"
17
+ }
18
+ },
19
+ "fields": {
20
+ "type": "object",
21
+ "patternProperties": {
22
+ "(^_([a-zA-Z0-9]_?)*$)|(^[a-zA-Z](_?[a-zA-Z0-9])*_?$)": {
23
+ "type": "object",
24
+ "anyOf": [
25
+ {
26
+ "type": "object",
27
+ "properties": {
28
+ "type": {
29
+ "type": "string",
30
+ "enum": [
31
+ "Pointer",
32
+ "Relation"
33
+ ]
34
+ },
35
+ "targetClass": {
36
+ "type": "string",
37
+ "regexp": {
38
+ "pattern": "(^_([a-zA-Z0-9]_?)*$)|(^[a-zA-Z](_?[a-zA-Z0-9])*_?$)",
39
+ "flags": "i"
40
+ }
41
+ },
42
+ "isAppClass": {
43
+ "type": "boolean",
44
+ "default": false
45
+ }
46
+ },
47
+ "required": [
48
+ "type", "targetClass"
49
+ ]
50
+ },
51
+ {
52
+ "type": "object",
53
+ "properties": {
54
+ "type": {
55
+ "type": "string",
56
+ "const": "String"
57
+ },
58
+ "defaultValue": {
59
+ "type": "string"
60
+ }
61
+ },
62
+ "required": [
63
+ "type"
64
+ ]
65
+ },
66
+ {
67
+ "type": "object",
68
+ "properties": {
69
+ "type": {
70
+ "type": "string",
71
+ "const": "Boolean"
72
+ },
73
+ "defaultValue": {
74
+ "type": "boolean"
75
+ }
76
+ },
77
+ "required": [
78
+ "type"
79
+ ]
80
+ },
81
+ {
82
+ "type": "object",
83
+ "properties": {
84
+ "type": {
85
+ "type": "string",
86
+ "const": "Number"
87
+ },
88
+ "defaultValue": {
89
+ "type": "number"
90
+ }
91
+ },
92
+ "required": [
93
+ "type"
94
+ ]
95
+ },
96
+ {
97
+ "type": "object",
98
+ "properties": {
99
+ "type": {
100
+ "type": "string",
101
+ "const": "Object"
102
+ },
103
+ "defaultValue": {
104
+ "type": "object"
105
+ }
106
+ },
107
+ "required": [
108
+ "type"
109
+ ]
110
+ },
111
+ {
112
+ "type": "object",
113
+ "properties": {
114
+ "type": {
115
+ "type": "string",
116
+ "const": "Array"
117
+ },
118
+ "defaultValue": {
119
+ "type": "array"
120
+ }
121
+ },
122
+ "required": [
123
+ "type"
124
+ ]
125
+ },
126
+ {
127
+ "type": "object",
128
+ "properties": {
129
+ "type": {
130
+ "type": "string",
131
+ "enum": [
132
+ "Date",
133
+ "File"
134
+ ]
135
+ }
136
+ },
137
+ "required": [
138
+ "type"
139
+ ]
140
+ }
141
+ ]
142
+ }
143
+ },
144
+ "additionalProperties": false
145
+ }
146
+ },
147
+ "required": [
148
+ "className", "fields"
149
+ ]
150
+ }
151
+ }
package/lib/types.d.ts CHANGED
@@ -19,6 +19,7 @@ export interface IManifestModule {
19
19
  function?: string;
20
20
  resource?: string;
21
21
  route?: string;
22
+ type?: string;
22
23
  }
23
24
  export interface IManifestFunction {
24
25
  key: string;
@@ -0,0 +1,46 @@
1
+ import type { IManifest } from './types';
2
+ export declare const validateAll: (json: IManifest) => {
3
+ pass: boolean;
4
+ errors: any[];
5
+ } | {
6
+ pass: false | undefined;
7
+ errors: {
8
+ path: string;
9
+ message: string | undefined;
10
+ }[] | null;
11
+ };
12
+ export declare const validateApp: (json: IManifest) => {
13
+ pass: boolean | Promise<unknown> | undefined;
14
+ errors: {
15
+ path: string;
16
+ message: string | undefined;
17
+ }[] | null;
18
+ };
19
+ export declare const validateModules: (json: IManifest) => {
20
+ pass: boolean | Promise<unknown> | undefined;
21
+ errors: {
22
+ path: string;
23
+ message: string | undefined;
24
+ }[] | null;
25
+ };
26
+ export declare const validateResources: (json: IManifest) => {
27
+ pass: boolean | Promise<unknown> | undefined;
28
+ errors: {
29
+ path: string;
30
+ message: string | undefined;
31
+ }[] | null;
32
+ };
33
+ export declare const validateTables: (json: IManifest) => {
34
+ pass: boolean | Promise<unknown> | undefined;
35
+ errors: {
36
+ path: string;
37
+ message: string | undefined;
38
+ }[] | null;
39
+ };
40
+ export declare const validateLocales: (json: IManifest) => {
41
+ pass: boolean | Promise<unknown> | undefined;
42
+ errors: {
43
+ path: string;
44
+ message: string | undefined;
45
+ }[] | null;
46
+ };
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validateLocales = exports.validateTables = exports.validateResources = exports.validateModules = exports.validateApp = exports.validateAll = void 0;
7
+ const ajv_1 = __importDefault(require("ajv"));
8
+ const ajv_keywords_1 = __importDefault(require("ajv-keywords"));
9
+ const lodash_1 = require("lodash");
10
+ const all_json_1 = __importDefault(require("./schema/all.json"));
11
+ const app_json_1 = __importDefault(require("./schema/app.json"));
12
+ const index_json_1 = __importDefault(require("./schema/modules/index.json"));
13
+ const base_json_1 = __importDefault(require("./schema/modules/frontend/base.json"));
14
+ const base_json_2 = __importDefault(require("./schema/modules/trigger/base.json"));
15
+ const webtrigger_json_1 = __importDefault(require("./schema/modules/trigger/webtrigger.json"));
16
+ const base_json_3 = __importDefault(require("./schema/modules/function/base.json"));
17
+ const field_json_1 = __importDefault(require("./schema/modules/custom-field/field.json"));
18
+ const type_json_1 = __importDefault(require("./schema/modules/custom-field/type.json"));
19
+ const resources_json_1 = __importDefault(require("./schema/resources.json"));
20
+ const tables_json_1 = __importDefault(require("./schema/tables.json"));
21
+ const locales_json_1 = __importDefault(require("./schema/locales.json"));
22
+ const validateResource = (json) => {
23
+ const errors = [];
24
+ const frontendModules = ['adminPage', 'itemPanel', 'itemActivity', 'appPage'];
25
+ const modules = (0, lodash_1.get)(json, 'modules') || {};
26
+ const resourcesEntries = (0, lodash_1.keyBy)((0, lodash_1.get)(json, 'resources'), 'key');
27
+ const functionEntries = (0, lodash_1.keyBy)((0, lodash_1.get)(json, 'modules.function'), 'key');
28
+ const customFieldTypeEntries = (0, lodash_1.keyBy)((0, lodash_1.get)(json, 'modules.customFieldType'), 'key');
29
+ const moduleKeys = {};
30
+ Object.keys(modules).forEach(moduleKey => {
31
+ const module = (0, lodash_1.get)(modules, moduleKey);
32
+ if (!module)
33
+ return;
34
+ const isFrontendModule = frontendModules.indexOf(moduleKey) > -1;
35
+ Array.from(module).forEach(({ resource, function: functionRef, type, key }, index) => {
36
+ const path = `/modules/${moduleKey}/${index}`;
37
+ if (moduleKeys[key]) {
38
+ errors.push({
39
+ path,
40
+ message: `Key '${key}' has already exits! `,
41
+ });
42
+ }
43
+ else {
44
+ moduleKeys[key] = true;
45
+ }
46
+ if (isFrontendModule) {
47
+ if (resource && !(0, lodash_1.get)(resourcesEntries, resource)) {
48
+ errors.push({
49
+ path,
50
+ message: `Resource '${resource}' not found! `,
51
+ });
52
+ }
53
+ }
54
+ else if (moduleKey === 'trigger' || moduleKey === 'webtrigger') {
55
+ if (functionRef && !(0, lodash_1.get)(functionEntries, functionRef)) {
56
+ errors.push({
57
+ path,
58
+ message: `Function '${functionRef}' not found! `,
59
+ });
60
+ }
61
+ }
62
+ else if (moduleKey === 'customField' && (0, lodash_1.startsWith)(type, '_self:')) {
63
+ const fieldTypeRef = type === null || type === void 0 ? void 0 : type.slice(6);
64
+ if (fieldTypeRef && !(0, lodash_1.get)(customFieldTypeEntries, fieldTypeRef)) {
65
+ errors.push({
66
+ path,
67
+ message: `FieldType '${fieldTypeRef}' not found! `,
68
+ });
69
+ }
70
+ }
71
+ });
72
+ });
73
+ return {
74
+ pass: errors.length === 0,
75
+ errors,
76
+ };
77
+ };
78
+ const validateFactory = (schema) => {
79
+ const ajv = new ajv_1.default({
80
+ // https://github.com/ajv-validator/ajv/issues/1417
81
+ strictTuples: false,
82
+ allowMatchingProperties: false,
83
+ schemas: [
84
+ all_json_1.default,
85
+ app_json_1.default,
86
+ index_json_1.default,
87
+ base_json_1.default,
88
+ base_json_2.default,
89
+ webtrigger_json_1.default,
90
+ base_json_3.default,
91
+ field_json_1.default,
92
+ type_json_1.default,
93
+ resources_json_1.default,
94
+ tables_json_1.default,
95
+ locales_json_1.default,
96
+ ],
97
+ });
98
+ (0, ajv_keywords_1.default)(ajv);
99
+ return (json) => {
100
+ const validate = ajv.getSchema(schema);
101
+ const pass = validate === null || validate === void 0 ? void 0 : validate(json);
102
+ const errors = validate === null || validate === void 0 ? void 0 : validate.errors;
103
+ return {
104
+ pass,
105
+ errors: errors
106
+ ? (0, lodash_1.map)(errors, error => ({
107
+ path: error.instancePath,
108
+ message: error.message,
109
+ }))
110
+ : null,
111
+ };
112
+ };
113
+ };
114
+ const validateAll = (json) => {
115
+ const { pass: schemaPass, errors } = validateFactory('http://proxima.com/schemas/all.json')(json);
116
+ if (!schemaPass) {
117
+ return { pass: schemaPass, errors };
118
+ }
119
+ // 校验一下需要的引用是否存在
120
+ return validateResource(json);
121
+ };
122
+ exports.validateAll = validateAll;
123
+ exports.validateApp = validateFactory('http://proxima.com/schemas/app.json');
124
+ exports.validateModules = validateFactory('http://proxima.com/schemas/modules/index.json');
125
+ exports.validateResources = validateFactory('http://proxima.com/schemas/resources.json');
126
+ exports.validateTables = validateFactory('http://proxima.com/schemas/tables.json');
127
+ exports.validateLocales = validateFactory('http://proxima.com/schemas/locales.json');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@giteeteam/apps-manifest",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Giteeteam Apps Manifest",
5
5
  "keywords": [
6
6
  "typescript",
@@ -21,6 +21,7 @@
21
21
  "url": "git+https://github.com/moriahq/proxima.git"
22
22
  },
23
23
  "scripts": {
24
+ "test": "jest --coverage",
24
25
  "dev": "tsc -w",
25
26
  "build": "rm -rf lib && tsc",
26
27
  "prepare": "pnpm run build",
@@ -32,6 +33,13 @@
32
33
  "registry": "https://registry.npmjs.org/"
33
34
  },
34
35
  "dependencies": {
36
+ "ajv": "^8.6.3",
37
+ "ajv-keywords": "^5.0.0",
38
+ "lodash": "^4.17.21",
35
39
  "yaml": "^2.1.1"
40
+ },
41
+ "devDependencies": {
42
+ "@types/lodash": "^4.14.191",
43
+ "jest": "^29.3.1"
36
44
  }
37
45
  }