@encatch/schema 1.2.0-beta.10 → 1.2.0-beta.12
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 +608 -169
- package/dist/esm/index.js.map +2 -2
- package/dist/types/index.d.ts +4 -4
- package/dist/types/schemas/api/fetch-feedback-schema.d.ts +182 -0
- package/dist/types/schemas/api/submit-feedback-schema.d.ts +60 -0
- package/dist/types/schemas/fields/answer-schema.d.ts +31 -0
- package/dist/types/schemas/fields/app-props-schema.d.ts +102 -0
- package/dist/types/schemas/fields/field-schema.d.ts +209 -1
- package/dist/types/schemas/fields/form-properties-schema.d.ts +102 -0
- package/dist/types/schemas/fields/translations-schema.d.ts +57 -0
- package/package.json +1 -1
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(
|
|
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(
|
|
38
|
+
return additionalKeys.every(
|
|
39
|
+
(key) => /^option\..+\.(label|value)$/.test(key)
|
|
40
|
+
);
|
|
37
41
|
},
|
|
38
|
-
{
|
|
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(
|
|
54
|
+
return additionalKeys.every(
|
|
55
|
+
(key) => /^option\..+\.(label|value)$/.test(key)
|
|
56
|
+
);
|
|
49
57
|
},
|
|
50
|
-
{
|
|
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(
|
|
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
|
-
{
|
|
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"),
|
|
@@ -104,7 +118,9 @@ var signatureQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.ext
|
|
|
104
118
|
}).describe("Translation schema for signature questions");
|
|
105
119
|
var schedulerQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
|
|
106
120
|
type: z.literal("scheduler").describe("Question type identifier"),
|
|
107
|
-
placeholder: z.string().max(200).optional().describe(
|
|
121
|
+
placeholder: z.string().max(200).optional().describe(
|
|
122
|
+
"Fallback for meeting CTA when scheduleMeetingLabel is unset"
|
|
123
|
+
),
|
|
108
124
|
scheduleMeetingLabel: z.string().max(200).optional().describe("Book-a-meeting button and modal label")
|
|
109
125
|
}).describe("Translation schema for scheduler questions");
|
|
110
126
|
var qnaWithAiQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
|
|
@@ -115,6 +131,14 @@ var qnaWithAiQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.ext
|
|
|
115
131
|
pairsRemainingTemplate: z.string().max(160).optional().describe("Under-limit counter; tokens {remaining} and {max}"),
|
|
116
132
|
pairsLimitReachedTemplate: z.string().max(160).optional().describe("At-limit message; token {max}")
|
|
117
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");
|
|
118
142
|
var nestedSelectionQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
|
|
119
143
|
type: z.literal("nested_selection").describe("Question type identifier"),
|
|
120
144
|
placeholder: translationEntrySchema.optional().describe("Dropdown placeholder translation")
|
|
@@ -123,9 +147,13 @@ var nestedSelectionQuestionTranslationSchema = baseQuestionTranslationFieldsSche
|
|
|
123
147
|
const additionalKeys = Object.keys(data).filter(
|
|
124
148
|
(key) => ![...BASE_QUESTION_TRANSLATION_KEYS, "placeholder"].includes(key)
|
|
125
149
|
);
|
|
126
|
-
return additionalKeys.every(
|
|
150
|
+
return additionalKeys.every(
|
|
151
|
+
(key) => /^nestedOption\..+\.(label|hint)$/.test(key)
|
|
152
|
+
);
|
|
127
153
|
},
|
|
128
|
-
{
|
|
154
|
+
{
|
|
155
|
+
message: "Additional keys must follow the pattern 'nestedOption.{id}.{label|hint}'"
|
|
156
|
+
}
|
|
129
157
|
).describe("Translation schema for nested selection questions");
|
|
130
158
|
var annotationQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
|
|
131
159
|
type: z.literal("annotation").describe("Question type identifier"),
|
|
@@ -143,7 +171,9 @@ var messagePanelQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.
|
|
|
143
171
|
}).describe("Translation schema for message panel questions");
|
|
144
172
|
var consentQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
|
|
145
173
|
type: z.literal("consent").describe("Question type identifier")
|
|
146
|
-
}).describe(
|
|
174
|
+
}).describe(
|
|
175
|
+
"Translation schema for consent questions; description carries the translated checkbox label (markdown supported)"
|
|
176
|
+
);
|
|
147
177
|
var yesNoQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.extend({
|
|
148
178
|
type: z.literal("yes_no").describe("Question type identifier"),
|
|
149
179
|
yesLabel: translationEntrySchema.optional().describe("Translated Yes label"),
|
|
@@ -160,9 +190,11 @@ var ratingMatrixQuestionTranslationSchema = baseQuestionTranslationFieldsSchema.
|
|
|
160
190
|
}).catchall(translationEntrySchema).refine(
|
|
161
191
|
(data) => {
|
|
162
192
|
const additionalKeys = Object.keys(data).filter(
|
|
163
|
-
(key) => ![
|
|
164
|
-
|
|
165
|
-
|
|
193
|
+
(key) => ![
|
|
194
|
+
...BASE_QUESTION_TRANSLATION_KEYS,
|
|
195
|
+
"minLabel",
|
|
196
|
+
"maxLabel"
|
|
197
|
+
].includes(key)
|
|
166
198
|
);
|
|
167
199
|
return additionalKeys.every(
|
|
168
200
|
(key) => /^statement\..+\.label$/.test(key) || /^scalePoint\..+\.label$/.test(key)
|
|
@@ -214,6 +246,7 @@ var questionTranslationSchema = z.union([
|
|
|
214
246
|
signatureQuestionTranslationSchema,
|
|
215
247
|
schedulerQuestionTranslationSchema,
|
|
216
248
|
qnaWithAiQuestionTranslationSchema,
|
|
249
|
+
paymentsUpiQuestionTranslationSchema,
|
|
217
250
|
nestedSelectionQuestionTranslationSchema,
|
|
218
251
|
annotationQuestionTranslationSchema,
|
|
219
252
|
welcomeQuestionTranslationSchema,
|
|
@@ -233,8 +266,12 @@ var sectionTranslationSchema = z.object({
|
|
|
233
266
|
}).describe("Translation payload for a section in a single language");
|
|
234
267
|
var sectionTranslationsByLanguageSchema = z.record(languageCodeSchema, sectionTranslationSchema).describe("Section translations keyed by language code");
|
|
235
268
|
var questionTranslationsByLanguageSchema = z.record(languageCodeSchema, questionTranslationSchema).describe("Question translations keyed by language code");
|
|
236
|
-
var questionCentricTranslationsSchema = z.record(z.string().uuid(), questionTranslationsByLanguageSchema).describe(
|
|
237
|
-
|
|
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
|
+
);
|
|
238
275
|
var _TranslationProvider = class _TranslationProvider {
|
|
239
276
|
constructor(translations, defaultLanguage = "en") {
|
|
240
277
|
this.translations = translations;
|
|
@@ -256,7 +293,10 @@ var _TranslationProvider = class _TranslationProvider {
|
|
|
256
293
|
* Get a specific translation text by field path
|
|
257
294
|
*/
|
|
258
295
|
getTranslationText(questionId, languageCode, fieldPath) {
|
|
259
|
-
const questionTranslation = this.getQuestionTranslations(
|
|
296
|
+
const questionTranslation = this.getQuestionTranslations(
|
|
297
|
+
questionId,
|
|
298
|
+
languageCode
|
|
299
|
+
);
|
|
260
300
|
if (!questionTranslation) return null;
|
|
261
301
|
if (fieldPath in questionTranslation) {
|
|
262
302
|
const value = questionTranslation[fieldPath];
|
|
@@ -359,7 +399,8 @@ var questionTypeSchema = z2.enum([
|
|
|
359
399
|
"address",
|
|
360
400
|
"video_audio",
|
|
361
401
|
"scheduler",
|
|
362
|
-
"qna_with_ai"
|
|
402
|
+
"qna_with_ai",
|
|
403
|
+
"payments_upi"
|
|
363
404
|
]).describe("Enumeration of all supported question types for form fields");
|
|
364
405
|
var QuestionTypes = {
|
|
365
406
|
RATING: "rating",
|
|
@@ -393,7 +434,8 @@ var QuestionTypes = {
|
|
|
393
434
|
ADDRESS: "address",
|
|
394
435
|
VIDEO_AUDIO: "video_audio",
|
|
395
436
|
SCHEDULER: "scheduler",
|
|
396
|
-
QNA_WITH_AI: "qna_with_ai"
|
|
437
|
+
QNA_WITH_AI: "qna_with_ai",
|
|
438
|
+
PAYMENTS_UPI: "payments_upi"
|
|
397
439
|
};
|
|
398
440
|
var validationRuleTypeSchema = z2.enum([
|
|
399
441
|
"required",
|
|
@@ -445,7 +487,9 @@ var VisibilityConditionOperators = {
|
|
|
445
487
|
};
|
|
446
488
|
var visibilityConditionSchema = z2.object({
|
|
447
489
|
field: z2.string().describe("ID of the field to check against"),
|
|
448
|
-
operator: visibilityConditionOperatorSchema.describe(
|
|
490
|
+
operator: visibilityConditionOperatorSchema.describe(
|
|
491
|
+
"Comparison operator for the condition"
|
|
492
|
+
),
|
|
449
493
|
value: z2.union([z2.string(), z2.number(), z2.boolean()]).optional().describe("Value to compare against (string, number, or boolean)"),
|
|
450
494
|
describe: z2.string().max(500).optional().describe("LLM tool call description for this visibility condition")
|
|
451
495
|
}).describe(
|
|
@@ -468,7 +512,9 @@ var sectionSchema = z2.object({
|
|
|
468
512
|
"When the global previousButton mode is 'auto', controls whether the Previous button is shown for this section. Defaults to false (hidden)."
|
|
469
513
|
),
|
|
470
514
|
questionIds: z2.array(z2.string()).min(1).describe("Array of question IDs that belong to this section")
|
|
471
|
-
}).describe(
|
|
515
|
+
}).describe(
|
|
516
|
+
"Schema defining sections that organize questions into logical groups"
|
|
517
|
+
);
|
|
472
518
|
var questionStatusSchema = z2.enum(["D", "P", "A", "S"]);
|
|
473
519
|
var QuestionStatuses = {
|
|
474
520
|
DRAFT: "D",
|
|
@@ -576,8 +622,12 @@ var questionSchema = z2.object({
|
|
|
576
622
|
"Label for the next button when advancing past this question (overrides section or form defaults when set)"
|
|
577
623
|
),
|
|
578
624
|
showQuestionTitle: z2.boolean().default(true).describe("Whether to display the question title; defaults to true"),
|
|
579
|
-
questionMediaUrl: z2.string().url().optional().describe(
|
|
580
|
-
|
|
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
|
+
)
|
|
581
631
|
}).describe("Base schema for all question types with common properties");
|
|
582
632
|
var ratingQuestionSchema = questionSchema.extend({
|
|
583
633
|
type: z2.literal("rating").describe("Must be exactly 'rating'"),
|
|
@@ -601,7 +651,9 @@ var welcomeQuestionSchema = questionSchema.extend({
|
|
|
601
651
|
title: z2.string().min(1).max(200).describe("The main heading displayed on the welcome screen"),
|
|
602
652
|
description: z2.string().max(1e3).optional().describe("Optional sub-text body shown below the heading"),
|
|
603
653
|
imageUrl: z2.string().url().optional().describe("Optional image URL displayed on the welcome screen")
|
|
604
|
-
}).describe(
|
|
654
|
+
}).describe(
|
|
655
|
+
"Schema for a welcome screen displayed at the start or inline within a form"
|
|
656
|
+
);
|
|
605
657
|
var thankYouQuestionSchema = questionSchema.extend({
|
|
606
658
|
type: z2.literal("thank_you").describe("Must be exactly 'thank_you'"),
|
|
607
659
|
title: z2.string().min(1).max(200).describe("The main heading displayed on the thank you screen"),
|
|
@@ -627,10 +679,18 @@ var exitFormQuestionSchema = questionSchema.extend({
|
|
|
627
679
|
);
|
|
628
680
|
var yesNoQuestionSchema = questionSchema.extend({
|
|
629
681
|
type: z2.literal("yes_no").describe("Must be exactly 'yes_no'"),
|
|
630
|
-
yesLabel: z2.string().min(1).max(50).optional().describe(
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
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
|
+
);
|
|
634
694
|
var consentQuestionSchema = questionSchema.extend({
|
|
635
695
|
type: z2.literal("consent").describe("Must be exactly 'consent'")
|
|
636
696
|
}).describe(
|
|
@@ -649,14 +709,18 @@ var RatingMatrixDisplayStyles = {
|
|
|
649
709
|
BUTTON: "button"
|
|
650
710
|
};
|
|
651
711
|
var ratingMatrixStatementSchema = z2.object({
|
|
652
|
-
id: z2.string().describe(
|
|
712
|
+
id: z2.string().describe(
|
|
713
|
+
"Unique identifier for this statement (system time milliseconds)"
|
|
714
|
+
),
|
|
653
715
|
value: z2.string().min(1).max(100).describe("Internal value / export key for this statement"),
|
|
654
716
|
label: z2.string().min(1).max(200).describe("Display text shown to users for this statement"),
|
|
655
717
|
describe: z2.string().max(500).optional().describe("LLM tool call description for this statement")
|
|
656
718
|
}).describe("Schema for an individual statement (row) in a rating matrix");
|
|
657
719
|
var ratingMatrixScalePointSchema = z2.object({
|
|
658
720
|
id: z2.string().describe("Unique identifier for this scale point"),
|
|
659
|
-
value: z2.union([z2.number(), z2.string()]).describe(
|
|
721
|
+
value: z2.union([z2.number(), z2.string()]).describe(
|
|
722
|
+
"Stored response value for this scale point (number or string)"
|
|
723
|
+
),
|
|
660
724
|
label: z2.string().min(1).max(200).describe("Display label shown for this scale point"),
|
|
661
725
|
describe: z2.string().max(500).optional().describe("LLM tool call description for this scale point")
|
|
662
726
|
}).describe("Schema for a single point on a custom rating scale");
|
|
@@ -681,12 +745,16 @@ var ratingMatrixScaleSchema = z2.discriminatedUnion("kind", [
|
|
|
681
745
|
var ratingMatrixQuestionSchema = questionSchema.extend({
|
|
682
746
|
type: z2.literal("rating_matrix").describe("Must be exactly 'rating_matrix'"),
|
|
683
747
|
statements: z2.array(ratingMatrixStatementSchema).min(1).max(10).describe("Statements (rows) users will rate on the shared scale (1-10)"),
|
|
684
|
-
scale: ratingMatrixScaleSchema.describe(
|
|
748
|
+
scale: ratingMatrixScaleSchema.describe(
|
|
749
|
+
"Scale configuration shared across all statement rows"
|
|
750
|
+
),
|
|
685
751
|
displayStyle: ratingMatrixDisplayStyleSchema.optional().describe(
|
|
686
752
|
"Visual representation of scale points per row (radio buttons, stars, emoji, or buttons)"
|
|
687
753
|
),
|
|
688
754
|
randomizeStatements: z2.boolean().optional().default(false).describe("Whether to randomize the order of statements")
|
|
689
|
-
}).describe(
|
|
755
|
+
}).describe(
|
|
756
|
+
"Schema for rating matrix questions with multiple statements on a shared scale"
|
|
757
|
+
);
|
|
690
758
|
var matrixRowSchema = z2.object({
|
|
691
759
|
id: z2.string().describe("Unique identifier for this row (system time milliseconds)"),
|
|
692
760
|
value: z2.string().min(1).max(100).describe("Internal value / export key for this row"),
|
|
@@ -705,7 +773,9 @@ var matrixSingleChoiceQuestionSchema = questionSchema.extend({
|
|
|
705
773
|
columns: z2.array(matrixColumnSchema).min(2).max(10).describe("Column options shared across all rows (2-10 columns)"),
|
|
706
774
|
randomizeRows: z2.boolean().optional().default(false).describe("Whether to randomize the order of rows"),
|
|
707
775
|
randomizeColumns: z2.boolean().optional().default(false).describe("Whether to randomize the order of columns")
|
|
708
|
-
}).describe(
|
|
776
|
+
}).describe(
|
|
777
|
+
"Schema for matrix single-choice questions where one column is selected per row"
|
|
778
|
+
);
|
|
709
779
|
var matrixMultipleChoiceQuestionSchema = questionSchema.extend({
|
|
710
780
|
type: z2.literal("matrix_multiple_choice").describe("Must be exactly 'matrix_multiple_choice'"),
|
|
711
781
|
rows: z2.array(matrixRowSchema).min(1).max(20).describe("Row items (1-20 rows)"),
|
|
@@ -732,7 +802,9 @@ var questionOptionSchema = z2.object({
|
|
|
732
802
|
id: z2.string().describe("Unique identifier for this option (system time milliseconds)"),
|
|
733
803
|
value: z2.string().min(1).max(100).describe("The internal value used for this option"),
|
|
734
804
|
label: z2.string().min(1).max(200).describe("The display text shown to users for this option"),
|
|
735
|
-
hint: z2.string().max(300).optional().describe(
|
|
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
|
+
),
|
|
736
808
|
describe: z2.string().max(500).optional().describe(
|
|
737
809
|
"LLM tool call description providing context about this option"
|
|
738
810
|
),
|
|
@@ -740,7 +812,9 @@ var questionOptionSchema = z2.object({
|
|
|
740
812
|
}).describe("Schema for individual options in choice-based questions");
|
|
741
813
|
var nestedOptionSchema = z2.lazy(
|
|
742
814
|
() => z2.object({
|
|
743
|
-
id: z2.string().describe(
|
|
815
|
+
id: z2.string().describe(
|
|
816
|
+
"Unique identifier for this nested option (system time milliseconds)"
|
|
817
|
+
),
|
|
744
818
|
value: z2.string().min(1).max(100).describe("The internal value used for this nested option"),
|
|
745
819
|
label: z2.string().min(1).max(200).describe("The display text shown for this nested option"),
|
|
746
820
|
describe: z2.string().max(500).optional().describe("LLM tool call description for this nested option context"),
|
|
@@ -759,7 +833,9 @@ var multipleChoiceSingleQuestionSchema = questionSchema.extend({
|
|
|
759
833
|
minChars: z2.number().int().min(0).optional().describe("Minimum number of characters required for the other text"),
|
|
760
834
|
maxChars: z2.number().int().min(1).optional().describe("Maximum number of characters allowed for the other text"),
|
|
761
835
|
placeholder: z2.string().max(200).optional().describe("Placeholder text for the other text input"),
|
|
762
|
-
showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe(
|
|
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
|
+
)
|
|
763
839
|
}).optional().describe('Configuration for the custom "other" text input'),
|
|
764
840
|
randomizeOptions: z2.boolean().optional().default(false).describe("Whether to randomize the order of options"),
|
|
765
841
|
options: z2.array(questionOptionSchema).min(1).max(50).describe("Array of options for user selection (1-50 options)")
|
|
@@ -772,7 +848,9 @@ var multipleChoiceMultipleQuestionSchema = questionSchema.extend({
|
|
|
772
848
|
minChars: z2.number().int().min(0).optional().describe("Minimum number of characters required for the other text"),
|
|
773
849
|
maxChars: z2.number().int().min(1).optional().describe("Maximum number of characters allowed for the other text"),
|
|
774
850
|
placeholder: z2.string().max(200).optional().describe("Placeholder text for the other text input"),
|
|
775
|
-
showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe(
|
|
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
|
+
)
|
|
776
854
|
}).optional().describe('Configuration for the custom "other" text input'),
|
|
777
855
|
minSelections: z2.number().int().min(0).optional().describe("Minimum number of options that must be selected"),
|
|
778
856
|
maxSelections: z2.number().int().min(1).optional().describe("Maximum number of options that can be selected"),
|
|
@@ -801,9 +879,15 @@ var npsQuestionSchema = questionSchema.extend({
|
|
|
801
879
|
maxLabel: z2.string().max(100).optional().describe("Label for the maximum NPS value (10)"),
|
|
802
880
|
scaleLabels: z2.record(z2.string().regex(/^\d+$/), z2.string().max(50)).optional().describe("Custom labels for specific NPS values (0-10)"),
|
|
803
881
|
prepopulatedValue: z2.number().int().min(0).max(10).optional().describe("Default value to pre-select (0-10)"),
|
|
804
|
-
detractorColor: z2.string().max(50).optional().describe(
|
|
805
|
-
|
|
806
|
-
|
|
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
|
+
)
|
|
807
891
|
}).refine(
|
|
808
892
|
(data) => {
|
|
809
893
|
if (data.scaleLabels) {
|
|
@@ -824,7 +908,9 @@ var shortAnswerQuestionSchema = questionSchema.extend({
|
|
|
824
908
|
type: z2.literal("short_answer").describe("Must be exactly 'short_answer'"),
|
|
825
909
|
maxCharacters: z2.number().int().min(1).max(1e4).optional().describe("Maximum number of characters allowed"),
|
|
826
910
|
minCharacters: z2.number().int().min(0).optional().describe("Minimum number of characters required"),
|
|
827
|
-
showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe(
|
|
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
|
+
),
|
|
828
914
|
placeholder: z2.string().max(200).optional().describe("Placeholder text shown in the input field"),
|
|
829
915
|
enableRegexValidation: z2.boolean().optional().default(false).describe("Whether to enable regex pattern validation"),
|
|
830
916
|
regexPattern: z2.string().optional().describe("Regular expression pattern for validation"),
|
|
@@ -872,7 +958,9 @@ var longAnswerQuestionSchema = questionSchema.extend({
|
|
|
872
958
|
"Maximum number of characters allowed (higher limit for long text)"
|
|
873
959
|
),
|
|
874
960
|
minCharacters: z2.number().int().min(0).optional().describe("Minimum number of characters required"),
|
|
875
|
-
showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe(
|
|
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
|
+
),
|
|
876
964
|
rows: z2.number().int().min(1).max(20).optional().describe("Number of textarea rows to display (1-20)"),
|
|
877
965
|
placeholder: z2.string().max(500).optional().describe("Placeholder text for the textarea (longer for long text)"),
|
|
878
966
|
enableEnhanceWithAi: z2.boolean().optional().default(false).describe("Whether to enable AI enhancement features"),
|
|
@@ -955,14 +1043,24 @@ var dateQuestionSchema = questionSchema.extend({
|
|
|
955
1043
|
format: dateFormatSchema.optional().default("DD/MM/YYYY").describe("Order of day, month, and year segments in the input"),
|
|
956
1044
|
separator: dateSeparatorSchema.optional().default("/").describe("Character used to separate day, month, and year segments"),
|
|
957
1045
|
includeTime: z2.boolean().optional().default(false).describe("Whether to also collect a time (HH:MM) alongside the date"),
|
|
958
|
-
minDate: z2.string().optional().describe(
|
|
959
|
-
|
|
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
|
+
),
|
|
960
1052
|
placeholder: z2.string().max(50).optional().describe("Placeholder text shown in the date input"),
|
|
961
|
-
segmentLabelDD: z2.string().max(40).optional().describe(
|
|
1053
|
+
segmentLabelDD: z2.string().max(40).optional().describe(
|
|
1054
|
+
"Visible label above the day segment; when absent a locale default is used"
|
|
1055
|
+
),
|
|
962
1056
|
segmentLabelMM: z2.string().max(40).optional().describe("Visible label above the month segment"),
|
|
963
1057
|
segmentLabelYYYY: z2.string().max(40).optional().describe("Visible label above the year segment"),
|
|
964
|
-
prepopulatedValue: z2.string().optional().describe(
|
|
965
|
-
|
|
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
|
+
);
|
|
966
1064
|
var csatScaleSchema = z2.union([
|
|
967
1065
|
z2.literal(2),
|
|
968
1066
|
z2.literal(3),
|
|
@@ -982,23 +1080,53 @@ var CsatDisplayStyles = {
|
|
|
982
1080
|
};
|
|
983
1081
|
var csatQuestionSchema = questionSchema.extend({
|
|
984
1082
|
type: z2.literal("csat").describe("Must be exactly 'csat'"),
|
|
985
|
-
scale: csatScaleSchema.optional().default(5).describe(
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
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
|
+
);
|
|
994
1110
|
var opinionScaleQuestionSchema = questionSchema.extend({
|
|
995
1111
|
type: z2.literal("opinion_scale").describe("Must be exactly 'opinion_scale'"),
|
|
996
1112
|
startValue: z2.union([z2.literal(0), z2.literal(1)]).optional().default(0).describe("Starting value of the scale \u2014 0 (default) or 1"),
|
|
997
|
-
steps: z2.number().int().min(5).max(11).optional().default(11).describe(
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
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
|
+
]);
|
|
1002
1130
|
var RankingDisplayStyles = {
|
|
1003
1131
|
DRAG_DROP: "drag_drop",
|
|
1004
1132
|
DROPDOWN: "dropdown",
|
|
@@ -1006,32 +1134,54 @@ var RankingDisplayStyles = {
|
|
|
1006
1134
|
};
|
|
1007
1135
|
var rankingQuestionSchema = questionSchema.extend({
|
|
1008
1136
|
type: z2.literal("ranking").describe("Must be exactly 'ranking'"),
|
|
1009
|
-
options: z2.array(questionOptionSchema).min(2).max(30).describe(
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
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
|
+
)
|
|
1013
1149
|
}).refine(
|
|
1014
1150
|
(data) => data.maxRank === void 0 || data.maxRank <= data.options.length,
|
|
1015
1151
|
{
|
|
1016
1152
|
message: "maxRank cannot exceed the number of options",
|
|
1017
1153
|
path: ["maxRank"]
|
|
1018
1154
|
}
|
|
1019
|
-
).describe(
|
|
1155
|
+
).describe(
|
|
1156
|
+
"Schema for a ranking question where respondents order items by preference"
|
|
1157
|
+
);
|
|
1020
1158
|
var pictureChoiceQuestionSchema = questionSchema.extend({
|
|
1021
1159
|
type: z2.literal("picture_choice").describe("Must be exactly 'picture_choice'"),
|
|
1022
|
-
options: z2.array(questionOptionSchema).min(1).max(50).describe(
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
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
|
+
),
|
|
1026
1172
|
supersize: z2.boolean().optional().default(false).describe("Whether to display images at an enlarged size"),
|
|
1027
1173
|
showLabels: z2.boolean().optional().default(true).describe("Whether to show the text label below each image"),
|
|
1028
|
-
randomizeOptions: z2.boolean().optional().default(false).describe(
|
|
1174
|
+
randomizeOptions: z2.boolean().optional().default(false).describe(
|
|
1175
|
+
"Whether to shuffle image order per respondent to avoid position bias"
|
|
1176
|
+
),
|
|
1029
1177
|
allowOther: z2.boolean().optional().default(false).describe('Whether to include a free-text "other" option'),
|
|
1030
1178
|
otherTextConfig: z2.object({
|
|
1031
1179
|
minChars: z2.number().int().min(0).optional().describe("Minimum number of characters required for the other text"),
|
|
1032
1180
|
maxChars: z2.number().int().min(1).optional().describe("Maximum number of characters allowed for the other text"),
|
|
1033
1181
|
placeholder: z2.string().max(200).optional().describe("Placeholder text for the other text input"),
|
|
1034
|
-
showLimitIndicatorThreshold: z2.number().int().min(0).optional().describe(
|
|
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
|
+
)
|
|
1035
1185
|
}).optional().describe('Configuration for the custom "other" text input')
|
|
1036
1186
|
}).refine(
|
|
1037
1187
|
(data) => {
|
|
@@ -1044,7 +1194,9 @@ var pictureChoiceQuestionSchema = questionSchema.extend({
|
|
|
1044
1194
|
message: "minSelections cannot be greater than maxSelections",
|
|
1045
1195
|
path: ["minSelections"]
|
|
1046
1196
|
}
|
|
1047
|
-
).describe(
|
|
1197
|
+
).describe(
|
|
1198
|
+
"Schema for a picture choice question where respondents select from image-based options"
|
|
1199
|
+
);
|
|
1048
1200
|
var signatureModeSchema = z2.enum(["type", "draw", "upload"]);
|
|
1049
1201
|
var SignatureModes = {
|
|
1050
1202
|
TYPE: "type",
|
|
@@ -1053,82 +1205,162 @@ var SignatureModes = {
|
|
|
1053
1205
|
};
|
|
1054
1206
|
var signatureQuestionSchema = questionSchema.extend({
|
|
1055
1207
|
type: z2.literal("signature").describe("Must be exactly 'signature'"),
|
|
1056
|
-
allowedModes: z2.array(signatureModeSchema).min(1).optional().describe(
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
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
|
+
),
|
|
1065
1235
|
placeholder: z2.string().max(200).optional().describe(
|
|
1066
1236
|
"Optional shared fallback copy for draw-canvas and upload-zone hints when their dedicated fields are unset"
|
|
1067
1237
|
),
|
|
1068
|
-
modeTabLabelType: z2.string().max(80).optional().describe(
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
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
|
+
);
|
|
1075
1259
|
var fileUploadQuestionSchema = questionSchema.extend({
|
|
1076
1260
|
type: z2.literal("file_upload").describe("Must be exactly 'file_upload'"),
|
|
1077
|
-
allowedFileTypes: z2.array(z2.string()).min(1).optional().describe(
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
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
|
+
);
|
|
1083
1279
|
var emailQuestionSchema = questionSchema.extend({
|
|
1084
1280
|
type: z2.literal("email").describe("Must be exactly 'email'"),
|
|
1085
1281
|
placeholder: z2.string().max(200).optional().describe("Placeholder text shown inside the email input"),
|
|
1086
|
-
prepopulatedValue: z2.string().optional().describe(
|
|
1087
|
-
|
|
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
|
+
);
|
|
1088
1288
|
var numberQuestionSchema = questionSchema.extend({
|
|
1089
1289
|
type: z2.literal("number").describe("Must be exactly 'number'"),
|
|
1090
|
-
min: z2.number().optional().describe(
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
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
|
+
),
|
|
1094
1302
|
placeholder: z2.string().max(200).optional().describe("Placeholder text shown inside the number input"),
|
|
1095
1303
|
prepopulatedValue: z2.number().optional().describe("Default numeric value to pre-fill the input"),
|
|
1096
|
-
unit: z2.string().max(10).optional().describe(
|
|
1304
|
+
unit: z2.string().max(10).optional().describe(
|
|
1305
|
+
"Unit label displayed beside the input (e.g. 'kg', '$', 'years')"
|
|
1306
|
+
)
|
|
1097
1307
|
}).refine(
|
|
1098
1308
|
(data) => data.min === void 0 || data.max === void 0 || data.min <= data.max,
|
|
1099
1309
|
{
|
|
1100
1310
|
message: "min cannot be greater than max",
|
|
1101
1311
|
path: ["min"]
|
|
1102
1312
|
}
|
|
1103
|
-
).describe(
|
|
1313
|
+
).describe(
|
|
1314
|
+
"Schema for a number question that only accepts numeric input with configurable range and format constraints"
|
|
1315
|
+
);
|
|
1104
1316
|
var websiteQuestionSchema = questionSchema.extend({
|
|
1105
1317
|
type: z2.literal("website").describe("Must be exactly 'website'"),
|
|
1106
|
-
placeholder: z2.string().max(200).optional().describe(
|
|
1318
|
+
placeholder: z2.string().max(200).optional().describe(
|
|
1319
|
+
"Placeholder text shown inside the URL input (e.g. 'https://yoursite.com')"
|
|
1320
|
+
),
|
|
1107
1321
|
prepopulatedValue: z2.string().optional().describe("Default URL to pre-fill the input")
|
|
1108
|
-
}).describe(
|
|
1322
|
+
}).describe(
|
|
1323
|
+
"Schema for a website question that collects a URL with built-in format validation"
|
|
1324
|
+
);
|
|
1109
1325
|
var phoneNumberQuestionSchema = questionSchema.extend({
|
|
1110
1326
|
type: z2.literal("phone_number").describe("Must be exactly 'phone_number'"),
|
|
1111
|
-
defaultCountryCode: z2.string().max(2).optional().describe(
|
|
1112
|
-
|
|
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
|
+
),
|
|
1113
1333
|
placeholder: z2.string().max(200).optional().describe("Placeholder text shown inside the phone number input"),
|
|
1114
|
-
prepopulatedValue: z2.string().optional().describe(
|
|
1115
|
-
|
|
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
|
+
);
|
|
1116
1340
|
var addressSubFieldConfigSchema = z2.object({
|
|
1117
1341
|
enabled: z2.boolean().default(true).describe("Whether this sub-field is shown in the question"),
|
|
1118
1342
|
required: z2.boolean().default(false).describe("Whether the respondent must fill in this sub-field"),
|
|
1119
1343
|
placeholder: z2.string().max(200).optional().describe("Placeholder text for this sub-field input"),
|
|
1120
|
-
label: z2.string().max(120).optional().describe(
|
|
1344
|
+
label: z2.string().max(120).optional().describe(
|
|
1345
|
+
"Visible caption above this sub-field; defaults to built-in copy when omitted"
|
|
1346
|
+
)
|
|
1121
1347
|
}).describe("Configuration for an individual address sub-field");
|
|
1122
1348
|
var addressQuestionSchema = questionSchema.extend({
|
|
1123
1349
|
type: z2.literal("address").describe("Must be exactly 'address'"),
|
|
1124
1350
|
addressLine1: addressSubFieldConfigSchema.optional().describe("Configuration for the primary street address line"),
|
|
1125
|
-
addressLine2: addressSubFieldConfigSchema.optional().describe(
|
|
1351
|
+
addressLine2: addressSubFieldConfigSchema.optional().describe(
|
|
1352
|
+
"Configuration for the secondary address line (apartment, suite, etc.); hidden by default"
|
|
1353
|
+
),
|
|
1126
1354
|
city: addressSubFieldConfigSchema.optional().describe("Configuration for the city/town sub-field"),
|
|
1127
1355
|
stateProvince: addressSubFieldConfigSchema.optional().describe("Configuration for the state, region, or province sub-field"),
|
|
1128
1356
|
postalCode: addressSubFieldConfigSchema.optional().describe("Configuration for the ZIP/postal code sub-field"),
|
|
1129
1357
|
country: addressSubFieldConfigSchema.optional().describe("Configuration for the country sub-field"),
|
|
1130
|
-
defaultCountry: z2.string().max(2).optional().describe(
|
|
1131
|
-
|
|
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
|
+
);
|
|
1132
1364
|
var videoAudioModeSchema = z2.enum(["video", "audio", "photo", "text"]);
|
|
1133
1365
|
var VideoAudioModes = {
|
|
1134
1366
|
VIDEO: "video",
|
|
@@ -1138,23 +1370,51 @@ var VideoAudioModes = {
|
|
|
1138
1370
|
};
|
|
1139
1371
|
var videoAudioQuestionSchema = questionSchema.extend({
|
|
1140
1372
|
type: z2.literal("video_audio").describe("Must be exactly 'video_audio'"),
|
|
1141
|
-
allowedModes: z2.array(videoAudioModeSchema).min(1).optional().describe(
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
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
|
+
),
|
|
1151
1403
|
recordButtonLabel: z2.string().max(80).optional().describe("Label for the Record button in video/audio modes"),
|
|
1152
|
-
uploadMediaButtonLabel: z2.string().max(80).optional().describe(
|
|
1153
|
-
|
|
1154
|
-
|
|
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
|
+
),
|
|
1155
1413
|
photoUseCameraButtonLabel: z2.string().max(80).optional().describe("Label for the Use camera button in photo mode"),
|
|
1156
1414
|
photoUploadImageButtonLabel: z2.string().max(80).optional().describe("Label for the upload image button in photo mode")
|
|
1157
|
-
}).describe(
|
|
1415
|
+
}).describe(
|
|
1416
|
+
"Schema for a video, audio, and photo question where respondents can record or upload media or enter a text answer"
|
|
1417
|
+
);
|
|
1158
1418
|
var schedulerProviderSchema = z2.enum(["google_calendar", "calendly"]);
|
|
1159
1419
|
var SchedulerProviders = {
|
|
1160
1420
|
GOOGLE_CALENDAR: "google_calendar",
|
|
@@ -1162,25 +1422,47 @@ var SchedulerProviders = {
|
|
|
1162
1422
|
};
|
|
1163
1423
|
var schedulerQuestionSchema = questionSchema.extend({
|
|
1164
1424
|
type: z2.literal("scheduler").describe("Must be exactly 'scheduler'"),
|
|
1165
|
-
provider: schedulerProviderSchema.optional().describe(
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
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
|
+
),
|
|
1170
1440
|
placeholder: z2.string().max(200).optional().describe(
|
|
1171
1441
|
"Fallback text for the book-a-meeting button when scheduleMeetingLabel is unset; also used as a secondary fallback in the CTA copy chain"
|
|
1172
1442
|
),
|
|
1173
1443
|
scheduleMeetingLabel: z2.string().max(200).optional().describe(
|
|
1174
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')"
|
|
1175
1445
|
)
|
|
1176
|
-
}).describe(
|
|
1446
|
+
}).describe(
|
|
1447
|
+
"Schema for a scheduler question where respondents book a time slot directly within the form via Google Calendar or Calendly"
|
|
1448
|
+
);
|
|
1177
1449
|
var qnaWithAiQuestionSchema = questionSchema.extend({
|
|
1178
1450
|
type: z2.literal("qna_with_ai").describe("Must be exactly 'qna_with_ai'"),
|
|
1179
|
-
knowledgeBase: z2.string().max(2e4).describe(
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
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
|
+
),
|
|
1184
1466
|
emptyStateHint: z2.string().max(200).optional().describe(
|
|
1185
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"
|
|
1186
1468
|
),
|
|
@@ -1190,7 +1472,79 @@ var qnaWithAiQuestionSchema = questionSchema.extend({
|
|
|
1190
1472
|
pairsLimitReachedTemplate: z2.string().max(160).optional().describe(
|
|
1191
1473
|
"Counter when the exchange limit is reached; use token {max}; when absent the client uses built-in English with pluralization"
|
|
1192
1474
|
)
|
|
1193
|
-
}).describe(
|
|
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
|
+
transactionNote: z2.string().max(80).optional().describe(
|
|
1537
|
+
"Short note included in the UPI intent; the platform may append the Encatch reference"
|
|
1538
|
+
),
|
|
1539
|
+
transactionReferencePrefix: z2.string().max(24).optional().describe("Optional prefix for generated Encatch payment references"),
|
|
1540
|
+
qrLabel: z2.string().max(100).optional().describe("Label shown above the UPI QR code"),
|
|
1541
|
+
openUpiAppLabel: z2.string().max(80).optional().describe("Label for the mobile UPI intent button"),
|
|
1542
|
+
copyUpiIdLabel: z2.string().max(80).optional().describe("Label for the copy UPI ID button"),
|
|
1543
|
+
transactionIdLabel: z2.string().max(100).optional().describe("Label for the self-reported transaction ID / UTR input"),
|
|
1544
|
+
transactionIdPlaceholder: z2.string().max(120).optional().describe("Placeholder for the transaction ID / UTR input")
|
|
1545
|
+
}).describe(
|
|
1546
|
+
"Schema for a self-reported UPI payment question that renders a UPI QR/intent link and collects the respondent-entered transaction ID"
|
|
1547
|
+
);
|
|
1194
1548
|
var combinedQuestionSchema = z2.discriminatedUnion("type", [
|
|
1195
1549
|
ratingQuestionSchema,
|
|
1196
1550
|
annotationQuestionSchema,
|
|
@@ -1223,7 +1577,8 @@ var combinedQuestionSchema = z2.discriminatedUnion("type", [
|
|
|
1223
1577
|
addressQuestionSchema,
|
|
1224
1578
|
videoAudioQuestionSchema,
|
|
1225
1579
|
schedulerQuestionSchema,
|
|
1226
|
-
qnaWithAiQuestionSchema
|
|
1580
|
+
qnaWithAiQuestionSchema,
|
|
1581
|
+
paymentsUpiQuestionSchema
|
|
1227
1582
|
]);
|
|
1228
1583
|
|
|
1229
1584
|
// src/schemas/fields/answer-schema.ts
|
|
@@ -1240,18 +1595,26 @@ var AnnotationSchema = z3.object({
|
|
|
1240
1595
|
});
|
|
1241
1596
|
var SignatureAnswerSchema = z3.object({
|
|
1242
1597
|
mode: z3.enum(["type", "draw", "upload"]).describe("The signing method the respondent used"),
|
|
1243
|
-
fileUrl: z3.string().optional().describe(
|
|
1598
|
+
fileUrl: z3.string().optional().describe(
|
|
1599
|
+
"Secure URL to the signature artifact for draw and upload modes"
|
|
1600
|
+
),
|
|
1244
1601
|
typedName: z3.string().optional().describe("The name the respondent typed for type mode")
|
|
1245
1602
|
}).describe("Answer for a signature question");
|
|
1246
1603
|
var FileUploadAnswerItemSchema = z3.object({
|
|
1247
1604
|
fileUrl: z3.string().describe("Secure URL to the uploaded file"),
|
|
1248
1605
|
fileName: z3.string().describe("Original filename as provided by the respondent"),
|
|
1249
1606
|
fileSizeMb: z3.number().describe("File size in megabytes"),
|
|
1250
|
-
mimeType: z3.string().optional().describe(
|
|
1607
|
+
mimeType: z3.string().optional().describe(
|
|
1608
|
+
"MIME type of the uploaded file (e.g. 'application/pdf', 'image/jpeg')"
|
|
1609
|
+
)
|
|
1251
1610
|
}).describe("Metadata for a single uploaded file");
|
|
1252
|
-
var FileUploadAnswerSchema = z3.array(FileUploadAnswerItemSchema).describe(
|
|
1611
|
+
var FileUploadAnswerSchema = z3.array(FileUploadAnswerItemSchema).describe(
|
|
1612
|
+
"Answer for a file upload question; array supports single and multiple file uploads"
|
|
1613
|
+
);
|
|
1253
1614
|
var PhoneNumberAnswerSchema = z3.object({
|
|
1254
|
-
countryCode: z3.string().describe(
|
|
1615
|
+
countryCode: z3.string().describe(
|
|
1616
|
+
"Dialing country code including the + prefix (e.g. '+1', '+91')"
|
|
1617
|
+
),
|
|
1255
1618
|
number: z3.string().describe("Local phone number without the country code"),
|
|
1256
1619
|
e164: z3.string().optional().describe("Full phone number in E.164 format (e.g. '+14155552671')")
|
|
1257
1620
|
}).describe("Answer for a phone number question");
|
|
@@ -1265,29 +1628,61 @@ var AddressAnswerSchema = z3.object({
|
|
|
1265
1628
|
}).describe("Answer for an address question");
|
|
1266
1629
|
var VideoAudioAnswerSchema = z3.object({
|
|
1267
1630
|
mode: z3.enum(["video", "audio", "photo", "text"]).describe("The answer mode the respondent chose"),
|
|
1268
|
-
fileUrl: z3.string().optional().describe(
|
|
1631
|
+
fileUrl: z3.string().optional().describe(
|
|
1632
|
+
"Secure URL or temporary data URL to the recorded, captured, or uploaded video, audio, or image file"
|
|
1633
|
+
),
|
|
1269
1634
|
text: z3.string().optional().describe("Written answer for text mode"),
|
|
1270
|
-
durationSeconds: z3.number().optional().describe(
|
|
1635
|
+
durationSeconds: z3.number().optional().describe(
|
|
1636
|
+
"Actual recording length in seconds for video and audio modes (not used for photo)"
|
|
1637
|
+
),
|
|
1271
1638
|
transcriptText: z3.string().optional().describe("Auto-generated transcript for video and audio recordings")
|
|
1272
1639
|
}).describe("Answer for a video and audio question");
|
|
1273
1640
|
var QnaWithAiPairSchema = z3.object({
|
|
1274
1641
|
question: z3.string().describe("The question the respondent asked"),
|
|
1275
1642
|
answer: z3.string().describe("The AI-generated answer based on the knowledge base")
|
|
1276
1643
|
}).describe("A single Q&A exchange between the respondent and the AI");
|
|
1277
|
-
var QnaWithAiAnswerSchema = z3.array(QnaWithAiPairSchema).describe(
|
|
1644
|
+
var QnaWithAiAnswerSchema = z3.array(QnaWithAiPairSchema).describe(
|
|
1645
|
+
"Answer for a qna_with_ai question; ordered transcript of Q&A pairs from the session"
|
|
1646
|
+
);
|
|
1278
1647
|
var SchedulerAnswerSchema = z3.discriminatedUnion("provider", [
|
|
1279
1648
|
z3.object({
|
|
1280
1649
|
provider: z3.literal("google_calendar").describe("The calendar integration used to make the booking"),
|
|
1281
|
-
bookedAt: z3.string().describe(
|
|
1650
|
+
bookedAt: z3.string().describe(
|
|
1651
|
+
"Unix timestamp in seconds as a string when the respondent confirmed the booking"
|
|
1652
|
+
)
|
|
1282
1653
|
}),
|
|
1283
1654
|
z3.object({
|
|
1284
1655
|
provider: z3.literal("calendly").describe("The calendar integration used to make the booking"),
|
|
1285
|
-
slotStart: z3.string().describe(
|
|
1286
|
-
|
|
1656
|
+
slotStart: z3.string().describe(
|
|
1657
|
+
"ISO 8601 datetime of the booked slot start (e.g. '2026-05-15T14:00:00Z')"
|
|
1658
|
+
),
|
|
1659
|
+
slotEnd: z3.string().describe(
|
|
1660
|
+
"ISO 8601 datetime of the booked slot end (e.g. '2026-05-15T14:30:00Z')"
|
|
1661
|
+
),
|
|
1287
1662
|
eventId: z3.string().optional().describe("Calendly event UUID"),
|
|
1288
|
-
bookedAt: z3.string().describe(
|
|
1663
|
+
bookedAt: z3.string().describe(
|
|
1664
|
+
"Unix timestamp in seconds as a string when the respondent completed the booking"
|
|
1665
|
+
)
|
|
1289
1666
|
})
|
|
1290
1667
|
]).describe("Answer for a scheduler question");
|
|
1668
|
+
var PaymentsUpiAnswerSchema = z3.object({
|
|
1669
|
+
transactionId: z3.string().describe(
|
|
1670
|
+
"Respondent-entered UPI transaction ID / UTR; self-reported and not verified by Encatch"
|
|
1671
|
+
),
|
|
1672
|
+
encatchPaymentReference: z3.string().describe(
|
|
1673
|
+
"Opaque Encatch-generated reconciliation reference included in the UPI intent"
|
|
1674
|
+
),
|
|
1675
|
+
amount: z3.number().positive().describe(
|
|
1676
|
+
"INR amount shown to the respondent when the payment instruction was generated"
|
|
1677
|
+
),
|
|
1678
|
+
currency: z3.literal("INR").describe("Currency for UPI payments"),
|
|
1679
|
+
payeeVpa: z3.string().describe("UPI VPA shown to the respondent"),
|
|
1680
|
+
payeeName: z3.string().optional().describe("Payee display name shown to the respondent"),
|
|
1681
|
+
upiIntentUri: z3.string().optional().describe("Generated UPI intent URI shown to the respondent"),
|
|
1682
|
+
selfReported: z3.literal(true).describe(
|
|
1683
|
+
"Always true: Encatch records this answer but does not verify the payment"
|
|
1684
|
+
)
|
|
1685
|
+
}).describe("Answer for a payments_upi question");
|
|
1291
1686
|
var AnswerItemSchema = z3.object({
|
|
1292
1687
|
nps: z3.number().optional().describe("Net Promoter Score value (e.g., 0-10)"),
|
|
1293
1688
|
nestedSelection: z3.array(z3.string()).optional().describe("Array of selected nested option IDs"),
|
|
@@ -1296,10 +1691,18 @@ var AnswerItemSchema = z3.object({
|
|
|
1296
1691
|
singleChoice: z3.string().optional().describe("Single selected option value for single choice questions"),
|
|
1297
1692
|
rating: z3.number().optional().describe("Star rating value (e.g., 1-5)"),
|
|
1298
1693
|
yesNo: z3.boolean().optional().describe("Yes/no answer for yes_no questions (true = Yes, false = No)"),
|
|
1299
|
-
consent: z3.boolean().optional().describe(
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1694
|
+
consent: z3.boolean().optional().describe(
|
|
1695
|
+
"Consent answer for consent questions (true = checked/agreed, false = unchecked)"
|
|
1696
|
+
),
|
|
1697
|
+
multipleChoiceMultiple: z3.array(z3.string()).optional().describe(
|
|
1698
|
+
"Array of selected option values for multiple choice questions"
|
|
1699
|
+
),
|
|
1700
|
+
singleChoiceOther: z3.string().optional().describe(
|
|
1701
|
+
'Free-text "other" answer for single choice questions when allowOther is enabled'
|
|
1702
|
+
),
|
|
1703
|
+
multipleChoiceOther: z3.string().optional().describe(
|
|
1704
|
+
'Free-text "other" answer for multiple choice questions when allowOther is enabled'
|
|
1705
|
+
),
|
|
1303
1706
|
annotation: AnnotationSchema.optional().describe(
|
|
1304
1707
|
"Annotation object containing file and marker details"
|
|
1305
1708
|
),
|
|
@@ -1316,36 +1719,68 @@ var AnswerItemSchema = z3.object({
|
|
|
1316
1719
|
"For multiple choice questions and single choice questions, this is the value of the other option"
|
|
1317
1720
|
),
|
|
1318
1721
|
// Date question
|
|
1319
|
-
date: z3.string().optional().describe(
|
|
1722
|
+
date: z3.string().optional().describe(
|
|
1723
|
+
"Answer for a date question; ISO 8601 format (YYYY-MM-DD or YYYY-MM-DDTHH:MM)"
|
|
1724
|
+
),
|
|
1320
1725
|
// CSAT question
|
|
1321
|
-
csat: z3.number().optional().describe(
|
|
1726
|
+
csat: z3.number().optional().describe(
|
|
1727
|
+
"Answer for a CSAT question; industry-standard value: 1 (lowest/worst) to N (highest/best) where N is the scale size (2\u20135)"
|
|
1728
|
+
),
|
|
1322
1729
|
// Opinion scale question
|
|
1323
|
-
opinionScale: z3.number().optional().describe(
|
|
1730
|
+
opinionScale: z3.number().optional().describe(
|
|
1731
|
+
"Answer for an opinion scale question; the selected numeric value on the scale"
|
|
1732
|
+
),
|
|
1324
1733
|
// Ranking question — ordered array of option values; index 0 = rank 1
|
|
1325
|
-
ranking: z3.array(z3.string()).optional().describe(
|
|
1734
|
+
ranking: z3.array(z3.string()).optional().describe(
|
|
1735
|
+
"Answer for a ranking question; ordered array of option values where index 0 is rank 1"
|
|
1736
|
+
),
|
|
1326
1737
|
// Picture choice — always an array of selected option values (single selection = one-element array)
|
|
1327
|
-
pictureChoice: z3.array(z3.string()).optional().describe(
|
|
1328
|
-
|
|
1738
|
+
pictureChoice: z3.array(z3.string()).optional().describe(
|
|
1739
|
+
"Answer for a picture choice question; array of selected option values (single selection produces a one-element array)"
|
|
1740
|
+
),
|
|
1741
|
+
pictureChoiceOther: z3.string().optional().describe(
|
|
1742
|
+
'Free-text "other" answer for picture choice questions when allowOther is enabled'
|
|
1743
|
+
),
|
|
1329
1744
|
// Signature question
|
|
1330
|
-
signature: SignatureAnswerSchema.optional().describe(
|
|
1745
|
+
signature: SignatureAnswerSchema.optional().describe(
|
|
1746
|
+
"Answer for a signature question"
|
|
1747
|
+
),
|
|
1331
1748
|
// File upload question
|
|
1332
|
-
fileUpload: FileUploadAnswerSchema.optional().describe(
|
|
1749
|
+
fileUpload: FileUploadAnswerSchema.optional().describe(
|
|
1750
|
+
"Answer for a file upload question; array supports single and multiple file uploads"
|
|
1751
|
+
),
|
|
1333
1752
|
// Email question
|
|
1334
1753
|
email: z3.string().optional().describe("Answer for an email question; the submitted email address"),
|
|
1335
1754
|
// Number question
|
|
1336
|
-
number: z3.string().optional().describe(
|
|
1755
|
+
number: z3.string().optional().describe(
|
|
1756
|
+
"Answer for a number question; the submitted numeric value as a string"
|
|
1757
|
+
),
|
|
1337
1758
|
// Website question
|
|
1338
1759
|
website: z3.string().optional().describe("Answer for a website question; the submitted URL"),
|
|
1339
1760
|
// Phone number question
|
|
1340
|
-
phoneNumber: PhoneNumberAnswerSchema.optional().describe(
|
|
1761
|
+
phoneNumber: PhoneNumberAnswerSchema.optional().describe(
|
|
1762
|
+
"Answer for a phone number question"
|
|
1763
|
+
),
|
|
1341
1764
|
// Address question
|
|
1342
|
-
address: AddressAnswerSchema.optional().describe(
|
|
1765
|
+
address: AddressAnswerSchema.optional().describe(
|
|
1766
|
+
"Answer for an address question"
|
|
1767
|
+
),
|
|
1343
1768
|
// Video and audio question
|
|
1344
|
-
videoAudio: VideoAudioAnswerSchema.optional().describe(
|
|
1769
|
+
videoAudio: VideoAudioAnswerSchema.optional().describe(
|
|
1770
|
+
"Answer for a video and audio question"
|
|
1771
|
+
),
|
|
1345
1772
|
// Scheduler question
|
|
1346
|
-
scheduler: SchedulerAnswerSchema.optional().describe(
|
|
1773
|
+
scheduler: SchedulerAnswerSchema.optional().describe(
|
|
1774
|
+
"Answer for a scheduler question"
|
|
1775
|
+
),
|
|
1347
1776
|
// Q&A with AI question
|
|
1348
|
-
qnaWithAi: QnaWithAiAnswerSchema.optional().describe(
|
|
1777
|
+
qnaWithAi: QnaWithAiAnswerSchema.optional().describe(
|
|
1778
|
+
"Answer for a qna_with_ai question; ordered transcript of Q&A pairs from the session"
|
|
1779
|
+
),
|
|
1780
|
+
// Payments UPI question
|
|
1781
|
+
paymentsUpi: PaymentsUpiAnswerSchema.optional().describe(
|
|
1782
|
+
"Answer for a payments_upi question; self-reported UPI transaction reference"
|
|
1783
|
+
)
|
|
1349
1784
|
}).describe(
|
|
1350
1785
|
"Flexible answer item supporting various question types and custom fields"
|
|
1351
1786
|
);
|
|
@@ -2102,6 +2537,7 @@ export {
|
|
|
2102
2537
|
MultipleChoiceMultipleDisplayStyles,
|
|
2103
2538
|
OtherFieldsSchema,
|
|
2104
2539
|
OtherFieldsTranslationSchema,
|
|
2540
|
+
PaymentsUpiAnswerSchema,
|
|
2105
2541
|
PhoneNumberAnswerSchema,
|
|
2106
2542
|
Positions,
|
|
2107
2543
|
PreviousButtonModes,
|
|
@@ -2212,6 +2648,9 @@ export {
|
|
|
2212
2648
|
opinionScaleQuestionSchema,
|
|
2213
2649
|
otherConfigurationPropertiesSchema,
|
|
2214
2650
|
partialFeedbackSchema,
|
|
2651
|
+
paymentsUpiAmountConfigSchema,
|
|
2652
|
+
paymentsUpiQuestionSchema,
|
|
2653
|
+
paymentsUpiQuestionTranslationSchema,
|
|
2215
2654
|
phoneNumberQuestionSchema,
|
|
2216
2655
|
pictureChoiceQuestionSchema,
|
|
2217
2656
|
positionSchema,
|