@commercetools-frontend/application-cli 1.2.2 → 1.4.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/README.md +12 -0
- package/package.json +3 -2
- package/src/bin/cli.js +5 -1
- package/src/commands/validate-menu.js +33 -0
- package/src/commands/validate-menu.spec.js +43 -0
- package/src/schema.js +112 -0
package/README.md
CHANGED
|
@@ -67,6 +67,18 @@ This command compiles the menu configuration [defined in the application config]
|
|
|
67
67
|
pnpm application-cli compile-menu
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
+
### Command: `validate-menu`
|
|
71
|
+
|
|
72
|
+
This command validates the `menu.json` file generated by `compile-menu` command.
|
|
73
|
+
|
|
74
|
+
> This is mostly useful for internal Merchant Center applications.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pnpm application-cli validate-menu \
|
|
78
|
+
--input-file=<filepath> \
|
|
79
|
+
--navigation=top #option to switch between navbar (side) and appbar schema (top)
|
|
80
|
+
```
|
|
81
|
+
|
|
70
82
|
### Command: `create-version`
|
|
71
83
|
|
|
72
84
|
This command outputs a JSON string containing a list of deployed versions.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercetools-frontend/application-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Internal CLI to manage Merchant Center application deployments across various environments.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"commercetools",
|
|
@@ -18,11 +18,12 @@
|
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@babel/core": "^7.21.0",
|
|
21
|
-
"@commercetools-frontend/application-config": "
|
|
21
|
+
"@commercetools-frontend/application-config": "22.0.0",
|
|
22
22
|
"@manypkg/find-root": "2.1.0",
|
|
23
23
|
"cosmiconfig": "8.1.3",
|
|
24
24
|
"dotenv": "16.0.3",
|
|
25
25
|
"execa": "6.1.0",
|
|
26
|
+
"jsonschema": "^1.4.1",
|
|
26
27
|
"listr": "0.14.3",
|
|
27
28
|
"listr-verbose-renderer": "0.6.0",
|
|
28
29
|
"mri": "1.2.0",
|
package/src/bin/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import mri from 'mri';
|
|
|
4
4
|
import compileDeployments from '../commands/compile-deployments.js';
|
|
5
5
|
import compileMenu from '../commands/compile-menu.js';
|
|
6
6
|
import createVersion from '../commands/create-version.js';
|
|
7
|
-
|
|
7
|
+
import validateMenu from '../commands/validate-menu.js';
|
|
8
8
|
const cwd = process.cwd();
|
|
9
9
|
|
|
10
10
|
(async () => {
|
|
@@ -82,6 +82,10 @@ Options:
|
|
|
82
82
|
await compileMenu(cliFlags, cwd);
|
|
83
83
|
process.exit(0);
|
|
84
84
|
break;
|
|
85
|
+
case 'validate-menu':
|
|
86
|
+
await validateMenu(cliFlags, cwd);
|
|
87
|
+
process.exit(0);
|
|
88
|
+
break;
|
|
85
89
|
case 'create-version':
|
|
86
90
|
await createVersion(cliFlags, cwd);
|
|
87
91
|
process.exit(0);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { Validator } from 'jsonschema';
|
|
3
|
+
import { navbarMenuSchema, appbarMenuSchema } from '../schema.js';
|
|
4
|
+
|
|
5
|
+
export function validateMenu(menuJson, schema = navbarMenuSchema) {
|
|
6
|
+
const validator = new Validator();
|
|
7
|
+
const result = validator.validate(menuJson, schema);
|
|
8
|
+
if (result.valid) {
|
|
9
|
+
return menuJson;
|
|
10
|
+
} else {
|
|
11
|
+
throw new Error('menu.json validation failed\n' + result.errors);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function command(cliFlags, cwd) {
|
|
16
|
+
const menuJsonPath = cliFlags['input-file'];
|
|
17
|
+
const isAppbarMenu = cliFlags['navigation'] === 'top';
|
|
18
|
+
|
|
19
|
+
if (!menuJsonPath)
|
|
20
|
+
throw new Error(
|
|
21
|
+
`--input-file cannot be empty. please provide the path of compiled menu.json`
|
|
22
|
+
);
|
|
23
|
+
if (!fs.existsSync(menuJsonPath))
|
|
24
|
+
throw new Error(`The menu.json file doesn't exist: ${menuJsonPath}`);
|
|
25
|
+
const menuJson = fs.readFileSync(menuJsonPath, 'utf-8');
|
|
26
|
+
|
|
27
|
+
return validateMenu(
|
|
28
|
+
JSON.parse(menuJson),
|
|
29
|
+
isAppbarMenu ? appbarMenuSchema : navbarMenuSchema
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default command;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { validateMenu } from './validate-menu.js';
|
|
2
|
+
|
|
3
|
+
describe('validate menu', () => {
|
|
4
|
+
test.each([
|
|
5
|
+
123,
|
|
6
|
+
'{value:123}',
|
|
7
|
+
{},
|
|
8
|
+
{ uriPath: 'products', icon: 'ProductsIcon', submenu: [] },
|
|
9
|
+
{
|
|
10
|
+
uriPath: 123,
|
|
11
|
+
intlMessage: 123,
|
|
12
|
+
icon: 123,
|
|
13
|
+
permissions: '',
|
|
14
|
+
submenu: {},
|
|
15
|
+
key: {},
|
|
16
|
+
labelAllLocales: {},
|
|
17
|
+
},
|
|
18
|
+
])('should return null for invalid menu configs', (json) => {
|
|
19
|
+
try {
|
|
20
|
+
expect(validateMenu(json)).toEqual([]);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
// catch block is required otherwise the test fails
|
|
23
|
+
// due to `validateMenu` throwing error for invalid menu
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
it('should return menu json for valid menu configs', async () => {
|
|
27
|
+
const menuJson = {
|
|
28
|
+
uriPath: 'products',
|
|
29
|
+
intlMessage: 'Products',
|
|
30
|
+
icon: 'ProductsIcon',
|
|
31
|
+
permissions: ['ViewProducts'],
|
|
32
|
+
submenu: [],
|
|
33
|
+
key: 'product',
|
|
34
|
+
labelAllLocales: [
|
|
35
|
+
{
|
|
36
|
+
locale: 'en',
|
|
37
|
+
value: 'product',
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
expect(validateMenu(menuJson)).toEqual(menuJson);
|
|
42
|
+
});
|
|
43
|
+
});
|
package/src/schema.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
const baseMenuProperties = {
|
|
2
|
+
key: {
|
|
3
|
+
type: 'string',
|
|
4
|
+
},
|
|
5
|
+
uriPath: {
|
|
6
|
+
type: 'string',
|
|
7
|
+
},
|
|
8
|
+
icon: {
|
|
9
|
+
type: 'string',
|
|
10
|
+
},
|
|
11
|
+
featureToggle: {
|
|
12
|
+
type: ['string', 'null'],
|
|
13
|
+
},
|
|
14
|
+
labelAllLocales: {
|
|
15
|
+
type: 'array',
|
|
16
|
+
items: [
|
|
17
|
+
{
|
|
18
|
+
type: 'object',
|
|
19
|
+
properties: {
|
|
20
|
+
locale: { type: 'string' },
|
|
21
|
+
value: { type: 'string' },
|
|
22
|
+
},
|
|
23
|
+
required: ['locale', 'value'],
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
menuVisibility: {
|
|
28
|
+
type: ['string', 'null'],
|
|
29
|
+
},
|
|
30
|
+
permissions: {
|
|
31
|
+
type: 'array',
|
|
32
|
+
items: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
dataFences: {
|
|
37
|
+
type: ['array', 'null'],
|
|
38
|
+
items: [
|
|
39
|
+
{
|
|
40
|
+
type: ['object'],
|
|
41
|
+
properties: {
|
|
42
|
+
group: {
|
|
43
|
+
type: 'string',
|
|
44
|
+
},
|
|
45
|
+
name: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
},
|
|
48
|
+
type: {
|
|
49
|
+
type: 'string',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
actionRights: {
|
|
56
|
+
type: ['array', 'null'],
|
|
57
|
+
items: [
|
|
58
|
+
{
|
|
59
|
+
type: ['object'],
|
|
60
|
+
properties: {
|
|
61
|
+
group: {
|
|
62
|
+
type: 'string',
|
|
63
|
+
},
|
|
64
|
+
name: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const navbarMenuSchema = {
|
|
74
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
75
|
+
// "$id":""
|
|
76
|
+
title: 'NavbarMenu',
|
|
77
|
+
type: 'object',
|
|
78
|
+
properties: {
|
|
79
|
+
...baseMenuProperties,
|
|
80
|
+
submenu: {
|
|
81
|
+
type: 'array',
|
|
82
|
+
items: [
|
|
83
|
+
{
|
|
84
|
+
type: 'object',
|
|
85
|
+
properties: baseMenuProperties,
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
required: [
|
|
91
|
+
'icon',
|
|
92
|
+
'key',
|
|
93
|
+
'labelAllLocales',
|
|
94
|
+
'permissions',
|
|
95
|
+
'submenu',
|
|
96
|
+
'uriPath',
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export const appbarMenuSchema = {
|
|
101
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
102
|
+
// "$id":""
|
|
103
|
+
title: 'AppbarMenu',
|
|
104
|
+
type: 'array',
|
|
105
|
+
items: [
|
|
106
|
+
{
|
|
107
|
+
type: 'object',
|
|
108
|
+
properties: baseMenuProperties,
|
|
109
|
+
required: ['key', 'labelAllLocales', 'permissions', 'uriPath'],
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
};
|