@nordcraft/search 1.0.44 → 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 (35) 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.test.js +3 -3
  4. package/dist/rules/actions/legacyActionRule.test.js.map +1 -1
  5. package/dist/rules/events/duplicateEventTriggerRule.js +2 -1
  6. package/dist/rules/events/duplicateEventTriggerRule.js.map +1 -1
  7. package/dist/rules/noReferenceNodeRule.js +22 -0
  8. package/dist/rules/noReferenceNodeRule.js.map +1 -0
  9. package/dist/rules/noReferenceNodeRule.test.js +131 -0
  10. package/dist/rules/noReferenceNodeRule.test.js.map +1 -0
  11. package/dist/rules/style/invalidStyleSyntaxRule.js +28 -0
  12. package/dist/rules/style/invalidStyleSyntaxRule.js.map +1 -0
  13. package/dist/rules/style/invalidStyleSyntaxRule.test.js +100 -0
  14. package/dist/rules/style/invalidStyleSyntaxRule.test.js.map +1 -0
  15. package/dist/searchProject.js +22 -1
  16. package/dist/searchProject.js.map +1 -1
  17. package/package.json +4 -3
  18. package/src/problems.worker.ts +4 -2
  19. package/src/rules/actions/legacyActionRule.test.ts +3 -3
  20. package/src/rules/events/duplicateEventTriggerRule.ts +2 -1
  21. package/src/rules/noReferenceNodeRule.test.ts +140 -0
  22. package/src/rules/noReferenceNodeRule.ts +27 -0
  23. package/src/rules/style/invalidStyleSyntaxRule.test.ts +106 -0
  24. package/src/rules/style/invalidStyleSyntaxRule.ts +35 -0
  25. package/src/searchProject.ts +25 -1
  26. package/src/types.d.ts +17 -2
  27. package/dist/memos/getAllCustomPropertiesBySyntax.js +0 -43
  28. package/dist/memos/getAllCustomPropertiesBySyntax.js.map +0 -1
  29. package/dist/rules/style-variables/ambiguousStyleVariableSyntaxRule.js +0 -50
  30. package/dist/rules/style-variables/ambiguousStyleVariableSyntaxRule.js.map +0 -1
  31. package/dist/rules/style-variables/ambiguousStyleVariableSyntaxRule.test.js +0 -265
  32. package/dist/rules/style-variables/ambiguousStyleVariableSyntaxRule.test.js.map +0 -1
  33. package/src/memos/getAllCustomPropertiesBySyntax.ts +0 -68
  34. package/src/rules/style-variables/ambiguousStyleVariableSyntaxRule.test.ts +0 -278
  35. package/src/rules/style-variables/ambiguousStyleVariableSyntaxRule.ts +0 -65
@@ -197,7 +197,7 @@ describe('fix legacyActions', () => {
197
197
  })
198
198
  const fixedAction = (
199
199
  fixedProject.components['apiComponent']?.nodes['root'] as ElementNodeModel
200
- ).events['click'].actions[0]
200
+ ).events['click']?.actions[0]
201
201
  expect(fixedAction).toMatchInlineSnapshot(`
202
202
  {
203
203
  "cases": [
@@ -321,7 +321,7 @@ describe('fix legacyActions', () => {
321
321
  })
322
322
  const fixedAction = (
323
323
  fixedProject.components['apiComponent']?.nodes['root'] as ElementNodeModel
324
- ).events['click'].actions[0]
324
+ ).events['click']?.actions[0]
325
325
  expect(fixedAction).toMatchInlineSnapshot(`
326
326
  {
327
327
  "data": {
@@ -378,7 +378,7 @@ describe('fix legacyActions', () => {
378
378
  })
379
379
  const fixedAction = (
380
380
  fixedProject.components['apiComponent']?.nodes['root'] as ElementNodeModel
381
- ).events['click'].actions[0]
381
+ ).events['click']?.actions[0]
382
382
  expect(fixedAction).toMatchInlineSnapshot(`
383
383
  {
384
384
  "arguments": [
@@ -10,8 +10,9 @@ export const duplicateEventTriggerRule: Rule<{ trigger: string }> = {
10
10
  }
11
11
  const eventTriggers = new Set<string>()
12
12
 
13
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
13
14
  Object.entries(value.events ?? {}).forEach(([key, event]) => {
14
- if (typeof event.trigger !== 'string') {
15
+ if (typeof event?.trigger !== 'string') {
15
16
  return
16
17
  }
17
18
  if (eventTriggers.has(event.trigger)) {
@@ -0,0 +1,140 @@
1
+ import type { ProjectFiles } from '@nordcraft/ssr/dist/ssr.types'
2
+ import { describe, expect, test } from 'bun:test'
3
+ import { fixProject } from '../fixProject'
4
+ import { searchProject } from '../searchProject'
5
+ import { noReferenceNodeRule } from './noReferenceNodeRule'
6
+
7
+ describe('find noReferenceNodeRule', () => {
8
+ test('should detect nodes with no references', () => {
9
+ const problems = Array.from(
10
+ searchProject({
11
+ files: {
12
+ formulas: {},
13
+ components: {
14
+ test: {
15
+ name: 'test',
16
+ nodes: {
17
+ root: {
18
+ id: 'root',
19
+ type: 'element',
20
+ tag: 'div',
21
+ children: [],
22
+ attrs: {},
23
+ style: {},
24
+ events: {},
25
+ classes: {},
26
+ },
27
+ '1LisbD0eCjsuccoUwajn1': {
28
+ id: 'XdhwPGsdFNI4s8A0oMwre',
29
+ type: 'text',
30
+ value: { type: 'value', value: 'Clone the project' },
31
+ },
32
+ },
33
+ formulas: {},
34
+ apis: {},
35
+ attributes: {},
36
+ variables: {},
37
+ },
38
+ },
39
+ },
40
+ rules: [noReferenceNodeRule],
41
+ }),
42
+ )
43
+
44
+ expect(problems).toHaveLength(1)
45
+ expect(problems[0].details).toEqual({ node: '1LisbD0eCjsuccoUwajn1' })
46
+ expect(problems[0].path).toEqual([
47
+ 'components',
48
+ 'test',
49
+ 'nodes',
50
+ '1LisbD0eCjsuccoUwajn1',
51
+ ])
52
+ })
53
+
54
+ test('should not detect nodes with references', () => {
55
+ const problems = Array.from(
56
+ searchProject({
57
+ files: {
58
+ formulas: {},
59
+ components: {
60
+ test: {
61
+ name: 'test',
62
+ nodes: {
63
+ root: {
64
+ id: 'root',
65
+ type: 'element',
66
+ tag: 'div',
67
+ children: ['1LisbD0eCjsuccoUwajn1'],
68
+ attrs: {},
69
+ style: {},
70
+ events: {},
71
+ classes: {},
72
+ },
73
+ '1LisbD0eCjsuccoUwajn1': {
74
+ id: 'XdhwPGsdFNI4s8A0oMwre',
75
+ type: 'text',
76
+ value: { type: 'value', value: 'Clone the project' },
77
+ },
78
+ },
79
+ formulas: {},
80
+ apis: {},
81
+ attributes: {},
82
+ variables: {},
83
+ },
84
+ },
85
+ },
86
+ rules: [noReferenceNodeRule],
87
+ }),
88
+ )
89
+
90
+ expect(problems).toEqual([])
91
+ })
92
+ })
93
+
94
+ describe('fix noReferenceNodeRule', () => {
95
+ test('should delete nodes with no references', () => {
96
+ const files: ProjectFiles = {
97
+ formulas: {},
98
+ components: {
99
+ test: {
100
+ name: 'test',
101
+ nodes: {
102
+ root: {
103
+ id: 'root',
104
+ type: 'element',
105
+ tag: 'div',
106
+ children: ['used'],
107
+ attrs: {},
108
+ style: {},
109
+ events: {},
110
+ classes: {},
111
+ },
112
+ '1LisbD0eCjsuccoUwajn1': {
113
+ id: 'XdhwPGsdFNI4s8A0oMwre',
114
+ type: 'text',
115
+ value: { type: 'value', value: 'Clone the project' },
116
+ },
117
+ used: {
118
+ id: 'used',
119
+ type: 'text',
120
+ value: { type: 'value', value: 'I am used' },
121
+ },
122
+ },
123
+ formulas: {},
124
+ apis: {},
125
+ attributes: {},
126
+ variables: {},
127
+ },
128
+ },
129
+ }
130
+ const fixedFiles = fixProject({
131
+ files,
132
+ rule: noReferenceNodeRule,
133
+ fixType: 'delete orphan node',
134
+ })
135
+ expect(Object.keys(fixedFiles.components.test!.nodes)).toEqual([
136
+ 'root',
137
+ 'used',
138
+ ])
139
+ })
140
+ })
@@ -0,0 +1,27 @@
1
+ import type { Rule } from '../types'
2
+ import { removeFromPathFix } from '../util/removeUnused.fix'
3
+
4
+ export const noReferenceNodeRule: Rule<{ node: string }> = {
5
+ code: 'no-reference node',
6
+ level: 'warning',
7
+ category: 'No References',
8
+ visit: (report, args) => {
9
+ if (args.nodeType !== 'component') {
10
+ return
11
+ }
12
+ const { path, value: component } = args
13
+ const referencedNodes = new Set(
14
+ Object.values(component.nodes).flatMap((node) => node.children ?? []),
15
+ )
16
+ for (const key of Object.keys(component.nodes)) {
17
+ if (key !== 'root' && !referencedNodes.has(key)) {
18
+ report([...path, 'nodes', key], { node: key }, ['delete orphan node'])
19
+ }
20
+ }
21
+ },
22
+ fixes: {
23
+ 'delete orphan node': removeFromPathFix,
24
+ },
25
+ }
26
+
27
+ export type NoReferenceNodeRuleFix = 'delete orphan node'
@@ -0,0 +1,106 @@
1
+ import type { ElementNodeModel } from '@nordcraft/core/dist/component/component.types'
2
+ import type { ProjectFiles } from '@nordcraft/ssr/dist/ssr.types'
3
+ import { describe, expect, test } from 'bun:test'
4
+ import { fixProject } from '../../fixProject'
5
+ import { searchProject } from '../../searchProject'
6
+ import { invalidStyleSyntaxRule } from './invalidStyleSyntaxRule'
7
+
8
+ describe('find invalidStyleSyntaxRule', () => {
9
+ test('should find invalid style syntax', () => {
10
+ const problems = Array.from(
11
+ searchProject({
12
+ files: {
13
+ formulas: {},
14
+ components: {
15
+ test: {
16
+ name: 'test',
17
+ nodes: {
18
+ root: {
19
+ tag: 'ul',
20
+ type: 'element',
21
+ attrs: {},
22
+ style: {
23
+ gap: '8px',
24
+ width: '100%',
25
+ 'max-width': 'calc(NOT VALID',
26
+ height: '/* 100px */ 22px',
27
+ '{': '100px',
28
+ 'border-width': '--my-var',
29
+ },
30
+ events: {},
31
+ classes: {},
32
+ children: [],
33
+ },
34
+ },
35
+ formulas: {},
36
+ apis: {},
37
+ attributes: {},
38
+ variables: {},
39
+ },
40
+ },
41
+ },
42
+ rules: [invalidStyleSyntaxRule],
43
+ }),
44
+ )
45
+
46
+ expect(problems).toHaveLength(2)
47
+ expect(problems[0].code).toBe('invalid style syntax')
48
+ expect(problems[0].path).toEqual([
49
+ 'components',
50
+ 'test',
51
+ 'nodes',
52
+ 'root',
53
+ 'style',
54
+ 'max-width',
55
+ ])
56
+ expect(problems[0].details.property).toBe('max-width')
57
+ expect(problems[1].details.property).toBe('{')
58
+ })
59
+ })
60
+
61
+ describe('fix invalidStyleSyntaxRule', () => {
62
+ test('should remove an invalid style property', () => {
63
+ const files: ProjectFiles = {
64
+ formulas: {},
65
+ components: {
66
+ test: {
67
+ name: 'test',
68
+ nodes: {
69
+ root: {
70
+ tag: 'ul',
71
+ type: 'element',
72
+ attrs: {},
73
+ style: {
74
+ gap: '8px',
75
+ width: '100%',
76
+ 'max-width': 'calc(NOT VALID',
77
+ height: '/* 100px */ 22px',
78
+ '{': '100px',
79
+ },
80
+ events: {},
81
+ classes: {},
82
+ children: [],
83
+ },
84
+ },
85
+ formulas: {},
86
+ apis: {},
87
+ attributes: {},
88
+ variables: {},
89
+ },
90
+ },
91
+ }
92
+ const fixedFiles = fixProject({
93
+ files,
94
+ rule: invalidStyleSyntaxRule,
95
+ fixType: 'delete style property',
96
+ })
97
+ expect((fixedFiles.components.test!.nodes.root as ElementNodeModel).style)
98
+ .toMatchInlineSnapshot(`
99
+ {
100
+ "gap": "8px",
101
+ "height": "/* 100px */ 22px",
102
+ "width": "100%",
103
+ }
104
+ `)
105
+ })
106
+ })
@@ -0,0 +1,35 @@
1
+ import { parse } from 'postcss'
2
+ import type { Rule } from '../../types'
3
+ import { removeFromPathFix } from '../../util/removeUnused.fix'
4
+
5
+ export const invalidStyleSyntaxRule: Rule<{
6
+ property: string
7
+ }> = {
8
+ code: 'invalid style syntax',
9
+ level: 'error',
10
+ category: 'Quality',
11
+ visit: (report, { nodeType, value, path, memo }) => {
12
+ if (nodeType !== 'style-declaration') {
13
+ return
14
+ }
15
+ const valid = memo(
16
+ `valid-style-${value.styleProperty}:${value.styleValue}`,
17
+ () => {
18
+ try {
19
+ parse(`${value.styleProperty}: ${value.styleValue}`)
20
+ return true
21
+ } catch {
22
+ return false
23
+ }
24
+ },
25
+ )
26
+ if (!valid) {
27
+ report(path, { property: value.styleProperty }, ['delete style property'])
28
+ }
29
+ },
30
+ fixes: {
31
+ 'delete style property': removeFromPathFix,
32
+ },
33
+ }
34
+
35
+ export type InvalidStyleSyntaxRuleFix = 'delete style property'
@@ -262,7 +262,12 @@ function* visitNode({
262
262
  // The rule must have an implementation for the fix
263
263
  rule.fixes?.[fixOptions.fixType]
264
264
  ) {
265
- const ruleFixes = rule.fixes[fixOptions.fixType]?.(data, state)
265
+ const ruleFixes = rule.fixes[fixOptions.fixType]?.(
266
+ // We must use the path from the report, not the original path
267
+ // because the report might be for a subpath
268
+ { ...data, path },
269
+ state,
270
+ )
266
271
  if (ruleFixes) {
267
272
  fixedFiles = ruleFixes
268
273
  }
@@ -571,6 +576,25 @@ function* visitNode({
571
576
  })
572
577
  }
573
578
  }
579
+ for (const [styleKey, styleValue] of Object.entries(
580
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
581
+ value.style ?? {},
582
+ )) {
583
+ yield* visitNode({
584
+ args: {
585
+ nodeType: 'style-declaration',
586
+ value: { styleProperty: styleKey, styleValue, element: value },
587
+ path: [...path, 'style', styleKey],
588
+ rules,
589
+ files,
590
+ pathsToVisit,
591
+ useExactPaths,
592
+ memo,
593
+ },
594
+ state,
595
+ fixOptions: fixOptions as any,
596
+ })
597
+ }
574
598
  }
575
599
  break
576
600
 
package/src/types.d.ts CHANGED
@@ -14,9 +14,9 @@ import type { ToddleComponent } from '@nordcraft/core/dist/component/ToddleCompo
14
14
  import type { Formula } from '@nordcraft/core/dist/formula/formula'
15
15
  import type { PluginFormula } from '@nordcraft/core/dist/formula/formulaTypes'
16
16
  import type { Theme } from '@nordcraft/core/dist/styling/theme'
17
+ import type { PluginAction } from '@nordcraft/core/dist/types'
17
18
  import type {
18
19
  ApiService,
19
- PluginAction,
20
20
  ProjectFiles,
21
21
  Route,
22
22
  ToddleProject,
@@ -30,9 +30,10 @@ import type { NoReferenceEventRuleFix } from './rules/events/noReferenceEventRul
30
30
  import type { LegacyFormulaRuleFix } from './rules/formulas/legacyFormulaRule'
31
31
  import type { NoReferenceComponentFormulaRuleFix } from './rules/formulas/noReferenceComponentFormulaRule'
32
32
  import type { NoReferenceProjectFormulaRuleFix } from './rules/formulas/noReferenceProjectFormulaRule'
33
+ import type { NoReferenceNodeRuleFix } from './rules/noReferenceNodeRule'
34
+ import type { InvalidStyleSyntaxRuleFix } from './rules/style/invalidStyleSyntaxRule'
33
35
 
34
36
  type Code =
35
- | 'ambiguous style variable syntax'
36
37
  | 'duplicate event trigger'
37
38
  | 'duplicate url parameter'
38
39
  | 'duplicate workflow parameter'
@@ -40,6 +41,7 @@ type Code =
40
41
  | 'invalid api parser mode'
41
42
  | 'invalid api proxy body setting'
42
43
  | 'invalid element child'
44
+ | 'invalid style syntax'
43
45
  | 'legacy action'
44
46
  | 'legacy api'
45
47
  | 'legacy formula'
@@ -53,6 +55,7 @@ type Code =
53
55
  | 'no-reference component workflow'
54
56
  | 'no-reference component'
55
57
  | 'no-reference event'
58
+ | 'no-reference node'
56
59
  | 'no-reference project action'
57
60
  | 'no-reference project formula'
58
61
  | 'no-reference variable'
@@ -297,6 +300,15 @@ type StyleVariantNode = {
297
300
  value: { variant: StyleVariant; element: ElementNodeModel }
298
301
  } & Base
299
302
 
303
+ type StyleNode = {
304
+ nodeType: 'style-declaration'
305
+ value: {
306
+ styleProperty: string
307
+ styleValue: string
308
+ element: ElementNodeModel
309
+ }
310
+ } & Base
311
+
300
312
  export type NodeType =
301
313
  | ActionModelNode
302
314
  | ComponentAPIInputNode
@@ -316,6 +328,7 @@ export type NodeType =
316
328
  | ProjectFormulaNode
317
329
  | ProjectThemeNode
318
330
  | ProjectRoute
331
+ | StyleNode
319
332
  | StyleVariantNode
320
333
 
321
334
  type FixType =
@@ -328,6 +341,8 @@ type FixType =
328
341
  | NoReferenceAttributeRuleFix
329
342
  | NoReferenceEventRuleFix
330
343
  | NoReferenceComponentFormulaRuleFix
344
+ | NoReferenceNodeRuleFix
345
+ | InvalidStyleSyntaxRuleFix
331
346
 
332
347
  export interface Rule<T = unknown, V = NodeType> {
333
348
  category: Category
@@ -1,43 +0,0 @@
1
- export const getAllCustomPropertiesBySyntax = (memo, { files, }) => memo('allCustomPropertiesBySyntax', () => {
2
- const store = {};
3
- const add = (propName, syntax, fullPath) => {
4
- if (syntax.type !== 'primitive')
5
- return;
6
- const sName = syntax.name;
7
- store[propName] ??= {};
8
- store[propName][sName] ??= [];
9
- store[propName][sName].push({ syntax, path: fullPath });
10
- };
11
- for (const [componentKey, component] of Object.entries(files.components)) {
12
- for (const [nodeKey, node] of Object.entries(component?.nodes ?? {})) {
13
- if (node.type !== 'element' && node.type !== 'component')
14
- continue;
15
- for (const [propName, prop] of Object.entries(node.customProperties ?? {})) {
16
- add(propName, prop.syntax, [
17
- 'components',
18
- componentKey,
19
- 'nodes',
20
- nodeKey,
21
- 'customProperties',
22
- propName,
23
- ]);
24
- }
25
- node.variants?.forEach((variant, variantIndex) => {
26
- for (const [propName, prop] of Object.entries(variant.customProperties ?? {})) {
27
- add(propName, prop.syntax, [
28
- 'components',
29
- componentKey,
30
- 'nodes',
31
- nodeKey,
32
- 'variants',
33
- String(variantIndex),
34
- 'customProperties',
35
- propName,
36
- ]);
37
- }
38
- });
39
- }
40
- }
41
- return store;
42
- });
43
- //# sourceMappingURL=getAllCustomPropertiesBySyntax.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getAllCustomPropertiesBySyntax.js","sourceRoot":"","sources":["../../src/memos/getAllCustomPropertiesBySyntax.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAC5C,IAAY,EACZ,EACE,KAAK,GAGN,EACD,EAAE,CACF,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE;IACvC,MAAM,KAAK,GAGP,EAAE,CAAA;IAEN,MAAM,GAAG,GAAG,CACV,QAAgB,EAChB,MAAqB,EACrB,QAAkB,EAClB,EAAE;QACF,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW;YAAE,OAAM;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAA;QACzB,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;QACtB,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;QAC7B,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IACzD,CAAC,CAAA;IAED,KAAK,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QACzE,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;YACrE,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;gBAAE,SAAQ;YAElE,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAC3C,IAAI,CAAC,gBAAgB,IAAI,EAAE,CAC5B,EAAE,CAAC;gBACF,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE;oBACzB,YAAY;oBACZ,YAAY;oBACZ,OAAO;oBACP,OAAO;oBACP,kBAAkB;oBAClB,QAAQ;iBACT,CAAC,CAAA;YACJ,CAAC;YAED,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE;gBAC/C,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAC3C,OAAO,CAAC,gBAAgB,IAAI,EAAE,CAC/B,EAAE,CAAC;oBACF,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE;wBACzB,YAAY;wBACZ,YAAY;wBACZ,OAAO;wBACP,OAAO;wBACP,UAAU;wBACV,MAAM,CAAC,YAAY,CAAC;wBACpB,kBAAkB;wBAClB,QAAQ;qBACT,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAC,CAAA"}
@@ -1,50 +0,0 @@
1
- import { getAllCustomPropertiesBySyntax } from '../../memos/getAllCustomPropertiesBySyntax';
2
- export const ambiguousStyleVariableSyntaxRule = {
3
- code: 'ambiguous style variable syntax',
4
- level: 'error',
5
- category: 'Other',
6
- visit: (report, args) => {
7
- const { nodeType, value, files, memo, path } = args;
8
- if (nodeType !== 'component-node')
9
- return;
10
- if (value.type !== 'element' && value.type !== 'component')
11
- return;
12
- const check = (propName, syntax, basePath) => {
13
- if (syntax.type !== 'primitive')
14
- return;
15
- const allCustomPropertiesBySyntax = getAllCustomPropertiesBySyntax(memo, {
16
- files,
17
- })[propName];
18
- const conflicts = Object.entries(allCustomPropertiesBySyntax)
19
- .filter(([name]) => name !== syntax.name)
20
- .flatMap(([, entries]) => entries);
21
- if (conflicts.length > 0) {
22
- report(basePath, {
23
- name: propName,
24
- duplicates: conflicts,
25
- });
26
- }
27
- };
28
- for (const [propName, prop] of Object.entries(value.customProperties ?? {})) {
29
- check(propName, prop.syntax, [
30
- ...path,
31
- 'customProperties',
32
- propName,
33
- 'name',
34
- ]);
35
- }
36
- value.variants?.forEach((variant, variantIndex) => {
37
- for (const [propName, prop] of Object.entries(variant.customProperties ?? {})) {
38
- check(propName, prop.syntax, [
39
- ...path,
40
- 'variants',
41
- String(variantIndex),
42
- 'customProperties',
43
- propName,
44
- 'name',
45
- ]);
46
- }
47
- });
48
- },
49
- };
50
- //# sourceMappingURL=ambiguousStyleVariableSyntaxRule.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ambiguousStyleVariableSyntaxRule.js","sourceRoot":"","sources":["../../../src/rules/style-variables/ambiguousStyleVariableSyntaxRule.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,4CAA4C,CAAA;AAG3F,MAAM,CAAC,MAAM,gCAAgC,GAGxC;IACH,IAAI,EAAE,iCAAiC;IACvC,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,OAAO;IACjB,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;QACtB,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,CAAA;QACnD,IAAI,QAAQ,KAAK,gBAAgB;YAAE,OAAM;QACzC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;YAAE,OAAM;QAElE,MAAM,KAAK,GAAG,CACZ,QAAgB,EAChB,MAAqB,EACrB,QAAgC,EAChC,EAAE;YACF,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW;gBAAE,OAAM;YACvC,MAAM,2BAA2B,GAAG,8BAA8B,CAAC,IAAI,EAAE;gBACvE,KAAK;aACN,CAAC,CAAC,QAAQ,CAAC,CAAA;YAEZ,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,2BAA2B,CAAC;iBAC1D,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC;iBACxC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAA;YAEpC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,CAAC,QAAQ,EAAE;oBACf,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE,SAAS;iBACtB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAA;QAED,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAC3C,KAAK,CAAC,gBAAgB,IAAI,EAAE,CAC7B,EAAE,CAAC;YACF,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE;gBAC3B,GAAG,IAAI;gBACP,kBAAkB;gBAClB,QAAQ;gBACR,MAAM;aACP,CAAC,CAAA;QACJ,CAAC;QAED,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE;YAChD,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAC3C,OAAO,CAAC,gBAAgB,IAAI,EAAE,CAC/B,EAAE,CAAC;gBACF,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE;oBAC3B,GAAG,IAAI;oBACP,UAAU;oBACV,MAAM,CAAC,YAAY,CAAC;oBACpB,kBAAkB;oBAClB,QAAQ;oBACR,MAAM;iBACP,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;CACF,CAAA"}