@teamkeel/functions-runtime 0.452.1 → 0.453.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 CHANGED
@@ -587,9 +587,9 @@ var InstrumentedClient = class extends import_pg.Client {
587
587
  }
588
588
  async query(...args) {
589
589
  const _super = super.query.bind(this);
590
- const sql4 = args[0];
590
+ const sql5 = args[0];
591
591
  let sqlAttribute = false;
592
- let spanName = txStatements[sql4.toLowerCase()];
592
+ let spanName = txStatements[sql5.toLowerCase()];
593
593
  if (!spanName) {
594
594
  spanName = "Database Query";
595
595
  sqlAttribute = true;
@@ -657,9 +657,9 @@ function getDialect(connString) {
657
657
  pool.on("connect", (client) => {
658
658
  const originalQuery = client.query;
659
659
  client.query = function(...args) {
660
- const sql4 = args[0];
660
+ const sql5 = args[0];
661
661
  let sqlAttribute = false;
662
- let spanName = txStatements[sql4.toLowerCase()];
662
+ let spanName = txStatements[sql5.toLowerCase()];
663
663
  if (!spanName) {
664
664
  spanName = "Database Query";
665
665
  sqlAttribute = true;
@@ -1029,7 +1029,7 @@ function transformRichDataTypes(data) {
1029
1029
  } else if (value.key && value.size && value.filename && value.contentType) {
1030
1030
  row[key] = File.fromDbRecord(value);
1031
1031
  } else {
1032
- row[key] = value;
1032
+ row[key] = transformRichDataTypes(value);
1033
1033
  }
1034
1034
  } else {
1035
1035
  row[key] = value;
@@ -1150,23 +1150,23 @@ var TimePeriod = class _TimePeriod {
1150
1150
  return new _TimePeriod(period, value, offset, complete2);
1151
1151
  }
1152
1152
  periodStartSQL() {
1153
- let sql4 = "NOW()";
1153
+ let sql5 = "NOW()";
1154
1154
  if (this.offset !== 0) {
1155
- sql4 = `${sql4} + INTERVAL '${this.offset} ${this.period}'`;
1155
+ sql5 = `${sql5} + INTERVAL '${this.offset} ${this.period}'`;
1156
1156
  }
1157
1157
  if (this.complete) {
1158
- sql4 = `DATE_TRUNC('${this.period}', ${sql4})`;
1158
+ sql5 = `DATE_TRUNC('${this.period}', ${sql5})`;
1159
1159
  } else {
1160
- sql4 = `(${sql4})`;
1160
+ sql5 = `(${sql5})`;
1161
1161
  }
1162
- return sql4;
1162
+ return sql5;
1163
1163
  }
1164
1164
  periodEndSQL() {
1165
- let sql4 = this.periodStartSQL();
1165
+ let sql5 = this.periodStartSQL();
1166
1166
  if (this.value != 0) {
1167
- sql4 = `(${sql4} + INTERVAL '${this.value} ${this.period}')`;
1167
+ sql5 = `(${sql5} + INTERVAL '${this.value} ${this.period}')`;
1168
1168
  }
1169
- return sql4;
1169
+ return sql5;
1170
1170
  }
1171
1171
  };
1172
1172
 
@@ -2570,7 +2570,9 @@ var FlowRun = class _FlowRun {
2570
2570
  const name = spanNameForModelAPI(this._flowName, "refresh");
2571
2571
  return withSpan(name, async () => {
2572
2572
  const apiUrl = getApiUrl2();
2573
- const url = `${apiUrl}/flows/json/${this._flowName}/${this.id}`;
2573
+ const url = `${apiUrl}/flows/json/${encodeURIComponent(
2574
+ this._flowName
2575
+ )}/${encodeURIComponent(this.id)}`;
2574
2576
  const response = await fetch(url, {
2575
2577
  method: "GET",
2576
2578
  headers: buildHeaders2(this._identity, this._authToken)
@@ -2598,7 +2600,9 @@ var FlowRun = class _FlowRun {
2598
2600
  const name = spanNameForModelAPI(this._flowName, "cancel");
2599
2601
  return withSpan(name, async () => {
2600
2602
  const apiUrl = getApiUrl2();
2601
- const url = `${apiUrl}/flows/json/${this._flowName}/${this.id}/cancel`;
2603
+ const url = `${apiUrl}/flows/json/${encodeURIComponent(
2604
+ this._flowName
2605
+ )}/${encodeURIComponent(this.id)}/cancel`;
2602
2606
  const response = await fetch(url, {
2603
2607
  method: "POST",
2604
2608
  headers: buildHeaders2(this._identity, this._authToken)
@@ -2658,7 +2662,7 @@ var FlowsAPI = class _FlowsAPI {
2658
2662
  const name = spanNameForModelAPI(this._flowName, "start");
2659
2663
  return withSpan(name, async () => {
2660
2664
  const apiUrl = getApiUrl2();
2661
- const url = `${apiUrl}/flows/json/${this._flowName}`;
2665
+ const url = `${apiUrl}/flows/json/${encodeURIComponent(this._flowName)}`;
2662
2666
  const response = await fetch(url, {
2663
2667
  method: "POST",
2664
2668
  headers: buildHeaders2(this._identity, this._authToken),
@@ -2688,7 +2692,9 @@ var FlowsAPI = class _FlowsAPI {
2688
2692
  const name = spanNameForModelAPI(this._flowName, "get");
2689
2693
  return withSpan(name, async () => {
2690
2694
  const apiUrl = getApiUrl2();
2691
- const url = `${apiUrl}/flows/json/${this._flowName}/${runId}`;
2695
+ const url = `${apiUrl}/flows/json/${encodeURIComponent(
2696
+ this._flowName
2697
+ )}/${encodeURIComponent(runId)}`;
2692
2698
  const response = await fetch(url, {
2693
2699
  method: "GET",
2694
2700
  headers: buildHeaders2(this._identity, this._authToken)
@@ -2722,7 +2728,7 @@ var FlowsAPI = class _FlowsAPI {
2722
2728
  const params = new URLSearchParams();
2723
2729
  if (options.limit) params.set("limit", options.limit.toString());
2724
2730
  if (options.offset) params.set("offset", options.offset.toString());
2725
- const url = `${apiUrl}/flows/json/${this._flowName}${params.toString() ? "?" + params.toString() : ""}`;
2731
+ const url = `${apiUrl}/flows/json/${encodeURIComponent(this._flowName)}${params.toString() ? "?" + params.toString() : ""}`;
2726
2732
  const response = await fetch(url, {
2727
2733
  method: "GET",
2728
2734
  headers: buildHeaders2(this._identity, this._authToken)
@@ -3313,11 +3319,24 @@ var import_json_rpc_26 = require("json-rpc-2.0");
3313
3319
  var opentelemetry6 = __toESM(require("@opentelemetry/api"), 1);
3314
3320
 
3315
3321
  // src/tryExecuteFlow.js
3322
+ var import_kysely6 = require("kysely");
3316
3323
  function tryExecuteFlow(db, request, cb) {
3317
- return withDatabase(db, false, async () => {
3318
- return withAuditContext(request, async () => {
3319
- return cb();
3320
- });
3324
+ return withDatabase(db, false, async ({ sDb }) => {
3325
+ const runId = request?.meta?.runId;
3326
+ if (runId && sDb) {
3327
+ await import_kysely6.sql`SELECT pg_advisory_lock(hashtextextended(${runId}, 0))`.execute(
3328
+ sDb
3329
+ );
3330
+ }
3331
+ try {
3332
+ return await withAuditContext(request, async () => {
3333
+ return cb();
3334
+ });
3335
+ } finally {
3336
+ if (runId && sDb) {
3337
+ await import_kysely6.sql`SELECT pg_advisory_unlock(hashtextextended(${runId}, 0))`.execute(sDb).catch(() => void 0);
3338
+ }
3339
+ }
3321
3340
  });
3322
3341
  }
3323
3342
  __name(tryExecuteFlow, "tryExecuteFlow");
@@ -3909,6 +3928,104 @@ var fileInput = /* @__PURE__ */ __name((name, options) => {
3909
3928
  };
3910
3929
  }, "fileInput");
3911
3930
 
3931
+ // src/flows/ui/elements/input/imageCapture.ts
3932
+ var isMultiOptions = /* @__PURE__ */ __name((opts) => opts && opts.mode === "multi", "isMultiOptions");
3933
+ function validateEntry(entry, requireCaption, context7) {
3934
+ if (!entry?.file?.key) {
3935
+ return `${context7}: an image is required`;
3936
+ }
3937
+ if (requireCaption && !entry.caption?.trim()) {
3938
+ return `${context7}: a caption is required`;
3939
+ }
3940
+ return true;
3941
+ }
3942
+ __name(validateEntry, "validateEntry");
3943
+ var imageCapture = /* @__PURE__ */ __name((name, options) => {
3944
+ const requireCaption = options?.requireCaption ?? false;
3945
+ const mode = options?.mode ?? "single";
3946
+ const multi = isMultiOptions(options);
3947
+ const max = multi ? options?.max : void 0;
3948
+ const min = multi ? options?.min : void 0;
3949
+ return {
3950
+ __type: "input",
3951
+ uiConfig: {
3952
+ __type: "ui.input.imageCapture",
3953
+ name,
3954
+ label: options?.label || name,
3955
+ optional: options?.optional || false,
3956
+ disabled: options?.disabled || false,
3957
+ helpText: options?.helpText,
3958
+ mode,
3959
+ requireCaption,
3960
+ ...multi ? { max, min } : {}
3961
+ },
3962
+ validate: /* @__PURE__ */ __name(async (data, action) => {
3963
+ const optional = options?.optional ?? false;
3964
+ if (mode === "multi") {
3965
+ const list2 = data ?? [];
3966
+ if (list2.length === 0) {
3967
+ if (!optional) return "At least one image is required";
3968
+ } else {
3969
+ if (min !== void 0 && list2.length < min) {
3970
+ return `At least ${min} image${min === 1 ? "" : "s"} required`;
3971
+ }
3972
+ if (max !== void 0 && list2.length > max) {
3973
+ return `At most ${max} image${max === 1 ? "" : "s"} allowed`;
3974
+ }
3975
+ for (let i = 0; i < list2.length; i++) {
3976
+ const result = validateEntry(
3977
+ list2[i],
3978
+ requireCaption,
3979
+ `Image ${i + 1}`
3980
+ );
3981
+ if (result !== true) return result;
3982
+ }
3983
+ }
3984
+ } else {
3985
+ const entry = data;
3986
+ const hasFile = !!entry?.file?.key;
3987
+ if (!optional && !hasFile) {
3988
+ return "An image is required";
3989
+ }
3990
+ if (hasFile) {
3991
+ const result = validateEntry(entry, requireCaption, "Image");
3992
+ if (result !== true) return result;
3993
+ }
3994
+ }
3995
+ return options?.validate?.(
3996
+ data,
3997
+ action
3998
+ ) ?? true;
3999
+ }, "validate"),
4000
+ getData: /* @__PURE__ */ __name((x) => x, "getData"),
4001
+ getPresignedUploadURL: /* @__PURE__ */ __name((async (input) => {
4002
+ const file2 = new File(input);
4003
+ const url = await file2.getPresignedUploadUrl();
4004
+ return {
4005
+ url: url.toString(),
4006
+ key: file2.key
4007
+ };
4008
+ }), "getPresignedUploadURL")
4009
+ };
4010
+ }, "imageCapture");
4011
+
4012
+ // src/flows/ui/elements/input/signature.ts
4013
+ var signatureInput = /* @__PURE__ */ __name((name, options) => {
4014
+ return {
4015
+ __type: "input",
4016
+ uiConfig: {
4017
+ __type: "ui.input.signature",
4018
+ name,
4019
+ label: options?.label || name,
4020
+ optional: options?.optional || false,
4021
+ disabled: options?.disabled || false,
4022
+ helpText: options?.helpText
4023
+ },
4024
+ validate: options?.validate,
4025
+ getData: /* @__PURE__ */ __name((x) => x, "getData")
4026
+ };
4027
+ }, "signatureInput");
4028
+
3912
4029
  // src/flows/ui/elements/iterator.ts
3913
4030
  var iterator = /* @__PURE__ */ __name((name, options) => {
3914
4031
  return {
@@ -4343,7 +4460,9 @@ function createFlowContext(runId, data, action, callback, element, spanId, ctx)
4343
4460
  dataGrid: dataGridInput,
4344
4461
  datePicker: datePickerInput,
4345
4462
  scan,
4346
- file: fileInput
4463
+ file: fileInput,
4464
+ imageCapture,
4465
+ signature: signatureInput
4347
4466
  },
4348
4467
  display: {
4349
4468
  divider,