@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.
@@ -0,0 +1,5 @@
1
+ import type { Command } from '../../types';
2
+ import { AnalyzerOptions } from './types';
3
+ declare const _default: Command<AnalyzerOptions>;
4
+ export default _default;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -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,7 @@
1
+ import { AnalyzerOptions } from '../types.js';
2
+ /**
3
+ * Runs the analyze command with the given Command Options.
4
+ * @param cmdOptions
5
+ */
6
+ export declare function run(cmdOptions: AnalyzerOptions): void;
7
+ //# sourceMappingURL=run.d.ts.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
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -1,3 +1,4 @@
1
1
  import modgen from './modgen/index.js';
2
- export { modgen };
2
+ import analyze from './analyze/index.js';
3
+ export { modgen, analyze };
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,4 @@
1
1
  import modgen from './modgen/index.js';
2
- export { modgen };
2
+ import analyze from './analyze/index.js';
3
+ export { modgen, analyze };
3
4
  //# sourceMappingURL=index.js.map
@@ -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 { readdirSync, existsSync, readFileSync } from 'fs';
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.4",
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.4",
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",