@nordcraft/search 1.0.39 → 1.0.41

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.
@@ -1,92 +1,106 @@
1
1
  import { ToddleComponent } from '@nordcraft/core/dist/component/ToddleComponent'
2
2
  import type { Formula } from '@nordcraft/core/dist/formula/formula'
3
3
  import { isToddleFormula } from '@nordcraft/core/dist/formula/formulaTypes'
4
+ import { omit } from '@nordcraft/core/dist/utils/collections'
4
5
  import { ToddleApiService } from '@nordcraft/ssr/dist/ToddleApiService'
5
6
  import { ToddleRoute } from '@nordcraft/ssr/dist/ToddleRoute'
6
- import type { Rule } from '../../types'
7
+ import type { NodeType, Rule } from '../../types'
7
8
 
8
9
  export const noReferenceProjectFormulaRule: Rule<void> = {
9
10
  code: 'no-reference project formula',
10
11
  level: 'warning',
11
12
  category: 'No References',
12
- visit: (report, { path, files, value, nodeType, memo }) => {
13
- if (nodeType !== 'project-formula' || value.exported === true) {
13
+ visit: (report, details) => {
14
+ if (hasReferences(details)) {
14
15
  return
15
16
  }
17
+ report(details.path, undefined, ['delete-project-formula'])
18
+ },
19
+ fixes: {
20
+ 'delete-project-formula': (data) => {
21
+ if (hasReferences(data)) {
22
+ return
23
+ }
24
+ return omit(data.files, data.path)
25
+ },
26
+ },
27
+ }
16
28
 
17
- // Check in all API services first, since that should be quick
18
- for (const apiService of Object.values(files.services ?? {})) {
19
- const service = new ToddleApiService({
20
- service: apiService,
21
- globalFormulas: { formulas: files.formulas, packages: files.packages },
22
- })
23
- const formulas = service.formulasInService()
24
- for (const { path: _formulaPath, formula } of formulas) {
25
- // Check if the formula is used in the formula
26
- if (checkFormula(formula, value.name)) {
27
- return
28
- }
29
+ export type NoReferenceProjectFormulaRuleFix = 'delete-project-formula'
30
+
31
+ const hasReferences = ({ value, files, nodeType, memo }: NodeType) => {
32
+ if (nodeType !== 'project-formula' || value.exported === true) {
33
+ return true
34
+ }
35
+
36
+ // Check in all API services first, since that should be quick
37
+ for (const apiService of Object.values(files.services ?? {})) {
38
+ const service = new ToddleApiService({
39
+ service: apiService,
40
+ globalFormulas: { formulas: files.formulas, packages: files.packages },
41
+ })
42
+ const formulas = service.formulasInService()
43
+ for (const { path: _formulaPath, formula } of formulas) {
44
+ // Check if the formula is used in the formula
45
+ if (checkFormula(formula, value.name)) {
46
+ return true
29
47
  }
30
48
  }
49
+ }
31
50
 
32
- // Check routes before components, since they should be quicker
33
- for (const projectRoute of Object.values(files.routes ?? {})) {
34
- const route = new ToddleRoute({
35
- route: projectRoute,
36
- globalFormulas: { formulas: files.formulas, packages: files.packages },
37
- })
38
- const formulas = route.formulasInRoute()
39
- for (const { path: _formulaPath, formula } of formulas) {
40
- // Check if the formula is used in the formula
41
- if (checkFormula(formula, value.name)) {
42
- return
43
- }
51
+ // Check routes before components, since they should be quicker
52
+ for (const projectRoute of Object.values(files.routes ?? {})) {
53
+ const route = new ToddleRoute({
54
+ route: projectRoute,
55
+ globalFormulas: { formulas: files.formulas, packages: files.packages },
56
+ })
57
+ const formulas = route.formulasInRoute()
58
+ for (const { path: _formulaPath, formula } of formulas) {
59
+ // Check if the formula is used in the formula
60
+ if (checkFormula(formula, value.name)) {
61
+ return true
44
62
  }
45
63
  }
64
+ }
46
65
 
47
- const componentFormulaReferences = memo(
48
- 'componentFormulaReferences',
49
- () => {
50
- const usedFormulas = new Set<string>()
51
- for (const component of Object.values(files.components)) {
52
- const c = new ToddleComponent({
53
- // Enforce that the component is not undefined since we're iterating
54
- component: component!,
55
- getComponent: (name) => files.components[name],
56
- packageName: undefined,
57
- globalFormulas: {
58
- formulas: files.formulas,
59
- packages: files.packages,
60
- },
61
- })
62
- for (const { formula } of c.formulasInComponent()) {
63
- if (formula.type === 'function') {
64
- usedFormulas.add(formula.name)
65
- }
66
- }
66
+ const componentFormulaReferences = memo('componentFormulaReferences', () => {
67
+ const usedFormulas = new Set<string>()
68
+ for (const component of Object.values(files.components)) {
69
+ const c = new ToddleComponent({
70
+ // Enforce that the component is not undefined since we're iterating
71
+ component: component!,
72
+ getComponent: (name) => files.components[name],
73
+ packageName: undefined,
74
+ globalFormulas: {
75
+ formulas: files.formulas,
76
+ packages: files.packages,
77
+ },
78
+ })
79
+ for (const { formula } of c.formulasInComponent()) {
80
+ if (formula.type === 'function') {
81
+ usedFormulas.add(formula.name)
67
82
  }
68
- return usedFormulas
69
- },
70
- )
71
-
72
- if (componentFormulaReferences.has(value.name)) {
73
- return
83
+ }
74
84
  }
85
+ return usedFormulas
86
+ })
75
87
 
76
- // TODO: Memoize similar to above. We need have a helper class `ToddleFormula` with `ToddleFormula.normalizeFormulas()`
77
- for (const f of Object.values(files.formulas ?? {})) {
78
- if (f.name === value.name) {
79
- continue
80
- }
88
+ if (componentFormulaReferences.has(value.name)) {
89
+ return true
90
+ }
81
91
 
82
- // Check if the formula is used in the formula
83
- if (isToddleFormula(f) && checkFormula(f.formula, value.name)) {
84
- return
85
- }
92
+ // TODO: Memoize similar to above. We need have a helper class `ToddleFormula` with `ToddleFormula.normalizeFormulas()`
93
+ for (const f of Object.values(files.formulas ?? {})) {
94
+ if (f.name === value.name) {
95
+ continue
86
96
  }
87
97
 
88
- report(path)
89
- },
98
+ // Check if the formula is used in the formula
99
+ if (isToddleFormula(f) && checkFormula(f.formula, value.name)) {
100
+ return true
101
+ }
102
+ }
103
+ return false
90
104
  }
91
105
 
92
106
  const checkArguments = (
package/src/types.d.ts CHANGED
@@ -21,8 +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'
24
25
  import type { NoReferenceComponentRuleFix } from './rules/components/noReferenceComponentRule'
25
26
  import type { LegacyFormulaRuleFix } from './rules/formulas/legacyFormulaRule'
27
+ import type { NoReferenceProjectFormulaRuleFix } from './rules/formulas/noReferenceProjectFormulaRule'
26
28
 
27
29
  type Code =
28
30
  | 'ambiguous style variable syntax'
@@ -311,7 +313,11 @@ export type NodeType =
311
313
  | ProjectRoute
312
314
  | StyleVariantNode
313
315
 
314
- type FixType = LegacyFormulaRuleFix | NoReferenceComponentRuleFix
316
+ type FixType =
317
+ | LegacyFormulaRuleFix
318
+ | LegacyActionRuleFix
319
+ | NoReferenceComponentRuleFix
320
+ | NoReferenceProjectFormulaRuleFix
315
321
 
316
322
  export interface Rule<T = unknown, V = NodeType> {
317
323
  category: Category
@@ -1,7 +1,10 @@
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
10
  /**
@@ -44,7 +47,9 @@ export function shouldSearchExactPath({
44
47
  )
45
48
  }
46
49
 
47
- export const isLegacyAction = (model: ActionModel) => {
50
+ export const isLegacyAction = (
51
+ model: ActionModel,
52
+ ): model is CustomActionModel => {
48
53
  switch (model.type) {
49
54
  case 'Custom':
50
55
  case undefined:
@@ -58,14 +63,12 @@ const LEGACY_CUSTOM_ACTIONS = new Set([
58
63
  'If',
59
64
  'PreventDefault',
60
65
  'StopPropagation',
61
- 'Copy To Clipboard',
62
66
  'CopyToClipboard',
63
67
  'UpdateVariable',
64
68
  'Update Variable',
65
69
  'Update URL parameter',
66
70
  'updateUrlParameters',
67
71
  'UpdateQueryParam',
68
- 'Update Query',
69
72
  'Fetch',
70
73
  'SetTimeout',
71
74
  'SetInterval',
@@ -74,6 +77,7 @@ const LEGACY_CUSTOM_ACTIONS = new Set([
74
77
  'GoToURL',
75
78
  'TriggerEvent',
76
79
  'Set session cookies',
80
+ '@toddle/setSessionCookies',
77
81
  ])
78
82
 
79
83
  interface BaseInteractiveContent {
@@ -130,3 +134,24 @@ export const interactiveContentElementDefinition = (
130
134
  }
131
135
  return true
132
136
  })
137
+
138
+ export const ARRAY_ARGUMENT_MAPPINGS = { List: 'Array' }
139
+ export const PREDICATE_ARGUMENT_MAPPINGS = {
140
+ ...ARRAY_ARGUMENT_MAPPINGS,
141
+ 'Predicate fx': 'Formula',
142
+ }
143
+
144
+ export const renameArguments = <
145
+ T extends FunctionArgument | CustomActionArgument,
146
+ >(
147
+ mappings: Record<string, string>,
148
+ args: T[] | undefined,
149
+ ): T[] =>
150
+ args?.map((arg) => ({
151
+ ...arg,
152
+ // Let's adjust the names
153
+ name:
154
+ typeof arg.name === 'string'
155
+ ? (mappings[arg.name] ?? arg.name)
156
+ : arg.name,
157
+ })) ?? []