@nordcraft/search 1.0.39 → 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.
- package/dist/rules/actions/legacyActionRule.js +144 -2
- package/dist/rules/actions/legacyActionRule.js.map +1 -1
- package/dist/rules/actions/legacyActionRule.test.js +235 -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 -3
- package/dist/util/helpers.js.map +1 -1
- package/package.json +2 -2
- package/src/rules/actions/legacyActionRule.test.ts +245 -1
- package/src/rules/actions/legacyActionRule.ts +166 -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 -4
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ActionModel,
|
|
3
|
+
CustomActionArgument,
|
|
4
|
+
} from '@nordcraft/core/dist/component/component.types'
|
|
5
|
+
import { set } from '@nordcraft/core/dist/utils/collections'
|
|
1
6
|
import type { Rule } from '../../types'
|
|
2
|
-
import { isLegacyAction } from '../../util/helpers'
|
|
7
|
+
import { isLegacyAction, renameArguments } from '../../util/helpers'
|
|
3
8
|
|
|
4
9
|
export const legacyActionRule: Rule<{
|
|
5
10
|
name: string
|
|
@@ -11,7 +16,6 @@ export const legacyActionRule: Rule<{
|
|
|
11
16
|
if (nodeType !== 'action-model') {
|
|
12
17
|
return
|
|
13
18
|
}
|
|
14
|
-
|
|
15
19
|
if (isLegacyAction(value)) {
|
|
16
20
|
let details: { name: string } | undefined
|
|
17
21
|
if ('name' in value) {
|
|
@@ -19,8 +23,166 @@ export const legacyActionRule: Rule<{
|
|
|
19
23
|
name: value.name,
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
report(
|
|
27
|
+
path,
|
|
28
|
+
details,
|
|
29
|
+
unfixableLegacyActions.has(value.name)
|
|
30
|
+
? undefined
|
|
31
|
+
: !formulaNamedActions.includes(value.name) ||
|
|
32
|
+
// Check if the first argument is a value formula with a string value
|
|
33
|
+
(value.arguments?.[0].formula.type === 'value' &&
|
|
34
|
+
typeof value.arguments[0].formula.value === 'string')
|
|
35
|
+
? ['replace-legacy-action']
|
|
36
|
+
: undefined,
|
|
37
|
+
)
|
|
24
38
|
}
|
|
25
39
|
},
|
|
40
|
+
fixes: {
|
|
41
|
+
'replace-legacy-action': ({ path, value, nodeType, files }) => {
|
|
42
|
+
if (nodeType !== 'action-model') {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
if (!isLegacyAction(value)) {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let newAction: ActionModel | undefined
|
|
50
|
+
switch (value.name) {
|
|
51
|
+
case 'If': {
|
|
52
|
+
const trueActions = value.events?.['true']?.actions ?? []
|
|
53
|
+
const falseActions = value.events?.['false']?.actions ?? []
|
|
54
|
+
const trueCondition: CustomActionArgument | undefined =
|
|
55
|
+
(value.arguments ?? [])[0]
|
|
56
|
+
newAction = {
|
|
57
|
+
type: 'Switch',
|
|
58
|
+
cases: [
|
|
59
|
+
{
|
|
60
|
+
condition: trueCondition?.formula ?? null,
|
|
61
|
+
actions: trueActions,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
default: { actions: falseActions },
|
|
65
|
+
}
|
|
66
|
+
break
|
|
67
|
+
}
|
|
68
|
+
case 'PreventDefault': {
|
|
69
|
+
newAction = {
|
|
70
|
+
name: '@toddle/preventDefault',
|
|
71
|
+
arguments: [],
|
|
72
|
+
label: 'Prevent default',
|
|
73
|
+
}
|
|
74
|
+
break
|
|
75
|
+
}
|
|
76
|
+
case 'StopPropagation': {
|
|
77
|
+
newAction = {
|
|
78
|
+
name: '@toddle/stopPropagation',
|
|
79
|
+
arguments: [],
|
|
80
|
+
label: 'Stop propagation',
|
|
81
|
+
}
|
|
82
|
+
break
|
|
83
|
+
}
|
|
84
|
+
case 'UpdateVariable': {
|
|
85
|
+
const variableName =
|
|
86
|
+
value.arguments?.[0]?.formula.type === 'value'
|
|
87
|
+
? value.arguments[0].formula.value
|
|
88
|
+
: undefined
|
|
89
|
+
if (typeof variableName !== 'string') {
|
|
90
|
+
break
|
|
91
|
+
}
|
|
92
|
+
const variableValue = value.arguments?.[1]?.formula
|
|
93
|
+
if (!variableValue) {
|
|
94
|
+
break
|
|
95
|
+
}
|
|
96
|
+
newAction = {
|
|
97
|
+
type: 'SetVariable',
|
|
98
|
+
variable: variableName,
|
|
99
|
+
data: variableValue,
|
|
100
|
+
}
|
|
101
|
+
break
|
|
102
|
+
}
|
|
103
|
+
case 'SetTimeout': {
|
|
104
|
+
newAction = {
|
|
105
|
+
...value,
|
|
106
|
+
name: '@toddle/sleep',
|
|
107
|
+
arguments: renameArguments(
|
|
108
|
+
{ 'Delay in ms': 'Delay in milliseconds' },
|
|
109
|
+
value.arguments,
|
|
110
|
+
),
|
|
111
|
+
events: value.events?.['timeout']
|
|
112
|
+
? { tick: value.events.timeout }
|
|
113
|
+
: undefined,
|
|
114
|
+
label: 'Sleep',
|
|
115
|
+
}
|
|
116
|
+
break
|
|
117
|
+
}
|
|
118
|
+
case 'SetInterval': {
|
|
119
|
+
newAction = {
|
|
120
|
+
...value,
|
|
121
|
+
name: '@toddle/interval',
|
|
122
|
+
arguments: renameArguments(
|
|
123
|
+
{ 'Interval in ms': 'Interval in milliseconds' },
|
|
124
|
+
value.arguments,
|
|
125
|
+
),
|
|
126
|
+
label: 'Interval',
|
|
127
|
+
}
|
|
128
|
+
break
|
|
129
|
+
}
|
|
130
|
+
case 'Debug': {
|
|
131
|
+
newAction = {
|
|
132
|
+
...value,
|
|
133
|
+
name: '@toddle/logToConsole',
|
|
134
|
+
label: 'Log to console',
|
|
135
|
+
}
|
|
136
|
+
break
|
|
137
|
+
}
|
|
138
|
+
case 'GoToURL': {
|
|
139
|
+
newAction = {
|
|
140
|
+
name: '@toddle/gotToURL', // Yes, the typo is in the action name
|
|
141
|
+
arguments: renameArguments({ url: 'URL' }, value.arguments),
|
|
142
|
+
label: 'Go to URL',
|
|
143
|
+
}
|
|
144
|
+
break
|
|
145
|
+
}
|
|
146
|
+
case 'TriggerEvent': {
|
|
147
|
+
const eventName =
|
|
148
|
+
value.arguments?.[0]?.formula.type === 'value'
|
|
149
|
+
? value.arguments[0].formula.value
|
|
150
|
+
: undefined
|
|
151
|
+
if (typeof eventName !== 'string') {
|
|
152
|
+
break
|
|
153
|
+
}
|
|
154
|
+
const eventData = value.arguments?.[1]?.formula
|
|
155
|
+
if (!eventData) {
|
|
156
|
+
break
|
|
157
|
+
}
|
|
158
|
+
newAction = {
|
|
159
|
+
type: 'TriggerEvent',
|
|
160
|
+
event: eventName,
|
|
161
|
+
data: eventData,
|
|
162
|
+
}
|
|
163
|
+
break
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (newAction) {
|
|
167
|
+
return set(files, path, newAction)
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
},
|
|
26
171
|
}
|
|
172
|
+
|
|
173
|
+
// These actions take a first argument which is a formula as the name
|
|
174
|
+
// of the thing to update/trigger. We can only safely autofix these if
|
|
175
|
+
// the argument is a value operation and a string
|
|
176
|
+
const formulaNamedActions = ['UpdateVariable', 'TriggerEvent']
|
|
177
|
+
|
|
178
|
+
const unfixableLegacyActions = new Set([
|
|
179
|
+
'CopyToClipboard', // Previously, this action would JSON stringify non-string inputs
|
|
180
|
+
'Update URL parameter', // The user will need to pick a history mode (push/replace)
|
|
181
|
+
'Fetch', // This was mainly used for APIs v1
|
|
182
|
+
'FocusElement', // The new 'Focus' action takes an element as input - not a selector
|
|
183
|
+
'UpdateVariable', // The variable name could be a formula in the legacy version
|
|
184
|
+
'TriggerEvent', // The name of the event could be a formula in the legacy version
|
|
185
|
+
'@toddle/setSessionCookies', // The new 'Set cookie' action takes more arguments
|
|
186
|
+
])
|
|
187
|
+
|
|
188
|
+
export type LegacyActionRuleFix = 'replace-legacy-action'
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AndOperation,
|
|
3
3
|
ArrayOperation,
|
|
4
|
-
FunctionArgument,
|
|
5
4
|
FunctionOperation,
|
|
6
5
|
OrOperation,
|
|
7
6
|
SwitchOperation,
|
|
@@ -11,6 +10,11 @@ import { omitKeys, set } from '@nordcraft/core/dist/utils/collections'
|
|
|
11
10
|
import { isDefined } from '@nordcraft/core/dist/utils/util'
|
|
12
11
|
import type { ProjectFiles } from '@nordcraft/ssr/dist/ssr.types'
|
|
13
12
|
import type { FormulaNode, NodeType, Rule } from '../../types'
|
|
13
|
+
import {
|
|
14
|
+
ARRAY_ARGUMENT_MAPPINGS,
|
|
15
|
+
PREDICATE_ARGUMENT_MAPPINGS,
|
|
16
|
+
renameArguments,
|
|
17
|
+
} from '../../util/helpers'
|
|
14
18
|
|
|
15
19
|
export const legacyFormulaRule: Rule<{
|
|
16
20
|
name: string
|
|
@@ -25,8 +29,10 @@ export const legacyFormulaRule: Rule<{
|
|
|
25
29
|
report(
|
|
26
30
|
data.path,
|
|
27
31
|
{ name: data.value.name },
|
|
28
|
-
// The TYPE
|
|
29
|
-
data.value.name !== 'TYPE'
|
|
32
|
+
// The TYPE and BOOLEAN formulas cannot be autofixed since the logic has changed between the 2 implementations
|
|
33
|
+
data.value.name !== 'TYPE' && data.value.name !== 'BOOLEAN'
|
|
34
|
+
? ['replace-legacy-formula']
|
|
35
|
+
: undefined,
|
|
30
36
|
)
|
|
31
37
|
},
|
|
32
38
|
fixes: {
|
|
@@ -372,14 +378,6 @@ export const legacyFormulaRule: Rule<{
|
|
|
372
378
|
}
|
|
373
379
|
return set(data.files, data.path, newAppendFormula)
|
|
374
380
|
}
|
|
375
|
-
case 'BOOLEAN': {
|
|
376
|
-
const newBooleanFormula: FunctionOperation = {
|
|
377
|
-
...data.value,
|
|
378
|
-
name: '@toddle/boolean',
|
|
379
|
-
display_name: 'Boolean',
|
|
380
|
-
}
|
|
381
|
-
return set(data.files, data.path, newBooleanFormula)
|
|
382
|
-
}
|
|
383
381
|
case 'CLAMP': {
|
|
384
382
|
const newClampFormula: FunctionOperation = {
|
|
385
383
|
...data.value,
|
|
@@ -845,23 +843,3 @@ const builtInFormulas = new Set([
|
|
|
845
843
|
'uppercase',
|
|
846
844
|
])
|
|
847
845
|
// cSpell: enable
|
|
848
|
-
|
|
849
|
-
const ARRAY_ARGUMENT_MAPPINGS = { List: 'Array' }
|
|
850
|
-
const PREDICATE_ARGUMENT_MAPPINGS = {
|
|
851
|
-
...ARRAY_ARGUMENT_MAPPINGS,
|
|
852
|
-
'Predicate fx': 'Formula',
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
const renameArguments = (
|
|
856
|
-
mappings: Record<string, string>,
|
|
857
|
-
args: FunctionArgument[] | undefined,
|
|
858
|
-
): FunctionArgument[] =>
|
|
859
|
-
args?.map((arg) => ({
|
|
860
|
-
...arg,
|
|
861
|
-
// Let's adjust the names
|
|
862
|
-
name:
|
|
863
|
-
typeof arg.name === 'string'
|
|
864
|
-
? // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
865
|
-
(mappings[arg.name] ?? arg.name)
|
|
866
|
-
: arg.name,
|
|
867
|
-
})) ?? []
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import type { ProjectFiles } from '@nordcraft/ssr/dist/ssr.types'
|
|
1
2
|
import { describe, expect, test } from 'bun:test'
|
|
3
|
+
import { fixProject } from '../../fixProject'
|
|
2
4
|
import { searchProject } from '../../searchProject'
|
|
3
5
|
import { noReferenceProjectFormulaRule } from './noReferenceProjectFormulaRule'
|
|
4
6
|
|
|
5
|
-
describe('noReferenceFormulaRule', () => {
|
|
7
|
+
describe('find noReferenceFormulaRule', () => {
|
|
6
8
|
test('should detect unused global formulas', () => {
|
|
7
9
|
const problems = Array.from(
|
|
8
10
|
searchProject({
|
|
@@ -289,3 +291,36 @@ describe('noReferenceFormulaRule', () => {
|
|
|
289
291
|
expect(problems).toHaveLength(0)
|
|
290
292
|
})
|
|
291
293
|
})
|
|
294
|
+
|
|
295
|
+
describe('fix noReferenceFormulaRule', () => {
|
|
296
|
+
test('should remove unused global formulas', () => {
|
|
297
|
+
const projectFiles: ProjectFiles = {
|
|
298
|
+
formulas: {
|
|
299
|
+
'my-formula': {
|
|
300
|
+
name: 'my-formula',
|
|
301
|
+
arguments: [],
|
|
302
|
+
formula: {
|
|
303
|
+
type: 'value',
|
|
304
|
+
value: 'value',
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
components: {
|
|
309
|
+
test: {
|
|
310
|
+
name: 'test',
|
|
311
|
+
nodes: {},
|
|
312
|
+
formulas: {},
|
|
313
|
+
apis: {},
|
|
314
|
+
attributes: {},
|
|
315
|
+
variables: {},
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
}
|
|
319
|
+
const fixedProject = fixProject({
|
|
320
|
+
files: projectFiles,
|
|
321
|
+
rule: noReferenceProjectFormulaRule,
|
|
322
|
+
fixType: 'delete-project-formula',
|
|
323
|
+
})
|
|
324
|
+
expect(fixedProject.formulas).toEqual({})
|
|
325
|
+
})
|
|
326
|
+
})
|
|
@@ -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,11 @@ 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
|
-
'Update Variable',
|
|
65
68
|
'Update URL parameter',
|
|
66
69
|
'updateUrlParameters',
|
|
67
70
|
'UpdateQueryParam',
|
|
68
|
-
'Update Query',
|
|
69
71
|
'Fetch',
|
|
70
72
|
'SetTimeout',
|
|
71
73
|
'SetInterval',
|
|
@@ -74,6 +76,7 @@ const LEGACY_CUSTOM_ACTIONS = new Set([
|
|
|
74
76
|
'GoToURL',
|
|
75
77
|
'TriggerEvent',
|
|
76
78
|
'Set session cookies',
|
|
79
|
+
'@toddle/setSessionCookies',
|
|
77
80
|
])
|
|
78
81
|
|
|
79
82
|
interface BaseInteractiveContent {
|
|
@@ -130,3 +133,24 @@ export const interactiveContentElementDefinition = (
|
|
|
130
133
|
}
|
|
131
134
|
return true
|
|
132
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
|
+
})) ?? []
|