ember-codemod-remove-global-styles 0.2.0 → 0.2.1

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 CHANGED
@@ -12,7 +12,7 @@ _Codemod to localize global styles_
12
12
  You must pass `--src` to indicate the location of your global stylesheet.
13
13
 
14
14
  ```sh
15
- ember-codemod-remove-global-styles --src app/assets/app.css
15
+ pnpx ember-codemod-remove-global-styles --src app/assets/app.css
16
16
  ```
17
17
 
18
18
  <details>
@@ -22,7 +22,7 @@ ember-codemod-remove-global-styles --src app/assets/app.css
22
22
  Pass `--root` to run the codemod somewhere else (i.e. not in the current directory).
23
23
 
24
24
  ```sh
25
- npx ember-codemod-remove-global-styles --root <path/to/your/project>
25
+ pnpx ember-codemod-remove-global-styles --root <path/to/your/project>
26
26
  ```
27
27
 
28
28
  </details>
@@ -13,6 +13,7 @@ export function updateProject(project, options) {
13
13
  let file = getFile(filePath);
14
14
  const data = {
15
15
  classToStyles: getClassToStyles(cssModuleFile),
16
+ isHbs: filePath.endsWith('.hbs'),
16
17
  };
17
18
  if (filePath.endsWith('.hbs')) {
18
19
  file = addLocalClasses(file, data);
@@ -29,6 +30,7 @@ export function updateProject(project, options) {
29
30
  let file = getFile(filePath);
30
31
  const data = {
31
32
  classToStyles: getClassToStyles(cssModuleFile),
33
+ isHbs: filePath.endsWith('.hbs'),
32
34
  };
33
35
  if (filePath.endsWith('.hbs')) {
34
36
  file = addLocalClasses(file, data);
@@ -1,11 +1,14 @@
1
1
  import { AST } from '@codemod-utils/ast-template';
2
2
  export class Processor {
3
- classToStyles;
3
+ args;
4
4
  constructor(args) {
5
- this.classToStyles = args.classToStyles;
5
+ this.args = args;
6
+ }
7
+ getLocalClass(className) {
8
+ return this.args.isHbs ? `this.styles.${className}` : `styles.${className}`;
6
9
  }
7
10
  isLocal(className) {
8
- return this.classToStyles.has(className);
11
+ return this.args.classToStyles.has(className);
9
12
  }
10
13
  processConcatStatement(nodeValue) {
11
14
  const parts = nodeValue.parts
@@ -63,7 +66,7 @@ export class Processor {
63
66
  if (classNames.length === 1) {
64
67
  const className = classNames[0];
65
68
  return this.isLocal(className)
66
- ? AST.builders.path(`styles.${className}`)
69
+ ? AST.builders.path(this.getLocalClass(className))
67
70
  : nodeValue;
68
71
  }
69
72
  const hasLocalClass = classNames.some(this.isLocal.bind(this));
@@ -73,7 +76,10 @@ export class Processor {
73
76
  const parts = classNames
74
77
  .map((className) => {
75
78
  return this.isLocal(className)
76
- ? [AST.builders.path(`styles.${className}`), AST.builders.string(' ')]
79
+ ? [
80
+ AST.builders.path(this.getLocalClass(className)),
81
+ AST.builders.string(' '),
82
+ ]
77
83
  : [AST.builders.string(`${className} `), AST.builders.string(' ')];
78
84
  })
79
85
  .flat();
@@ -81,6 +87,33 @@ export class Processor {
81
87
  parts.splice(-1);
82
88
  return AST.builders.sexpr(AST.builders.path('concat'), parts);
83
89
  }
90
+ processSubExpression(nodeValue) {
91
+ switch (nodeValue.path.type) {
92
+ case 'PathExpression': {
93
+ switch (nodeValue.path.original) {
94
+ case 'if':
95
+ case 'unless': {
96
+ if (nodeValue.params[1]?.type === 'StringLiteral') {
97
+ // @ts-expect-error: Incorrect type
98
+ nodeValue.params[1] = this.processStringLiteral(nodeValue.params[1]);
99
+ }
100
+ if (nodeValue.params[2]?.type === 'StringLiteral') {
101
+ // @ts-expect-error: Incorrect type
102
+ nodeValue.params[2] = this.processStringLiteral(nodeValue.params[2]);
103
+ }
104
+ break;
105
+ }
106
+ }
107
+ break;
108
+ }
109
+ case 'StringLiteral': {
110
+ // @ts-expect-error: Incorrect type
111
+ nodeValue.path = this.processStringLiteral(nodeValue.path);
112
+ break;
113
+ }
114
+ }
115
+ return nodeValue;
116
+ }
84
117
  processTextNode(nodeValue) {
85
118
  const classNames = nodeValue.chars.split(/\s+/).filter(Boolean);
86
119
  if (classNames.length === 0) {
@@ -89,7 +122,7 @@ export class Processor {
89
122
  if (classNames.length === 1) {
90
123
  const className = classNames[0];
91
124
  return this.isLocal(className)
92
- ? AST.builders.mustache(`styles.${className}`)
125
+ ? AST.builders.mustache(this.getLocalClass(className))
93
126
  : nodeValue;
94
127
  }
95
128
  const hasLocalClass = classNames.some(this.isLocal.bind(this));
@@ -99,7 +132,10 @@ export class Processor {
99
132
  const parts = classNames
100
133
  .map((className) => {
101
134
  return this.isLocal(className)
102
- ? [AST.builders.path(`styles.${className}`), AST.builders.string(' ')]
135
+ ? [
136
+ AST.builders.path(this.getLocalClass(className)),
137
+ AST.builders.string(' '),
138
+ ]
103
139
  : [AST.builders.string(className), AST.builders.string(' ')];
104
140
  })
105
141
  .flat();
@@ -23,6 +23,22 @@ export function addLocalClasses(file, data) {
23
23
  }
24
24
  }
25
25
  },
26
+ HashPair(node) {
27
+ if (node.key !== 'class') {
28
+ return;
29
+ }
30
+ switch (node.value.type) {
31
+ case 'StringLiteral': {
32
+ // @ts-expect-error: Incorrect type
33
+ node.value = processor.processStringLiteral(node.value);
34
+ break;
35
+ }
36
+ case 'SubExpression': {
37
+ node.value = processor.processSubExpression(node.value);
38
+ break;
39
+ }
40
+ }
41
+ },
26
42
  });
27
43
  return AST.print(ast);
28
44
  }
@@ -60,6 +60,35 @@ export class Processor {
60
60
  this.classes.add(className);
61
61
  });
62
62
  }
63
+ processSubExpression(nodeValue) {
64
+ switch (nodeValue.path.type) {
65
+ case 'PathExpression': {
66
+ switch (nodeValue.path.original) {
67
+ case 'if':
68
+ case 'unless': {
69
+ if (nodeValue.params[1]?.type === 'StringLiteral') {
70
+ this.processStringLiteral(nodeValue.params[1]);
71
+ }
72
+ if (nodeValue.params[2]?.type === 'StringLiteral') {
73
+ this.processStringLiteral(nodeValue.params[2]);
74
+ }
75
+ break;
76
+ }
77
+ default: {
78
+ const isLocalClass = nodeValue.path.original.startsWith('styles.');
79
+ if (!isLocalClass) {
80
+ this.errors.push(`Could not analyze {{${nodeValue.path.original}}} in template, line ${nodeValue.loc.start.line}.`);
81
+ }
82
+ }
83
+ }
84
+ break;
85
+ }
86
+ case 'StringLiteral': {
87
+ this.processStringLiteral(nodeValue.path);
88
+ break;
89
+ }
90
+ }
91
+ }
63
92
  processTextNode(nodeValue) {
64
93
  const classNames = extractClasses(nodeValue.chars);
65
94
  classNames.forEach((className) => {
@@ -23,6 +23,21 @@ export function getClasses(file) {
23
23
  }
24
24
  }
25
25
  },
26
+ HashPair(node) {
27
+ if (node.key !== 'class') {
28
+ return;
29
+ }
30
+ switch (node.value.type) {
31
+ case 'StringLiteral': {
32
+ processor.processStringLiteral(node.value);
33
+ break;
34
+ }
35
+ case 'SubExpression': {
36
+ processor.processSubExpression(node.value);
37
+ break;
38
+ }
39
+ }
40
+ },
26
41
  });
27
42
  return processor.print();
28
43
  }
@@ -1,3 +1,3 @@
1
1
  export function getModuleFilePath(filePath) {
2
- return filePath.replace(/\.(gjs|gts|hbs)$/, '.module.css');
2
+ return filePath.replace(/(.+)\.(gjs|gts|hbs)$/, '$1.module.css');
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-codemod-remove-global-styles",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Codemod to localize global styles",
5
5
  "keywords": [
6
6
  "codemod",