@lunora/server 1.0.0-alpha.61 → 1.0.0-alpha.63

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 (32) hide show
  1. package/dist/data-model.d.mts +10 -10
  2. package/dist/data-model.d.ts +10 -10
  3. package/dist/index.d.mts +281 -293
  4. package/dist/index.d.ts +281 -293
  5. package/dist/index.mjs +1 -1
  6. package/dist/packem_shared/{PRESENCE_DEFAULT_TTL_MS-DmnVChTY.mjs → PRESENCE_DEFAULT_TTL_MS-Dyb1szd2.mjs} +1 -1
  7. package/dist/packem_shared/buildRlsReadRegistry-CE5k6akj.mjs +1 -0
  8. package/dist/packem_shared/{composePluginMiddleware-B9NyOR1k.mjs → composePluginMiddleware-ByhCqIGt.mjs} +1 -1
  9. package/dist/packem_shared/{defineAggregateIndex-C3CMy5jn.mjs → defineAggregateIndex-BoiwhUKL.mjs} +1 -1
  10. package/dist/packem_shared/httpAction-BpEJYwzV.mjs +5 -0
  11. package/dist/packem_shared/initLunora-BadfSfpJ.mjs +1 -0
  12. package/dist/packem_shared/mask-Chnz8Z0H.mjs +1 -0
  13. package/dist/packem_shared/middleware-D9_39C5C.mjs +1 -0
  14. package/dist/packem_shared/plugin-184MITA3.mjs +1 -0
  15. package/dist/packem_shared/rls-CI2149Ve.mjs +1 -0
  16. package/dist/packem_shared/storageRules-6_G8JpCv.mjs +1 -0
  17. package/dist/packem_shared/{types.d-C4CMJK8x.d.mts → types.d-B-pIn8rE.d.mts} +2 -2
  18. package/dist/packem_shared/{types.d-DdYF8E18.d.ts → types.d-CdPDEjhz.d.ts} +2 -2
  19. package/dist/rls/testing.d.mts +1 -1
  20. package/dist/rls/testing.d.ts +1 -1
  21. package/dist/rls/testing.mjs +1 -1
  22. package/dist/types.d.mts +21 -21
  23. package/dist/types.d.ts +21 -21
  24. package/package.json +4 -4
  25. package/dist/packem_shared/buildRlsReadRegistry-CA-aUi7I.mjs +0 -1
  26. package/dist/packem_shared/httpAction-C14NuF3V.mjs +0 -4
  27. package/dist/packem_shared/initLunora-DXCOVntr.mjs +0 -1
  28. package/dist/packem_shared/mask-DF7mtxQe.mjs +0 -1
  29. package/dist/packem_shared/optional-writer-override-CXXO30sZ.mjs +0 -1
  30. package/dist/packem_shared/plugin-CDBMGCeQ.mjs +0 -1
  31. package/dist/packem_shared/rls-tRDkICWZ.mjs +0 -1
  32. package/dist/packem_shared/storageRules-BptPZbi8.mjs +0 -1
package/dist/index.d.mts CHANGED
@@ -6,8 +6,8 @@ import { LunoraError as LunoraError$1, LunoraErrorCode } from '@lunora/errors';
6
6
  export type { LunoraErrorCode } from '@lunora/errors';
7
7
  import { Context, Hono } from 'hono';
8
8
  import { WhereOperators, QueryArgs as QueryArgs$2 } from "./data-model.mjs";
9
- import { b as Permission, R as Role, T as TypedDefinePolicyInput, a as Policy, D as DefinePolicyInput, W as WhereInput, c as RlsOptions } from "./packem_shared/types.d-C4CMJK8x.mjs";
10
- export type { d as PolicyContext, e as PolicyDecision, f as PolicyDecisionOf, P as PolicyOperation } from "./packem_shared/types.d-C4CMJK8x.mjs";
9
+ import { W as WhereInput, a as Policy, b as RlsOptions, c as Permission, R as Role, T as TypedDefinePolicyInput, D as DefinePolicyInput } from "./packem_shared/types.d-B-pIn8rE.mjs";
10
+ export type { d as PolicyContext, e as PolicyDecision, f as PolicyDecisionOf, P as PolicyOperation } from "./packem_shared/types.d-B-pIn8rE.mjs";
11
11
  export { type CronJob, type CronJobsBuilder, type CronScheduleKind, type DailySchedule, type IntervalSchedule, type MonthlySchedule, type WeeklySchedule, cronJobs } from '@lunora/scheduler';
12
12
  /**
13
13
  * Make any resolved storage capability bucket-aware so `ctx.storage.bucket(name)`
@@ -51,7 +51,7 @@ type Middleware<ContextIn, ContextOut> = (options: {
51
51
  ctx: ContextIn;
52
52
  next: MiddlewareNext<ContextIn>;
53
53
  }) => ContextOut | Promise<ContextOut>;
54
- /** Options accepted by `initLunora.dataModel&lt;DM>().create(...)`. Reserved for transformer/error-formatter wiring. */
54
+ /** Options accepted by `initLunora.dataModel<DM>().create(...)`. Reserved for transformer/error-formatter wiring. */
55
55
  type CreateOptions = Record<never, never>;
56
56
  /**
57
57
  * `Output` carries the type declared by `.output(validator)`. It defaults to
@@ -66,7 +66,7 @@ interface QueryBuilder<Context, Args extends ArgsValidator, Output = undefined>
66
66
  readonly __lunoraProcedure: "query";
67
67
  /**
68
68
  * Publish this query on the opt-in public REST surface (plan 167) — the
69
- * runtime mints `GET /_lunora/rest/&lt;namespace>/&lt;fn>` (and `POST`), dispatching
69
+ * runtime mints `GET /_lunora/rest/<namespace>/<fn>` (and `POST`), dispatching
70
70
  * THROUGH the procedure so `ctx.auth` / RLS / validators are enforced, and the
71
71
  * generated OpenAPI describes it. Default-closed: omit to keep it RPC-only.
72
72
  */
@@ -93,7 +93,7 @@ interface QueryBuilder<Context, Args extends ArgsValidator, Output = undefined>
93
93
  }) => Output | Promise<Output>) => RegisteredQuery<Args, Output>;
94
94
  /**
95
95
  * Terminal: declare this procedure as a streaming query. The handler is an
96
- * async generator (or any function returning an `AsyncIterable&lt;R>`) that
96
+ * async generator (or any function returning an `AsyncIterable<R>`) that
97
97
  * yields one chunk per server-pushed frame. The third `signal` argument is
98
98
  * tripped when the client cancels — break out of the loop or check
99
99
  * `signal.aborted` between yields. `.output()` does not apply: per-chunk
@@ -117,7 +117,7 @@ interface MutationBuilder<Context, Args extends ArgsValidator, Output = undefine
117
117
  readonly __lunoraProcedure: "mutation";
118
118
  /**
119
119
  * Publish this mutation on the opt-in public REST surface (plan 167) — the
120
- * runtime mints `POST /_lunora/rest/&lt;namespace>/&lt;fn>`, dispatching THROUGH the
120
+ * runtime mints `POST /_lunora/rest/<namespace>/<fn>`, dispatching THROUGH the
121
121
  * procedure so `ctx.auth` / RLS / validators are enforced, and the generated
122
122
  * OpenAPI describes it. Default-closed: omit to keep it RPC-only.
123
123
  */
@@ -162,7 +162,7 @@ interface ActionBuilder<Context, Args extends ArgsValidator, Output = undefined>
162
162
  }) => Output | Promise<Output>) => RegisteredAction<Args, Output>;
163
163
  /**
164
164
  * Publish this action on the opt-in public REST surface (plan 167) — the
165
- * runtime mints `POST /_lunora/rest/&lt;namespace>/&lt;fn>`, dispatching THROUGH the
165
+ * runtime mints `POST /_lunora/rest/<namespace>/<fn>`, dispatching THROUGH the
166
166
  * procedure so `ctx.auth` / RLS / validators are enforced, and the generated
167
167
  * OpenAPI describes it. Default-closed: omit to keep it RPC-only.
168
168
  */
@@ -291,7 +291,7 @@ interface DataModelInit<DataModel> {
291
291
  create: (options?: CreateOptions) => LunoraBuilders;
292
292
  }
293
293
  /**
294
- * Entry point for the procedure builder. `dataModel&lt;DM>()` binds the generated
294
+ * Entry point for the procedure builder. `dataModel<DM>()` binds the generated
295
295
  * `DataModel` (phantom for now), and `.create()` yields the public root builders
296
296
  * plus their `internal*` counterparts.
297
297
  */
@@ -482,7 +482,7 @@ interface FacadeEntry {
482
482
  * Insert many documents into this table in one call. With
483
483
  * `{ skipDuplicates: true }`, UNIQUE breaches resolve to `null` for that row
484
484
  * instead of failing the batch. The typed facade narrows the return to
485
- * `Id&lt;T>[]` when skipDuplicates is not requested.
485
+ * `Id<T>[]` when skipDuplicates is not requested.
486
486
  */
487
487
  insertMany: (documents: ReadonlyArray<Record<string, unknown>>, options?: {
488
488
  limit?: number;
@@ -556,7 +556,7 @@ interface UpsertManyArgs {
556
556
  *
557
557
  * The by-id accessors (`get`/`delete`/`patch`/`replace`) forward the bound
558
558
  * `tableName` as `expectedTable` so the underlying writer scopes its id lookup
559
- * to this table. Without it, a branded `Id&lt;"posts">` carrying another table's
559
+ * to this table. Without it, a branded `Id<"posts">` carrying another table's
560
560
  * id would resolve cross-table (the writer probes every table by id), letting
561
561
  * `ctx.db.posts.get(foreignId)` read — or `.delete`/`.patch`/`.replace`
562
562
  * mutate — a row in an unrelated table (IDOR). Writers that ignore the second
@@ -710,7 +710,7 @@ interface HttpRouteBuilder<SearchParams extends ArgsValidator, Body extends Args
710
710
  /**
711
711
  * Terminal: declare this route as a streaming Server-Sent Events endpoint.
712
712
  * The handler is an async generator (or any function returning an
713
- * `AsyncIterable&lt;R>`) that yields one chunk per SSE `data:` frame; on
713
+ * `AsyncIterable<R>`) that yields one chunk per SSE `data:` frame; on
714
714
  * iterator completion the route writes a final `event: complete` frame; on
715
715
  * throw, an `event: error` frame is written with `{code, message}` before
716
716
  * the stream closes. The chunks are JSON-encoded; `R` is inferred from the
@@ -957,7 +957,7 @@ interface ListArgsSpec<TDocument, F, O extends string> {
957
957
  * `limit` clamped into `[1, maxLimit]`, `orderBy` reshaped from
958
958
  * `{ field, direction }[]` into `ctx.db`'s `{ column: direction }[]`.
959
959
  *
960
- * Returns `QueryArgs&lt;Doc>` — bound to the table, not free — so a mismatch
960
+ * Returns `QueryArgs<Doc>` — bound to the table, not free — so a mismatch
961
961
  * between what this helper declares and what the table actually holds is a
962
962
  * compile error at the `findMany` call site.
963
963
  */
@@ -967,10 +967,10 @@ interface ListArgsSpec<TDocument, F, O extends string> {
967
967
  declare const clampLimit: (limit: number | undefined, fallback: number, maxLimit: number) => number;
968
968
  /**
969
969
  * Declare the filter / sort / page arguments for a list endpoint, plus the
970
- * translation into `ctx.db.&lt;table>.findMany(...)` options. See the module docs
970
+ * translation into `ctx.db.<table>.findMany(...)` options. See the module docs
971
971
  * for the shape and the reasoning behind it.
972
972
  *
973
- * Curried on the document type: `defineListArgs&lt;Doc&lt;"messages">>()({ … })`. The
973
+ * Curried on the document type: `defineListArgs<Doc<"messages">>()({ … })`. The
974
974
  * extra `()` buys the thing that matters — with `Doc` bound, `filter` keys and
975
975
  * `orderBy` entries are checked against the table's real columns, so a typo or a
976
976
  * column renamed out from under the endpoint is a COMPILE error instead of a
@@ -1012,6 +1012,248 @@ interface ShardRankPageResultLike {
1012
1012
  hasMore: boolean;
1013
1013
  rows: ReadonlyArray<RankPageRowLike>;
1014
1014
  }
1015
+ /**
1016
+ * Structural mirror of `@lunora/do`'s `QueryArgs` and `CountArgs`. The
1017
+ * runtime ORM in `@lunora/do`/`@lunora/d1` reads `baseWhere` /
1018
+ * `restrictsCounts` straight off these option objects, so as long as the
1019
+ * fields here stay name-compatible the wrapper is portable across the two
1020
+ * dialects without an inter-package dependency.
1021
+ */
1022
+ interface QueryArgs$1 {
1023
+ baseWhere?: WhereInput;
1024
+ cursor?: null | string;
1025
+ limit?: number;
1026
+ orderBy?: ReadonlyArray<unknown>;
1027
+ /**
1028
+ * Per-target-table read filter the RLS wrapper attaches so a `with` relation
1029
+ * is policy-filtered on its own hop (see `@lunora/do`'s `QueryArgs`). Mirrors
1030
+ * the top-level read: `(table) => readBase(table).baseWhere`.
1031
+ */
1032
+ relationBaseWhere?: (table: string) => undefined | WhereInput;
1033
+ restrictsCounts?: boolean;
1034
+ where?: WhereInput;
1035
+ with?: Record<string, unknown>;
1036
+ }
1037
+ interface CountArgs {
1038
+ baseWhere?: WhereInput;
1039
+ relationBaseWhere?: (table: string) => undefined | WhereInput;
1040
+ restrictsCounts?: boolean;
1041
+ where?: WhereInput;
1042
+ }
1043
+ /** Structural mirror of `@lunora/do`'s `AggregateOptions` — only the fields the wrapper touches. */
1044
+ interface AggregateArgs$1 {
1045
+ baseWhere?: WhereInput;
1046
+ field?: string;
1047
+ op: string;
1048
+ relationBaseWhere?: (table: string) => undefined | WhereInput;
1049
+ restrictsCounts?: boolean;
1050
+ where?: WhereInput;
1051
+ }
1052
+ /** Structural mirror of `@lunora/do`'s `GroupByOptions`. */
1053
+ interface GroupByArgs$1 {
1054
+ agg?: {
1055
+ field?: string;
1056
+ op: string;
1057
+ };
1058
+ baseWhere?: WhereInput;
1059
+ by: ReadonlyArray<string>;
1060
+ relationBaseWhere?: (table: string) => undefined | WhereInput;
1061
+ restrictsCounts?: boolean;
1062
+ where?: WhereInput;
1063
+ }
1064
+ /** Structural mirror of `@lunora/do`'s `RankOptions`. */
1065
+ interface RankArgs {
1066
+ baseWhere?: WhereInput;
1067
+ restrictsCounts?: boolean;
1068
+ row: Record<string, unknown> | string;
1069
+ where?: WhereInput;
1070
+ }
1071
+ /** Structural mirror of `@lunora/do`'s `RankBeforeOptions`. */
1072
+ interface RankBeforeArgs {
1073
+ partitionKey: string;
1074
+ restrictsCounts?: boolean;
1075
+ rowId: string;
1076
+ sortValues: ReadonlyArray<unknown>;
1077
+ }
1078
+ /** Structural mirror of `@lunora/do`'s `RankPageOptions`. */
1079
+ interface RankPageArgs {
1080
+ baseWhere?: WhereInput;
1081
+ cursor?: null | string;
1082
+ restrictsCounts?: boolean;
1083
+ take?: number;
1084
+ where?: WhereInput;
1085
+ }
1086
+ interface QueryPage$1 {
1087
+ continueCursor: null | string;
1088
+ isDone: boolean;
1089
+ page: Record<string, unknown>[];
1090
+ }
1091
+ interface TableReaderLike$1 {
1092
+ collect: () => Promise<Record<string, unknown>[]>;
1093
+ filter: (predicate: (document: Record<string, unknown>) => boolean) => TableReaderLike$1;
1094
+ first: () => Promise<Record<string, unknown> | null>;
1095
+ paginate: (options: {
1096
+ cursor?: null | string;
1097
+ numItems: number;
1098
+ }) => Promise<QueryPage$1>;
1099
+ take: (limit: number) => Promise<Record<string, unknown>[]>;
1100
+ withGeoIndex: (indexName: string, build: (q: unknown) => unknown) => TableReaderLike$1;
1101
+ withIndex: (indexName: string, range?: (q: unknown) => unknown) => TableReaderLike$1;
1102
+ withSearchIndex: (indexName: string, search: (q: unknown) => unknown) => TableReaderLike$1;
1103
+ }
1104
+ /**
1105
+ * Structural projection of the runtime ORM writer. The wrapper relies only
1106
+ * on these fields, so it's interchangeable between `@lunora/do`'s
1107
+ * `DatabaseWriterLike` and `@lunora/d1`'s `DatabaseWriterLike`.
1108
+ */
1109
+ interface DatabaseWriterLike {
1110
+ /**
1111
+ * Reduce matching rows to a scalar. The RLS wrapper AND-merges the read
1112
+ * `baseWhere` into `options` so the reduction only sees policy-visible rows
1113
+ * (safe: an aggregate scoped to `where` never reveals a hidden row — see
1114
+ * `@lunora/do`'s `RestrictableQueryOptions`). Required: the only writer ever
1115
+ * wrapped is `@lunora/do`'s `createShardCtxDb`, which always implements it.
1116
+ */
1117
+ aggregate: (tableName: string, options: AggregateArgs$1) => Promise<null | number>;
1118
+ count: (tableName: string, whereOrArgs?: CountArgs | WhereInput) => Promise<number>;
1119
+ delete: (id: string, expectedTable?: string, options?: {
1120
+ hard?: boolean;
1121
+ }) => Promise<void>;
1122
+ /** Uncapped, chunked erase of a whole table. The RLS wrapper gates each row like a single delete. */
1123
+ deleteAll?: (tableName: string, options?: {
1124
+ chunkSize?: number;
1125
+ hard?: boolean;
1126
+ }) => Promise<{
1127
+ deleted: number;
1128
+ }>;
1129
+ deleteMany: (ids: ReadonlyArray<string>, options?: {
1130
+ limit?: number;
1131
+ }, expectedTable?: string) => Promise<{
1132
+ deleted: number;
1133
+ }>;
1134
+ deleteWhere?: (tableName: string, where: WhereInput, options?: {
1135
+ limit?: number;
1136
+ }) => Promise<{
1137
+ deleted: number;
1138
+ }>;
1139
+ findFirst: (tableName: string, args?: QueryArgs$1) => Promise<Record<string, unknown> | null>;
1140
+ findFirstOrThrow: (tableName: string, args?: QueryArgs$1) => Promise<Record<string, unknown>>;
1141
+ findMany: (tableName: string, args?: QueryArgs$1) => Promise<QueryPage$1>;
1142
+ get: (id: string, expectedTable?: string) => Promise<Record<string, unknown> | null>;
1143
+ /**
1144
+ * Group + reduce. Same `baseWhere` injection as `aggregate`: the per-group
1145
+ * reduction is scoped to policy-visible rows, so a group count tallies only
1146
+ * rows the caller may read. Required for the same reason as `aggregate`.
1147
+ */
1148
+ groupBy: (tableName: string, options: GroupByArgs$1) => Promise<ReadonlyArray<{
1149
+ key: Record<string, unknown>;
1150
+ value: null | number;
1151
+ }>>;
1152
+ insert: (tableName: string, document: Record<string, unknown>) => Promise<string>;
1153
+ insertMany: (tableName: string, documents: ReadonlyArray<Record<string, unknown>>, options?: {
1154
+ limit?: number;
1155
+ skipDuplicates?: boolean;
1156
+ }) => Promise<(string | null)[]>;
1157
+ insertManyUnsafe: (tableName: string, documents: ReadonlyArray<Record<string, unknown>>, options?: {
1158
+ allowExplicitId?: boolean;
1159
+ limit?: number;
1160
+ }) => Promise<string[]>;
1161
+ /**
1162
+ * Optional table-aware lookup. The underlying writer (e.g. `@lunora/do`)
1163
+ * already knows the owning table of an id internally, so it can return
1164
+ * `{ row, tableName }` in a single round-trip. When present, the RLS wrapper
1165
+ * uses it to collapse the per-call membership-probe fan-out (1 `get` + N
1166
+ * `findFirst` across every policy table) down to one lookup. Writers that
1167
+ * don't implement it fall back to the probe path.
1168
+ */
1169
+ lookupById?: (id: string, expectedTable?: string) => Promise<null | {
1170
+ row: Record<string, unknown>;
1171
+ tableName: string;
1172
+ }>;
1173
+ patch: (id: string, patch: Record<string, unknown>, expectedTable?: string) => Promise<void>;
1174
+ patchMany: (patches: ReadonlyArray<{
1175
+ id: string;
1176
+ patch: Record<string, unknown>;
1177
+ }>, options?: {
1178
+ limit?: number;
1179
+ }, expectedTable?: string) => Promise<{
1180
+ patched: number;
1181
+ }>;
1182
+ patchWhere?: (tableName: string, args: {
1183
+ patch: Record<string, unknown>;
1184
+ where: WhereInput;
1185
+ }, options?: {
1186
+ limit?: number;
1187
+ }) => Promise<{
1188
+ patched: number;
1189
+ }>;
1190
+ query: (tableName: string) => TableReaderLike$1;
1191
+ /**
1192
+ * Rank a row within its partition. A position is a count-of-rows-before, so
1193
+ * — exactly like `count()` — it can't be trusted in an RLS-restricted
1194
+ * reader: the wrapper fails it closed with `COUNT_RLS_UNSUPPORTED`. Required
1195
+ * for the same reason as `aggregate`.
1196
+ */
1197
+ rank: (tableName: string, indexName: string, options: RankArgs) => Promise<null | {
1198
+ position: number;
1199
+ total: number;
1200
+ }>;
1201
+ /** Cross-shard rank primitive — same count-of-before RLS hazard as `rank`; failed closed under a read policy. */
1202
+ rankBefore?: (tableName: string, indexName: string, options: RankBeforeArgs) => Promise<{
1203
+ before: number;
1204
+ total: number;
1205
+ }>;
1206
+ /**
1207
+ * Sorted pagination over a rank companion. The companion stores only the
1208
+ * partition + sort keys + id, so an arbitrary read `baseWhere` can't be
1209
+ * enforced against it (and re-filtering the fetched rows would break page
1210
+ * sizing). RLS therefore fails it closed rather than leak hidden rows.
1211
+ * Required for the same reason as `aggregate`.
1212
+ */
1213
+ rankPage: (tableName: string, indexName: string, options?: RankPageArgs) => Promise<QueryPage$1>;
1214
+ /**
1215
+ * Cross-shard companion to `rankPage`: same ranked slice, but each row
1216
+ * keeps its rank-key tuple for the query coordinator's k-way merge. Same
1217
+ * count-of-partition RLS hazard as `rankPage` — failed closed under a read
1218
+ * policy for the identical reason (see `rankPage` above).
1219
+ */
1220
+ rankPageRows?: (tableName: string, indexName: string, options?: RankPageArgs) => Promise<ShardRankPageResultLike>;
1221
+ replace: (id: string, document: Record<string, unknown>, expectedTable?: string) => Promise<void>;
1222
+ restore?: (id: string, expectedTable?: string) => Promise<void>;
1223
+ /**
1224
+ * Whole-shard erase. The RLS wrapper deliberately **fails this closed** rather
1225
+ * than wrapping it — see the wrapper's `wipeShard`.
1226
+ */
1227
+ wipeShard?: (options?: {
1228
+ chunkSize?: number;
1229
+ exclude?: ReadonlyArray<string>;
1230
+ tables?: ReadonlyArray<string>;
1231
+ }) => Promise<{
1232
+ deleted: number;
1233
+ tables: Record<string, number>;
1234
+ }>;
1235
+ }
1236
+ /**
1237
+ * What a procedure's `ctx.db` must structurally satisfy for the middleware
1238
+ * to wrap it. We deliberately mirror `@lunora/do`'s `DatabaseWriterLike`
1239
+ * rather than `@lunora/server`'s nominal `DatabaseWriter`/`DatabaseReader`:
1240
+ * the runtime adapter that flows in is the `DatabaseWriterLike`-shaped one,
1241
+ * and structural matching keeps this module free of an `@lunora/do`-typed
1242
+ * `ctx`.
1243
+ */
1244
+ type RlsDatabase = DatabaseWriterLike;
1245
+ /** Roles list source on the context. Tolerant of older auth states. */
1246
+ type AuthLike = {
1247
+ getIdentity?: () => Promise<Record<string, unknown> | null>;
1248
+ roles?: ReadonlyArray<string>;
1249
+ userId?: null | string;
1250
+ };
1251
+ /** Minimal shape the middleware needs on the incoming ctx. */
1252
+ interface RlsContextIn {
1253
+ auth?: AuthLike;
1254
+ db: RlsDatabase;
1255
+ }
1256
+ declare const rls: <Context extends RlsContextIn = RlsContextIn>(policies: ReadonlyArray<Policy<Context>>, options?: RlsOptions) => Middleware<Context, Context>;
1015
1257
  /**
1016
1258
  * The prefixed tables a single plugin `P` contributes, or an empty map when it
1017
1259
  * ships no schema extension. Mirrors {@link PrefixedTables} at the plugin level
@@ -1030,7 +1272,7 @@ type ExtensionTablesOf<P> = P extends {
1030
1272
  type InstalledTables<T extends Record<string, TableDefinition>, Plugins extends ReadonlyArray<unknown>> = Plugins extends readonly [infer Head, ...infer Rest] ? InstalledTables<ExtensionTablesOf<Head> & T, Rest> : T;
1031
1273
  /**
1032
1274
  * Union every plugin's `ContextOut` in a tuple — the type-level mirror of the
1033
- * `ctx.api.&lt;key>` additions {@link composePluginMiddleware} accumulates as each
1275
+ * `ctx.api.<key>` additions {@link composePluginMiddleware} accumulates as each
1034
1276
  * plugin middleware runs. Independent of the incoming context, which the builder
1035
1277
  * infers at the `.use(...)` site.
1036
1278
  */
@@ -1083,7 +1325,7 @@ interface Plugin<TExtension extends Record<string, TableDefinition> = Record<str
1083
1325
  /**
1084
1326
  * Optional middleware. Users attach with `c.query.use(plugin.middleware)`.
1085
1327
  * The middleware can extend `ctx`; convention is to attach helpers under
1086
- * `ctx.api.&lt;key>`, e.g.
1328
+ * `ctx.api.<key>`, e.g.
1087
1329
  *
1088
1330
  * ```ts
1089
1331
  * middleware: ({ ctx, next }) =>
@@ -1228,7 +1470,7 @@ declare const installPlugins: <T extends Record<string, TableDefinition>, const
1228
1470
  * Compose every plugin's middleware into a single middleware you attach with one
1229
1471
  * `.use(...)`. Plugins without middleware (schema-only) are skipped; the rest run
1230
1472
  * in array order, each seeing the context the previous one widened, so the final
1231
- * `next({ ctx })` the builder receives carries every plugin's `ctx.api.&lt;key>`
1473
+ * `next({ ctx })` the builder receives carries every plugin's `ctx.api.<key>`
1232
1474
  * additions. Equivalent to `.use(a.middleware).use(b.middleware)…` but as one
1233
1475
  * value, the middleware sibling of {@link installPlugins}.
1234
1476
  *
@@ -1388,7 +1630,7 @@ interface TableBuilder<Shape extends Record<string, Validator> = Record<string,
1388
1630
  shardBy: (field: keyof Shape & string) => TableBuilder<Shape>;
1389
1631
  /**
1390
1632
  * Turn on soft delete. Adds a nullable timestamp column (`options.field`,
1391
- * default `deletedAt`) and changes `ctx.db.&lt;table>.delete()` to **set** it
1633
+ * default `deletedAt`) and changes `ctx.db.<table>.delete()` to **set** it
1392
1634
  * instead of removing the row; `onDelete: "cascade"` children are recursively
1393
1635
  * soft-deleted too. **List reads** (`findMany`/`findFirst`/`query()`/`count`/
1394
1636
  * `aggregate`/relation loads) then hide soft-deleted rows unless they pass
@@ -1677,12 +1919,12 @@ interface MaskOptions<Context = unknown> {
1677
1919
  readonly indexFields?: IndexFieldsByTable;
1678
1920
  readonly roles?: ReadonlyArray<Role>;
1679
1921
  }
1680
- interface QueryPage$1 {
1922
+ interface QueryPage {
1681
1923
  continueCursor: null | string;
1682
1924
  isDone: boolean;
1683
1925
  page: Record<string, unknown>[];
1684
1926
  }
1685
- interface QueryArgs$1 {
1927
+ interface QueryArgs {
1686
1928
  baseWhere?: unknown;
1687
1929
  cursor?: null | string;
1688
1930
  limit?: number;
@@ -1690,12 +1932,12 @@ interface QueryArgs$1 {
1690
1932
  where?: unknown;
1691
1933
  with?: Record<string, unknown>;
1692
1934
  }
1693
- interface AggregateArgs$1 {
1935
+ interface AggregateArgs {
1694
1936
  field?: string;
1695
1937
  op: string;
1696
1938
  where?: unknown;
1697
1939
  }
1698
- interface GroupByArgs$1 {
1940
+ interface GroupByArgs {
1699
1941
  agg?: {
1700
1942
  field?: string;
1701
1943
  op: string;
@@ -1717,22 +1959,22 @@ interface SearchScoredDocument {
1717
1959
  document: Record<string, unknown>;
1718
1960
  score: number;
1719
1961
  }
1720
- interface TableReaderLike$1 {
1962
+ interface TableReaderLike {
1721
1963
  [Symbol.asyncIterator]: () => AsyncIterator<Record<string, unknown>>;
1722
1964
  collect: () => Promise<Record<string, unknown>[]>;
1723
1965
  collectWithScores: () => Promise<ScoredDocument[]>;
1724
- filter: (predicate: (document: Record<string, unknown>) => boolean) => TableReaderLike$1;
1966
+ filter: (predicate: (document: Record<string, unknown>) => boolean) => TableReaderLike;
1725
1967
  first: () => Promise<Record<string, unknown> | null>;
1726
- order: (direction: "asc" | "desc") => TableReaderLike$1;
1968
+ order: (direction: "asc" | "desc") => TableReaderLike;
1727
1969
  paginate: (options: {
1728
1970
  cursor?: null | string;
1729
1971
  numItems: number;
1730
- }) => Promise<QueryPage$1>;
1972
+ }) => Promise<QueryPage>;
1731
1973
  take: (limit: number) => Promise<Record<string, unknown>[]>;
1732
1974
  unique: () => Promise<Record<string, unknown> | null>;
1733
- withGeoIndex: (indexName: string, build: (q: unknown) => unknown) => TableReaderLike$1;
1734
- withIndex: (indexName: string, range?: (q: unknown) => unknown) => TableReaderLike$1;
1735
- withSearchIndex: (indexName: string, search: (q: unknown) => unknown) => TableReaderLike$1;
1975
+ withGeoIndex: (indexName: string, build: (q: unknown) => unknown) => TableReaderLike;
1976
+ withIndex: (indexName: string, range?: (q: unknown) => unknown) => TableReaderLike;
1977
+ withSearchIndex: (indexName: string, search: (q: unknown) => unknown) => TableReaderLike;
1736
1978
  }
1737
1979
  /**
1738
1980
  * Structural projection of the runtime ORM writer — the same subset
@@ -1741,7 +1983,7 @@ interface TableReaderLike$1 {
1741
1983
  * inter-package dependency. `rankBefore` is optional (the D1 twin omits it).
1742
1984
  */
1743
1985
  interface MaskDatabase {
1744
- aggregate: (tableName: string, options: AggregateArgs$1) => Promise<null | number>;
1986
+ aggregate: (tableName: string, options: AggregateArgs) => Promise<null | number>;
1745
1987
  count: (tableName: string, whereOrArgs?: unknown) => Promise<number>;
1746
1988
  delete: (id: string, expectedTable?: string) => Promise<void>;
1747
1989
  deleteMany: (ids: ReadonlyArray<string>, options?: {
@@ -1754,11 +1996,11 @@ interface MaskDatabase {
1754
1996
  }) => Promise<{
1755
1997
  deleted: number;
1756
1998
  }>;
1757
- findFirst: (tableName: string, args?: QueryArgs$1) => Promise<Record<string, unknown> | null>;
1758
- findFirstOrThrow: (tableName: string, args?: QueryArgs$1) => Promise<Record<string, unknown>>;
1759
- findMany: (tableName: string, args?: QueryArgs$1) => Promise<QueryPage$1>;
1999
+ findFirst: (tableName: string, args?: QueryArgs) => Promise<Record<string, unknown> | null>;
2000
+ findFirstOrThrow: (tableName: string, args?: QueryArgs) => Promise<Record<string, unknown>>;
2001
+ findMany: (tableName: string, args?: QueryArgs) => Promise<QueryPage>;
1760
2002
  get: (id: string, expectedTable?: string) => Promise<Record<string, unknown> | null>;
1761
- groupBy: (tableName: string, options: GroupByArgs$1) => Promise<ReadonlyArray<{
2003
+ groupBy: (tableName: string, options: GroupByArgs) => Promise<ReadonlyArray<{
1762
2004
  key: Record<string, unknown>;
1763
2005
  value: null | number;
1764
2006
  }>>;
@@ -1788,7 +2030,7 @@ interface MaskDatabase {
1788
2030
  }) => Promise<{
1789
2031
  patched: number;
1790
2032
  }>;
1791
- query: (tableName: string) => TableReaderLike$1;
2033
+ query: (tableName: string) => TableReaderLike;
1792
2034
  rank: (tableName: string, indexName: string, options: unknown) => Promise<null | {
1793
2035
  position: number;
1794
2036
  total: number;
@@ -1797,19 +2039,13 @@ interface MaskDatabase {
1797
2039
  before: number;
1798
2040
  total: number;
1799
2041
  }>;
1800
- rankPage: (tableName: string, indexName: string, options?: unknown) => Promise<QueryPage$1>;
2042
+ rankPage: (tableName: string, indexName: string, options?: unknown) => Promise<QueryPage>;
1801
2043
  /** Cross-shard companion to `rankPage`, gated the same way `rankPage` is masked below. */
1802
2044
  rankPageRows?: (tableName: string, indexName: string, options?: unknown) => Promise<ShardRankPageResultLike>;
1803
2045
  replace: (id: string, document: Record<string, unknown>, expectedTable?: string) => Promise<void>;
1804
2046
  }
1805
- /** Roles list source on the context. Tolerant of older auth states (mirrors RLS's `AuthLike`). */
1806
- type AuthLike$1 = {
1807
- getIdentity?: () => Promise<Record<string, unknown> | null>;
1808
- roles?: ReadonlyArray<string>;
1809
- userId?: null | string;
1810
- };
1811
2047
  interface MaskContextIn {
1812
- auth?: AuthLike$1;
2048
+ auth?: AuthLike;
1813
2049
  db: MaskDatabase;
1814
2050
  }
1815
2051
  /**
@@ -2114,7 +2350,7 @@ declare const definePolicy: <Context = unknown>(input: DefinePolicyInput<Context
2114
2350
  /**
2115
2351
  * Build a project-bound, relation-aware `definePolicy` typed against the
2116
2352
  * generated `DataModel` (`DM`) + `Relations` (`REL`) maps. Codegen emits a
2117
- * `createPolicyDsl&lt;DataModel, Relations>()` binding into `_generated/server.ts`,
2353
+ * `createPolicyDsl<DataModel, Relations>()` binding into `_generated/server.ts`,
2118
2354
  * so importing `definePolicy` from the generated module constrains `table` to a
2119
2355
  * real table name and type-checks the `when` predicate — including Prisma-style
2120
2356
  * relation predicates (`is`/`some`/…) the `@lunora/do` pre-resolver now resolves
@@ -2148,248 +2384,6 @@ declare const definePermission: (name: string, options?: Omit<Permission, "name"
2148
2384
  */
2149
2385
  declare const definePolicies: <Context = unknown>(policies: ReadonlyArray<Policy<Context>>) => ReadonlyArray<Policy<Context>>;
2150
2386
  declare const defineRole: (name: string, options?: Omit<Role, "name">) => Role;
2151
- /**
2152
- * Structural mirror of `@lunora/do`'s `QueryArgs` and `CountArgs`. The
2153
- * runtime ORM in `@lunora/do`/`@lunora/d1` reads `baseWhere` /
2154
- * `restrictsCounts` straight off these option objects, so as long as the
2155
- * fields here stay name-compatible the wrapper is portable across the two
2156
- * dialects without an inter-package dependency.
2157
- */
2158
- interface QueryArgs {
2159
- baseWhere?: WhereInput;
2160
- cursor?: null | string;
2161
- limit?: number;
2162
- orderBy?: ReadonlyArray<unknown>;
2163
- /**
2164
- * Per-target-table read filter the RLS wrapper attaches so a `with` relation
2165
- * is policy-filtered on its own hop (see `@lunora/do`'s `QueryArgs`). Mirrors
2166
- * the top-level read: `(table) => readBase(table).baseWhere`.
2167
- */
2168
- relationBaseWhere?: (table: string) => undefined | WhereInput;
2169
- restrictsCounts?: boolean;
2170
- where?: WhereInput;
2171
- with?: Record<string, unknown>;
2172
- }
2173
- interface CountArgs {
2174
- baseWhere?: WhereInput;
2175
- relationBaseWhere?: (table: string) => undefined | WhereInput;
2176
- restrictsCounts?: boolean;
2177
- where?: WhereInput;
2178
- }
2179
- /** Structural mirror of `@lunora/do`'s `AggregateOptions` — only the fields the wrapper touches. */
2180
- interface AggregateArgs {
2181
- baseWhere?: WhereInput;
2182
- field?: string;
2183
- op: string;
2184
- relationBaseWhere?: (table: string) => undefined | WhereInput;
2185
- restrictsCounts?: boolean;
2186
- where?: WhereInput;
2187
- }
2188
- /** Structural mirror of `@lunora/do`'s `GroupByOptions`. */
2189
- interface GroupByArgs {
2190
- agg?: {
2191
- field?: string;
2192
- op: string;
2193
- };
2194
- baseWhere?: WhereInput;
2195
- by: ReadonlyArray<string>;
2196
- relationBaseWhere?: (table: string) => undefined | WhereInput;
2197
- restrictsCounts?: boolean;
2198
- where?: WhereInput;
2199
- }
2200
- /** Structural mirror of `@lunora/do`'s `RankOptions`. */
2201
- interface RankArgs {
2202
- baseWhere?: WhereInput;
2203
- restrictsCounts?: boolean;
2204
- row: Record<string, unknown> | string;
2205
- where?: WhereInput;
2206
- }
2207
- /** Structural mirror of `@lunora/do`'s `RankBeforeOptions`. */
2208
- interface RankBeforeArgs {
2209
- partitionKey: string;
2210
- restrictsCounts?: boolean;
2211
- rowId: string;
2212
- sortValues: ReadonlyArray<unknown>;
2213
- }
2214
- /** Structural mirror of `@lunora/do`'s `RankPageOptions`. */
2215
- interface RankPageArgs {
2216
- baseWhere?: WhereInput;
2217
- cursor?: null | string;
2218
- restrictsCounts?: boolean;
2219
- take?: number;
2220
- where?: WhereInput;
2221
- }
2222
- interface QueryPage {
2223
- continueCursor: null | string;
2224
- isDone: boolean;
2225
- page: Record<string, unknown>[];
2226
- }
2227
- interface TableReaderLike {
2228
- collect: () => Promise<Record<string, unknown>[]>;
2229
- filter: (predicate: (document: Record<string, unknown>) => boolean) => TableReaderLike;
2230
- first: () => Promise<Record<string, unknown> | null>;
2231
- paginate: (options: {
2232
- cursor?: null | string;
2233
- numItems: number;
2234
- }) => Promise<QueryPage>;
2235
- take: (limit: number) => Promise<Record<string, unknown>[]>;
2236
- withGeoIndex: (indexName: string, build: (q: unknown) => unknown) => TableReaderLike;
2237
- withIndex: (indexName: string, range?: (q: unknown) => unknown) => TableReaderLike;
2238
- withSearchIndex: (indexName: string, search: (q: unknown) => unknown) => TableReaderLike;
2239
- }
2240
- /**
2241
- * Structural projection of the runtime ORM writer. The wrapper relies only
2242
- * on these fields, so it's interchangeable between `@lunora/do`'s
2243
- * `DatabaseWriterLike` and `@lunora/d1`'s `DatabaseWriterLike`.
2244
- */
2245
- interface DatabaseWriterLike {
2246
- /**
2247
- * Reduce matching rows to a scalar. The RLS wrapper AND-merges the read
2248
- * `baseWhere` into `options` so the reduction only sees policy-visible rows
2249
- * (safe: an aggregate scoped to `where` never reveals a hidden row — see
2250
- * `@lunora/do`'s `RestrictableQueryOptions`). Required: the only writer ever
2251
- * wrapped is `@lunora/do`'s `createShardCtxDb`, which always implements it.
2252
- */
2253
- aggregate: (tableName: string, options: AggregateArgs) => Promise<null | number>;
2254
- count: (tableName: string, whereOrArgs?: CountArgs | WhereInput) => Promise<number>;
2255
- delete: (id: string, expectedTable?: string, options?: {
2256
- hard?: boolean;
2257
- }) => Promise<void>;
2258
- /** Uncapped, chunked erase of a whole table. The RLS wrapper gates each row like a single delete. */
2259
- deleteAll?: (tableName: string, options?: {
2260
- chunkSize?: number;
2261
- hard?: boolean;
2262
- }) => Promise<{
2263
- deleted: number;
2264
- }>;
2265
- deleteMany: (ids: ReadonlyArray<string>, options?: {
2266
- limit?: number;
2267
- }, expectedTable?: string) => Promise<{
2268
- deleted: number;
2269
- }>;
2270
- deleteWhere?: (tableName: string, where: WhereInput, options?: {
2271
- limit?: number;
2272
- }) => Promise<{
2273
- deleted: number;
2274
- }>;
2275
- findFirst: (tableName: string, args?: QueryArgs) => Promise<Record<string, unknown> | null>;
2276
- findFirstOrThrow: (tableName: string, args?: QueryArgs) => Promise<Record<string, unknown>>;
2277
- findMany: (tableName: string, args?: QueryArgs) => Promise<QueryPage>;
2278
- get: (id: string, expectedTable?: string) => Promise<Record<string, unknown> | null>;
2279
- /**
2280
- * Group + reduce. Same `baseWhere` injection as `aggregate`: the per-group
2281
- * reduction is scoped to policy-visible rows, so a group count tallies only
2282
- * rows the caller may read. Required for the same reason as `aggregate`.
2283
- */
2284
- groupBy: (tableName: string, options: GroupByArgs) => Promise<ReadonlyArray<{
2285
- key: Record<string, unknown>;
2286
- value: null | number;
2287
- }>>;
2288
- insert: (tableName: string, document: Record<string, unknown>) => Promise<string>;
2289
- insertMany: (tableName: string, documents: ReadonlyArray<Record<string, unknown>>, options?: {
2290
- limit?: number;
2291
- skipDuplicates?: boolean;
2292
- }) => Promise<(string | null)[]>;
2293
- insertManyUnsafe: (tableName: string, documents: ReadonlyArray<Record<string, unknown>>, options?: {
2294
- allowExplicitId?: boolean;
2295
- limit?: number;
2296
- }) => Promise<string[]>;
2297
- /**
2298
- * Optional table-aware lookup. The underlying writer (e.g. `@lunora/do`)
2299
- * already knows the owning table of an id internally, so it can return
2300
- * `{ row, tableName }` in a single round-trip. When present, the RLS wrapper
2301
- * uses it to collapse the per-call membership-probe fan-out (1 `get` + N
2302
- * `findFirst` across every policy table) down to one lookup. Writers that
2303
- * don't implement it fall back to the probe path.
2304
- */
2305
- lookupById?: (id: string, expectedTable?: string) => Promise<null | {
2306
- row: Record<string, unknown>;
2307
- tableName: string;
2308
- }>;
2309
- patch: (id: string, patch: Record<string, unknown>, expectedTable?: string) => Promise<void>;
2310
- patchMany: (patches: ReadonlyArray<{
2311
- id: string;
2312
- patch: Record<string, unknown>;
2313
- }>, options?: {
2314
- limit?: number;
2315
- }, expectedTable?: string) => Promise<{
2316
- patched: number;
2317
- }>;
2318
- patchWhere?: (tableName: string, args: {
2319
- patch: Record<string, unknown>;
2320
- where: WhereInput;
2321
- }, options?: {
2322
- limit?: number;
2323
- }) => Promise<{
2324
- patched: number;
2325
- }>;
2326
- query: (tableName: string) => TableReaderLike;
2327
- /**
2328
- * Rank a row within its partition. A position is a count-of-rows-before, so
2329
- * — exactly like `count()` — it can't be trusted in an RLS-restricted
2330
- * reader: the wrapper fails it closed with `COUNT_RLS_UNSUPPORTED`. Required
2331
- * for the same reason as `aggregate`.
2332
- */
2333
- rank: (tableName: string, indexName: string, options: RankArgs) => Promise<null | {
2334
- position: number;
2335
- total: number;
2336
- }>;
2337
- /** Cross-shard rank primitive — same count-of-before RLS hazard as `rank`; failed closed under a read policy. */
2338
- rankBefore?: (tableName: string, indexName: string, options: RankBeforeArgs) => Promise<{
2339
- before: number;
2340
- total: number;
2341
- }>;
2342
- /**
2343
- * Sorted pagination over a rank companion. The companion stores only the
2344
- * partition + sort keys + id, so an arbitrary read `baseWhere` can't be
2345
- * enforced against it (and re-filtering the fetched rows would break page
2346
- * sizing). RLS therefore fails it closed rather than leak hidden rows.
2347
- * Required for the same reason as `aggregate`.
2348
- */
2349
- rankPage: (tableName: string, indexName: string, options?: RankPageArgs) => Promise<QueryPage>;
2350
- /**
2351
- * Cross-shard companion to `rankPage`: same ranked slice, but each row
2352
- * keeps its rank-key tuple for the query coordinator's k-way merge. Same
2353
- * count-of-partition RLS hazard as `rankPage` — failed closed under a read
2354
- * policy for the identical reason (see `rankPage` above).
2355
- */
2356
- rankPageRows?: (tableName: string, indexName: string, options?: RankPageArgs) => Promise<ShardRankPageResultLike>;
2357
- replace: (id: string, document: Record<string, unknown>, expectedTable?: string) => Promise<void>;
2358
- restore?: (id: string, expectedTable?: string) => Promise<void>;
2359
- /**
2360
- * Whole-shard erase. The RLS wrapper deliberately **fails this closed** rather
2361
- * than wrapping it — see the wrapper's `wipeShard`.
2362
- */
2363
- wipeShard?: (options?: {
2364
- chunkSize?: number;
2365
- exclude?: ReadonlyArray<string>;
2366
- tables?: ReadonlyArray<string>;
2367
- }) => Promise<{
2368
- deleted: number;
2369
- tables: Record<string, number>;
2370
- }>;
2371
- }
2372
- /**
2373
- * What a procedure's `ctx.db` must structurally satisfy for the middleware
2374
- * to wrap it. We deliberately mirror `@lunora/do`'s `DatabaseWriterLike`
2375
- * rather than `@lunora/server`'s nominal `DatabaseWriter`/`DatabaseReader`:
2376
- * the runtime adapter that flows in is the `DatabaseWriterLike`-shaped one,
2377
- * and structural matching keeps this module free of an `@lunora/do`-typed
2378
- * `ctx`.
2379
- */
2380
- type RlsDatabase = DatabaseWriterLike;
2381
- /** Roles list source on the context. Tolerant of older auth states. */
2382
- type AuthLike = {
2383
- getIdentity?: () => Promise<Record<string, unknown> | null>;
2384
- roles?: ReadonlyArray<string>;
2385
- userId?: null | string;
2386
- };
2387
- /** Minimal shape the middleware needs on the incoming ctx. */
2388
- interface RlsContextIn {
2389
- auth?: AuthLike;
2390
- db: RlsDatabase;
2391
- }
2392
- declare const rls: <Context extends RlsContextIn = RlsContextIn>(policies: ReadonlyArray<Policy<Context>>, options?: RlsOptions) => Middleware<Context, Context>;
2393
2387
  /**
2394
2388
  * A predicate matching **no** rows — the deny decision.
2395
2389
  *
@@ -2623,14 +2617,8 @@ declare const defineStorageRule: <Context = unknown>(input: DefineStorageRuleInp
2623
2617
  * immediately rather than as a silently double-evaluated predicate.
2624
2618
  */
2625
2619
  declare const defineStorageRules: <Context = unknown>(rules: ReadonlyArray<StorageRule<Context>>) => ReadonlyArray<StorageRule<Context>>;
2626
- /** The minimal `ctx.auth` shape the middleware reads — a structural subset that the full AuthState satisfies. Tolerant of older auth states (mirrors RLS's `AuthLike`). */
2627
- type StorageAuthLike = {
2628
- getIdentity?: () => Promise<Record<string, unknown> | null>;
2629
- roles?: ReadonlyArray<string>;
2630
- userId?: null | string;
2631
- };
2632
2620
  interface StorageContextIn {
2633
- auth?: StorageAuthLike;
2621
+ auth?: AuthLike;
2634
2622
  storage?: unknown;
2635
2623
  }
2636
2624
  declare const storageRules: <Context extends StorageContextIn = StorageContextIn>(rules: ReadonlyArray<StorageRule<Context>>, options?: StorageRulesOptions) => Middleware<Context, Context>;