pasika 0.3.3 → 0.3.4
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/README.md +13 -17
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/index.js +4999 -103
- package/dist/eslint/pasika/index.d.ts +165 -53
- package/dist/eslint/pasika/index.js +4424 -89
- package/package.json +3 -3
- package/dist/cli/output.d.ts +0 -3
- package/dist/cli/output.js +0 -11
- package/dist/enforcement/coverage.d.ts +0 -55
- package/dist/enforcement/coverage.js +0 -239
- package/dist/enforcement/doctor.d.ts +0 -16
- package/dist/enforcement/doctor.js +0 -249
- package/dist/enforcement/normalize.d.ts +0 -11
- package/dist/enforcement/normalize.js +0 -21
- package/dist/enforcement/parse-docs.d.ts +0 -58
- package/dist/enforcement/parse-docs.js +0 -98
- package/dist/enforcement/types.d.ts +0 -54
- package/dist/enforcement/types.js +0 -50
- package/dist/eslint/pasika/ast-types.d.ts +0 -122
- package/dist/eslint/pasika/ast-types.js +0 -1
- package/dist/eslint/pasika/project/ccf.d.ts +0 -48
- package/dist/eslint/pasika/project/ccf.js +0 -119
- package/dist/eslint/pasika/project/index.d.ts +0 -21
- package/dist/eslint/pasika/project/index.js +0 -139
- package/dist/eslint/pasika/project/parse-module.d.ts +0 -27
- package/dist/eslint/pasika/project/parse-module.js +0 -128
- package/dist/eslint/pasika/rules/application-structure.d.ts +0 -2
- package/dist/eslint/pasika/rules/application-structure.js +0 -152
- package/dist/eslint/pasika/rules/component-conventions.d.ts +0 -16
- package/dist/eslint/pasika/rules/component-conventions.js +0 -145
- package/dist/eslint/pasika/rules/component-nesting.d.ts +0 -12
- package/dist/eslint/pasika/rules/component-nesting.js +0 -69
- package/dist/eslint/pasika/rules/component-placement.d.ts +0 -11
- package/dist/eslint/pasika/rules/component-placement.js +0 -75
- package/dist/eslint/pasika/rules/config-extraction.d.ts +0 -14
- package/dist/eslint/pasika/rules/config-extraction.js +0 -74
- package/dist/eslint/pasika/rules/cross-feature-import.d.ts +0 -2
- package/dist/eslint/pasika/rules/cross-feature-import.js +0 -75
- package/dist/eslint/pasika/rules/css/apply-usage.d.ts +0 -10
- package/dist/eslint/pasika/rules/css/apply-usage.js +0 -45
- package/dist/eslint/pasika/rules/css/base-layer-pair.d.ts +0 -10
- package/dist/eslint/pasika/rules/css/base-layer-pair.js +0 -49
- package/dist/eslint/pasika/rules/css/css-variable-naming.d.ts +0 -10
- package/dist/eslint/pasika/rules/css/css-variable-naming.js +0 -39
- package/dist/eslint/pasika/rules/css/custom-utility-apply.d.ts +0 -11
- package/dist/eslint/pasika/rules/css/custom-utility-apply.js +0 -52
- package/dist/eslint/pasika/rules/css/global-css-location.d.ts +0 -10
- package/dist/eslint/pasika/rules/css/global-css-location.js +0 -42
- package/dist/eslint/pasika/rules/css/helpers.d.ts +0 -29
- package/dist/eslint/pasika/rules/css/helpers.js +0 -93
- package/dist/eslint/pasika/rules/css/index.d.ts +0 -13
- package/dist/eslint/pasika/rules/css/index.js +0 -25
- package/dist/eslint/pasika/rules/css/root-variables.d.ts +0 -11
- package/dist/eslint/pasika/rules/css/root-variables.js +0 -53
- package/dist/eslint/pasika/rules/css/rule-tester.d.ts +0 -11
- package/dist/eslint/pasika/rules/css/rule-tester.js +0 -22
- package/dist/eslint/pasika/rules/css/stylesheet-ordering.d.ts +0 -11
- package/dist/eslint/pasika/rules/css/stylesheet-ordering.js +0 -76
- package/dist/eslint/pasika/rules/css/surface-utility.d.ts +0 -10
- package/dist/eslint/pasika/rules/css/surface-utility.js +0 -41
- package/dist/eslint/pasika/rules/css/theme-reset.d.ts +0 -9
- package/dist/eslint/pasika/rules/css/theme-reset.js +0 -36
- package/dist/eslint/pasika/rules/css/theme-variable-namespace.d.ts +0 -11
- package/dist/eslint/pasika/rules/css/theme-variable-namespace.js +0 -53
- package/dist/eslint/pasika/rules/cva-appearance-props.d.ts +0 -10
- package/dist/eslint/pasika/rules/cva-appearance-props.js +0 -77
- package/dist/eslint/pasika/rules/cva-boolean-variants.d.ts +0 -11
- package/dist/eslint/pasika/rules/cva-boolean-variants.js +0 -97
- package/dist/eslint/pasika/rules/data-testid-case.d.ts +0 -2
- package/dist/eslint/pasika/rules/data-testid-case.js +0 -76
- package/dist/eslint/pasika/rules/enforce-barrel-exports.d.ts +0 -9
- package/dist/eslint/pasika/rules/enforce-barrel-exports.js +0 -78
- package/dist/eslint/pasika/rules/enforce-cn-merge.d.ts +0 -21
- package/dist/eslint/pasika/rules/enforce-cn-merge.js +0 -86
- package/dist/eslint/pasika/rules/enforce-cva-variant-props.d.ts +0 -9
- package/dist/eslint/pasika/rules/enforce-cva-variant-props.js +0 -86
- package/dist/eslint/pasika/rules/filename-case.d.ts +0 -2
- package/dist/eslint/pasika/rules/filename-case.js +0 -123
- package/dist/eslint/pasika/rules/hook-complexity.d.ts +0 -12
- package/dist/eslint/pasika/rules/hook-complexity.js +0 -114
- package/dist/eslint/pasika/rules/hook-extraction.d.ts +0 -11
- package/dist/eslint/pasika/rules/hook-extraction.js +0 -55
- package/dist/eslint/pasika/rules/import-boundaries.d.ts +0 -2
- package/dist/eslint/pasika/rules/import-boundaries.js +0 -167
- package/dist/eslint/pasika/rules/import-through-index.d.ts +0 -2
- package/dist/eslint/pasika/rules/import-through-index.js +0 -52
- package/dist/eslint/pasika/rules/interactive-component.d.ts +0 -10
- package/dist/eslint/pasika/rules/interactive-component.js +0 -76
- package/dist/eslint/pasika/rules/json/index.d.ts +0 -5
- package/dist/eslint/pasika/rules/json/index.js +0 -9
- package/dist/eslint/pasika/rules/json/no-cache-flag.d.ts +0 -10
- package/dist/eslint/pasika/rules/json/no-cache-flag.js +0 -45
- package/dist/eslint/pasika/rules/json/no-vulyk-dependency.d.ts +0 -10
- package/dist/eslint/pasika/rules/json/no-vulyk-dependency.js +0 -41
- package/dist/eslint/pasika/rules/json/rule-tester.d.ts +0 -11
- package/dist/eslint/pasika/rules/json/rule-tester.js +0 -21
- package/dist/eslint/pasika/rules/jsx-hygiene.d.ts +0 -9
- package/dist/eslint/pasika/rules/jsx-hygiene.js +0 -108
- package/dist/eslint/pasika/rules/locale-dotted-path.d.ts +0 -10
- package/dist/eslint/pasika/rules/locale-dotted-path.js +0 -65
- package/dist/eslint/pasika/rules/locale-placement.d.ts +0 -13
- package/dist/eslint/pasika/rules/locale-placement.js +0 -163
- package/dist/eslint/pasika/rules/locales-location.d.ts +0 -11
- package/dist/eslint/pasika/rules/locales-location.js +0 -56
- package/dist/eslint/pasika/rules/md/doc-kind-suffix.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/doc-kind-suffix.js +0 -29
- package/dist/eslint/pasika/rules/md/example-heading-description.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/example-heading-description.js +0 -30
- package/dist/eslint/pasika/rules/md/glossary-term-linking.d.ts +0 -2
- package/dist/eslint/pasika/rules/md/glossary-term-linking.js +0 -99
- package/dist/eslint/pasika/rules/md/guide-folder-entry-point.d.ts +0 -2
- package/dist/eslint/pasika/rules/md/guide-folder-entry-point.js +0 -46
- package/dist/eslint/pasika/rules/md/guide-link-anchors.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/guide-link-anchors.js +0 -50
- package/dist/eslint/pasika/rules/md/guide-overview-no-links.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/guide-overview-no-links.js +0 -51
- package/dist/eslint/pasika/rules/md/guide-states-no-requirement.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/guide-states-no-requirement.js +0 -26
- package/dist/eslint/pasika/rules/md/guide-step-single-link.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/guide-step-single-link.js +0 -48
- package/dist/eslint/pasika/rules/md/guide-step-single-sentence.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/guide-step-single-sentence.js +0 -42
- package/dist/eslint/pasika/rules/md/helpers.d.ts +0 -25
- package/dist/eslint/pasika/rules/md/helpers.js +0 -37
- package/dist/eslint/pasika/rules/md/index.d.ts +0 -27
- package/dist/eslint/pasika/rules/md/index.js +0 -53
- package/dist/eslint/pasika/rules/md/no-cross-document-link.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/no-cross-document-link.js +0 -36
- package/dist/eslint/pasika/rules/md/no-nested-how-to.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/no-nested-how-to.js +0 -39
- package/dist/eslint/pasika/rules/md/no-template-prompt.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/no-template-prompt.js +0 -22
- package/dist/eslint/pasika/rules/md/overview-length.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/overview-length.js +0 -47
- package/dist/eslint/pasika/rules/md/overview-present.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/overview-present.js +0 -41
- package/dist/eslint/pasika/rules/md/policy-no-examples.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/policy-no-examples.js +0 -28
- package/dist/eslint/pasika/rules/md/policy-single-document.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/policy-single-document.js +0 -34
- package/dist/eslint/pasika/rules/md/policy-subject-headings.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/policy-subject-headings.js +0 -58
- package/dist/eslint/pasika/rules/md/project-index.d.ts +0 -17
- package/dist/eslint/pasika/rules/md/project-index.js +0 -67
- package/dist/eslint/pasika/rules/md/reference-block-headings.d.ts +0 -6
- package/dist/eslint/pasika/rules/md/reference-block-headings.js +0 -31
- package/dist/eslint/pasika/rules/md/reference-no-rfc-vocabulary.d.ts +0 -6
- package/dist/eslint/pasika/rules/md/reference-no-rfc-vocabulary.js +0 -26
- package/dist/eslint/pasika/rules/md/requirement-present.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/requirement-present.js +0 -41
- package/dist/eslint/pasika/rules/md/rfc-only-in-bullets.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/rfc-only-in-bullets.js +0 -46
- package/dist/eslint/pasika/rules/md/rule-paired-examples.d.ts +0 -5
- package/dist/eslint/pasika/rules/md/rule-paired-examples.js +0 -36
- package/dist/eslint/pasika/rules/md/rule-tester.d.ts +0 -11
- package/dist/eslint/pasika/rules/md/rule-tester.js +0 -21
- package/dist/eslint/pasika/rules/md/support-document-placement.d.ts +0 -2
- package/dist/eslint/pasika/rules/md/support-document-placement.js +0 -36
- package/dist/eslint/pasika/rules/md/title-matches-file-name.d.ts +0 -2
- package/dist/eslint/pasika/rules/md/title-matches-file-name.js +0 -46
- package/dist/eslint/pasika/rules/named-exports.d.ts +0 -2
- package/dist/eslint/pasika/rules/named-exports.js +0 -49
- package/dist/eslint/pasika/rules/no-arbitrary-tailwind.d.ts +0 -9
- package/dist/eslint/pasika/rules/no-arbitrary-tailwind.js +0 -97
- package/dist/eslint/pasika/rules/no-eslint-disable.d.ts +0 -10
- package/dist/eslint/pasika/rules/no-eslint-disable.js +0 -33
- package/dist/eslint/pasika/rules/no-mixed-concerns.d.ts +0 -9
- package/dist/eslint/pasika/rules/no-mixed-concerns.js +0 -71
- package/dist/eslint/pasika/rules/no-util-barrel.d.ts +0 -2
- package/dist/eslint/pasika/rules/no-util-barrel.js +0 -48
- package/dist/eslint/pasika/rules/pure-function-extract.d.ts +0 -9
- package/dist/eslint/pasika/rules/pure-function-extract.js +0 -92
- package/dist/eslint/pasika/rules/shared-style-dedup.d.ts +0 -13
- package/dist/eslint/pasika/rules/shared-style-dedup.js +0 -91
- package/dist/eslint/pasika/rules/stay-flat.d.ts +0 -12
- package/dist/eslint/pasika/rules/stay-flat.js +0 -81
- package/dist/eslint/pasika/rules/support-file-placement.d.ts +0 -15
- package/dist/eslint/pasika/rules/support-file-placement.js +0 -70
- package/dist/eslint/pasika/rules/support-folder-shape.d.ts +0 -2
- package/dist/eslint/pasika/rules/support-folder-shape.js +0 -59
- package/dist/eslint/pasika/rules/type-extraction.d.ts +0 -13
- package/dist/eslint/pasika/rules/type-extraction.js +0 -85
- package/dist/eslint/pasika/rules/ui-state.d.ts +0 -9
- package/dist/eslint/pasika/rules/ui-state.js +0 -99
- package/dist/eslint/pasika/rules/util-file-name.d.ts +0 -2
- package/dist/eslint/pasika/rules/util-file-name.js +0 -48
- package/dist/eslint/pasika/rules/value-extraction.d.ts +0 -13
- package/dist/eslint/pasika/rules/value-extraction.js +0 -48
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/component-nesting
|
|
3
|
-
*
|
|
4
|
-
* A component MUST NOT be nested only because it has support files. Nesting is
|
|
5
|
-
* justified by exclusive child components, so a nested component folder whose
|
|
6
|
-
* only contents are the component, its index, and support folders must be
|
|
7
|
-
* flattened.
|
|
8
|
-
*
|
|
9
|
-
* @see docs/code-organization-guide/rules/folder-nesting-rule.md
|
|
10
|
-
*/
|
|
11
|
-
import path from "node:path";
|
|
12
|
-
import { getProjectIndex } from "../project/index.js";
|
|
13
|
-
import { segmentsOf } from "../project/ccf.js";
|
|
14
|
-
export const componentNestingRule = {
|
|
15
|
-
meta: {
|
|
16
|
-
schema: [],
|
|
17
|
-
type: "problem",
|
|
18
|
-
docs: {
|
|
19
|
-
description: "Require a nested component to have exclusive child components, not only support files.",
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
create(context) {
|
|
23
|
-
const sourceRoot = path.resolve("src");
|
|
24
|
-
const file = path.resolve(context.filename);
|
|
25
|
-
const segments = segmentsOf(file, sourceRoot);
|
|
26
|
-
// A component file directly inside a feature subfolder:
|
|
27
|
-
// src/features/<feature>/<folder>/<file>
|
|
28
|
-
if (segments.length !== 4 || segments[0] !== "features")
|
|
29
|
-
return {};
|
|
30
|
-
const index = getProjectIndex(sourceRoot);
|
|
31
|
-
if (!index)
|
|
32
|
-
return {};
|
|
33
|
-
const module = index.modules.get(file);
|
|
34
|
-
if (!module?.exports.some((exp) => exp.kind === "component"))
|
|
35
|
-
return {};
|
|
36
|
-
const folder = segments.slice(0, 3);
|
|
37
|
-
// Another component file in the same folder is an exclusive child and makes
|
|
38
|
-
// the nesting real; an index barrel does not count.
|
|
39
|
-
const hasChildComponent = [...index.modules.values()].some((candidate) => {
|
|
40
|
-
if (candidate.file === file)
|
|
41
|
-
return false;
|
|
42
|
-
const candidateSegments = segmentsOf(candidate.file, sourceRoot);
|
|
43
|
-
if (candidateSegments.length !== 4)
|
|
44
|
-
return false;
|
|
45
|
-
if (candidateSegments[0] !== folder[0] ||
|
|
46
|
-
candidateSegments[1] !== folder[1] ||
|
|
47
|
-
candidateSegments[2] !== folder[2]) {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
if (candidateSegments[3]?.startsWith("index."))
|
|
51
|
-
return false;
|
|
52
|
-
return candidate.exports.some((exp) => exp.kind === "component");
|
|
53
|
-
});
|
|
54
|
-
if (hasChildComponent)
|
|
55
|
-
return {};
|
|
56
|
-
const flatFolder = segments.slice(0, 2).join("/");
|
|
57
|
-
return {
|
|
58
|
-
Program(node) {
|
|
59
|
-
context.report({
|
|
60
|
-
node,
|
|
61
|
-
loc: { line: 1, column: 0 },
|
|
62
|
-
message: `This component is nested in src/${folder.join("/")}/ but its folder has no exclusive ` +
|
|
63
|
-
`child components — only support files. Flatten it back into src/${flatFolder}/. ` +
|
|
64
|
-
"See docs/code-organization-guide/rules/folder-nesting-rule.md",
|
|
65
|
-
});
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
},
|
|
69
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/component-placement
|
|
3
|
-
*
|
|
4
|
-
* Enforces the placement requirements from the "Component Placement Rule" by
|
|
5
|
-
* reading the whole source tree, because where a component belongs depends on
|
|
6
|
-
* which files import it — something a single-file pass cannot see.
|
|
7
|
-
*
|
|
8
|
-
* @see docs/code-organization-guide/rules/component-placement-rule.md
|
|
9
|
-
*/
|
|
10
|
-
import type { Rule } from "eslint";
|
|
11
|
-
export declare const componentPlacementRule: Rule.RuleModule;
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/component-placement
|
|
3
|
-
*
|
|
4
|
-
* Enforces the placement requirements from the "Component Placement Rule" by
|
|
5
|
-
* reading the whole source tree, because where a component belongs depends on
|
|
6
|
-
* which files import it — something a single-file pass cannot see.
|
|
7
|
-
*
|
|
8
|
-
* @see docs/code-organization-guide/rules/component-placement-rule.md
|
|
9
|
-
*/
|
|
10
|
-
import path from "node:path";
|
|
11
|
-
import { getProjectIndex } from "../project/index.js";
|
|
12
|
-
import { describeConsumers, folderSegmentsOf, formatFolder, isConfigModule, isUnderApp, resolveComponentPlacement, segmentsOf, } from "../project/ccf.js";
|
|
13
|
-
const REASON_TEXT = {
|
|
14
|
-
ccf: "that is the closest folder its consumers share",
|
|
15
|
-
"across-features": "its consumers span more than one feature, and no feature may import from another",
|
|
16
|
-
"across-layers": "its consumers span more than one layer, so no feature can own it",
|
|
17
|
-
};
|
|
18
|
-
const sameFolder = (left, right) => left.length === right.length && left.every((segment, depth) => segment === right[depth]);
|
|
19
|
-
export const componentPlacementRule = {
|
|
20
|
-
meta: {
|
|
21
|
-
schema: [],
|
|
22
|
-
type: "problem",
|
|
23
|
-
docs: {
|
|
24
|
-
description: "Enforce that a component lives in the folder its consumers imply.",
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
create(context) {
|
|
28
|
-
const filename = context.filename;
|
|
29
|
-
if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx"))
|
|
30
|
-
return {};
|
|
31
|
-
const sourceRoot = path.resolve("src");
|
|
32
|
-
const index = getProjectIndex(sourceRoot);
|
|
33
|
-
if (!index)
|
|
34
|
-
return {};
|
|
35
|
-
const componentFile = path.resolve(filename);
|
|
36
|
-
const segments = segmentsOf(componentFile, sourceRoot);
|
|
37
|
-
if (segments.length === 0)
|
|
38
|
-
return {};
|
|
39
|
-
// Routing files and configuration modules are not placed by their consumers.
|
|
40
|
-
if (isUnderApp(segments) || isConfigModule(segments))
|
|
41
|
-
return {};
|
|
42
|
-
const module = index.modules.get(componentFile);
|
|
43
|
-
if (!module?.exports.some((moduleExport) => moduleExport.kind === "component"))
|
|
44
|
-
return {};
|
|
45
|
-
const currentFolder = folderSegmentsOf(componentFile, sourceRoot);
|
|
46
|
-
const placement = resolveComponentPlacement(componentFile, index);
|
|
47
|
-
return {
|
|
48
|
-
Program(node) {
|
|
49
|
-
if (!placement) {
|
|
50
|
-
// No consumer counts, so the component belongs to the feature it represents.
|
|
51
|
-
if (segments[0] !== "features" || segments.length < 3) {
|
|
52
|
-
context.report({
|
|
53
|
-
node,
|
|
54
|
-
loc: { line: 1, column: 0 },
|
|
55
|
-
message: `This component has no consumer outside src/app/ or a configuration module, ` +
|
|
56
|
-
`so it belongs in the feature folder it represents, not in ${formatFolder(currentFolder)}. ` +
|
|
57
|
-
"See docs/code-organization-guide/rules/component-placement-rule.md",
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
if (sameFolder(currentFolder, placement.expectedFolder))
|
|
63
|
-
return;
|
|
64
|
-
const explanation = REASON_TEXT[placement.reason] ?? "that is where its consumers place it";
|
|
65
|
-
context.report({
|
|
66
|
-
node,
|
|
67
|
-
loc: { line: 1, column: 0 },
|
|
68
|
-
message: `Move this component to ${formatFolder(placement.expectedFolder)} — ${explanation}. ` +
|
|
69
|
-
`Imported by ${describeConsumers(placement.countedConsumers, sourceRoot)}. ` +
|
|
70
|
-
"See docs/code-organization-guide/rules/component-placement-rule.md",
|
|
71
|
-
});
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
},
|
|
75
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/config-extraction
|
|
3
|
-
*
|
|
4
|
-
* A type, schema, or utility used only to implement one configuration module
|
|
5
|
-
* MUST be extracted even with one consumer. A configuration module is a
|
|
6
|
-
* src/config/<name>/ folder with index.ts as its entry point, so any type or
|
|
7
|
-
* schema still declared in a module file that is not a support file belongs in
|
|
8
|
-
* the module's types/ or schemas/ folder — or, once a consumer outside the
|
|
9
|
-
* module imports it, in the matching root support folder.
|
|
10
|
-
*
|
|
11
|
-
* @see docs/code-organization-guide/rules/configuration-rule.md
|
|
12
|
-
*/
|
|
13
|
-
import type { Rule } from "eslint";
|
|
14
|
-
export declare const configExtractionRule: Rule.RuleModule;
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/config-extraction
|
|
3
|
-
*
|
|
4
|
-
* A type, schema, or utility used only to implement one configuration module
|
|
5
|
-
* MUST be extracted even with one consumer. A configuration module is a
|
|
6
|
-
* src/config/<name>/ folder with index.ts as its entry point, so any type or
|
|
7
|
-
* schema still declared in a module file that is not a support file belongs in
|
|
8
|
-
* the module's types/ or schemas/ folder — or, once a consumer outside the
|
|
9
|
-
* module imports it, in the matching root support folder.
|
|
10
|
-
*
|
|
11
|
-
* @see docs/code-organization-guide/rules/configuration-rule.md
|
|
12
|
-
*/
|
|
13
|
-
import path from "node:path";
|
|
14
|
-
import { getProjectIndex, symbolKey } from "../project/index.js";
|
|
15
|
-
import { describeConsumers, segmentsOf, SUPPORT_FOLDERS } from "../project/ccf.js";
|
|
16
|
-
export const configExtractionRule = {
|
|
17
|
-
meta: {
|
|
18
|
-
schema: [],
|
|
19
|
-
type: "problem",
|
|
20
|
-
docs: {
|
|
21
|
-
description: "Require config-only types and schemas to be extracted into the module's support folder.",
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
create(context) {
|
|
25
|
-
const sourceRoot = path.resolve("src");
|
|
26
|
-
const file = path.resolve(context.filename);
|
|
27
|
-
const segments = segmentsOf(file, sourceRoot);
|
|
28
|
-
// A configuration module file: src/config/<name>/<file>. Support folders are
|
|
29
|
-
// already the extraction destination, so they are not candidates.
|
|
30
|
-
if (segments.length < 3 || segments[0] !== "config")
|
|
31
|
-
return {};
|
|
32
|
-
if (SUPPORT_FOLDERS.has(segments[2] ?? ""))
|
|
33
|
-
return {};
|
|
34
|
-
const index = getProjectIndex(sourceRoot);
|
|
35
|
-
if (!index)
|
|
36
|
-
return {};
|
|
37
|
-
const module = index.modules.get(file);
|
|
38
|
-
if (!module)
|
|
39
|
-
return {};
|
|
40
|
-
const suspects = module.exports.filter((exp) => exp.kind === "type" || exp.kind === "schema");
|
|
41
|
-
if (suspects.length === 0)
|
|
42
|
-
return {};
|
|
43
|
-
const findings = [];
|
|
44
|
-
for (const exp of suspects) {
|
|
45
|
-
const consumers = [...(index.symbolConsumers.get(symbolKey(file, exp.name)) ?? [])];
|
|
46
|
-
const outsideConfig = consumers.filter((consumer) => segmentsOf(consumer, sourceRoot)[0] !== "config");
|
|
47
|
-
if (outsideConfig.length > 0) {
|
|
48
|
-
findings.push({
|
|
49
|
-
line: exp.line,
|
|
50
|
-
message: `${exp.kind} "${exp.name}" in a configuration module is imported by ` +
|
|
51
|
-
`${describeConsumers(outsideConfig, sourceRoot)} outside src/config/. Move it to the ` +
|
|
52
|
-
"matching root support folder. See docs/code-organization-guide/rules/configuration-rule.md",
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
else if (consumers.length > 0) {
|
|
56
|
-
findings.push({
|
|
57
|
-
line: exp.line,
|
|
58
|
-
message: `${exp.kind} "${exp.name}" is used only to implement this configuration module; ` +
|
|
59
|
-
`extract it to the module's ${exp.kind === "schema" ? "schemas/" : "types/"} folder even with one consumer. ` +
|
|
60
|
-
"See docs/code-organization-guide/rules/configuration-rule.md",
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (findings.length === 0)
|
|
65
|
-
return {};
|
|
66
|
-
return {
|
|
67
|
-
Program(node) {
|
|
68
|
-
for (const finding of findings) {
|
|
69
|
-
context.report({ node, loc: { line: finding.line, column: 0 }, message: finding.message });
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
},
|
|
74
|
-
};
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/cross-feature-import
|
|
3
|
-
*
|
|
4
|
-
* A component that imports from two or more feature folders MUST live in
|
|
5
|
-
* src/compositions/.
|
|
6
|
-
*
|
|
7
|
-
* @see docs/code-organization-guide/rules/component-placement-rule.md
|
|
8
|
-
*/
|
|
9
|
-
import path from "node:path";
|
|
10
|
-
const FEATURES_SEGMENT = "features";
|
|
11
|
-
function featureNameOf(resolvedPath, sourceRoot) {
|
|
12
|
-
const relative = path.relative(sourceRoot, resolvedPath);
|
|
13
|
-
if (relative.startsWith(".."))
|
|
14
|
-
return undefined;
|
|
15
|
-
const segments = relative.split(path.sep);
|
|
16
|
-
if (segments[0] !== FEATURES_SEGMENT || segments.length < 2)
|
|
17
|
-
return undefined;
|
|
18
|
-
return segments[1];
|
|
19
|
-
}
|
|
20
|
-
export const crossFeatureImportRule = {
|
|
21
|
-
meta: {
|
|
22
|
-
schema: [],
|
|
23
|
-
type: "problem",
|
|
24
|
-
docs: {
|
|
25
|
-
description: "Require non-composition files that import from two or more feature folders to live in src/compositions/.",
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
create(context) {
|
|
29
|
-
const filename = context.filename;
|
|
30
|
-
if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx"))
|
|
31
|
-
return {};
|
|
32
|
-
const sourceRoot = path.resolve("src");
|
|
33
|
-
const fileRelative = path.relative(sourceRoot, filename);
|
|
34
|
-
if (fileRelative.startsWith(".."))
|
|
35
|
-
return {};
|
|
36
|
-
const fileSegments = fileRelative.split(path.sep);
|
|
37
|
-
const isInCompositions = fileSegments[0] === "compositions";
|
|
38
|
-
const isInApp = fileSegments[0] === "app";
|
|
39
|
-
const isConfig = fileSegments[0] === "config";
|
|
40
|
-
if (isInCompositions || isInApp || isConfig)
|
|
41
|
-
return {};
|
|
42
|
-
const importedFeatures = new Set();
|
|
43
|
-
let alreadyReported = false;
|
|
44
|
-
return {
|
|
45
|
-
ImportDeclaration(node) {
|
|
46
|
-
if (alreadyReported)
|
|
47
|
-
return;
|
|
48
|
-
const source = node.source;
|
|
49
|
-
if (typeof source.value !== "string")
|
|
50
|
-
return;
|
|
51
|
-
let resolved;
|
|
52
|
-
if (source.value.startsWith("@/")) {
|
|
53
|
-
resolved = path.resolve(sourceRoot, source.value.slice(2));
|
|
54
|
-
}
|
|
55
|
-
else if (source.value.startsWith(".")) {
|
|
56
|
-
resolved = path.resolve(path.dirname(filename), source.value);
|
|
57
|
-
}
|
|
58
|
-
if (!resolved)
|
|
59
|
-
return;
|
|
60
|
-
const feature = featureNameOf(resolved, sourceRoot);
|
|
61
|
-
if (feature)
|
|
62
|
-
importedFeatures.add(feature);
|
|
63
|
-
if (importedFeatures.size >= 2) {
|
|
64
|
-
alreadyReported = true;
|
|
65
|
-
const names = [...importedFeatures].sort().join(", ");
|
|
66
|
-
context.report({
|
|
67
|
-
node,
|
|
68
|
-
message: `This component imports from two or more feature folders (${names}) and must live in src/compositions/. ` +
|
|
69
|
-
"See docs/code-organization-guide/rules/component-placement-rule.md",
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
},
|
|
75
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/apply-usage
|
|
3
|
-
*
|
|
4
|
-
* Style declarations added by the project inside global selectors MUST use
|
|
5
|
-
* @apply.
|
|
6
|
-
*
|
|
7
|
-
* @see docs/styling-guide/rules/global-stylesheet-rule.md
|
|
8
|
-
*/
|
|
9
|
-
import type { CSSRuleDefinition } from "@eslint/css";
|
|
10
|
-
export declare const applyUsageRule: CSSRuleDefinition;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/apply-usage
|
|
3
|
-
*
|
|
4
|
-
* Style declarations added by the project inside global selectors MUST use
|
|
5
|
-
* @apply.
|
|
6
|
-
*
|
|
7
|
-
* @see docs/styling-guide/rules/global-stylesheet-rule.md
|
|
8
|
-
*/
|
|
9
|
-
import { blockChildren } from "./helpers.js";
|
|
10
|
-
export const applyUsageRule = {
|
|
11
|
-
meta: {
|
|
12
|
-
schema: [],
|
|
13
|
-
type: "problem",
|
|
14
|
-
docs: {
|
|
15
|
-
description: "Require @apply for project style declarations inside global selectors.",
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
create(context) {
|
|
19
|
-
return {
|
|
20
|
-
"StyleSheet:exit"(node) {
|
|
21
|
-
// Project style declarations inside global selectors are the ones in
|
|
22
|
-
// @layer base rules. Each rule's declarations must go through @apply,
|
|
23
|
-
// not raw CSS properties.
|
|
24
|
-
const layers = node.children.filter((child) => child.type === "Atrule" && child.name === "layer");
|
|
25
|
-
for (const layer of layers) {
|
|
26
|
-
for (const child of blockChildren(layer)) {
|
|
27
|
-
if (child.type !== "Rule")
|
|
28
|
-
continue;
|
|
29
|
-
for (const declaration of blockChildren(child)) {
|
|
30
|
-
if (declaration.type !== "Declaration")
|
|
31
|
-
continue;
|
|
32
|
-
// @apply itself arrives as an Atrule, so a raw Declaration means
|
|
33
|
-
// the project wrote a property by hand instead of applying a
|
|
34
|
-
// utility.
|
|
35
|
-
context.report({
|
|
36
|
-
node: declaration,
|
|
37
|
-
message: `Style declaration "${declaration.property}" inside a global selector must use @apply.`,
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
},
|
|
45
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/base-layer-pair
|
|
3
|
-
*
|
|
4
|
-
* The global base layer MUST apply base-canvas and base-ink to the document
|
|
5
|
-
* body as the default page pair.
|
|
6
|
-
*
|
|
7
|
-
* @see docs/styling-guide/rules/global-stylesheet-rule.md
|
|
8
|
-
*/
|
|
9
|
-
import type { CSSRuleDefinition } from "@eslint/css";
|
|
10
|
-
export declare const baseLayerPairRule: CSSRuleDefinition;
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/base-layer-pair
|
|
3
|
-
*
|
|
4
|
-
* The global base layer MUST apply base-canvas and base-ink to the document
|
|
5
|
-
* body as the default page pair.
|
|
6
|
-
*
|
|
7
|
-
* @see docs/styling-guide/rules/global-stylesheet-rule.md
|
|
8
|
-
*/
|
|
9
|
-
import { atrulesNamed, blockChildren, preludeIdentifiers, selectorNames } from "./helpers.js";
|
|
10
|
-
export const baseLayerPairRule = {
|
|
11
|
-
meta: {
|
|
12
|
-
schema: [],
|
|
13
|
-
type: "problem",
|
|
14
|
-
docs: {
|
|
15
|
-
description: "Require the base layer to apply base-canvas and base-ink to the body.",
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
create(context) {
|
|
19
|
-
return {
|
|
20
|
-
"StyleSheet:exit"(node) {
|
|
21
|
-
const baseLayers = atrulesNamed(node, "layer").filter((layer) => preludeIdentifiers(layer).includes("base"));
|
|
22
|
-
if (baseLayers.length === 0)
|
|
23
|
-
return;
|
|
24
|
-
const applied = [];
|
|
25
|
-
for (const layer of baseLayers) {
|
|
26
|
-
for (const child of blockChildren(layer)) {
|
|
27
|
-
if (child.type !== "Rule")
|
|
28
|
-
continue;
|
|
29
|
-
if (!selectorNames(child).includes("body"))
|
|
30
|
-
continue;
|
|
31
|
-
for (const declaration of blockChildren(child)) {
|
|
32
|
-
if (declaration.type !== "Atrule" || declaration.name !== "apply")
|
|
33
|
-
continue;
|
|
34
|
-
applied.push(...preludeIdentifiers(declaration));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
const hasCanvas = applied.some((name) => name.includes("canvas"));
|
|
39
|
-
const hasInk = applied.some((name) => name.includes("ink"));
|
|
40
|
-
if (!hasCanvas || !hasInk) {
|
|
41
|
-
context.report({
|
|
42
|
-
node,
|
|
43
|
-
message: "The global base layer must apply a canvas and an ink utility to the document body as the default page pair.",
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
},
|
|
49
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/css-variable-naming
|
|
3
|
-
*
|
|
4
|
-
* A CSS variable intended only for a background MUST be named --<role>-canvas,
|
|
5
|
-
* and one intended only for readable text MUST be named --<role>-ink.
|
|
6
|
-
*
|
|
7
|
-
* @see docs/styling-guide/rules/theme-and-utility-definition-rule.md
|
|
8
|
-
*/
|
|
9
|
-
import type { CSSRuleDefinition } from "@eslint/css";
|
|
10
|
-
export declare const cssVariableNamingRule: CSSRuleDefinition;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/css-variable-naming
|
|
3
|
-
*
|
|
4
|
-
* A CSS variable intended only for a background MUST be named --<role>-canvas,
|
|
5
|
-
* and one intended only for readable text MUST be named --<role>-ink.
|
|
6
|
-
*
|
|
7
|
-
* @see docs/styling-guide/rules/theme-and-utility-definition-rule.md
|
|
8
|
-
*/
|
|
9
|
-
export const cssVariableNamingRule = {
|
|
10
|
-
meta: {
|
|
11
|
-
schema: [],
|
|
12
|
-
type: "problem",
|
|
13
|
-
docs: {
|
|
14
|
-
description: "Require background variables to end in -canvas and text variables to end in -ink.",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
create(context) {
|
|
18
|
-
return {
|
|
19
|
-
Declaration(node) {
|
|
20
|
-
const property = node.property;
|
|
21
|
-
if (!property.startsWith("--"))
|
|
22
|
-
return;
|
|
23
|
-
const lower = property.toLowerCase();
|
|
24
|
-
if ((lower.includes("bg") || lower.includes("background")) && !lower.endsWith("-canvas")) {
|
|
25
|
-
context.report({
|
|
26
|
-
node,
|
|
27
|
-
message: `CSS variable "${property}" looks like a background token; name it --<role>-canvas instead.`,
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
if (lower.includes("text") && !lower.endsWith("-ink")) {
|
|
31
|
-
context.report({
|
|
32
|
-
node,
|
|
33
|
-
message: `CSS variable "${property}" looks like a text token; name it --<role>-ink instead.`,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
},
|
|
39
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/custom-utility-apply
|
|
3
|
-
*
|
|
4
|
-
* A custom utility MUST use @apply for every styling declaration added by the
|
|
5
|
-
* project. When no named built-in utility represents a property value, it MUST
|
|
6
|
-
* apply the Tailwind custom-property or arbitrary-property utility instead.
|
|
7
|
-
*
|
|
8
|
-
* @see docs/styling-guide/rules/theme-and-utility-definition-rule.md
|
|
9
|
-
*/
|
|
10
|
-
import type { CSSRuleDefinition } from "@eslint/css";
|
|
11
|
-
export declare const customUtilityApplyRule: CSSRuleDefinition;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/custom-utility-apply
|
|
3
|
-
*
|
|
4
|
-
* A custom utility MUST use @apply for every styling declaration added by the
|
|
5
|
-
* project. When no named built-in utility represents a property value, it MUST
|
|
6
|
-
* apply the Tailwind custom-property or arbitrary-property utility instead.
|
|
7
|
-
*
|
|
8
|
-
* @see docs/styling-guide/rules/theme-and-utility-definition-rule.md
|
|
9
|
-
*/
|
|
10
|
-
import { atrulesNamed, blockChildren } from "./helpers.js";
|
|
11
|
-
/** The property name when a tolerant-mode `Raw` is actually `property: value`. */
|
|
12
|
-
function rawProperty(raw) {
|
|
13
|
-
const match = /^\s*(?<property>[a-z][a-z-]*)\s*:/.exec(raw);
|
|
14
|
-
return match?.groups?.property;
|
|
15
|
-
}
|
|
16
|
-
export const customUtilityApplyRule = {
|
|
17
|
-
meta: {
|
|
18
|
-
schema: [],
|
|
19
|
-
type: "problem",
|
|
20
|
-
docs: {
|
|
21
|
-
description: "Require @utility blocks to style through @apply.",
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
create(context) {
|
|
25
|
-
return {
|
|
26
|
-
"StyleSheet:exit"(node) {
|
|
27
|
-
for (const utility of atrulesNamed(node, "utility")) {
|
|
28
|
-
for (const child of blockChildren(utility)) {
|
|
29
|
-
if (child.type === "Atrule" && child.name === "apply")
|
|
30
|
-
continue;
|
|
31
|
-
if (child.type === "Declaration") {
|
|
32
|
-
context.report({
|
|
33
|
-
node: child,
|
|
34
|
-
message: `Custom utility must use @apply for styling declaration "${child.property}".`,
|
|
35
|
-
});
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
if (child.type === "Raw") {
|
|
39
|
-
const property = rawProperty(child.value);
|
|
40
|
-
if (property !== undefined) {
|
|
41
|
-
context.report({
|
|
42
|
-
node: child,
|
|
43
|
-
message: `Custom utility must use @apply for styling declaration "${property}".`,
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
},
|
|
52
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/global-css-location
|
|
3
|
-
*
|
|
4
|
-
* The project's global CSS MUST live in the global stylesheet entry point and
|
|
5
|
-
* MUST NOT be imported from another file.
|
|
6
|
-
*
|
|
7
|
-
* @see docs/styling-guide/rules/global-stylesheet-rule.md
|
|
8
|
-
*/
|
|
9
|
-
import type { CSSRuleDefinition } from "@eslint/css";
|
|
10
|
-
export declare const globalCssLocationRule: CSSRuleDefinition;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint rule: pasika/global-css-location
|
|
3
|
-
*
|
|
4
|
-
* The project's global CSS MUST live in the global stylesheet entry point and
|
|
5
|
-
* MUST NOT be imported from another file.
|
|
6
|
-
*
|
|
7
|
-
* @see docs/styling-guide/rules/global-stylesheet-rule.md
|
|
8
|
-
*/
|
|
9
|
-
export const globalCssLocationRule = {
|
|
10
|
-
meta: {
|
|
11
|
-
schema: [],
|
|
12
|
-
type: "problem",
|
|
13
|
-
docs: {
|
|
14
|
-
description: "Require project global CSS to live only in the entry point stylesheet.",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
create(context) {
|
|
18
|
-
return {
|
|
19
|
-
"StyleSheet:exit"(node) {
|
|
20
|
-
// The entry point registers Tailwind. Any other stylesheet with
|
|
21
|
-
// project CSS — or that imports the entry point — splits global CSS
|
|
22
|
-
// out of the entry point.
|
|
23
|
-
const registersTailwind = node.children.some((child) => child.type === "Atrule" && child.name === "import" && JSON.stringify(child.prelude).includes("tailwindcss"));
|
|
24
|
-
if (registersTailwind)
|
|
25
|
-
return;
|
|
26
|
-
const hasProjectCss = node.children.some((child) => {
|
|
27
|
-
if (child.type === "Atrule" && child.name === "import")
|
|
28
|
-
return false;
|
|
29
|
-
if (child.type === "Comment")
|
|
30
|
-
return false;
|
|
31
|
-
return true;
|
|
32
|
-
});
|
|
33
|
-
if (!hasProjectCss)
|
|
34
|
-
return;
|
|
35
|
-
context.report({
|
|
36
|
-
node,
|
|
37
|
-
message: "Global CSS must live in the global stylesheet entry point that registers Tailwind, not in this file.",
|
|
38
|
-
});
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
},
|
|
42
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared AST walkers for the CSS rules.
|
|
3
|
-
*
|
|
4
|
-
* The @eslint/css language parses with css-tree in tolerant mode, so constructs
|
|
5
|
-
* Tailwind v4 extends beyond the CSS grammar — `--*: initial`, arbitrary
|
|
6
|
-
* properties inside `@apply`, nested `@media` inside `@theme` — survive as
|
|
7
|
-
* `Raw` nodes instead of structured ones. Rules therefore walk the plain AST
|
|
8
|
-
* and fall back to raw text when a construct came through unparsed.
|
|
9
|
-
*/
|
|
10
|
-
import type { CssNodePlain } from "@eslint/css-tree";
|
|
11
|
-
/** Visits `node` and every descendant, in document order. */
|
|
12
|
-
export declare function walkNodes(node: CssNodePlain, visit: (current: CssNodePlain) => void): void;
|
|
13
|
-
/** Every `Atrule` node in the sheet, in document order. */
|
|
14
|
-
export declare function atrules(node: CssNodePlain): CssNodePlain[];
|
|
15
|
-
/** Every `Atrule` with the given name. */
|
|
16
|
-
export declare function atrulesNamed(node: CssNodePlain, name: string): CssNodePlain[];
|
|
17
|
-
/** The children of a block-bearing node. */
|
|
18
|
-
export declare function blockChildren(node: CssNodePlain | undefined): CssNodePlain[];
|
|
19
|
-
/**
|
|
20
|
-
* The names in an at-rule prelude: `Identifier`s (the classes of an `@apply`,
|
|
21
|
-
* the `inline` of `@theme inline`) and `Layer`s (the layers of `@layer base`).
|
|
22
|
-
*/
|
|
23
|
-
export declare function preludeIdentifiers(node: CssNodePlain | undefined): string[];
|
|
24
|
-
/** The text of a `Raw` node, or the empty string. */
|
|
25
|
-
export declare function rawValue(node: CssNodePlain | undefined): string;
|
|
26
|
-
/** Every `Rule` node in the sheet, in document order. */
|
|
27
|
-
export declare function rules(node: CssNodePlain): CssNodePlain[];
|
|
28
|
-
/** The selector names of a rule's prelude, e.g. `root` for `:root`. */
|
|
29
|
-
export declare function selectorNames(node: CssNodePlain | undefined): string[];
|