ember-codemod-remove-ember-css-modules 4.0.3 → 4.0.5
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,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
|
2
1
|
import { readFileSync } from 'node:fs';
|
|
3
2
|
import { join } from 'node:path';
|
|
4
3
|
import { AST } from '@codemod-utils/ast-javascript';
|
|
@@ -20,22 +19,25 @@ function removeTemplateOnlyComponentMethod(file, data) {
|
|
|
20
19
|
const traverse = AST.traverse(data.isTypeScript);
|
|
21
20
|
const ast = traverse(file, {
|
|
22
21
|
visitCallExpression(path) {
|
|
23
|
-
|
|
22
|
+
// @ts-expect-error: Incorrect type
|
|
23
|
+
if (path.node.callee.name !== 'templateOnlyComponent') {
|
|
24
24
|
return false;
|
|
25
25
|
}
|
|
26
26
|
const superClass = AST.builders.identifier('Component');
|
|
27
27
|
if (data.isTypeScript) {
|
|
28
|
-
|
|
28
|
+
// @ts-expect-error: Incorrect type
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
30
|
+
superClass.typeAnnotation = path.node.typeParameters;
|
|
29
31
|
}
|
|
30
32
|
return AST.builders.classExpression(null, AST.builders.classBody([
|
|
31
33
|
AST.builders.classProperty(AST.builders.identifier('styles'), AST.builders.identifier('styles')),
|
|
32
34
|
]), superClass);
|
|
33
35
|
},
|
|
34
36
|
visitImportDeclaration(path) {
|
|
35
|
-
if (path.
|
|
37
|
+
if (path.node.source.value !== '@ember/component/template-only') {
|
|
36
38
|
return false;
|
|
37
39
|
}
|
|
38
|
-
const defaultImport = path.
|
|
40
|
+
const defaultImport = path.node.specifiers?.find((specifier) => specifier.type === 'ImportDefaultSpecifier');
|
|
39
41
|
if (defaultImport?.local?.name !== 'templateOnlyComponent') {
|
|
40
42
|
return false;
|
|
41
43
|
}
|
|
@@ -55,6 +57,7 @@ function importStylesInClass(file, data) {
|
|
|
55
57
|
if (!lastImportDeclarationPath) {
|
|
56
58
|
lastImportDeclarationPath = path;
|
|
57
59
|
// @ts-expect-error: Incorrect type
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
58
61
|
}
|
|
59
62
|
else if (path.node.start > lastImportDeclarationPath.node.start) {
|
|
60
63
|
lastImportDeclarationPath = path;
|
|
@@ -64,9 +67,12 @@ function importStylesInClass(file, data) {
|
|
|
64
67
|
});
|
|
65
68
|
// Append the styles import
|
|
66
69
|
// @ts-expect-error: Incorrect type
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
67
71
|
const nodes = ast.program.body;
|
|
68
72
|
// @ts-expect-error: Incorrect type
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
69
74
|
const index = lastImportDeclarationPath?.name ?? -1;
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
70
76
|
nodes.splice(index + 1, 0, AST.builders.importDeclaration([AST.builders.importDefaultSpecifier(AST.builders.identifier('styles'))], AST.builders.literal(`./${data.fileName}.css`)));
|
|
71
77
|
return AST.print(ast);
|
|
72
78
|
}
|
|
@@ -1,27 +1,19 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/explicit-function-return-type, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
|
2
1
|
import { readFileSync } from 'node:fs';
|
|
3
2
|
import { join } from 'node:path';
|
|
4
3
|
import { AST } from '@codemod-utils/ast-template';
|
|
5
4
|
import { createFiles } from '@codemod-utils/files';
|
|
6
5
|
function sanitizeClassAndLocalClassAttributes(file) {
|
|
7
6
|
function removeAttributeWithoutValue(attributeName, attributes) {
|
|
8
|
-
const attributeIndex = attributes.findIndex(
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
const attributeIndex = attributes.findIndex((attribute) => {
|
|
8
|
+
return attribute.name === attributeName;
|
|
9
|
+
});
|
|
11
10
|
if (attributeIndex === -1) {
|
|
12
11
|
return;
|
|
13
12
|
}
|
|
14
13
|
const attribute = attributes[attributeIndex];
|
|
15
|
-
// @ts-expect-error: Incorrect type
|
|
16
|
-
if (attribute.isValueless) {
|
|
17
|
-
attributes.splice(attributeIndex, 1);
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
// @ts-expect-error: Incorrect type
|
|
21
14
|
if (attribute.value.type !== 'TextNode') {
|
|
22
15
|
return;
|
|
23
16
|
}
|
|
24
|
-
// @ts-expect-error: Incorrect type
|
|
25
17
|
const attributeValue = attribute.value.chars.trim();
|
|
26
18
|
if (attributeValue === '') {
|
|
27
19
|
attributes.splice(attributeIndex, 1);
|
|
@@ -44,8 +36,12 @@ function mergeClassAndLocalClassAttributes(file) {
|
|
|
44
36
|
ElementNode(node) {
|
|
45
37
|
// Check that both class and local-class attributes exist
|
|
46
38
|
const { attributes } = node;
|
|
47
|
-
const localClassAttributeIndex = attributes.findIndex((attribute) =>
|
|
48
|
-
|
|
39
|
+
const localClassAttributeIndex = attributes.findIndex((attribute) => {
|
|
40
|
+
return attribute.name === 'local-class';
|
|
41
|
+
});
|
|
42
|
+
const classAttributeIndex = attributes.findIndex((attribute) => {
|
|
43
|
+
return attribute.name === 'class';
|
|
44
|
+
});
|
|
49
45
|
if (localClassAttributeIndex === -1 || classAttributeIndex === -1) {
|
|
50
46
|
return;
|
|
51
47
|
}
|
|
@@ -91,20 +87,22 @@ function removeLocalClassHelpers(file) {
|
|
|
91
87
|
*/
|
|
92
88
|
function canRemoveLocalClassHelper(path) {
|
|
93
89
|
// @ts-expect-error: Incorrect type
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
94
91
|
const hasFromArgument = path.hash.pairs.some((pair) => pair.key === 'from');
|
|
95
92
|
if (hasFromArgument) {
|
|
96
|
-
throw new RangeError(
|
|
97
|
-
// @ts-expect-error: Incorrect type
|
|
98
|
-
`Unable to handle the {{local-class}} helper's \`from\` key. See lines ${path.loc.start.line}-${path.loc.end.line}.`);
|
|
93
|
+
throw new RangeError(`Unable to handle the {{local-class}} helper's \`from\` key. See lines ${path.loc.start.line}-${path.loc.end.line}.`);
|
|
99
94
|
}
|
|
100
95
|
// @ts-expect-error: Incorrect type
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
101
97
|
const param = path.params[0];
|
|
102
98
|
if (param === undefined) {
|
|
103
99
|
return true;
|
|
104
100
|
}
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
105
102
|
if (param.type !== 'StringLiteral') {
|
|
106
103
|
return false;
|
|
107
104
|
}
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
108
106
|
const value = param.value.trim();
|
|
109
107
|
return value === '';
|
|
110
108
|
}
|
|
@@ -116,7 +114,7 @@ function removeLocalClassHelpers(file) {
|
|
|
116
114
|
return;
|
|
117
115
|
}
|
|
118
116
|
const hasLocalClassHelper = node.value.type === 'MustacheStatement' &&
|
|
119
|
-
|
|
117
|
+
node.value.path.type === 'PathExpression' &&
|
|
120
118
|
node.value.path.original === 'local-class';
|
|
121
119
|
if (!hasLocalClassHelper) {
|
|
122
120
|
return;
|
|
@@ -125,23 +123,32 @@ function removeLocalClassHelpers(file) {
|
|
|
125
123
|
return null;
|
|
126
124
|
}
|
|
127
125
|
// @ts-expect-error: Incorrect type
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
128
127
|
const param = node.value.params[0];
|
|
128
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
129
129
|
if (param.type !== 'StringLiteral') {
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
132
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
132
133
|
const localClassNames = param.value.trim().split(/\s+/);
|
|
134
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
133
135
|
if (localClassNames.length === 1) {
|
|
134
|
-
node.value = AST.builders.mustache(
|
|
136
|
+
node.value = AST.builders.mustache(
|
|
137
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
138
|
+
AST.builders.path(`this.styles.${localClassNames[0]}`));
|
|
135
139
|
return;
|
|
136
140
|
}
|
|
137
141
|
node.value = AST.builders.mustache(AST.builders.path('local'), [
|
|
138
142
|
AST.builders.path('this.styles'),
|
|
143
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
139
144
|
...localClassNames.map(AST.builders.string),
|
|
140
145
|
]);
|
|
146
|
+
return;
|
|
141
147
|
},
|
|
142
148
|
MustacheStatement(node) {
|
|
143
|
-
|
|
144
|
-
node.path.original
|
|
149
|
+
const hasLocalClassHelper = node.path.type === 'PathExpression' &&
|
|
150
|
+
node.path.original === 'local-class';
|
|
151
|
+
if (!hasLocalClassHelper) {
|
|
145
152
|
return;
|
|
146
153
|
}
|
|
147
154
|
const param = node.params[0];
|
|
@@ -158,8 +165,8 @@ function removeLocalClassHelpers(file) {
|
|
|
158
165
|
]);
|
|
159
166
|
},
|
|
160
167
|
SubExpression(node) {
|
|
161
|
-
|
|
162
|
-
|
|
168
|
+
const hasLocalClassHelper = node.path.type === 'PathExpression' &&
|
|
169
|
+
node.path.original === 'local-class';
|
|
163
170
|
if (!hasLocalClassHelper) {
|
|
164
171
|
return;
|
|
165
172
|
}
|
|
@@ -183,60 +190,56 @@ function removeLocalClassHelpers(file) {
|
|
|
183
190
|
return AST.print(ast);
|
|
184
191
|
}
|
|
185
192
|
function removeLocalClassAttributes(file) {
|
|
186
|
-
function
|
|
187
|
-
|
|
188
|
-
switch (param.type) {
|
|
193
|
+
function transformExpression(expression) {
|
|
194
|
+
switch (expression.type) {
|
|
189
195
|
case 'StringLiteral': {
|
|
190
|
-
|
|
191
|
-
const localClassNames = param.value.trim().split(/\s+/);
|
|
196
|
+
const localClassNames = expression.value.trim().split(/\s+/);
|
|
192
197
|
if (localClassNames.length === 1) {
|
|
193
|
-
|
|
194
|
-
param.value = localClassNames[0];
|
|
198
|
+
expression.value = localClassNames[0];
|
|
195
199
|
}
|
|
196
200
|
else {
|
|
197
|
-
|
|
201
|
+
expression = AST.builders.sexpr('array', localClassNames.map(AST.builders.string));
|
|
198
202
|
}
|
|
199
203
|
break;
|
|
200
204
|
}
|
|
201
205
|
case 'SubExpression': {
|
|
202
|
-
|
|
203
|
-
|
|
206
|
+
if (expression.path.type !== 'PathExpression') {
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
switch (expression.path.original) {
|
|
204
210
|
case 'if':
|
|
205
211
|
case 'unless': {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
// @ts-expect-error: Incorrect type
|
|
209
|
-
param = AST.builders.sexpr(param.path.original, subparams);
|
|
212
|
+
const subparams = expression.params.map(transformExpression);
|
|
213
|
+
expression = AST.builders.sexpr(expression.path.original, subparams);
|
|
210
214
|
break;
|
|
211
215
|
}
|
|
212
216
|
}
|
|
213
217
|
break;
|
|
214
218
|
}
|
|
215
219
|
}
|
|
216
|
-
return
|
|
220
|
+
return expression;
|
|
217
221
|
}
|
|
218
|
-
// @ts-expect-error: Incorrect type
|
|
219
222
|
function transformPart(part) {
|
|
220
|
-
// @ts-expect-error: Incorrect type
|
|
221
223
|
switch (part.type) {
|
|
222
224
|
case 'MustacheStatement': {
|
|
223
|
-
|
|
225
|
+
if (part.path.type === 'SubExpression') {
|
|
226
|
+
return AST.builders.mustache(AST.builders.path('get'), [
|
|
227
|
+
AST.builders.path('this.styles'),
|
|
228
|
+
part.path,
|
|
229
|
+
]);
|
|
230
|
+
}
|
|
224
231
|
switch (part.path.original) {
|
|
225
232
|
case 'concat': {
|
|
226
233
|
function hasPathExpression(params) {
|
|
227
|
-
// @ts-expect-error: Incorrect type
|
|
228
234
|
return params.some((param) => param.type === 'PathExpression');
|
|
229
235
|
}
|
|
230
|
-
// @ts-expect-error: Incorrect type
|
|
231
236
|
if (hasPathExpression(part.params)) {
|
|
232
237
|
return AST.builders.mustache(AST.builders.path('get'), [
|
|
233
238
|
AST.builders.path('this.styles'),
|
|
234
|
-
// @ts-expect-error: Incorrect type
|
|
235
239
|
AST.builders.sexpr(part.path.original, part.params),
|
|
236
240
|
]);
|
|
237
241
|
}
|
|
238
|
-
|
|
239
|
-
const params = part.params.map(transformParam);
|
|
242
|
+
const params = part.params.map(transformExpression);
|
|
240
243
|
return AST.builders.mustache('local', [
|
|
241
244
|
AST.builders.path('this.styles'),
|
|
242
245
|
...params,
|
|
@@ -244,25 +247,21 @@ function removeLocalClassAttributes(file) {
|
|
|
244
247
|
}
|
|
245
248
|
case 'if':
|
|
246
249
|
case 'unless': {
|
|
247
|
-
|
|
248
|
-
const params = part.params.map(transformParam);
|
|
250
|
+
const params = part.params.map(transformExpression);
|
|
249
251
|
return AST.builders.mustache('local', [
|
|
250
252
|
AST.builders.path('this.styles'),
|
|
251
|
-
// @ts-expect-error: Incorrect type
|
|
252
253
|
AST.builders.sexpr(part.path.original, params),
|
|
253
254
|
]);
|
|
254
255
|
}
|
|
255
256
|
default: {
|
|
256
257
|
return AST.builders.mustache(AST.builders.path('get'), [
|
|
257
258
|
AST.builders.path('this.styles'),
|
|
258
|
-
// @ts-expect-error: Incorrect type
|
|
259
259
|
part.path,
|
|
260
260
|
]);
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
264
|
case 'TextNode': {
|
|
265
|
-
// @ts-expect-error: Incorrect type
|
|
266
265
|
const value = part.chars.trim();
|
|
267
266
|
if (value === '') {
|
|
268
267
|
return part;
|
|
@@ -281,10 +280,8 @@ function removeLocalClassAttributes(file) {
|
|
|
281
280
|
function transformParts(parts) {
|
|
282
281
|
const numParts = parts.length;
|
|
283
282
|
return parts.reduce((accumulator, part, index) => {
|
|
284
|
-
// @ts-expect-error: Incorrect type
|
|
285
283
|
accumulator.push(transformPart(part));
|
|
286
284
|
if (index < numParts - 1) {
|
|
287
|
-
// @ts-expect-error: Incorrect type
|
|
288
285
|
accumulator.push(AST.builders.text(' '));
|
|
289
286
|
}
|
|
290
287
|
return accumulator;
|
|
@@ -310,13 +307,11 @@ function removeLocalClassAttributes(file) {
|
|
|
310
307
|
}
|
|
311
308
|
case 'MustacheStatement': {
|
|
312
309
|
localClassAttribute.name = 'class';
|
|
313
|
-
// @ts-expect-error: Incorrect type
|
|
314
310
|
localClassAttribute.value = transformPart(localClassAttribute.value);
|
|
315
311
|
break;
|
|
316
312
|
}
|
|
317
313
|
case 'TextNode': {
|
|
318
314
|
localClassAttribute.name = 'class';
|
|
319
|
-
// @ts-expect-error: Incorrect type
|
|
320
315
|
localClassAttribute.value = transformPart(localClassAttribute.value);
|
|
321
316
|
break;
|
|
322
317
|
}
|
|
@@ -327,17 +322,13 @@ function removeLocalClassAttributes(file) {
|
|
|
327
322
|
return;
|
|
328
323
|
}
|
|
329
324
|
node.key = 'class';
|
|
330
|
-
const newValue =
|
|
331
|
-
// @ts-expect-error: Incorrect type
|
|
325
|
+
const newValue = transformExpression(node.value);
|
|
332
326
|
if (newValue.type === 'StringLiteral') {
|
|
333
|
-
node.value = AST.builders.path(
|
|
334
|
-
// @ts-expect-error: Incorrect type
|
|
335
|
-
`this.styles.${newValue.value}`);
|
|
327
|
+
node.value = AST.builders.path(`this.styles.${newValue.value}`);
|
|
336
328
|
return;
|
|
337
329
|
}
|
|
338
330
|
node.value = AST.builders.sexpr('local', [
|
|
339
331
|
AST.builders.path('this.styles'),
|
|
340
|
-
// @ts-expect-error: Incorrect type
|
|
341
332
|
newValue,
|
|
342
333
|
]);
|
|
343
334
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ember-codemod-remove-ember-css-modules",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.5",
|
|
4
4
|
"description": "Codemod to replace ember-css-modules with embroider-css-modules",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"codemod",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"dist"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@codemod-utils/ast-javascript": "^3.0.
|
|
28
|
-
"@codemod-utils/ast-template": "^3.0
|
|
27
|
+
"@codemod-utils/ast-javascript": "^3.0.2",
|
|
28
|
+
"@codemod-utils/ast-template": "^3.1.0",
|
|
29
29
|
"@codemod-utils/blueprints": "^3.1.0",
|
|
30
30
|
"@codemod-utils/ember": "^4.1.1",
|
|
31
31
|
"@codemod-utils/files": "^4.0.1",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"prettier": "^3.8.3",
|
|
43
43
|
"typescript": "^5.9.3",
|
|
44
44
|
"@shared-configs/eslint-config-node": "0.0.0",
|
|
45
|
-
"@shared-configs/
|
|
46
|
-
"@shared-configs/
|
|
45
|
+
"@shared-configs/prettier": "0.0.0",
|
|
46
|
+
"@shared-configs/typescript": "0.0.0"
|
|
47
47
|
},
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": "22.* || >= 24"
|