@teamkeel/functions-runtime 0.423.3 → 0.425.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/index.cjs +286 -272
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -4
- package/dist/index.d.ts +36 -4
- package/dist/index.js +286 -272
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -608,175 +608,40 @@ __name(getDialect, "getDialect");
|
|
|
608
608
|
var import_client_s3 = require("@aws-sdk/client-s3");
|
|
609
609
|
var import_credential_providers = require("@aws-sdk/credential-providers");
|
|
610
610
|
var import_s3_request_presigner = require("@aws-sdk/s3-request-presigner");
|
|
611
|
-
|
|
612
|
-
// src/errors.js
|
|
613
|
-
var import_json_rpc_2 = require("json-rpc-2.0");
|
|
614
|
-
var RuntimeErrors = {
|
|
615
|
-
// Catchall error type for unhandled execution errors during custom function
|
|
616
|
-
UnknownError: -32001,
|
|
617
|
-
// DatabaseError represents any error at pg level that isn't handled explicitly below
|
|
618
|
-
DatabaseError: -32002,
|
|
619
|
-
// No result returned from custom function by user
|
|
620
|
-
NoResultError: -32003,
|
|
621
|
-
// When trying to delete/update a non existent record in the db
|
|
622
|
-
RecordNotFoundError: -32004,
|
|
623
|
-
ForeignKeyConstraintError: -32005,
|
|
624
|
-
NotNullConstraintError: -32006,
|
|
625
|
-
UniqueConstraintError: -32007,
|
|
626
|
-
PermissionError: -32008,
|
|
627
|
-
BadRequestError: -32009
|
|
628
|
-
};
|
|
629
|
-
var PermissionError = class extends Error {
|
|
630
|
-
static {
|
|
631
|
-
__name(this, "PermissionError");
|
|
632
|
-
}
|
|
633
|
-
};
|
|
634
|
-
var DatabaseError = class extends Error {
|
|
635
|
-
static {
|
|
636
|
-
__name(this, "DatabaseError");
|
|
637
|
-
}
|
|
638
|
-
constructor(error) {
|
|
639
|
-
super(error.message);
|
|
640
|
-
this.error = error;
|
|
641
|
-
}
|
|
642
|
-
};
|
|
643
|
-
var NotFoundError = class extends Error {
|
|
644
|
-
static {
|
|
645
|
-
__name(this, "NotFoundError");
|
|
646
|
-
}
|
|
647
|
-
errorCode = RuntimeErrors.RecordNotFoundError;
|
|
648
|
-
constructor(message) {
|
|
649
|
-
super(message);
|
|
650
|
-
}
|
|
651
|
-
};
|
|
652
|
-
var BadRequestError = class extends Error {
|
|
653
|
-
static {
|
|
654
|
-
__name(this, "BadRequestError");
|
|
655
|
-
}
|
|
656
|
-
errorCode = RuntimeErrors.BadRequestError;
|
|
657
|
-
constructor(message = "bad request") {
|
|
658
|
-
super(message);
|
|
659
|
-
}
|
|
660
|
-
};
|
|
661
|
-
var UnknownError = class extends Error {
|
|
662
|
-
static {
|
|
663
|
-
__name(this, "UnknownError");
|
|
664
|
-
}
|
|
665
|
-
errorCode = RuntimeErrors.UnknownError;
|
|
666
|
-
constructor(message = "unknown error") {
|
|
667
|
-
super(message);
|
|
668
|
-
}
|
|
669
|
-
};
|
|
670
|
-
var ErrorPresets = {
|
|
671
|
-
NotFound: NotFoundError,
|
|
672
|
-
BadRequest: BadRequestError,
|
|
673
|
-
Unknown: UnknownError
|
|
674
|
-
};
|
|
675
|
-
function errorToJSONRPCResponse(request, e) {
|
|
676
|
-
switch (e.constructor.name) {
|
|
677
|
-
case "PermissionError":
|
|
678
|
-
return (0, import_json_rpc_2.createJSONRPCErrorResponse)(
|
|
679
|
-
request.id,
|
|
680
|
-
RuntimeErrors.PermissionError,
|
|
681
|
-
e.message
|
|
682
|
-
);
|
|
683
|
-
// Any error thrown in the ModelAPI class is
|
|
684
|
-
// wrapped in a DatabaseError in order to differentiate 'our code' vs the user's own code.
|
|
685
|
-
case "NoResultError":
|
|
686
|
-
return (0, import_json_rpc_2.createJSONRPCErrorResponse)(
|
|
687
|
-
request.id,
|
|
688
|
-
// to be matched to https://github.com/teamkeel/keel/blob/e3115ffe381bfc371d4f45bbf96a15072a994ce5/runtime/actions/update.go#L54-L54
|
|
689
|
-
RuntimeErrors.RecordNotFoundError,
|
|
690
|
-
""
|
|
691
|
-
// Don't pass on the message as we want to normalise these at the runtime layer but still support custom messages in other NotFound errors
|
|
692
|
-
);
|
|
693
|
-
case "DatabaseError":
|
|
694
|
-
let err = e;
|
|
695
|
-
if (e instanceof DatabaseError) {
|
|
696
|
-
err = e.error;
|
|
697
|
-
}
|
|
698
|
-
if (err.constructor.name == "NoResultError") {
|
|
699
|
-
return (0, import_json_rpc_2.createJSONRPCErrorResponse)(
|
|
700
|
-
request.id,
|
|
701
|
-
// to be matched to https://github.com/teamkeel/keel/blob/e3115ffe381bfc371d4f45bbf96a15072a994ce5/runtime/actions/update.go#L54-L54
|
|
702
|
-
RuntimeErrors.RecordNotFoundError,
|
|
703
|
-
""
|
|
704
|
-
// Don't pass on the message as we want to normalise these at the runtime layer but still support custom messages in other NotFound errors
|
|
705
|
-
);
|
|
706
|
-
}
|
|
707
|
-
if ("code" in err) {
|
|
708
|
-
const { code: code2, detail, table: table2 } = err;
|
|
709
|
-
let rpcErrorCode, column, value;
|
|
710
|
-
const [col, val] = parseKeyMessage(err.detail);
|
|
711
|
-
column = col;
|
|
712
|
-
value = val;
|
|
713
|
-
switch (code2) {
|
|
714
|
-
case "23502":
|
|
715
|
-
rpcErrorCode = RuntimeErrors.NotNullConstraintError;
|
|
716
|
-
column = err.column;
|
|
717
|
-
break;
|
|
718
|
-
case "23503":
|
|
719
|
-
rpcErrorCode = RuntimeErrors.ForeignKeyConstraintError;
|
|
720
|
-
break;
|
|
721
|
-
case "23505":
|
|
722
|
-
rpcErrorCode = RuntimeErrors.UniqueConstraintError;
|
|
723
|
-
break;
|
|
724
|
-
default:
|
|
725
|
-
rpcErrorCode = RuntimeErrors.DatabaseError;
|
|
726
|
-
break;
|
|
727
|
-
}
|
|
728
|
-
return (0, import_json_rpc_2.createJSONRPCErrorResponse)(request.id, rpcErrorCode, e.message, {
|
|
729
|
-
table: table2,
|
|
730
|
-
column,
|
|
731
|
-
code: code2,
|
|
732
|
-
detail,
|
|
733
|
-
value
|
|
734
|
-
});
|
|
735
|
-
}
|
|
736
|
-
return (0, import_json_rpc_2.createJSONRPCErrorResponse)(
|
|
737
|
-
request.id,
|
|
738
|
-
RuntimeErrors.DatabaseError,
|
|
739
|
-
e.message
|
|
740
|
-
);
|
|
741
|
-
default:
|
|
742
|
-
return (0, import_json_rpc_2.createJSONRPCErrorResponse)(
|
|
743
|
-
request.id,
|
|
744
|
-
e.errorCode ?? RuntimeErrors.UnknownError,
|
|
745
|
-
e.message
|
|
746
|
-
);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
__name(errorToJSONRPCResponse, "errorToJSONRPCResponse");
|
|
750
|
-
var keyMessagePattern = /\Key\s[(](.*)[)][=][(](.*)[)]/;
|
|
751
|
-
var parseKeyMessage = /* @__PURE__ */ __name((msg) => {
|
|
752
|
-
const [, col, value] = keyMessagePattern.exec(msg) || [];
|
|
753
|
-
return [col, value];
|
|
754
|
-
}, "parseKeyMessage");
|
|
755
|
-
|
|
756
|
-
// src/File.ts
|
|
757
611
|
var import_ksuid = __toESM(require("ksuid"), 1);
|
|
758
612
|
var s3Client = (() => {
|
|
759
613
|
if (!process.env.KEEL_FILES_BUCKET_NAME) {
|
|
760
614
|
return null;
|
|
761
615
|
}
|
|
762
|
-
const endpoint = process.env.
|
|
763
|
-
if (
|
|
616
|
+
const endpoint = process.env.KEEL_S3_ENDPOINT;
|
|
617
|
+
if (endpoint) {
|
|
764
618
|
return new import_client_s3.S3Client({
|
|
765
619
|
region: process.env.KEEL_REGION,
|
|
766
|
-
credentials:
|
|
620
|
+
credentials: {
|
|
621
|
+
accessKeyId: "keelstorage",
|
|
622
|
+
secretAccessKey: "keelstorage"
|
|
623
|
+
},
|
|
624
|
+
endpoint
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
const testEndpoint = process.env.TEST_AWS_ENDPOINT;
|
|
628
|
+
if (testEndpoint) {
|
|
629
|
+
return new import_client_s3.S3Client({
|
|
630
|
+
region: process.env.KEEL_REGION,
|
|
631
|
+
credentials: {
|
|
632
|
+
accessKeyId: "test",
|
|
633
|
+
secretAccessKey: "test"
|
|
634
|
+
},
|
|
635
|
+
endpointProvider: /* @__PURE__ */ __name(() => {
|
|
636
|
+
return {
|
|
637
|
+
url: new URL(testEndpoint)
|
|
638
|
+
};
|
|
639
|
+
}, "endpointProvider")
|
|
767
640
|
});
|
|
768
641
|
}
|
|
769
642
|
return new import_client_s3.S3Client({
|
|
770
643
|
region: process.env.KEEL_REGION,
|
|
771
|
-
credentials:
|
|
772
|
-
accessKeyId: "test",
|
|
773
|
-
secretAccessKey: "test"
|
|
774
|
-
},
|
|
775
|
-
endpointProvider: /* @__PURE__ */ __name(() => {
|
|
776
|
-
return {
|
|
777
|
-
url: new URL(endpoint)
|
|
778
|
-
};
|
|
779
|
-
}, "endpointProvider")
|
|
644
|
+
credentials: (0, import_credential_providers.fromEnv)()
|
|
780
645
|
});
|
|
781
646
|
})();
|
|
782
647
|
var InlineFile = class _InlineFile {
|
|
@@ -881,24 +746,17 @@ var File = class _File extends InlineFile {
|
|
|
881
746
|
const arrayBuffer = await this._contents.arrayBuffer();
|
|
882
747
|
return Buffer.from(arrayBuffer);
|
|
883
748
|
}
|
|
884
|
-
if (s3Client) {
|
|
885
|
-
|
|
886
|
-
Bucket: process.env.KEEL_FILES_BUCKET_NAME,
|
|
887
|
-
Key: "files/" + this.key
|
|
888
|
-
};
|
|
889
|
-
const command = new import_client_s3.GetObjectCommand(params);
|
|
890
|
-
const response = await s3Client.send(command);
|
|
891
|
-
const blob = await response.Body.transformToByteArray();
|
|
892
|
-
return Buffer.from(blob);
|
|
893
|
-
}
|
|
894
|
-
const db = useDatabase();
|
|
895
|
-
try {
|
|
896
|
-
const query = db.selectFrom("keel_storage").select("data").where("id", "=", this.key);
|
|
897
|
-
const row = await query.executeTakeFirstOrThrow();
|
|
898
|
-
return row.data;
|
|
899
|
-
} catch (e) {
|
|
900
|
-
throw new DatabaseError(e);
|
|
749
|
+
if (!s3Client) {
|
|
750
|
+
throw new Error("S3 client is required");
|
|
901
751
|
}
|
|
752
|
+
const params = {
|
|
753
|
+
Bucket: process.env.KEEL_FILES_BUCKET_NAME,
|
|
754
|
+
Key: "files/" + this.key
|
|
755
|
+
};
|
|
756
|
+
const command = new import_client_s3.GetObjectCommand(params);
|
|
757
|
+
const response = await s3Client.send(command);
|
|
758
|
+
const blob = await response.Body.transformToByteArray();
|
|
759
|
+
return Buffer.from(blob);
|
|
902
760
|
}
|
|
903
761
|
async store(expires = null) {
|
|
904
762
|
if (this._contents) {
|
|
@@ -916,19 +774,16 @@ var File = class _File extends InlineFile {
|
|
|
916
774
|
}
|
|
917
775
|
// Generates a presigned download URL
|
|
918
776
|
async getPresignedUrl() {
|
|
919
|
-
if (s3Client) {
|
|
920
|
-
|
|
921
|
-
Bucket: process.env.KEEL_FILES_BUCKET_NAME,
|
|
922
|
-
Key: "files/" + this.key,
|
|
923
|
-
ResponseContentDisposition: "inline"
|
|
924
|
-
});
|
|
925
|
-
const url = await (0, import_s3_request_presigner.getSignedUrl)(s3Client, command, { expiresIn: 60 * 60 });
|
|
926
|
-
return new URL(url);
|
|
927
|
-
} else {
|
|
928
|
-
const contents = await this.read();
|
|
929
|
-
const dataurl = `data:${this.contentType};name=${this.filename};base64,${contents.toString("base64")}`;
|
|
930
|
-
return new URL(dataurl);
|
|
777
|
+
if (!s3Client) {
|
|
778
|
+
throw new Error("S3 client is required");
|
|
931
779
|
}
|
|
780
|
+
const command = new import_client_s3.GetObjectCommand({
|
|
781
|
+
Bucket: process.env.KEEL_FILES_BUCKET_NAME,
|
|
782
|
+
Key: "files/" + this.key,
|
|
783
|
+
ResponseContentDisposition: "inline"
|
|
784
|
+
});
|
|
785
|
+
const url = await (0, import_s3_request_presigner.getSignedUrl)(s3Client, command, { expiresIn: 60 * 60 });
|
|
786
|
+
return new URL(url);
|
|
932
787
|
}
|
|
933
788
|
// Persists the file
|
|
934
789
|
toDbRecord() {
|
|
@@ -944,54 +799,36 @@ var File = class _File extends InlineFile {
|
|
|
944
799
|
}
|
|
945
800
|
};
|
|
946
801
|
async function storeFile(contents, key, filename, contentType, size, expires) {
|
|
947
|
-
if (s3Client) {
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
const command = new import_client_s3.PutObjectCommand(params);
|
|
969
|
-
try {
|
|
970
|
-
await s3Client.send(command);
|
|
971
|
-
} catch (error) {
|
|
972
|
-
console.error("Error uploading file:", error);
|
|
973
|
-
throw error;
|
|
974
|
-
}
|
|
975
|
-
} else {
|
|
976
|
-
const db = useDatabase();
|
|
977
|
-
try {
|
|
978
|
-
const query = db.insertInto("keel_storage").values({
|
|
979
|
-
id: key,
|
|
980
|
-
filename,
|
|
981
|
-
content_type: contentType,
|
|
982
|
-
data: contents
|
|
983
|
-
}).onConflict(
|
|
984
|
-
(oc) => oc.column("id").doUpdateSet(() => ({
|
|
985
|
-
filename,
|
|
986
|
-
content_type: contentType,
|
|
987
|
-
data: contents
|
|
988
|
-
})).where("keel_storage.id", "=", key)
|
|
989
|
-
).returningAll();
|
|
990
|
-
await query.execute();
|
|
991
|
-
} catch (e) {
|
|
992
|
-
throw new DatabaseError(e);
|
|
802
|
+
if (!s3Client) {
|
|
803
|
+
throw new Error("S3 client is required");
|
|
804
|
+
}
|
|
805
|
+
const params = {
|
|
806
|
+
Bucket: process.env.KEEL_FILES_BUCKET_NAME,
|
|
807
|
+
Key: "files/" + key,
|
|
808
|
+
Body: contents,
|
|
809
|
+
ContentType: contentType,
|
|
810
|
+
ContentDisposition: `attachment; filename="${encodeURIComponent(
|
|
811
|
+
filename
|
|
812
|
+
)}"`,
|
|
813
|
+
Metadata: {
|
|
814
|
+
filename
|
|
815
|
+
},
|
|
816
|
+
ACL: "private"
|
|
817
|
+
};
|
|
818
|
+
if (expires) {
|
|
819
|
+
if (expires instanceof Date) {
|
|
820
|
+
params.Expires = expires;
|
|
821
|
+
} else {
|
|
822
|
+
console.warn("Invalid expires value. Skipping Expires parameter.");
|
|
993
823
|
}
|
|
994
824
|
}
|
|
825
|
+
const command = new import_client_s3.PutObjectCommand(params);
|
|
826
|
+
try {
|
|
827
|
+
await s3Client.send(command);
|
|
828
|
+
} catch (error) {
|
|
829
|
+
console.error("Error uploading file:", error);
|
|
830
|
+
throw error;
|
|
831
|
+
}
|
|
995
832
|
}
|
|
996
833
|
__name(storeFile, "storeFile");
|
|
997
834
|
|
|
@@ -1431,6 +1268,150 @@ function joinAlias(tablePath) {
|
|
|
1431
1268
|
}
|
|
1432
1269
|
__name(joinAlias, "joinAlias");
|
|
1433
1270
|
|
|
1271
|
+
// src/errors.js
|
|
1272
|
+
var import_json_rpc_2 = require("json-rpc-2.0");
|
|
1273
|
+
var RuntimeErrors = {
|
|
1274
|
+
// Catchall error type for unhandled execution errors during custom function
|
|
1275
|
+
UnknownError: -32001,
|
|
1276
|
+
// DatabaseError represents any error at pg level that isn't handled explicitly below
|
|
1277
|
+
DatabaseError: -32002,
|
|
1278
|
+
// No result returned from custom function by user
|
|
1279
|
+
NoResultError: -32003,
|
|
1280
|
+
// When trying to delete/update a non existent record in the db
|
|
1281
|
+
RecordNotFoundError: -32004,
|
|
1282
|
+
ForeignKeyConstraintError: -32005,
|
|
1283
|
+
NotNullConstraintError: -32006,
|
|
1284
|
+
UniqueConstraintError: -32007,
|
|
1285
|
+
PermissionError: -32008,
|
|
1286
|
+
BadRequestError: -32009
|
|
1287
|
+
};
|
|
1288
|
+
var PermissionError = class extends Error {
|
|
1289
|
+
static {
|
|
1290
|
+
__name(this, "PermissionError");
|
|
1291
|
+
}
|
|
1292
|
+
};
|
|
1293
|
+
var DatabaseError = class extends Error {
|
|
1294
|
+
static {
|
|
1295
|
+
__name(this, "DatabaseError");
|
|
1296
|
+
}
|
|
1297
|
+
constructor(error) {
|
|
1298
|
+
super(error.message);
|
|
1299
|
+
this.error = error;
|
|
1300
|
+
}
|
|
1301
|
+
};
|
|
1302
|
+
var NotFoundError = class extends Error {
|
|
1303
|
+
static {
|
|
1304
|
+
__name(this, "NotFoundError");
|
|
1305
|
+
}
|
|
1306
|
+
errorCode = RuntimeErrors.RecordNotFoundError;
|
|
1307
|
+
constructor(message) {
|
|
1308
|
+
super(message);
|
|
1309
|
+
}
|
|
1310
|
+
};
|
|
1311
|
+
var BadRequestError = class extends Error {
|
|
1312
|
+
static {
|
|
1313
|
+
__name(this, "BadRequestError");
|
|
1314
|
+
}
|
|
1315
|
+
errorCode = RuntimeErrors.BadRequestError;
|
|
1316
|
+
constructor(message = "bad request") {
|
|
1317
|
+
super(message);
|
|
1318
|
+
}
|
|
1319
|
+
};
|
|
1320
|
+
var UnknownError = class extends Error {
|
|
1321
|
+
static {
|
|
1322
|
+
__name(this, "UnknownError");
|
|
1323
|
+
}
|
|
1324
|
+
errorCode = RuntimeErrors.UnknownError;
|
|
1325
|
+
constructor(message = "unknown error") {
|
|
1326
|
+
super(message);
|
|
1327
|
+
}
|
|
1328
|
+
};
|
|
1329
|
+
var ErrorPresets = {
|
|
1330
|
+
NotFound: NotFoundError,
|
|
1331
|
+
BadRequest: BadRequestError,
|
|
1332
|
+
Unknown: UnknownError
|
|
1333
|
+
};
|
|
1334
|
+
function errorToJSONRPCResponse(request, e) {
|
|
1335
|
+
switch (e.constructor.name) {
|
|
1336
|
+
case "PermissionError":
|
|
1337
|
+
return (0, import_json_rpc_2.createJSONRPCErrorResponse)(
|
|
1338
|
+
request.id,
|
|
1339
|
+
RuntimeErrors.PermissionError,
|
|
1340
|
+
e.message
|
|
1341
|
+
);
|
|
1342
|
+
// Any error thrown in the ModelAPI class is
|
|
1343
|
+
// wrapped in a DatabaseError in order to differentiate 'our code' vs the user's own code.
|
|
1344
|
+
case "NoResultError":
|
|
1345
|
+
return (0, import_json_rpc_2.createJSONRPCErrorResponse)(
|
|
1346
|
+
request.id,
|
|
1347
|
+
// to be matched to https://github.com/teamkeel/keel/blob/e3115ffe381bfc371d4f45bbf96a15072a994ce5/runtime/actions/update.go#L54-L54
|
|
1348
|
+
RuntimeErrors.RecordNotFoundError,
|
|
1349
|
+
""
|
|
1350
|
+
// Don't pass on the message as we want to normalise these at the runtime layer but still support custom messages in other NotFound errors
|
|
1351
|
+
);
|
|
1352
|
+
case "DatabaseError":
|
|
1353
|
+
let err = e;
|
|
1354
|
+
if (e instanceof DatabaseError) {
|
|
1355
|
+
err = e.error;
|
|
1356
|
+
}
|
|
1357
|
+
if (err.constructor.name == "NoResultError") {
|
|
1358
|
+
return (0, import_json_rpc_2.createJSONRPCErrorResponse)(
|
|
1359
|
+
request.id,
|
|
1360
|
+
// to be matched to https://github.com/teamkeel/keel/blob/e3115ffe381bfc371d4f45bbf96a15072a994ce5/runtime/actions/update.go#L54-L54
|
|
1361
|
+
RuntimeErrors.RecordNotFoundError,
|
|
1362
|
+
""
|
|
1363
|
+
// Don't pass on the message as we want to normalise these at the runtime layer but still support custom messages in other NotFound errors
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
if ("code" in err) {
|
|
1367
|
+
const { code: code2, detail, table: table2 } = err;
|
|
1368
|
+
let rpcErrorCode, column, value;
|
|
1369
|
+
const [col, val] = parseKeyMessage(err.detail);
|
|
1370
|
+
column = col;
|
|
1371
|
+
value = val;
|
|
1372
|
+
switch (code2) {
|
|
1373
|
+
case "23502":
|
|
1374
|
+
rpcErrorCode = RuntimeErrors.NotNullConstraintError;
|
|
1375
|
+
column = err.column;
|
|
1376
|
+
break;
|
|
1377
|
+
case "23503":
|
|
1378
|
+
rpcErrorCode = RuntimeErrors.ForeignKeyConstraintError;
|
|
1379
|
+
break;
|
|
1380
|
+
case "23505":
|
|
1381
|
+
rpcErrorCode = RuntimeErrors.UniqueConstraintError;
|
|
1382
|
+
break;
|
|
1383
|
+
default:
|
|
1384
|
+
rpcErrorCode = RuntimeErrors.DatabaseError;
|
|
1385
|
+
break;
|
|
1386
|
+
}
|
|
1387
|
+
return (0, import_json_rpc_2.createJSONRPCErrorResponse)(request.id, rpcErrorCode, e.message, {
|
|
1388
|
+
table: table2,
|
|
1389
|
+
column,
|
|
1390
|
+
code: code2,
|
|
1391
|
+
detail,
|
|
1392
|
+
value
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
return (0, import_json_rpc_2.createJSONRPCErrorResponse)(
|
|
1396
|
+
request.id,
|
|
1397
|
+
RuntimeErrors.DatabaseError,
|
|
1398
|
+
e.message
|
|
1399
|
+
);
|
|
1400
|
+
default:
|
|
1401
|
+
return (0, import_json_rpc_2.createJSONRPCErrorResponse)(
|
|
1402
|
+
request.id,
|
|
1403
|
+
e.errorCode ?? RuntimeErrors.UnknownError,
|
|
1404
|
+
e.message
|
|
1405
|
+
);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
__name(errorToJSONRPCResponse, "errorToJSONRPCResponse");
|
|
1409
|
+
var keyMessagePattern = /\Key\s[(](.*)[)][=][(](.*)[)]/;
|
|
1410
|
+
var parseKeyMessage = /* @__PURE__ */ __name((msg) => {
|
|
1411
|
+
const [, col, value] = keyMessagePattern.exec(msg) || [];
|
|
1412
|
+
return [col, value];
|
|
1413
|
+
}, "parseKeyMessage");
|
|
1414
|
+
|
|
1434
1415
|
// src/QueryBuilder.js
|
|
1435
1416
|
var QueryBuilder = class _QueryBuilder {
|
|
1436
1417
|
static {
|
|
@@ -2503,15 +2484,38 @@ async function page(options, data, action) {
|
|
|
2503
2484
|
const content = options.content;
|
|
2504
2485
|
let hasValidationErrors = false;
|
|
2505
2486
|
let validationError;
|
|
2506
|
-
if (options.actions &&
|
|
2507
|
-
const
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2487
|
+
if (options.actions && options.actions.length > 0) {
|
|
2488
|
+
const normalizedAction = action === "undefined" || action === void 0 ? null : action;
|
|
2489
|
+
if (data !== null) {
|
|
2490
|
+
if (normalizedAction === null) {
|
|
2491
|
+
const validValues = options.actions.map((a) => {
|
|
2492
|
+
if (typeof a === "string") return a;
|
|
2493
|
+
return a && typeof a === "object" && "value" in a ? a.value : "";
|
|
2494
|
+
}).filter(Boolean);
|
|
2495
|
+
throw new Error(
|
|
2496
|
+
`action is required. Valid actions are: ${validValues.join(", ")}`
|
|
2497
|
+
);
|
|
2498
|
+
}
|
|
2499
|
+
const isValidAction = options.actions.some((a) => {
|
|
2500
|
+
if (typeof a === "string") return a === normalizedAction;
|
|
2501
|
+
return a && typeof a === "object" && "value" in a && a.value === normalizedAction;
|
|
2502
|
+
});
|
|
2503
|
+
if (!isValidAction) {
|
|
2504
|
+
const validValues = options.actions.map((a) => {
|
|
2505
|
+
if (typeof a === "string") return a;
|
|
2506
|
+
return a && typeof a === "object" && "value" in a ? a.value : "";
|
|
2507
|
+
}).filter(Boolean);
|
|
2508
|
+
throw new Error(
|
|
2509
|
+
`invalid action "${normalizedAction}". Valid actions are: ${validValues.join(
|
|
2510
|
+
", "
|
|
2511
|
+
)}`
|
|
2512
|
+
);
|
|
2513
|
+
}
|
|
2514
2514
|
}
|
|
2515
|
+
} else if (action !== null && action !== void 0 && action !== "undefined") {
|
|
2516
|
+
throw new Error(
|
|
2517
|
+
`invalid action "${action}". No actions are defined for this page`
|
|
2518
|
+
);
|
|
2515
2519
|
}
|
|
2516
2520
|
const contentUiConfig = await Promise.all(
|
|
2517
2521
|
content.map(async (c) => {
|
|
@@ -2519,14 +2523,15 @@ async function page(options, data, action) {
|
|
|
2519
2523
|
const elementData = data && typeof data === "object" && resolvedC.uiConfig.name in data ? data[resolvedC.uiConfig.name] : void 0;
|
|
2520
2524
|
const { uiConfig, validationErrors } = await recursivelyProcessElement(
|
|
2521
2525
|
c,
|
|
2522
|
-
elementData
|
|
2526
|
+
elementData,
|
|
2527
|
+
options.actions && options.actions.length > 0 ? action : null
|
|
2523
2528
|
);
|
|
2524
2529
|
if (validationErrors) hasValidationErrors = true;
|
|
2525
2530
|
return uiConfig;
|
|
2526
2531
|
})
|
|
2527
2532
|
);
|
|
2528
2533
|
if (data && options.validate) {
|
|
2529
|
-
const validationResult = await options.validate(data);
|
|
2534
|
+
const validationResult = options.actions && action !== null ? await options.validate(data, action) : await options.validate(data);
|
|
2530
2535
|
if (typeof validationResult === "string") {
|
|
2531
2536
|
hasValidationErrors = true;
|
|
2532
2537
|
validationError = validationResult;
|
|
@@ -2556,19 +2561,21 @@ async function page(options, data, action) {
|
|
|
2556
2561
|
};
|
|
2557
2562
|
}
|
|
2558
2563
|
__name(page, "page");
|
|
2559
|
-
var recursivelyProcessElement = /* @__PURE__ */ __name(async (c, data) => {
|
|
2564
|
+
var recursivelyProcessElement = /* @__PURE__ */ __name(async (c, data, action) => {
|
|
2560
2565
|
const resolvedC = await c;
|
|
2561
2566
|
const elementType = "__type" in resolvedC ? resolvedC.__type : null;
|
|
2562
2567
|
switch (elementType) {
|
|
2563
2568
|
case "input":
|
|
2564
2569
|
return processInputElement(
|
|
2565
2570
|
resolvedC,
|
|
2566
|
-
data
|
|
2571
|
+
data,
|
|
2572
|
+
action
|
|
2567
2573
|
);
|
|
2568
2574
|
case "iterator":
|
|
2569
2575
|
return processIteratorElement(
|
|
2570
2576
|
resolvedC,
|
|
2571
|
-
data
|
|
2577
|
+
data,
|
|
2578
|
+
action
|
|
2572
2579
|
);
|
|
2573
2580
|
default:
|
|
2574
2581
|
return {
|
|
@@ -2577,7 +2584,7 @@ var recursivelyProcessElement = /* @__PURE__ */ __name(async (c, data) => {
|
|
|
2577
2584
|
};
|
|
2578
2585
|
}
|
|
2579
2586
|
}, "recursivelyProcessElement");
|
|
2580
|
-
var processInputElement = /* @__PURE__ */ __name(async (element, data) => {
|
|
2587
|
+
var processInputElement = /* @__PURE__ */ __name(async (element, data, action) => {
|
|
2581
2588
|
const hasData = data !== void 0 && data !== null;
|
|
2582
2589
|
if (!hasData || !element.validate) {
|
|
2583
2590
|
return {
|
|
@@ -2585,7 +2592,7 @@ var processInputElement = /* @__PURE__ */ __name(async (element, data) => {
|
|
|
2585
2592
|
validationErrors: false
|
|
2586
2593
|
};
|
|
2587
2594
|
}
|
|
2588
|
-
const validationError = await element.validate(data);
|
|
2595
|
+
const validationError = action !== null ? await element.validate(data, action) : await element.validate(data);
|
|
2589
2596
|
const hasValidationErrors = typeof validationError === "string";
|
|
2590
2597
|
return {
|
|
2591
2598
|
uiConfig: {
|
|
@@ -2595,19 +2602,23 @@ var processInputElement = /* @__PURE__ */ __name(async (element, data) => {
|
|
|
2595
2602
|
validationErrors: hasValidationErrors
|
|
2596
2603
|
};
|
|
2597
2604
|
}, "processInputElement");
|
|
2598
|
-
var processIteratorElement = /* @__PURE__ */ __name(async (element, data) => {
|
|
2605
|
+
var processIteratorElement = /* @__PURE__ */ __name(async (element, data, action) => {
|
|
2599
2606
|
const elements = element.uiConfig.content;
|
|
2600
2607
|
const dataArr = data;
|
|
2601
2608
|
const ui = [];
|
|
2602
2609
|
for (const el of elements) {
|
|
2603
|
-
const result = await recursivelyProcessElement(el, void 0);
|
|
2610
|
+
const result = await recursivelyProcessElement(el, void 0, action);
|
|
2604
2611
|
ui.push(result.uiConfig);
|
|
2605
2612
|
}
|
|
2606
|
-
const validationErrors = await validateIteratorData(
|
|
2613
|
+
const validationErrors = await validateIteratorData(
|
|
2614
|
+
elements,
|
|
2615
|
+
dataArr,
|
|
2616
|
+
action
|
|
2617
|
+
);
|
|
2607
2618
|
let hasValidationErrors = validationErrors.length > 0;
|
|
2608
2619
|
let validationError = void 0;
|
|
2609
2620
|
if (dataArr && element.validate) {
|
|
2610
|
-
const v = await element.validate(dataArr);
|
|
2621
|
+
const v = action !== null ? await element.validate(dataArr, action) : await element.validate(dataArr);
|
|
2611
2622
|
if (typeof v === "string") {
|
|
2612
2623
|
hasValidationErrors = true;
|
|
2613
2624
|
validationError = v;
|
|
@@ -2623,7 +2634,7 @@ var processIteratorElement = /* @__PURE__ */ __name(async (element, data) => {
|
|
|
2623
2634
|
validationErrors: hasValidationErrors
|
|
2624
2635
|
};
|
|
2625
2636
|
}, "processIteratorElement");
|
|
2626
|
-
var validateIteratorData = /* @__PURE__ */ __name(async (elements, dataArr) => {
|
|
2637
|
+
var validateIteratorData = /* @__PURE__ */ __name(async (elements, dataArr, action) => {
|
|
2627
2638
|
const validationErrors = [];
|
|
2628
2639
|
if (!dataArr || dataArr.length === 0) {
|
|
2629
2640
|
return validationErrors;
|
|
@@ -2635,9 +2646,7 @@ var validateIteratorData = /* @__PURE__ */ __name(async (elements, dataArr) => {
|
|
|
2635
2646
|
if ("__type" in resolvedEl && resolvedEl.__type === "input" && "validate" in resolvedEl && resolvedEl.validate && typeof resolvedEl.validate === "function") {
|
|
2636
2647
|
const fieldName = resolvedEl.uiConfig.name;
|
|
2637
2648
|
if (rowData && typeof rowData === "object" && fieldName in rowData) {
|
|
2638
|
-
const validationError = await resolvedEl.validate(
|
|
2639
|
-
rowData[fieldName]
|
|
2640
|
-
);
|
|
2649
|
+
const validationError = action !== null ? await resolvedEl.validate(rowData[fieldName], action) : await resolvedEl.validate(rowData[fieldName]);
|
|
2641
2650
|
if (typeof validationError === "string") {
|
|
2642
2651
|
validationErrors.push({
|
|
2643
2652
|
index: i,
|
|
@@ -2906,17 +2915,22 @@ var iterator = /* @__PURE__ */ __name((name, options) => {
|
|
|
2906
2915
|
var print = /* @__PURE__ */ __name(async (options) => {
|
|
2907
2916
|
const dataConfig = Array.isArray(options.jobs) ? options.jobs : [options.jobs];
|
|
2908
2917
|
const dataPromises = dataConfig.map(async (d) => {
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
+
return {
|
|
2919
|
+
type: d.type,
|
|
2920
|
+
name: d.name,
|
|
2921
|
+
data: "data" in d && d.data ? Array.isArray(d.data) ? d.data : [d.data] : void 0,
|
|
2922
|
+
printer: d.printer,
|
|
2923
|
+
url: "url" in d && d.url ? d.url : void 0,
|
|
2924
|
+
...d.type === "rawPdf" ? {
|
|
2925
|
+
dpi: d.dpi,
|
|
2926
|
+
pageWidth: d.pageWidth,
|
|
2927
|
+
pageHeight: d.pageHeight
|
|
2928
|
+
} : {}
|
|
2929
|
+
};
|
|
2918
2930
|
});
|
|
2919
|
-
const data = (await Promise.all(dataPromises)).filter(
|
|
2931
|
+
const data = (await Promise.all(dataPromises)).filter(
|
|
2932
|
+
(x) => x !== null
|
|
2933
|
+
);
|
|
2920
2934
|
return {
|
|
2921
2935
|
uiConfig: {
|
|
2922
2936
|
__type: "ui.interactive.print",
|
|
@@ -2954,7 +2968,7 @@ var pickList = /* @__PURE__ */ __name((name, options) => {
|
|
|
2954
2968
|
};
|
|
2955
2969
|
})
|
|
2956
2970
|
},
|
|
2957
|
-
validate: /* @__PURE__ */ __name(async (data) => {
|
|
2971
|
+
validate: /* @__PURE__ */ __name(async (data, action) => {
|
|
2958
2972
|
if (!("items" in data)) {
|
|
2959
2973
|
return "Missing items in response";
|
|
2960
2974
|
}
|
|
@@ -2966,7 +2980,7 @@ var pickList = /* @__PURE__ */ __name((name, options) => {
|
|
|
2966
2980
|
)) {
|
|
2967
2981
|
return "Invalid data";
|
|
2968
2982
|
}
|
|
2969
|
-
return options?.validate?.(data) ?? true;
|
|
2983
|
+
return options?.validate?.(data, action) ?? true;
|
|
2970
2984
|
}, "validate"),
|
|
2971
2985
|
getData: /* @__PURE__ */ __name((x) => x, "getData")
|
|
2972
2986
|
};
|
|
@@ -3006,8 +3020,8 @@ var scan = /* @__PURE__ */ __name((name, options) => {
|
|
|
3006
3020
|
autoContinue: options.autoContinue
|
|
3007
3021
|
} : {}
|
|
3008
3022
|
},
|
|
3009
|
-
validate: /* @__PURE__ */ __name(async (data) => {
|
|
3010
|
-
return options?.validate?.(data) ?? true;
|
|
3023
|
+
validate: /* @__PURE__ */ __name(async (data, action) => {
|
|
3024
|
+
return options?.validate?.(data, action) ?? true;
|
|
3011
3025
|
}, "validate"),
|
|
3012
3026
|
getData: /* @__PURE__ */ __name((x) => x, "getData")
|
|
3013
3027
|
};
|
|
@@ -3178,7 +3192,7 @@ function createFlowContext(runId, data, action, callback, element, spanId, ctx)
|
|
|
3178
3192
|
});
|
|
3179
3193
|
}, "step"),
|
|
3180
3194
|
ui: {
|
|
3181
|
-
page: /* @__PURE__ */ __name(async (name, options) => {
|
|
3195
|
+
page: /* @__PURE__ */ __name((async (name, options) => {
|
|
3182
3196
|
return withSpan(`Page - ${name}`, async (span) => {
|
|
3183
3197
|
const db = useDatabase();
|
|
3184
3198
|
const isCallback = element && callback;
|
|
@@ -3274,7 +3288,7 @@ function createFlowContext(runId, data, action, callback, element, spanId, ctx)
|
|
|
3274
3288
|
}
|
|
3275
3289
|
return data;
|
|
3276
3290
|
});
|
|
3277
|
-
}, "page"),
|
|
3291
|
+
}), "page"),
|
|
3278
3292
|
inputs: {
|
|
3279
3293
|
text: textInput,
|
|
3280
3294
|
number: numberInput,
|