@palbase/backend 32.0.0 → 33.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 +79 -26
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +5 -5
- package/dist/{chunk-AZJIKCOR.js → chunk-IKDONZ5D.js} +39 -23
- package/dist/{chunk-AZJIKCOR.js.map → chunk-IKDONZ5D.js.map} +1 -1
- package/dist/{chunk-IXAX5CON.js → chunk-SI4KGEM3.js} +1 -1
- package/dist/{chunk-IXAX5CON.js.map → chunk-SI4KGEM3.js.map} +1 -1
- package/dist/{chunk-XEGZ3S2Q.js → chunk-TVCCR6SO.js} +32 -7
- package/dist/chunk-TVCCR6SO.js.map +1 -0
- package/dist/{chunk-5C5UCILO.js → chunk-WWUG2QXF.js} +3 -3
- package/dist/{chunk-KGP6ALIU.js → chunk-XOX6RFPZ.js} +30 -8
- package/dist/chunk-XOX6RFPZ.js.map +1 -0
- package/dist/{chunk-Z4CZRMNF.js → chunk-YIQ4RS4F.js} +2 -2
- package/dist/db/index.cjs +14 -4
- 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 +3 -3
- package/dist/engine/index.cjs +79 -26
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +3 -3
- package/dist/engine/index.d.ts +3 -3
- package/dist/engine/index.js +5 -5
- package/dist/{index-BILC9WwS.d.ts → index-D-3duy8Y.d.ts} +2 -2
- package/dist/{index-DgYkdNT9.d.cts → index-DB_nW-AV.d.cts} +87 -30
- package/dist/{index-CWGiJ2Up.d.cts → index-DLveQoOf.d.cts} +2 -2
- package/dist/{index-BgWnP07a.d.ts → index-DMZG3kpo.d.ts} +87 -30
- package/dist/index.cjs +59 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +5 -5
- package/dist/openapi/index.d.cts +2 -2
- package/dist/openapi/index.d.ts +2 -2
- package/dist/{registry-BcRYIQ-R.d.cts → registry-DSTThhKf.d.cts} +1 -1
- package/dist/{registry-ClzjxIWy.d.ts → registry-JjF5lcj4.d.ts} +1 -1
- package/dist/test/index.cjs +1155 -12
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +1 -1
- package/dist/test/index.d.ts +1 -1
- package/dist/test/index.js +1126 -8
- package/dist/test/index.js.map +1 -1
- package/docs/README.md +124 -80
- package/docs/auth.md +112 -26
- package/docs/background.md +16 -7
- package/docs/database.md +22 -18
- package/docs/endpoints.md +26 -20
- package/docs/errors.md +2 -3
- package/docs/events.md +63 -29
- package/docs/getting-started.md +8 -7
- package/docs/llms-full.txt +519 -244
- package/docs/migrations.md +6 -5
- package/docs/routing.md +34 -11
- package/docs/schema.md +78 -27
- package/docs/services.md +30 -13
- package/package.json +2 -1
- package/stack-images.json +24 -0
- package/template/db/public.ts +23 -0
- package/template/package.json +1 -1
- package/dist/chunk-KGP6ALIU.js.map +0 -1
- package/dist/chunk-XEGZ3S2Q.js.map +0 -1
- /package/dist/{chunk-5C5UCILO.js.map → chunk-WWUG2QXF.js.map} +0 -0
- /package/dist/{chunk-Z4CZRMNF.js.map → chunk-YIQ4RS4F.js.map} +0 -0
package/dist/engine/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import '../index-
|
|
2
|
-
export { A as App, g as AuthVerifier, B as BootRefused, h as CreateAppOptions, D as DECLARATION_REFUSAL, a as DeclarationRefused, E as EgressPolicy, j as EngineConfig, M as ModuleClients, R as RateLimiter, k as RequestDatabase, l as RouteEntry, m as RuntimeHooks, S as ScrubResult, n as SqlDriver, o as SqlTx, p as buildRouteTable, q as createApp, r as createLazyTransaction, s as createOps, t as createRequestDatabase, u as effectiveAuth, v as hostAllowed, w as installEgressFence, i as isDeclarationRefused, x as loadConfig, y as makeMemoryCache, z as matchRoute, F as quoteIdent, G as scrubSecrets, H as withTables } from '../index-
|
|
1
|
+
import '../index-DB_nW-AV.cjs';
|
|
2
|
+
export { A as App, g as AuthVerifier, B as BootRefused, h as CreateAppOptions, D as DECLARATION_REFUSAL, a as DeclarationRefused, E as EgressPolicy, j as EngineConfig, M as ModuleClients, R as RateLimiter, k as RequestDatabase, l as RouteEntry, m as RuntimeHooks, S as ScrubResult, n as SqlDriver, o as SqlTx, p as buildRouteTable, q as createApp, r as createLazyTransaction, s as createOps, t as createRequestDatabase, u as effectiveAuth, v as hostAllowed, w as installEgressFence, i as isDeclarationRefused, x as loadConfig, y as makeMemoryCache, z as matchRoute, F as quoteIdent, G as scrubSecrets, H as withTables } from '../index-DLveQoOf.cjs';
|
|
3
3
|
import '../db/env.cjs';
|
|
4
4
|
import '../stack.cjs';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import 'node:async_hooks';
|
|
7
7
|
import '../module-Dl1KFVtc.cjs';
|
|
8
|
-
import '../registry-
|
|
8
|
+
import '../registry-DSTThhKf.cjs';
|
package/dist/engine/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import '../index-
|
|
2
|
-
export { A as App, g as AuthVerifier, B as BootRefused, h as CreateAppOptions, D as DECLARATION_REFUSAL, a as DeclarationRefused, E as EgressPolicy, j as EngineConfig, M as ModuleClients, R as RateLimiter, k as RequestDatabase, l as RouteEntry, m as RuntimeHooks, S as ScrubResult, n as SqlDriver, o as SqlTx, p as buildRouteTable, q as createApp, r as createLazyTransaction, s as createOps, t as createRequestDatabase, u as effectiveAuth, v as hostAllowed, w as installEgressFence, i as isDeclarationRefused, x as loadConfig, y as makeMemoryCache, z as matchRoute, F as quoteIdent, G as scrubSecrets, H as withTables } from '../index-
|
|
1
|
+
import '../index-DMZG3kpo.js';
|
|
2
|
+
export { A as App, g as AuthVerifier, B as BootRefused, h as CreateAppOptions, D as DECLARATION_REFUSAL, a as DeclarationRefused, E as EgressPolicy, j as EngineConfig, M as ModuleClients, R as RateLimiter, k as RequestDatabase, l as RouteEntry, m as RuntimeHooks, S as ScrubResult, n as SqlDriver, o as SqlTx, p as buildRouteTable, q as createApp, r as createLazyTransaction, s as createOps, t as createRequestDatabase, u as effectiveAuth, v as hostAllowed, w as installEgressFence, i as isDeclarationRefused, x as loadConfig, y as makeMemoryCache, z as matchRoute, F as quoteIdent, G as scrubSecrets, H as withTables } from '../index-D-3duy8Y.js';
|
|
3
3
|
import '../db/env.js';
|
|
4
4
|
import '../stack.js';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import 'node:async_hooks';
|
|
7
7
|
import '../module-Dl1KFVtc.js';
|
|
8
|
-
import '../registry-
|
|
8
|
+
import '../registry-JjF5lcj4.js';
|
package/dist/engine/index.js
CHANGED
|
@@ -16,15 +16,15 @@ import {
|
|
|
16
16
|
quoteIdent,
|
|
17
17
|
scrubSecrets,
|
|
18
18
|
withTables
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-IKDONZ5D.js";
|
|
20
20
|
import {
|
|
21
21
|
DECLARATION_REFUSAL,
|
|
22
22
|
DeclarationRefused,
|
|
23
23
|
isDeclarationRefused
|
|
24
|
-
} from "../chunk-
|
|
25
|
-
import "../chunk-
|
|
26
|
-
import "../chunk-
|
|
27
|
-
import "../chunk-
|
|
24
|
+
} from "../chunk-WWUG2QXF.js";
|
|
25
|
+
import "../chunk-TVCCR6SO.js";
|
|
26
|
+
import "../chunk-XOX6RFPZ.js";
|
|
27
|
+
import "../chunk-SI4KGEM3.js";
|
|
28
28
|
import "../chunk-BRLJOXWS.js";
|
|
29
29
|
import "../chunk-KATPXCJ5.js";
|
|
30
30
|
export {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { D as DBClient, b as DBOps, T as TxPlanBody, c as TxPlanResponse, A as AuthSpec, C as CacheClient, a as RuntimeServices, _ as __runWithRuntime, d as __requestALS } from './index-
|
|
1
|
+
import { D as DBClient, b as DBOps, T as TxPlanBody, c as TxPlanResponse, A as AuthSpec, C as CacheClient, a as RuntimeServices, _ as __runWithRuntime, d as __requestALS } from './index-DMZG3kpo.js';
|
|
2
2
|
import { T as Token } from './module-Dl1KFVtc.js';
|
|
3
|
-
import { R as RouteMeta } from './registry-
|
|
3
|
+
import { R as RouteMeta } from './registry-JjF5lcj4.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* engine/config.ts — settings from the environment, and the gate that refuses
|
|
@@ -28,16 +28,32 @@ interface User {
|
|
|
28
28
|
/**
|
|
29
29
|
* Whether that email address has been confirmed.
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
31
|
+
* READ FROM THE VERIFIED TOKEN (`email_verified`), so it says what was true
|
|
32
|
+
* when that token was minted: a user who confirms their address mid-session
|
|
33
|
+
* keeps reporting `false` until their next one. {@link User.roles} is the
|
|
34
|
+
* deliberate exception — it is read from the table on every request.
|
|
35
|
+
*
|
|
36
|
+
* This paragraph used to claim the opposite ("server-resolved from the
|
|
37
|
+
* verified profile, not read from the JWT") and to describe a ~30-second
|
|
38
|
+
* profile cache. Measured 2026-09-04: the engine fills this field from
|
|
39
|
+
* `claims.email_verified` and no such cache exists anywhere in the runtime.
|
|
40
|
+
* Whether the claim or a profile read is the RIGHT source is a separate
|
|
41
|
+
* question and an open one — but the type may not answer it wrongly while it
|
|
42
|
+
* is open.
|
|
34
43
|
*
|
|
35
44
|
* `false` for a phone-only user (no address to confirm) and for any user who
|
|
36
|
-
* has not clicked through yet.
|
|
37
|
-
* address confirmed" in a handler cost an extra network round-trip PER
|
|
38
|
-
* REQUEST for one boolean the runtime already had.
|
|
45
|
+
* has not clicked through yet.
|
|
39
46
|
*/
|
|
40
47
|
emailVerified: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* The caller's DATABASE role — the string RLS reads, not an application role.
|
|
50
|
+
*
|
|
51
|
+
* It is the literal `"authenticated"` for every signed-in caller and
|
|
52
|
+
* `"anon"` for every unauthenticated one, so `user.role === "admin"` is
|
|
53
|
+
* ALWAYS false and reads like a working check. Application roles are
|
|
54
|
+
* {@link User.roles}; this field says which Postgres role the request runs
|
|
55
|
+
* as, and that is the only question it answers.
|
|
56
|
+
*/
|
|
41
57
|
role: string;
|
|
42
58
|
/**
|
|
43
59
|
* The caller's APPLICATION roles, as assigned in `auth.user_roles`.
|
|
@@ -2241,7 +2257,7 @@ interface PalbaseFunctionsClient {
|
|
|
2241
2257
|
invoke<T = unknown>(fnName: string, options?: PalbaseInvokeOptions): Promise<PalbaseResult<T>>;
|
|
2242
2258
|
}
|
|
2243
2259
|
/**
|
|
2244
|
-
* Cross-user admin write surface, reached via `Flags
|
|
2260
|
+
* Cross-user admin write surface, reached via `Flags.$asService()`.
|
|
2245
2261
|
*
|
|
2246
2262
|
* These five methods set/clear overrides for an ARBITRARY user (named
|
|
2247
2263
|
* explicitly), so they bypass the current-request-user scope that `Flags.*`
|
|
@@ -2249,10 +2265,10 @@ interface PalbaseFunctionsClient {
|
|
|
2249
2265
|
* `Database` / `Database.$asService()` split: the privileged, cross-user path
|
|
2250
2266
|
* is moved OFF the default surface so it is greppable and intentional — a
|
|
2251
2267
|
* handler that calls `Flags.setOverrideForUser(...)` on the default surface is
|
|
2252
|
-
* a compile error and must reach for `Flags
|
|
2268
|
+
* a compile error and must reach for `Flags.$asService()` first.
|
|
2253
2269
|
*
|
|
2254
2270
|
* @example
|
|
2255
|
-
* await Flags
|
|
2271
|
+
* await Flags.$asService().setOverrideForUser("user_123", "new_checkout", true);
|
|
2256
2272
|
*/
|
|
2257
2273
|
interface PalbaseFlagsServiceClient {
|
|
2258
2274
|
/**
|
|
@@ -2315,7 +2331,7 @@ interface PalbaseFlagsClient {
|
|
|
2315
2331
|
* user until cleared.
|
|
2316
2332
|
*
|
|
2317
2333
|
* Errors when there is no signed-in user (an anonymous request); reach for
|
|
2318
|
-
* `Flags
|
|
2334
|
+
* `Flags.$asService().setOverrideForUser(userId, key, value)` to write a flag
|
|
2319
2335
|
* for an arbitrary (cross-user) target.
|
|
2320
2336
|
*
|
|
2321
2337
|
* @example
|
|
@@ -2325,8 +2341,12 @@ interface PalbaseFlagsClient {
|
|
|
2325
2341
|
/**
|
|
2326
2342
|
* Return the cross-user admin write surface ({@link PalbaseFlagsServiceClient}).
|
|
2327
2343
|
* Use sparingly and explicitly — the default `Flags.setOverride(...)` path is
|
|
2328
|
-
* bound to the current request user;
|
|
2329
|
-
*
|
|
2344
|
+
* bound to the current request user; this is how you write a flag override for
|
|
2345
|
+
* an ARBITRARY user. Mirrors `Database.$asService()`.
|
|
2346
|
+
*
|
|
2347
|
+
* NOT the name a handler writes: the ambient `Flags` singleton OMITS this
|
|
2348
|
+
* member and exposes `$asService()` instead — `Flags.asService()` still
|
|
2349
|
+
* type-checks there and THROWS, naming its replacement (H1).
|
|
2330
2350
|
*/
|
|
2331
2351
|
asService(): PalbaseFlagsServiceClient;
|
|
2332
2352
|
}
|
|
@@ -2603,7 +2623,7 @@ interface PalbaseLinksClient {
|
|
|
2603
2623
|
* \@Controller("/todos")
|
|
2604
2624
|
* export default class TodosController {
|
|
2605
2625
|
* \@Post("") create(\@Body(CreateTodoBody) body: CreateTodoBody): unknown {
|
|
2606
|
-
* return Database.insert(
|
|
2626
|
+
* return Database.public.todos.insert({ title: body.title });
|
|
2607
2627
|
* }
|
|
2608
2628
|
* }
|
|
2609
2629
|
*
|
|
@@ -2688,11 +2708,6 @@ declare function __setRuntime(services: RuntimeServices): void;
|
|
|
2688
2708
|
* The persistent worker calls this once per request so concurrent requests
|
|
2689
2709
|
* never share a services slot. NOT part of the public author-facing API. */
|
|
2690
2710
|
declare function __runWithRuntime<T>(services: RuntimeServices, fn: () => T): T;
|
|
2691
|
-
/** Read the live clients, throwing if accessed outside a request scope.
|
|
2692
|
-
*
|
|
2693
|
-
* Resolves the ALS store first (persistent server, per-request), then the
|
|
2694
|
-
* process-global fallback (dev-server / tests). NOT part of the public
|
|
2695
|
-
* author-facing API — used by the runtime and the singleton Proxies. */
|
|
2696
2711
|
declare function __getRuntime(): RuntimeServices;
|
|
2697
2712
|
/** A lifecycle hook. Sync or async; the runtime awaits what it returns. */
|
|
2698
2713
|
type LifecycleHook = () => void | Promise<void>;
|
|
@@ -2805,7 +2820,7 @@ declare const Database: EnvTypedDatabase;
|
|
|
2805
2820
|
/** Firestore-like document client (PalDocs). */
|
|
2806
2821
|
declare const Documents: PalbaseDocsClient;
|
|
2807
2822
|
/**
|
|
2808
|
-
* `buckets.<name>` — the storage twin of `Database.
|
|
2823
|
+
* `buckets.<name>` — the storage twin of `Database.public.<name>`, and the same
|
|
2809
2824
|
* mechanism: `config/storage.ts` generates a `Buckets` augmentation into
|
|
2810
2825
|
* `palbase-env.d.ts`, so a bucket name is a property with no import and no
|
|
2811
2826
|
* generic, and a typo is a compile error.
|
|
@@ -2869,21 +2884,46 @@ declare const Notifications: PalbaseNotificationsClient;
|
|
|
2869
2884
|
/**
|
|
2870
2885
|
* Feature flags.
|
|
2871
2886
|
*
|
|
2872
|
-
* Mirrors the `Database` / `Database
|
|
2887
|
+
* Mirrors the `Database` / `Database.$asService()` model. The default surface is
|
|
2873
2888
|
* RLS-equivalent for flags: reads resolve against the CURRENT request user and
|
|
2874
2889
|
* `Flags.setOverride(key, value)` writes an override for that same signed-in
|
|
2875
2890
|
* user (no userId argument, no admin power). Cross-user admin writes
|
|
2876
|
-
* (`setOverrideForUser`, …) live behind `Flags
|
|
2877
|
-
* greppable, just like `Database
|
|
2891
|
+
* (`setOverrideForUser`, …) live behind `Flags.$asService()` — explicit and
|
|
2892
|
+
* greppable, just like `Database.$asService()`.
|
|
2878
2893
|
*
|
|
2879
2894
|
* @example
|
|
2880
2895
|
* import { Flags } from "@palbase/backend";
|
|
2881
2896
|
*
|
|
2882
2897
|
* if (await Flags.isEnabled("new_checkout")) { ... } // current user
|
|
2883
2898
|
* await Flags.setOverride("new_checkout", true); // current user
|
|
2884
|
-
* await Flags
|
|
2899
|
+
* await Flags.$asService().setOverrideForUser("u_9", "x", true); // cross-user
|
|
2900
|
+
*/
|
|
2901
|
+
/**
|
|
2902
|
+
* The ambient `Flags` singleton's own surface — NOT the raw client's.
|
|
2903
|
+
*
|
|
2904
|
+
* MEASURED, as a consumer, against the built tarball: annotating the singleton
|
|
2905
|
+
* as `PalbaseFlagsClient` ERASED the `$asService` that `Object.assign` adds, so
|
|
2906
|
+
* `Flags.$asService()` did not exist for anyone outside this package —
|
|
2907
|
+
*
|
|
2908
|
+
* TS2551: Property '$asService' does not exist on type 'PalbaseFlagsClient'.
|
|
2909
|
+
* Did you mean 'asService'?
|
|
2910
|
+
*
|
|
2911
|
+
* — while the only path that DID compile (`asService()`) throws by design. The
|
|
2912
|
+
* feature was written and unreachable, which is the defect class this surface
|
|
2913
|
+
* exists to remove.
|
|
2914
|
+
*
|
|
2915
|
+
* `Database` never had the problem because its singleton carries its OWN type
|
|
2916
|
+
* (`EnvTypedDatabase`) rather than the raw client's (`DBClient`). This is that,
|
|
2917
|
+
* for `Flags`. The raw `PalbaseFlagsClient.asService()` is untouched (FR-023) —
|
|
2918
|
+
* it is the seam this forwards to.
|
|
2885
2919
|
*/
|
|
2886
|
-
|
|
2920
|
+
type PalbaseFlagsAmbient = Omit<PalbaseFlagsClient, "asService"> & {
|
|
2921
|
+
/** RLS'i aşan, kullanıcılar arası yazma yüzeyi. */
|
|
2922
|
+
$asService(): PalbaseFlagsServiceClient;
|
|
2923
|
+
/** 31.0.0 öncesinin adı — SESSİZCE çalışmaz, yerini söyleyerek fırlatır. */
|
|
2924
|
+
asService(): never;
|
|
2925
|
+
};
|
|
2926
|
+
declare const Flags: PalbaseFlagsAmbient;
|
|
2887
2927
|
/**
|
|
2888
2928
|
* The Realtime broadcast singleton for the current request scope. Backend-side
|
|
2889
2929
|
* Realtime is BROADCAST-ONLY (a stateless handler can push but not subscribe —
|
|
@@ -3454,8 +3494,20 @@ type WithRowOf<Rels, R extends keyof Rels, Q> = Rels[R] extends {
|
|
|
3454
3494
|
* özdeş değil" hâle getirirdi ve tam eşitlik iddiaları kırılırdı. Ölçüldü:
|
|
3455
3495
|
* `toEqualTypeOf` dört yerde düştü.
|
|
3456
3496
|
*/
|
|
3457
|
-
|
|
3458
|
-
|
|
3497
|
+
/**
|
|
3498
|
+
* Yalnız GERÇEKTEN istenen dallar. `undefined extends W[R]` olan anahtarlar
|
|
3499
|
+
* düşüyor — ve bu, `ReturnType<typeof t.findMany>` yazan herkes için kritik:
|
|
3500
|
+
* generic bir imzada `ReturnType` tip parametrelerini VARSAYILANLA değil
|
|
3501
|
+
* KISITLA örnekliyor, yani `W = WithInput<Rels>` oluyor ve her ilişki
|
|
3502
|
+
* (`?:` ile, dolayısıyla `| undefined`) zorunlu bir alana dönüşüyordu.
|
|
3503
|
+
* Gerçek projede ölçüldü: `type MemberRow = Awaited<ReturnType<…findMany>>[number]`
|
|
3504
|
+
* 32 ilişkiyi birden ister hâle geldi ve 4 yerde kırıldı.
|
|
3505
|
+
*/
|
|
3506
|
+
type RequestedWith<W> = {
|
|
3507
|
+
[R in keyof W]-?: undefined extends W[R] ? never : R;
|
|
3508
|
+
}[keyof W];
|
|
3509
|
+
type WithResult<Rels, W> = [RequestedWith<W>] extends [never] ? unknown : {
|
|
3510
|
+
[R in RequestedWith<W> & keyof Rels]: WithRowOf<Rels, R, W[R]>;
|
|
3459
3511
|
};
|
|
3460
3512
|
type QueryInput<Row, K extends keyof Row = keyof Row, Rels = unknown> = {
|
|
3461
3513
|
/**
|
|
@@ -3987,12 +4039,17 @@ type EnvServiceDatabase = EnvSchemaSurface & {
|
|
|
3987
4039
|
}): Promise<Materialized<T>>;
|
|
3988
4040
|
};
|
|
3989
4041
|
/**
|
|
3990
|
-
* The typed-by-default Database surface: the
|
|
3991
|
-
* PLUS
|
|
3992
|
-
*
|
|
4042
|
+
* The typed-by-default Database surface: the `$`-prefixed string-keyed
|
|
4043
|
+
* `DBClient` ops PLUS one property per schema — `public` and every schema the
|
|
4044
|
+
* project declares — typed against the generated `palbase-env.d.ts`, a
|
|
4045
|
+
* `$transaction` that runs a whole plan in one request, and `$asService()` for
|
|
3993
4046
|
* the explicit RLS-bypass sibling.
|
|
3994
4047
|
*
|
|
3995
|
-
*
|
|
4048
|
+
* NOT `tables`: that intermediate layer was removed (FR-001) and this sentence
|
|
4049
|
+
* outlived it by two majors, teaching a spelling that is TS2339. Pinned in
|
|
4050
|
+
* `src/database-ambient.test-d.ts`.
|
|
4051
|
+
*
|
|
4052
|
+
* The low-level `txPlan` op is deliberately NOT re-exposed here: `$transaction`
|
|
3996
4053
|
* is the surface, and a hand-built plan would bypass the ref/guard machinery
|
|
3997
4054
|
* that makes one safe to write.
|
|
3998
4055
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { D as DBClient, b as DBOps, T as TxPlanBody, c as TxPlanResponse, A as AuthSpec, C as CacheClient, a as RuntimeServices, _ as __runWithRuntime, d as __requestALS } from './index-
|
|
1
|
+
import { D as DBClient, b as DBOps, T as TxPlanBody, c as TxPlanResponse, A as AuthSpec, C as CacheClient, a as RuntimeServices, _ as __runWithRuntime, d as __requestALS } from './index-DB_nW-AV.cjs';
|
|
2
2
|
import { T as Token } from './module-Dl1KFVtc.cjs';
|
|
3
|
-
import { R as RouteMeta } from './registry-
|
|
3
|
+
import { R as RouteMeta } from './registry-DSTThhKf.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* engine/config.ts — settings from the environment, and the gate that refuses
|
|
@@ -28,16 +28,32 @@ interface User {
|
|
|
28
28
|
/**
|
|
29
29
|
* Whether that email address has been confirmed.
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
31
|
+
* READ FROM THE VERIFIED TOKEN (`email_verified`), so it says what was true
|
|
32
|
+
* when that token was minted: a user who confirms their address mid-session
|
|
33
|
+
* keeps reporting `false` until their next one. {@link User.roles} is the
|
|
34
|
+
* deliberate exception — it is read from the table on every request.
|
|
35
|
+
*
|
|
36
|
+
* This paragraph used to claim the opposite ("server-resolved from the
|
|
37
|
+
* verified profile, not read from the JWT") and to describe a ~30-second
|
|
38
|
+
* profile cache. Measured 2026-09-04: the engine fills this field from
|
|
39
|
+
* `claims.email_verified` and no such cache exists anywhere in the runtime.
|
|
40
|
+
* Whether the claim or a profile read is the RIGHT source is a separate
|
|
41
|
+
* question and an open one — but the type may not answer it wrongly while it
|
|
42
|
+
* is open.
|
|
34
43
|
*
|
|
35
44
|
* `false` for a phone-only user (no address to confirm) and for any user who
|
|
36
|
-
* has not clicked through yet.
|
|
37
|
-
* address confirmed" in a handler cost an extra network round-trip PER
|
|
38
|
-
* REQUEST for one boolean the runtime already had.
|
|
45
|
+
* has not clicked through yet.
|
|
39
46
|
*/
|
|
40
47
|
emailVerified: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* The caller's DATABASE role — the string RLS reads, not an application role.
|
|
50
|
+
*
|
|
51
|
+
* It is the literal `"authenticated"` for every signed-in caller and
|
|
52
|
+
* `"anon"` for every unauthenticated one, so `user.role === "admin"` is
|
|
53
|
+
* ALWAYS false and reads like a working check. Application roles are
|
|
54
|
+
* {@link User.roles}; this field says which Postgres role the request runs
|
|
55
|
+
* as, and that is the only question it answers.
|
|
56
|
+
*/
|
|
41
57
|
role: string;
|
|
42
58
|
/**
|
|
43
59
|
* The caller's APPLICATION roles, as assigned in `auth.user_roles`.
|
|
@@ -2241,7 +2257,7 @@ interface PalbaseFunctionsClient {
|
|
|
2241
2257
|
invoke<T = unknown>(fnName: string, options?: PalbaseInvokeOptions): Promise<PalbaseResult<T>>;
|
|
2242
2258
|
}
|
|
2243
2259
|
/**
|
|
2244
|
-
* Cross-user admin write surface, reached via `Flags
|
|
2260
|
+
* Cross-user admin write surface, reached via `Flags.$asService()`.
|
|
2245
2261
|
*
|
|
2246
2262
|
* These five methods set/clear overrides for an ARBITRARY user (named
|
|
2247
2263
|
* explicitly), so they bypass the current-request-user scope that `Flags.*`
|
|
@@ -2249,10 +2265,10 @@ interface PalbaseFunctionsClient {
|
|
|
2249
2265
|
* `Database` / `Database.$asService()` split: the privileged, cross-user path
|
|
2250
2266
|
* is moved OFF the default surface so it is greppable and intentional — a
|
|
2251
2267
|
* handler that calls `Flags.setOverrideForUser(...)` on the default surface is
|
|
2252
|
-
* a compile error and must reach for `Flags
|
|
2268
|
+
* a compile error and must reach for `Flags.$asService()` first.
|
|
2253
2269
|
*
|
|
2254
2270
|
* @example
|
|
2255
|
-
* await Flags
|
|
2271
|
+
* await Flags.$asService().setOverrideForUser("user_123", "new_checkout", true);
|
|
2256
2272
|
*/
|
|
2257
2273
|
interface PalbaseFlagsServiceClient {
|
|
2258
2274
|
/**
|
|
@@ -2315,7 +2331,7 @@ interface PalbaseFlagsClient {
|
|
|
2315
2331
|
* user until cleared.
|
|
2316
2332
|
*
|
|
2317
2333
|
* Errors when there is no signed-in user (an anonymous request); reach for
|
|
2318
|
-
* `Flags
|
|
2334
|
+
* `Flags.$asService().setOverrideForUser(userId, key, value)` to write a flag
|
|
2319
2335
|
* for an arbitrary (cross-user) target.
|
|
2320
2336
|
*
|
|
2321
2337
|
* @example
|
|
@@ -2325,8 +2341,12 @@ interface PalbaseFlagsClient {
|
|
|
2325
2341
|
/**
|
|
2326
2342
|
* Return the cross-user admin write surface ({@link PalbaseFlagsServiceClient}).
|
|
2327
2343
|
* Use sparingly and explicitly — the default `Flags.setOverride(...)` path is
|
|
2328
|
-
* bound to the current request user;
|
|
2329
|
-
*
|
|
2344
|
+
* bound to the current request user; this is how you write a flag override for
|
|
2345
|
+
* an ARBITRARY user. Mirrors `Database.$asService()`.
|
|
2346
|
+
*
|
|
2347
|
+
* NOT the name a handler writes: the ambient `Flags` singleton OMITS this
|
|
2348
|
+
* member and exposes `$asService()` instead — `Flags.asService()` still
|
|
2349
|
+
* type-checks there and THROWS, naming its replacement (H1).
|
|
2330
2350
|
*/
|
|
2331
2351
|
asService(): PalbaseFlagsServiceClient;
|
|
2332
2352
|
}
|
|
@@ -2603,7 +2623,7 @@ interface PalbaseLinksClient {
|
|
|
2603
2623
|
* \@Controller("/todos")
|
|
2604
2624
|
* export default class TodosController {
|
|
2605
2625
|
* \@Post("") create(\@Body(CreateTodoBody) body: CreateTodoBody): unknown {
|
|
2606
|
-
* return Database.insert(
|
|
2626
|
+
* return Database.public.todos.insert({ title: body.title });
|
|
2607
2627
|
* }
|
|
2608
2628
|
* }
|
|
2609
2629
|
*
|
|
@@ -2688,11 +2708,6 @@ declare function __setRuntime(services: RuntimeServices): void;
|
|
|
2688
2708
|
* The persistent worker calls this once per request so concurrent requests
|
|
2689
2709
|
* never share a services slot. NOT part of the public author-facing API. */
|
|
2690
2710
|
declare function __runWithRuntime<T>(services: RuntimeServices, fn: () => T): T;
|
|
2691
|
-
/** Read the live clients, throwing if accessed outside a request scope.
|
|
2692
|
-
*
|
|
2693
|
-
* Resolves the ALS store first (persistent server, per-request), then the
|
|
2694
|
-
* process-global fallback (dev-server / tests). NOT part of the public
|
|
2695
|
-
* author-facing API — used by the runtime and the singleton Proxies. */
|
|
2696
2711
|
declare function __getRuntime(): RuntimeServices;
|
|
2697
2712
|
/** A lifecycle hook. Sync or async; the runtime awaits what it returns. */
|
|
2698
2713
|
type LifecycleHook = () => void | Promise<void>;
|
|
@@ -2805,7 +2820,7 @@ declare const Database: EnvTypedDatabase;
|
|
|
2805
2820
|
/** Firestore-like document client (PalDocs). */
|
|
2806
2821
|
declare const Documents: PalbaseDocsClient;
|
|
2807
2822
|
/**
|
|
2808
|
-
* `buckets.<name>` — the storage twin of `Database.
|
|
2823
|
+
* `buckets.<name>` — the storage twin of `Database.public.<name>`, and the same
|
|
2809
2824
|
* mechanism: `config/storage.ts` generates a `Buckets` augmentation into
|
|
2810
2825
|
* `palbase-env.d.ts`, so a bucket name is a property with no import and no
|
|
2811
2826
|
* generic, and a typo is a compile error.
|
|
@@ -2869,21 +2884,46 @@ declare const Notifications: PalbaseNotificationsClient;
|
|
|
2869
2884
|
/**
|
|
2870
2885
|
* Feature flags.
|
|
2871
2886
|
*
|
|
2872
|
-
* Mirrors the `Database` / `Database
|
|
2887
|
+
* Mirrors the `Database` / `Database.$asService()` model. The default surface is
|
|
2873
2888
|
* RLS-equivalent for flags: reads resolve against the CURRENT request user and
|
|
2874
2889
|
* `Flags.setOverride(key, value)` writes an override for that same signed-in
|
|
2875
2890
|
* user (no userId argument, no admin power). Cross-user admin writes
|
|
2876
|
-
* (`setOverrideForUser`, …) live behind `Flags
|
|
2877
|
-
* greppable, just like `Database
|
|
2891
|
+
* (`setOverrideForUser`, …) live behind `Flags.$asService()` — explicit and
|
|
2892
|
+
* greppable, just like `Database.$asService()`.
|
|
2878
2893
|
*
|
|
2879
2894
|
* @example
|
|
2880
2895
|
* import { Flags } from "@palbase/backend";
|
|
2881
2896
|
*
|
|
2882
2897
|
* if (await Flags.isEnabled("new_checkout")) { ... } // current user
|
|
2883
2898
|
* await Flags.setOverride("new_checkout", true); // current user
|
|
2884
|
-
* await Flags
|
|
2899
|
+
* await Flags.$asService().setOverrideForUser("u_9", "x", true); // cross-user
|
|
2900
|
+
*/
|
|
2901
|
+
/**
|
|
2902
|
+
* The ambient `Flags` singleton's own surface — NOT the raw client's.
|
|
2903
|
+
*
|
|
2904
|
+
* MEASURED, as a consumer, against the built tarball: annotating the singleton
|
|
2905
|
+
* as `PalbaseFlagsClient` ERASED the `$asService` that `Object.assign` adds, so
|
|
2906
|
+
* `Flags.$asService()` did not exist for anyone outside this package —
|
|
2907
|
+
*
|
|
2908
|
+
* TS2551: Property '$asService' does not exist on type 'PalbaseFlagsClient'.
|
|
2909
|
+
* Did you mean 'asService'?
|
|
2910
|
+
*
|
|
2911
|
+
* — while the only path that DID compile (`asService()`) throws by design. The
|
|
2912
|
+
* feature was written and unreachable, which is the defect class this surface
|
|
2913
|
+
* exists to remove.
|
|
2914
|
+
*
|
|
2915
|
+
* `Database` never had the problem because its singleton carries its OWN type
|
|
2916
|
+
* (`EnvTypedDatabase`) rather than the raw client's (`DBClient`). This is that,
|
|
2917
|
+
* for `Flags`. The raw `PalbaseFlagsClient.asService()` is untouched (FR-023) —
|
|
2918
|
+
* it is the seam this forwards to.
|
|
2885
2919
|
*/
|
|
2886
|
-
|
|
2920
|
+
type PalbaseFlagsAmbient = Omit<PalbaseFlagsClient, "asService"> & {
|
|
2921
|
+
/** RLS'i aşan, kullanıcılar arası yazma yüzeyi. */
|
|
2922
|
+
$asService(): PalbaseFlagsServiceClient;
|
|
2923
|
+
/** 31.0.0 öncesinin adı — SESSİZCE çalışmaz, yerini söyleyerek fırlatır. */
|
|
2924
|
+
asService(): never;
|
|
2925
|
+
};
|
|
2926
|
+
declare const Flags: PalbaseFlagsAmbient;
|
|
2887
2927
|
/**
|
|
2888
2928
|
* The Realtime broadcast singleton for the current request scope. Backend-side
|
|
2889
2929
|
* Realtime is BROADCAST-ONLY (a stateless handler can push but not subscribe —
|
|
@@ -3454,8 +3494,20 @@ type WithRowOf<Rels, R extends keyof Rels, Q> = Rels[R] extends {
|
|
|
3454
3494
|
* özdeş değil" hâle getirirdi ve tam eşitlik iddiaları kırılırdı. Ölçüldü:
|
|
3455
3495
|
* `toEqualTypeOf` dört yerde düştü.
|
|
3456
3496
|
*/
|
|
3457
|
-
|
|
3458
|
-
|
|
3497
|
+
/**
|
|
3498
|
+
* Yalnız GERÇEKTEN istenen dallar. `undefined extends W[R]` olan anahtarlar
|
|
3499
|
+
* düşüyor — ve bu, `ReturnType<typeof t.findMany>` yazan herkes için kritik:
|
|
3500
|
+
* generic bir imzada `ReturnType` tip parametrelerini VARSAYILANLA değil
|
|
3501
|
+
* KISITLA örnekliyor, yani `W = WithInput<Rels>` oluyor ve her ilişki
|
|
3502
|
+
* (`?:` ile, dolayısıyla `| undefined`) zorunlu bir alana dönüşüyordu.
|
|
3503
|
+
* Gerçek projede ölçüldü: `type MemberRow = Awaited<ReturnType<…findMany>>[number]`
|
|
3504
|
+
* 32 ilişkiyi birden ister hâle geldi ve 4 yerde kırıldı.
|
|
3505
|
+
*/
|
|
3506
|
+
type RequestedWith<W> = {
|
|
3507
|
+
[R in keyof W]-?: undefined extends W[R] ? never : R;
|
|
3508
|
+
}[keyof W];
|
|
3509
|
+
type WithResult<Rels, W> = [RequestedWith<W>] extends [never] ? unknown : {
|
|
3510
|
+
[R in RequestedWith<W> & keyof Rels]: WithRowOf<Rels, R, W[R]>;
|
|
3459
3511
|
};
|
|
3460
3512
|
type QueryInput<Row, K extends keyof Row = keyof Row, Rels = unknown> = {
|
|
3461
3513
|
/**
|
|
@@ -3987,12 +4039,17 @@ type EnvServiceDatabase = EnvSchemaSurface & {
|
|
|
3987
4039
|
}): Promise<Materialized<T>>;
|
|
3988
4040
|
};
|
|
3989
4041
|
/**
|
|
3990
|
-
* The typed-by-default Database surface: the
|
|
3991
|
-
* PLUS
|
|
3992
|
-
*
|
|
4042
|
+
* The typed-by-default Database surface: the `$`-prefixed string-keyed
|
|
4043
|
+
* `DBClient` ops PLUS one property per schema — `public` and every schema the
|
|
4044
|
+
* project declares — typed against the generated `palbase-env.d.ts`, a
|
|
4045
|
+
* `$transaction` that runs a whole plan in one request, and `$asService()` for
|
|
3993
4046
|
* the explicit RLS-bypass sibling.
|
|
3994
4047
|
*
|
|
3995
|
-
*
|
|
4048
|
+
* NOT `tables`: that intermediate layer was removed (FR-001) and this sentence
|
|
4049
|
+
* outlived it by two majors, teaching a spelling that is TS2339. Pinned in
|
|
4050
|
+
* `src/database-ambient.test-d.ts`.
|
|
4051
|
+
*
|
|
4052
|
+
* The low-level `txPlan` op is deliberately NOT re-exposed here: `$transaction`
|
|
3996
4053
|
* is the surface, and a hand-built plan would bypass the ref/guard machinery
|
|
3997
4054
|
* that makes one safe to write.
|
|
3998
4055
|
*/
|
package/dist/index.cjs
CHANGED
|
@@ -1286,9 +1286,29 @@ function __runWithRuntime(services, fn) {
|
|
|
1286
1286
|
}, fn);
|
|
1287
1287
|
}
|
|
1288
1288
|
__name(__runWithRuntime, "__runWithRuntime");
|
|
1289
|
+
var REQUIRED_SERVICES = [
|
|
1290
|
+
"Database",
|
|
1291
|
+
"Auth",
|
|
1292
|
+
"Secrets",
|
|
1293
|
+
"Documents",
|
|
1294
|
+
"Storage",
|
|
1295
|
+
"Cache",
|
|
1296
|
+
"Log",
|
|
1297
|
+
"Notifications",
|
|
1298
|
+
"Flags",
|
|
1299
|
+
"Realtime"
|
|
1300
|
+
];
|
|
1301
|
+
function refuseIncompleteBox(services) {
|
|
1302
|
+
const missing = REQUIRED_SERVICES.filter((k) => services[k] === void 0);
|
|
1303
|
+
if (missing.length > 0) {
|
|
1304
|
+
throw new Error(`the request scope is missing ${missing.join(", ")} \u2014 this box was most likely written by a DIFFERENT @palbase/backend major sharing the same process (the request store is a process-wide well-known Symbol, deliberately, so two bundles of ONE version can share it). Align the versions, or pass every service when building the scope yourself.`);
|
|
1305
|
+
}
|
|
1306
|
+
return services;
|
|
1307
|
+
}
|
|
1308
|
+
__name(refuseIncompleteBox, "refuseIncompleteBox");
|
|
1289
1309
|
function __getRuntime() {
|
|
1290
1310
|
const scoped = __requestALS.getStore();
|
|
1291
|
-
if (scoped) return scoped.runtime;
|
|
1311
|
+
if (scoped) return refuseIncompleteBox(scoped.runtime);
|
|
1292
1312
|
if (runtime === null) {
|
|
1293
1313
|
throw new Error("Palbase services accessed outside a request scope. The Database/Documents/\u2026 singletons are only available inside an endpoint handler (or after the runtime has called __runWithRuntime / __setRuntime).");
|
|
1294
1314
|
}
|
|
@@ -1430,7 +1450,12 @@ function makeTypedSurface(raw2) {
|
|
|
1430
1450
|
$findById: /* @__PURE__ */ __name((table, id) => raw2.findById(table, id), "$findById"),
|
|
1431
1451
|
$findMany: /* @__PURE__ */ __name((table, query, opts) => raw2.findMany(table, query, opts), "$findMany"),
|
|
1432
1452
|
$put: /* @__PURE__ */ __name((table, data, opts) => raw2.put(table, data, opts), "$put"),
|
|
1433
|
-
|
|
1453
|
+
// `opts` İLETİLİR. Düşürüldüğü sürece `Database.$updateMany(t, w, s,
|
|
1454
|
+
// { returning: false })` sessizce SATIRLARI döndürüyordu, sayıyı değil —
|
|
1455
|
+
// ve `if (n === 0) throw new Conflict(...)` guard'ı HİÇ çalışmıyordu,
|
|
1456
|
+
// çünkü `[] === 0` yanlıştır. Komşu forwarder'lar (`$findMany`, `$put`)
|
|
1457
|
+
// kendi opsiyonlarını zaten iletiyordu; bu biri unutulmuştu.
|
|
1458
|
+
$updateMany: /* @__PURE__ */ __name((table, where, set, opts) => raw2.updateMany(table, where, set, opts), "$updateMany"),
|
|
1434
1459
|
$deleteMany: /* @__PURE__ */ __name((table, where) => raw2.deleteMany(table, where), "$deleteMany"),
|
|
1435
1460
|
$count: /* @__PURE__ */ __name((table, where) => raw2.count(table, where), "$count"),
|
|
1436
1461
|
$search: /* @__PURE__ */ __name((table, params) => raw2.search(table, params), "$search"),
|
|
@@ -1561,13 +1586,13 @@ var Flags = Object.assign({
|
|
|
1561
1586
|
* Lazily resolve the runtime's cross-user sibling on each call. We do NOT
|
|
1562
1587
|
* cache it: `rawFlags.asService()` reads the CURRENT request scope through
|
|
1563
1588
|
* the runtime proxy, so caching would leak one request's sibling into
|
|
1564
|
-
* another concurrent request. Mirrors `Database
|
|
1589
|
+
* another concurrent request. Mirrors `Database.$asService()`.
|
|
1565
1590
|
*/
|
|
1566
1591
|
$asService() {
|
|
1567
1592
|
return rawFlags.asService();
|
|
1568
1593
|
},
|
|
1569
1594
|
/**
|
|
1570
|
-
* The name this member carried before
|
|
1595
|
+
* The name this member carried before 32.0.0.
|
|
1571
1596
|
*
|
|
1572
1597
|
* It does NOT work silently. A retired member that quietly keeps returning
|
|
1573
1598
|
* is how a rename becomes a mystery: the old call site goes on compiling,
|
|
@@ -1577,7 +1602,7 @@ var Flags = Object.assign({
|
|
|
1577
1602
|
* Database.$asService()" while the promise went unkept.
|
|
1578
1603
|
*/
|
|
1579
1604
|
asService() {
|
|
1580
|
-
throw new Error("Flags.asService() was renamed to Flags.$asService() in
|
|
1605
|
+
throw new Error("Flags.asService() was renamed to Flags.$asService() in 32.0.0 \u2014 system members carry the `$` prefix, like Database.$asService().");
|
|
1581
1606
|
}
|
|
1582
1607
|
});
|
|
1583
1608
|
var Realtime = makeServiceProxy("Realtime");
|
|
@@ -3317,15 +3342,27 @@ var CODECS = {
|
|
|
3317
3342
|
// not representable and the author wants `asDecimal()` instead.
|
|
3318
3343
|
number: {
|
|
3319
3344
|
fromDb: /* @__PURE__ */ __name((v) => Number(v), "fromDb"),
|
|
3320
|
-
|
|
3345
|
+
// YAZMA YOLUNDA SESSİZ BOZULMA YOK. `toDb(9007199254740993)` bir zamanlar
|
|
3346
|
+
// "9007199254740992" yazıyordu: uygulamanın tuttuğundan BAŞKA bir sayı
|
|
3347
|
+
// kolona gidiyordu ve hiçbir şey söylemiyordu. `asNumber()`'ın JSDoc'u
|
|
3348
|
+
// "2^53'ün altında güvenli" diyordu ama bunu uygulayan bir şey yoktu.
|
|
3349
|
+
toDb: /* @__PURE__ */ __name((v) => {
|
|
3350
|
+
if (typeof v === "number" && !Number.isSafeInteger(v)) {
|
|
3351
|
+
throw new Error(`asNumber() cannot write ${v}: it is outside the safe integer range and would be stored as a different number. Declare .asDecimal() and hand this column a string.`);
|
|
3352
|
+
}
|
|
3353
|
+
return String(v);
|
|
3354
|
+
}, "toDb"),
|
|
3321
3355
|
tsType: "number"
|
|
3322
3356
|
},
|
|
3323
3357
|
// Exact-precision column → the string Postgres sent. It exists so the
|
|
3324
3358
|
// DECLARATION is explicit: "this column is a decimal I handle as text",
|
|
3325
3359
|
// rather than the ABSENCE of a declaration meaning the same thing by default.
|
|
3360
|
+
// NULL güvencesi ÇİFTİN KENDİSİNDE. Motor NULL'ı zaten atlıyor (üç ayrı
|
|
3361
|
+
// yerde), ama bir değişmez, onu koruyan üç `if`'in DIŞINDA yazılmalı: biri
|
|
3362
|
+
// düşerse `String(null)` kolonu "null" dizesine çevirirdi.
|
|
3326
3363
|
decimal: {
|
|
3327
|
-
fromDb: /* @__PURE__ */ __name((v) => String(v), "fromDb"),
|
|
3328
|
-
toDb: /* @__PURE__ */ __name((v) => String(v), "toDb"),
|
|
3364
|
+
fromDb: /* @__PURE__ */ __name((v) => v === null || v === void 0 ? v : String(v), "fromDb"),
|
|
3365
|
+
toDb: /* @__PURE__ */ __name((v) => v === null || v === void 0 ? v : String(v), "toDb"),
|
|
3329
3366
|
tsType: "string"
|
|
3330
3367
|
}
|
|
3331
3368
|
};
|
|
@@ -3558,12 +3595,22 @@ var ColumnBuilder = class _ColumnBuilder {
|
|
|
3558
3595
|
if (this._def.transform !== void 0) {
|
|
3559
3596
|
throw new Error(`.${method}() and .transform() are two ways to say the same thing on one column \u2014 keep .${method}().`);
|
|
3560
3597
|
}
|
|
3561
|
-
this._def.codec
|
|
3562
|
-
|
|
3598
|
+
if (this._def.codec !== void 0) {
|
|
3599
|
+
throw new Error(`column already declares .as${this._def.codec === "number" ? "Number" : "Decimal"}(); a column has ONE codec.`);
|
|
3600
|
+
}
|
|
3601
|
+
return new _ColumnBuilder(this._def.type, {
|
|
3602
|
+
...this._def,
|
|
3603
|
+
codec
|
|
3604
|
+
});
|
|
3563
3605
|
}
|
|
3564
3606
|
transform(fns) {
|
|
3565
|
-
this._def.
|
|
3566
|
-
|
|
3607
|
+
if (this._def.codec !== void 0) {
|
|
3608
|
+
throw new Error(`column already declares a named codec; .transform() and .as*() are two ways to say the same thing \u2014 keep the codec.`);
|
|
3609
|
+
}
|
|
3610
|
+
return new _ColumnBuilder(this._def.type, {
|
|
3611
|
+
...this._def,
|
|
3612
|
+
transform: fns
|
|
3613
|
+
});
|
|
3567
3614
|
}
|
|
3568
3615
|
};
|
|
3569
3616
|
function uuid() {
|