@nordcraft/search 1.0.82 → 1.0.83

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.
@@ -7,6 +7,7 @@ import { noReferenceApiServiceRule } from './noReferenceApiServiceRule';
7
7
  import { unknownApiInputRule } from './unknownApiInputRule';
8
8
  import { unknownApiRule } from './unknownApiRule';
9
9
  import { unknownApiServiceRule } from './unknownApiServiceRule';
10
+ import { unknownFetchInputRule } from './unknownFetchInputRule';
10
11
  export default [
11
12
  // noReferenceApiInputRule,
12
13
  invalidApiParserModeRule,
@@ -15,6 +16,7 @@ export default [
15
16
  legacyApiRule,
16
17
  noReferenceApiRule,
17
18
  noReferenceApiServiceRule,
19
+ unknownFetchInputRule,
18
20
  unknownApiInputRule,
19
21
  unknownApiRule,
20
22
  unknownApiServiceRule,
@@ -1 +1 @@
1
- {"version":3,"file":"apiRules.index.js","sourceRoot":"","sources":["../../../../src/rules/issues/apis/apiRules.index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAA;AACjF,OAAO,EAAE,gCAAgC,EAAE,MAAM,oCAAoC,CAAA;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAE/D,eAAe;IACb,2BAA2B;IAC3B,wBAAwB;IACxB,8BAA8B;IAC9B,gCAAgC;IAChC,aAAa;IACb,kBAAkB;IAClB,yBAAyB;IACzB,mBAAmB;IACnB,cAAc;IACd,qBAAqB;CACtB,CAAA"}
1
+ {"version":3,"file":"apiRules.index.js","sourceRoot":"","sources":["../../../../src/rules/issues/apis/apiRules.index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAA;AACjF,OAAO,EAAE,gCAAgC,EAAE,MAAM,oCAAoC,CAAA;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAE/D,eAAe;IACb,2BAA2B;IAC3B,wBAAwB;IACxB,8BAA8B;IAC9B,gCAAgC;IAChC,aAAa;IACb,kBAAkB;IAClB,yBAAyB;IACzB,qBAAqB;IACrB,mBAAmB;IACnB,cAAc;IACd,qBAAqB;CACtB,CAAA"}
@@ -0,0 +1,42 @@
1
+ import { get } from '@nordcraft/core/dist/utils/collections';
2
+ import { removeFromPathFix } from '../../../util/removeUnused.fix';
3
+ export const unknownFetchInputRule = {
4
+ code: 'unknown fetch input',
5
+ level: 'warning',
6
+ category: 'Unknown Reference',
7
+ visit: (report, { path, files, value, nodeType }) => {
8
+ if (nodeType !== 'action-model' ||
9
+ value.type !== 'Fetch' ||
10
+ Object.keys(value.inputs ?? {}).length === 0) {
11
+ return;
12
+ }
13
+ const [components, componentName] = path;
14
+ const targetApi = get(files, [components, componentName, 'apis', value.api]);
15
+ if (!targetApi) {
16
+ return;
17
+ }
18
+ const validInputs = new Set(Object.keys(targetApi.inputs ?? {}));
19
+ for (const inputName of Object.keys(value.inputs ?? {})) {
20
+ if (!validInputs.has(inputName)) {
21
+ report(path, { name: inputName }, ['delete-fetch-input']);
22
+ }
23
+ }
24
+ },
25
+ fixes: {
26
+ 'delete-fetch-input': deleteUnknownFetchInputFix,
27
+ },
28
+ };
29
+ function deleteUnknownFetchInputFix(args) {
30
+ const inputToRemove = args.details?.name;
31
+ if (typeof inputToRemove !== 'string') {
32
+ return args.data.files;
33
+ }
34
+ return removeFromPathFix({
35
+ ...args,
36
+ data: {
37
+ ...args.data,
38
+ path: [...args.data.path, 'inputs', inputToRemove],
39
+ },
40
+ });
41
+ }
42
+ //# sourceMappingURL=unknownFetchInputRule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unknownFetchInputRule.js","sourceRoot":"","sources":["../../../../src/rules/issues/apis/unknownFetchInputRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,wCAAwC,CAAA;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAElE,MAAM,CAAC,MAAM,qBAAqB,GAE7B;IACH,IAAI,EAAE,qBAAqB;IAC3B,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,mBAAmB;IAC7B,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACnD,IACE,QAAQ,KAAK,cAAc;YAC3B,KAAK,CAAC,IAAI,KAAK,OAAO;YACtB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAC5C,CAAC;YACD,OAAM;QACR,CAAC;QACD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,IAAI,CAAA;QACxC,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;QAC5E,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAM;QACR,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAA;QAChE,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBAChC,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAA;YAC3D,CAAC;QACH,CAAC;IAAA,CACF;IACD,KAAK,EAAE;QACL,oBAAoB,EAAE,0BAA0B;KACjD;CACF,CAAA;AAED,SAAS,0BAA0B,CACjC,IAAmE,EACP;IAC5D,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAA;IACxC,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAA;IACxB,CAAC;IACD,OAAO,iBAAiB,CAAC;QACvB,GAAG,IAAI;QACP,IAAI,EAAE;YACJ,GAAG,IAAI,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,aAAa,CAAC;SACnD;KACF,CAAC,CAAA;AAAA,CACH"}
@@ -0,0 +1,175 @@
1
+ import { valueFormula } from '@nordcraft/core/dist/formula/formulaUtils';
2
+ import { describe, expect, test } from 'bun:test';
3
+ import { fixProject } from '../../../fixProject';
4
+ import { searchProject } from '../../../searchProject';
5
+ import { unknownFetchInputRule } from './unknownFetchInputRule';
6
+ describe('find unknownFetchInputRule', () => {
7
+ test('should report unknown api input overrides', () => {
8
+ const problems = Array.from(searchProject({
9
+ files: {
10
+ components: {
11
+ test: {
12
+ name: 'test',
13
+ onLoad: {
14
+ trigger: 'onLoad',
15
+ actions: [
16
+ {
17
+ type: 'Fetch',
18
+ api: 'my-api',
19
+ inputs: {
20
+ invalidInput: { formula: valueFormula('test') },
21
+ },
22
+ onSuccess: { actions: [] },
23
+ onError: { actions: [] },
24
+ },
25
+ ],
26
+ },
27
+ nodes: {
28
+ root: {
29
+ type: 'element',
30
+ attrs: {},
31
+ classes: {},
32
+ events: {},
33
+ tag: 'div',
34
+ children: [],
35
+ style: {},
36
+ },
37
+ },
38
+ formulas: {},
39
+ apis: {
40
+ 'my-api': {
41
+ name: 'my-api',
42
+ type: 'http',
43
+ version: 2,
44
+ autoFetch: valueFormula(true),
45
+ inputs: {
46
+ validInput: {
47
+ formula: valueFormula(null),
48
+ },
49
+ },
50
+ },
51
+ },
52
+ attributes: {},
53
+ variables: {},
54
+ },
55
+ },
56
+ },
57
+ rules: [unknownFetchInputRule],
58
+ }));
59
+ expect(problems).toHaveLength(1);
60
+ expect(problems[0].code).toBe('unknown fetch input');
61
+ expect(problems[0].details).toEqual({ name: 'invalidInput' });
62
+ });
63
+ test('should not report valid api input overrides', () => {
64
+ const problems = Array.from(searchProject({
65
+ files: {
66
+ components: {
67
+ test: {
68
+ name: 'test',
69
+ onLoad: {
70
+ trigger: 'onLoad',
71
+ actions: [
72
+ {
73
+ type: 'Fetch',
74
+ api: 'my-api',
75
+ inputs: {
76
+ validInput: { formula: valueFormula('test') },
77
+ },
78
+ onSuccess: { actions: [] },
79
+ onError: { actions: [] },
80
+ },
81
+ ],
82
+ },
83
+ nodes: {
84
+ root: {
85
+ type: 'element',
86
+ attrs: {},
87
+ classes: {},
88
+ events: {},
89
+ tag: 'div',
90
+ children: [],
91
+ style: {},
92
+ },
93
+ },
94
+ formulas: {},
95
+ apis: {
96
+ 'my-api': {
97
+ name: 'my-api',
98
+ type: 'http',
99
+ version: 2,
100
+ autoFetch: valueFormula(true),
101
+ inputs: {
102
+ validInput: {
103
+ formula: valueFormula(null),
104
+ },
105
+ },
106
+ },
107
+ },
108
+ attributes: {},
109
+ variables: {},
110
+ },
111
+ },
112
+ },
113
+ rules: [unknownFetchInputRule],
114
+ }));
115
+ expect(problems).toBeEmpty();
116
+ });
117
+ });
118
+ describe('fix unknownFetchInputRule', () => {
119
+ test('should remove unknown api input overrides', () => {
120
+ const project = {
121
+ formulas: {},
122
+ components: {
123
+ test: {
124
+ name: 'test',
125
+ onLoad: {
126
+ trigger: 'onLoad',
127
+ actions: [
128
+ {
129
+ type: 'Fetch',
130
+ api: 'my-api',
131
+ inputs: {
132
+ invalidInput: { formula: valueFormula('test') },
133
+ validInput: { formula: valueFormula('test') },
134
+ },
135
+ onSuccess: { actions: [] },
136
+ onError: { actions: [] },
137
+ },
138
+ ],
139
+ },
140
+ nodes: {},
141
+ formulas: {},
142
+ apis: {
143
+ 'my-api': {
144
+ name: 'my-api',
145
+ type: 'http',
146
+ version: 2,
147
+ autoFetch: valueFormula(true),
148
+ inputs: {
149
+ validInput: {
150
+ formula: valueFormula(null),
151
+ },
152
+ },
153
+ },
154
+ },
155
+ attributes: {},
156
+ variables: {},
157
+ },
158
+ },
159
+ };
160
+ const fixedProject = fixProject({
161
+ files: project,
162
+ rule: unknownFetchInputRule,
163
+ fixType: 'delete-fetch-input',
164
+ });
165
+ const fixedAction = fixedProject.components['test']?.onLoad?.actions?.[0];
166
+ if (fixedAction?.type !== 'Fetch') {
167
+ // To help Typescript narrow the type
168
+ throw new Error('Fixed action is not a Fetch action');
169
+ }
170
+ expect(fixedAction.inputs).toMatchObject({
171
+ validInput: { formula: valueFormula('test') },
172
+ });
173
+ });
174
+ });
175
+ //# sourceMappingURL=unknownFetchInputRule.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unknownFetchInputRule.test.js","sourceRoot":"","sources":["../../../../src/rules/issues/apis/unknownFetchInputRule.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -10,8 +10,8 @@
10
10
  "directory": "packages/search"
11
11
  },
12
12
  "dependencies": {
13
- "@nordcraft/ssr": "1.0.82",
14
- "@nordcraft/core": "1.0.82",
13
+ "@nordcraft/ssr": "1.0.83",
14
+ "@nordcraft/core": "1.0.83",
15
15
  "jsondiffpatch": "0.7.3",
16
16
  "postcss": "8.5.6",
17
17
  "zod": "4.2.1"
@@ -26,5 +26,5 @@
26
26
  "test:watch:only": "bun test --watch --only"
27
27
  },
28
28
  "files": ["dist", "src"],
29
- "version": "1.0.82"
29
+ "version": "1.0.83"
30
30
  }
@@ -7,6 +7,7 @@ import { noReferenceApiServiceRule } from './noReferenceApiServiceRule'
7
7
  import { unknownApiInputRule } from './unknownApiInputRule'
8
8
  import { unknownApiRule } from './unknownApiRule'
9
9
  import { unknownApiServiceRule } from './unknownApiServiceRule'
10
+ import { unknownFetchInputRule } from './unknownFetchInputRule'
10
11
 
11
12
  export default [
12
13
  // noReferenceApiInputRule,
@@ -16,6 +17,7 @@ export default [
16
17
  legacyApiRule,
17
18
  noReferenceApiRule,
18
19
  noReferenceApiServiceRule,
20
+ unknownFetchInputRule,
19
21
  unknownApiInputRule,
20
22
  unknownApiRule,
21
23
  unknownApiServiceRule,
@@ -0,0 +1,181 @@
1
+ import { valueFormula } from '@nordcraft/core/dist/formula/formulaUtils'
2
+ import type { ProjectFiles } from '@nordcraft/ssr/dist/ssr.types'
3
+ import { describe, expect, test } from 'bun:test'
4
+ import { fixProject } from '../../../fixProject'
5
+ import { searchProject } from '../../../searchProject'
6
+ import { unknownFetchInputRule } from './unknownFetchInputRule'
7
+
8
+ describe('find unknownFetchInputRule', () => {
9
+ test('should report unknown api input overrides', () => {
10
+ const problems = Array.from(
11
+ searchProject({
12
+ files: {
13
+ components: {
14
+ test: {
15
+ name: 'test',
16
+ onLoad: {
17
+ trigger: 'onLoad',
18
+ actions: [
19
+ {
20
+ type: 'Fetch',
21
+ api: 'my-api',
22
+ inputs: {
23
+ invalidInput: { formula: valueFormula('test') },
24
+ },
25
+ onSuccess: { actions: [] },
26
+ onError: { actions: [] },
27
+ },
28
+ ],
29
+ },
30
+ nodes: {
31
+ root: {
32
+ type: 'element',
33
+ attrs: {},
34
+ classes: {},
35
+ events: {},
36
+ tag: 'div',
37
+ children: [],
38
+ style: {},
39
+ },
40
+ },
41
+ formulas: {},
42
+ apis: {
43
+ 'my-api': {
44
+ name: 'my-api',
45
+ type: 'http',
46
+ version: 2,
47
+ autoFetch: valueFormula(true),
48
+ inputs: {
49
+ validInput: {
50
+ formula: valueFormula(null),
51
+ },
52
+ },
53
+ },
54
+ },
55
+ attributes: {},
56
+ variables: {},
57
+ },
58
+ },
59
+ },
60
+ rules: [unknownFetchInputRule],
61
+ }),
62
+ )
63
+
64
+ expect(problems).toHaveLength(1)
65
+ expect(problems[0].code).toBe('unknown fetch input')
66
+ expect(problems[0].details).toEqual({ name: 'invalidInput' })
67
+ })
68
+ test('should not report valid api input overrides', () => {
69
+ const problems = Array.from(
70
+ searchProject({
71
+ files: {
72
+ components: {
73
+ test: {
74
+ name: 'test',
75
+ onLoad: {
76
+ trigger: 'onLoad',
77
+ actions: [
78
+ {
79
+ type: 'Fetch',
80
+ api: 'my-api',
81
+ inputs: {
82
+ validInput: { formula: valueFormula('test') },
83
+ },
84
+ onSuccess: { actions: [] },
85
+ onError: { actions: [] },
86
+ },
87
+ ],
88
+ },
89
+ nodes: {
90
+ root: {
91
+ type: 'element',
92
+ attrs: {},
93
+ classes: {},
94
+ events: {},
95
+ tag: 'div',
96
+ children: [],
97
+ style: {},
98
+ },
99
+ },
100
+ formulas: {},
101
+ apis: {
102
+ 'my-api': {
103
+ name: 'my-api',
104
+ type: 'http',
105
+ version: 2,
106
+ autoFetch: valueFormula(true),
107
+ inputs: {
108
+ validInput: {
109
+ formula: valueFormula(null),
110
+ },
111
+ },
112
+ },
113
+ },
114
+ attributes: {},
115
+ variables: {},
116
+ },
117
+ },
118
+ },
119
+ rules: [unknownFetchInputRule],
120
+ }),
121
+ )
122
+ expect(problems).toBeEmpty()
123
+ })
124
+ })
125
+ describe('fix unknownFetchInputRule', () => {
126
+ test('should remove unknown api input overrides', () => {
127
+ const project: ProjectFiles = {
128
+ formulas: {},
129
+ components: {
130
+ test: {
131
+ name: 'test',
132
+ onLoad: {
133
+ trigger: 'onLoad',
134
+ actions: [
135
+ {
136
+ type: 'Fetch',
137
+ api: 'my-api',
138
+ inputs: {
139
+ invalidInput: { formula: valueFormula('test') },
140
+ validInput: { formula: valueFormula('test') },
141
+ },
142
+ onSuccess: { actions: [] },
143
+ onError: { actions: [] },
144
+ },
145
+ ],
146
+ },
147
+ nodes: {},
148
+ formulas: {},
149
+ apis: {
150
+ 'my-api': {
151
+ name: 'my-api',
152
+ type: 'http',
153
+ version: 2,
154
+ autoFetch: valueFormula(true),
155
+ inputs: {
156
+ validInput: {
157
+ formula: valueFormula(null),
158
+ },
159
+ },
160
+ },
161
+ },
162
+ attributes: {},
163
+ variables: {},
164
+ },
165
+ },
166
+ }
167
+ const fixedProject = fixProject({
168
+ files: project,
169
+ rule: unknownFetchInputRule,
170
+ fixType: 'delete-fetch-input',
171
+ })
172
+ const fixedAction = fixedProject.components['test']?.onLoad?.actions?.[0]
173
+ if (fixedAction?.type !== 'Fetch') {
174
+ // To help Typescript narrow the type
175
+ throw new Error('Fixed action is not a Fetch action')
176
+ }
177
+ expect(fixedAction.inputs!).toMatchObject({
178
+ validInput: { formula: valueFormula('test') },
179
+ })
180
+ })
181
+ })
@@ -0,0 +1,52 @@
1
+ import { get } from '@nordcraft/core/dist/utils/collections'
2
+ import type { ActionModelNode, FixFunction, Rule } from '../../../types'
3
+ import { removeFromPathFix } from '../../../util/removeUnused.fix'
4
+
5
+ export const unknownFetchInputRule: Rule<{
6
+ name: string
7
+ }> = {
8
+ code: 'unknown fetch input',
9
+ level: 'warning',
10
+ category: 'Unknown Reference',
11
+ visit: (report, { path, files, value, nodeType }) => {
12
+ if (
13
+ nodeType !== 'action-model' ||
14
+ value.type !== 'Fetch' ||
15
+ Object.keys(value.inputs ?? {}).length === 0
16
+ ) {
17
+ return
18
+ }
19
+ const [components, componentName] = path
20
+ const targetApi = get(files, [components, componentName, 'apis', value.api])
21
+ if (!targetApi) {
22
+ return
23
+ }
24
+ const validInputs = new Set(Object.keys(targetApi.inputs ?? {}))
25
+ for (const inputName of Object.keys(value.inputs ?? {})) {
26
+ if (!validInputs.has(inputName)) {
27
+ report(path, { name: inputName }, ['delete-fetch-input'])
28
+ }
29
+ }
30
+ },
31
+ fixes: {
32
+ 'delete-fetch-input': deleteUnknownFetchInputFix,
33
+ },
34
+ }
35
+
36
+ function deleteUnknownFetchInputFix(
37
+ args: Parameters<FixFunction<ActionModelNode, { name: string }>>[0],
38
+ ): ReturnType<FixFunction<ActionModelNode, { name: string }>> {
39
+ const inputToRemove = args.details?.name
40
+ if (typeof inputToRemove !== 'string') {
41
+ return args.data.files
42
+ }
43
+ return removeFromPathFix({
44
+ ...args,
45
+ data: {
46
+ ...args.data,
47
+ path: [...args.data.path, 'inputs', inputToRemove],
48
+ },
49
+ })
50
+ }
51
+
52
+ export type DeleteFetchInputFix = 'delete-fetch-input'
package/src/types.d.ts CHANGED
@@ -32,6 +32,7 @@ import type { UnknownActionEventRuleFix } from './rules/issues/actions/unknownAc
32
32
  import type { NoReferenceApiRuleFix } from './rules/issues/apis/noReferenceApiRule'
33
33
  import type { NoReferenceApiServiceRuleFix } from './rules/issues/apis/noReferenceApiServiceRule'
34
34
  import type { UnknownApiServiceRuleFix } from './rules/issues/apis/unknownApiServiceRule'
35
+ import type { DeleteFetchInputFix } from './rules/issues/apis/unknownFetchInputRule'
35
36
  import type { NoReferenceAttributeRuleFix } from './rules/issues/attributes/noReferenceAttributeRule'
36
37
  import type { UnknownComponentAttributeRuleFix } from './rules/issues/attributes/unknownComponentAttributeRule'
37
38
  import type { ChangeDataTypeFix } from './rules/issues/components/invalidComponentStructureRule'
@@ -107,6 +108,7 @@ type Code =
107
108
  | 'unknown cookie'
108
109
  | 'unknown component'
109
110
  | 'unknown event'
111
+ | 'unknown fetch input'
110
112
  | 'unknown formula'
111
113
  | 'unknown project action'
112
114
  | 'unknown project formula input'
@@ -405,6 +407,7 @@ type NodeType =
405
407
 
406
408
  type FixType =
407
409
  | ChangeDataTypeFix
410
+ | DeleteFetchInputFix
408
411
  | InvalidStyleSyntaxRuleFix
409
412
  | LegacyActionRuleFix
410
413
  | LegacyFormulaRuleFix