@vantageos/backend-doctor 0.1.14 → 0.3.0

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 (93) hide show
  1. package/README.md +66 -5
  2. package/dist/args.d.ts +16 -0
  3. package/dist/args.js +72 -0
  4. package/dist/build-stamp.d.ts +13 -0
  5. package/dist/build-stamp.js +76 -0
  6. package/dist/build-stamp.json +4 -0
  7. package/dist/caller-resolution.d.ts +222 -0
  8. package/dist/caller-resolution.js +1198 -0
  9. package/dist/cli.js +249 -17
  10. package/dist/contract.d.ts +25 -7
  11. package/dist/contract.js +52 -7
  12. package/dist/coverage-cli.js +8 -0
  13. package/dist/coverage.d.ts +1 -1
  14. package/dist/coverage.js +2 -2
  15. package/dist/detectors/oracle-axis1.d.ts +5 -3
  16. package/dist/detectors/oracle-axis1.js +28 -18
  17. package/dist/detectors/oracle-axis2.d.ts +6 -0
  18. package/dist/detectors/oracle-axis2.js +37 -22
  19. package/dist/detectors/predicates.d.ts +3 -0
  20. package/dist/detectors/predicates.js +93 -19
  21. package/dist/detectors/shared.js +8 -7
  22. package/dist/detectors/source/_ast.d.ts +92 -0
  23. package/dist/detectors/source/_ast.js +353 -0
  24. package/dist/detectors/source/_scan.js +4 -3
  25. package/dist/detectors/source/backfill.js +71 -18
  26. package/dist/detectors/source/contract.js +21 -13
  27. package/dist/detectors/source/cross-tenant-write.d.ts +46 -0
  28. package/dist/detectors/source/cross-tenant-write.js +1408 -0
  29. package/dist/detectors/source/guard-helper-flow.d.ts +134 -0
  30. package/dist/detectors/source/guard-helper-flow.js +1216 -0
  31. package/dist/detectors/source/identity-by-id.d.ts +80 -0
  32. package/dist/detectors/source/identity-by-id.js +1783 -0
  33. package/dist/detectors/source/identity.d.ts +58 -2
  34. package/dist/detectors/source/identity.js +1158 -28
  35. package/dist/detectors/source/isolation.d.ts +11 -1
  36. package/dist/detectors/source/isolation.js +106 -25
  37. package/dist/detectors/source/jobs.js +178 -4
  38. package/dist/detectors/source/lifecycle.js +14 -2
  39. package/dist/detectors/source/local-identity.d.ts +26 -0
  40. package/dist/detectors/source/local-identity.js +661 -0
  41. package/dist/detectors/source/package-principal.d.ts +9 -0
  42. package/dist/detectors/source/package-principal.js +177 -0
  43. package/dist/detectors/source/r6-shapes.d.ts +20 -0
  44. package/dist/detectors/source/r6-shapes.js +285 -0
  45. package/dist/detectors/source/readbudget.d.ts +1 -0
  46. package/dist/detectors/source/readbudget.js +358 -4
  47. package/dist/detectors/source/recipient-by-id.d.ts +40 -0
  48. package/dist/detectors/source/recipient-by-id.js +1108 -0
  49. package/dist/detectors/source/refusal.d.ts +14 -0
  50. package/dist/detectors/source/refusal.js +75 -2
  51. package/dist/detectors/source/security.d.ts +16 -0
  52. package/dist/detectors/source/security.js +680 -33
  53. package/dist/detectors/source/write-isolation.d.ts +8 -1
  54. package/dist/detectors/source/write-isolation.js +64 -30
  55. package/dist/detectors/source/writesafety.js +27 -14
  56. package/dist/detectors/standard/_doc.d.ts +1 -1
  57. package/dist/detectors/standard/_doc.js +5 -4
  58. package/dist/detectors/standard/r41-frontier.js +3 -2
  59. package/dist/detectors/standard/r46-returns-validator.d.ts +8 -0
  60. package/dist/detectors/standard/r46-returns-validator.js +48 -16
  61. package/dist/detectors/structural.d.ts +6 -7
  62. package/dist/detectors/structural.js +84 -48
  63. package/dist/not-checkable.d.ts +1 -1
  64. package/dist/not-checkable.js +11 -0
  65. package/dist/oracle.d.ts +92 -3
  66. package/dist/oracle.js +229 -12
  67. package/dist/registry.d.ts +8 -1
  68. package/dist/registry.js +74 -8
  69. package/dist/report.d.ts +11 -1
  70. package/dist/report.js +15 -2
  71. package/dist/rule-class.d.ts +85 -0
  72. package/dist/rule-class.js +218 -0
  73. package/dist/state-rank.d.ts +5 -0
  74. package/dist/state-rank.js +9 -0
  75. package/dist/tally.d.ts +13 -5
  76. package/dist/tally.js +15 -13
  77. package/dist/target.d.ts +32 -0
  78. package/dist/target.js +173 -0
  79. package/dist/violation-count.d.ts +48 -0
  80. package/dist/violation-count.js +94 -0
  81. package/fixtures/backend-standard-2825122.md +722 -0
  82. package/fixtures/backend-standard-4dcd3e0.md +722 -0
  83. package/fixtures/cr1-classes/_generated/api.d.ts +24 -0
  84. package/fixtures/cr1-classes/surface.ts +206 -0
  85. package/fixtures/cr1-empty/nothing.ts +1 -0
  86. package/fixtures/cr1-refusal-on-resolved/_generated/api.d.ts +24 -0
  87. package/fixtures/cr1-refusal-on-resolved/doors.ts +180 -0
  88. package/fixtures/cr1-refusal-on-resolved/lib/auth.ts +104 -0
  89. package/fixtures/r34-vp-auth-30e821b/auth-805-812.ts.txt +8 -0
  90. package/fixtures/r34-vp-auth-30e821b/auth-878-890.ts.txt +13 -0
  91. package/fixtures/rule-classes-2825122.json +228 -0
  92. package/fixtures/vp-writer-tier-1e4ab36.csv +55 -0
  93. package/package.json +2 -2
@@ -0,0 +1,134 @@
1
+ import * as ts from "typescript";
2
+ export type GuardHelperKind = "binds-arg" | "master-only";
3
+ export type HelperVerdict = {
4
+ verdict: "honoured";
5
+ } | {
6
+ verdict: "refused";
7
+ why: string;
8
+ } | {
9
+ verdict: "could-not-judge";
10
+ why: string;
11
+ };
12
+ /**
13
+ * SCOPE REFINERS, by name: a call `await R(ctx, <scope>, …)` whose result is
14
+ * scope-derived exactly when the scope it is handed (at `argIndex`) is. The
15
+ * refiner returns that scope unchanged, or rebuilds it from a SERVER-SIDE row
16
+ * after refusing every transport but the fleet service account — vantage-peers
17
+ * `convex/lib/personPrincipal.ts::resolveVerifiedPerson` (the `verifiedPerson`
18
+ * proof is believed from the service account only and the person's scope is
19
+ * re-read from `oauth_access_tokens`). The other arguments it is handed (a
20
+ * proof, a door name, an asserted name) never become its return.
21
+ *
22
+ * Trusted by NAME, on the same footing as `withOrgScope` in isIdentityRead: the
23
+ * flow walk cannot model "a scope rebuilt from a stored row" as the identity.
24
+ * The trust is narrow — the result is pure only when the scope argument itself
25
+ * is pure; a refiner handed anything else confers nothing.
26
+ */
27
+ export declare const SCOPE_REFINERS: Readonly<Record<string, {
28
+ argIndex: number;
29
+ }>>;
30
+ /** A callee name, as seen from the function being judged, resolved to its
31
+ * definition in the tree (and to a resolver for names seen from THAT file). */
32
+ export type CallResolver = (name: string) => {
33
+ fn: ts.FunctionLikeDeclaration;
34
+ key: string;
35
+ resolve: CallResolver;
36
+ } | undefined;
37
+ /** Judge one helper function on its control flow. */
38
+ export declare function judgeHelperFunction(fn: ts.FunctionLikeDeclaration, kind: GuardHelperKind): HelperVerdict;
39
+ export interface FoundHelper {
40
+ name: string;
41
+ line: number;
42
+ exported: boolean;
43
+ judgement: HelperVerdict;
44
+ }
45
+ /** Every definition, in `source`, of a helper named in `kinds`. */
46
+ export declare function findHelperDefinitions(fileName: string, source: string, kinds: Readonly<Record<string, GuardHelperKind>>): FoundHelper[];
47
+ /** The arguments of each `await <helper>(…)` that is a DIRECT statement of the
48
+ * handler `name` (`export const name = mutation({ handler: … })`) and starts
49
+ * before `beforeLine`. A helper call nested in a branch, a try, or a closure of
50
+ * the handler is not a statement every path runs, so it is not returned.
51
+ * `null` = the handler's body could not be located in the file. */
52
+ export declare function topLevelHelperCalls(fileName: string, source: string, handlerName: string,
53
+ /** `null` = any identifier callee (judged by the caller on its body). */
54
+ helpers: ReadonlySet<string> | null, beforeLine: number): {
55
+ name: string;
56
+ args: string;
57
+ argNodes: readonly ts.Expression[];
58
+ line: number;
59
+ }[] | null;
60
+ export interface TopLevelFunction {
61
+ name: string;
62
+ line: number;
63
+ exported: boolean;
64
+ fn: ts.FunctionLikeDeclaration;
65
+ }
66
+ /** Every top-level function declaration and `const f = (…) => {…}` /
67
+ * `function (…) {…}` of a file. */
68
+ export declare function topLevelFunctions(fileName: string, source: string): TopLevelFunction[];
69
+ /** Judge a function as an IDENTITY RESOLVER (shape 1 above). */
70
+ export declare function judgeResolverFunction(fn: ts.FunctionLikeDeclaration): HelperVerdict;
71
+ export type ValidatorSummary = {
72
+ ok: false;
73
+ why: string;
74
+ } | {
75
+ ok: true;
76
+ /** every normal exit binds the target parameter (or is the master's) */
77
+ exitsBound: boolean;
78
+ /** every normal exit is the fleet master's */
79
+ exitsMaster: boolean;
80
+ /** no normal exit at all: it refuses every caller */
81
+ never: boolean;
82
+ };
83
+ export declare function summarizeValidator(fn: ts.FunctionLikeDeclaration, o: {
84
+ /** the parameter whose binding is asked; undefined = master-only asked */
85
+ boundIdx: number | undefined;
86
+ /** the parameter receiving the caller's verified scope, if any */
87
+ identityIdx: number | undefined;
88
+ /** the call's arguments (object literals become constants) */
89
+ callArgs: readonly ts.Expression[];
90
+ resolve: CallResolver;
91
+ key: string;
92
+ depth: number;
93
+ }): ValidatorSummary;
94
+ /** Judge a function as a REFUSING PREDICATE (shape 2 above): parameter
95
+ * `identityIdx` receives the caller's verified scope, `boundIdx` the value the
96
+ * caller then writes. */
97
+ export declare function judgePredicateFunction(fn: ts.FunctionLikeDeclaration, identityIdx: number, boundIdx: number): HelperVerdict;
98
+ /** What a mutation handler's own body declares and refuses before `beforeLine`. */
99
+ export interface HandlerGuards {
100
+ /** Top-level `const` locals: whether bound straight to an identity read, or
101
+ * to `await <callee>(…)` (the callee is then judged by the caller). */
102
+ consts: Map<string, {
103
+ identityRead: boolean;
104
+ awaitedCallee?: string;
105
+ }>;
106
+ /** `if (!P(a, b, …)) { …throw }` statements: the predicate and its args. */
107
+ refusals: {
108
+ predicate: string;
109
+ args: {
110
+ text: string;
111
+ ident?: string;
112
+ memberBase?: string;
113
+ }[];
114
+ line: number;
115
+ }[];
116
+ }
117
+ /** The block body of the `handler` of `const <handlerName> = <builder>({ … })`
118
+ * at the top level of `sf` (arrow, function expression or method); undefined
119
+ * when it cannot be located. */
120
+ export declare function handlerBodyOf(sf: ts.SourceFile, handlerName: string): ts.Block | undefined;
121
+ /** Read the direct statements of handler `name` before `beforeLine`. `null`
122
+ * when the handler's body cannot be located. */
123
+ export declare function readHandlerGuards(fileName: string, source: string, handlerName: string, beforeLine: number): HandlerGuards | null;
124
+ /** A CONDITIONAL boundary value at a write site (`orgId: c ? a : b`): which arm
125
+ * reads the caller's `args`, and whether the condition is a positive
126
+ * `<local>.isMaster` test (the fleet carve-out, which may write what the
127
+ * master names). Read with the TypeScript parser on the write-site text. */
128
+ export interface ConditionalBoundary {
129
+ field: string;
130
+ masterBase?: string;
131
+ trueReadsArgs: boolean;
132
+ falseReadsArgs: boolean;
133
+ }
134
+ export declare function conditionalBoundaries(text: string, fields: ReadonlySet<string>): ConditionalBoundary[];