@pega/dx-component-builder-sdk 0.1.10 → 0.1.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pega/dx-component-builder-sdk",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Utility for building custom UI components",
5
5
  "bin": "./bin/index.js",
6
6
  "scripts": {
package/src/cli.js CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  createComponent,
8
8
  deleteComponent,
9
9
  deleteAllComponents,
10
+ generateMissingCompanions,
10
11
  listComponents,
11
12
  overrideComponent,
12
13
  publishComponent,
@@ -28,7 +29,8 @@ const TASKS = {
28
29
  DELETE: 'delete',
29
30
  DELETE_ALL: "deleteAll",
30
31
  AUTHENTICATE: 'authenticate',
31
- UPGRADE: 'upgrade'
32
+ UPGRADE: 'upgrade',
33
+ GENERATE_MISSING_COMPANIONS: 'generateMissingCompanions'
32
34
  };
33
35
 
34
36
  const parseArgumentsIntoOptions = rawArgs => {
@@ -102,6 +104,10 @@ export default async (args = []) => {
102
104
  upgrade(options);
103
105
  break;
104
106
  }
107
+ case TASKS.GENERATE_MISSING_COMPANIONS: {
108
+ generateMissingCompanions(options);
109
+ break;
110
+ }
105
111
  default: {
106
112
  console.log(chalk.red(`No task matched with ${task}`));
107
113
  break;
package/src/constants.js CHANGED
@@ -517,7 +517,7 @@ export const COMPONENT_SCHEMA = {
517
517
  },
518
518
  {
519
519
  name: 'Action Buttons For File Utility',
520
- value: 'FileUtility/ActionButtonsForFileUtility'
520
+ value: 'FileUtility/ActionButtonsForFileUtil'
521
521
  },
522
522
  {
523
523
  name: 'Followers',
@@ -130,7 +130,7 @@ export const compileMustacheTemplates = async (
130
130
 
131
131
 
132
132
 
133
- const validateCompile = async (
133
+ export const validateCompile = async (
134
134
  {
135
135
  library,
136
136
  organization,
@@ -143,7 +143,8 @@ const validateCompile = async (
143
143
  description,
144
144
  allowedApplications
145
145
  },
146
- options
146
+ options,
147
+ onlyCompanion = false
147
148
  ) => {
148
149
 
149
150
  let sSubType = subtype;
@@ -177,41 +178,55 @@ const validateCompile = async (
177
178
  const targetDirectoryConstellation = await getComponentDirectoryPath(join(typeLC, "/",componentKey), CATEGORY_CONSTELLATION);
178
179
 
179
180
  const components = await getComponents(false);
180
- if (components.includes(componentKey)) {
181
- console.log(chalk.red(`${componentKey} component already exists in ${targetDirectory}`));
182
181
 
183
- let componentsConstellation = await getComponents(false, CATEGORY_CONSTELLATION);
182
+ if (!onlyCompanion) {
184
183
  if (components.includes(componentKey)) {
184
+ console.log(chalk.red(`${componentKey} component already exists in ${targetDirectory}`));
185
+
186
+ let componentsConstellation = await getComponents(false, CATEGORY_CONSTELLATION);
187
+ if (components.includes(componentKey)) {
188
+ console.log(chalk.red(`${componentKey} companion component already exists in ${targetDirectoryConstellation}`));
189
+ }
190
+
191
+ return;
192
+ }
193
+ // test for constellation
194
+ const componentsConstellation = await getComponents(false, CATEGORY_CONSTELLATION);
195
+ if (componentsConstellation.includes(componentKey)) {
185
196
  console.log(chalk.red(`${componentKey} companion component already exists in ${targetDirectoryConstellation}`));
197
+ return;
186
198
  }
187
-
188
- return;
189
199
  }
190
- // test for constellation
191
- const componentsConstellation = await getComponents(false, CATEGORY_CONSTELLATION);
192
- if (components.includes(componentKey)) {
193
- console.log(chalk.red(`${componentKey} companion component already exists in ${targetDirectoryConstellation}`));
194
- return;
200
+ else {
201
+ // test for constellation
202
+ const componentsConstellation = await getComponents(false, CATEGORY_CONSTELLATION);
203
+ if (componentsConstellation.includes(componentKey)) {
204
+ console.log(chalk.red(`${componentKey} companion component already exists in ${targetDirectoryConstellation}`));
205
+ return;
206
+ }
195
207
  }
196
208
 
197
- // component
198
- await copyComponentTemplate({
199
- ...options,
200
- targetDirectory,
201
- templateDirectory
202
- });
203
- await compileMustacheTemplates(targetDirectory, {
204
- componentKey,
205
- componentName,
206
- componentLabel,
207
- library,
208
- version,
209
- type,
210
- subtype,
211
- description,
212
- organization,
213
- allowedApplications
214
- });
209
+
210
+ if (!onlyCompanion) {
211
+ // component
212
+ await copyComponentTemplate({
213
+ ...options,
214
+ targetDirectory,
215
+ templateDirectory
216
+ });
217
+ await compileMustacheTemplates(targetDirectory, {
218
+ componentKey,
219
+ componentName,
220
+ componentLabel,
221
+ library,
222
+ version,
223
+ type,
224
+ subtype,
225
+ description,
226
+ organization,
227
+ allowedApplications
228
+ });
229
+ }
215
230
 
216
231
  // matching constellation
217
232
  await copyComponentTemplate({
@@ -232,7 +247,10 @@ const validateCompile = async (
232
247
  allowedApplications
233
248
  });
234
249
 
235
- console.log(chalk.green(`created ${componentKey} component in ${targetDirectory}`));
250
+ if (!onlyCompanion) {
251
+ console.log(chalk.green(`created ${componentKey} component in ${targetDirectory}`));
252
+ }
253
+
236
254
  console.log(chalk.green(`created ${componentKey} companion component in ${targetDirectoryConstellation}`));
237
255
 
238
256
  };
@@ -28,25 +28,24 @@ export const getDeleteComponentsQuestions = async (options, sourceOfComponentsOp
28
28
  const categoryType = getOptionsCategory(options);
29
29
 
30
30
  return [
31
- {
32
- name: 'category',
33
- type: 'rawlist',
34
- message: 'Category of components ?',
35
- choices: COMPONENT_SCHEMA.category,
36
- when() {
37
- return !options.params[4] && categoryType == null;
38
- }
39
- },
40
31
  {
41
32
  name: 'sourceOfComponents',
42
33
  type: 'rawlist',
43
34
  message: 'Delete components from Server or Local ?',
44
35
  choices: Object.values(SOURCE_OF_COMPONENT_TYPES),
45
36
  default: defaultPegaServerConfig.sourceOfComponents,
37
+
38
+ },
39
+ {
40
+ name: 'category',
41
+ type: 'rawlist',
42
+ message: 'Category of components ?',
43
+ choices: COMPONENT_SCHEMA.category,
46
44
  when(answers) {
47
- return !options.params[4] && answers.category != CATEGORY_OVERRIDE && categoryType != CATEGORY_OVERRIDE;
45
+ return answers.sourceOfComponents != "Server"
48
46
  }
49
47
  }
48
+
50
49
  ];
51
50
  };
52
51
 
@@ -81,7 +80,7 @@ export const deleteLocalComponents = async (sourceOfComponents, category = CATEG
81
80
  await deleteFromComponentMap(answers.componentKey, category);
82
81
  }
83
82
  else {
84
- console.log(chalk.bold.redBright(`No component in map: ` + componnetName));
83
+ console.log(chalk.bold.redBright(`No component in map: ` + componentName));
85
84
  }
86
85
 
87
86
  }
@@ -115,7 +114,7 @@ export const deleteServerComponents = async (sourceOfComponents, answers) => {
115
114
  const answers = await inquirer.prompt({
116
115
  name: 'componentToDelete',
117
116
  type: 'rawlist',
118
- pageSize: 10,
117
+ pageSize: 15,
119
118
  message: `Select component to delete \n ${standardizeStr('Rule name', 48)} ${standardizeStr(
120
119
  'Ruleset name',
121
120
  30
@@ -128,11 +127,23 @@ export const deleteServerComponents = async (sourceOfComponents, answers) => {
128
127
  const componentName = answers.componentToDelete.split("~")[0];
129
128
  const componentKey = componentObj.find( theObj => theObj.name === componentName);
130
129
 
130
+ // check to see if component is an override component
131
+ if (componentKey === undefined) {
132
+ const overrideObj = await getComponentsObj(false, CATEGORY_OVERRIDE);
133
+ if (overrideObj) {
134
+ const overrideKey = overrideObj.find( theObj => theObj.name === componentName);
135
+ if (overrideKey != undefined) {
136
+ // override component, don't remove from map, just end
137
+ return;
138
+ }
139
+ }
140
+ }
141
+
131
142
  if (componentKey != undefined) {
132
143
  await deleteFromComponentMap(componentKey.value);
133
144
  }
134
145
  else {
135
- console.log(chalk.bold.redBright(`No component in map: ` + componnetName));
146
+ console.log(chalk.bold.redBright(`No component in map: ` + componentName));
136
147
  }
137
148
 
138
149
  } else {
@@ -29,24 +29,21 @@ export const getDeleteComponentsQuestions = async (options, sourceOfComponentsOp
29
29
  const categoryType = getOptionsCategory(options);
30
30
 
31
31
  return [
32
- {
33
- name: 'category',
34
- type: 'rawlist',
35
- message: 'Category of components ?',
36
- choices: COMPONENT_SCHEMA.category,
37
- when() {
38
- return !options.params[4] && categoryType == null;
39
- }
40
- },
41
32
  {
42
33
  name: 'sourceOfComponents',
43
34
  type: 'rawlist',
44
35
  message: 'Delete components from Server or Local ?',
45
36
  choices: Object.values(SOURCE_OF_COMPONENT_TYPES),
46
37
  default: defaultPegaServerConfig.sourceOfComponents,
47
- when(answers) {
48
- return !options.params[4] && answers.category != CATEGORY_OVERRIDE && categoryType != CATEGORY_OVERRIDE;
49
38
 
39
+ },
40
+ {
41
+ name: 'category',
42
+ type: 'rawlist',
43
+ message: 'Category of components ?',
44
+ choices: COMPONENT_SCHEMA.category,
45
+ when(answers) {
46
+ return answers.sourceOfComponents != "Server"
50
47
  }
51
48
  }
52
49
  ];
@@ -180,6 +177,18 @@ export const deleteServerComponents = async (sourceOfComponents, answers) => {
180
177
  const componentName = componentToDelete.split("~")[0];
181
178
  const componentKey = componentObj.find( theObj => theObj.name === componentName);
182
179
 
180
+ // check to see if component is an override component
181
+ if (componentKey === undefined) {
182
+ const overrideObj = await getComponentsObj(false, CATEGORY_OVERRIDE);
183
+ if (overrideObj) {
184
+ const overrideKey = overrideObj.find( theObj => theObj.name === componentName);
185
+ if (overrideKey != undefined) {
186
+ // override component, don't remove from map, just end
187
+ continue;
188
+ }
189
+ }
190
+ }
191
+
183
192
  if (componentKey != undefined) {
184
193
  await deleteFromComponentMap(componentKey.value);
185
194
  }
@@ -0,0 +1,77 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+
5
+ import { validateCompile } from '../create/index.js';
6
+ import {
7
+ showVersion,
8
+ getComponents,
9
+ getComponentsObj,
10
+ getComponentDirectoryPath,
11
+ getComponentsAndSubDirectory
12
+ } from '../../util.js';
13
+ import {CATEGORY_CONSTELLATION, CATEGORY_CUSTOM, CATEGORY_OVERRIDE } from '../..//constants.js';
14
+ import { or } from 'ajv/dist/compile/codegen/index.js';
15
+
16
+ export const DXCB_CONFIG_INTERNAL_JSON_FILENAME = 'src/dxcb.config.json';
17
+ const pegaConfigInternalJsonPath = path.join(path.resolve(), DXCB_CONFIG_INTERNAL_JSON_FILENAME);
18
+
19
+
20
+ const getMissingList = async () => {
21
+ const customList = await getComponentsAndSubDirectory(CATEGORY_CUSTOM);
22
+ const constellationList = await getComponentsAndSubDirectory(CATEGORY_CONSTELLATION);
23
+ let missingList = [];
24
+
25
+ for (var el in customList) {
26
+ const found = constellationList.find(element => element === customList[el]);
27
+ if (found === undefined) {
28
+ missingList.push(customList[el]);
29
+ }
30
+ }
31
+
32
+ return missingList;
33
+ }
34
+
35
+ const generateMissingCompanion = async (componentKey) => {
36
+ const srcDirectory = await getComponentDirectoryPath(componentKey, CATEGORY_CUSTOM);
37
+ const configJson = `${srcDirectory}/config.json`;
38
+
39
+ if (fs.existsSync(configJson)) {
40
+ let data = fs.readFileSync(configJson, { encoding: 'utf8' });
41
+ data = JSON.parse(data);
42
+
43
+ const { name, label, description, organization, version, library, componentKey, type, subtype} = data;
44
+ let { allowedApplications } = data;
45
+
46
+ const componentName = componentKey.split("_")[2];
47
+
48
+ // look up the framework
49
+ let internalData = fs.readFileSync(pegaConfigInternalJsonPath, { encoding: 'utf8' });
50
+ internalData = internalData && JSON.parse(internalData);
51
+
52
+ const framework = internalData.sdkType;
53
+ allowedApplications = allowedApplications.toString();
54
+
55
+
56
+ validateCompile({library, organization, componentName, label, version, framework, type, subtype, description, allowedApplications}, null, true);
57
+ }
58
+
59
+ }
60
+
61
+ export default async options => {
62
+
63
+ showVersion();
64
+
65
+ const missingList = await getMissingList();
66
+
67
+ if (missingList.length === 0) {
68
+ console.log(chalk.bold.green("No missing companion components!"));
69
+ return;
70
+ }
71
+
72
+ for (var el in missingList) {
73
+ await generateMissingCompanion(missingList[el]);
74
+ }
75
+
76
+
77
+ }
@@ -10,3 +10,4 @@ export { default as validate } from './validator/index.js';
10
10
  export { default as authenticate } from './authenticate/index.js';
11
11
  export { default as upgrade } from './upgrade/index.js';
12
12
  export { default as buildComponent } from './build/index.js';
13
+ export { default as generateMissingCompanions } from './generate-missing-companions/index.js';
@@ -20,25 +20,23 @@ export const getListComponentsQuestions = async (options, sourceOfComponentsOpti
20
20
  const categoryType = getOptionsCategory(options);
21
21
 
22
22
  return [
23
- {
24
- name: 'category',
25
- type: 'rawlist',
26
- message: 'Category of components ?',
27
- choices: COMPONENT_SCHEMA.category,
28
- when() {
29
- return !options.params[4] && categoryType == null;
30
- }
31
- },
23
+
32
24
  {
33
25
  name: 'sourceOfComponents',
34
26
  type: 'rawlist',
35
27
  message: 'List components from Server or Local ?',
36
28
  choices: Object.values(SOURCE_OF_COMPONENT_TYPES),
37
29
  default: defaultPegaServerConfig.sourceOfComponents,
30
+ },
31
+ {
32
+ name: 'category',
33
+ type: 'rawlist',
34
+ message: 'Category of components ?',
35
+ choices: COMPONENT_SCHEMA.category,
38
36
  when(answers) {
39
- return !options.params[4] && answers.category != 'override' && categoryType != 'override';
37
+ return answers.sourceOfComponents != "Server"
40
38
  }
41
- }
39
+ },
42
40
  ];
43
41
  };
44
42
 
@@ -53,7 +53,8 @@ export const getPublishComponentQuestions = async (category) => {
53
53
  name: 'componentKey',
54
54
  type: 'rawlist',
55
55
  message: 'Select component to publish',
56
- choices: components
56
+ choices: components,
57
+ pageSize: 15,
57
58
  },
58
59
  {
59
60
  name: 'rulesetName',
@@ -107,8 +108,9 @@ export const zipComponent = async (componentKey, category = CATEGORY_CUSTOM) =>
107
108
 
108
109
  const zip = new AdmZip();
109
110
 
110
- zip.addLocalFolder(srcDirectory, 'src/');
111
+
111
112
  if (category === CATEGORY_CUSTOM || category == CATEGORY_CONSTELLATION) {
113
+ zip.addLocalFolder(srcDirectory, 'src/');
112
114
  zip.addLocalFile(configJson);
113
115
  }
114
116
  else {
@@ -119,7 +121,9 @@ export const zipComponent = async (componentKey, category = CATEGORY_CUSTOM) =>
119
121
 
120
122
  }
121
123
 
122
- zip.addLocalFolder(buildDirectory);
124
+ if (category === CATEGORY_CUSTOM || category === CATEGORY_CONSTELLATION) {
125
+ zip.addLocalFolder(buildDirectory);
126
+ }
123
127
  const zipContent = zip.toBuffer().toString('base64');
124
128
 
125
129
  let configContent = "{ }";
@@ -165,10 +169,17 @@ export const publishComponentToServer = async data => {
165
169
  componentKey = arKey[arKey.length - 1];
166
170
  }
167
171
 
172
+ const configContentObj = JSON.parse(configContent);
173
+
174
+ if (configContentObj.type == null || configContentObj.subtype == null) {
175
+ console.log(chalk.bold.yellow(`No config-ext to publish for ${componentKey}`));
176
+ return;
177
+ }
178
+
168
179
  const apiBody = {
169
180
  configContent,
170
181
  zipContent,
171
- componentKey: JSON.parse(configContent).componentKey,
182
+ componentKey: configContentObj.componentKey,
172
183
  publishFor: 'constellation',
173
184
  rulesetName,
174
185
  rulesetVersion,
@@ -132,14 +132,13 @@ export default async options => {
132
132
  content = { ...content, ...output };
133
133
  }
134
134
  },
135
- /*
136
135
  {
137
136
  title: 'Publish component',
138
137
  task: async () => {
139
138
  await publishComponentToServer(content);
140
139
  }
141
140
  }
142
- */
141
+
143
142
  ],
144
143
  {
145
144
  exitOnError: true
@@ -100,8 +100,9 @@ export const zipComponent = async (componentKey, category = CATEGORY_CUSTOM) =>
100
100
 
101
101
  const zip = new AdmZip();
102
102
 
103
- zip.addLocalFolder(srcDirectory, 'src/');
103
+
104
104
  if (category === CATEGORY_CUSTOM || category == CATEGORY_CONSTELLATION) {
105
+ zip.addLocalFolder(srcDirectory, 'src/');
105
106
  zip.addLocalFile(configJson);
106
107
  }
107
108
  else {
@@ -112,7 +113,9 @@ export const zipComponent = async (componentKey, category = CATEGORY_CUSTOM) =>
112
113
 
113
114
  }
114
115
 
115
- zip.addLocalFolder(buildDirectory);
116
+ if (category === CATEGORY_CUSTOM || category === CATEGORY_CONSTELLATION) {
117
+ zip.addLocalFolder(buildDirectory);
118
+ }
116
119
  const zipContent = zip.toBuffer().toString('base64');
117
120
 
118
121
  let configContent = "{ }";
@@ -149,12 +152,26 @@ export const zipComponent = async (componentKey, category = CATEGORY_CUSTOM) =>
149
152
  };
150
153
 
151
154
  export const publishComponentToServer = async data => {
152
- const { configContent, zipContent, componentKey, rulesetName, rulesetVersion } = data;
155
+ const { configContent, zipContent, rulesetName, rulesetVersion } = data;
156
+ let { componentKey } = data;
157
+
158
+
159
+ if (componentKey.indexOf("/") >=0) {
160
+ const arKey = componentKey.split("/");
161
+ componentKey = arKey[arKey.length - 1];
162
+ }
163
+
164
+ const configContentObj = JSON.parse(configContent);
165
+
166
+ if (configContentObj.type == null || configContentObj.subtype == null) {
167
+ console.log(chalk.bold.yellow(`No config-ext to publish for ${componentKey}`));
168
+ return;
169
+ }
153
170
 
154
171
  const apiBody = {
155
172
  configContent,
156
173
  zipContent,
157
- componentKey: JSON.parse(configContent).componentKey,
174
+ componentKey: configContentObj.componentKey,
158
175
  publishFor: 'constellation',
159
176
  rulesetName,
160
177
  rulesetVersion,
@@ -128,17 +128,15 @@ export default async options => {
128
128
  title: 'Zip Component',
129
129
  task: async () => {
130
130
  const output = await zipComponent(componentKey, category);
131
- content = { ...content, ...output };
131
+ content = { ...content, ...output, componentKey };
132
132
  }
133
- }
134
- /*
133
+ },
135
134
  {
136
135
  title: 'Publish component',
137
136
  task: async () => {
138
137
  await publishComponentToServer(content);
139
138
  }
140
139
  }
141
- */
142
140
  ],
143
141
  {
144
142
  exitOnError: true
@@ -167,7 +167,145 @@ const schema = {
167
167
  additionalProperties: true
168
168
  };
169
169
 
170
+ const overrideSchema = {
171
+ type: 'object',
172
+ properties: {
173
+ baseComponentName: { type: 'string' },
174
+ componentKey: { type: 'string', pattern: '^[A-Za-z0-9]+$' },
175
+ name: { type: 'string', pattern: '^[A-Za-z0-9]+$' },
176
+ label: { type: 'string' },
177
+ description: { type: 'string' },
178
+ organization: { type: 'string' },
179
+ version: { type: 'string' },
180
+ library: { type: 'string' },
181
+ allowedApplications: { type: 'array' },
182
+ type: { type: 'string', enum: COMPONENT_SCHEMA.type.map(({ value }) => value) },
183
+ subtype: {
184
+ anyOf: [{ type: 'string' }, { type: 'array' }],
185
+
186
+ enum: allowedSubtypes
187
+ },
188
+ icon: { type: 'string' },
189
+ properties: {
190
+ type: 'array',
191
+ uniqueItems: true,
192
+ items: {
193
+ anyOf: [
194
+ {
195
+ type: 'object',
196
+ properties: {
197
+ name: { type: 'string' },
198
+ label: { type: 'string' },
199
+ format: { type: 'string' }
200
+ },
201
+ required: ['name', 'label', 'format']
202
+ },
203
+ {
204
+ type: 'object',
205
+ properties: {
206
+ format: { type: 'string' },
207
+ source: {
208
+ type: 'object',
209
+ properties: {
210
+ name: { type: 'string' },
211
+ label: { type: 'string' },
212
+ format: { type: 'string' }
213
+ },
214
+ required: ['name', 'label', 'format']
215
+ },
216
+ cascadeElements: {
217
+ type: 'array',
218
+ uniqueItems: true,
219
+ items: {
220
+ anyOf: [
221
+ {
222
+ type: 'object',
223
+ properties: {
224
+ key: { type: 'string'},
225
+ name: { type: 'string' },
226
+ label: { type: 'string' },
227
+ format: { type: 'string' }
228
+ },
229
+ required: ['key','name', 'label', 'format']
230
+ }
231
+ ]
232
+ }
233
+ },
234
+ },
235
+ required: ['format']
236
+ },
237
+ {
238
+ type: 'object',
239
+ properties: {
240
+ label: { type: 'string' },
241
+ format: { type: 'string' },
242
+ properties: {
243
+ type: 'array',
244
+ uniqueItems: true,
245
+ items: {
246
+ anyOf: [
247
+ {
248
+ type: 'object',
249
+ properties: {
250
+ name: { type: 'string' },
251
+ label: { type: 'string' },
252
+ format: { type: 'string' }
253
+ },
254
+ required: ['name', 'label', 'format']
255
+ },
256
+ {
257
+ type: 'object',
258
+ properties: {
259
+ variant: { type: 'string' },
260
+ label: { type: 'string' },
261
+ format: { type: 'string' }
262
+ },
263
+ required: ['variant', 'label', 'format']
264
+ },
265
+ {
266
+ type: 'object',
267
+ properties: {
268
+ format: { type: 'string' },
269
+ elements: {
270
+ type: 'array',
271
+ uniqueItems: true,
272
+ items: {
273
+ anyOf: [
274
+ {
275
+ type: 'object',
276
+ properties: {
277
+ key: { type: 'string' },
278
+ name: { type: 'string' },
279
+ label: { type: 'string' },
280
+ format: { type: 'string' },
281
+ variant: { type: 'string' }
282
+ },
283
+ required: ['key', 'format', 'label']
284
+ }
285
+ ]
286
+ }
287
+ }
288
+ },
289
+ required: ['format', 'elements']
290
+ },
291
+ ]
292
+ }
293
+ }
294
+
295
+ },
296
+ required: ['label', 'format'],
297
+ }
298
+ ]
299
+ }
300
+ },
301
+ defaultConfig: { type: 'object' }
302
+ },
303
+ required: ['componentKey', 'name', 'description', 'type', 'subtype', 'properties'],
304
+ additionalProperties: true
305
+ };
306
+
170
307
  const validateSchema = ajv.compile(schema);
308
+ const validateOverideSchema = ajv.compile(overrideSchema);
171
309
 
172
310
 
173
311
 
@@ -192,7 +330,11 @@ export default async (option, category = CATEGORY_CUSTOM) => {
192
330
  }
193
331
 
194
332
  const componentDirectory = await getComponentDirectoryPath(componentToValidate, category);
195
- const configFile = path.join(componentDirectory, 'config.json');
333
+ let configFileName = "config.json";
334
+ if (category === CATEGORY_OVERRIDE) {
335
+ configFileName = "config-ext.json";
336
+ }
337
+ const configFile = path.join(componentDirectory, configFileName);
196
338
  let configData;
197
339
  try {
198
340
  configData = fs.readFileSync(path.resolve(configFile), 'utf8');
@@ -211,23 +353,27 @@ export default async (option, category = CATEGORY_CUSTOM) => {
211
353
  //const data = JSON.parse(fs.readFileSync(path.resolve(configFile), 'utf8'));
212
354
  const data = JSON.parse(configData);
213
355
 
214
- const valid = validateSchema(data);
356
+ const valid = (category === CATEGORY_OVERRIDE) ? validateOverideSchema(data) : validateSchema(data);
215
357
 
216
358
  if (valid) {
217
359
 
218
360
  // need to remove path
219
361
  componentToValidate = removeComponentPrefix(componentToValidate);
220
362
 
221
- if (
222
- componentToValidate &&
223
- !/^[A-Za-z0-9]+_[A-Za-z0-9]+_[A-Za-z0-9]+$/.test(componentToValidate)
224
- ) {
225
- const ootbComponents = await getOOTBComponents();
226
- if (ootbComponents.includes(componentToValidate)) {
227
- throw new Error(`Invalid: Error occurred in validating ${componentToValidate}`);
363
+ // don't check for out the box if override
364
+ if (category != CATEGORY_OVERRIDE) {
365
+ if (
366
+ componentToValidate &&
367
+ !/^[A-Za-z0-9]+_[A-Za-z0-9]+_[A-Za-z0-9]+$/.test(componentToValidate)
368
+ ) {
369
+ const ootbComponents = await getOOTBComponents();
370
+ if (ootbComponents.includes(componentToValidate)) {
371
+ throw new Error(`Invalid: Error occurred in validating ${componentToValidate}`);
372
+ }
228
373
  }
229
374
  }
230
375
 
376
+
231
377
  console.log(`${chalk.bold.green(componentToValidate)} schema is valid`);
232
378
  } else {
233
379
  throw new Error(`Invalid: ${ajv.errorsText(validateSchema.errors)}`);
package/src/util.js CHANGED
@@ -36,7 +36,8 @@ import {
36
36
  COMPONENT_PREFIX_DSE_PATH,
37
37
  COMPONENT_PREFIX_INFRA_PATH,
38
38
  CATEGORY_CUSTOM,
39
- CATEGORY_OVERRIDE
39
+ CATEGORY_OVERRIDE,
40
+ CATEGORY_CONSTELLATION
40
41
  } from './constants.js';
41
42
 
42
43
 
@@ -172,6 +173,7 @@ export const getComponents = async (showSeparator = false, category = CATEGORY_C
172
173
 
173
174
  switch (category) {
174
175
  case CATEGORY_CUSTOM:
176
+ case CATEGORY_CONSTELLATION:
175
177
  const fieldComps = await getSubComponents(directory, FIELD_PATH);
176
178
  const templateComps = await getSubComponents(directory, TEMPLATE_PATH);
177
179
  const widgetComps = await getSubComponents(directory, WIDGET_PATH);