@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.
- package/dist/rules/actions/legacyActionRule.js +168 -2
- package/dist/rules/actions/legacyActionRule.js.map +1 -1
- package/dist/rules/actions/legacyActionRule.test.js +304 -1
- package/dist/rules/actions/legacyActionRule.test.js.map +1 -1
- package/dist/rules/formulas/legacyFormulaRule.js +5 -23
- package/dist/rules/formulas/legacyFormulaRule.js.map +1 -1
- package/dist/rules/formulas/noReferenceProjectFormulaRule.js +73 -58
- package/dist/rules/formulas/noReferenceProjectFormulaRule.js.map +1 -1
- package/dist/rules/formulas/noReferenceProjectFormulaRule.test.js +34 -1
- package/dist/rules/formulas/noReferenceProjectFormulaRule.test.js.map +1 -1
- package/dist/util/helpers.js +13 -2
- package/dist/util/helpers.js.map +1 -1
- package/package.json +2 -2
- package/src/rules/actions/legacyActionRule.test.ts +316 -1
- package/src/rules/actions/legacyActionRule.ts +191 -4
- package/src/rules/formulas/legacyFormulaRule.ts +9 -31
- package/src/rules/formulas/noReferenceProjectFormulaRule.test.ts +36 -1
- package/src/rules/formulas/noReferenceProjectFormulaRule.ts +78 -64
- package/src/types.d.ts +7 -1
- package/src/util/helpers.ts +28 -3
|
@@ -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,
|
|
13
|
-
if (
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
69
|
-
},
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
if (componentFormulaReferences.has(value.name)) {
|
|
73
|
-
return
|
|
83
|
+
}
|
|
74
84
|
}
|
|
85
|
+
return usedFormulas
|
|
86
|
+
})
|
|
75
87
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
continue
|
|
80
|
-
}
|
|
88
|
+
if (componentFormulaReferences.has(value.name)) {
|
|
89
|
+
return true
|
|
90
|
+
}
|
|
81
91
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
package/src/util/helpers.ts
CHANGED
|
@@ -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 = (
|
|
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
|
+
})) ?? []
|