@lunora/advisor 1.0.0-alpha.205 → 1.0.0-alpha.207

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 (61) hide show
  1. package/dist/index.d.mts +135 -11
  2. package/dist/index.d.ts +135 -11
  3. package/dist/index.mjs +1 -1
  4. package/dist/packem_shared/{actionFetchSsrf-B4ZaOBlW.mjs → actionFetchSsrf-Ckr3MZNs.mjs} +1 -1
  5. package/dist/packem_shared/{aiRawRunEscapeHatch-B5980eT9.mjs → aiRawRunEscapeHatch-kE49dAwE.mjs} +1 -1
  6. package/dist/packem_shared/{aiToolSideEffectPromptInjection-_3MrX9Ul.mjs → aiToolSideEffectPromptInjection-BZLjJ5Cy.mjs} +1 -1
  7. package/dist/packem_shared/{authApiCallWithoutHeaders-D8U1hv8s.mjs → authApiCallWithoutHeaders-HbSNJ0Hc.mjs} +1 -1
  8. package/dist/packem_shared/{authCsrfCheckDisabled-C6bxME5y.mjs → authCsrfCheckDisabled-KwbenvXt.mjs} +1 -1
  9. package/dist/packem_shared/{authEmailVerificationDisabled-yROPDgn-.mjs → authEmailVerificationDisabled-JBOb3BF8.mjs} +1 -1
  10. package/dist/packem_shared/{authScimWithoutTransactions-w9qb3iBe.mjs → authScimWithoutTransactions-CCYuq6pk.mjs} +1 -1
  11. package/dist/packem_shared/{authSecureCookiesDisabled-qrCktlch.mjs → authSecureCookiesDisabled-unvM30AR.mjs} +1 -1
  12. package/dist/packem_shared/{authSessionFreshageZero-BMisjIIS.mjs → authSessionFreshageZero-CBzcaids.mjs} +1 -1
  13. package/dist/packem_shared/{authTrustedOriginsWildcard-DFDpfN84.mjs → authTrustedOriginsWildcard-Czbv3hzH.mjs} +1 -1
  14. package/dist/packem_shared/{browserUserUrlWithoutAllowlist-CcK27rvt.mjs → browserUserUrlWithoutAllowlist-CsA_4hLR.mjs} +1 -1
  15. package/dist/packem_shared/{containerInstanceKeyFromUserInput-DBdjUnQb.mjs → containerInstanceKeyFromUserInput-CQPWh9L_.mjs} +1 -1
  16. package/dist/packem_shared/{containerRuntimeEgressRelaxation-CioCA2zY.mjs → containerRuntimeEgressRelaxation-BU4-7YkE.mjs} +1 -1
  17. package/dist/packem_shared/{containerStartEnableInternetOverride-C6dbznku.mjs → containerStartEnableInternetOverride-BHglJwGb.mjs} +1 -1
  18. package/dist/packem_shared/filterAfterIndexScan-Di_Zsrj7.mjs +1 -0
  19. package/dist/packem_shared/{filterOnPrimaryKey-DbFriOZA.mjs → filterOnPrimaryKey-C3N-wvB_.mjs} +1 -1
  20. package/dist/packem_shared/{filterWithoutIndex-Dc7Nn0y2.mjs → filterWithoutIndex-BgUUzQSY.mjs} +1 -1
  21. package/dist/packem_shared/{flagGatesSecurityWithUnsafeDefault-DB9M6hLM.mjs → flagGatesSecurityWithUnsafeDefault-tQivheR5.mjs} +1 -1
  22. package/dist/packem_shared/{geoIndexFieldNotGeopoint-CDMNbAfp.mjs → geoIndexFieldNotGeopoint-B_3rAicD.mjs} +1 -1
  23. package/dist/packem_shared/helpers-BwOMPdUk.mjs +1 -0
  24. package/dist/packem_shared/{httpActionMissingAuthGuard-BhvcmkwW.mjs → httpActionMissingAuthGuard-CqS3GLB1.mjs} +1 -1
  25. package/dist/packem_shared/{httpActionResponseHeaderInjection-DKz2SlCa.mjs → httpActionResponseHeaderInjection-Daul1_t3.mjs} +1 -1
  26. package/dist/packem_shared/{identityUndeclaredClaimTrusted-CAUagXkJ.mjs → identityUndeclaredClaimTrusted-DzgQiHe1.mjs} +1 -1
  27. package/dist/packem_shared/{imagesUrlSourceFromUserInput-C2CJTTCI.mjs → imagesUrlSourceFromUserInput-DE5goRdp.mjs} +1 -1
  28. package/dist/packem_shared/{indexReferencesUnknownField-Dm8SL4Tp.mjs → indexReferencesUnknownField-Dve5ViiG.mjs} +1 -1
  29. package/dist/packem_shared/{kvUnscopedUserKeyIdor-CXFKAyM2.mjs → kvUnscopedUserKeyIdor-CJOTcIoG.mjs} +1 -1
  30. package/dist/packem_shared/{mailRecipientFromRequestInput-CQZeOsP9.mjs → mailRecipientFromRequestInput-C1G95HJQ.mjs} +1 -1
  31. package/dist/packem_shared/{maskWeakHashStrategyOnPii-njstapQY.mjs → maskWeakHashStrategyOnPii-Ul325weF.mjs} +1 -1
  32. package/dist/packem_shared/nondeterministicQueryMutation-Bbb-AGOS.mjs +1 -0
  33. package/dist/packem_shared/{outputProjectionMissingOnPublicRead-DHivs_73.mjs → outputProjectionMissingOnPublicRead-DfGQfxaK.mjs} +1 -1
  34. package/dist/packem_shared/{ownerFieldFromArgsNotAuth-lgjS8mdd.mjs → ownerFieldFromArgsNotAuth-D1VEIgac.mjs} +1 -1
  35. package/dist/packem_shared/paymentCreateWithoutAuthorize-CdenWpXD.mjs +1 -0
  36. package/dist/packem_shared/{paymentWebhookWideTolerance-CtZb2AVA.mjs → paymentWebhookWideTolerance-Bm10PglC.mjs} +1 -1
  37. package/dist/packem_shared/{privilegedDispatchUnvalidatedPayload-DlJovHrt.mjs → privilegedDispatchUnvalidatedPayload-G-9sV5zL.mjs} +1 -1
  38. package/dist/packem_shared/{publicMutationWithoutRatelimit-BeYapu1F.mjs → publicMutationWithoutRatelimit-DQj1xkax.mjs} +1 -1
  39. package/dist/packem_shared/{publicTableRlsOptoutConfusion-BFmh1kH0.mjs → publicTableRlsOptoutConfusion-DUXkgvhl.mjs} +1 -1
  40. package/dist/packem_shared/{ratelimitKeySpoofableOrGlobal-DlvJfSXs.mjs → ratelimitKeySpoofableOrGlobal-J6uHCtnZ.mjs} +1 -1
  41. package/dist/packem_shared/{ratelimitMiddlewareFailOpen-DGtyt-pc.mjs → ratelimitMiddlewareFailOpen-C4ha9Kkp.mjs} +1 -1
  42. package/dist/packem_shared/{relationReferencesUnknownField-CqGEJD57.mjs → relationReferencesUnknownField-BkS_YTgj.mjs} +1 -1
  43. package/dist/packem_shared/selfRescheduleWithoutProgress-BQIKeW3m.mjs +1 -0
  44. package/dist/packem_shared/{signupMutationWithoutDisposableGating-CFtFMJz8.mjs → signupMutationWithoutDisposableGating-CKES8QJL.mjs} +1 -1
  45. package/dist/packem_shared/{sqlInjectionRisk-y-7c46LJ.mjs → sqlInjectionRisk-CoTZ127r.mjs} +1 -1
  46. package/dist/packem_shared/{storageGenerateUploadUrlNoContentTypePin-Bx9oGOjM.mjs → storageGenerateUploadUrlNoContentTypePin-BAmzI6ru.mjs} +1 -1
  47. package/dist/packem_shared/{storageKeyFromUserArgs-BryKJJM-.mjs → storageKeyFromUserArgs-jwnnKvrm.mjs} +1 -1
  48. package/dist/packem_shared/{storagePresignedUrlForPrivateContent-lqE6LvNu.mjs → storagePresignedUrlForPrivateContent-CfTyQxW3.mjs} +1 -1
  49. package/dist/packem_shared/{storageUploadWithoutContentTypeAllowlist-DMr7w29r.mjs → storageUploadWithoutContentTypeAllowlist-CkkuOKU4.mjs} +1 -1
  50. package/dist/packem_shared/{storageUploadWithoutMaxSize-rSNFNb2l.mjs → storageUploadWithoutMaxSize-Bz521ysH.mjs} +1 -1
  51. package/dist/packem_shared/sweeps-BXSVvIW-.mjs +1 -0
  52. package/dist/packem_shared/{ttlFieldNotTimestamp-Dxa-6RfM.mjs → ttlFieldNotTimestamp-obKZetLE.mjs} +1 -1
  53. package/dist/packem_shared/unboundedCollectOnOpenRange-ClpZwgAd.mjs +1 -0
  54. package/dist/packem_shared/{unboundedLoop-BqbZ7boE.mjs → unboundedLoop-DQBL-C0q.mjs} +1 -1
  55. package/dist/packem_shared/{userCreatingMutationWithoutCaptcha-C8yaqIIj.mjs → userCreatingMutationWithoutCaptcha-CLE-QBZ9.mjs} +1 -1
  56. package/dist/packem_shared/{vectorsNamespaceFromUserInput-7I_Kwxvp.mjs → vectorsNamespaceFromUserInput-hCNg2Slm.mjs} +1 -1
  57. package/dist/packem_shared/{workflowUnknownTarget-Cm1hfTTs.mjs → workflowUnknownTarget-O1U8Kwvc.mjs} +1 -1
  58. package/package.json +2 -2
  59. package/dist/packem_shared/helpers-BmppB5nL.mjs +0 -1
  60. package/dist/packem_shared/nondeterministicQueryMutation-sxmixc0l.mjs +0 -1
  61. package/dist/packem_shared/paymentCreateWithoutAuthorize-CICGmRFR.mjs +0 -1
package/dist/index.d.mts CHANGED
@@ -287,6 +287,15 @@ interface AdvisorCallEdge {
287
287
  line: number;
288
288
  /** Why the target could not be read statically — set exactly when `target` is absent. */
289
289
  reason?: string;
290
+ /**
291
+ * The facts of a scheduled dispatch, present on `schedule` edges only. `delayMs` is
292
+ * the literal `runAfter` delay. `argKeys` are the top-level property names of the
293
+ * args object, `[]` when there are none, and `undefined` when they cannot be read.
294
+ */
295
+ schedule?: {
296
+ argKeys?: string[];
297
+ delayMs?: number;
298
+ };
290
299
  /** Who the site runs on behalf of — see {@link AdvisorCallSiteScope}. */
291
300
  scope: AdvisorCallSiteScope;
292
301
  /** The `namespace:export` function key (or queue/topic/service name) the edge points at. */
@@ -716,6 +725,11 @@ interface AdvisorInsertWrite {
716
725
  * input alongside {@link AdvisorInsertWrite}.
717
726
  */
718
727
  interface AdvisorTableWrite extends AdvisorInsertWrite {
728
+ /**
729
+ * The fields a `patch` / `patchMany` writes, or `undefined` for any other method
730
+ * and when the patch argument is not an object literal.
731
+ */
732
+ fields?: string[];
719
733
  /** The writer method called, e.g. `patch`, `deleteMany`, `upsert`. */
720
734
  method: string;
721
735
  }
@@ -1211,6 +1225,11 @@ interface AdvisorProcedureProtection {
1211
1225
  interface AdvisorQueryRead {
1212
1226
  /** Source file the read appears in (relative to the lunora dir, no extension). */
1213
1227
  file: string;
1228
+ /**
1229
+ * The fields the `.filter(...)` predicate reads off its row parameter. `undefined`
1230
+ * when there is no filter or the predicate is not a function literal.
1231
+ */
1232
+ filterFields?: string[];
1214
1233
  /**
1215
1234
  * True when the chain's `.filter()` predicate compares `_id`
1216
1235
  * (`(d) => d._id === args.id`) — a full scan for a row that `ctx.db.get`
@@ -1222,6 +1241,16 @@ interface AdvisorQueryRead {
1222
1241
  hasFilter: boolean;
1223
1242
  /** True when the chain narrows with `.withIndex(...)` or `.withSearchIndex(...)`. */
1224
1243
  hasIndex: boolean;
1244
+ /**
1245
+ * The chain's `.withIndex(...)`, present exactly when the chain has one. `name` is
1246
+ * the literal index name, or `undefined` when it is not a string literal. `bounds`
1247
+ * are the comparators its range callback calls: `[]` for a bare `.withIndex(name)`
1248
+ * (an open range), `undefined` when the callback cannot be read.
1249
+ */
1250
+ index?: {
1251
+ bounds?: string[];
1252
+ name?: string;
1253
+ };
1225
1254
  /** 1-based line of the `query(...)` call, or `0` when unknown. */
1226
1255
  line: number;
1227
1256
  /** Who the site runs on behalf of — see {@link AdvisorCallSiteScope}. */
@@ -1240,6 +1269,12 @@ interface AdvisorQueryRead {
1240
1269
  * rather than guessing a terminal.
1241
1270
  */
1242
1271
  terminal?: string;
1272
+ /**
1273
+ * Visibility of the procedure the read runs on behalf of: `internal` when every
1274
+ * caller is internal, `public` when any caller is public. `undefined` when the
1275
+ * feeder could not read the registered functions.
1276
+ */
1277
+ visibility?: "internal" | "public";
1243
1278
  }
1244
1279
  /**
1245
1280
  * The queue-shaped input the `queue_*` lints consume, produced by the codegen
@@ -1410,6 +1445,24 @@ interface AdvisorRlsProcedure {
1410
1445
  /** `"internal"` when the procedure uses `internalQuery` / `internalMutation` / `internalAction`. */
1411
1446
  visibility: "internal" | "public";
1412
1447
  }
1448
+ /**
1449
+ * A row-changing write an EXPORT can reach, directly or through the functions it
1450
+ * calls, possibly in another file. Produced by the codegen feeder; the sweep lints
1451
+ * read it to tell a function that removes rows from the one that only reads them.
1452
+ * Runtime callers don't supply it, so the lints then see no progress from helpers.
1453
+ */
1454
+ interface AdvisorRowEffect {
1455
+ /** The export the write is reachable from. */
1456
+ exportName: string;
1457
+ /** The fields a `patch` writes, or `undefined` when they cannot be read. */
1458
+ fields?: string[];
1459
+ /** Source file of that export, relative to the lunora dir, without extension. */
1460
+ file: string;
1461
+ /** The write method, e.g. `delete`, `patch`, `replace`. */
1462
+ method: string;
1463
+ /** The table the write targets. Never `""`. */
1464
+ table: string;
1465
+ }
1413
1466
  /**
1414
1467
  * Normalized, feeder-agnostic view of a schema that lints run against. Both the
1415
1468
  * runtime `@lunora/server` {@link Schema} (record-shaped) and `@lunora/codegen`'s
@@ -2082,6 +2135,12 @@ interface LintContext {
2082
2135
  * the container lints find nothing.
2083
2136
  */
2084
2137
  containers?: ReadonlyArray<AdvisorContainer>;
2138
+ /**
2139
+ * The `namespace:export` keys of the function-targeted cron jobs. A cron fires
2140
+ * its target without a request, so the target is server-driven even when it is
2141
+ * public. Supplied by the codegen feeder; absent for runtime callers.
2142
+ */
2143
+ cronTargets?: ReadonlyArray<string>;
2085
2144
  /**
2086
2145
  * CDC export-sink constructions (`defineExportSink` / `webhookExportSink` /
2087
2146
  * `r2Sink`) discovered in function bodies — the `export_sink_misconfigured`
@@ -2390,6 +2449,12 @@ interface LintContext {
2390
2449
  * runtime callers, where the lint finds nothing.
2391
2450
  */
2392
2451
  rlsProcedures?: ReadonlyArray<AdvisorRlsProcedure>;
2452
+ /**
2453
+ * Row-changing writes each export reaches, including writes in helpers it calls
2454
+ * (even in other files). The sweep lints count these as progress. Absent for
2455
+ * runtime callers, where a helper's write is then not seen.
2456
+ */
2457
+ rowEffects?: ReadonlyArray<AdvisorRowEffect>;
2393
2458
  /** The declared schema under audit, normalized to the feeder-agnostic {@link AdvisorSchema}. */
2394
2459
  schema: AdvisorSchema;
2395
2460
  /**
@@ -3230,6 +3295,26 @@ declare const externalSourceOnGlobal: Lint;
3230
3295
  * sourced declaration, or one not sharded, is skipped.
3231
3296
  */
3232
3297
  declare const externalSourceUnscoped: Lint;
3298
+ /**
3299
+ * Flags a `.withIndex(…)` read whose `.filter(…)` tests a field the index does not
3300
+ * cover. The index narrows the scan, and the filter then discards most of what it
3301
+ * read. Usually the index was meant to cover the filtered field, and the range is
3302
+ * just open. Extending the index with that field lets the read seek instead.
3303
+ *
3304
+ * `filter_without_index` covers the unindexed case. The `_id` part of a predicate is
3305
+ * not a column of any index: it is `filter_on_primary_key`'s, which points at
3306
+ * `ctx.db.get`, so `_id` is never reported here. A predicate that tests `_id` and an
3307
+ * uncovered field is still reported, for the field.
3308
+ *
3309
+ * Reported at INFO: a filter is sometimes the right tool, for a predicate an index
3310
+ * cannot express (a comparison on a second column, a computed value). The finding
3311
+ * asks the author to decide, rather than assuming the index is wrong. A read that is
3312
+ * a server-driven open-range sweep is left to `unbounded_collect_on_open_range`, which
3313
+ * reports the same fields, so each read gets one finding.
3314
+ *
3315
+ * Runs only when the codegen feeder supplied reads (`context.queries` present).
3316
+ */
3317
+ declare const filterAfterIndexScan: Lint;
3233
3318
  /**
3234
3319
  * Flags `ctx.db.query("t").filter((d) => d._id === x)` — a full scan for a row
3235
3320
  * that is directly addressable.
@@ -3874,18 +3959,16 @@ declare const ownerFieldFromArgsNotAuth: Lint;
3874
3959
  *
3875
3960
  * The `authorize(referenceId)` hook is `@lunora/payment`'s access-control gate: it
3876
3961
  * runs before every charge/refund/subscription operation and decides whether the
3877
- * current caller may act on that payment reference. Omit it and the guard is
3878
- * effectively open — any caller who can reach a reference id (often a
3879
- * client-supplied string) can drive money movement against someone else's
3880
- * payment, a broken-access-control (IDOR) escalation on the most sensitive
3881
- * surface an app has.
3962
+ * current caller may act on that payment reference. `createPayment` requires it,
3963
+ * and throws `CONFIG_INVALID` at construction when it is missing, so a config
3964
+ * without it fails at startup and no mutation runs. This lint reports that
3965
+ * config statically, before it ships.
3882
3966
  *
3883
3967
  * The context accessor `ctx.payments` is authorization-scoped by default; this
3884
- * lint targets the direct `createPayment(...)` factory, where the gate is
3885
- * opt-in. Runs only when the codegen feeder supplies config-call evidence
3886
- * (`context.configCalls`); a runtime caller flags nothing. Skips calls whose
3887
- * config wasn't a static object literal (the key may be set on a config built
3888
- * elsewhere). One finding per unguarded call.
3968
+ * lint targets the direct `createPayment(...)` factory. Runs only when the
3969
+ * codegen feeder supplies config-call evidence (`context.configCalls`); a runtime
3970
+ * caller flags nothing. Skips calls whose config wasn't a static object literal
3971
+ * (the key may be set on a config built elsewhere). One finding per unguarded call.
3889
3972
  */
3890
3973
  declare const paymentCreateWithoutAuthorize: Lint;
3891
3974
  /**
@@ -4220,6 +4303,25 @@ declare const relationReferencesUnknownTable: Lint;
4220
4303
  * constants, but it never over-reports (no false positives).
4221
4304
  */
4222
4305
  declare const rlsUncoveredTable: Lint;
4306
+ /**
4307
+ * Flags a function that re-arms itself on a short literal delay (`runAfter(…, self)`)
4308
+ * when the re-arming carries no progress. The next run would find the same rows and
4309
+ * start the same work again, as often as the delay allows.
4310
+ *
4311
+ * A finding is suppressed when the dispatch carries a cursor arg key (see `CURSOR_KEY`),
4312
+ * when the function removes a row it reads, itself or through a function it calls (a
4313
+ * delete or replace, or a patch of an index field), when it has no reads at all
4314
+ * (nothing is re-read), when it calls out to another function (`ctx.run*`, where the
4315
+ * progress may happen and this rule cannot see it), and when the args are not an object
4316
+ * literal (no evidence either way, so no finding).
4317
+ *
4318
+ * An unconditional self-dispatch is `dispatch_cycle`'s, which already reports it as
4319
+ * an error. This rule takes only the conditional ones, so each site gets one finding.
4320
+ * A longer delay is left alone: it is a poll, not a spin.
4321
+ *
4322
+ * Runs only when the codegen feeder supplied call edges (`context.callEdges` present).
4323
+ */
4324
+ declare const selfRescheduleWithoutProgress: Lint;
4223
4325
  /**
4224
4326
  * Flags a replication shape whose `table` is a `.global()` table.
4225
4327
  *
@@ -4492,6 +4594,28 @@ declare const topicTooManySubscriptions: Lint;
4492
4594
  * codegen time rather than at 3am when the sweep silently misbehaves.
4493
4595
  */
4494
4596
  declare const ttlFieldNotTimestamp: Lint;
4597
+ /**
4598
+ * Flags a server-driven `.withIndex(…).collect()` on an open range that nothing in
4599
+ * the same function makes progress on. The sweep itself is defined in `../sweeps`.
4600
+ *
4601
+ * Each run of such a sweep reads the whole open range again. The rows it found on
4602
+ * the last run are still there, so the next run selects them too, and the work
4603
+ * grows with the table. A `.take(n)` or `.paginate(…)` ends the chain in another
4604
+ * terminal, so this rule never sees those reads. A `.collect()` with no index at all
4605
+ * is `unbounded_collect`'s.
4606
+ *
4607
+ * Progress counts a delete or replace in the function or in anything it calls, and
4608
+ * a patch that writes an index field of the range. A patch of other fields leaves
4609
+ * the rows in range, so it does not count.
4610
+ *
4611
+ * When the read also filters on a field the index does not cover, the finding says
4612
+ * so. This rule and `filter_after_index_scan` agree on one finding per read: this
4613
+ * one asks for a bound, and the filter's own finding is suppressed.
4614
+ *
4615
+ * Runs only when the codegen feeder supplied reads (`context.queries` present);
4616
+ * a runtime caller supplies none and so flags nothing.
4617
+ */
4618
+ declare const unboundedCollectOnOpenRange: Lint;
4495
4619
  /**
4496
4620
  * Flags a literal-infinite loop — `while (true)`, `for (;;)` / `for (; true;)`,
4497
4621
  * `do { … } while (true)` — that has no statically reachable way out: no
@@ -4985,4 +5109,4 @@ interface RunAdvisorOptions {
4985
5109
  * `static` lints at build time and defer `runtime` lints to a live shard.
4986
5110
  */
4987
5111
  declare const runAdvisor: (context: LintContext, options?: RunAdvisorOptions) => Finding[];
4988
- export { ALL_LINTS, type AdvisorAdminRoute, type AdvisorAiRawRun, type AdvisorAiToolSideEffect, type AdvisorArgumentDerivedFetch, type AdvisorArgumentValidator, type AdvisorAuthApiCall, type AdvisorAuthConfig, type AdvisorBrowserUrlAccess, type AdvisorCallEdge, type AdvisorCallSiteScope, type AdvisorConfigCall, type AdvisorContainer, type AdvisorContainerKeyAccess, type AdvisorContainerOverride, type AdvisorExportSink, type AdvisorFailOpenGuard, type AdvisorFlagRead, 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 AdvisorModule, type AdvisorMutatorDeclaration, 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 AdvisorStaleMigrationImport, type AdvisorStorageKeyAccess, type AdvisorStorageUpload, type AdvisorTable, type AdvisorTableScan, type AdvisorTableWrite, type AdvisorUnboundedLoop, type AdvisorVectorNamespaceAccess, type AdvisorWorkflow, type AdvisorWorkflowCall, type AdvisorWranglerVariable, type AnalyticsMetricsOptions, type AnalyticsMetricsSource, type AnalyticsRuntimeMetrics, type BaselineComparison, type CallSiteMetadata, 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, callSiteCallers, callSiteDescription, callSiteLabel, callSiteMetadata, circularFk, classifySensitivity, commitOrderedHardDelete, compareToBaseline, containerInstanceKeyFromUserInput, containerOversizedInstance, containerPublicInternet, containerRuntimeEgressRelaxation, containerStartEnableInternetOverride, crossModuleTableWrite, dedupeCacheKeys, dispatchCycle, duplicateIndex, emptyIndex, errorWithoutCatalog, exportSinkMisconfigured, externalSourceIncrementalNoDeletePath, externalSourceOnGlobal, externalSourceUnscoped, fanOutBreadth, filterOnPrimaryKey, filterWithoutIndex, flagGatesSecurityWithUnsafeDefault, flagReadInSubscription, fromServerSchema, geoIndexFieldNotGeopoint, geoIndexUnused, globalTableNearColumnLimit, gradeFromScore, hardcodedSecret, helperRole, hotShard, httpActionMissingAuthGuard, httpActionResponseHeaderInjection, hyperdriveOutsideAction, identityUndeclaredClaimTrusted, imagesUrlSourceFromUserInput, indexReferencesUnknownField, indexUtilization, insertManyUnsafeUserData, isReachableSite, kvUnscopedUserKeyIdor, mailInboundDispatchWithoutVerify, mailRecipientFromRequestInput, maskUncoveredPiiColumn, maskWeakHashStrategyOnPii, maskedRelationLeakViaWith, mutatorFullRowReplace, mutatorWithoutOwnerScope, nondeterministicQueryMutation, normalizeIdUsedAsAuthorization, notifyMissingPushConfig, notifySendOutsideAction, outputProjectionMissingOnPublicRead, ownerFieldFromArgsNotAuth, parseAdvisorMap, paymentCreateWithoutAuthorize, paymentWebhookWideTolerance, plaintextSecretInWranglerVariables, policyReferencesUnknownTable, privilegedDispatchUnvalidatedPayload, privilegedFanoutFromPublicProcedure, procedureWithoutStructuredEvent, publicArgumentUsesAny, publicMutationWithoutRatelimit, publicTableRlsOptoutConfusion, queueWithoutDlq, r2sqlOutsideAction, ratelimitDefaultMemoryStore, ratelimitKeySpoofableOrGlobal, ratelimitMiddlewareFailOpen, readCallSiteCallers, relationReferencesUnknownField, relationReferencesUnknownTable, rlsUncoveredTable, runAdvisor, scoreAdvisor, shapeTargetsGlobalTable, shapeUnknownTable, signupMutationWithoutDisposableGating, softDeleteIncludeDeletedFromArgs, sqlInjectionRisk, storageGenerateUploadUrlNoContentTypePin, storageKeyFromUserArgs, storagePresignedUrlForPrivateContent, storageUploadWithoutContentTypeAllowlist, storageUploadWithoutMaxSize, tableWithoutInsert, topicTooManySubscriptions, ttlFieldNotTimestamp, unboundedLoop, unboundedStringArgument, unindexedForeignKey, unindexedRelationTarget, unrestrictedWhereBranch, userCreatingMutationWithoutCaptcha, vectorsNamespaceFromUserInput, workflowDuplicateStepName, workflowUnknownTarget, workflowUnused };
5112
+ export { ALL_LINTS, type AdvisorAdminRoute, type AdvisorAiRawRun, type AdvisorAiToolSideEffect, type AdvisorArgumentDerivedFetch, type AdvisorArgumentValidator, type AdvisorAuthApiCall, type AdvisorAuthConfig, type AdvisorBrowserUrlAccess, type AdvisorCallEdge, type AdvisorCallSiteScope, type AdvisorConfigCall, type AdvisorContainer, type AdvisorContainerKeyAccess, type AdvisorContainerOverride, type AdvisorExportSink, type AdvisorFailOpenGuard, type AdvisorFlagRead, 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 AdvisorModule, type AdvisorMutatorDeclaration, 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 AdvisorRowEffect, type AdvisorSchema, type AdvisorSecretLiteral, type AdvisorShape, type AdvisorShardTraffic, type AdvisorSoftDeleteRead, type AdvisorSqlInterpolation, type AdvisorStaleMigrationImport, type AdvisorStorageKeyAccess, type AdvisorStorageUpload, type AdvisorTable, type AdvisorTableScan, type AdvisorTableWrite, type AdvisorUnboundedLoop, type AdvisorVectorNamespaceAccess, type AdvisorWorkflow, type AdvisorWorkflowCall, type AdvisorWranglerVariable, type AnalyticsMetricsOptions, type AnalyticsMetricsSource, type AnalyticsRuntimeMetrics, type BaselineComparison, type CallSiteMetadata, 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, callSiteCallers, callSiteDescription, callSiteLabel, callSiteMetadata, circularFk, classifySensitivity, commitOrderedHardDelete, compareToBaseline, containerInstanceKeyFromUserInput, containerOversizedInstance, containerPublicInternet, containerRuntimeEgressRelaxation, containerStartEnableInternetOverride, crossModuleTableWrite, dedupeCacheKeys, dispatchCycle, duplicateIndex, emptyIndex, errorWithoutCatalog, exportSinkMisconfigured, externalSourceIncrementalNoDeletePath, externalSourceOnGlobal, externalSourceUnscoped, fanOutBreadth, filterAfterIndexScan, filterOnPrimaryKey, filterWithoutIndex, flagGatesSecurityWithUnsafeDefault, flagReadInSubscription, fromServerSchema, geoIndexFieldNotGeopoint, geoIndexUnused, globalTableNearColumnLimit, gradeFromScore, hardcodedSecret, helperRole, hotShard, httpActionMissingAuthGuard, httpActionResponseHeaderInjection, hyperdriveOutsideAction, identityUndeclaredClaimTrusted, imagesUrlSourceFromUserInput, indexReferencesUnknownField, indexUtilization, insertManyUnsafeUserData, isReachableSite, kvUnscopedUserKeyIdor, mailInboundDispatchWithoutVerify, mailRecipientFromRequestInput, maskUncoveredPiiColumn, maskWeakHashStrategyOnPii, maskedRelationLeakViaWith, mutatorFullRowReplace, mutatorWithoutOwnerScope, nondeterministicQueryMutation, normalizeIdUsedAsAuthorization, notifyMissingPushConfig, notifySendOutsideAction, outputProjectionMissingOnPublicRead, ownerFieldFromArgsNotAuth, parseAdvisorMap, paymentCreateWithoutAuthorize, paymentWebhookWideTolerance, plaintextSecretInWranglerVariables, policyReferencesUnknownTable, privilegedDispatchUnvalidatedPayload, privilegedFanoutFromPublicProcedure, procedureWithoutStructuredEvent, publicArgumentUsesAny, publicMutationWithoutRatelimit, publicTableRlsOptoutConfusion, queueWithoutDlq, r2sqlOutsideAction, ratelimitDefaultMemoryStore, ratelimitKeySpoofableOrGlobal, ratelimitMiddlewareFailOpen, readCallSiteCallers, relationReferencesUnknownField, relationReferencesUnknownTable, rlsUncoveredTable, runAdvisor, scoreAdvisor, selfRescheduleWithoutProgress, shapeTargetsGlobalTable, shapeUnknownTable, signupMutationWithoutDisposableGating, softDeleteIncludeDeletedFromArgs, sqlInjectionRisk, storageGenerateUploadUrlNoContentTypePin, storageKeyFromUserArgs, storagePresignedUrlForPrivateContent, storageUploadWithoutContentTypeAllowlist, storageUploadWithoutMaxSize, tableWithoutInsert, topicTooManySubscriptions, ttlFieldNotTimestamp, unboundedCollectOnOpenRange, unboundedLoop, unboundedStringArgument, unindexedForeignKey, unindexedRelationTarget, unrestrictedWhereBranch, userCreatingMutationWithoutCaptcha, vectorsNamespaceFromUserInput, workflowDuplicateStepName, workflowUnknownTarget, workflowUnused };
package/dist/index.d.ts CHANGED
@@ -287,6 +287,15 @@ interface AdvisorCallEdge {
287
287
  line: number;
288
288
  /** Why the target could not be read statically — set exactly when `target` is absent. */
289
289
  reason?: string;
290
+ /**
291
+ * The facts of a scheduled dispatch, present on `schedule` edges only. `delayMs` is
292
+ * the literal `runAfter` delay. `argKeys` are the top-level property names of the
293
+ * args object, `[]` when there are none, and `undefined` when they cannot be read.
294
+ */
295
+ schedule?: {
296
+ argKeys?: string[];
297
+ delayMs?: number;
298
+ };
290
299
  /** Who the site runs on behalf of — see {@link AdvisorCallSiteScope}. */
291
300
  scope: AdvisorCallSiteScope;
292
301
  /** The `namespace:export` function key (or queue/topic/service name) the edge points at. */
@@ -716,6 +725,11 @@ interface AdvisorInsertWrite {
716
725
  * input alongside {@link AdvisorInsertWrite}.
717
726
  */
718
727
  interface AdvisorTableWrite extends AdvisorInsertWrite {
728
+ /**
729
+ * The fields a `patch` / `patchMany` writes, or `undefined` for any other method
730
+ * and when the patch argument is not an object literal.
731
+ */
732
+ fields?: string[];
719
733
  /** The writer method called, e.g. `patch`, `deleteMany`, `upsert`. */
720
734
  method: string;
721
735
  }
@@ -1211,6 +1225,11 @@ interface AdvisorProcedureProtection {
1211
1225
  interface AdvisorQueryRead {
1212
1226
  /** Source file the read appears in (relative to the lunora dir, no extension). */
1213
1227
  file: string;
1228
+ /**
1229
+ * The fields the `.filter(...)` predicate reads off its row parameter. `undefined`
1230
+ * when there is no filter or the predicate is not a function literal.
1231
+ */
1232
+ filterFields?: string[];
1214
1233
  /**
1215
1234
  * True when the chain's `.filter()` predicate compares `_id`
1216
1235
  * (`(d) => d._id === args.id`) — a full scan for a row that `ctx.db.get`
@@ -1222,6 +1241,16 @@ interface AdvisorQueryRead {
1222
1241
  hasFilter: boolean;
1223
1242
  /** True when the chain narrows with `.withIndex(...)` or `.withSearchIndex(...)`. */
1224
1243
  hasIndex: boolean;
1244
+ /**
1245
+ * The chain's `.withIndex(...)`, present exactly when the chain has one. `name` is
1246
+ * the literal index name, or `undefined` when it is not a string literal. `bounds`
1247
+ * are the comparators its range callback calls: `[]` for a bare `.withIndex(name)`
1248
+ * (an open range), `undefined` when the callback cannot be read.
1249
+ */
1250
+ index?: {
1251
+ bounds?: string[];
1252
+ name?: string;
1253
+ };
1225
1254
  /** 1-based line of the `query(...)` call, or `0` when unknown. */
1226
1255
  line: number;
1227
1256
  /** Who the site runs on behalf of — see {@link AdvisorCallSiteScope}. */
@@ -1240,6 +1269,12 @@ interface AdvisorQueryRead {
1240
1269
  * rather than guessing a terminal.
1241
1270
  */
1242
1271
  terminal?: string;
1272
+ /**
1273
+ * Visibility of the procedure the read runs on behalf of: `internal` when every
1274
+ * caller is internal, `public` when any caller is public. `undefined` when the
1275
+ * feeder could not read the registered functions.
1276
+ */
1277
+ visibility?: "internal" | "public";
1243
1278
  }
1244
1279
  /**
1245
1280
  * The queue-shaped input the `queue_*` lints consume, produced by the codegen
@@ -1410,6 +1445,24 @@ interface AdvisorRlsProcedure {
1410
1445
  /** `"internal"` when the procedure uses `internalQuery` / `internalMutation` / `internalAction`. */
1411
1446
  visibility: "internal" | "public";
1412
1447
  }
1448
+ /**
1449
+ * A row-changing write an EXPORT can reach, directly or through the functions it
1450
+ * calls, possibly in another file. Produced by the codegen feeder; the sweep lints
1451
+ * read it to tell a function that removes rows from the one that only reads them.
1452
+ * Runtime callers don't supply it, so the lints then see no progress from helpers.
1453
+ */
1454
+ interface AdvisorRowEffect {
1455
+ /** The export the write is reachable from. */
1456
+ exportName: string;
1457
+ /** The fields a `patch` writes, or `undefined` when they cannot be read. */
1458
+ fields?: string[];
1459
+ /** Source file of that export, relative to the lunora dir, without extension. */
1460
+ file: string;
1461
+ /** The write method, e.g. `delete`, `patch`, `replace`. */
1462
+ method: string;
1463
+ /** The table the write targets. Never `""`. */
1464
+ table: string;
1465
+ }
1413
1466
  /**
1414
1467
  * Normalized, feeder-agnostic view of a schema that lints run against. Both the
1415
1468
  * runtime `@lunora/server` {@link Schema} (record-shaped) and `@lunora/codegen`'s
@@ -2082,6 +2135,12 @@ interface LintContext {
2082
2135
  * the container lints find nothing.
2083
2136
  */
2084
2137
  containers?: ReadonlyArray<AdvisorContainer>;
2138
+ /**
2139
+ * The `namespace:export` keys of the function-targeted cron jobs. A cron fires
2140
+ * its target without a request, so the target is server-driven even when it is
2141
+ * public. Supplied by the codegen feeder; absent for runtime callers.
2142
+ */
2143
+ cronTargets?: ReadonlyArray<string>;
2085
2144
  /**
2086
2145
  * CDC export-sink constructions (`defineExportSink` / `webhookExportSink` /
2087
2146
  * `r2Sink`) discovered in function bodies — the `export_sink_misconfigured`
@@ -2390,6 +2449,12 @@ interface LintContext {
2390
2449
  * runtime callers, where the lint finds nothing.
2391
2450
  */
2392
2451
  rlsProcedures?: ReadonlyArray<AdvisorRlsProcedure>;
2452
+ /**
2453
+ * Row-changing writes each export reaches, including writes in helpers it calls
2454
+ * (even in other files). The sweep lints count these as progress. Absent for
2455
+ * runtime callers, where a helper's write is then not seen.
2456
+ */
2457
+ rowEffects?: ReadonlyArray<AdvisorRowEffect>;
2393
2458
  /** The declared schema under audit, normalized to the feeder-agnostic {@link AdvisorSchema}. */
2394
2459
  schema: AdvisorSchema;
2395
2460
  /**
@@ -3230,6 +3295,26 @@ declare const externalSourceOnGlobal: Lint;
3230
3295
  * sourced declaration, or one not sharded, is skipped.
3231
3296
  */
3232
3297
  declare const externalSourceUnscoped: Lint;
3298
+ /**
3299
+ * Flags a `.withIndex(…)` read whose `.filter(…)` tests a field the index does not
3300
+ * cover. The index narrows the scan, and the filter then discards most of what it
3301
+ * read. Usually the index was meant to cover the filtered field, and the range is
3302
+ * just open. Extending the index with that field lets the read seek instead.
3303
+ *
3304
+ * `filter_without_index` covers the unindexed case. The `_id` part of a predicate is
3305
+ * not a column of any index: it is `filter_on_primary_key`'s, which points at
3306
+ * `ctx.db.get`, so `_id` is never reported here. A predicate that tests `_id` and an
3307
+ * uncovered field is still reported, for the field.
3308
+ *
3309
+ * Reported at INFO: a filter is sometimes the right tool, for a predicate an index
3310
+ * cannot express (a comparison on a second column, a computed value). The finding
3311
+ * asks the author to decide, rather than assuming the index is wrong. A read that is
3312
+ * a server-driven open-range sweep is left to `unbounded_collect_on_open_range`, which
3313
+ * reports the same fields, so each read gets one finding.
3314
+ *
3315
+ * Runs only when the codegen feeder supplied reads (`context.queries` present).
3316
+ */
3317
+ declare const filterAfterIndexScan: Lint;
3233
3318
  /**
3234
3319
  * Flags `ctx.db.query("t").filter((d) => d._id === x)` — a full scan for a row
3235
3320
  * that is directly addressable.
@@ -3874,18 +3959,16 @@ declare const ownerFieldFromArgsNotAuth: Lint;
3874
3959
  *
3875
3960
  * The `authorize(referenceId)` hook is `@lunora/payment`'s access-control gate: it
3876
3961
  * runs before every charge/refund/subscription operation and decides whether the
3877
- * current caller may act on that payment reference. Omit it and the guard is
3878
- * effectively open — any caller who can reach a reference id (often a
3879
- * client-supplied string) can drive money movement against someone else's
3880
- * payment, a broken-access-control (IDOR) escalation on the most sensitive
3881
- * surface an app has.
3962
+ * current caller may act on that payment reference. `createPayment` requires it,
3963
+ * and throws `CONFIG_INVALID` at construction when it is missing, so a config
3964
+ * without it fails at startup and no mutation runs. This lint reports that
3965
+ * config statically, before it ships.
3882
3966
  *
3883
3967
  * The context accessor `ctx.payments` is authorization-scoped by default; this
3884
- * lint targets the direct `createPayment(...)` factory, where the gate is
3885
- * opt-in. Runs only when the codegen feeder supplies config-call evidence
3886
- * (`context.configCalls`); a runtime caller flags nothing. Skips calls whose
3887
- * config wasn't a static object literal (the key may be set on a config built
3888
- * elsewhere). One finding per unguarded call.
3968
+ * lint targets the direct `createPayment(...)` factory. Runs only when the
3969
+ * codegen feeder supplies config-call evidence (`context.configCalls`); a runtime
3970
+ * caller flags nothing. Skips calls whose config wasn't a static object literal
3971
+ * (the key may be set on a config built elsewhere). One finding per unguarded call.
3889
3972
  */
3890
3973
  declare const paymentCreateWithoutAuthorize: Lint;
3891
3974
  /**
@@ -4220,6 +4303,25 @@ declare const relationReferencesUnknownTable: Lint;
4220
4303
  * constants, but it never over-reports (no false positives).
4221
4304
  */
4222
4305
  declare const rlsUncoveredTable: Lint;
4306
+ /**
4307
+ * Flags a function that re-arms itself on a short literal delay (`runAfter(…, self)`)
4308
+ * when the re-arming carries no progress. The next run would find the same rows and
4309
+ * start the same work again, as often as the delay allows.
4310
+ *
4311
+ * A finding is suppressed when the dispatch carries a cursor arg key (see `CURSOR_KEY`),
4312
+ * when the function removes a row it reads, itself or through a function it calls (a
4313
+ * delete or replace, or a patch of an index field), when it has no reads at all
4314
+ * (nothing is re-read), when it calls out to another function (`ctx.run*`, where the
4315
+ * progress may happen and this rule cannot see it), and when the args are not an object
4316
+ * literal (no evidence either way, so no finding).
4317
+ *
4318
+ * An unconditional self-dispatch is `dispatch_cycle`'s, which already reports it as
4319
+ * an error. This rule takes only the conditional ones, so each site gets one finding.
4320
+ * A longer delay is left alone: it is a poll, not a spin.
4321
+ *
4322
+ * Runs only when the codegen feeder supplied call edges (`context.callEdges` present).
4323
+ */
4324
+ declare const selfRescheduleWithoutProgress: Lint;
4223
4325
  /**
4224
4326
  * Flags a replication shape whose `table` is a `.global()` table.
4225
4327
  *
@@ -4492,6 +4594,28 @@ declare const topicTooManySubscriptions: Lint;
4492
4594
  * codegen time rather than at 3am when the sweep silently misbehaves.
4493
4595
  */
4494
4596
  declare const ttlFieldNotTimestamp: Lint;
4597
+ /**
4598
+ * Flags a server-driven `.withIndex(…).collect()` on an open range that nothing in
4599
+ * the same function makes progress on. The sweep itself is defined in `../sweeps`.
4600
+ *
4601
+ * Each run of such a sweep reads the whole open range again. The rows it found on
4602
+ * the last run are still there, so the next run selects them too, and the work
4603
+ * grows with the table. A `.take(n)` or `.paginate(…)` ends the chain in another
4604
+ * terminal, so this rule never sees those reads. A `.collect()` with no index at all
4605
+ * is `unbounded_collect`'s.
4606
+ *
4607
+ * Progress counts a delete or replace in the function or in anything it calls, and
4608
+ * a patch that writes an index field of the range. A patch of other fields leaves
4609
+ * the rows in range, so it does not count.
4610
+ *
4611
+ * When the read also filters on a field the index does not cover, the finding says
4612
+ * so. This rule and `filter_after_index_scan` agree on one finding per read: this
4613
+ * one asks for a bound, and the filter's own finding is suppressed.
4614
+ *
4615
+ * Runs only when the codegen feeder supplied reads (`context.queries` present);
4616
+ * a runtime caller supplies none and so flags nothing.
4617
+ */
4618
+ declare const unboundedCollectOnOpenRange: Lint;
4495
4619
  /**
4496
4620
  * Flags a literal-infinite loop — `while (true)`, `for (;;)` / `for (; true;)`,
4497
4621
  * `do { … } while (true)` — that has no statically reachable way out: no
@@ -4985,4 +5109,4 @@ interface RunAdvisorOptions {
4985
5109
  * `static` lints at build time and defer `runtime` lints to a live shard.
4986
5110
  */
4987
5111
  declare const runAdvisor: (context: LintContext, options?: RunAdvisorOptions) => Finding[];
4988
- export { ALL_LINTS, type AdvisorAdminRoute, type AdvisorAiRawRun, type AdvisorAiToolSideEffect, type AdvisorArgumentDerivedFetch, type AdvisorArgumentValidator, type AdvisorAuthApiCall, type AdvisorAuthConfig, type AdvisorBrowserUrlAccess, type AdvisorCallEdge, type AdvisorCallSiteScope, type AdvisorConfigCall, type AdvisorContainer, type AdvisorContainerKeyAccess, type AdvisorContainerOverride, type AdvisorExportSink, type AdvisorFailOpenGuard, type AdvisorFlagRead, 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 AdvisorModule, type AdvisorMutatorDeclaration, 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 AdvisorStaleMigrationImport, type AdvisorStorageKeyAccess, type AdvisorStorageUpload, type AdvisorTable, type AdvisorTableScan, type AdvisorTableWrite, type AdvisorUnboundedLoop, type AdvisorVectorNamespaceAccess, type AdvisorWorkflow, type AdvisorWorkflowCall, type AdvisorWranglerVariable, type AnalyticsMetricsOptions, type AnalyticsMetricsSource, type AnalyticsRuntimeMetrics, type BaselineComparison, type CallSiteMetadata, 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, callSiteCallers, callSiteDescription, callSiteLabel, callSiteMetadata, circularFk, classifySensitivity, commitOrderedHardDelete, compareToBaseline, containerInstanceKeyFromUserInput, containerOversizedInstance, containerPublicInternet, containerRuntimeEgressRelaxation, containerStartEnableInternetOverride, crossModuleTableWrite, dedupeCacheKeys, dispatchCycle, duplicateIndex, emptyIndex, errorWithoutCatalog, exportSinkMisconfigured, externalSourceIncrementalNoDeletePath, externalSourceOnGlobal, externalSourceUnscoped, fanOutBreadth, filterOnPrimaryKey, filterWithoutIndex, flagGatesSecurityWithUnsafeDefault, flagReadInSubscription, fromServerSchema, geoIndexFieldNotGeopoint, geoIndexUnused, globalTableNearColumnLimit, gradeFromScore, hardcodedSecret, helperRole, hotShard, httpActionMissingAuthGuard, httpActionResponseHeaderInjection, hyperdriveOutsideAction, identityUndeclaredClaimTrusted, imagesUrlSourceFromUserInput, indexReferencesUnknownField, indexUtilization, insertManyUnsafeUserData, isReachableSite, kvUnscopedUserKeyIdor, mailInboundDispatchWithoutVerify, mailRecipientFromRequestInput, maskUncoveredPiiColumn, maskWeakHashStrategyOnPii, maskedRelationLeakViaWith, mutatorFullRowReplace, mutatorWithoutOwnerScope, nondeterministicQueryMutation, normalizeIdUsedAsAuthorization, notifyMissingPushConfig, notifySendOutsideAction, outputProjectionMissingOnPublicRead, ownerFieldFromArgsNotAuth, parseAdvisorMap, paymentCreateWithoutAuthorize, paymentWebhookWideTolerance, plaintextSecretInWranglerVariables, policyReferencesUnknownTable, privilegedDispatchUnvalidatedPayload, privilegedFanoutFromPublicProcedure, procedureWithoutStructuredEvent, publicArgumentUsesAny, publicMutationWithoutRatelimit, publicTableRlsOptoutConfusion, queueWithoutDlq, r2sqlOutsideAction, ratelimitDefaultMemoryStore, ratelimitKeySpoofableOrGlobal, ratelimitMiddlewareFailOpen, readCallSiteCallers, relationReferencesUnknownField, relationReferencesUnknownTable, rlsUncoveredTable, runAdvisor, scoreAdvisor, shapeTargetsGlobalTable, shapeUnknownTable, signupMutationWithoutDisposableGating, softDeleteIncludeDeletedFromArgs, sqlInjectionRisk, storageGenerateUploadUrlNoContentTypePin, storageKeyFromUserArgs, storagePresignedUrlForPrivateContent, storageUploadWithoutContentTypeAllowlist, storageUploadWithoutMaxSize, tableWithoutInsert, topicTooManySubscriptions, ttlFieldNotTimestamp, unboundedLoop, unboundedStringArgument, unindexedForeignKey, unindexedRelationTarget, unrestrictedWhereBranch, userCreatingMutationWithoutCaptcha, vectorsNamespaceFromUserInput, workflowDuplicateStepName, workflowUnknownTarget, workflowUnused };
5112
+ export { ALL_LINTS, type AdvisorAdminRoute, type AdvisorAiRawRun, type AdvisorAiToolSideEffect, type AdvisorArgumentDerivedFetch, type AdvisorArgumentValidator, type AdvisorAuthApiCall, type AdvisorAuthConfig, type AdvisorBrowserUrlAccess, type AdvisorCallEdge, type AdvisorCallSiteScope, type AdvisorConfigCall, type AdvisorContainer, type AdvisorContainerKeyAccess, type AdvisorContainerOverride, type AdvisorExportSink, type AdvisorFailOpenGuard, type AdvisorFlagRead, 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 AdvisorModule, type AdvisorMutatorDeclaration, 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 AdvisorRowEffect, type AdvisorSchema, type AdvisorSecretLiteral, type AdvisorShape, type AdvisorShardTraffic, type AdvisorSoftDeleteRead, type AdvisorSqlInterpolation, type AdvisorStaleMigrationImport, type AdvisorStorageKeyAccess, type AdvisorStorageUpload, type AdvisorTable, type AdvisorTableScan, type AdvisorTableWrite, type AdvisorUnboundedLoop, type AdvisorVectorNamespaceAccess, type AdvisorWorkflow, type AdvisorWorkflowCall, type AdvisorWranglerVariable, type AnalyticsMetricsOptions, type AnalyticsMetricsSource, type AnalyticsRuntimeMetrics, type BaselineComparison, type CallSiteMetadata, 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, callSiteCallers, callSiteDescription, callSiteLabel, callSiteMetadata, circularFk, classifySensitivity, commitOrderedHardDelete, compareToBaseline, containerInstanceKeyFromUserInput, containerOversizedInstance, containerPublicInternet, containerRuntimeEgressRelaxation, containerStartEnableInternetOverride, crossModuleTableWrite, dedupeCacheKeys, dispatchCycle, duplicateIndex, emptyIndex, errorWithoutCatalog, exportSinkMisconfigured, externalSourceIncrementalNoDeletePath, externalSourceOnGlobal, externalSourceUnscoped, fanOutBreadth, filterAfterIndexScan, filterOnPrimaryKey, filterWithoutIndex, flagGatesSecurityWithUnsafeDefault, flagReadInSubscription, fromServerSchema, geoIndexFieldNotGeopoint, geoIndexUnused, globalTableNearColumnLimit, gradeFromScore, hardcodedSecret, helperRole, hotShard, httpActionMissingAuthGuard, httpActionResponseHeaderInjection, hyperdriveOutsideAction, identityUndeclaredClaimTrusted, imagesUrlSourceFromUserInput, indexReferencesUnknownField, indexUtilization, insertManyUnsafeUserData, isReachableSite, kvUnscopedUserKeyIdor, mailInboundDispatchWithoutVerify, mailRecipientFromRequestInput, maskUncoveredPiiColumn, maskWeakHashStrategyOnPii, maskedRelationLeakViaWith, mutatorFullRowReplace, mutatorWithoutOwnerScope, nondeterministicQueryMutation, normalizeIdUsedAsAuthorization, notifyMissingPushConfig, notifySendOutsideAction, outputProjectionMissingOnPublicRead, ownerFieldFromArgsNotAuth, parseAdvisorMap, paymentCreateWithoutAuthorize, paymentWebhookWideTolerance, plaintextSecretInWranglerVariables, policyReferencesUnknownTable, privilegedDispatchUnvalidatedPayload, privilegedFanoutFromPublicProcedure, procedureWithoutStructuredEvent, publicArgumentUsesAny, publicMutationWithoutRatelimit, publicTableRlsOptoutConfusion, queueWithoutDlq, r2sqlOutsideAction, ratelimitDefaultMemoryStore, ratelimitKeySpoofableOrGlobal, ratelimitMiddlewareFailOpen, readCallSiteCallers, relationReferencesUnknownField, relationReferencesUnknownTable, rlsUncoveredTable, runAdvisor, scoreAdvisor, selfRescheduleWithoutProgress, shapeTargetsGlobalTable, shapeUnknownTable, signupMutationWithoutDisposableGating, softDeleteIncludeDeletedFromArgs, sqlInjectionRisk, storageGenerateUploadUrlNoContentTypePin, storageKeyFromUserArgs, storagePresignedUrlForPrivateContent, storageUploadWithoutContentTypeAllowlist, storageUploadWithoutMaxSize, tableWithoutInsert, topicTooManySubscriptions, ttlFieldNotTimestamp, unboundedCollectOnOpenRange, unboundedLoop, unboundedStringArgument, unindexedForeignKey, unindexedRelationTarget, unrestrictedWhereBranch, userCreatingMutationWithoutCaptcha, vectorsNamespaceFromUserInput, workflowDuplicateStepName, workflowUnknownTarget, workflowUnused };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{dedupeCacheKeys as c}from"./packem_shared/dedupeCacheKeys-DtBOHffV.mjs";import d from"./packem_shared/fanOutBreadth-CBtmZnoh.mjs";import u from"./packem_shared/hotShard-BwGYZ3Tq.mjs";import h from"./packem_shared/indexUtilization-CkVPZcVe.mjs";import g from"./packem_shared/actionFetchSsrf-B4ZaOBlW.mjs";import b from"./packem_shared/actionWithoutErrorHandling-4GCBT0_z.mjs";import y from"./packem_shared/adminRouteWithoutGuard-DPE7LuNh.mjs";import S from"./packem_shared/aiRawRunEscapeHatch-B5980eT9.mjs";import w from"./packem_shared/aiRunWithoutLogging-CvHHtEN9.mjs";import v from"./packem_shared/aiToolSideEffectPromptInjection-_3MrX9Ul.mjs";import A from"./packem_shared/aiUnboundedGenerationPublic-C17h6sMV.mjs";import R from"./packem_shared/allowUnauthenticatedShardAccessEnabled-BQufF5Kb.mjs";import U from"./packem_shared/authApiCallWithoutHeaders-D8U1hv8s.mjs";import W from"./packem_shared/authCsrfCheckDisabled-C6bxME5y.mjs";import T from"./packem_shared/authEmailVerificationDisabled-yROPDgn-.mjs";import I from"./packem_shared/authScimWithoutTransactions-w9qb3iBe.mjs";import k from"./packem_shared/authSecureCookiesDisabled-qrCktlch.mjs";import C from"./packem_shared/authSessionFreshageZero-BMisjIIS.mjs";import N from"./packem_shared/authTrustedOriginsWildcard-DFDpfN84.mjs";import x from"./packem_shared/browserAllowPrivateTargets-Cj5sizhv.mjs";import F from"./packem_shared/browserUserUrlWithoutAllowlist-CcK27rvt.mjs";import M from"./packem_shared/circularFk-DtcWFJxK.mjs";import O from"./packem_shared/commitOrderedHardDelete-BPdwOKA7.mjs";import D from"./packem_shared/containerInstanceKeyFromUserInput-DBdjUnQb.mjs";import $ from"./packem_shared/containerOversizedInstance-Bx89uR7E.mjs";import E from"./packem_shared/containerPublicInternet-BFfZf_P4.mjs";import P from"./packem_shared/containerRuntimeEgressRelaxation-CioCA2zY.mjs";import K from"./packem_shared/containerStartEnableInternetOverride-C6dbznku.mjs";import L from"./packem_shared/crossModuleTableWrite-DjiVTAwK.mjs";import q from"./packem_shared/dispatchCycle-CWc5Q0cd.mjs";import G from"./packem_shared/duplicateIndex-Cip6-Rpu.mjs";import _ from"./packem_shared/emptyIndex-BnHDcXza.mjs";import z from"./packem_shared/errorWithoutCatalog-BTfvaXHR.mjs";import H from"./packem_shared/exportSinkMisconfigured-JfbAx9AI.mjs";import B from"./packem_shared/externalSourceIncrementalNoDeletePath-BCzm3HzF.mjs";import j from"./packem_shared/externalSourceOnGlobal-CH7xbJ49.mjs";import V from"./packem_shared/externalSourceUnscoped-BxU2uSXk.mjs";import Q from"./packem_shared/filterOnPrimaryKey-DbFriOZA.mjs";import X from"./packem_shared/filterWithoutIndex-Dc7Nn0y2.mjs";import Z from"./packem_shared/flagGatesSecurityWithUnsafeDefault-DB9M6hLM.mjs";import J from"./packem_shared/flagReadInSubscription-DabIhYGD.mjs";import Y from"./packem_shared/geoIndexFieldNotGeopoint-CDMNbAfp.mjs";import oo from"./packem_shared/geoIndexUnused-D7C9Qr4U.mjs";import eo from"./packem_shared/globalTableNearColumnLimit-BFbBBd6A.mjs";import ro from"./packem_shared/hardcodedSecret-Bw_4FYrs.mjs";import to from"./packem_shared/httpActionMissingAuthGuard-BhvcmkwW.mjs";import io from"./packem_shared/httpActionResponseHeaderInjection-DKz2SlCa.mjs";import no from"./packem_shared/hyperdriveOutsideAction-CPDdGP2g.mjs";import ao from"./packem_shared/identityUndeclaredClaimTrusted-CAUagXkJ.mjs";import mo from"./packem_shared/imagesUrlSourceFromUserInput-C2CJTTCI.mjs";import lo from"./packem_shared/indexReferencesUnknownField-Dm8SL4Tp.mjs";import so from"./packem_shared/insertManyUnsafeUserData-DWE8d_DF.mjs";import po from"./packem_shared/kvUnscopedUserKeyIdor-CXFKAyM2.mjs";import fo from"./packem_shared/mailInboundDispatchWithoutVerify-CWwqXyPX.mjs";import co from"./packem_shared/mailRecipientFromRequestInput-CQZeOsP9.mjs";import uo from"./packem_shared/maskUncoveredPiiColumn-axEka4nd.mjs";import ho from"./packem_shared/maskWeakHashStrategyOnPii-njstapQY.mjs";import go from"./packem_shared/maskedRelationLeakViaWith-CIFij6vE.mjs";import{e as a}from"./packem_shared/finding-NrKO8idM.mjs";import bo from"./packem_shared/mutatorFullRowReplace-BzRpZ47r.mjs";import yo from"./packem_shared/mutatorWithoutOwnerScope-BoS81ns0.mjs";import So from"./packem_shared/nondeterministicQueryMutation-sxmixc0l.mjs";import wo from"./packem_shared/normalizeIdUsedAsAuthorization-BXN-Can6.mjs";import vo from"./packem_shared/notifyMissingPushConfig-DeQMoNwm.mjs";import Ao from"./packem_shared/notifySendOutsideAction-BJrDkr4h.mjs";import Ro from"./packem_shared/outputProjectionMissingOnPublicRead-DHivs_73.mjs";import Uo from"./packem_shared/ownerFieldFromArgsNotAuth-lgjS8mdd.mjs";import Wo from"./packem_shared/paymentCreateWithoutAuthorize-CICGmRFR.mjs";import To from"./packem_shared/paymentWebhookWideTolerance-CtZb2AVA.mjs";import Io from"./packem_shared/plaintextSecretInWranglerVariables-bNkqmNqV.mjs";import ko from"./packem_shared/policyReferencesUnknownTable-CIKuRZ5Y.mjs";import Co from"./packem_shared/privilegedDispatchUnvalidatedPayload-DlJovHrt.mjs";import No from"./packem_shared/privilegedFanoutFromPublicProcedure-DV188gHQ.mjs";import xo from"./packem_shared/procedureWithoutStructuredEvent-CZ_B23nM.mjs";import Fo from"./packem_shared/publicArgumentUsesAny-BDEvMA8Q.mjs";import Mo from"./packem_shared/publicMutationWithoutRatelimit-BeYapu1F.mjs";import Oo from"./packem_shared/publicTableRlsOptoutConfusion-BFmh1kH0.mjs";import Do from"./packem_shared/queueWithoutDlq-BvHz3Opg.mjs";import $o from"./packem_shared/r2sqlOutsideAction-BdLiLOAX.mjs";import Eo from"./packem_shared/ratelimitDefaultMemoryStore-Dj0Kk7t9.mjs";import Po from"./packem_shared/ratelimitKeySpoofableOrGlobal-DlvJfSXs.mjs";import Ko from"./packem_shared/ratelimitMiddlewareFailOpen-DGtyt-pc.mjs";import Lo from"./packem_shared/relationReferencesUnknownField-CqGEJD57.mjs";import qo from"./packem_shared/relationReferencesUnknownTable-CP4aWtAJ.mjs";import Go from"./packem_shared/rlsUncoveredTable-CZ4ie4gX.mjs";import _o from"./packem_shared/shapeTargetsGlobalTable-Bu3eEDic.mjs";import zo from"./packem_shared/shapeUnknownTable-CREfNnWi.mjs";import Ho from"./packem_shared/signupMutationWithoutDisposableGating-CFtFMJz8.mjs";import Bo from"./packem_shared/softDeleteIncludeDeletedFromArgs-C7Ugg4zb.mjs";import jo from"./packem_shared/sqlInjectionRisk-y-7c46LJ.mjs";import Vo from"./packem_shared/storageGenerateUploadUrlNoContentTypePin-Bx9oGOjM.mjs";import Qo from"./packem_shared/storageKeyFromUserArgs-BryKJJM-.mjs";import Xo from"./packem_shared/storagePresignedUrlForPrivateContent-lqE6LvNu.mjs";import Zo from"./packem_shared/storageUploadWithoutContentTypeAllowlist-DMr7w29r.mjs";import Jo from"./packem_shared/storageUploadWithoutMaxSize-rSNFNb2l.mjs";import Yo from"./packem_shared/tableWithoutInsert-ClJp_jDr.mjs";import oe from"./packem_shared/topicTooManySubscriptions-CiZhFm9r.mjs";import ee from"./packem_shared/ttlFieldNotTimestamp-Dxa-6RfM.mjs";import{s as re,q as te,c as ie}from"./packem_shared/helpers-BmppB5nL.mjs";import ne from"./packem_shared/unboundedLoop-BqbZ7boE.mjs";import ae from"./packem_shared/unboundedStringArgument-jZnCbwB0.mjs";import me from"./packem_shared/unindexedForeignKey-Dypgn8uH.mjs";import le from"./packem_shared/unindexedRelationTarget-CSqRJWYZ.mjs";import se from"./packem_shared/unrestrictedWhereBranch-CcIBmHik.mjs";import pe from"./packem_shared/userCreatingMutationWithoutCaptcha-C8yaqIIj.mjs";import fe from"./packem_shared/vectorsNamespaceFromUserInput-7I_Kwxvp.mjs";import ce from"./packem_shared/workflowDuplicateStepName-B6eAJzwA.mjs";import de from"./packem_shared/workflowUnknownTarget-Cm1hfTTs.mjs";import ue from"./packem_shared/workflowUnused-DHwwE-1P.mjs";import{callSiteCallers as Wt,callSiteDescription as Tt,callSiteLabel as It,callSiteMetadata as kt,helperRole as Ct,isReachableSite as Nt,readCallSiteCallers as xt}from"./packem_shared/callSiteCallers-DArHfQSU.mjs";import{compareToBaseline as Mt,parseAdvisorMap as Ot}from"./packem_shared/compareToBaseline-CUG59IOy.mjs";import{gradeFromScore as $t}from"./packem_shared/gradeFromScore-KSt58rj1.mjs";import{MAP_VERSION as Pt,byCodepoint as Kt,scoreAdvisor as Lt}from"./packem_shared/MAP_VERSION-MQ5W2B6n.mjs";import{default as Gt}from"./packem_shared/classifySensitivity-JnjaTGYi.mjs";import{fromServerSchema as zt}from"./packem_shared/fromServerSchema-fAymN8o2.mjs";const he={convex:"migrating/from-convex",firebase:"migrating/from-firebase",supabase:"migrating/from-supabase"},m={categories:["SCHEMA"],description:"A migrated-away platform's SDK is still imported from `lunora/` source. The code compiles and typechecks, so a half-finished port keeps reading from the old platform at runtime and the two stores silently drift apart.",facing:"INTERNAL",level:"WARN",name:"migration_stale_import",remediation:"Replace the call with its Lunora equivalent and drop the dependency. If the import is deliberate — a second data source you still read from — move it out of `lunora/` so it is not mistaken for an unfinished migration.",run:r=>r.staleMigrationImports===void 0?[]:r.staleMigrationImports.map(o=>a(m,{cacheKey:`migration_stale_import:${o.file}:${o.line.toString()}:${o.moduleSpecifier}`,detail:`\`${o.file}\` (line ${o.line.toString()}) still imports \`${o.moduleSpecifier}\`. Finish the port — see \`${he[o.platform]}\` — or move the import out of \`lunora/\` if you genuinely still read from ${o.platform}.`,metadata:{file:o.file,line:o.line,moduleSpecifier:o.moduleSpecifier,platform:o.platform}})),source:"static",title:"Stale migration import"},ge=new Map([["global",{level:"WARN",scope:r=>`it reads the whole D1 table "${r}" over a cross-region round trip`}],["root",{level:"WARN",scope:r=>`it loads every row of "${r}" from the root Durable Object's SQLite into memory`}],["shardBy",{level:"INFO",scope:r=>`"${r}" is \`.shardBy()\`, so this collects one shard's rows rather than the whole table — bounded by a single tenant's row count`}]]),be={level:"WARN",scope:r=>`it loads every row of "${r}"`},l={categories:["PERFORMANCE"],description:"A query calls `.collect()` with no `.withIndex()` and no `.filter()`, so it materializes every row of the table. Any live subscription over it also re-sends that whole result to every subscribed client on every write to the table.",facing:"EXTERNAL",level:"WARN",name:"unbounded_collect",remediation:'Narrow the read with `.withIndex("name", (q) => q.eq(...))`, cap it with `.take(n)`, or page it with `.paginate(args.paginationOpts)` so neither the scan nor the subscription payload grows with the table.',run:r=>{const o=[],i=re(r.schema);for(const e of r.queries??[]){if(e.terminal!=="collect"||e.hasIndex||e.table===""||e.hasFilter)continue;const t=i.get(e.table),{level:n,scope:s}=ge.get(t??"")??be,p=te(e),f=n==="WARN"?` A live subscription over this query records a whole-table dependency, so every write to "${e.table}" re-runs it and re-sends the full result to each subscribed socket.`:" Cap it with `.take(n)` if that count can grow.";o.push(a(l,{cacheKey:`unbounded_collect:${e.file}:${e.line.toString()}:${e.table}`,detail:`Query on "${e.table}" at ${p} calls .collect() with no index and no filter — ${s(e.table)}.${f}`,level:n,metadata:{...ie(e),shardKind:t??"unknown",table:e.table}}))}return o},source:"static",title:"Unbounded collect"},ye=[lo,qo,Lo,de,ce,zo,B,j,V,_,eo,z,Y,oo,H,ee,O,M,L,me,le,G,Yo,ue,Do,oe,Q,X,l,ne,q,_o,bo,yo,So,no,$o,U,ko,Go,uo,ho,$,E,Mo,se,pe,Ho,Fo,ae,ro,jo,y,Wo,fo,Eo,x,No,xo,so,A,g,b,Uo,Qo,po,D,S,w,fe,co,F,Co,K,P,I,N,W,k,T,C,mo,Po,Oo,R,Zo,Jo,Vo,Xo,to,io,Ko,Z,J,v,ao,To,Bo,go,Ro,wo,Ao,vo,Io,m],Se=[u,h,d],we=[...ye,...Se],At=(r,o={})=>{const i=o.lints??we,e=[];for(const t of i)o.source!==void 0&&t.source!==o.source||e.push(...t.run(r));return c(e)};export{we as ALL_LINTS,Pt as MAP_VERSION,Se as RUNTIME_LINTS,ye as STATIC_LINTS,g as actionFetchSsrf,b as actionWithoutErrorHandling,y as adminRouteWithoutGuard,S as aiRawRunEscapeHatch,w as aiRunWithoutLogging,v as aiToolSideEffectPromptInjection,A as aiUnboundedGenerationPublic,R as allowUnauthenticatedShardAccessEnabled,U as authApiCallWithoutHeaders,W as authCsrfCheckDisabled,T as authEmailVerificationDisabled,I as authScimWithoutTransactions,k as authSecureCookiesDisabled,C as authSessionFreshageZero,N as authTrustedOriginsWildcard,x as browserAllowPrivateTargets,F as browserUserUrlWithoutAllowlist,Kt as byCodepoint,Wt as callSiteCallers,Tt as callSiteDescription,It as callSiteLabel,kt as callSiteMetadata,M as circularFk,Gt as classifySensitivity,O as commitOrderedHardDelete,Mt as compareToBaseline,D as containerInstanceKeyFromUserInput,$ as containerOversizedInstance,E as containerPublicInternet,P as containerRuntimeEgressRelaxation,K as containerStartEnableInternetOverride,L as crossModuleTableWrite,c as dedupeCacheKeys,q as dispatchCycle,G as duplicateIndex,_ as emptyIndex,z as errorWithoutCatalog,H as exportSinkMisconfigured,B as externalSourceIncrementalNoDeletePath,j as externalSourceOnGlobal,V as externalSourceUnscoped,d as fanOutBreadth,Q as filterOnPrimaryKey,X as filterWithoutIndex,Z as flagGatesSecurityWithUnsafeDefault,J as flagReadInSubscription,zt as fromServerSchema,Y as geoIndexFieldNotGeopoint,oo as geoIndexUnused,eo as globalTableNearColumnLimit,$t as gradeFromScore,ro as hardcodedSecret,Ct as helperRole,u as hotShard,to as httpActionMissingAuthGuard,io as httpActionResponseHeaderInjection,no as hyperdriveOutsideAction,ao as identityUndeclaredClaimTrusted,mo as imagesUrlSourceFromUserInput,lo as indexReferencesUnknownField,h as indexUtilization,so as insertManyUnsafeUserData,Nt as isReachableSite,po as kvUnscopedUserKeyIdor,fo as mailInboundDispatchWithoutVerify,co as mailRecipientFromRequestInput,uo as maskUncoveredPiiColumn,ho as maskWeakHashStrategyOnPii,go as maskedRelationLeakViaWith,bo as mutatorFullRowReplace,yo as mutatorWithoutOwnerScope,So as nondeterministicQueryMutation,wo as normalizeIdUsedAsAuthorization,vo as notifyMissingPushConfig,Ao as notifySendOutsideAction,Ro as outputProjectionMissingOnPublicRead,Uo as ownerFieldFromArgsNotAuth,Ot as parseAdvisorMap,Wo as paymentCreateWithoutAuthorize,To as paymentWebhookWideTolerance,Io as plaintextSecretInWranglerVariables,ko as policyReferencesUnknownTable,Co as privilegedDispatchUnvalidatedPayload,No as privilegedFanoutFromPublicProcedure,xo as procedureWithoutStructuredEvent,Fo as publicArgumentUsesAny,Mo as publicMutationWithoutRatelimit,Oo as publicTableRlsOptoutConfusion,Do as queueWithoutDlq,$o as r2sqlOutsideAction,Eo as ratelimitDefaultMemoryStore,Po as ratelimitKeySpoofableOrGlobal,Ko as ratelimitMiddlewareFailOpen,xt as readCallSiteCallers,Lo as relationReferencesUnknownField,qo as relationReferencesUnknownTable,Go as rlsUncoveredTable,At as runAdvisor,Lt as scoreAdvisor,_o as shapeTargetsGlobalTable,zo as shapeUnknownTable,Ho as signupMutationWithoutDisposableGating,Bo as softDeleteIncludeDeletedFromArgs,jo as sqlInjectionRisk,Vo as storageGenerateUploadUrlNoContentTypePin,Qo as storageKeyFromUserArgs,Xo as storagePresignedUrlForPrivateContent,Zo as storageUploadWithoutContentTypeAllowlist,Jo as storageUploadWithoutMaxSize,Yo as tableWithoutInsert,oe as topicTooManySubscriptions,ee as ttlFieldNotTimestamp,ne as unboundedLoop,ae as unboundedStringArgument,me as unindexedForeignKey,le as unindexedRelationTarget,se as unrestrictedWhereBranch,pe as userCreatingMutationWithoutCaptcha,fe as vectorsNamespaceFromUserInput,ce as workflowDuplicateStepName,de as workflowUnknownTarget,ue as workflowUnused};
1
+ import{dedupeCacheKeys as c}from"./packem_shared/dedupeCacheKeys-DtBOHffV.mjs";import d from"./packem_shared/fanOutBreadth-CBtmZnoh.mjs";import u from"./packem_shared/hotShard-BwGYZ3Tq.mjs";import h from"./packem_shared/indexUtilization-CkVPZcVe.mjs";import g from"./packem_shared/actionFetchSsrf-Ckr3MZNs.mjs";import b from"./packem_shared/actionWithoutErrorHandling-4GCBT0_z.mjs";import y from"./packem_shared/adminRouteWithoutGuard-DPE7LuNh.mjs";import S from"./packem_shared/aiRawRunEscapeHatch-kE49dAwE.mjs";import w from"./packem_shared/aiRunWithoutLogging-CvHHtEN9.mjs";import v from"./packem_shared/aiToolSideEffectPromptInjection-BZLjJ5Cy.mjs";import A from"./packem_shared/aiUnboundedGenerationPublic-C17h6sMV.mjs";import R from"./packem_shared/allowUnauthenticatedShardAccessEnabled-BQufF5Kb.mjs";import U from"./packem_shared/authApiCallWithoutHeaders-HbSNJ0Hc.mjs";import W from"./packem_shared/authCsrfCheckDisabled-KwbenvXt.mjs";import T from"./packem_shared/authEmailVerificationDisabled-JBOb3BF8.mjs";import I from"./packem_shared/authScimWithoutTransactions-CCYuq6pk.mjs";import C from"./packem_shared/authSecureCookiesDisabled-unvM30AR.mjs";import k from"./packem_shared/authSessionFreshageZero-CBzcaids.mjs";import x from"./packem_shared/authTrustedOriginsWildcard-Czbv3hzH.mjs";import N from"./packem_shared/browserAllowPrivateTargets-Cj5sizhv.mjs";import F from"./packem_shared/browserUserUrlWithoutAllowlist-CsA_4hLR.mjs";import O from"./packem_shared/circularFk-DtcWFJxK.mjs";import M from"./packem_shared/commitOrderedHardDelete-BPdwOKA7.mjs";import D from"./packem_shared/containerInstanceKeyFromUserInput-CQPWh9L_.mjs";import P from"./packem_shared/containerOversizedInstance-Bx89uR7E.mjs";import $ from"./packem_shared/containerPublicInternet-BFfZf_P4.mjs";import E from"./packem_shared/containerRuntimeEgressRelaxation-BU4-7YkE.mjs";import K from"./packem_shared/containerStartEnableInternetOverride-BHglJwGb.mjs";import L from"./packem_shared/crossModuleTableWrite-DjiVTAwK.mjs";import q from"./packem_shared/dispatchCycle-CWc5Q0cd.mjs";import G from"./packem_shared/duplicateIndex-Cip6-Rpu.mjs";import _ from"./packem_shared/emptyIndex-BnHDcXza.mjs";import z from"./packem_shared/errorWithoutCatalog-BTfvaXHR.mjs";import H from"./packem_shared/exportSinkMisconfigured-JfbAx9AI.mjs";import B from"./packem_shared/externalSourceIncrementalNoDeletePath-BCzm3HzF.mjs";import j from"./packem_shared/externalSourceOnGlobal-CH7xbJ49.mjs";import V from"./packem_shared/externalSourceUnscoped-BxU2uSXk.mjs";import Q from"./packem_shared/filterAfterIndexScan-Di_Zsrj7.mjs";import X from"./packem_shared/filterOnPrimaryKey-C3N-wvB_.mjs";import Z from"./packem_shared/filterWithoutIndex-BgUUzQSY.mjs";import J from"./packem_shared/flagGatesSecurityWithUnsafeDefault-tQivheR5.mjs";import Y from"./packem_shared/flagReadInSubscription-DabIhYGD.mjs";import oo from"./packem_shared/geoIndexFieldNotGeopoint-B_3rAicD.mjs";import eo from"./packem_shared/geoIndexUnused-D7C9Qr4U.mjs";import ro from"./packem_shared/globalTableNearColumnLimit-BFbBBd6A.mjs";import to from"./packem_shared/hardcodedSecret-Bw_4FYrs.mjs";import io from"./packem_shared/httpActionMissingAuthGuard-CqS3GLB1.mjs";import no from"./packem_shared/httpActionResponseHeaderInjection-Daul1_t3.mjs";import ao from"./packem_shared/hyperdriveOutsideAction-CPDdGP2g.mjs";import mo from"./packem_shared/identityUndeclaredClaimTrusted-DzgQiHe1.mjs";import lo from"./packem_shared/imagesUrlSourceFromUserInput-DE5goRdp.mjs";import so from"./packem_shared/indexReferencesUnknownField-Dve5ViiG.mjs";import po from"./packem_shared/insertManyUnsafeUserData-DWE8d_DF.mjs";import fo from"./packem_shared/kvUnscopedUserKeyIdor-CJOTcIoG.mjs";import co from"./packem_shared/mailInboundDispatchWithoutVerify-CWwqXyPX.mjs";import uo from"./packem_shared/mailRecipientFromRequestInput-C1G95HJQ.mjs";import ho from"./packem_shared/maskUncoveredPiiColumn-axEka4nd.mjs";import go from"./packem_shared/maskWeakHashStrategyOnPii-Ul325weF.mjs";import bo from"./packem_shared/maskedRelationLeakViaWith-CIFij6vE.mjs";import{e as a}from"./packem_shared/finding-NrKO8idM.mjs";import yo from"./packem_shared/mutatorFullRowReplace-BzRpZ47r.mjs";import So from"./packem_shared/mutatorWithoutOwnerScope-BoS81ns0.mjs";import wo from"./packem_shared/nondeterministicQueryMutation-Bbb-AGOS.mjs";import vo from"./packem_shared/normalizeIdUsedAsAuthorization-BXN-Can6.mjs";import Ao from"./packem_shared/notifyMissingPushConfig-DeQMoNwm.mjs";import Ro from"./packem_shared/notifySendOutsideAction-BJrDkr4h.mjs";import Uo from"./packem_shared/outputProjectionMissingOnPublicRead-DfGQfxaK.mjs";import Wo from"./packem_shared/ownerFieldFromArgsNotAuth-D1VEIgac.mjs";import To from"./packem_shared/paymentCreateWithoutAuthorize-CdenWpXD.mjs";import Io from"./packem_shared/paymentWebhookWideTolerance-Bm10PglC.mjs";import Co from"./packem_shared/plaintextSecretInWranglerVariables-bNkqmNqV.mjs";import ko from"./packem_shared/policyReferencesUnknownTable-CIKuRZ5Y.mjs";import xo from"./packem_shared/privilegedDispatchUnvalidatedPayload-G-9sV5zL.mjs";import No from"./packem_shared/privilegedFanoutFromPublicProcedure-DV188gHQ.mjs";import Fo from"./packem_shared/procedureWithoutStructuredEvent-CZ_B23nM.mjs";import Oo from"./packem_shared/publicArgumentUsesAny-BDEvMA8Q.mjs";import Mo from"./packem_shared/publicMutationWithoutRatelimit-DQj1xkax.mjs";import Do from"./packem_shared/publicTableRlsOptoutConfusion-DUXkgvhl.mjs";import Po from"./packem_shared/queueWithoutDlq-BvHz3Opg.mjs";import $o from"./packem_shared/r2sqlOutsideAction-BdLiLOAX.mjs";import Eo from"./packem_shared/ratelimitDefaultMemoryStore-Dj0Kk7t9.mjs";import Ko from"./packem_shared/ratelimitKeySpoofableOrGlobal-J6uHCtnZ.mjs";import Lo from"./packem_shared/ratelimitMiddlewareFailOpen-C4ha9Kkp.mjs";import qo from"./packem_shared/relationReferencesUnknownField-BkS_YTgj.mjs";import Go from"./packem_shared/relationReferencesUnknownTable-CP4aWtAJ.mjs";import _o from"./packem_shared/rlsUncoveredTable-CZ4ie4gX.mjs";import zo from"./packem_shared/selfRescheduleWithoutProgress-BQIKeW3m.mjs";import Ho from"./packem_shared/shapeTargetsGlobalTable-Bu3eEDic.mjs";import Bo from"./packem_shared/shapeUnknownTable-CREfNnWi.mjs";import jo from"./packem_shared/signupMutationWithoutDisposableGating-CKES8QJL.mjs";import Vo from"./packem_shared/softDeleteIncludeDeletedFromArgs-C7Ugg4zb.mjs";import Qo from"./packem_shared/sqlInjectionRisk-CoTZ127r.mjs";import Xo from"./packem_shared/storageGenerateUploadUrlNoContentTypePin-BAmzI6ru.mjs";import Zo from"./packem_shared/storageKeyFromUserArgs-jwnnKvrm.mjs";import Jo from"./packem_shared/storagePresignedUrlForPrivateContent-CfTyQxW3.mjs";import Yo from"./packem_shared/storageUploadWithoutContentTypeAllowlist-CkkuOKU4.mjs";import oe from"./packem_shared/storageUploadWithoutMaxSize-Bz521ysH.mjs";import ee from"./packem_shared/tableWithoutInsert-ClJp_jDr.mjs";import re from"./packem_shared/topicTooManySubscriptions-CiZhFm9r.mjs";import te from"./packem_shared/ttlFieldNotTimestamp-obKZetLE.mjs";import{s as ie,q as ne,c as ae}from"./packem_shared/helpers-BwOMPdUk.mjs";import me from"./packem_shared/unboundedCollectOnOpenRange-ClpZwgAd.mjs";import le from"./packem_shared/unboundedLoop-DQBL-C0q.mjs";import se from"./packem_shared/unboundedStringArgument-jZnCbwB0.mjs";import pe from"./packem_shared/unindexedForeignKey-Dypgn8uH.mjs";import fe from"./packem_shared/unindexedRelationTarget-CSqRJWYZ.mjs";import ce from"./packem_shared/unrestrictedWhereBranch-CcIBmHik.mjs";import de from"./packem_shared/userCreatingMutationWithoutCaptcha-CLE-QBZ9.mjs";import ue from"./packem_shared/vectorsNamespaceFromUserInput-hCNg2Slm.mjs";import he from"./packem_shared/workflowDuplicateStepName-B6eAJzwA.mjs";import ge from"./packem_shared/workflowUnknownTarget-O1U8Kwvc.mjs";import be from"./packem_shared/workflowUnused-DHwwE-1P.mjs";import{callSiteCallers as Nt,callSiteDescription as Ft,callSiteLabel as Ot,callSiteMetadata as Mt,helperRole as Dt,isReachableSite as Pt,readCallSiteCallers as $t}from"./packem_shared/callSiteCallers-DArHfQSU.mjs";import{compareToBaseline as Kt,parseAdvisorMap as Lt}from"./packem_shared/compareToBaseline-CUG59IOy.mjs";import{gradeFromScore as Gt}from"./packem_shared/gradeFromScore-KSt58rj1.mjs";import{MAP_VERSION as zt,byCodepoint as Ht,scoreAdvisor as Bt}from"./packem_shared/MAP_VERSION-MQ5W2B6n.mjs";import{default as Vt}from"./packem_shared/classifySensitivity-JnjaTGYi.mjs";import{fromServerSchema as Xt}from"./packem_shared/fromServerSchema-fAymN8o2.mjs";const ye={convex:"migrating/from-convex",firebase:"migrating/from-firebase",supabase:"migrating/from-supabase"},m={categories:["SCHEMA"],description:"A migrated-away platform's SDK is still imported from `lunora/` source. The code compiles and typechecks, so a half-finished port keeps reading from the old platform at runtime and the two stores silently drift apart.",facing:"INTERNAL",level:"WARN",name:"migration_stale_import",remediation:"Replace the call with its Lunora equivalent and drop the dependency. If the import is deliberate — a second data source you still read from — move it out of `lunora/` so it is not mistaken for an unfinished migration.",run:r=>r.staleMigrationImports===void 0?[]:r.staleMigrationImports.map(o=>a(m,{cacheKey:`migration_stale_import:${o.file}:${o.line.toString()}:${o.moduleSpecifier}`,detail:`\`${o.file}\` (line ${o.line.toString()}) still imports \`${o.moduleSpecifier}\`. Finish the port — see \`${ye[o.platform]}\` — or move the import out of \`lunora/\` if you genuinely still read from ${o.platform}.`,metadata:{file:o.file,line:o.line,moduleSpecifier:o.moduleSpecifier,platform:o.platform}})),source:"static",title:"Stale migration import"},Se=new Map([["global",{level:"WARN",scope:r=>`it reads the whole D1 table "${r}" over a cross-region round trip`}],["root",{level:"WARN",scope:r=>`it loads every row of "${r}" from the root Durable Object's SQLite into memory`}],["shardBy",{level:"INFO",scope:r=>`"${r}" is \`.shardBy()\`, so this collects one shard's rows rather than the whole table — bounded by a single tenant's row count`}]]),we={level:"WARN",scope:r=>`it loads every row of "${r}"`},l={categories:["PERFORMANCE"],description:"A query calls `.collect()` with no `.withIndex()` and no `.filter()`, so it materializes every row of the table. Any live subscription over it also re-sends that whole result to every subscribed client on every write to the table.",facing:"EXTERNAL",level:"WARN",name:"unbounded_collect",remediation:'Narrow the read with `.withIndex("name", (q) => q.eq(...))`, cap it with `.take(n)`, or page it with `.paginate(args.paginationOpts)` so neither the scan nor the subscription payload grows with the table.',run:r=>{const o=[],i=ie(r.schema);for(const e of r.queries??[]){if(e.terminal!=="collect"||e.hasIndex||e.table===""||e.hasFilter)continue;const t=i.get(e.table),{level:n,scope:s}=Se.get(t??"")??we,p=ne(e),f=n==="WARN"?` A live subscription over this query records a whole-table dependency, so every write to "${e.table}" re-runs it and re-sends the full result to each subscribed socket.`:" Cap it with `.take(n)` if that count can grow.";o.push(a(l,{cacheKey:`unbounded_collect:${e.file}:${e.line.toString()}:${e.table}`,detail:`Query on "${e.table}" at ${p} calls .collect() with no index and no filter — ${s(e.table)}.${f}`,level:n,metadata:{...ae(e),shardKind:t??"unknown",table:e.table}}))}return o},source:"static",title:"Unbounded collect"},ve=[so,Go,qo,ge,he,Bo,B,j,V,_,ro,z,oo,eo,H,te,M,O,L,pe,fe,G,ee,be,Po,re,X,Z,Q,l,me,le,q,zo,Ho,yo,So,wo,ao,$o,U,ko,_o,ho,go,P,$,Mo,ce,de,jo,Oo,se,to,Qo,y,To,co,Eo,N,No,Fo,po,A,g,b,Wo,Zo,fo,D,S,w,ue,uo,F,xo,K,E,I,x,W,C,T,k,lo,Ko,Do,R,Yo,oe,Xo,Jo,io,no,Lo,J,Y,v,mo,Io,Vo,bo,Uo,vo,Ro,Ao,Co,m],Ae=[u,h,d],Re=[...ve,...Ae],Ct=(r,o={})=>{const i=o.lints??Re,e=[];for(const t of i)o.source!==void 0&&t.source!==o.source||e.push(...t.run(r));return c(e)};export{Re as ALL_LINTS,zt as MAP_VERSION,Ae as RUNTIME_LINTS,ve as STATIC_LINTS,g as actionFetchSsrf,b as actionWithoutErrorHandling,y as adminRouteWithoutGuard,S as aiRawRunEscapeHatch,w as aiRunWithoutLogging,v as aiToolSideEffectPromptInjection,A as aiUnboundedGenerationPublic,R as allowUnauthenticatedShardAccessEnabled,U as authApiCallWithoutHeaders,W as authCsrfCheckDisabled,T as authEmailVerificationDisabled,I as authScimWithoutTransactions,C as authSecureCookiesDisabled,k as authSessionFreshageZero,x as authTrustedOriginsWildcard,N as browserAllowPrivateTargets,F as browserUserUrlWithoutAllowlist,Ht as byCodepoint,Nt as callSiteCallers,Ft as callSiteDescription,Ot as callSiteLabel,Mt as callSiteMetadata,O as circularFk,Vt as classifySensitivity,M as commitOrderedHardDelete,Kt as compareToBaseline,D as containerInstanceKeyFromUserInput,P as containerOversizedInstance,$ as containerPublicInternet,E as containerRuntimeEgressRelaxation,K as containerStartEnableInternetOverride,L as crossModuleTableWrite,c as dedupeCacheKeys,q as dispatchCycle,G as duplicateIndex,_ as emptyIndex,z as errorWithoutCatalog,H as exportSinkMisconfigured,B as externalSourceIncrementalNoDeletePath,j as externalSourceOnGlobal,V as externalSourceUnscoped,d as fanOutBreadth,Q as filterAfterIndexScan,X as filterOnPrimaryKey,Z as filterWithoutIndex,J as flagGatesSecurityWithUnsafeDefault,Y as flagReadInSubscription,Xt as fromServerSchema,oo as geoIndexFieldNotGeopoint,eo as geoIndexUnused,ro as globalTableNearColumnLimit,Gt as gradeFromScore,to as hardcodedSecret,Dt as helperRole,u as hotShard,io as httpActionMissingAuthGuard,no as httpActionResponseHeaderInjection,ao as hyperdriveOutsideAction,mo as identityUndeclaredClaimTrusted,lo as imagesUrlSourceFromUserInput,so as indexReferencesUnknownField,h as indexUtilization,po as insertManyUnsafeUserData,Pt as isReachableSite,fo as kvUnscopedUserKeyIdor,co as mailInboundDispatchWithoutVerify,uo as mailRecipientFromRequestInput,ho as maskUncoveredPiiColumn,go as maskWeakHashStrategyOnPii,bo as maskedRelationLeakViaWith,yo as mutatorFullRowReplace,So as mutatorWithoutOwnerScope,wo as nondeterministicQueryMutation,vo as normalizeIdUsedAsAuthorization,Ao as notifyMissingPushConfig,Ro as notifySendOutsideAction,Uo as outputProjectionMissingOnPublicRead,Wo as ownerFieldFromArgsNotAuth,Lt as parseAdvisorMap,To as paymentCreateWithoutAuthorize,Io as paymentWebhookWideTolerance,Co as plaintextSecretInWranglerVariables,ko as policyReferencesUnknownTable,xo as privilegedDispatchUnvalidatedPayload,No as privilegedFanoutFromPublicProcedure,Fo as procedureWithoutStructuredEvent,Oo as publicArgumentUsesAny,Mo as publicMutationWithoutRatelimit,Do as publicTableRlsOptoutConfusion,Po as queueWithoutDlq,$o as r2sqlOutsideAction,Eo as ratelimitDefaultMemoryStore,Ko as ratelimitKeySpoofableOrGlobal,Lo as ratelimitMiddlewareFailOpen,$t as readCallSiteCallers,qo as relationReferencesUnknownField,Go as relationReferencesUnknownTable,_o as rlsUncoveredTable,Ct as runAdvisor,Bt as scoreAdvisor,zo as selfRescheduleWithoutProgress,Ho as shapeTargetsGlobalTable,Bo as shapeUnknownTable,jo as signupMutationWithoutDisposableGating,Vo as softDeleteIncludeDeletedFromArgs,Qo as sqlInjectionRisk,Xo as storageGenerateUploadUrlNoContentTypePin,Zo as storageKeyFromUserArgs,Jo as storagePresignedUrlForPrivateContent,Yo as storageUploadWithoutContentTypeAllowlist,oe as storageUploadWithoutMaxSize,ee as tableWithoutInsert,re as topicTooManySubscriptions,te as ttlFieldNotTimestamp,me as unboundedCollectOnOpenRange,le as unboundedLoop,se as unboundedStringArgument,pe as unindexedForeignKey,fe as unindexedRelationTarget,ce as unrestrictedWhereBranch,de as userCreatingMutationWithoutCaptcha,ue as vectorsNamespaceFromUserInput,he as workflowDuplicateStepName,ge as workflowUnknownTarget,be as workflowUnused};
@@ -1 +1 @@
1
- import{e as a}from"./finding-NrKO8idM.mjs";import{c as r,a as s}from"./helpers-BmppB5nL.mjs";const i={categories:["SECURITY"],description:"An action's `ctx.fetch(url)` fetches a URL derived from the handler's `args`. `ctx.fetch` applies no host allowlist, so request-controlled URLs let a caller reach cloud metadata endpoints or internal services — server-side request forgery.",facing:"EXTERNAL",level:"ERROR",name:"action_fetch_ssrf",remediation:"Validate the URL against an allowlist of expected hosts before fetching, and reject private, loopback, and link-local addresses (notably `169.254.169.254`). Never pass request input straight to `ctx.fetch`.",run:t=>t.argumentDerivedFetches===void 0?[]:t.argumentDerivedFetches.map(e=>a(i,{cacheKey:`action_fetch_ssrf:${e.file}:${e.line.toString()}`,detail:`\`ctx.fetch\` in ${s(e)} fetches a URL derived from \`args\` — a server-side request forgery vector. Validate the URL against a host allowlist and reject private/link-local targets before fetching.`,metadata:{...r(e)}})),source:"static",title:"Possible SSRF from arg-derived ctx.fetch URL"};export{i as default};
1
+ import{e as a}from"./finding-NrKO8idM.mjs";import{c as r,a as s}from"./helpers-BwOMPdUk.mjs";const i={categories:["SECURITY"],description:"An action's `ctx.fetch(url)` fetches a URL derived from the handler's `args`. `ctx.fetch` applies no host allowlist, so request-controlled URLs let a caller reach cloud metadata endpoints or internal services — server-side request forgery.",facing:"EXTERNAL",level:"ERROR",name:"action_fetch_ssrf",remediation:"Validate the URL against an allowlist of expected hosts before fetching, and reject private, loopback, and link-local addresses (notably `169.254.169.254`). Never pass request input straight to `ctx.fetch`.",run:t=>t.argumentDerivedFetches===void 0?[]:t.argumentDerivedFetches.map(e=>a(i,{cacheKey:`action_fetch_ssrf:${e.file}:${e.line.toString()}`,detail:`\`ctx.fetch\` in ${s(e)} fetches a URL derived from \`args\` — a server-side request forgery vector. Validate the URL against a host allowlist and reject private/link-local targets before fetching.`,metadata:{...r(e)}})),source:"static",title:"Possible SSRF from arg-derived ctx.fetch URL"};export{i as default};
@@ -1 +1 @@
1
- import{e as r}from"./finding-NrKO8idM.mjs";import{c as t,a as i}from"./helpers-BmppB5nL.mjs";const s={categories:["SECURITY"],description:"A `ctx.ai.run(model, …)` call selects its model from the handler's `args` with no server-side scoping. `ctx.ai.run` is the raw Workers AI binding passthrough, so an arg-derived model id lets any caller pick an arbitrary model — bypassing the typed `ctx.ai.model(...)` + AI-SDK layer's cap/schema.",facing:"EXTERNAL",level:"WARN",name:"ai_raw_run_escape_hatch",remediation:"Select the model from a fixed server-side allowlist — never from `args`. Prefer the typed `ctx.ai.model(...)` + `generateText`/`streamText` path with an output cap over the raw `ctx.ai.run` escape hatch.",run:a=>a.aiRawRuns===void 0?[]:a.aiRawRuns.map(e=>r(s,{cacheKey:`ai_raw_run_escape_hatch:${e.file}:${e.line.toString()}`,detail:`\`ctx.ai.run\` in ${i(e)} selects its model from \`args\` with no server-side scoping — any caller can pick an arbitrary model, bypassing the typed AI-SDK layer's cap/schema. Select the model from a fixed server-side allowlist instead.`,metadata:{...t(e)}})),source:"static",title:"Possible arbitrary model selection from arg-derived ctx.ai.run"};export{s as default};
1
+ import{e as r}from"./finding-NrKO8idM.mjs";import{c as t,a as i}from"./helpers-BwOMPdUk.mjs";const s={categories:["SECURITY"],description:"A `ctx.ai.run(model, …)` call selects its model from the handler's `args` with no server-side scoping. `ctx.ai.run` is the raw Workers AI binding passthrough, so an arg-derived model id lets any caller pick an arbitrary model — bypassing the typed `ctx.ai.model(...)` + AI-SDK layer's cap/schema.",facing:"EXTERNAL",level:"WARN",name:"ai_raw_run_escape_hatch",remediation:"Select the model from a fixed server-side allowlist — never from `args`. Prefer the typed `ctx.ai.model(...)` + `generateText`/`streamText` path with an output cap over the raw `ctx.ai.run` escape hatch.",run:a=>a.aiRawRuns===void 0?[]:a.aiRawRuns.map(e=>r(s,{cacheKey:`ai_raw_run_escape_hatch:${e.file}:${e.line.toString()}`,detail:`\`ctx.ai.run\` in ${i(e)} selects its model from \`args\` with no server-side scoping — any caller can pick an arbitrary model, bypassing the typed AI-SDK layer's cap/schema. Select the model from a fixed server-side allowlist instead.`,metadata:{...t(e)}})),source:"static",title:"Possible arbitrary model selection from arg-derived ctx.ai.run"};export{s as default};
@@ -1 +1 @@
1
- import{e as o}from"./finding-NrKO8idM.mjs";import{a as n,c as a}from"./helpers-BmppB5nL.mjs";const r={categories:["SECURITY"],description:"A `generateText` / `streamText` call whose prompt/messages carry user-supplied text and whose model-callable `tools` perform a privileged side effect (DB write, `ctx.run` dispatch, or outbound send). An injected instruction in the user text can steer the model into firing that action — the confused-deputy prompt-injection hazard.",facing:"EXTERNAL",level:"WARN",name:"ai_tool_side_effect_prompt_injection",remediation:"Don't let a model with user-derived input directly trigger a privileged action. Have the tool return a proposal the server validates and authorizes before executing, gate the side effect behind an explicit human/step confirmation, or keep side-effecting tools out of any generation whose prompt includes untrusted input.",run:t=>t.aiToolSideEffects===void 0?[]:t.aiToolSideEffects.filter(e=>e.userInputDerived).map(e=>{const i=n(e);return o(r,{cacheKey:`ai_tool_side_effect_prompt_injection:${e.file}:${e.line.toString()}`,detail:`\`${e.method}\` in ${i} feeds user-derived input to a model whose tools reach \`${e.sideEffect}\`. An injected instruction can steer the model into firing that side effect.`,metadata:{...a(e),method:e.method,sideEffect:e.sideEffect}})}),source:"static",title:"AI tool side effect reachable via prompt injection"};export{r as default};
1
+ import{e as o}from"./finding-NrKO8idM.mjs";import{a as n,c as a}from"./helpers-BwOMPdUk.mjs";const r={categories:["SECURITY"],description:"A `generateText` / `streamText` call whose prompt/messages carry user-supplied text and whose model-callable `tools` perform a privileged side effect (DB write, `ctx.run` dispatch, or outbound send). An injected instruction in the user text can steer the model into firing that action — the confused-deputy prompt-injection hazard.",facing:"EXTERNAL",level:"WARN",name:"ai_tool_side_effect_prompt_injection",remediation:"Don't let a model with user-derived input directly trigger a privileged action. Have the tool return a proposal the server validates and authorizes before executing, gate the side effect behind an explicit human/step confirmation, or keep side-effecting tools out of any generation whose prompt includes untrusted input.",run:t=>t.aiToolSideEffects===void 0?[]:t.aiToolSideEffects.filter(e=>e.userInputDerived).map(e=>{const i=n(e);return o(r,{cacheKey:`ai_tool_side_effect_prompt_injection:${e.file}:${e.line.toString()}`,detail:`\`${e.method}\` in ${i} feeds user-derived input to a model whose tools reach \`${e.sideEffect}\`. An injected instruction can steer the model into firing that side effect.`,metadata:{...a(e),method:e.method,sideEffect:e.sideEffect}})}),source:"static",title:"AI tool side effect reachable via prompt injection"};export{r as default};
@@ -1 +1 @@
1
- import{dedupeCacheKeys as i}from"./dedupeCacheKeys-DtBOHffV.mjs";import{e as a}from"./finding-NrKO8idM.mjs";import{c as s,a as r}from"./helpers-BmppB5nL.mjs";const h={categories:["SECURITY"],description:"A `ctx.authApi.<method>(...)` call omits `headers` — better-auth skips session authorization and runs the call with full server-to-server privileges, regardless of the caller's identity.",facing:"EXTERNAL",level:"WARN",name:"auth_api_call_without_headers",remediation:"Pass the inbound `headers` from the incoming request into every `ctx.authApi.*` call: `ctx.authApi.<method>({ body, headers: request.headers })`. See the `withAuthPlugins` middleware doc for details.",run:t=>t.authApiCalls===void 0?[]:i(t.authApiCalls.filter(e=>!e.hasHeaders).map(e=>a(h,{cacheKey:`auth_api_call_without_headers:${e.file}:${e.line.toString()}:${e.method}`,detail:`\`ctx.authApi.${e.method||"<method>"}(…)\` in ${r(e)} is called without \`headers\` — better-auth skips session authorization, so this runs with full privileges. Pass the inbound \`headers\`.`,metadata:{...s(e),method:e.method}}))),source:"static",title:"Privileged ctx.authApi call missing headers"};export{h as default};
1
+ import{dedupeCacheKeys as i}from"./dedupeCacheKeys-DtBOHffV.mjs";import{e as a}from"./finding-NrKO8idM.mjs";import{c as s,a as r}from"./helpers-BwOMPdUk.mjs";const h={categories:["SECURITY"],description:"A `ctx.authApi.<method>(...)` call omits `headers` — better-auth skips session authorization and runs the call with full server-to-server privileges, regardless of the caller's identity.",facing:"EXTERNAL",level:"WARN",name:"auth_api_call_without_headers",remediation:"Pass the inbound `headers` from the incoming request into every `ctx.authApi.*` call: `ctx.authApi.<method>({ body, headers: request.headers })`. See the `withAuthPlugins` middleware doc for details.",run:t=>t.authApiCalls===void 0?[]:i(t.authApiCalls.filter(e=>!e.hasHeaders).map(e=>a(h,{cacheKey:`auth_api_call_without_headers:${e.file}:${e.line.toString()}:${e.method}`,detail:`\`ctx.authApi.${e.method||"<method>"}(…)\` in ${r(e)} is called without \`headers\` — better-auth skips session authorization, so this runs with full privileges. Pass the inbound \`headers\`.`,metadata:{...s(e),method:e.method}}))),source:"static",title:"Privileged ctx.authApi call missing headers"};export{h as default};