@lunora/advisor 1.0.0-alpha.54 → 1.0.0-alpha.56
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/README.md +53 -0
- package/dist/index.d.mts +397 -61
- package/dist/index.d.ts +397 -61
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/MAP_VERSION-BS08jBkS.mjs +1 -0
- package/dist/packem_shared/actionWithoutErrorHandling-D1DqSPpg.mjs +1 -0
- package/dist/packem_shared/aiRunWithoutLogging-CMvQPNBr.mjs +1 -0
- package/dist/packem_shared/classifySensitivity-DjswRYWd.mjs +1 -0
- package/dist/packem_shared/compareToBaseline-T1_kl8VY.mjs +1 -0
- package/dist/packem_shared/errorWithoutCatalog-DTDVKU4b.mjs +1 -0
- package/dist/packem_shared/{filterWithoutIndex-ht2GZQWV.mjs → filterWithoutIndex-yd1N-GQ0.mjs} +1 -1
- package/dist/packem_shared/gradeFromScore-DW82YDVY.mjs +1 -0
- package/dist/packem_shared/procedureWithoutStructuredEvent-D4Qi2vH7.mjs +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -93,6 +93,59 @@ const findings = runAdvisor({ schema: fromServerSchema(schema), ...metrics }, {
|
|
|
93
93
|
|
|
94
94
|
A missing metric degrades to an empty array rather than throwing, so a partially configured read path still returns what it can.
|
|
95
95
|
|
|
96
|
+
### Observability map (score, coverage, baseline)
|
|
97
|
+
|
|
98
|
+
`runAdvisor` answers "what is wrong?". `scoreAdvisor` answers "how are we doing, and did it get worse?" — a scored coverage map over your procedures. It is a pure function over findings you already have, so it never re-runs a lint:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { fromServerSchema, runAdvisor, scoreAdvisor } from "@lunora/advisor";
|
|
102
|
+
|
|
103
|
+
import schema from "./lunora/schema";
|
|
104
|
+
|
|
105
|
+
const context = { schema: fromServerSchema(schema) };
|
|
106
|
+
const findings = runAdvisor(context, { source: "static" });
|
|
107
|
+
const map = scoreAdvisor(context.procedureProtections ?? [], findings);
|
|
108
|
+
|
|
109
|
+
console.log(map.score, map.grade); // e.g. 84 "good"
|
|
110
|
+
console.log(map.summary); // { clean: 9, exempt: 0, failing: 1, procedures: 12, rulesFired: 6, warned: 2 }
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Each procedure starts at 100 and loses each fired **rule's** weight (`Lint.weight`, else a severity ladder: `ERROR` 20 / `WARN` 10 / `INFO` 5) — charged once however many times that rule fires — then rolls up into a weighted global mean: public handlers count double, internal ones and queries half. Findings that name no procedure (schema shape, wrangler config) land in a project bucket weighted against the procedure population, so schema debt genuinely moves the grade.
|
|
114
|
+
|
|
115
|
+
The verdicts are `clean` / `warned` / `failing` / `exempt` — named for severity, because the score is driven by every lint family rather than an observability family.
|
|
116
|
+
|
|
117
|
+
Commit the map and gate CI on it:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { compareToBaseline, parseAdvisorMap } from "@lunora/advisor";
|
|
121
|
+
|
|
122
|
+
const baseline = parseAdvisorMap(JSON.parse(await readFile("lunora.advisor.map.json", "utf8")));
|
|
123
|
+
|
|
124
|
+
if (baseline === undefined) {
|
|
125
|
+
// Missing, hand-edited, or written by an older MAP_VERSION. Fail loudly —
|
|
126
|
+
// treating it as "no regression" would silently disable the gate forever.
|
|
127
|
+
throw new Error("advisor baseline is unreadable; regenerate lunora.advisor.map.json");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const diff = compareToBaseline(map, baseline);
|
|
131
|
+
|
|
132
|
+
// `comparable` must be narrowed before `regressed` is reachable, so a stale
|
|
133
|
+
// baseline cannot read as a clean run.
|
|
134
|
+
if (!diff.comparable) {
|
|
135
|
+
throw new Error(`advisor baseline not comparable: ${diff.reason}`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Five independent signals: the global score fell, an existing procedure got
|
|
139
|
+
// worse, one started failing, one's findings grew without its score moving, or
|
|
140
|
+
// the project bucket gained findings. The growth signals matter because a rule is
|
|
141
|
+
// charged once however many times it fires, and the project score saturates at 0.
|
|
142
|
+
if (diff.regressed) {
|
|
143
|
+
process.exitCode = 1;
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`@lunora/codegen` exposes `toAdvisorContext()` to build the context straight from the feeder, and `lunora advisor` wraps all of this as a command. Full reference for the scoring, verdicts, and the baseline gate is in the [package docs](https://lunora.sh/docs/packages/advisor).
|
|
148
|
+
|
|
96
149
|
> This README covers the basics. For the full API, options, and guides, see the **[documentation](https://lunora.sh/docs/addons/studio)**.
|
|
97
150
|
|
|
98
151
|
## Related
|
package/dist/index.d.mts
CHANGED
|
@@ -814,36 +814,6 @@ interface AdvisorOwnerFieldWrite {
|
|
|
814
814
|
/** The `ctx.db` write method (`insert` / `replace` / `patch` / `insertManyUnsafe`). */
|
|
815
815
|
method: string;
|
|
816
816
|
}
|
|
817
|
-
/**
|
|
818
|
-
* One branching `defineShape({ where })` / `definePolicy({ when })` predicate arm
|
|
819
|
-
* that returns an unrestricted predicate — the `unrestricted_where_branch` lint
|
|
820
|
-
* input.
|
|
821
|
-
*
|
|
822
|
-
* A row predicate returns a *filter*, not a boolean, so the denial arm has to be a
|
|
823
|
-
* predicate matching **no** rows: `deny()` / `{ OR: [] }`, a disjunction over zero
|
|
824
|
-
* branches. The plausible-looking `{}` is its exact opposite — it matches every row,
|
|
825
|
-
* so an arm meaning "this caller sees nothing" silently replicates or exposes the
|
|
826
|
-
* whole table, with no error and no log line.
|
|
827
|
-
*
|
|
828
|
-
* Only reported for a *branching* predicate: a single-exit `where: () => ({})` is an
|
|
829
|
-
* author deliberately replicating everything, which is legitimate. Produced by the
|
|
830
|
-
* codegen feeder; runtime callers don't supply it, so the lint finds nothing there.
|
|
831
|
-
* Structurally identical to `UnrestrictedWhereBranchIR`.
|
|
832
|
-
*/
|
|
833
|
-
interface AdvisorUnrestrictedWhereBranch {
|
|
834
|
-
/** The exported binding name of the shape / policy the predicate belongs to. */
|
|
835
|
-
exportName: string;
|
|
836
|
-
/** Source file relative to the lunora dir, no extension. */
|
|
837
|
-
file: string;
|
|
838
|
-
/** Which unrestricted form was returned. */
|
|
839
|
-
form: "empty-object" | "undefined";
|
|
840
|
-
/** The config key carrying the predicate (`where` for a shape, `when` for a policy). */
|
|
841
|
-
key: string;
|
|
842
|
-
/** 1-based line of the offending returned expression. */
|
|
843
|
-
line: number;
|
|
844
|
-
/** The declaring call (`defineShape` / `definePolicy`). */
|
|
845
|
-
owner: string;
|
|
846
|
-
}
|
|
847
817
|
/**
|
|
848
818
|
* One payment webhook-adapter construction (`createStripeAdapter` /
|
|
849
819
|
* `createPolarAdapter` / `createAutumnAdapter` / `createDodoPaymentsAdapter`) —
|
|
@@ -906,12 +876,24 @@ interface AdvisorPrivilegedDispatch {
|
|
|
906
876
|
interface AdvisorProcedureProtection {
|
|
907
877
|
/** `true` when the handler references `ctx.mail` / `ctx.email` (sends mail). */
|
|
908
878
|
callsMail: boolean;
|
|
879
|
+
/** `true` when the handler emits a structured observability event (`ctx.log` / `ctx.span` / `ctx.trace`). */
|
|
880
|
+
emitsEvent?: boolean;
|
|
881
|
+
/**
|
|
882
|
+
* `true` when the source carries a `// lunora-advisor-exempt` directive above
|
|
883
|
+
* the export — the developer's explicit opt-out. The row still appears in the
|
|
884
|
+
* map, marked `exempt`, but pulls no weight.
|
|
885
|
+
*/
|
|
886
|
+
exempt?: boolean;
|
|
887
|
+
/** The `-- reason` from the directive, so an exemption is argued rather than silent. */
|
|
888
|
+
exemptReason?: string;
|
|
909
889
|
/** The exported binding name of the procedure (e.g. `signUp`). */
|
|
910
890
|
exportName: string;
|
|
911
891
|
/** `true` when the handler fans work out to a privileged, cost-bearing dispatch surface (scheduler `runAfter`/`runAt`, a queue producer send, or a workflow create). Read by the privileged-fanout lint, paired with public visibility and no rate limit. */
|
|
912
892
|
fanOut: boolean;
|
|
913
893
|
/** Source file relative to the lunora dir, no extension. */
|
|
914
894
|
file: string;
|
|
895
|
+
/** `true` when the handler wraps work in `try`/`catch`. */
|
|
896
|
+
handlesErrors?: boolean;
|
|
915
897
|
/**
|
|
916
898
|
* `true` when the procedure declares an email-shaped argument. Read by the
|
|
917
899
|
* `signup_mutation_without_disposable_gating` lint: `emailGateMiddleware`
|
|
@@ -924,6 +906,12 @@ interface AdvisorProcedureProtection {
|
|
|
924
906
|
hasEmailArg?: boolean;
|
|
925
907
|
/** Registration kind — `query` is read-only; `mutation`/`action` are write-shaped. */
|
|
926
908
|
kind: "action" | "mutation" | "query";
|
|
909
|
+
/** `true` when the handler runs any AI generation, bounded or not. */
|
|
910
|
+
runsAiGeneration?: boolean;
|
|
911
|
+
/** `true` when the handler reaches an outbound surface (`ctx.fetch`, mail, queues, storage, sql, ai, …) that can fail. */
|
|
912
|
+
reachesOutbound?: boolean;
|
|
913
|
+
/** `true` when the handler throws a bare `new Error(...)` rather than a coded `LunoraError`. */
|
|
914
|
+
throwsBareError?: boolean;
|
|
927
915
|
/** `true` when the handler runs an AI generation (`generateText`/`streamText`/`generateObject`/`streamObject`) with no `maxOutputTokens` bound. Read by the `ai_unbounded_generation_public` lint (paired with public visibility). */
|
|
928
916
|
unboundedAiGeneration: boolean;
|
|
929
917
|
/** `true` when the chain carries `.use(verifyTurnstile(...))` or a `protectPublic({ captcha })` bundle. */
|
|
@@ -950,6 +938,16 @@ interface AdvisorProcedureProtection {
|
|
|
950
938
|
* supply it, so the lint simply finds nothing there.
|
|
951
939
|
*/
|
|
952
940
|
interface AdvisorQueryRead {
|
|
941
|
+
/**
|
|
942
|
+
* The exported procedure the read sits in, when the feeder could resolve one.
|
|
943
|
+
* Carried so the advisor map can attribute the finding to that procedure's row
|
|
944
|
+
* rather than to the project bucket; a read outside any export (module scope)
|
|
945
|
+
* legitimately has none.
|
|
946
|
+
*
|
|
947
|
+
* Optional so a feeder predating this field still typechecks — such a run
|
|
948
|
+
* simply attributes project-wide, exactly as before.
|
|
949
|
+
*/
|
|
950
|
+
exportName?: string;
|
|
953
951
|
/** Source file the read appears in (relative to the lunora dir, no extension). */
|
|
954
952
|
file: string;
|
|
955
953
|
/** True when the chain calls `.filter(...)`. */
|
|
@@ -1468,6 +1466,36 @@ interface AdvisorTableSample {
|
|
|
1468
1466
|
/** Whether more rows exist beyond the cap. */
|
|
1469
1467
|
readonly truncated: boolean;
|
|
1470
1468
|
}
|
|
1469
|
+
/**
|
|
1470
|
+
* One branching `defineShape({ where })` / `definePolicy({ when })` predicate arm
|
|
1471
|
+
* that returns an unrestricted predicate — the `unrestricted_where_branch` lint
|
|
1472
|
+
* input.
|
|
1473
|
+
*
|
|
1474
|
+
* A row predicate returns a *filter*, not a boolean, so the denial arm has to be a
|
|
1475
|
+
* predicate matching **no** rows: `deny()` / `{ OR: [] }`, a disjunction over zero
|
|
1476
|
+
* branches. The plausible-looking `{}` is its exact opposite — it matches every row,
|
|
1477
|
+
* so an arm meaning "this caller sees nothing" silently replicates or exposes the
|
|
1478
|
+
* whole table, with no error and no log line.
|
|
1479
|
+
*
|
|
1480
|
+
* Only reported for a *branching* predicate: a single-exit `where: () => ({})` is an
|
|
1481
|
+
* author deliberately replicating everything, which is legitimate. Produced by the
|
|
1482
|
+
* codegen feeder; runtime callers don't supply it, so the lint finds nothing there.
|
|
1483
|
+
* Structurally identical to `UnrestrictedWhereBranchIR`.
|
|
1484
|
+
*/
|
|
1485
|
+
interface AdvisorUnrestrictedWhereBranch {
|
|
1486
|
+
/** The exported binding name of the shape / policy the predicate belongs to. */
|
|
1487
|
+
exportName: string;
|
|
1488
|
+
/** Source file relative to the lunora dir, no extension. */
|
|
1489
|
+
file: string;
|
|
1490
|
+
/** Which unrestricted form was returned. */
|
|
1491
|
+
form: "empty-object" | "undefined";
|
|
1492
|
+
/** The config key carrying the predicate (`where` for a shape, `when` for a policy). */
|
|
1493
|
+
key: string;
|
|
1494
|
+
/** 1-based line of the offending returned expression. */
|
|
1495
|
+
line: number;
|
|
1496
|
+
/** The declaring call (`defineShape` / `definePolicy`). */
|
|
1497
|
+
owner: string;
|
|
1498
|
+
}
|
|
1471
1499
|
/**
|
|
1472
1500
|
* One `ctx.vectors.<method>(indexName, input)` call whose `input.namespace` is
|
|
1473
1501
|
* derived from the handler's `args` with no server-side scoping — the input the
|
|
@@ -1912,12 +1940,6 @@ interface LintContext {
|
|
|
1912
1940
|
* absent for runtime callers, where the lint finds nothing.
|
|
1913
1941
|
*/
|
|
1914
1942
|
ownerFieldWrites?: ReadonlyArray<AdvisorOwnerFieldWrite>;
|
|
1915
|
-
/**
|
|
1916
|
-
* Branching shape/policy predicate arms returning an unrestricted filter (`{}` /
|
|
1917
|
-
* `undefined`) — the `unrestricted_where_branch` lint input. Supplied by the
|
|
1918
|
-
* codegen feeder only.
|
|
1919
|
-
*/
|
|
1920
|
-
unrestrictedWhereBranches?: ReadonlyArray<AdvisorUnrestrictedWhereBranch>;
|
|
1921
1943
|
/**
|
|
1922
1944
|
* Payment webhook-adapter constructions (`createStripeAdapter` /
|
|
1923
1945
|
* `createPolarAdapter` / `createAutumnAdapter` / `createDodoPaymentsAdapter`) — the payment-webhook wide-tolerance lint's input. Each row's
|
|
@@ -2090,6 +2112,12 @@ interface LintContext {
|
|
|
2090
2112
|
* and shards. Absent for static callers, where the lint finds nothing.
|
|
2091
2113
|
*/
|
|
2092
2114
|
tableScans?: ReadonlyArray<AdvisorTableScan>;
|
|
2115
|
+
/**
|
|
2116
|
+
* Branching shape/policy predicate arms returning an unrestricted filter (`{}` /
|
|
2117
|
+
* `undefined`) — the `unrestricted_where_branch` lint input. Supplied by the
|
|
2118
|
+
* codegen feeder only.
|
|
2119
|
+
*/
|
|
2120
|
+
unrestrictedWhereBranches?: ReadonlyArray<AdvisorUnrestrictedWhereBranch>;
|
|
2093
2121
|
/**
|
|
2094
2122
|
* `ctx.vectors.<method>(index, { namespace, … })` calls whose `namespace` is
|
|
2095
2123
|
* derived from the handler's `args` with no server-side scoping — the
|
|
@@ -2322,6 +2350,21 @@ declare const indexUtilization: Lint;
|
|
|
2322
2350
|
* arg-derived `ctx.fetch` call.
|
|
2323
2351
|
*/
|
|
2324
2352
|
declare const actionFetchSsrf: Lint;
|
|
2353
|
+
/**
|
|
2354
|
+
* Flags an `action` that reaches an outbound surface with no `try`/`catch`
|
|
2355
|
+
* anywhere in its body.
|
|
2356
|
+
*
|
|
2357
|
+
* Actions are where Lunora talks to things it does not control — `ctx.fetch`,
|
|
2358
|
+
* mail, queues, storage, external SQL, AI. Every one of those fails routinely
|
|
2359
|
+
* (timeout, 5xx, quota), and an uncaught rejection there surfaces to the caller
|
|
2360
|
+
* as an opaque failure with no indication of which dependency broke. Catching it
|
|
2361
|
+
* is what lets the handler add that context, or degrade instead of failing.
|
|
2362
|
+
*
|
|
2363
|
+
* Only `action` is checked: queries and mutations run inside the Durable Object
|
|
2364
|
+
* and cannot reach these surfaces. Runs only when the codegen feeder supplies
|
|
2365
|
+
* procedure evidence.
|
|
2366
|
+
*/
|
|
2367
|
+
declare const actionWithoutErrorHandling: Lint;
|
|
2325
2368
|
/**
|
|
2326
2369
|
* Flags an `httpRoute` on an admin/privileged-looking path whose handler shows no
|
|
2327
2370
|
* auth/admin guard.
|
|
@@ -2359,6 +2402,22 @@ declare const adminRouteWithoutGuard: Lint;
|
|
|
2359
2402
|
* arg-derived, unscoped `ctx.ai.run` call.
|
|
2360
2403
|
*/
|
|
2361
2404
|
declare const aiRawRunEscapeHatch: Lint;
|
|
2405
|
+
/**
|
|
2406
|
+
* Flags a procedure that runs an AI generation but emits no structured event.
|
|
2407
|
+
*
|
|
2408
|
+
* Model calls are the least reproducible thing in an app and the only one that
|
|
2409
|
+
* bills per invocation: the same input can return a different answer tomorrow,
|
|
2410
|
+
* and a runaway loop is a cost incident rather than an outage. Without an event
|
|
2411
|
+
* recording that the call happened there is no way to attribute spend, compare a
|
|
2412
|
+
* bad answer against the prompt that produced it, or notice a retry storm.
|
|
2413
|
+
*
|
|
2414
|
+
* Keyed on whether the handler runs a model at all — bounded or not. An earlier
|
|
2415
|
+
* cut reused the `unboundedAiGeneration` / raw-run signals, which meant the
|
|
2416
|
+
* correctly-bounded `generateText({ …, maxOutputTokens })` — the common case, and
|
|
2417
|
+
* the one this rule exists for — was never flagged, while procedures another lint
|
|
2418
|
+
* had already caught were charged twice.
|
|
2419
|
+
*/
|
|
2420
|
+
declare const aiRunWithoutLogging: Lint;
|
|
2362
2421
|
/**
|
|
2363
2422
|
* Flags a `generateText` / `streamText` call whose model input is user-derived
|
|
2364
2423
|
* **and** whose model-callable `tools` reach a privileged side effect.
|
|
@@ -2476,6 +2535,30 @@ declare const authCsrfCheckDisabled: Lint;
|
|
|
2476
2535
|
* call.
|
|
2477
2536
|
*/
|
|
2478
2537
|
declare const authEmailVerificationDisabled: Lint;
|
|
2538
|
+
/**
|
|
2539
|
+
* Flags a `createAuth({...})` call that loads `scim()` on an adapter with no native
|
|
2540
|
+
* transactions.
|
|
2541
|
+
*
|
|
2542
|
+
* `@better-auth/scim` refuses to serve at all unless its adapter exposes a
|
|
2543
|
+
* `transaction` function — its provisioning writes go through a read-then-conditional-write
|
|
2544
|
+
* decommission lease. `lunoraD1Adapter` and `lunoraAuthAdapter` are single-table CRUD,
|
|
2545
|
+
* and D1 has no interactive transactions to expose in the first place, so this pairing
|
|
2546
|
+
* throws on the first SCIM request:
|
|
2547
|
+
*
|
|
2548
|
+
* ```
|
|
2549
|
+
* BetterAuthError: The scim plugin requires a database adapter with native transaction support.
|
|
2550
|
+
* ```
|
|
2551
|
+
*
|
|
2552
|
+
* This exists because the combination shipped in real documentation once. It is not a
|
|
2553
|
+
* subtle misconfiguration — it is a deployment where directory sync cannot work at all —
|
|
2554
|
+
* and it is entirely visible at build time, so there is no reason for the first
|
|
2555
|
+
* indication to be a 500 from an IdP's provisioning call.
|
|
2556
|
+
*
|
|
2557
|
+
* Runs only when the codegen feeder supplies auth-config evidence
|
|
2558
|
+
* (`context.authConfigs`), and only for an analyzable config; an opaque one could pass
|
|
2559
|
+
* a different `database` and is skipped rather than guessed at.
|
|
2560
|
+
*/
|
|
2561
|
+
declare const authScimWithoutTransactions: Lint;
|
|
2479
2562
|
/**
|
|
2480
2563
|
* Flags a `createAuth({...})` call whose `advanced.useSecureCookies` is
|
|
2481
2564
|
* explicitly `false`.
|
|
@@ -2515,30 +2598,6 @@ declare const authSecureCookiesDisabled: Lint;
|
|
|
2515
2598
|
* call.
|
|
2516
2599
|
*/
|
|
2517
2600
|
declare const authSessionFreshageZero: Lint;
|
|
2518
|
-
/**
|
|
2519
|
-
* Flags a `createAuth({...})` call that loads `scim()` on an adapter with no native
|
|
2520
|
-
* transactions.
|
|
2521
|
-
*
|
|
2522
|
-
* `@better-auth/scim` refuses to serve at all unless its adapter exposes a
|
|
2523
|
-
* `transaction` function — its provisioning writes go through a read-then-conditional-write
|
|
2524
|
-
* decommission lease. `lunoraD1Adapter` and `lunoraAuthAdapter` are single-table CRUD,
|
|
2525
|
-
* and D1 has no interactive transactions to expose in the first place, so this pairing
|
|
2526
|
-
* throws on the first SCIM request:
|
|
2527
|
-
*
|
|
2528
|
-
* ```
|
|
2529
|
-
* BetterAuthError: The scim plugin requires a database adapter with native transaction support.
|
|
2530
|
-
* ```
|
|
2531
|
-
*
|
|
2532
|
-
* This exists because the combination shipped in real documentation once. It is not a
|
|
2533
|
-
* subtle misconfiguration — it is a deployment where directory sync cannot work at all —
|
|
2534
|
-
* and it is entirely visible at build time, so there is no reason for the first
|
|
2535
|
-
* indication to be a 500 from an IdP's provisioning call.
|
|
2536
|
-
*
|
|
2537
|
-
* Runs only when the codegen feeder supplies auth-config evidence
|
|
2538
|
-
* (`context.authConfigs`), and only for an analyzable config; an opaque one could pass
|
|
2539
|
-
* a different `database` and is skipped rather than guessed at.
|
|
2540
|
-
*/
|
|
2541
|
-
declare const authScimWithoutTransactions: Lint;
|
|
2542
2601
|
/**
|
|
2543
2602
|
* Flags a `createAuth({...})` call whose `trustedOrigins` array literal
|
|
2544
2603
|
* contains a `"*"` entry.
|
|
@@ -2694,6 +2753,19 @@ declare const duplicateIndex: Lint;
|
|
|
2694
2753
|
* least one field by construction, so only `kind: "index"` is checked.)
|
|
2695
2754
|
*/
|
|
2696
2755
|
declare const emptyIndex: Lint;
|
|
2756
|
+
/**
|
|
2757
|
+
* Flags a procedure that throws a bare `new Error(...)`.
|
|
2758
|
+
*
|
|
2759
|
+
* A bare `Error` crosses the RPC boundary as an opaque message: the client
|
|
2760
|
+
* cannot branch on it, `@lunora/fingerprint` cannot group it into an issue, and
|
|
2761
|
+
* the message itself is free text that changes whenever someone edits the
|
|
2762
|
+
* string. `LunoraError` carries a stable code from `ERROR_CATALOG`, which is
|
|
2763
|
+
* what makes an error both matchable on the client and groupable in Studio.
|
|
2764
|
+
*
|
|
2765
|
+
* Runs only when the codegen feeder supplies procedure evidence; a runtime
|
|
2766
|
+
* caller with no evidence flags nothing.
|
|
2767
|
+
*/
|
|
2768
|
+
declare const errorWithoutCatalog: Lint;
|
|
2697
2769
|
/**
|
|
2698
2770
|
* Flags a misconfigured CDC export sink (plan 170) — a `defineExportSink` /
|
|
2699
2771
|
* `webhookExportSink` / `r2Sink` construction with a required config field
|
|
@@ -3378,6 +3450,23 @@ declare const privilegedDispatchUnvalidatedPayload: Lint;
|
|
|
3378
3450
|
* per unguarded public fan-out procedure.
|
|
3379
3451
|
*/
|
|
3380
3452
|
declare const privilegedFanoutFromPublicProcedure: Lint;
|
|
3453
|
+
/**
|
|
3454
|
+
* Flags a public `mutation`/`action` whose handler emits no structured
|
|
3455
|
+
* observability event.
|
|
3456
|
+
*
|
|
3457
|
+
* When one of these fails in production you get a stack trace and nothing about
|
|
3458
|
+
* the request that caused it — no ids, no tenant, no outcome. `ctx.log` /
|
|
3459
|
+
* `ctx.span` attach that context to the invocation, so the failure is
|
|
3460
|
+
* searchable instead of merely visible. Reads are excluded: a `query` that
|
|
3461
|
+
* returns the wrong rows is diagnosable from its arguments, while a write that
|
|
3462
|
+
* half-succeeded is not.
|
|
3463
|
+
*
|
|
3464
|
+
* Runs only when the codegen feeder supplies procedure evidence; a runtime
|
|
3465
|
+
* caller with no evidence flags nothing. The feeder reports "no event" only when
|
|
3466
|
+
* it could read the body, so a procedure whose handler it cannot analyze is left
|
|
3467
|
+
* alone rather than nagged.
|
|
3468
|
+
*/
|
|
3469
|
+
declare const procedureWithoutStructuredEvent: Lint;
|
|
3381
3470
|
/**
|
|
3382
3471
|
* Flags a `v.any()` argument on a public procedure.
|
|
3383
3472
|
*
|
|
@@ -3982,6 +4071,253 @@ declare const workflowUnknownTarget: Lint;
|
|
|
3982
4071
|
* (`context.workflows` present); a runtime caller flags nothing.
|
|
3983
4072
|
*/
|
|
3984
4073
|
declare const workflowUnused: Lint;
|
|
4074
|
+
/** Letter band for a 0–100 score. */
|
|
4075
|
+
type Grade = "at-risk" | "excellent" | "good" | "needs-work";
|
|
4076
|
+
/**
|
|
4077
|
+
* How a single procedure came out of the lints that apply to it.
|
|
4078
|
+
*
|
|
4079
|
+
* Named for severity rather than instrumentation, because the score is driven by
|
|
4080
|
+
* every lint family (security, performance, schema): a verdict like
|
|
4081
|
+
* "uninstrumented" would claim something the map does not measure, and would
|
|
4082
|
+
* report a security regression as a telemetry gap. `clean` means no lint fired.
|
|
4083
|
+
* `exempt` rows pull no weight.
|
|
4084
|
+
*/
|
|
4085
|
+
type Coverage = "clean" | "exempt" | "failing" | "warned";
|
|
4086
|
+
/**
|
|
4087
|
+
* One *rule* that fired against a procedure, reduced to its score contribution.
|
|
4088
|
+
*
|
|
4089
|
+
* Deduplicated by lint: a rule that fires on five call sites is one check with
|
|
4090
|
+
* `occurrences: 5`, costing its weight once. Counting occurrences instead would
|
|
4091
|
+
* let a single rule zero a procedure and would fill the artifact with identical
|
|
4092
|
+
* rows.
|
|
4093
|
+
*/
|
|
4094
|
+
interface CheckResult {
|
|
4095
|
+
/** Worst severity seen across this rule's occurrences. */
|
|
4096
|
+
level: Level;
|
|
4097
|
+
/** The lint id that fired, e.g. `unindexed_foreign_key`. */
|
|
4098
|
+
name: string;
|
|
4099
|
+
/** How many findings this rule produced on the procedure (>= 1). */
|
|
4100
|
+
occurrences: number;
|
|
4101
|
+
/** Points subtracted from the procedure's score — charged once, not per occurrence. */
|
|
4102
|
+
weight: number;
|
|
4103
|
+
}
|
|
4104
|
+
/** How much a procedure's failures matter — see `classifySensitivity`. */
|
|
4105
|
+
type SensitivityLevel = "high" | "none";
|
|
4106
|
+
/** A procedure's sensitivity plus the declarations that produced it. */
|
|
4107
|
+
interface Sensitivity {
|
|
4108
|
+
/** `high` when any signal fired; `none` means no signal, not "safe". */
|
|
4109
|
+
level: SensitivityLevel;
|
|
4110
|
+
/** Human-readable signals, e.g. "writes an identity table". Empty when `none`. */
|
|
4111
|
+
reasons: string[];
|
|
4112
|
+
}
|
|
4113
|
+
/** One scored procedure — the unit the map is built from. */
|
|
4114
|
+
interface ProcedureScore {
|
|
4115
|
+
/** Rules that fired against this procedure, sorted by `name`. */
|
|
4116
|
+
checks: CheckResult[];
|
|
4117
|
+
/** Verdict derived from {@link ProcedureScore.score}. */
|
|
4118
|
+
coverage: Coverage;
|
|
4119
|
+
/** Why this row is `exempt`, when a source directive said so. Empty when none was given. */
|
|
4120
|
+
exemptReason?: string;
|
|
4121
|
+
/** Exported binding name, e.g. `sendMessage`. */
|
|
4122
|
+
exportName: string;
|
|
4123
|
+
/** Source file relative to the lunora dir, no extension. */
|
|
4124
|
+
file: string;
|
|
4125
|
+
/** Stable `file#exportName` identity — the baseline diff key. */
|
|
4126
|
+
id: string;
|
|
4127
|
+
/** Registration kind. */
|
|
4128
|
+
kind: "action" | "mutation" | "query";
|
|
4129
|
+
/** 0–100, starting at 100 less each fired rule's weight. */
|
|
4130
|
+
score: number;
|
|
4131
|
+
/** How much this procedure's failures matter, and why. */
|
|
4132
|
+
sensitivity: Sensitivity;
|
|
4133
|
+
/** Public (client-callable) or internal (server-called). */
|
|
4134
|
+
visibility: "internal" | "public";
|
|
4135
|
+
/** This row's weight in the global mean — see `procedureWeight`. */
|
|
4136
|
+
weight: number;
|
|
4137
|
+
}
|
|
4138
|
+
/**
|
|
4139
|
+
* Findings that name no procedure — schema-shape and project-wide lints
|
|
4140
|
+
* (missing index, circular FK, plaintext wrangler secret), plus any finding
|
|
4141
|
+
* whose `file`/`exportName` matches no declared procedure.
|
|
4142
|
+
*
|
|
4143
|
+
* Folded into the global mean at a weight proportional to the procedure
|
|
4144
|
+
* population (see `projectWeight`) so schema debt genuinely moves the grade.
|
|
4145
|
+
* Because this single score saturates at 0, `compareToBaseline` also diffs
|
|
4146
|
+
* `checks.length` — otherwise new schema errors would be free once the bucket
|
|
4147
|
+
* bottoms out.
|
|
4148
|
+
*/
|
|
4149
|
+
interface ProjectScore {
|
|
4150
|
+
/** Rules that fired at project level, sorted by `name`. */
|
|
4151
|
+
checks: CheckResult[];
|
|
4152
|
+
/** 0–100, same formula as a procedure. */
|
|
4153
|
+
score: number;
|
|
4154
|
+
}
|
|
4155
|
+
/** Coverage tallies for the summary line and the Studio matrix header. */
|
|
4156
|
+
interface MapSummary {
|
|
4157
|
+
/** Procedures with no lint firing. */
|
|
4158
|
+
clean: number;
|
|
4159
|
+
/** Procedures excluded from scoring. */
|
|
4160
|
+
exempt: number;
|
|
4161
|
+
/** Procedures scoring below the failing floor. */
|
|
4162
|
+
failing: number;
|
|
4163
|
+
/** Total procedures in the map, exempt included. */
|
|
4164
|
+
procedures: number;
|
|
4165
|
+
/** Findings attributed to a scored row, after per-rule deduplication. */
|
|
4166
|
+
rulesFired: number;
|
|
4167
|
+
/** Procedures scoring at or above the failing floor, but not clean. */
|
|
4168
|
+
warned: number;
|
|
4169
|
+
}
|
|
4170
|
+
/**
|
|
4171
|
+
* The `lunora.advisor.map.json` artifact — the unit a baseline is diffed
|
|
4172
|
+
* against and the Studio health panel renders.
|
|
4173
|
+
*/
|
|
4174
|
+
interface AdvisorMap {
|
|
4175
|
+
/**
|
|
4176
|
+
* ISO-8601 stamp. Defaults to the current time; pass
|
|
4177
|
+
* `ScoreAdvisorOptions.generatedAt` explicitly when the artifact must be
|
|
4178
|
+
* byte-stable (tests, reproducible builds) — everything else in the map is
|
|
4179
|
+
* a pure function of the findings.
|
|
4180
|
+
*/
|
|
4181
|
+
generatedAt: string;
|
|
4182
|
+
/** Band for {@link AdvisorMap.score}. */
|
|
4183
|
+
grade: Grade;
|
|
4184
|
+
/** Per-procedure rows, sorted by `id` for a stable diff. */
|
|
4185
|
+
procedures: ProcedureScore[];
|
|
4186
|
+
/** Findings not attributable to a procedure. */
|
|
4187
|
+
project: ProjectScore;
|
|
4188
|
+
/** Weighted mean over non-exempt procedures plus the project entry, 0–100. */
|
|
4189
|
+
score: number;
|
|
4190
|
+
/** Coverage tallies. */
|
|
4191
|
+
summary: MapSummary;
|
|
4192
|
+
/** Artifact shape version; bump on a breaking change so an old baseline is rejected rather than mis-read. */
|
|
4193
|
+
version: number;
|
|
4194
|
+
}
|
|
4195
|
+
/** One procedure whose score moved between the baseline and the current map. */
|
|
4196
|
+
interface ProcedureDelta {
|
|
4197
|
+
/** Score in the current map. */
|
|
4198
|
+
after: number;
|
|
4199
|
+
/** Score in the baseline. */
|
|
4200
|
+
before: number;
|
|
4201
|
+
/** `file#exportName`. */
|
|
4202
|
+
id: string;
|
|
4203
|
+
}
|
|
4204
|
+
/**
|
|
4205
|
+
* The verdict a CI gate acts on.
|
|
4206
|
+
*
|
|
4207
|
+
* A discriminated union on purpose: the obvious shape (a flat object with
|
|
4208
|
+
* `comparable: boolean` and `regressed: false` when incomparable) reads as
|
|
4209
|
+
* "no regression" for a missing, stale, or corrupt baseline, so a gate written
|
|
4210
|
+
* as `if (diff.regressed)` silently passes forever after a `MAP_VERSION` bump.
|
|
4211
|
+
* Forcing the caller to narrow makes that mistake unrepresentable.
|
|
4212
|
+
*/
|
|
4213
|
+
type BaselineComparison = {
|
|
4214
|
+
comparable: false;
|
|
4215
|
+
/** Why no comparison was possible — a gate should treat this as "cannot verify", not "clean". */
|
|
4216
|
+
reason: "version-mismatch";
|
|
4217
|
+
} | {
|
|
4218
|
+
comparable: true;
|
|
4219
|
+
/** Procedures present in both maps whose score fell, sorted by `id`. */
|
|
4220
|
+
dropped: ProcedureDelta[];
|
|
4221
|
+
/** Procedures that are `failing` now and were not before — new rows included. */
|
|
4222
|
+
newFailing: string[];
|
|
4223
|
+
/** `true` when the project bucket gained rules or occurrences, even if its saturated score did not move. */
|
|
4224
|
+
projectRegressed: boolean;
|
|
4225
|
+
/** `true` when any signal above fired. */
|
|
4226
|
+
regressed: boolean;
|
|
4227
|
+
/** Current global score less the baseline's; negative is a regression. */
|
|
4228
|
+
scoreDelta: number;
|
|
4229
|
+
/**
|
|
4230
|
+
* Procedures whose score held but whose findings grew — a new rule fired,
|
|
4231
|
+
* or an existing one fired at more call sites. Scoring charges a rule once
|
|
4232
|
+
* however many times it fires, so without this signal "same rule, five more
|
|
4233
|
+
* violations" would look identical to the baseline.
|
|
4234
|
+
*/
|
|
4235
|
+
worsened: string[];
|
|
4236
|
+
};
|
|
4237
|
+
/**
|
|
4238
|
+
* Diff a freshly-scored map against a committed one.
|
|
4239
|
+
*
|
|
4240
|
+
* Five independent regression signals, any of which fails a gate: the global
|
|
4241
|
+
* score fell, a procedure that existed before got worse, a procedure started
|
|
4242
|
+
* failing, a procedure's findings grew without its score moving, or the project
|
|
4243
|
+
* bucket gained findings. The per-procedure signals matter because a refactor can
|
|
4244
|
+
* leave the global mean flat while gutting one handler; the growth signals matter
|
|
4245
|
+
* because a rule is charged once however many times it fires, and the project
|
|
4246
|
+
* score saturates at 0 — without them, new violations would be free.
|
|
4247
|
+
*/
|
|
4248
|
+
declare const compareToBaseline: (current: AdvisorMap, baseline: AdvisorMap) => BaselineComparison;
|
|
4249
|
+
/**
|
|
4250
|
+
* Narrow a parsed `lunora.advisor.map.json` to an {@link AdvisorMap}, returning
|
|
4251
|
+
* `undefined` when it is not one this build can read.
|
|
4252
|
+
*
|
|
4253
|
+
* Validates *shape* — the header and every procedure row — because
|
|
4254
|
+
* `compareToBaseline` dereferences `entry.id` / `entry.score` /
|
|
4255
|
+
* `entry.coverage`: a truncated or merge-conflicted baseline with a `null` row
|
|
4256
|
+
* would otherwise crash the gate, and a row of `{}` would compare as a silent
|
|
4257
|
+
* no-op. Non-finite scores are rejected for the same reason — `NaN < 0` is
|
|
4258
|
+
* `false`, which reads as "no regression".
|
|
4259
|
+
*
|
|
4260
|
+
* Version *policy* deliberately lives in {@link compareToBaseline}, not here.
|
|
4261
|
+
* Rejecting a mismatch in both places made that function's `comparable: false`
|
|
4262
|
+
* arm unreachable through every shipped path, so the union that exists to stop a
|
|
4263
|
+
* stale baseline reading as "clean" was never exercised. Here we only require a
|
|
4264
|
+
* version to be present and finite.
|
|
4265
|
+
*/
|
|
4266
|
+
declare const parseAdvisorMap: (value: unknown) => AdvisorMap | undefined;
|
|
4267
|
+
/** Band a 0–100 score. */
|
|
4268
|
+
declare const gradeFromScore: (score: number) => Grade;
|
|
4269
|
+
/**
|
|
4270
|
+
* Codepoint ordering. `localeCompare` would sort by the host's `LANG`/`LC_ALL`,
|
|
4271
|
+
* so the same repo scored on a Danish-locale runner emits a different row order
|
|
4272
|
+
* than an `en_US` one — the committed artifact would churn and a
|
|
4273
|
+
* `git diff --exit-code` gate would fail for no reason. Ordering must be a
|
|
4274
|
+
* property of the data, not the machine.
|
|
4275
|
+
*/
|
|
4276
|
+
declare const byCodepoint: (a: string, b: string) => number;
|
|
4277
|
+
/**
|
|
4278
|
+
* {@link AdvisorMap.version} this build emits. Bump on a breaking shape change
|
|
4279
|
+
* so `compareToBaseline` rejects a stale artifact instead of mis-reading it.
|
|
4280
|
+
*/
|
|
4281
|
+
declare const MAP_VERSION = 1;
|
|
4282
|
+
/** Options for {@link scoreAdvisor}. */
|
|
4283
|
+
interface ScoreAdvisorOptions {
|
|
4284
|
+
/**
|
|
4285
|
+
* Procedure ids (`file#exportName`) to exclude from scoring, for a caller
|
|
4286
|
+
* that computes exemptions itself. Source-level `// lunora-advisor-exempt`
|
|
4287
|
+
* directives are honoured independently; the two compose.
|
|
4288
|
+
*/
|
|
4289
|
+
exempt?: ReadonlyArray<string>;
|
|
4290
|
+
/**
|
|
4291
|
+
* Stamp written to {@link AdvisorMap.generatedAt}. Defaults to now; pass it
|
|
4292
|
+
* explicitly when the map must be byte-stable (tests, reproducible builds).
|
|
4293
|
+
*/
|
|
4294
|
+
generatedAt?: string;
|
|
4295
|
+
}
|
|
4296
|
+
/**
|
|
4297
|
+
* Roll a lint run up into a scored coverage map (see the package's
|
|
4298
|
+
* `docs/index.mdx` for the scoring rules and the baseline gate).
|
|
4299
|
+
*
|
|
4300
|
+
* Pure: it re-reads the `findings` a caller already got from `runAdvisor` rather
|
|
4301
|
+
* than running lints itself, so scoring never double-runs a rule and the lint
|
|
4302
|
+
* core stays untouched. Findings are attributed to a procedure via their
|
|
4303
|
+
* `metadata.file` + `metadata.exportName`; everything else lands in the project
|
|
4304
|
+
* bucket, which is folded into the global mean at a weight proportional to the
|
|
4305
|
+
* procedure population so schema debt genuinely moves the grade.
|
|
4306
|
+
*
|
|
4307
|
+
* Takes the procedure list directly rather than a `LintContext`: it reads no
|
|
4308
|
+
* other feeder, and asking for the whole context forced callers with only a
|
|
4309
|
+
* procedure array to fabricate an empty schema.
|
|
4310
|
+
*/
|
|
4311
|
+
declare const scoreAdvisor: (procedures: ReadonlyArray<AdvisorProcedureProtection>, findings: ReadonlyArray<Finding>, options?: ScoreAdvisorOptions) => AdvisorMap;
|
|
4312
|
+
/**
|
|
4313
|
+
* Classify how much a procedure's failures matter, from the protective
|
|
4314
|
+
* declarations and behavioural facts the feeder already collected.
|
|
4315
|
+
*
|
|
4316
|
+
* Runs before any rule so a lint can gate on it, and feeds the global weighting:
|
|
4317
|
+
* a handler touching identity, mail, or tenant-scoped rows pulls harder on the
|
|
4318
|
+
* grade than a plain read. `none` means no signal fired — not "safe".
|
|
4319
|
+
*/
|
|
4320
|
+
declare const classifySensitivity: (procedure: AdvisorProcedureProtection) => Sensitivity;
|
|
3985
4321
|
/**
|
|
3986
4322
|
* Every lint that runs against the declared schema (and, for
|
|
3987
4323
|
* `filter_without_index`, the discovered query reads) — no running shard
|
|
@@ -4013,4 +4349,4 @@ interface RunAdvisorOptions {
|
|
|
4013
4349
|
* `static` lints at build time and defer `runtime` lints to a live shard.
|
|
4014
4350
|
*/
|
|
4015
4351
|
declare const runAdvisor: (context: LintContext, options?: RunAdvisorOptions) => Finding[];
|
|
4016
|
-
export { AE_METRIC_EVENTS, ALL_LINTS, type AdvisorAdminRoute, type AdvisorAiRawRun, type AdvisorAiToolSideEffect, type AdvisorArgumentDerivedFetch, type AdvisorArgumentValidator, type AdvisorAuthApiCall, type AdvisorAuthConfig, type AdvisorBrowserUrlAccess, type AdvisorConfigCall, type AdvisorContainer, type AdvisorContainerKeyAccess, type AdvisorContainerOverride, type AdvisorExportSink, type AdvisorFailOpenGuard, type AdvisorFlagSecurityDefault, type AdvisorGeoIndexUsage, type AdvisorHttpActionGuard, type AdvisorHttpHeaderWrite, type AdvisorHyperdriveCall, type AdvisorIdentityClaimRead, type AdvisorImageDeliveryUrlAccess, type AdvisorIndex, type AdvisorIndexHit, type AdvisorInsertWrite, type AdvisorKvKeyAccess, type AdvisorMailRecipientAccess, type AdvisorMaskProcedure, type AdvisorMaskStrategy, type AdvisorMutatorWrite, type AdvisorNondeterministicCall, type AdvisorNormalizeIdAuthorization, type AdvisorNotifyCall, type AdvisorNotifyConfig, type AdvisorOwnerFieldWrite, type AdvisorPaymentWebhook, type AdvisorPrivilegedDispatch, type AdvisorProcedureProtection, type AdvisorQueryRead, type AdvisorQueue, type AdvisorQueueTuning, type AdvisorR2sqlCall, type AdvisorRatelimitKeySelector, type AdvisorRawRowReturn, type AdvisorRelation, type AdvisorRelationLoad, type AdvisorRlsProcedure, type AdvisorSchema, type AdvisorSecretLiteral, type AdvisorShape, type AdvisorShardTraffic, type AdvisorSoftDeleteRead, type AdvisorSqlInterpolation, type AdvisorStorageKeyAccess, type AdvisorStorageUpload, type AdvisorTable, type AdvisorTableSample, type AdvisorTableScan, type AdvisorVectorNamespaceAccess, type AdvisorWorkflow, type AdvisorWorkflowCall, type AdvisorWranglerVariable, type AnalyticsMetricsOptions, type AnalyticsMetricsSource, type AnalyticsRuntimeMetrics, type Category, type Facing, type Finding, type Level, type Lint, type LintContext, type LintSource, RUNTIME_LINTS, RunAdvisorOptions, STATIC_LINTS, actionFetchSsrf, adminRouteWithoutGuard, aiRawRunEscapeHatch, aiToolSideEffectPromptInjection, aiUnboundedGenerationPublic, allowUnauthenticatedShardAccessEnabled, authApiCallWithoutHeaders, authCsrfCheckDisabled, authEmailVerificationDisabled, authScimWithoutTransactions, authSecureCookiesDisabled, authSessionFreshageZero, authTrustedOriginsWildcard, browserAllowPrivateTargets, browserUserUrlWithoutAllowlist, circularFk, constraintValidator, containerInstanceKeyFromUserInput, containerOversizedInstance, containerPublicInternet, containerRuntimeEgressRelaxation, containerStartEnableInternetOverride, dedupeCacheKeys, duplicateIndex, emptyIndex, exportSinkMisconfigured, externalSourceIncrementalNoDeletePath, externalSourceOnGlobal, externalSourceUnscoped, filterWithoutIndex, flagGatesSecurityWithUnsafeDefault, fromServerSchema, geoIndexFieldNotGeopoint, geoIndexUnused, hardcodedSecret, hotShard, httpActionMissingAuthGuard, httpActionResponseHeaderInjection, hyperdriveOutsideAction, identityUndeclaredClaimTrusted, imagesUrlSourceFromUserInput, indexReferencesUnknownField, indexUtilization, insertManyUnsafeUserData, kvUnscopedUserKeyIdor, loadAnalyticsRuntimeMetrics, mailInboundDispatchWithoutVerify, mailRecipientFromRequestInput, maskUncoveredPiiColumn, maskWeakHashStrategyOnPii, maskedRelationLeakViaWith, mutatorFullRowReplace, nondeterministicQueryMutation, normalizeIdUsedAsAuthorization, notifyMissingPushConfig, notifySendOutsideAction, outputProjectionMissingOnPublicRead, ownerFieldFromArgsNotAuth, paymentCreateWithoutAuthorize, paymentWebhookWideTolerance, plaintextSecretInWranglerVariables, policyReferencesUnknownTable, privilegedDispatchUnvalidatedPayload, privilegedFanoutFromPublicProcedure, publicArgumentUsesAny, publicMutationWithoutRatelimit, publicTableRlsOptoutConfusion, queueWithoutDlq, r2sqlOutsideAction, ratelimitDefaultMemoryStore, ratelimitKeySpoofableOrGlobal, ratelimitMiddlewareFailOpen, relationReferencesUnknownField, relationReferencesUnknownTable, rlsUncoveredTable, runAdvisor, shapeTargetsGlobalTable, shapeUnknownTable, signupMutationWithoutDisposableGating, softDeleteIncludeDeletedFromArgs, sqlInjectionRisk, storageGenerateUploadUrlNoContentTypePin, storageKeyFromUserArgs, storagePresignedUrlForPrivateContent, storageUploadWithoutContentTypeAllowlist, storageUploadWithoutMaxSize, tableWithoutInsert, ttlFieldNotTimestamp, unboundedStringArgument, unindexedForeignKey, unindexedRelationTarget, unrestrictedWhereBranch, userCreatingMutationWithoutCaptcha, vectorsNamespaceFromUserInput, workflowDuplicateStepName, workflowUnknownTarget, workflowUnused };
|
|
4352
|
+
export { AE_METRIC_EVENTS, ALL_LINTS, type AdvisorAdminRoute, type AdvisorAiRawRun, type AdvisorAiToolSideEffect, type AdvisorArgumentDerivedFetch, type AdvisorArgumentValidator, type AdvisorAuthApiCall, type AdvisorAuthConfig, type AdvisorBrowserUrlAccess, type AdvisorConfigCall, type AdvisorContainer, type AdvisorContainerKeyAccess, type AdvisorContainerOverride, type AdvisorExportSink, type AdvisorFailOpenGuard, type AdvisorFlagSecurityDefault, type AdvisorGeoIndexUsage, type AdvisorHttpActionGuard, type AdvisorHttpHeaderWrite, type AdvisorHyperdriveCall, type AdvisorIdentityClaimRead, type AdvisorImageDeliveryUrlAccess, type AdvisorIndex, type AdvisorIndexHit, type AdvisorInsertWrite, type AdvisorKvKeyAccess, type AdvisorMailRecipientAccess, type AdvisorMap, type AdvisorMaskProcedure, type AdvisorMaskStrategy, type AdvisorMutatorWrite, type AdvisorNondeterministicCall, type AdvisorNormalizeIdAuthorization, type AdvisorNotifyCall, type AdvisorNotifyConfig, type AdvisorOwnerFieldWrite, type AdvisorPaymentWebhook, type AdvisorPrivilegedDispatch, type AdvisorProcedureProtection, type AdvisorQueryRead, type AdvisorQueue, type AdvisorQueueTuning, type AdvisorR2sqlCall, type AdvisorRatelimitKeySelector, type AdvisorRawRowReturn, type AdvisorRelation, type AdvisorRelationLoad, type AdvisorRlsProcedure, type AdvisorSchema, type AdvisorSecretLiteral, type AdvisorShape, type AdvisorShardTraffic, type AdvisorSoftDeleteRead, type AdvisorSqlInterpolation, type AdvisorStorageKeyAccess, type AdvisorStorageUpload, type AdvisorTable, type AdvisorTableSample, type AdvisorTableScan, type AdvisorVectorNamespaceAccess, type AdvisorWorkflow, type AdvisorWorkflowCall, type AdvisorWranglerVariable, type AnalyticsMetricsOptions, type AnalyticsMetricsSource, type AnalyticsRuntimeMetrics, type BaselineComparison, type Category, type CheckResult, type Coverage, type Facing, type Finding, type Grade, type Level, type Lint, type LintContext, type LintSource, MAP_VERSION, type MapSummary, type ProcedureDelta, type ProcedureScore, type ProjectScore, RUNTIME_LINTS, RunAdvisorOptions, STATIC_LINTS, type ScoreAdvisorOptions, type Sensitivity, type SensitivityLevel, actionFetchSsrf, actionWithoutErrorHandling, adminRouteWithoutGuard, aiRawRunEscapeHatch, aiRunWithoutLogging, aiToolSideEffectPromptInjection, aiUnboundedGenerationPublic, allowUnauthenticatedShardAccessEnabled, authApiCallWithoutHeaders, authCsrfCheckDisabled, authEmailVerificationDisabled, authScimWithoutTransactions, authSecureCookiesDisabled, authSessionFreshageZero, authTrustedOriginsWildcard, browserAllowPrivateTargets, browserUserUrlWithoutAllowlist, byCodepoint, circularFk, classifySensitivity, compareToBaseline, constraintValidator, containerInstanceKeyFromUserInput, containerOversizedInstance, containerPublicInternet, containerRuntimeEgressRelaxation, containerStartEnableInternetOverride, dedupeCacheKeys, duplicateIndex, emptyIndex, errorWithoutCatalog, exportSinkMisconfigured, externalSourceIncrementalNoDeletePath, externalSourceOnGlobal, externalSourceUnscoped, filterWithoutIndex, flagGatesSecurityWithUnsafeDefault, fromServerSchema, geoIndexFieldNotGeopoint, geoIndexUnused, gradeFromScore, hardcodedSecret, hotShard, httpActionMissingAuthGuard, httpActionResponseHeaderInjection, hyperdriveOutsideAction, identityUndeclaredClaimTrusted, imagesUrlSourceFromUserInput, indexReferencesUnknownField, indexUtilization, insertManyUnsafeUserData, kvUnscopedUserKeyIdor, loadAnalyticsRuntimeMetrics, mailInboundDispatchWithoutVerify, mailRecipientFromRequestInput, maskUncoveredPiiColumn, maskWeakHashStrategyOnPii, maskedRelationLeakViaWith, mutatorFullRowReplace, nondeterministicQueryMutation, normalizeIdUsedAsAuthorization, notifyMissingPushConfig, notifySendOutsideAction, outputProjectionMissingOnPublicRead, ownerFieldFromArgsNotAuth, parseAdvisorMap, paymentCreateWithoutAuthorize, paymentWebhookWideTolerance, plaintextSecretInWranglerVariables, policyReferencesUnknownTable, privilegedDispatchUnvalidatedPayload, privilegedFanoutFromPublicProcedure, procedureWithoutStructuredEvent, publicArgumentUsesAny, publicMutationWithoutRatelimit, publicTableRlsOptoutConfusion, queueWithoutDlq, r2sqlOutsideAction, ratelimitDefaultMemoryStore, ratelimitKeySpoofableOrGlobal, ratelimitMiddlewareFailOpen, relationReferencesUnknownField, relationReferencesUnknownTable, rlsUncoveredTable, runAdvisor, scoreAdvisor, shapeTargetsGlobalTable, shapeUnknownTable, signupMutationWithoutDisposableGating, softDeleteIncludeDeletedFromArgs, sqlInjectionRisk, storageGenerateUploadUrlNoContentTypePin, storageKeyFromUserArgs, storagePresignedUrlForPrivateContent, storageUploadWithoutContentTypeAllowlist, storageUploadWithoutMaxSize, tableWithoutInsert, ttlFieldNotTimestamp, unboundedStringArgument, unindexedForeignKey, unindexedRelationTarget, unrestrictedWhereBranch, userCreatingMutationWithoutCaptcha, vectorsNamespaceFromUserInput, workflowDuplicateStepName, workflowUnknownTarget, workflowUnused };
|