@salesforce-ux/eslint-plugin-slds 0.1.5 → 0.1.7-alpha.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.
- package/build/index.d.ts +19 -0
- package/build/index.js +19 -0
- package/build/rules/enforce-bem-class.d.ts +28 -0
- package/build/rules/enforce-bem-class.js +74 -0
- package/build/rules/modal-close-button-issue.d.ts +17 -0
- package/build/rules/modal-close-button-issue.js +190 -0
- package/build/rules/no-deprecated-classes-slds2.d.ts +16 -0
- package/build/rules/no-deprecated-classes-slds2.js +54 -0
- package/build/rules/utils/node.d.ts +79 -0
- package/build/rules/utils/node.js +197 -0
- package/build/rules/utils/rule.d.ts +7 -0
- package/build/rules/utils/rule.js +10 -0
- package/build/services/metadata.service.d.ts +53 -0
- package/build/services/metadata.service.js +106 -0
- package/package.json +2 -1
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
rules: {
|
|
3
|
+
"enforce-bem-class": any;
|
|
4
|
+
"no-deprecated-classes-slds2": any;
|
|
5
|
+
"modal-close-button-issue": any;
|
|
6
|
+
};
|
|
7
|
+
configs: {
|
|
8
|
+
recommended: {
|
|
9
|
+
parser: string;
|
|
10
|
+
plugins: string[];
|
|
11
|
+
rules: {
|
|
12
|
+
"@salesforce-ux/slds/enforce-bem-class": string;
|
|
13
|
+
"@salesforce-ux/slds/no-deprecated-classes-slds2": string;
|
|
14
|
+
"@salesforce-ux/slds/modal-close-button-issue": string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export = _default;
|
package/build/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
module.exports = {
|
|
3
|
+
rules: {
|
|
4
|
+
"enforce-bem-class": require('./rules/enforce-bem-class'),
|
|
5
|
+
"no-deprecated-classes-slds2": require('./rules/no-deprecated-classes-slds2'),
|
|
6
|
+
"modal-close-button-issue": require('./rules/modal-close-button-issue')
|
|
7
|
+
},
|
|
8
|
+
configs: {
|
|
9
|
+
recommended: {
|
|
10
|
+
parser: "@html-eslint/parser", // Use HTML parser
|
|
11
|
+
plugins: ["@salesforce-ux/slds"],
|
|
12
|
+
rules: {
|
|
13
|
+
"@salesforce-ux/slds/enforce-bem-class": "error",
|
|
14
|
+
"@salesforce-ux/slds/no-deprecated-classes-slds2": "error",
|
|
15
|
+
"@salesforce-ux/slds/modal-close-button-issue": "error"
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
meta: {
|
|
3
|
+
type: string;
|
|
4
|
+
docs: {
|
|
5
|
+
category: string;
|
|
6
|
+
recommended: boolean;
|
|
7
|
+
description: string;
|
|
8
|
+
url: string;
|
|
9
|
+
};
|
|
10
|
+
fixable: string;
|
|
11
|
+
schema: {
|
|
12
|
+
type: string;
|
|
13
|
+
properties: {
|
|
14
|
+
pattern: {
|
|
15
|
+
type: string;
|
|
16
|
+
};
|
|
17
|
+
flags: {
|
|
18
|
+
type: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
additionalProperties: boolean;
|
|
22
|
+
}[];
|
|
23
|
+
};
|
|
24
|
+
create(context: any): {
|
|
25
|
+
Tag: (node: any) => void;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export = _default;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const node_1 = require("./utils/node");
|
|
3
|
+
const metadata_service_1 = require("../services/metadata.service");
|
|
4
|
+
const bemMapping = metadata_service_1.MetadataService.loadMetadata(metadata_service_1.MetadataFile.BEM_NAMING);
|
|
5
|
+
module.exports = {
|
|
6
|
+
meta: {
|
|
7
|
+
type: "problem", // The rule type
|
|
8
|
+
docs: {
|
|
9
|
+
category: "Stylistic Issues",
|
|
10
|
+
recommended: true,
|
|
11
|
+
description: "Replace BEM double-dash syntax in class names with single underscore syntax.",
|
|
12
|
+
url: ""
|
|
13
|
+
},
|
|
14
|
+
fixable: "code", // This rule can be fixed automatically
|
|
15
|
+
schema: [
|
|
16
|
+
{
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
pattern: { type: "string" }, // Regex pattern for BEM
|
|
20
|
+
flags: { type: "string" }, // Regex flags
|
|
21
|
+
},
|
|
22
|
+
additionalProperties: false,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
create(context) {
|
|
27
|
+
function check(node) {
|
|
28
|
+
if ((0, node_1.isAttributesEmpty)(node)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const classAttr = (0, node_1.findAttr)(node, "class");
|
|
32
|
+
if (classAttr && classAttr.value) {
|
|
33
|
+
const classNames = classAttr.value.value.split(/\s+/);
|
|
34
|
+
classNames.forEach((className) => {
|
|
35
|
+
if (className && className in bemMapping) {
|
|
36
|
+
// Find the exact location of the problematic class name
|
|
37
|
+
const classNameStart = classAttr.value.value.indexOf(className) + 7; // 7 here is for `class= "`
|
|
38
|
+
const classNameEnd = classNameStart + className.length;
|
|
39
|
+
// Use the loc property to get line and column from the class attribute
|
|
40
|
+
const startLoc = {
|
|
41
|
+
line: classAttr.loc.start.line,
|
|
42
|
+
column: classAttr.loc.start.column + classNameStart,
|
|
43
|
+
};
|
|
44
|
+
const endLoc = {
|
|
45
|
+
line: classAttr.loc.start.line,
|
|
46
|
+
column: classAttr.loc.start.column + classNameEnd,
|
|
47
|
+
};
|
|
48
|
+
// Check whether a fixed class is available
|
|
49
|
+
const newValue = bemMapping[className];
|
|
50
|
+
context.report({
|
|
51
|
+
node,
|
|
52
|
+
loc: { start: startLoc, end: endLoc },
|
|
53
|
+
data: {
|
|
54
|
+
actual: className,
|
|
55
|
+
newValue
|
|
56
|
+
},
|
|
57
|
+
message: JSON.stringify({ message: "{{actual}} has been retired. Update it to the new name {{newValue}}.", suggestions: [newValue] }),
|
|
58
|
+
fix(fixer) {
|
|
59
|
+
if (newValue) {
|
|
60
|
+
const newClassValue = classAttr.value.value.replace(className, newValue);
|
|
61
|
+
return fixer.replaceTextRange([classAttr.value.range[0], classAttr.value.range[1]], `${newClassValue}`);
|
|
62
|
+
}
|
|
63
|
+
return null; // Ensure a return value even if no fix is applied
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
Tag: check,
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
meta: {
|
|
3
|
+
type: string;
|
|
4
|
+
docs: {
|
|
5
|
+
category: string;
|
|
6
|
+
recommended: boolean;
|
|
7
|
+
description: string;
|
|
8
|
+
url: string;
|
|
9
|
+
};
|
|
10
|
+
fixable: string;
|
|
11
|
+
schema: any[];
|
|
12
|
+
};
|
|
13
|
+
create(context: any): {
|
|
14
|
+
Tag: (node: any) => void;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export = _default;
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const node_1 = require("./utils/node");
|
|
3
|
+
const rule_1 = require("./utils/rule");
|
|
4
|
+
module.exports = {
|
|
5
|
+
meta: {
|
|
6
|
+
type: "problem",
|
|
7
|
+
docs: {
|
|
8
|
+
category: "Best Practices",
|
|
9
|
+
recommended: true,
|
|
10
|
+
description: "Update component attributes or CSS classes for the modal close button to comply with the modal component blueprint.",
|
|
11
|
+
url: ""
|
|
12
|
+
},
|
|
13
|
+
fixable: "code",
|
|
14
|
+
schema: [],
|
|
15
|
+
},
|
|
16
|
+
create(context) {
|
|
17
|
+
function check(node) {
|
|
18
|
+
if ((0, node_1.isAttributesEmpty)(node)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const tagName = node.name;
|
|
22
|
+
// ✅ Scenario 1: Remove 'slds-button_icon-inverse' from <button>
|
|
23
|
+
// (optional) when the parent of the button has class name `slds-modal`
|
|
24
|
+
// and also button should have class `slds-modal__close`
|
|
25
|
+
if (tagName === "button") {
|
|
26
|
+
const classAttr = (0, node_1.findAttr)(node, "class");
|
|
27
|
+
if (classAttr && classAttr.value) {
|
|
28
|
+
const classList = classAttr.value.value.split(/\s+/);
|
|
29
|
+
// ✅ Ensure button has "slds-modal__close" before proceeding
|
|
30
|
+
if (!classList.includes("slds-modal__close")) {
|
|
31
|
+
return; // Stop execution if the class is missing
|
|
32
|
+
}
|
|
33
|
+
if (classList.includes("slds-button_icon-inverse") || classList.includes("slds-button--icon-inverse")) {
|
|
34
|
+
const newClassList = classList
|
|
35
|
+
.filter((cls) => (cls !== "slds-button_icon-inverse" && cls !== "slds-button--icon-inverse"))
|
|
36
|
+
.join(" ");
|
|
37
|
+
context.report({
|
|
38
|
+
node,
|
|
39
|
+
loc: classAttr.loc,
|
|
40
|
+
message: JSON.stringify({ message: rule_1.messages["removeClass"], suggestions: [`class="${newClassList}"`] }),
|
|
41
|
+
fix(fixer) {
|
|
42
|
+
return fixer.replaceText(classAttr, // Replace the full attribute
|
|
43
|
+
`class="${newClassList}"` // Updated class list
|
|
44
|
+
);
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// ✅ Scenario 2: Fix <lightning-button-icon> and this should have class `slds-modal__close`
|
|
51
|
+
if (tagName === "lightning-button-icon" || tagName === "lightning:buttonIcon") {
|
|
52
|
+
const variantAttr = (0, node_1.findAttr)(node, "variant");
|
|
53
|
+
const sizeAttr = (0, node_1.findAttr)(node, "size");
|
|
54
|
+
const classAttr = (0, node_1.findAttr)(node, "class");
|
|
55
|
+
const iconClassAttr = (0, node_1.findAttr)(node, "icon-class"); // 🔍 Check for icon-class attribute
|
|
56
|
+
function validateClassAttr(attribute, attrName) {
|
|
57
|
+
if (attribute && attribute.value) {
|
|
58
|
+
const classList = attribute.value.value.split(/\s+/);
|
|
59
|
+
// Irrespective of whether we are checking for class or icon-class we need to check whether the attribute is present or not.
|
|
60
|
+
// ✅ Ensure "slds-modal__close" exists before proceeding
|
|
61
|
+
if (!classAttr?.value?.value?.includes("slds-modal__close")) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// ✅ Ensure "slds-modal__close" exists before proceeding
|
|
65
|
+
// if (!classList.includes("slds-modal__close")) {
|
|
66
|
+
// return; // Stop execution if the class is missing
|
|
67
|
+
// }
|
|
68
|
+
// Remove inverse classes
|
|
69
|
+
if (classList.includes("slds-button_icon-inverse") || classList.includes("slds-button--icon-inverse")) {
|
|
70
|
+
const newClassList = classList
|
|
71
|
+
.filter((cls) => cls !== "slds-button_icon-inverse" && cls !== "slds-button--icon-inverse")
|
|
72
|
+
.join(" ");
|
|
73
|
+
context.report({
|
|
74
|
+
node,
|
|
75
|
+
loc: attribute.loc,
|
|
76
|
+
message: JSON.stringify({ message: rule_1.messages["removeClass"], suggestions: [`${attrName}="${newClassList}"`] }),
|
|
77
|
+
fix(fixer) {
|
|
78
|
+
return fixer.replaceText(attribute, // Replace the full attribute
|
|
79
|
+
`${attrName}="${newClassList}"` // Correctly modifies the respective attribute
|
|
80
|
+
);
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// Ensure 'slds-button' and 'slds-button_icon' exist
|
|
85
|
+
if (!classList.includes("slds-button") || !classList.includes("slds-button_icon")) {
|
|
86
|
+
let newClassList;
|
|
87
|
+
if (attrName === 'icon-class') {
|
|
88
|
+
newClassList = [
|
|
89
|
+
...classList.filter((cls) => cls !== "slds-button_icon-inverse"),
|
|
90
|
+
].join(" ");
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
newClassList = [
|
|
94
|
+
"slds-button",
|
|
95
|
+
"slds-button_icon",
|
|
96
|
+
...classList.filter((cls) => cls !== "slds-button_icon-inverse"),
|
|
97
|
+
].join(" ");
|
|
98
|
+
}
|
|
99
|
+
context.report({
|
|
100
|
+
node: attribute,
|
|
101
|
+
loc: attribute.value.loc,
|
|
102
|
+
message: JSON.stringify({ message: rule_1.messages["ensureButtonClasses"], suggestions: [newClassList] }),
|
|
103
|
+
fix(fixer) {
|
|
104
|
+
return fixer.replaceText(attribute.value, `${newClassList}`);
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
// Fix variant="bare-inverse" to "bare"
|
|
109
|
+
if (variantAttr && variantAttr.value && variantAttr.value.value === "bare-inverse") {
|
|
110
|
+
context.report({
|
|
111
|
+
node: variantAttr,
|
|
112
|
+
message: JSON.stringify({ message: rule_1.messages["changeVariant"], suggestions: ["bare"] }),
|
|
113
|
+
loc: variantAttr.value.loc,
|
|
114
|
+
fix(fixer) {
|
|
115
|
+
return fixer.replaceText(variantAttr.value, `bare`);
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
// Ensure size="large" exists
|
|
120
|
+
// if (!sizeAttr) {
|
|
121
|
+
// context.report({
|
|
122
|
+
// node,
|
|
123
|
+
// message: messages["ensureSizeAttribute"],
|
|
124
|
+
// fix(fixer) {
|
|
125
|
+
// if (variantAttr) {
|
|
126
|
+
// return fixer.insertTextAfterRange([variantAttr.range[1], variantAttr.range[1]], ' size="large"');
|
|
127
|
+
// }
|
|
128
|
+
// },
|
|
129
|
+
// });
|
|
130
|
+
// }
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// ✅ Validate `class` and `icon-class` separately, maintaining their own attribute names
|
|
134
|
+
validateClassAttr(classAttr, "class");
|
|
135
|
+
validateClassAttr(iconClassAttr, "icon-class");
|
|
136
|
+
}
|
|
137
|
+
// ✅ Scenario 3: Fix <lightning-icon> inside <button> & the class name of the parent name as button and it should have `slds-modal__close`
|
|
138
|
+
if ((tagName === "lightning-icon" || tagName === "lightning:icon") && node.parent?.name === "button") {
|
|
139
|
+
const parentClassAttr = (0, node_1.findAttr)(node.parent, "class");
|
|
140
|
+
if (parentClassAttr && parentClassAttr.value) {
|
|
141
|
+
const parentClassList = parentClassAttr.value.value.split(/\s+/);
|
|
142
|
+
// ✅ Ensure the parent <button> has "slds-modal__close" before proceeding
|
|
143
|
+
if (!parentClassList.includes("slds-modal__close")) {
|
|
144
|
+
return; // Stop execution if the class is missing
|
|
145
|
+
}
|
|
146
|
+
const variantAttr = (0, node_1.findAttr)(node, "variant");
|
|
147
|
+
const sizeAttr = (0, node_1.findAttr)(node, "size");
|
|
148
|
+
// Fix variant="bare-inverse" to "bare"
|
|
149
|
+
if (variantAttr && variantAttr.value && variantAttr.value.value === "bare-inverse") {
|
|
150
|
+
context.report({
|
|
151
|
+
node: variantAttr,
|
|
152
|
+
message: JSON.stringify({ message: rule_1.messages["changeVariant"], suggestions: ["bare"] }),
|
|
153
|
+
loc: variantAttr.value.loc,
|
|
154
|
+
fix(fixer) {
|
|
155
|
+
return fixer.replaceText(variantAttr.value, `bare`);
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
// // Remove variant attribute completely
|
|
160
|
+
// if (variantAttr) {
|
|
161
|
+
// context.report({
|
|
162
|
+
// node: variantAttr,
|
|
163
|
+
// messageId: "removeVariant",
|
|
164
|
+
// fix(fixer) {
|
|
165
|
+
// return fixer.remove(variantAttr);
|
|
166
|
+
// },
|
|
167
|
+
// });
|
|
168
|
+
// }
|
|
169
|
+
//Ensure size="large" is set
|
|
170
|
+
// if (!sizeAttr) {
|
|
171
|
+
// context.report({
|
|
172
|
+
// node,
|
|
173
|
+
// message: messages["ensureSizeAttribute"],
|
|
174
|
+
// fix(fixer) {
|
|
175
|
+
// //return fixer.insertTextAfter(node, ' size="large"');
|
|
176
|
+
// if(variantAttr)
|
|
177
|
+
// {
|
|
178
|
+
// return fixer.insertTextAfterRange([variantAttr.range[1], variantAttr.range[1]], ' size="large"')
|
|
179
|
+
// }
|
|
180
|
+
// },
|
|
181
|
+
// });
|
|
182
|
+
// }
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
Tag: check,
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
meta: {
|
|
3
|
+
type: string;
|
|
4
|
+
docs: {
|
|
5
|
+
category: string;
|
|
6
|
+
recommended: boolean;
|
|
7
|
+
description: string;
|
|
8
|
+
url: string;
|
|
9
|
+
};
|
|
10
|
+
schema: any[];
|
|
11
|
+
};
|
|
12
|
+
create(context: any): {
|
|
13
|
+
Tag: (node: any) => void;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export = _default;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const node_1 = require("./utils/node");
|
|
3
|
+
const metadata_service_1 = require("../services/metadata.service");
|
|
4
|
+
const deprecatedClasses = metadata_service_1.MetadataService.loadMetadata(metadata_service_1.MetadataFile.DEPRECATED_CLASSES);
|
|
5
|
+
module.exports = {
|
|
6
|
+
meta: {
|
|
7
|
+
type: "problem", // The rule type
|
|
8
|
+
docs: {
|
|
9
|
+
category: "Best Practices",
|
|
10
|
+
recommended: true,
|
|
11
|
+
description: "Replace classes that aren’t available with SLDS 2 classes. See lightningdesignsystem.com for more info.",
|
|
12
|
+
url: ""
|
|
13
|
+
},
|
|
14
|
+
schema: [], // No additional options needed
|
|
15
|
+
},
|
|
16
|
+
create(context) {
|
|
17
|
+
function check(node) {
|
|
18
|
+
if ((0, node_1.isAttributesEmpty)(node)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const classAttr = (0, node_1.findAttr)(node, "class");
|
|
22
|
+
if (classAttr && classAttr.value) {
|
|
23
|
+
const classNames = classAttr.value.value.split(/\s+/);
|
|
24
|
+
classNames.forEach((className) => {
|
|
25
|
+
if (className && deprecatedClasses.includes(className)) {
|
|
26
|
+
// Find the exact location of the problematic class name
|
|
27
|
+
const classNameStart = classAttr.value.value.indexOf(className) + 7; // 7 here is for `class= "`
|
|
28
|
+
const classNameEnd = classNameStart + className.length;
|
|
29
|
+
// Use the loc property to get line and column from the class attribute
|
|
30
|
+
const startLoc = {
|
|
31
|
+
line: classAttr.loc.start.line,
|
|
32
|
+
column: classAttr.loc.start.column + classNameStart,
|
|
33
|
+
};
|
|
34
|
+
const endLoc = {
|
|
35
|
+
line: classAttr.loc.start.line,
|
|
36
|
+
column: classAttr.loc.start.column + classNameEnd,
|
|
37
|
+
};
|
|
38
|
+
context.report({
|
|
39
|
+
node,
|
|
40
|
+
loc: { start: startLoc, end: endLoc },
|
|
41
|
+
data: {
|
|
42
|
+
className,
|
|
43
|
+
},
|
|
44
|
+
message: JSON.stringify({ message: "The class {{className}} isn't available in SLDS 2. Update it to a class supported in SLDS 2. See lightningdesignsystem.com for more information.", suggestions: [] }),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
Tag: check,
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {TagNode | ScriptTagNode | StyleTagNode} node
|
|
3
|
+
* @param {string} key
|
|
4
|
+
* @returns {AttributeNode | undefined}
|
|
5
|
+
*/
|
|
6
|
+
declare function findAttr(node: any, key: any): any;
|
|
7
|
+
/**
|
|
8
|
+
* Checks whether a node's attributes is empty or not.
|
|
9
|
+
* @param {TagNode | ScriptTagNode | StyleTagNode} node
|
|
10
|
+
* @returns {boolean}
|
|
11
|
+
*/
|
|
12
|
+
declare function isAttributesEmpty(node: any): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Checks whether a node's all tokens are on the same line or not.
|
|
15
|
+
* @param {AnyNode} node A node to check
|
|
16
|
+
* @returns {boolean} `true` if a node's tokens are on the same line, otherwise `false`.
|
|
17
|
+
*/
|
|
18
|
+
declare function isNodeTokensOnSameLine(node: any): boolean;
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @param {Range} rangeA
|
|
22
|
+
* @param {Range} rangeB
|
|
23
|
+
* @returns {boolean}
|
|
24
|
+
*/
|
|
25
|
+
declare function isRangesOverlap(rangeA: any, rangeB: any): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* @param {(TextNode | CommentContentNode)['templates']} templates
|
|
28
|
+
* @param {Range} range
|
|
29
|
+
* @returns {boolean}
|
|
30
|
+
*/
|
|
31
|
+
declare function isOverlapWithTemplates(templates: any, range: any): any;
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param {TextNode | CommentContentNode} node
|
|
35
|
+
* @returns {LineNode[]}
|
|
36
|
+
*/
|
|
37
|
+
declare function splitToLineNodes(node: any): any[];
|
|
38
|
+
/**
|
|
39
|
+
* Get location between two nodes.
|
|
40
|
+
* @param {BaseNode} before A node placed in before
|
|
41
|
+
* @param {BaseNode} after A node placed in after
|
|
42
|
+
* @returns {Location} location between two nodes.
|
|
43
|
+
*/
|
|
44
|
+
declare function getLocBetween(before: any, after: any): {
|
|
45
|
+
start: any;
|
|
46
|
+
end: any;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* @param {AttributeValueNode} node
|
|
50
|
+
* @return {boolean}
|
|
51
|
+
*/
|
|
52
|
+
declare function isExpressionInTemplate(node: any): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* @param {AnyNode} node
|
|
55
|
+
* @returns {node is TagNode}
|
|
56
|
+
*/
|
|
57
|
+
declare function isTag(node: any): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* @param {AnyNode} node
|
|
60
|
+
* @returns {node is CommentNode}
|
|
61
|
+
*/
|
|
62
|
+
declare function isComment(node: any): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* @param {AnyNode} node
|
|
65
|
+
* @returns {node is TextNode}
|
|
66
|
+
*/
|
|
67
|
+
declare function isText(node: any): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* @param {string} source
|
|
70
|
+
* @returns {string[]}
|
|
71
|
+
*/
|
|
72
|
+
declare function codeToLines(source: any): any;
|
|
73
|
+
/**
|
|
74
|
+
*
|
|
75
|
+
* @param {AnyToken[]} tokens
|
|
76
|
+
* @returns {((CommentContentNode | TextNode)['templates'][number])[]}
|
|
77
|
+
*/
|
|
78
|
+
declare function getTemplateTokens(tokens: any): any[];
|
|
79
|
+
export { findAttr, isAttributesEmpty, isNodeTokensOnSameLine, splitToLineNodes, getLocBetween, isExpressionInTemplate, isTag, isComment, isText, isOverlapWithTemplates, codeToLines, isRangesOverlap, getTemplateTokens, };
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// THIS IS TAKEN FROM html-eslint
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.findAttr = findAttr;
|
|
5
|
+
exports.isAttributesEmpty = isAttributesEmpty;
|
|
6
|
+
exports.isNodeTokensOnSameLine = isNodeTokensOnSameLine;
|
|
7
|
+
exports.splitToLineNodes = splitToLineNodes;
|
|
8
|
+
exports.getLocBetween = getLocBetween;
|
|
9
|
+
exports.isExpressionInTemplate = isExpressionInTemplate;
|
|
10
|
+
exports.isTag = isTag;
|
|
11
|
+
exports.isComment = isComment;
|
|
12
|
+
exports.isText = isText;
|
|
13
|
+
exports.isOverlapWithTemplates = isOverlapWithTemplates;
|
|
14
|
+
exports.codeToLines = codeToLines;
|
|
15
|
+
exports.isRangesOverlap = isRangesOverlap;
|
|
16
|
+
exports.getTemplateTokens = getTemplateTokens;
|
|
17
|
+
const parser_1 = require("@html-eslint/parser");
|
|
18
|
+
/**
|
|
19
|
+
* @param {TagNode | ScriptTagNode | StyleTagNode} node
|
|
20
|
+
* @param {string} key
|
|
21
|
+
* @returns {AttributeNode | undefined}
|
|
22
|
+
*/
|
|
23
|
+
function findAttr(node, key) {
|
|
24
|
+
return node.attributes.find((attr) => attr.key && attr.key.value.toLowerCase() === key.toLowerCase());
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Checks whether a node's attributes is empty or not.
|
|
28
|
+
* @param {TagNode | ScriptTagNode | StyleTagNode} node
|
|
29
|
+
* @returns {boolean}
|
|
30
|
+
*/
|
|
31
|
+
function isAttributesEmpty(node) {
|
|
32
|
+
return !node.attributes || node.attributes.length <= 0;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Checks whether a node's all tokens are on the same line or not.
|
|
36
|
+
* @param {AnyNode} node A node to check
|
|
37
|
+
* @returns {boolean} `true` if a node's tokens are on the same line, otherwise `false`.
|
|
38
|
+
*/
|
|
39
|
+
function isNodeTokensOnSameLine(node) {
|
|
40
|
+
return node.loc.start.line === node.loc.end.line;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* @param {Range} rangeA
|
|
45
|
+
* @param {Range} rangeB
|
|
46
|
+
* @returns {boolean}
|
|
47
|
+
*/
|
|
48
|
+
function isRangesOverlap(rangeA, rangeB) {
|
|
49
|
+
return rangeA[0] < rangeB[1] && rangeB[0] < rangeA[1];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* @param {(TextNode | CommentContentNode)['templates']} templates
|
|
53
|
+
* @param {Range} range
|
|
54
|
+
* @returns {boolean}
|
|
55
|
+
*/
|
|
56
|
+
function isOverlapWithTemplates(templates, range) {
|
|
57
|
+
return templates
|
|
58
|
+
.filter((template) => template.isTemplate)
|
|
59
|
+
.some((template) => isRangesOverlap(template.range, range));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
*
|
|
63
|
+
* @param {TextNode | CommentContentNode} node
|
|
64
|
+
* @returns {LineNode[]}
|
|
65
|
+
*/
|
|
66
|
+
function splitToLineNodes(node) {
|
|
67
|
+
let start = node.range[0];
|
|
68
|
+
let line = node.loc.start.line;
|
|
69
|
+
const startCol = node.loc.start.column;
|
|
70
|
+
/**
|
|
71
|
+
* @type {LineNode[]}
|
|
72
|
+
*/
|
|
73
|
+
const lineNodes = [];
|
|
74
|
+
const templates = node.templates || [];
|
|
75
|
+
/**
|
|
76
|
+
*
|
|
77
|
+
* @param {import("../../types").Range} range
|
|
78
|
+
*/
|
|
79
|
+
function shouldSkipIndentCheck(range) {
|
|
80
|
+
const overlappedTemplates = templates.filter((template) => template.isTemplate && isRangesOverlap(template.range, range));
|
|
81
|
+
const isLineInTemplate = overlappedTemplates.some((template) => {
|
|
82
|
+
return template.range[0] <= range[0] && template.range[1] >= range[1];
|
|
83
|
+
});
|
|
84
|
+
if (isLineInTemplate) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
const isLineBeforeTemplate = overlappedTemplates.some((template) => {
|
|
88
|
+
return template.range[0] <= range[0] && template.range[1] <= range[1];
|
|
89
|
+
});
|
|
90
|
+
if (isLineBeforeTemplate) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
const isLineAfterTemplate = overlappedTemplates.some((template) => {
|
|
94
|
+
return template.range[1] <= range[0];
|
|
95
|
+
});
|
|
96
|
+
if (isLineAfterTemplate) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
node.value.split("\n").forEach((value, index) => {
|
|
102
|
+
const columnStart = index === 0 ? startCol : 0;
|
|
103
|
+
/**
|
|
104
|
+
* @type {import("../../types").Range}
|
|
105
|
+
*/
|
|
106
|
+
const range = [start, start + value.length];
|
|
107
|
+
const loc = {
|
|
108
|
+
start: {
|
|
109
|
+
line,
|
|
110
|
+
column: columnStart,
|
|
111
|
+
},
|
|
112
|
+
end: {
|
|
113
|
+
line,
|
|
114
|
+
column: columnStart + value.length,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* @type {LineNode}
|
|
119
|
+
*/
|
|
120
|
+
const lineNode = {
|
|
121
|
+
type: "Line",
|
|
122
|
+
value,
|
|
123
|
+
range,
|
|
124
|
+
loc,
|
|
125
|
+
skipIndentCheck: shouldSkipIndentCheck(range),
|
|
126
|
+
};
|
|
127
|
+
start += value.length + 1;
|
|
128
|
+
line += 1;
|
|
129
|
+
lineNodes.push(lineNode);
|
|
130
|
+
});
|
|
131
|
+
return lineNodes;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get location between two nodes.
|
|
135
|
+
* @param {BaseNode} before A node placed in before
|
|
136
|
+
* @param {BaseNode} after A node placed in after
|
|
137
|
+
* @returns {Location} location between two nodes.
|
|
138
|
+
*/
|
|
139
|
+
function getLocBetween(before, after) {
|
|
140
|
+
return {
|
|
141
|
+
start: before.loc.end,
|
|
142
|
+
end: after.loc.start,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* @param {AttributeValueNode} node
|
|
147
|
+
* @return {boolean}
|
|
148
|
+
*/
|
|
149
|
+
function isExpressionInTemplate(node) {
|
|
150
|
+
if (node.type === parser_1.NODE_TYPES.AttributeValue) {
|
|
151
|
+
return node.value.indexOf("${") === 0;
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* @param {AnyNode} node
|
|
157
|
+
* @returns {node is TagNode}
|
|
158
|
+
*/
|
|
159
|
+
function isTag(node) {
|
|
160
|
+
return node.type === parser_1.NODE_TYPES.Tag;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* @param {AnyNode} node
|
|
164
|
+
* @returns {node is CommentNode}
|
|
165
|
+
*/
|
|
166
|
+
function isComment(node) {
|
|
167
|
+
return node.type === parser_1.NODE_TYPES.Comment;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* @param {AnyNode} node
|
|
171
|
+
* @returns {node is TextNode}
|
|
172
|
+
*/
|
|
173
|
+
function isText(node) {
|
|
174
|
+
return node.type === parser_1.NODE_TYPES.Text;
|
|
175
|
+
}
|
|
176
|
+
const lineBreakPattern = /\r\n|[\r\n\u2028\u2029]/u;
|
|
177
|
+
const lineEndingPattern = new RegExp(lineBreakPattern.source, "gu");
|
|
178
|
+
/**
|
|
179
|
+
* @param {string} source
|
|
180
|
+
* @returns {string[]}
|
|
181
|
+
*/
|
|
182
|
+
function codeToLines(source) {
|
|
183
|
+
return source.split(lineEndingPattern);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
*
|
|
187
|
+
* @param {AnyToken[]} tokens
|
|
188
|
+
* @returns {((CommentContentNode | TextNode)['templates'][number])[]}
|
|
189
|
+
*/
|
|
190
|
+
function getTemplateTokens(tokens) {
|
|
191
|
+
return ([]
|
|
192
|
+
.concat(...tokens
|
|
193
|
+
// @ts-ignore
|
|
194
|
+
.map((token) => token["templates"] || []))
|
|
195
|
+
// @ts-ignore
|
|
196
|
+
.filter((token) => token.isTemplate));
|
|
197
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.messages = void 0;
|
|
4
|
+
exports.messages = {
|
|
5
|
+
removeClass: "Remove the slds-button_icon-inverse class from the modal close button in components that use the SLDS modal blueprint.",
|
|
6
|
+
changeVariant: "Change the variant attribute value from bare-inverse to bare in <lightning-button-icon> or <lightning-icon>.",
|
|
7
|
+
removeVariant: "Remove the variant attribute from the <lightning-icon> component inside the <button> element.",
|
|
8
|
+
ensureButtonClasses: "Add or move slds-button and slds-button_icon to the class attribute of the <button> element or <lightning-button-icon> component.",
|
|
9
|
+
ensureSizeAttribute: "To size icons properly, set the size attribute to large in the <lightning-icon> and <lightning-button-icon> components.",
|
|
10
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export * from '@salesforce-ux/sds-metadata';
|
|
2
|
+
/**
|
|
3
|
+
* Enum representing all available metadata JSON files
|
|
4
|
+
*/
|
|
5
|
+
export declare enum MetadataFile {
|
|
6
|
+
AURA_TO_LWC_TOKENS = "auraToLwcTokensMapping.json",
|
|
7
|
+
BEM_NAMING = "bem-naming.json",
|
|
8
|
+
DEPRECATED_CLASSES = "deprecatedClasses.json",
|
|
9
|
+
DEPRECATED_STYLING_HOOKS = "deprecatedStylingHooks.json",
|
|
10
|
+
GLOBAL_STYLING_HOOKS = "globalStylingHooks.metadata.json",
|
|
11
|
+
ICONS = "icons.json",
|
|
12
|
+
LWC_TO_SLDS = "lwc-to-slds.json",
|
|
13
|
+
SLDS_CLASSES = "sldsClasses.json",
|
|
14
|
+
SLDS_PLUS_CLASSES = "sldsPlusClasses.json",
|
|
15
|
+
SLDS_PLUS_STYLING_HOOKS = "sldsPlusStylingHooks.json",
|
|
16
|
+
SLDS_STYLING_HOOKS = "sldsStylingHooks.json",
|
|
17
|
+
VALUE_TO_STYLING_HOOKS_COSMOS = "valueToStylingHooks.cosmos.json",
|
|
18
|
+
VALUE_TO_STYLING_HOOKS_SLDS = "valueToStylingHooks.slds.json"
|
|
19
|
+
}
|
|
20
|
+
export declare class MetadataService {
|
|
21
|
+
private static instance;
|
|
22
|
+
private readonly metadataPath;
|
|
23
|
+
private cache;
|
|
24
|
+
private constructor();
|
|
25
|
+
/**
|
|
26
|
+
* Get the singleton instance of MetadataService
|
|
27
|
+
*/
|
|
28
|
+
static getInstance(): MetadataService;
|
|
29
|
+
/**
|
|
30
|
+
* Loads a metadata file from the package
|
|
31
|
+
* @param filePath - Path to the metadata file relative to the metadata package root
|
|
32
|
+
* @returns Parsed metadata as a JavaScript object/array
|
|
33
|
+
*/
|
|
34
|
+
private loadMetadata;
|
|
35
|
+
/**
|
|
36
|
+
* Loads multiple metadata files from the package
|
|
37
|
+
* @param filePaths - Array of paths to metadata files relative to the metadata package root
|
|
38
|
+
* @returns Array of parsed metadata as JavaScript objects/arrays
|
|
39
|
+
*/
|
|
40
|
+
private loadMultipleMetadata;
|
|
41
|
+
/**
|
|
42
|
+
* Static method to load a single metadata file
|
|
43
|
+
* @param file - The metadata file to load
|
|
44
|
+
* @returns Parsed metadata as a JavaScript object/array
|
|
45
|
+
*/
|
|
46
|
+
static loadMetadata<T>(file: MetadataFile): T;
|
|
47
|
+
/**
|
|
48
|
+
* Static method to load multiple metadata files
|
|
49
|
+
* @param files - Array of metadata files to load
|
|
50
|
+
* @returns Array of parsed metadata as JavaScript objects/arrays
|
|
51
|
+
*/
|
|
52
|
+
static loadMultipleMetadata<T>(files: MetadataFile[]): T[];
|
|
53
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.MetadataService = exports.MetadataFile = void 0;
|
|
18
|
+
__exportStar(require("@salesforce-ux/sds-metadata"), exports);
|
|
19
|
+
const path_1 = require("path");
|
|
20
|
+
const fs_1 = require("fs");
|
|
21
|
+
/**
|
|
22
|
+
* Enum representing all available metadata JSON files
|
|
23
|
+
*/
|
|
24
|
+
var MetadataFile;
|
|
25
|
+
(function (MetadataFile) {
|
|
26
|
+
MetadataFile["AURA_TO_LWC_TOKENS"] = "auraToLwcTokensMapping.json";
|
|
27
|
+
MetadataFile["BEM_NAMING"] = "bem-naming.json";
|
|
28
|
+
MetadataFile["DEPRECATED_CLASSES"] = "deprecatedClasses.json";
|
|
29
|
+
MetadataFile["DEPRECATED_STYLING_HOOKS"] = "deprecatedStylingHooks.json";
|
|
30
|
+
MetadataFile["GLOBAL_STYLING_HOOKS"] = "globalStylingHooks.metadata.json";
|
|
31
|
+
MetadataFile["ICONS"] = "icons.json";
|
|
32
|
+
MetadataFile["LWC_TO_SLDS"] = "lwc-to-slds.json";
|
|
33
|
+
MetadataFile["SLDS_CLASSES"] = "sldsClasses.json";
|
|
34
|
+
MetadataFile["SLDS_PLUS_CLASSES"] = "sldsPlusClasses.json";
|
|
35
|
+
MetadataFile["SLDS_PLUS_STYLING_HOOKS"] = "sldsPlusStylingHooks.json";
|
|
36
|
+
MetadataFile["SLDS_STYLING_HOOKS"] = "sldsStylingHooks.json";
|
|
37
|
+
MetadataFile["VALUE_TO_STYLING_HOOKS_COSMOS"] = "valueToStylingHooks.cosmos.json";
|
|
38
|
+
MetadataFile["VALUE_TO_STYLING_HOOKS_SLDS"] = "valueToStylingHooks.slds.json";
|
|
39
|
+
})(MetadataFile || (exports.MetadataFile = MetadataFile = {}));
|
|
40
|
+
class MetadataService {
|
|
41
|
+
static instance;
|
|
42
|
+
metadataPath;
|
|
43
|
+
cache = new Map();
|
|
44
|
+
constructor() {
|
|
45
|
+
// Create a require function for the current module
|
|
46
|
+
//const require = createRequire(import.meta.url);
|
|
47
|
+
// Resolve the path to @salesforce-ux/sds-metadata package
|
|
48
|
+
this.metadataPath = require.resolve('@salesforce-ux/sds-metadata');
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get the singleton instance of MetadataService
|
|
52
|
+
*/
|
|
53
|
+
static getInstance() {
|
|
54
|
+
if (!MetadataService.instance) {
|
|
55
|
+
MetadataService.instance = new MetadataService();
|
|
56
|
+
}
|
|
57
|
+
return MetadataService.instance;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Loads a metadata file from the package
|
|
61
|
+
* @param filePath - Path to the metadata file relative to the metadata package root
|
|
62
|
+
* @returns Parsed metadata as a JavaScript object/array
|
|
63
|
+
*/
|
|
64
|
+
loadMetadata(filePath) {
|
|
65
|
+
try {
|
|
66
|
+
// Check cache first
|
|
67
|
+
if (this.cache.has(filePath)) {
|
|
68
|
+
return this.cache.get(filePath);
|
|
69
|
+
}
|
|
70
|
+
const fullPath = (0, path_1.join)(this.metadataPath, '..', filePath);
|
|
71
|
+
const fileContent = (0, fs_1.readFileSync)(fullPath, 'utf8');
|
|
72
|
+
const data = JSON.parse(fileContent);
|
|
73
|
+
// Cache the result
|
|
74
|
+
this.cache.set(filePath, data);
|
|
75
|
+
return data;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
throw new Error(`Failed to load metadata file: ${filePath}. Error: ${error.message}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Loads multiple metadata files from the package
|
|
83
|
+
* @param filePaths - Array of paths to metadata files relative to the metadata package root
|
|
84
|
+
* @returns Array of parsed metadata as JavaScript objects/arrays
|
|
85
|
+
*/
|
|
86
|
+
loadMultipleMetadata(filePaths) {
|
|
87
|
+
return filePaths.map(filePath => this.loadMetadata(filePath));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Static method to load a single metadata file
|
|
91
|
+
* @param file - The metadata file to load
|
|
92
|
+
* @returns Parsed metadata as a JavaScript object/array
|
|
93
|
+
*/
|
|
94
|
+
static loadMetadata(file) {
|
|
95
|
+
return MetadataService.getInstance().loadMetadata(file);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Static method to load multiple metadata files
|
|
99
|
+
* @param files - Array of metadata files to load
|
|
100
|
+
* @returns Array of parsed metadata as JavaScript objects/arrays
|
|
101
|
+
*/
|
|
102
|
+
static loadMultipleMetadata(files) {
|
|
103
|
+
return MetadataService.getInstance().loadMultipleMetadata(files);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.MetadataService = MetadataService;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce-ux/eslint-plugin-slds",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7-alpha.0",
|
|
4
4
|
"main": "build/index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"build/*",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@html-eslint/eslint-plugin": "^0.34.0",
|
|
22
22
|
"@html-eslint/parser": "^0.34.0",
|
|
23
|
+
"@salesforce-ux/sds-metadata": "~0.0.1-alpha.3",
|
|
23
24
|
"eslint": "^8.0.0"
|
|
24
25
|
},
|
|
25
26
|
"repository": {
|