@nordcraft/search 1.0.38 → 1.0.39

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/src/types.d.ts CHANGED
@@ -21,6 +21,8 @@ import type {
21
21
  Route,
22
22
  ToddleProject,
23
23
  } from '@nordcraft/ssr/dist/ssr.types'
24
+ import type { NoReferenceComponentRuleFix } from './rules/components/noReferenceComponentRule'
25
+ import type { LegacyFormulaRuleFix } from './rules/formulas/legacyFormulaRule'
24
26
 
25
27
  type Code =
26
28
  | 'ambiguous style variable syntax'
@@ -106,6 +108,7 @@ export type Result = {
106
108
  category: Category
107
109
  level: Level
108
110
  details?: any
111
+ fixes?: FixType[]
109
112
  }
110
113
 
111
114
  interface ApplicationCookie {
@@ -239,9 +242,9 @@ type ComponentAttributeNode = {
239
242
  component: ToddleComponent<Function>
240
243
  } & Base
241
244
 
242
- type FormulaNode = {
245
+ type FormulaNode<F = Formula> = {
243
246
  nodeType: 'formula'
244
- value: Formula
247
+ value: F
245
248
  component?: ToddleComponent<Function>
246
249
  } & Base
247
250
 
@@ -308,13 +311,21 @@ export type NodeType =
308
311
  | ProjectRoute
309
312
  | StyleVariantNode
310
313
 
314
+ type FixType = LegacyFormulaRuleFix | NoReferenceComponentRuleFix
315
+
311
316
  export interface Rule<T = unknown, V = NodeType> {
312
317
  category: Category
313
318
  code: Code
314
319
  level: Level
315
320
  visit: (
316
- report: (path: (string | number)[], details?: T) => void,
321
+ report: (path: (string | number)[], details?: T, fixes?: FixType[]) => void,
317
322
  data: V,
318
323
  state?: ApplicationState | undefined,
319
324
  ) => void
325
+ fixes?: Partial<
326
+ Record<
327
+ FixType,
328
+ (data: V, state?: ApplicationState | undefined) => ProjectFiles | void
329
+ >
330
+ >
320
331
  }
@@ -0,0 +1,80 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+ import { shouldSearchExactPath, shouldVisitTree } from './helpers'
3
+
4
+ describe('shouldSearchPath', () => {
5
+ test('should return true for paths in pathsToVisit', () => {
6
+ const pathsToVisit = [
7
+ ['components', 'Button'],
8
+ ['components', 'Input'],
9
+ ]
10
+ expect(
11
+ shouldVisitTree({
12
+ path: ['components', 'Button', 'attrs', 'attr1', 'testValue'],
13
+ pathsToVisit,
14
+ }),
15
+ ).toBe(true)
16
+ expect(
17
+ shouldVisitTree({ path: ['components', 'Input'], pathsToVisit }),
18
+ ).toBe(true)
19
+ expect(
20
+ shouldVisitTree({
21
+ path: ['components', 'Button', 'formulas'],
22
+ pathsToVisit,
23
+ }),
24
+ ).toBe(true)
25
+ expect(
26
+ shouldVisitTree({
27
+ path: ['components', 'project-sidebar-item'],
28
+ pathsToVisit: [
29
+ [
30
+ 'components',
31
+ 'project-sidebar-item',
32
+ 'formulas',
33
+ 'p_Z1PzOcDop79KGafQ7Lm',
34
+ 'formula',
35
+ ],
36
+ ],
37
+ }),
38
+ ).toBe(true)
39
+ })
40
+
41
+ test('should return false for paths not in pathsToVisit', () => {
42
+ const pathsToVisit = [
43
+ ['components', 'Button'],
44
+ ['components', 'Input'],
45
+ ]
46
+ expect(
47
+ shouldVisitTree({ path: ['components', 'Card'], pathsToVisit }),
48
+ ).toBe(false)
49
+ expect(
50
+ shouldVisitTree({ path: ['components', 'Form'], pathsToVisit }),
51
+ ).toBe(false)
52
+ })
53
+ })
54
+
55
+ describe('shouldSearchExactPath', () => {
56
+ test.only('should only return true for exact matches', () => {
57
+ const pathsToVisit = [
58
+ ['components', 'Button'],
59
+ ['components', 'Input'],
60
+ ]
61
+ expect(
62
+ shouldSearchExactPath({ path: ['components', 'Button'], pathsToVisit }),
63
+ ).toBe(true)
64
+ expect(
65
+ shouldSearchExactPath({ path: ['components', 'Input'], pathsToVisit }),
66
+ ).toBe(true)
67
+ expect(
68
+ shouldSearchExactPath({
69
+ path: ['components', 'Button', 'formulas'],
70
+ pathsToVisit,
71
+ }),
72
+ ).toBe(false)
73
+ expect(
74
+ shouldSearchExactPath({
75
+ path: ['components', 'project-sidebar-item'],
76
+ pathsToVisit,
77
+ }),
78
+ ).toBe(false)
79
+ })
80
+ })
@@ -4,18 +4,46 @@ import type {
4
4
  } from '@nordcraft/core/dist/component/component.types'
5
5
  import { isDefined } from '@nordcraft/core/dist/utils/util'
6
6
 
7
- export function shouldSearchPath(
8
- path: (string | number)[],
9
- pathsToVisit: string[][] = [],
10
- ) {
7
+ /**
8
+ * Returns true if the full path is included in any of the pathsToVisit
9
+ * This allows searching only certain sub-trees in the files
10
+ * If pathsToVisit is empty, all paths are searched
11
+ */
12
+ export function shouldVisitTree({
13
+ path,
14
+ pathsToVisit = [],
15
+ }: {
16
+ path: (string | number)[]
17
+ pathsToVisit?: (string | number)[][]
18
+ }) {
11
19
  return (
12
20
  pathsToVisit.length === 0 ||
13
21
  pathsToVisit.some((pathToVisit) =>
14
- pathToVisit.every((p1, i) => path[i] === p1),
22
+ // Either the index is outside the current path (we are deeper in the tree)
23
+ // or the path matches on each index
24
+ pathToVisit.every((p1, i) => i >= path.length || path[i] === p1),
15
25
  )
16
26
  )
17
27
  }
18
28
 
29
+ /**
30
+ * Returns true if the exact path is included in pathsToVisit
31
+ * This allows searching only certain nodes in the files
32
+ */
33
+ export function shouldSearchExactPath({
34
+ path,
35
+ pathsToVisit,
36
+ }: {
37
+ path: (string | number)[]
38
+ pathsToVisit: (string | number)[][]
39
+ }) {
40
+ return pathsToVisit.some(
41
+ (pathToVisit) =>
42
+ path.length === pathToVisit.length &&
43
+ pathToVisit.every((p1, i) => path[i] === p1),
44
+ )
45
+ }
46
+
19
47
  export const isLegacyAction = (model: ActionModel) => {
20
48
  switch (model.type) {
21
49
  case 'Custom':