@palbase/backend 28.0.0 → 30.0.0
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 +166 -12
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +3 -3
- package/dist/{chunk-RVP6BTEZ.js → chunk-5J5W75A6.js} +15 -4
- package/dist/chunk-5J5W75A6.js.map +1 -0
- package/dist/{chunk-IVZERLTM.js → chunk-ENZ2RFFJ.js} +2 -2
- package/dist/{chunk-SNDXY565.js → chunk-SG4UTNOP.js} +5 -2
- package/dist/chunk-SG4UTNOP.js.map +1 -0
- package/dist/{chunk-75YROPRZ.js → chunk-VN7NMDUH.js} +166 -15
- package/dist/chunk-VN7NMDUH.js.map +1 -0
- package/dist/db/index.cjs +4 -1
- 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 +2 -2
- package/dist/engine/index.cjs +166 -12
- 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 +3 -3
- package/dist/{index-dTTLlHIn.d.ts → index-8qy3kIuA.d.ts} +228 -12
- package/dist/{index-DtISj9QX.d.cts → index-DtCgaZAg.d.cts} +228 -12
- package/dist/{index-9C3JHxg-.d.cts → index-Zi7MptvP.d.cts} +30 -8
- package/dist/{index-BbvOoZFr.d.ts → index-b-Q3l7W5.d.ts} +30 -8
- package/dist/index.cjs +66 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -11
- package/dist/index.d.ts +51 -11
- package/dist/index.js +52 -3
- package/dist/index.js.map +1 -1
- package/dist/openapi/index.d.cts +2 -2
- package/dist/openapi/index.d.ts +2 -2
- package/dist/{registry-JQNIX-eA.d.ts → registry-BGJ-Al6F.d.ts} +1 -1
- package/dist/{registry-qIPM5BQe.d.cts → registry-CEYLH-Iz.d.cts} +1 -1
- package/dist/test/index.cjs +56 -0
- 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 +56 -0
- package/dist/test/index.js.map +1 -1
- package/docs/README.md +1 -1
- package/docs/database.md +49 -0
- package/docs/llms-full.txt +50 -1
- package/package.json +1 -1
- package/template/package.json +1 -1
- package/dist/chunk-75YROPRZ.js.map +0 -1
- package/dist/chunk-RVP6BTEZ.js.map +0 -1
- package/dist/chunk-SNDXY565.js.map +0 -1
- /package/dist/{chunk-IVZERLTM.js.map → chunk-ENZ2RFFJ.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-DtCgaZAg.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-Zi7MptvP.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-CEYLH-Iz.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-8qy3kIuA.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-b-Q3l7W5.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-BGJ-Al6F.js';
|
package/dist/engine/index.js
CHANGED
|
@@ -16,13 +16,13 @@ import {
|
|
|
16
16
|
quoteIdent,
|
|
17
17
|
scrubSecrets,
|
|
18
18
|
withTables
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-VN7NMDUH.js";
|
|
20
20
|
import {
|
|
21
21
|
DECLARATION_REFUSAL,
|
|
22
22
|
DeclarationRefused,
|
|
23
23
|
isDeclarationRefused
|
|
24
|
-
} from "../chunk-
|
|
25
|
-
import "../chunk-
|
|
24
|
+
} from "../chunk-5J5W75A6.js";
|
|
25
|
+
import "../chunk-SG4UTNOP.js";
|
|
26
26
|
import "../chunk-3TUJWHC2.js";
|
|
27
27
|
import "../chunk-VVMJEVQP.js";
|
|
28
28
|
import "../chunk-CGNN2PUH.js";
|
|
@@ -39,6 +39,20 @@ interface User {
|
|
|
39
39
|
*/
|
|
40
40
|
emailVerified: boolean;
|
|
41
41
|
role: string;
|
|
42
|
+
/**
|
|
43
|
+
* The caller's APPLICATION roles, as assigned in `auth.user_roles`.
|
|
44
|
+
*
|
|
45
|
+
* Not to be confused with {@link User.role}, which is the DATABASE role RLS
|
|
46
|
+
* reads and is the literal string "authenticated" for every signed-in user.
|
|
47
|
+
* These are the names a stack declares (`palbase roles`) and an operator
|
|
48
|
+
* assigns; `auth: { role }` gates on the same set.
|
|
49
|
+
*
|
|
50
|
+
* Resolved per request from the table, in the transaction the handler is
|
|
51
|
+
* about to use — never from a token claim, so a role revoked a second ago is
|
|
52
|
+
* already gone here. An empty array for a caller who holds none, never null:
|
|
53
|
+
* `user.roles.includes("agent")` needs no guard.
|
|
54
|
+
*/
|
|
55
|
+
roles: string[];
|
|
42
56
|
metadata: Record<string, unknown>;
|
|
43
57
|
/**
|
|
44
58
|
* Reserved, server-owned verified device claim. `null` on an authenticated
|
|
@@ -51,12 +65,24 @@ interface User {
|
|
|
51
65
|
interface AuthConfig {
|
|
52
66
|
/** Whether authentication is required. Defaults to true. */
|
|
53
67
|
required: boolean;
|
|
54
|
-
/** Required role for access. If undefined, any authenticated user is allowed.
|
|
68
|
+
/** Required application role for access. If undefined, any authenticated user is allowed.
|
|
69
|
+
*
|
|
70
|
+
* Matched against the caller's rows in `auth.user_roles` — NOT against the
|
|
71
|
+
* `role` claim, which is the DATABASE role RLS reads and is the literal
|
|
72
|
+
* string "authenticated" for every signed-in user. Reading it from the table
|
|
73
|
+
* is what makes a revoked role take effect on the very NEXT request instead
|
|
74
|
+
* of whenever the token happens to expire.
|
|
55
75
|
*
|
|
56
|
-
*
|
|
57
|
-
* database role RLS reads and is always "authenticated" for a signed-in user.
|
|
58
|
-
* Not signed in → 401; signed in with a different or missing role → 403. */
|
|
76
|
+
* Not signed in → 401; signed in without the role → 403. */
|
|
59
77
|
role?: string;
|
|
78
|
+
/** Required permission for access, as `resource.action` (e.g. "posts.delete_any").
|
|
79
|
+
*
|
|
80
|
+
* Resolved through `auth.has_permission(...)`, which answers from the roles
|
|
81
|
+
* the caller holds and the permissions those roles carry. The query runs in
|
|
82
|
+
* the request's own transaction, so it costs no extra connection.
|
|
83
|
+
*
|
|
84
|
+
* Signed in without the permission → 403. */
|
|
85
|
+
permission?: string;
|
|
60
86
|
/** Require a confirmed email address. An unverified caller gets 403
|
|
61
87
|
* `email_not_verified`. Fences a whole controller; for a partial rule read
|
|
62
88
|
* `user.emailVerified` in the handler instead. */
|
|
@@ -2068,6 +2094,37 @@ interface PalbaseAuthClient {
|
|
|
2068
2094
|
dispose(): void;
|
|
2069
2095
|
};
|
|
2070
2096
|
}
|
|
2097
|
+
/**
|
|
2098
|
+
* The `Auth` singleton a backend handler reaches — the ROLE-ASSIGNMENT surface,
|
|
2099
|
+
* and nothing else.
|
|
2100
|
+
*
|
|
2101
|
+
* Deliberately not {@link PalbaseAuthClient}: that one is a person acting on
|
|
2102
|
+
* their own account (sign-in, MFA, device attestation) and it belongs to the
|
|
2103
|
+
* client SDK. What a server needs is the operator verb — "make this user an
|
|
2104
|
+
* agent" — because the promotion usually happens inside the tenant's own
|
|
2105
|
+
* product, in a handler a supervisor triggers.
|
|
2106
|
+
*
|
|
2107
|
+
* These calls carry the SERVICE-ROLE credential: the routes behind them refuse
|
|
2108
|
+
* anon and `authenticated` alike (FR-013), which is what stops an end user from
|
|
2109
|
+
* granting themselves the permission the rest of the feature gates on.
|
|
2110
|
+
*
|
|
2111
|
+
* Unlike the other clients here these THROW rather than envelope, because two
|
|
2112
|
+
* of the three answer `void` — a refusal that came back as a value would be
|
|
2113
|
+
* indistinguishable from a write that happened. See `clients/auth.ts`.
|
|
2114
|
+
*/
|
|
2115
|
+
interface PalbaseAuthAdminClient {
|
|
2116
|
+
/**
|
|
2117
|
+
* Give a user a role. Idempotent: assigning one they already hold is not an
|
|
2118
|
+
* error and leaves one row. Throws `RoleNotDefined` when the stack declares
|
|
2119
|
+
* no role by that name.
|
|
2120
|
+
*/
|
|
2121
|
+
assignRole(userId: string, role: string): Promise<void>;
|
|
2122
|
+
/** Take a role away. Revoking one they do not hold is not an error. */
|
|
2123
|
+
revokeRole(userId: string, role: string): Promise<void>;
|
|
2124
|
+
/** What that user holds right now. `[]` for a user with no roles — a FAILED
|
|
2125
|
+
* read throws rather than answering the same thing. */
|
|
2126
|
+
rolesOf(userId: string): Promise<string[]>;
|
|
2127
|
+
}
|
|
2071
2128
|
/**
|
|
2072
2129
|
* Bucket-level file operations available via `ctx.storage.bucket(name)`.
|
|
2073
2130
|
* `getPublicUrl` is synchronous (no network call — constructs URL locally).
|
|
@@ -2527,11 +2584,14 @@ interface PalbaseLinksClient {
|
|
|
2527
2584
|
* Realtime is BROADCAST-ONLY here (a stateless handler can push an event but
|
|
2528
2585
|
* cannot hold a subscription socket — `subscribe()` lives on the client SDK).
|
|
2529
2586
|
*
|
|
2530
|
-
* EXCLUDED on purpose: Functions, Links, Analytics
|
|
2531
|
-
*
|
|
2532
|
-
*
|
|
2587
|
+
* EXCLUDED on purpose: Functions, Links, Analytics. They are not exposed as
|
|
2588
|
+
* backend handler singletons — out of scope for backend endpoints. `Auth` is
|
|
2589
|
+
* here in its ROLE-ASSIGNMENT shape only: signing in is the client SDK's job,
|
|
2590
|
+
* but granting a role is an operator verb the tenant's own handler needs
|
|
2591
|
+
* (FR-009). */
|
|
2533
2592
|
interface RuntimeServices {
|
|
2534
2593
|
Database: DBClient;
|
|
2594
|
+
Auth: PalbaseAuthAdminClient;
|
|
2535
2595
|
Secrets: SecretsService;
|
|
2536
2596
|
Documents: PalbaseDocsClient;
|
|
2537
2597
|
Storage: PalbaseStorageClient;
|
|
@@ -2741,6 +2801,20 @@ declare const Cache: CacheClient;
|
|
|
2741
2801
|
* the STACK holds, because no route returns a platform secret's value at all.
|
|
2742
2802
|
*/
|
|
2743
2803
|
declare const Secrets: SecretsService;
|
|
2804
|
+
/**
|
|
2805
|
+
* Role assignment, as an operator — `Auth.assignRole(userId, "agent")`.
|
|
2806
|
+
*
|
|
2807
|
+
* The half of auth a SERVER owns. Signing in, MFA and device attestation are a
|
|
2808
|
+
* person acting on their own account and live on the client SDK; granting a
|
|
2809
|
+
* role is the tenant's product doing something to somebody else, which is
|
|
2810
|
+
* exactly what a handler is for. It writes with the service-role credential,
|
|
2811
|
+
* because an end user who could write their own assignment would make every
|
|
2812
|
+
* permission underneath it meaningless.
|
|
2813
|
+
*
|
|
2814
|
+
* The write is visible to the very next request: authority is read from the
|
|
2815
|
+
* table on each call, never carried on a token.
|
|
2816
|
+
*/
|
|
2817
|
+
declare const Auth: PalbaseAuthAdminClient;
|
|
2744
2818
|
/** Structured logger. */
|
|
2745
2819
|
declare const Log: Logger;
|
|
2746
2820
|
/** Push / email / SMS / in-app notifications. */
|
|
@@ -2864,11 +2938,33 @@ interface TypedTable<T extends TableDef> {
|
|
|
2864
2938
|
* if (row === undefined) throw new Conflict("yetersiz bakiye");
|
|
2865
2939
|
* ```
|
|
2866
2940
|
*/
|
|
2867
|
-
updateMany
|
|
2941
|
+
updateMany<const Q extends MutateInput<RowShape<T>, InsertShape<T>>>(q: Q): Promise<Q extends {
|
|
2942
|
+
returning: false;
|
|
2943
|
+
} ? number : RowShape<T>[]>;
|
|
2868
2944
|
/** Delete every matching row; resolves to how many. Empty filter refused. */
|
|
2869
2945
|
deleteMany(q: {
|
|
2870
2946
|
where: WhereFilter<RowShape<T>> | SqlFragment;
|
|
2871
2947
|
}): Promise<number>;
|
|
2948
|
+
/**
|
|
2949
|
+
* Toplama — `sum` / `avg` / `min` / `max` / `count`, isteğe bağlı `groupBy`.
|
|
2950
|
+
*
|
|
2951
|
+
* ```ts
|
|
2952
|
+
* const r = await Database.public.entries.aggregate({
|
|
2953
|
+
* where: { account_id },
|
|
2954
|
+
* sum: ["amount_kurus"],
|
|
2955
|
+
* count: true,
|
|
2956
|
+
* });
|
|
2957
|
+
* r.sum.amount_kurus; // string | null — KAYIPSIZ
|
|
2958
|
+
* r.count; // number
|
|
2959
|
+
* ```
|
|
2960
|
+
*
|
|
2961
|
+
* `sum`/`avg` yalnız sayısal kolonlarda ve HER ZAMAN `string` döner: para JS
|
|
2962
|
+
* `number`'ına uğradığı anda kesinliğini kaybeder. `| null` çünkü Postgres
|
|
2963
|
+
* boş kümede NULL döndürür — "hiç satır yoktu" ile "toplam sıfırdı" farklı.
|
|
2964
|
+
*
|
|
2965
|
+
* `groupBy` verilirse dönüş bir DİZİ ve her satır grup kolonlarını taşır.
|
|
2966
|
+
*/
|
|
2967
|
+
aggregate<const Q extends AggregateInput<RowShape<T>>>(q: Q): Promise<AggregateResult<Q, RowShape<T>>>;
|
|
2872
2968
|
/** How many rows match. An empty filter is legitimate: counting is a read. */
|
|
2873
2969
|
count(q?: {
|
|
2874
2970
|
where?: WhereFilter<RowShape<T>> | SqlFragment;
|
|
@@ -3020,7 +3116,26 @@ type ColumnsComparableTo<Row, V> = {
|
|
|
3020
3116
|
* `findMany`'nin `Row`'u bilmediği yolların ve jsonb kolonlarının hâli, ve
|
|
3021
3117
|
* ikisinde de tipin söyleyebileceği bir şey yok.
|
|
3022
3118
|
*/
|
|
3023
|
-
|
|
3119
|
+
/**
|
|
3120
|
+
* "Kısıt verilmedi" için AYRI bir işaret — `unknown` DEĞİL.
|
|
3121
|
+
*
|
|
3122
|
+
* Eskiden varsayılan `unknown`'dı ve dal `[unknown] extends [V]` ile
|
|
3123
|
+
* seçiliyordu. Ama `jsonb` kolonlarının DEĞER TİPİ de `unknown`: yani gerçek
|
|
3124
|
+
* bir jsonb kolonu "kısıt verilmedi" sanılıp TÜM kolonlarla karşılaştırılabilir
|
|
3125
|
+
* hâle geliyordu. D-021 bunu "jsonb ↔ text derleniyor" diye kaydetmişti ve PG
|
|
3126
|
+
* markası tek başına kapatmadı — `unknown & X` kesişimi `X`'e çöktüğü için
|
|
3127
|
+
* jsonb markalanamıyor (markalamak kolonu daraltıp meşru yazmaları kırdı,
|
|
3128
|
+
* gerçek projede ölçüldü).
|
|
3129
|
+
*
|
|
3130
|
+
* Ayrı bir işaretle iki durum artık ayrışıyor: kısıtsız yol kısıtsız kalıyor,
|
|
3131
|
+
* jsonb ise KENDİ ailesine düşüyor — yani yalnız başka bir jsonb ile
|
|
3132
|
+
* karşılaştırılabiliyor.
|
|
3133
|
+
*/
|
|
3134
|
+
declare const NO_CONSTRAINT: unique symbol;
|
|
3135
|
+
type NoColConstraint = {
|
|
3136
|
+
readonly [NO_CONSTRAINT]: true;
|
|
3137
|
+
};
|
|
3138
|
+
type ColRefOf<Row, V = NoColConstraint> = [keyof Row] extends [never] ? never : [V] extends [NoColConstraint] ? ColRef<Extract<keyof Row, string>> : ColRef<Extract<ColumnsComparableTo<Row, V>, string>>;
|
|
3024
3139
|
/**
|
|
3025
3140
|
* Doğrulanmış, GÖMÜLEBİLİR bir SQL parçası (FR-018, FR-019).
|
|
3026
3141
|
*
|
|
@@ -3281,6 +3396,15 @@ type QueryInput<Row, K extends keyof Row = keyof Row, Rels = unknown> = {
|
|
|
3281
3396
|
type MutateInput<Row, Insert, Rels = unknown> = {
|
|
3282
3397
|
where: WhereFilter<Row> | SqlFragment | HasBranch<Row, Rels>;
|
|
3283
3398
|
set: SetShape<Insert>;
|
|
3399
|
+
/**
|
|
3400
|
+
* `false` verilirse SATIRLAR değil SAYI döner — `deleteMany` ile aynı şekil.
|
|
3401
|
+
*
|
|
3402
|
+
* ÖLÇÜLDÜ (200 bin satır, canlı pg16): `RETURNING *` sunucuda %55 daha
|
|
3403
|
+
* pahalı (7,2 sn → 11,1 sn) ve JS'te 45 MB yığın tutuyor — satır başına 236
|
|
3404
|
+
* bayt, yani bir milyon satırda 225 MB. Çoğu çağrı için dönen diziyi okumak
|
|
3405
|
+
* DOĞRU ve varsayılan odur; toplu bir iş için çıkış yolu olması gerekiyordu.
|
|
3406
|
+
*/
|
|
3407
|
+
returning?: boolean;
|
|
3284
3408
|
};
|
|
3285
3409
|
/**
|
|
3286
3410
|
* `set`'e yazılabilen değer (FR-012): kolonun kendi tipi ya da — sayısal
|
|
@@ -3391,6 +3515,64 @@ type RecommendParamsTyped<T extends TableTypes> = SimilarParamsTyped<T> & {
|
|
|
3391
3515
|
type RelsOf<T> = T extends {
|
|
3392
3516
|
relations: infer R;
|
|
3393
3517
|
} ? R : unknown;
|
|
3518
|
+
/**
|
|
3519
|
+
* TOPLAMA — dönüş tipi PG markasından TÜRETİLİR, tahmin edilmez.
|
|
3520
|
+
*
|
|
3521
|
+
* Para bu SDK'dan geçecek, ve toplamada kaybedilecek tek şey kesinliktir:
|
|
3522
|
+
* `sum(numeric)` Postgres'te `numeric`, `sum(integer)` `bigint` — İKİSİ DE JS
|
|
3523
|
+
* `number`'ında kayıplı. Bu yüzden `sum`/`avg` HER ZAMAN `string` döner ve
|
|
3524
|
+
* motor `::text` ile döker. D-007'nin kapattığı hata buydu:
|
|
3525
|
+
* 41.00821234567890123 canlıda 41.0082123456789 oluyordu.
|
|
3526
|
+
*
|
|
3527
|
+
* `| null` bir süs değil: Postgres BOŞ kümede NULL döndürür, 0 değil. "Hiç
|
|
3528
|
+
* satır yoktu" ile "toplam sıfırdı" farklı şeyler, ve tip bunu sormaya
|
|
3529
|
+
* ZORLUYOR.
|
|
3530
|
+
*/
|
|
3531
|
+
type SummableCols<Row> = {
|
|
3532
|
+
[K in keyof Row]-?: "?" extends PgTag<Row[K]> ? NonNullable<Row[K]> extends number | string ? K : never : PgKind<PgTag<Row[K]>> extends "num" ? K : never;
|
|
3533
|
+
}[keyof Row];
|
|
3534
|
+
/** `min`/`max` sıralanabilir her kolonda — jsonb ve vektör hariç. */
|
|
3535
|
+
type OrderableCols<Row> = {
|
|
3536
|
+
[K in keyof Row]-?: "?" extends PgTag<Row[K]> ? NonNullable<Row[K]> extends number | string | Date ? K : never : PgTag<Row[K]> extends "jsonb" | "vector" ? never : K;
|
|
3537
|
+
}[keyof Row];
|
|
3538
|
+
type AggCols<Row> = Extract<SummableCols<Row>, string>;
|
|
3539
|
+
type AggOrderCols<Row> = Extract<OrderableCols<Row>, string>;
|
|
3540
|
+
type AggregateInput<Row, Rels = unknown> = {
|
|
3541
|
+
where?: WhereFilter<Row> | SqlFragment | HasBranch<Row, Rels>;
|
|
3542
|
+
/** Toplam — yalnız sayısal kolonlarda; sonuç `string | null` (kayıpsız). */
|
|
3543
|
+
sum?: readonly AggCols<Row>[];
|
|
3544
|
+
/** Ortalama — sonuç `numeric`, yani `string | null`. */
|
|
3545
|
+
avg?: readonly AggCols<Row>[];
|
|
3546
|
+
min?: readonly AggOrderCols<Row>[];
|
|
3547
|
+
max?: readonly AggOrderCols<Row>[];
|
|
3548
|
+
/** Kaç satır — `count()` ile aynı sayı, ama AYNI turda. */
|
|
3549
|
+
count?: boolean;
|
|
3550
|
+
/** Verilirse SATIRLAR döner ve her satır grup kolonlarını taşır. */
|
|
3551
|
+
groupBy?: readonly Extract<keyof Row, string>[];
|
|
3552
|
+
};
|
|
3553
|
+
type AggPart<Q, Row, F extends "sum" | "avg" | "min" | "max"> = Q extends {
|
|
3554
|
+
[K in F]: readonly (infer C extends keyof Row)[];
|
|
3555
|
+
} ? {
|
|
3556
|
+
[P in C]: F extends "sum" | "avg" ? string | null : Row[P] | null;
|
|
3557
|
+
} : never;
|
|
3558
|
+
type AggBody<Q, Row> = ([AggPart<Q, Row, "sum">] extends [never] ? unknown : {
|
|
3559
|
+
sum: AggPart<Q, Row, "sum">;
|
|
3560
|
+
}) & ([AggPart<Q, Row, "avg">] extends [never] ? unknown : {
|
|
3561
|
+
avg: AggPart<Q, Row, "avg">;
|
|
3562
|
+
}) & ([AggPart<Q, Row, "min">] extends [never] ? unknown : {
|
|
3563
|
+
min: AggPart<Q, Row, "min">;
|
|
3564
|
+
}) & ([AggPart<Q, Row, "max">] extends [never] ? unknown : {
|
|
3565
|
+
max: AggPart<Q, Row, "max">;
|
|
3566
|
+
}) & (Q extends {
|
|
3567
|
+
count: true;
|
|
3568
|
+
} ? {
|
|
3569
|
+
count: number;
|
|
3570
|
+
} : unknown);
|
|
3571
|
+
type AggregateResult<Q, Row> = Q extends {
|
|
3572
|
+
groupBy: readonly (infer G extends keyof Row)[];
|
|
3573
|
+
} ? ({
|
|
3574
|
+
[P in G]: Row[P];
|
|
3575
|
+
} & AggBody<Q, Row>)[] : AggBody<Q, Row>;
|
|
3394
3576
|
/** Temel tablo erişimcisi — search'süz beş op. */
|
|
3395
3577
|
interface EnvTypedTableBase<T extends TableTypes> {
|
|
3396
3578
|
insert(data: InsertValues<T["insert"]>): Promise<T["row"]>;
|
|
@@ -3489,11 +3671,34 @@ interface EnvTypedTableBase<T extends TableTypes> {
|
|
|
3489
3671
|
* if (row === undefined) throw new Conflict("yetersiz bakiye");
|
|
3490
3672
|
* ```
|
|
3491
3673
|
*/
|
|
3492
|
-
updateMany
|
|
3674
|
+
updateMany<const Q extends MutateInput<T["row"], T["insert"], RelsOf<T>>>(q: Q): Promise<Q extends {
|
|
3675
|
+
returning: false;
|
|
3676
|
+
} ? number : T["row"][]>;
|
|
3493
3677
|
/** Delete every matching row; resolves to how many. Empty filter refused. */
|
|
3494
3678
|
deleteMany(q: {
|
|
3495
3679
|
where: WhereFilter<T["row"]> | SqlFragment | HasBranch<T["row"], RelsOf<T>>;
|
|
3496
3680
|
}): Promise<number>;
|
|
3681
|
+
/**
|
|
3682
|
+
* Toplama — `sum` / `avg` / `min` / `max` / `count`, isteğe bağlı `groupBy`.
|
|
3683
|
+
*
|
|
3684
|
+
* ```ts
|
|
3685
|
+
* const r = await Database.public.entries.aggregate({
|
|
3686
|
+
* where: { account_id },
|
|
3687
|
+
* sum: ["amount_kurus"],
|
|
3688
|
+
* count: true,
|
|
3689
|
+
* });
|
|
3690
|
+
* r.sum.amount_kurus; // string | null — KAYIPSIZ
|
|
3691
|
+
* r.count; // number
|
|
3692
|
+
* ```
|
|
3693
|
+
*
|
|
3694
|
+
* `sum`/`avg` yalnız sayısal kolonlarda ve HER ZAMAN `string` döner: para JS
|
|
3695
|
+
* `number`'ına uğradığı anda kesinliğini kaybeder. `| null` çünkü Postgres
|
|
3696
|
+
* boş kümede NULL döndürür — "hiç satır yoktu" ile "toplam sıfırdı" farklı
|
|
3697
|
+
* şeyler ve tip bunu sormaya zorluyor.
|
|
3698
|
+
*
|
|
3699
|
+
* `groupBy` verilirse dönüş bir DİZİ ve her satır grup kolonlarını taşır.
|
|
3700
|
+
*/
|
|
3701
|
+
aggregate<const Q extends AggregateInput<T["row"], RelsOf<T>>>(q: Q): Promise<AggregateResult<Q, T["row"]>>;
|
|
3497
3702
|
/** How many rows match. An empty filter is legitimate: counting is a read. */
|
|
3498
3703
|
count(q?: {
|
|
3499
3704
|
where?: WhereFilter<T["row"]> | SqlFragment | HasBranch<T["row"], RelsOf<T>>;
|
|
@@ -4441,6 +4646,15 @@ interface DBOps {
|
|
|
4441
4646
|
/** Çok satır, TEK statement. Satırların anahtar kümesi aynı olmalı — kolon
|
|
4442
4647
|
* listesi paylaşıldığı için farklı şekilli bir satırın kolonu sessizce
|
|
4443
4648
|
* yazılmazdı. */
|
|
4649
|
+
aggregate(table: string, q: {
|
|
4650
|
+
where?: Record<string, unknown>;
|
|
4651
|
+
sum?: readonly string[];
|
|
4652
|
+
avg?: readonly string[];
|
|
4653
|
+
min?: readonly string[];
|
|
4654
|
+
max?: readonly string[];
|
|
4655
|
+
count?: boolean;
|
|
4656
|
+
groupBy?: readonly string[];
|
|
4657
|
+
}): Promise<Record<string, unknown> | Record<string, unknown>[]>;
|
|
4444
4658
|
insertMany(table: string, rows: readonly Record<string, unknown>[], opts?: {
|
|
4445
4659
|
onConflict: readonly string[];
|
|
4446
4660
|
action?: "ignore" | "update";
|
|
@@ -4518,7 +4732,9 @@ interface DBOps {
|
|
|
4518
4732
|
* yetmedi) — ikisini ayıran tek şey dönen dizidir. Çağrı hata fırlatmadı diye
|
|
4519
4733
|
* işlem oldu SAYILAMAZ; kontrol çağıranın işi.
|
|
4520
4734
|
*/
|
|
4521
|
-
updateMany(table: string, where: Record<string, unknown>, set: Record<string, unknown
|
|
4735
|
+
updateMany(table: string, where: Record<string, unknown>, set: Record<string, unknown>, opts?: {
|
|
4736
|
+
returning?: boolean;
|
|
4737
|
+
}): Promise<Record<string, unknown>[] | number>;
|
|
4522
4738
|
/**
|
|
4523
4739
|
* Bir idempotency anahtarını sahiplen (FR-033).
|
|
4524
4740
|
*
|
|
@@ -4944,4 +5160,4 @@ type Middleware = (ctx: MiddlewareContext, next: () => Promise<void>) => Promise
|
|
|
4944
5160
|
*/
|
|
4945
5161
|
type AuthSpec = boolean | Partial<AuthConfig>;
|
|
4946
5162
|
|
|
4947
|
-
export {
|
|
5163
|
+
export { NotFound as $, type AuthSpec as A, BadRequest as B, type CacheClient as C, type DBClient as D, EXTENSION_DEPENDENCIES as E, type ErrorMap as F, type ErrorThrowers as G, HttpError as H, type FileContext as I, Flags as J, Forbidden as K, type HttpMethod as L, IndexBuilder as M, type IndexDef as N, type InsertShape as O, type PalbaseResult as P, type LifecycleHook as Q, type RateLimitConfig as R, type SchemaDef as S, type TxPlanBody as T, Log as U, type Logger as V, type Materialized as W, type Middleware as X, type MiddlewareContext as Y, type MiddlewareHandler as Z, __runWithRuntime as _, type DBOps as a, type PalbaseListLinksOptions as a$, Notifications as a0, type OnDeleteAction as a1, PALBASE_EXTENSIONS as a2, type PBRequest as a3, PalError as a4, type PalbaseAnalyticsClient as a5, type PalbaseAnalyticsManagementNamespace as a6, type PalbaseAnalyticsProperties as a7, type PalbaseAnalyticsQueryNamespace as a8, type PalbaseAttestAndroidParams as a9, type PalbaseEventsQueryInput as aA, type PalbaseEventsResult as aB, type PalbaseExtension as aC, type PalbaseFileObject as aD, type PalbaseFlag as aE, type PalbaseFlagContext as aF, type PalbaseFlagSource as aG, type PalbaseFlagValue as aH, type PalbaseFlagVariant as aI, type PalbaseFlagsClient as aJ, type PalbaseFlagsServiceClient as aK, type PalbaseFunctionsClient as aL, type PalbaseFunnelQueryInput as aM, type PalbaseFunnelResult as aN, type PalbaseIdentifyTraits as aO, type PalbaseInboxClient as aP, type PalbaseInboxListOptions as aQ, type PalbaseInboxListResult as aR, type PalbaseInboxMessage as aS, type PalbaseInboxSendParams as aT, type PalbaseInboxSendResponse as aU, type PalbaseInitialLink as aV, type PalbaseInvokeOptions as aW, type PalbaseLink as aX, type PalbaseLinkAnalytics as aY, type PalbaseLinkDetails as aZ, type PalbaseLinksClient as a_, type PalbaseAttestAndroidResult as aa, type PalbaseAttestiOSParams as ab, type PalbaseAttestiOSResult as ac, type PalbaseAuthAdminClient as ad, type PalbaseAuthClient as ae, type PalbaseBatchOverrideOperation as af, type PalbaseBatchSetOverridesResult as ag, type PalbaseBindDeviceParams as ah, type PalbaseBucketClient as ai, type PalbaseClearAllOverridesResult as aj, type PalbaseClearOverrideResult as ak, type PalbaseCohortQueryInput as al, type PalbaseCohortResult as am, type PalbaseCollectionRef as an, type PalbaseCountQueryInput as ao, type PalbaseCountResult as ap, type PalbaseCreateLinkParams as aq, type PalbaseDeviceInfo as ar, type PalbaseDeviceTokenView as as, type PalbaseDocsClient as at, type PalbaseDocumentRef as au, type PalbaseDocumentSnapshot as av, type PalbaseEmailClient as aw, type PalbaseEmailSendParams as ax, type PalbaseEmailSendResponse as ay, type PalbaseEventNamesResult as az, type TxPlanResponse as b, type TxNow as b$, type PalbaseListLinksResult as b0, type PalbaseListOptions as b1, type PalbaseMatchParams as b2, type PalbaseMultiChannelResponse as b3, type PalbaseNotificationsClient as b4, type PalbaseOverviewResult as b5, type PalbasePreferences as b6, type PalbasePreferencesClient as b7, type PalbasePushClient as b8, type PalbasePushSendParams as b9, type PolicyCommand as bA, type PolicyDef as bB, type PolicyExprCtx as bC, PolicyExprRef as bD, type PolicyMode as bE, type PolicyOperand as bF, type RawConstraintDef as bG, Realtime as bH, type Ref as bI, type RequestStore as bJ, type RowShape as bK, Secrets as bL, type SecretsService as bM, SerializationFailure as bN, type SetShape as bO, type SetValue as bP, type ShutdownRunner as bQ, type SqlFragment as bR, Storage as bS, TABLE_META as bT, type TableDef as bU, type TableHandle as bV, type TableInput as bW, TooManyRequests as bX, type TxColumnExpr as bY, type TxInsertShape as bZ, type TxInsertValue as b_, type PalbasePushSendResponse as ba, type PalbaseQrCodeOptions as bb, type PalbaseQuerySnapshot as bc, type PalbaseRealtimeClient as bd, type PalbaseRegisterDeviceParams as be, type PalbaseRetentionQueryInput as bf, type PalbaseRetentionResult as bg, type PalbaseSession as bh, type PalbaseSetOverrideResult as bi, type PalbaseSetOverridesResult as bj, type PalbaseSignedUrlResponse as bk, type PalbaseSmsClient as bl, type PalbaseSmsSendParams as bm, type PalbaseSmsSendResponse as bn, type PalbaseStorageClient as bo, type PalbaseTransformOptions as bp, type PalbaseUpdateLinkParams as bq, type PalbaseUploadOptions as br, type PalbaseUser as bs, type PalbaseUserDetailResult as bt, type PalbaseUsersQueryInput as bu, type PalbaseUsersResult as bv, type PalbaseVerifyRequestSignatureParams as bw, type PalbaseWhereOperator as bx, type PolicyBinOp as by, PolicyBuilder as bz, type RuntimeServices as c, withRetry as c$, type TxPlan as c0, TxPlanError as c1, type TxPlanHandle as c2, type TxPlanOpResult as c3, type TxPlanRejection as c4, TxRefError as c5, type TxRow as c6, type TxRows as c7, type TxSelectOptions as c8, type TxSetShape as c9, defineSchema as cA, defineTable as cB, enumType as cC, exprCtx as cD, inc as cE, increment as cF, index as cG, installationRef as cH, integer as cI, isPalbaseExtension as cJ, isRetryable as cK, jsonb as cL, makeTypedDB as cM, now as cN, numeric as cO, onShutdown as cP, onStart as cQ, openai as cR, ownedByUser as cS, policy as cT, raw as cU, sqlFragment as cV, text as cW, timestamp as cX, userRef as cY, uuid as cZ, vector as c_, type TxSetValue as ca, type TxTable as cb, type TxTables as cc, type TxWhere as cd, type TxWireExpr as ce, type TxWireGuard as cf, type TxWireOp as cg, type TxWireRef as ch, type TxWireValue as ci, type TypedDB as cj, type TypedTable as ck, type TypedTx as cl, Unauthorized as cm, UniqueViolation as cn, type User as co, type VerifiedDevice as cp, __getRuntime as cq, __resetLifecycleHooks as cr, __runStartHooks as cs, __setRuntime as ct, bigint as cu, boolean as cv, col as cw, dec as cx, decrement as cy, defineMiddleware as cz, __requestALS as d, type PolicyExpr as e, type AnyColumn as f, Auth as g, type AuthConfig as h, Cache as i, type ClientInfo as j, type ColRef as k, ColumnBuilder as l, type ColumnDef as m, type ColumnMap as n, type ColumnType as o, Conflict as p, Database as q, DeadlockDetected as r, Documents as s, type EmbeddingModelRef as t, type EnvSchemas as u, type EnvServiceDatabase as v, type EnvTables as w, type EnvTypedDatabase as x, type EnvTypedTable as y, type ErrorDef as z };
|