@pega/dx-component-builder-sdk 0.1.26 → 0.1.27

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.
Files changed (29) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +6 -0
  3. package/src/constants.js +30 -1
  4. package/src/tasks/create/templates/SDK-React/field/Boolean/index.tsx.mustache +14 -2
  5. package/src/tasks/create/templates/SDK-React/field/Date/demo.stories.jsx.mustache +13 -0
  6. package/src/tasks/create/templates/SDK-React/field/Date/index.tsx.mustache +26 -11
  7. package/src/tasks/create/templates/SDK-React/field/DateTime/demo.stories.jsx.mustache +12 -0
  8. package/src/tasks/create/templates/SDK-React/field/DateTime/index.tsx.mustache +32 -12
  9. package/src/tasks/create/templates/SDK-React/field/Decimal/index.tsx.mustache +9 -7
  10. package/src/tasks/create/templates/SDK-React/field/Decimal-Currency/demo.stories.jsx.mustache +3 -0
  11. package/src/tasks/create/templates/SDK-React/field/Decimal-Currency/index.tsx.mustache +29 -8
  12. package/src/tasks/create/templates/SDK-React/field/Decimal-Percentage/index.tsx.mustache +10 -8
  13. package/src/tasks/create/templates/SDK-React/field/Integer/index.tsx.mustache +10 -7
  14. package/src/tasks/create/templates/SDK-React/field/Picklist/index.tsx.mustache +16 -6
  15. package/src/tasks/create/templates/SDK-React/field/Text/index.tsx.mustache +9 -7
  16. package/src/tasks/create/templates/SDK-React/field/Text-Email/index.tsx.mustache +9 -9
  17. package/src/tasks/create/templates/SDK-React/field/Text-Input/index.tsx.mustache +9 -7
  18. package/src/tasks/create/templates/SDK-React/field/Text-Paragraph/index.tsx.mustache +9 -7
  19. package/src/tasks/create/templates/SDK-React/field/Text-Phone/index.tsx.mustache +9 -9
  20. package/src/tasks/create/templates/SDK-React/field/Text-URL/index.tsx.mustache +9 -7
  21. package/src/tasks/create/templates/SDK-React/field/TimeofDay/index.tsx.mustache +7 -5
  22. package/src/tasks/create/templates/SDK-React/widget/CASE/index.tsx.mustache +0 -6
  23. package/src/tasks/create/templates/SDK-React/widget/PAGE/index.tsx.mustache +0 -1
  24. package/src/tasks/create/templates/SDK-React/widget/PAGE-CASE/demo.stories.jsx.mustache +1 -8
  25. package/src/tasks/create/templates/SDK-React/widget/PAGE-CASE/index.tsx.mustache +14 -42
  26. package/src/tasks/create-all/index.js +456 -0
  27. package/src/tasks/delete-all/helper.js +8 -10
  28. package/src/tasks/index.js +1 -0
  29. package/src/tasks/linter/index.js +55 -30
@@ -0,0 +1,456 @@
1
+ import path from 'path';
2
+ import { URL, fileURLToPath } from 'url';
3
+ import fs from 'fs';
4
+ import { promisify } from 'util';
5
+ import { join } from 'path';
6
+
7
+ import inquirer from 'inquirer';
8
+ import ncp from 'ncp';
9
+ import chalk from 'chalk';
10
+
11
+ import { checkPathAccess, showVersion } from '../../util.js';
12
+ import { CATEGORY_CONSTELLATION,
13
+ SDK_CONFIG_JSON_FILENAME,
14
+ DXCB_CONFIG,
15
+ DXCB_COMPONENT_DEFAULTS,
16
+ CUSTOM_TEMPLATES,
17
+ CUSTOM_TEMPLATE_PATH } from '../../constants.js';
18
+
19
+
20
+
21
+ export const DXCB_CONFIG_INTERNAL_JSON_FILENAME = 'src/dxcb.config.json';
22
+
23
+ const pegaConfigJsonPath = path.join(path.resolve(), SDK_CONFIG_JSON_FILENAME);
24
+ const pegaConfigInternalJsonPath = path.join(path.resolve(), DXCB_CONFIG_INTERNAL_JSON_FILENAME);
25
+
26
+ import {
27
+ convertIntoPascalCase,
28
+ compileMustacheTemplate,
29
+ getComponentDirectoryPath,
30
+ getPegaConfig,
31
+ getComponents,
32
+ getComponentDefaults,
33
+ sanitize,
34
+ validateSemver
35
+ } from '../../util.js';
36
+ import { COMPONENT_SCHEMA } from '../../constants.js';
37
+
38
+ const copy = promisify(ncp);
39
+
40
+ const copyComponentTemplate = async options => {
41
+ if (options.targetDirectory) {
42
+ return copy(options.templateDirectory, options.targetDirectory, {
43
+ clobber: false
44
+ });
45
+ }
46
+ else {
47
+ return copy(options.templateDirectoryConstellation, options.targetDirectoryConstellation, {
48
+ clobber: false,
49
+ filter: (fileName) => {
50
+ // filter out the file config.json or config.json.mustache
51
+ if (fileName.indexOf("config.json") >= 0) return false;
52
+ else return true;
53
+ }
54
+ });
55
+ }
56
+
57
+ };
58
+
59
+ export const compileMustacheTemplates = async (
60
+ componentDirectory,
61
+ {
62
+ componentKey,
63
+ componentName,
64
+ componentLabel,
65
+ library,
66
+ version,
67
+ type,
68
+ subtype,
69
+ description,
70
+ organization,
71
+ allowedApplications
72
+ }
73
+ ) => {
74
+ const files = fs.readdirSync(componentDirectory);
75
+ const componentClassName = convertIntoPascalCase(componentKey);
76
+
77
+ const isTemplate = type === 'Template';
78
+ const isPicklist = subtype === 'Picklist';
79
+ const isBool = subtype === 'Boolean';
80
+ const isPhone = subtype === 'Phone';
81
+
82
+ if (Array.isArray(subtype) && subtype.length === 1) {
83
+ subtype = subtype.toString();
84
+ }
85
+
86
+ let mustacheSubType = subtype;
87
+
88
+ // overrides
89
+ if (typeof(mustacheSubType) == "string") {
90
+ switch (mustacheSubType) {
91
+ case "FORM-region" :
92
+ mustacheSubType = "FORM";
93
+ break;
94
+ case "DETAILS-region" :
95
+ mustacheSubType = "DETAILS";
96
+ break;
97
+ case "Text-Input" :
98
+ mustacheSubType = "Text";
99
+ break;
100
+ }
101
+
102
+ }
103
+
104
+ if (allowedApplications.trim() === '') {
105
+ allowedApplications = [];
106
+ } else {
107
+ if (allowedApplications.indexOf(',') !== -1) {
108
+ allowedApplications = allowedApplications.split(',');
109
+ }
110
+ allowedApplications = [].concat(allowedApplications);
111
+ }
112
+
113
+ allowedApplications = allowedApplications.filter(el => !!el.trim()).map(el => el.trim());
114
+ files.forEach(file => {
115
+ const filePath = path.join(componentDirectory, file);
116
+
117
+ const output = compileMustacheTemplate(filePath, {
118
+ COMPONENT_KEY: componentKey,
119
+ COMPONENT_NAME: componentName,
120
+ COMPONENT_LABEL: componentLabel,
121
+ COMPONENT_CLASS_NAME: componentClassName,
122
+ ORGANIZATION: organization,
123
+ VERSION: version,
124
+ LIBRARY: library,
125
+ ALLOWEDAPPS: JSON.stringify(allowedApplications),
126
+ TYPE: type,
127
+ SUB_TYPE: JSON.stringify(mustacheSubType),
128
+ DESCRIPTION: description || componentLabel,
129
+ IS_TEMPLATE: isTemplate,
130
+ IS_PICKLIST: isPicklist,
131
+ IS_BOOLEAN: isBool,
132
+ IS_PHONE: isPhone
133
+ });
134
+ fs.writeFileSync(filePath, output);
135
+ fs.renameSync(filePath, filePath.replace('.mustache', ''));
136
+ });
137
+ };
138
+
139
+
140
+ export const validateCompileAll = async (
141
+ {
142
+ prefix,
143
+ library,
144
+ version,
145
+ allowedApplications,
146
+ organization
147
+ },
148
+ options,
149
+ onlyCompanion = false
150
+
151
+ ) => {
152
+
153
+
154
+ for (let fieldIdx in COMPONENT_SCHEMA.subtype.field) {
155
+ const type = "Field";
156
+ const subtype = COMPONENT_SCHEMA.subtype.field[fieldIdx].value;
157
+ const prefixNoSpace = prefix.replace(/\s+/g, '');
158
+ const componentName = "".concat(prefixNoSpace).concat(COMPONENT_SCHEMA.subtype.field[fieldIdx].name);
159
+ const componentLabel = "".concat(prefix).concat(" ").concat(COMPONENT_SCHEMA.subtype.field[fieldIdx].name);
160
+ const description = componentLabel;
161
+
162
+ await validateCompile(
163
+ {
164
+ library,
165
+ organization,
166
+ componentName,
167
+ componentLabel,
168
+ version,
169
+ type,
170
+ subtype,
171
+ description,
172
+ allowedApplications
173
+ },
174
+ options
175
+ )
176
+ }
177
+
178
+ for (let templateIdx in COMPONENT_SCHEMA.subtype.template) {
179
+ const type = "Template";
180
+ const subtype = COMPONENT_SCHEMA.subtype.template[templateIdx].value;
181
+ const prefixNoSpace = prefix.replace(/\s+/g, '');
182
+ let templateName = convertIntoPascalCase(COMPONENT_SCHEMA.subtype.template[templateIdx].name);
183
+ let templateLabel = convertIntoPascalCase(COMPONENT_SCHEMA.subtype.template[templateIdx].name);
184
+ if (templateName.indexOf("region") >= 0) {
185
+ templateName = templateName.replace(" region", "");
186
+ templateName = "TwoColumn".concat(templateName);
187
+ templateLabel = "Two Column".concat(templateName);
188
+ }
189
+ const componentName = "".concat(prefixNoSpace).concat(templateName);
190
+ const componentLabel = "".concat(prefix).concat(" ").concat(templateLabel);
191
+ const description = componentLabel;
192
+
193
+ await validateCompile(
194
+ {
195
+ library,
196
+ organization,
197
+ componentName,
198
+ componentLabel,
199
+ version,
200
+ type,
201
+ subtype,
202
+ description,
203
+ allowedApplications
204
+ },
205
+ options
206
+ )
207
+ }
208
+
209
+
210
+ for (let widgetIdx in COMPONENT_SCHEMA.subtype.widget) {
211
+ const type = "Widget";
212
+ const subtype = COMPONENT_SCHEMA.subtype.widget[widgetIdx].value;
213
+ const prefixNoSpace = prefix.replace(/\s+/g, '');
214
+ let widgetName = convertIntoPascalCase(COMPONENT_SCHEMA.subtype.widget[widgetIdx].name).concat("Widget");
215
+ let widgetLabel = convertIntoPascalCase(COMPONENT_SCHEMA.subtype.widget[widgetIdx].name).concat(" Widget");
216
+ if (widgetName.indexOf("&") >= 0) {
217
+ widgetName = widgetName.replace(" & ", "");
218
+ }
219
+ const componentName = "".concat(prefixNoSpace).concat(widgetName);
220
+ const componentLabel = "".concat(prefix).concat(" ").concat(widgetLabel);
221
+ const description = componentLabel;
222
+
223
+ await validateCompile(
224
+ {
225
+ library,
226
+ organization,
227
+ componentName,
228
+ componentLabel,
229
+ version,
230
+ type,
231
+ subtype,
232
+ description,
233
+ allowedApplications
234
+ },
235
+ options
236
+ )
237
+ }
238
+
239
+
240
+ }
241
+
242
+
243
+ export const validateCompile = async (
244
+ {
245
+ library,
246
+ organization,
247
+ componentName,
248
+ componentLabel,
249
+ version,
250
+ framework,
251
+ type,
252
+ subtype,
253
+ description,
254
+ allowedApplications
255
+ },
256
+ options,
257
+ onlyCompanion = false
258
+ ) => {
259
+
260
+ let sSubType = subtype;
261
+ if (Array.isArray(subtype)) {
262
+ sSubType = subtype.join("-");
263
+ }
264
+
265
+ const typeLC = type.toLowerCase();
266
+
267
+ await checkPathAccess(pegaConfigInternalJsonPath);
268
+
269
+ let internalData = fs.readFileSync(pegaConfigInternalJsonPath, { encoding: 'utf8' });
270
+ internalData = internalData && JSON.parse(internalData);
271
+
272
+ framework = internalData.sdkType;
273
+
274
+ let pegaConfig = await getPegaConfig();
275
+ let templateParentDir = `./templates/${framework}`;
276
+ if (pegaConfig[DXCB_CONFIG] &&
277
+ pegaConfig[DXCB_CONFIG][CUSTOM_TEMPLATES] &&
278
+ pegaConfig[DXCB_CONFIG][CUSTOM_TEMPLATES][CUSTOM_TEMPLATE_PATH] &&
279
+ pegaConfig[DXCB_CONFIG][CUSTOM_TEMPLATES][CUSTOM_TEMPLATE_PATH] != "") {
280
+ templateParentDir = pegaConfig[DXCB_CONFIG][CUSTOM_TEMPLATES][CUSTOM_TEMPLATE_PATH];
281
+ }
282
+
283
+ const templateDir = `${templateParentDir}/${typeLC}/${sSubType}`;
284
+ let templateDirectory = fileURLToPath(new URL(templateDir, import.meta.url));
285
+ templateDirectory = templateDirectory.replace("/create-all", "/create");
286
+
287
+ const templateDirConstellation = `./templates/Constellation/${typeLC}/${sSubType}`;
288
+ let templateDirectoryConstellation = fileURLToPath(new URL(templateDirConstellation, import.meta.url));
289
+ templateDirectoryConstellation = templateDirectoryConstellation.replace("/create-all", "/create");
290
+
291
+ const componentKey = `${organization}_${library}_${componentName}`;
292
+
293
+
294
+ const targetDirectory = await getComponentDirectoryPath(join(typeLC, "/",componentKey));
295
+ const targetDirectoryConstellation = await getComponentDirectoryPath(join(typeLC, "/",componentKey), CATEGORY_CONSTELLATION);
296
+
297
+ const components = await getComponents(false);
298
+
299
+ if (!onlyCompanion) {
300
+ if (components.includes(componentKey)) {
301
+ console.log(chalk.red(`${componentKey} component already exists in ${targetDirectory}`));
302
+
303
+ let componentsConstellation = await getComponents(false, CATEGORY_CONSTELLATION);
304
+ if (components.includes(componentKey)) {
305
+ console.log(chalk.red(`${componentKey} companion component already exists in ${targetDirectoryConstellation}`));
306
+ }
307
+
308
+ return;
309
+ }
310
+ // test for constellation
311
+ const componentsConstellation = await getComponents(false, CATEGORY_CONSTELLATION);
312
+ if (componentsConstellation.includes(componentKey)) {
313
+ console.log(chalk.red(`${componentKey} companion component already exists in ${targetDirectoryConstellation}`));
314
+ return;
315
+ }
316
+ }
317
+ else {
318
+ // test for constellation
319
+ const componentsConstellation = await getComponents(false, CATEGORY_CONSTELLATION);
320
+ if (componentsConstellation.includes(componentKey)) {
321
+ console.log(chalk.red(`${componentKey} companion component already exists in ${targetDirectoryConstellation}`));
322
+ return;
323
+ }
324
+ }
325
+
326
+
327
+ if (!onlyCompanion) {
328
+ // component
329
+ await copyComponentTemplate({
330
+ ...options,
331
+ targetDirectory,
332
+ templateDirectory
333
+ });
334
+ await compileMustacheTemplates(targetDirectory, {
335
+ componentKey,
336
+ componentName,
337
+ componentLabel,
338
+ library,
339
+ version,
340
+ type,
341
+ subtype,
342
+ description,
343
+ organization,
344
+ allowedApplications
345
+ });
346
+ }
347
+
348
+ // matching constellation
349
+ await copyComponentTemplate({
350
+ ...options,
351
+ targetDirectoryConstellation,
352
+ templateDirectoryConstellation
353
+ });
354
+ await compileMustacheTemplates(targetDirectoryConstellation, {
355
+ componentKey,
356
+ componentName,
357
+ componentLabel,
358
+ library,
359
+ version,
360
+ type,
361
+ subtype,
362
+ description,
363
+ organization,
364
+ allowedApplications
365
+ });
366
+
367
+ if (!onlyCompanion) {
368
+ console.log(chalk.green(`created ${componentKey} component in ${targetDirectory}`));
369
+ }
370
+
371
+ console.log(chalk.green(`created ${componentKey} companion component in ${targetDirectoryConstellation}`));
372
+
373
+ };
374
+
375
+ export default async options => {
376
+ showVersion();
377
+
378
+ await checkPathAccess(pegaConfigJsonPath);
379
+
380
+ let data = fs.readFileSync(pegaConfigJsonPath, { encoding: 'utf8' });
381
+ data = data && JSON.parse(data);
382
+
383
+ if (!data[DXCB_CONFIG] || !data[DXCB_CONFIG][DXCB_COMPONENT_DEFAULTS]) {
384
+ console.error(
385
+ `${chalk.red.bold('ERROR')} Could not able find component defaults in config.json`
386
+ );
387
+ process.exit(1);
388
+ }
389
+
390
+ const componentData = data[DXCB_CONFIG][DXCB_COMPONENT_DEFAULTS];
391
+
392
+ const { organization, library} = componentData;
393
+
394
+ let componentDefaults = await getComponentDefaults();
395
+ componentDefaults.library = library;
396
+
397
+
398
+ const questions = [
399
+ {
400
+ name: 'prefix',
401
+ message: 'Enter prefix label'
402
+ },
403
+ {
404
+ name: 'version',
405
+ message: 'Enter component version',
406
+ default: componentDefaults.version,
407
+ validate: value => {
408
+ if (validateSemver(value)) {
409
+ return true;
410
+ }
411
+ return 'Please provide semver compatible version e.g 0.0.1';
412
+ }
413
+ },
414
+ {
415
+ name: 'library',
416
+ message: 'Enter library name (required)',
417
+ default: componentDefaults.library,
418
+ validate: value => {
419
+ /* value should not be empty
420
+ It should not have spaces
421
+ It should not start with a number
422
+ Only case-insensitive alphanumeric values are allowed
423
+ */
424
+ if (value && !/^\d/.test(value) && value === sanitize(value)) {
425
+ return true;
426
+ }
427
+ return 'Only alphanumeric values are allowed, starting with alphabets';
428
+ }
429
+ },
430
+ {
431
+ name: 'allowedApplications',
432
+ message: 'Please enter the application names to be supported (comma-separated). ',
433
+ suffix: 'Keep empty for all applications'
434
+ }
435
+ ];
436
+
437
+ await inquirer.prompt(questions).then(async answers => {
438
+ const {
439
+ prefix,
440
+ library,
441
+ version,
442
+ allowedApplications
443
+ } = answers;
444
+ await validateCompileAll(
445
+ {
446
+ prefix,
447
+ library,
448
+ version,
449
+ allowedApplications,
450
+ organization
451
+ },
452
+ options
453
+ );
454
+ });
455
+
456
+ };
@@ -76,20 +76,18 @@ export const deleteLocalComponents = async (sourceOfComponents, category = CATEG
76
76
  if (localComponents[index].type == undefined) {
77
77
  var componentToDelete = localComponents[index].value;
78
78
  await deleteLocalComponent(componentToDelete, category);
79
- if (category === "custom") {
79
+ if (category === CATEGORY_CUSTOM) {
80
80
  await deleteLocalComponent(componentToDelete, CATEGORY_CONSTELLATION);
81
81
  }
82
82
 
83
- if (category === CATEGORY_OVERRIDE) {
84
- // need to remove the map as well
85
- if (componentToDelete != undefined) {
86
- await deleteFromComponentMap(componentToDelete, category);
87
- }
88
- else {
89
- console.log(chalk.bold.redBright(`No component in map: ` + componentToDelete));
90
- }
91
-
83
+ // need to remove the map as well
84
+ if (componentToDelete != undefined) {
85
+ await deleteFromComponentMap(componentToDelete, category);
92
86
  }
87
+ else {
88
+ console.log(chalk.bold.redBright(`No component in map: ` + componentToDelete));
89
+ }
90
+
93
91
  }
94
92
 
95
93
  }
@@ -1,4 +1,5 @@
1
1
  export { default as createComponent } from './create/index.js';
2
+ export { default as createAllComponents } from './create-all/index.js';
2
3
  export { default as overrideComponent } from './override/index.js';
3
4
  export { default as overrideAllComponents } from './override-all/index.js';
4
5
  export { default as deleteComponent } from './delete/index.js';
@@ -1,46 +1,71 @@
1
1
  import { ESLint } from 'eslint';
2
2
  import chalk from 'chalk';
3
+ import { getPegaConfig } from '../../util.js'
4
+ import { DXCB_CONFIG, DXCB_COMPONENT_DEFAULTS, LINT_SETTING_KEY, LINT_OFF, LINT_SHOW, LINT_BLOCK, LINT_DEFAULT } from '../../constants.js';
5
+
6
+ // lintSettings immported from constants.js: a set of the expected values of lint setting from sdk-config.json
7
+ // LINT_OFF: don't run lint
8
+ // LINT_SHOW: run lint, show results, but don't block processing from continuing if there are lint errors/warnings
9
+ // LINT_BLOCK: run lint, show results, block processing from continuing if there are lint errors/warnings
10
+
11
+ const lintSettings = new Set([LINT_OFF, LINT_SHOW, LINT_BLOCK]);
3
12
 
4
13
  export const lintComponent = async (dirToLint) => {
5
- // console.log("in dx-component-builder-sdk: lintComponent - dirToLint: " + dirToLint);
6
- //console.log(chalk.green(` linting ${dirToLint}`));
14
+ // get setting from sdk-config. If not found or unexpected value, default to LINT_DEFAULT
15
+ const pegaConfig = await getPegaConfig();
16
+ let lintSetting = pegaConfig[DXCB_CONFIG][DXCB_COMPONENT_DEFAULTS][LINT_SETTING_KEY];
7
17
 
8
- // 1. Create an instance.
9
- const eslint = new ESLint();
18
+ // Check to see if lintSetting is an expected value. Show error if unexpected value encountered
19
+ if (!lintSettings?.has(lintSetting)) {
20
+ console.log(chalk.red(`Invalid or missing ${LINT_SETTING_KEY}: ${lintSetting}. Using \"${LINT_BLOCK}\".`));
21
+ lintSetting = LINT_DEFAULT;
22
+ }
10
23
 
11
- // 2. Lint files.
12
- const results = await eslint.lintFiles([dirToLint]);
24
+ // console.log("in dx-component-builder-sdk: lintComponent - dirToLint: " + dirToLint);
25
+ // console.log(chalk.green(` linting ${dirToLint} - setting: ${lintSetting}`));
13
26
 
14
- // 3. Format the results.
15
- const formatter = await eslint.loadFormatter("stylish");
16
- const resultText = formatter.format(results);
27
+ let resultText = undefined;
17
28
 
18
- // 4. Output it.
19
- // console.log(`lint resultText: ${resultText}`);
20
- console.log(resultText);
29
+ if (lintSetting !== LINT_OFF) {
30
+ // 1. Create an instance.
31
+ const eslint = new ESLint();
21
32
 
22
- // Indicate linting is complete
23
- //console.log(chalk.green(` linting complete...`));
24
- };
33
+ // 2. Lint file(s) .
34
+ const results = await eslint.lintFiles([dirToLint]);
25
35
 
26
- // inpsired by https://eslint.org/docs/latest/developer-guide/nodejs-api
36
+ // 3. Format results.
37
+ const formatter = await eslint.loadFormatter("stylish");
38
+ resultText = formatter.format(results);
27
39
 
28
- // (async function main() {
29
- // // 1. Create an instance.
30
- // const eslint = new ESLint();
40
+ // 4. Output results.
41
+ // console.log("lint results[");
42
+ // results.forEach(function (result) { console.log(JSON.stringify(result)) });
43
+ // console.log("]");
44
+ // console.log("lint resultText[" + resultText + "]");
31
45
 
32
- // // 2. Lint files.
33
- // const results = await eslint.lintFiles(["lib/**/*.js"]);
46
+ if (resultText.length > 0) {
47
+ if (lintSetting === LINT_SHOW) {
48
+ // Config setting says to allow processing to continue. So, show lint output but continue
49
+ console.log(chalk.yellow(` Lint: `));
50
+ console.log(`${resultText}`);
51
+ console.log(chalk.yellow(` Continuing...`));
52
+ } else {
53
+ // Config setting (at this point, assumed to be "block") says to NOT allow processing to continue.
54
+ // So, throw error!
55
+ console.log(chalk.red(` Lint errors/warnings. Processing blocked.`));
56
+ throw new Error( "Lint:\n" + resultText );
57
+ }
58
+ }
59
+ } else {
60
+ console.log(chalk.green(` Lint is off.`));
61
+ }
62
+ // Indicate linting is complete
63
+ if ((lintSetting !== LINT_OFF) && resultText) {
64
+ console.log(chalk.green(` linting complete...`));
65
+ }
34
66
 
35
- // // 3. Format the results.
36
- // const formatter = await eslint.loadFormatter("stylish");
37
- // const resultText = formatter.format(results);
67
+ };
38
68
 
39
- // // 4. Output it.
40
- // console.log(resultText);
41
- // })().catch((error) => {
42
- // process.exitCode = 1;
43
- // console.error(error);
44
- // });
69
+ // inspired by https://eslint.org/docs/latest/developer-guide/nodejs-api
45
70
 
46
71
  export default lintComponent;