@komaci/cli 244.1.4 → 244.1.7
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/build/cmds/analyze/index.d.ts +5 -0
- package/build/cmds/analyze/index.js +29 -0
- package/build/cmds/analyze/lib/analyzeBundle.d.ts +13 -0
- package/build/cmds/analyze/lib/analyzeBundle.js +38 -0
- package/build/cmds/analyze/lib/run.d.ts +7 -0
- package/build/cmds/analyze/lib/run.js +128 -0
- package/build/cmds/analyze/types.d.ts +8 -0
- package/build/cmds/analyze/types.js +2 -0
- package/build/cmds/index.d.ts +2 -1
- package/build/cmds/index.js +2 -1
- package/build/cmds/modgen/lib/readAndParseBundle.d.ts +0 -22
- package/build/cmds/modgen/lib/readAndParseBundle.js +2 -42
- package/build/index.js +2 -2
- package/build/lib/collectBundle.d.ts +23 -0
- package/build/lib/collectBundle.js +43 -0
- package/package.json +5 -3
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { run } from './lib/run.js';
|
|
2
|
+
export default {
|
|
3
|
+
name: 'analyze',
|
|
4
|
+
alias: 'a',
|
|
5
|
+
options: [
|
|
6
|
+
{
|
|
7
|
+
name: 'paths',
|
|
8
|
+
alias: 'p',
|
|
9
|
+
multiple: true,
|
|
10
|
+
type: String,
|
|
11
|
+
required: true,
|
|
12
|
+
defaultOption: true,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: 'bundleType',
|
|
16
|
+
alias: 't',
|
|
17
|
+
type: String,
|
|
18
|
+
defaultValue: 'internal',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'raw',
|
|
22
|
+
alias: 'r',
|
|
23
|
+
type: Boolean,
|
|
24
|
+
defaultValue: false,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
run,
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PrimingDiagnostic } from '@komaci/static-analyzer';
|
|
2
|
+
export declare type AnalyzeOutput = {
|
|
3
|
+
files: Record<string, string>;
|
|
4
|
+
diagnostics: PrimingDiagnostic[];
|
|
5
|
+
};
|
|
6
|
+
export declare function collectGlobbedModulePaths(globPath: string): string[];
|
|
7
|
+
/**
|
|
8
|
+
* Takes the directory path of an LWC module bundle. Returns the priming diagnostics for the given bundle.
|
|
9
|
+
* @param path
|
|
10
|
+
* @returns PrimingDiagnostics for the bundle
|
|
11
|
+
*/
|
|
12
|
+
export declare function analyzeBundle(path: string): AnalyzeOutput;
|
|
13
|
+
//# sourceMappingURL=analyzeBundle.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { basename, dirname } from 'path';
|
|
2
|
+
import { generatePrimingDiagnosticsModule } from '@komaci/static-analyzer';
|
|
3
|
+
import { readBundle } from '../../../lib/collectBundle.js';
|
|
4
|
+
import glob from 'glob';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
export function collectGlobbedModulePaths(globPath) {
|
|
7
|
+
return glob.sync(globPath).filter((path) => {
|
|
8
|
+
const info = fs.statSync(path);
|
|
9
|
+
return info.isDirectory();
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Takes the directory path of an LWC module bundle. Returns the priming diagnostics for the given bundle.
|
|
14
|
+
* @param path
|
|
15
|
+
* @returns PrimingDiagnostics for the bundle
|
|
16
|
+
*/
|
|
17
|
+
export function analyzeBundle(path) {
|
|
18
|
+
const files = readBundle(path);
|
|
19
|
+
const name = basename(path);
|
|
20
|
+
const namespace = basename(dirname(path));
|
|
21
|
+
const filesMap = {};
|
|
22
|
+
files.forEach((value) => {
|
|
23
|
+
const fileName = value.fileName.substring(value.fileName.lastIndexOf('/') + 1);
|
|
24
|
+
filesMap[fileName] = value.source;
|
|
25
|
+
});
|
|
26
|
+
const analyzerInput = {
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
type: 'bundle',
|
|
29
|
+
name,
|
|
30
|
+
namespace,
|
|
31
|
+
files: filesMap,
|
|
32
|
+
};
|
|
33
|
+
return {
|
|
34
|
+
diagnostics: generatePrimingDiagnosticsModule(analyzerInput),
|
|
35
|
+
files: filesMap,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=analyzeBundle.js.map
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import logger from '../../../lib/log.js';
|
|
2
|
+
import { analyzeBundle, collectGlobbedModulePaths } from './analyzeBundle.js';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import glob from 'glob';
|
|
5
|
+
const { log, warn } = logger;
|
|
6
|
+
/**
|
|
7
|
+
* Runs the analyze command with the given Command Options.
|
|
8
|
+
* @param cmdOptions
|
|
9
|
+
*/
|
|
10
|
+
export function run(cmdOptions) {
|
|
11
|
+
const { paths = [] } = cmdOptions;
|
|
12
|
+
if (paths.length) {
|
|
13
|
+
let hasDiagnostics = false;
|
|
14
|
+
const inflatedPaths = [];
|
|
15
|
+
paths.forEach((path) => {
|
|
16
|
+
if (glob.hasMagic(path)) {
|
|
17
|
+
collectGlobbedModulePaths(path).forEach((inflatedPath) => inflatedPaths.push(inflatedPath));
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
inflatedPaths.push(path);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
const parsedBundles = inflatedPaths.map((path) => analyzeBundle(path));
|
|
24
|
+
for (let i = 0; i < parsedBundles.length; i++) {
|
|
25
|
+
printOutput(cmdOptions, parsedBundles[i], inflatedPaths[i]);
|
|
26
|
+
hasDiagnostics = hasDiagnostics || parsedBundles[i].diagnostics.length > 0;
|
|
27
|
+
}
|
|
28
|
+
if (hasDiagnostics) {
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
warn('Please provide 1 or more paths to a LWC bundle directory.');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* do a bunch of fancy parsing on the file to output in a format that matches eslint or produces the raw json files
|
|
38
|
+
* @param cmdOptions
|
|
39
|
+
* @param toPrint
|
|
40
|
+
*/
|
|
41
|
+
function printOutput(cmdOptions, parsedBundle, basePath) {
|
|
42
|
+
const { raw } = cmdOptions;
|
|
43
|
+
if (raw) {
|
|
44
|
+
log(JSON.stringify(parsedBundle, null, 2));
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
log(chalk.bold(`Diagnostics for ${basePath}:`));
|
|
48
|
+
if (parsedBundle.diagnostics.length === 0) {
|
|
49
|
+
log('No failures found 🎉');
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
let currentFilename = '';
|
|
53
|
+
let currentFileLines = [];
|
|
54
|
+
for (const diagnostic of parsedBundle.diagnostics) {
|
|
55
|
+
let message = '';
|
|
56
|
+
if (diagnostic.code?.target &&
|
|
57
|
+
diagnostic.code?.target.path !== currentFilename) {
|
|
58
|
+
currentFilename = diagnostic.code?.target.path;
|
|
59
|
+
if (parsedBundle.files[currentFilename]) {
|
|
60
|
+
currentFileLines = parsedBundle.files[currentFilename].split('\n');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
message += chalk.cyan(`${currentFilename}:`);
|
|
64
|
+
message += `${message === '' ? ':' : ''}${chalk.gray(diagnostic.range.start.line)}:${chalk.gray(diagnostic.range.start.character)} `;
|
|
65
|
+
let underlineHighlight = chalk.whiteBright;
|
|
66
|
+
if (diagnostic.severity === 'error') {
|
|
67
|
+
message += `- ${chalk.red('error')} `;
|
|
68
|
+
underlineHighlight = chalk.redBright;
|
|
69
|
+
}
|
|
70
|
+
else if (diagnostic.severity === 'warning') {
|
|
71
|
+
message += `- ${chalk.yellow('warning')} `;
|
|
72
|
+
underlineHighlight = chalk.yellowBright;
|
|
73
|
+
}
|
|
74
|
+
else if (diagnostic.severity === 'info') {
|
|
75
|
+
message += `- ${chalk.white('info')} `;
|
|
76
|
+
}
|
|
77
|
+
if (diagnostic.code && diagnostic.code.value) {
|
|
78
|
+
message += `${diagnostic.code.value}: `;
|
|
79
|
+
}
|
|
80
|
+
else if (diagnostic.code) {
|
|
81
|
+
message += `${diagnostic.code}: `;
|
|
82
|
+
}
|
|
83
|
+
message += diagnostic.message;
|
|
84
|
+
if (currentFileLines.length > 0) {
|
|
85
|
+
message += '\n';
|
|
86
|
+
for (let i = diagnostic.range.start.line; i <= diagnostic.range.end.line && i < currentFileLines.length; i++) {
|
|
87
|
+
message += `${chalk.bgBlack(chalk.white(i))} `;
|
|
88
|
+
let start = 0;
|
|
89
|
+
let end = currentFileLines[i].length;
|
|
90
|
+
message += currentFileLines[i] + '\n';
|
|
91
|
+
if (i === diagnostic.range.start.line) {
|
|
92
|
+
start = diagnostic.range.start.character;
|
|
93
|
+
}
|
|
94
|
+
if (i === diagnostic.range.end.line) {
|
|
95
|
+
end = diagnostic.range.end.character;
|
|
96
|
+
}
|
|
97
|
+
let squiggle = ' ';
|
|
98
|
+
const frontFiller = String(i).length;
|
|
99
|
+
for (let j = 0; j < frontFiller; j++) {
|
|
100
|
+
message += chalk.bgBlack(' ');
|
|
101
|
+
}
|
|
102
|
+
for (let j = 0; j < start; j++) {
|
|
103
|
+
squiggle += ' ';
|
|
104
|
+
}
|
|
105
|
+
let lastCharNotSpace = false;
|
|
106
|
+
for (let j = start; j < end; j++) {
|
|
107
|
+
if (currentFileLines[i].charAt(j) !== ' ' ||
|
|
108
|
+
(lastCharNotSpace &&
|
|
109
|
+
j + 1 !== end &&
|
|
110
|
+
currentFileLines[i].charAt(j + 1) !== ' ')) {
|
|
111
|
+
squiggle += '~';
|
|
112
|
+
lastCharNotSpace = true;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
squiggle += ' ';
|
|
116
|
+
lastCharNotSpace = false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
message += underlineHighlight(squiggle);
|
|
120
|
+
message += '\n';
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
log(message);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CommandLineOptions } from 'command-line-args';
|
|
2
|
+
import type { BundleType } from '@lwc/metadata/dist/shared/config';
|
|
3
|
+
export interface AnalyzerOptions extends CommandLineOptions {
|
|
4
|
+
paths: string[];
|
|
5
|
+
bundleType: BundleType;
|
|
6
|
+
raw: boolean;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=types.d.ts.map
|
package/build/cmds/index.d.ts
CHANGED
package/build/cmds/index.js
CHANGED
|
@@ -1,26 +1,5 @@
|
|
|
1
1
|
import { BundleConfig } from '@lwc/metadata';
|
|
2
2
|
import { ParsedBundle } from '../types';
|
|
3
|
-
/**
|
|
4
|
-
* typeof BundleConfig.file
|
|
5
|
-
*/
|
|
6
|
-
declare type BundleFile = {
|
|
7
|
-
fileName: string;
|
|
8
|
-
source: string;
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* Finds all .js, .mjs, .css, and .html files within the given directory, reads their contents, and combines them into a bundle,
|
|
12
|
-
* and returning the array of BundleFile containing the file's fileName and source
|
|
13
|
-
* @param path
|
|
14
|
-
* @returns An array of BundleFile
|
|
15
|
-
*/
|
|
16
|
-
export declare function readBundle(path: string): BundleFile[];
|
|
17
|
-
/**
|
|
18
|
-
* Finds all .js, .mjs, .css, and .html files within the given directory, reads their contents, and combines them into a bundle,
|
|
19
|
-
* and returning the array of BundleFile containing the file's fileName and source
|
|
20
|
-
* @param path
|
|
21
|
-
* @returns An array of BundleFile
|
|
22
|
-
*/
|
|
23
|
-
export declare function traverseDir(path: string, filesArr: BundleFile[]): BundleFile[];
|
|
24
3
|
/**
|
|
25
4
|
* Takes the directory path of an LWC module bundle and an optional set of config overrides. Returns the ParsedBundle, inlcuding
|
|
26
5
|
* the bundle's 1) LWC Metadata and 2) Komaci / Resolvable module.
|
|
@@ -38,5 +17,4 @@ export declare function readAndParseBundle(path: string, configOverrides: Partia
|
|
|
38
17
|
* @returns ParsedBundle that includes the BundleConfig & GeneratorInput inputs, and BundleMetadata and generated module output
|
|
39
18
|
*/
|
|
40
19
|
export declare function readAndParseBundleWithExceptions(path: string, configOverrides: Partial<BundleConfig>): string;
|
|
41
|
-
export {};
|
|
42
20
|
//# sourceMappingURL=readAndParseBundle.d.ts.map
|
|
@@ -1,47 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { basename, dirname, extname, resolve } from 'path';
|
|
1
|
+
import { basename, dirname } from 'path';
|
|
3
2
|
import { collectBundleMetadata } from '@lwc/metadata';
|
|
4
3
|
import { generateKomaciModule, processGeneratorInputAndState } from '@komaci/esm-generator';
|
|
5
|
-
|
|
6
|
-
* Finds all .js, .mjs, .css, and .html files within the given directory, reads their contents, and combines them into a bundle,
|
|
7
|
-
* and returning the array of BundleFile containing the file's fileName and source
|
|
8
|
-
* @param path
|
|
9
|
-
* @returns An array of BundleFile
|
|
10
|
-
*/
|
|
11
|
-
export function readBundle(path) {
|
|
12
|
-
path = resolve(path);
|
|
13
|
-
return traverseDir(path, []);
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Finds all .js, .mjs, .css, and .html files within the given directory, reads their contents, and combines them into a bundle,
|
|
17
|
-
* and returning the array of BundleFile containing the file's fileName and source
|
|
18
|
-
* @param path
|
|
19
|
-
* @returns An array of BundleFile
|
|
20
|
-
*/
|
|
21
|
-
export function traverseDir(path, filesArr) {
|
|
22
|
-
if (existsSync(path)) {
|
|
23
|
-
const contents = readdirSync(path, { withFileTypes: true });
|
|
24
|
-
const LWC_EXT = ['.js', '.mjs', '.css', '.html'];
|
|
25
|
-
contents.forEach((file) => {
|
|
26
|
-
if (file.isDirectory()) {
|
|
27
|
-
filesArr.concat(traverseDir(path + '/' + file.name, filesArr));
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
//check the file extension here and then add it to the files arr
|
|
31
|
-
if (LWC_EXT.includes(extname(file.name))) {
|
|
32
|
-
filesArr.push({
|
|
33
|
-
fileName: path + '/' + file.name,
|
|
34
|
-
source: readFileSync(resolve(path, file.name), 'utf-8').toString(),
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
return filesArr;
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
throw new Error(`path doesn't exist: ${path}`);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
4
|
+
import { readBundle } from '../../../lib/collectBundle.js';
|
|
45
5
|
/**
|
|
46
6
|
* Takes the directory path of an LWC module bundle and an optional set of config overrides. Returns the ParsedBundle, inlcuding
|
|
47
7
|
* the bundle's 1) LWC Metadata and 2) Komaci / Resolvable module.
|
package/build/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import commandLineArgs from 'command-line-args';
|
|
2
|
-
import { modgen } from './cmds/index.js';
|
|
2
|
+
import { modgen, analyze } from './cmds/index.js';
|
|
3
3
|
import { commander } from './lib/commander.js';
|
|
4
4
|
import logger from './lib/log.js';
|
|
5
5
|
const { error } = logger;
|
|
6
6
|
const optionDefinitions = [{ name: 'command', defaultOption: true }];
|
|
7
7
|
const mainCommand = commandLineArgs(optionDefinitions, { stopAtFirstUnknown: true });
|
|
8
8
|
const { command, _unknown: argv = [] } = mainCommand;
|
|
9
|
-
if (!commander(command, argv, [modgen])) {
|
|
9
|
+
if (!commander(command, argv, [modgen, analyze])) {
|
|
10
10
|
error(`No command "${command}" found`);
|
|
11
11
|
process.exit(1);
|
|
12
12
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* typeof BundleConfig.file
|
|
3
|
+
*/
|
|
4
|
+
declare type BundleFile = {
|
|
5
|
+
fileName: string;
|
|
6
|
+
source: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Finds all .js, .mjs, .css, and .html files within the given directory, reads their contents, and combines them into a bundle,
|
|
10
|
+
* and returning the array of BundleFile containing the file's fileName and source
|
|
11
|
+
* @param path
|
|
12
|
+
* @returns An array of BundleFile
|
|
13
|
+
*/
|
|
14
|
+
export declare function readBundle(path: string): BundleFile[];
|
|
15
|
+
/**
|
|
16
|
+
* Finds all .js, .mjs, .css, and .html files within the given directory, reads their contents, and combines them into a bundle,
|
|
17
|
+
* and returning the array of BundleFile containing the file's fileName and source
|
|
18
|
+
* @param path
|
|
19
|
+
* @returns An array of BundleFile
|
|
20
|
+
*/
|
|
21
|
+
export declare function traverseDir(path: string, filesArr: BundleFile[]): BundleFile[];
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=collectBundle.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readdirSync, existsSync, readFileSync } from 'fs';
|
|
2
|
+
import { extname, resolve } from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Finds all .js, .mjs, .css, and .html files within the given directory, reads their contents, and combines them into a bundle,
|
|
5
|
+
* and returning the array of BundleFile containing the file's fileName and source
|
|
6
|
+
* @param path
|
|
7
|
+
* @returns An array of BundleFile
|
|
8
|
+
*/
|
|
9
|
+
export function readBundle(path) {
|
|
10
|
+
path = resolve(path);
|
|
11
|
+
return traverseDir(path, []);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Finds all .js, .mjs, .css, and .html files within the given directory, reads their contents, and combines them into a bundle,
|
|
15
|
+
* and returning the array of BundleFile containing the file's fileName and source
|
|
16
|
+
* @param path
|
|
17
|
+
* @returns An array of BundleFile
|
|
18
|
+
*/
|
|
19
|
+
export function traverseDir(path, filesArr) {
|
|
20
|
+
if (existsSync(path)) {
|
|
21
|
+
const contents = readdirSync(path, { withFileTypes: true });
|
|
22
|
+
const LWC_EXT = ['.js', '.mjs', '.css', '.html'];
|
|
23
|
+
contents.forEach((file) => {
|
|
24
|
+
if (file.isDirectory()) {
|
|
25
|
+
filesArr.concat(traverseDir(path + '/' + file.name, filesArr));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
//check the file extension here and then add it to the files arr
|
|
29
|
+
if (LWC_EXT.includes(extname(file.name))) {
|
|
30
|
+
filesArr.push({
|
|
31
|
+
fileName: path + '/' + file.name,
|
|
32
|
+
source: readFileSync(resolve(path, file.name), 'utf-8').toString(),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return filesArr;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
throw new Error(`path doesn't exist: ${path}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=collectBundle.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@komaci/cli",
|
|
3
|
-
"version": "244.1.
|
|
3
|
+
"version": "244.1.7",
|
|
4
4
|
"description": "CLI utility that enables developers to use komaci from the command line.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -24,11 +24,13 @@
|
|
|
24
24
|
"url": "https://github.com/AndrewHuffman/komaci/issues"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@komaci/esm-generator": "244.1.
|
|
27
|
+
"@komaci/esm-generator": "244.1.7",
|
|
28
|
+
"@komaci/static-analyzer": "244.1.7",
|
|
28
29
|
"@lwc/metadata": "2.32.0-0",
|
|
29
30
|
"@lwc/sfdc-compiler-utils": "2.22.0-0",
|
|
30
31
|
"chalk": "^5.0.1",
|
|
31
|
-
"command-line-args": "^5.2.1"
|
|
32
|
+
"command-line-args": "^5.2.1",
|
|
33
|
+
"glob": "^7.1.7"
|
|
32
34
|
},
|
|
33
35
|
"devDependencies": {
|
|
34
36
|
"@types/command-line-args": "^5.2.0",
|