@lunora/server 1.0.0-alpha.62 → 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 (28) hide show
  1. package/dist/index.d.mts +264 -276
  2. package/dist/index.d.ts +264 -276
  3. package/dist/index.mjs +1 -1
  4. package/dist/packem_shared/{PRESENCE_DEFAULT_TTL_MS-DmnVChTY.mjs → PRESENCE_DEFAULT_TTL_MS-Dyb1szd2.mjs} +1 -1
  5. package/dist/packem_shared/buildRlsReadRegistry-CE5k6akj.mjs +1 -0
  6. package/dist/packem_shared/{composePluginMiddleware-B9NyOR1k.mjs → composePluginMiddleware-ByhCqIGt.mjs} +1 -1
  7. package/dist/packem_shared/{defineAggregateIndex-C3CMy5jn.mjs → defineAggregateIndex-BoiwhUKL.mjs} +1 -1
  8. package/dist/packem_shared/httpAction-BpEJYwzV.mjs +5 -0
  9. package/dist/packem_shared/initLunora-BadfSfpJ.mjs +1 -0
  10. package/dist/packem_shared/mask-Chnz8Z0H.mjs +1 -0
  11. package/dist/packem_shared/middleware-D9_39C5C.mjs +1 -0
  12. package/dist/packem_shared/plugin-184MITA3.mjs +1 -0
  13. package/dist/packem_shared/rls-CI2149Ve.mjs +1 -0
  14. package/dist/packem_shared/storageRules-6_G8JpCv.mjs +1 -0
  15. package/dist/packem_shared/{types.d-BXr-YW9j.d.mts → types.d-B-pIn8rE.d.mts} +1 -1
  16. package/dist/packem_shared/{types.d-D6Lv3h_-.d.ts → types.d-CdPDEjhz.d.ts} +1 -1
  17. package/dist/rls/testing.d.mts +1 -1
  18. package/dist/rls/testing.d.ts +1 -1
  19. package/dist/rls/testing.mjs +1 -1
  20. package/package.json +4 -4
  21. package/dist/packem_shared/buildRlsReadRegistry-CA-aUi7I.mjs +0 -1
  22. package/dist/packem_shared/httpAction-C14NuF3V.mjs +0 -4
  23. package/dist/packem_shared/initLunora-DXCOVntr.mjs +0 -1
  24. package/dist/packem_shared/mask-DF7mtxQe.mjs +0 -1
  25. package/dist/packem_shared/optional-writer-override-CXXO30sZ.mjs +0 -1
  26. package/dist/packem_shared/plugin-CDBMGCeQ.mjs +0 -1
  27. package/dist/packem_shared/rls-tRDkICWZ.mjs +0 -1
  28. 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-BXr-YW9j.mjs";
10
- export type { d as PolicyContext, e as PolicyDecision, f as PolicyDecisionOf, P as PolicyOperation } from "./packem_shared/types.d-BXr-YW9j.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)`
@@ -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
@@ -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
  /**
@@ -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>;