@encatch/schema 1.2.0-beta.9 → 1.2.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/esm/index.js CHANGED
@@ -11,7 +11,9 @@ var baseQuestionTranslationFieldsSchema = z.object({
11
11
  title: translationEntrySchema.describe("Question title translation"),
12
12
  description: translationEntrySchema.optional().describe("Question description translation"),
13
13
  errorMessage: translationEntrySchema.optional().describe("Error message translation"),
14
- nextButtonLabel: translationEntrySchema.max(50).optional().describe("Next button label translation when advancing past this question")
14
+ nextButtonLabel: translationEntrySchema.max(50).optional().describe(
15
+ "Next button label translation when advancing past this question"
16
+ )
15
17
  });
16
18
  var BASE_QUESTION_TRANSLATION_KEYS = [
17
19
  "type",
@@ -33,9 +35,13 @@ var singleChoiceQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.
33
35
  const additionalKeys = Object.keys(data).filter(
34
36
  (key) => ![...BASE_QUESTION_TRANSLATION_KEYS, "placeholder"].includes(key)
35
37
  );
36
- return additionalKeys.every((key) => /^option\..+\.(label|value)$/.test(key));
38
+ return additionalKeys.every(
39
+ (key) => /^option\..+\.(label|value)$/.test(key)
40
+ );
37
41
  },
38
- { message: "Additional keys must follow the pattern 'option.{id}.{label|value}'" }
42
+ {
43
+ message: "Additional keys must follow the pattern 'option.{id}.{label|value}'"
44
+ }
39
45
  ).describe("Translation schema for single choice questions");
40
46
  var multipleChoiceQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
41
47
  type: z.literal("multiple_choice_multiple").describe("Question type identifier"),
@@ -45,9 +51,13 @@ var multipleChoiceQuestionTranslationSchema = baseQuestionTranslationFieldsSchem
45
51
  const additionalKeys = Object.keys(data).filter(
46
52
  (key) => ![...BASE_QUESTION_TRANSLATION_KEYS, "placeholder"].includes(key)
47
53
  );
48
- return additionalKeys.every((key) => /^option\..+\.(label|value)$/.test(key));
54
+ return additionalKeys.every(
55
+ (key) => /^option\..+\.(label|value)$/.test(key)
56
+ );
49
57
  },
50
- { message: "Additional keys must follow the pattern 'option.{id}.{label|value}'" }
58
+ {
59
+ message: "Additional keys must follow the pattern 'option.{id}.{label|value}'"
60
+ }
51
61
  ).describe("Translation schema for multiple choice questions");
52
62
  var npsQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
53
63
  type: z.literal("nps").describe("Question type identifier"),
@@ -56,11 +66,15 @@ var npsQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
56
66
  }).catchall(translationEntrySchema).refine(
57
67
  (data) => {
58
68
  const additionalKeys = Object.keys(data).filter(
59
- (key) => ![...BASE_QUESTION_TRANSLATION_KEYS, "minLabel", "maxLabel"].includes(key)
69
+ (key) => ![...BASE_QUESTION_TRANSLATION_KEYS, "minLabel", "maxLabel"].includes(
70
+ key
71
+ )
60
72
  );
61
73
  return additionalKeys.every((key) => /^scaleLabel\.\d+$/.test(key));
62
74
  },
63
- { message: "Additional keys must follow the pattern 'scaleLabel.{number}'" }
75
+ {
76
+ message: "Additional keys must follow the pattern 'scaleLabel.{number}'"
77
+ }
64
78
  ).describe("Translation schema for NPS questions");
65
79
  var shortAnswerQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
66
80
  type: z.literal("short_answer").describe("Question type identifier"),
@@ -102,6 +116,29 @@ var signatureQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.ext
102
116
  uploadZonePrimary: z.string().max(200).optional().describe("Translated idle upload prompt"),
103
117
  uploadZoneDrag: z.string().max(120).optional().describe("Translated drag-over upload prompt")
104
118
  }).describe("Translation schema for signature questions");
119
+ var schedulerQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
120
+ type: z.literal("scheduler").describe("Question type identifier"),
121
+ placeholder: z.string().max(200).optional().describe(
122
+ "Fallback for meeting CTA when scheduleMeetingLabel is unset"
123
+ ),
124
+ scheduleMeetingLabel: z.string().max(200).optional().describe("Book-a-meeting button and modal label")
125
+ }).describe("Translation schema for scheduler questions");
126
+ var qnaWithAiQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
127
+ type: z.literal("qna_with_ai").describe("Question type identifier"),
128
+ placeholder: z.string().max(200).optional().describe("Input placeholder for the question field"),
129
+ askButtonLabel: z.string().max(50).optional().describe("Ask / submit control label"),
130
+ emptyStateHint: z.string().max(200).optional().describe("Empty chat area hint"),
131
+ pairsRemainingTemplate: z.string().max(160).optional().describe("Under-limit counter; tokens {remaining} and {max}"),
132
+ pairsLimitReachedTemplate: z.string().max(160).optional().describe("At-limit message; token {max}")
133
+ }).describe("Translation schema for Q&A with AI questions");
134
+ var paymentsUpiQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
135
+ type: z.literal("payments_upi").describe("Question type identifier"),
136
+ qrLabel: z.string().max(100).optional().describe("Label shown above the UPI QR code"),
137
+ openUpiAppLabel: z.string().max(80).optional().describe("UPI intent button label"),
138
+ copyUpiIdLabel: z.string().max(80).optional().describe("Copy UPI ID button label"),
139
+ transactionIdLabel: z.string().max(100).optional().describe("Transaction ID / UTR input label"),
140
+ transactionIdPlaceholder: z.string().max(120).optional().describe("Transaction ID / UTR input placeholder")
141
+ }).describe("Translation schema for payments_upi questions");
105
142
  var nestedSelectionQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
106
143
  type: z.literal("nested_selection").describe("Question type identifier"),
107
144
  placeholder: translationEntrySchema.optional().describe("Dropdown placeholder translation")
@@ -110,9 +147,13 @@ var nestedSelectionQuestionTranslationSchema = baseQuestionTranslationFieldsSche
110
147
  const additionalKeys = Object.keys(data).filter(
111
148
  (key) => ![...BASE_QUESTION_TRANSLATION_KEYS, "placeholder"].includes(key)
112
149
  );
113
- return additionalKeys.every((key) => /^nestedOption\..+\.(label|hint)$/.test(key));
150
+ return additionalKeys.every(
151
+ (key) => /^nestedOption\..+\.(label|hint)$/.test(key)
152
+ );
114
153
  },
115
- { message: "Additional keys must follow the pattern 'nestedOption.{id}.{label|hint}'" }
154
+ {
155
+ message: "Additional keys must follow the pattern 'nestedOption.{id}.{label|hint}'"
156
+ }
116
157
  ).describe("Translation schema for nested selection questions");
117
158
  var annotationQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
118
159
  type: z.literal("annotation").describe("Question type identifier"),
@@ -130,7 +171,9 @@ var messagePanelQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.
130
171
  }).describe("Translation schema for message panel questions");
131
172
  var consentQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
132
173
  type: z.literal("consent").describe("Question type identifier")
133
- }).describe("Translation schema for consent questions; description carries the translated checkbox label (markdown supported)");
174
+ }).describe(
175
+ "Translation schema for consent questions; description carries the translated checkbox label (markdown supported)"
176
+ );
134
177
  var yesNoQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
135
178
  type: z.literal("yes_no").describe("Question type identifier"),
136
179
  yesLabel: translationEntrySchema.optional().describe("Translated Yes label"),
@@ -147,9 +190,11 @@ var ratingMatrixQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.
147
190
  }).catchall(translationEntrySchema).refine(
148
191
  (data) => {
149
192
  const additionalKeys = Object.keys(data).filter(
150
- (key) => ![...BASE_QUESTION_TRANSLATION_KEYS, "minLabel", "maxLabel"].includes(
151
- key
152
- )
193
+ (key) => ![
194
+ ...BASE_QUESTION_TRANSLATION_KEYS,
195
+ "minLabel",
196
+ "maxLabel"
197
+ ].includes(key)
153
198
  );
154
199
  return additionalKeys.every(
155
200
  (key) => /^statement\..+\.label$/.test(key) || /^scalePoint\..+\.label$/.test(key)
@@ -199,6 +244,9 @@ var questionTranslationSchema = z.union([
199
244
  videoAudioQuestionTranslationSchema,
200
245
  dateQuestionTranslationSchema,
201
246
  signatureQuestionTranslationSchema,
247
+ schedulerQuestionTranslationSchema,
248
+ qnaWithAiQuestionTranslationSchema,
249
+ paymentsUpiQuestionTranslationSchema,
202
250
  nestedSelectionQuestionTranslationSchema,
203
251
  annotationQuestionTranslationSchema,
204
252
  welcomeQuestionTranslationSchema,
@@ -218,8 +266,12 @@ var sectionTranslationSchema = z.object({
218
266
  }).describe("Translation payload for a section in a single language");
219
267
  var sectionTranslationsByLanguageSchema = z.record(languageCodeSchema, sectionTranslationSchema).describe("Section translations keyed by language code");
220
268
  var questionTranslationsByLanguageSchema = z.record(languageCodeSchema, questionTranslationSchema).describe("Question translations keyed by language code");
221
- var questionCentricTranslationsSchema = z.record(z.string().uuid(), questionTranslationsByLanguageSchema).describe("Question-centric translations keyed by question ID, then by language code");
222
- var translationsSchema = questionCentricTranslationsSchema.describe("Question-centric translations at root level");
269
+ var questionCentricTranslationsSchema = z.record(z.string().uuid(), questionTranslationsByLanguageSchema).describe(
270
+ "Question-centric translations keyed by question ID, then by language code"
271
+ );
272
+ var translationsSchema = questionCentricTranslationsSchema.describe(
273
+ "Question-centric translations at root level"
274
+ );
223
275
  var _TranslationProvider = class _TranslationProvider {
224
276
  constructor(translations, defaultLanguage = "en") {
225
277
  this.translations = translations;
@@ -241,7 +293,10 @@ var _TranslationProvider = class _TranslationProvider {
241
293
  * Get a specific translation text by field path
242
294
  */
243
295
  getTranslationText(questionId, languageCode, fieldPath) {
244
- const questionTranslation = this.getQuestionTranslations(questionId, languageCode);
296
+ const questionTranslation = this.getQuestionTranslations(
297
+ questionId,
298
+ languageCode
299
+ );
245
300
  if (!questionTranslation) return null;
246
301
  if (fieldPath in questionTranslation) {
247
302
  const value = questionTranslation[fieldPath];
@@ -344,7 +399,8 @@ var questionTypeSchema = z2.enum([
344
399
  "address",
345
400
  "video_audio",
346
401
  "scheduler",
347
- "qna_with_ai"
402
+ "qna_with_ai",
403
+ "payments_upi"
348
404
  ]).describe("Enumeration of all supported question types for form fields");
349
405
  var QuestionTypes = {
350
406
  RATING: "rating",
@@ -378,7 +434,8 @@ var QuestionTypes = {
378
434
  ADDRESS: "address",
379
435
  VIDEO_AUDIO: "video_audio",
380
436
  SCHEDULER: "scheduler",
381
- QNA_WITH_AI: "qna_with_ai"
437
+ QNA_WITH_AI: "qna_with_ai",
438
+ PAYMENTS_UPI: "payments_upi"
382
439
  };
383
440
  var validationRuleTypeSchema = z2.enum([
384
441
  "required",
@@ -430,7 +487,9 @@ var VisibilityConditionOperators = {
430
487
  };
431
488
  var visibilityConditionSchema = z2.object({
432
489
  field: z2.string().describe("ID of the field to check against"),
433
- operator: visibilityConditionOperatorSchema.describe("Comparison operator for the condition"),
490
+ operator: visibilityConditionOperatorSchema.describe(
491
+ "Comparison operator for the condition"
492
+ ),
434
493
  value: z2.union([z2.string(), z2.number(), z2.boolean()]).optional().describe("Value to compare against (string, number, or boolean)"),
435
494
  describe: z2.string().max(500).optional().describe("LLM tool call description for this visibility condition")
436
495
  }).describe(
@@ -453,7 +512,9 @@ var sectionSchema = z2.object({
453
512
  "When the global previousButton mode is 'auto', controls whether the Previous button is shown for this section. Defaults to false (hidden)."
454
513
  ),
455
514
  questionIds: z2.array(z2.string()).min(1).describe("Array of question IDs that belong to this section")
456
- }).describe("Schema defining sections that organize questions into logical groups");
515
+ }).describe(
516
+ "Schema defining sections that organize questions into logical groups"
517
+ );
457
518
  var questionStatusSchema = z2.enum(["D", "P", "A", "S"]);
458
519
  var QuestionStatuses = {
459
520
  DRAFT: "D",
@@ -561,8 +622,12 @@ var questionSchema = z2.object({
561
622
  "Label for the next button when advancing past this question (overrides section or form defaults when set)"
562
623
  ),
563
624
  showQuestionTitle: z2.boolean().default(true).describe("Whether to display the question title; defaults to true"),
564
- questionMediaUrl: z2.string().url().optional().describe("Optional URL for media (image or video) displayed alongside the question"),
565
- questionMediaType: z2.enum(["image", "video", "youtube", "vimeo"]).optional().describe("Type of media referenced by questionMediaUrl; one of 'image', 'video', 'youtube', or 'vimeo'")
625
+ questionMediaUrl: z2.string().url().optional().describe(
626
+ "Optional URL for media (image or video) displayed alongside the question"
627
+ ),
628
+ questionMediaType: z2.enum(["image", "video", "youtube", "vimeo"]).optional().describe(
629
+ "Type of media referenced by questionMediaUrl; one of 'image', 'video', 'youtube', or 'vimeo'"
630
+ )
566
631
  }).describe("Base schema for all question types with common properties");
567
632
  var ratingQuestionSchema = questionSchema.extend({
568
633
  type: z2.literal("rating").describe("Must be exactly 'rating'"),
@@ -586,7 +651,9 @@ var welcomeQuestionSchema = questionSchema.extend({
586
651
  title: z2.string().min(1).max(200).describe("The main heading displayed on the welcome screen"),
587
652
  description: z2.string().max(1e3).optional().describe("Optional sub-text body shown below the heading"),
588
653
  imageUrl: z2.string().url().optional().describe("Optional image URL displayed on the welcome screen")
589
- }).describe("Schema for a welcome screen displayed at the start or inline within a form");
654
+ }).describe(
655
+ "Schema for a welcome screen displayed at the start or inline within a form"
656
+ );
590
657
  var thankYouQuestionSchema = questionSchema.extend({
591
658
  type: z2.literal("thank_you").describe("Must be exactly 'thank_you'"),
592
659
  title: z2.string().min(1).max(200).describe("The main heading displayed on the thank you screen"),
@@ -612,10 +679,18 @@ var exitFormQuestionSchema = questionSchema.extend({
612
679
  );
613
680
  var yesNoQuestionSchema = questionSchema.extend({
614
681
  type: z2.literal("yes_no").describe("Must be exactly 'yes_no'"),
615
- yesLabel: z2.string().min(1).max(50).optional().describe("Label for the Yes option (defaults to 'Yes' in the UI if omitted)"),
616
- noLabel: z2.string().min(1).max(50).optional().describe("Label for the No option (defaults to 'No' in the UI if omitted)"),
617
- displayStyle: yesNoDisplayStyleSchema.optional().describe("Layout for the Yes/No controls (horizontal row or vertical stack)")
618
- }).describe("Schema for yes/no questions with optional custom labels and layout");
682
+ yesLabel: z2.string().min(1).max(50).optional().describe(
683
+ "Label for the Yes option (defaults to 'Yes' in the UI if omitted)"
684
+ ),
685
+ noLabel: z2.string().min(1).max(50).optional().describe(
686
+ "Label for the No option (defaults to 'No' in the UI if omitted)"
687
+ ),
688
+ displayStyle: yesNoDisplayStyleSchema.optional().describe(
689
+ "Layout for the Yes/No controls (horizontal row or vertical stack)"
690
+ )
691
+ }).describe(
692
+ "Schema for yes/no questions with optional custom labels and layout"
693
+ );
619
694
  var consentQuestionSchema = questionSchema.extend({
620
695
  type: z2.literal("consent").describe("Must be exactly 'consent'")
621
696
  }).describe(
@@ -634,14 +709,18 @@ var RatingMatrixDisplayStyles = {
634
709
  BUTTON: "button"
635
710
  };
636
711
  var ratingMatrixStatementSchema = z2.object({
637
- id: z2.string().describe("Unique identifier for this statement (system time milliseconds)"),
712
+ id: z2.string().describe(
713
+ "Unique identifier for this statement (system time milliseconds)"
714
+ ),
638
715
  value: z2.string().min(1).max(100).describe("Internal value / export key for this statement"),
639
716
  label: z2.string().min(1).max(200).describe("Display text shown to users for this statement"),
640
717
  describe: z2.string().max(500).optional().describe("LLM tool call description for this statement")
641
718
  }).describe("Schema for an individual statement (row) in a rating matrix");
642
719
  var ratingMatrixScalePointSchema = z2.object({
643
720
  id: z2.string().describe("Unique identifier for this scale point"),
644
- value: z2.union([z2.number(), z2.string()]).describe("Stored response value for this scale point (number or string)"),
721
+ value: z2.union([z2.number(), z2.string()]).describe(
722
+ "Stored response value for this scale point (number or string)"
723
+ ),
645
724
  label: z2.string().min(1).max(200).describe("Display label shown for this scale point"),
646
725
  describe: z2.string().max(500).optional().describe("LLM tool call description for this scale point")
647
726
  }).describe("Schema for a single point on a custom rating scale");
@@ -666,12 +745,16 @@ var ratingMatrixScaleSchema = z2.discriminatedUnion("kind", [
666
745
  var ratingMatrixQuestionSchema = questionSchema.extend({
667
746
  type: z2.literal("rating_matrix").describe("Must be exactly 'rating_matrix'"),
668
747
  statements: z2.array(ratingMatrixStatementSchema).min(1).max(10).describe("Statements (rows) users will rate on the shared scale (1-10)"),
669
- scale: ratingMatrixScaleSchema.describe("Scale configuration shared across all statement rows"),
748
+ scale: ratingMatrixScaleSchema.describe(
749
+ "Scale configuration shared across all statement rows"
750
+ ),
670
751
  displayStyle: ratingMatrixDisplayStyleSchema.optional().describe(
671
752
  "Visual representation of scale points per row (radio buttons, stars, emoji, or buttons)"
672
753
  ),
673
754
  randomizeStatements: z2.boolean().optional().default(false).describe("Whether to randomize the order of statements")
674
- }).describe("Schema for rating matrix questions with multiple statements on a shared scale");
755
+ }).describe(
756
+ "Schema for rating matrix questions with multiple statements on a shared scale"
757
+ );
675
758
  var matrixRowSchema = z2.object({
676
759
  id: z2.string().describe("Unique identifier for this row (system time milliseconds)"),
677
760
  value: z2.string().min(1).max(100).describe("Internal value / export key for this row"),
@@ -690,7 +773,9 @@ var matrixSingleChoiceQuestionSchema = questionSchema.extend({
690
773
  columns: z2.array(matrixColumnSchema).min(2).max(10).describe("Column options shared across all rows (2-10 columns)"),
691
774
  randomizeRows: z2.boolean().optional().default(false).describe("Whether to randomize the order of rows"),
692
775
  randomizeColumns: z2.boolean().optional().default(false).describe("Whether to randomize the order of columns")
693
- }).describe("Schema for matrix single-choice questions where one column is selected per row");
776
+ }).describe(
777
+ "Schema for matrix single-choice questions where one column is selected per row"
778
+ );
694
779
  var matrixMultipleChoiceQuestionSchema = questionSchema.extend({
695
780
  type: z2.literal("matrix_multiple_choice").describe("Must be exactly 'matrix_multiple_choice'"),
696
781
  rows: z2.array(matrixRowSchema).min(1).max(20).describe("Row items (1-20 rows)"),
@@ -717,7 +802,9 @@ var questionOptionSchema = z2.object({
717
802
  id: z2.string().describe("Unique identifier for this option (system time milliseconds)"),
718
803
  value: z2.string().min(1).max(100).describe("The internal value used for this option"),
719
804
  label: z2.string().min(1).max(200).describe("The display text shown to users for this option"),
720
- hint: z2.string().max(300).optional().describe("Optional short description shown below the option label to help respondents understand what they are selecting or ranking"),
805
+ hint: z2.string().max(300).optional().describe(
806
+ "Optional short description shown below the option label to help respondents understand what they are selecting or ranking"
807
+ ),
721
808
  describe: z2.string().max(500).optional().describe(
722
809
  "LLM tool call description providing context about this option"
723
810
  ),
@@ -725,7 +812,9 @@ var questionOptionSchema = z2.object({
725
812
  }).describe("Schema for individual options in choice-based questions");
726
813
  var nestedOptionSchema = z2.lazy(
727
814
  () => z2.object({
728
- id: z2.string().describe("Unique identifier for this nested option (system time milliseconds)"),
815
+ id: z2.string().describe(
816
+ "Unique identifier for this nested option (system time milliseconds)"
817
+ ),
729
818
  value: z2.string().min(1).max(100).describe("The internal value used for this nested option"),
730
819
  label: z2.string().min(1).max(200).describe("The display text shown for this nested option"),
731
820
  describe: z2.string().max(500).optional().describe("LLM tool call description for this nested option context"),
@@ -744,7 +833,9 @@ var multipleChoiceSingleQuestionSchema = questionSchema.extend({
744
833
  minChars: z2.number().int().min(0).optional().describe("Minimum number of characters required for the other text"),
745
834
  maxChars: z2.number().int().min(1).optional().describe("Maximum number of characters allowed for the other text"),
746
835
  placeholder: z2.string().max(200).optional().describe("Placeholder text for the other text input"),
747
- showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe("Show the character limit indicator (e.g. '12/100') once the user has typed this many characters; 0 = show immediately, absent = never show")
836
+ showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe(
837
+ "Show the character limit indicator (e.g. '12/100') once the user has typed this many characters; 0 = show immediately, absent = never show"
838
+ )
748
839
  }).optional().describe('Configuration for the custom "other" text input'),
749
840
  randomizeOptions: z2.boolean().optional().default(false).describe("Whether to randomize the order of options"),
750
841
  options: z2.array(questionOptionSchema).min(1).max(50).describe("Array of options for user selection (1-50 options)")
@@ -757,7 +848,9 @@ var multipleChoiceMultipleQuestionSchema = questionSchema.extend({
757
848
  minChars: z2.number().int().min(0).optional().describe("Minimum number of characters required for the other text"),
758
849
  maxChars: z2.number().int().min(1).optional().describe("Maximum number of characters allowed for the other text"),
759
850
  placeholder: z2.string().max(200).optional().describe("Placeholder text for the other text input"),
760
- showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe("Show the character limit indicator (e.g. '12/100') once the user has typed this many characters; 0 = show immediately, absent = never show")
851
+ showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe(
852
+ "Show the character limit indicator (e.g. '12/100') once the user has typed this many characters; 0 = show immediately, absent = never show"
853
+ )
761
854
  }).optional().describe('Configuration for the custom "other" text input'),
762
855
  minSelections: z2.number().int().min(0).optional().describe("Minimum number of options that must be selected"),
763
856
  maxSelections: z2.number().int().min(1).optional().describe("Maximum number of options that can be selected"),
@@ -786,9 +879,15 @@ var npsQuestionSchema = questionSchema.extend({
786
879
  maxLabel: z2.string().max(100).optional().describe("Label for the maximum NPS value (10)"),
787
880
  scaleLabels: z2.record(z2.string().regex(/^\d+$/), z2.string().max(50)).optional().describe("Custom labels for specific NPS values (0-10)"),
788
881
  prepopulatedValue: z2.number().int().min(0).max(10).optional().describe("Default value to pre-select (0-10)"),
789
- detractorColor: z2.string().max(50).optional().describe("Color applied to detractor scores (0\u20136); accepts any valid CSS color value (hex, rgb, hsl, named)"),
790
- passiveColor: z2.string().max(50).optional().describe("Color applied to passive scores (7\u20138); accepts any valid CSS color value"),
791
- promoterColor: z2.string().max(50).optional().describe("Color applied to promoter scores (9\u201310); accepts any valid CSS color value")
882
+ detractorColor: z2.string().max(50).optional().describe(
883
+ "Color applied to detractor scores (0\u20136); accepts any valid CSS color value (hex, rgb, hsl, named)"
884
+ ),
885
+ passiveColor: z2.string().max(50).optional().describe(
886
+ "Color applied to passive scores (7\u20138); accepts any valid CSS color value"
887
+ ),
888
+ promoterColor: z2.string().max(50).optional().describe(
889
+ "Color applied to promoter scores (9\u201310); accepts any valid CSS color value"
890
+ )
792
891
  }).refine(
793
892
  (data) => {
794
893
  if (data.scaleLabels) {
@@ -809,7 +908,9 @@ var shortAnswerQuestionSchema = questionSchema.extend({
809
908
  type: z2.literal("short_answer").describe("Must be exactly 'short_answer'"),
810
909
  maxCharacters: z2.number().int().min(1).max(1e4).optional().describe("Maximum number of characters allowed"),
811
910
  minCharacters: z2.number().int().min(0).optional().describe("Minimum number of characters required"),
812
- showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe("Show the character limit indicator (e.g. '12/100') once the user has typed this many characters; 0 = show immediately, absent = never show"),
911
+ showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe(
912
+ "Show the character limit indicator (e.g. '12/100') once the user has typed this many characters; 0 = show immediately, absent = never show"
913
+ ),
813
914
  placeholder: z2.string().max(200).optional().describe("Placeholder text shown in the input field"),
814
915
  enableRegexValidation: z2.boolean().optional().default(false).describe("Whether to enable regex pattern validation"),
815
916
  regexPattern: z2.string().optional().describe("Regular expression pattern for validation"),
@@ -857,7 +958,9 @@ var longAnswerQuestionSchema = questionSchema.extend({
857
958
  "Maximum number of characters allowed (higher limit for long text)"
858
959
  ),
859
960
  minCharacters: z2.number().int().min(0).optional().describe("Minimum number of characters required"),
860
- showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe("Show the character limit indicator (e.g. '12/100') once the user has typed this many characters; 0 = show immediately, absent = never show"),
961
+ showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe(
962
+ "Show the character limit indicator (e.g. '12/100') once the user has typed this many characters; 0 = show immediately, absent = never show"
963
+ ),
861
964
  rows: z2.number().int().min(1).max(20).optional().describe("Number of textarea rows to display (1-20)"),
862
965
  placeholder: z2.string().max(500).optional().describe("Placeholder text for the textarea (longer for long text)"),
863
966
  enableEnhanceWithAi: z2.boolean().optional().default(false).describe("Whether to enable AI enhancement features"),
@@ -940,14 +1043,24 @@ var dateQuestionSchema = questionSchema.extend({
940
1043
  format: dateFormatSchema.optional().default("DD/MM/YYYY").describe("Order of day, month, and year segments in the input"),
941
1044
  separator: dateSeparatorSchema.optional().default("/").describe("Character used to separate day, month, and year segments"),
942
1045
  includeTime: z2.boolean().optional().default(false).describe("Whether to also collect a time (HH:MM) alongside the date"),
943
- minDate: z2.string().optional().describe("Earliest allowed date in ISO 8601 format (YYYY-MM-DD); when absent no lower bound is enforced"),
944
- maxDate: z2.string().optional().describe("Latest allowed date in ISO 8601 format (YYYY-MM-DD); when absent no upper bound is enforced"),
1046
+ minDate: z2.string().optional().describe(
1047
+ "Earliest allowed date in ISO 8601 format (YYYY-MM-DD); when absent no lower bound is enforced"
1048
+ ),
1049
+ maxDate: z2.string().optional().describe(
1050
+ "Latest allowed date in ISO 8601 format (YYYY-MM-DD); when absent no upper bound is enforced"
1051
+ ),
945
1052
  placeholder: z2.string().max(50).optional().describe("Placeholder text shown in the date input"),
946
- segmentLabelDD: z2.string().max(40).optional().describe("Visible label above the day segment; when absent a locale default is used"),
1053
+ segmentLabelDD: z2.string().max(40).optional().describe(
1054
+ "Visible label above the day segment; when absent a locale default is used"
1055
+ ),
947
1056
  segmentLabelMM: z2.string().max(40).optional().describe("Visible label above the month segment"),
948
1057
  segmentLabelYYYY: z2.string().max(40).optional().describe("Visible label above the year segment"),
949
- prepopulatedValue: z2.string().optional().describe("Default date value in ISO 8601 format (YYYY-MM-DD) to pre-fill the input")
950
- }).describe("Schema for a date question that collects a structured date (and optionally time) from the respondent");
1058
+ prepopulatedValue: z2.string().optional().describe(
1059
+ "Default date value in ISO 8601 format (YYYY-MM-DD) to pre-fill the input"
1060
+ )
1061
+ }).describe(
1062
+ "Schema for a date question that collects a structured date (and optionally time) from the respondent"
1063
+ );
951
1064
  var csatScaleSchema = z2.union([
952
1065
  z2.literal(2),
953
1066
  z2.literal(3),
@@ -967,23 +1080,53 @@ var CsatDisplayStyles = {
967
1080
  };
968
1081
  var csatQuestionSchema = questionSchema.extend({
969
1082
  type: z2.literal("csat").describe("Must be exactly 'csat'"),
970
- scale: csatScaleSchema.optional().default(5).describe("Number of response points (2\u20135); 2 and 4 have no neutral option, default is 5"),
971
- displayStyle: csatDisplayStyleSchema.optional().default("emoji").describe("How response options are rendered \u2014 emoji faces (default) or text buttons"),
972
- multicolor: z2.boolean().optional().default(false).describe("Whether to apply distinct colors to negative, neutral, and positive segments"),
973
- negativeColor: z2.string().max(50).optional().describe("Color for negative response options (lower half of scale); any valid CSS color; used when multicolor is true"),
974
- neutralColor: z2.string().max(50).optional().describe("Color for the neutral midpoint option (odd scales only: scale 3 = value 2, scale 5 = value 3); any valid CSS color; used when multicolor is true"),
975
- positiveColor: z2.string().max(50).optional().describe("Color for positive response options (upper half of scale); any valid CSS color; used when multicolor is true"),
976
- showLabels: z2.boolean().optional().default(false).describe("Whether to render per-point labels below each response option"),
977
- scaleLabels: z2.record(z2.string(), z2.string().max(100)).optional().describe("Per-point label text keyed by value string ('1'\u2013'5'); keys must match the chosen scale size")
978
- }).describe("Schema for a CSAT (Customer Satisfaction Score) question using an industry-standard 1-to-N positive scale (N = 2\u20135)");
1083
+ scale: csatScaleSchema.optional().default(5).describe(
1084
+ "Number of response points (2\u20135); 2 and 4 have no neutral option, default is 5"
1085
+ ),
1086
+ displayStyle: csatDisplayStyleSchema.optional().default("emoji").describe(
1087
+ "How response options are rendered \u2014 emoji faces (default) or text buttons"
1088
+ ),
1089
+ multicolor: z2.boolean().optional().default(false).describe(
1090
+ "Whether to apply distinct colors to negative, neutral, and positive segments"
1091
+ ),
1092
+ negativeColor: z2.string().max(50).optional().describe(
1093
+ "Color for negative response options (lower half of scale); any valid CSS color; used when multicolor is true"
1094
+ ),
1095
+ neutralColor: z2.string().max(50).optional().describe(
1096
+ "Color for the neutral midpoint option (odd scales only: scale 3 = value 2, scale 5 = value 3); any valid CSS color; used when multicolor is true"
1097
+ ),
1098
+ positiveColor: z2.string().max(50).optional().describe(
1099
+ "Color for positive response options (upper half of scale); any valid CSS color; used when multicolor is true"
1100
+ ),
1101
+ showLabels: z2.boolean().optional().default(false).describe(
1102
+ "Whether to render per-point labels below each response option"
1103
+ ),
1104
+ scaleLabels: z2.record(z2.string(), z2.string().max(100)).optional().describe(
1105
+ "Per-point label text keyed by value string ('1'\u2013'5'); keys must match the chosen scale size"
1106
+ )
1107
+ }).describe(
1108
+ "Schema for a CSAT (Customer Satisfaction Score) question using an industry-standard 1-to-N positive scale (N = 2\u20135)"
1109
+ );
979
1110
  var opinionScaleQuestionSchema = questionSchema.extend({
980
1111
  type: z2.literal("opinion_scale").describe("Must be exactly 'opinion_scale'"),
981
1112
  startValue: z2.union([z2.literal(0), z2.literal(1)]).optional().default(0).describe("Starting value of the scale \u2014 0 (default) or 1"),
982
- steps: z2.number().int().min(5).max(11).optional().default(11).describe("Number of points on the scale (5\u201311); default 11 gives a 0\u201310 or 1\u201311 range depending on startValue"),
983
- minLabel: z2.string().max(100).optional().describe("Optional label anchoring the low end of the scale (e.g. 'Not at all likely')"),
984
- maxLabel: z2.string().max(100).optional().describe("Optional label anchoring the high end of the scale (e.g. 'Extremely likely')")
985
- }).describe("Schema for an opinion scale question \u2014 a horizontal numeric button scale with configurable range and optional end labels");
986
- var rankingDisplayStyleSchema = z2.enum(["drag_drop", "dropdown", "up_down"]);
1113
+ steps: z2.number().int().min(5).max(11).optional().default(11).describe(
1114
+ "Number of points on the scale (5\u201311); default 11 gives a 0\u201310 or 1\u201311 range depending on startValue"
1115
+ ),
1116
+ minLabel: z2.string().max(100).optional().describe(
1117
+ "Optional label anchoring the low end of the scale (e.g. 'Not at all likely')"
1118
+ ),
1119
+ maxLabel: z2.string().max(100).optional().describe(
1120
+ "Optional label anchoring the high end of the scale (e.g. 'Extremely likely')"
1121
+ )
1122
+ }).describe(
1123
+ "Schema for an opinion scale question \u2014 a horizontal numeric button scale with configurable range and optional end labels"
1124
+ );
1125
+ var rankingDisplayStyleSchema = z2.enum([
1126
+ "drag_drop",
1127
+ "dropdown",
1128
+ "up_down"
1129
+ ]);
987
1130
  var RankingDisplayStyles = {
988
1131
  DRAG_DROP: "drag_drop",
989
1132
  DROPDOWN: "dropdown",
@@ -991,32 +1134,54 @@ var RankingDisplayStyles = {
991
1134
  };
992
1135
  var rankingQuestionSchema = questionSchema.extend({
993
1136
  type: z2.literal("ranking").describe("Must be exactly 'ranking'"),
994
- options: z2.array(questionOptionSchema).min(2).max(30).describe("List of items to rank (2\u201330 items); each item supports an optional hint for clarification"),
995
- randomizeOptions: z2.boolean().optional().default(false).describe("Whether to shuffle item order per respondent to avoid position bias"),
996
- displayStyle: rankingDisplayStyleSchema.optional().default("drag_drop").describe("Interaction mode \u2014 drag_drop (default) for drag-and-drop reordering, dropdown for selecting a rank number per item, up_down for arrow button reordering"),
997
- maxRank: z2.number().int().min(1).optional().describe("Maximum number of items the respondent must rank (e.g. 3 = 'rank your top 3'); when absent all items must be ranked")
1137
+ options: z2.array(questionOptionSchema).min(2).max(30).describe(
1138
+ "List of items to rank (2\u201330 items); each item supports an optional hint for clarification"
1139
+ ),
1140
+ randomizeOptions: z2.boolean().optional().default(false).describe(
1141
+ "Whether to shuffle item order per respondent to avoid position bias"
1142
+ ),
1143
+ displayStyle: rankingDisplayStyleSchema.optional().default("drag_drop").describe(
1144
+ "Interaction mode \u2014 drag_drop (default) for drag-and-drop reordering, dropdown for selecting a rank number per item, up_down for arrow button reordering"
1145
+ ),
1146
+ maxRank: z2.number().int().min(1).optional().describe(
1147
+ "Maximum number of items the respondent must rank (e.g. 3 = 'rank your top 3'); when absent all items must be ranked"
1148
+ )
998
1149
  }).refine(
999
1150
  (data) => data.maxRank === void 0 || data.maxRank <= data.options.length,
1000
1151
  {
1001
1152
  message: "maxRank cannot exceed the number of options",
1002
1153
  path: ["maxRank"]
1003
1154
  }
1004
- ).describe("Schema for a ranking question where respondents order items by preference");
1155
+ ).describe(
1156
+ "Schema for a ranking question where respondents order items by preference"
1157
+ );
1005
1158
  var pictureChoiceQuestionSchema = questionSchema.extend({
1006
1159
  type: z2.literal("picture_choice").describe("Must be exactly 'picture_choice'"),
1007
- options: z2.array(questionOptionSchema).min(1).max(50).describe("Array of options; each should include an imageUrl for the picture to display"),
1008
- multiple: z2.boolean().optional().default(false).describe("When true respondents may select more than one image; when false (default) only one image can be selected"),
1009
- minSelections: z2.number().int().min(1).optional().describe("Minimum number of images the respondent must select (only applies when multiple is true)"),
1010
- maxSelections: z2.number().int().min(1).optional().describe("Maximum number of images the respondent may select (only applies when multiple is true)"),
1160
+ options: z2.array(questionOptionSchema).min(1).max(50).describe(
1161
+ "Array of options; each should include an imageUrl for the picture to display"
1162
+ ),
1163
+ multiple: z2.boolean().optional().default(false).describe(
1164
+ "When true respondents may select more than one image; when false (default) only one image can be selected"
1165
+ ),
1166
+ minSelections: z2.number().int().min(1).optional().describe(
1167
+ "Minimum number of images the respondent must select (only applies when multiple is true)"
1168
+ ),
1169
+ maxSelections: z2.number().int().min(1).optional().describe(
1170
+ "Maximum number of images the respondent may select (only applies when multiple is true)"
1171
+ ),
1011
1172
  supersize: z2.boolean().optional().default(false).describe("Whether to display images at an enlarged size"),
1012
1173
  showLabels: z2.boolean().optional().default(true).describe("Whether to show the text label below each image"),
1013
- randomizeOptions: z2.boolean().optional().default(false).describe("Whether to shuffle image order per respondent to avoid position bias"),
1174
+ randomizeOptions: z2.boolean().optional().default(false).describe(
1175
+ "Whether to shuffle image order per respondent to avoid position bias"
1176
+ ),
1014
1177
  allowOther: z2.boolean().optional().default(false).describe('Whether to include a free-text "other" option'),
1015
1178
  otherTextConfig: z2.object({
1016
1179
  minChars: z2.number().int().min(0).optional().describe("Minimum number of characters required for the other text"),
1017
1180
  maxChars: z2.number().int().min(1).optional().describe("Maximum number of characters allowed for the other text"),
1018
1181
  placeholder: z2.string().max(200).optional().describe("Placeholder text for the other text input"),
1019
- showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe("Show the character limit indicator once the user has typed this many characters; 0 = show immediately, absent = never show")
1182
+ showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe(
1183
+ "Show the character limit indicator once the user has typed this many characters; 0 = show immediately, absent = never show"
1184
+ )
1020
1185
  }).optional().describe('Configuration for the custom "other" text input')
1021
1186
  }).refine(
1022
1187
  (data) => {
@@ -1029,7 +1194,9 @@ var pictureChoiceQuestionSchema = questionSchema.extend({
1029
1194
  message: "minSelections cannot be greater than maxSelections",
1030
1195
  path: ["minSelections"]
1031
1196
  }
1032
- ).describe("Schema for a picture choice question where respondents select from image-based options");
1197
+ ).describe(
1198
+ "Schema for a picture choice question where respondents select from image-based options"
1199
+ );
1033
1200
  var signatureModeSchema = z2.enum(["type", "draw", "upload"]);
1034
1201
  var SignatureModes = {
1035
1202
  TYPE: "type",
@@ -1038,82 +1205,162 @@ var SignatureModes = {
1038
1205
  };
1039
1206
  var signatureQuestionSchema = questionSchema.extend({
1040
1207
  type: z2.literal("signature").describe("Must be exactly 'signature'"),
1041
- allowedModes: z2.array(signatureModeSchema).min(1).optional().describe("Which signing methods the respondent can choose from (type, draw, upload); when absent all three are enabled"),
1042
- defaultMode: signatureModeSchema.optional().describe("Which signing tab is pre-selected when the question is first shown; when absent the platform chooses"),
1043
- collectSignerEmail: z2.boolean().optional().default(true).describe("Whether to auto-collect the signer's email so a signed PDF copy can be sent to them; set to false if the form already collects an email via signerEmailFieldId or another question"),
1044
- signerEmailFieldId: z2.string().optional().describe("ID of an existing email question in the form whose value will be used as the signer's email address, instead of auto-appending a new email prompt"),
1045
- penColor: z2.string().max(50).optional().describe("Stroke color for the draw canvas; any valid CSS color; when absent the theme foreground color is used"),
1046
- penWidth: z2.number().int().min(1).max(20).optional().describe("Pen stroke thickness in pixels for the draw canvas (1\u201320); when absent the renderer default (typically 2) is used"),
1047
- backgroundColor: z2.string().max(50).optional().describe("Background color of the draw canvas; any valid CSS color; when absent the canvas is transparent and inherits the form background"),
1048
- canvasHeight: z2.number().int().min(60).max(600).optional().describe("Draw canvas height in logical pixels (60\u2013600); width always fills the container; when absent the renderer chooses a sensible default (typically 200)"),
1049
- clearButtonLabel: z2.string().max(50).optional().describe("Label for the clear/redo button in draw mode; when absent the platform default label or icon is shown"),
1208
+ allowedModes: z2.array(signatureModeSchema).min(1).optional().describe(
1209
+ "Which signing methods the respondent can choose from (type, draw, upload); when absent all three are enabled"
1210
+ ),
1211
+ defaultMode: signatureModeSchema.optional().describe(
1212
+ "Which signing tab is pre-selected when the question is first shown; when absent the platform chooses"
1213
+ ),
1214
+ collectSignerEmail: z2.boolean().optional().default(true).describe(
1215
+ "Whether to auto-collect the signer's email so a signed PDF copy can be sent to them; set to false if the form already collects an email via signerEmailFieldId or another question"
1216
+ ),
1217
+ signerEmailFieldId: z2.string().optional().describe(
1218
+ "ID of an existing email question in the form whose value will be used as the signer's email address, instead of auto-appending a new email prompt"
1219
+ ),
1220
+ penColor: z2.string().max(50).optional().describe(
1221
+ "Stroke color for the draw canvas; any valid CSS color; when absent the theme foreground color is used"
1222
+ ),
1223
+ penWidth: z2.number().int().min(1).max(20).optional().describe(
1224
+ "Pen stroke thickness in pixels for the draw canvas (1\u201320); when absent the renderer default (typically 2) is used"
1225
+ ),
1226
+ backgroundColor: z2.string().max(50).optional().describe(
1227
+ "Background color of the draw canvas; any valid CSS color; when absent the canvas is transparent and inherits the form background"
1228
+ ),
1229
+ canvasHeight: z2.number().int().min(60).max(600).optional().describe(
1230
+ "Draw canvas height in logical pixels (60\u2013600); width always fills the container; when absent the renderer chooses a sensible default (typically 200)"
1231
+ ),
1232
+ clearButtonLabel: z2.string().max(50).optional().describe(
1233
+ "Label for the clear/redo button in draw mode; when absent the platform default label or icon is shown"
1234
+ ),
1050
1235
  placeholder: z2.string().max(200).optional().describe(
1051
1236
  "Optional shared fallback copy for draw-canvas and upload-zone hints when their dedicated fields are unset"
1052
1237
  ),
1053
- modeTabLabelType: z2.string().max(80).optional().describe("Custom visible label for the Type tab; when absent only the tab icon is shown (use aria-label on the client)"),
1054
- modeTabLabelDraw: z2.string().max(80).optional().describe("Custom visible label for the Draw tab; when absent only the tab icon is shown"),
1055
- modeTabLabelUpload: z2.string().max(80).optional().describe("Custom visible label for the Upload tab; when absent only the tab icon is shown"),
1056
- drawCanvasHint: z2.string().max(200).optional().describe("Hint shown on the empty draw canvas (e.g. 'Draw your signature here'); falls back to placeholder then platform default"),
1057
- uploadZonePrimary: z2.string().max(200).optional().describe("Main prompt on the upload drop zone when idle (e.g. click to upload); falls back to placeholder then default"),
1058
- uploadZoneDrag: z2.string().max(120).optional().describe("Short prompt when dragging a file over the upload zone; falls back to platform default")
1059
- }).describe("Schema for a signature question where respondents can type, draw, or upload their electronic signature");
1238
+ modeTabLabelType: z2.string().max(80).optional().describe(
1239
+ "Custom visible label for the Type tab; when absent only the tab icon is shown (use aria-label on the client)"
1240
+ ),
1241
+ modeTabLabelDraw: z2.string().max(80).optional().describe(
1242
+ "Custom visible label for the Draw tab; when absent only the tab icon is shown"
1243
+ ),
1244
+ modeTabLabelUpload: z2.string().max(80).optional().describe(
1245
+ "Custom visible label for the Upload tab; when absent only the tab icon is shown"
1246
+ ),
1247
+ drawCanvasHint: z2.string().max(200).optional().describe(
1248
+ "Hint shown on the empty draw canvas (e.g. 'Draw your signature here'); falls back to placeholder then platform default"
1249
+ ),
1250
+ uploadZonePrimary: z2.string().max(200).optional().describe(
1251
+ "Main prompt on the upload drop zone when idle (e.g. click to upload); falls back to placeholder then default"
1252
+ ),
1253
+ uploadZoneDrag: z2.string().max(120).optional().describe(
1254
+ "Short prompt when dragging a file over the upload zone; falls back to platform default"
1255
+ )
1256
+ }).describe(
1257
+ "Schema for a signature question where respondents can type, draw, or upload their electronic signature"
1258
+ );
1060
1259
  var fileUploadQuestionSchema = questionSchema.extend({
1061
1260
  type: z2.literal("file_upload").describe("Must be exactly 'file_upload'"),
1062
- allowedFileTypes: z2.array(z2.string()).min(1).optional().describe("MIME types and/or file extensions the respondent is allowed to upload (e.g. ['image/jpeg', '.pdf']); when absent all file types are accepted"),
1063
- maxFileSizeMb: z2.number().int().min(1).max(100).optional().describe("Maximum size per uploaded file in megabytes (1\u2013100); when absent the platform enforces its own ceiling"),
1064
- multiple: z2.boolean().optional().default(false).describe("When true the respondent may upload more than one file in a single question; when false (default) only one file is accepted"),
1065
- maxFiles: z2.number().int().min(1).max(20).optional().describe("Maximum number of files the respondent may upload (1\u201320); only applies when multiple is true; when absent no per-question file count limit is enforced"),
1066
- placeholder: z2.string().max(200).optional().describe("Text shown inside the upload dropzone to guide respondents (e.g. 'Drop your CV here or click to browse')")
1067
- }).describe("Schema for a file upload question where respondents can attach one or more files from their device");
1261
+ allowedFileTypes: z2.array(z2.string()).min(1).optional().describe(
1262
+ "MIME types and/or file extensions the respondent is allowed to upload (e.g. ['image/jpeg', '.pdf']); when absent all file types are accepted"
1263
+ ),
1264
+ maxFileSizeMb: z2.number().int().min(1).max(100).optional().describe(
1265
+ "Maximum size per uploaded file in megabytes (1\u2013100); when absent the platform enforces its own ceiling"
1266
+ ),
1267
+ multiple: z2.boolean().optional().default(false).describe(
1268
+ "When true the respondent may upload more than one file in a single question; when false (default) only one file is accepted"
1269
+ ),
1270
+ maxFiles: z2.number().int().min(1).max(20).optional().describe(
1271
+ "Maximum number of files the respondent may upload (1\u201320); only applies when multiple is true; when absent no per-question file count limit is enforced"
1272
+ ),
1273
+ placeholder: z2.string().max(200).optional().describe(
1274
+ "Text shown inside the upload dropzone to guide respondents (e.g. 'Drop your CV here or click to browse')"
1275
+ )
1276
+ }).describe(
1277
+ "Schema for a file upload question where respondents can attach one or more files from their device"
1278
+ );
1068
1279
  var emailQuestionSchema = questionSchema.extend({
1069
1280
  type: z2.literal("email").describe("Must be exactly 'email'"),
1070
1281
  placeholder: z2.string().max(200).optional().describe("Placeholder text shown inside the email input"),
1071
- prepopulatedValue: z2.string().optional().describe("Default email address to pre-fill the input (e.g. passed via URL param or hidden field)")
1072
- }).describe("Schema for an email question that only accepts correctly formatted email addresses");
1282
+ prepopulatedValue: z2.string().optional().describe(
1283
+ "Default email address to pre-fill the input (e.g. passed via URL param or hidden field)"
1284
+ )
1285
+ }).describe(
1286
+ "Schema for an email question that only accepts correctly formatted email addresses"
1287
+ );
1073
1288
  var numberQuestionSchema = questionSchema.extend({
1074
1289
  type: z2.literal("number").describe("Must be exactly 'number'"),
1075
- min: z2.number().optional().describe("Minimum allowed value (inclusive); when absent no lower bound is enforced"),
1076
- max: z2.number().optional().describe("Maximum allowed value (inclusive); when absent no upper bound is enforced"),
1077
- allowDecimal: z2.boolean().optional().default(false).describe("Whether decimal (non-integer) values are accepted; Typeform restricts to whole numbers only, making this a differentiator"),
1078
- allowNegative: z2.boolean().optional().default(false).describe("Whether negative values are accepted; Typeform restricts to positive numbers only, making this a differentiator"),
1290
+ min: z2.number().optional().describe(
1291
+ "Minimum allowed value (inclusive); when absent no lower bound is enforced"
1292
+ ),
1293
+ max: z2.number().optional().describe(
1294
+ "Maximum allowed value (inclusive); when absent no upper bound is enforced"
1295
+ ),
1296
+ allowDecimal: z2.boolean().optional().default(false).describe(
1297
+ "Whether decimal (non-integer) values are accepted; Typeform restricts to whole numbers only, making this a differentiator"
1298
+ ),
1299
+ allowNegative: z2.boolean().optional().default(false).describe(
1300
+ "Whether negative values are accepted; Typeform restricts to positive numbers only, making this a differentiator"
1301
+ ),
1079
1302
  placeholder: z2.string().max(200).optional().describe("Placeholder text shown inside the number input"),
1080
1303
  prepopulatedValue: z2.number().optional().describe("Default numeric value to pre-fill the input"),
1081
- unit: z2.string().max(10).optional().describe("Unit label displayed beside the input (e.g. 'kg', '$', 'years')")
1304
+ unit: z2.string().max(10).optional().describe(
1305
+ "Unit label displayed beside the input (e.g. 'kg', '$', 'years')"
1306
+ )
1082
1307
  }).refine(
1083
1308
  (data) => data.min === void 0 || data.max === void 0 || data.min <= data.max,
1084
1309
  {
1085
1310
  message: "min cannot be greater than max",
1086
1311
  path: ["min"]
1087
1312
  }
1088
- ).describe("Schema for a number question that only accepts numeric input with configurable range and format constraints");
1313
+ ).describe(
1314
+ "Schema for a number question that only accepts numeric input with configurable range and format constraints"
1315
+ );
1089
1316
  var websiteQuestionSchema = questionSchema.extend({
1090
1317
  type: z2.literal("website").describe("Must be exactly 'website'"),
1091
- placeholder: z2.string().max(200).optional().describe("Placeholder text shown inside the URL input (e.g. 'https://yoursite.com')"),
1318
+ placeholder: z2.string().max(200).optional().describe(
1319
+ "Placeholder text shown inside the URL input (e.g. 'https://yoursite.com')"
1320
+ ),
1092
1321
  prepopulatedValue: z2.string().optional().describe("Default URL to pre-fill the input")
1093
- }).describe("Schema for a website question that collects a URL with built-in format validation");
1322
+ }).describe(
1323
+ "Schema for a website question that collects a URL with built-in format validation"
1324
+ );
1094
1325
  var phoneNumberQuestionSchema = questionSchema.extend({
1095
1326
  type: z2.literal("phone_number").describe("Must be exactly 'phone_number'"),
1096
- defaultCountryCode: z2.string().max(2).optional().describe("ISO 3166-1 alpha-2 country code to pre-select in the country picker (e.g. 'US', 'IN'); when absent the platform uses the device/locale default"),
1097
- allowCountryChange: z2.boolean().optional().default(true).describe("Whether the respondent can change the country code; when false the default country is locked"),
1327
+ defaultCountryCode: z2.string().max(2).optional().describe(
1328
+ "ISO 3166-1 alpha-2 country code to pre-select in the country picker (e.g. 'US', 'IN'); when absent the platform uses the device/locale default"
1329
+ ),
1330
+ allowCountryChange: z2.boolean().optional().default(true).describe(
1331
+ "Whether the respondent can change the country code; when false the default country is locked"
1332
+ ),
1098
1333
  placeholder: z2.string().max(200).optional().describe("Placeholder text shown inside the phone number input"),
1099
- prepopulatedValue: z2.string().optional().describe("Default phone number to pre-fill the input; E.164 format recommended (e.g. '+14155552671')")
1100
- }).describe("Schema for a phone number question with country code picker and country-specific format validation");
1334
+ prepopulatedValue: z2.string().optional().describe(
1335
+ "Default phone number to pre-fill the input; E.164 format recommended (e.g. '+14155552671')"
1336
+ )
1337
+ }).describe(
1338
+ "Schema for a phone number question with country code picker and country-specific format validation"
1339
+ );
1101
1340
  var addressSubFieldConfigSchema = z2.object({
1102
1341
  enabled: z2.boolean().default(true).describe("Whether this sub-field is shown in the question"),
1103
1342
  required: z2.boolean().default(false).describe("Whether the respondent must fill in this sub-field"),
1104
1343
  placeholder: z2.string().max(200).optional().describe("Placeholder text for this sub-field input"),
1105
- label: z2.string().max(120).optional().describe("Visible caption above this sub-field; defaults to built-in copy when omitted")
1344
+ label: z2.string().max(120).optional().describe(
1345
+ "Visible caption above this sub-field; defaults to built-in copy when omitted"
1346
+ )
1106
1347
  }).describe("Configuration for an individual address sub-field");
1107
1348
  var addressQuestionSchema = questionSchema.extend({
1108
1349
  type: z2.literal("address").describe("Must be exactly 'address'"),
1109
1350
  addressLine1: addressSubFieldConfigSchema.optional().describe("Configuration for the primary street address line"),
1110
- addressLine2: addressSubFieldConfigSchema.optional().describe("Configuration for the secondary address line (apartment, suite, etc.); hidden by default"),
1351
+ addressLine2: addressSubFieldConfigSchema.optional().describe(
1352
+ "Configuration for the secondary address line (apartment, suite, etc.); hidden by default"
1353
+ ),
1111
1354
  city: addressSubFieldConfigSchema.optional().describe("Configuration for the city/town sub-field"),
1112
1355
  stateProvince: addressSubFieldConfigSchema.optional().describe("Configuration for the state, region, or province sub-field"),
1113
1356
  postalCode: addressSubFieldConfigSchema.optional().describe("Configuration for the ZIP/postal code sub-field"),
1114
1357
  country: addressSubFieldConfigSchema.optional().describe("Configuration for the country sub-field"),
1115
- defaultCountry: z2.string().max(2).optional().describe("ISO 3166-1 alpha-2 country code to pre-select in the country dropdown (e.g. 'US', 'GB')")
1116
- }).describe("Schema for an address question that collects a full structured address on a single screen");
1358
+ defaultCountry: z2.string().max(2).optional().describe(
1359
+ "ISO 3166-1 alpha-2 country code to pre-select in the country dropdown (e.g. 'US', 'GB')"
1360
+ )
1361
+ }).describe(
1362
+ "Schema for an address question that collects a full structured address on a single screen"
1363
+ );
1117
1364
  var videoAudioModeSchema = z2.enum(["video", "audio", "photo", "text"]);
1118
1365
  var VideoAudioModes = {
1119
1366
  VIDEO: "video",
@@ -1123,23 +1370,51 @@ var VideoAudioModes = {
1123
1370
  };
1124
1371
  var videoAudioQuestionSchema = questionSchema.extend({
1125
1372
  type: z2.literal("video_audio").describe("Must be exactly 'video_audio'"),
1126
- allowedModes: z2.array(videoAudioModeSchema).min(1).optional().describe("Which answer types the respondent can choose from (video, audio, photo, text); when absent all four are enabled"),
1127
- defaultMode: videoAudioModeSchema.optional().describe("Which mode tab is pre-selected when the question opens; when absent the platform chooses"),
1128
- maxDurationSeconds: z2.number().int().min(5).max(600).optional().describe("Maximum recording length in seconds (5\u2013600); Typeform hardcodes 120s with no config, making this a differentiator; when absent the platform default applies"),
1129
- maxFileSizeMb: z2.number().int().min(1).max(500).optional().describe("Maximum size in megabytes for uploaded pre-recorded files (1\u2013500); when absent the platform ceiling applies"),
1130
- allowUpload: z2.boolean().optional().default(true).describe("Whether the respondent can upload a file in addition to recording or capturing live (video, audio, or photo)"),
1131
- placeholder: z2.string().max(200).optional().describe("Instructional text shown to the respondent before they begin recording or capturing"),
1132
- modeTabLabelVideo: z2.string().max(80).optional().describe("Custom tab label for video mode in the respondent UI; when absent defaults to 'Video'"),
1133
- modeTabLabelAudio: z2.string().max(80).optional().describe("Custom tab label for audio mode; when absent defaults to 'Audio'"),
1134
- modeTabLabelPhoto: z2.string().max(80).optional().describe("Custom tab label for photo mode; when absent defaults to 'Photo'"),
1135
- modeTabLabelText: z2.string().max(80).optional().describe("Custom tab label for text mode; when absent defaults to 'Text'"),
1373
+ allowedModes: z2.array(videoAudioModeSchema).min(1).optional().describe(
1374
+ "Which answer types the respondent can choose from (video, audio, photo, text); when absent all four are enabled"
1375
+ ),
1376
+ defaultMode: videoAudioModeSchema.optional().describe(
1377
+ "Which mode tab is pre-selected when the question opens; when absent the platform chooses"
1378
+ ),
1379
+ maxDurationSeconds: z2.number().int().min(5).max(600).optional().describe(
1380
+ "Maximum recording length in seconds (5\u2013600); Typeform hardcodes 120s with no config, making this a differentiator; when absent the platform default applies"
1381
+ ),
1382
+ maxFileSizeMb: z2.number().int().min(1).max(500).optional().describe(
1383
+ "Maximum size in megabytes for uploaded pre-recorded files (1\u2013500); when absent the platform ceiling applies"
1384
+ ),
1385
+ allowUpload: z2.boolean().optional().default(true).describe(
1386
+ "Whether the respondent can upload a file in addition to recording or capturing live (video, audio, or photo)"
1387
+ ),
1388
+ placeholder: z2.string().max(200).optional().describe(
1389
+ "Instructional text shown to the respondent before they begin recording or capturing"
1390
+ ),
1391
+ modeTabLabelVideo: z2.string().max(80).optional().describe(
1392
+ "Custom tab label for video mode in the respondent UI; when absent defaults to 'Video'"
1393
+ ),
1394
+ modeTabLabelAudio: z2.string().max(80).optional().describe(
1395
+ "Custom tab label for audio mode; when absent defaults to 'Audio'"
1396
+ ),
1397
+ modeTabLabelPhoto: z2.string().max(80).optional().describe(
1398
+ "Custom tab label for photo mode; when absent defaults to 'Photo'"
1399
+ ),
1400
+ modeTabLabelText: z2.string().max(80).optional().describe(
1401
+ "Custom tab label for text mode; when absent defaults to 'Text'"
1402
+ ),
1136
1403
  recordButtonLabel: z2.string().max(80).optional().describe("Label for the Record button in video/audio modes"),
1137
- uploadMediaButtonLabel: z2.string().max(80).optional().describe("Label for the upload control in video/audio modes when uploads are allowed"),
1138
- videoIdleHint: z2.string().max(200).optional().describe("Hint shown over the video preview when idle; falls back to placeholder then built-in copy"),
1139
- photoEmptyHint: z2.string().max(200).optional().describe("Hint in the empty photo preview area; falls back to placeholder then built-in copy"),
1404
+ uploadMediaButtonLabel: z2.string().max(80).optional().describe(
1405
+ "Label for the upload control in video/audio modes when uploads are allowed"
1406
+ ),
1407
+ videoIdleHint: z2.string().max(200).optional().describe(
1408
+ "Hint shown over the video preview when idle; falls back to placeholder then built-in copy"
1409
+ ),
1410
+ photoEmptyHint: z2.string().max(200).optional().describe(
1411
+ "Hint in the empty photo preview area; falls back to placeholder then built-in copy"
1412
+ ),
1140
1413
  photoUseCameraButtonLabel: z2.string().max(80).optional().describe("Label for the Use camera button in photo mode"),
1141
1414
  photoUploadImageButtonLabel: z2.string().max(80).optional().describe("Label for the upload image button in photo mode")
1142
- }).describe("Schema for a video, audio, and photo question where respondents can record or upload media or enter a text answer");
1415
+ }).describe(
1416
+ "Schema for a video, audio, and photo question where respondents can record or upload media or enter a text answer"
1417
+ );
1143
1418
  var schedulerProviderSchema = z2.enum(["google_calendar", "calendly"]);
1144
1419
  var SchedulerProviders = {
1145
1420
  GOOGLE_CALENDAR: "google_calendar",
@@ -1147,21 +1422,132 @@ var SchedulerProviders = {
1147
1422
  };
1148
1423
  var schedulerQuestionSchema = questionSchema.extend({
1149
1424
  type: z2.literal("scheduler").describe("Must be exactly 'scheduler'"),
1150
- provider: schedulerProviderSchema.optional().describe("Which calendar integration to use (google_calendar or calendly); when absent the platform uses whatever is connected"),
1151
- calendarId: z2.string().optional().describe("Specific Google Calendar ID or Calendly event-type URL/slug to book from; when absent the default calendar or event type is used"),
1152
- showIntroScreen: z2.boolean().optional().default(true).describe("Whether to show the Calendly event intro screen (account name, event name, duration) before the time picker; only applies when provider is 'calendly'"),
1153
- autofillNameFieldId: z2.string().optional().describe("ID of a prior Short Text or Name question whose answer is pre-filled into the Calendly booking name field; only applies when provider is 'calendly'"),
1154
- autofillEmailFieldId: z2.string().optional().describe("ID of a prior Email question whose answer is pre-filled into the Calendly booking email field; only applies when provider is 'calendly'"),
1155
- placeholder: z2.string().max(200).optional().describe("Instructional text shown above the calendar picker to guide the respondent")
1156
- }).describe("Schema for a scheduler question where respondents book a time slot directly within the form via Google Calendar or Calendly");
1425
+ provider: schedulerProviderSchema.optional().describe(
1426
+ "Which calendar integration to use (google_calendar or calendly); when absent the platform uses whatever is connected"
1427
+ ),
1428
+ calendarId: z2.string().optional().describe(
1429
+ "Specific Google Calendar ID or Calendly event-type URL/slug to book from; when absent the default calendar or event type is used"
1430
+ ),
1431
+ showIntroScreen: z2.boolean().optional().default(true).describe(
1432
+ "Whether to show the Calendly event intro screen (account name, event name, duration) before the time picker; only applies when provider is 'calendly'"
1433
+ ),
1434
+ autofillNameFieldId: z2.string().optional().describe(
1435
+ "ID of a prior Short Text or Name question whose answer is pre-filled into the Calendly booking name field; only applies when provider is 'calendly'"
1436
+ ),
1437
+ autofillEmailFieldId: z2.string().optional().describe(
1438
+ "ID of a prior Email question whose answer is pre-filled into the Calendly booking email field; only applies when provider is 'calendly'"
1439
+ ),
1440
+ placeholder: z2.string().max(200).optional().describe(
1441
+ "Fallback text for the book-a-meeting button when scheduleMeetingLabel is unset; also used as a secondary fallback in the CTA copy chain"
1442
+ ),
1443
+ scheduleMeetingLabel: z2.string().max(200).optional().describe(
1444
+ "Primary label on the book-a-meeting button and modal; when absent uses placeholder then the built-in default (e.g. 'Schedule a meeting')"
1445
+ )
1446
+ }).describe(
1447
+ "Schema for a scheduler question where respondents book a time slot directly within the form via Google Calendar or Calendly"
1448
+ );
1157
1449
  var qnaWithAiQuestionSchema = questionSchema.extend({
1158
1450
  type: z2.literal("qna_with_ai").describe("Must be exactly 'qna_with_ai'"),
1159
- knowledgeBase: z2.string().max(2e4).describe("The knowledge base content the AI draws from when answering respondent questions; Markdown formatting is recommended; up to 20,000 characters"),
1160
- maxResponseLength: z2.number().int().min(50).max(2e3).optional().describe("Maximum number of characters per AI-generated response (50\u20132000); Typeform hardcodes 300, making this configurable a differentiator; when absent the platform default (300) applies"),
1161
- maxQaPairs: z2.number().int().min(1).max(100).optional().describe("Maximum number of Q&A exchanges allowed per submission (1\u2013100); Typeform hardcodes 20, making this configurable a differentiator; when absent the platform default (20) applies"),
1162
- placeholder: z2.string().max(200).optional().describe("Hint text shown in the respondent's question input field (e.g. 'Ask me anything about this event...')"),
1163
- askButtonLabel: z2.string().max(50).optional().describe("Label for the submit/ask button; when absent the platform default (e.g. 'Ask AI') is shown")
1164
- }).describe("Schema for a Q&A with AI question where respondents ask questions and receive AI-generated answers drawn from a configurable knowledge base");
1451
+ knowledgeBase: z2.string().max(2e4).describe(
1452
+ "The knowledge base content the AI draws from when answering respondent questions; Markdown formatting is recommended; up to 20,000 characters"
1453
+ ),
1454
+ maxResponseLength: z2.number().int().min(50).max(2e3).optional().describe(
1455
+ "Maximum number of characters per AI-generated response (50\u20132000); Typeform hardcodes 300, making this configurable a differentiator; when absent the platform default (300) applies"
1456
+ ),
1457
+ maxQaPairs: z2.number().int().min(1).max(100).optional().describe(
1458
+ "Maximum number of Q&A exchanges allowed per submission (1\u2013100); Typeform hardcodes 20, making this configurable a differentiator; when absent the platform default (20) applies"
1459
+ ),
1460
+ placeholder: z2.string().max(200).optional().describe(
1461
+ "Hint text shown in the respondent's question input field (e.g. 'Ask me anything about this event...')"
1462
+ ),
1463
+ askButtonLabel: z2.string().max(50).optional().describe(
1464
+ "Label for the submit/ask button; when absent the platform default (e.g. 'Ask AI') is shown"
1465
+ ),
1466
+ emptyStateHint: z2.string().max(200).optional().describe(
1467
+ "Message in the empty chat area (e.g. 'Ask the AI a question to get started.'); when absent uses placeholder then a built-in default"
1468
+ ),
1469
+ pairsRemainingTemplate: z2.string().max(160).optional().describe(
1470
+ "Counter when under the limit; use tokens {remaining} and {max} (e.g. '{remaining} of {max} questions remaining'); when absent the client uses built-in English with pluralization"
1471
+ ),
1472
+ pairsLimitReachedTemplate: z2.string().max(160).optional().describe(
1473
+ "Counter when the exchange limit is reached; use token {max}; when absent the client uses built-in English with pluralization"
1474
+ )
1475
+ }).describe(
1476
+ "Schema for a Q&A with AI question where respondents ask questions and receive AI-generated answers drawn from a configurable knowledge base"
1477
+ );
1478
+ var paymentsUpiAmountConfigSchema = z2.discriminatedUnion("mode", [
1479
+ z2.object({
1480
+ mode: z2.literal("fixed").describe("A fixed amount configured by the form builder"),
1481
+ amount: z2.number().positive().describe("Fixed amount to request in INR")
1482
+ }),
1483
+ z2.object({
1484
+ mode: z2.literal("range").describe("Respondent enters an amount within the configured range"),
1485
+ minAmount: z2.number().positive().describe("Minimum allowed amount in INR"),
1486
+ maxAmount: z2.number().positive().describe("Maximum allowed amount in INR"),
1487
+ defaultAmount: z2.number().positive().optional().describe("Optional initial amount shown to the respondent")
1488
+ }),
1489
+ z2.object({
1490
+ mode: z2.literal("question_mappings").describe("Amount is summed from one or more previous question answers"),
1491
+ sources: z2.array(
1492
+ z2.object({
1493
+ sourceQuestionId: z2.string().describe(
1494
+ "ID of the prior question whose answer contributes to the amount"
1495
+ ),
1496
+ mappings: z2.array(
1497
+ z2.object({
1498
+ answerValue: z2.string().describe("Previous question answer value to match"),
1499
+ amount: z2.number().nonnegative().describe(
1500
+ "Amount to add in INR when this answer is selected"
1501
+ ),
1502
+ label: z2.string().max(120).optional().describe("Optional display label for this mapped amount")
1503
+ })
1504
+ ).min(1).describe("Answer-to-amount mappings for this source question")
1505
+ })
1506
+ ).min(1).describe("Previous question sources that contribute to the amount"),
1507
+ fallbackAmount: z2.number().nonnegative().optional().describe("Optional amount to use when no source mapping matches")
1508
+ })
1509
+ ]).superRefine((data, ctx) => {
1510
+ if (data.mode !== "range") return;
1511
+ if (data.minAmount > data.maxAmount) {
1512
+ ctx.addIssue({
1513
+ code: z2.ZodIssueCode.custom,
1514
+ message: "minAmount cannot be greater than maxAmount",
1515
+ path: ["minAmount"]
1516
+ });
1517
+ }
1518
+ if (data.defaultAmount !== void 0 && (data.defaultAmount < data.minAmount || data.defaultAmount > data.maxAmount)) {
1519
+ ctx.addIssue({
1520
+ code: z2.ZodIssueCode.custom,
1521
+ message: "defaultAmount must be within minAmount and maxAmount",
1522
+ path: ["defaultAmount"]
1523
+ });
1524
+ }
1525
+ }).describe("Amount configuration for a payments_upi question");
1526
+ var paymentsUpiQuestionSchema = questionSchema.extend({
1527
+ type: z2.literal("payments_upi").describe("Must be exactly 'payments_upi'"),
1528
+ payeeVpa: z2.string().min(3).max(255).regex(
1529
+ /^[\w.\-]+@[\w.\-]+$/,
1530
+ "payeeVpa must be a valid UPI VPA such as merchant@bank"
1531
+ ).describe("UPI virtual payment address that receives the payment"),
1532
+ payeeName: z2.string().max(100).optional().describe("Display name for the UPI payee"),
1533
+ amount: paymentsUpiAmountConfigSchema.describe(
1534
+ "How the requested INR amount is determined"
1535
+ ),
1536
+ sourceEmailQuestionId: z2.string().optional().describe(
1537
+ "Optional ID of the email question whose answer is used for form submission receipt emails"
1538
+ ),
1539
+ transactionNote: z2.string().max(80).optional().describe(
1540
+ "Short note included in the UPI intent; the platform may append the Encatch reference"
1541
+ ),
1542
+ transactionReferencePrefix: z2.string().max(24).optional().describe("Optional prefix for generated Encatch payment references"),
1543
+ qrLabel: z2.string().max(100).optional().describe("Label shown above the UPI QR code"),
1544
+ openUpiAppLabel: z2.string().max(80).optional().describe("Label for the mobile UPI intent button"),
1545
+ copyUpiIdLabel: z2.string().max(80).optional().describe("Label for the copy UPI ID button"),
1546
+ transactionIdLabel: z2.string().max(100).optional().describe("Label for the self-reported transaction ID / UTR input"),
1547
+ transactionIdPlaceholder: z2.string().max(120).optional().describe("Placeholder for the transaction ID / UTR input")
1548
+ }).describe(
1549
+ "Schema for a self-reported UPI payment question that renders a UPI QR/intent link and collects the respondent-entered transaction ID"
1550
+ );
1165
1551
  var combinedQuestionSchema = z2.discriminatedUnion("type", [
1166
1552
  ratingQuestionSchema,
1167
1553
  annotationQuestionSchema,
@@ -1194,7 +1580,8 @@ var combinedQuestionSchema = z2.discriminatedUnion("type", [
1194
1580
  addressQuestionSchema,
1195
1581
  videoAudioQuestionSchema,
1196
1582
  schedulerQuestionSchema,
1197
- qnaWithAiQuestionSchema
1583
+ qnaWithAiQuestionSchema,
1584
+ paymentsUpiQuestionSchema
1198
1585
  ]);
1199
1586
 
1200
1587
  // src/schemas/fields/answer-schema.ts
@@ -1211,18 +1598,26 @@ var AnnotationSchema = z3.object({
1211
1598
  });
1212
1599
  var SignatureAnswerSchema = z3.object({
1213
1600
  mode: z3.enum(["type", "draw", "upload"]).describe("The signing method the respondent used"),
1214
- fileUrl: z3.string().optional().describe("Secure URL to the signature artifact for draw and upload modes"),
1601
+ fileUrl: z3.string().optional().describe(
1602
+ "Secure URL to the signature artifact for draw and upload modes"
1603
+ ),
1215
1604
  typedName: z3.string().optional().describe("The name the respondent typed for type mode")
1216
1605
  }).describe("Answer for a signature question");
1217
1606
  var FileUploadAnswerItemSchema = z3.object({
1218
1607
  fileUrl: z3.string().describe("Secure URL to the uploaded file"),
1219
1608
  fileName: z3.string().describe("Original filename as provided by the respondent"),
1220
1609
  fileSizeMb: z3.number().describe("File size in megabytes"),
1221
- mimeType: z3.string().optional().describe("MIME type of the uploaded file (e.g. 'application/pdf', 'image/jpeg')")
1610
+ mimeType: z3.string().optional().describe(
1611
+ "MIME type of the uploaded file (e.g. 'application/pdf', 'image/jpeg')"
1612
+ )
1222
1613
  }).describe("Metadata for a single uploaded file");
1223
- var FileUploadAnswerSchema = z3.array(FileUploadAnswerItemSchema).describe("Answer for a file upload question; array supports single and multiple file uploads");
1614
+ var FileUploadAnswerSchema = z3.array(FileUploadAnswerItemSchema).describe(
1615
+ "Answer for a file upload question; array supports single and multiple file uploads"
1616
+ );
1224
1617
  var PhoneNumberAnswerSchema = z3.object({
1225
- countryCode: z3.string().describe("Dialing country code including the + prefix (e.g. '+1', '+91')"),
1618
+ countryCode: z3.string().describe(
1619
+ "Dialing country code including the + prefix (e.g. '+1', '+91')"
1620
+ ),
1226
1621
  number: z3.string().describe("Local phone number without the country code"),
1227
1622
  e164: z3.string().optional().describe("Full phone number in E.164 format (e.g. '+14155552671')")
1228
1623
  }).describe("Answer for a phone number question");
@@ -1236,29 +1631,65 @@ var AddressAnswerSchema = z3.object({
1236
1631
  }).describe("Answer for an address question");
1237
1632
  var VideoAudioAnswerSchema = z3.object({
1238
1633
  mode: z3.enum(["video", "audio", "photo", "text"]).describe("The answer mode the respondent chose"),
1239
- fileUrl: z3.string().optional().describe("Secure URL or temporary data URL to the recorded, captured, or uploaded video, audio, or image file"),
1634
+ fileUrl: z3.string().optional().describe(
1635
+ "Secure URL or temporary data URL to the recorded, captured, or uploaded video, audio, or image file"
1636
+ ),
1240
1637
  text: z3.string().optional().describe("Written answer for text mode"),
1241
- durationSeconds: z3.number().optional().describe("Actual recording length in seconds for video and audio modes (not used for photo)"),
1638
+ durationSeconds: z3.number().optional().describe(
1639
+ "Actual recording length in seconds for video and audio modes (not used for photo)"
1640
+ ),
1242
1641
  transcriptText: z3.string().optional().describe("Auto-generated transcript for video and audio recordings")
1243
1642
  }).describe("Answer for a video and audio question");
1244
1643
  var QnaWithAiPairSchema = z3.object({
1245
1644
  question: z3.string().describe("The question the respondent asked"),
1246
1645
  answer: z3.string().describe("The AI-generated answer based on the knowledge base")
1247
1646
  }).describe("A single Q&A exchange between the respondent and the AI");
1248
- var QnaWithAiAnswerSchema = z3.array(QnaWithAiPairSchema).describe("Answer for a qna_with_ai question; ordered transcript of Q&A pairs from the session");
1647
+ var QnaWithAiAnswerSchema = z3.array(QnaWithAiPairSchema).describe(
1648
+ "Answer for a qna_with_ai question; ordered transcript of Q&A pairs from the session"
1649
+ );
1249
1650
  var SchedulerAnswerSchema = z3.discriminatedUnion("provider", [
1250
1651
  z3.object({
1251
1652
  provider: z3.literal("google_calendar").describe("The calendar integration used to make the booking"),
1252
- bookedAt: z3.string().describe("Unix timestamp in seconds as a string when the respondent confirmed the booking")
1653
+ bookedAt: z3.string().describe(
1654
+ "Unix timestamp in seconds as a string when the respondent confirmed the booking"
1655
+ )
1253
1656
  }),
1254
1657
  z3.object({
1255
1658
  provider: z3.literal("calendly").describe("The calendar integration used to make the booking"),
1256
- slotStart: z3.string().describe("ISO 8601 datetime of the booked slot start (e.g. '2026-05-15T14:00:00Z')"),
1257
- slotEnd: z3.string().describe("ISO 8601 datetime of the booked slot end (e.g. '2026-05-15T14:30:00Z')"),
1659
+ slotStart: z3.string().describe(
1660
+ "ISO 8601 datetime of the booked slot start (e.g. '2026-05-15T14:00:00Z')"
1661
+ ),
1662
+ slotEnd: z3.string().describe(
1663
+ "ISO 8601 datetime of the booked slot end (e.g. '2026-05-15T14:30:00Z')"
1664
+ ),
1258
1665
  eventId: z3.string().optional().describe("Calendly event UUID"),
1259
- bookedAt: z3.string().describe("Unix timestamp in seconds as a string when the respondent completed the booking")
1666
+ bookedAt: z3.string().describe(
1667
+ "Unix timestamp in seconds as a string when the respondent completed the booking"
1668
+ )
1260
1669
  })
1261
1670
  ]).describe("Answer for a scheduler question");
1671
+ var PaymentsUpiAnswerSchema = z3.object({
1672
+ transactionId: z3.string().describe(
1673
+ "Respondent-entered UPI transaction ID / UTR; self-reported and not verified by Encatch"
1674
+ ),
1675
+ encatchPaymentReference: z3.string().describe(
1676
+ "Opaque Encatch-generated reconciliation reference included in the UPI intent"
1677
+ ),
1678
+ amount: z3.string().trim().refine((s) => {
1679
+ const n = Number(s);
1680
+ return Number.isFinite(n) && n > 0;
1681
+ }, { message: "Amount must be a positive numeric value" }).describe(
1682
+ "INR amount shown to the respondent when the payment instruction was generated, as a decimal string (legacy numeric values are accepted when parsing)"
1683
+ ),
1684
+ currency: z3.literal("INR").describe("Currency for UPI payments"),
1685
+ payeeVpa: z3.string().describe("UPI VPA shown to the respondent"),
1686
+ payeeName: z3.string().optional().describe("Payee display name shown to the respondent"),
1687
+ sourceEmail: z3.string().optional().describe("Email address resolved from the configured source email question"),
1688
+ upiIntentUri: z3.string().optional().describe("Generated UPI intent URI shown to the respondent"),
1689
+ selfReported: z3.literal(true).describe(
1690
+ "Always true: Encatch records this answer but does not verify the payment"
1691
+ )
1692
+ }).describe("Answer for a payments_upi question");
1262
1693
  var AnswerItemSchema = z3.object({
1263
1694
  nps: z3.number().optional().describe("Net Promoter Score value (e.g., 0-10)"),
1264
1695
  nestedSelection: z3.array(z3.string()).optional().describe("Array of selected nested option IDs"),
@@ -1267,10 +1698,18 @@ var AnswerItemSchema = z3.object({
1267
1698
  singleChoice: z3.string().optional().describe("Single selected option value for single choice questions"),
1268
1699
  rating: z3.number().optional().describe("Star rating value (e.g., 1-5)"),
1269
1700
  yesNo: z3.boolean().optional().describe("Yes/no answer for yes_no questions (true = Yes, false = No)"),
1270
- consent: z3.boolean().optional().describe("Consent answer for consent questions (true = checked/agreed, false = unchecked)"),
1271
- multipleChoiceMultiple: z3.array(z3.string()).optional().describe("Array of selected option values for multiple choice questions"),
1272
- singleChoiceOther: z3.string().optional().describe('Free-text "other" answer for single choice questions when allowOther is enabled'),
1273
- multipleChoiceOther: z3.string().optional().describe('Free-text "other" answer for multiple choice questions when allowOther is enabled'),
1701
+ consent: z3.boolean().optional().describe(
1702
+ "Consent answer for consent questions (true = checked/agreed, false = unchecked)"
1703
+ ),
1704
+ multipleChoiceMultiple: z3.array(z3.string()).optional().describe(
1705
+ "Array of selected option values for multiple choice questions"
1706
+ ),
1707
+ singleChoiceOther: z3.string().optional().describe(
1708
+ 'Free-text "other" answer for single choice questions when allowOther is enabled'
1709
+ ),
1710
+ multipleChoiceOther: z3.string().optional().describe(
1711
+ 'Free-text "other" answer for multiple choice questions when allowOther is enabled'
1712
+ ),
1274
1713
  annotation: AnnotationSchema.optional().describe(
1275
1714
  "Annotation object containing file and marker details"
1276
1715
  ),
@@ -1287,36 +1726,68 @@ var AnswerItemSchema = z3.object({
1287
1726
  "For multiple choice questions and single choice questions, this is the value of the other option"
1288
1727
  ),
1289
1728
  // Date question
1290
- date: z3.string().optional().describe("Answer for a date question; ISO 8601 format (YYYY-MM-DD or YYYY-MM-DDTHH:MM)"),
1729
+ date: z3.string().optional().describe(
1730
+ "Answer for a date question; ISO 8601 format (YYYY-MM-DD or YYYY-MM-DDTHH:MM)"
1731
+ ),
1291
1732
  // CSAT question
1292
- csat: z3.number().optional().describe("Answer for a CSAT question; industry-standard value: 1 (lowest/worst) to N (highest/best) where N is the scale size (2\u20135)"),
1733
+ csat: z3.number().optional().describe(
1734
+ "Answer for a CSAT question; industry-standard value: 1 (lowest/worst) to N (highest/best) where N is the scale size (2\u20135)"
1735
+ ),
1293
1736
  // Opinion scale question
1294
- opinionScale: z3.number().optional().describe("Answer for an opinion scale question; the selected numeric value on the scale"),
1737
+ opinionScale: z3.number().optional().describe(
1738
+ "Answer for an opinion scale question; the selected numeric value on the scale"
1739
+ ),
1295
1740
  // Ranking question — ordered array of option values; index 0 = rank 1
1296
- ranking: z3.array(z3.string()).optional().describe("Answer for a ranking question; ordered array of option values where index 0 is rank 1"),
1741
+ ranking: z3.array(z3.string()).optional().describe(
1742
+ "Answer for a ranking question; ordered array of option values where index 0 is rank 1"
1743
+ ),
1297
1744
  // Picture choice — always an array of selected option values (single selection = one-element array)
1298
- pictureChoice: z3.array(z3.string()).optional().describe("Answer for a picture choice question; array of selected option values (single selection produces a one-element array)"),
1299
- pictureChoiceOther: z3.string().optional().describe('Free-text "other" answer for picture choice questions when allowOther is enabled'),
1745
+ pictureChoice: z3.array(z3.string()).optional().describe(
1746
+ "Answer for a picture choice question; array of selected option values (single selection produces a one-element array)"
1747
+ ),
1748
+ pictureChoiceOther: z3.string().optional().describe(
1749
+ 'Free-text "other" answer for picture choice questions when allowOther is enabled'
1750
+ ),
1300
1751
  // Signature question
1301
- signature: SignatureAnswerSchema.optional().describe("Answer for a signature question"),
1752
+ signature: SignatureAnswerSchema.optional().describe(
1753
+ "Answer for a signature question"
1754
+ ),
1302
1755
  // File upload question
1303
- fileUpload: FileUploadAnswerSchema.optional().describe("Answer for a file upload question; array supports single and multiple file uploads"),
1756
+ fileUpload: FileUploadAnswerSchema.optional().describe(
1757
+ "Answer for a file upload question; array supports single and multiple file uploads"
1758
+ ),
1304
1759
  // Email question
1305
1760
  email: z3.string().optional().describe("Answer for an email question; the submitted email address"),
1306
1761
  // Number question
1307
- number: z3.string().optional().describe("Answer for a number question; the submitted numeric value as a string"),
1762
+ number: z3.string().optional().describe(
1763
+ "Answer for a number question; the submitted numeric value as a string"
1764
+ ),
1308
1765
  // Website question
1309
1766
  website: z3.string().optional().describe("Answer for a website question; the submitted URL"),
1310
1767
  // Phone number question
1311
- phoneNumber: PhoneNumberAnswerSchema.optional().describe("Answer for a phone number question"),
1768
+ phoneNumber: PhoneNumberAnswerSchema.optional().describe(
1769
+ "Answer for a phone number question"
1770
+ ),
1312
1771
  // Address question
1313
- address: AddressAnswerSchema.optional().describe("Answer for an address question"),
1772
+ address: AddressAnswerSchema.optional().describe(
1773
+ "Answer for an address question"
1774
+ ),
1314
1775
  // Video and audio question
1315
- videoAudio: VideoAudioAnswerSchema.optional().describe("Answer for a video and audio question"),
1776
+ videoAudio: VideoAudioAnswerSchema.optional().describe(
1777
+ "Answer for a video and audio question"
1778
+ ),
1316
1779
  // Scheduler question
1317
- scheduler: SchedulerAnswerSchema.optional().describe("Answer for a scheduler question"),
1780
+ scheduler: SchedulerAnswerSchema.optional().describe(
1781
+ "Answer for a scheduler question"
1782
+ ),
1318
1783
  // Q&A with AI question
1319
- qnaWithAi: QnaWithAiAnswerSchema.optional().describe("Answer for a qna_with_ai question; ordered transcript of Q&A pairs from the session")
1784
+ qnaWithAi: QnaWithAiAnswerSchema.optional().describe(
1785
+ "Answer for a qna_with_ai question; ordered transcript of Q&A pairs from the session"
1786
+ ),
1787
+ // Payments UPI question
1788
+ paymentsUpi: PaymentsUpiAnswerSchema.optional().describe(
1789
+ "Answer for a payments_upi question; self-reported UPI transaction reference"
1790
+ )
1320
1791
  }).describe(
1321
1792
  "Flexible answer item supporting various question types and custom fields"
1322
1793
  );
@@ -1421,6 +1892,30 @@ var PreviousButtonModes = {
1421
1892
  ALWAYS: "always",
1422
1893
  AUTO: "auto"
1423
1894
  };
1895
+ var logoPlacementSchema = z6.enum(["top-left", "top-center", "top-right"]).describe("Where the logo is anchored in the form header");
1896
+ var logoSizeSchema = z6.enum(["small", "medium", "large"]).describe("Rendered display size of the logo within the 96\xD740 px container");
1897
+ var logoSurfaceOverrideSchema = z6.object({
1898
+ size: logoSizeSchema.optional().describe("Size override for this surface; falls back to the global size"),
1899
+ placement: logoPlacementSchema.optional().describe("Placement override for this surface; falls back to the global placement"),
1900
+ hidden: z6.boolean().optional().describe("When true, the logo is suppressed on this surface"),
1901
+ disableLink: z6.boolean().optional().describe("When true, the logo is not clickable on this surface")
1902
+ }).describe("Per-surface overrides for logo display on link/shareable");
1903
+ var logoSchema = z6.object({
1904
+ href: z6.object({
1905
+ light: z6.string().url().describe("Logo URL for light mode \u2014 rendered within a 96\xD740 px container"),
1906
+ dark: z6.string().url().optional().describe("Logo URL for dark mode; falls back to light if absent")
1907
+ }).describe("Logo image URLs per theme mode"),
1908
+ placement: logoPlacementSchema.default("top-left").describe("Default placement in the form header"),
1909
+ size: logoSizeSchema.default("medium").describe("Default rendered size of the logo"),
1910
+ linkUrl: z6.string().url().optional().describe("Optional URL to navigate to when the logo is clicked"),
1911
+ altText: z6.string().max(200).optional().describe("Accessible alt text for the logo image"),
1912
+ surfaces: z6.object({
1913
+ link: z6.object({
1914
+ mobile: logoSurfaceOverrideSchema.optional().describe("Overrides for link/shareable on mobile viewports"),
1915
+ others: logoSurfaceOverrideSchema.optional().describe("Overrides for link/shareable on tablet and desktop viewports")
1916
+ }).optional()
1917
+ }).optional().describe("Per-surface overrides; logo is link/shareable only \u2014 not rendered in-app")
1918
+ }).describe("Logo displayed in the form header; applies to link/shareable surfaces only");
1424
1919
  var featureSettingsSchema = z6.object({
1425
1920
  darkOverlay: z6.boolean().default(false).describe("Whether to show a dark overlay behind the widget"),
1426
1921
  closeButton: z6.boolean().default(true).describe("Whether to display a close button on the widget"),
@@ -1438,7 +1933,8 @@ var featureSettingsSchema = z6.object({
1438
1933
  rtl: z6.boolean().default(false).describe("Whether right-to-left text direction is enabled"),
1439
1934
  previousButton: previousButtonModeSchema.default(PreviousButtonModes.ALWAYS).describe("Previous button: never (hidden) or always (shown)"),
1440
1935
  maxDialogHeightPercentInApp: z6.number().int().min(10).max(100).optional().describe("Maximum height of the in-app dialog as a percentage of the viewport height (10\u2013100); when absent the dialog uses its default height"),
1441
- faviconUrl: z6.string().optional().describe("URL of a custom favicon image to display in the browser tab; when absent the platform default favicon is used")
1936
+ faviconUrl: z6.string().optional().describe("URL of a custom favicon image to display in the browser tab; when absent the platform default favicon is used"),
1937
+ logo: logoSchema.optional().describe("Optional form-level logo shown in the header on link/shareable surfaces; omit to show no logo")
1442
1938
  }).describe("Feature settings controlling widget UI behavior and appearance");
1443
1939
  var themeColorsSchema = z6.object({
1444
1940
  theme: z6.string().optional().describe("Theme for a single mode (shadcn variables JSON)")
@@ -1551,7 +2047,7 @@ var imageAttachmentSchema = z8.object({
1551
2047
  decorative: z8.boolean().default(false).describe(
1552
2048
  "When true the image is purely visual; screen readers skip it and description is not surfaced as alt text"
1553
2049
  ),
1554
- brightness: z8.number().min(-100).max(100).optional().describe("Brightness adjustment: -100 darkest, 0 unchanged, +100 brightest. Applied as filter: brightness(1 + value/100)."),
2050
+ brightness: z8.number().min(-100).max(100).optional().describe("Brightness adjustment rendered with a black/white overlay: -100 fully black, 0 unchanged, +100 fully white."),
1555
2051
  focalPoint: focalPointSchema.optional()
1556
2052
  }).optional().describe("Optional display properties for the image")
1557
2053
  }).describe("Image attachment for section layouts");
@@ -1564,7 +2060,7 @@ var videoAttachmentSchema = z8.object({
1564
2060
  properties: z8.object({
1565
2061
  description: z8.string().optional().describe("Accessible description of the video"),
1566
2062
  decorative: z8.boolean().default(false).describe("When true the video is purely decorative and screen readers skip it"),
1567
- brightness: z8.number().min(-100).max(100).optional().describe("Brightness adjustment: -100 darkest, 0 unchanged, +100 brightest. Applied as filter: brightness(1 + value/100).")
2063
+ brightness: z8.number().min(-100).max(100).optional().describe("Brightness adjustment rendered with a black/white overlay: -100 fully black, 0 unchanged, +100 fully white.")
1568
2064
  }).optional().describe("Optional display properties for the video")
1569
2065
  }).describe("Video attachment for section layouts (external embed or self-hosted CDN)");
1570
2066
  var colorAttachmentSchema = z8.object({
@@ -2073,6 +2569,7 @@ export {
2073
2569
  MultipleChoiceMultipleDisplayStyles,
2074
2570
  OtherFieldsSchema,
2075
2571
  OtherFieldsTranslationSchema,
2572
+ PaymentsUpiAnswerSchema,
2076
2573
  PhoneNumberAnswerSchema,
2077
2574
  Positions,
2078
2575
  PreviousButtonModes,
@@ -2183,12 +2680,16 @@ export {
2183
2680
  opinionScaleQuestionSchema,
2184
2681
  otherConfigurationPropertiesSchema,
2185
2682
  partialFeedbackSchema,
2683
+ paymentsUpiAmountConfigSchema,
2684
+ paymentsUpiQuestionSchema,
2685
+ paymentsUpiQuestionTranslationSchema,
2186
2686
  phoneNumberQuestionSchema,
2187
2687
  pictureChoiceQuestionSchema,
2188
2688
  positionSchema,
2189
2689
  previousButtonModeSchema,
2190
2690
  publicationStatusSchema,
2191
2691
  qnaWithAiQuestionSchema,
2692
+ qnaWithAiQuestionTranslationSchema,
2192
2693
  queryOutputSchema,
2193
2694
  questionCentricTranslationsSchema,
2194
2695
  questionOptionSchema,
@@ -2216,6 +2717,7 @@ export {
2216
2717
  responseSchema,
2217
2718
  schedulerProviderSchema,
2218
2719
  schedulerQuestionSchema,
2720
+ schedulerQuestionTranslationSchema,
2219
2721
  sectionLayoutSchema,
2220
2722
  sectionLayoutVariantSchema,
2221
2723
  sectionSchema,