@palbase/backend 33.0.2 → 34.1.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 +2273 -358
- 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-YIQ4RS4F.js → chunk-5UGPXKMJ.js} +331 -5
- package/dist/chunk-5UGPXKMJ.js.map +1 -0
- package/dist/chunk-GHNC2UHS.js +20 -0
- package/dist/chunk-GHNC2UHS.js.map +1 -0
- package/dist/{chunk-AAT5G7KY.js → chunk-JJW3L62T.js} +2 -2
- package/dist/chunk-JJW3L62T.js.map +1 -0
- package/dist/{chunk-SI4KGEM3.js → chunk-P7MGSAFT.js} +102 -96
- package/dist/chunk-P7MGSAFT.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-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-X2UYIXDS.js} +59 -4
- package/dist/chunk-X2UYIXDS.js.map +1 -0
- package/dist/{chunk-C6COAB3E.js → chunk-XZPDPYVY.js} +1905 -195
- package/dist/chunk-XZPDPYVY.js.map +1 -0
- package/dist/{chunk-TVCCR6SO.js → chunk-YO5GYM73.js} +58 -9
- package/dist/chunk-YO5GYM73.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 +285 -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-BXPdsTA5.d.ts} +370 -58
- package/dist/{index-DB_nW-AV.d.cts → endpoint-DqhUP7RT.d.cts} +370 -58
- package/dist/engine/index.cjs +2279 -356
- 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-DLveQoOf.d.cts → index-Co0Hj_aO.d.cts} +108 -50
- package/dist/{index-D-3duy8Y.d.ts → index-MhCL7ll4.d.ts} +108 -50
- package/dist/index.cjs +806 -386
- 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 +27 -15
- package/dist/index.js.map +1 -1
- package/dist/openapi/index.cjs +7 -0
- 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-BkIVHPzB.d.cts} +3 -1
- package/dist/{registry-JjF5lcj4.d.ts → registry-CvGLR5j1.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/auth.md +58 -0
- 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 +382 -1
- package/docs/schema.md +15 -0
- package/package.json +1 -2
- package/template/db/public.ts +12 -0
- package/template/package.json +1 -1
- package/dist/chunk-AAT5G7KY.js.map +0 -1
- package/dist/chunk-C6COAB3E.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,11 +102,13 @@ __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,
|
|
108
109
|
buildContainer: () => buildContainer,
|
|
109
110
|
buildModuleClients: () => buildModuleClients,
|
|
111
|
+
can: () => can,
|
|
110
112
|
col: () => col,
|
|
111
113
|
controllersOf: () => controllersOf,
|
|
112
114
|
dec: () => dec,
|
|
@@ -115,8 +117,10 @@ __export(src_exports, {
|
|
|
115
117
|
defineDefaultAuth: () => defineDefaultAuth,
|
|
116
118
|
defineError: () => defineError,
|
|
117
119
|
defineMiddleware: () => defineMiddleware,
|
|
120
|
+
defineQuery: () => defineQuery,
|
|
118
121
|
defineSchema: () => defineSchema,
|
|
119
122
|
defineTable: () => defineTable,
|
|
123
|
+
defineWorkload: () => defineWorkload,
|
|
120
124
|
enumType: () => enumType,
|
|
121
125
|
exprCtx: () => exprCtx,
|
|
122
126
|
getErrorRegistry: () => getErrorRegistry,
|
|
@@ -152,6 +156,7 @@ __export(src_exports, {
|
|
|
152
156
|
ownerOnly: () => ownerOnly,
|
|
153
157
|
policy: () => policy,
|
|
154
158
|
publicChannel: () => publicChannel,
|
|
159
|
+
queryManifest: () => queryManifest,
|
|
155
160
|
raw: () => raw,
|
|
156
161
|
recordThrows: () => recordThrows,
|
|
157
162
|
resolveEffectiveAuth: () => resolveEffectiveAuth,
|
|
@@ -165,7 +170,7 @@ __export(src_exports, {
|
|
|
165
170
|
vector: () => vector,
|
|
166
171
|
webhooksOf: () => webhooksOf,
|
|
167
172
|
withRetry: () => withRetry,
|
|
168
|
-
z: () =>
|
|
173
|
+
z: () => import_zod4.z
|
|
169
174
|
});
|
|
170
175
|
module.exports = __toCommonJS(src_exports);
|
|
171
176
|
|
|
@@ -741,260 +746,54 @@ function translateRejection(err, builder) {
|
|
|
741
746
|
}
|
|
742
747
|
__name(translateRejection, "translateRejection");
|
|
743
748
|
|
|
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
|
-
}
|
|
749
|
+
// src/db/workload.ts
|
|
750
|
+
function defineWorkload(name, options) {
|
|
951
751
|
const result = {
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
}
|
|
960
|
-
return runTxPlan(raw2, {
|
|
961
|
-
tables: planTables
|
|
962
|
-
}, builder, fn);
|
|
963
|
-
}
|
|
752
|
+
name,
|
|
753
|
+
concurrency: options.concurrency,
|
|
754
|
+
queueLimit: options.queueLimit,
|
|
755
|
+
tenantConcurrency: options.tenantConcurrency ?? options.concurrency,
|
|
756
|
+
tenantQueueLimit: options.tenantQueueLimit ?? options.queueLimit,
|
|
757
|
+
queueTimeoutMs: options.queueTimeoutMs ?? 1e3,
|
|
758
|
+
tenantClaim: options.tenantClaim ?? "tenant_id"
|
|
964
759
|
};
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
760
|
+
validateWorkload(result);
|
|
761
|
+
return Object.freeze(result);
|
|
762
|
+
}
|
|
763
|
+
__name(defineWorkload, "defineWorkload");
|
|
764
|
+
function validateWorkload(value) {
|
|
765
|
+
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");
|
|
766
|
+
for (const name of [
|
|
767
|
+
"concurrency",
|
|
768
|
+
"tenantConcurrency",
|
|
769
|
+
"queueLimit",
|
|
770
|
+
"tenantQueueLimit",
|
|
771
|
+
"queueTimeoutMs"
|
|
772
|
+
]) {
|
|
773
|
+
const n = value[name], min = name.endsWith("Limit") ? 0 : 1;
|
|
774
|
+
const max = name === "queueTimeoutMs" ? 6e4 : name.endsWith("Limit") ? 1e4 : 1e3;
|
|
775
|
+
if (!Number.isInteger(n) || n < min || n > max) throw new Error(`workload ${name} must be an integer between ${min} and ${max}`);
|
|
776
|
+
}
|
|
777
|
+
if (value.tenantConcurrency > value.concurrency || value.tenantQueueLimit > value.queueLimit) throw new Error("workload tenant limits cannot exceed global limits");
|
|
778
|
+
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");
|
|
779
|
+
}
|
|
780
|
+
__name(validateWorkload, "validateWorkload");
|
|
781
|
+
|
|
782
|
+
// src/db/transaction-options.ts
|
|
783
|
+
function retryBudget(value) {
|
|
784
|
+
const n = value ?? 0;
|
|
785
|
+
if (!Number.isInteger(n) || n < 0 || n > 10) {
|
|
786
|
+
throw new Error("transaction retry must be an integer between 0 and 10");
|
|
984
787
|
}
|
|
788
|
+
return n;
|
|
985
789
|
}
|
|
986
|
-
__name(
|
|
987
|
-
function
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
...strings
|
|
992
|
-
],
|
|
993
|
-
values
|
|
994
|
-
}
|
|
995
|
-
}, "sql");
|
|
790
|
+
__name(retryBudget, "retryBudget");
|
|
791
|
+
function assertPlanRetry(options) {
|
|
792
|
+
if (retryBudget(options?.retry) !== 0) {
|
|
793
|
+
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.");
|
|
794
|
+
}
|
|
996
795
|
}
|
|
997
|
-
__name(
|
|
796
|
+
__name(assertPlanRetry, "assertPlanRetry");
|
|
998
797
|
|
|
999
798
|
// src/db/schema-json.ts
|
|
1000
799
|
function defOf(column) {
|
|
@@ -1177,6 +976,11 @@ function tableToJSON(table, schemaName) {
|
|
|
1177
976
|
// drifts — the direction it drifted last time was "expose everything", and
|
|
1178
977
|
// the live proof was one user reading another's rows.
|
|
1179
978
|
rls: table.rls,
|
|
979
|
+
// KOŞAN SÜRÜMÜN SÖZÜ TELE ÇIKAR — yoksa daralma kapısı onu göremez.
|
|
980
|
+
// `ColumnJSON.ignored` ile aynı sözleşme: işaretlenmemişse alan YOK.
|
|
981
|
+
...table.ignored === true ? {
|
|
982
|
+
ignored: true
|
|
983
|
+
} : {},
|
|
1180
984
|
policies: (table.policies ?? []).map(policyToJSON)
|
|
1181
985
|
};
|
|
1182
986
|
if (table.primaryKey !== void 0 && table.primaryKey.length > 0) {
|
|
@@ -1407,6 +1211,14 @@ function makeTableProxy(ops, prefix) {
|
|
|
1407
1211
|
update: /* @__PURE__ */ __name((q) => ops().update(name, q.where.id, q.set), "update"),
|
|
1408
1212
|
delete: /* @__PURE__ */ __name((id) => ops().delete(name, id), "delete"),
|
|
1409
1213
|
findById: /* @__PURE__ */ __name((id) => ops().findById(name, id), "findById"),
|
|
1214
|
+
findUnique: /* @__PURE__ */ __name((q) => ops().findUnique(name, q.where, {
|
|
1215
|
+
select: q.select,
|
|
1216
|
+
with: q.with
|
|
1217
|
+
}), "findUnique"),
|
|
1218
|
+
page: /* @__PURE__ */ __name((q) => {
|
|
1219
|
+
const { where, ...opts } = q ?? {};
|
|
1220
|
+
return ops().page(name, where, opts);
|
|
1221
|
+
}, "page"),
|
|
1410
1222
|
findMany: /* @__PURE__ */ __name((q) => {
|
|
1411
1223
|
const { where, ...opts } = q ?? {};
|
|
1412
1224
|
return ops().findMany(name, where, opts);
|
|
@@ -1444,10 +1256,16 @@ function makeTypedSurface(raw2) {
|
|
|
1444
1256
|
const reco = raw2;
|
|
1445
1257
|
const ops = {
|
|
1446
1258
|
$query: /* @__PURE__ */ __name((sql, params) => raw2.query(sql, params), "$query"),
|
|
1259
|
+
$diagnostics: /* @__PURE__ */ __name(() => raw2.diagnostics(), "$diagnostics"),
|
|
1260
|
+
$readQuery: /* @__PURE__ */ __name((query) => raw2.readQuery(query), "$readQuery"),
|
|
1261
|
+
$compileQuery: /* @__PURE__ */ __name((query) => raw2.compileQuery(query), "$compileQuery"),
|
|
1262
|
+
$explainQuery: /* @__PURE__ */ __name((query) => raw2.explainQuery(query), "$explainQuery"),
|
|
1447
1263
|
$insert: /* @__PURE__ */ __name((table, data) => raw2.insert(table, data), "$insert"),
|
|
1448
1264
|
$update: /* @__PURE__ */ __name((table, id, data) => raw2.update(table, id, data), "$update"),
|
|
1449
1265
|
$delete: /* @__PURE__ */ __name((table, id) => raw2.delete(table, id), "$delete"),
|
|
1450
1266
|
$findById: /* @__PURE__ */ __name((table, id) => raw2.findById(table, id), "$findById"),
|
|
1267
|
+
$findUnique: /* @__PURE__ */ __name((table, where, opts) => raw2.findUnique(table, where, opts), "$findUnique"),
|
|
1268
|
+
$page: /* @__PURE__ */ __name((table, query, opts) => raw2.page(table, query, opts), "$page"),
|
|
1451
1269
|
$findMany: /* @__PURE__ */ __name((table, query, opts) => raw2.findMany(table, query, opts), "$findMany"),
|
|
1452
1270
|
$put: /* @__PURE__ */ __name((table, data, opts) => raw2.put(table, data, opts), "$put"),
|
|
1453
1271
|
// `opts` İLETİLİR. Düşürüldüğü sürece `Database.$updateMany(t, w, s,
|
|
@@ -1470,16 +1288,51 @@ function makeTypedSurface(raw2) {
|
|
|
1470
1288
|
$supersede: /* @__PURE__ */ __name((table, id, row) => raw2.supersede(table, id, row), "$supersede")
|
|
1471
1289
|
};
|
|
1472
1290
|
const base = Object.assign(ops, {
|
|
1291
|
+
$atomic(fn, options) {
|
|
1292
|
+
if (typeof raw2.atomic !== "function") {
|
|
1293
|
+
throw new Error("This Database handle cannot open a root transaction; nested $atomic is not supported");
|
|
1294
|
+
}
|
|
1295
|
+
const parent = __requestALS.getStore();
|
|
1296
|
+
let runtime2;
|
|
1297
|
+
try {
|
|
1298
|
+
runtime2 = __getRuntime();
|
|
1299
|
+
} catch {
|
|
1300
|
+
}
|
|
1301
|
+
return raw2.atomic(async (tx) => {
|
|
1302
|
+
const typed = makeTypedSurface(tx);
|
|
1303
|
+
const invoke = /* @__PURE__ */ __name(() => fn(typed), "invoke");
|
|
1304
|
+
if (!runtime2) return invoke();
|
|
1305
|
+
const refuse2 = /* @__PURE__ */ __name(() => {
|
|
1306
|
+
throw new Error("Database.$atomic owns one transaction and identity; nested roots and $asService are not allowed");
|
|
1307
|
+
}, "refuse");
|
|
1308
|
+
const ambient = Object.assign({}, tx, {
|
|
1309
|
+
atomic: refuse2,
|
|
1310
|
+
asService: refuse2
|
|
1311
|
+
});
|
|
1312
|
+
return __requestALS.run({
|
|
1313
|
+
...parent,
|
|
1314
|
+
runtime: {
|
|
1315
|
+
...runtime2,
|
|
1316
|
+
Database: ambient
|
|
1317
|
+
}
|
|
1318
|
+
}, invoke);
|
|
1319
|
+
}, options);
|
|
1320
|
+
},
|
|
1473
1321
|
// Both surfaces get it: a savepoint on the service transaction is as useful
|
|
1474
1322
|
// as one on the request's, and each is bound to its own connection.
|
|
1475
1323
|
$attempt: /* @__PURE__ */ __name((fn) => raw2.attempt(fn), "$attempt"),
|
|
1476
1324
|
$transaction(fn, opts) {
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1325
|
+
assertPlanRetry(opts);
|
|
1326
|
+
const builder = new TxPlanBuilder();
|
|
1327
|
+
return runTxPlan(raw2, makeTxPlanHandle(builder), builder, fn);
|
|
1328
|
+
},
|
|
1329
|
+
$command(fn, options) {
|
|
1330
|
+
const builder = new TxPlanBuilder();
|
|
1331
|
+
return runTxPlan({
|
|
1332
|
+
txPlan: /* @__PURE__ */ __name((plan) => raw2.command(plan, options), "txPlan")
|
|
1333
|
+
}, makeTxPlanHandle(builder), builder, fn);
|
|
1334
|
+
}
|
|
1335
|
+
});
|
|
1483
1336
|
return new Proxy(base, {
|
|
1484
1337
|
get(target, prop, receiver) {
|
|
1485
1338
|
if (prop === "tables") return makeTableProxy(() => reco, "");
|
|
@@ -2738,6 +2591,7 @@ function buildModuleClients(cfg) {
|
|
|
2738
2591
|
__name(buildModuleClients, "buildModuleClients");
|
|
2739
2592
|
|
|
2740
2593
|
// src/db/policy.ts
|
|
2594
|
+
var import_zod = require("zod");
|
|
2741
2595
|
var PolicyExprRef = class _PolicyExprRef {
|
|
2742
2596
|
static {
|
|
2743
2597
|
__name(this, "PolicyExprRef");
|
|
@@ -2970,6 +2824,45 @@ function policy(name) {
|
|
|
2970
2824
|
return new PolicyBuilder(name);
|
|
2971
2825
|
}
|
|
2972
2826
|
__name(policy, "policy");
|
|
2827
|
+
function can(table) {
|
|
2828
|
+
const def = table;
|
|
2829
|
+
if (typeof def.name !== "string" || def.columns === null || typeof def.columns !== "object" || !Array.isArray(def.policies)) {
|
|
2830
|
+
throw new Error("can(<table>): expects the schema's table definition \u2014 can(publicSchema.tables.notes) \u2014 not the defineTable handle (`notes`)");
|
|
2831
|
+
}
|
|
2832
|
+
if (Object.prototype.hasOwnProperty.call(table.columns, "can")) {
|
|
2833
|
+
throw new Error(`can(${table.name}): the table declares a column named "can", so the row carries that column and no policy echo \u2014 rename the column to get can`);
|
|
2834
|
+
}
|
|
2835
|
+
const rel = reservedCanRelation(table.name, table.columns);
|
|
2836
|
+
if (rel !== null) {
|
|
2837
|
+
throw new Error(`can(${table.name}): ${rel}`);
|
|
2838
|
+
}
|
|
2839
|
+
const names = table.policies.filter((p) => p.command === "update" && p.permissive !== false && Buffer.byteLength(`can:${p.name}`, "utf8") <= 63).map((p) => p.name);
|
|
2840
|
+
if (names.length === 0) {
|
|
2841
|
+
const all = table.policies.filter((p) => p.command === "all").map((p) => p.name);
|
|
2842
|
+
const hint = all.length > 0 ? ` The table's ${all.map((n) => `"${n}"`).join(", ")} ${all.length === 1 ? "policy is" : "policies are"} for("all") \u2014 for("all") governs UPDATE but is not a named update policy and never appears in can.` : "";
|
|
2843
|
+
throw new Error(`can(${table.name}): the table declares no update policy \u2014 there is nothing a row could echo. Name one with policy("<name>").for("update").using(\u2026) first.${hint}`);
|
|
2844
|
+
}
|
|
2845
|
+
return import_zod.z.array(import_zod.z.enum(names));
|
|
2846
|
+
}
|
|
2847
|
+
__name(can, "can");
|
|
2848
|
+
function reservedCanRelation(tableName, columns) {
|
|
2849
|
+
if (tableName === "can") {
|
|
2850
|
+
return `a table named "can" would put a relation named "can" on every parent it references \u2014 rename the table`;
|
|
2851
|
+
}
|
|
2852
|
+
for (const [col2, b] of Object.entries(columns)) {
|
|
2853
|
+
const def = b._def;
|
|
2854
|
+
if (def.referencesThunk === void 0 && def.selfRefColumn === void 0) continue;
|
|
2855
|
+
if (def.reverseAs === "can") {
|
|
2856
|
+
return `column "${col2}" names its reverse relation "can" \u2014 the parent's rows would carry a relation where can is reserved; pick another reverseAs`;
|
|
2857
|
+
}
|
|
2858
|
+
const forward = def.owns === true ? "owner" : def.refAs ?? (col2.endsWith("_id") ? col2.slice(0, -3) : col2);
|
|
2859
|
+
if (forward === "can") {
|
|
2860
|
+
return `column "${col2}" would be read as a relation named "can" (${def.refAs === void 0 ? "derived from the column name" : "its as: option"}) \u2014 can is reserved for the policy echo; rename it`;
|
|
2861
|
+
}
|
|
2862
|
+
}
|
|
2863
|
+
return null;
|
|
2864
|
+
}
|
|
2865
|
+
__name(reservedCanRelation, "reservedCanRelation");
|
|
2973
2866
|
|
|
2974
2867
|
// src/db/schema.ts
|
|
2975
2868
|
var IndexBuilder = class {
|
|
@@ -3047,6 +2940,10 @@ function defineTable(name, input) {
|
|
|
3047
2940
|
if (name.trim() === "") {
|
|
3048
2941
|
throw new Error("defineTable(name, \u2026): name must not be empty");
|
|
3049
2942
|
}
|
|
2943
|
+
{
|
|
2944
|
+
const reserved = reservedCanRelation(name, input.columns);
|
|
2945
|
+
if (reserved !== null) throw new Error(`defineTable(${JSON.stringify(name)}): ${reserved}`);
|
|
2946
|
+
}
|
|
3050
2947
|
const policies = (input.policies?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(toPolicyDef);
|
|
3051
2948
|
const rls = policies.length > 0 || input.rls !== false;
|
|
3052
2949
|
const owned2 = {};
|
|
@@ -3075,6 +2972,7 @@ function defineTable(name, input) {
|
|
|
3075
2972
|
const declaredIndexes = (input.indexes?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map((i) => i instanceof IndexBuilder ? i._def : i);
|
|
3076
2973
|
if (declaredIndexes.length > 0) def.indexes = declaredIndexes;
|
|
3077
2974
|
if (input.appendOnly === true) def.appendOnly = true;
|
|
2975
|
+
if (input.ignored === true) def.ignored = true;
|
|
3078
2976
|
if (input.search !== void 0) {
|
|
3079
2977
|
const s = input.search;
|
|
3080
2978
|
if (s.from !== void 0) {
|
|
@@ -3134,6 +3032,13 @@ function defineTable(name, input) {
|
|
|
3134
3032
|
}
|
|
3135
3033
|
__name(defineTable, "defineTable");
|
|
3136
3034
|
var declaringSchemaOf = /* @__PURE__ */ new WeakMap();
|
|
3035
|
+
function declaredTableKey(table) {
|
|
3036
|
+
const metadata = table[TABLE_META];
|
|
3037
|
+
const schema = declaringSchemaOf.get(metadata);
|
|
3038
|
+
if (schema === void 0) throw new Error(`defineQuery: table ${metadata.name} must belong to defineSchema before defining its query`);
|
|
3039
|
+
return qualifiedTableKey(schema, metadata.name);
|
|
3040
|
+
}
|
|
3041
|
+
__name(declaredTableKey, "declaredTableKey");
|
|
3137
3042
|
function resolveReferences(tables, schemaName) {
|
|
3138
3043
|
for (const table of Object.values(tables)) {
|
|
3139
3044
|
for (const [colName, builder] of Object.entries(table.columns)) {
|
|
@@ -3603,135 +3508,424 @@ var ColumnBuilder = class _ColumnBuilder {
|
|
|
3603
3508
|
codec
|
|
3604
3509
|
});
|
|
3605
3510
|
}
|
|
3606
|
-
transform(fns) {
|
|
3607
|
-
if (this._def.codec !== void 0) {
|
|
3608
|
-
throw new Error(`column already declares a named codec; .transform() and .as*() are two ways to say the same thing \u2014 keep the codec.`);
|
|
3609
|
-
}
|
|
3610
|
-
return new _ColumnBuilder(this._def.type, {
|
|
3611
|
-
...this._def,
|
|
3612
|
-
transform: fns
|
|
3613
|
-
});
|
|
3511
|
+
transform(fns) {
|
|
3512
|
+
if (this._def.codec !== void 0) {
|
|
3513
|
+
throw new Error(`column already declares a named codec; .transform() and .as*() are two ways to say the same thing \u2014 keep the codec.`);
|
|
3514
|
+
}
|
|
3515
|
+
return new _ColumnBuilder(this._def.type, {
|
|
3516
|
+
...this._def,
|
|
3517
|
+
transform: fns
|
|
3518
|
+
});
|
|
3519
|
+
}
|
|
3520
|
+
};
|
|
3521
|
+
function uuid() {
|
|
3522
|
+
return new ColumnBuilder("uuid");
|
|
3523
|
+
}
|
|
3524
|
+
__name(uuid, "uuid");
|
|
3525
|
+
function text() {
|
|
3526
|
+
return new ColumnBuilder("text");
|
|
3527
|
+
}
|
|
3528
|
+
__name(text, "text");
|
|
3529
|
+
function integer() {
|
|
3530
|
+
return new ColumnBuilder("integer");
|
|
3531
|
+
}
|
|
3532
|
+
__name(integer, "integer");
|
|
3533
|
+
function bigint() {
|
|
3534
|
+
return new ColumnBuilder("bigint");
|
|
3535
|
+
}
|
|
3536
|
+
__name(bigint, "bigint");
|
|
3537
|
+
function numeric() {
|
|
3538
|
+
return new ColumnBuilder("numeric");
|
|
3539
|
+
}
|
|
3540
|
+
__name(numeric, "numeric");
|
|
3541
|
+
function boolean() {
|
|
3542
|
+
return new ColumnBuilder("boolean");
|
|
3543
|
+
}
|
|
3544
|
+
__name(boolean, "boolean");
|
|
3545
|
+
function timestamp() {
|
|
3546
|
+
return new ColumnBuilder("timestamp");
|
|
3547
|
+
}
|
|
3548
|
+
__name(timestamp, "timestamp");
|
|
3549
|
+
function jsonb() {
|
|
3550
|
+
return new ColumnBuilder("jsonb");
|
|
3551
|
+
}
|
|
3552
|
+
__name(jsonb, "jsonb");
|
|
3553
|
+
function enumType(name, values) {
|
|
3554
|
+
const builder = new ColumnBuilder("enum");
|
|
3555
|
+
builder._def.enumName = name;
|
|
3556
|
+
builder._def.enumValues = [
|
|
3557
|
+
...values
|
|
3558
|
+
];
|
|
3559
|
+
return builder;
|
|
3560
|
+
}
|
|
3561
|
+
__name(enumType, "enumType");
|
|
3562
|
+
function vector(dimensions) {
|
|
3563
|
+
if (!Number.isInteger(dimensions) || dimensions < 1 || dimensions > 2e3) {
|
|
3564
|
+
throw new Error(`vector(): dimensions must be an integer in [1, 2000], got ${String(dimensions)}`);
|
|
3565
|
+
}
|
|
3566
|
+
const b = new ColumnBuilder("vector");
|
|
3567
|
+
b._def.dimensions = dimensions;
|
|
3568
|
+
return b;
|
|
3569
|
+
}
|
|
3570
|
+
__name(vector, "vector");
|
|
3571
|
+
function ownedByUser() {
|
|
3572
|
+
const b = new ColumnBuilder("text");
|
|
3573
|
+
b._def.nullable = false;
|
|
3574
|
+
b._def.references = {
|
|
3575
|
+
table: "auth.users",
|
|
3576
|
+
column: "id"
|
|
3577
|
+
};
|
|
3578
|
+
b._def.onDeleteAction = "cascade";
|
|
3579
|
+
b._def.owns = true;
|
|
3580
|
+
return b;
|
|
3581
|
+
}
|
|
3582
|
+
__name(ownedByUser, "ownedByUser");
|
|
3583
|
+
function userRef(opts) {
|
|
3584
|
+
const b = new ColumnBuilder("text");
|
|
3585
|
+
b._def.references = {
|
|
3586
|
+
table: "auth.users",
|
|
3587
|
+
column: "id"
|
|
3588
|
+
};
|
|
3589
|
+
b._def.onDeleteAction = opts.onDelete;
|
|
3590
|
+
if (opts.as !== void 0) b._def.refAs = opts.as;
|
|
3591
|
+
return b;
|
|
3592
|
+
}
|
|
3593
|
+
__name(userRef, "userRef");
|
|
3594
|
+
function installationRef(opts) {
|
|
3595
|
+
const b = new ColumnBuilder("text");
|
|
3596
|
+
b._def.references = {
|
|
3597
|
+
table: "auth.installations",
|
|
3598
|
+
column: "id"
|
|
3599
|
+
};
|
|
3600
|
+
b._def.onDeleteAction = opts.onDelete;
|
|
3601
|
+
if (opts.as !== void 0) b._def.refAs = opts.as;
|
|
3602
|
+
return b;
|
|
3603
|
+
}
|
|
3604
|
+
__name(installationRef, "installationRef");
|
|
3605
|
+
|
|
3606
|
+
// src/db/raw.ts
|
|
3607
|
+
function raw(name, up, opts) {
|
|
3608
|
+
return {
|
|
3609
|
+
name,
|
|
3610
|
+
up,
|
|
3611
|
+
...opts?.down != null ? {
|
|
3612
|
+
down: opts.down
|
|
3613
|
+
} : {}
|
|
3614
|
+
};
|
|
3615
|
+
}
|
|
3616
|
+
__name(raw, "raw");
|
|
3617
|
+
|
|
3618
|
+
// src/db/embedding.ts
|
|
3619
|
+
var openai = {
|
|
3620
|
+
embedding(model, opts) {
|
|
3621
|
+
return {
|
|
3622
|
+
provider: "openai",
|
|
3623
|
+
model,
|
|
3624
|
+
apiKeyName: opts?.apiKeyName ?? "OPENAI_API_KEY",
|
|
3625
|
+
...opts?.dimensions !== void 0 ? {
|
|
3626
|
+
dimensions: opts.dimensions
|
|
3627
|
+
} : {},
|
|
3628
|
+
...opts?.baseURL !== void 0 ? {
|
|
3629
|
+
baseURL: opts.baseURL
|
|
3630
|
+
} : {}
|
|
3631
|
+
};
|
|
3632
|
+
},
|
|
3633
|
+
chat(model) {
|
|
3634
|
+
return {
|
|
3635
|
+
provider: "openai",
|
|
3636
|
+
model
|
|
3637
|
+
};
|
|
3638
|
+
}
|
|
3639
|
+
};
|
|
3640
|
+
|
|
3641
|
+
// src/db/sqlstate.ts
|
|
3642
|
+
var SQLSTATE = Object.freeze({
|
|
3643
|
+
serializationFailure: "40001",
|
|
3644
|
+
deadlockDetected: "40P01",
|
|
3645
|
+
commandGuardFailed: "PBC01"
|
|
3646
|
+
});
|
|
3647
|
+
function isTransactionRollbackState(state) {
|
|
3648
|
+
return state === SQLSTATE.serializationFailure || state === SQLSTATE.deadlockDetected;
|
|
3649
|
+
}
|
|
3650
|
+
__name(isTransactionRollbackState, "isTransactionRollbackState");
|
|
3651
|
+
|
|
3652
|
+
// src/errors.ts
|
|
3653
|
+
var HTTP_ERROR_BRAND = /* @__PURE__ */ Symbol.for("palbase.backend.httpError");
|
|
3654
|
+
var HttpError = class extends Error {
|
|
3655
|
+
static {
|
|
3656
|
+
__name(this, "HttpError");
|
|
3657
|
+
}
|
|
3658
|
+
status;
|
|
3659
|
+
error;
|
|
3660
|
+
errorDescription;
|
|
3661
|
+
data;
|
|
3662
|
+
/** See {@link HTTP_ERROR_BRAND} — how the engine recognises this across SDK copies. */
|
|
3663
|
+
[HTTP_ERROR_BRAND] = true;
|
|
3664
|
+
constructor(status, error, errorDescription, data) {
|
|
3665
|
+
super(errorDescription);
|
|
3666
|
+
this.name = "HttpError";
|
|
3667
|
+
this.status = status;
|
|
3668
|
+
this.error = error;
|
|
3669
|
+
this.errorDescription = errorDescription;
|
|
3670
|
+
if (data !== void 0) {
|
|
3671
|
+
this.data = data;
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
/**
|
|
3675
|
+
* Serialize to the standard Palbase error response format.
|
|
3676
|
+
* The `requestId` is injected by the runtime layer from the request context.
|
|
3677
|
+
* When called without arguments (e.g. JSON.stringify), request_id is omitted.
|
|
3678
|
+
* When `data` is set, it is appended as a strict-superset field.
|
|
3679
|
+
*/
|
|
3680
|
+
toJSON(requestId) {
|
|
3681
|
+
const result = {
|
|
3682
|
+
error: this.error,
|
|
3683
|
+
error_description: this.errorDescription,
|
|
3684
|
+
status: this.status
|
|
3685
|
+
};
|
|
3686
|
+
if (requestId) {
|
|
3687
|
+
result.request_id = requestId;
|
|
3688
|
+
}
|
|
3689
|
+
if (this.data !== void 0) {
|
|
3690
|
+
result.data = this.data;
|
|
3691
|
+
}
|
|
3692
|
+
return result;
|
|
3693
|
+
}
|
|
3694
|
+
};
|
|
3695
|
+
var PalError = class extends HttpError {
|
|
3696
|
+
static {
|
|
3697
|
+
__name(this, "PalError");
|
|
3698
|
+
}
|
|
3699
|
+
constructor(status, code, description, data) {
|
|
3700
|
+
super(status, code, description, data);
|
|
3701
|
+
this.name = "PalError";
|
|
3702
|
+
}
|
|
3703
|
+
};
|
|
3704
|
+
var NamedHttpError = class NamedHttpError2 extends HttpError {
|
|
3705
|
+
static {
|
|
3706
|
+
__name(this, "NamedHttpError");
|
|
3707
|
+
}
|
|
3708
|
+
constructor(status, defaultCode, name, message, code, data) {
|
|
3709
|
+
super(status, code ?? defaultCode, message ?? defaultMessage(name), data);
|
|
3710
|
+
this.name = name;
|
|
3711
|
+
}
|
|
3712
|
+
};
|
|
3713
|
+
function defaultMessage(name) {
|
|
3714
|
+
const spaced = name.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
|
|
3715
|
+
return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
|
|
3716
|
+
}
|
|
3717
|
+
__name(defaultMessage, "defaultMessage");
|
|
3718
|
+
var BadRequest = class extends NamedHttpError {
|
|
3719
|
+
static {
|
|
3720
|
+
__name(this, "BadRequest");
|
|
3721
|
+
}
|
|
3722
|
+
constructor(data, message) {
|
|
3723
|
+
super(400, "bad_request", "BadRequest", message, void 0, data);
|
|
3724
|
+
}
|
|
3725
|
+
};
|
|
3726
|
+
var Unauthorized = class extends NamedHttpError {
|
|
3727
|
+
static {
|
|
3728
|
+
__name(this, "Unauthorized");
|
|
3729
|
+
}
|
|
3730
|
+
constructor(message, code, data) {
|
|
3731
|
+
super(401, "unauthorized", "Unauthorized", message, code, data);
|
|
3732
|
+
}
|
|
3733
|
+
};
|
|
3734
|
+
var Forbidden = class extends NamedHttpError {
|
|
3735
|
+
static {
|
|
3736
|
+
__name(this, "Forbidden");
|
|
3737
|
+
}
|
|
3738
|
+
constructor(message, code, data) {
|
|
3739
|
+
super(403, "forbidden", "Forbidden", message, code, data);
|
|
3740
|
+
}
|
|
3741
|
+
};
|
|
3742
|
+
var NotFound = class extends NamedHttpError {
|
|
3743
|
+
static {
|
|
3744
|
+
__name(this, "NotFound");
|
|
3745
|
+
}
|
|
3746
|
+
constructor(message, code, data) {
|
|
3747
|
+
super(404, "not_found", "NotFound", message, code, data);
|
|
3748
|
+
}
|
|
3749
|
+
};
|
|
3750
|
+
var Conflict = class extends NamedHttpError {
|
|
3751
|
+
static {
|
|
3752
|
+
__name(this, "Conflict");
|
|
3753
|
+
}
|
|
3754
|
+
constructor(message, code, data) {
|
|
3755
|
+
super(409, "conflict", "Conflict", message, code, data);
|
|
3756
|
+
}
|
|
3757
|
+
};
|
|
3758
|
+
var UniqueViolation = class extends Conflict {
|
|
3759
|
+
static {
|
|
3760
|
+
__name(this, "UniqueViolation");
|
|
3761
|
+
}
|
|
3762
|
+
/**
|
|
3763
|
+
* Whether `e` is a unique violation — REGARDLESS of which copy of this SDK
|
|
3764
|
+
* constructed it.
|
|
3765
|
+
*
|
|
3766
|
+
* Use this instead of `instanceof`. Measured on a live stack: a controller
|
|
3767
|
+
* bundle INLINES its own copy of `@palbase/backend`, and the engine that
|
|
3768
|
+
* raises this error is the runtime's copy. Two copies, two class identities,
|
|
3769
|
+
* and `e instanceof UniqueViolation` is false in the one place a caller
|
|
3770
|
+
* writes it — a check that reads as correct and silently never matches.
|
|
3771
|
+
*/
|
|
3772
|
+
static is(e) {
|
|
3773
|
+
return typeof e === "object" && e !== null && e.name === "UniqueViolation" && typeof e.constraint === "string";
|
|
3774
|
+
}
|
|
3775
|
+
/** The unique constraint the statement violated, as Postgres named it.
|
|
3776
|
+
* `""` when the driver did not say which — see `engine/db.ts`. */
|
|
3777
|
+
constraint;
|
|
3778
|
+
constructor(constraint, message, code, data) {
|
|
3779
|
+
super(message ?? "Unique constraint violated", code ?? "unique_violation", data);
|
|
3780
|
+
this.name = "UniqueViolation";
|
|
3781
|
+
this.constraint = constraint;
|
|
3782
|
+
}
|
|
3783
|
+
};
|
|
3784
|
+
function isRetryable(e) {
|
|
3785
|
+
return typeof e === "object" && e !== null && e.retryable === true && isTransactionRollbackState(e.sqlstate);
|
|
3786
|
+
}
|
|
3787
|
+
__name(isRetryable, "isRetryable");
|
|
3788
|
+
var SerializationFailure = class extends Conflict {
|
|
3789
|
+
static {
|
|
3790
|
+
__name(this, "SerializationFailure");
|
|
3791
|
+
}
|
|
3792
|
+
retryable = true;
|
|
3793
|
+
sqlstate;
|
|
3794
|
+
static is(e) {
|
|
3795
|
+
return typeof e === "object" && e !== null && e.name === "SerializationFailure";
|
|
3796
|
+
}
|
|
3797
|
+
constructor(sqlstate = SQLSTATE.serializationFailure, message, data) {
|
|
3798
|
+
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);
|
|
3799
|
+
this.name = "SerializationFailure";
|
|
3800
|
+
this.sqlstate = sqlstate;
|
|
3801
|
+
}
|
|
3802
|
+
};
|
|
3803
|
+
var DeadlockDetected = class extends Conflict {
|
|
3804
|
+
static {
|
|
3805
|
+
__name(this, "DeadlockDetected");
|
|
3806
|
+
}
|
|
3807
|
+
retryable = true;
|
|
3808
|
+
sqlstate;
|
|
3809
|
+
static is(e) {
|
|
3810
|
+
return typeof e === "object" && e !== null && e.name === "DeadlockDetected";
|
|
3811
|
+
}
|
|
3812
|
+
constructor(sqlstate = SQLSTATE.deadlockDetected, message, data) {
|
|
3813
|
+
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);
|
|
3814
|
+
this.name = "DeadlockDetected";
|
|
3815
|
+
this.sqlstate = sqlstate;
|
|
3816
|
+
}
|
|
3817
|
+
};
|
|
3818
|
+
var TooManyRequests = class extends NamedHttpError {
|
|
3819
|
+
static {
|
|
3820
|
+
__name(this, "TooManyRequests");
|
|
3821
|
+
}
|
|
3822
|
+
constructor(data, message) {
|
|
3823
|
+
super(429, "too_many_requests", "TooManyRequests", message, void 0, data);
|
|
3614
3824
|
}
|
|
3615
3825
|
};
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
__name(
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
__name(
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
}
|
|
3631
|
-
__name(
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
}
|
|
3643
|
-
__name(
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
}
|
|
3647
|
-
__name(jsonb, "jsonb");
|
|
3648
|
-
function enumType(name, values) {
|
|
3649
|
-
const builder = new ColumnBuilder("enum");
|
|
3650
|
-
builder._def.enumName = name;
|
|
3651
|
-
builder._def.enumValues = [
|
|
3652
|
-
...values
|
|
3653
|
-
];
|
|
3654
|
-
return builder;
|
|
3826
|
+
|
|
3827
|
+
// src/db/typed-db.ts
|
|
3828
|
+
function makeTypedTable(name, raw2) {
|
|
3829
|
+
return {
|
|
3830
|
+
insert: /* @__PURE__ */ __name((data) => raw2.insert(name, data), "insert"),
|
|
3831
|
+
aggregate: /* @__PURE__ */ __name((q) => raw2.aggregate(name, q), "aggregate"),
|
|
3832
|
+
insertMany: /* @__PURE__ */ __name((rows, opts) => raw2.insertMany(name, rows, opts), "insertMany"),
|
|
3833
|
+
put: /* @__PURE__ */ __name((q) => raw2.put(name, q.data, {
|
|
3834
|
+
onConflict: q.onConflict
|
|
3835
|
+
}), "put"),
|
|
3836
|
+
update: /* @__PURE__ */ __name((q) => raw2.update(name, q.where.id, q.set), "update"),
|
|
3837
|
+
delete: /* @__PURE__ */ __name((id) => raw2.delete(name, id), "delete"),
|
|
3838
|
+
findUnique: /* @__PURE__ */ __name((q) => raw2.findUnique(name, q.where, {
|
|
3839
|
+
select: q.select
|
|
3840
|
+
}), "findUnique"),
|
|
3841
|
+
findById: /* @__PURE__ */ __name((id) => raw2.findById(name, id), "findById"),
|
|
3842
|
+
page: /* @__PURE__ */ __name((q) => {
|
|
3843
|
+
const { where, ...opts } = q ?? {};
|
|
3844
|
+
return raw2.page(name, where, opts);
|
|
3845
|
+
}, "page"),
|
|
3846
|
+
findMany: /* @__PURE__ */ __name((q) => {
|
|
3847
|
+
const { where, ...opts } = q ?? {};
|
|
3848
|
+
return raw2.findMany(name, where, opts);
|
|
3849
|
+
}, "findMany"),
|
|
3850
|
+
updateMany: /* @__PURE__ */ __name((q) => raw2.updateMany(name, q.where, q.set, q.returning === void 0 ? void 0 : {
|
|
3851
|
+
returning: q.returning
|
|
3852
|
+
}), "updateMany"),
|
|
3853
|
+
deleteMany: /* @__PURE__ */ __name((q) => raw2.deleteMany(name, q.where), "deleteMany"),
|
|
3854
|
+
count: /* @__PURE__ */ __name((q) => raw2.count(name, q?.where), "count")
|
|
3855
|
+
};
|
|
3655
3856
|
}
|
|
3656
|
-
__name(
|
|
3657
|
-
function
|
|
3658
|
-
|
|
3659
|
-
|
|
3857
|
+
__name(makeTypedTable, "makeTypedTable");
|
|
3858
|
+
function makeTypedDB(schema, raw2) {
|
|
3859
|
+
const tables = {};
|
|
3860
|
+
for (const key of Object.keys(schema.tables)) {
|
|
3861
|
+
const tableDef = schema.tables[key];
|
|
3862
|
+
if (tableDef !== void 0) {
|
|
3863
|
+
tables[key] = makeTypedTable(qualifiedTableKey(schema.name, tableDef.name), raw2);
|
|
3864
|
+
}
|
|
3660
3865
|
}
|
|
3661
|
-
const
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
__name(
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3866
|
+
const result = {
|
|
3867
|
+
tables,
|
|
3868
|
+
diagnostics: /* @__PURE__ */ __name(() => raw2.diagnostics(), "diagnostics"),
|
|
3869
|
+
readQuery: /* @__PURE__ */ __name((query) => raw2.readQuery(query), "readQuery"),
|
|
3870
|
+
compileQuery: /* @__PURE__ */ __name((query) => raw2.compileQuery(query), "compileQuery"),
|
|
3871
|
+
explainQuery: /* @__PURE__ */ __name((query) => raw2.explainQuery(query), "explainQuery"),
|
|
3872
|
+
command(fn, options) {
|
|
3873
|
+
const builder = new TxPlanBuilder();
|
|
3874
|
+
const planTables = Object.fromEntries(Object.entries(schema.tables).map(([key, table]) => [
|
|
3875
|
+
key,
|
|
3876
|
+
builder.table(qualifiedTableKey(schema.name, table.name))
|
|
3877
|
+
]));
|
|
3878
|
+
return runTxPlan({
|
|
3879
|
+
txPlan: /* @__PURE__ */ __name((plan) => raw2.command(plan, options), "txPlan")
|
|
3880
|
+
}, {
|
|
3881
|
+
tables: planTables
|
|
3882
|
+
}, builder, fn);
|
|
3883
|
+
},
|
|
3884
|
+
transaction(fn) {
|
|
3885
|
+
const builder = new TxPlanBuilder();
|
|
3886
|
+
const planTables = {};
|
|
3887
|
+
for (const key of Object.keys(schema.tables)) {
|
|
3888
|
+
const tableDef = schema.tables[key];
|
|
3889
|
+
if (tableDef !== void 0) planTables[key] = builder.table(qualifiedTableKey(schema.name, tableDef.name));
|
|
3890
|
+
}
|
|
3891
|
+
return runTxPlan(raw2, {
|
|
3892
|
+
tables: planTables
|
|
3893
|
+
}, builder, fn);
|
|
3894
|
+
}
|
|
3672
3895
|
};
|
|
3673
|
-
|
|
3674
|
-
b._def.owns = true;
|
|
3675
|
-
return b;
|
|
3896
|
+
return result;
|
|
3676
3897
|
}
|
|
3677
|
-
__name(
|
|
3678
|
-
function
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
column: "id"
|
|
3683
|
-
};
|
|
3684
|
-
b._def.onDeleteAction = opts.onDelete;
|
|
3685
|
-
if (opts.as !== void 0) b._def.refAs = opts.as;
|
|
3686
|
-
return b;
|
|
3898
|
+
__name(makeTypedDB, "makeTypedDB");
|
|
3899
|
+
function col(name) {
|
|
3900
|
+
return brandRef({
|
|
3901
|
+
$col: name
|
|
3902
|
+
}, "col");
|
|
3687
3903
|
}
|
|
3688
|
-
__name(
|
|
3689
|
-
function
|
|
3690
|
-
const
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3904
|
+
__name(col, "col");
|
|
3905
|
+
async function withRetry(fn, opts = {}) {
|
|
3906
|
+
const budget = retryBudget(opts.retry);
|
|
3907
|
+
let attempt = 0;
|
|
3908
|
+
for (; ; ) {
|
|
3909
|
+
try {
|
|
3910
|
+
return await fn();
|
|
3911
|
+
} catch (e) {
|
|
3912
|
+
if (attempt >= budget || !isRetryable(e)) throw e;
|
|
3913
|
+
attempt += 1;
|
|
3914
|
+
}
|
|
3915
|
+
}
|
|
3698
3916
|
}
|
|
3699
|
-
__name(
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
};
|
|
3917
|
+
__name(withRetry, "withRetry");
|
|
3918
|
+
function sqlFragment(strings, ...values) {
|
|
3919
|
+
return brandRef({
|
|
3920
|
+
$sql: {
|
|
3921
|
+
text: [
|
|
3922
|
+
...strings
|
|
3923
|
+
],
|
|
3924
|
+
values
|
|
3925
|
+
}
|
|
3926
|
+
}, "sql");
|
|
3710
3927
|
}
|
|
3711
|
-
__name(
|
|
3712
|
-
|
|
3713
|
-
// src/db/embedding.ts
|
|
3714
|
-
var openai = {
|
|
3715
|
-
embedding(model, opts) {
|
|
3716
|
-
return {
|
|
3717
|
-
provider: "openai",
|
|
3718
|
-
model,
|
|
3719
|
-
apiKeyName: opts?.apiKeyName ?? "OPENAI_API_KEY",
|
|
3720
|
-
...opts?.dimensions !== void 0 ? {
|
|
3721
|
-
dimensions: opts.dimensions
|
|
3722
|
-
} : {},
|
|
3723
|
-
...opts?.baseURL !== void 0 ? {
|
|
3724
|
-
baseURL: opts.baseURL
|
|
3725
|
-
} : {}
|
|
3726
|
-
};
|
|
3727
|
-
},
|
|
3728
|
-
chat(model) {
|
|
3729
|
-
return {
|
|
3730
|
-
provider: "openai",
|
|
3731
|
-
model
|
|
3732
|
-
};
|
|
3733
|
-
}
|
|
3734
|
-
};
|
|
3928
|
+
__name(sqlFragment, "sqlFragment");
|
|
3735
3929
|
|
|
3736
3930
|
// src/refusals.ts
|
|
3737
3931
|
var DECLARATION_REFUSAL = /* @__PURE__ */ Symbol.for("palbase.backend.declarationRefusal");
|
|
@@ -3751,6 +3945,39 @@ function isDeclarationRefused(e) {
|
|
|
3751
3945
|
}
|
|
3752
3946
|
__name(isDeclarationRefused, "isDeclarationRefused");
|
|
3753
3947
|
|
|
3948
|
+
// src/db/unique.ts
|
|
3949
|
+
function uniqueKeysOf(table) {
|
|
3950
|
+
const columns = table.columns ?? {};
|
|
3951
|
+
const inlinePrimary = [], keys = [];
|
|
3952
|
+
for (const [name, value] of Object.entries(columns)) {
|
|
3953
|
+
const col2 = value && typeof value === "object" && "_def" in value ? value._def : value;
|
|
3954
|
+
if (col2?.primaryKey) inlinePrimary.push(name);
|
|
3955
|
+
if (col2?.unique) keys.push([
|
|
3956
|
+
name
|
|
3957
|
+
]);
|
|
3958
|
+
}
|
|
3959
|
+
const primary = table.primaryKey ?? inlinePrimary;
|
|
3960
|
+
if (primary.length) keys.unshift([
|
|
3961
|
+
...primary
|
|
3962
|
+
]);
|
|
3963
|
+
for (const key of table.unique ?? []) keys.push([
|
|
3964
|
+
...key.columns
|
|
3965
|
+
]);
|
|
3966
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3967
|
+
return keys.filter((key) => {
|
|
3968
|
+
if (!key.length || new Set(key).size !== key.length || key.some((col2) => !Object.hasOwn(columns, col2))) {
|
|
3969
|
+
throw new Error("Unique lookup requires a nonempty declared key of distinct, known columns");
|
|
3970
|
+
}
|
|
3971
|
+
const identity = JSON.stringify([
|
|
3972
|
+
...key
|
|
3973
|
+
].sort());
|
|
3974
|
+
if (seen.has(identity)) return false;
|
|
3975
|
+
seen.add(identity);
|
|
3976
|
+
return true;
|
|
3977
|
+
});
|
|
3978
|
+
}
|
|
3979
|
+
__name(uniqueKeysOf, "uniqueKeysOf");
|
|
3980
|
+
|
|
3754
3981
|
// src/db/env-gen.ts
|
|
3755
3982
|
function baseTsType(def) {
|
|
3756
3983
|
if (def.codec !== void 0 && def.codec in CODECS) {
|
|
@@ -3902,6 +4129,9 @@ function tableBlock(table, relations, indent) {
|
|
|
3902
4129
|
const rowLines = cols.map(([col2, builder]) => {
|
|
3903
4130
|
return `${indent} ${col2}: ${rowType(builder._def)};`;
|
|
3904
4131
|
});
|
|
4132
|
+
const hasCanColumn = Object.prototype.hasOwnProperty.call(table.columns, "can") || relations.some((r) => r.name === "can");
|
|
4133
|
+
const canNames = (table.policies ?? []).filter((p) => p.command === "update" && p.permissive !== false && Buffer.byteLength(`can:${p.name}`, "utf8") <= 63).map((p) => JSON.stringify(p.name));
|
|
4134
|
+
const canLine = hasCanColumn ? null : `${indent} can: ${canNames.length === 0 ? "never[]" : `(${canNames.join(" | ")})[]`};`;
|
|
3905
4135
|
const insertLines = cols.map(([col2, builder]) => {
|
|
3906
4136
|
const def = builder._def;
|
|
3907
4137
|
const opt = optionalOnInsert(def) ? "?" : "";
|
|
@@ -3912,11 +4142,15 @@ function tableBlock(table, relations, indent) {
|
|
|
3912
4142
|
`${indent}${table.name}: {`,
|
|
3913
4143
|
`${indent} row: {`,
|
|
3914
4144
|
...rowLines,
|
|
4145
|
+
...canLine === null ? [] : [
|
|
4146
|
+
canLine
|
|
4147
|
+
],
|
|
3915
4148
|
`${indent} };`,
|
|
3916
4149
|
`${indent} insert: {`,
|
|
3917
4150
|
...insertLines,
|
|
3918
4151
|
`${indent} };`,
|
|
3919
4152
|
`${indent} relations: {${relEntries === "" ? "" : ` ${relEntries} `}};`,
|
|
4153
|
+
`${indent} uniqueKeys: ${JSON.stringify(uniqueKeysOf(table))};`,
|
|
3920
4154
|
// searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()
|
|
3921
4155
|
// üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki
|
|
3922
4156
|
// mevcut şemaların d.ts'i bayt-aynı kalsın.
|
|
@@ -4733,18 +4967,18 @@ __name(defineMiddleware, "defineMiddleware");
|
|
|
4733
4967
|
|
|
4734
4968
|
// src/error-registry.ts
|
|
4735
4969
|
var import_zod_to_openapi = require("@asteasolutions/zod-to-openapi");
|
|
4736
|
-
var
|
|
4737
|
-
(0, import_zod_to_openapi.extendZodWithOpenApi)(
|
|
4970
|
+
var import_zod2 = require("zod");
|
|
4971
|
+
(0, import_zod_to_openapi.extendZodWithOpenApi)(import_zod2.z);
|
|
4738
4972
|
var ERROR_REGISTRY = /* @__PURE__ */ Symbol.for("palbase.backend.errorRegistry");
|
|
4739
4973
|
var BUILTIN_DATA_SCHEMAS = {
|
|
4740
|
-
bad_request:
|
|
4741
|
-
fields:
|
|
4742
|
-
field:
|
|
4743
|
-
message:
|
|
4974
|
+
bad_request: import_zod2.z.object({
|
|
4975
|
+
fields: import_zod2.z.array(import_zod2.z.object({
|
|
4976
|
+
field: import_zod2.z.string(),
|
|
4977
|
+
message: import_zod2.z.string()
|
|
4744
4978
|
}))
|
|
4745
4979
|
}),
|
|
4746
|
-
too_many_requests:
|
|
4747
|
-
retryAfter:
|
|
4980
|
+
too_many_requests: import_zod2.z.object({
|
|
4981
|
+
retryAfter: import_zod2.z.number().int()
|
|
4748
4982
|
})
|
|
4749
4983
|
};
|
|
4750
4984
|
function getErrorRegistry() {
|
|
@@ -4861,7 +5095,7 @@ __name(defineError, "defineError");
|
|
|
4861
5095
|
function digestOf(code, dataSchema) {
|
|
4862
5096
|
const TMP_REF = "__PalbaseErrorDataDigest";
|
|
4863
5097
|
const tmpRegistry = new import_zod_to_openapi.OpenAPIRegistry();
|
|
4864
|
-
tmpRegistry.register(TMP_REF,
|
|
5098
|
+
tmpRegistry.register(TMP_REF, import_zod2.z.object({
|
|
4865
5099
|
data: dataSchema
|
|
4866
5100
|
}).openapi(TMP_REF));
|
|
4867
5101
|
const generated = new import_zod_to_openapi.OpenApiGeneratorV31(tmpRegistry.definitions).generateComponents();
|
|
@@ -5455,7 +5689,188 @@ function getJobConfig(ctor, container) {
|
|
|
5455
5689
|
__name(getJobConfig, "getJobConfig");
|
|
5456
5690
|
|
|
5457
5691
|
// src/index.ts
|
|
5458
|
-
var
|
|
5692
|
+
var import_zod4 = require("zod");
|
|
5693
|
+
|
|
5694
|
+
// src/db/query.ts
|
|
5695
|
+
var import_zod3 = require("zod");
|
|
5696
|
+
var import_zod_to_openapi2 = require("@asteasolutions/zod-to-openapi");
|
|
5697
|
+
|
|
5698
|
+
// src/db/query-contract.ts
|
|
5699
|
+
function queryColumnContract(column) {
|
|
5700
|
+
const def = column && typeof column === "object" && "_def" in column ? column._def : column;
|
|
5701
|
+
if (!def?.type) throw new Error("Query contract requires declared column types");
|
|
5702
|
+
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");
|
|
5703
|
+
return {
|
|
5704
|
+
type: def.type,
|
|
5705
|
+
nullable: def.nullable === true,
|
|
5706
|
+
...def.codec === void 0 ? {} : {
|
|
5707
|
+
codec: def.codec
|
|
5708
|
+
},
|
|
5709
|
+
...def.enumValues === void 0 ? {} : {
|
|
5710
|
+
enumValues: [
|
|
5711
|
+
...def.enumValues
|
|
5712
|
+
]
|
|
5713
|
+
},
|
|
5714
|
+
...def.dimensions === void 0 ? {} : {
|
|
5715
|
+
dimensions: def.dimensions
|
|
5716
|
+
}
|
|
5717
|
+
};
|
|
5718
|
+
}
|
|
5719
|
+
__name(queryColumnContract, "queryColumnContract");
|
|
5720
|
+
function stableContract(value) {
|
|
5721
|
+
if (Array.isArray(value)) return `[${value.map(stableContract).join(",")}]`;
|
|
5722
|
+
if (value && typeof value === "object") return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableContract(value[key])}`).join(",")}}`;
|
|
5723
|
+
return JSON.stringify(value) ?? "null";
|
|
5724
|
+
}
|
|
5725
|
+
__name(stableContract, "stableContract");
|
|
5726
|
+
|
|
5727
|
+
// src/db/query.ts
|
|
5728
|
+
(0, import_zod_to_openapi2.extendZodWithOpenApi)(import_zod3.z);
|
|
5729
|
+
function responseColumn(column, validator) {
|
|
5730
|
+
const contract = queryColumnContract(column);
|
|
5731
|
+
let schema;
|
|
5732
|
+
if (validator) return validator;
|
|
5733
|
+
if (contract.codec === "number") schema = import_zod3.z.number().finite();
|
|
5734
|
+
else if (contract.codec === "decimal") schema = import_zod3.z.string();
|
|
5735
|
+
else switch (contract.type) {
|
|
5736
|
+
case "integer":
|
|
5737
|
+
schema = import_zod3.z.number().int().min(-2147483648).max(2147483647);
|
|
5738
|
+
break;
|
|
5739
|
+
case "boolean":
|
|
5740
|
+
schema = import_zod3.z.boolean();
|
|
5741
|
+
break;
|
|
5742
|
+
case "vector":
|
|
5743
|
+
schema = import_zod3.z.array(import_zod3.z.number().finite());
|
|
5744
|
+
break;
|
|
5745
|
+
case "enum": {
|
|
5746
|
+
const values = contract.enumValues;
|
|
5747
|
+
if (!values?.length) throw new Error("Query response requires declared enum values");
|
|
5748
|
+
schema = import_zod3.z.enum(values);
|
|
5749
|
+
break;
|
|
5750
|
+
}
|
|
5751
|
+
case "uuid":
|
|
5752
|
+
case "text":
|
|
5753
|
+
case "timestamp":
|
|
5754
|
+
case "numeric":
|
|
5755
|
+
case "bigint":
|
|
5756
|
+
schema = import_zod3.z.string();
|
|
5757
|
+
break;
|
|
5758
|
+
case "jsonb":
|
|
5759
|
+
throw new Error("Query response requires a fields validator for a selected jsonb column: its TypeScript payload is erased at runtime");
|
|
5760
|
+
default:
|
|
5761
|
+
throw new Error(`Query response does not support column type ${contract.type}`);
|
|
5762
|
+
}
|
|
5763
|
+
return contract.nullable ? schema.nullable() : schema;
|
|
5764
|
+
}
|
|
5765
|
+
__name(responseColumn, "responseColumn");
|
|
5766
|
+
function defineQuery(name, options) {
|
|
5767
|
+
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");
|
|
5768
|
+
const table = declaredTableKey(options.table);
|
|
5769
|
+
const select = [
|
|
5770
|
+
...options.select
|
|
5771
|
+
];
|
|
5772
|
+
if (!select.length || new Set(select).size !== select.length) throw new Error(`Query ${name}: select must be explicit, nonempty and distinct`);
|
|
5773
|
+
const shape = {}, columns = {};
|
|
5774
|
+
for (const key of select) {
|
|
5775
|
+
if (!Object.hasOwn(options.table[TABLE_META].columns, key)) throw new Error(`Query ${name}: unknown column ${key}`);
|
|
5776
|
+
columns[key] = queryColumnContract(options.table[key]);
|
|
5777
|
+
shape[key] = responseColumn(options.table[key], options.fields?.[key]);
|
|
5778
|
+
}
|
|
5779
|
+
const response = import_zod3.z.array(import_zod3.z.object(shape).strict());
|
|
5780
|
+
const queryInput = options.input, where = options.where, limit = options.limit;
|
|
5781
|
+
const orderBy = options.orderBy === void 0 ? void 0 : JSON.parse(JSON.stringify(options.orderBy));
|
|
5782
|
+
const prepare = /* @__PURE__ */ __name((input) => {
|
|
5783
|
+
const parsed = queryInput.parse(input);
|
|
5784
|
+
const filter = where === void 0 ? {} : where(parsed);
|
|
5785
|
+
if (!filter || typeof filter !== "object" || Array.isArray(filter) || typeof filter.then === "function") {
|
|
5786
|
+
throw new Error(`Query ${name}: where must return a synchronous filter object`);
|
|
5787
|
+
}
|
|
5788
|
+
const size = typeof limit === "function" ? limit(parsed) : limit;
|
|
5789
|
+
if (limit !== void 0 && (typeof size !== "number" || !Number.isSafeInteger(size) || size < 0)) throw new Error(`Query ${name}: limit must produce a nonnegative safe integer`);
|
|
5790
|
+
return {
|
|
5791
|
+
name,
|
|
5792
|
+
table,
|
|
5793
|
+
columns: JSON.parse(JSON.stringify(columns)),
|
|
5794
|
+
where: filter,
|
|
5795
|
+
options: {
|
|
5796
|
+
select: [
|
|
5797
|
+
...select
|
|
5798
|
+
],
|
|
5799
|
+
...orderBy === void 0 ? {} : {
|
|
5800
|
+
orderBy: structuredClone(orderBy)
|
|
5801
|
+
},
|
|
5802
|
+
...limit === void 0 ? {} : {
|
|
5803
|
+
limit: size
|
|
5804
|
+
}
|
|
5805
|
+
}
|
|
5806
|
+
};
|
|
5807
|
+
}, "prepare");
|
|
5808
|
+
const attach = /* @__PURE__ */ __name((schema) => {
|
|
5809
|
+
const api = {
|
|
5810
|
+
queryName: name,
|
|
5811
|
+
input: queryInput,
|
|
5812
|
+
prepare,
|
|
5813
|
+
async run(database, input) {
|
|
5814
|
+
const request = prepare(input);
|
|
5815
|
+
const rows = await ("$readQuery" in database ? database.$readQuery(request) : database.readQuery(request));
|
|
5816
|
+
return schema.parse(rows);
|
|
5817
|
+
},
|
|
5818
|
+
sql(database, input) {
|
|
5819
|
+
const request = prepare(input);
|
|
5820
|
+
return "$compileQuery" in database ? database.$compileQuery(request) : database.compileQuery(request);
|
|
5821
|
+
},
|
|
5822
|
+
explain(database, input) {
|
|
5823
|
+
const request = prepare(input);
|
|
5824
|
+
return "$explainQuery" in database ? database.$explainQuery(request) : database.explainQuery(request);
|
|
5825
|
+
},
|
|
5826
|
+
contract() {
|
|
5827
|
+
const registry2 = new import_zod_to_openapi2.OpenAPIRegistry();
|
|
5828
|
+
registry2.register(`${name}Input`, queryInput);
|
|
5829
|
+
registry2.register(`${name}Response`, schema);
|
|
5830
|
+
return JSON.parse(JSON.stringify({
|
|
5831
|
+
name,
|
|
5832
|
+
table,
|
|
5833
|
+
select,
|
|
5834
|
+
columns,
|
|
5835
|
+
components: new import_zod_to_openapi2.OpenApiGeneratorV31(registry2.definitions).generateComponents().components
|
|
5836
|
+
}));
|
|
5837
|
+
}
|
|
5838
|
+
};
|
|
5839
|
+
for (const key of [
|
|
5840
|
+
"min",
|
|
5841
|
+
"max",
|
|
5842
|
+
"length",
|
|
5843
|
+
"describe",
|
|
5844
|
+
"openapi"
|
|
5845
|
+
]) {
|
|
5846
|
+
const modify = schema[key].bind(schema);
|
|
5847
|
+
Object.defineProperty(schema, key, {
|
|
5848
|
+
value: /* @__PURE__ */ __name((...args) => attach(modify(...args)), "value"),
|
|
5849
|
+
configurable: true
|
|
5850
|
+
});
|
|
5851
|
+
}
|
|
5852
|
+
return Object.assign(schema, api);
|
|
5853
|
+
}, "attach");
|
|
5854
|
+
return attach(response);
|
|
5855
|
+
}
|
|
5856
|
+
__name(defineQuery, "defineQuery");
|
|
5857
|
+
function queryManifest(queries) {
|
|
5858
|
+
const sorted = [
|
|
5859
|
+
...queries
|
|
5860
|
+
].sort((a, b) => a.queryName.localeCompare(b.queryName));
|
|
5861
|
+
if (new Set(sorted.map((query) => query.queryName)).size !== sorted.length) throw new Error("Query manifest contains duplicate names");
|
|
5862
|
+
return JSON.parse(stableContract({
|
|
5863
|
+
version: 1,
|
|
5864
|
+
queries: sorted.map((query) => query.contract())
|
|
5865
|
+
}));
|
|
5866
|
+
}
|
|
5867
|
+
__name(queryManifest, "queryManifest");
|
|
5868
|
+
function assertQueryManifest(queries, baseline) {
|
|
5869
|
+
if (stableContract(queryManifest(queries)) !== stableContract(baseline)) {
|
|
5870
|
+
throw new Error("Query contract drift: compare queryManifest() with the committed manifest and review the API/client changes before updating it");
|
|
5871
|
+
}
|
|
5872
|
+
}
|
|
5873
|
+
__name(assertQueryManifest, "assertQueryManifest");
|
|
5459
5874
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5460
5875
|
0 && (module.exports = {
|
|
5461
5876
|
Auth,
|
|
@@ -5539,11 +5954,13 @@ var import_zod2 = require("zod");
|
|
|
5539
5954
|
__runWithRuntime,
|
|
5540
5955
|
__setRuntime,
|
|
5541
5956
|
assertNoOrphanEntryPoints,
|
|
5957
|
+
assertQueryManifest,
|
|
5542
5958
|
assertZeroArgConstructor,
|
|
5543
5959
|
bigint,
|
|
5544
5960
|
boolean,
|
|
5545
5961
|
buildContainer,
|
|
5546
5962
|
buildModuleClients,
|
|
5963
|
+
can,
|
|
5547
5964
|
col,
|
|
5548
5965
|
controllersOf,
|
|
5549
5966
|
dec,
|
|
@@ -5552,8 +5969,10 @@ var import_zod2 = require("zod");
|
|
|
5552
5969
|
defineDefaultAuth,
|
|
5553
5970
|
defineError,
|
|
5554
5971
|
defineMiddleware,
|
|
5972
|
+
defineQuery,
|
|
5555
5973
|
defineSchema,
|
|
5556
5974
|
defineTable,
|
|
5975
|
+
defineWorkload,
|
|
5557
5976
|
enumType,
|
|
5558
5977
|
exprCtx,
|
|
5559
5978
|
getErrorRegistry,
|
|
@@ -5589,6 +6008,7 @@ var import_zod2 = require("zod");
|
|
|
5589
6008
|
ownerOnly,
|
|
5590
6009
|
policy,
|
|
5591
6010
|
publicChannel,
|
|
6011
|
+
queryManifest,
|
|
5592
6012
|
raw,
|
|
5593
6013
|
recordThrows,
|
|
5594
6014
|
resolveEffectiveAuth,
|