@ontrails/warden 1.0.0-beta.14 → 1.0.0-beta.16
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/CHANGELOG.md +149 -0
- package/README.md +77 -34
- package/bin/warden.ts +22 -0
- package/package.json +26 -6
- package/src/ast.ts +28 -0
- package/src/cli.ts +1169 -116
- package/src/command.ts +927 -0
- package/src/config.ts +184 -0
- package/src/drift.ts +76 -34
- package/src/formatters.ts +54 -7
- package/src/guide.ts +234 -0
- package/src/index.ts +151 -38
- package/src/project-context.ts +163 -0
- package/src/resolve.ts +530 -0
- package/src/rules/activation-orphan.ts +97 -0
- package/src/rules/ast.ts +2884 -124
- package/src/rules/circular-refs.ts +154 -0
- package/src/rules/{context-no-trailhead-types.ts → context-no-surface-types.ts} +72 -12
- package/src/rules/contour-exists.ts +251 -0
- package/src/rules/contour-ids.ts +15 -0
- package/src/rules/cross-declarations.ts +277 -69
- package/src/rules/dead-internal-trail.ts +141 -0
- package/src/rules/draft-file-marking.ts +51 -3
- package/src/rules/draft-visible-debt.ts +40 -15
- package/src/rules/error-mapping-completeness.ts +288 -0
- package/src/rules/example-valid.ts +401 -0
- package/src/rules/fires-declarations.ts +758 -0
- package/src/rules/implementation-returns-result.ts +1042 -122
- package/src/rules/incomplete-accessor-for-standard-op.ts +272 -0
- package/src/rules/incomplete-crud.ts +580 -0
- package/src/rules/index.ts +156 -19
- package/src/rules/intent-propagation.ts +127 -0
- package/src/rules/layer-field-name-drift.ts +96 -0
- package/src/rules/metadata.ts +508 -0
- package/src/rules/missing-reconcile.ts +98 -0
- package/src/rules/missing-visibility.ts +110 -0
- package/src/rules/no-dev-permit-in-source.ts +99 -0
- package/src/rules/no-direct-implementation-call.ts +1 -1
- package/src/rules/no-legacy-layer-imports.ts +193 -0
- package/src/rules/no-native-error-result.ts +111 -0
- package/src/rules/no-sync-result-assumption.ts +1131 -96
- package/src/rules/no-throw-in-detour-recover.ts +225 -0
- package/src/rules/no-throw-in-implementation.ts +6 -4
- package/src/rules/on-references-exist.ts +194 -0
- package/src/rules/orphaned-signal.ts +150 -0
- package/src/rules/owner-projection-parity.ts +146 -0
- package/src/rules/permit-governance.ts +25 -0
- package/src/rules/public-internal-deep-imports.ts +517 -0
- package/src/rules/public-output-schema.ts +29 -0
- package/src/rules/public-union-output-discriminants.ts +150 -0
- package/src/rules/read-intent-fires.ts +187 -0
- package/src/rules/reference-exists.ts +98 -0
- package/src/rules/registry-names.ts +113 -0
- package/src/rules/resolved-import-boundary.ts +146 -0
- package/src/rules/{provision-declarations.ts → resource-declarations.ts} +208 -138
- package/src/rules/{provision-exists.ts → resource-exists.ts} +46 -51
- package/src/rules/resource-id-grammar.ts +65 -0
- package/src/rules/scan.ts +0 -26
- package/src/rules/scheduled-destroy-intent.ts +44 -0
- package/src/rules/signal-graph-coaching.ts +191 -0
- package/src/rules/specs.ts +5 -1
- package/src/rules/static-resource-accessor-preference.ts +657 -0
- package/src/rules/types.ts +187 -7
- package/src/rules/unmaterialized-activation-source.ts +84 -0
- package/src/rules/unreachable-detour-shadowing.ts +344 -0
- package/src/rules/valid-describe-refs.ts +160 -32
- package/src/rules/valid-detour-contract.ts +78 -0
- package/src/rules/warden-export-symmetry.ts +533 -0
- package/src/rules/warden-rules-use-ast.ts +996 -0
- package/src/rules/webhook-route-collision.ts +243 -0
- package/src/trails/activation-orphan.trail.ts +81 -0
- package/src/trails/circular-refs.trail.ts +29 -0
- package/src/trails/{context-no-trailhead-types.trail.ts → context-no-surface-types.trail.ts} +4 -4
- package/src/trails/contour-exists.trail.ts +21 -0
- package/src/trails/dead-internal-trail.trail.ts +26 -0
- package/src/trails/draft-file-marking.trail.ts +16 -0
- package/src/trails/draft-visible-debt.trail.ts +16 -0
- package/src/trails/error-mapping-completeness.trail.ts +29 -0
- package/src/trails/example-valid.trail.ts +25 -0
- package/src/trails/fires-declarations.trail.ts +23 -0
- package/src/trails/incomplete-accessor-for-standard-op.trail.ts +76 -0
- package/src/trails/incomplete-crud.trail.ts +39 -0
- package/src/trails/index.ts +56 -8
- package/src/trails/intent-propagation.trail.ts +30 -0
- package/src/trails/layer-field-name-drift.trail.ts +39 -0
- package/src/trails/missing-reconcile.trail.ts +33 -0
- package/src/trails/missing-visibility.trail.ts +22 -0
- package/src/trails/no-dev-permit-in-source.trail.ts +16 -0
- package/src/trails/no-legacy-layer-imports.trail.ts +35 -0
- package/src/trails/no-native-error-result.trail.ts +18 -0
- package/src/trails/no-throw-in-detour-recover.trail.ts +24 -0
- package/src/trails/on-references-exist.trail.ts +21 -0
- package/src/trails/orphaned-signal.trail.ts +36 -0
- package/src/trails/owner-projection-parity.trail.ts +26 -0
- package/src/trails/permit-governance.trail.ts +51 -0
- package/src/trails/public-internal-deep-imports.trail.ts +94 -0
- package/src/trails/public-output-schema.trail.ts +55 -0
- package/src/trails/public-union-output-discriminants.trail.ts +33 -0
- package/src/trails/read-intent-fires.trail.ts +20 -0
- package/src/trails/reference-exists.trail.ts +25 -0
- package/src/trails/resolved-import-boundary.trail.ts +109 -0
- package/src/trails/{provision-declarations.trail.ts → resource-declarations.trail.ts} +6 -6
- package/src/trails/{provision-exists.trail.ts → resource-exists.trail.ts} +7 -7
- package/src/trails/resource-id-grammar.trail.ts +39 -0
- package/src/trails/run.ts +133 -24
- package/src/trails/scheduled-destroy-intent.trail.ts +56 -0
- package/src/trails/schema.ts +122 -4
- package/src/trails/signal-graph-coaching.trail.ts +74 -0
- package/src/trails/static-resource-accessor-preference.trail.ts +25 -0
- package/src/trails/unmaterialized-activation-source.trail.ts +69 -0
- package/src/trails/unreachable-detour-shadowing.trail.ts +45 -0
- package/src/trails/valid-detour-contract.trail.ts +71 -0
- package/src/trails/warden-export-symmetry.trail.ts +16 -0
- package/src/trails/warden-rules-use-ast.trail.ts +45 -0
- package/src/trails/webhook-route-collision.trail.ts +50 -0
- package/src/trails/wrap-rule.ts +133 -14
- package/src/workspaces.ts +238 -0
- package/.turbo/turbo-build.log +0 -1
- package/.turbo/turbo-lint.log +0 -3
- package/.turbo/turbo-typecheck.log +0 -1
- package/dist/cli.d.ts +0 -46
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -247
- package/dist/cli.js.map +0 -1
- package/dist/draft.d.ts +0 -5
- package/dist/draft.d.ts.map +0 -1
- package/dist/draft.js +0 -16
- package/dist/draft.js.map +0 -1
- package/dist/drift.d.ts +0 -29
- package/dist/drift.d.ts.map +0 -1
- package/dist/drift.js +0 -61
- package/dist/drift.js.map +0 -1
- package/dist/formatters.d.ts +0 -30
- package/dist/formatters.d.ts.map +0 -1
- package/dist/formatters.js +0 -98
- package/dist/formatters.js.map +0 -1
- package/dist/index.d.ts +0 -37
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -38
- package/dist/index.js.map +0 -1
- package/dist/rules/ast.d.ts +0 -82
- package/dist/rules/ast.d.ts.map +0 -1
- package/dist/rules/ast.js +0 -363
- package/dist/rules/ast.js.map +0 -1
- package/dist/rules/context-no-surface-types.d.ts +0 -12
- package/dist/rules/context-no-surface-types.d.ts.map +0 -1
- package/dist/rules/context-no-surface-types.js +0 -96
- package/dist/rules/context-no-surface-types.js.map +0 -1
- package/dist/rules/context-no-trailhead-types.d.ts +0 -12
- package/dist/rules/context-no-trailhead-types.d.ts.map +0 -1
- package/dist/rules/context-no-trailhead-types.js +0 -96
- package/dist/rules/context-no-trailhead-types.js.map +0 -1
- package/dist/rules/cross-declarations.d.ts +0 -13
- package/dist/rules/cross-declarations.d.ts.map +0 -1
- package/dist/rules/cross-declarations.js +0 -264
- package/dist/rules/cross-declarations.js.map +0 -1
- package/dist/rules/draft-file-marking.d.ts +0 -6
- package/dist/rules/draft-file-marking.d.ts.map +0 -1
- package/dist/rules/draft-file-marking.js +0 -65
- package/dist/rules/draft-file-marking.js.map +0 -1
- package/dist/rules/draft-visible-debt.d.ts +0 -12
- package/dist/rules/draft-visible-debt.d.ts.map +0 -1
- package/dist/rules/draft-visible-debt.js +0 -45
- package/dist/rules/draft-visible-debt.js.map +0 -1
- package/dist/rules/follow-declarations.d.ts +0 -13
- package/dist/rules/follow-declarations.d.ts.map +0 -1
- package/dist/rules/follow-declarations.js +0 -264
- package/dist/rules/follow-declarations.js.map +0 -1
- package/dist/rules/implementation-returns-result.d.ts +0 -13
- package/dist/rules/implementation-returns-result.d.ts.map +0 -1
- package/dist/rules/implementation-returns-result.js +0 -277
- package/dist/rules/implementation-returns-result.js.map +0 -1
- package/dist/rules/index.d.ts +0 -20
- package/dist/rules/index.d.ts.map +0 -1
- package/dist/rules/index.js +0 -49
- package/dist/rules/index.js.map +0 -1
- package/dist/rules/no-direct-impl-in-route.d.ts +0 -12
- package/dist/rules/no-direct-impl-in-route.d.ts.map +0 -1
- package/dist/rules/no-direct-impl-in-route.js +0 -47
- package/dist/rules/no-direct-impl-in-route.js.map +0 -1
- package/dist/rules/no-direct-implementation-call.d.ts +0 -12
- package/dist/rules/no-direct-implementation-call.d.ts.map +0 -1
- package/dist/rules/no-direct-implementation-call.js +0 -39
- package/dist/rules/no-direct-implementation-call.js.map +0 -1
- package/dist/rules/no-sync-result-assumption.d.ts +0 -6
- package/dist/rules/no-sync-result-assumption.d.ts.map +0 -1
- package/dist/rules/no-sync-result-assumption.js +0 -98
- package/dist/rules/no-sync-result-assumption.js.map +0 -1
- package/dist/rules/no-throw-in-detour-target.d.ts +0 -12
- package/dist/rules/no-throw-in-detour-target.d.ts.map +0 -1
- package/dist/rules/no-throw-in-detour-target.js +0 -87
- package/dist/rules/no-throw-in-detour-target.js.map +0 -1
- package/dist/rules/no-throw-in-implementation.d.ts +0 -9
- package/dist/rules/no-throw-in-implementation.d.ts.map +0 -1
- package/dist/rules/no-throw-in-implementation.js +0 -34
- package/dist/rules/no-throw-in-implementation.js.map +0 -1
- package/dist/rules/prefer-schema-inference.d.ts +0 -7
- package/dist/rules/prefer-schema-inference.d.ts.map +0 -1
- package/dist/rules/prefer-schema-inference.js +0 -86
- package/dist/rules/prefer-schema-inference.js.map +0 -1
- package/dist/rules/provision-declarations.d.ts +0 -14
- package/dist/rules/provision-declarations.d.ts.map +0 -1
- package/dist/rules/provision-declarations.js +0 -344
- package/dist/rules/provision-declarations.js.map +0 -1
- package/dist/rules/provision-exists.d.ts +0 -6
- package/dist/rules/provision-exists.d.ts.map +0 -1
- package/dist/rules/provision-exists.js +0 -90
- package/dist/rules/provision-exists.js.map +0 -1
- package/dist/rules/scan.d.ts +0 -8
- package/dist/rules/scan.d.ts.map +0 -1
- package/dist/rules/scan.js +0 -32
- package/dist/rules/scan.js.map +0 -1
- package/dist/rules/service-declarations.d.ts +0 -16
- package/dist/rules/service-declarations.d.ts.map +0 -1
- package/dist/rules/service-declarations.js +0 -346
- package/dist/rules/service-declarations.js.map +0 -1
- package/dist/rules/service-exists.d.ts +0 -8
- package/dist/rules/service-exists.d.ts.map +0 -1
- package/dist/rules/service-exists.js +0 -91
- package/dist/rules/service-exists.js.map +0 -1
- package/dist/rules/specs.d.ts +0 -29
- package/dist/rules/specs.d.ts.map +0 -1
- package/dist/rules/specs.js +0 -192
- package/dist/rules/specs.js.map +0 -1
- package/dist/rules/structure.d.ts +0 -13
- package/dist/rules/structure.d.ts.map +0 -1
- package/dist/rules/structure.js +0 -142
- package/dist/rules/structure.js.map +0 -1
- package/dist/rules/types.d.ts +0 -54
- package/dist/rules/types.d.ts.map +0 -1
- package/dist/rules/types.js +0 -2
- package/dist/rules/types.js.map +0 -1
- package/dist/rules/valid-describe-refs.d.ts +0 -7
- package/dist/rules/valid-describe-refs.d.ts.map +0 -1
- package/dist/rules/valid-describe-refs.js +0 -51
- package/dist/rules/valid-describe-refs.js.map +0 -1
- package/dist/rules/valid-detour-refs.d.ts +0 -6
- package/dist/rules/valid-detour-refs.d.ts.map +0 -1
- package/dist/rules/valid-detour-refs.js +0 -117
- package/dist/rules/valid-detour-refs.js.map +0 -1
- package/dist/trails/context-no-surface-types.trail.d.ts +0 -13
- package/dist/trails/context-no-surface-types.trail.d.ts.map +0 -1
- package/dist/trails/context-no-surface-types.trail.js +0 -21
- package/dist/trails/context-no-surface-types.trail.js.map +0 -1
- package/dist/trails/context-no-trailhead-types.trail.d.ts +0 -13
- package/dist/trails/context-no-trailhead-types.trail.d.ts.map +0 -1
- package/dist/trails/context-no-trailhead-types.trail.js +0 -21
- package/dist/trails/context-no-trailhead-types.trail.js.map +0 -1
- package/dist/trails/cross-declarations.trail.d.ts +0 -13
- package/dist/trails/cross-declarations.trail.d.ts.map +0 -1
- package/dist/trails/cross-declarations.trail.js +0 -22
- package/dist/trails/cross-declarations.trail.js.map +0 -1
- package/dist/trails/follow-declarations.trail.d.ts +0 -13
- package/dist/trails/follow-declarations.trail.d.ts.map +0 -1
- package/dist/trails/follow-declarations.trail.js +0 -22
- package/dist/trails/follow-declarations.trail.js.map +0 -1
- package/dist/trails/implementation-returns-result.trail.d.ts +0 -13
- package/dist/trails/implementation-returns-result.trail.d.ts.map +0 -1
- package/dist/trails/implementation-returns-result.trail.js +0 -20
- package/dist/trails/implementation-returns-result.trail.js.map +0 -1
- package/dist/trails/index.d.ts +0 -16
- package/dist/trails/index.d.ts.map +0 -1
- package/dist/trails/index.js +0 -15
- package/dist/trails/index.js.map +0 -1
- package/dist/trails/no-direct-impl-in-route.trail.d.ts +0 -13
- package/dist/trails/no-direct-impl-in-route.trail.d.ts.map +0 -1
- package/dist/trails/no-direct-impl-in-route.trail.js +0 -22
- package/dist/trails/no-direct-impl-in-route.trail.js.map +0 -1
- package/dist/trails/no-direct-implementation-call.trail.d.ts +0 -13
- package/dist/trails/no-direct-implementation-call.trail.d.ts.map +0 -1
- package/dist/trails/no-direct-implementation-call.trail.js +0 -16
- package/dist/trails/no-direct-implementation-call.trail.js.map +0 -1
- package/dist/trails/no-sync-result-assumption.trail.d.ts +0 -13
- package/dist/trails/no-sync-result-assumption.trail.d.ts.map +0 -1
- package/dist/trails/no-sync-result-assumption.trail.js +0 -19
- package/dist/trails/no-sync-result-assumption.trail.js.map +0 -1
- package/dist/trails/no-throw-in-detour-target.trail.d.ts +0 -15
- package/dist/trails/no-throw-in-detour-target.trail.d.ts.map +0 -1
- package/dist/trails/no-throw-in-detour-target.trail.js +0 -20
- package/dist/trails/no-throw-in-detour-target.trail.js.map +0 -1
- package/dist/trails/no-throw-in-implementation.trail.d.ts +0 -13
- package/dist/trails/no-throw-in-implementation.trail.d.ts.map +0 -1
- package/dist/trails/no-throw-in-implementation.trail.js +0 -20
- package/dist/trails/no-throw-in-implementation.trail.js.map +0 -1
- package/dist/trails/prefer-schema-inference.trail.d.ts +0 -13
- package/dist/trails/prefer-schema-inference.trail.d.ts.map +0 -1
- package/dist/trails/prefer-schema-inference.trail.js +0 -21
- package/dist/trails/prefer-schema-inference.trail.js.map +0 -1
- package/dist/trails/provision-declarations.trail.d.ts +0 -13
- package/dist/trails/provision-declarations.trail.d.ts.map +0 -1
- package/dist/trails/provision-declarations.trail.js +0 -25
- package/dist/trails/provision-declarations.trail.js.map +0 -1
- package/dist/trails/provision-exists.trail.d.ts +0 -15
- package/dist/trails/provision-exists.trail.d.ts.map +0 -1
- package/dist/trails/provision-exists.trail.js +0 -27
- package/dist/trails/provision-exists.trail.js.map +0 -1
- package/dist/trails/run.d.ts +0 -17
- package/dist/trails/run.d.ts.map +0 -1
- package/dist/trails/run.js +0 -39
- package/dist/trails/run.js.map +0 -1
- package/dist/trails/schema.d.ts +0 -53
- package/dist/trails/schema.d.ts.map +0 -1
- package/dist/trails/schema.js +0 -42
- package/dist/trails/schema.js.map +0 -1
- package/dist/trails/service-declarations.trail.d.ts +0 -26
- package/dist/trails/service-declarations.trail.d.ts.map +0 -1
- package/dist/trails/service-declarations.trail.js +0 -27
- package/dist/trails/service-declarations.trail.js.map +0 -1
- package/dist/trails/service-exists.trail.d.ts +0 -32
- package/dist/trails/service-exists.trail.d.ts.map +0 -1
- package/dist/trails/service-exists.trail.js +0 -29
- package/dist/trails/service-exists.trail.js.map +0 -1
- package/dist/trails/topo.d.ts +0 -3
- package/dist/trails/topo.d.ts.map +0 -1
- package/dist/trails/topo.js +0 -5
- package/dist/trails/topo.js.map +0 -1
- package/dist/trails/valid-describe-refs.trail.d.ts +0 -15
- package/dist/trails/valid-describe-refs.trail.d.ts.map +0 -1
- package/dist/trails/valid-describe-refs.trail.js +0 -18
- package/dist/trails/valid-describe-refs.trail.js.map +0 -1
- package/dist/trails/valid-detour-refs.trail.d.ts +0 -15
- package/dist/trails/valid-detour-refs.trail.d.ts.map +0 -1
- package/dist/trails/valid-detour-refs.trail.js +0 -24
- package/dist/trails/valid-detour-refs.trail.js.map +0 -1
- package/dist/trails/wrap-rule.d.ts +0 -29
- package/dist/trails/wrap-rule.d.ts.map +0 -1
- package/dist/trails/wrap-rule.js +0 -47
- package/dist/trails/wrap-rule.js.map +0 -1
- package/src/__tests__/cli.test.ts +0 -311
- package/src/__tests__/cross-declarations.test.ts +0 -303
- package/src/__tests__/drift.test.ts +0 -144
- package/src/__tests__/formatters.test.ts +0 -157
- package/src/__tests__/implementation-returns-result.test.ts +0 -129
- package/src/__tests__/no-direct-implementation-call.test.ts +0 -83
- package/src/__tests__/no-sync-result-assumption.test.ts +0 -85
- package/src/__tests__/no-throw-in-detour-target.test.ts +0 -78
- package/src/__tests__/prefer-schema-inference.test.ts +0 -84
- package/src/__tests__/provision-declarations.test.ts +0 -318
- package/src/__tests__/provision-exists.test.ts +0 -122
- package/src/__tests__/rules.test.ts +0 -227
- package/src/__tests__/trails.test.ts +0 -19
- package/src/__tests__/valid-describe-refs.test.ts +0 -60
- package/src/__tests__/wrap-rule.test.ts +0 -41
- package/src/rules/no-direct-impl-in-route.ts +0 -81
- package/src/rules/no-throw-in-detour-target.ts +0 -150
- package/src/rules/valid-detour-refs.ts +0 -189
- package/src/trails/no-direct-impl-in-route.trail.ts +0 -22
- package/src/trails/no-throw-in-detour-target.trail.ts +0 -20
- package/src/trails/valid-detour-refs.trail.ts +0 -24
- package/tsconfig.json +0 -9
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validates that `ctx.cross()` calls match the declared `crosses` array.
|
|
3
|
-
*
|
|
4
|
-
* Statically analyzes trail `blaze` functions to find `ctx.cross('trailId', ...)`
|
|
5
|
-
* calls and compares them against the `crosses: [...]` declaration in the trail
|
|
6
|
-
* config. Reports errors for undeclared crossings and warnings for unused ones.
|
|
7
|
-
*/
|
|
8
|
-
import { findConfigProperty, findBlazeBodies, findTrailDefinitions, offsetToLine, parse, walk, } from './ast.js';
|
|
9
|
-
import { isTestFile } from './scan.js';
|
|
10
|
-
// ---------------------------------------------------------------------------
|
|
11
|
-
// Shared identifier helpers
|
|
12
|
-
// ---------------------------------------------------------------------------
|
|
13
|
-
/** Get the name of an Identifier node, or null. */
|
|
14
|
-
const identifierName = (node) => {
|
|
15
|
-
if (node?.type !== 'Identifier') {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
return node.name ?? null;
|
|
19
|
-
};
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
// String literal helpers
|
|
22
|
-
// ---------------------------------------------------------------------------
|
|
23
|
-
/** Check if a node is a string literal (covers `StringLiteral` and `Literal` with string value). */
|
|
24
|
-
const isStringLiteral = (node) => {
|
|
25
|
-
if (node.type === 'StringLiteral') {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
if (node.type === 'Literal') {
|
|
29
|
-
return typeof node.value === 'string';
|
|
30
|
-
}
|
|
31
|
-
return false;
|
|
32
|
-
};
|
|
33
|
-
/** Extract the string value from a string literal node. */
|
|
34
|
-
const getStringValue = (node) => {
|
|
35
|
-
const val = node.value;
|
|
36
|
-
return typeof val === 'string' ? val : null;
|
|
37
|
-
};
|
|
38
|
-
// ---------------------------------------------------------------------------
|
|
39
|
-
// Const identifier resolution
|
|
40
|
-
// ---------------------------------------------------------------------------
|
|
41
|
-
/**
|
|
42
|
-
* Best-effort resolution of `const NAME = 'value'` declarations via regex.
|
|
43
|
-
*
|
|
44
|
-
* Returns the string value if a simple `const <name> = '...'` or `"..."` is
|
|
45
|
-
* found in the source. Returns null for anything more complex.
|
|
46
|
-
*/
|
|
47
|
-
const resolveConstString = (name, sourceCode) => {
|
|
48
|
-
const pattern = new RegExp(`const\\s+${name}\\s*=\\s*(?:'([^']*)'|"([^"]*)")`);
|
|
49
|
-
const match = pattern.exec(sourceCode);
|
|
50
|
-
if (!match) {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
return match[1] ?? match[2] ?? null;
|
|
54
|
-
};
|
|
55
|
-
/** Try to resolve an Identifier element to a string via const declaration. */
|
|
56
|
-
const resolveIdentifierElement = (el, sourceCode) => {
|
|
57
|
-
const name = identifierName(el);
|
|
58
|
-
if (!name) {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
return resolveConstString(name, sourceCode);
|
|
62
|
-
};
|
|
63
|
-
/** Resolve an array element to a static trail ID when possible. */
|
|
64
|
-
const resolveCrossElementId = (element, sourceCode) => {
|
|
65
|
-
if (isStringLiteral(element)) {
|
|
66
|
-
return getStringValue(element);
|
|
67
|
-
}
|
|
68
|
-
if (element.type === 'Identifier') {
|
|
69
|
-
return resolveIdentifierElement(element, sourceCode);
|
|
70
|
-
}
|
|
71
|
-
return null;
|
|
72
|
-
};
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
// Declared crossing extraction
|
|
75
|
-
// ---------------------------------------------------------------------------
|
|
76
|
-
/** Extract the ArrayExpression elements from a config's `crosses` property. */
|
|
77
|
-
const getCrossElements = (config) => {
|
|
78
|
-
const crossesProp = findConfigProperty(config, 'crosses');
|
|
79
|
-
if (!crossesProp) {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
const arrayNode = crossesProp.value;
|
|
83
|
-
if (!arrayNode || arrayNode.type !== 'ArrayExpression') {
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
const elements = arrayNode['elements'];
|
|
87
|
-
return elements ?? null;
|
|
88
|
-
};
|
|
89
|
-
/** Collect string IDs from array elements, resolving identifiers when possible. */
|
|
90
|
-
const collectStringIds = (elements, sourceCode) => {
|
|
91
|
-
const ids = new Set();
|
|
92
|
-
for (const element of elements) {
|
|
93
|
-
const resolved = resolveCrossElementId(element, sourceCode);
|
|
94
|
-
if (resolved) {
|
|
95
|
-
ids.add(resolved);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return ids;
|
|
99
|
-
};
|
|
100
|
-
/** Extract string literal elements from a `crosses: [...]` array property. */
|
|
101
|
-
const extractDeclaredCrosses = (config, sourceCode) => {
|
|
102
|
-
const elements = getCrossElements(config);
|
|
103
|
-
return elements ? collectStringIds(elements, sourceCode) : new Set();
|
|
104
|
-
};
|
|
105
|
-
// ---------------------------------------------------------------------------
|
|
106
|
-
// Called crossing extraction — member expression helpers
|
|
107
|
-
// ---------------------------------------------------------------------------
|
|
108
|
-
const MEMBER_TYPES = new Set(['StaticMemberExpression', 'MemberExpression']);
|
|
109
|
-
/** Extract object and property Identifier names from a MemberExpression. */
|
|
110
|
-
const extractMemberPair = (callee) => {
|
|
111
|
-
if (!MEMBER_TYPES.has(callee.type)) {
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
const objName = identifierName(callee.object);
|
|
115
|
-
const propName = identifierName(callee.property);
|
|
116
|
-
return objName && propName ? { objName, propName } : null;
|
|
117
|
-
};
|
|
118
|
-
/** Extract the first argument string from a CallExpression's arguments list. */
|
|
119
|
-
const extractFirstStringArg = (node) => {
|
|
120
|
-
const args = node['arguments'];
|
|
121
|
-
if (!args || args.length === 0) {
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
const [firstArg] = args;
|
|
125
|
-
if (!firstArg || !isStringLiteral(firstArg)) {
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
return getStringValue(firstArg);
|
|
129
|
-
};
|
|
130
|
-
/**
|
|
131
|
-
* Extract the second parameter name from a blaze function node.
|
|
132
|
-
*
|
|
133
|
-
* Handles `(input, ctx) => ...`, `async (input, context) => ...`, and
|
|
134
|
-
* `function(input, ctx) { ... }` forms.
|
|
135
|
-
*/
|
|
136
|
-
const extractContextParamName = (blazeBody) => {
|
|
137
|
-
const params = blazeBody['params'];
|
|
138
|
-
if (!params || params.length < 2) {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
return identifierName(params[1]);
|
|
142
|
-
};
|
|
143
|
-
/** Check if a callee is a member-style cross call: <ctxName>.cross(...). */
|
|
144
|
-
const isMemberCrossCall = (callee, ctxNames) => {
|
|
145
|
-
const pair = extractMemberPair(callee);
|
|
146
|
-
return !!pair && ctxNames.has(pair.objName) && pair.propName === 'cross';
|
|
147
|
-
};
|
|
148
|
-
/**
|
|
149
|
-
* Check if a node is a `<ctxName>.cross(...)` call and return the string trail ID.
|
|
150
|
-
*
|
|
151
|
-
* Also matches bare `cross(...)` calls from destructuring.
|
|
152
|
-
*/
|
|
153
|
-
const extractCrossCallId = (node, ctxNames) => {
|
|
154
|
-
if (node.type !== 'CallExpression') {
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
const callee = node['callee'];
|
|
158
|
-
if (!callee) {
|
|
159
|
-
return null;
|
|
160
|
-
}
|
|
161
|
-
if (isMemberCrossCall(callee, ctxNames)) {
|
|
162
|
-
return extractFirstStringArg(node);
|
|
163
|
-
}
|
|
164
|
-
if (identifierName(callee) === 'cross') {
|
|
165
|
-
return extractFirstStringArg(node);
|
|
166
|
-
}
|
|
167
|
-
return null;
|
|
168
|
-
};
|
|
169
|
-
/** Build the set of context parameter names to match against. */
|
|
170
|
-
const buildCtxNames = (body) => {
|
|
171
|
-
const ctxNames = new Set(['ctx', 'context']);
|
|
172
|
-
const paramName = extractContextParamName(body);
|
|
173
|
-
if (paramName) {
|
|
174
|
-
ctxNames.add(paramName);
|
|
175
|
-
}
|
|
176
|
-
return ctxNames;
|
|
177
|
-
};
|
|
178
|
-
/** Walk blaze bodies and collect all statically resolvable ctx.cross() trail IDs. */
|
|
179
|
-
const extractCalledCrosses = (config) => {
|
|
180
|
-
const ids = new Set();
|
|
181
|
-
for (const body of findBlazeBodies(config)) {
|
|
182
|
-
const ctxNames = buildCtxNames(body);
|
|
183
|
-
walk(body, (node) => {
|
|
184
|
-
const id = extractCrossCallId(node, ctxNames);
|
|
185
|
-
if (id) {
|
|
186
|
-
ids.add(id);
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
return ids;
|
|
191
|
-
};
|
|
192
|
-
// ---------------------------------------------------------------------------
|
|
193
|
-
// Diagnostic builders
|
|
194
|
-
// ---------------------------------------------------------------------------
|
|
195
|
-
const buildUndeclaredDiagnostic = (trailId, crossedId, filePath, line) => ({
|
|
196
|
-
filePath,
|
|
197
|
-
line,
|
|
198
|
-
message: `Trail "${trailId}": ctx.cross('${crossedId}') called but '${crossedId}' is not declared in crosses`,
|
|
199
|
-
rule: 'cross-declarations',
|
|
200
|
-
severity: 'error',
|
|
201
|
-
});
|
|
202
|
-
const buildUnusedDiagnostic = (trailId, crossedId, filePath, line) => ({
|
|
203
|
-
filePath,
|
|
204
|
-
line,
|
|
205
|
-
message: `Trail "${trailId}": '${crossedId}' declared in crosses but ctx.cross('${crossedId}') never called`,
|
|
206
|
-
rule: 'cross-declarations',
|
|
207
|
-
severity: 'warn',
|
|
208
|
-
});
|
|
209
|
-
// ---------------------------------------------------------------------------
|
|
210
|
-
// Comparison
|
|
211
|
-
// ---------------------------------------------------------------------------
|
|
212
|
-
/** Emit error for each called ID not present in declared set. */
|
|
213
|
-
const reportUndeclared = (called, declared, ctx, diagnostics) => {
|
|
214
|
-
for (const id of called) {
|
|
215
|
-
if (!declared.has(id)) {
|
|
216
|
-
diagnostics.push(buildUndeclaredDiagnostic(ctx.trailId, id, ctx.filePath, ctx.line));
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
/** Emit warning for each declared ID not present in called set. */
|
|
221
|
-
const reportUnused = (declared, called, ctx, diagnostics) => {
|
|
222
|
-
for (const id of declared) {
|
|
223
|
-
if (!called.has(id)) {
|
|
224
|
-
diagnostics.push(buildUnusedDiagnostic(ctx.trailId, id, ctx.filePath, ctx.line));
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
const checkTrailDefinition = (def, filePath, sourceCode, diagnostics) => {
|
|
229
|
-
const declared = extractDeclaredCrosses(def.config, sourceCode);
|
|
230
|
-
const called = extractCalledCrosses(def.config);
|
|
231
|
-
if (declared.size === 0 && called.size === 0) {
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
const line = offsetToLine(sourceCode, def.start);
|
|
235
|
-
const ctx = { filePath, line, trailId: def.id };
|
|
236
|
-
reportUndeclared(called, declared, ctx, diagnostics);
|
|
237
|
-
reportUnused(declared, called, ctx, diagnostics);
|
|
238
|
-
};
|
|
239
|
-
// ---------------------------------------------------------------------------
|
|
240
|
-
// Rule
|
|
241
|
-
// ---------------------------------------------------------------------------
|
|
242
|
-
/**
|
|
243
|
-
* Validates that `ctx.cross()` calls align with declared `crosses` arrays.
|
|
244
|
-
*/
|
|
245
|
-
export const crossDeclarations = {
|
|
246
|
-
check(sourceCode, filePath) {
|
|
247
|
-
if (isTestFile(filePath)) {
|
|
248
|
-
return [];
|
|
249
|
-
}
|
|
250
|
-
const ast = parse(filePath, sourceCode);
|
|
251
|
-
if (!ast) {
|
|
252
|
-
return [];
|
|
253
|
-
}
|
|
254
|
-
const diagnostics = [];
|
|
255
|
-
for (const def of findTrailDefinitions(ast)) {
|
|
256
|
-
checkTrailDefinition(def, filePath, sourceCode, diagnostics);
|
|
257
|
-
}
|
|
258
|
-
return diagnostics;
|
|
259
|
-
},
|
|
260
|
-
description: 'Ensure ctx.cross() calls match the declared crosses array in trail definitions.',
|
|
261
|
-
name: 'cross-declarations',
|
|
262
|
-
severity: 'error',
|
|
263
|
-
};
|
|
264
|
-
//# sourceMappingURL=cross-declarations.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cross-declarations.js","sourceRoot":"","sources":["../../src/rules/cross-declarations.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"draft-file-marking.d.ts","sourceRoot":"","sources":["../../src/rules/draft-file-marking.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAoB,UAAU,EAAE,MAAM,YAAY,CAAC;AA2F/D;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,UAa9B,CAAC"}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { isDraftId } from '@ontrails/core';
|
|
2
|
-
import { isDraftMarkedFile } from '../draft.js';
|
|
3
|
-
import { findStringLiterals, offsetToLine, parse } from './ast.js';
|
|
4
|
-
const messageForMissingMarker = (draftId) => `Draft id "${draftId}" appears in source, but the file is not draft-marked. ` +
|
|
5
|
-
'Rename it with an _draft. prefix or a .draft. trailing segment.';
|
|
6
|
-
const makeDiagnostic = (sourceCode, filePath, start, message, severity) => ({
|
|
7
|
-
filePath,
|
|
8
|
-
line: offsetToLine(sourceCode, start),
|
|
9
|
-
message,
|
|
10
|
-
rule: 'draft-file-marking',
|
|
11
|
-
severity,
|
|
12
|
-
});
|
|
13
|
-
const draftMissingMarkerDiagnostic = (sourceCode, filePath, ast) => {
|
|
14
|
-
const draftMatches = findStringLiterals(ast, (value) => isDraftId(value));
|
|
15
|
-
if (!draftMatches.length || isDraftMarkedFile(filePath)) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
const [first] = draftMatches;
|
|
19
|
-
if (!first) {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
return makeDiagnostic(sourceCode, filePath, first.start, messageForMissingMarker(first.value), 'error');
|
|
23
|
-
};
|
|
24
|
-
const draftMarkedWithoutIdsDiagnostic = (filePath, ast) => {
|
|
25
|
-
if (findStringLiterals(ast, (value) => isDraftId(value)).length > 0) {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
if (!isDraftMarkedFile(filePath)) {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
return {
|
|
32
|
-
filePath,
|
|
33
|
-
line: 1,
|
|
34
|
-
message: 'File is draft-marked but no longer contains draft ids. Remove the draft filename marker or finish the promotion cleanup.',
|
|
35
|
-
rule: 'draft-file-marking',
|
|
36
|
-
severity: 'warn',
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
const collectDraftFileMarkingDiagnostics = (sourceCode, filePath, ast) => {
|
|
40
|
-
const missingMarkerDiagnostic = draftMissingMarkerDiagnostic(sourceCode, filePath, ast);
|
|
41
|
-
if (missingMarkerDiagnostic) {
|
|
42
|
-
return [missingMarkerDiagnostic];
|
|
43
|
-
}
|
|
44
|
-
const markedWithoutIdsDiagnostic = draftMarkedWithoutIdsDiagnostic(filePath, ast);
|
|
45
|
-
if (markedWithoutIdsDiagnostic) {
|
|
46
|
-
return [markedWithoutIdsDiagnostic];
|
|
47
|
-
}
|
|
48
|
-
return [];
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
* Ensures files containing draft ids are visibly marked as draft-bearing files.
|
|
52
|
-
*/
|
|
53
|
-
export const draftFileMarking = {
|
|
54
|
-
check(sourceCode, filePath) {
|
|
55
|
-
const ast = parse(filePath, sourceCode);
|
|
56
|
-
if (!ast) {
|
|
57
|
-
return [];
|
|
58
|
-
}
|
|
59
|
-
return collectDraftFileMarkingDiagnostics(sourceCode, filePath, ast);
|
|
60
|
-
},
|
|
61
|
-
description: 'Require draft-bearing files to use _draft.* or *.draft.* filename markers.',
|
|
62
|
-
name: 'draft-file-marking',
|
|
63
|
-
severity: 'error',
|
|
64
|
-
};
|
|
65
|
-
//# sourceMappingURL=draft-file-marking.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"draft-file-marking.js","sourceRoot":"","sources":["../../src/rules/draft-file-marking.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { WardenRule } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Warns when draft ids are still present so the debt stays visible during
|
|
4
|
-
* review even when the file is correctly marked.
|
|
5
|
-
*
|
|
6
|
-
* Severity is intentionally `warn`, not `error`. The hard rejection gate for
|
|
7
|
-
* draft state leaking into established outputs is `validateEstablishedTopo` at
|
|
8
|
-
* runtime — it blocks topo export, trailhead projection, and lockfile writes.
|
|
9
|
-
* This rule surfaces the debt for human reviewers without duplicating that gate.
|
|
10
|
-
*/
|
|
11
|
-
export declare const draftVisibleDebt: WardenRule;
|
|
12
|
-
//# sourceMappingURL=draft-visible-debt.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"draft-visible-debt.d.ts","sourceRoot":"","sources":["../../src/rules/draft-visible-debt.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAoB,UAAU,EAAE,MAAM,YAAY,CAAC;AAoC/D;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,EAAE,UAa9B,CAAC"}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { isDraftId } from '@ontrails/core';
|
|
2
|
-
import { findStringLiterals, offsetToLine, parse } from './ast.js';
|
|
3
|
-
const createDiagnostic = (sourceCode, filePath, match) => ({
|
|
4
|
-
filePath,
|
|
5
|
-
line: offsetToLine(sourceCode, match.start),
|
|
6
|
-
message: `Draft id "${match.value}" is still visible debt. ` +
|
|
7
|
-
'Established trailheads, lock export, and OpenAPI generation will reject it until it is promoted.',
|
|
8
|
-
rule: 'draft-visible-debt',
|
|
9
|
-
severity: 'warn',
|
|
10
|
-
});
|
|
11
|
-
const collectDraftVisibleDebtDiagnostics = (sourceCode, filePath, ast) => {
|
|
12
|
-
const seen = new Set();
|
|
13
|
-
const diagnostics = [];
|
|
14
|
-
for (const match of findStringLiterals(ast, (value) => isDraftId(value))) {
|
|
15
|
-
const key = `${match.value}:${String(match.start)}`;
|
|
16
|
-
if (seen.has(key)) {
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
19
|
-
seen.add(key);
|
|
20
|
-
diagnostics.push(createDiagnostic(sourceCode, filePath, match));
|
|
21
|
-
}
|
|
22
|
-
return diagnostics;
|
|
23
|
-
};
|
|
24
|
-
/**
|
|
25
|
-
* Warns when draft ids are still present so the debt stays visible during
|
|
26
|
-
* review even when the file is correctly marked.
|
|
27
|
-
*
|
|
28
|
-
* Severity is intentionally `warn`, not `error`. The hard rejection gate for
|
|
29
|
-
* draft state leaking into established outputs is `validateEstablishedTopo` at
|
|
30
|
-
* runtime — it blocks topo export, trailhead projection, and lockfile writes.
|
|
31
|
-
* This rule surfaces the debt for human reviewers without duplicating that gate.
|
|
32
|
-
*/
|
|
33
|
-
export const draftVisibleDebt = {
|
|
34
|
-
check(sourceCode, filePath) {
|
|
35
|
-
const ast = parse(filePath, sourceCode);
|
|
36
|
-
if (!ast) {
|
|
37
|
-
return [];
|
|
38
|
-
}
|
|
39
|
-
return collectDraftVisibleDebtDiagnostics(sourceCode, filePath, ast);
|
|
40
|
-
},
|
|
41
|
-
description: 'Warn when draft ids remain in source so the debt stays visible during review.',
|
|
42
|
-
name: 'draft-visible-debt',
|
|
43
|
-
severity: 'warn',
|
|
44
|
-
};
|
|
45
|
-
//# sourceMappingURL=draft-visible-debt.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"draft-visible-debt.js","sourceRoot":"","sources":["../../src/rules/draft-visible-debt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAGnE,MAAM,gBAAgB,GAAG,CACvB,UAAkB,EAClB,QAAgB,EAChB,KAAuC,EACrB,EAAE,CAAC,CAAC;IACtB,QAAQ;IACR,IAAI,EAAE,YAAY,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC;IAC3C,OAAO,EACL,aAAa,KAAK,CAAC,KAAK,2BAA2B;QACnD,kGAAkG;IACpG,IAAI,EAAE,oBAAoB;IAC1B,QAAQ,EAAE,MAAM;CACjB,CAAC,CAAC;AAEH,MAAM,kCAAkC,GAAG,CACzC,UAAkB,EAClB,QAAgB,EAChB,GAA0C,EACtB,EAAE;IACtB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,WAAW,GAAuB,EAAE,CAAC;IAE3C,KAAK,MAAM,KAAK,IAAI,kBAAkB,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACpD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,KAAK,CAAC,UAAkB,EAAE,QAAgB;QACxC,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QACxC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,kCAAkC,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;IACvE,CAAC;IACD,WAAW,EACT,+EAA+E;IACjF,IAAI,EAAE,oBAAoB;IAC1B,QAAQ,EAAE,MAAM;CACjB,CAAC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validates that `ctx.follow()` calls match the declared `follow` array.
|
|
3
|
-
*
|
|
4
|
-
* Statically analyzes trail `blaze` functions to find `ctx.follow('trailId', ...)`
|
|
5
|
-
* calls and compares them against the `follow: [...]` declaration in the trail
|
|
6
|
-
* config. Reports errors for undeclared follows and warnings for unused ones.
|
|
7
|
-
*/
|
|
8
|
-
import type { WardenRule } from './types.js';
|
|
9
|
-
/**
|
|
10
|
-
* Validates that `ctx.follow()` calls align with declared `follow` arrays.
|
|
11
|
-
*/
|
|
12
|
-
export declare const followDeclarations: WardenRule;
|
|
13
|
-
//# sourceMappingURL=follow-declarations.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"follow-declarations.d.ts","sourceRoot":"","sources":["../../src/rules/follow-declarations.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,OAAO,KAAK,EAAoB,UAAU,EAAE,MAAM,YAAY,CAAC;AA+U/D;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,UAuBhC,CAAC"}
|