@palbase/backend 27.0.0 → 28.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 +165 -39
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +4 -4
- package/dist/{chunk-GYK6QYS4.js → chunk-3TUJWHC2.js} +28 -3
- package/dist/chunk-3TUJWHC2.js.map +1 -0
- package/dist/{chunk-OO7R25AI.js → chunk-75YROPRZ.js} +118 -39
- package/dist/chunk-75YROPRZ.js.map +1 -0
- package/dist/{chunk-TS4U7NBD.js → chunk-IVZERLTM.js} +2 -2
- package/dist/{chunk-I3C4PFIW.js → chunk-RVP6BTEZ.js} +63 -6
- package/dist/chunk-RVP6BTEZ.js.map +1 -0
- package/dist/{chunk-DRZFQRJI.js → chunk-SNDXY565.js} +3 -2
- package/dist/chunk-SNDXY565.js.map +1 -0
- package/dist/db/index.cjs +30 -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 +3 -3
- package/dist/engine/index.cjs +175 -39
- 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 +11 -4
- package/dist/{index-VtToZmUm.d.cts → index-9C3JHxg-.d.cts} +112 -5
- package/dist/{index-NuzRCuxe.d.ts → index-BbvOoZFr.d.ts} +112 -5
- package/dist/{index-Bve7BBTL.d.cts → index-DtISj9QX.d.cts} +125 -22
- package/dist/{index-BrvvxSpn.d.ts → index-dTTLlHIn.d.ts} +125 -22
- package/dist/index.cjs +93 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -22
- package/dist/index.d.ts +6 -22
- package/dist/index.js +10 -4
- 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-B0eyOF9x.d.ts → registry-JQNIX-eA.d.ts} +1 -1
- package/dist/{registry-Bk9_rbNd.d.cts → registry-qIPM5BQe.d.cts} +1 -1
- package/dist/test/index.cjs +100 -6
- 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 +88 -6
- package/dist/test/index.js.map +1 -1
- package/docs/README.md +1 -1
- package/docs/database.md +103 -1
- package/docs/llms-full.txt +104 -2
- package/package.json +1 -1
- package/template/package.json +1 -1
- package/dist/chunk-DRZFQRJI.js.map +0 -1
- package/dist/chunk-GYK6QYS4.js.map +0 -1
- package/dist/chunk-I3C4PFIW.js.map +0 -1
- package/dist/chunk-OO7R25AI.js.map +0 -1
- /package/dist/{chunk-TS4U7NBD.js.map → chunk-IVZERLTM.js.map} +0 -0
|
@@ -2825,7 +2825,12 @@ type RowShape<T extends TableDef> = {
|
|
|
2825
2825
|
};
|
|
2826
2826
|
/** A typed table accessor that mirrors the runtime DBClient surface. */
|
|
2827
2827
|
interface TypedTable<T extends TableDef> {
|
|
2828
|
-
insert(data: InsertShape<T
|
|
2828
|
+
insert(data: InsertValues<InsertShape<T>>): Promise<RowShape<T>>;
|
|
2829
|
+
/** Çok satır, TEK statement. Satırların anahtar kümesi aynı olmalı. */
|
|
2830
|
+
insertMany(rows: readonly InsertValues<InsertShape<T>>[], opts?: {
|
|
2831
|
+
onConflict: readonly string[];
|
|
2832
|
+
action?: "ignore" | "update";
|
|
2833
|
+
}): Promise<RowShape<T>[]>;
|
|
2829
2834
|
put(q: {
|
|
2830
2835
|
data: InsertShape<T>;
|
|
2831
2836
|
onConflict: readonly string[];
|
|
@@ -2837,7 +2842,7 @@ interface TypedTable<T extends TableDef> {
|
|
|
2837
2842
|
where: {
|
|
2838
2843
|
id: string;
|
|
2839
2844
|
};
|
|
2840
|
-
set:
|
|
2845
|
+
set: SetShape<InsertShape<T>>;
|
|
2841
2846
|
}): Promise<RowShape<T> | null>;
|
|
2842
2847
|
delete(id: string): Promise<void>;
|
|
2843
2848
|
findById(id: string): Promise<RowShape<T> | null>;
|
|
@@ -2974,9 +2979,39 @@ declare function col<const N extends string>(name: N): ColRef<N>;
|
|
|
2974
2979
|
* kabul, `numeric ↔ text` ret olur ve ikisi de DOĞRU olur. Defterde teklif.
|
|
2975
2980
|
*/
|
|
2976
2981
|
type PgFamily<V> = [NonNullable<V>] extends [boolean] ? "bool" : [NonNullable<V>] extends [readonly (number | string)[]] ? "array" : [NonNullable<V>] extends [Date] ? "date" : [NonNullable<V>] extends [string | number] ? "scalar" : "opaque";
|
|
2977
|
-
/**
|
|
2982
|
+
/**
|
|
2983
|
+
* Kolonun BİLDİRİLMİŞ Postgres tipi — `env-gen`'in bastığı markadan.
|
|
2984
|
+
*
|
|
2985
|
+
* Marka yoksa `"?"`: elle yazılmış bir `Tables` (testler) ya da yeniden
|
|
2986
|
+
* üretilmemiş bir `palbase-env.d.ts`. O durumda eski TS-tipi sezgiseline
|
|
2987
|
+
* düşülüyor, çünkü marka olmadan söylenebilecek daha doğru bir şey yok.
|
|
2988
|
+
*/
|
|
2989
|
+
type PgTag<V> = [NonNullable<V>] extends [{
|
|
2990
|
+
readonly __pg?: infer N;
|
|
2991
|
+
}] ? [N] extends [string] ? N : "?" : "?";
|
|
2992
|
+
/**
|
|
2993
|
+
* Postgres'te birbirleriyle karşılaştırılabilen tipler tek "cins".
|
|
2994
|
+
*
|
|
2995
|
+
* `integer`, `bigint` ve `numeric` örtük sayısal dönüşümle karşılaştırılır;
|
|
2996
|
+
* geri kalan her tip yalnız kendisiyle. `uuid ↔ text` ve `enum ↔ text`
|
|
2997
|
+
* Postgres'te `operator does not exist` verir — D-021'de CANLI ölçülmüştü ve
|
|
2998
|
+
* tip bunu göremediği için kabul ediyordu.
|
|
2999
|
+
*/
|
|
3000
|
+
type PgKind<P> = P extends "integer" | "bigint" | "numeric" ? "num" : P;
|
|
3001
|
+
/** İki tarafın da markası var mı — yoksa sezgisele düşülür. */
|
|
3002
|
+
type BothBranded<A, B> = "?" extends PgTag<A> ? false : "?" extends PgTag<B> ? false : true;
|
|
3003
|
+
type PgSameKind<A, B> = [PgKind<PgTag<A>>] extends [PgKind<PgTag<B>>] ? [PgKind<PgTag<B>>] extends [PgKind<PgTag<A>>] ? true : false : false;
|
|
3004
|
+
/**
|
|
3005
|
+
* `A` kolonu `B` ile karşılaştırılabilir mi.
|
|
3006
|
+
*
|
|
3007
|
+
* Marka varsa CEVAP KESİN: ne yanlış ret ne yanlış kabul. D-021 bu kuralı
|
|
3008
|
+
* "doğru olamaz" diye kaydetmişti çünkü tipte ayırt edecek bilgi yoktu; bilgi
|
|
3009
|
+
* artık tipte.
|
|
3010
|
+
*/
|
|
3011
|
+
type ColComparable<A, B> = BothBranded<A, B> extends true ? PgSameKind<A, B> : [PgFamily<A>] extends [PgFamily<B>] ? true : false;
|
|
3012
|
+
/** `Row`'un `V` ile karşılaştırılabilir kolonları. */
|
|
2978
3013
|
type ColumnsComparableTo<Row, V> = {
|
|
2979
|
-
[K in keyof Row]-?:
|
|
3014
|
+
[K in keyof Row]-?: ColComparable<Row[K], V> extends true ? K : never;
|
|
2980
3015
|
}[keyof Row];
|
|
2981
3016
|
/**
|
|
2982
3017
|
* Bu satırın kolonlarından birine referans. `Row` bilinmiyorsa hiçbiri.
|
|
@@ -3052,12 +3087,24 @@ type TextOps<V> = V extends string ? {
|
|
|
3052
3087
|
* `C` bir parametre, çünkü `ColRefOf<Row, V>` aksi hâlde altı operatör
|
|
3053
3088
|
* konumunda AYRI AYRI instantiate edilirdi — kolon başına altı mapped type.
|
|
3054
3089
|
* Böyle kolon başına BİR tane (N-2). */
|
|
3090
|
+
/**
|
|
3091
|
+
* `now()` HANGİ kolonlarda karşılaştırma değeri olabilir.
|
|
3092
|
+
*
|
|
3093
|
+
* `timestamp` TypeScript'e `string` olarak geliyor — `text` ile aynı tip. Yani
|
|
3094
|
+
* "yalnız zaman kolonları" tip düzeyinde İFADE EDİLEMEZ (D-021'in tam olarak
|
|
3095
|
+
* kaydettiği sınır: TS numeric/bigint/text/uuid/timestamp'ı `string`'e
|
|
3096
|
+
* çöktürüyor). İki seçenekten yanlış KABUL, yanlış RET'e tercih ediliyor:
|
|
3097
|
+
* `now()`'ı bir metin kolonunda yazmak Postgres hatası verir, ama zaman
|
|
3098
|
+
* kolonunda YASAKLAMAK yazarı bu yüzden `sqlFragment`e düşürürdü — ve bu
|
|
3099
|
+
* özelliğin var olma nedeni tam olarak o düşüşü kaldırmak.
|
|
3100
|
+
*/
|
|
3101
|
+
type NowComparable<V> = "?" extends PgTag<V> ? [NonNullable<V>] extends [string | Date] ? TxNow : never : PgTag<V> extends "timestamp" ? TxNow : never;
|
|
3055
3102
|
type WhereOpBody<V, C> = {
|
|
3056
|
-
gt?: V | C
|
|
3057
|
-
gte?: V | C
|
|
3058
|
-
lt?: V | C
|
|
3059
|
-
lte?: V | C
|
|
3060
|
-
neq?: V | C
|
|
3103
|
+
gt?: V | C | NowComparable<V>;
|
|
3104
|
+
gte?: V | C | NowComparable<V>;
|
|
3105
|
+
lt?: V | C | NowComparable<V>;
|
|
3106
|
+
lte?: V | C | NowComparable<V>;
|
|
3107
|
+
neq?: V | C | NowComparable<V>;
|
|
3061
3108
|
in?: V[];
|
|
3062
3109
|
/** `IS NULL` / `IS NOT NULL` (FR-006) — `= NULL` SQL'de her zaman UNKNOWN'dır. */
|
|
3063
3110
|
isNull?: boolean;
|
|
@@ -3072,7 +3119,7 @@ type WhereOp<V, Row = unknown> = WhereOpWith<V, ColRefOf<Row, V>>;
|
|
|
3072
3119
|
* `TextOps<V>` `V extends string` diye soruyor ve `string | Ref<string>` o
|
|
3073
3120
|
* soruya HAYIR der, yani `contains`/`startsWith` sessizce KAYBOLURDU.
|
|
3074
3121
|
*/
|
|
3075
|
-
type WhereOpWith<V, C> = V | C | WhereOpBody<V, C>;
|
|
3122
|
+
type WhereOpWith<V, C> = V | C | NowComparable<V> | WhereOpBody<V, C>;
|
|
3076
3123
|
/**
|
|
3077
3124
|
* A filter over a row: every field optional, each one a plain value (equality)
|
|
3078
3125
|
* or an operator object. THE filter language — `findMany`, `updateMany`,
|
|
@@ -3089,10 +3136,18 @@ type WhereFilter<Row> = {
|
|
|
3089
3136
|
* Kysely'nin TS7'de 9,8M instantiation üreten vakası derin generic
|
|
3090
3137
|
* özyinelemeydi. Burada derinlik yazarın filtresi kadardır ve pratikte
|
|
3091
3138
|
* bir-iki seviyedir; tip maliyeti T001'in tavanına karşı ölçülür.
|
|
3139
|
+
*
|
|
3140
|
+
* Dal bir `sqlFragment` DE olabilir. Motor bunu zaten derliyordu — parantezli
|
|
3141
|
+
* ve parametreli (`… AND (((expires_at > now())) AND (t."city" = $2))`) —
|
|
3142
|
+
* ama tip yalnız üst düzey `where`'de fragment'e izin veriyordu. Yani
|
|
3143
|
+
* "fragment sorgudan KAÇMAK için değil, sorgunun İÇİNE girmek için" sözü tam
|
|
3144
|
+
* da bileşim anında kırılıyordu: bir koşulu bir fragment'le birleştirmek
|
|
3145
|
+
* isteyen yazar SORGUNUN TAMAMINI ham SQL'e taşımak zorunda kalıyordu.
|
|
3146
|
+
* Ölçüldü: bir müşteri sorgusunda tam olarak bu oldu.
|
|
3092
3147
|
*/
|
|
3093
|
-
OR?: WhereFilter<Row>[];
|
|
3094
|
-
AND?: WhereFilter<Row>[];
|
|
3095
|
-
NOT?: WhereFilter<Row
|
|
3148
|
+
OR?: (WhereFilter<Row> | SqlFragment)[];
|
|
3149
|
+
AND?: (WhereFilter<Row> | SqlFragment)[];
|
|
3150
|
+
NOT?: WhereFilter<Row> | SqlFragment;
|
|
3096
3151
|
};
|
|
3097
3152
|
/**
|
|
3098
3153
|
* Ordering and paging for a read.
|
|
@@ -3237,7 +3292,25 @@ type MutateInput<Row, Insert, Rels = unknown> = {
|
|
|
3237
3292
|
* string de sayısal sayılır; ayrımı burada yapamayız, ama D-007 zaten miktarın
|
|
3238
3293
|
* JS `number`'a hiç uğramamasını istiyor.
|
|
3239
3294
|
*/
|
|
3240
|
-
|
|
3295
|
+
/** `increment()`/`decrement()` HANGİ kolonlarda anlamlı — bildirilmiş PG tipine
|
|
3296
|
+
* göre. Marka yoksa eski sezgisel (`number | string`), ki o `text` kolonda da
|
|
3297
|
+
* izin veriyordu: Postgres `text + 1` demez. */
|
|
3298
|
+
type NumericCol<V> = "?" extends PgTag<V> ? NonNullable<V> extends number | string ? TxColumnExpr : never : PgKind<PgTag<V>> extends "num" ? TxColumnExpr : never;
|
|
3299
|
+
/**
|
|
3300
|
+
* Bir EKLEME yolunda yazılabilecek değer.
|
|
3301
|
+
*
|
|
3302
|
+
* Kolonun kendi tipi ya da — zaman kolonlarında — sunucu saati. `increment()`
|
|
3303
|
+
* burada YOK ve olamaz: satır henüz yokken "kolonun şu anki değeri" diye bir
|
|
3304
|
+
* şey yok, motor da bunu adıyla reddediyor.
|
|
3305
|
+
*
|
|
3306
|
+
* Var olma nedeni ölçülmüş: introspect edilmiş şemalarda zaman kolonlarının
|
|
3307
|
+
* çoğu varsayılansız (`timestamp()`), yani "eklerken sunucu saatini yaz"ın tek
|
|
3308
|
+
* karşılığı istemci saatiydi — 33 tablolu bir projede 12 yerde.
|
|
3309
|
+
*/
|
|
3310
|
+
type InsertValues<Insert> = {
|
|
3311
|
+
[K in keyof Insert]: Insert[K] | NowComparable<Insert[K]>;
|
|
3312
|
+
};
|
|
3313
|
+
type SetValue<V> = V | NumericCol<V> | NowComparable<V>;
|
|
3241
3314
|
/** Bir update'in `set`'i: insert şeklinin herhangi bir alt kümesi, ifadelerle. */
|
|
3242
3315
|
type SetShape<Insert> = {
|
|
3243
3316
|
[K in keyof Insert]?: SetValue<Insert[K]>;
|
|
@@ -3320,7 +3393,30 @@ type RelsOf<T> = T extends {
|
|
|
3320
3393
|
} ? R : unknown;
|
|
3321
3394
|
/** Temel tablo erişimcisi — search'süz beş op. */
|
|
3322
3395
|
interface EnvTypedTableBase<T extends TableTypes> {
|
|
3323
|
-
insert(data: T["insert"]): Promise<T["row"]>;
|
|
3396
|
+
insert(data: InsertValues<T["insert"]>): Promise<T["row"]>;
|
|
3397
|
+
/**
|
|
3398
|
+
* Çok satırı TEK statement'la ekle (tek gidiş-dönüş).
|
|
3399
|
+
*
|
|
3400
|
+
* ```ts
|
|
3401
|
+
* await Database.public.journey_stops.insertMany(
|
|
3402
|
+
* stops.map((s, i) => ({ journey_id, name: s.name, sort_order: i })),
|
|
3403
|
+
* );
|
|
3404
|
+
* ```
|
|
3405
|
+
*
|
|
3406
|
+
* Satırların anahtar kümesi AYNI olmalı: tek statement kolon listesini
|
|
3407
|
+
* paylaşır, yani farklı şekilli bir satırın fazla kolonu sessizce yazılmaz
|
|
3408
|
+
* ve eksiği yanlış sütuna kayardı. Eksik alan için `null` yazın.
|
|
3409
|
+
*
|
|
3410
|
+
* Boş dizi boş sonuç döner — hata değil: "eklenecek bir şey yoktu".
|
|
3411
|
+
*/
|
|
3412
|
+
insertMany(rows: readonly InsertValues<T["insert"]>[], opts?: {
|
|
3413
|
+
/** Çakışmanın ARANDIĞI kolonlar — benzersiz bir kısıt ya da index taşımalı. */
|
|
3414
|
+
onConflict: readonly Extract<keyof T["row"], string>[];
|
|
3415
|
+
/** `"ignore"` (VARSAYILAN, plan yoluyla aynı) çakışanı atlar ve o satır
|
|
3416
|
+
* SONUÇTA DÖNMEZ — Postgres yalnız yazdıklarını döndürür; `"update"`
|
|
3417
|
+
* üzerine yazar. */
|
|
3418
|
+
action?: "ignore" | "update";
|
|
3419
|
+
}): Promise<T["row"][]>;
|
|
3324
3420
|
/**
|
|
3325
3421
|
* Bir idempotency anahtarını sahiplen (FR-033).
|
|
3326
3422
|
*
|
|
@@ -3336,7 +3432,7 @@ interface EnvTypedTableBase<T extends TableTypes> {
|
|
|
3336
3432
|
* İlk argüman satırı BULAN alanlar, ikincisi yalnız yazılanlar — ikinci çağrı
|
|
3337
3433
|
* farklı bir yük gönderse bile satır anahtarla bulunur.
|
|
3338
3434
|
*/
|
|
3339
|
-
claim(unique: Partial<T["insert"]>, extra?: Partial<T["insert"]
|
|
3435
|
+
claim(unique: Partial<T["insert"]>, extra?: Partial<InsertValues<T["insert"]>>): Promise<{
|
|
3340
3436
|
inserted: boolean;
|
|
3341
3437
|
row: T["row"];
|
|
3342
3438
|
}>;
|
|
@@ -3361,7 +3457,7 @@ interface EnvTypedTableBase<T extends TableTypes> {
|
|
|
3361
3457
|
* seçmeyi kolay yapıyordu.
|
|
3362
3458
|
*/
|
|
3363
3459
|
put(q: {
|
|
3364
|
-
data: T["insert"]
|
|
3460
|
+
data: InsertValues<T["insert"]>;
|
|
3365
3461
|
onConflict: readonly Extract<keyof T["row"], string>[];
|
|
3366
3462
|
}): Promise<T["row"]>;
|
|
3367
3463
|
/** Update the row by id; resolves to the updated row, or `null` if no row
|
|
@@ -3371,7 +3467,7 @@ interface EnvTypedTableBase<T extends TableTypes> {
|
|
|
3371
3467
|
where: {
|
|
3372
3468
|
id: string;
|
|
3373
3469
|
};
|
|
3374
|
-
set:
|
|
3470
|
+
set: SetShape<T["insert"]>;
|
|
3375
3471
|
}): Promise<T["row"] | null>;
|
|
3376
3472
|
delete(id: string): Promise<void>;
|
|
3377
3473
|
findById(id: string): Promise<T["row"] | null>;
|
|
@@ -3406,7 +3502,7 @@ interface EnvTypedTableBase<T extends TableTypes> {
|
|
|
3406
3502
|
* kapanır (valid_to/superseded_by), yenisi TEK savepoint'te eklenir; dönüş
|
|
3407
3503
|
* yeni satır. Validity beyanı olmayan tabloda adlandırılmış çalışma-zamanı
|
|
3408
3504
|
* hatası — tip düzeyinde ayrım env `Tables` bayrağı taşımadığından yapılamaz. */
|
|
3409
|
-
supersede(id: string, row: T["insert"]): Promise<T["row"]>;
|
|
3505
|
+
supersede(id: string, row: InsertValues<T["insert"]>): Promise<T["row"]>;
|
|
3410
3506
|
}
|
|
3411
3507
|
/** Tablo erişimcisi: env girdisi `searchable: true` taşıyorsa (vector kolonu ya da
|
|
3412
3508
|
* search beyanı — env-gen üretir) `search()` üyesi VARDIR; yoksa üye hiç yoktur ve
|
|
@@ -3960,9 +4056,9 @@ type TxWhereField<Row, K extends keyof Row> = WhereOpWith<Row[K], ColRefOf<Row,
|
|
|
3960
4056
|
type TxWhere<Row, Rels = unknown> = {
|
|
3961
4057
|
[K in keyof Row]?: TxWhereField<Row, K>;
|
|
3962
4058
|
} & {
|
|
3963
|
-
OR?: TxWhere<Row, Rels>[];
|
|
3964
|
-
AND?: TxWhere<Row, Rels>[];
|
|
3965
|
-
NOT?: TxWhere<Row, Rels
|
|
4059
|
+
OR?: (TxWhere<Row, Rels> | SqlFragment)[];
|
|
4060
|
+
AND?: (TxWhere<Row, Rels> | SqlFragment)[];
|
|
4061
|
+
NOT?: TxWhere<Row, Rels> | SqlFragment;
|
|
3966
4062
|
} & HasOnly<Rels>;
|
|
3967
4063
|
/** Options for a plan `select`. */
|
|
3968
4064
|
interface TxSelectOptions {
|
|
@@ -4342,6 +4438,13 @@ interface DBOps {
|
|
|
4342
4438
|
*/
|
|
4343
4439
|
query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
4344
4440
|
insert(table: string, data: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
4441
|
+
/** Çok satır, TEK statement. Satırların anahtar kümesi aynı olmalı — kolon
|
|
4442
|
+
* listesi paylaşıldığı için farklı şekilli bir satırın kolonu sessizce
|
|
4443
|
+
* yazılmazdı. */
|
|
4444
|
+
insertMany(table: string, rows: readonly Record<string, unknown>[], opts?: {
|
|
4445
|
+
onConflict: readonly string[];
|
|
4446
|
+
action?: "ignore" | "update";
|
|
4447
|
+
}): Promise<Record<string, unknown>[]>;
|
|
4345
4448
|
/**
|
|
4346
4449
|
* Insert the row, or update it when it collides on `onConflict` — one
|
|
4347
4450
|
* statement, so two concurrent callers cannot both lose.
|
package/dist/index.cjs
CHANGED
|
@@ -27,8 +27,10 @@ __export(src_exports, {
|
|
|
27
27
|
Client: () => Client,
|
|
28
28
|
Conflict: () => Conflict,
|
|
29
29
|
Controller: () => Controller,
|
|
30
|
+
DECLARATION_REFUSAL: () => DECLARATION_REFUSAL,
|
|
30
31
|
Database: () => Database,
|
|
31
32
|
DeadlockDetected: () => DeadlockDetected,
|
|
33
|
+
DeclarationRefused: () => DeclarationRefused,
|
|
32
34
|
Delete: () => Delete,
|
|
33
35
|
Deny: () => Deny,
|
|
34
36
|
DiError: () => DiError,
|
|
@@ -130,6 +132,7 @@ __export(src_exports, {
|
|
|
130
132
|
index: () => index,
|
|
131
133
|
installationRef: () => installationRef,
|
|
132
134
|
integer: () => integer,
|
|
135
|
+
isDeclarationRefused: () => isDeclarationRefused,
|
|
133
136
|
isPalbaseExtension: () => isPalbaseExtension,
|
|
134
137
|
isRetryable: () => isRetryable,
|
|
135
138
|
jobsOf: () => jobsOf,
|
|
@@ -192,6 +195,27 @@ function isSqlFragment(v) {
|
|
|
192
195
|
return f !== void 0 && Array.isArray(f.text) && Array.isArray(f.values);
|
|
193
196
|
}
|
|
194
197
|
__name(isSqlFragment, "isSqlFragment");
|
|
198
|
+
var TX_EXPR = /* @__PURE__ */ Symbol.for("palbase.tx.expr");
|
|
199
|
+
function isNowExpr(v) {
|
|
200
|
+
if (!isColumnExpr(v)) return false;
|
|
201
|
+
try {
|
|
202
|
+
const e = v[TX_EXPR];
|
|
203
|
+
return typeof e === "object" && e !== null && e.fn === "now";
|
|
204
|
+
} catch {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
__name(isNowExpr, "isNowExpr");
|
|
209
|
+
function isColumnExpr(v) {
|
|
210
|
+
if (typeof v !== "object" && typeof v !== "function") return false;
|
|
211
|
+
if (v === null) return false;
|
|
212
|
+
try {
|
|
213
|
+
return v[TX_EXPR] !== void 0;
|
|
214
|
+
} catch {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
__name(isColumnExpr, "isColumnExpr");
|
|
195
219
|
|
|
196
220
|
// src/db/tx-plan.ts
|
|
197
221
|
var TxRefError = class extends Error {
|
|
@@ -349,6 +373,11 @@ function encodeValue(value, column, allowColumnExpr) {
|
|
|
349
373
|
field: ref.field
|
|
350
374
|
}
|
|
351
375
|
}, "ref");
|
|
376
|
+
if (isNowExpr(value)) return {
|
|
377
|
+
$expr: {
|
|
378
|
+
fn: "now"
|
|
379
|
+
}
|
|
380
|
+
};
|
|
352
381
|
const expr = exprOf(value);
|
|
353
382
|
if (expr) {
|
|
354
383
|
if (expr.fn !== "now" && !allowColumnExpr) {
|
|
@@ -426,7 +455,9 @@ function encodeMap(map, allowColumnExpr) {
|
|
|
426
455
|
const out = {};
|
|
427
456
|
for (const key of Object.keys(map).sort()) {
|
|
428
457
|
const value = map[key];
|
|
429
|
-
if (value === void 0)
|
|
458
|
+
if (value === void 0) {
|
|
459
|
+
throw new TxPlanError(`${key} de\u011Feri undefined \u2014 bu bir yazma de\u011Feri de\u011Fil. Anahtar duruyor ama de\u011Feri yok, yani kolon sessizce YAZILMAZDI (istek g\xF6vdesinden gelen bir alan\u0131n eksik olmas\u0131 bu \u015Fekilde g\xF6r\xFCn\xFCr). Kolon varsay\u0131lan\u0131n\u0131 istiyorsan\u0131z anahtar\u0131 hi\xE7 koymay\u0131n; NULL yazmak istiyorsan\u0131z a\xE7\u0131k\xE7a null yaz\u0131n.`);
|
|
460
|
+
}
|
|
430
461
|
out[key] = encodeValue(value, key, allowColumnExpr);
|
|
431
462
|
}
|
|
432
463
|
return out;
|
|
@@ -887,6 +918,7 @@ var TooManyRequests = class extends NamedHttpError {
|
|
|
887
918
|
function makeTypedTable(name, raw2) {
|
|
888
919
|
return {
|
|
889
920
|
insert: /* @__PURE__ */ __name((data) => raw2.insert(name, data), "insert"),
|
|
921
|
+
insertMany: /* @__PURE__ */ __name((rows, opts) => raw2.insertMany(name, rows, opts), "insertMany"),
|
|
890
922
|
put: /* @__PURE__ */ __name((q) => raw2.put(name, q.data, {
|
|
891
923
|
onConflict: q.onConflict
|
|
892
924
|
}), "put"),
|
|
@@ -1338,6 +1370,10 @@ function makeTableProxy(ops, prefix) {
|
|
|
1338
1370
|
const name = `${prefix}${prop}`;
|
|
1339
1371
|
return {
|
|
1340
1372
|
insert: /* @__PURE__ */ __name((data) => ops().insert(name, data), "insert"),
|
|
1373
|
+
// DÖRDÜNCÜ FİİL, aynı gerekçeyle: tip söz veriyor, ops katmanı
|
|
1374
|
+
// uyguluyor, ve bir handler'ın gerçekten dokunduğu yer BURASI.
|
|
1375
|
+
// `runtime-table-verbs` kapısı bunu adıyla saydı.
|
|
1376
|
+
insertMany: /* @__PURE__ */ __name((rows, opts) => ops().insertMany(name, rows, opts), "insertMany"),
|
|
1341
1377
|
update: /* @__PURE__ */ __name((q) => ops().update(name, q.where.id, q.set), "update"),
|
|
1342
1378
|
delete: /* @__PURE__ */ __name((id) => ops().delete(name, id), "delete"),
|
|
1343
1379
|
findById: /* @__PURE__ */ __name((id) => ops().findById(name, id), "findById"),
|
|
@@ -1394,6 +1430,7 @@ function makeTypedSurface(raw2) {
|
|
|
1394
1430
|
$claim: /* @__PURE__ */ __name((table, unique, extra) => reco.claim(table, unique, extra), "$claim"),
|
|
1395
1431
|
$lockRows: /* @__PURE__ */ __name((table, ids) => reco.lockRows(table, ids), "$lockRows"),
|
|
1396
1432
|
$advisoryXactLock: /* @__PURE__ */ __name((key) => reco.advisoryXactLock(key), "$advisoryXactLock"),
|
|
1433
|
+
$insertMany: /* @__PURE__ */ __name((table, rows, opts) => raw2.insertMany(table, rows, opts), "$insertMany"),
|
|
1397
1434
|
$supersede: /* @__PURE__ */ __name((table, id, row) => raw2.supersede(table, id, row), "$supersede")
|
|
1398
1435
|
};
|
|
1399
1436
|
const base = Object.assign(ops, {
|
|
@@ -3532,6 +3569,24 @@ var openai = {
|
|
|
3532
3569
|
}
|
|
3533
3570
|
};
|
|
3534
3571
|
|
|
3572
|
+
// src/refusals.ts
|
|
3573
|
+
var DECLARATION_REFUSAL = /* @__PURE__ */ Symbol.for("palbase.backend.declarationRefusal");
|
|
3574
|
+
var DeclarationRefused = class extends Error {
|
|
3575
|
+
static {
|
|
3576
|
+
__name(this, "DeclarationRefused");
|
|
3577
|
+
}
|
|
3578
|
+
/** @see DECLARATION_REFUSAL — realm-safe, unlike `instanceof`. */
|
|
3579
|
+
[DECLARATION_REFUSAL] = true;
|
|
3580
|
+
constructor(message) {
|
|
3581
|
+
super(message);
|
|
3582
|
+
this.name = "DeclarationRefused";
|
|
3583
|
+
}
|
|
3584
|
+
};
|
|
3585
|
+
function isDeclarationRefused(e) {
|
|
3586
|
+
return typeof e === "object" && e !== null && e[DECLARATION_REFUSAL] === true;
|
|
3587
|
+
}
|
|
3588
|
+
__name(isDeclarationRefused, "isDeclarationRefused");
|
|
3589
|
+
|
|
3535
3590
|
// src/db/env-gen.ts
|
|
3536
3591
|
function baseTsType(def) {
|
|
3537
3592
|
switch (def.type) {
|
|
@@ -3568,9 +3623,21 @@ function baseTsType(def) {
|
|
|
3568
3623
|
}
|
|
3569
3624
|
}
|
|
3570
3625
|
__name(baseTsType, "baseTsType");
|
|
3626
|
+
function pgBrand(def) {
|
|
3627
|
+
if (def.type === "enum") {
|
|
3628
|
+
const values = [
|
|
3629
|
+
...def.enumValues ?? []
|
|
3630
|
+
].sort();
|
|
3631
|
+
return values.length === 0 ? "enum" : `enum:${values.join("|")}`;
|
|
3632
|
+
}
|
|
3633
|
+
return def.type;
|
|
3634
|
+
}
|
|
3635
|
+
__name(pgBrand, "pgBrand");
|
|
3571
3636
|
function rowType(def) {
|
|
3572
3637
|
const base = baseTsType(def);
|
|
3573
|
-
return def.nullable ? `${base} | null` : base;
|
|
3638
|
+
if (base === "unknown") return def.nullable ? `${base} | null` : base;
|
|
3639
|
+
const branded = `Pg<${base}, ${JSON.stringify(pgBrand(def))}>`;
|
|
3640
|
+
return def.nullable ? `${branded} | null` : branded;
|
|
3574
3641
|
}
|
|
3575
3642
|
__name(rowType, "rowType");
|
|
3576
3643
|
function optionalOnInsert(def) {
|
|
@@ -3613,12 +3680,12 @@ function buildRelations(schemas) {
|
|
|
3613
3680
|
const held = names.get(name);
|
|
3614
3681
|
if (held !== void 0) {
|
|
3615
3682
|
if (held.def.owns === true && origin.def.owns === true) {
|
|
3616
|
-
throw new
|
|
3683
|
+
throw new DeclarationRefused(`table "${tableKey}" declares TWO owner columns (${held.column}, ${origin.column}) \u2014 a table has at most ONE ownedByUser(). If the other column only POINTS at a user, declare it userRef({ onDelete: \u2026 }) instead.`);
|
|
3617
3684
|
}
|
|
3618
3685
|
const heldFix = renameCall(held);
|
|
3619
3686
|
const originFix = renameCall(origin);
|
|
3620
3687
|
const remedy = heldFix === originFix ? `rename one of them: ${heldFix}` : `rename one of them \u2014 "${held.table}.${held.column}": ${heldFix}; "${origin.table}.${origin.column}": ${originFix}`;
|
|
3621
|
-
throw new
|
|
3688
|
+
throw new DeclarationRefused(`table "${tableKey}": ${describeOrigin(held)} and ${describeOrigin(origin)} both resolve to the relation name "${name}" \u2014 ${remedy}.`);
|
|
3622
3689
|
}
|
|
3623
3690
|
names.set(name, origin);
|
|
3624
3691
|
out.get(tableKey)?.push(edge);
|
|
@@ -3721,6 +3788,17 @@ ${schemaBlocks.join("\n")}
|
|
|
3721
3788
|
// is typed with no import and no generic. Schemas other than \`public\` land
|
|
3722
3789
|
// under \`Schemas\`, reached with \`Database.schema("<name>").tables.*\`.
|
|
3723
3790
|
|
|
3791
|
+
/**
|
|
3792
|
+
* Kolonun POSTGRES tipini tipte tasiyan marka.
|
|
3793
|
+
*
|
|
3794
|
+
* __pg ISTEGE BAGLI oldugu icin satir hala duz string/number gibi okunur ve duz
|
|
3795
|
+
* bir degerle yazilir \u2014 marka yalniz col() ve now() karsilastirma kurallarinin
|
|
3796
|
+
* gordugu bir bilgidir. TypeScript numeric, bigint, text, uuid ve timestamp'i
|
|
3797
|
+
* tek string'e dusurdugu icin bu bilgi olmadan integer<->numeric (gecerli) ile
|
|
3798
|
+
* integer<->text (gecersiz) ayirt edilemiyordu.
|
|
3799
|
+
*/
|
|
3800
|
+
type Pg<T, N extends string> = T & { readonly __pg?: N };
|
|
3801
|
+
|
|
3724
3802
|
declare module "@palbase/backend/env" {
|
|
3725
3803
|
interface Tables {${body}}
|
|
3726
3804
|
interface Schemas {${schemasBody}}
|
|
@@ -4685,6 +4763,14 @@ var DiError = class extends Error {
|
|
|
4685
4763
|
path;
|
|
4686
4764
|
at;
|
|
4687
4765
|
fixes;
|
|
4766
|
+
/**
|
|
4767
|
+
* EVERY `DiKind` IS A FACT ABOUT THE AUTHOR'S DECLARATIONS — an unresolvable
|
|
4768
|
+
* dependency, a cycle, a class no module owns. Not one of them is something
|
|
4769
|
+
* the environment could change, so restarting re-reads the same bytes and
|
|
4770
|
+
* fails identically. The cure is a new artifact, and the tag is how the
|
|
4771
|
+
* runtime learns that without matching on wording.
|
|
4772
|
+
*/
|
|
4773
|
+
[DECLARATION_REFUSAL] = true;
|
|
4688
4774
|
constructor(kind, path, at, detail, fixes) {
|
|
4689
4775
|
super(`
|
|
4690
4776
|
Kind: ${kind}
|
|
@@ -5188,8 +5274,10 @@ var import_zod2 = require("zod");
|
|
|
5188
5274
|
Client,
|
|
5189
5275
|
Conflict,
|
|
5190
5276
|
Controller,
|
|
5277
|
+
DECLARATION_REFUSAL,
|
|
5191
5278
|
Database,
|
|
5192
5279
|
DeadlockDetected,
|
|
5280
|
+
DeclarationRefused,
|
|
5193
5281
|
Delete,
|
|
5194
5282
|
Deny,
|
|
5195
5283
|
DiError,
|
|
@@ -5291,6 +5379,7 @@ var import_zod2 = require("zod");
|
|
|
5291
5379
|
index,
|
|
5292
5380
|
installationRef,
|
|
5293
5381
|
integer,
|
|
5382
|
+
isDeclarationRefused,
|
|
5294
5383
|
isPalbaseExtension,
|
|
5295
5384
|
isRetryable,
|
|
5296
5385
|
jobsOf,
|