@palbase/backend 24.3.0 → 25.0.1
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/bin/palbase-backend.cjs +103 -60
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +17 -13
- package/dist/bin/palbase-backend.js.map +1 -1
- package/dist/{chunk-EIXCY4SS.js → chunk-34I4GB7D.js} +82 -49
- package/dist/chunk-34I4GB7D.js.map +1 -0
- package/dist/{chunk-UWSYTUGM.js → chunk-35PNTIRN.js} +48 -1
- package/dist/chunk-35PNTIRN.js.map +1 -0
- package/dist/chunk-HBOJLP2Z.js +840 -0
- package/dist/chunk-HBOJLP2Z.js.map +1 -0
- package/dist/{chunk-7Z6MGMXQ.js → chunk-XJ2RSHEU.js} +11 -5
- package/dist/chunk-XJ2RSHEU.js.map +1 -0
- package/dist/{chunk-ERDL5VAE.js → chunk-YOY5DFQS.js} +2 -2
- package/dist/db/env.cjs.map +1 -1
- package/dist/db/env.d.cts +31 -14
- package/dist/db/env.d.ts +31 -14
- package/dist/db/index.cjs +226 -111
- package/dist/db/index.cjs.map +1 -1
- package/dist/db/index.d.cts +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.js +11 -1
- package/dist/engine/index.cjs +89 -50
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +2 -2
- package/dist/engine/index.d.ts +2 -2
- package/dist/engine/index.js +3 -3
- package/dist/{index-BTMYod_l.d.ts → index-B4CcpqLb.d.ts} +224 -75
- package/dist/{index-DEneI8Mn.d.ts → index-B8v6hVyU.d.ts} +5 -2
- package/dist/{index-BLAbr9ZH.d.cts → index-DmVyY6N7.d.cts} +224 -75
- package/dist/{index-C-ALG22n.d.cts → index-VsjBQ4Kw.d.cts} +5 -2
- package/dist/index.cjs +580 -301
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +125 -22
- package/dist/index.d.ts +125 -22
- package/dist/index.js +173 -217
- package/dist/index.js.map +1 -1
- package/dist/openapi/index.cjs +100 -36
- package/dist/openapi/index.cjs.map +1 -1
- package/dist/openapi/index.js +59 -2
- package/dist/openapi/index.js.map +1 -1
- package/docs/README.md +64 -31
- package/docs/endpoints.md +25 -28
- package/docs/llms-full.txt +430 -153
- package/docs/schema.md +303 -91
- package/docs/services.md +39 -4
- package/package.json +1 -1
- package/template/AGENTS.md +119 -314
- package/template/CLAUDE.md +13 -0
- package/template/controllers/notes.controller.ts +6 -13
- package/template/db/public.ts +38 -0
- package/template/models/notes/create.ts +38 -0
- package/template/package.json +6 -3
- package/template/services/note.service.test.ts +45 -0
- package/template/services/note.service.ts +2 -2
- package/dist/chunk-7Z6MGMXQ.js.map +0 -1
- package/dist/chunk-D5CQES25.js +0 -556
- package/dist/chunk-D5CQES25.js.map +0 -1
- package/dist/chunk-EIXCY4SS.js.map +0 -1
- package/dist/chunk-UWSYTUGM.js.map +0 -1
- package/template/db/schema.ts +0 -35
- /package/dist/{chunk-ERDL5VAE.js.map → chunk-YOY5DFQS.js.map} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tables, TableTypes } from './db/env.cjs';
|
|
1
|
+
import { Tables, TableTypes, Schemas } from './db/env.cjs';
|
|
2
2
|
import { D as DBClient, b8 as TxPlanHandle, bh as TxTable, M as Materialized } from './endpoint-BSGw1pTu.cjs';
|
|
3
3
|
|
|
4
4
|
/** On delete action for foreign key references. */
|
|
@@ -26,6 +26,31 @@ interface ColumnDef {
|
|
|
26
26
|
table: string;
|
|
27
27
|
column: string;
|
|
28
28
|
};
|
|
29
|
+
/** Pending FK target, resolved by `defineSchema` once every binding exists. */
|
|
30
|
+
referencesThunk?: () => ColumnBuilder;
|
|
31
|
+
/** FK onto THIS table — no thunk needed, the target is the declaring table. */
|
|
32
|
+
selfRefColumn?: string;
|
|
33
|
+
/** This column OWNS the row: erasure, RLS and the `owner` relation read it. */
|
|
34
|
+
owns?: true;
|
|
35
|
+
/** Explicit name for the FORWARD relation (child → parent), when the one
|
|
36
|
+
* derived from the column would be ambiguous or unclear. */
|
|
37
|
+
refAs?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Explicit name for the REVERSE relation (parent → children).
|
|
40
|
+
*
|
|
41
|
+
* Separate from {@link refAs} because the two directions are different facts:
|
|
42
|
+
* the forward name describes the parent this row points at (`author`), the
|
|
43
|
+
* reverse one describes the rows hanging off the parent (`posts`). One option
|
|
44
|
+
* naming both made an ordinary schema undeclarable — `posts.author_id` and
|
|
45
|
+
* `comments.author_id` both named `{ as: "author" }` collided on `users`, and
|
|
46
|
+
* the refusal asked for the `{ as }` they had both already written.
|
|
47
|
+
*/
|
|
48
|
+
reverseAs?: string;
|
|
49
|
+
/** The table this column belongs to; set by `defineTable`. */
|
|
50
|
+
ownerTable?: {
|
|
51
|
+
name: string;
|
|
52
|
+
columns: Record<string, ColumnBuilder>;
|
|
53
|
+
};
|
|
29
54
|
/**
|
|
30
55
|
* The name this column used to have. A diff cannot tell a rename from a drop and
|
|
31
56
|
* an add — both leave one name gone and another present — so the intent has to be
|
|
@@ -171,47 +196,44 @@ declare class ColumnBuilder<K extends ColumnType = ColumnType, N extends boolean
|
|
|
171
196
|
* safety gate in silence.
|
|
172
197
|
*/
|
|
173
198
|
ignored(): ColumnBuilder<K, N, D, E, P, T>;
|
|
174
|
-
references(table: string, column: string): ColumnBuilder<K, N, D, E, P, T>;
|
|
175
199
|
/**
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
200
|
+
* Foreign key onto another table's column.
|
|
201
|
+
*
|
|
202
|
+
* The target is a THUNK, not a direct reference. In a cycle (`x → y`, `y → x`)
|
|
203
|
+
* the second table does not exist yet when the first is built; a direct
|
|
204
|
+
* reference makes TypeScript chase its own tail (TS7022 — measured, and making
|
|
205
|
+
* the return type independent of the target does NOT help). The thunk is
|
|
206
|
+
* invoked in `defineSchema`, where every binding exists and every table
|
|
207
|
+
* already knows its name.
|
|
180
208
|
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
* the referencing column must be `text()` too.
|
|
209
|
+
* In a cycle, ONE side needs an explicit return type:
|
|
210
|
+
* `references((): AnyColumn => y.id)`. One side is enough — measured.
|
|
211
|
+
* For a self-reference use `selfReferences(column)`: no thunk, no annotation.
|
|
185
212
|
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* `
|
|
190
|
-
*
|
|
191
|
-
* (validateAuthUserFK) enforces this — and the remaining rules the type can't
|
|
192
|
-
* express (referencing column is text, `set null` needs a nullable column) —
|
|
193
|
-
* as the real boundary; this signature is the compile-time DX mirror.
|
|
213
|
+
* `as` names the FORWARD relation (`author_id` → `author` by default);
|
|
214
|
+
* `reverseAs` names the REVERSE one on the parent, whose default is this
|
|
215
|
+
* table's own name (`users.posts`). Two foreign keys from one table onto one
|
|
216
|
+
* parent therefore need a `reverseAs` on at least one of them — the reverse
|
|
217
|
+
* names would otherwise both be this table's name.
|
|
194
218
|
*/
|
|
195
|
-
|
|
219
|
+
references(target: () => AnyColumn, opts?: {
|
|
220
|
+
as?: string;
|
|
221
|
+
reverseAs?: string;
|
|
222
|
+
onDelete?: OnDeleteAction;
|
|
223
|
+
}): ColumnBuilder<K, N, D, E, P, T>;
|
|
196
224
|
/**
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
* root (`ins_...`). Sugar for `.references("auth.installations", "id")`.
|
|
225
|
+
* Foreign key onto THIS table (`parent_id → id`) — category trees, comment
|
|
226
|
+
* replies, org charts.
|
|
200
227
|
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
* routing, …), alongside a separate auth-user FK where the row is user-owned.
|
|
206
|
-
*
|
|
207
|
-
* `auth.installations` lives in the SAME tenant DB (palauth-owned); its `id` is
|
|
208
|
-
* `text` (`ins_<uuid>`), so the referencing column must be `text()` too. ON
|
|
209
|
-
* DELETE is REQUIRED and may only be `cascade` or `set null` (same allowed set
|
|
210
|
-
* as an auth-user FK): an installation revoke / orphan cleanup must never be
|
|
211
|
-
* blocked by a lingering FK. The server (validateAuthAnchorFK) is the real
|
|
212
|
-
* boundary; this signature is the compile-time DX mirror.
|
|
228
|
+
* No thunk and no type annotation: the target table is the one being declared,
|
|
229
|
+
* so there is nothing to defer and nothing for TypeScript to chase in a circle.
|
|
230
|
+
* Drizzle forces an explicit `(): AnyPgColumn =>` here because its reference
|
|
231
|
+
* always goes through a callback; measured, we do not need one.
|
|
213
232
|
*/
|
|
214
|
-
|
|
233
|
+
selfReferences(column: string, opts?: {
|
|
234
|
+
as?: string;
|
|
235
|
+
onDelete?: OnDeleteAction;
|
|
236
|
+
}): ColumnBuilder<K, N, D, E, P, T>;
|
|
215
237
|
/** Set the ON DELETE action for a foreign key reference. */
|
|
216
238
|
onDelete(action: OnDeleteAction): ColumnBuilder<K, N, D, E, P, T>;
|
|
217
239
|
/** Add a single-column UNIQUE constraint. */
|
|
@@ -310,6 +332,54 @@ declare function enumType<const V extends readonly string[]>(name: string, value
|
|
|
310
332
|
* 2000 = pgvector'ün HNSW-indekslenebilir tavanı; auto-index bu beyanla bağlı
|
|
311
333
|
* (spec FR-001, D-3). */
|
|
312
334
|
declare function vector(dimensions: number): ColumnBuilder<'vector', false, false, unknown, number[]>;
|
|
335
|
+
/**
|
|
336
|
+
* Any column, whatever its type parameters.
|
|
337
|
+
*
|
|
338
|
+
* Exported so a cycle can be broken from ONE side:
|
|
339
|
+
* `references((): AnyColumn => y.id)`.
|
|
340
|
+
*/
|
|
341
|
+
type AnyColumn = ColumnBuilder;
|
|
342
|
+
/**
|
|
343
|
+
* The column that OWNS this row: a `text` FK onto `auth.users(id)`, NOT NULL,
|
|
344
|
+
* ON DELETE CASCADE.
|
|
345
|
+
*
|
|
346
|
+
* Ownership drives account erasure, so cascade is the only correct action and
|
|
347
|
+
* takes no argument. The referencing column must be `text` (palauth ids are
|
|
348
|
+
* `usr_<uuid>`) and NOT NULL — both are implied here rather than left to the
|
|
349
|
+
* caller, so three rules the type could not express before become UNWRITABLE.
|
|
350
|
+
*
|
|
351
|
+
* At most ONE per table. The old shape let several columns reference
|
|
352
|
+
* `auth.users` and picked the FIRST IN DECLARATION ORDER as the owner — moving a
|
|
353
|
+
* `created_by` above a `user_id` silently changed which rows an account deletion
|
|
354
|
+
* took with it. A second one is now rejected at push.
|
|
355
|
+
*
|
|
356
|
+
* For a column that merely POINTS at a user without owning the row
|
|
357
|
+
* (`created_by`, `edited_by`), use `userRef({ onDelete })`.
|
|
358
|
+
*/
|
|
359
|
+
declare function ownedByUser(): ColumnBuilder<'text', false, false, never>;
|
|
360
|
+
/**
|
|
361
|
+
* A plain FK onto `auth.users(id)` that does NOT own the row.
|
|
362
|
+
*
|
|
363
|
+
* `created_by` / `edited_by`: deleting that user must not delete the row. ON
|
|
364
|
+
* DELETE is required and limited to `cascade | set null` so an erasure request
|
|
365
|
+
* is never blocked by a lingering FK; `set null` needs a nullable column.
|
|
366
|
+
*/
|
|
367
|
+
declare function userRef(opts: {
|
|
368
|
+
onDelete: AuthUserOnDelete;
|
|
369
|
+
as?: string;
|
|
370
|
+
}): ColumnBuilder<'text', boolean, false, never>;
|
|
371
|
+
/**
|
|
372
|
+
* A plain FK onto `auth.installations(id)` — the app-scoped verified-device
|
|
373
|
+
* anchor.
|
|
374
|
+
*
|
|
375
|
+
* An installation is an APP INSTALL, not a user: this is NOT ownership. A
|
|
376
|
+
* user-owned row still needs its own `ownedByUser()` so account erasure removes
|
|
377
|
+
* it; an installation reference alone does not tie a row to a user's deletion.
|
|
378
|
+
*/
|
|
379
|
+
declare function installationRef(opts: {
|
|
380
|
+
onDelete: AuthUserOnDelete;
|
|
381
|
+
as?: string;
|
|
382
|
+
}): ColumnBuilder<'text', boolean, false, never>;
|
|
313
383
|
|
|
314
384
|
/**
|
|
315
385
|
* policy.ts — the RLS policy authoring DSL.
|
|
@@ -438,7 +508,8 @@ declare const EXTENSION_DEPENDENCIES: Partial<Record<PalbaseExtension, PalbaseEx
|
|
|
438
508
|
declare function isPalbaseExtension(name: string): name is PalbaseExtension;
|
|
439
509
|
|
|
440
510
|
/**
|
|
441
|
-
* A named raw-SQL DDL object declared in db/
|
|
511
|
+
* A named raw-SQL DDL object declared in a schema file (`db/public.ts`,
|
|
512
|
+
* `db/billing.ts`, …) for anything the typed DSL
|
|
442
513
|
* cannot express (EXCLUDE, CHECK, partial/expression indexes, triggers, views).
|
|
443
514
|
* The deploy emits `up` verbatim on the privileged DDL connection — same trust
|
|
444
515
|
* posture as policy().using(). Tracked by NAME (not by diffing the body), so a
|
|
@@ -482,7 +553,7 @@ declare const openai: {
|
|
|
482
553
|
|
|
483
554
|
/**
|
|
484
555
|
* A map of column builders keyed by column name — the value you write under
|
|
485
|
-
* the `columns` key of `
|
|
556
|
+
* the `columns` key of `defineTable("<name>", { columns })`.
|
|
486
557
|
*
|
|
487
558
|
* The default `Record<string, ColumnBuilder>` keeps bare references compiling
|
|
488
559
|
* without a type argument.
|
|
@@ -655,55 +726,50 @@ interface TableDef<C extends ColumnMap = ColumnMap> {
|
|
|
655
726
|
* `TableDef<{ id: ColumnBuilder<'uuid', false, true, never>; ... }>`.
|
|
656
727
|
*/
|
|
657
728
|
interface SchemaDef<T extends Record<string, TableDef> = Record<string, TableDef>> {
|
|
729
|
+
/** The schema's own name — `public`, `billing`, … Declared, never derived. */
|
|
730
|
+
name: string;
|
|
731
|
+
/** Reachable over HTTP? False unless the author opts in. */
|
|
732
|
+
exposed: boolean;
|
|
658
733
|
tables: T;
|
|
659
734
|
/** Postgres extensions to install on deploy. Normalized to `[]` when absent. */
|
|
660
735
|
extensions: PalbaseExtension[];
|
|
661
736
|
}
|
|
662
|
-
/** The author-facing input to `defineSchema` — a `tables` map whose keys are
|
|
663
|
-
* the table names and whose values are `{ columns, rls?, policies? }`, plus an
|
|
664
|
-
* optional `extensions` allowlist. */
|
|
665
|
-
interface SchemaInput<T extends Record<string, TableInput> = Record<string, TableInput>> {
|
|
666
|
-
tables: T;
|
|
667
|
-
/**
|
|
668
|
-
* Postgres extensions to enable for this project, e.g. `["vector"]`.
|
|
669
|
-
* Config-as-code: installed by the deploy (CREATE EXTENSION … SCHEMA
|
|
670
|
-
* extensions) with the privileged deploy connection. The type is an
|
|
671
|
-
* allowlist union, so unsupported names fail typecheck.
|
|
672
|
-
*/
|
|
673
|
-
extensions?: PalbaseExtension[];
|
|
674
|
-
}
|
|
675
737
|
/** Map the author's `{ tables: { <name>: { columns } } }` input to the
|
|
676
738
|
* `{ tables: { <name>: TableDef<columns> } }` runtime/type shape, threading the
|
|
677
739
|
* per-table column map `T[K]["columns"]` so column-level inference survives. */
|
|
678
|
-
type
|
|
679
|
-
[K in
|
|
740
|
+
type TablesByName<T extends readonly TableHandle[]> = {
|
|
741
|
+
[K in T[number] as K[typeof TABLE_META]["name"]]: K[typeof TABLE_META];
|
|
680
742
|
};
|
|
681
743
|
/**
|
|
682
|
-
*
|
|
683
|
-
*
|
|
744
|
+
* How a schema file reads. One file per schema — `db/public.ts`, `db/billing.ts`
|
|
745
|
+
* — and the schema says its own name:
|
|
684
746
|
*
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
*
|
|
688
|
-
*
|
|
689
|
-
*
|
|
690
|
-
* owner: text().notNull(),
|
|
691
|
-
* title: text().notNull(),
|
|
692
|
-
* },
|
|
693
|
-
* rls: true,
|
|
694
|
-
* policies: [
|
|
695
|
-
* policy("owner_all").for("all").to("authenticated")
|
|
696
|
-
* .using("owner = (select auth.uid())")
|
|
697
|
-
* .withCheck("owner = (select auth.uid())"),
|
|
698
|
-
* ],
|
|
699
|
-
* },
|
|
747
|
+
* const todos = defineTable("todos", {
|
|
748
|
+
* columns: {
|
|
749
|
+
* id: uuid().primaryKey().defaultRandom(),
|
|
750
|
+
* owner: text().notNull(),
|
|
751
|
+
* title: text().notNull(),
|
|
700
752
|
* },
|
|
753
|
+
* rls: true,
|
|
754
|
+
* policies: [
|
|
755
|
+
* policy("owner_all").for("all").to("authenticated")
|
|
756
|
+
* .using("owner = (select auth.uid())")
|
|
757
|
+
* .withCheck("owner = (select auth.uid())"),
|
|
758
|
+
* ],
|
|
701
759
|
* });
|
|
702
760
|
*
|
|
703
|
-
*
|
|
704
|
-
*
|
|
705
|
-
*
|
|
706
|
-
*
|
|
761
|
+
* export default defineSchema("public", { tables: [todos] });
|
|
762
|
+
*
|
|
763
|
+
* The dictionary form `defineSchema({ tables: { todos: {…} } })` is RETIRED and
|
|
764
|
+
* refused by name: a table whose name comes from a key does not know what it is
|
|
765
|
+
* called while it is being built, so it cannot resolve `references(() =>
|
|
766
|
+
* other.id)`, and a schema that does not say its own name cannot tell one
|
|
767
|
+
* `invoices` from another schema's `invoices`.
|
|
768
|
+
*
|
|
769
|
+
* The returned value is `{ name, tables: { todos: { name, columns, rls,
|
|
770
|
+
* policies } }, extensions, exposed }` — the exact shape the runtime schema
|
|
771
|
+
* extractor parses. Per-column phantom types are preserved so
|
|
772
|
+
* `Database.tables.todos.insert({...})` stays typed.
|
|
707
773
|
*
|
|
708
774
|
* RLS normalization: `rls` defaults to **`true`**, `policies` to `[]`. A table
|
|
709
775
|
* that declares neither is therefore deny-all — nothing reads it until a policy
|
|
@@ -713,7 +779,46 @@ type TablesFromInput<T extends Record<string, TableInput>> = {
|
|
|
713
779
|
* `rls` is forced on (ENABLE + FORCE) regardless of the declared flag — a table
|
|
714
780
|
* with policies must have RLS enabled or the policies would be inert.
|
|
715
781
|
*/
|
|
716
|
-
|
|
782
|
+
/**
|
|
783
|
+
* Where a table's metadata lives.
|
|
784
|
+
*
|
|
785
|
+
* The table VALUE is its columns, so `lists.id` is the column — which means a
|
|
786
|
+
* column called `name` would overwrite the table's own name if metadata sat in
|
|
787
|
+
* a plain field. Measured, not imagined: the existing `users` / `rooms` tests
|
|
788
|
+
* (both declare a `name` column) produced an `[object Object]` table key.
|
|
789
|
+
* `columns`, `rls`, `search`, `memory`, `unique` and `indexes` are all plausible
|
|
790
|
+
* column names too. A column cannot collide with a symbol.
|
|
791
|
+
*/
|
|
792
|
+
declare const TABLE_META: unique symbol;
|
|
793
|
+
/** A value produced by `defineTable`: the columns, plus metadata behind the symbol. */
|
|
794
|
+
type TableHandle<C extends ColumnMap = ColumnMap, N extends string = string> = C & {
|
|
795
|
+
readonly [TABLE_META]: TableDef<C> & {
|
|
796
|
+
name: N;
|
|
797
|
+
};
|
|
798
|
+
};
|
|
799
|
+
/**
|
|
800
|
+
* Declare one table as a standalone value that KNOWS ITS OWN NAME.
|
|
801
|
+
*
|
|
802
|
+
* The name lives here, not in a dictionary key. A table whose name comes from a
|
|
803
|
+
* key cannot resolve `references(() => other.id)` when it is built — it does not
|
|
804
|
+
* know what to call itself — which forces a two-phase resolution with an
|
|
805
|
+
* empty-name intermediate state. One name source, no empty identity.
|
|
806
|
+
*
|
|
807
|
+
* The returned object spreads its own columns, so a sibling can point at it:
|
|
808
|
+
* `references(() => lists.id)`.
|
|
809
|
+
*/
|
|
810
|
+
declare function defineTable<const N extends string, C extends ColumnMap>(name: N, input: TableInput<C>): TableHandle<C, N>;
|
|
811
|
+
/**
|
|
812
|
+
* Collect declared tables into one schema.
|
|
813
|
+
*
|
|
814
|
+
* Takes an ARRAY, not a dictionary: the tables already carry their names, and a
|
|
815
|
+
* second name source is a second thing that can disagree.
|
|
816
|
+
*/
|
|
817
|
+
declare function defineSchema<const T extends readonly TableHandle[]>(name: string, input: {
|
|
818
|
+
tables: T;
|
|
819
|
+
exposed?: boolean;
|
|
820
|
+
extensions?: PalbaseExtension[];
|
|
821
|
+
}): SchemaDef<TablesByName<T>>;
|
|
717
822
|
|
|
718
823
|
/**
|
|
719
824
|
* typed-db.ts — Task 2: TypedDB schema-derived insert/row shapes.
|
|
@@ -978,6 +1083,26 @@ type EnvTypedTable<T extends TableTypes> = EnvTypedTableBase<T> & (T extends {
|
|
|
978
1083
|
type EnvTables = {
|
|
979
1084
|
[K in keyof Tables]: EnvTypedTable<Tables[K]>;
|
|
980
1085
|
};
|
|
1086
|
+
/**
|
|
1087
|
+
* The project's NON-public schemas, keyed by schema name, each exposing its own
|
|
1088
|
+
* `tables` map — the shape `Database.schema("billing")` returns.
|
|
1089
|
+
*
|
|
1090
|
+
* The intermediate `tables` is there for the reason {@link EnvTables} sits under
|
|
1091
|
+
* `.tables`: a schema's table names must not share a namespace with anything the
|
|
1092
|
+
* accessor itself might grow.
|
|
1093
|
+
*
|
|
1094
|
+
* Empty by default. The generated `palbase-env.d.ts` augments `Schemas` with one
|
|
1095
|
+
* member per declared schema other than `public`, so a project that declares
|
|
1096
|
+
* none has `keyof Schemas = never` and every `schema(...)` call is a compile
|
|
1097
|
+
* error rather than a runtime surprise.
|
|
1098
|
+
*/
|
|
1099
|
+
type EnvSchemas = {
|
|
1100
|
+
[S in keyof Schemas]: {
|
|
1101
|
+
tables: {
|
|
1102
|
+
[T in keyof Schemas[S]]: EnvTypedTable<Extract<Schemas[S][T], TableTypes>>;
|
|
1103
|
+
};
|
|
1104
|
+
};
|
|
1105
|
+
};
|
|
981
1106
|
/** The project's tables as PLAN operations, keyed by the env `Tables`
|
|
982
1107
|
* interface. The transaction twin of {@link EnvTables}. */
|
|
983
1108
|
type TxTables = {
|
|
@@ -999,6 +1124,10 @@ type TxPlan = TxPlanHandle<TxTables>;
|
|
|
999
1124
|
*/
|
|
1000
1125
|
interface EnvServiceDatabase extends Omit<DBClient, "txPlan" | "asService"> {
|
|
1001
1126
|
tables: EnvTables;
|
|
1127
|
+
/** See {@link EnvTypedDatabase.schema}. The bypass sibling reaches every
|
|
1128
|
+
* schema the default surface does — a `billing` table is no less reachable
|
|
1129
|
+
* because the caller asked to run as the service role. */
|
|
1130
|
+
schema<S extends keyof Schemas>(name: S): EnvSchemas[S];
|
|
1002
1131
|
transaction<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T): Promise<Materialized<T>>;
|
|
1003
1132
|
}
|
|
1004
1133
|
/**
|
|
@@ -1013,6 +1142,26 @@ interface EnvServiceDatabase extends Omit<DBClient, "txPlan" | "asService"> {
|
|
|
1013
1142
|
*/
|
|
1014
1143
|
interface EnvTypedDatabase extends Omit<DBClient, "txPlan" | "asService"> {
|
|
1015
1144
|
tables: EnvTables;
|
|
1145
|
+
/**
|
|
1146
|
+
* The tables of a schema other than `public`.
|
|
1147
|
+
*
|
|
1148
|
+
* `Database.tables.*` is the PUBLIC schema and only the public schema. Two
|
|
1149
|
+
* schemas may declare the same table name — `public.invoices` and
|
|
1150
|
+
* `billing.invoices` are different tables — so one flat namespace would make
|
|
1151
|
+
* `Database.tables.invoices` resolve by declaration order. It does not: the
|
|
1152
|
+
* bare name is always public's, and everything else is asked for by schema.
|
|
1153
|
+
*
|
|
1154
|
+
* The name is `keyof Schemas`, so a schema the project never declared is a
|
|
1155
|
+
* compile error. On the wire the table travels schema-qualified
|
|
1156
|
+
* (`billing.invoices`); `public` stays bare.
|
|
1157
|
+
*
|
|
1158
|
+
* Declaring a schema does not publish it — reachability over HTTP is the
|
|
1159
|
+
* schema's own `exposed` flag, checked by the broker.
|
|
1160
|
+
*
|
|
1161
|
+
* @example
|
|
1162
|
+
* const inv = await Database.schema("billing").tables.invoices.findById(id);
|
|
1163
|
+
*/
|
|
1164
|
+
schema<S extends keyof Schemas>(name: S): EnvSchemas[S];
|
|
1016
1165
|
/**
|
|
1017
1166
|
* Run a transaction. The callback DESCRIBES the operations; the whole
|
|
1018
1167
|
* description travels in one request and the broker runs it inside a single
|
|
@@ -1070,4 +1219,4 @@ interface EnvTypedDatabase extends Omit<DBClient, "txPlan" | "asService"> {
|
|
|
1070
1219
|
asService(): EnvServiceDatabase;
|
|
1071
1220
|
}
|
|
1072
1221
|
|
|
1073
|
-
export {
|
|
1222
|
+
export { type AnyColumn as A, defineTable as B, ColumnBuilder as C, enumType as D, type EnvTypedDatabase as E, installationRef as F, integer as G, isPalbaseExtension as H, type InsertShape as I, jsonb as J, makeTypedDB as K, numeric as L, openai as M, ownedByUser as N, type OnDeleteAction as O, PALBASE_EXTENSIONS as P, policy as Q, type RawConstraintDef as R, type SchemaDef as S, TABLE_META as T, raw as U, text as V, timestamp as W, userRef as X, uuid as Y, vector as Z, type ColumnDef as a, type ColumnMap as b, type ColumnType as c, EXTENSION_DEPENDENCIES as d, type EmbeddingModelRef as e, type EnvSchemas as f, type EnvServiceDatabase as g, type EnvTables as h, type EnvTypedTable as i, type PalbaseExtension as j, PolicyBuilder as k, type PolicyCommand as l, type PolicyDef as m, type PolicyMode as n, type RowShape as o, type TableDef as p, type TableHandle as q, type TableInput as r, type TxPlan as s, type TxTables as t, type TypedDB as u, type TypedTable as v, type TypedTx as w, bigint as x, boolean as y, defineSchema as z };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Buckets, BucketTypes } from './stack.cjs';
|
|
2
2
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
3
3
|
import { C as CacheClient, P as PalbaseDocsClient, a as PalbaseFlagsClient, L as Logger, b as PalbaseNotificationsClient, c as PalbaseRealtimeClient, D as DBClient, S as SecretsService, d as PalbaseStorageClient, e as PalbaseBucketClient, f as DBOps, T as TxPlanBody, g as TxPlanResponse, A as AuthSpec } from './endpoint-BSGw1pTu.cjs';
|
|
4
|
-
import { E as EnvTypedDatabase } from './index-
|
|
4
|
+
import { E as EnvTypedDatabase } from './index-DmVyY6N7.cjs';
|
|
5
5
|
import { R as RouteMeta } from './registry-CgJvDYUW.cjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -673,6 +673,9 @@ declare function withTables<T extends ReturnType<typeof createOps>>(ops: T, sche
|
|
|
673
673
|
}>;
|
|
674
674
|
}): T & {
|
|
675
675
|
tables: Record<string, unknown>;
|
|
676
|
+
schema: (name: string) => {
|
|
677
|
+
tables: Record<string, unknown>;
|
|
678
|
+
};
|
|
676
679
|
};
|
|
677
680
|
/** The two transactions a request may hold, and the single `Database` over them. */
|
|
678
681
|
interface RequestDatabase {
|
|
@@ -1007,7 +1010,7 @@ interface CreateAppOptions {
|
|
|
1007
1010
|
/** `@Controller` classes. A class that collected zero routes is fatal. */
|
|
1008
1011
|
controllers: readonly unknown[];
|
|
1009
1012
|
/** The project's `defineSchema()` result, for the typed `.tables` surface. */
|
|
1010
|
-
|
|
1013
|
+
schemas?: readonly unknown[];
|
|
1011
1014
|
/** The SQL driver. Omitted ⇒ built from `Bun.sql` when running under Bun. */
|
|
1012
1015
|
sql?: SqlDriver;
|
|
1013
1016
|
/** Module clients. Omitted ⇒ each corresponding singleton throws when used. */
|