@angular-eslint/utils 20.5.3-alpha.4 → 20.6.0
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.
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CssSelector } from '@angular-eslint/bundled-angular-compiler';
|
|
1
2
|
import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
|
|
2
3
|
import type { SelectorStyle } from './ast-utils';
|
|
3
4
|
export declare const OPTION_TYPE_ATTRIBUTE = "attribute";
|
|
@@ -6,6 +7,14 @@ export declare const OPTION_TYPE_ELEMENT = "element";
|
|
|
6
7
|
export type SelectorStyleOption = SelectorStyle | string;
|
|
7
8
|
export type SelectorTypeOption = typeof OPTION_TYPE_ATTRIBUTE | typeof OPTION_TYPE_ELEMENT | string;
|
|
8
9
|
export type SelectorTypeInternal = typeof OPTION_TYPE_ATTRS | typeof OPTION_TYPE_ELEMENT;
|
|
10
|
+
export type SelectorConfig = {
|
|
11
|
+
readonly type: SelectorTypeOption;
|
|
12
|
+
readonly prefix: string | readonly string[];
|
|
13
|
+
readonly style: SelectorStyleOption;
|
|
14
|
+
};
|
|
15
|
+
export type SingleConfigOption = Options[number];
|
|
16
|
+
export type MultipleConfigOption = readonly SelectorConfig[];
|
|
17
|
+
export type RuleOptions = readonly [SingleConfigOption | MultipleConfigOption];
|
|
9
18
|
export type Options = [
|
|
10
19
|
{
|
|
11
20
|
readonly type: SelectorTypeOption | readonly SelectorTypeOption[];
|
|
@@ -24,10 +33,14 @@ export declare const reportPrefixError: (node: TSESTree.Node, prefix: string | r
|
|
|
24
33
|
export declare const reportStyleError: (node: TSESTree.Node, style: SelectorStyleOption, context: Readonly<TSESLint.RuleContext<string, readonly unknown[]>>) => void;
|
|
25
34
|
export declare const reportStyleAndPrefixError: (node: TSESTree.Node, style: SelectorStyleOption, prefix: string | readonly string[], context: Readonly<TSESLint.RuleContext<string, readonly unknown[]>>) => void;
|
|
26
35
|
export declare const reportTypeError: (node: TSESTree.Node, type: SelectorTypeOption | readonly SelectorTypeOption[], context: Readonly<TSESLint.RuleContext<string, readonly unknown[]>>) => void;
|
|
36
|
+
export declare const parseSelectorNode: (node: TSESTree.Node) => readonly CssSelector[] | null;
|
|
37
|
+
export declare const getActualSelectorType: (node: TSESTree.Node) => SelectorTypeOption | null;
|
|
27
38
|
export declare const checkValidOptions: (type: SelectorTypeOption | readonly SelectorTypeOption[], prefix: string | readonly string[], style: SelectorStyleOption) => boolean;
|
|
28
|
-
export declare const checkSelector: (node: TSESTree.Node, typeOption: SelectorTypeOption | readonly SelectorTypeOption[], prefixOption: readonly string[], styleOption: SelectorStyle) => {
|
|
39
|
+
export declare const checkSelector: (node: TSESTree.Node, typeOption: SelectorTypeOption | readonly SelectorTypeOption[], prefixOption: readonly string[], styleOption: SelectorStyle, parsedSelectors?: readonly CssSelector[] | null) => {
|
|
29
40
|
readonly hasExpectedPrefix: boolean;
|
|
30
41
|
readonly hasExpectedType: boolean;
|
|
31
42
|
readonly hasExpectedStyle: boolean;
|
|
32
43
|
} | null;
|
|
44
|
+
export declare const isMultipleConfigOption: (option: SingleConfigOption | MultipleConfigOption) => option is MultipleConfigOption;
|
|
45
|
+
export declare const normalizeOptionsToConfigs: (option: SingleConfigOption | MultipleConfigOption) => Map<string, SelectorConfig>;
|
|
33
46
|
//# sourceMappingURL=selector-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selector-utils.d.ts","sourceRoot":"","sources":["../../src/eslint-plugin/selector-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"selector-utils.d.ts","sourceRoot":"","sources":["../../src/eslint-plugin/selector-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkSelector = exports.checkValidOptions = exports.reportTypeError = exports.reportStyleAndPrefixError = exports.reportStyleError = exports.reportPrefixError = exports.SelectorValidator = exports.OPTION_TYPE_ELEMENT = exports.OPTION_TYPE_ATTRS = exports.OPTION_TYPE_ATTRIBUTE = void 0;
|
|
3
|
+
exports.normalizeOptionsToConfigs = exports.isMultipleConfigOption = exports.checkSelector = exports.checkValidOptions = exports.getActualSelectorType = exports.parseSelectorNode = exports.reportTypeError = exports.reportStyleAndPrefixError = exports.reportStyleError = exports.reportPrefixError = exports.SelectorValidator = exports.OPTION_TYPE_ELEMENT = exports.OPTION_TYPE_ATTRS = exports.OPTION_TYPE_ATTRIBUTE = void 0;
|
|
4
4
|
const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
|
|
5
5
|
const ast_utils_1 = require("./ast-utils");
|
|
6
6
|
const utils_1 = require("../utils");
|
|
@@ -92,6 +92,37 @@ const reportTypeError = (node, type, context) => {
|
|
|
92
92
|
});
|
|
93
93
|
};
|
|
94
94
|
exports.reportTypeError = reportTypeError;
|
|
95
|
+
const parseSelectorNode = (node) => {
|
|
96
|
+
if ((0, ast_utils_1.isLiteral)(node)) {
|
|
97
|
+
return bundled_angular_compiler_1.CssSelector.parse(node.raw);
|
|
98
|
+
}
|
|
99
|
+
else if ((0, ast_utils_1.isTemplateLiteral)(node) && node.quasis[0]) {
|
|
100
|
+
return bundled_angular_compiler_1.CssSelector.parse(node.quasis[0].value.raw);
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
};
|
|
104
|
+
exports.parseSelectorNode = parseSelectorNode;
|
|
105
|
+
const getActualSelectorType = (node) => {
|
|
106
|
+
const listSelectors = (0, exports.parseSelectorNode)(node);
|
|
107
|
+
if (!listSelectors || listSelectors.length === 0) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
// Check the first selector to determine type
|
|
111
|
+
const firstSelector = listSelectors[0];
|
|
112
|
+
// Attribute selectors have attrs populated (e.g., [appFoo])
|
|
113
|
+
// CssSelector.attrs is an array where each attribute is stored as [name, value]
|
|
114
|
+
if (Array.isArray(firstSelector.attrs) && firstSelector.attrs.length > 0) {
|
|
115
|
+
return exports.OPTION_TYPE_ATTRIBUTE;
|
|
116
|
+
}
|
|
117
|
+
// Element selectors have a non-null, non-empty element (e.g., app-foo)
|
|
118
|
+
if (firstSelector.element != null &&
|
|
119
|
+
firstSelector.element !== '' &&
|
|
120
|
+
firstSelector.element !== '*') {
|
|
121
|
+
return exports.OPTION_TYPE_ELEMENT;
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
};
|
|
125
|
+
exports.getActualSelectorType = getActualSelectorType;
|
|
95
126
|
const checkValidOptions = (type, prefix, style) => {
|
|
96
127
|
// Get options
|
|
97
128
|
const typeOption = (0, utils_1.arrayify)(type);
|
|
@@ -105,19 +136,14 @@ const checkValidOptions = (type, prefix, style) => {
|
|
|
105
136
|
return isTypeOptionValid && isPrefixOptionValid && isStyleOptionValid;
|
|
106
137
|
};
|
|
107
138
|
exports.checkValidOptions = checkValidOptions;
|
|
108
|
-
const checkSelector = (node, typeOption, prefixOption, styleOption) => {
|
|
139
|
+
const checkSelector = (node, typeOption, prefixOption, styleOption, parsedSelectors) => {
|
|
109
140
|
// Get valid list of selectors
|
|
110
141
|
const types = (0, utils_1.arrayify)(typeOption || [exports.OPTION_TYPE_ATTRS, exports.OPTION_TYPE_ELEMENT]).reduce((previousValue, currentValue) => previousValue.concat(SELECTOR_TYPE_MAPPER[currentValue]), []);
|
|
111
142
|
const styleValidator = styleOption === ast_utils_1.OPTION_STYLE_KEBAB_CASE
|
|
112
143
|
? exports.SelectorValidator.kebabCase
|
|
113
144
|
: exports.SelectorValidator.camelCase;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
listSelectors = bundled_angular_compiler_1.CssSelector.parse(node.raw);
|
|
117
|
-
}
|
|
118
|
-
else if (node && (0, ast_utils_1.isTemplateLiteral)(node) && node.quasis[0]) {
|
|
119
|
-
listSelectors = bundled_angular_compiler_1.CssSelector.parse(node.quasis[0].value.raw);
|
|
120
|
-
}
|
|
145
|
+
// Use provided parsed selectors or parse them
|
|
146
|
+
const listSelectors = parsedSelectors ?? (0, exports.parseSelectorNode)(node);
|
|
121
147
|
if (!listSelectors) {
|
|
122
148
|
return null;
|
|
123
149
|
}
|
|
@@ -132,3 +158,40 @@ const checkSelector = (node, typeOption, prefixOption, styleOption) => {
|
|
|
132
158
|
};
|
|
133
159
|
};
|
|
134
160
|
exports.checkSelector = checkSelector;
|
|
161
|
+
// Type guard for multiple configs
|
|
162
|
+
const isMultipleConfigOption = (option) => {
|
|
163
|
+
return (Array.isArray(option) &&
|
|
164
|
+
option.length >= 1 &&
|
|
165
|
+
option.length <= 2 &&
|
|
166
|
+
option.every((config) => typeof config.type === 'string'));
|
|
167
|
+
};
|
|
168
|
+
exports.isMultipleConfigOption = isMultipleConfigOption;
|
|
169
|
+
// Normalize options to a consistent format
|
|
170
|
+
const normalizeOptionsToConfigs = (option) => {
|
|
171
|
+
const configByType = new Map();
|
|
172
|
+
if ((0, exports.isMultipleConfigOption)(option)) {
|
|
173
|
+
// Validate no duplicate types
|
|
174
|
+
const types = option.map((config) => config.type);
|
|
175
|
+
if (new Set(types).size !== types.length) {
|
|
176
|
+
throw new Error('Invalid rule config: Each config object in the options array must have a unique "type" property (either "element" or "attribute")');
|
|
177
|
+
}
|
|
178
|
+
// Build lookup map by type
|
|
179
|
+
for (const config of option) {
|
|
180
|
+
configByType.set(config.type, config);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
// Single config - normalize to map format
|
|
185
|
+
// Handle both single type and array of types
|
|
186
|
+
const types = (0, utils_1.arrayify)(option.type);
|
|
187
|
+
for (const type of types) {
|
|
188
|
+
configByType.set(type, {
|
|
189
|
+
type,
|
|
190
|
+
prefix: option.prefix,
|
|
191
|
+
style: option.style,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return configByType;
|
|
196
|
+
};
|
|
197
|
+
exports.normalizeOptionsToConfigs = normalizeOptionsToConfigs;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-eslint/utils",
|
|
3
|
-
"version": "20.
|
|
3
|
+
"version": "20.6.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"typescript": "*"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@angular-eslint/bundled-angular-compiler": "20.
|
|
25
|
+
"@angular-eslint/bundled-angular-compiler": "20.6.0"
|
|
26
26
|
},
|
|
27
27
|
"nx": {
|
|
28
28
|
"namedInputs": {
|