@nordcraft/search 1.0.38 → 1.0.40

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 (41) hide show
  1. package/dist/fixProject.js +32 -0
  2. package/dist/fixProject.js.map +1 -0
  3. package/dist/problems.worker.js +45 -8
  4. package/dist/problems.worker.js.map +1 -1
  5. package/dist/rules/actions/legacyActionRule.js +144 -2
  6. package/dist/rules/actions/legacyActionRule.js.map +1 -1
  7. package/dist/rules/actions/legacyActionRule.test.js +235 -1
  8. package/dist/rules/actions/legacyActionRule.test.js.map +1 -1
  9. package/dist/rules/components/noReferenceComponentRule.js +31 -17
  10. package/dist/rules/components/noReferenceComponentRule.js.map +1 -1
  11. package/dist/rules/components/noReferenceComponentRule.test.js +86 -1
  12. package/dist/rules/components/noReferenceComponentRule.test.js.map +1 -1
  13. package/dist/rules/formulas/legacyFormulaRule.js +602 -6
  14. package/dist/rules/formulas/legacyFormulaRule.js.map +1 -1
  15. package/dist/rules/formulas/legacyFormulaRule.test.js +232 -1
  16. package/dist/rules/formulas/legacyFormulaRule.test.js.map +1 -1
  17. package/dist/rules/formulas/noReferenceProjectFormulaRule.js +73 -58
  18. package/dist/rules/formulas/noReferenceProjectFormulaRule.js.map +1 -1
  19. package/dist/rules/formulas/noReferenceProjectFormulaRule.test.js +34 -1
  20. package/dist/rules/formulas/noReferenceProjectFormulaRule.test.js.map +1 -1
  21. package/dist/searchProject.js +338 -217
  22. package/dist/searchProject.js.map +1 -1
  23. package/dist/util/helpers.js +31 -5
  24. package/dist/util/helpers.js.map +1 -1
  25. package/dist/util/helpers.test.js +58 -0
  26. package/dist/util/helpers.test.js.map +1 -0
  27. package/package.json +3 -2
  28. package/src/fixProject.ts +47 -0
  29. package/src/problems.worker.ts +90 -12
  30. package/src/rules/actions/legacyActionRule.test.ts +245 -1
  31. package/src/rules/actions/legacyActionRule.ts +166 -4
  32. package/src/rules/components/noReferenceComponentRule.test.ts +87 -1
  33. package/src/rules/components/noReferenceComponentRule.ts +38 -23
  34. package/src/rules/formulas/legacyFormulaRule.test.ts +242 -1
  35. package/src/rules/formulas/legacyFormulaRule.ts +697 -10
  36. package/src/rules/formulas/noReferenceProjectFormulaRule.test.ts +36 -1
  37. package/src/rules/formulas/noReferenceProjectFormulaRule.ts +78 -64
  38. package/src/searchProject.ts +217 -98
  39. package/src/types.d.ts +20 -3
  40. package/src/util/helpers.test.ts +80 -0
  41. package/src/util/helpers.ts +61 -9
package/src/types.d.ts CHANGED
@@ -21,6 +21,10 @@ import type {
21
21
  Route,
22
22
  ToddleProject,
23
23
  } from '@nordcraft/ssr/dist/ssr.types'
24
+ import type { LegacyActionRuleFix } from './rules/actions/legacyActionRule'
25
+ import type { NoReferenceComponentRuleFix } from './rules/components/noReferenceComponentRule'
26
+ import type { LegacyFormulaRuleFix } from './rules/formulas/legacyFormulaRule'
27
+ import type { NoReferenceProjectFormulaRuleFix } from './rules/formulas/noReferenceProjectFormulaRule'
24
28
 
25
29
  type Code =
26
30
  | 'ambiguous style variable syntax'
@@ -106,6 +110,7 @@ export type Result = {
106
110
  category: Category
107
111
  level: Level
108
112
  details?: any
113
+ fixes?: FixType[]
109
114
  }
110
115
 
111
116
  interface ApplicationCookie {
@@ -239,9 +244,9 @@ type ComponentAttributeNode = {
239
244
  component: ToddleComponent<Function>
240
245
  } & Base
241
246
 
242
- type FormulaNode = {
247
+ type FormulaNode<F = Formula> = {
243
248
  nodeType: 'formula'
244
- value: Formula
249
+ value: F
245
250
  component?: ToddleComponent<Function>
246
251
  } & Base
247
252
 
@@ -308,13 +313,25 @@ export type NodeType =
308
313
  | ProjectRoute
309
314
  | StyleVariantNode
310
315
 
316
+ type FixType =
317
+ | LegacyFormulaRuleFix
318
+ | LegacyActionRuleFix
319
+ | NoReferenceComponentRuleFix
320
+ | NoReferenceProjectFormulaRuleFix
321
+
311
322
  export interface Rule<T = unknown, V = NodeType> {
312
323
  category: Category
313
324
  code: Code
314
325
  level: Level
315
326
  visit: (
316
- report: (path: (string | number)[], details?: T) => void,
327
+ report: (path: (string | number)[], details?: T, fixes?: FixType[]) => void,
317
328
  data: V,
318
329
  state?: ApplicationState | undefined,
319
330
  ) => void
331
+ fixes?: Partial<
332
+ Record<
333
+ FixType,
334
+ (data: V, state?: ApplicationState | undefined) => ProjectFiles | void
335
+ >
336
+ >
320
337
  }
@@ -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
+ })
@@ -1,22 +1,55 @@
1
1
  import type {
2
2
  ActionModel,
3
+ CustomActionArgument,
4
+ CustomActionModel,
3
5
  ElementNodeModel,
4
6
  } from '@nordcraft/core/dist/component/component.types'
7
+ import type { FunctionArgument } from '@nordcraft/core/dist/formula/formula'
5
8
  import { isDefined } from '@nordcraft/core/dist/utils/util'
6
9
 
7
- export function shouldSearchPath(
8
- path: (string | number)[],
9
- pathsToVisit: string[][] = [],
10
- ) {
10
+ /**
11
+ * Returns true if the full path is included in any of the pathsToVisit
12
+ * This allows searching only certain sub-trees in the files
13
+ * If pathsToVisit is empty, all paths are searched
14
+ */
15
+ export function shouldVisitTree({
16
+ path,
17
+ pathsToVisit = [],
18
+ }: {
19
+ path: (string | number)[]
20
+ pathsToVisit?: (string | number)[][]
21
+ }) {
11
22
  return (
12
23
  pathsToVisit.length === 0 ||
13
24
  pathsToVisit.some((pathToVisit) =>
14
- pathToVisit.every((p1, i) => path[i] === p1),
25
+ // Either the index is outside the current path (we are deeper in the tree)
26
+ // or the path matches on each index
27
+ pathToVisit.every((p1, i) => i >= path.length || path[i] === p1),
15
28
  )
16
29
  )
17
30
  }
18
31
 
19
- export const isLegacyAction = (model: ActionModel) => {
32
+ /**
33
+ * Returns true if the exact path is included in pathsToVisit
34
+ * This allows searching only certain nodes in the files
35
+ */
36
+ export function shouldSearchExactPath({
37
+ path,
38
+ pathsToVisit,
39
+ }: {
40
+ path: (string | number)[]
41
+ pathsToVisit: (string | number)[][]
42
+ }) {
43
+ return pathsToVisit.some(
44
+ (pathToVisit) =>
45
+ path.length === pathToVisit.length &&
46
+ pathToVisit.every((p1, i) => path[i] === p1),
47
+ )
48
+ }
49
+
50
+ export const isLegacyAction = (
51
+ model: ActionModel,
52
+ ): model is CustomActionModel => {
20
53
  switch (model.type) {
21
54
  case 'Custom':
22
55
  case undefined:
@@ -30,14 +63,11 @@ const LEGACY_CUSTOM_ACTIONS = new Set([
30
63
  'If',
31
64
  'PreventDefault',
32
65
  'StopPropagation',
33
- 'Copy To Clipboard',
34
66
  'CopyToClipboard',
35
67
  'UpdateVariable',
36
- 'Update Variable',
37
68
  'Update URL parameter',
38
69
  'updateUrlParameters',
39
70
  'UpdateQueryParam',
40
- 'Update Query',
41
71
  'Fetch',
42
72
  'SetTimeout',
43
73
  'SetInterval',
@@ -46,6 +76,7 @@ const LEGACY_CUSTOM_ACTIONS = new Set([
46
76
  'GoToURL',
47
77
  'TriggerEvent',
48
78
  'Set session cookies',
79
+ '@toddle/setSessionCookies',
49
80
  ])
50
81
 
51
82
  interface BaseInteractiveContent {
@@ -102,3 +133,24 @@ export const interactiveContentElementDefinition = (
102
133
  }
103
134
  return true
104
135
  })
136
+
137
+ export const ARRAY_ARGUMENT_MAPPINGS = { List: 'Array' }
138
+ export const PREDICATE_ARGUMENT_MAPPINGS = {
139
+ ...ARRAY_ARGUMENT_MAPPINGS,
140
+ 'Predicate fx': 'Formula',
141
+ }
142
+
143
+ export const renameArguments = <
144
+ T extends FunctionArgument | CustomActionArgument,
145
+ >(
146
+ mappings: Record<string, string>,
147
+ args: T[] | undefined,
148
+ ): T[] =>
149
+ args?.map((arg) => ({
150
+ ...arg,
151
+ // Let's adjust the names
152
+ name:
153
+ typeof arg.name === 'string'
154
+ ? (mappings[arg.name] ?? arg.name)
155
+ : arg.name,
156
+ })) ?? []