@ontrails/warden 1.0.0-beta.8 → 1.0.0-beta.9

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.
Files changed (91) hide show
  1. package/.turbo/turbo-lint.log +1 -1
  2. package/CHANGELOG.md +26 -0
  3. package/README.md +20 -0
  4. package/dist/index.d.ts +4 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +4 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/trails/context-no-surface-types.trail.d.ts +13 -0
  9. package/dist/trails/context-no-surface-types.trail.d.ts.map +1 -0
  10. package/dist/trails/context-no-surface-types.trail.js +21 -0
  11. package/dist/trails/context-no-surface-types.trail.js.map +1 -0
  12. package/dist/trails/follow-declarations.trail.d.ts +13 -0
  13. package/dist/trails/follow-declarations.trail.d.ts.map +1 -0
  14. package/dist/trails/follow-declarations.trail.js +22 -0
  15. package/dist/trails/follow-declarations.trail.js.map +1 -0
  16. package/dist/trails/implementation-returns-result.trail.d.ts +13 -0
  17. package/dist/trails/implementation-returns-result.trail.d.ts.map +1 -0
  18. package/dist/trails/implementation-returns-result.trail.js +20 -0
  19. package/dist/trails/implementation-returns-result.trail.js.map +1 -0
  20. package/dist/trails/index.d.ts +14 -0
  21. package/dist/trails/index.d.ts.map +1 -0
  22. package/dist/trails/index.js +13 -0
  23. package/dist/trails/index.js.map +1 -0
  24. package/dist/trails/no-direct-impl-in-route.trail.d.ts +13 -0
  25. package/dist/trails/no-direct-impl-in-route.trail.d.ts.map +1 -0
  26. package/dist/trails/no-direct-impl-in-route.trail.js +22 -0
  27. package/dist/trails/no-direct-impl-in-route.trail.js.map +1 -0
  28. package/dist/trails/no-direct-implementation-call.trail.d.ts +13 -0
  29. package/dist/trails/no-direct-implementation-call.trail.d.ts.map +1 -0
  30. package/dist/trails/no-direct-implementation-call.trail.js +16 -0
  31. package/dist/trails/no-direct-implementation-call.trail.js.map +1 -0
  32. package/dist/trails/no-sync-result-assumption.trail.d.ts +13 -0
  33. package/dist/trails/no-sync-result-assumption.trail.d.ts.map +1 -0
  34. package/dist/trails/no-sync-result-assumption.trail.js +19 -0
  35. package/dist/trails/no-sync-result-assumption.trail.js.map +1 -0
  36. package/dist/trails/no-throw-in-detour-target.trail.d.ts +14 -0
  37. package/dist/trails/no-throw-in-detour-target.trail.d.ts.map +1 -0
  38. package/dist/trails/no-throw-in-detour-target.trail.js +20 -0
  39. package/dist/trails/no-throw-in-detour-target.trail.js.map +1 -0
  40. package/dist/trails/no-throw-in-implementation.trail.d.ts +13 -0
  41. package/dist/trails/no-throw-in-implementation.trail.d.ts.map +1 -0
  42. package/dist/trails/no-throw-in-implementation.trail.js +20 -0
  43. package/dist/trails/no-throw-in-implementation.trail.js.map +1 -0
  44. package/dist/trails/prefer-schema-inference.trail.d.ts +13 -0
  45. package/dist/trails/prefer-schema-inference.trail.d.ts.map +1 -0
  46. package/dist/trails/prefer-schema-inference.trail.js +21 -0
  47. package/dist/trails/prefer-schema-inference.trail.js.map +1 -0
  48. package/dist/trails/run.d.ts +16 -0
  49. package/dist/trails/run.d.ts.map +1 -0
  50. package/dist/trails/run.js +30 -0
  51. package/dist/trails/run.js.map +1 -0
  52. package/dist/trails/schema.d.ts +52 -0
  53. package/dist/trails/schema.d.ts.map +1 -0
  54. package/dist/trails/schema.js +38 -0
  55. package/dist/trails/schema.js.map +1 -0
  56. package/dist/trails/topo.d.ts +3 -0
  57. package/dist/trails/topo.d.ts.map +1 -0
  58. package/dist/trails/topo.js +5 -0
  59. package/dist/trails/topo.js.map +1 -0
  60. package/dist/trails/valid-describe-refs.trail.d.ts +14 -0
  61. package/dist/trails/valid-describe-refs.trail.d.ts.map +1 -0
  62. package/dist/trails/valid-describe-refs.trail.js +18 -0
  63. package/dist/trails/valid-describe-refs.trail.js.map +1 -0
  64. package/dist/trails/valid-detour-refs.trail.d.ts +14 -0
  65. package/dist/trails/valid-detour-refs.trail.d.ts.map +1 -0
  66. package/dist/trails/valid-detour-refs.trail.js +24 -0
  67. package/dist/trails/valid-detour-refs.trail.js.map +1 -0
  68. package/dist/trails/wrap-rule.d.ts +29 -0
  69. package/dist/trails/wrap-rule.d.ts.map +1 -0
  70. package/dist/trails/wrap-rule.js +43 -0
  71. package/dist/trails/wrap-rule.js.map +1 -0
  72. package/package.json +4 -3
  73. package/src/__tests__/trails.test.ts +19 -0
  74. package/src/index.ts +21 -0
  75. package/src/trails/context-no-surface-types.trail.ts +21 -0
  76. package/src/trails/follow-declarations.trail.ts +22 -0
  77. package/src/trails/implementation-returns-result.trail.ts +20 -0
  78. package/src/trails/index.ts +14 -0
  79. package/src/trails/no-direct-impl-in-route.trail.ts +22 -0
  80. package/src/trails/no-direct-implementation-call.trail.ts +16 -0
  81. package/src/trails/no-sync-result-assumption.trail.ts +19 -0
  82. package/src/trails/no-throw-in-detour-target.trail.ts +20 -0
  83. package/src/trails/no-throw-in-implementation.trail.ts +20 -0
  84. package/src/trails/prefer-schema-inference.trail.ts +21 -0
  85. package/src/trails/run.ts +40 -0
  86. package/src/trails/schema.ts +46 -0
  87. package/src/trails/topo.ts +6 -0
  88. package/src/trails/valid-describe-refs.trail.ts +18 -0
  89. package/src/trails/valid-detour-refs.trail.ts +24 -0
  90. package/src/trails/wrap-rule.ts +84 -0
  91. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Shared Zod schemas for warden rule trails.
3
+ *
4
+ * Every rule trail shares the same input (source file) and output
5
+ * (array of diagnostics) shape.
6
+ */
7
+
8
+ import { z } from 'zod';
9
+
10
+ /** A single diagnostic emitted by a warden rule trail. */
11
+ export const diagnosticSchema = z.object({
12
+ filePath: z.string().describe('File path that was analyzed'),
13
+ line: z.number().describe('1-based line number'),
14
+ message: z.string().describe('Human-readable diagnostic message'),
15
+ rule: z.string().describe('Rule name'),
16
+ severity: z.enum(['error', 'warn']).describe('Diagnostic severity'),
17
+ });
18
+
19
+ /** Input accepted by every warden rule trail. */
20
+ export const ruleInput = z.object({
21
+ filePath: z.string().describe('Path to the source file'),
22
+ sourceCode: z.string().describe('Source code content'),
23
+ });
24
+
25
+ /**
26
+ * Extended input for project-aware warden rule trails.
27
+ *
28
+ * Adds `knownTrailIds` so the caller can supply cross-file context and avoid
29
+ * false positives for detour targets or `@see` references defined in other
30
+ * files.
31
+ */
32
+ export const projectAwareRuleInput = ruleInput.extend({
33
+ knownTrailIds: z
34
+ .array(z.string())
35
+ .optional()
36
+ .describe('Trail IDs known across the project'),
37
+ });
38
+
39
+ /** Output returned by every warden rule trail. */
40
+ export const ruleOutput = z.object({
41
+ diagnostics: z.array(diagnosticSchema).describe('Diagnostics found'),
42
+ });
43
+
44
+ export type RuleInput = z.infer<typeof ruleInput>;
45
+ export type ProjectAwareRuleInput = z.infer<typeof projectAwareRuleInput>;
46
+ export type RuleOutput = z.infer<typeof ruleOutput>;
@@ -0,0 +1,6 @@
1
+ import { topo } from '@ontrails/core';
2
+
3
+ import * as rules from './index.js';
4
+
5
+ /** Topo collecting all warden rule trails. */
6
+ export const wardenTopo = topo('warden', rules);
@@ -0,0 +1,18 @@
1
+ import { validDescribeRefs } from '../rules/valid-describe-refs.js';
2
+ import { wrapRule } from './wrap-rule.js';
3
+
4
+ export const validDescribeRefsTrail = wrapRule({
5
+ examples: [
6
+ {
7
+ expected: { diagnostics: [] },
8
+ input: {
9
+ filePath: 'clean.ts',
10
+ sourceCode: `const schema = z.object({
11
+ name: z.string().describe("User display name"),
12
+ });`,
13
+ },
14
+ name: 'Describe without @see refs',
15
+ },
16
+ ],
17
+ rule: validDescribeRefs,
18
+ });
@@ -0,0 +1,24 @@
1
+ import { validDetourRefs } from '../rules/valid-detour-refs.js';
2
+ import { wrapRule } from './wrap-rule.js';
3
+
4
+ export const validDetourRefsTrail = wrapRule({
5
+ examples: [
6
+ {
7
+ expected: { diagnostics: [] },
8
+ input: {
9
+ filePath: 'clean.ts',
10
+ knownTrailIds: ['entity.fallback', 'entity.show'],
11
+ sourceCode: `trail("entity.fallback", {
12
+ run: async (input, ctx) => Result.ok(data)
13
+ })
14
+
15
+ trail("entity.show", {
16
+ detours: [{ target: "entity.fallback" }],
17
+ run: async (input, ctx) => Result.ok(data)
18
+ })`,
19
+ },
20
+ name: 'Valid detour target reference',
21
+ },
22
+ ],
23
+ rule: validDetourRefs,
24
+ });
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Factory that wraps a WardenRule as a trail.
3
+ *
4
+ * Keeps each rule trail file minimal — just the import + examples.
5
+ */
6
+
7
+ import { trail, Result } from '@ontrails/core';
8
+ import type { Trail } from '@ontrails/core';
9
+
10
+ import type { ProjectAwareWardenRule, WardenRule } from '../rules/types.js';
11
+ import { projectAwareRuleInput, ruleInput, ruleOutput } from './schema.js';
12
+ import type { ProjectAwareRuleInput, RuleInput, RuleOutput } from './schema.js';
13
+
14
+ interface WrapRuleOptions {
15
+ /** The existing warden rule to wrap. */
16
+ readonly rule: WardenRule;
17
+ /** Trail examples for testing and documentation. */
18
+ readonly examples: Trail<RuleInput, RuleOutput>['examples'];
19
+ }
20
+
21
+ interface WrapProjectAwareRuleOptions {
22
+ /** The existing project-aware warden rule to wrap. */
23
+ readonly rule: ProjectAwareWardenRule;
24
+ /** Trail examples for testing and documentation. */
25
+ readonly examples: Trail<ProjectAwareRuleInput, RuleOutput>['examples'];
26
+ }
27
+
28
+ /**
29
+ * Wrap an existing `WardenRule` as a trail with typed input/output.
30
+ *
31
+ * The trail ID follows the pattern `warden.rule.<rule-name>`.
32
+ */
33
+ export function wrapRule(
34
+ options: WrapProjectAwareRuleOptions
35
+ ): Trail<ProjectAwareRuleInput, RuleOutput>;
36
+ export function wrapRule(
37
+ options: WrapRuleOptions
38
+ ): Trail<RuleInput, RuleOutput>;
39
+ export function wrapRule(
40
+ options: WrapRuleOptions | WrapProjectAwareRuleOptions
41
+ ): Trail<RuleInput, RuleOutput> | Trail<ProjectAwareRuleInput, RuleOutput> {
42
+ const { rule, examples } = options;
43
+ const isProjectAware = 'checkWithContext' in rule;
44
+
45
+ if (isProjectAware) {
46
+ const projectAwareRule = rule as ProjectAwareWardenRule;
47
+ return trail(`warden.rule.${rule.name}`, {
48
+ description: rule.description,
49
+ examples: examples as Trail<
50
+ ProjectAwareRuleInput,
51
+ RuleOutput
52
+ >['examples'],
53
+ input: projectAwareRuleInput,
54
+ intent: 'read',
55
+ metadata: { category: 'governance', severity: rule.severity },
56
+ output: ruleOutput,
57
+ run: (input: ProjectAwareRuleInput) => {
58
+ const diagnostics = projectAwareRule.checkWithContext(
59
+ input.sourceCode,
60
+ input.filePath,
61
+ {
62
+ knownTrailIds: input.knownTrailIds
63
+ ? new Set(input.knownTrailIds)
64
+ : new Set<string>(),
65
+ }
66
+ );
67
+ return Result.ok({ diagnostics: [...diagnostics] });
68
+ },
69
+ });
70
+ }
71
+
72
+ return trail(`warden.rule.${rule.name}`, {
73
+ description: rule.description,
74
+ examples: examples as Trail<RuleInput, RuleOutput>['examples'],
75
+ input: ruleInput,
76
+ intent: 'read',
77
+ metadata: { category: 'governance', severity: rule.severity },
78
+ output: ruleOutput,
79
+ run: (input: RuleInput) => {
80
+ const diagnostics = rule.check(input.sourceCode, input.filePath);
81
+ return Result.ok({ diagnostics: [...diagnostics] });
82
+ },
83
+ });
84
+ }
@@ -1 +1 @@
1
- {"root":["./src/cli.ts","./src/drift.ts","./src/formatters.ts","./src/index.ts","./src/rules/ast.ts","./src/rules/context-no-surface-types.ts","./src/rules/follow-declarations.ts","./src/rules/implementation-returns-result.ts","./src/rules/index.ts","./src/rules/no-direct-impl-in-route.ts","./src/rules/no-direct-implementation-call.ts","./src/rules/no-sync-result-assumption.ts","./src/rules/no-throw-in-detour-target.ts","./src/rules/no-throw-in-implementation.ts","./src/rules/prefer-schema-inference.ts","./src/rules/scan.ts","./src/rules/specs.ts","./src/rules/structure.ts","./src/rules/types.ts","./src/rules/valid-describe-refs.ts","./src/rules/valid-detour-refs.ts"],"version":"5.9.3"}
1
+ {"root":["./src/cli.ts","./src/drift.ts","./src/formatters.ts","./src/index.ts","./src/rules/ast.ts","./src/rules/context-no-surface-types.ts","./src/rules/follow-declarations.ts","./src/rules/implementation-returns-result.ts","./src/rules/index.ts","./src/rules/no-direct-impl-in-route.ts","./src/rules/no-direct-implementation-call.ts","./src/rules/no-sync-result-assumption.ts","./src/rules/no-throw-in-detour-target.ts","./src/rules/no-throw-in-implementation.ts","./src/rules/prefer-schema-inference.ts","./src/rules/scan.ts","./src/rules/specs.ts","./src/rules/structure.ts","./src/rules/types.ts","./src/rules/valid-describe-refs.ts","./src/rules/valid-detour-refs.ts","./src/trails/context-no-surface-types.trail.ts","./src/trails/follow-declarations.trail.ts","./src/trails/implementation-returns-result.trail.ts","./src/trails/index.ts","./src/trails/no-direct-impl-in-route.trail.ts","./src/trails/no-direct-implementation-call.trail.ts","./src/trails/no-sync-result-assumption.trail.ts","./src/trails/no-throw-in-detour-target.trail.ts","./src/trails/no-throw-in-implementation.trail.ts","./src/trails/prefer-schema-inference.trail.ts","./src/trails/run.ts","./src/trails/schema.ts","./src/trails/topo.ts","./src/trails/valid-describe-refs.trail.ts","./src/trails/valid-detour-refs.trail.ts","./src/trails/wrap-rule.ts"],"version":"5.9.3"}