@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
@@ -1,265 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { searchProject } from '../../searchProject';
3
- import { ambiguousStyleVariableSyntaxRule } from './ambiguousStyleVariableSyntaxRule';
4
- describe('ambiguousStyleVariableSyntaxRule', () => {
5
- test('should report when there are style variables with the same name but different syntax', () => {
6
- const problems = Array.from(searchProject({
7
- files: {
8
- components: {
9
- component1: {
10
- name: 'component1',
11
- nodes: {
12
- node1: {
13
- type: 'element',
14
- customProperties: {
15
- '--my-variable': {
16
- syntax: { type: 'primitive', name: 'length' },
17
- formula: { type: 'value', value: '10px' },
18
- },
19
- },
20
- attrs: {},
21
- style: {},
22
- children: [],
23
- events: {},
24
- classes: {},
25
- tag: 'div',
26
- },
27
- },
28
- apis: {},
29
- attributes: {},
30
- variables: {},
31
- formulas: {},
32
- },
33
- component2: {
34
- name: 'component2',
35
- nodes: {
36
- node2: {
37
- type: 'element',
38
- customProperties: {
39
- '--my-variable': {
40
- syntax: { type: 'primitive', name: 'color' },
41
- formula: { type: 'value', value: '#ff0000' },
42
- },
43
- },
44
- attrs: {},
45
- style: {},
46
- children: [],
47
- events: {},
48
- classes: {},
49
- tag: 'div',
50
- },
51
- },
52
- apis: {},
53
- attributes: {},
54
- variables: {},
55
- formulas: {},
56
- },
57
- },
58
- },
59
- rules: [ambiguousStyleVariableSyntaxRule],
60
- }));
61
- expect(problems).toHaveLength(2);
62
- expect(problems[0].code).toBe('ambiguous style variable syntax');
63
- expect(problems[1].code).toBe('ambiguous style variable syntax');
64
- expect(problems[0].details.name).toBe('--my-variable');
65
- expect(problems[1].details.name).toBe('--my-variable');
66
- expect(problems[0].details.duplicates).toEqual([
67
- {
68
- path: [
69
- 'components',
70
- 'component2',
71
- 'nodes',
72
- 'node2',
73
- 'customProperties',
74
- '--my-variable',
75
- ],
76
- syntax: { type: 'primitive', name: 'color' },
77
- },
78
- ]);
79
- expect(problems[1].details.duplicates).toEqual([
80
- {
81
- path: [
82
- 'components',
83
- 'component1',
84
- 'nodes',
85
- 'node1',
86
- 'customProperties',
87
- '--my-variable',
88
- ],
89
- syntax: { type: 'primitive', name: 'length' },
90
- },
91
- ]);
92
- });
93
- test('should not report when style variables have same name and same syntax', () => {
94
- const problems = Array.from(searchProject({
95
- files: {
96
- components: {
97
- component1: {
98
- name: 'component1',
99
- nodes: {
100
- node1: {
101
- type: 'element',
102
- customProperties: {
103
- '--my-variable': {
104
- syntax: { type: 'primitive', name: 'length' },
105
- formula: { type: 'value', value: '10px' },
106
- },
107
- },
108
- attrs: {},
109
- style: {},
110
- children: [],
111
- events: {},
112
- classes: {},
113
- tag: 'div',
114
- },
115
- },
116
- apis: {},
117
- attributes: {},
118
- variables: {},
119
- formulas: {},
120
- },
121
- component2: {
122
- name: 'component2',
123
- nodes: {
124
- node2: {
125
- type: 'element',
126
- customProperties: {
127
- '--my-variable': {
128
- syntax: { type: 'primitive', name: 'length' },
129
- formula: { type: 'value', value: '20px' },
130
- },
131
- },
132
- attrs: {},
133
- style: {},
134
- children: [],
135
- events: {},
136
- classes: {},
137
- tag: 'div',
138
- },
139
- },
140
- apis: {},
141
- attributes: {},
142
- variables: {},
143
- formulas: {},
144
- },
145
- },
146
- },
147
- rules: [ambiguousStyleVariableSyntaxRule],
148
- }));
149
- expect(problems).toHaveLength(0);
150
- });
151
- test('should handle variant customProperties too', () => {
152
- const problems = Array.from(searchProject({
153
- files: {
154
- components: {
155
- component1: {
156
- name: 'component1',
157
- nodes: {
158
- node1: {
159
- type: 'element',
160
- customProperties: {
161
- '--my-variable': {
162
- syntax: { type: 'primitive', name: 'length' },
163
- formula: { type: 'value', value: '10px' },
164
- },
165
- },
166
- variants: [
167
- {
168
- breakpoint: 'medium',
169
- style: {},
170
- customProperties: {
171
- '--my-variable': {
172
- syntax: { type: 'primitive', name: 'color' },
173
- formula: { type: 'value', value: '#ff0000' },
174
- },
175
- },
176
- },
177
- ],
178
- attrs: {},
179
- style: {},
180
- children: [],
181
- events: {},
182
- classes: {},
183
- tag: 'div',
184
- },
185
- },
186
- apis: {},
187
- attributes: {},
188
- variables: {},
189
- formulas: {},
190
- },
191
- },
192
- },
193
- rules: [ambiguousStyleVariableSyntaxRule],
194
- }));
195
- // Should flag both the base and the variant for conflicting syntax
196
- expect(problems).toHaveLength(2);
197
- expect(problems.map((p) => p.details.name)).toEqual([
198
- '--my-variable',
199
- '--my-variable',
200
- ]);
201
- });
202
- test('should ignore non-primitive syntax', () => {
203
- const problems = Array.from(searchProject({
204
- files: {
205
- components: {
206
- component1: {
207
- name: 'component1',
208
- nodes: {
209
- node1: {
210
- type: 'element',
211
- customProperties: {
212
- '--my-variable': {
213
- syntax: {
214
- type: 'keyword',
215
- keywords: ['auto', 'inherit'],
216
- },
217
- formula: { type: 'value', value: '10px' },
218
- },
219
- },
220
- attrs: {},
221
- style: {},
222
- children: [],
223
- events: {},
224
- classes: {},
225
- tag: 'div',
226
- },
227
- },
228
- apis: {},
229
- attributes: {},
230
- variables: {},
231
- formulas: {},
232
- },
233
- component2: {
234
- name: 'component2',
235
- nodes: {
236
- node2: {
237
- type: 'element',
238
- customProperties: {
239
- '--my-variable': {
240
- syntax: { type: 'primitive', name: 'color' },
241
- formula: { type: 'value', value: '#ff0000' },
242
- },
243
- },
244
- attrs: {},
245
- style: {},
246
- children: [],
247
- events: {},
248
- classes: {},
249
- tag: 'div',
250
- },
251
- },
252
- apis: {},
253
- attributes: {},
254
- variables: {},
255
- formulas: {},
256
- },
257
- },
258
- },
259
- rules: [ambiguousStyleVariableSyntaxRule],
260
- }));
261
- // Should not report because non-primitive should be skipped
262
- expect(problems).toHaveLength(0);
263
- });
264
- });
265
- //# sourceMappingURL=ambiguousStyleVariableSyntaxRule.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ambiguousStyleVariableSyntaxRule.test.js","sourceRoot":"","sources":["../../../src/rules/style-variables/ambiguousStyleVariableSyntaxRule.test.ts"],"names":[],"mappings":"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"}
@@ -1,68 +0,0 @@
1
- import type { CssSyntaxNode } from '@nordcraft/core/dist/styling/customProperty'
2
- import type { ProjectFiles } from '@nordcraft/ssr/dist/ssr.types'
3
- import type { MemoFn } from '../types'
4
-
5
- export const getAllCustomPropertiesBySyntax = (
6
- memo: MemoFn,
7
- {
8
- files,
9
- }: {
10
- files: Omit<ProjectFiles, 'config'> & Partial<Pick<ProjectFiles, 'config'>>
11
- },
12
- ) =>
13
- memo('allCustomPropertiesBySyntax', () => {
14
- const store: Record<
15
- string,
16
- Record<string, Array<{ syntax: CssSyntaxNode; path: string[] }>>
17
- > = {}
18
-
19
- const add = (
20
- propName: string,
21
- syntax: CssSyntaxNode,
22
- fullPath: string[],
23
- ) => {
24
- if (syntax.type !== 'primitive') return
25
- const sName = syntax.name
26
- store[propName] ??= {}
27
- store[propName][sName] ??= []
28
- store[propName][sName].push({ syntax, path: fullPath })
29
- }
30
-
31
- for (const [componentKey, component] of Object.entries(files.components)) {
32
- for (const [nodeKey, node] of Object.entries(component?.nodes ?? {})) {
33
- if (node.type !== 'element' && node.type !== 'component') continue
34
-
35
- for (const [propName, prop] of Object.entries(
36
- node.customProperties ?? {},
37
- )) {
38
- add(propName, prop.syntax, [
39
- 'components',
40
- componentKey,
41
- 'nodes',
42
- nodeKey,
43
- 'customProperties',
44
- propName,
45
- ])
46
- }
47
-
48
- node.variants?.forEach((variant, variantIndex) => {
49
- for (const [propName, prop] of Object.entries(
50
- variant.customProperties ?? {},
51
- )) {
52
- add(propName, prop.syntax, [
53
- 'components',
54
- componentKey,
55
- 'nodes',
56
- nodeKey,
57
- 'variants',
58
- String(variantIndex),
59
- 'customProperties',
60
- propName,
61
- ])
62
- }
63
- })
64
- }
65
- }
66
-
67
- return store
68
- })
@@ -1,278 +0,0 @@
1
- import { describe, expect, test } from 'bun:test'
2
- import { searchProject } from '../../searchProject'
3
- import { ambiguousStyleVariableSyntaxRule } from './ambiguousStyleVariableSyntaxRule'
4
-
5
- describe('ambiguousStyleVariableSyntaxRule', () => {
6
- test('should report when there are style variables with the same name but different syntax', () => {
7
- const problems = Array.from(
8
- searchProject({
9
- files: {
10
- components: {
11
- component1: {
12
- name: 'component1',
13
- nodes: {
14
- node1: {
15
- type: 'element',
16
- customProperties: {
17
- '--my-variable': {
18
- syntax: { type: 'primitive', name: 'length' },
19
- formula: { type: 'value', value: '10px' },
20
- },
21
- },
22
- attrs: {},
23
- style: {},
24
- children: [],
25
- events: {},
26
- classes: {},
27
- tag: 'div',
28
- },
29
- },
30
- apis: {},
31
- attributes: {},
32
- variables: {},
33
- formulas: {},
34
- },
35
- component2: {
36
- name: 'component2',
37
- nodes: {
38
- node2: {
39
- type: 'element',
40
- customProperties: {
41
- '--my-variable': {
42
- syntax: { type: 'primitive', name: 'color' },
43
- formula: { type: 'value', value: '#ff0000' },
44
- },
45
- },
46
- attrs: {},
47
- style: {},
48
- children: [],
49
- events: {},
50
- classes: {},
51
- tag: 'div',
52
- },
53
- },
54
- apis: {},
55
- attributes: {},
56
- variables: {},
57
- formulas: {},
58
- },
59
- },
60
- },
61
- rules: [ambiguousStyleVariableSyntaxRule],
62
- }),
63
- )
64
- expect(problems).toHaveLength(2)
65
- expect(problems[0].code).toBe('ambiguous style variable syntax')
66
- expect(problems[1].code).toBe('ambiguous style variable syntax')
67
- expect(problems[0].details.name).toBe('--my-variable')
68
- expect(problems[1].details.name).toBe('--my-variable')
69
- expect(problems[0].details.duplicates).toEqual([
70
- {
71
- path: [
72
- 'components',
73
- 'component2',
74
- 'nodes',
75
- 'node2',
76
- 'customProperties',
77
- '--my-variable',
78
- ],
79
- syntax: { type: 'primitive', name: 'color' },
80
- },
81
- ])
82
- expect(problems[1].details.duplicates).toEqual([
83
- {
84
- path: [
85
- 'components',
86
- 'component1',
87
- 'nodes',
88
- 'node1',
89
- 'customProperties',
90
- '--my-variable',
91
- ],
92
- syntax: { type: 'primitive', name: 'length' },
93
- },
94
- ])
95
- })
96
-
97
- test('should not report when style variables have same name and same syntax', () => {
98
- const problems = Array.from(
99
- searchProject({
100
- files: {
101
- components: {
102
- component1: {
103
- name: 'component1',
104
- nodes: {
105
- node1: {
106
- type: 'element',
107
- customProperties: {
108
- '--my-variable': {
109
- syntax: { type: 'primitive', name: 'length' },
110
- formula: { type: 'value', value: '10px' },
111
- },
112
- },
113
- attrs: {},
114
- style: {},
115
- children: [],
116
- events: {},
117
- classes: {},
118
- tag: 'div',
119
- },
120
- },
121
- apis: {},
122
- attributes: {},
123
- variables: {},
124
- formulas: {},
125
- },
126
- component2: {
127
- name: 'component2',
128
- nodes: {
129
- node2: {
130
- type: 'element',
131
- customProperties: {
132
- '--my-variable': {
133
- syntax: { type: 'primitive', name: 'length' },
134
- formula: { type: 'value', value: '20px' },
135
- },
136
- },
137
- attrs: {},
138
- style: {},
139
- children: [],
140
- events: {},
141
- classes: {},
142
- tag: 'div',
143
- },
144
- },
145
- apis: {},
146
- attributes: {},
147
- variables: {},
148
- formulas: {},
149
- },
150
- },
151
- },
152
- rules: [ambiguousStyleVariableSyntaxRule],
153
- }),
154
- )
155
- expect(problems).toHaveLength(0)
156
- })
157
-
158
- test('should handle variant customProperties too', () => {
159
- const problems = Array.from(
160
- searchProject({
161
- files: {
162
- components: {
163
- component1: {
164
- name: 'component1',
165
- nodes: {
166
- node1: {
167
- type: 'element',
168
- customProperties: {
169
- '--my-variable': {
170
- syntax: { type: 'primitive', name: 'length' },
171
- formula: { type: 'value', value: '10px' },
172
- },
173
- },
174
- variants: [
175
- {
176
- breakpoint: 'medium',
177
- style: {},
178
- customProperties: {
179
- '--my-variable': {
180
- syntax: { type: 'primitive', name: 'color' },
181
- formula: { type: 'value', value: '#ff0000' },
182
- },
183
- },
184
- },
185
- ],
186
- attrs: {},
187
- style: {},
188
- children: [],
189
- events: {},
190
- classes: {},
191
- tag: 'div',
192
- },
193
- },
194
- apis: {},
195
- attributes: {},
196
- variables: {},
197
- formulas: {},
198
- },
199
- },
200
- },
201
- rules: [ambiguousStyleVariableSyntaxRule],
202
- }),
203
- )
204
-
205
- // Should flag both the base and the variant for conflicting syntax
206
- expect(problems).toHaveLength(2)
207
- expect(problems.map((p) => p.details.name)).toEqual([
208
- '--my-variable',
209
- '--my-variable',
210
- ])
211
- })
212
-
213
- test('should ignore non-primitive syntax', () => {
214
- const problems = Array.from(
215
- searchProject({
216
- files: {
217
- components: {
218
- component1: {
219
- name: 'component1',
220
- nodes: {
221
- node1: {
222
- type: 'element',
223
- customProperties: {
224
- '--my-variable': {
225
- syntax: {
226
- type: 'keyword',
227
- keywords: ['auto', 'inherit'],
228
- },
229
- formula: { type: 'value', value: '10px' },
230
- },
231
- },
232
- attrs: {},
233
- style: {},
234
- children: [],
235
- events: {},
236
- classes: {},
237
- tag: 'div',
238
- },
239
- },
240
- apis: {},
241
- attributes: {},
242
- variables: {},
243
- formulas: {},
244
- },
245
- component2: {
246
- name: 'component2',
247
- nodes: {
248
- node2: {
249
- type: 'element',
250
- customProperties: {
251
- '--my-variable': {
252
- syntax: { type: 'primitive', name: 'color' },
253
- formula: { type: 'value', value: '#ff0000' },
254
- },
255
- },
256
- attrs: {},
257
- style: {},
258
- children: [],
259
- events: {},
260
- classes: {},
261
- tag: 'div',
262
- },
263
- },
264
- apis: {},
265
- attributes: {},
266
- variables: {},
267
- formulas: {},
268
- },
269
- },
270
- },
271
- rules: [ambiguousStyleVariableSyntaxRule],
272
- }),
273
- )
274
-
275
- // Should not report because non-primitive should be skipped
276
- expect(problems).toHaveLength(0)
277
- })
278
- })
@@ -1,65 +0,0 @@
1
- import type { CssSyntaxNode } from '@nordcraft/core/dist/styling/customProperty'
2
- import { getAllCustomPropertiesBySyntax } from '../../memos/getAllCustomPropertiesBySyntax'
3
- import type { Rule } from '../../types'
4
-
5
- export const ambiguousStyleVariableSyntaxRule: Rule<{
6
- name: string
7
- duplicates: Array<{ path: string[]; syntax: CssSyntaxNode }>
8
- }> = {
9
- code: 'ambiguous style variable syntax',
10
- level: 'error',
11
- category: 'Other',
12
- visit: (report, args) => {
13
- const { nodeType, value, files, memo, path } = args
14
- if (nodeType !== 'component-node') return
15
- if (value.type !== 'element' && value.type !== 'component') return
16
-
17
- const check = (
18
- propName: string,
19
- syntax: CssSyntaxNode,
20
- basePath: Array<string | number>,
21
- ) => {
22
- if (syntax.type !== 'primitive') return
23
- const allCustomPropertiesBySyntax = getAllCustomPropertiesBySyntax(memo, {
24
- files,
25
- })[propName]
26
-
27
- const conflicts = Object.entries(allCustomPropertiesBySyntax)
28
- .filter(([name]) => name !== syntax.name)
29
- .flatMap(([, entries]) => entries)
30
-
31
- if (conflicts.length > 0) {
32
- report(basePath, {
33
- name: propName,
34
- duplicates: conflicts,
35
- })
36
- }
37
- }
38
-
39
- for (const [propName, prop] of Object.entries(
40
- value.customProperties ?? {},
41
- )) {
42
- check(propName, prop.syntax, [
43
- ...path,
44
- 'customProperties',
45
- propName,
46
- 'name',
47
- ])
48
- }
49
-
50
- value.variants?.forEach((variant, variantIndex) => {
51
- for (const [propName, prop] of Object.entries(
52
- variant.customProperties ?? {},
53
- )) {
54
- check(propName, prop.syntax, [
55
- ...path,
56
- 'variants',
57
- String(variantIndex),
58
- 'customProperties',
59
- propName,
60
- 'name',
61
- ])
62
- }
63
- })
64
- },
65
- }