@nordcraft/search 1.0.43 → 1.0.44
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.fix.js +140 -0
- package/dist/rules/actions/legacyActionRule.fix.js.map +1 -0
- package/dist/rules/actions/legacyActionRule.js +3 -144
- package/dist/rules/actions/legacyActionRule.js.map +1 -1
- package/dist/rules/actions/legacyActionRule.test.js +1 -0
- package/dist/rules/actions/legacyActionRule.test.js.map +1 -1
- package/dist/rules/actions/noReferenceProjectActionRule.js +33 -40
- package/dist/rules/actions/noReferenceProjectActionRule.js.map +1 -1
- package/dist/rules/apis/noReferenceApiRule.js +7 -2
- package/dist/rules/apis/noReferenceApiRule.js.map +1 -1
- package/dist/rules/apis/noReferenceApiRule.test.js +65 -1
- package/dist/rules/apis/noReferenceApiRule.test.js.map +1 -1
- package/dist/rules/attributes/noReferenceAttributeRule.js +5 -1
- package/dist/rules/attributes/noReferenceAttributeRule.js.map +1 -1
- package/dist/rules/attributes/noReferenceAttributeRule.test.js +33 -1
- package/dist/rules/attributes/noReferenceAttributeRule.test.js.map +1 -1
- package/dist/rules/components/noReferenceComponentRule.js +18 -28
- package/dist/rules/components/noReferenceComponentRule.js.map +1 -1
- package/dist/rules/events/noReferenceEventRule.js +6 -2
- package/dist/rules/events/noReferenceEventRule.js.map +1 -1
- package/dist/rules/events/noReferenceEventRule.test.js +57 -1
- package/dist/rules/events/noReferenceEventRule.test.js.map +1 -1
- package/dist/rules/formulas/legacyFormulaRule.fix.js +574 -0
- package/dist/rules/formulas/legacyFormulaRule.fix.js.map +1 -0
- package/dist/rules/formulas/legacyFormulaRule.js +5 -580
- package/dist/rules/formulas/legacyFormulaRule.js.map +1 -1
- package/dist/rules/formulas/noReferenceComponentFormulaRule.js +8 -1
- package/dist/rules/formulas/noReferenceComponentFormulaRule.js.map +1 -1
- package/dist/rules/formulas/noReferenceProjectFormulaRule.js +63 -72
- package/dist/rules/formulas/noReferenceProjectFormulaRule.js.map +1 -1
- package/dist/searchProject.js +36 -16
- package/dist/searchProject.js.map +1 -1
- package/dist/util/removeUnused.fix.js +3 -0
- package/dist/util/removeUnused.fix.js.map +1 -0
- package/package.json +2 -2
- package/src/rules/actions/legacyActionRule.fix.ts +157 -0
- package/src/rules/actions/legacyActionRule.test.ts +1 -0
- package/src/rules/actions/legacyActionRule.ts +3 -159
- package/src/rules/actions/noReferenceProjectActionRule.ts +39 -47
- package/src/rules/apis/noReferenceApiRule.test.ts +67 -1
- package/src/rules/apis/noReferenceApiRule.ts +9 -2
- package/src/rules/attributes/noReferenceAttributeRule.test.ts +35 -1
- package/src/rules/attributes/noReferenceAttributeRule.ts +7 -2
- package/src/rules/components/noReferenceComponentRule.ts +23 -34
- package/src/rules/events/noReferenceEventRule.test.ts +59 -1
- package/src/rules/events/noReferenceEventRule.ts +8 -3
- package/src/rules/formulas/legacyFormulaRule.fix.ts +661 -0
- package/src/rules/formulas/legacyFormulaRule.ts +9 -670
- package/src/rules/formulas/noReferenceComponentFormulaRule.ts +15 -3
- package/src/rules/formulas/noReferenceProjectFormulaRule.ts +70 -77
- package/src/searchProject.ts +42 -22
- package/src/types.d.ts +16 -8
- package/src/util/removeUnused.fix.ts +5 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ToddleComponent } from '@nordcraft/core/dist/component/ToddleComponent'
|
|
2
2
|
import type { Rule } from '../../types'
|
|
3
|
+
import { removeFromPathFix } from '../../util/removeUnused.fix'
|
|
3
4
|
|
|
4
5
|
export const noReferenceComponentFormulaRule: Rule<{
|
|
5
6
|
name: string
|
|
@@ -38,7 +39,7 @@ export const noReferenceComponentFormulaRule: Rule<{
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
// It is possible that a formula is never used, but still has subscribers
|
|
41
|
-
const contextSubscribers = []
|
|
42
|
+
const contextSubscribers: string[] = []
|
|
42
43
|
if (value.exposeInContext) {
|
|
43
44
|
for (const _component of Object.values(files.components)) {
|
|
44
45
|
// Enforce that the component is not undefined since we're iterating
|
|
@@ -74,7 +75,18 @@ export const noReferenceComponentFormulaRule: Rule<{
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
report(
|
|
79
|
+
args.path,
|
|
80
|
+
{
|
|
81
|
+
contextSubscribers,
|
|
82
|
+
name: value.name,
|
|
83
|
+
},
|
|
84
|
+
['delete-component-formula'],
|
|
85
|
+
)
|
|
86
|
+
},
|
|
87
|
+
fixes: {
|
|
88
|
+
'delete-component-formula': removeFromPathFix,
|
|
79
89
|
},
|
|
80
90
|
}
|
|
91
|
+
|
|
92
|
+
export type NoReferenceComponentFormulaRuleFix = 'delete-component-formula'
|
|
@@ -1,106 +1,99 @@
|
|
|
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'
|
|
5
4
|
import { ToddleApiService } from '@nordcraft/ssr/dist/ToddleApiService'
|
|
6
5
|
import { ToddleRoute } from '@nordcraft/ssr/dist/ToddleRoute'
|
|
7
|
-
import type {
|
|
6
|
+
import type { Rule } from '../../types'
|
|
7
|
+
import { removeFromPathFix } from '../../util/removeUnused.fix'
|
|
8
8
|
|
|
9
9
|
export const noReferenceProjectFormulaRule: Rule<void> = {
|
|
10
10
|
code: 'no-reference project formula',
|
|
11
11
|
level: 'warning',
|
|
12
12
|
category: 'No References',
|
|
13
|
-
visit: (report,
|
|
14
|
-
if (
|
|
15
|
-
|
|
13
|
+
visit: (report, { value, path, files, nodeType, memo }) => {
|
|
14
|
+
if (nodeType !== 'project-formula' || value.exported === true) {
|
|
15
|
+
return
|
|
16
16
|
}
|
|
17
|
-
},
|
|
18
|
-
fixes: {
|
|
19
|
-
'delete-project-formula': (data) => {
|
|
20
|
-
if (!hasReferences(data)) {
|
|
21
|
-
return omit(data.files, data.path)
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export type NoReferenceProjectFormulaRuleFix = 'delete-project-formula'
|
|
28
|
-
|
|
29
|
-
const hasReferences = ({ value, files, nodeType, memo }: NodeType) => {
|
|
30
|
-
if (nodeType !== 'project-formula' || value.exported === true) {
|
|
31
|
-
return true
|
|
32
|
-
}
|
|
33
17
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
18
|
+
// Check in all API services first, since that should be quick
|
|
19
|
+
for (const apiService of Object.values(files.services ?? {})) {
|
|
20
|
+
const service = new ToddleApiService({
|
|
21
|
+
service: apiService,
|
|
22
|
+
globalFormulas: { formulas: files.formulas, packages: files.packages },
|
|
23
|
+
})
|
|
24
|
+
const formulas = service.formulasInService()
|
|
25
|
+
for (const { path: _formulaPath, formula } of formulas) {
|
|
26
|
+
// Check if the formula is used in the formula
|
|
27
|
+
if (checkFormula(formula, value.name)) {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
45
30
|
}
|
|
46
31
|
}
|
|
47
|
-
}
|
|
48
32
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
})
|
|
55
|
-
const formulas = route.formulasInRoute()
|
|
56
|
-
for (const { path: _formulaPath, formula } of formulas) {
|
|
57
|
-
// Check if the formula is used in the formula
|
|
58
|
-
if (checkFormula(formula, value.name)) {
|
|
59
|
-
return true
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const componentFormulaReferences = memo('componentFormulaReferences', () => {
|
|
65
|
-
const usedFormulas = new Set<string>()
|
|
66
|
-
for (const component of Object.values(files.components)) {
|
|
67
|
-
const c = new ToddleComponent({
|
|
68
|
-
// Enforce that the component is not undefined since we're iterating
|
|
69
|
-
component: component!,
|
|
70
|
-
getComponent: (name) => files.components[name],
|
|
71
|
-
packageName: undefined,
|
|
72
|
-
globalFormulas: {
|
|
73
|
-
formulas: files.formulas,
|
|
74
|
-
packages: files.packages,
|
|
75
|
-
},
|
|
33
|
+
// Check routes before components, since they should be quicker
|
|
34
|
+
for (const projectRoute of Object.values(files.routes ?? {})) {
|
|
35
|
+
const route = new ToddleRoute({
|
|
36
|
+
route: projectRoute,
|
|
37
|
+
globalFormulas: { formulas: files.formulas, packages: files.packages },
|
|
76
38
|
})
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
39
|
+
const formulas = route.formulasInRoute()
|
|
40
|
+
for (const { path: _formulaPath, formula } of formulas) {
|
|
41
|
+
// Check if the formula is used in the formula
|
|
42
|
+
if (checkFormula(formula, value.name)) {
|
|
43
|
+
return
|
|
80
44
|
}
|
|
81
45
|
}
|
|
82
46
|
}
|
|
83
|
-
return usedFormulas
|
|
84
|
-
})
|
|
85
47
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
48
|
+
const componentFormulaReferences = memo(
|
|
49
|
+
'componentFormulaReferences',
|
|
50
|
+
() => {
|
|
51
|
+
const usedFormulas = new Set<string>()
|
|
52
|
+
for (const component of Object.values(files.components)) {
|
|
53
|
+
const c = new ToddleComponent({
|
|
54
|
+
// Enforce that the component is not undefined since we're iterating
|
|
55
|
+
component: component!,
|
|
56
|
+
getComponent: (name) => files.components[name],
|
|
57
|
+
packageName: undefined,
|
|
58
|
+
globalFormulas: {
|
|
59
|
+
formulas: files.formulas,
|
|
60
|
+
packages: files.packages,
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
for (const { formula } of c.formulasInComponent()) {
|
|
64
|
+
if (formula.type === 'function') {
|
|
65
|
+
usedFormulas.add(formula.name)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return usedFormulas
|
|
70
|
+
},
|
|
71
|
+
)
|
|
89
72
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (f.name === value.name) {
|
|
93
|
-
continue
|
|
73
|
+
if (componentFormulaReferences.has(value.name)) {
|
|
74
|
+
return
|
|
94
75
|
}
|
|
95
76
|
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
77
|
+
// TODO: Memoize similar to above. We need have a helper class `ToddleFormula` with `ToddleFormula.normalizeFormulas()`
|
|
78
|
+
for (const f of Object.values(files.formulas ?? {})) {
|
|
79
|
+
if (f.name === value.name) {
|
|
80
|
+
continue
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Check if the formula is used in the formula
|
|
84
|
+
if (isToddleFormula(f) && checkFormula(f.formula, value.name)) {
|
|
85
|
+
return
|
|
86
|
+
}
|
|
99
87
|
}
|
|
100
|
-
|
|
101
|
-
|
|
88
|
+
report(path, undefined, ['delete-project-formula'])
|
|
89
|
+
},
|
|
90
|
+
fixes: {
|
|
91
|
+
'delete-project-formula': removeFromPathFix,
|
|
92
|
+
},
|
|
102
93
|
}
|
|
103
94
|
|
|
95
|
+
export type NoReferenceProjectFormulaRuleFix = 'delete-project-formula'
|
|
96
|
+
|
|
104
97
|
const checkArguments = (
|
|
105
98
|
args: {
|
|
106
99
|
formula: Formula
|
package/src/searchProject.ts
CHANGED
|
@@ -200,6 +200,7 @@ function visitNode(args: {
|
|
|
200
200
|
useExactPaths: boolean
|
|
201
201
|
} & NodeType
|
|
202
202
|
state: ApplicationState | undefined
|
|
203
|
+
fixOptions: never
|
|
203
204
|
}): Generator<Result>
|
|
204
205
|
function visitNode(args: {
|
|
205
206
|
args: {
|
|
@@ -210,7 +211,7 @@ function visitNode(args: {
|
|
|
210
211
|
useExactPaths: boolean
|
|
211
212
|
} & NodeType
|
|
212
213
|
state: ApplicationState | undefined
|
|
213
|
-
fixOptions:
|
|
214
|
+
fixOptions: FixOptions
|
|
214
215
|
}): Generator<ProjectFiles | void>
|
|
215
216
|
function* visitNode({
|
|
216
217
|
args,
|
|
@@ -225,7 +226,7 @@ function* visitNode({
|
|
|
225
226
|
useExactPaths: boolean
|
|
226
227
|
} & NodeType
|
|
227
228
|
state: ApplicationState | undefined
|
|
228
|
-
fixOptions?:
|
|
229
|
+
fixOptions?: FixOptions
|
|
229
230
|
}): Generator<Result | ProjectFiles | void> {
|
|
230
231
|
const { rules, pathsToVisit, useExactPaths, ...data } = args
|
|
231
232
|
const { files, value, path, memo, nodeType } = data
|
|
@@ -243,22 +244,31 @@ function* visitNode({
|
|
|
243
244
|
!useExactPaths ||
|
|
244
245
|
shouldSearchExactPath({ path: data.path, pathsToVisit })
|
|
245
246
|
) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
247
|
+
const results: Result[] = []
|
|
248
|
+
let fixedFiles: ProjectFiles | undefined
|
|
249
|
+
for (const rule of rules) {
|
|
250
|
+
// eslint-disable-next-line no-console
|
|
251
|
+
console.timeStamp(`Visiting rule ${rule.code}`)
|
|
252
|
+
rule.visit(
|
|
253
|
+
// Report callback used to report issues
|
|
254
|
+
(path, details, fixes) => {
|
|
255
|
+
if (fixOptions) {
|
|
256
|
+
// We're in "fix mode"
|
|
257
|
+
if (
|
|
258
|
+
// We only overwrite fixedFiles once to avoid conflicting fixes
|
|
259
|
+
!fixedFiles &&
|
|
260
|
+
// The current fix must be one of the fixes reported
|
|
261
|
+
fixes?.includes(fixOptions.fixType) &&
|
|
262
|
+
// The rule must have an implementation for the fix
|
|
263
|
+
rule.fixes?.[fixOptions.fixType]
|
|
264
|
+
) {
|
|
265
|
+
const ruleFixes = rule.fixes[fixOptions.fixType]?.(data, state)
|
|
266
|
+
if (ruleFixes) {
|
|
267
|
+
fixedFiles = ruleFixes
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
// We're in "report mode"
|
|
262
272
|
results.push({
|
|
263
273
|
code: rule.code,
|
|
264
274
|
category: rule.category,
|
|
@@ -267,12 +277,22 @@ function* visitNode({
|
|
|
267
277
|
details,
|
|
268
278
|
fixes,
|
|
269
279
|
})
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
data,
|
|
283
|
+
state,
|
|
284
|
+
)
|
|
285
|
+
if (fixedFiles) {
|
|
286
|
+
// We have applied a fix, stop processing more rules
|
|
287
|
+
break
|
|
274
288
|
}
|
|
289
|
+
}
|
|
275
290
|
|
|
291
|
+
if (fixOptions) {
|
|
292
|
+
if (fixedFiles) {
|
|
293
|
+
yield fixedFiles
|
|
294
|
+
}
|
|
295
|
+
} else {
|
|
276
296
|
for (const result of results) {
|
|
277
297
|
yield result
|
|
278
298
|
}
|
package/src/types.d.ts
CHANGED
|
@@ -23,8 +23,12 @@ import type {
|
|
|
23
23
|
} from '@nordcraft/ssr/dist/ssr.types'
|
|
24
24
|
import type { LegacyActionRuleFix } from './rules/actions/legacyActionRule'
|
|
25
25
|
import type { NoReferenceProjectActionRuleFix } from './rules/actions/noReferenceProjectActionRule'
|
|
26
|
+
import type { NoReferenceApiRuleFix } from './rules/apis/noReferenceApiRule'
|
|
27
|
+
import type { NoReferenceAttributeRuleFix } from './rules/attributes/noReferenceAttributeRule'
|
|
26
28
|
import type { NoReferenceComponentRuleFix } from './rules/components/noReferenceComponentRule'
|
|
29
|
+
import type { NoReferenceEventRuleFix } from './rules/events/noReferenceEventRule'
|
|
27
30
|
import type { LegacyFormulaRuleFix } from './rules/formulas/legacyFormulaRule'
|
|
31
|
+
import type { NoReferenceComponentFormulaRuleFix } from './rules/formulas/noReferenceComponentFormulaRule'
|
|
28
32
|
import type { NoReferenceProjectFormulaRuleFix } from './rules/formulas/noReferenceProjectFormulaRule'
|
|
29
33
|
|
|
30
34
|
type Code =
|
|
@@ -251,9 +255,9 @@ type FormulaNode<F = Formula> = {
|
|
|
251
255
|
component?: ToddleComponent<Function>
|
|
252
256
|
} & Base
|
|
253
257
|
|
|
254
|
-
type ActionModelNode = {
|
|
258
|
+
type ActionModelNode<A = ActionModel> = {
|
|
255
259
|
nodeType: 'action-model'
|
|
256
|
-
value:
|
|
260
|
+
value: A
|
|
257
261
|
component: ToddleComponent<Function>
|
|
258
262
|
} & Base
|
|
259
263
|
|
|
@@ -320,6 +324,10 @@ type FixType =
|
|
|
320
324
|
| NoReferenceComponentRuleFix
|
|
321
325
|
| NoReferenceProjectFormulaRuleFix
|
|
322
326
|
| NoReferenceProjectActionRuleFix
|
|
327
|
+
| NoReferenceApiRuleFix
|
|
328
|
+
| NoReferenceAttributeRuleFix
|
|
329
|
+
| NoReferenceEventRuleFix
|
|
330
|
+
| NoReferenceComponentFormulaRuleFix
|
|
323
331
|
|
|
324
332
|
export interface Rule<T = unknown, V = NodeType> {
|
|
325
333
|
category: Category
|
|
@@ -330,10 +338,10 @@ export interface Rule<T = unknown, V = NodeType> {
|
|
|
330
338
|
data: V,
|
|
331
339
|
state?: ApplicationState | undefined,
|
|
332
340
|
) => void
|
|
333
|
-
fixes?: Partial<
|
|
334
|
-
Record<
|
|
335
|
-
FixType,
|
|
336
|
-
(data: V, state?: ApplicationState | undefined) => ProjectFiles | void
|
|
337
|
-
>
|
|
338
|
-
>
|
|
341
|
+
fixes?: Partial<Record<FixType, FixFunction>>
|
|
339
342
|
}
|
|
343
|
+
|
|
344
|
+
export type FixFunction<T extends NodeType> = (
|
|
345
|
+
data: T,
|
|
346
|
+
state?: ApplicationState,
|
|
347
|
+
) => ProjectFiles | void
|