Skip to content

Commit ae44e59

Browse files
authored
Merge pull request #59 from khawkins/programmatic_file_api
Support programmatic linting, remove FS-centric bundle management
2 parents a1a244b + 7acb1a4 commit ae44e59

File tree

90 files changed

+2081
-381
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+2081
-381
lines changed

.eslintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"node": true
2020
},
2121
"parserOptions": {
22-
"ecmaVersion": 6
22+
"ecmaVersion": "latest"
2323
},
2424
"rules": {
2525
"strict": ["error", "global"]

jest.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ module.exports = {
1313
testMatch: [
1414
'<rootDir>/test/plugin.js',
1515
'<rootDir>/test/lib/rules/**/*.js',
16+
'<rootDir>/test/lib/util/**/*.js',
17+
'<rootDir>/test/lib/lwc-bundle.js',
18+
'<rootDir>/test/lib/processor.js',
1619
'!**/test/lib/rules/**/test.js',
1720
'!**/test/lib/rules/artifacts-combined-files/helper.js',
1821
'!**/test/lib/rules/shared.js'

lib/configs/base.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@
1010
module.exports = {
1111
plugins: ['@salesforce/lwc-graph-analyzer'],
1212
processor: '@salesforce/lwc-graph-analyzer/bundleAnalyzer',
13+
parser: '@babel/eslint-parser',
14+
parserOptions: {
15+
ecmaVersion: 'latest',
16+
requireConfigFile: false,
17+
sourceType: 'module',
18+
babelOptions: {
19+
parserOpts: {
20+
plugins: [['decorators', { decoratorsBeforeExport: false }]]
21+
}
22+
}
23+
},
1324
overrides: [
1425
{
1526
files: ['**/*.html']

lib/index.d.ts

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import type { Linter, ESLint } from 'eslint';
2+
3+
/**
4+
* Represents a file in an LWC bundle, with its content and designation as the primary file,
5+
* i.e. the file requested by ESLint to be linted.
6+
*/
7+
export type LwcBundleFile = {
8+
/** The name of the file */
9+
filename: string;
10+
/** The content of the file */
11+
content: string;
12+
/** Whether this is the primary file being linted by ESLint */
13+
isPrimary: boolean;
14+
};
15+
16+
/**
17+
* Represents a bundle of files that make up an LWC component. The bundle contains the JavaScript
18+
* file and any HTML template files that comprise the component. One file in the bundle will be
19+
* designated as the primary file, which is the file that ESLint is currently processing.
20+
*/
21+
declare class LwcBundle {
22+
/**
23+
* Creates a new LWC bundle instance
24+
*
25+
* @param componentBaseName - The base name of the component (e.g., 'myComponent' for 'myComponent.js' et al)
26+
* @param js - The JavaScript file of the bundle, if present
27+
* @param htmlTemplates - The HTML template files of the bundle, if present
28+
*/
29+
constructor(componentBaseName: string, js?: LwcBundleFile, htmlTemplates?: LwcBundleFile[]);
30+
31+
/** Gets the base name of the component */
32+
get componentBaseName(): string;
33+
34+
/** Gets the JavaScript file of the bundle, if present */
35+
get js(): LwcBundleFile | undefined;
36+
37+
/** Gets the HTML template files of the bundle, if present */
38+
get htmlTemplates(): LwcBundleFile[] | undefined;
39+
40+
/** Gets the primary file being linted by ESLint */
41+
get primaryFile(): LwcBundleFile;
42+
43+
/**
44+
* Creates a record of filenames to their content for Komaci analysis
45+
*
46+
* @returns A record mapping filenames to their content
47+
*/
48+
filesRecord(): Record<string, string>;
49+
50+
/**
51+
* Sets the primary file in the bundle based on content matching
52+
*
53+
* @param content - The content to match against
54+
* @returns True if a matching file was found and set as primary
55+
*/
56+
setPrimaryFileByContent(content: string): boolean;
57+
58+
/**
59+
* Creates an `LwcBundle` instance from the specified content files. The primary file
60+
* designation will be set later when the bundle is processed by ESLint.
61+
*
62+
* @param componentBaseName - The base name of the component
63+
* @param jsContent - The content of the JavaScript file, if present
64+
* @param htmlTemplateContent - The contents of the HTML template files, if any
65+
* @returns A new LWC bundle instance
66+
*/
67+
static lwcBundleFromContent(
68+
componentBaseName: string,
69+
jsContent?: string,
70+
...htmlTemplateContent: string[]
71+
): LwcBundle;
72+
73+
/**
74+
* Creates a bundle from filesystem files
75+
*
76+
* @param lwcFileContent - The content of the file being processed
77+
* @param lwcFilePath - The path to the file being processed
78+
* @param lwcFileExtension - The file extension of the file being processed
79+
* @returns A new LWC bundle instance, or null if the file cannot be found
80+
*/
81+
static lwcBundleFromFilesystem(
82+
lwcFileContent: string,
83+
lwcFilePath: string,
84+
lwcFileExtension: string
85+
): LwcBundle | null;
86+
}
87+
88+
/**
89+
* ESLint processor that analyzes LWC bundles. This will set up the LWC bundle to be processed
90+
* by Komaci.
91+
*/
92+
export class BundleAnalyzer implements Linter.Processor {
93+
/** Gets the current LWC bundle being processed */
94+
get lwcBundle(): LwcBundle | null;
95+
96+
/** Sets the LWC bundle to be processed */
97+
set lwcBundle(value: LwcBundle | null);
98+
99+
/**
100+
* Sets the LWC bundle content from content files
101+
*
102+
* @param componentBaseName - The base name of the component
103+
* @param jsContent - The content of the JavaScript file, if present
104+
* @param htmlTemplateContent - The contents of the HTML template files, if any
105+
*/
106+
setLwcBundleFromContent(
107+
componentBaseName: string,
108+
jsContent?: string,
109+
...htmlTemplateContent: string[]
110+
): void;
111+
112+
/**
113+
* Preprocesses the input file for ESLint
114+
*
115+
* @param text - The content of the ESLint file
116+
* @param filename - The input filename
117+
* @returns An array of files and their content to be processed
118+
*/
119+
preprocess(text: string, filename: string): string[];
120+
121+
/**
122+
* Postprocesses the linting results
123+
*
124+
* @param messages - The two-dimensional array of messages returned from linting
125+
* @param filename - The input filename
126+
* @returns A one-dimensional flattened array of messages
127+
*/
128+
postprocess(messages: Linter.LintMessage[][], filename: string): Linter.LintMessage[];
129+
130+
/** Whether the processor supports autofix */
131+
supportsAutofix: boolean;
132+
}
133+
134+
/**
135+
* The ESLint plugin for LWC graph analysis
136+
*/
137+
declare const lwcGraphAnalyzerPlugin: ESLint.Plugin & {
138+
/** The bundle analyzer processor */
139+
processors: {
140+
bundleAnalyzer: BundleAnalyzer;
141+
};
142+
/** The plugin's configuration presets */
143+
configs: {
144+
base: Linter.Config;
145+
recommended: Linter.Config;
146+
};
147+
};
148+
149+
export = lwcGraphAnalyzerPlugin;
150+
export { LwcBundle };

lib/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77

88
'use strict';
99

10-
const processor = require('./processor');
10+
const bundleAnalyzer = require('./processor');
1111
const base = require('./configs/base');
1212
const recommended = require('./configs/recommended');
13+
const LwcBundle = require('./lwc-bundle');
1314

1415
const noGetterContainsMoreThanReturnStatement = require('./rules/no-getter-contains-more-than-return-statement');
1516
const noAssignmentExpressionAssignsValueToMemberVariable = require('./rules/no-assignment-expression-assigns-value-to-member-variable');
@@ -117,6 +118,7 @@ module.exports = {
117118
recommended
118119
},
119120
processors: {
120-
bundleAnalyzer: processor
121+
bundleAnalyzer
121122
}
122123
};
124+
module.exports.LwcBundle = LwcBundle;

0 commit comments

Comments
 (0)