@lunora/do 1.0.0-alpha.20 → 1.0.0-alpha.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +30 -90
- package/dist/index.d.ts +30 -90
- package/dist/index.mjs +18 -18
- package/dist/packem_shared/{AGGREGATE_SQL_FUNCTION-CFk6adSu.mjs → AGGREGATE_SQL_FUNCTION-CQsu2Xga.mjs} +5 -3
- package/dist/packem_shared/{CDC_LOG_TABLE-DSycmnDf.mjs → CDC_LOG_TABLE-DZSVKRr7.mjs} +1 -1
- package/dist/packem_shared/{ConflictError-C0STs6bU.mjs → ConflictError-CLoq37xH.mjs} +4 -5
- package/dist/packem_shared/{CountRlsUnsupportedError-28ZvvwKS.mjs → CountRlsUnsupportedError-BGxj0pgS.mjs} +4 -4
- package/dist/packem_shared/{DATA_MIGRATION_STATE_TABLE-DfPxn8I0.mjs → DATA_MIGRATION_STATE_TABLE-DB3IYUR3.mjs} +3 -1
- package/dist/packem_shared/{DEFAULT_MAX_RELATION_KEYS-DU-Y4-LJ.mjs → DEFAULT_MAX_RELATION_KEYS-CjM9Y1_G.mjs} +8 -6
- package/dist/packem_shared/NotFoundError-C70b9hLw.mjs +9 -0
- package/dist/packem_shared/{NotUniqueError-Do5h_jiW.mjs → NotUniqueError-D1U5SBFR.mjs} +63 -55
- package/dist/packem_shared/{RLS_UNWRAP_SYMBOL-EtGQdC9d.mjs → RLS_UNWRAP_SYMBOL-DnjkqVgY.mjs} +6 -5
- package/dist/packem_shared/{ROOT_DO_SIZE_WARN_BYTES-BbHQKxG6.mjs → ROOT_DO_SIZE_WARN_BYTES-BQoX61l-.mjs} +20 -38
- package/dist/packem_shared/{applyOnDelete-BQ-8ZlZ1.mjs → applyOnDelete-CAwZfp-5.mjs} +4 -3
- package/dist/packem_shared/{backfillAggregateIndexes-BZsOqDXP.mjs → backfillAggregateIndexes-DDoT-UUI.mjs} +1 -1
- package/dist/packem_shared/{compileWhereSql-MW_Lk8nJ.mjs → compileWhereSql-DE6yfRcQ.mjs} +2 -1
- package/dist/packem_shared/{createSystemReader-8CzSZP9V.mjs → createSystemReader-D12eNH13.mjs} +4 -2
- package/dist/packem_shared/{ctx-db-shapes-0RaIOy7J.mjs → ctx-db-shapes-Cz9dHyh1.mjs} +1 -1
- package/dist/packem_shared/{isSourceDue-9mJRJ9Ld.mjs → isSourceDue-BptUN8CR.mjs} +3 -2
- package/dist/packem_shared/{materializeExternalRows-Bj6EXy50.mjs → materializeExternalRows-DNcvoLRT.mjs} +2 -2
- package/dist/packem_shared/{runShardMigrations-nIwoQeOK.mjs → runShardMigrations-DeZr0KZp.mjs} +1 -1
- package/dist/packem_shared/{subscription-delivery-Z6nXHvQN.mjs → subscription-delivery-CK8qga-k.mjs} +8 -1
- package/dist/packem_shared/{subscriptionListDeltas-CXwfoEE_.mjs → subscriptionListDeltas-BxygQlXT.mjs} +1 -1
- package/package.json +2 -1
- package/dist/packem_shared/NotFoundError-CMuMZt81.mjs +0 -10
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LunoraError } from '@lunora/errors';
|
|
1
2
|
import { SQL } from 'drizzle-orm';
|
|
2
3
|
import { DrizzleSqliteDODatabase } from 'drizzle-orm/durable-sqlite';
|
|
3
4
|
/**
|
|
@@ -110,17 +111,13 @@ interface GroupByEntry {
|
|
|
110
111
|
value: AggregateResult;
|
|
111
112
|
}
|
|
112
113
|
/**
|
|
113
|
-
* Thrown when `count` runs in an RLS-restricted ctx.
|
|
114
|
-
* (`
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* the operation is invalid in this context, not malformed.
|
|
114
|
+
* Thrown when `count` runs in an RLS-restricted ctx. A `LunoraError` subclass
|
|
115
|
+
* (`code: "COUNT_RLS_UNSUPPORTED"`, `status: 422`) recognised structurally by the
|
|
116
|
+
* runtime's error mapper (via `isLunoraError`), so `@lunora/do` needs no runtime
|
|
117
|
+
* dependency on `@lunora/server`. 422 = the operation is invalid in this context,
|
|
118
|
+
* not malformed.
|
|
119
119
|
*/
|
|
120
|
-
declare class CountRlsUnsupportedError extends
|
|
121
|
-
readonly code: string;
|
|
122
|
-
override readonly name = "LunoraError";
|
|
123
|
-
readonly status: number;
|
|
120
|
+
declare class CountRlsUnsupportedError extends LunoraError {
|
|
124
121
|
constructor(table?: string);
|
|
125
122
|
}
|
|
126
123
|
/**
|
|
@@ -761,37 +758,6 @@ declare class ReactiveCache {
|
|
|
761
758
|
* everyone. Anonymous/subscription callers pass `null` (their own bucket).
|
|
762
759
|
*/
|
|
763
760
|
declare const reactiveCacheKey: (functionPath: string, args: Record<string, unknown>, identity: null | string) => string;
|
|
764
|
-
/**
|
|
765
|
-
* `ctx.db.system` — a best-effort, read-only reader over Lunora's *system*
|
|
766
|
-
* tables.
|
|
767
|
-
*
|
|
768
|
-
* Convex surfaces a handful of read-only system tables (`_scheduled_functions`,
|
|
769
|
-
* `_storage`, ...) through `ctx.db.system`. Lunora mirrors that surface, but with
|
|
770
|
-
* one load-bearing caveat: **the data these tables expose does not live in the
|
|
771
|
-
* shard's SQLite**. Scheduled functions live in the `SchedulerDO`; storage
|
|
772
|
-
* objects live in R2. So unlike `ctx.db.<table>` — which reads the same
|
|
773
|
-
* transactional SQLite snapshot the mutation writes into — `ctx.db.system`
|
|
774
|
-
* reaches across a network/DO boundary on every call.
|
|
775
|
-
*
|
|
776
|
-
* Consequences callers must keep in mind:
|
|
777
|
-
*
|
|
778
|
-
* Asynchronous + eventually consistent: each `collect()` / `get()` issues a fresh
|
|
779
|
-
* read against the backing source. A row a mutation just scheduled may not yet be
|
|
780
|
-
* visible; a job that just fired may still appear pending.
|
|
781
|
-
*
|
|
782
|
-
* NOT part of the transaction snapshot: reading a system table inside a mutation
|
|
783
|
-
* does not pin it; there is no OCC guard and no subscription dependency is
|
|
784
|
-
* recorded. Treat the result as a point-in-time best effort.
|
|
785
|
-
*
|
|
786
|
-
* Read-only: there is no `insert`/`patch`/`delete`. Mutate scheduled jobs via
|
|
787
|
-
* `ctx.scheduler`, storage objects via `ctx.storage`.
|
|
788
|
-
*
|
|
789
|
-
* The reader is intentionally minimal: `query(table).collect()` returns the full
|
|
790
|
-
* list (no indexes, no filtering, no pagination) and `get(table, id)` resolves a
|
|
791
|
-
* single row. That matches Convex's system-table read surface closely enough for
|
|
792
|
-
* the studio / introspection use cases without re-implementing the query
|
|
793
|
-
* planner against a remote source.
|
|
794
|
-
*/
|
|
795
761
|
/** The system tables `ctx.db.system` can read. */
|
|
796
762
|
type SystemTableName = "_scheduled_functions" | "_storage";
|
|
797
763
|
/**
|
|
@@ -1893,14 +1859,12 @@ interface DatabaseWriterLike {
|
|
|
1893
1859
|
system?: SystemDatabaseReader;
|
|
1894
1860
|
}
|
|
1895
1861
|
/**
|
|
1896
|
-
* Thrown by `.unique()` when more than one row matches.
|
|
1897
|
-
*
|
|
1898
|
-
* cross-package
|
|
1899
|
-
*
|
|
1862
|
+
* Thrown by `.unique()` when more than one row matches. A `LunoraError` subclass
|
|
1863
|
+
* (`code: "NOT_UNIQUE"`, `status: 400`) recognised structurally by the
|
|
1864
|
+
* cross-package transport mapper (via `isLunoraError`) without an `instanceof`
|
|
1865
|
+
* check against `@lunora/do`.
|
|
1900
1866
|
*/
|
|
1901
|
-
declare class NotUniqueError extends
|
|
1902
|
-
readonly code: string;
|
|
1903
|
-
readonly status: number;
|
|
1867
|
+
declare class NotUniqueError extends LunoraError {
|
|
1904
1868
|
constructor(message?: string);
|
|
1905
1869
|
}
|
|
1906
1870
|
/**
|
|
@@ -2804,6 +2768,8 @@ interface StudioFeaturesResult {
|
|
|
2804
2768
|
analytics: boolean;
|
|
2805
2769
|
/** `@lunora/auth` is a declared dependency (backs the Users / Sessions / Organizations / Configuration pages). */
|
|
2806
2770
|
auth: boolean;
|
|
2771
|
+
/** `@lunora/container` / `ctx.containers` is used, the app declares containers, or it is a declared dependency. */
|
|
2772
|
+
containers: boolean;
|
|
2807
2773
|
/** `@lunora/flags` / `ctx.flags` is used, or it is a declared dependency. */
|
|
2808
2774
|
flags: boolean;
|
|
2809
2775
|
/** `@lunora/bindings/kv` / `ctx.kv` is used, or it is a declared dependency. */
|
|
@@ -3447,13 +3413,11 @@ declare const clearCapturedMail: (sql: SqlExec) => {
|
|
|
3447
3413
|
/**
|
|
3448
3414
|
* Thrown by `findFirstOrThrow` when no document matches the query.
|
|
3449
3415
|
*
|
|
3450
|
-
*
|
|
3451
|
-
*
|
|
3452
|
-
* `instanceof` check against `@lunora/do`.
|
|
3416
|
+
* A `LunoraError` subclass (`code: "NOT_FOUND"`, `status: 404`) so the
|
|
3417
|
+
* cross-package transport mapper maps it to a 404 structurally (via
|
|
3418
|
+
* `isLunoraError`) without an `instanceof` check against `@lunora/do`.
|
|
3453
3419
|
*/
|
|
3454
|
-
declare class NotFoundError extends
|
|
3455
|
-
readonly code: string;
|
|
3456
|
-
readonly status: number;
|
|
3420
|
+
declare class NotFoundError extends LunoraError {
|
|
3457
3421
|
constructor(message?: string);
|
|
3458
3422
|
}
|
|
3459
3423
|
/**
|
|
@@ -3689,24 +3653,6 @@ interface LogEventInput {
|
|
|
3689
3653
|
* that want the raw values.
|
|
3690
3654
|
*/
|
|
3691
3655
|
/**
|
|
3692
|
-
* Secure-by-default write-path guard for `ctx.db`.
|
|
3693
|
-
*
|
|
3694
|
-
* When a schema is marked `defineSchema(...).rls("required")`, the generated
|
|
3695
|
-
* user-facing ctx wraps its writer with {@link guardWriter}. The guard denies
|
|
3696
|
-
* every read/write against a PROTECTED table (any table not marked `.public()`)
|
|
3697
|
-
* so a procedure that forgot `.use(rls(policies))` fails CLOSED — it can never
|
|
3698
|
-
* silently see or mutate a protected table through the unwrapped writer.
|
|
3699
|
-
*
|
|
3700
|
-
* The guard is transparent to the RLS middleware: it hangs the UNWRAPPED writer
|
|
3701
|
-
* off {@link RLS_UNWRAP_SYMBOL}, so `@lunora/server`'s `rls()` middleware
|
|
3702
|
-
* recovers the raw writer (via the same `Symbol.for` key — no cross-package
|
|
3703
|
-
* import) to evaluate policies and issue policy-filtered reads without tripping
|
|
3704
|
-
* the guard. Only procedures that NEVER engaged RLS keep talking to the guard.
|
|
3705
|
-
*
|
|
3706
|
-
* Admin / migration / studio writers (built from `createShardCtxDb` WITHOUT
|
|
3707
|
-
* `enforceRls`) are never guarded — they are trusted system paths.
|
|
3708
|
-
*/
|
|
3709
|
-
/**
|
|
3710
3656
|
* Well-known symbol the guard hangs the unwrapped writer off of. `Symbol.for`
|
|
3711
3657
|
* (the cross-realm global registry) lets `@lunora/server`'s RLS middleware read
|
|
3712
3658
|
* it WITHOUT importing this module — both sides reference the same registered
|
|
@@ -3715,14 +3661,12 @@ interface LogEventInput {
|
|
|
3715
3661
|
declare const RLS_UNWRAP_SYMBOL: symbol;
|
|
3716
3662
|
/**
|
|
3717
3663
|
* Thrown when a raw (non-RLS) handler touches a protected table under a
|
|
3718
|
-
* `.rls("required")` schema.
|
|
3719
|
-
*
|
|
3720
|
-
* deliberately avoid a hard `@lunora/do` runtime dependency —
|
|
3721
|
-
*
|
|
3722
|
-
*/
|
|
3723
|
-
declare class RlsRequiredError extends
|
|
3724
|
-
readonly code: string;
|
|
3725
|
-
readonly status: number;
|
|
3664
|
+
* `.rls("required")` schema. A `LunoraError` subclass (`code: "RLS_REQUIRED"`,
|
|
3665
|
+
* `status: 403`) recognised structurally across packages (via `isLunoraError`) —
|
|
3666
|
+
* which deliberately avoid a hard `@lunora/do` runtime dependency — without an
|
|
3667
|
+
* `instanceof` check. `table` is kept as an own property.
|
|
3668
|
+
*/
|
|
3669
|
+
declare class RlsRequiredError extends LunoraError {
|
|
3726
3670
|
readonly table: string;
|
|
3727
3671
|
constructor(table: string);
|
|
3728
3672
|
}
|
|
@@ -6585,18 +6529,14 @@ type ConflictKind = "conflict" | "occ" | "restrict" | "trigger" | "unique";
|
|
|
6585
6529
|
* Thrown by mutation handlers when an optimistic-concurrency check fails (or a
|
|
6586
6530
|
* related write guard trips — see {@link ConflictKind}).
|
|
6587
6531
|
*
|
|
6588
|
-
*
|
|
6589
|
-
*
|
|
6590
|
-
*
|
|
6591
|
-
*
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
*/
|
|
6595
|
-
declare class ConflictError extends Error {
|
|
6596
|
-
readonly code: string;
|
|
6532
|
+
* A `LunoraError` subclass (`code: "CONFLICT"`, `status: 409`) so the runtime/DO
|
|
6533
|
+
* transport mappers recognise it structurally (via `isLunoraError`) — structural
|
|
6534
|
+
* callers across packages still avoid a hard `instanceof` dependency on
|
|
6535
|
+
* `@lunora/do`. `kind` is kept as an own property for the metrics layer.
|
|
6536
|
+
*/
|
|
6537
|
+
declare class ConflictError extends LunoraError {
|
|
6597
6538
|
/** Why the conflict fired; `occ` is the contention signal the metrics layer counts. */
|
|
6598
6539
|
readonly kind: ConflictKind;
|
|
6599
|
-
readonly status: number;
|
|
6600
6540
|
constructor(message?: string, kind?: ConflictKind);
|
|
6601
6541
|
}
|
|
6602
6542
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LunoraError } from '@lunora/errors';
|
|
1
2
|
import { SQL } from 'drizzle-orm';
|
|
2
3
|
import { DrizzleSqliteDODatabase } from 'drizzle-orm/durable-sqlite';
|
|
3
4
|
/**
|
|
@@ -110,17 +111,13 @@ interface GroupByEntry {
|
|
|
110
111
|
value: AggregateResult;
|
|
111
112
|
}
|
|
112
113
|
/**
|
|
113
|
-
* Thrown when `count` runs in an RLS-restricted ctx.
|
|
114
|
-
* (`
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* the operation is invalid in this context, not malformed.
|
|
114
|
+
* Thrown when `count` runs in an RLS-restricted ctx. A `LunoraError` subclass
|
|
115
|
+
* (`code: "COUNT_RLS_UNSUPPORTED"`, `status: 422`) recognised structurally by the
|
|
116
|
+
* runtime's error mapper (via `isLunoraError`), so `@lunora/do` needs no runtime
|
|
117
|
+
* dependency on `@lunora/server`. 422 = the operation is invalid in this context,
|
|
118
|
+
* not malformed.
|
|
119
119
|
*/
|
|
120
|
-
declare class CountRlsUnsupportedError extends
|
|
121
|
-
readonly code: string;
|
|
122
|
-
override readonly name = "LunoraError";
|
|
123
|
-
readonly status: number;
|
|
120
|
+
declare class CountRlsUnsupportedError extends LunoraError {
|
|
124
121
|
constructor(table?: string);
|
|
125
122
|
}
|
|
126
123
|
/**
|
|
@@ -761,37 +758,6 @@ declare class ReactiveCache {
|
|
|
761
758
|
* everyone. Anonymous/subscription callers pass `null` (their own bucket).
|
|
762
759
|
*/
|
|
763
760
|
declare const reactiveCacheKey: (functionPath: string, args: Record<string, unknown>, identity: null | string) => string;
|
|
764
|
-
/**
|
|
765
|
-
* `ctx.db.system` — a best-effort, read-only reader over Lunora's *system*
|
|
766
|
-
* tables.
|
|
767
|
-
*
|
|
768
|
-
* Convex surfaces a handful of read-only system tables (`_scheduled_functions`,
|
|
769
|
-
* `_storage`, ...) through `ctx.db.system`. Lunora mirrors that surface, but with
|
|
770
|
-
* one load-bearing caveat: **the data these tables expose does not live in the
|
|
771
|
-
* shard's SQLite**. Scheduled functions live in the `SchedulerDO`; storage
|
|
772
|
-
* objects live in R2. So unlike `ctx.db.<table>` — which reads the same
|
|
773
|
-
* transactional SQLite snapshot the mutation writes into — `ctx.db.system`
|
|
774
|
-
* reaches across a network/DO boundary on every call.
|
|
775
|
-
*
|
|
776
|
-
* Consequences callers must keep in mind:
|
|
777
|
-
*
|
|
778
|
-
* Asynchronous + eventually consistent: each `collect()` / `get()` issues a fresh
|
|
779
|
-
* read against the backing source. A row a mutation just scheduled may not yet be
|
|
780
|
-
* visible; a job that just fired may still appear pending.
|
|
781
|
-
*
|
|
782
|
-
* NOT part of the transaction snapshot: reading a system table inside a mutation
|
|
783
|
-
* does not pin it; there is no OCC guard and no subscription dependency is
|
|
784
|
-
* recorded. Treat the result as a point-in-time best effort.
|
|
785
|
-
*
|
|
786
|
-
* Read-only: there is no `insert`/`patch`/`delete`. Mutate scheduled jobs via
|
|
787
|
-
* `ctx.scheduler`, storage objects via `ctx.storage`.
|
|
788
|
-
*
|
|
789
|
-
* The reader is intentionally minimal: `query(table).collect()` returns the full
|
|
790
|
-
* list (no indexes, no filtering, no pagination) and `get(table, id)` resolves a
|
|
791
|
-
* single row. That matches Convex's system-table read surface closely enough for
|
|
792
|
-
* the studio / introspection use cases without re-implementing the query
|
|
793
|
-
* planner against a remote source.
|
|
794
|
-
*/
|
|
795
761
|
/** The system tables `ctx.db.system` can read. */
|
|
796
762
|
type SystemTableName = "_scheduled_functions" | "_storage";
|
|
797
763
|
/**
|
|
@@ -1893,14 +1859,12 @@ interface DatabaseWriterLike {
|
|
|
1893
1859
|
system?: SystemDatabaseReader;
|
|
1894
1860
|
}
|
|
1895
1861
|
/**
|
|
1896
|
-
* Thrown by `.unique()` when more than one row matches.
|
|
1897
|
-
*
|
|
1898
|
-
* cross-package
|
|
1899
|
-
*
|
|
1862
|
+
* Thrown by `.unique()` when more than one row matches. A `LunoraError` subclass
|
|
1863
|
+
* (`code: "NOT_UNIQUE"`, `status: 400`) recognised structurally by the
|
|
1864
|
+
* cross-package transport mapper (via `isLunoraError`) without an `instanceof`
|
|
1865
|
+
* check against `@lunora/do`.
|
|
1900
1866
|
*/
|
|
1901
|
-
declare class NotUniqueError extends
|
|
1902
|
-
readonly code: string;
|
|
1903
|
-
readonly status: number;
|
|
1867
|
+
declare class NotUniqueError extends LunoraError {
|
|
1904
1868
|
constructor(message?: string);
|
|
1905
1869
|
}
|
|
1906
1870
|
/**
|
|
@@ -2804,6 +2768,8 @@ interface StudioFeaturesResult {
|
|
|
2804
2768
|
analytics: boolean;
|
|
2805
2769
|
/** `@lunora/auth` is a declared dependency (backs the Users / Sessions / Organizations / Configuration pages). */
|
|
2806
2770
|
auth: boolean;
|
|
2771
|
+
/** `@lunora/container` / `ctx.containers` is used, the app declares containers, or it is a declared dependency. */
|
|
2772
|
+
containers: boolean;
|
|
2807
2773
|
/** `@lunora/flags` / `ctx.flags` is used, or it is a declared dependency. */
|
|
2808
2774
|
flags: boolean;
|
|
2809
2775
|
/** `@lunora/bindings/kv` / `ctx.kv` is used, or it is a declared dependency. */
|
|
@@ -3447,13 +3413,11 @@ declare const clearCapturedMail: (sql: SqlExec) => {
|
|
|
3447
3413
|
/**
|
|
3448
3414
|
* Thrown by `findFirstOrThrow` when no document matches the query.
|
|
3449
3415
|
*
|
|
3450
|
-
*
|
|
3451
|
-
*
|
|
3452
|
-
* `instanceof` check against `@lunora/do`.
|
|
3416
|
+
* A `LunoraError` subclass (`code: "NOT_FOUND"`, `status: 404`) so the
|
|
3417
|
+
* cross-package transport mapper maps it to a 404 structurally (via
|
|
3418
|
+
* `isLunoraError`) without an `instanceof` check against `@lunora/do`.
|
|
3453
3419
|
*/
|
|
3454
|
-
declare class NotFoundError extends
|
|
3455
|
-
readonly code: string;
|
|
3456
|
-
readonly status: number;
|
|
3420
|
+
declare class NotFoundError extends LunoraError {
|
|
3457
3421
|
constructor(message?: string);
|
|
3458
3422
|
}
|
|
3459
3423
|
/**
|
|
@@ -3689,24 +3653,6 @@ interface LogEventInput {
|
|
|
3689
3653
|
* that want the raw values.
|
|
3690
3654
|
*/
|
|
3691
3655
|
/**
|
|
3692
|
-
* Secure-by-default write-path guard for `ctx.db`.
|
|
3693
|
-
*
|
|
3694
|
-
* When a schema is marked `defineSchema(...).rls("required")`, the generated
|
|
3695
|
-
* user-facing ctx wraps its writer with {@link guardWriter}. The guard denies
|
|
3696
|
-
* every read/write against a PROTECTED table (any table not marked `.public()`)
|
|
3697
|
-
* so a procedure that forgot `.use(rls(policies))` fails CLOSED — it can never
|
|
3698
|
-
* silently see or mutate a protected table through the unwrapped writer.
|
|
3699
|
-
*
|
|
3700
|
-
* The guard is transparent to the RLS middleware: it hangs the UNWRAPPED writer
|
|
3701
|
-
* off {@link RLS_UNWRAP_SYMBOL}, so `@lunora/server`'s `rls()` middleware
|
|
3702
|
-
* recovers the raw writer (via the same `Symbol.for` key — no cross-package
|
|
3703
|
-
* import) to evaluate policies and issue policy-filtered reads without tripping
|
|
3704
|
-
* the guard. Only procedures that NEVER engaged RLS keep talking to the guard.
|
|
3705
|
-
*
|
|
3706
|
-
* Admin / migration / studio writers (built from `createShardCtxDb` WITHOUT
|
|
3707
|
-
* `enforceRls`) are never guarded — they are trusted system paths.
|
|
3708
|
-
*/
|
|
3709
|
-
/**
|
|
3710
3656
|
* Well-known symbol the guard hangs the unwrapped writer off of. `Symbol.for`
|
|
3711
3657
|
* (the cross-realm global registry) lets `@lunora/server`'s RLS middleware read
|
|
3712
3658
|
* it WITHOUT importing this module — both sides reference the same registered
|
|
@@ -3715,14 +3661,12 @@ interface LogEventInput {
|
|
|
3715
3661
|
declare const RLS_UNWRAP_SYMBOL: symbol;
|
|
3716
3662
|
/**
|
|
3717
3663
|
* Thrown when a raw (non-RLS) handler touches a protected table under a
|
|
3718
|
-
* `.rls("required")` schema.
|
|
3719
|
-
*
|
|
3720
|
-
* deliberately avoid a hard `@lunora/do` runtime dependency —
|
|
3721
|
-
*
|
|
3722
|
-
*/
|
|
3723
|
-
declare class RlsRequiredError extends
|
|
3724
|
-
readonly code: string;
|
|
3725
|
-
readonly status: number;
|
|
3664
|
+
* `.rls("required")` schema. A `LunoraError` subclass (`code: "RLS_REQUIRED"`,
|
|
3665
|
+
* `status: 403`) recognised structurally across packages (via `isLunoraError`) —
|
|
3666
|
+
* which deliberately avoid a hard `@lunora/do` runtime dependency — without an
|
|
3667
|
+
* `instanceof` check. `table` is kept as an own property.
|
|
3668
|
+
*/
|
|
3669
|
+
declare class RlsRequiredError extends LunoraError {
|
|
3726
3670
|
readonly table: string;
|
|
3727
3671
|
constructor(table: string);
|
|
3728
3672
|
}
|
|
@@ -6585,18 +6529,14 @@ type ConflictKind = "conflict" | "occ" | "restrict" | "trigger" | "unique";
|
|
|
6585
6529
|
* Thrown by mutation handlers when an optimistic-concurrency check fails (or a
|
|
6586
6530
|
* related write guard trips — see {@link ConflictKind}).
|
|
6587
6531
|
*
|
|
6588
|
-
*
|
|
6589
|
-
*
|
|
6590
|
-
*
|
|
6591
|
-
*
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
*/
|
|
6595
|
-
declare class ConflictError extends Error {
|
|
6596
|
-
readonly code: string;
|
|
6532
|
+
* A `LunoraError` subclass (`code: "CONFLICT"`, `status: 409`) so the runtime/DO
|
|
6533
|
+
* transport mappers recognise it structurally (via `isLunoraError`) — structural
|
|
6534
|
+
* callers across packages still avoid a hard `instanceof` dependency on
|
|
6535
|
+
* `@lunora/do`. `kind` is kept as an own property for the metrics layer.
|
|
6536
|
+
*/
|
|
6537
|
+
declare class ConflictError extends LunoraError {
|
|
6597
6538
|
/** Why the conflict fired; `occ` is the contention signal the metrics layer counts. */
|
|
6598
6539
|
readonly kind: ConflictKind;
|
|
6599
|
-
readonly status: number;
|
|
6600
6540
|
constructor(message?: string, kind?: ConflictKind);
|
|
6601
6541
|
}
|
|
6602
6542
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
export { exportShardRows, exportShardTable, importShardRows, parseExportShardArgs, parseImportShardArgs, selectExportTables, validateImportRow } from './packem_shared/exportShardRows-DZEhUeyI.mjs';
|
|
2
|
-
export { AGGREGATE_SQL_FUNCTION, aggregateSqlFunction, matchesStaticWhere, normalizeCountArgument, throwingScheduler } from './packem_shared/AGGREGATE_SQL_FUNCTION-
|
|
2
|
+
export { AGGREGATE_SQL_FUNCTION, aggregateSqlFunction, matchesStaticWhere, normalizeCountArgument, throwingScheduler } from './packem_shared/AGGREGATE_SQL_FUNCTION-CQsu2Xga.mjs';
|
|
3
3
|
export { aggregateTableName, coerceAggregateNumber, encodeAggregateKey, foldAggregateTally, readAggregateValue } from './packem_shared/aggregateTableName-CxNqY1Sl.mjs';
|
|
4
|
-
export { CountRlsUnsupportedError, mergeWhere, planAggregateLookup, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy } from './packem_shared/CountRlsUnsupportedError-
|
|
4
|
+
export { CountRlsUnsupportedError, mergeWhere, planAggregateLookup, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy } from './packem_shared/CountRlsUnsupportedError-BGxj0pgS.mjs';
|
|
5
5
|
export { AUTH_METRICS_BUCKETS_TABLE, AUTH_METRICS_BUCKET_MS, AUTH_METRICS_BUCKET_RETENTION, AUTH_METRICS_TABLE, ensureAuthMetricsTables, readAuthMetrics, recordAuthEvent } from './packem_shared/AUTH_METRICS_BUCKETS_TABLE-CiHHYeJi.mjs';
|
|
6
|
-
export { NotUniqueError, assertValidClientId, createShardCtxDb, normalizeIdStructurally } from './packem_shared/NotUniqueError-
|
|
7
|
-
export { DATA_MIGRATION_STATE_TABLE, readMigrationStatus, runDataMigration } from './packem_shared/DATA_MIGRATION_STATE_TABLE-
|
|
6
|
+
export { NotUniqueError, assertValidClientId, createShardCtxDb, normalizeIdStructurally } from './packem_shared/NotUniqueError-D1U5SBFR.mjs';
|
|
7
|
+
export { DATA_MIGRATION_STATE_TABLE, readMigrationStatus, runDataMigration } from './packem_shared/DATA_MIGRATION_STATE_TABLE-DB3IYUR3.mjs';
|
|
8
8
|
export { SCAN_DEP, createDependencyTracker, depKey } from './packem_shared/SCAN_DEP-DLJF8dsj.mjs';
|
|
9
9
|
export { renderSql } from './packem_shared/renderSql-D6eUcn2N.mjs';
|
|
10
10
|
export { diffExternalSource } from './packem_shared/diffExternalSource-Cx9HUPJj.mjs';
|
|
11
|
-
export { materializeExternalRows, readExternalSourceBaseline, runExternalSourceTick } from './packem_shared/materializeExternalRows-
|
|
12
|
-
export { isSourceDue, liftSourceId, pullExternalSourceTick } from './packem_shared/isSourceDue-
|
|
11
|
+
export { materializeExternalRows, readExternalSourceBaseline, runExternalSourceTick } from './packem_shared/materializeExternalRows-DNcvoLRT.mjs';
|
|
12
|
+
export { isSourceDue, liftSourceId, pullExternalSourceTick } from './packem_shared/isSourceDue-BptUN8CR.mjs';
|
|
13
13
|
export { FUNCTION_METRICS_BUCKETS_TABLE, FUNCTION_METRICS_BUCKET_MS, FUNCTION_METRICS_BUCKET_RETENTION, FUNCTION_METRICS_INDEX_TABLE, FUNCTION_METRICS_TABLE, ensureFunctionMetricsTables, readFunctionMetricBuckets, readFunctionMetricIndexHits, readFunctionMetrics, readFunctionMetricsTotals, recordFunctionMetric } from './packem_shared/FUNCTION_METRICS_BUCKETS_TABLE-UDNVD7FS.mjs';
|
|
14
14
|
export { ADMIN_FUNCTIONS, ADMIN_FUNCTION_PREFIX, FLAGS_FUNCTION_PREFIX, RELATION_FUNCTION_PREFIX, facetColumn, listTables, readTablePage, selectMatchingIds } from './packem_shared/ADMIN_FUNCTIONS-DSUQ5fX9.mjs';
|
|
15
15
|
export { LogBuffer } from './packem_shared/LogBuffer-B_Ezju_N.mjs';
|
|
16
16
|
export { MAIL_RETENTION, MAIL_TABLE, clearCapturedMail, ensureMailTable, readCapturedMail, recordCapturedMail } from './packem_shared/MAIL_RETENTION-CPpgl-dX.mjs';
|
|
17
|
-
export { default as NotFoundError } from './packem_shared/NotFoundError-
|
|
17
|
+
export { default as NotFoundError } from './packem_shared/NotFoundError-C70b9hLw.mjs';
|
|
18
18
|
export { armRestore, readBookmark } from './packem_shared/armRestore-BJk53Ro8.mjs';
|
|
19
19
|
export { applySelect, buildSeekWhere, decodeCursor, encodeCursor, normalizeOrderKeys, softDeleteScope } from './packem_shared/applySelect-BvZdFUBT.mjs';
|
|
20
20
|
export { RANK_TIEBREAK, encodePartitionKey, matchesRankStaticWhere, rankTableName, resolveRankPartition, sortColumnName } from './packem_shared/RANK_TIEBREAK-CXhdcA1o.mjs';
|
|
21
21
|
export { ReactiveCache, reactiveCacheKey } from './packem_shared/ReactiveCache-BYlSGY0N.mjs';
|
|
22
22
|
export { serveRelationFanout } from './packem_shared/serveRelationFanout-C5axmGDj.mjs';
|
|
23
|
-
export { DEFAULT_MAX_RELATION_KEYS, assertFlatPredicate, assertShapeShardable, containsRelationPredicate, isRelationPredicate, resolveRelationPredicates } from './packem_shared/DEFAULT_MAX_RELATION_KEYS-
|
|
24
|
-
export { applyOnDelete, fanOutScalarCounts, resolveWith, runRowValidators } from './packem_shared/applyOnDelete-
|
|
25
|
-
export { RLS_UNWRAP_SYMBOL, RlsRequiredError, guardWriter } from './packem_shared/RLS_UNWRAP_SYMBOL-
|
|
23
|
+
export { DEFAULT_MAX_RELATION_KEYS, assertFlatPredicate, assertShapeShardable, containsRelationPredicate, isRelationPredicate, resolveRelationPredicates } from './packem_shared/DEFAULT_MAX_RELATION_KEYS-CjM9Y1_G.mjs';
|
|
24
|
+
export { applyOnDelete, fanOutScalarCounts, resolveWith, runRowValidators } from './packem_shared/applyOnDelete-CAwZfp-5.mjs';
|
|
25
|
+
export { RLS_UNWRAP_SYMBOL, RlsRequiredError, guardWriter } from './packem_shared/RLS_UNWRAP_SYMBOL-DnjkqVgY.mjs';
|
|
26
26
|
export { buildFtsMatch, ftsTableName, scoreDocument, stringifySearchText, tokenizeSearch } from './packem_shared/buildFtsMatch-BLEMawrp.mjs';
|
|
27
27
|
export { M as MIN_ADMIN_TOKEN_LENGTH, a as MIN_AUTH_SECRET_LENGTH, b as buildSecurityAudit } from './packem_shared/security-audit-CucgBice.mjs';
|
|
28
28
|
export { SESSION_DO_TTL_DEFAULT, SessionDO } from './packem_shared/SESSION_DO_TTL_DEFAULT-ilPZsVwu.mjs';
|
|
29
|
-
export { ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, ShardDO } from './packem_shared/ROOT_DO_SIZE_WARN_BYTES-
|
|
29
|
+
export { ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, ShardDO } from './packem_shared/ROOT_DO_SIZE_WARN_BYTES-BQoX61l-.mjs';
|
|
30
30
|
export { SHARD_REGISTRY_DO_NAME, ShardRegistryDO } from './packem_shared/SHARD_REGISTRY_DO_NAME-BsAbi5Mn.mjs';
|
|
31
31
|
export { MAX_SQL_ROWS, assertReadonly, runReadonlySql } from './packem_shared/MAX_SQL_ROWS-dDcFE1YZ.mjs';
|
|
32
|
-
export { createSystemReader } from './packem_shared/createSystemReader-
|
|
33
|
-
export { ConflictError } from './packem_shared/ConflictError-
|
|
32
|
+
export { createSystemReader } from './packem_shared/createSystemReader-D12eNH13.mjs';
|
|
33
|
+
export { ConflictError } from './packem_shared/ConflictError-CLoq37xH.mjs';
|
|
34
34
|
export { hasTrigger, runTriggers } from './packem_shared/hasTrigger-5N6_Fx0A.mjs';
|
|
35
|
-
export { compileWhereSql } from './packem_shared/compileWhereSql-
|
|
36
|
-
export { CDC_LOG_TABLE, applyCdcChanges, readCdcChanges, trimCdcChanges } from './packem_shared/CDC_LOG_TABLE-
|
|
37
|
-
export { backfillAggregateIndexes, backfillRankIndexes } from './packem_shared/backfillAggregateIndexes-
|
|
38
|
-
export { runShardMigrations } from './packem_shared/runShardMigrations-
|
|
35
|
+
export { compileWhereSql } from './packem_shared/compileWhereSql-DE6yfRcQ.mjs';
|
|
36
|
+
export { CDC_LOG_TABLE, applyCdcChanges, readCdcChanges, trimCdcChanges } from './packem_shared/CDC_LOG_TABLE-DZSVKRr7.mjs';
|
|
37
|
+
export { backfillAggregateIndexes, backfillRankIndexes } from './packem_shared/backfillAggregateIndexes-DDoT-UUI.mjs';
|
|
38
|
+
export { runShardMigrations } from './packem_shared/runShardMigrations-DeZr0KZp.mjs';
|
|
39
39
|
export { stableStringify } from './packem_shared/stableStringify-MydiuScU.mjs';
|
|
40
|
-
export { s as subscriptionListDeltas } from './packem_shared/subscription-delivery-
|
|
40
|
+
export { s as subscriptionListDeltas } from './packem_shared/subscription-delivery-CK8qga-k.mjs';
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { LunoraError } from '@lunora/errors';
|
|
2
|
+
|
|
1
3
|
const COUNT_OPTION_KEYS = /* @__PURE__ */ new Set(["baseWhere", "relationBaseWhere", "restrictsCounts", "where"]);
|
|
2
4
|
const matchesStaticWhere = (document, predicate) => {
|
|
3
5
|
for (const [field, expected] of Object.entries(predicate)) {
|
|
@@ -38,16 +40,16 @@ const AGGREGATE_SQL_FUNCTION = { avg: "AVG", count: "COUNT", max: "MAX", min: "M
|
|
|
38
40
|
const aggregateSqlFunction = (op) => {
|
|
39
41
|
const sqlFunction = AGGREGATE_SQL_FUNCTION[op];
|
|
40
42
|
if (sqlFunction === void 0) {
|
|
41
|
-
throw new
|
|
43
|
+
throw new LunoraError("INTERNAL", `unknown aggregate op "${op}": expected one of ${Object.keys(AGGREGATE_SQL_FUNCTION).join(", ")}`);
|
|
42
44
|
}
|
|
43
45
|
return sqlFunction;
|
|
44
46
|
};
|
|
45
47
|
const throwingScheduler = {
|
|
46
48
|
runAfter: () => {
|
|
47
|
-
throw new
|
|
49
|
+
throw new LunoraError("INTERNAL", "ctx.scheduler: no scheduler configured for triggers. Pass `scheduler` to the ctx-db factory.");
|
|
48
50
|
},
|
|
49
51
|
runAt: () => {
|
|
50
|
-
throw new
|
|
52
|
+
throw new LunoraError("INTERNAL", "ctx.scheduler: no scheduler configured for triggers. Pass `scheduler` to the ctx-db factory.");
|
|
51
53
|
}
|
|
52
54
|
};
|
|
53
55
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { sql } from 'drizzle-orm';
|
|
2
2
|
import { r as runDrizzle } from './do-exec-5eQy5cEi.mjs';
|
|
3
|
-
import { ConflictError } from './ConflictError-
|
|
3
|
+
import { ConflictError } from './ConflictError-CLoq37xH.mjs';
|
|
4
4
|
|
|
5
5
|
const CDC_LOG_TABLE = "__cdc_log";
|
|
6
6
|
const migrateCdcLog = (sql$1) => {
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { LunoraError } from '@lunora/errors';
|
|
2
|
+
|
|
3
|
+
class ConflictError extends LunoraError {
|
|
3
4
|
/** Why the conflict fired; `occ` is the contention signal the metrics layer counts. */
|
|
4
5
|
kind;
|
|
5
|
-
status = 409;
|
|
6
6
|
constructor(message = "Optimistic concurrency conflict", kind = "conflict") {
|
|
7
|
-
super(message);
|
|
8
|
-
this.name = "ConflictError";
|
|
7
|
+
super("CONFLICT", message, { name: "ConflictError" });
|
|
9
8
|
this.kind = kind;
|
|
10
9
|
}
|
|
11
10
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
status = 422;
|
|
1
|
+
import { LunoraError } from '@lunora/errors';
|
|
2
|
+
|
|
3
|
+
class CountRlsUnsupportedError extends LunoraError {
|
|
5
4
|
constructor(table) {
|
|
6
5
|
super(
|
|
6
|
+
"COUNT_RLS_UNSUPPORTED",
|
|
7
7
|
table === void 0 ? "count() is not supported in an RLS-restricted context" : `count() is not supported on table "${table}" inside an RLS-restricted context`
|
|
8
8
|
);
|
|
9
9
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { LunoraError } from '@lunora/errors';
|
|
2
|
+
|
|
1
3
|
const DATA_MIGRATION_STATE_TABLE = "__lunora_migrations";
|
|
2
4
|
const DEFAULT_BATCH_SIZE = 100;
|
|
3
5
|
const STALE_CLAIM_TIMEOUT_MS = 3e4;
|
|
@@ -128,7 +130,7 @@ const runDataMigration = async (options) => {
|
|
|
128
130
|
const batchSize = options.batchSize ?? migration.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
129
131
|
const transform = direction === "up" ? migration.up : migration.down;
|
|
130
132
|
if (!transform) {
|
|
131
|
-
throw new
|
|
133
|
+
throw new LunoraError("INTERNAL", `data migration "${migration.id}" has no \`${direction}\` transform`);
|
|
132
134
|
}
|
|
133
135
|
let cursor = null;
|
|
134
136
|
let processed = 0;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LunoraError } from '@lunora/errors';
|
|
2
|
+
import { distinctValues } from './applyOnDelete-CAwZfp-5.mjs';
|
|
2
3
|
|
|
3
4
|
const RELATION_EXISTS_KEY = "__relationExists";
|
|
4
5
|
|
|
@@ -43,7 +44,7 @@ const containsRelationPredicate = (where, schema, tableName) => {
|
|
|
43
44
|
};
|
|
44
45
|
const assertFlatPredicate = (where, schema, tableName, op) => {
|
|
45
46
|
if (where && containsRelationPredicate(where, schema, tableName)) {
|
|
46
|
-
throw new
|
|
47
|
+
throw new LunoraError("INTERNAL", `relation-crossing predicates are not supported in ${op}() — use them in findMany/findFirst or an RLS read policy`);
|
|
47
48
|
}
|
|
48
49
|
};
|
|
49
50
|
const projectChildKeys = async (relation, childWhere, projectField, context, escalatable) => {
|
|
@@ -58,7 +59,8 @@ const projectChildKeys = async (relation, childWhere, projectField, context, esc
|
|
|
58
59
|
if (escalatable) {
|
|
59
60
|
return KEY_OVERFLOW;
|
|
60
61
|
}
|
|
61
|
-
throw new
|
|
62
|
+
throw new LunoraError(
|
|
63
|
+
"INTERNAL",
|
|
62
64
|
`relation predicate on "${relation.table}" matched ${String(keys.length)} rows, exceeding the ${String(context.maxRelationKeys)}-key limit; narrow the predicate (a same-shard EXISTS push-down lifts this cap)`
|
|
63
65
|
);
|
|
64
66
|
}
|
|
@@ -67,7 +69,7 @@ const projectChildKeys = async (relation, childWhere, projectField, context, esc
|
|
|
67
69
|
const compileOperator = async (operator, relation, childWhere, context, escalatable) => {
|
|
68
70
|
const meta = RELATION_OPERATOR_META[operator];
|
|
69
71
|
if (!meta) {
|
|
70
|
-
throw new
|
|
72
|
+
throw new LunoraError("INTERNAL", `unknown relation operator "${operator}"`);
|
|
71
73
|
}
|
|
72
74
|
const { clause, project } = joinColumns(relation);
|
|
73
75
|
const keys = await projectChildKeys(relation, meta.negateChild ? { NOT: childWhere } : childWhere, project, context, escalatable);
|
|
@@ -85,7 +87,7 @@ const compileOperator = async (operator, relation, childWhere, context, escalata
|
|
|
85
87
|
const buildExistsMarker = async (operator, relation, childWhere, parentTable, context) => {
|
|
86
88
|
const meta = RELATION_OPERATOR_META[operator];
|
|
87
89
|
if (!meta) {
|
|
88
|
-
throw new
|
|
90
|
+
throw new LunoraError("INTERNAL", `unknown relation operator "${operator}"`);
|
|
89
91
|
}
|
|
90
92
|
const base = context.relationBaseWhere?.(relation.table);
|
|
91
93
|
const predicatePart = meta.negateChild ? { NOT: childWhere } : childWhere;
|
|
@@ -97,7 +99,7 @@ const buildExistsMarker = async (operator, relation, childWhere, parentTable, co
|
|
|
97
99
|
const assertCardinality = (operator, name, relation) => {
|
|
98
100
|
const meta = RELATION_OPERATOR_META[operator];
|
|
99
101
|
if (meta && meta.kind !== relation.kind) {
|
|
100
|
-
throw new
|
|
102
|
+
throw new LunoraError("INTERNAL", `relation operator "${operator}" requires a to-${meta.kind} relation, but "${name}" is to-${relation.kind}`);
|
|
101
103
|
}
|
|
102
104
|
};
|
|
103
105
|
const resolveRelationNode = async (name, relation, predicate, parentTable, context) => {
|