@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.d.cts CHANGED
@@ -565,55 +565,55 @@ type TraceAPI = {
565
565
  setAttributes(attributes: TraceAttributes): void;
566
566
  };
567
567
 
568
- type ElementDataType$5 = string | number | boolean | Date;
569
- type UiElementSelectOne = <const TValue extends ElementDataType$5, N extends string, O extends boolean = false>(name: N, options?: BaseInputConfig<TValue, O> & {
568
+ type ElementDataType$6 = string | number | boolean | Date;
569
+ type UiElementSelectOne = <const TValue extends ElementDataType$6, N extends string, O extends boolean = false>(name: N, options?: BaseInputConfig<TValue, O> & {
570
570
  options: ({
571
571
  label: string;
572
572
  value: TValue;
573
573
  } | TValue)[];
574
574
  }) => InputElementResponse<N, O extends true ? TValue | undefined : TValue>;
575
- interface UiElementSelectOneApiResponse extends BaseUiInputResponse<"ui.select.one", ElementDataType$5> {
575
+ interface UiElementSelectOneApiResponse extends BaseUiInputResponse<"ui.select.one", ElementDataType$6> {
576
576
  options: ({
577
577
  label: string;
578
- value: ElementDataType$5;
579
- } | ElementDataType$5)[];
578
+ value: ElementDataType$6;
579
+ } | ElementDataType$6)[];
580
580
  }
581
581
 
582
- type ElementDataType$4 = string;
583
- type UiElementInputText = InputElement<ElementDataType$4, {
582
+ type ElementDataType$5 = string;
583
+ type UiElementInputText = InputElement<ElementDataType$5, {
584
584
  placeholder?: string;
585
585
  multiline?: boolean;
586
586
  maxLength?: number;
587
587
  minLength?: number;
588
588
  }>;
589
- interface UiElementInputTextApiResponse extends BaseUiInputResponse<"ui.input.text", ElementDataType$4> {
589
+ interface UiElementInputTextApiResponse extends BaseUiInputResponse<"ui.input.text", ElementDataType$5> {
590
590
  placeholder?: string;
591
591
  multiline?: boolean;
592
592
  maxLength?: number;
593
593
  minLength?: number;
594
594
  }
595
595
 
596
- type ElementDataType$3 = number;
597
- type UiElementInputNumber = InputElement<ElementDataType$3, {
596
+ type ElementDataType$4 = number;
597
+ type UiElementInputNumber = InputElement<ElementDataType$4, {
598
598
  placeholder?: string;
599
599
  min?: number;
600
600
  max?: number;
601
601
  }>;
602
- interface UiElementInputNumberApiResponse extends BaseUiInputResponse<"ui.input.number", ElementDataType$3> {
602
+ interface UiElementInputNumberApiResponse extends BaseUiInputResponse<"ui.input.number", ElementDataType$4> {
603
603
  placeholder?: string;
604
604
  min?: number;
605
605
  max?: number;
606
606
  }
607
607
 
608
- type ElementDataType$2 = boolean;
609
- type UiElementInputBoolean = InputElement<ElementDataType$2, {
608
+ type ElementDataType$3 = boolean;
609
+ type UiElementInputBoolean = InputElement<ElementDataType$3, {
610
610
  mode?: "checkbox" | "switch";
611
611
  }>;
612
- interface UiElementInputBooleanApiResponse extends BaseUiInputResponse<"ui.input.boolean", ElementDataType$2> {
612
+ interface UiElementInputBooleanApiResponse extends BaseUiInputResponse<"ui.input.boolean", ElementDataType$3> {
613
613
  mode: "checkbox" | "switch";
614
614
  }
615
615
 
616
- type ElementDataType$1 = string;
616
+ type ElementDataType$2 = string;
617
617
  /**
618
618
  * Defines what type of datepicker should we use.
619
619
  * @default "dateTime"
@@ -623,22 +623,73 @@ type DatePickerMode =
623
623
  "dateTime"
624
624
  /** Pick only a date */
625
625
  | "date";
626
- type UiElementInputDatePicker = InputElement<ElementDataType$1, {
626
+ type UiElementInputDatePicker = InputElement<ElementDataType$2, {
627
627
  mode?: DatePickerMode;
628
628
  /** Allows selecting only dates/datetimes past this given date. */
629
629
  min?: string;
630
630
  /** Allows selecting only dates/datetimes before this given date. */
631
631
  max?: string;
632
632
  }>;
633
- interface UiElementInputDatePickerApiResponse extends BaseUiInputResponse<"ui.input.datePicker", ElementDataType$1> {
633
+ interface UiElementInputDatePickerApiResponse extends BaseUiInputResponse<"ui.input.datePicker", ElementDataType$2> {
634
634
  mode?: DatePickerMode;
635
635
  min?: string;
636
636
  max?: string;
637
637
  }
638
638
 
639
- type ElementDataType = Partial<FileDbRecord>;
640
- type UiElementInputFile = InputElement<ElementDataType, {}, File>;
641
- interface UiElementInputFileApiResponse extends BaseUiInputResponse<"ui.input.file", ElementDataType> {
639
+ type ElementDataType$1 = Partial<FileDbRecord>;
640
+ type UiElementInputFile = InputElement<ElementDataType$1, {}, File>;
641
+ interface UiElementInputFileApiResponse extends BaseUiInputResponse<"ui.input.file", ElementDataType$1> {
642
+ }
643
+
644
+ /**
645
+ * Data posted by the client for a single image capture entry.
646
+ * `file` carries the upload metadata (the bytes go via the presigned URL).
647
+ */
648
+ type ImageCaptureValue = {
649
+ file: Partial<FileDbRecord>;
650
+ caption?: string;
651
+ };
652
+ /**
653
+ * Hydrated entry handed to the flow function: `file` becomes a real File
654
+ * instance (via transformRichDataTypes).
655
+ */
656
+ type ImageCaptureResult = {
657
+ file: File;
658
+ caption?: string;
659
+ };
660
+ type ImageCaptureMode = "single" | "multi";
661
+ type ImageCaptureValueFor<M> = M extends "multi" ? ImageCaptureValue[] : ImageCaptureValue;
662
+ type ImageCaptureResultFor<M> = M extends "multi" ? ImageCaptureResult[] : ImageCaptureResult;
663
+ type SharedOptions = {
664
+ /** When true, every captured image must have a caption. */
665
+ requireCaption?: boolean;
666
+ };
667
+ type ImageCaptureOptions<M extends ImageCaptureMode> = SharedOptions & {
668
+ /** The mode of the image capture input. Defaults to "single". */
669
+ mode?: M;
670
+ } & (M extends "multi" ? {
671
+ /** Maximum number of photos the user can capture. */
672
+ max?: number;
673
+ /** Minimum number of photos the user must capture. */
674
+ min?: number;
675
+ } : {});
676
+ type UiElementInputImageCapture = <N extends string, const M extends ImageCaptureMode = "single">(name: N, options?: BaseInputConfig<ImageCaptureValueFor<M>> & ImageCaptureOptions<M>) => InputElementResponse<N, ImageCaptureValueFor<M>, ImageCaptureResultFor<M>>;
677
+ interface UiElementInputImageCaptureApiResponse extends BaseUiInputResponse<"ui.input.imageCapture", ImageCaptureValue | ImageCaptureValue[]> {
678
+ mode: ImageCaptureMode;
679
+ requireCaption: boolean;
680
+ /** Multi mode only: maximum number of photos. */
681
+ max?: number;
682
+ /** Multi mode only: minimum number of photos. */
683
+ min?: number;
684
+ }
685
+
686
+ type ElementDataType = {
687
+ svg: string;
688
+ signedAt: string;
689
+ ipAddress: string;
690
+ };
691
+ type UiElementInputSignature = InputElement<ElementDataType, {}>;
692
+ interface UiElementInputSignatureApiResponse extends BaseUiInputResponse<"ui.input.signature", ElementDataType> {
642
693
  }
643
694
 
644
695
  type UiElementMarkdown = DisplayElement<{
@@ -1146,6 +1197,8 @@ type UiInputsElements = {
1146
1197
  datePicker: UiElementInputDatePicker;
1147
1198
  scan: UiElementScan;
1148
1199
  file: UiElementInputFile;
1200
+ imageCapture: UiElementInputImageCapture;
1201
+ signature: UiElementInputSignature;
1149
1202
  };
1150
1203
  type UiSelectElements = {
1151
1204
  one: UiElementSelectOne;
@@ -1250,6 +1303,8 @@ type UIApiResponses = {
1250
1303
  datePicker: UiElementInputDatePickerApiResponse;
1251
1304
  scan: UiElementInputScanApiResponse;
1252
1305
  file: UiElementInputFileApiResponse;
1306
+ imageCapture: UiElementInputImageCaptureApiResponse;
1307
+ signature: UiElementInputSignatureApiResponse;
1253
1308
  };
1254
1309
  select: {
1255
1310
  one: UiElementSelectOneApiResponse;
@@ -1261,7 +1316,7 @@ type UIApiResponses = {
1261
1316
  pickList: UiElementPickListApiResponse;
1262
1317
  };
1263
1318
  };
1264
- type UiElementApiResponse = UiElementDividerApiResponse | UiElementMarkdownApiResponse | UiElementHeaderApiResponse | UiElementBannerApiResponse | UiElementImageApiResponse | UiElementCodeApiResponse | UiElementGridApiResponse | UiElementListApiResponse | UiElementTableApiResponse | UiElementKeyValueApiResponse | UiElementFileApiResponse | UiElementInputTextApiResponse | UiElementInputNumberApiResponse | UiElementInputBooleanApiResponse | UiElementInputDataGridApiResponse | UiElementInputScanApiResponse | UiElementInputDatePickerApiResponse | UiElementInputFileApiResponse | UiElementSelectOneApiResponse | UiElementSelectTableApiResponse | UiElementIteratorApiResponse | UiElementPrintApiResponse | UiElementPickListApiResponse;
1319
+ type UiElementApiResponse = UiElementDividerApiResponse | UiElementMarkdownApiResponse | UiElementHeaderApiResponse | UiElementBannerApiResponse | UiElementImageApiResponse | UiElementCodeApiResponse | UiElementGridApiResponse | UiElementListApiResponse | UiElementTableApiResponse | UiElementKeyValueApiResponse | UiElementFileApiResponse | UiElementInputTextApiResponse | UiElementInputNumberApiResponse | UiElementInputBooleanApiResponse | UiElementInputDataGridApiResponse | UiElementInputScanApiResponse | UiElementInputDatePickerApiResponse | UiElementInputFileApiResponse | UiElementInputImageCaptureApiResponse | UiElementInputSignatureApiResponse | UiElementSelectOneApiResponse | UiElementSelectTableApiResponse | UiElementIteratorApiResponse | UiElementPrintApiResponse | UiElementPickListApiResponse;
1265
1320
  type UiElementApiResponses = UiElementApiResponse[];
1266
1321
 
1267
1322
  declare class NonRetriableError extends Error {
package/dist/index.d.ts CHANGED
@@ -565,55 +565,55 @@ type TraceAPI = {
565
565
  setAttributes(attributes: TraceAttributes): void;
566
566
  };
567
567
 
568
- type ElementDataType$5 = string | number | boolean | Date;
569
- type UiElementSelectOne = <const TValue extends ElementDataType$5, N extends string, O extends boolean = false>(name: N, options?: BaseInputConfig<TValue, O> & {
568
+ type ElementDataType$6 = string | number | boolean | Date;
569
+ type UiElementSelectOne = <const TValue extends ElementDataType$6, N extends string, O extends boolean = false>(name: N, options?: BaseInputConfig<TValue, O> & {
570
570
  options: ({
571
571
  label: string;
572
572
  value: TValue;
573
573
  } | TValue)[];
574
574
  }) => InputElementResponse<N, O extends true ? TValue | undefined : TValue>;
575
- interface UiElementSelectOneApiResponse extends BaseUiInputResponse<"ui.select.one", ElementDataType$5> {
575
+ interface UiElementSelectOneApiResponse extends BaseUiInputResponse<"ui.select.one", ElementDataType$6> {
576
576
  options: ({
577
577
  label: string;
578
- value: ElementDataType$5;
579
- } | ElementDataType$5)[];
578
+ value: ElementDataType$6;
579
+ } | ElementDataType$6)[];
580
580
  }
581
581
 
582
- type ElementDataType$4 = string;
583
- type UiElementInputText = InputElement<ElementDataType$4, {
582
+ type ElementDataType$5 = string;
583
+ type UiElementInputText = InputElement<ElementDataType$5, {
584
584
  placeholder?: string;
585
585
  multiline?: boolean;
586
586
  maxLength?: number;
587
587
  minLength?: number;
588
588
  }>;
589
- interface UiElementInputTextApiResponse extends BaseUiInputResponse<"ui.input.text", ElementDataType$4> {
589
+ interface UiElementInputTextApiResponse extends BaseUiInputResponse<"ui.input.text", ElementDataType$5> {
590
590
  placeholder?: string;
591
591
  multiline?: boolean;
592
592
  maxLength?: number;
593
593
  minLength?: number;
594
594
  }
595
595
 
596
- type ElementDataType$3 = number;
597
- type UiElementInputNumber = InputElement<ElementDataType$3, {
596
+ type ElementDataType$4 = number;
597
+ type UiElementInputNumber = InputElement<ElementDataType$4, {
598
598
  placeholder?: string;
599
599
  min?: number;
600
600
  max?: number;
601
601
  }>;
602
- interface UiElementInputNumberApiResponse extends BaseUiInputResponse<"ui.input.number", ElementDataType$3> {
602
+ interface UiElementInputNumberApiResponse extends BaseUiInputResponse<"ui.input.number", ElementDataType$4> {
603
603
  placeholder?: string;
604
604
  min?: number;
605
605
  max?: number;
606
606
  }
607
607
 
608
- type ElementDataType$2 = boolean;
609
- type UiElementInputBoolean = InputElement<ElementDataType$2, {
608
+ type ElementDataType$3 = boolean;
609
+ type UiElementInputBoolean = InputElement<ElementDataType$3, {
610
610
  mode?: "checkbox" | "switch";
611
611
  }>;
612
- interface UiElementInputBooleanApiResponse extends BaseUiInputResponse<"ui.input.boolean", ElementDataType$2> {
612
+ interface UiElementInputBooleanApiResponse extends BaseUiInputResponse<"ui.input.boolean", ElementDataType$3> {
613
613
  mode: "checkbox" | "switch";
614
614
  }
615
615
 
616
- type ElementDataType$1 = string;
616
+ type ElementDataType$2 = string;
617
617
  /**
618
618
  * Defines what type of datepicker should we use.
619
619
  * @default "dateTime"
@@ -623,22 +623,73 @@ type DatePickerMode =
623
623
  "dateTime"
624
624
  /** Pick only a date */
625
625
  | "date";
626
- type UiElementInputDatePicker = InputElement<ElementDataType$1, {
626
+ type UiElementInputDatePicker = InputElement<ElementDataType$2, {
627
627
  mode?: DatePickerMode;
628
628
  /** Allows selecting only dates/datetimes past this given date. */
629
629
  min?: string;
630
630
  /** Allows selecting only dates/datetimes before this given date. */
631
631
  max?: string;
632
632
  }>;
633
- interface UiElementInputDatePickerApiResponse extends BaseUiInputResponse<"ui.input.datePicker", ElementDataType$1> {
633
+ interface UiElementInputDatePickerApiResponse extends BaseUiInputResponse<"ui.input.datePicker", ElementDataType$2> {
634
634
  mode?: DatePickerMode;
635
635
  min?: string;
636
636
  max?: string;
637
637
  }
638
638
 
639
- type ElementDataType = Partial<FileDbRecord>;
640
- type UiElementInputFile = InputElement<ElementDataType, {}, File>;
641
- interface UiElementInputFileApiResponse extends BaseUiInputResponse<"ui.input.file", ElementDataType> {
639
+ type ElementDataType$1 = Partial<FileDbRecord>;
640
+ type UiElementInputFile = InputElement<ElementDataType$1, {}, File>;
641
+ interface UiElementInputFileApiResponse extends BaseUiInputResponse<"ui.input.file", ElementDataType$1> {
642
+ }
643
+
644
+ /**
645
+ * Data posted by the client for a single image capture entry.
646
+ * `file` carries the upload metadata (the bytes go via the presigned URL).
647
+ */
648
+ type ImageCaptureValue = {
649
+ file: Partial<FileDbRecord>;
650
+ caption?: string;
651
+ };
652
+ /**
653
+ * Hydrated entry handed to the flow function: `file` becomes a real File
654
+ * instance (via transformRichDataTypes).
655
+ */
656
+ type ImageCaptureResult = {
657
+ file: File;
658
+ caption?: string;
659
+ };
660
+ type ImageCaptureMode = "single" | "multi";
661
+ type ImageCaptureValueFor<M> = M extends "multi" ? ImageCaptureValue[] : ImageCaptureValue;
662
+ type ImageCaptureResultFor<M> = M extends "multi" ? ImageCaptureResult[] : ImageCaptureResult;
663
+ type SharedOptions = {
664
+ /** When true, every captured image must have a caption. */
665
+ requireCaption?: boolean;
666
+ };
667
+ type ImageCaptureOptions<M extends ImageCaptureMode> = SharedOptions & {
668
+ /** The mode of the image capture input. Defaults to "single". */
669
+ mode?: M;
670
+ } & (M extends "multi" ? {
671
+ /** Maximum number of photos the user can capture. */
672
+ max?: number;
673
+ /** Minimum number of photos the user must capture. */
674
+ min?: number;
675
+ } : {});
676
+ type UiElementInputImageCapture = <N extends string, const M extends ImageCaptureMode = "single">(name: N, options?: BaseInputConfig<ImageCaptureValueFor<M>> & ImageCaptureOptions<M>) => InputElementResponse<N, ImageCaptureValueFor<M>, ImageCaptureResultFor<M>>;
677
+ interface UiElementInputImageCaptureApiResponse extends BaseUiInputResponse<"ui.input.imageCapture", ImageCaptureValue | ImageCaptureValue[]> {
678
+ mode: ImageCaptureMode;
679
+ requireCaption: boolean;
680
+ /** Multi mode only: maximum number of photos. */
681
+ max?: number;
682
+ /** Multi mode only: minimum number of photos. */
683
+ min?: number;
684
+ }
685
+
686
+ type ElementDataType = {
687
+ svg: string;
688
+ signedAt: string;
689
+ ipAddress: string;
690
+ };
691
+ type UiElementInputSignature = InputElement<ElementDataType, {}>;
692
+ interface UiElementInputSignatureApiResponse extends BaseUiInputResponse<"ui.input.signature", ElementDataType> {
642
693
  }
643
694
 
644
695
  type UiElementMarkdown = DisplayElement<{
@@ -1146,6 +1197,8 @@ type UiInputsElements = {
1146
1197
  datePicker: UiElementInputDatePicker;
1147
1198
  scan: UiElementScan;
1148
1199
  file: UiElementInputFile;
1200
+ imageCapture: UiElementInputImageCapture;
1201
+ signature: UiElementInputSignature;
1149
1202
  };
1150
1203
  type UiSelectElements = {
1151
1204
  one: UiElementSelectOne;
@@ -1250,6 +1303,8 @@ type UIApiResponses = {
1250
1303
  datePicker: UiElementInputDatePickerApiResponse;
1251
1304
  scan: UiElementInputScanApiResponse;
1252
1305
  file: UiElementInputFileApiResponse;
1306
+ imageCapture: UiElementInputImageCaptureApiResponse;
1307
+ signature: UiElementInputSignatureApiResponse;
1253
1308
  };
1254
1309
  select: {
1255
1310
  one: UiElementSelectOneApiResponse;
@@ -1261,7 +1316,7 @@ type UIApiResponses = {
1261
1316
  pickList: UiElementPickListApiResponse;
1262
1317
  };
1263
1318
  };
1264
- type UiElementApiResponse = UiElementDividerApiResponse | UiElementMarkdownApiResponse | UiElementHeaderApiResponse | UiElementBannerApiResponse | UiElementImageApiResponse | UiElementCodeApiResponse | UiElementGridApiResponse | UiElementListApiResponse | UiElementTableApiResponse | UiElementKeyValueApiResponse | UiElementFileApiResponse | UiElementInputTextApiResponse | UiElementInputNumberApiResponse | UiElementInputBooleanApiResponse | UiElementInputDataGridApiResponse | UiElementInputScanApiResponse | UiElementInputDatePickerApiResponse | UiElementInputFileApiResponse | UiElementSelectOneApiResponse | UiElementSelectTableApiResponse | UiElementIteratorApiResponse | UiElementPrintApiResponse | UiElementPickListApiResponse;
1319
+ type UiElementApiResponse = UiElementDividerApiResponse | UiElementMarkdownApiResponse | UiElementHeaderApiResponse | UiElementBannerApiResponse | UiElementImageApiResponse | UiElementCodeApiResponse | UiElementGridApiResponse | UiElementListApiResponse | UiElementTableApiResponse | UiElementKeyValueApiResponse | UiElementFileApiResponse | UiElementInputTextApiResponse | UiElementInputNumberApiResponse | UiElementInputBooleanApiResponse | UiElementInputDataGridApiResponse | UiElementInputScanApiResponse | UiElementInputDatePickerApiResponse | UiElementInputFileApiResponse | UiElementInputImageCaptureApiResponse | UiElementInputSignatureApiResponse | UiElementSelectOneApiResponse | UiElementSelectTableApiResponse | UiElementIteratorApiResponse | UiElementPrintApiResponse | UiElementPickListApiResponse;
1265
1320
  type UiElementApiResponses = UiElementApiResponse[];
1266
1321
 
1267
1322
  declare class NonRetriableError extends Error {
package/dist/index.js CHANGED
@@ -530,9 +530,9 @@ var InstrumentedClient = class extends Client {
530
530
  }
531
531
  async query(...args) {
532
532
  const _super = super.query.bind(this);
533
- const sql4 = args[0];
533
+ const sql5 = args[0];
534
534
  let sqlAttribute = false;
535
- let spanName = txStatements[sql4.toLowerCase()];
535
+ let spanName = txStatements[sql5.toLowerCase()];
536
536
  if (!spanName) {
537
537
  spanName = "Database Query";
538
538
  sqlAttribute = true;
@@ -600,9 +600,9 @@ function getDialect(connString) {
600
600
  pool.on("connect", (client) => {
601
601
  const originalQuery = client.query;
602
602
  client.query = function(...args) {
603
- const sql4 = args[0];
603
+ const sql5 = args[0];
604
604
  let sqlAttribute = false;
605
- let spanName = txStatements[sql4.toLowerCase()];
605
+ let spanName = txStatements[sql5.toLowerCase()];
606
606
  if (!spanName) {
607
607
  spanName = "Database Query";
608
608
  sqlAttribute = true;
@@ -976,7 +976,7 @@ function transformRichDataTypes(data) {
976
976
  } else if (value.key && value.size && value.filename && value.contentType) {
977
977
  row[key] = File.fromDbRecord(value);
978
978
  } else {
979
- row[key] = value;
979
+ row[key] = transformRichDataTypes(value);
980
980
  }
981
981
  } else {
982
982
  row[key] = value;
@@ -1097,23 +1097,23 @@ var TimePeriod = class _TimePeriod {
1097
1097
  return new _TimePeriod(period, value, offset, complete2);
1098
1098
  }
1099
1099
  periodStartSQL() {
1100
- let sql4 = "NOW()";
1100
+ let sql5 = "NOW()";
1101
1101
  if (this.offset !== 0) {
1102
- sql4 = `${sql4} + INTERVAL '${this.offset} ${this.period}'`;
1102
+ sql5 = `${sql5} + INTERVAL '${this.offset} ${this.period}'`;
1103
1103
  }
1104
1104
  if (this.complete) {
1105
- sql4 = `DATE_TRUNC('${this.period}', ${sql4})`;
1105
+ sql5 = `DATE_TRUNC('${this.period}', ${sql5})`;
1106
1106
  } else {
1107
- sql4 = `(${sql4})`;
1107
+ sql5 = `(${sql5})`;
1108
1108
  }
1109
- return sql4;
1109
+ return sql5;
1110
1110
  }
1111
1111
  periodEndSQL() {
1112
- let sql4 = this.periodStartSQL();
1112
+ let sql5 = this.periodStartSQL();
1113
1113
  if (this.value != 0) {
1114
- sql4 = `(${sql4} + INTERVAL '${this.value} ${this.period}')`;
1114
+ sql5 = `(${sql5} + INTERVAL '${this.value} ${this.period}')`;
1115
1115
  }
1116
- return sql4;
1116
+ return sql5;
1117
1117
  }
1118
1118
  };
1119
1119
 
@@ -2517,7 +2517,9 @@ var FlowRun = class _FlowRun {
2517
2517
  const name = spanNameForModelAPI(this._flowName, "refresh");
2518
2518
  return withSpan(name, async () => {
2519
2519
  const apiUrl = getApiUrl2();
2520
- const url = `${apiUrl}/flows/json/${this._flowName}/${this.id}`;
2520
+ const url = `${apiUrl}/flows/json/${encodeURIComponent(
2521
+ this._flowName
2522
+ )}/${encodeURIComponent(this.id)}`;
2521
2523
  const response = await fetch(url, {
2522
2524
  method: "GET",
2523
2525
  headers: buildHeaders2(this._identity, this._authToken)
@@ -2545,7 +2547,9 @@ var FlowRun = class _FlowRun {
2545
2547
  const name = spanNameForModelAPI(this._flowName, "cancel");
2546
2548
  return withSpan(name, async () => {
2547
2549
  const apiUrl = getApiUrl2();
2548
- const url = `${apiUrl}/flows/json/${this._flowName}/${this.id}/cancel`;
2550
+ const url = `${apiUrl}/flows/json/${encodeURIComponent(
2551
+ this._flowName
2552
+ )}/${encodeURIComponent(this.id)}/cancel`;
2549
2553
  const response = await fetch(url, {
2550
2554
  method: "POST",
2551
2555
  headers: buildHeaders2(this._identity, this._authToken)
@@ -2605,7 +2609,7 @@ var FlowsAPI = class _FlowsAPI {
2605
2609
  const name = spanNameForModelAPI(this._flowName, "start");
2606
2610
  return withSpan(name, async () => {
2607
2611
  const apiUrl = getApiUrl2();
2608
- const url = `${apiUrl}/flows/json/${this._flowName}`;
2612
+ const url = `${apiUrl}/flows/json/${encodeURIComponent(this._flowName)}`;
2609
2613
  const response = await fetch(url, {
2610
2614
  method: "POST",
2611
2615
  headers: buildHeaders2(this._identity, this._authToken),
@@ -2635,7 +2639,9 @@ var FlowsAPI = class _FlowsAPI {
2635
2639
  const name = spanNameForModelAPI(this._flowName, "get");
2636
2640
  return withSpan(name, async () => {
2637
2641
  const apiUrl = getApiUrl2();
2638
- const url = `${apiUrl}/flows/json/${this._flowName}/${runId}`;
2642
+ const url = `${apiUrl}/flows/json/${encodeURIComponent(
2643
+ this._flowName
2644
+ )}/${encodeURIComponent(runId)}`;
2639
2645
  const response = await fetch(url, {
2640
2646
  method: "GET",
2641
2647
  headers: buildHeaders2(this._identity, this._authToken)
@@ -2669,7 +2675,7 @@ var FlowsAPI = class _FlowsAPI {
2669
2675
  const params = new URLSearchParams();
2670
2676
  if (options.limit) params.set("limit", options.limit.toString());
2671
2677
  if (options.offset) params.set("offset", options.offset.toString());
2672
- const url = `${apiUrl}/flows/json/${this._flowName}${params.toString() ? "?" + params.toString() : ""}`;
2678
+ const url = `${apiUrl}/flows/json/${encodeURIComponent(this._flowName)}${params.toString() ? "?" + params.toString() : ""}`;
2673
2679
  const response = await fetch(url, {
2674
2680
  method: "GET",
2675
2681
  headers: buildHeaders2(this._identity, this._authToken)
@@ -3280,11 +3286,24 @@ import {
3280
3286
  import * as opentelemetry6 from "@opentelemetry/api";
3281
3287
 
3282
3288
  // src/tryExecuteFlow.js
3289
+ import { sql as sql4 } from "kysely";
3283
3290
  function tryExecuteFlow(db, request, cb) {
3284
- return withDatabase(db, false, async () => {
3285
- return withAuditContext(request, async () => {
3286
- return cb();
3287
- });
3291
+ return withDatabase(db, false, async ({ sDb }) => {
3292
+ const runId = request?.meta?.runId;
3293
+ if (runId && sDb) {
3294
+ await sql4`SELECT pg_advisory_lock(hashtextextended(${runId}, 0))`.execute(
3295
+ sDb
3296
+ );
3297
+ }
3298
+ try {
3299
+ return await withAuditContext(request, async () => {
3300
+ return cb();
3301
+ });
3302
+ } finally {
3303
+ if (runId && sDb) {
3304
+ await sql4`SELECT pg_advisory_unlock(hashtextextended(${runId}, 0))`.execute(sDb).catch(() => void 0);
3305
+ }
3306
+ }
3288
3307
  });
3289
3308
  }
3290
3309
  __name(tryExecuteFlow, "tryExecuteFlow");
@@ -3876,6 +3895,104 @@ var fileInput = /* @__PURE__ */ __name((name, options) => {
3876
3895
  };
3877
3896
  }, "fileInput");
3878
3897
 
3898
+ // src/flows/ui/elements/input/imageCapture.ts
3899
+ var isMultiOptions = /* @__PURE__ */ __name((opts) => opts && opts.mode === "multi", "isMultiOptions");
3900
+ function validateEntry(entry, requireCaption, context7) {
3901
+ if (!entry?.file?.key) {
3902
+ return `${context7}: an image is required`;
3903
+ }
3904
+ if (requireCaption && !entry.caption?.trim()) {
3905
+ return `${context7}: a caption is required`;
3906
+ }
3907
+ return true;
3908
+ }
3909
+ __name(validateEntry, "validateEntry");
3910
+ var imageCapture = /* @__PURE__ */ __name((name, options) => {
3911
+ const requireCaption = options?.requireCaption ?? false;
3912
+ const mode = options?.mode ?? "single";
3913
+ const multi = isMultiOptions(options);
3914
+ const max = multi ? options?.max : void 0;
3915
+ const min = multi ? options?.min : void 0;
3916
+ return {
3917
+ __type: "input",
3918
+ uiConfig: {
3919
+ __type: "ui.input.imageCapture",
3920
+ name,
3921
+ label: options?.label || name,
3922
+ optional: options?.optional || false,
3923
+ disabled: options?.disabled || false,
3924
+ helpText: options?.helpText,
3925
+ mode,
3926
+ requireCaption,
3927
+ ...multi ? { max, min } : {}
3928
+ },
3929
+ validate: /* @__PURE__ */ __name(async (data, action) => {
3930
+ const optional = options?.optional ?? false;
3931
+ if (mode === "multi") {
3932
+ const list2 = data ?? [];
3933
+ if (list2.length === 0) {
3934
+ if (!optional) return "At least one image is required";
3935
+ } else {
3936
+ if (min !== void 0 && list2.length < min) {
3937
+ return `At least ${min} image${min === 1 ? "" : "s"} required`;
3938
+ }
3939
+ if (max !== void 0 && list2.length > max) {
3940
+ return `At most ${max} image${max === 1 ? "" : "s"} allowed`;
3941
+ }
3942
+ for (let i = 0; i < list2.length; i++) {
3943
+ const result = validateEntry(
3944
+ list2[i],
3945
+ requireCaption,
3946
+ `Image ${i + 1}`
3947
+ );
3948
+ if (result !== true) return result;
3949
+ }
3950
+ }
3951
+ } else {
3952
+ const entry = data;
3953
+ const hasFile = !!entry?.file?.key;
3954
+ if (!optional && !hasFile) {
3955
+ return "An image is required";
3956
+ }
3957
+ if (hasFile) {
3958
+ const result = validateEntry(entry, requireCaption, "Image");
3959
+ if (result !== true) return result;
3960
+ }
3961
+ }
3962
+ return options?.validate?.(
3963
+ data,
3964
+ action
3965
+ ) ?? true;
3966
+ }, "validate"),
3967
+ getData: /* @__PURE__ */ __name((x) => x, "getData"),
3968
+ getPresignedUploadURL: /* @__PURE__ */ __name((async (input) => {
3969
+ const file2 = new File(input);
3970
+ const url = await file2.getPresignedUploadUrl();
3971
+ return {
3972
+ url: url.toString(),
3973
+ key: file2.key
3974
+ };
3975
+ }), "getPresignedUploadURL")
3976
+ };
3977
+ }, "imageCapture");
3978
+
3979
+ // src/flows/ui/elements/input/signature.ts
3980
+ var signatureInput = /* @__PURE__ */ __name((name, options) => {
3981
+ return {
3982
+ __type: "input",
3983
+ uiConfig: {
3984
+ __type: "ui.input.signature",
3985
+ name,
3986
+ label: options?.label || name,
3987
+ optional: options?.optional || false,
3988
+ disabled: options?.disabled || false,
3989
+ helpText: options?.helpText
3990
+ },
3991
+ validate: options?.validate,
3992
+ getData: /* @__PURE__ */ __name((x) => x, "getData")
3993
+ };
3994
+ }, "signatureInput");
3995
+
3879
3996
  // src/flows/ui/elements/iterator.ts
3880
3997
  var iterator = /* @__PURE__ */ __name((name, options) => {
3881
3998
  return {
@@ -4310,7 +4427,9 @@ function createFlowContext(runId, data, action, callback, element, spanId, ctx)
4310
4427
  dataGrid: dataGridInput,
4311
4428
  datePicker: datePickerInput,
4312
4429
  scan,
4313
- file: fileInput
4430
+ file: fileInput,
4431
+ imageCapture,
4432
+ signature: signatureInput
4314
4433
  },
4315
4434
  display: {
4316
4435
  divider,