@nordcraft/search 1.0.93 → 1.0.94
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/findProblems.js.map +1 -1
- package/dist/findSearch.d.ts +6 -0
- package/dist/findSearch.js +102 -0
- package/dist/findSearch.js.map +1 -0
- package/dist/fixProblems.js.map +1 -1
- package/dist/fixProject.js.map +1 -1
- package/dist/problems.worker.js.map +1 -1
- package/dist/rules/issues/actions/actionRules.index.d.ts +1 -1
- package/dist/rules/issues/actions/createActionNameRule.d.ts +2 -2
- package/dist/rules/issues/actions/createActionNameRule.js.map +1 -1
- package/dist/rules/issues/actions/duplicateActionArgumentNameRule.d.ts +2 -2
- package/dist/rules/issues/actions/duplicateActionArgumentNameRule.js.map +1 -1
- package/dist/rules/issues/actions/legacyActionRule.d.ts +2 -2
- package/dist/rules/issues/actions/legacyActionRule.fix.js.map +1 -1
- package/dist/rules/issues/actions/legacyActionRule.js.map +1 -1
- package/dist/rules/issues/actions/noReferenceProjectActionRule.d.ts +2 -2
- package/dist/rules/issues/actions/noReferenceProjectActionRule.js.map +1 -1
- package/dist/rules/issues/actions/projectActionIsReferenced.memo.js.map +1 -1
- package/dist/rules/issues/actions/unknownActionArgumentRule.d.ts +2 -2
- package/dist/rules/issues/actions/unknownActionArgumentRule.js.map +1 -1
- package/dist/rules/issues/actions/unknownActionEventRule.d.ts +2 -2
- package/dist/rules/issues/actions/unknownActionEventRule.js.map +1 -1
- package/dist/rules/issues/actions/unknownProjectActionRule.d.ts +2 -2
- package/dist/rules/issues/actions/unknownProjectActionRule.js.map +1 -1
- package/dist/rules/issues/apis/apiRules.index.d.ts +4 -4
- package/dist/rules/issues/apis/invalidApiParserModeRule.d.ts +2 -2
- package/dist/rules/issues/apis/invalidApiParserModeRule.js.map +1 -1
- package/dist/rules/issues/apis/invalidApiProxyBodySettingRule.d.ts +2 -2
- package/dist/rules/issues/apis/invalidApiProxyBodySettingRule.js.map +1 -1
- package/dist/rules/issues/apis/invalidApiProxyCookieSettingRule.d.ts +2 -2
- package/dist/rules/issues/apis/invalidApiProxyCookieSettingRule.js.map +1 -1
- package/dist/rules/issues/apis/legacyApiRule.d.ts +2 -2
- package/dist/rules/issues/apis/legacyApiRule.js.map +1 -1
- package/dist/rules/issues/apis/noReferenceApiInputRule.d.ts +2 -2
- package/dist/rules/issues/apis/noReferenceApiInputRule.js.map +1 -1
- package/dist/rules/issues/apis/noReferenceApiRule.d.ts +2 -2
- package/dist/rules/issues/apis/noReferenceApiRule.js.map +1 -1
- package/dist/rules/issues/apis/noReferenceApiServiceRule.d.ts +2 -2
- package/dist/rules/issues/apis/noReferenceApiServiceRule.js.map +1 -1
- package/dist/rules/issues/apis/unknownApiInputRule.d.ts +2 -2
- package/dist/rules/issues/apis/unknownApiInputRule.js.map +1 -1
- package/dist/rules/issues/apis/unknownApiRule.d.ts +2 -2
- package/dist/rules/issues/apis/unknownApiRule.js.map +1 -1
- package/dist/rules/issues/apis/unknownApiServiceRule.d.ts +2 -2
- package/dist/rules/issues/apis/unknownApiServiceRule.js.map +1 -1
- package/dist/rules/issues/apis/unknownFetchInputRule.d.ts +2 -2
- package/dist/rules/issues/apis/unknownFetchInputRule.js.map +1 -1
- package/dist/rules/issues/attributes/attributeRules.index.d.ts +2 -2
- package/dist/rules/issues/attributes/noReferenceAttributeInInstanceRule.d.ts +2 -2
- package/dist/rules/issues/attributes/noReferenceAttributeInInstanceRule.js.map +1 -1
- package/dist/rules/issues/attributes/noReferenceAttributeRule.d.ts +2 -2
- package/dist/rules/issues/attributes/noReferenceAttributeRule.js.map +1 -1
- package/dist/rules/issues/attributes/unknownAttributeRule.d.ts +2 -2
- package/dist/rules/issues/attributes/unknownAttributeRule.js.map +1 -1
- package/dist/rules/issues/attributes/unknownComponentAttributeRule.d.ts +2 -2
- package/dist/rules/issues/attributes/unknownComponentAttributeRule.js.map +1 -1
- package/dist/rules/issues/components/componentIsReferenced.memo.js.map +1 -1
- package/dist/rules/issues/components/componentRules.index.d.ts +1 -1
- package/dist/rules/issues/components/invalidComponentStructureRule.d.ts +2 -2
- package/dist/rules/issues/components/invalidComponentStructureRule.js.map +1 -1
- package/dist/rules/issues/components/noReferenceComponentRule.d.ts +2 -2
- package/dist/rules/issues/components/noReferenceComponentRule.js.map +1 -1
- package/dist/rules/issues/components/unknownComponentRule.d.ts +2 -2
- package/dist/rules/issues/components/unknownComponentRule.js.map +1 -1
- package/dist/rules/issues/context/contextRules.index.d.ts +3 -3
- package/dist/rules/issues/context/noContextConsumersRule.d.ts +2 -2
- package/dist/rules/issues/context/noContextConsumersRule.js.map +1 -1
- package/dist/rules/issues/context/unknownContextFormulaRule.d.ts +2 -2
- package/dist/rules/issues/context/unknownContextFormulaRule.js.map +1 -1
- package/dist/rules/issues/context/unknownContextProviderFormulaRule.d.ts +2 -2
- package/dist/rules/issues/context/unknownContextProviderFormulaRule.js.map +1 -1
- package/dist/rules/issues/context/unknownContextProviderRule.d.ts +2 -2
- package/dist/rules/issues/context/unknownContextProviderRule.js.map +1 -1
- package/dist/rules/issues/dom/createRequiredDirectChildRule.d.ts +2 -2
- package/dist/rules/issues/dom/createRequiredDirectChildRule.js.map +1 -1
- package/dist/rules/issues/dom/createRequiredDirectParentRule.d.ts +2 -2
- package/dist/rules/issues/dom/createRequiredDirectParentRule.js.map +1 -1
- package/dist/rules/issues/dom/createRequiredElementAttributeRule.d.ts +2 -2
- package/dist/rules/issues/dom/createRequiredElementAttributeRule.js.map +1 -1
- package/dist/rules/issues/dom/createRequiredMetaTagRule.d.ts +2 -2
- package/dist/rules/issues/dom/createRequiredMetaTagRule.js.map +1 -1
- package/dist/rules/issues/dom/domRules.index.d.ts +5 -5
- package/dist/rules/issues/dom/elementWithoutInteractiveContentRule.d.ts +2 -2
- package/dist/rules/issues/dom/elementWithoutInteractiveContentRule.js.map +1 -1
- package/dist/rules/issues/dom/imageWithoutDimensionRule.d.ts +2 -2
- package/dist/rules/issues/dom/imageWithoutDimensionRule.js.map +1 -1
- package/dist/rules/issues/dom/nonEmptyVoidElementRule.d.ts +2 -2
- package/dist/rules/issues/dom/nonEmptyVoidElementRule.js.map +1 -1
- package/dist/rules/issues/events/duplicateEventTriggerRule.d.ts +2 -2
- package/dist/rules/issues/events/duplicateEventTriggerRule.js.map +1 -1
- package/dist/rules/issues/events/eventRules.index.d.ts +2 -2
- package/dist/rules/issues/events/noReferenceEventRule.d.ts +2 -2
- package/dist/rules/issues/events/noReferenceEventRule.js.map +1 -1
- package/dist/rules/issues/events/unknownEventRule.d.ts +2 -2
- package/dist/rules/issues/events/unknownEventRule.js.map +1 -1
- package/dist/rules/issues/events/unknownTriggerEventRule.d.ts +2 -2
- package/dist/rules/issues/events/unknownTriggerEventRule.js.map +1 -1
- package/dist/rules/issues/formulas/duplicateFormulaArgumentNameRule.d.ts +2 -2
- package/dist/rules/issues/formulas/duplicateFormulaArgumentNameRule.js.map +1 -1
- package/dist/rules/issues/formulas/formulaRules.index.d.ts +2 -2
- package/dist/rules/issues/formulas/legacyFormulaRule.d.ts +2 -2
- package/dist/rules/issues/formulas/legacyFormulaRule.fix.js.map +1 -1
- package/dist/rules/issues/formulas/legacyFormulaRule.js.map +1 -1
- package/dist/rules/issues/formulas/noReferenceComponentFormulaRule.d.ts +2 -2
- package/dist/rules/issues/formulas/noReferenceComponentFormulaRule.js.map +1 -1
- package/dist/rules/issues/formulas/noReferenceProjectFormulaRule.d.ts +2 -2
- package/dist/rules/issues/formulas/noReferenceProjectFormulaRule.js.map +1 -1
- package/dist/rules/issues/formulas/projectFormulaIsReferenced.memo.js.map +1 -1
- package/dist/rules/issues/formulas/unknownComponentFormulaInputRule.d.ts +2 -2
- package/dist/rules/issues/formulas/unknownComponentFormulaInputRule.js.map +1 -1
- package/dist/rules/issues/formulas/unknownFormulaRule.d.ts +2 -2
- package/dist/rules/issues/formulas/unknownFormulaRule.js.map +1 -1
- package/dist/rules/issues/formulas/unknownProjectFormulaInputRule.d.ts +2 -2
- package/dist/rules/issues/formulas/unknownProjectFormulaInputRule.js.map +1 -1
- package/dist/rules/issues/formulas/unknownProjectFormulaRule.d.ts +2 -2
- package/dist/rules/issues/formulas/unknownProjectFormulaRule.js.map +1 -1
- package/dist/rules/issues/formulas/unknownRepeatIndexFormulaRule.d.ts +2 -2
- package/dist/rules/issues/formulas/unknownRepeatIndexFormulaRule.js.map +1 -1
- package/dist/rules/issues/formulas/unknownRepeatItemFormulaRule.d.ts +2 -2
- package/dist/rules/issues/formulas/unknownRepeatItemFormulaRule.js.map +1 -1
- package/dist/rules/issues/logic/logicRules.index.d.ts +2 -2
- package/dist/rules/issues/logic/noStaticNodeCondition.d.ts +2 -2
- package/dist/rules/issues/logic/noStaticNodeCondition.js.map +1 -1
- package/dist/rules/issues/logic/noUnnecessaryConditionFalsy.d.ts +2 -2
- package/dist/rules/issues/logic/noUnnecessaryConditionFalsy.js.map +1 -1
- package/dist/rules/issues/logic/noUnnecessaryConditionTruthy.d.ts +2 -2
- package/dist/rules/issues/logic/noUnnecessaryConditionTruthy.js.map +1 -1
- package/dist/rules/issues/miscellaneous/createStaticSizeConstraintRule.d.ts +2 -2
- package/dist/rules/issues/miscellaneous/createStaticSizeConstraintRule.js.map +1 -1
- package/dist/rules/issues/miscellaneous/miscRules.index.d.ts +3 -3
- package/dist/rules/issues/miscellaneous/noReferenceNodeRule.d.ts +2 -2
- package/dist/rules/issues/miscellaneous/noReferenceNodeRule.js.map +1 -1
- package/dist/rules/issues/miscellaneous/noReferencePackageRule.d.ts +2 -2
- package/dist/rules/issues/miscellaneous/noReferencePackageRule.js.map +1 -1
- package/dist/rules/issues/miscellaneous/requireExtensionRule.d.ts +2 -2
- package/dist/rules/issues/miscellaneous/requireExtensionRule.js.map +1 -1
- package/dist/rules/issues/miscellaneous/unknownCookieRule.d.ts +2 -2
- package/dist/rules/issues/miscellaneous/unknownCookieRule.js.map +1 -1
- package/dist/rules/issues/routing/duplicateRouteRule.d.ts +2 -2
- package/dist/rules/issues/routing/duplicateRouteRule.js.map +1 -1
- package/dist/rules/issues/routing/duplicateUrlParameterRule.d.ts +2 -2
- package/dist/rules/issues/routing/duplicateUrlParameterRule.js.map +1 -1
- package/dist/rules/issues/routing/routingRules.index.d.ts +2 -2
- package/dist/rules/issues/routing/unknownSetUrlParameterRule.d.ts +2 -2
- package/dist/rules/issues/routing/unknownSetUrlParameterRule.js.map +1 -1
- package/dist/rules/issues/routing/unknownSetUrlParametersRule.d.ts +2 -2
- package/dist/rules/issues/routing/unknownSetUrlParametersRule.js.map +1 -1
- package/dist/rules/issues/routing/unknownUrlParameterRule.d.ts +2 -2
- package/dist/rules/issues/routing/unknownUrlParameterRule.js.map +1 -1
- package/dist/rules/issues/slots/slotRules.index.d.ts +1 -1
- package/dist/rules/issues/slots/unknownComponentSlotRule.d.ts +2 -2
- package/dist/rules/issues/slots/unknownComponentSlotRule.js.map +1 -1
- package/dist/rules/issues/style/invalidStyleSyntaxRule.d.ts +2 -2
- package/dist/rules/issues/style/invalidStyleSyntaxRule.js.map +1 -1
- package/dist/rules/issues/style/legacyStyleVariableRule.d.ts +2 -2
- package/dist/rules/issues/style/legacyStyleVariableRule.js.map +1 -1
- package/dist/rules/issues/style/legacyThemeRule.d.ts +2 -2
- package/dist/rules/issues/style/legacyThemeRule.js.map +1 -1
- package/dist/rules/issues/style/noReferenceAnimationRule.d.ts +2 -2
- package/dist/rules/issues/style/noReferenceAnimationRule.js.map +1 -1
- package/dist/rules/issues/style/noReferenceGlobalCSSVariable.d.ts +2 -2
- package/dist/rules/issues/style/noReferenceGlobalCSSVariable.js.map +1 -1
- package/dist/rules/issues/style/styleRules.index.d.ts +3 -3
- package/dist/rules/issues/style/unknownCSSVariable.d.ts +2 -2
- package/dist/rules/issues/style/unknownCSSVariable.js.map +1 -1
- package/dist/rules/issues/style/unknownClassnameRule.d.ts +2 -2
- package/dist/rules/issues/style/unknownClassnameRule.js.map +1 -1
- package/dist/rules/issues/variables/noReferenceVariableRule.d.ts +2 -2
- package/dist/rules/issues/variables/noReferenceVariableRule.js.map +1 -1
- package/dist/rules/issues/variables/unknownVariableRule.d.ts +2 -2
- package/dist/rules/issues/variables/unknownVariableRule.js.map +1 -1
- package/dist/rules/issues/variables/unknownVariableSetterRule.d.ts +2 -2
- package/dist/rules/issues/variables/unknownVariableSetterRule.js.map +1 -1
- package/dist/rules/issues/variables/variableRules.index.d.ts +1 -1
- package/dist/rules/issues/workflows/duplicateWorkflowParameterRule.d.ts +2 -2
- package/dist/rules/issues/workflows/duplicateWorkflowParameterRule.js.map +1 -1
- package/dist/rules/issues/workflows/noPostNavigateAction.d.ts +2 -2
- package/dist/rules/issues/workflows/noPostNavigateAction.js.map +1 -1
- package/dist/rules/issues/workflows/noReferenceComponentWorkflowRule.d.ts +2 -2
- package/dist/rules/issues/workflows/noReferenceComponentWorkflowRule.js.map +1 -1
- package/dist/rules/issues/workflows/unknownContextProviderWorkflowRule.d.ts +2 -2
- package/dist/rules/issues/workflows/unknownContextProviderWorkflowRule.js.map +1 -1
- package/dist/rules/issues/workflows/unknownContextWorkflowRule.d.ts +2 -2
- package/dist/rules/issues/workflows/unknownContextWorkflowRule.js.map +1 -1
- package/dist/rules/issues/workflows/unknownTriggerWorkflowParameterRule.d.ts +2 -2
- package/dist/rules/issues/workflows/unknownTriggerWorkflowParameterRule.js.map +1 -1
- package/dist/rules/issues/workflows/unknownTriggerWorkflowRule.d.ts +2 -2
- package/dist/rules/issues/workflows/unknownTriggerWorkflowRule.js.map +1 -1
- package/dist/rules/issues/workflows/unknownWorkflowParameterRule.d.ts +2 -2
- package/dist/rules/issues/workflows/unknownWorkflowParameterRule.js.map +1 -1
- package/dist/rules/issues/workflows/workflowRules.index.d.ts +3 -3
- package/dist/rules/search/fieldSearchRule.d.ts +8 -0
- package/dist/rules/search/fieldSearchRule.js +293 -0
- package/dist/rules/search/fieldSearchRule.js.map +1 -0
- package/dist/search.worker.d.ts +1 -11
- package/dist/search.worker.js +17 -6
- package/dist/search.worker.js.map +1 -1
- package/dist/searchProject.d.ts +11 -5
- package/dist/searchProject.js +11 -12
- package/dist/searchProject.js.map +1 -1
- package/dist/types.d.ts +33 -3
- package/dist/util/contextlessEvaluateFormula.js.map +1 -1
- package/dist/util/helpers.js.map +1 -1
- package/dist/util/parseSearchQuery.d.ts +24 -0
- package/dist/util/parseSearchQuery.js +81 -0
- package/dist/util/parseSearchQuery.js.map +1 -0
- package/dist/util/removeUnused.fix.js.map +1 -1
- package/package.json +6 -5
- package/src/findProblems.ts +7 -3
- package/src/findSearch.ts +134 -0
- package/src/rules/issues/actions/createActionNameRule.ts +2 -2
- package/src/rules/issues/actions/duplicateActionArgumentNameRule.ts +2 -2
- package/src/rules/issues/actions/legacyActionRule.ts +2 -2
- package/src/rules/issues/actions/noReferenceProjectActionRule.ts +2 -2
- package/src/rules/issues/actions/unknownActionArgumentRule.ts +2 -2
- package/src/rules/issues/actions/unknownActionEventRule.ts +2 -2
- package/src/rules/issues/actions/unknownProjectActionRule.ts +2 -2
- package/src/rules/issues/apis/invalidApiParserModeRule.ts +2 -2
- package/src/rules/issues/apis/invalidApiProxyBodySettingRule.ts +2 -2
- package/src/rules/issues/apis/invalidApiProxyCookieSettingRule.ts +2 -2
- package/src/rules/issues/apis/legacyApiRule.ts +2 -2
- package/src/rules/issues/apis/noReferenceApiInputRule.ts +2 -2
- package/src/rules/issues/apis/noReferenceApiRule.ts +2 -2
- package/src/rules/issues/apis/noReferenceApiServiceRule.ts +2 -2
- package/src/rules/issues/apis/unknownApiInputRule.ts +2 -2
- package/src/rules/issues/apis/unknownApiRule.ts +2 -2
- package/src/rules/issues/apis/unknownApiServiceRule.ts +2 -2
- package/src/rules/issues/apis/unknownFetchInputRule.ts +2 -2
- package/src/rules/issues/attributes/noReferenceAttributeInInstanceRule.ts +2 -2
- package/src/rules/issues/attributes/noReferenceAttributeRule.ts +2 -2
- package/src/rules/issues/attributes/unknownAttributeRule.ts +2 -2
- package/src/rules/issues/attributes/unknownComponentAttributeRule.ts +2 -2
- package/src/rules/issues/components/invalidComponentStructureRule.ts +2 -2
- package/src/rules/issues/components/noReferenceComponentRule.ts +2 -2
- package/src/rules/issues/components/unknownComponentRule.ts +2 -2
- package/src/rules/issues/context/noContextConsumersRule.ts +2 -2
- package/src/rules/issues/context/unknownContextFormulaRule.ts +2 -2
- package/src/rules/issues/context/unknownContextProviderFormulaRule.ts +2 -2
- package/src/rules/issues/context/unknownContextProviderRule.ts +32 -31
- package/src/rules/issues/dom/createRequiredDirectChildRule.ts +2 -2
- package/src/rules/issues/dom/createRequiredDirectParentRule.ts +2 -2
- package/src/rules/issues/dom/createRequiredElementAttributeRule.ts +2 -2
- package/src/rules/issues/dom/createRequiredMetaTagRule.ts +2 -2
- package/src/rules/issues/dom/elementWithoutInteractiveContentRule.ts +2 -2
- package/src/rules/issues/dom/imageWithoutDimensionRule.ts +2 -2
- package/src/rules/issues/dom/nonEmptyVoidElementRule.ts +2 -2
- package/src/rules/issues/events/duplicateEventTriggerRule.ts +2 -2
- package/src/rules/issues/events/noReferenceEventRule.ts +2 -2
- package/src/rules/issues/events/unknownEventRule.ts +2 -2
- package/src/rules/issues/events/unknownTriggerEventRule.ts +2 -2
- package/src/rules/issues/formulas/duplicateFormulaArgumentNameRule.ts +2 -2
- package/src/rules/issues/formulas/legacyFormulaRule.ts +2 -2
- package/src/rules/issues/formulas/noReferenceComponentFormulaRule.ts +2 -2
- package/src/rules/issues/formulas/noReferenceProjectFormulaRule.ts +2 -2
- package/src/rules/issues/formulas/unknownComponentFormulaInputRule.ts +2 -2
- package/src/rules/issues/formulas/unknownFormulaRule.ts +2 -2
- package/src/rules/issues/formulas/unknownProjectFormulaInputRule.ts +2 -2
- package/src/rules/issues/formulas/unknownProjectFormulaRule.ts +2 -2
- package/src/rules/issues/formulas/unknownRepeatIndexFormulaRule.ts +2 -2
- package/src/rules/issues/formulas/unknownRepeatItemFormulaRule.ts +2 -2
- package/src/rules/issues/logic/noStaticNodeCondition.ts +2 -2
- package/src/rules/issues/logic/noUnnecessaryConditionFalsy.ts +2 -2
- package/src/rules/issues/logic/noUnnecessaryConditionTruthy.ts +2 -2
- package/src/rules/issues/miscellaneous/createStaticSizeConstraintRule.ts +2 -2
- package/src/rules/issues/miscellaneous/noReferenceNodeRule.ts +2 -2
- package/src/rules/issues/miscellaneous/noReferencePackageRule.ts +2 -2
- package/src/rules/issues/miscellaneous/requireExtensionRule.ts +2 -2
- package/src/rules/issues/miscellaneous/unknownCookieRule.ts +2 -2
- package/src/rules/issues/routing/duplicateRouteRule.ts +2 -2
- package/src/rules/issues/routing/duplicateUrlParameterRule.ts +2 -2
- package/src/rules/issues/routing/unknownSetUrlParameterRule.ts +2 -2
- package/src/rules/issues/routing/unknownSetUrlParametersRule.ts +2 -2
- package/src/rules/issues/routing/unknownUrlParameterRule.ts +2 -2
- package/src/rules/issues/slots/unknownComponentSlotRule.ts +2 -2
- package/src/rules/issues/style/invalidStyleSyntaxRule.ts +2 -2
- package/src/rules/issues/style/legacyStyleVariableRule.ts +2 -2
- package/src/rules/issues/style/legacyThemeRule.ts +2 -2
- package/src/rules/issues/style/noReferenceAnimationRule.ts +2 -2
- package/src/rules/issues/style/noReferenceGlobalCSSVariable.ts +2 -2
- package/src/rules/issues/style/unknownCSSVariable.ts +2 -2
- package/src/rules/issues/style/unknownClassnameRule.ts +2 -2
- package/src/rules/issues/variables/noReferenceVariableRule.ts +2 -2
- package/src/rules/issues/variables/unknownVariableRule.ts +2 -2
- package/src/rules/issues/variables/unknownVariableSetterRule.ts +2 -2
- package/src/rules/issues/workflows/duplicateWorkflowParameterRule.ts +29 -28
- package/src/rules/issues/workflows/noPostNavigateAction.ts +2 -2
- package/src/rules/issues/workflows/noReferenceComponentWorkflowRule.ts +2 -2
- package/src/rules/issues/workflows/unknownContextProviderWorkflowRule.ts +2 -2
- package/src/rules/issues/workflows/unknownContextWorkflowRule.ts +2 -2
- package/src/rules/issues/workflows/unknownTriggerWorkflowParameterRule.ts +55 -54
- package/src/rules/issues/workflows/unknownTriggerWorkflowRule.ts +2 -2
- package/src/rules/issues/workflows/unknownWorkflowParameterRule.ts +2 -2
- package/src/rules/search/fieldSearchRule.test.ts +464 -0
- package/src/rules/search/fieldSearchRule.ts +391 -0
- package/src/search.worker.ts +19 -46
- package/src/searchProject.ts +45 -27
- package/src/types.ts +41 -3
- package/src/util/parseSearchQuery.test.ts +56 -0
- package/src/util/parseSearchQuery.ts +92 -0
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import equal from 'fast-deep-equal'
|
|
2
|
+
import type { NodeType, SearchRule } from '../../types'
|
|
3
|
+
import { parseSearchQuery } from '../../util/parseSearchQuery'
|
|
4
|
+
|
|
5
|
+
type MatchResult =
|
|
6
|
+
| {
|
|
7
|
+
hasMatch: boolean
|
|
8
|
+
context: { before: string; matched: string; after: string }
|
|
9
|
+
}
|
|
10
|
+
| boolean
|
|
11
|
+
|
|
12
|
+
function makeMatch(str: string, index: number, length: number): MatchResult {
|
|
13
|
+
return {
|
|
14
|
+
hasMatch: true,
|
|
15
|
+
context: {
|
|
16
|
+
before: str.slice(0, index),
|
|
17
|
+
matched: str.slice(index, index + length),
|
|
18
|
+
after: str.slice(index + length),
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function fullMatch(matched: string): MatchResult {
|
|
24
|
+
return { hasMatch: true, context: { before: '', matched, after: '' } }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function checkStringMatch(
|
|
28
|
+
stringVal: string,
|
|
29
|
+
targetValue: string,
|
|
30
|
+
isExact: boolean,
|
|
31
|
+
): MatchResult {
|
|
32
|
+
const stringValueLower = stringVal.toLowerCase()
|
|
33
|
+
const targetValueLower = targetValue.toLowerCase()
|
|
34
|
+
|
|
35
|
+
if (targetValueLower === '') {
|
|
36
|
+
return stringValueLower === ''
|
|
37
|
+
? { hasMatch: true, context: { before: '', matched: '', after: '' } }
|
|
38
|
+
: false
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (isExact) {
|
|
42
|
+
// Attempt JSON structural match for bracket/brace targets
|
|
43
|
+
if (isJsonStructuralTarget(targetValue)) {
|
|
44
|
+
try {
|
|
45
|
+
// JSON parse only used for structural equality — not reproduced as output
|
|
46
|
+
const parsed = JSON.parse(targetValue)
|
|
47
|
+
if (equal(stringVal, parsed) || equal(JSON.parse(stringVal), parsed)) {
|
|
48
|
+
return fullMatch(stringVal)
|
|
49
|
+
}
|
|
50
|
+
} catch {
|
|
51
|
+
// fall through to string comparison
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return stringValueLower === targetValueLower ? fullMatch(stringVal) : false
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const index = stringValueLower.indexOf(targetValueLower)
|
|
58
|
+
return index !== -1 ? makeMatch(stringVal, index, targetValue.length) : false
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function matchRegex(value: any, matcher: RegExp, key?: string): MatchResult {
|
|
62
|
+
const check = (v: any): MatchResult => {
|
|
63
|
+
const str = String(v)
|
|
64
|
+
const m = str.match(matcher)
|
|
65
|
+
if (!m) {
|
|
66
|
+
if (key) {
|
|
67
|
+
const combined = `${key}: ${str}`
|
|
68
|
+
const mCombined = combined.match(matcher)
|
|
69
|
+
if (mCombined) {
|
|
70
|
+
return {
|
|
71
|
+
hasMatch: true,
|
|
72
|
+
context: {
|
|
73
|
+
before: combined.slice(0, mCombined.index),
|
|
74
|
+
matched: combined.slice(
|
|
75
|
+
mCombined.index ?? 0,
|
|
76
|
+
(mCombined.index ?? 0) + mCombined[0].length,
|
|
77
|
+
),
|
|
78
|
+
after: combined.slice(
|
|
79
|
+
(mCombined.index ?? 0) + mCombined[0].length,
|
|
80
|
+
),
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return false
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return makeMatch(str, m.index ?? 0, m[0].length)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!Array.isArray(value)) {
|
|
92
|
+
return check(value)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return false
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function matchString(value: any, matcher: string, key?: string): MatchResult {
|
|
99
|
+
const isExact = matcher.startsWith('"') && matcher.endsWith('"')
|
|
100
|
+
const targetValue = isExact ? matcher.slice(1, -1) : matcher
|
|
101
|
+
const valToCheck = value
|
|
102
|
+
|
|
103
|
+
if (Array.isArray(valToCheck)) {
|
|
104
|
+
const isExactStructural = isExact && isJsonStructuralTarget(targetValue)
|
|
105
|
+
|
|
106
|
+
if (!isExactStructural) {
|
|
107
|
+
for (const v of valToCheck) {
|
|
108
|
+
if (typeof v === 'object' && v !== null && !Array.isArray(v)) {
|
|
109
|
+
if (v.type === 'value' || v.type === 'formula') {
|
|
110
|
+
const inner = matchString(v.value, matcher)
|
|
111
|
+
if (typeof inner === 'object' && inner.hasMatch) {
|
|
112
|
+
return inner
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
continue
|
|
116
|
+
}
|
|
117
|
+
const m = matchString(v, matcher)
|
|
118
|
+
if (typeof m === 'object' && m.hasMatch) {
|
|
119
|
+
return m
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
for (const sep of [',', ', ']) {
|
|
124
|
+
const res = checkStringMatch(valToCheck.join(sep), targetValue, isExact)
|
|
125
|
+
if (res) {
|
|
126
|
+
return res
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return false
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return checkStringMatch(String(valToCheck), targetValue, isExact)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (typeof valToCheck === 'object' && valToCheck !== null) {
|
|
136
|
+
if (isExact) {
|
|
137
|
+
if (isJsonStructuralTarget(targetValue)) {
|
|
138
|
+
try {
|
|
139
|
+
if (equal(valToCheck, JSON.parse(targetValue)))
|
|
140
|
+
return fullMatch(targetValue)
|
|
141
|
+
} catch {
|
|
142
|
+
// fall through
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return false
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const stringified = String(valToCheck)
|
|
149
|
+
if (
|
|
150
|
+
stringified === '[object Object]' &&
|
|
151
|
+
targetValue.toLowerCase() !== '[object object]'
|
|
152
|
+
) {
|
|
153
|
+
return false
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return checkStringMatch(stringified, targetValue, isExact)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const matchRes = checkStringMatch(String(valToCheck), targetValue, isExact)
|
|
160
|
+
if (
|
|
161
|
+
typeof matchRes === 'object' &&
|
|
162
|
+
matchRes.hasMatch &&
|
|
163
|
+
key?.toLowerCase().includes(targetValue.toLowerCase())
|
|
164
|
+
) {
|
|
165
|
+
return matchRes
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return matchRes
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function isMatch(
|
|
172
|
+
value: any,
|
|
173
|
+
matcher: string | RegExp | object | null,
|
|
174
|
+
key?: string,
|
|
175
|
+
): MatchResult {
|
|
176
|
+
if (matcher instanceof RegExp) {
|
|
177
|
+
return matchRegex(value, matcher, key)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (typeof matcher === 'string') {
|
|
181
|
+
return matchString(value, matcher, key)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (Array.isArray(matcher)) {
|
|
185
|
+
return (
|
|
186
|
+
Array.isArray(value) &&
|
|
187
|
+
value.length >= matcher.length &&
|
|
188
|
+
matcher.every((m, i) => equal(value[i], m))
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (typeof matcher === 'object' && matcher !== null) {
|
|
193
|
+
if (typeof value !== 'object' || value === null) {
|
|
194
|
+
return false
|
|
195
|
+
}
|
|
196
|
+
for (const key in matcher) {
|
|
197
|
+
if (!equal(value[key], (matcher as any)[key])) {
|
|
198
|
+
return false
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return true
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return value === matcher
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function getValueByPath(
|
|
208
|
+
obj: any,
|
|
209
|
+
path: string,
|
|
210
|
+
): { value: any; found: boolean } {
|
|
211
|
+
const parts: string[] = []
|
|
212
|
+
const partRegex = /"([^"]+)"|'([^']+)'|([^.\s]+)/g
|
|
213
|
+
let match
|
|
214
|
+
const trimmedPath = path.trim()
|
|
215
|
+
|
|
216
|
+
while ((match = partRegex.exec(trimmedPath)) !== null) {
|
|
217
|
+
parts.push(match[1] || match[2] || match[3])
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (trimmedPath.includes('*')) {
|
|
221
|
+
const results: any[] = []
|
|
222
|
+
const walk = (curr: any, i: number) => {
|
|
223
|
+
if (i === parts.length) {
|
|
224
|
+
results.push(curr)
|
|
225
|
+
return
|
|
226
|
+
}
|
|
227
|
+
if (curr === null || typeof curr !== 'object') {
|
|
228
|
+
return
|
|
229
|
+
}
|
|
230
|
+
if (parts[i] === '*') {
|
|
231
|
+
for (const k in curr) walk(curr[k], i + 1)
|
|
232
|
+
} else if (parts[i] in curr) {
|
|
233
|
+
walk(curr[parts[i]], i + 1)
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
walk(obj, 0)
|
|
237
|
+
return { value: results, found: results.length > 0 }
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
let curr = obj
|
|
241
|
+
for (const p of parts) {
|
|
242
|
+
if (curr === null || typeof curr !== 'object' || !(p in curr)) {
|
|
243
|
+
return { value: undefined, found: false }
|
|
244
|
+
}
|
|
245
|
+
curr = curr[p]
|
|
246
|
+
}
|
|
247
|
+
return { value: curr, found: true }
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export function createFieldSearchRule({
|
|
251
|
+
query,
|
|
252
|
+
skippedFields,
|
|
253
|
+
}: {
|
|
254
|
+
query: string
|
|
255
|
+
withDetails?: boolean
|
|
256
|
+
skippedFields?: Partial<{
|
|
257
|
+
[K in NodeType as K['nodeType']]: (keyof K['value'])[]
|
|
258
|
+
}>
|
|
259
|
+
}): SearchRule {
|
|
260
|
+
const parsedQuery = parseSearchQuery(query)
|
|
261
|
+
const reportedPaths = new Set<string>()
|
|
262
|
+
|
|
263
|
+
function evaluateFieldsObject(
|
|
264
|
+
val: any,
|
|
265
|
+
fieldsObj: Record<string, string | RegExp>,
|
|
266
|
+
): MatchResult {
|
|
267
|
+
let lastMatch: MatchResult = true
|
|
268
|
+
for (const f in fieldsObj) {
|
|
269
|
+
const m = fieldsObj[f]
|
|
270
|
+
|
|
271
|
+
const { value: fv, found } = getValueByPath(val, f)
|
|
272
|
+
if (!found) {
|
|
273
|
+
return false
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const matchResult = isMatch(fv, m, f)
|
|
277
|
+
if (!matchResult) {
|
|
278
|
+
return false
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (typeof matchResult === 'object' && matchResult.hasMatch) {
|
|
282
|
+
lastMatch = { ...matchResult, field: f } as any
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return lastMatch
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function evaluateValue(val: any, part: any, key: string): MatchResult {
|
|
290
|
+
const { fields, exclude } = part
|
|
291
|
+
|
|
292
|
+
if (!fields) {
|
|
293
|
+
return !exclude
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
let matched: MatchResult = false
|
|
297
|
+
|
|
298
|
+
if (
|
|
299
|
+
typeof fields === 'object' &&
|
|
300
|
+
!Array.isArray(fields) &&
|
|
301
|
+
!(fields instanceof RegExp)
|
|
302
|
+
) {
|
|
303
|
+
matched = evaluateFieldsObject(
|
|
304
|
+
val,
|
|
305
|
+
fields as Record<string, string | RegExp>,
|
|
306
|
+
)
|
|
307
|
+
} else {
|
|
308
|
+
const matchResult = isMatch(val, fields, key)
|
|
309
|
+
matched =
|
|
310
|
+
typeof matchResult === 'object' && matchResult.hasMatch
|
|
311
|
+
? matchResult
|
|
312
|
+
: !!matchResult
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return exclude ? !matched : matched
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
visit: (report, { path, value, nodeType }) => {
|
|
320
|
+
if (
|
|
321
|
+
typeof value !== 'object' ||
|
|
322
|
+
value === null ||
|
|
323
|
+
parsedQuery.length === 0
|
|
324
|
+
)
|
|
325
|
+
return
|
|
326
|
+
|
|
327
|
+
let matchContext: any = null
|
|
328
|
+
let matchedFieldName: string | null = null
|
|
329
|
+
|
|
330
|
+
const allMatched = parsedQuery.every((p) => {
|
|
331
|
+
if (p.nodeType && nodeType !== p.nodeType) {
|
|
332
|
+
return false
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const evalRes = evaluateValue(value, p, '')
|
|
336
|
+
if (evalRes) {
|
|
337
|
+
if (typeof evalRes === 'object' && evalRes.hasMatch) {
|
|
338
|
+
matchContext = evalRes.context
|
|
339
|
+
matchedFieldName = (evalRes as any).field ?? matchedFieldName
|
|
340
|
+
}
|
|
341
|
+
{
|
|
342
|
+
return true
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return Object.entries(value).some(([k, v]) => {
|
|
347
|
+
if (
|
|
348
|
+
(skippedFields?.[nodeType] as Array<string> | undefined)?.includes(
|
|
349
|
+
k,
|
|
350
|
+
)
|
|
351
|
+
) {
|
|
352
|
+
return false
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const resValue = evaluateValue(v, p, k)
|
|
356
|
+
if (resValue) {
|
|
357
|
+
if (typeof resValue === 'object' && resValue.hasMatch) {
|
|
358
|
+
matchContext = resValue.context
|
|
359
|
+
matchedFieldName = (resValue as any).field ?? k
|
|
360
|
+
}
|
|
361
|
+
return true
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return false
|
|
365
|
+
})
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
if (allMatched) {
|
|
369
|
+
const pk = path.join('.')
|
|
370
|
+
if (!reportedPaths.has(pk)) {
|
|
371
|
+
reportedPaths.add(pk)
|
|
372
|
+
report({
|
|
373
|
+
path,
|
|
374
|
+
details: {
|
|
375
|
+
context: matchContext,
|
|
376
|
+
field: matchedFieldName,
|
|
377
|
+
nodeType,
|
|
378
|
+
},
|
|
379
|
+
})
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function isJsonStructuralTarget(targetValue: string): boolean {
|
|
387
|
+
return (
|
|
388
|
+
(targetValue.startsWith('[') && targetValue.endsWith(']')) ||
|
|
389
|
+
(targetValue.startsWith('{') && targetValue.endsWith('}'))
|
|
390
|
+
)
|
|
391
|
+
}
|
package/src/search.worker.ts
CHANGED
|
@@ -1,49 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
type Query =
|
|
4
|
-
| {
|
|
5
|
-
type: 'freeform'
|
|
6
|
-
value: string
|
|
7
|
-
}
|
|
8
|
-
| {
|
|
9
|
-
type: 'component'
|
|
10
|
-
name: string
|
|
11
|
-
references?: boolean
|
|
12
|
-
}
|
|
13
|
-
| {
|
|
14
|
-
type: 'formula'
|
|
15
|
-
name: string
|
|
16
|
-
references?: boolean
|
|
17
|
-
}
|
|
18
|
-
| {
|
|
19
|
-
type: 'action'
|
|
20
|
-
name: string
|
|
21
|
-
references?: boolean
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export type Options = {
|
|
25
|
-
/**
|
|
26
|
-
* Useful for running search on a subset or a single file.
|
|
27
|
-
*/
|
|
28
|
-
pathsToVisit?: string[][]
|
|
29
|
-
/**
|
|
30
|
-
* The number of reports to send per message.
|
|
31
|
-
* @default 1
|
|
32
|
-
*/
|
|
33
|
-
batchSize?: number | 'all' | 'per-file'
|
|
34
|
-
}
|
|
35
|
-
|
|
1
|
+
/* eslint-disable no-console */
|
|
36
2
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* Great for finding freeform text anywhere in a project, or references, dependencies etc.
|
|
3
|
+
* This function is a web worker that checks for problems in the files.
|
|
40
4
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
) => {
|
|
48
|
-
|
|
5
|
+
import { findSearch } from './findSearch'
|
|
6
|
+
import type { SearchArgs } from './types'
|
|
7
|
+
|
|
8
|
+
onmessage = (event: MessageEvent<SearchArgs>) => {
|
|
9
|
+
console.time('search:' + event.data.id)
|
|
10
|
+
findSearch(event.data, (results) => postMessage(results))
|
|
11
|
+
.then(() => {
|
|
12
|
+
console.timeEnd('search:' + event.data.id)
|
|
13
|
+
})
|
|
14
|
+
.catch((error) => {
|
|
15
|
+
postMessage({
|
|
16
|
+
id: event.data.id,
|
|
17
|
+
complete: true,
|
|
18
|
+
cancelled: true,
|
|
19
|
+
cancelReason: `Search failed with error: ${error instanceof Error ? error.message : String(error)}`,
|
|
20
|
+
})
|
|
21
|
+
})
|
|
49
22
|
}
|
package/src/searchProject.ts
CHANGED
|
@@ -3,11 +3,20 @@ import type { CustomPropertyName } from '@nordcraft/core/dist/component/componen
|
|
|
3
3
|
import { ToddleComponent } from '@nordcraft/core/dist/component/ToddleComponent'
|
|
4
4
|
import { isToddleFormula } from '@nordcraft/core/dist/formula/formula'
|
|
5
5
|
import { ToddleFormula } from '@nordcraft/core/dist/formula/ToddleFormula'
|
|
6
|
+
import { isDefined } from '@nordcraft/core/dist/utils/util'
|
|
6
7
|
import type { ProjectFiles } from '@nordcraft/ssr/dist/ssr.types'
|
|
7
8
|
import { ToddleApiService } from '@nordcraft/ssr/dist/ToddleApiService'
|
|
8
9
|
import { ToddleRoute } from '@nordcraft/ssr/dist/ToddleRoute'
|
|
9
|
-
import type {
|
|
10
|
-
|
|
10
|
+
import type {
|
|
11
|
+
ApplicationState,
|
|
12
|
+
FixType,
|
|
13
|
+
IssueResult,
|
|
14
|
+
IssueRule,
|
|
15
|
+
NodeType,
|
|
16
|
+
Rule,
|
|
17
|
+
SearchResult,
|
|
18
|
+
SearchRule,
|
|
19
|
+
} from './types'
|
|
11
20
|
import { shouldSearchExactPath, shouldVisitTree } from './util/helpers'
|
|
12
21
|
|
|
13
22
|
interface FixOptions {
|
|
@@ -27,14 +36,21 @@ interface FixOptions {
|
|
|
27
36
|
*/
|
|
28
37
|
export function searchProject(args: {
|
|
29
38
|
files: Omit<ProjectFiles, 'config'> & Partial<Pick<ProjectFiles, 'config'>>
|
|
30
|
-
rules:
|
|
39
|
+
rules: SearchRule<any, any>[]
|
|
40
|
+
pathsToVisit?: string[][]
|
|
41
|
+
useExactPaths?: boolean
|
|
42
|
+
withDetails?: boolean
|
|
43
|
+
}): Generator<SearchResult>
|
|
44
|
+
export function searchProject(args: {
|
|
45
|
+
files: Omit<ProjectFiles, 'config'> & Partial<Pick<ProjectFiles, 'config'>>
|
|
46
|
+
rules: IssueRule<any, any>[]
|
|
31
47
|
pathsToVisit?: string[][]
|
|
32
48
|
useExactPaths?: boolean
|
|
33
49
|
state?: ApplicationState
|
|
34
|
-
}): Generator<
|
|
50
|
+
}): Generator<IssueResult>
|
|
35
51
|
export function searchProject(args: {
|
|
36
52
|
files: Omit<ProjectFiles, 'config'> & Partial<Pick<ProjectFiles, 'config'>>
|
|
37
|
-
rules:
|
|
53
|
+
rules: IssueRule<any, any>[]
|
|
38
54
|
pathsToVisit?: string[][]
|
|
39
55
|
useExactPaths?: boolean
|
|
40
56
|
state?: ApplicationState
|
|
@@ -49,12 +65,12 @@ export function* searchProject({
|
|
|
49
65
|
fixOptions,
|
|
50
66
|
}: {
|
|
51
67
|
files: Omit<ProjectFiles, 'config'> & Partial<Pick<ProjectFiles, 'config'>>
|
|
52
|
-
rules:
|
|
68
|
+
rules: Rule[]
|
|
53
69
|
pathsToVisit?: string[][]
|
|
54
70
|
useExactPaths?: boolean
|
|
55
71
|
state?: ApplicationState
|
|
56
72
|
fixOptions?: FixOptions
|
|
57
|
-
}): Generator<
|
|
73
|
+
}): Generator<SearchResult | IssueResult | ProjectFiles | void> {
|
|
58
74
|
const memos = new Map<string, any>()
|
|
59
75
|
const memo = (key: string | string[], fn: () => any) => {
|
|
60
76
|
const stringKey = Array.isArray(key) ? key.join('/') : key
|
|
@@ -238,18 +254,18 @@ export function* searchProject({
|
|
|
238
254
|
function visitNode(args: {
|
|
239
255
|
args: {
|
|
240
256
|
path: (string | number)[]
|
|
241
|
-
rules: Rule
|
|
257
|
+
rules: Rule[]
|
|
242
258
|
files: Omit<ProjectFiles, 'config'> & Partial<Pick<ProjectFiles, 'config'>>
|
|
243
259
|
pathsToVisit: string[][]
|
|
244
260
|
useExactPaths: boolean
|
|
245
261
|
} & NodeType
|
|
246
262
|
state: ApplicationState | undefined
|
|
247
263
|
fixOptions: never
|
|
248
|
-
}): Generator<
|
|
264
|
+
}): Generator<IssueResult>
|
|
249
265
|
function visitNode(args: {
|
|
250
266
|
args: {
|
|
251
267
|
path: (string | number)[]
|
|
252
|
-
rules: Rule
|
|
268
|
+
rules: Rule[]
|
|
253
269
|
files: Omit<ProjectFiles, 'config'> & Partial<Pick<ProjectFiles, 'config'>>
|
|
254
270
|
pathsToVisit: string[][]
|
|
255
271
|
useExactPaths: boolean
|
|
@@ -264,14 +280,14 @@ function* visitNode({
|
|
|
264
280
|
}: {
|
|
265
281
|
args: {
|
|
266
282
|
path: (string | number)[]
|
|
267
|
-
rules: Rule
|
|
283
|
+
rules: Rule[]
|
|
268
284
|
files: Omit<ProjectFiles, 'config'> & Partial<Pick<ProjectFiles, 'config'>>
|
|
269
285
|
pathsToVisit: string[][]
|
|
270
286
|
useExactPaths: boolean
|
|
271
287
|
} & NodeType
|
|
272
288
|
state: ApplicationState | undefined
|
|
273
289
|
fixOptions?: FixOptions
|
|
274
|
-
}): Generator<
|
|
290
|
+
}): Generator<IssueResult | ProjectFiles | void> {
|
|
275
291
|
const { rules, pathsToVisit, useExactPaths, ...data } = args
|
|
276
292
|
const { files, value, path, memo, nodeType } = data
|
|
277
293
|
if (
|
|
@@ -288,11 +304,9 @@ function* visitNode({
|
|
|
288
304
|
!useExactPaths ||
|
|
289
305
|
shouldSearchExactPath({ path: data.path, pathsToVisit })
|
|
290
306
|
) {
|
|
291
|
-
const results:
|
|
307
|
+
const results: IssueResult[] | SearchResult[] = []
|
|
292
308
|
let fixedFiles: ProjectFiles | undefined
|
|
293
|
-
for (const rule of rules) {
|
|
294
|
-
// eslint-disable-next-line no-console
|
|
295
|
-
console.timeStamp(`Visiting rule ${rule.code}`)
|
|
309
|
+
for (const rule of rules as (IssueRule & SearchRule)[]) {
|
|
296
310
|
rule.visit(
|
|
297
311
|
// Report callback used to report issues
|
|
298
312
|
({ path, details, fixes, info }) => {
|
|
@@ -316,16 +330,20 @@ function* visitNode({
|
|
|
316
330
|
}
|
|
317
331
|
}
|
|
318
332
|
} else {
|
|
319
|
-
//
|
|
320
|
-
results.push(
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
333
|
+
// Optional filtering to remove undefined entries as different rule types have only subset of fields
|
|
334
|
+
results.push(
|
|
335
|
+
Object.fromEntries(
|
|
336
|
+
[
|
|
337
|
+
['code', rule.code],
|
|
338
|
+
['category', rule.category],
|
|
339
|
+
['level', rule.level],
|
|
340
|
+
['path', path],
|
|
341
|
+
['details', details],
|
|
342
|
+
['fixes', fixes],
|
|
343
|
+
['info', info],
|
|
344
|
+
].filter(([, value]) => isDefined(value)),
|
|
345
|
+
),
|
|
346
|
+
)
|
|
329
347
|
}
|
|
330
348
|
},
|
|
331
349
|
data,
|
|
@@ -343,7 +361,7 @@ function* visitNode({
|
|
|
343
361
|
}
|
|
344
362
|
} else {
|
|
345
363
|
for (const result of results) {
|
|
346
|
-
yield result
|
|
364
|
+
yield result as IssueResult & SearchResult
|
|
347
365
|
}
|
|
348
366
|
}
|
|
349
367
|
}
|
package/src/types.ts
CHANGED
|
@@ -158,7 +158,7 @@ export type Category =
|
|
|
158
158
|
|
|
159
159
|
export type Level = 'error' | 'warning' | 'info'
|
|
160
160
|
|
|
161
|
-
export type
|
|
161
|
+
export type IssueResult = {
|
|
162
162
|
path: (string | number)[]
|
|
163
163
|
code: Code
|
|
164
164
|
category: Category
|
|
@@ -168,6 +168,11 @@ export type Result = {
|
|
|
168
168
|
info: ReportedIssueInfo
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
export type SearchResult = {
|
|
172
|
+
path: (string | number)[]
|
|
173
|
+
details?: any
|
|
174
|
+
}
|
|
175
|
+
|
|
171
176
|
export interface ApplicationCookie {
|
|
172
177
|
url: string
|
|
173
178
|
name: string
|
|
@@ -494,7 +499,7 @@ interface ReportedIssueInfo {
|
|
|
494
499
|
description: string
|
|
495
500
|
}
|
|
496
501
|
|
|
497
|
-
export interface
|
|
502
|
+
export interface IssueRule<
|
|
498
503
|
T = unknown,
|
|
499
504
|
V extends NodeType = NodeType,
|
|
500
505
|
N extends NodeType = V,
|
|
@@ -515,6 +520,16 @@ export interface Rule<
|
|
|
515
520
|
fixes?: Partial<Record<FixType, FixFunction<N, T>>>
|
|
516
521
|
}
|
|
517
522
|
|
|
523
|
+
export interface SearchRule<T = unknown, V extends NodeType = NodeType> {
|
|
524
|
+
visit: (
|
|
525
|
+
report: (args: { path: (string | number)[]; details?: T }) => void,
|
|
526
|
+
data: V,
|
|
527
|
+
state?: ApplicationState | undefined,
|
|
528
|
+
) => void
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
export type Rule = IssueRule | SearchRule
|
|
532
|
+
|
|
518
533
|
export interface FixFunctionArgs<Data extends NodeType, Details = unknown> {
|
|
519
534
|
data: Data
|
|
520
535
|
details?: Details
|
|
@@ -565,7 +580,8 @@ export interface FindProblemsArgs {
|
|
|
565
580
|
|
|
566
581
|
export interface FindProblemsResponse {
|
|
567
582
|
id: string
|
|
568
|
-
results:
|
|
583
|
+
results: IssueResult[]
|
|
584
|
+
complete?: true
|
|
569
585
|
}
|
|
570
586
|
|
|
571
587
|
export interface FixProblemsArgs {
|
|
@@ -582,3 +598,25 @@ export interface FixProblemsResponse {
|
|
|
582
598
|
fixRule: Code
|
|
583
599
|
fixType: FixType
|
|
584
600
|
}
|
|
601
|
+
|
|
602
|
+
export interface SearchArgs {
|
|
603
|
+
id: string
|
|
604
|
+
query: string
|
|
605
|
+
// Files are optional, to allow for updating the query without resending the files in cases where they have not changed
|
|
606
|
+
files?: ProjectFiles
|
|
607
|
+
options?: {
|
|
608
|
+
pathsToVisit?: string[][]
|
|
609
|
+
useExactPaths?: boolean
|
|
610
|
+
batchSize?: number | 'all' | 'per-file'
|
|
611
|
+
// disabling details can improve performance as they sometimes require extra computation
|
|
612
|
+
withDetails?: boolean
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
export interface SearchResponse {
|
|
617
|
+
id: string
|
|
618
|
+
results: SearchResult[]
|
|
619
|
+
complete?: boolean
|
|
620
|
+
cancelled?: boolean
|
|
621
|
+
cancelReason?: string
|
|
622
|
+
}
|