Skip to content

Commit 809ea4c

Browse files
nzakasfasttime
andauthored
feat: Type checking for all APIs and rules (#103)
* feat: Type checking for all APIs and rules * Fix types being removed * Fix errors * Fix JSR config * Update src/types.ts Co-authored-by: Francesco Trotta <[email protected]> * Update src/types.ts Co-authored-by: Francesco Trotta <[email protected]> * Apply feedback --------- Co-authored-by: Francesco Trotta <[email protected]>
1 parent 2acd805 commit 809ea4c

17 files changed

+327
-72
lines changed

jsr.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@
77
},
88
"publish": {
99
"include": [
10-
"dist/esm/index.js",
11-
"dist/esm/index.d.ts",
12-
"dist/esm/syntax/index.js",
13-
"dist/esm/syntax/index.d.ts",
10+
"dist/esm",
1411
"README.md",
1512
"jsr.json",
1613
"LICENSE"

package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"scripts": {
6363
"build:dedupe-types": "node tools/dedupe-types.js dist/cjs/index.cjs dist/esm/index.js",
6464
"build:cts": "node -e \"fs.copyFileSync('dist/esm/index.d.ts', 'dist/cjs/index.d.cts')\"",
65-
"build:syntax-cts": "node -e \"fs.copyFileSync('dist/esm/syntax/index.d.ts', 'dist/cjs/syntax/index.d.cts')\"",
65+
"build:syntax-cts": "node -e \"fs.copyFileSync('dist/esm/syntax/index.d.ts', 'dist/cjs/syntax/index.d.cts')\" && node tools/update-cts.js dist/cjs/types.cts dist/cjs/index.d.cts",
6666
"build": "rollup -c && npm run build:dedupe-types && tsc -p tsconfig.esm.json && npm run build:cts && tsc -p tsconfig.syntax.json && npm run build:syntax-cts",
6767
"build:readme": "node tools/update-readme.js",
6868
"build:update-rules-docs": "node tools/update-rules-docs.js",
@@ -85,16 +85,16 @@
8585
],
8686
"license": "Apache-2.0",
8787
"dependencies": {
88-
"@eslint/core": "^0.10.0",
89-
"@eslint/css-tree": "^3.3.1",
88+
"@eslint/core": "^0.13.0",
89+
"@eslint/css-tree": "^3.3.3",
9090
"@eslint/plugin-kit": "^0.2.5"
9191
},
9292
"devDependencies": {
9393
"@eslint/json": "^0.5.0",
9494
"c8": "^9.1.0",
9595
"compute-baseline": "^0.3.0",
9696
"dedent": "^1.5.3",
97-
"eslint": "^9.11.1",
97+
"eslint": "^9.24.0",
9898
"eslint-config-eslint": "^11.0.0",
9999
"eslint-plugin-eslint-plugin": "^6.3.2",
100100
"got": "^14.4.2",
@@ -105,7 +105,8 @@
105105
"prettier": "^3.4.1",
106106
"rollup": "^4.16.2",
107107
"rollup-plugin-copy": "^3.5.0",
108-
"typescript": "^5.4.5",
108+
"rollup-plugin-delete": "^3.0.1",
109+
"typescript": "^5.8.2",
109110
"web-features": "^2.23.0",
110111
"yorkie": "^2.0.0"
111112
},

rollup.config.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import copy from "rollup-plugin-copy";
2+
import del from "rollup-plugin-delete";
3+
14
export default [
25
{
36
input: "src/index.js",
@@ -12,6 +15,19 @@ export default [
1215
banner: '// @ts-self-types="./index.d.ts"',
1316
},
1417
],
18+
plugins: [
19+
del({ targets: ["dist/*"] }),
20+
copy({
21+
targets: [
22+
{
23+
src: "src/types.ts",
24+
dest: "dist/cjs",
25+
rename: "types.cts",
26+
},
27+
{ src: "src/types.ts", dest: "dist/esm" },
28+
],
29+
}),
30+
],
1531
},
1632
{
1733
input: "src/syntax/index.js",

src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,5 @@ const plugin = {
5858
}
5959

6060
export default plugin;
61-
export { CSSLanguage, CSSSourceCode };
61+
export { CSSSourceCode };
62+
export * from "./languages/css-language.js";

src/languages/css-language.js

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,13 @@ import { visitorKeys } from "./css-visitor-keys.js";
2121
// Types
2222
//-----------------------------------------------------------------------------
2323

24-
/** @typedef {import("@eslint/css-tree").CssNode} CssNode */
25-
/** @typedef {import("@eslint/css-tree").CssNodePlain} CssNodePlain */
26-
/** @typedef {import("@eslint/css-tree").StyleSheet} StyleSheet */
27-
/** @typedef {import("@eslint/css-tree").Comment} Comment */
28-
/** @typedef {import("@eslint/css-tree").Lexer} Lexer */
29-
/** @typedef {import("@eslint/css-tree").SyntaxConfig} SyntaxConfig */
30-
/** @typedef {import("@eslint/core").Language} Language */
31-
/** @typedef {import("@eslint/core").OkParseResult<CssNodePlain> & { comments: Comment[], lexer: Lexer }} OkParseResult */
32-
/** @typedef {import("@eslint/core").ParseResult<CssNodePlain>} ParseResult */
33-
/** @typedef {import("@eslint/core").File} File */
34-
/** @typedef {import("@eslint/core").FileError} FileError */
24+
/**
25+
* @import { CssNodePlain, Comment, Lexer, StyleSheetPlain, SyntaxConfig } from "@eslint/css-tree"
26+
* @import { Language, OkParseResult, ParseResult, File, FileError } from "@eslint/core";
27+
*/
3528

29+
/** @typedef {OkParseResult<StyleSheetPlain> & { comments: Comment[], lexer: Lexer }} CSSOkParseResult */
30+
/** @typedef {ParseResult<StyleSheetPlain>} CSSParseResult */
3631
/**
3732
* @typedef {Object} CSSLanguageOptions
3833
* @property {boolean} [tolerant] Whether to be tolerant of recoverable parsing errors.
@@ -62,7 +57,7 @@ const blockCloserTokenTypes = new Map([
6257

6358
/**
6459
* CSS Language Object
65-
* @implements {Language}
60+
* @implements {Language<{ LangOptions: CSSLanguageOptions; Code: CSSSourceCode; RootNode: StyleSheetPlain; Node: CssNodePlain}>}
6661
*/
6762
export class CSSLanguage {
6863
/**
@@ -135,7 +130,7 @@ export class CSSLanguage {
135130
* @param {File} file The virtual file to parse.
136131
* @param {Object} [context] The parsing context.
137132
* @param {CSSLanguageOptions} [context.languageOptions] The language options to use for parsing.
138-
* @returns {ParseResult} The result of parsing.
133+
* @returns {CSSParseResult} The result of parsing.
139134
*/
140135
parse(file, { languageOptions = {} } = {}) {
141136
// Note: BOM already removed
@@ -242,7 +237,7 @@ export class CSSLanguage {
242237

243238
return {
244239
ok: true,
245-
ast: root,
240+
ast: /** @type {StyleSheetPlain} */ (root),
246241
comments,
247242
lexer,
248243
};
@@ -257,7 +252,7 @@ export class CSSLanguage {
257252
/**
258253
* Creates a new `CSSSourceCode` object from the given information.
259254
* @param {File} file The virtual file to create a `CSSSourceCode` object from.
260-
* @param {OkParseResult} parseResult The result returned from `parse()`.
255+
* @param {CSSOkParseResult} parseResult The result returned from `parse()`.
261256
* @returns {CSSSourceCode} The new `CSSSourceCode` object.
262257
*/
263258
createSourceCode(file, parseResult) {

src/languages/css-source-code.js

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,12 @@ import { visitorKeys } from "./css-visitor-keys.js";
1919
// Types
2020
//-----------------------------------------------------------------------------
2121

22-
/** @typedef {import("@eslint/css-tree").CssNode} CssNode */
23-
/** @typedef {import("@eslint/css-tree").CssNodePlain} CssNodePlain */
24-
/** @typedef {import("@eslint/css-tree").BlockPlain} BlockPlain */
25-
/** @typedef {import("@eslint/css-tree").Comment} Comment */
26-
/** @typedef {import("@eslint/css-tree").Lexer} Lexer */
27-
/** @typedef {import("@eslint/core").SourceRange} SourceRange */
28-
/** @typedef {import("@eslint/core").SourceLocation} SourceLocation */
29-
/** @typedef {import("@eslint/core").SourceLocationWithOffset} SourceLocationWithOffset */
30-
/** @typedef {import("@eslint/core").File} File */
31-
/** @typedef {import("@eslint/core").TraversalStep} TraversalStep */
32-
/** @typedef {import("@eslint/core").TextSourceCode} TextSourceCode */
33-
/** @typedef {import("@eslint/core").VisitTraversalStep} VisitTraversalStep */
34-
/** @typedef {import("@eslint/core").FileProblem} FileProblem */
35-
/** @typedef {import("@eslint/core").DirectiveType} DirectiveType */
36-
/** @typedef {import("@eslint/core").RulesConfig} RulesConfig */
22+
/**
23+
* @import { CssNode, CssNodePlain, Comment, Lexer, StyleSheetPlain } from "@eslint/css-tree"
24+
* @import { SourceRange, SourceLocation, FileProblem, DirectiveType, RulesConfig, TextSourceCode } from "@eslint/core"
25+
* @import { CSSSyntaxElement } from "../types.js"
26+
* @import { CSSLanguageOptions } from "./css-language.js"
27+
*/
3728

3829
//-----------------------------------------------------------------------------
3930
// Helpers
@@ -73,7 +64,8 @@ class CSSTraversalStep extends VisitNodeStep {
7364
//-----------------------------------------------------------------------------
7465

7566
/**
76-
* CSS Source Code Object
67+
* CSS Source Code Object.
68+
* @implements {TextSourceCode<{LangOptions: CSSLanguageOptions, RootNode: StyleSheetPlain, SyntaxElementWithLoc: CSSSyntaxElement, ConfigNode: Comment}>}
7769
*/
7870
export class CSSSourceCode extends TextSourceCodeBase {
7971
/**
@@ -96,7 +88,7 @@ export class CSSSourceCode extends TextSourceCodeBase {
9688

9789
/**
9890
* The AST of the source code.
99-
* @type {CssNodePlain}
91+
* @type {StyleSheetPlain}
10092
*/
10193
ast = undefined;
10294

@@ -116,7 +108,7 @@ export class CSSSourceCode extends TextSourceCodeBase {
116108
* Creates a new instance.
117109
* @param {Object} options The options for the instance.
118110
* @param {string} options.text The source code text.
119-
* @param {CssNodePlain} options.ast The root AST node.
111+
* @param {StyleSheetPlain} options.ast The root AST node.
120112
* @param {Array<Comment>} options.comments The comment nodes in the source code.
121113
* @param {Lexer} options.lexer The lexer used to parse the source code.
122114
*/

src/rules/no-duplicate-imports.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,26 @@
33
* @author Nicholas C. Zakas
44
*/
55

6+
//-----------------------------------------------------------------------------
7+
// Type Definitions
8+
//-----------------------------------------------------------------------------
9+
10+
/**
11+
* @import { CSSRuleDefinition } from "../types.js"
12+
* @typedef {"duplicateImport"} NoDuplicateKeysMessageIds
13+
* @typedef {CSSRuleDefinition<{ RuleOptions: [], MessageIds: NoDuplicateKeysMessageIds }>} NoDuplicateImportsRuleDefinition
14+
*/
15+
16+
//-----------------------------------------------------------------------------
17+
// Rule
18+
//-----------------------------------------------------------------------------
19+
20+
/**
21+
* @type {NoDuplicateImportsRuleDefinition}
22+
*/
623
export default {
724
meta: {
8-
type: /** @type {const} */ ("problem"),
25+
type: "problem",
926

1027
docs: {
1128
description: "Disallow duplicate @import rules",

src/rules/no-empty-blocks.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,24 @@
33
* @author Nicholas C. Zakas
44
*/
55

6+
//-----------------------------------------------------------------------------
7+
// Type Definitions
8+
//-----------------------------------------------------------------------------
9+
10+
/**
11+
* @import { CSSRuleDefinition } from "../types.js"
12+
* @typedef {"emptyBlock"} NoEmptyBlocksMessageIds
13+
* @typedef {CSSRuleDefinition<{ RuleOptions: [], MessageIds: NoEmptyBlocksMessageIds }>} NoEmptyBlocksRuleDefinition
14+
*/
15+
16+
//-----------------------------------------------------------------------------
17+
// Rule Definition
18+
//-----------------------------------------------------------------------------
19+
20+
/** @type {NoEmptyBlocksRuleDefinition} */
621
export default {
722
meta: {
8-
type: /** @type {const} */ ("problem"),
23+
type: "problem",
924

1025
docs: {
1126
description: "Disallow empty blocks",

src/rules/no-invalid-at-rules.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@
99

1010
import { isSyntaxMatchError } from "../util.js";
1111

12+
//-----------------------------------------------------------------------------
13+
// Type Definitions
14+
//-----------------------------------------------------------------------------
15+
16+
/**
17+
* @import { AtrulePlain } from "@eslint/css-tree"
18+
* @import { CSSRuleDefinition } from "../types.js"
19+
* @typedef {"unknownAtRule" | "invalidPrelude" | "unknownDescriptor" | "invalidDescriptor" | "invalidExtraPrelude" | "missingPrelude"} NoInvalidAtRulesMessageIds
20+
* @typedef {CSSRuleDefinition<{ RuleOptions: [], MessageIds: NoInvalidAtRulesMessageIds }>} NoInvalidAtRulesRuleDefinition
21+
*/
22+
1223
//-----------------------------------------------------------------------------
1324
// Helpers
1425
//-----------------------------------------------------------------------------
@@ -41,9 +52,10 @@ function extractMetaDataFromError(error) {
4152
// Rule Definition
4253
//-----------------------------------------------------------------------------
4354

55+
/** @type {NoInvalidAtRulesRuleDefinition} */
4456
export default {
4557
meta: {
46-
type: /** @type {const} */ ("problem"),
58+
type: "problem",
4759

4860
docs: {
4961
description: "Disallow invalid at-rules",
@@ -110,7 +122,9 @@ export default {
110122

111123
"AtRule > Block > Declaration"(node) {
112124
// get at rule node
113-
const atRule = sourceCode.getParent(sourceCode.getParent(node));
125+
const atRule = /** @type {AtrulePlain} */ (
126+
sourceCode.getParent(sourceCode.getParent(node))
127+
);
114128

115129
const { error } = lexer.matchAtruleDescriptor(
116130
atRule.name,

src/rules/no-invalid-properties.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,24 @@
99

1010
import { isSyntaxMatchError } from "../util.js";
1111

12+
//-----------------------------------------------------------------------------
13+
// Type Definitions
14+
//-----------------------------------------------------------------------------
15+
16+
/**
17+
* @import { CSSRuleDefinition } from "../types.js"
18+
* @typedef {"invalidPropertyValue" | "unknownProperty"} NoInvalidPropertiesMessageIds
19+
* @typedef {CSSRuleDefinition<{ RuleOptions: [], MessageIds: NoInvalidPropertiesMessageIds }>} NoInvalidPropertiesRuleDefinition
20+
*/
21+
1222
//-----------------------------------------------------------------------------
1323
// Rule Definition
1424
//-----------------------------------------------------------------------------
1525

26+
/** @type {NoInvalidPropertiesRuleDefinition} */
1627
export default {
1728
meta: {
18-
type: /** @type {const} */ ("problem"),
29+
type: "problem",
1930

2031
docs: {
2132
description: "Disallow invalid properties",

0 commit comments

Comments
 (0)