@palbase/backend 33.0.1 → 34.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 +2020 -350
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +9 -7
- package/dist/bin/palbase-backend.js.map +1 -1
- package/dist/{chunk-SI4KGEM3.js → chunk-FOWA7PF4.js} +97 -96
- package/dist/chunk-FOWA7PF4.js.map +1 -0
- package/dist/chunk-GHNC2UHS.js +20 -0
- package/dist/chunk-GHNC2UHS.js.map +1 -0
- package/dist/{chunk-BRLJOXWS.js → chunk-JJW3L62T.js} +3 -3
- package/dist/chunk-JJW3L62T.js.map +1 -0
- package/dist/{chunk-TVCCR6SO.js → chunk-LOGL2ZHD.js} +58 -9
- package/dist/chunk-LOGL2ZHD.js.map +1 -0
- package/dist/{chunk-IKDONZ5D.js → chunk-MNGZE2MM.js} +1651 -186
- package/dist/chunk-MNGZE2MM.js.map +1 -0
- package/dist/{chunk-XOX6RFPZ.js → chunk-PRH45NZU.js} +46 -3
- package/dist/chunk-PRH45NZU.js.map +1 -0
- package/dist/{chunk-26GH54D2.js → chunk-RZLY4BOY.js} +5 -3
- package/dist/{chunk-26GH54D2.js.map → chunk-RZLY4BOY.js.map} +1 -1
- package/dist/{chunk-YIQ4RS4F.js → chunk-SEM36BWY.js} +283 -5
- package/dist/chunk-SEM36BWY.js.map +1 -0
- package/dist/{chunk-KATPXCJ5.js → chunk-UMESJJRS.js} +19 -40
- package/dist/chunk-UMESJJRS.js.map +1 -0
- package/dist/chunk-VXPNPVAG.js +40 -0
- package/dist/chunk-VXPNPVAG.js.map +1 -0
- package/dist/{chunk-WWUG2QXF.js → chunk-YX7UA7VC.js} +53 -4
- package/dist/chunk-YX7UA7VC.js.map +1 -0
- package/dist/db/env.cjs.map +1 -1
- package/dist/db/env.d.cts +2 -0
- package/dist/db/env.d.ts +2 -0
- package/dist/db/index.cjs +261 -2
- package/dist/db/index.cjs.map +1 -1
- package/dist/db/index.d.cts +46 -3
- package/dist/db/index.d.ts +46 -3
- package/dist/db/index.js +14 -5
- package/dist/{index-DMZG3kpo.d.ts → endpoint-DpNUx-ON.d.ts} +315 -57
- package/dist/{index-DB_nW-AV.d.cts → endpoint-kYgEHrrV.d.cts} +315 -57
- package/dist/engine/index.cjs +2026 -348
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +5 -5
- package/dist/engine/index.d.ts +5 -5
- package/dist/engine/index.js +17 -7
- package/dist/{index-D-3duy8Y.d.ts → index-JrHqNsjQ.d.ts} +108 -50
- package/dist/{index-DLveQoOf.d.cts → index-pnDsEfxJ.d.cts} +108 -50
- package/dist/index.cjs +616 -254
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +25 -15
- package/dist/index.js.map +1 -1
- package/dist/openapi/index.cjs +8 -1
- package/dist/openapi/index.cjs.map +1 -1
- package/dist/openapi/index.d.cts +3 -3
- package/dist/openapi/index.d.ts +3 -3
- package/dist/openapi/index.js +4 -3
- package/dist/openapi/index.js.map +1 -1
- package/dist/{registry-DSTThhKf.d.cts → registry-BcOd8Zhf.d.cts} +3 -1
- package/dist/{registry-JjF5lcj4.d.ts → registry-BoX5iNyY.d.ts} +3 -1
- package/dist/test/index.cjs +103 -66
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +3 -3
- package/dist/test/index.d.ts +3 -3
- package/dist/test/index.js +33 -7
- package/dist/test/index.js.map +1 -1
- package/docs/README.md +1 -1
- package/docs/database.md +308 -0
- package/docs/examples/check-query-contracts.ts +5 -0
- package/docs/examples/database-dx.contract.json +65 -0
- package/docs/examples/database-dx.ts +63 -0
- package/docs/examples/money-transfer.ts +73 -0
- package/docs/llms-full.txt +309 -1
- package/package.json +1 -2
- package/template/AGENTS.md +7 -7
- package/template/modules/health/health.controller.ts +7 -4
- package/template/modules/notes/dto/create.ts +4 -3
- package/template/modules/notes/notes.controller.ts +8 -6
- package/template/package.json +1 -1
- package/dist/chunk-BRLJOXWS.js.map +0 -1
- package/dist/chunk-IKDONZ5D.js.map +0 -1
- package/dist/chunk-KATPXCJ5.js.map +0 -1
- package/dist/chunk-SI4KGEM3.js.map +0 -1
- package/dist/chunk-TVCCR6SO.js.map +0 -1
- package/dist/chunk-WWUG2QXF.js.map +0 -1
- package/dist/chunk-XOX6RFPZ.js.map +0 -1
- package/dist/chunk-YIQ4RS4F.js.map +0 -1
- package/stack-images.json +0 -24
package/dist/index.cjs
CHANGED
|
@@ -102,6 +102,7 @@ __export(src_exports, {
|
|
|
102
102
|
__runWithRuntime: () => __runWithRuntime,
|
|
103
103
|
__setRuntime: () => __setRuntime,
|
|
104
104
|
assertNoOrphanEntryPoints: () => assertNoOrphanEntryPoints,
|
|
105
|
+
assertQueryManifest: () => assertQueryManifest,
|
|
105
106
|
assertZeroArgConstructor: () => assertZeroArgConstructor,
|
|
106
107
|
bigint: () => bigint,
|
|
107
108
|
boolean: () => boolean,
|
|
@@ -115,8 +116,10 @@ __export(src_exports, {
|
|
|
115
116
|
defineDefaultAuth: () => defineDefaultAuth,
|
|
116
117
|
defineError: () => defineError,
|
|
117
118
|
defineMiddleware: () => defineMiddleware,
|
|
119
|
+
defineQuery: () => defineQuery,
|
|
118
120
|
defineSchema: () => defineSchema,
|
|
119
121
|
defineTable: () => defineTable,
|
|
122
|
+
defineWorkload: () => defineWorkload,
|
|
120
123
|
enumType: () => enumType,
|
|
121
124
|
exprCtx: () => exprCtx,
|
|
122
125
|
getErrorRegistry: () => getErrorRegistry,
|
|
@@ -152,6 +155,7 @@ __export(src_exports, {
|
|
|
152
155
|
ownerOnly: () => ownerOnly,
|
|
153
156
|
policy: () => policy,
|
|
154
157
|
publicChannel: () => publicChannel,
|
|
158
|
+
queryManifest: () => queryManifest,
|
|
155
159
|
raw: () => raw,
|
|
156
160
|
recordThrows: () => recordThrows,
|
|
157
161
|
resolveEffectiveAuth: () => resolveEffectiveAuth,
|
|
@@ -165,7 +169,7 @@ __export(src_exports, {
|
|
|
165
169
|
vector: () => vector,
|
|
166
170
|
webhooksOf: () => webhooksOf,
|
|
167
171
|
withRetry: () => withRetry,
|
|
168
|
-
z: () =>
|
|
172
|
+
z: () => import_zod3.z
|
|
169
173
|
});
|
|
170
174
|
module.exports = __toCommonJS(src_exports);
|
|
171
175
|
|
|
@@ -741,260 +745,54 @@ function translateRejection(err, builder) {
|
|
|
741
745
|
}
|
|
742
746
|
__name(translateRejection, "translateRejection");
|
|
743
747
|
|
|
744
|
-
// src/
|
|
745
|
-
|
|
746
|
-
var HttpError = class extends Error {
|
|
747
|
-
static {
|
|
748
|
-
__name(this, "HttpError");
|
|
749
|
-
}
|
|
750
|
-
status;
|
|
751
|
-
error;
|
|
752
|
-
errorDescription;
|
|
753
|
-
data;
|
|
754
|
-
/** See {@link HTTP_ERROR_BRAND} — how the engine recognises this across SDK copies. */
|
|
755
|
-
[HTTP_ERROR_BRAND] = true;
|
|
756
|
-
constructor(status, error, errorDescription, data) {
|
|
757
|
-
super(errorDescription);
|
|
758
|
-
this.name = "HttpError";
|
|
759
|
-
this.status = status;
|
|
760
|
-
this.error = error;
|
|
761
|
-
this.errorDescription = errorDescription;
|
|
762
|
-
if (data !== void 0) {
|
|
763
|
-
this.data = data;
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
/**
|
|
767
|
-
* Serialize to the standard Palbase error response format.
|
|
768
|
-
* The `requestId` is injected by the runtime layer from the request context.
|
|
769
|
-
* When called without arguments (e.g. JSON.stringify), request_id is omitted.
|
|
770
|
-
* When `data` is set, it is appended as a strict-superset field.
|
|
771
|
-
*/
|
|
772
|
-
toJSON(requestId) {
|
|
773
|
-
const result = {
|
|
774
|
-
error: this.error,
|
|
775
|
-
error_description: this.errorDescription,
|
|
776
|
-
status: this.status
|
|
777
|
-
};
|
|
778
|
-
if (requestId) {
|
|
779
|
-
result.request_id = requestId;
|
|
780
|
-
}
|
|
781
|
-
if (this.data !== void 0) {
|
|
782
|
-
result.data = this.data;
|
|
783
|
-
}
|
|
784
|
-
return result;
|
|
785
|
-
}
|
|
786
|
-
};
|
|
787
|
-
var PalError = class extends HttpError {
|
|
788
|
-
static {
|
|
789
|
-
__name(this, "PalError");
|
|
790
|
-
}
|
|
791
|
-
constructor(status, code, description, data) {
|
|
792
|
-
super(status, code, description, data);
|
|
793
|
-
this.name = "PalError";
|
|
794
|
-
}
|
|
795
|
-
};
|
|
796
|
-
var NamedHttpError = class NamedHttpError2 extends HttpError {
|
|
797
|
-
static {
|
|
798
|
-
__name(this, "NamedHttpError");
|
|
799
|
-
}
|
|
800
|
-
constructor(status, defaultCode, name, message, code, data) {
|
|
801
|
-
super(status, code ?? defaultCode, message ?? defaultMessage(name), data);
|
|
802
|
-
this.name = name;
|
|
803
|
-
}
|
|
804
|
-
};
|
|
805
|
-
function defaultMessage(name) {
|
|
806
|
-
const spaced = name.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
|
|
807
|
-
return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
|
|
808
|
-
}
|
|
809
|
-
__name(defaultMessage, "defaultMessage");
|
|
810
|
-
var BadRequest = class extends NamedHttpError {
|
|
811
|
-
static {
|
|
812
|
-
__name(this, "BadRequest");
|
|
813
|
-
}
|
|
814
|
-
constructor(data, message) {
|
|
815
|
-
super(400, "bad_request", "BadRequest", message, void 0, data);
|
|
816
|
-
}
|
|
817
|
-
};
|
|
818
|
-
var Unauthorized = class extends NamedHttpError {
|
|
819
|
-
static {
|
|
820
|
-
__name(this, "Unauthorized");
|
|
821
|
-
}
|
|
822
|
-
constructor(message, code, data) {
|
|
823
|
-
super(401, "unauthorized", "Unauthorized", message, code, data);
|
|
824
|
-
}
|
|
825
|
-
};
|
|
826
|
-
var Forbidden = class extends NamedHttpError {
|
|
827
|
-
static {
|
|
828
|
-
__name(this, "Forbidden");
|
|
829
|
-
}
|
|
830
|
-
constructor(message, code, data) {
|
|
831
|
-
super(403, "forbidden", "Forbidden", message, code, data);
|
|
832
|
-
}
|
|
833
|
-
};
|
|
834
|
-
var NotFound = class extends NamedHttpError {
|
|
835
|
-
static {
|
|
836
|
-
__name(this, "NotFound");
|
|
837
|
-
}
|
|
838
|
-
constructor(message, code, data) {
|
|
839
|
-
super(404, "not_found", "NotFound", message, code, data);
|
|
840
|
-
}
|
|
841
|
-
};
|
|
842
|
-
var Conflict = class extends NamedHttpError {
|
|
843
|
-
static {
|
|
844
|
-
__name(this, "Conflict");
|
|
845
|
-
}
|
|
846
|
-
constructor(message, code, data) {
|
|
847
|
-
super(409, "conflict", "Conflict", message, code, data);
|
|
848
|
-
}
|
|
849
|
-
};
|
|
850
|
-
var UniqueViolation = class extends Conflict {
|
|
851
|
-
static {
|
|
852
|
-
__name(this, "UniqueViolation");
|
|
853
|
-
}
|
|
854
|
-
/**
|
|
855
|
-
* Whether `e` is a unique violation — REGARDLESS of which copy of this SDK
|
|
856
|
-
* constructed it.
|
|
857
|
-
*
|
|
858
|
-
* Use this instead of `instanceof`. Measured on a live stack: a controller
|
|
859
|
-
* bundle INLINES its own copy of `@palbase/backend`, and the engine that
|
|
860
|
-
* raises this error is the runtime's copy. Two copies, two class identities,
|
|
861
|
-
* and `e instanceof UniqueViolation` is false in the one place a caller
|
|
862
|
-
* writes it — a check that reads as correct and silently never matches.
|
|
863
|
-
*/
|
|
864
|
-
static is(e) {
|
|
865
|
-
return typeof e === "object" && e !== null && e.name === "UniqueViolation" && typeof e.constraint === "string";
|
|
866
|
-
}
|
|
867
|
-
/** The unique constraint the statement violated, as Postgres named it.
|
|
868
|
-
* `""` when the driver did not say which — see `engine/db.ts`. */
|
|
869
|
-
constraint;
|
|
870
|
-
constructor(constraint, message, code, data) {
|
|
871
|
-
super(message ?? "Unique constraint violated", code ?? "unique_violation", data);
|
|
872
|
-
this.name = "UniqueViolation";
|
|
873
|
-
this.constraint = constraint;
|
|
874
|
-
}
|
|
875
|
-
};
|
|
876
|
-
function isRetryable(e) {
|
|
877
|
-
return typeof e === "object" && e !== null && e.retryable === true && typeof e.sqlstate === "string";
|
|
878
|
-
}
|
|
879
|
-
__name(isRetryable, "isRetryable");
|
|
880
|
-
var SerializationFailure = class extends Conflict {
|
|
881
|
-
static {
|
|
882
|
-
__name(this, "SerializationFailure");
|
|
883
|
-
}
|
|
884
|
-
retryable = true;
|
|
885
|
-
sqlstate;
|
|
886
|
-
static is(e) {
|
|
887
|
-
return typeof e === "object" && e !== null && e.name === "SerializationFailure";
|
|
888
|
-
}
|
|
889
|
-
constructor(sqlstate = "40001", message, data) {
|
|
890
|
-
super(message ?? "i\u015Flem e\u015Fzamanl\u0131 bir i\u015Flemle serile\u015Ftirilemedi \u2014 ayn\u0131 i\u015Flemi ba\u015Ftan \xE7al\u0131\u015Ft\u0131r\u0131n ($transaction'a { retry: n } verebilirsiniz)", "serialization_failure", data);
|
|
891
|
-
this.name = "SerializationFailure";
|
|
892
|
-
this.sqlstate = sqlstate;
|
|
893
|
-
}
|
|
894
|
-
};
|
|
895
|
-
var DeadlockDetected = class extends Conflict {
|
|
896
|
-
static {
|
|
897
|
-
__name(this, "DeadlockDetected");
|
|
898
|
-
}
|
|
899
|
-
retryable = true;
|
|
900
|
-
sqlstate;
|
|
901
|
-
static is(e) {
|
|
902
|
-
return typeof e === "object" && e !== null && e.name === "DeadlockDetected";
|
|
903
|
-
}
|
|
904
|
-
constructor(sqlstate = "40P01", message, data) {
|
|
905
|
-
super(message ?? "deadlock: iki i\u015Flem birbirinin kilidini bekledi ve bu i\u015Flem iptal edildi \u2014 kilit s\u0131ras\u0131n\u0131 sabitlemek i\xE7in Database.$lockRows(tablo, id'ler) kullan\u0131n", "deadlock_detected", data);
|
|
906
|
-
this.name = "DeadlockDetected";
|
|
907
|
-
this.sqlstate = sqlstate;
|
|
908
|
-
}
|
|
909
|
-
};
|
|
910
|
-
var TooManyRequests = class extends NamedHttpError {
|
|
911
|
-
static {
|
|
912
|
-
__name(this, "TooManyRequests");
|
|
913
|
-
}
|
|
914
|
-
constructor(data, message) {
|
|
915
|
-
super(429, "too_many_requests", "TooManyRequests", message, void 0, data);
|
|
916
|
-
}
|
|
917
|
-
};
|
|
918
|
-
|
|
919
|
-
// src/db/typed-db.ts
|
|
920
|
-
function makeTypedTable(name, raw2) {
|
|
921
|
-
return {
|
|
922
|
-
insert: /* @__PURE__ */ __name((data) => raw2.insert(name, data), "insert"),
|
|
923
|
-
aggregate: /* @__PURE__ */ __name((q) => raw2.aggregate(name, q), "aggregate"),
|
|
924
|
-
insertMany: /* @__PURE__ */ __name((rows, opts) => raw2.insertMany(name, rows, opts), "insertMany"),
|
|
925
|
-
put: /* @__PURE__ */ __name((q) => raw2.put(name, q.data, {
|
|
926
|
-
onConflict: q.onConflict
|
|
927
|
-
}), "put"),
|
|
928
|
-
update: /* @__PURE__ */ __name((q) => raw2.update(name, q.where.id, q.set), "update"),
|
|
929
|
-
delete: /* @__PURE__ */ __name((id) => raw2.delete(name, id), "delete"),
|
|
930
|
-
findById: /* @__PURE__ */ __name((id) => raw2.findById(name, id), "findById"),
|
|
931
|
-
findMany: /* @__PURE__ */ __name((q) => {
|
|
932
|
-
const { where, ...opts } = q ?? {};
|
|
933
|
-
return raw2.findMany(name, where, opts);
|
|
934
|
-
}, "findMany"),
|
|
935
|
-
updateMany: /* @__PURE__ */ __name((q) => raw2.updateMany(name, q.where, q.set, q.returning === void 0 ? void 0 : {
|
|
936
|
-
returning: q.returning
|
|
937
|
-
}), "updateMany"),
|
|
938
|
-
deleteMany: /* @__PURE__ */ __name((q) => raw2.deleteMany(name, q.where), "deleteMany"),
|
|
939
|
-
count: /* @__PURE__ */ __name((q) => raw2.count(name, q?.where), "count")
|
|
940
|
-
};
|
|
941
|
-
}
|
|
942
|
-
__name(makeTypedTable, "makeTypedTable");
|
|
943
|
-
function makeTypedDB(schema, raw2) {
|
|
944
|
-
const tables = {};
|
|
945
|
-
for (const key of Object.keys(schema.tables)) {
|
|
946
|
-
const tableDef = schema.tables[key];
|
|
947
|
-
if (tableDef !== void 0) {
|
|
948
|
-
tables[key] = makeTypedTable(tableDef.name, raw2);
|
|
949
|
-
}
|
|
950
|
-
}
|
|
748
|
+
// src/db/workload.ts
|
|
749
|
+
function defineWorkload(name, options) {
|
|
951
750
|
const result = {
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
}
|
|
960
|
-
return runTxPlan(raw2, {
|
|
961
|
-
tables: planTables
|
|
962
|
-
}, builder, fn);
|
|
963
|
-
}
|
|
751
|
+
name,
|
|
752
|
+
concurrency: options.concurrency,
|
|
753
|
+
queueLimit: options.queueLimit,
|
|
754
|
+
tenantConcurrency: options.tenantConcurrency ?? options.concurrency,
|
|
755
|
+
tenantQueueLimit: options.tenantQueueLimit ?? options.queueLimit,
|
|
756
|
+
queueTimeoutMs: options.queueTimeoutMs ?? 1e3,
|
|
757
|
+
tenantClaim: options.tenantClaim ?? "tenant_id"
|
|
964
758
|
};
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
759
|
+
validateWorkload(result);
|
|
760
|
+
return Object.freeze(result);
|
|
761
|
+
}
|
|
762
|
+
__name(defineWorkload, "defineWorkload");
|
|
763
|
+
function validateWorkload(value) {
|
|
764
|
+
if (typeof value.name !== "string" || !/^[a-zA-Z][a-zA-Z0-9_.-]{0,63}$/.test(value.name)) throw new Error("workload name must be 1\u201364 letters/digits/dots/dashes");
|
|
765
|
+
for (const name of [
|
|
766
|
+
"concurrency",
|
|
767
|
+
"tenantConcurrency",
|
|
768
|
+
"queueLimit",
|
|
769
|
+
"tenantQueueLimit",
|
|
770
|
+
"queueTimeoutMs"
|
|
771
|
+
]) {
|
|
772
|
+
const n = value[name], min = name.endsWith("Limit") ? 0 : 1;
|
|
773
|
+
const max = name === "queueTimeoutMs" ? 6e4 : name.endsWith("Limit") ? 1e4 : 1e3;
|
|
774
|
+
if (!Number.isInteger(n) || n < min || n > max) throw new Error(`workload ${name} must be an integer between ${min} and ${max}`);
|
|
775
|
+
}
|
|
776
|
+
if (value.tenantConcurrency > value.concurrency || value.tenantQueueLimit > value.queueLimit) throw new Error("workload tenant limits cannot exceed global limits");
|
|
777
|
+
if (typeof value.tenantClaim !== "string" || !/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/.test(value.tenantClaim)) throw new Error("workload tenantClaim must be a top-level claim name");
|
|
778
|
+
}
|
|
779
|
+
__name(validateWorkload, "validateWorkload");
|
|
780
|
+
|
|
781
|
+
// src/db/transaction-options.ts
|
|
782
|
+
function retryBudget(value) {
|
|
783
|
+
const n = value ?? 0;
|
|
784
|
+
if (!Number.isInteger(n) || n < 0 || n > 10) {
|
|
785
|
+
throw new Error("transaction retry must be an integer between 0 and 10");
|
|
984
786
|
}
|
|
787
|
+
return n;
|
|
985
788
|
}
|
|
986
|
-
__name(
|
|
987
|
-
function
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
...strings
|
|
992
|
-
],
|
|
993
|
-
values
|
|
994
|
-
}
|
|
995
|
-
}, "sql");
|
|
789
|
+
__name(retryBudget, "retryBudget");
|
|
790
|
+
function assertPlanRetry(options) {
|
|
791
|
+
if (retryBudget(options?.retry) !== 0) {
|
|
792
|
+
throw new Error("Database.$transaction is a savepoint plan on the request transaction and cannot retry its snapshot or COMMIT. Use Database.$atomic(async tx => { ... }, { retry, isolation }) and put all decision reads and writes inside that callback.");
|
|
793
|
+
}
|
|
996
794
|
}
|
|
997
|
-
__name(
|
|
795
|
+
__name(assertPlanRetry, "assertPlanRetry");
|
|
998
796
|
|
|
999
797
|
// src/db/schema-json.ts
|
|
1000
798
|
function defOf(column) {
|
|
@@ -1407,6 +1205,14 @@ function makeTableProxy(ops, prefix) {
|
|
|
1407
1205
|
update: /* @__PURE__ */ __name((q) => ops().update(name, q.where.id, q.set), "update"),
|
|
1408
1206
|
delete: /* @__PURE__ */ __name((id) => ops().delete(name, id), "delete"),
|
|
1409
1207
|
findById: /* @__PURE__ */ __name((id) => ops().findById(name, id), "findById"),
|
|
1208
|
+
findUnique: /* @__PURE__ */ __name((q) => ops().findUnique(name, q.where, {
|
|
1209
|
+
select: q.select,
|
|
1210
|
+
with: q.with
|
|
1211
|
+
}), "findUnique"),
|
|
1212
|
+
page: /* @__PURE__ */ __name((q) => {
|
|
1213
|
+
const { where, ...opts } = q ?? {};
|
|
1214
|
+
return ops().page(name, where, opts);
|
|
1215
|
+
}, "page"),
|
|
1410
1216
|
findMany: /* @__PURE__ */ __name((q) => {
|
|
1411
1217
|
const { where, ...opts } = q ?? {};
|
|
1412
1218
|
return ops().findMany(name, where, opts);
|
|
@@ -1444,10 +1250,16 @@ function makeTypedSurface(raw2) {
|
|
|
1444
1250
|
const reco = raw2;
|
|
1445
1251
|
const ops = {
|
|
1446
1252
|
$query: /* @__PURE__ */ __name((sql, params) => raw2.query(sql, params), "$query"),
|
|
1253
|
+
$diagnostics: /* @__PURE__ */ __name(() => raw2.diagnostics(), "$diagnostics"),
|
|
1254
|
+
$readQuery: /* @__PURE__ */ __name((query) => raw2.readQuery(query), "$readQuery"),
|
|
1255
|
+
$compileQuery: /* @__PURE__ */ __name((query) => raw2.compileQuery(query), "$compileQuery"),
|
|
1256
|
+
$explainQuery: /* @__PURE__ */ __name((query) => raw2.explainQuery(query), "$explainQuery"),
|
|
1447
1257
|
$insert: /* @__PURE__ */ __name((table, data) => raw2.insert(table, data), "$insert"),
|
|
1448
1258
|
$update: /* @__PURE__ */ __name((table, id, data) => raw2.update(table, id, data), "$update"),
|
|
1449
1259
|
$delete: /* @__PURE__ */ __name((table, id) => raw2.delete(table, id), "$delete"),
|
|
1450
1260
|
$findById: /* @__PURE__ */ __name((table, id) => raw2.findById(table, id), "$findById"),
|
|
1261
|
+
$findUnique: /* @__PURE__ */ __name((table, where, opts) => raw2.findUnique(table, where, opts), "$findUnique"),
|
|
1262
|
+
$page: /* @__PURE__ */ __name((table, query, opts) => raw2.page(table, query, opts), "$page"),
|
|
1451
1263
|
$findMany: /* @__PURE__ */ __name((table, query, opts) => raw2.findMany(table, query, opts), "$findMany"),
|
|
1452
1264
|
$put: /* @__PURE__ */ __name((table, data, opts) => raw2.put(table, data, opts), "$put"),
|
|
1453
1265
|
// `opts` İLETİLİR. Düşürüldüğü sürece `Database.$updateMany(t, w, s,
|
|
@@ -1470,14 +1282,49 @@ function makeTypedSurface(raw2) {
|
|
|
1470
1282
|
$supersede: /* @__PURE__ */ __name((table, id, row) => raw2.supersede(table, id, row), "$supersede")
|
|
1471
1283
|
};
|
|
1472
1284
|
const base = Object.assign(ops, {
|
|
1285
|
+
$atomic(fn, options) {
|
|
1286
|
+
if (typeof raw2.atomic !== "function") {
|
|
1287
|
+
throw new Error("This Database handle cannot open a root transaction; nested $atomic is not supported");
|
|
1288
|
+
}
|
|
1289
|
+
const parent = __requestALS.getStore();
|
|
1290
|
+
let runtime2;
|
|
1291
|
+
try {
|
|
1292
|
+
runtime2 = __getRuntime();
|
|
1293
|
+
} catch {
|
|
1294
|
+
}
|
|
1295
|
+
return raw2.atomic(async (tx) => {
|
|
1296
|
+
const typed = makeTypedSurface(tx);
|
|
1297
|
+
const invoke = /* @__PURE__ */ __name(() => fn(typed), "invoke");
|
|
1298
|
+
if (!runtime2) return invoke();
|
|
1299
|
+
const refuse2 = /* @__PURE__ */ __name(() => {
|
|
1300
|
+
throw new Error("Database.$atomic owns one transaction and identity; nested roots and $asService are not allowed");
|
|
1301
|
+
}, "refuse");
|
|
1302
|
+
const ambient = Object.assign({}, tx, {
|
|
1303
|
+
atomic: refuse2,
|
|
1304
|
+
asService: refuse2
|
|
1305
|
+
});
|
|
1306
|
+
return __requestALS.run({
|
|
1307
|
+
...parent,
|
|
1308
|
+
runtime: {
|
|
1309
|
+
...runtime2,
|
|
1310
|
+
Database: ambient
|
|
1311
|
+
}
|
|
1312
|
+
}, invoke);
|
|
1313
|
+
}, options);
|
|
1314
|
+
},
|
|
1473
1315
|
// Both surfaces get it: a savepoint on the service transaction is as useful
|
|
1474
1316
|
// as one on the request's, and each is bound to its own connection.
|
|
1475
1317
|
$attempt: /* @__PURE__ */ __name((fn) => raw2.attempt(fn), "$attempt"),
|
|
1476
1318
|
$transaction(fn, opts) {
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1319
|
+
assertPlanRetry(opts);
|
|
1320
|
+
const builder = new TxPlanBuilder();
|
|
1321
|
+
return runTxPlan(raw2, makeTxPlanHandle(builder), builder, fn);
|
|
1322
|
+
},
|
|
1323
|
+
$command(fn, options) {
|
|
1324
|
+
const builder = new TxPlanBuilder();
|
|
1325
|
+
return runTxPlan({
|
|
1326
|
+
txPlan: /* @__PURE__ */ __name((plan) => raw2.command(plan, options), "txPlan")
|
|
1327
|
+
}, makeTxPlanHandle(builder), builder, fn);
|
|
1481
1328
|
}
|
|
1482
1329
|
});
|
|
1483
1330
|
return new Proxy(base, {
|
|
@@ -3134,6 +2981,13 @@ function defineTable(name, input) {
|
|
|
3134
2981
|
}
|
|
3135
2982
|
__name(defineTable, "defineTable");
|
|
3136
2983
|
var declaringSchemaOf = /* @__PURE__ */ new WeakMap();
|
|
2984
|
+
function declaredTableKey(table) {
|
|
2985
|
+
const metadata = table[TABLE_META];
|
|
2986
|
+
const schema = declaringSchemaOf.get(metadata);
|
|
2987
|
+
if (schema === void 0) throw new Error(`defineQuery: table ${metadata.name} must belong to defineSchema before defining its query`);
|
|
2988
|
+
return qualifiedTableKey(schema, metadata.name);
|
|
2989
|
+
}
|
|
2990
|
+
__name(declaredTableKey, "declaredTableKey");
|
|
3137
2991
|
function resolveReferences(tables, schemaName) {
|
|
3138
2992
|
for (const table of Object.values(tables)) {
|
|
3139
2993
|
for (const [colName, builder] of Object.entries(table.columns)) {
|
|
@@ -3733,6 +3587,295 @@ var openai = {
|
|
|
3733
3587
|
}
|
|
3734
3588
|
};
|
|
3735
3589
|
|
|
3590
|
+
// src/db/sqlstate.ts
|
|
3591
|
+
var SQLSTATE = Object.freeze({
|
|
3592
|
+
serializationFailure: "40001",
|
|
3593
|
+
deadlockDetected: "40P01",
|
|
3594
|
+
commandGuardFailed: "PBC01"
|
|
3595
|
+
});
|
|
3596
|
+
function isTransactionRollbackState(state) {
|
|
3597
|
+
return state === SQLSTATE.serializationFailure || state === SQLSTATE.deadlockDetected;
|
|
3598
|
+
}
|
|
3599
|
+
__name(isTransactionRollbackState, "isTransactionRollbackState");
|
|
3600
|
+
|
|
3601
|
+
// src/errors.ts
|
|
3602
|
+
var HTTP_ERROR_BRAND = /* @__PURE__ */ Symbol.for("palbase.backend.httpError");
|
|
3603
|
+
var HttpError = class extends Error {
|
|
3604
|
+
static {
|
|
3605
|
+
__name(this, "HttpError");
|
|
3606
|
+
}
|
|
3607
|
+
status;
|
|
3608
|
+
error;
|
|
3609
|
+
errorDescription;
|
|
3610
|
+
data;
|
|
3611
|
+
/** See {@link HTTP_ERROR_BRAND} — how the engine recognises this across SDK copies. */
|
|
3612
|
+
[HTTP_ERROR_BRAND] = true;
|
|
3613
|
+
constructor(status, error, errorDescription, data) {
|
|
3614
|
+
super(errorDescription);
|
|
3615
|
+
this.name = "HttpError";
|
|
3616
|
+
this.status = status;
|
|
3617
|
+
this.error = error;
|
|
3618
|
+
this.errorDescription = errorDescription;
|
|
3619
|
+
if (data !== void 0) {
|
|
3620
|
+
this.data = data;
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3623
|
+
/**
|
|
3624
|
+
* Serialize to the standard Palbase error response format.
|
|
3625
|
+
* The `requestId` is injected by the runtime layer from the request context.
|
|
3626
|
+
* When called without arguments (e.g. JSON.stringify), request_id is omitted.
|
|
3627
|
+
* When `data` is set, it is appended as a strict-superset field.
|
|
3628
|
+
*/
|
|
3629
|
+
toJSON(requestId) {
|
|
3630
|
+
const result = {
|
|
3631
|
+
error: this.error,
|
|
3632
|
+
error_description: this.errorDescription,
|
|
3633
|
+
status: this.status
|
|
3634
|
+
};
|
|
3635
|
+
if (requestId) {
|
|
3636
|
+
result.request_id = requestId;
|
|
3637
|
+
}
|
|
3638
|
+
if (this.data !== void 0) {
|
|
3639
|
+
result.data = this.data;
|
|
3640
|
+
}
|
|
3641
|
+
return result;
|
|
3642
|
+
}
|
|
3643
|
+
};
|
|
3644
|
+
var PalError = class extends HttpError {
|
|
3645
|
+
static {
|
|
3646
|
+
__name(this, "PalError");
|
|
3647
|
+
}
|
|
3648
|
+
constructor(status, code, description, data) {
|
|
3649
|
+
super(status, code, description, data);
|
|
3650
|
+
this.name = "PalError";
|
|
3651
|
+
}
|
|
3652
|
+
};
|
|
3653
|
+
var NamedHttpError = class NamedHttpError2 extends HttpError {
|
|
3654
|
+
static {
|
|
3655
|
+
__name(this, "NamedHttpError");
|
|
3656
|
+
}
|
|
3657
|
+
constructor(status, defaultCode, name, message, code, data) {
|
|
3658
|
+
super(status, code ?? defaultCode, message ?? defaultMessage(name), data);
|
|
3659
|
+
this.name = name;
|
|
3660
|
+
}
|
|
3661
|
+
};
|
|
3662
|
+
function defaultMessage(name) {
|
|
3663
|
+
const spaced = name.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
|
|
3664
|
+
return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
|
|
3665
|
+
}
|
|
3666
|
+
__name(defaultMessage, "defaultMessage");
|
|
3667
|
+
var BadRequest = class extends NamedHttpError {
|
|
3668
|
+
static {
|
|
3669
|
+
__name(this, "BadRequest");
|
|
3670
|
+
}
|
|
3671
|
+
constructor(data, message) {
|
|
3672
|
+
super(400, "bad_request", "BadRequest", message, void 0, data);
|
|
3673
|
+
}
|
|
3674
|
+
};
|
|
3675
|
+
var Unauthorized = class extends NamedHttpError {
|
|
3676
|
+
static {
|
|
3677
|
+
__name(this, "Unauthorized");
|
|
3678
|
+
}
|
|
3679
|
+
constructor(message, code, data) {
|
|
3680
|
+
super(401, "unauthorized", "Unauthorized", message, code, data);
|
|
3681
|
+
}
|
|
3682
|
+
};
|
|
3683
|
+
var Forbidden = class extends NamedHttpError {
|
|
3684
|
+
static {
|
|
3685
|
+
__name(this, "Forbidden");
|
|
3686
|
+
}
|
|
3687
|
+
constructor(message, code, data) {
|
|
3688
|
+
super(403, "forbidden", "Forbidden", message, code, data);
|
|
3689
|
+
}
|
|
3690
|
+
};
|
|
3691
|
+
var NotFound = class extends NamedHttpError {
|
|
3692
|
+
static {
|
|
3693
|
+
__name(this, "NotFound");
|
|
3694
|
+
}
|
|
3695
|
+
constructor(message, code, data) {
|
|
3696
|
+
super(404, "not_found", "NotFound", message, code, data);
|
|
3697
|
+
}
|
|
3698
|
+
};
|
|
3699
|
+
var Conflict = class extends NamedHttpError {
|
|
3700
|
+
static {
|
|
3701
|
+
__name(this, "Conflict");
|
|
3702
|
+
}
|
|
3703
|
+
constructor(message, code, data) {
|
|
3704
|
+
super(409, "conflict", "Conflict", message, code, data);
|
|
3705
|
+
}
|
|
3706
|
+
};
|
|
3707
|
+
var UniqueViolation = class extends Conflict {
|
|
3708
|
+
static {
|
|
3709
|
+
__name(this, "UniqueViolation");
|
|
3710
|
+
}
|
|
3711
|
+
/**
|
|
3712
|
+
* Whether `e` is a unique violation — REGARDLESS of which copy of this SDK
|
|
3713
|
+
* constructed it.
|
|
3714
|
+
*
|
|
3715
|
+
* Use this instead of `instanceof`. Measured on a live stack: a controller
|
|
3716
|
+
* bundle INLINES its own copy of `@palbase/backend`, and the engine that
|
|
3717
|
+
* raises this error is the runtime's copy. Two copies, two class identities,
|
|
3718
|
+
* and `e instanceof UniqueViolation` is false in the one place a caller
|
|
3719
|
+
* writes it — a check that reads as correct and silently never matches.
|
|
3720
|
+
*/
|
|
3721
|
+
static is(e) {
|
|
3722
|
+
return typeof e === "object" && e !== null && e.name === "UniqueViolation" && typeof e.constraint === "string";
|
|
3723
|
+
}
|
|
3724
|
+
/** The unique constraint the statement violated, as Postgres named it.
|
|
3725
|
+
* `""` when the driver did not say which — see `engine/db.ts`. */
|
|
3726
|
+
constraint;
|
|
3727
|
+
constructor(constraint, message, code, data) {
|
|
3728
|
+
super(message ?? "Unique constraint violated", code ?? "unique_violation", data);
|
|
3729
|
+
this.name = "UniqueViolation";
|
|
3730
|
+
this.constraint = constraint;
|
|
3731
|
+
}
|
|
3732
|
+
};
|
|
3733
|
+
function isRetryable(e) {
|
|
3734
|
+
return typeof e === "object" && e !== null && e.retryable === true && isTransactionRollbackState(e.sqlstate);
|
|
3735
|
+
}
|
|
3736
|
+
__name(isRetryable, "isRetryable");
|
|
3737
|
+
var SerializationFailure = class extends Conflict {
|
|
3738
|
+
static {
|
|
3739
|
+
__name(this, "SerializationFailure");
|
|
3740
|
+
}
|
|
3741
|
+
retryable = true;
|
|
3742
|
+
sqlstate;
|
|
3743
|
+
static is(e) {
|
|
3744
|
+
return typeof e === "object" && e !== null && e.name === "SerializationFailure";
|
|
3745
|
+
}
|
|
3746
|
+
constructor(sqlstate = SQLSTATE.serializationFailure, message, data) {
|
|
3747
|
+
super(message ?? "i\u015Flem e\u015Fzamanl\u0131 bir i\u015Flemle serile\u015Ftirilemedi \u2014 ayn\u0131 i\u015Flemi ba\u015Ftan \xE7al\u0131\u015Ft\u0131r\u0131n (karar okumalar\u0131 ve yazmalar\u0131 $atomic i\xE7ine al\u0131p { retry: n } verin)", "serialization_failure", data);
|
|
3748
|
+
this.name = "SerializationFailure";
|
|
3749
|
+
this.sqlstate = sqlstate;
|
|
3750
|
+
}
|
|
3751
|
+
};
|
|
3752
|
+
var DeadlockDetected = class extends Conflict {
|
|
3753
|
+
static {
|
|
3754
|
+
__name(this, "DeadlockDetected");
|
|
3755
|
+
}
|
|
3756
|
+
retryable = true;
|
|
3757
|
+
sqlstate;
|
|
3758
|
+
static is(e) {
|
|
3759
|
+
return typeof e === "object" && e !== null && e.name === "DeadlockDetected";
|
|
3760
|
+
}
|
|
3761
|
+
constructor(sqlstate = SQLSTATE.deadlockDetected, message, data) {
|
|
3762
|
+
super(message ?? "deadlock: iki i\u015Flem birbirinin kilidini bekledi ve bu i\u015Flem iptal edildi \u2014 kilit s\u0131ras\u0131n\u0131 sabitlemek i\xE7in Database.$lockRows(tablo, id'ler) kullan\u0131n", "deadlock_detected", data);
|
|
3763
|
+
this.name = "DeadlockDetected";
|
|
3764
|
+
this.sqlstate = sqlstate;
|
|
3765
|
+
}
|
|
3766
|
+
};
|
|
3767
|
+
var TooManyRequests = class extends NamedHttpError {
|
|
3768
|
+
static {
|
|
3769
|
+
__name(this, "TooManyRequests");
|
|
3770
|
+
}
|
|
3771
|
+
constructor(data, message) {
|
|
3772
|
+
super(429, "too_many_requests", "TooManyRequests", message, void 0, data);
|
|
3773
|
+
}
|
|
3774
|
+
};
|
|
3775
|
+
|
|
3776
|
+
// src/db/typed-db.ts
|
|
3777
|
+
function makeTypedTable(name, raw2) {
|
|
3778
|
+
return {
|
|
3779
|
+
insert: /* @__PURE__ */ __name((data) => raw2.insert(name, data), "insert"),
|
|
3780
|
+
aggregate: /* @__PURE__ */ __name((q) => raw2.aggregate(name, q), "aggregate"),
|
|
3781
|
+
insertMany: /* @__PURE__ */ __name((rows, opts) => raw2.insertMany(name, rows, opts), "insertMany"),
|
|
3782
|
+
put: /* @__PURE__ */ __name((q) => raw2.put(name, q.data, {
|
|
3783
|
+
onConflict: q.onConflict
|
|
3784
|
+
}), "put"),
|
|
3785
|
+
update: /* @__PURE__ */ __name((q) => raw2.update(name, q.where.id, q.set), "update"),
|
|
3786
|
+
delete: /* @__PURE__ */ __name((id) => raw2.delete(name, id), "delete"),
|
|
3787
|
+
findUnique: /* @__PURE__ */ __name((q) => raw2.findUnique(name, q.where, {
|
|
3788
|
+
select: q.select
|
|
3789
|
+
}), "findUnique"),
|
|
3790
|
+
findById: /* @__PURE__ */ __name((id) => raw2.findById(name, id), "findById"),
|
|
3791
|
+
page: /* @__PURE__ */ __name((q) => {
|
|
3792
|
+
const { where, ...opts } = q ?? {};
|
|
3793
|
+
return raw2.page(name, where, opts);
|
|
3794
|
+
}, "page"),
|
|
3795
|
+
findMany: /* @__PURE__ */ __name((q) => {
|
|
3796
|
+
const { where, ...opts } = q ?? {};
|
|
3797
|
+
return raw2.findMany(name, where, opts);
|
|
3798
|
+
}, "findMany"),
|
|
3799
|
+
updateMany: /* @__PURE__ */ __name((q) => raw2.updateMany(name, q.where, q.set, q.returning === void 0 ? void 0 : {
|
|
3800
|
+
returning: q.returning
|
|
3801
|
+
}), "updateMany"),
|
|
3802
|
+
deleteMany: /* @__PURE__ */ __name((q) => raw2.deleteMany(name, q.where), "deleteMany"),
|
|
3803
|
+
count: /* @__PURE__ */ __name((q) => raw2.count(name, q?.where), "count")
|
|
3804
|
+
};
|
|
3805
|
+
}
|
|
3806
|
+
__name(makeTypedTable, "makeTypedTable");
|
|
3807
|
+
function makeTypedDB(schema, raw2) {
|
|
3808
|
+
const tables = {};
|
|
3809
|
+
for (const key of Object.keys(schema.tables)) {
|
|
3810
|
+
const tableDef = schema.tables[key];
|
|
3811
|
+
if (tableDef !== void 0) {
|
|
3812
|
+
tables[key] = makeTypedTable(qualifiedTableKey(schema.name, tableDef.name), raw2);
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
3815
|
+
const result = {
|
|
3816
|
+
tables,
|
|
3817
|
+
diagnostics: /* @__PURE__ */ __name(() => raw2.diagnostics(), "diagnostics"),
|
|
3818
|
+
readQuery: /* @__PURE__ */ __name((query) => raw2.readQuery(query), "readQuery"),
|
|
3819
|
+
compileQuery: /* @__PURE__ */ __name((query) => raw2.compileQuery(query), "compileQuery"),
|
|
3820
|
+
explainQuery: /* @__PURE__ */ __name((query) => raw2.explainQuery(query), "explainQuery"),
|
|
3821
|
+
command(fn, options) {
|
|
3822
|
+
const builder = new TxPlanBuilder();
|
|
3823
|
+
const planTables = Object.fromEntries(Object.entries(schema.tables).map(([key, table]) => [
|
|
3824
|
+
key,
|
|
3825
|
+
builder.table(qualifiedTableKey(schema.name, table.name))
|
|
3826
|
+
]));
|
|
3827
|
+
return runTxPlan({
|
|
3828
|
+
txPlan: /* @__PURE__ */ __name((plan) => raw2.command(plan, options), "txPlan")
|
|
3829
|
+
}, {
|
|
3830
|
+
tables: planTables
|
|
3831
|
+
}, builder, fn);
|
|
3832
|
+
},
|
|
3833
|
+
transaction(fn) {
|
|
3834
|
+
const builder = new TxPlanBuilder();
|
|
3835
|
+
const planTables = {};
|
|
3836
|
+
for (const key of Object.keys(schema.tables)) {
|
|
3837
|
+
const tableDef = schema.tables[key];
|
|
3838
|
+
if (tableDef !== void 0) planTables[key] = builder.table(qualifiedTableKey(schema.name, tableDef.name));
|
|
3839
|
+
}
|
|
3840
|
+
return runTxPlan(raw2, {
|
|
3841
|
+
tables: planTables
|
|
3842
|
+
}, builder, fn);
|
|
3843
|
+
}
|
|
3844
|
+
};
|
|
3845
|
+
return result;
|
|
3846
|
+
}
|
|
3847
|
+
__name(makeTypedDB, "makeTypedDB");
|
|
3848
|
+
function col(name) {
|
|
3849
|
+
return brandRef({
|
|
3850
|
+
$col: name
|
|
3851
|
+
}, "col");
|
|
3852
|
+
}
|
|
3853
|
+
__name(col, "col");
|
|
3854
|
+
async function withRetry(fn, opts = {}) {
|
|
3855
|
+
const budget = retryBudget(opts.retry);
|
|
3856
|
+
let attempt = 0;
|
|
3857
|
+
for (; ; ) {
|
|
3858
|
+
try {
|
|
3859
|
+
return await fn();
|
|
3860
|
+
} catch (e) {
|
|
3861
|
+
if (attempt >= budget || !isRetryable(e)) throw e;
|
|
3862
|
+
attempt += 1;
|
|
3863
|
+
}
|
|
3864
|
+
}
|
|
3865
|
+
}
|
|
3866
|
+
__name(withRetry, "withRetry");
|
|
3867
|
+
function sqlFragment(strings, ...values) {
|
|
3868
|
+
return brandRef({
|
|
3869
|
+
$sql: {
|
|
3870
|
+
text: [
|
|
3871
|
+
...strings
|
|
3872
|
+
],
|
|
3873
|
+
values
|
|
3874
|
+
}
|
|
3875
|
+
}, "sql");
|
|
3876
|
+
}
|
|
3877
|
+
__name(sqlFragment, "sqlFragment");
|
|
3878
|
+
|
|
3736
3879
|
// src/refusals.ts
|
|
3737
3880
|
var DECLARATION_REFUSAL = /* @__PURE__ */ Symbol.for("palbase.backend.declarationRefusal");
|
|
3738
3881
|
var DeclarationRefused = class extends Error {
|
|
@@ -3751,6 +3894,39 @@ function isDeclarationRefused(e) {
|
|
|
3751
3894
|
}
|
|
3752
3895
|
__name(isDeclarationRefused, "isDeclarationRefused");
|
|
3753
3896
|
|
|
3897
|
+
// src/db/unique.ts
|
|
3898
|
+
function uniqueKeysOf(table) {
|
|
3899
|
+
const columns = table.columns ?? {};
|
|
3900
|
+
const inlinePrimary = [], keys = [];
|
|
3901
|
+
for (const [name, value] of Object.entries(columns)) {
|
|
3902
|
+
const col2 = value && typeof value === "object" && "_def" in value ? value._def : value;
|
|
3903
|
+
if (col2?.primaryKey) inlinePrimary.push(name);
|
|
3904
|
+
if (col2?.unique) keys.push([
|
|
3905
|
+
name
|
|
3906
|
+
]);
|
|
3907
|
+
}
|
|
3908
|
+
const primary = table.primaryKey ?? inlinePrimary;
|
|
3909
|
+
if (primary.length) keys.unshift([
|
|
3910
|
+
...primary
|
|
3911
|
+
]);
|
|
3912
|
+
for (const key of table.unique ?? []) keys.push([
|
|
3913
|
+
...key.columns
|
|
3914
|
+
]);
|
|
3915
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3916
|
+
return keys.filter((key) => {
|
|
3917
|
+
if (!key.length || new Set(key).size !== key.length || key.some((col2) => !Object.hasOwn(columns, col2))) {
|
|
3918
|
+
throw new Error("Unique lookup requires a nonempty declared key of distinct, known columns");
|
|
3919
|
+
}
|
|
3920
|
+
const identity = JSON.stringify([
|
|
3921
|
+
...key
|
|
3922
|
+
].sort());
|
|
3923
|
+
if (seen.has(identity)) return false;
|
|
3924
|
+
seen.add(identity);
|
|
3925
|
+
return true;
|
|
3926
|
+
});
|
|
3927
|
+
}
|
|
3928
|
+
__name(uniqueKeysOf, "uniqueKeysOf");
|
|
3929
|
+
|
|
3754
3930
|
// src/db/env-gen.ts
|
|
3755
3931
|
function baseTsType(def) {
|
|
3756
3932
|
if (def.codec !== void 0 && def.codec in CODECS) {
|
|
@@ -3917,6 +4093,7 @@ function tableBlock(table, relations, indent) {
|
|
|
3917
4093
|
...insertLines,
|
|
3918
4094
|
`${indent} };`,
|
|
3919
4095
|
`${indent} relations: {${relEntries === "" ? "" : ` ${relEntries} `}};`,
|
|
4096
|
+
`${indent} uniqueKeys: ${JSON.stringify(uniqueKeysOf(table))};`,
|
|
3920
4097
|
// searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()
|
|
3921
4098
|
// üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki
|
|
3922
4099
|
// mevcut şemaların d.ts'i bayt-aynı kalsın.
|
|
@@ -5455,7 +5632,188 @@ function getJobConfig(ctor, container) {
|
|
|
5455
5632
|
__name(getJobConfig, "getJobConfig");
|
|
5456
5633
|
|
|
5457
5634
|
// src/index.ts
|
|
5635
|
+
var import_zod3 = require("zod");
|
|
5636
|
+
|
|
5637
|
+
// src/db/query.ts
|
|
5458
5638
|
var import_zod2 = require("zod");
|
|
5639
|
+
var import_zod_to_openapi2 = require("@asteasolutions/zod-to-openapi");
|
|
5640
|
+
|
|
5641
|
+
// src/db/query-contract.ts
|
|
5642
|
+
function queryColumnContract(column) {
|
|
5643
|
+
const def = column && typeof column === "object" && "_def" in column ? column._def : column;
|
|
5644
|
+
if (!def?.type) throw new Error("Query contract requires declared column types");
|
|
5645
|
+
if (def.transform !== void 0 && def.codec === void 0) throw new Error("Query contracts require a named codec instead of a free-form column transform");
|
|
5646
|
+
return {
|
|
5647
|
+
type: def.type,
|
|
5648
|
+
nullable: def.nullable === true,
|
|
5649
|
+
...def.codec === void 0 ? {} : {
|
|
5650
|
+
codec: def.codec
|
|
5651
|
+
},
|
|
5652
|
+
...def.enumValues === void 0 ? {} : {
|
|
5653
|
+
enumValues: [
|
|
5654
|
+
...def.enumValues
|
|
5655
|
+
]
|
|
5656
|
+
},
|
|
5657
|
+
...def.dimensions === void 0 ? {} : {
|
|
5658
|
+
dimensions: def.dimensions
|
|
5659
|
+
}
|
|
5660
|
+
};
|
|
5661
|
+
}
|
|
5662
|
+
__name(queryColumnContract, "queryColumnContract");
|
|
5663
|
+
function stableContract(value) {
|
|
5664
|
+
if (Array.isArray(value)) return `[${value.map(stableContract).join(",")}]`;
|
|
5665
|
+
if (value && typeof value === "object") return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableContract(value[key])}`).join(",")}}`;
|
|
5666
|
+
return JSON.stringify(value) ?? "null";
|
|
5667
|
+
}
|
|
5668
|
+
__name(stableContract, "stableContract");
|
|
5669
|
+
|
|
5670
|
+
// src/db/query.ts
|
|
5671
|
+
(0, import_zod_to_openapi2.extendZodWithOpenApi)(import_zod2.z);
|
|
5672
|
+
function responseColumn(column, validator) {
|
|
5673
|
+
const contract = queryColumnContract(column);
|
|
5674
|
+
let schema;
|
|
5675
|
+
if (validator) return validator;
|
|
5676
|
+
if (contract.codec === "number") schema = import_zod2.z.number().finite();
|
|
5677
|
+
else if (contract.codec === "decimal") schema = import_zod2.z.string();
|
|
5678
|
+
else switch (contract.type) {
|
|
5679
|
+
case "integer":
|
|
5680
|
+
schema = import_zod2.z.number().int().min(-2147483648).max(2147483647);
|
|
5681
|
+
break;
|
|
5682
|
+
case "boolean":
|
|
5683
|
+
schema = import_zod2.z.boolean();
|
|
5684
|
+
break;
|
|
5685
|
+
case "vector":
|
|
5686
|
+
schema = import_zod2.z.array(import_zod2.z.number().finite());
|
|
5687
|
+
break;
|
|
5688
|
+
case "enum": {
|
|
5689
|
+
const values = contract.enumValues;
|
|
5690
|
+
if (!values?.length) throw new Error("Query response requires declared enum values");
|
|
5691
|
+
schema = import_zod2.z.enum(values);
|
|
5692
|
+
break;
|
|
5693
|
+
}
|
|
5694
|
+
case "uuid":
|
|
5695
|
+
case "text":
|
|
5696
|
+
case "timestamp":
|
|
5697
|
+
case "numeric":
|
|
5698
|
+
case "bigint":
|
|
5699
|
+
schema = import_zod2.z.string();
|
|
5700
|
+
break;
|
|
5701
|
+
case "jsonb":
|
|
5702
|
+
throw new Error("Query response requires a fields validator for a selected jsonb column: its TypeScript payload is erased at runtime");
|
|
5703
|
+
default:
|
|
5704
|
+
throw new Error(`Query response does not support column type ${contract.type}`);
|
|
5705
|
+
}
|
|
5706
|
+
return contract.nullable ? schema.nullable() : schema;
|
|
5707
|
+
}
|
|
5708
|
+
__name(responseColumn, "responseColumn");
|
|
5709
|
+
function defineQuery(name, options) {
|
|
5710
|
+
if (typeof name !== "string" || !/^[A-Za-z][A-Za-z0-9_]{0,127}$/.test(name)) throw new Error("defineQuery requires a stable name of 1\u2013128 letters, digits or underscores");
|
|
5711
|
+
const table = declaredTableKey(options.table);
|
|
5712
|
+
const select = [
|
|
5713
|
+
...options.select
|
|
5714
|
+
];
|
|
5715
|
+
if (!select.length || new Set(select).size !== select.length) throw new Error(`Query ${name}: select must be explicit, nonempty and distinct`);
|
|
5716
|
+
const shape = {}, columns = {};
|
|
5717
|
+
for (const key of select) {
|
|
5718
|
+
if (!Object.hasOwn(options.table[TABLE_META].columns, key)) throw new Error(`Query ${name}: unknown column ${key}`);
|
|
5719
|
+
columns[key] = queryColumnContract(options.table[key]);
|
|
5720
|
+
shape[key] = responseColumn(options.table[key], options.fields?.[key]);
|
|
5721
|
+
}
|
|
5722
|
+
const response = import_zod2.z.array(import_zod2.z.object(shape).strict());
|
|
5723
|
+
const queryInput = options.input, where = options.where, limit = options.limit;
|
|
5724
|
+
const orderBy = options.orderBy === void 0 ? void 0 : JSON.parse(JSON.stringify(options.orderBy));
|
|
5725
|
+
const prepare = /* @__PURE__ */ __name((input) => {
|
|
5726
|
+
const parsed = queryInput.parse(input);
|
|
5727
|
+
const filter = where === void 0 ? {} : where(parsed);
|
|
5728
|
+
if (!filter || typeof filter !== "object" || Array.isArray(filter) || typeof filter.then === "function") {
|
|
5729
|
+
throw new Error(`Query ${name}: where must return a synchronous filter object`);
|
|
5730
|
+
}
|
|
5731
|
+
const size = typeof limit === "function" ? limit(parsed) : limit;
|
|
5732
|
+
if (limit !== void 0 && (typeof size !== "number" || !Number.isSafeInteger(size) || size < 0)) throw new Error(`Query ${name}: limit must produce a nonnegative safe integer`);
|
|
5733
|
+
return {
|
|
5734
|
+
name,
|
|
5735
|
+
table,
|
|
5736
|
+
columns: JSON.parse(JSON.stringify(columns)),
|
|
5737
|
+
where: filter,
|
|
5738
|
+
options: {
|
|
5739
|
+
select: [
|
|
5740
|
+
...select
|
|
5741
|
+
],
|
|
5742
|
+
...orderBy === void 0 ? {} : {
|
|
5743
|
+
orderBy: structuredClone(orderBy)
|
|
5744
|
+
},
|
|
5745
|
+
...limit === void 0 ? {} : {
|
|
5746
|
+
limit: size
|
|
5747
|
+
}
|
|
5748
|
+
}
|
|
5749
|
+
};
|
|
5750
|
+
}, "prepare");
|
|
5751
|
+
const attach = /* @__PURE__ */ __name((schema) => {
|
|
5752
|
+
const api = {
|
|
5753
|
+
queryName: name,
|
|
5754
|
+
input: queryInput,
|
|
5755
|
+
prepare,
|
|
5756
|
+
async run(database, input) {
|
|
5757
|
+
const request = prepare(input);
|
|
5758
|
+
const rows = await ("$readQuery" in database ? database.$readQuery(request) : database.readQuery(request));
|
|
5759
|
+
return schema.parse(rows);
|
|
5760
|
+
},
|
|
5761
|
+
sql(database, input) {
|
|
5762
|
+
const request = prepare(input);
|
|
5763
|
+
return "$compileQuery" in database ? database.$compileQuery(request) : database.compileQuery(request);
|
|
5764
|
+
},
|
|
5765
|
+
explain(database, input) {
|
|
5766
|
+
const request = prepare(input);
|
|
5767
|
+
return "$explainQuery" in database ? database.$explainQuery(request) : database.explainQuery(request);
|
|
5768
|
+
},
|
|
5769
|
+
contract() {
|
|
5770
|
+
const registry2 = new import_zod_to_openapi2.OpenAPIRegistry();
|
|
5771
|
+
registry2.register(`${name}Input`, queryInput);
|
|
5772
|
+
registry2.register(`${name}Response`, schema);
|
|
5773
|
+
return JSON.parse(JSON.stringify({
|
|
5774
|
+
name,
|
|
5775
|
+
table,
|
|
5776
|
+
select,
|
|
5777
|
+
columns,
|
|
5778
|
+
components: new import_zod_to_openapi2.OpenApiGeneratorV31(registry2.definitions).generateComponents().components
|
|
5779
|
+
}));
|
|
5780
|
+
}
|
|
5781
|
+
};
|
|
5782
|
+
for (const key of [
|
|
5783
|
+
"min",
|
|
5784
|
+
"max",
|
|
5785
|
+
"length",
|
|
5786
|
+
"describe",
|
|
5787
|
+
"openapi"
|
|
5788
|
+
]) {
|
|
5789
|
+
const modify = schema[key].bind(schema);
|
|
5790
|
+
Object.defineProperty(schema, key, {
|
|
5791
|
+
value: /* @__PURE__ */ __name((...args) => attach(modify(...args)), "value"),
|
|
5792
|
+
configurable: true
|
|
5793
|
+
});
|
|
5794
|
+
}
|
|
5795
|
+
return Object.assign(schema, api);
|
|
5796
|
+
}, "attach");
|
|
5797
|
+
return attach(response);
|
|
5798
|
+
}
|
|
5799
|
+
__name(defineQuery, "defineQuery");
|
|
5800
|
+
function queryManifest(queries) {
|
|
5801
|
+
const sorted = [
|
|
5802
|
+
...queries
|
|
5803
|
+
].sort((a, b) => a.queryName.localeCompare(b.queryName));
|
|
5804
|
+
if (new Set(sorted.map((query) => query.queryName)).size !== sorted.length) throw new Error("Query manifest contains duplicate names");
|
|
5805
|
+
return JSON.parse(stableContract({
|
|
5806
|
+
version: 1,
|
|
5807
|
+
queries: sorted.map((query) => query.contract())
|
|
5808
|
+
}));
|
|
5809
|
+
}
|
|
5810
|
+
__name(queryManifest, "queryManifest");
|
|
5811
|
+
function assertQueryManifest(queries, baseline) {
|
|
5812
|
+
if (stableContract(queryManifest(queries)) !== stableContract(baseline)) {
|
|
5813
|
+
throw new Error("Query contract drift: compare queryManifest() with the committed manifest and review the API/client changes before updating it");
|
|
5814
|
+
}
|
|
5815
|
+
}
|
|
5816
|
+
__name(assertQueryManifest, "assertQueryManifest");
|
|
5459
5817
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5460
5818
|
0 && (module.exports = {
|
|
5461
5819
|
Auth,
|
|
@@ -5539,6 +5897,7 @@ var import_zod2 = require("zod");
|
|
|
5539
5897
|
__runWithRuntime,
|
|
5540
5898
|
__setRuntime,
|
|
5541
5899
|
assertNoOrphanEntryPoints,
|
|
5900
|
+
assertQueryManifest,
|
|
5542
5901
|
assertZeroArgConstructor,
|
|
5543
5902
|
bigint,
|
|
5544
5903
|
boolean,
|
|
@@ -5552,8 +5911,10 @@ var import_zod2 = require("zod");
|
|
|
5552
5911
|
defineDefaultAuth,
|
|
5553
5912
|
defineError,
|
|
5554
5913
|
defineMiddleware,
|
|
5914
|
+
defineQuery,
|
|
5555
5915
|
defineSchema,
|
|
5556
5916
|
defineTable,
|
|
5917
|
+
defineWorkload,
|
|
5557
5918
|
enumType,
|
|
5558
5919
|
exprCtx,
|
|
5559
5920
|
getErrorRegistry,
|
|
@@ -5589,6 +5950,7 @@ var import_zod2 = require("zod");
|
|
|
5589
5950
|
ownerOnly,
|
|
5590
5951
|
policy,
|
|
5591
5952
|
publicChannel,
|
|
5953
|
+
queryManifest,
|
|
5592
5954
|
raw,
|
|
5593
5955
|
recordThrows,
|
|
5594
5956
|
resolveEffectiveAuth,
|