@nordcraft/search 1.0.43 → 1.0.45

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.
Files changed (80) hide show
  1. package/dist/problems.worker.js +4 -2
  2. package/dist/problems.worker.js.map +1 -1
  3. package/dist/rules/actions/legacyActionRule.fix.js +140 -0
  4. package/dist/rules/actions/legacyActionRule.fix.js.map +1 -0
  5. package/dist/rules/actions/legacyActionRule.js +3 -144
  6. package/dist/rules/actions/legacyActionRule.js.map +1 -1
  7. package/dist/rules/actions/legacyActionRule.test.js +4 -3
  8. package/dist/rules/actions/legacyActionRule.test.js.map +1 -1
  9. package/dist/rules/actions/noReferenceProjectActionRule.js +33 -40
  10. package/dist/rules/actions/noReferenceProjectActionRule.js.map +1 -1
  11. package/dist/rules/apis/noReferenceApiRule.js +7 -2
  12. package/dist/rules/apis/noReferenceApiRule.js.map +1 -1
  13. package/dist/rules/apis/noReferenceApiRule.test.js +65 -1
  14. package/dist/rules/apis/noReferenceApiRule.test.js.map +1 -1
  15. package/dist/rules/attributes/noReferenceAttributeRule.js +5 -1
  16. package/dist/rules/attributes/noReferenceAttributeRule.js.map +1 -1
  17. package/dist/rules/attributes/noReferenceAttributeRule.test.js +33 -1
  18. package/dist/rules/attributes/noReferenceAttributeRule.test.js.map +1 -1
  19. package/dist/rules/components/noReferenceComponentRule.js +18 -28
  20. package/dist/rules/components/noReferenceComponentRule.js.map +1 -1
  21. package/dist/rules/events/duplicateEventTriggerRule.js +2 -1
  22. package/dist/rules/events/duplicateEventTriggerRule.js.map +1 -1
  23. package/dist/rules/events/noReferenceEventRule.js +6 -2
  24. package/dist/rules/events/noReferenceEventRule.js.map +1 -1
  25. package/dist/rules/events/noReferenceEventRule.test.js +57 -1
  26. package/dist/rules/events/noReferenceEventRule.test.js.map +1 -1
  27. package/dist/rules/formulas/legacyFormulaRule.fix.js +574 -0
  28. package/dist/rules/formulas/legacyFormulaRule.fix.js.map +1 -0
  29. package/dist/rules/formulas/legacyFormulaRule.js +5 -580
  30. package/dist/rules/formulas/legacyFormulaRule.js.map +1 -1
  31. package/dist/rules/formulas/noReferenceComponentFormulaRule.js +8 -1
  32. package/dist/rules/formulas/noReferenceComponentFormulaRule.js.map +1 -1
  33. package/dist/rules/formulas/noReferenceProjectFormulaRule.js +63 -72
  34. package/dist/rules/formulas/noReferenceProjectFormulaRule.js.map +1 -1
  35. package/dist/rules/noReferenceNodeRule.js +22 -0
  36. package/dist/rules/noReferenceNodeRule.js.map +1 -0
  37. package/dist/rules/noReferenceNodeRule.test.js +131 -0
  38. package/dist/rules/noReferenceNodeRule.test.js.map +1 -0
  39. package/dist/rules/style/invalidStyleSyntaxRule.js +28 -0
  40. package/dist/rules/style/invalidStyleSyntaxRule.js.map +1 -0
  41. package/dist/rules/style/invalidStyleSyntaxRule.test.js +100 -0
  42. package/dist/rules/style/invalidStyleSyntaxRule.test.js.map +1 -0
  43. package/dist/searchProject.js +57 -16
  44. package/dist/searchProject.js.map +1 -1
  45. package/dist/util/removeUnused.fix.js +3 -0
  46. package/dist/util/removeUnused.fix.js.map +1 -0
  47. package/package.json +4 -3
  48. package/src/problems.worker.ts +4 -2
  49. package/src/rules/actions/legacyActionRule.fix.ts +157 -0
  50. package/src/rules/actions/legacyActionRule.test.ts +4 -3
  51. package/src/rules/actions/legacyActionRule.ts +3 -159
  52. package/src/rules/actions/noReferenceProjectActionRule.ts +39 -47
  53. package/src/rules/apis/noReferenceApiRule.test.ts +67 -1
  54. package/src/rules/apis/noReferenceApiRule.ts +9 -2
  55. package/src/rules/attributes/noReferenceAttributeRule.test.ts +35 -1
  56. package/src/rules/attributes/noReferenceAttributeRule.ts +7 -2
  57. package/src/rules/components/noReferenceComponentRule.ts +23 -34
  58. package/src/rules/events/duplicateEventTriggerRule.ts +2 -1
  59. package/src/rules/events/noReferenceEventRule.test.ts +59 -1
  60. package/src/rules/events/noReferenceEventRule.ts +8 -3
  61. package/src/rules/formulas/legacyFormulaRule.fix.ts +661 -0
  62. package/src/rules/formulas/legacyFormulaRule.ts +9 -670
  63. package/src/rules/formulas/noReferenceComponentFormulaRule.ts +15 -3
  64. package/src/rules/formulas/noReferenceProjectFormulaRule.ts +70 -77
  65. package/src/rules/noReferenceNodeRule.test.ts +140 -0
  66. package/src/rules/noReferenceNodeRule.ts +27 -0
  67. package/src/rules/style/invalidStyleSyntaxRule.test.ts +106 -0
  68. package/src/rules/style/invalidStyleSyntaxRule.ts +35 -0
  69. package/src/searchProject.ts +66 -22
  70. package/src/types.d.ts +33 -10
  71. package/src/util/removeUnused.fix.ts +5 -0
  72. package/dist/memos/getAllCustomPropertiesBySyntax.js +0 -43
  73. package/dist/memos/getAllCustomPropertiesBySyntax.js.map +0 -1
  74. package/dist/rules/style-variables/ambiguousStyleVariableSyntaxRule.js +0 -50
  75. package/dist/rules/style-variables/ambiguousStyleVariableSyntaxRule.js.map +0 -1
  76. package/dist/rules/style-variables/ambiguousStyleVariableSyntaxRule.test.js +0 -265
  77. package/dist/rules/style-variables/ambiguousStyleVariableSyntaxRule.test.js.map +0 -1
  78. package/src/memos/getAllCustomPropertiesBySyntax.ts +0 -68
  79. package/src/rules/style-variables/ambiguousStyleVariableSyntaxRule.test.ts +0 -278
  80. package/src/rules/style-variables/ambiguousStyleVariableSyntaxRule.ts +0 -65
@@ -1,4 +1,5 @@
1
1
  import { ToddleComponent } from '@nordcraft/core/dist/component/ToddleComponent';
2
+ import { removeFromPathFix } from '../../util/removeUnused.fix';
2
3
  export const noReferenceComponentFormulaRule = {
3
4
  code: 'no-reference component formula',
4
5
  level: 'warning',
@@ -55,7 +56,13 @@ export const noReferenceComponentFormulaRule = {
55
56
  }
56
57
  }
57
58
  }
58
- report(path, { contextSubscribers, name: value.name });
59
+ report(args.path, {
60
+ contextSubscribers,
61
+ name: value.name,
62
+ }, ['delete-component-formula']);
63
+ },
64
+ fixes: {
65
+ 'delete-component-formula': removeFromPathFix,
59
66
  },
60
67
  };
61
68
  //# sourceMappingURL=noReferenceComponentFormulaRule.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"noReferenceComponentFormulaRule.js","sourceRoot":"","sources":["../../../src/rules/formulas/noReferenceComponentFormulaRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAA;AAGhF,MAAM,CAAC,MAAM,+BAA+B,GAGvC;IACH,IAAI,EAAE,gCAAgC;IACtC,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,eAAe;IACzB,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;QACtB,IAAI,IAAI,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;YAC1C,OAAM;QACR,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;QAC9C,MAAM,CAAC,EAAE,aAAa,EAAE,AAAD,EAAG,UAAU,CAAC,GAAG,IAAI,CAAA;QAC5C,KAAK,MAAM,EACT,IAAI,EAAE,WAAW,EACjB,OAAO,GACR,IAAI,SAAS,CAAC,mBAAmB,EAAE,EAAE,CAAC;YACrC,IACE,OAAO,CAAC,IAAI,KAAK,OAAO;gBACxB,OAAO,CAAC,IAAI,KAAK,UAAU;gBAC3B,mCAAmC;gBACnC,mGAAmG;gBACnG,sGAAsG;gBACtG,8FAA8F;gBAC9F,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,UAAU,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,EACjE,CAAC;gBACD,OAAM;YACR,CAAC;QACH,CAAC;QAED,oHAAoH;QACpH,IAAI,KAAK,CAAC,eAAe,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;YAChD,OAAM;QACR,CAAC;QAED,yEAAyE;QACzE,MAAM,kBAAkB,GAAG,EAAE,CAAA;QAC7B,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;YAC1B,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;gBACzD,oEAAoE;gBACpE,MAAM,SAAS,GAAG,UAAW,CAAA;gBAC7B,KAAK,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAChD,SAAS,CAAC,QAAQ,IAAI,EAAE,CACzB,EAAE,CAAC;oBACF,IACE,UAAU,KAAK,aAAa;wBAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,EAChD,CAAC;wBACD,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;wBACvC,MAAM,gBAAgB,GAAG,IAAI,eAAe,CAAC;4BAC3C,SAAS;4BACT,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;4BAC9C,WAAW,EAAE,SAAS;4BACtB,cAAc,EAAE;gCACd,QAAQ,EAAE,KAAK,CAAC,QAAQ;gCACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;6BACzB;yBACF,CAAC,CAAA;wBACF,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,gBAAgB,CAAC,mBAAmB,EAAE,EAAE,CAAC;4BACjE,IACE,OAAO,CAAC,IAAI,KAAK,MAAM;gCACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU;gCAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,aAAa;gCACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,EAC9B,CAAC;gCACD,OAAM;4BACR,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,CAAC,IAAI,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;IACxD,CAAC;CACF,CAAA"}
1
+ {"version":3,"file":"noReferenceComponentFormulaRule.js","sourceRoot":"","sources":["../../../src/rules/formulas/noReferenceComponentFormulaRule.ts"],"names":[],"mappings":"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"}
@@ -1,92 +1,83 @@
1
1
  import { ToddleComponent } from '@nordcraft/core/dist/component/ToddleComponent';
2
2
  import { isToddleFormula } from '@nordcraft/core/dist/formula/formulaTypes';
3
- import { omit } from '@nordcraft/core/dist/utils/collections';
4
3
  import { ToddleApiService } from '@nordcraft/ssr/dist/ToddleApiService';
5
4
  import { ToddleRoute } from '@nordcraft/ssr/dist/ToddleRoute';
5
+ import { removeFromPathFix } from '../../util/removeUnused.fix';
6
6
  export const noReferenceProjectFormulaRule = {
7
7
  code: 'no-reference project formula',
8
8
  level: 'warning',
9
9
  category: 'No References',
10
- visit: (report, details) => {
11
- if (!hasReferences(details)) {
12
- report(details.path, undefined, ['delete-project-formula']);
10
+ visit: (report, { value, path, files, nodeType, memo }) => {
11
+ if (nodeType !== 'project-formula' || value.exported === true) {
12
+ return;
13
13
  }
14
- },
15
- fixes: {
16
- 'delete-project-formula': (data) => {
17
- if (!hasReferences(data)) {
18
- return omit(data.files, data.path);
19
- }
20
- },
21
- },
22
- };
23
- const hasReferences = ({ value, files, nodeType, memo }) => {
24
- if (nodeType !== 'project-formula' || value.exported === true) {
25
- return true;
26
- }
27
- // Check in all API services first, since that should be quick
28
- for (const apiService of Object.values(files.services ?? {})) {
29
- const service = new ToddleApiService({
30
- service: apiService,
31
- globalFormulas: { formulas: files.formulas, packages: files.packages },
32
- });
33
- const formulas = service.formulasInService();
34
- for (const { path: _formulaPath, formula } of formulas) {
35
- // Check if the formula is used in the formula
36
- if (checkFormula(formula, value.name)) {
37
- return true;
38
- }
39
- }
40
- }
41
- // Check routes before components, since they should be quicker
42
- for (const projectRoute of Object.values(files.routes ?? {})) {
43
- const route = new ToddleRoute({
44
- route: projectRoute,
45
- globalFormulas: { formulas: files.formulas, packages: files.packages },
46
- });
47
- const formulas = route.formulasInRoute();
48
- for (const { path: _formulaPath, formula } of formulas) {
49
- // Check if the formula is used in the formula
50
- if (checkFormula(formula, value.name)) {
51
- return true;
14
+ // Check in all API services first, since that should be quick
15
+ for (const apiService of Object.values(files.services ?? {})) {
16
+ const service = new ToddleApiService({
17
+ service: apiService,
18
+ globalFormulas: { formulas: files.formulas, packages: files.packages },
19
+ });
20
+ const formulas = service.formulasInService();
21
+ for (const { path: _formulaPath, formula } of formulas) {
22
+ // Check if the formula is used in the formula
23
+ if (checkFormula(formula, value.name)) {
24
+ return;
25
+ }
52
26
  }
53
27
  }
54
- }
55
- const componentFormulaReferences = memo('componentFormulaReferences', () => {
56
- const usedFormulas = new Set();
57
- for (const component of Object.values(files.components)) {
58
- const c = new ToddleComponent({
59
- // Enforce that the component is not undefined since we're iterating
60
- component: component,
61
- getComponent: (name) => files.components[name],
62
- packageName: undefined,
63
- globalFormulas: {
64
- formulas: files.formulas,
65
- packages: files.packages,
66
- },
28
+ // Check routes before components, since they should be quicker
29
+ for (const projectRoute of Object.values(files.routes ?? {})) {
30
+ const route = new ToddleRoute({
31
+ route: projectRoute,
32
+ globalFormulas: { formulas: files.formulas, packages: files.packages },
67
33
  });
68
- for (const { formula } of c.formulasInComponent()) {
69
- if (formula.type === 'function') {
70
- usedFormulas.add(formula.name);
34
+ const formulas = route.formulasInRoute();
35
+ for (const { path: _formulaPath, formula } of formulas) {
36
+ // Check if the formula is used in the formula
37
+ if (checkFormula(formula, value.name)) {
38
+ return;
71
39
  }
72
40
  }
73
41
  }
74
- return usedFormulas;
75
- });
76
- if (componentFormulaReferences.has(value.name)) {
77
- return true;
78
- }
79
- // TODO: Memoize similar to above. We need have a helper class `ToddleFormula` with `ToddleFormula.normalizeFormulas()`
80
- for (const f of Object.values(files.formulas ?? {})) {
81
- if (f.name === value.name) {
82
- continue;
42
+ const componentFormulaReferences = memo('componentFormulaReferences', () => {
43
+ const usedFormulas = new Set();
44
+ for (const component of Object.values(files.components)) {
45
+ const c = new ToddleComponent({
46
+ // Enforce that the component is not undefined since we're iterating
47
+ component: component,
48
+ getComponent: (name) => files.components[name],
49
+ packageName: undefined,
50
+ globalFormulas: {
51
+ formulas: files.formulas,
52
+ packages: files.packages,
53
+ },
54
+ });
55
+ for (const { formula } of c.formulasInComponent()) {
56
+ if (formula.type === 'function') {
57
+ usedFormulas.add(formula.name);
58
+ }
59
+ }
60
+ }
61
+ return usedFormulas;
62
+ });
63
+ if (componentFormulaReferences.has(value.name)) {
64
+ return;
83
65
  }
84
- // Check if the formula is used in the formula
85
- if (isToddleFormula(f) && checkFormula(f.formula, value.name)) {
86
- return true;
66
+ // TODO: Memoize similar to above. We need have a helper class `ToddleFormula` with `ToddleFormula.normalizeFormulas()`
67
+ for (const f of Object.values(files.formulas ?? {})) {
68
+ if (f.name === value.name) {
69
+ continue;
70
+ }
71
+ // Check if the formula is used in the formula
72
+ if (isToddleFormula(f) && checkFormula(f.formula, value.name)) {
73
+ return;
74
+ }
87
75
  }
88
- }
89
- return false;
76
+ report(path, undefined, ['delete-project-formula']);
77
+ },
78
+ fixes: {
79
+ 'delete-project-formula': removeFromPathFix,
80
+ },
90
81
  };
91
82
  const checkArguments = (args, formulaName) => {
92
83
  args.forEach((a) => {
@@ -1 +1 @@
1
- {"version":3,"file":"noReferenceProjectFormulaRule.js","sourceRoot":"","sources":["../../../src/rules/formulas/noReferenceProjectFormulaRule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"noReferenceProjectFormulaRule.js","sourceRoot":"","sources":["../../../src/rules/formulas/noReferenceProjectFormulaRule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { removeFromPathFix } from '../util/removeUnused.fix';
2
+ export const noReferenceNodeRule = {
3
+ code: 'no-reference node',
4
+ level: 'warning',
5
+ category: 'No References',
6
+ visit: (report, args) => {
7
+ if (args.nodeType !== 'component') {
8
+ return;
9
+ }
10
+ const { path, value: component } = args;
11
+ const referencedNodes = new Set(Object.values(component.nodes).flatMap((node) => node.children ?? []));
12
+ for (const key of Object.keys(component.nodes)) {
13
+ if (key !== 'root' && !referencedNodes.has(key)) {
14
+ report([...path, 'nodes', key], { node: key }, ['delete orphan node']);
15
+ }
16
+ }
17
+ },
18
+ fixes: {
19
+ 'delete orphan node': removeFromPathFix,
20
+ },
21
+ };
22
+ //# sourceMappingURL=noReferenceNodeRule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noReferenceNodeRule.js","sourceRoot":"","sources":["../../src/rules/noReferenceNodeRule.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE5D,MAAM,CAAC,MAAM,mBAAmB,GAA2B;IACzD,IAAI,EAAE,mBAAmB;IACzB,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,eAAe;IACzB,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;QACtB,IAAI,IAAI,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;QACvC,MAAM,eAAe,GAAG,IAAI,GAAG,CAC7B,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CACtE,CAAA;QACD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/C,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChD,MAAM,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAA;YACxE,CAAC;QACH,CAAC;IACH,CAAC;IACD,KAAK,EAAE;QACL,oBAAoB,EAAE,iBAAiB;KACxC;CACF,CAAA"}
@@ -0,0 +1,131 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { fixProject } from '../fixProject';
3
+ import { searchProject } from '../searchProject';
4
+ import { noReferenceNodeRule } from './noReferenceNodeRule';
5
+ describe('find noReferenceNodeRule', () => {
6
+ test('should detect nodes with no references', () => {
7
+ const problems = Array.from(searchProject({
8
+ files: {
9
+ formulas: {},
10
+ components: {
11
+ test: {
12
+ name: 'test',
13
+ nodes: {
14
+ root: {
15
+ id: 'root',
16
+ type: 'element',
17
+ tag: 'div',
18
+ children: [],
19
+ attrs: {},
20
+ style: {},
21
+ events: {},
22
+ classes: {},
23
+ },
24
+ '1LisbD0eCjsuccoUwajn1': {
25
+ id: 'XdhwPGsdFNI4s8A0oMwre',
26
+ type: 'text',
27
+ value: { type: 'value', value: 'Clone the project' },
28
+ },
29
+ },
30
+ formulas: {},
31
+ apis: {},
32
+ attributes: {},
33
+ variables: {},
34
+ },
35
+ },
36
+ },
37
+ rules: [noReferenceNodeRule],
38
+ }));
39
+ expect(problems).toHaveLength(1);
40
+ expect(problems[0].details).toEqual({ node: '1LisbD0eCjsuccoUwajn1' });
41
+ expect(problems[0].path).toEqual([
42
+ 'components',
43
+ 'test',
44
+ 'nodes',
45
+ '1LisbD0eCjsuccoUwajn1',
46
+ ]);
47
+ });
48
+ test('should not detect nodes with references', () => {
49
+ const problems = Array.from(searchProject({
50
+ files: {
51
+ formulas: {},
52
+ components: {
53
+ test: {
54
+ name: 'test',
55
+ nodes: {
56
+ root: {
57
+ id: 'root',
58
+ type: 'element',
59
+ tag: 'div',
60
+ children: ['1LisbD0eCjsuccoUwajn1'],
61
+ attrs: {},
62
+ style: {},
63
+ events: {},
64
+ classes: {},
65
+ },
66
+ '1LisbD0eCjsuccoUwajn1': {
67
+ id: 'XdhwPGsdFNI4s8A0oMwre',
68
+ type: 'text',
69
+ value: { type: 'value', value: 'Clone the project' },
70
+ },
71
+ },
72
+ formulas: {},
73
+ apis: {},
74
+ attributes: {},
75
+ variables: {},
76
+ },
77
+ },
78
+ },
79
+ rules: [noReferenceNodeRule],
80
+ }));
81
+ expect(problems).toEqual([]);
82
+ });
83
+ });
84
+ describe('fix noReferenceNodeRule', () => {
85
+ test('should delete nodes with no references', () => {
86
+ const files = {
87
+ formulas: {},
88
+ components: {
89
+ test: {
90
+ name: 'test',
91
+ nodes: {
92
+ root: {
93
+ id: 'root',
94
+ type: 'element',
95
+ tag: 'div',
96
+ children: ['used'],
97
+ attrs: {},
98
+ style: {},
99
+ events: {},
100
+ classes: {},
101
+ },
102
+ '1LisbD0eCjsuccoUwajn1': {
103
+ id: 'XdhwPGsdFNI4s8A0oMwre',
104
+ type: 'text',
105
+ value: { type: 'value', value: 'Clone the project' },
106
+ },
107
+ used: {
108
+ id: 'used',
109
+ type: 'text',
110
+ value: { type: 'value', value: 'I am used' },
111
+ },
112
+ },
113
+ formulas: {},
114
+ apis: {},
115
+ attributes: {},
116
+ variables: {},
117
+ },
118
+ },
119
+ };
120
+ const fixedFiles = fixProject({
121
+ files,
122
+ rule: noReferenceNodeRule,
123
+ fixType: 'delete orphan node',
124
+ });
125
+ expect(Object.keys(fixedFiles.components.test.nodes)).toEqual([
126
+ 'root',
127
+ 'used',
128
+ ]);
129
+ });
130
+ });
131
+ //# sourceMappingURL=noReferenceNodeRule.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noReferenceNodeRule.test.js","sourceRoot":"","sources":["../../src/rules/noReferenceNodeRule.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { parse } from 'postcss';
2
+ import { removeFromPathFix } from '../../util/removeUnused.fix';
3
+ export const invalidStyleSyntaxRule = {
4
+ code: 'invalid style syntax',
5
+ level: 'error',
6
+ category: 'Quality',
7
+ visit: (report, { nodeType, value, path, memo }) => {
8
+ if (nodeType !== 'style-declaration') {
9
+ return;
10
+ }
11
+ const valid = memo(`valid-style-${value.styleProperty}:${value.styleValue}`, () => {
12
+ try {
13
+ parse(`${value.styleProperty}: ${value.styleValue}`);
14
+ return true;
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ });
20
+ if (!valid) {
21
+ report(path, { property: value.styleProperty }, ['delete style property']);
22
+ }
23
+ },
24
+ fixes: {
25
+ 'delete style property': removeFromPathFix,
26
+ },
27
+ };
28
+ //# sourceMappingURL=invalidStyleSyntaxRule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invalidStyleSyntaxRule.js","sourceRoot":"","sources":["../../../src/rules/style/invalidStyleSyntaxRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAE/D,MAAM,CAAC,MAAM,sBAAsB,GAE9B;IACH,IAAI,EAAE,sBAAsB;IAC5B,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,SAAS;IACnB,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;QACjD,IAAI,QAAQ,KAAK,mBAAmB,EAAE,CAAC;YACrC,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAChB,eAAe,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,UAAU,EAAE,EACxD,GAAG,EAAE;YACH,IAAI,CAAC;gBACH,KAAK,CAAC,GAAG,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC,UAAU,EAAE,CAAC,CAAA;gBACpD,OAAO,IAAI,CAAA;YACb,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAA;YACd,CAAC;QACH,CAAC,CACF,CAAA;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAA;QAC5E,CAAC;IACH,CAAC;IACD,KAAK,EAAE;QACL,uBAAuB,EAAE,iBAAiB;KAC3C;CACF,CAAA"}
@@ -0,0 +1,100 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { fixProject } from '../../fixProject';
3
+ import { searchProject } from '../../searchProject';
4
+ import { invalidStyleSyntaxRule } from './invalidStyleSyntaxRule';
5
+ describe('find invalidStyleSyntaxRule', () => {
6
+ test('should find invalid style syntax', () => {
7
+ const problems = Array.from(searchProject({
8
+ files: {
9
+ formulas: {},
10
+ components: {
11
+ test: {
12
+ name: 'test',
13
+ nodes: {
14
+ root: {
15
+ tag: 'ul',
16
+ type: 'element',
17
+ attrs: {},
18
+ style: {
19
+ gap: '8px',
20
+ width: '100%',
21
+ 'max-width': 'calc(NOT VALID',
22
+ height: '/* 100px */ 22px',
23
+ '{': '100px',
24
+ 'border-width': '--my-var',
25
+ },
26
+ events: {},
27
+ classes: {},
28
+ children: [],
29
+ },
30
+ },
31
+ formulas: {},
32
+ apis: {},
33
+ attributes: {},
34
+ variables: {},
35
+ },
36
+ },
37
+ },
38
+ rules: [invalidStyleSyntaxRule],
39
+ }));
40
+ expect(problems).toHaveLength(2);
41
+ expect(problems[0].code).toBe('invalid style syntax');
42
+ expect(problems[0].path).toEqual([
43
+ 'components',
44
+ 'test',
45
+ 'nodes',
46
+ 'root',
47
+ 'style',
48
+ 'max-width',
49
+ ]);
50
+ expect(problems[0].details.property).toBe('max-width');
51
+ expect(problems[1].details.property).toBe('{');
52
+ });
53
+ });
54
+ describe('fix invalidStyleSyntaxRule', () => {
55
+ test('should remove an invalid style property', () => {
56
+ const files = {
57
+ formulas: {},
58
+ components: {
59
+ test: {
60
+ name: 'test',
61
+ nodes: {
62
+ root: {
63
+ tag: 'ul',
64
+ type: 'element',
65
+ attrs: {},
66
+ style: {
67
+ gap: '8px',
68
+ width: '100%',
69
+ 'max-width': 'calc(NOT VALID',
70
+ height: '/* 100px */ 22px',
71
+ '{': '100px',
72
+ },
73
+ events: {},
74
+ classes: {},
75
+ children: [],
76
+ },
77
+ },
78
+ formulas: {},
79
+ apis: {},
80
+ attributes: {},
81
+ variables: {},
82
+ },
83
+ },
84
+ };
85
+ const fixedFiles = fixProject({
86
+ files,
87
+ rule: invalidStyleSyntaxRule,
88
+ fixType: 'delete style property',
89
+ });
90
+ expect(fixedFiles.components.test.nodes.root.style)
91
+ .toMatchInlineSnapshot(`
92
+ {
93
+ "gap": "8px",
94
+ "height": "/* 100px */ 22px",
95
+ "width": "100%",
96
+ }
97
+ `);
98
+ });
99
+ });
100
+ //# sourceMappingURL=invalidStyleSyntaxRule.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invalidStyleSyntaxRule.test.js","sourceRoot":"","sources":["../../../src/rules/style/invalidStyleSyntaxRule.test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AAEjE,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC5C,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CACzB,aAAa,CAAC;YACZ,KAAK,EAAE;gBACL,QAAQ,EAAE,EAAE;gBACZ,UAAU,EAAE;oBACV,IAAI,EAAE;wBACJ,IAAI,EAAE,MAAM;wBACZ,KAAK,EAAE;4BACL,IAAI,EAAE;gCACJ,GAAG,EAAE,IAAI;gCACT,IAAI,EAAE,SAAS;gCACf,KAAK,EAAE,EAAE;gCACT,KAAK,EAAE;oCACL,GAAG,EAAE,KAAK;oCACV,KAAK,EAAE,MAAM;oCACb,WAAW,EAAE,gBAAgB;oCAC7B,MAAM,EAAE,kBAAkB;oCAC1B,GAAG,EAAE,OAAO;oCACZ,cAAc,EAAE,UAAU;iCAC3B;gCACD,MAAM,EAAE,EAAE;gCACV,OAAO,EAAE,EAAE;gCACX,QAAQ,EAAE,EAAE;6BACb;yBACF;wBACD,QAAQ,EAAE,EAAE;wBACZ,IAAI,EAAE,EAAE;wBACR,UAAU,EAAE,EAAE;wBACd,SAAS,EAAE,EAAE;qBACd;iBACF;aACF;YACD,KAAK,EAAE,CAAC,sBAAsB,CAAC;SAChC,CAAC,CACH,CAAA;QAED,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;QAChC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA;QACrD,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YAC/B,YAAY;YACZ,MAAM;YACN,OAAO;YACP,MAAM;YACN,OAAO;YACP,WAAW;SACZ,CAAC,CAAA;QACF,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACtD,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAChD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,IAAI,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACnD,MAAM,KAAK,GAAiB;YAC1B,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,MAAM;oBACZ,KAAK,EAAE;wBACL,IAAI,EAAE;4BACJ,GAAG,EAAE,IAAI;4BACT,IAAI,EAAE,SAAS;4BACf,KAAK,EAAE,EAAE;4BACT,KAAK,EAAE;gCACL,GAAG,EAAE,KAAK;gCACV,KAAK,EAAE,MAAM;gCACb,WAAW,EAAE,gBAAgB;gCAC7B,MAAM,EAAE,kBAAkB;gCAC1B,GAAG,EAAE,OAAO;6BACb;4BACD,MAAM,EAAE,EAAE;4BACV,OAAO,EAAE,EAAE;4BACX,QAAQ,EAAE,EAAE;yBACb;qBACF;oBACD,QAAQ,EAAE,EAAE;oBACZ,IAAI,EAAE,EAAE;oBACR,UAAU,EAAE,EAAE;oBACd,SAAS,EAAE,EAAE;iBACd;aACF;SACF,CAAA;QACD,MAAM,UAAU,GAAG,UAAU,CAAC;YAC5B,KAAK;YACL,IAAI,EAAE,sBAAsB;YAC5B,OAAO,EAAE,uBAAuB;SACjC,CAAC,CAAA;QACF,MAAM,CAAE,UAAU,CAAC,UAAU,CAAC,IAAK,CAAC,KAAK,CAAC,IAAyB,CAAC,KAAK,CAAC;aACvE,qBAAqB,CAAC;;;;;;KAMxB,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -147,22 +147,34 @@ function* visitNode({ args, state, fixOptions, }) {
147
147
  }
148
148
  if (!useExactPaths ||
149
149
  shouldSearchExactPath({ path: data.path, pathsToVisit })) {
150
- if (fixOptions) {
151
- // We're fixing issues
152
- for (const rule of rules) {
153
- const fixedFiles = rule.fixes?.[fixOptions.fixType]?.(data, state);
154
- if (fixedFiles) {
155
- yield fixedFiles;
150
+ const results = [];
151
+ let fixedFiles;
152
+ for (const rule of rules) {
153
+ // eslint-disable-next-line no-console
154
+ console.timeStamp(`Visiting rule ${rule.code}`);
155
+ rule.visit(
156
+ // Report callback used to report issues
157
+ (path, details, fixes) => {
158
+ if (fixOptions) {
159
+ // We're in "fix mode"
160
+ if (
161
+ // We only overwrite fixedFiles once to avoid conflicting fixes
162
+ !fixedFiles &&
163
+ // The current fix must be one of the fixes reported
164
+ fixes?.includes(fixOptions.fixType) &&
165
+ // The rule must have an implementation for the fix
166
+ rule.fixes?.[fixOptions.fixType]) {
167
+ const ruleFixes = rule.fixes[fixOptions.fixType]?.(
168
+ // We must use the path from the report, not the original path
169
+ // because the report might be for a subpath
170
+ { ...data, path }, state);
171
+ if (ruleFixes) {
172
+ fixedFiles = ruleFixes;
173
+ }
174
+ }
156
175
  }
157
- }
158
- }
159
- else {
160
- // We're looking for issues
161
- const results = [];
162
- for (const rule of rules) {
163
- // eslint-disable-next-line no-console
164
- console.timeStamp(`Visiting rule ${rule.code}`);
165
- rule.visit((path, details, fixes) => {
176
+ else {
177
+ // We're in "report mode"
166
178
  results.push({
167
179
  code: rule.code,
168
180
  category: rule.category,
@@ -171,8 +183,19 @@ function* visitNode({ args, state, fixOptions, }) {
171
183
  details,
172
184
  fixes,
173
185
  });
174
- }, data, state);
186
+ }
187
+ }, data, state);
188
+ if (fixedFiles) {
189
+ // We have applied a fix, stop processing more rules
190
+ break;
175
191
  }
192
+ }
193
+ if (fixOptions) {
194
+ if (fixedFiles) {
195
+ yield fixedFiles;
196
+ }
197
+ }
198
+ else {
176
199
  for (const result of results) {
177
200
  yield result;
178
201
  }
@@ -432,6 +455,24 @@ function* visitNode({ args, state, fixOptions, }) {
432
455
  });
433
456
  }
434
457
  }
458
+ for (const [styleKey, styleValue] of Object.entries(
459
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
460
+ value.style ?? {})) {
461
+ yield* visitNode({
462
+ args: {
463
+ nodeType: 'style-declaration',
464
+ value: { styleProperty: styleKey, styleValue, element: value },
465
+ path: [...path, 'style', styleKey],
466
+ rules,
467
+ files,
468
+ pathsToVisit,
469
+ useExactPaths,
470
+ memo,
471
+ },
472
+ state,
473
+ fixOptions: fixOptions,
474
+ });
475
+ }
435
476
  }
436
477
  break;
437
478
  case 'api-service': {