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
- if (path.value.callee.name !== 'templateOnlyComponent') {
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
- superClass.typeAnnotation = path.value.typeParameters;
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.value.source.value !== '@ember/component/template-only') {
37
+ if (path.node.source.value !== '@ember/component/template-only') {
36
38
  return false;
37
39
  }
38
- const defaultImport = path.value.specifiers.find((specifier) => specifier.type === 'ImportDefaultSpecifier');
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
- // @ts-expect-error: Incorrect type
10
- (attribute) => attribute.name === attributeName);
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) => attribute.name === 'local-class');
48
- const classAttributeIndex = attributes.findIndex((attribute) => attribute.name === 'class');
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
- // @ts-expect-error: Incorrect type
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(AST.builders.path(`this.styles.${localClassNames[0]}`));
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
- if (node.path.type !== 'PathExpression' ||
144
- node.path.original !== 'local-class') {
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
- // @ts-expect-error: Incorrect type
162
- const hasLocalClassHelper = node.path.original === 'local-class';
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 transformParam(param) {
187
- // @ts-expect-error: Incorrect type
188
- switch (param.type) {
193
+ function transformExpression(expression) {
194
+ switch (expression.type) {
189
195
  case 'StringLiteral': {
190
- // @ts-expect-error: Incorrect type
191
- const localClassNames = param.value.trim().split(/\s+/);
196
+ const localClassNames = expression.value.trim().split(/\s+/);
192
197
  if (localClassNames.length === 1) {
193
- // @ts-expect-error: Incorrect type
194
- param.value = localClassNames[0];
198
+ expression.value = localClassNames[0];
195
199
  }
196
200
  else {
197
- param = AST.builders.sexpr('array', localClassNames.map(AST.builders.string));
201
+ expression = AST.builders.sexpr('array', localClassNames.map(AST.builders.string));
198
202
  }
199
203
  break;
200
204
  }
201
205
  case 'SubExpression': {
202
- // @ts-expect-error: Incorrect type
203
- switch (param.path.original) {
206
+ if (expression.path.type !== 'PathExpression') {
207
+ break;
208
+ }
209
+ switch (expression.path.original) {
204
210
  case 'if':
205
211
  case 'unless': {
206
- // @ts-expect-error: Incorrect type
207
- const subparams = param.params.map(transformParam);
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 param;
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
- // @ts-expect-error: Incorrect type
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
- // @ts-expect-error: Incorrect type
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
- // @ts-expect-error: Incorrect type
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 = transformParam(node.value);
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",
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.1",
28
- "@codemod-utils/ast-template": "^3.0.1",
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/typescript": "0.0.0",
46
- "@shared-configs/prettier": "0.0.0"
45
+ "@shared-configs/prettier": "0.0.0",
46
+ "@shared-configs/typescript": "0.0.0"
47
47
  },
48
48
  "engines": {
49
49
  "node": "22.* || >= 24"