@surveystudio/node-registery 1.3.0 → 1.5.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/logic.mjs CHANGED
@@ -67,17 +67,354 @@ var plainTextLogic = {
67
67
  ]
68
68
  };
69
69
 
70
- // src/nodes/consent/manifest.ts
70
+ // src/nodes/captcha/manifest.ts
71
71
  var defaultCondition = {
72
72
  id: "root",
73
73
  type: "group",
74
74
  logicType: "AND",
75
75
  children: []
76
76
  };
77
+ var captchaDefaultData = {
78
+ label: "Captcha",
79
+ description: "",
80
+ isPii: false,
81
+ condition: defaultCondition,
82
+ sitekey: ""
83
+ };
84
+
85
+ // src/nodes/captcha/logic.ts
86
+ var normalizeCaptchaValue = (rawValue) => typeof rawValue === "string" ? rawValue : "";
87
+ var captchaLogic = {
88
+ type: "captcha",
89
+ dataType: "text",
90
+ defaultData: captchaDefaultData,
91
+ defaultValue: "",
92
+ normalizeValue: normalizeCaptchaValue,
93
+ validate: (value) => value ? { valid: true } : { valid: false, error: "Captcha verification is required" },
94
+ extractValue: () => []
95
+ };
96
+
97
+ // src/nodes/emojiRating/manifest.ts
98
+ var defaultCondition2 = {
99
+ id: "root",
100
+ type: "group",
101
+ logicType: "AND",
102
+ children: []
103
+ };
104
+ var emojiRatingDefaultData = {
105
+ label: "Emoji Rating",
106
+ description: "",
107
+ isPii: false,
108
+ condition: defaultCondition2,
109
+ options: [
110
+ { label: "Angry", value: "\u{1F620}" },
111
+ { label: "Sad", value: "\u{1F641}" },
112
+ { label: "Neutral", value: "\u{1F610}" },
113
+ { label: "Happy", value: "\u{1F642}" },
114
+ { label: "Love", value: "\u{1F60D}" }
115
+ ]
116
+ };
117
+
118
+ // src/nodes/emojiRating/logic.ts
119
+ var normalizeEmojiValue = (rawValue) => {
120
+ if (typeof rawValue === "string") return rawValue;
121
+ if (typeof rawValue === "number" || typeof rawValue === "boolean") return String(rawValue);
122
+ return "";
123
+ };
124
+ var optionsFor = (nodeData) => Array.isArray(nodeData.options) ? nodeData.options : [];
125
+ var optionForValue = (nodeData, value) => optionsFor(nodeData).find((option) => option.exportId === value || option.value === value || option.id === value);
126
+ var optionId = (option, value) => option?.exportId || option?.value || option?.id || value;
127
+ var optionText = (option, value) => option?.value || option?.label || value;
128
+ var extractEmojiRatingValue = (value, nodeData) => {
129
+ if (!value) return [];
130
+ const option = optionForValue(nodeData, value);
131
+ return [{
132
+ optionUuid: optionId(option, value),
133
+ optionText: option?.label || optionText(option, value),
134
+ textValue: optionText(option, value)
135
+ }];
136
+ };
137
+ var emojiRatingLogic = {
138
+ type: "emojiRating",
139
+ dataType: "option",
140
+ defaultData: emojiRatingDefaultData,
141
+ defaultValue: "",
142
+ normalizeValue: normalizeEmojiValue,
143
+ validate: (value, nodeData) => {
144
+ if (!value) return { valid: true };
145
+ if (optionsFor(nodeData).length === 0) return { valid: true };
146
+ return optionForValue(nodeData, value) ? { valid: true } : { valid: false, error: "Selected emoji is not available" };
147
+ },
148
+ extractValue: extractEmojiRatingValue
149
+ };
150
+
151
+ // src/nodes/media/manifest.ts
152
+ var defaultCondition3 = {
153
+ id: "root",
154
+ type: "group",
155
+ logicType: "AND",
156
+ children: []
157
+ };
158
+ var interactionOptions = [
159
+ { label: "None (Display Only)", value: "none" },
160
+ { label: "Text Question", value: "text" },
161
+ { label: "Slider Rating", value: "slider" },
162
+ { label: "Multiple Choice", value: "choice" }
163
+ ];
164
+ var mediaCommonData = {
165
+ label: "",
166
+ description: "",
167
+ isPii: false,
168
+ condition: defaultCondition3,
169
+ interactionType: "none",
170
+ questionLabel: "",
171
+ sliderConfig: "0-10",
172
+ choices: []
173
+ };
174
+ var mediaInteractionProperties = [
175
+ {
176
+ name: "interactionType",
177
+ label: "Enable Interaction",
178
+ type: "select",
179
+ defaultValue: "none",
180
+ options: interactionOptions,
181
+ helperText: "Add a question below this media"
182
+ },
183
+ {
184
+ name: "questionLabel",
185
+ label: "Question / Text",
186
+ type: "text",
187
+ placeholder: "Type your text here...",
188
+ visible: (data) => data.interactionType === "text"
189
+ },
190
+ {
191
+ name: "sliderConfig",
192
+ label: "Slider Config (Min-Max)",
193
+ type: "text",
194
+ placeholder: "0-10",
195
+ visible: (data) => data.interactionType === "slider"
196
+ },
197
+ {
198
+ name: "choices",
199
+ label: "Choices",
200
+ type: "options",
201
+ defaultValue: [],
202
+ visible: (data) => data.interactionType === "choice"
203
+ }
204
+ ];
205
+ var imageDefaultData = {
206
+ ...mediaCommonData,
207
+ label: "Image",
208
+ urls: [],
209
+ alt: ""
210
+ };
211
+ var videoDefaultData = {
212
+ ...mediaCommonData,
213
+ label: "Video",
214
+ url: "",
215
+ autoplay: false
216
+ };
217
+ var audioDefaultData = {
218
+ ...mediaCommonData,
219
+ label: "Audio",
220
+ url: "",
221
+ autoplay: false
222
+ };
223
+ var imageManifest = {
224
+ type: "image",
225
+ label: "Image",
226
+ description: "Display an image",
227
+ category: "media",
228
+ dataType: "object",
229
+ defaultData: imageDefaultData,
230
+ properties: [
231
+ { name: "label", label: "Field Label", type: "text", placeholder: "e.g., Product image" },
232
+ { name: "description", label: "Description", type: "textarea", placeholder: "Helper text for the user", defaultValue: "" },
233
+ { name: "isPii", label: "Contains PII", type: "switch", defaultValue: false, helperText: "Encrypt this field and exclude it from analytics/export." },
234
+ { name: "condition", label: "When should this question be shown?", type: "condition", defaultValue: defaultCondition3, helperText: "If no rules are added, this question will always be shown." },
235
+ { name: "urls", label: "Images", type: "files", defaultValue: [] },
236
+ { name: "alt", label: "Alt Text", type: "text" },
237
+ ...mediaInteractionProperties
238
+ ]
239
+ };
240
+ var videoManifest = {
241
+ type: "video",
242
+ label: "Video",
243
+ description: "Embed a video",
244
+ category: "media",
245
+ dataType: "object",
246
+ defaultData: videoDefaultData,
247
+ properties: [
248
+ { name: "label", label: "Field Label", type: "text", placeholder: "e.g., Watch this clip" },
249
+ { name: "description", label: "Description", type: "textarea", placeholder: "Helper text for the user", defaultValue: "" },
250
+ { name: "isPii", label: "Contains PII", type: "switch", defaultValue: false, helperText: "Encrypt this field and exclude it from analytics/export." },
251
+ { name: "condition", label: "When should this question be shown?", type: "condition", defaultValue: defaultCondition3, helperText: "If no rules are added, this question will always be shown." },
252
+ { name: "url", label: "Video URL", type: "file", placeholder: "Upload or paste URL..." },
253
+ { name: "autoplay", label: "Autoplay", type: "switch", defaultValue: false },
254
+ ...mediaInteractionProperties
255
+ ]
256
+ };
257
+ var audioManifest = {
258
+ type: "audio",
259
+ label: "Audio",
260
+ description: "Play an audio clip",
261
+ category: "media",
262
+ dataType: "object",
263
+ defaultData: audioDefaultData,
264
+ properties: [
265
+ { name: "label", label: "Field Label", type: "text", placeholder: "e.g., Listen to this clip" },
266
+ { name: "description", label: "Description", type: "textarea", placeholder: "Helper text for the user", defaultValue: "" },
267
+ { name: "isPii", label: "Contains PII", type: "switch", defaultValue: false, helperText: "Encrypt this field and exclude it from analytics/export." },
268
+ { name: "condition", label: "When should this question be shown?", type: "condition", defaultValue: defaultCondition3, helperText: "If no rules are added, this question will always be shown." },
269
+ { name: "url", label: "Audio URL", type: "file", placeholder: "Upload or paste URL..." },
270
+ { name: "autoplay", label: "Autoplay", type: "switch", defaultValue: false },
271
+ ...mediaInteractionProperties
272
+ ]
273
+ };
274
+
275
+ // src/nodes/media/logic.ts
276
+ var normalizeMediaValue = (rawValue) => {
277
+ if (typeof rawValue === "number") return rawValue;
278
+ if (typeof rawValue === "string") return rawValue;
279
+ if (typeof rawValue === "boolean") return String(rawValue);
280
+ return void 0;
281
+ };
282
+ var choicesFor = (nodeData) => Array.isArray(nodeData.choices) ? nodeData.choices : [];
283
+ var choiceForValue = (nodeData, value) => choicesFor(nodeData).find((choice) => choice.exportId === value || choice.value === value || choice.id === value);
284
+ var choiceId = (choice, value) => choice?.exportId || choice?.value || choice?.id || value;
285
+ var choiceLabel = (choice, value) => choice?.label || value;
286
+ var extractMediaValue = (value, nodeData) => {
287
+ const interactionType = nodeData.interactionType || "none";
288
+ if (value === void 0 || value === "" || interactionType === "none") return [];
289
+ if (interactionType === "slider") {
290
+ const numberValue2 = Number(value);
291
+ return [Number.isFinite(numberValue2) ? { numberValue: numberValue2, textValue: String(value) } : { textValue: String(value) }];
292
+ }
293
+ if (interactionType === "choice") {
294
+ const selectedValue = String(value);
295
+ const choice = choiceForValue(nodeData, selectedValue);
296
+ const label = choiceLabel(choice, selectedValue);
297
+ return [{
298
+ optionUuid: choiceId(choice, selectedValue),
299
+ optionText: label,
300
+ textValue: label
301
+ }];
302
+ }
303
+ return [{ textValue: String(value) }];
304
+ };
305
+ var validateMediaValue = (value, nodeData) => {
306
+ const interactionType = nodeData.interactionType || "none";
307
+ if (interactionType === "none") return { valid: true };
308
+ if (value === void 0 || value === "") return { valid: false, error: "Media interaction answer is required" };
309
+ if (interactionType === "choice" && choicesFor(nodeData).length > 0 && !choiceForValue(nodeData, String(value))) {
310
+ return { valid: false, error: "Selected option is not available" };
311
+ }
312
+ return { valid: true };
313
+ };
314
+ var imageLogic = {
315
+ type: "image",
316
+ dataType: "object",
317
+ defaultData: imageDefaultData,
318
+ defaultValue: void 0,
319
+ normalizeValue: normalizeMediaValue,
320
+ validate: validateMediaValue,
321
+ extractValue: extractMediaValue
322
+ };
323
+ var videoLogic = {
324
+ type: "video",
325
+ dataType: "object",
326
+ defaultData: videoDefaultData,
327
+ defaultValue: void 0,
328
+ normalizeValue: normalizeMediaValue,
329
+ validate: validateMediaValue,
330
+ extractValue: extractMediaValue
331
+ };
332
+ var audioLogic = {
333
+ type: "audio",
334
+ dataType: "object",
335
+ defaultData: audioDefaultData,
336
+ defaultValue: void 0,
337
+ normalizeValue: normalizeMediaValue,
338
+ validate: validateMediaValue,
339
+ extractValue: extractMediaValue
340
+ };
341
+
342
+ // src/nodes/flow/manifest.ts
343
+ var defaultCondition4 = {
344
+ id: "root",
345
+ type: "group",
346
+ logicType: "AND",
347
+ children: []
348
+ };
349
+ var startDefaultData = {
350
+ welcomeMessage: ""
351
+ };
352
+ var branchDefaultData = {
353
+ condition: defaultCondition4
354
+ };
355
+ var validationDefaultData = {
356
+ label: "Validation Gate",
357
+ condition: defaultCondition4,
358
+ outcome: "security_terminate"
359
+ };
360
+ var endDefaultData = {
361
+ message: "",
362
+ redirectUrl: "",
363
+ outcome: "completed"
364
+ };
365
+
366
+ // src/nodes/flow/logic.ts
367
+ var normalizeNone = () => void 0;
368
+ var validatePass = () => ({ valid: true });
369
+ var extractNone = () => [];
370
+ var startLogic = {
371
+ type: "start",
372
+ dataType: "none",
373
+ defaultData: startDefaultData,
374
+ defaultValue: void 0,
375
+ normalizeValue: normalizeNone,
376
+ validate: validatePass,
377
+ extractValue: extractNone
378
+ };
379
+ var branchLogic = {
380
+ type: "branch",
381
+ dataType: "none",
382
+ defaultData: branchDefaultData,
383
+ defaultValue: void 0,
384
+ normalizeValue: normalizeNone,
385
+ validate: validatePass,
386
+ extractValue: extractNone
387
+ };
388
+ var validationLogic = {
389
+ type: "validation",
390
+ dataType: "none",
391
+ defaultData: validationDefaultData,
392
+ defaultValue: void 0,
393
+ normalizeValue: normalizeNone,
394
+ validate: validatePass,
395
+ extractValue: extractNone
396
+ };
397
+ var endLogic = {
398
+ type: "end",
399
+ dataType: "none",
400
+ defaultData: endDefaultData,
401
+ defaultValue: void 0,
402
+ normalizeValue: normalizeNone,
403
+ validate: validatePass,
404
+ extractValue: extractNone
405
+ };
406
+
407
+ // src/nodes/consent/manifest.ts
408
+ var defaultCondition5 = {
409
+ id: "root",
410
+ type: "group",
411
+ logicType: "AND",
412
+ children: []
413
+ };
77
414
  var consentDefaultData = {
78
415
  label: "Consent",
79
416
  description: "I agree to the terms and conditions.",
80
- condition: defaultCondition,
417
+ condition: defaultCondition5,
81
418
  checkboxLabel: "I agree",
82
419
  disagreeLabel: "I do not agree to the terms"
83
420
  };
@@ -109,7 +446,7 @@ var consentLogic = {
109
446
  };
110
447
 
111
448
  // src/nodes/scale/manifest.ts
112
- var defaultCondition2 = {
449
+ var defaultCondition6 = {
113
450
  id: "root",
114
451
  type: "group",
115
452
  logicType: "AND",
@@ -118,7 +455,7 @@ var defaultCondition2 = {
118
455
  var baseScaleData = {
119
456
  label: "",
120
457
  description: "",
121
- condition: defaultCondition2,
458
+ condition: defaultCondition6,
122
459
  responseMode: "single",
123
460
  items: []
124
461
  };
@@ -140,9 +477,8 @@ var commonProperties = [
140
477
  name: "condition",
141
478
  label: "Logic Rule",
142
479
  type: "condition",
143
- defaultValue: defaultCondition2
144
- },
145
- { name: "items", label: "Items", type: "options", defaultValue: [] }
480
+ defaultValue: defaultCondition6
481
+ }
146
482
  ];
147
483
  var ratingDefaultData = {
148
484
  ...baseScaleData,
@@ -166,6 +502,7 @@ var ratingManifest = {
166
502
  defaultData: ratingDefaultData,
167
503
  properties: [
168
504
  ...commonProperties,
505
+ { name: "items", label: "Questions/Items", type: "options", defaultValue: [], visible: (data) => data.responseMode === "multi" },
169
506
  { name: "maxRating", label: "Max Stars", type: "number", defaultValue: 5 }
170
507
  ]
171
508
  };
@@ -178,6 +515,7 @@ var sliderManifest = {
178
515
  defaultData: sliderDefaultData,
179
516
  properties: [
180
517
  ...commonProperties,
518
+ { name: "items", label: "Items to Rate", type: "options", defaultValue: [], visible: (data) => data.responseMode === "multi" },
181
519
  { name: "min", label: "Minimum", type: "number", defaultValue: 0 },
182
520
  { name: "max", label: "Maximum", type: "number", defaultValue: 10 },
183
521
  { name: "step", label: "Step", type: "number", defaultValue: 1, min: 0 },
@@ -276,7 +614,7 @@ var sliderLogic = {
276
614
  };
277
615
 
278
616
  // src/nodes/choice/manifest.ts
279
- var defaultCondition3 = {
617
+ var defaultCondition7 = {
280
618
  id: "root",
281
619
  type: "group",
282
620
  logicType: "AND",
@@ -285,7 +623,7 @@ var defaultCondition3 = {
285
623
  var baseChoiceData = {
286
624
  label: "",
287
625
  description: "",
288
- condition: defaultCondition3,
626
+ condition: defaultCondition7,
289
627
  options: [],
290
628
  randomizeOptions: false
291
629
  };
@@ -296,27 +634,34 @@ var commonProperties2 = [
296
634
  name: "condition",
297
635
  label: "Logic Rule",
298
636
  type: "condition",
299
- defaultValue: defaultCondition3
637
+ defaultValue: defaultCondition7
300
638
  },
301
639
  { name: "options", label: "Options", type: "options", defaultValue: [] },
302
- { name: "bulkOptions", label: "Bulk Add (one per line)", type: "textarea", placeholder: "Option A\nOption B\nOption C..." }
640
+ { name: "bulkOptions", label: "Bulk Add (one per line)", type: "textarea", placeholder: "Option A\nOption B\nOption C...", helperText: "Paste a list to replace all options above" }
303
641
  ];
304
642
  var singleChoiceDefaultData = {
305
643
  ...baseChoiceData,
306
644
  label: "Single Choice",
307
645
  allowOther: false,
308
- otherLabel: "Other"
646
+ otherLabel: "Other (Please specify)",
647
+ allowNone: false,
648
+ noneLabel: "None of these"
309
649
  };
310
650
  var dropdownDefaultData = {
311
651
  ...baseChoiceData,
312
- label: "Dropdown",
652
+ label: "Dropdown Select",
653
+ placeholder: "Select an option...",
313
654
  searchable: true
314
655
  };
315
656
  var multipleChoiceDefaultData = {
316
657
  ...baseChoiceData,
317
658
  label: "Multiple Choice",
318
659
  minChoices: 0,
319
- maxChoices: 0
660
+ maxChoices: 0,
661
+ allowOther: false,
662
+ otherLabel: "Other (Please specify)",
663
+ allowNone: false,
664
+ noneLabel: "None of these"
320
665
  };
321
666
  var rankingDefaultData = {
322
667
  ...baseChoiceData,
@@ -327,26 +672,29 @@ var rankingDefaultData = {
327
672
  var singleChoiceManifest = {
328
673
  type: "singleChoice",
329
674
  label: "Single Choice",
330
- description: "Select one option",
675
+ description: "Select one option from a list",
331
676
  category: "choice",
332
677
  dataType: "option",
333
678
  defaultData: singleChoiceDefaultData,
334
679
  properties: [
335
680
  ...commonProperties2,
336
- { name: "allowOther", label: "Allow Other", type: "switch", defaultValue: false },
337
- { name: "otherLabel", label: "Other Label", type: "text", defaultValue: "Other" },
681
+ { name: "allowOther", label: 'Allow "Other" Option', type: "switch", defaultValue: false },
682
+ { name: "otherLabel", label: '"Other" Placeholder', type: "text", placeholder: "Other (Please specify)", helperText: "Label for the open-ended option" },
683
+ { name: "allowNone", label: 'Allow "None of these"', type: "switch", defaultValue: false },
684
+ { name: "noneLabel", label: '"None" Label', type: "text", placeholder: "None of these", visible: (data) => Boolean(data.allowNone) },
338
685
  { name: "randomizeOptions", label: "Randomize Options", type: "switch", defaultValue: false }
339
686
  ]
340
687
  };
341
688
  var dropdownManifest = {
342
689
  type: "dropdown",
343
- label: "Dropdown",
690
+ label: "Dropdown Select",
344
691
  description: "Select from a dropdown menu",
345
692
  category: "choice",
346
693
  dataType: "option",
347
694
  defaultData: dropdownDefaultData,
348
695
  properties: [
349
696
  ...commonProperties2,
697
+ { name: "placeholder", label: "Placeholder Text", type: "text", placeholder: "Select an option..." },
350
698
  { name: "searchable", label: "Searchable", type: "switch", defaultValue: true }
351
699
  ]
352
700
  };
@@ -359,9 +707,12 @@ var multipleChoiceManifest = {
359
707
  defaultData: multipleChoiceDefaultData,
360
708
  properties: [
361
709
  ...commonProperties2,
362
- { name: "minChoices", label: "Minimum Choices", type: "number", defaultValue: 0 },
363
- { name: "maxChoices", label: "Maximum Choices", type: "number", defaultValue: 0 },
364
- { name: "randomizeOptions", label: "Randomize Options", type: "switch", defaultValue: false }
710
+ { name: "maxChoices", label: "Maximum Choices", type: "number", helperText: "Limit how many options a user can select. Leave empty for no limit.", defaultValue: 0 },
711
+ { name: "allowOther", label: 'Allow "Other" Option', type: "switch", defaultValue: false },
712
+ { name: "otherLabel", label: '"Other" Placeholder', type: "text", placeholder: "Other (Please specify)" },
713
+ { name: "allowNone", label: 'Allow "None of these"', type: "switch", defaultValue: false },
714
+ { name: "noneLabel", label: '"None" Label', type: "text", placeholder: "None of these", visible: (data) => Boolean(data.allowNone) },
715
+ { name: "randomizeOptions", label: "Randomize Options", type: "switch", defaultValue: false, helperText: "Shuffle options for every viewer" }
365
716
  ]
366
717
  };
367
718
  var rankingManifest = {
@@ -373,7 +724,6 @@ var rankingManifest = {
373
724
  defaultData: rankingDefaultData,
374
725
  properties: [
375
726
  ...commonProperties2,
376
- { name: "maxRank", label: "Maximum Rank", type: "number", defaultValue: 0 },
377
727
  {
378
728
  name: "displayMode",
379
729
  label: "Display Mode",
@@ -381,7 +731,7 @@ var rankingManifest = {
381
731
  defaultValue: "drag",
382
732
  options: [
383
733
  { label: "Drag and Drop", value: "drag" },
384
- { label: "Dropdown Selection", value: "select" }
734
+ { label: "Select Rank", value: "select" }
385
735
  ]
386
736
  }
387
737
  ]
@@ -401,18 +751,18 @@ var positiveNumber2 = (value) => {
401
751
  const parsed = Number(value);
402
752
  return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
403
753
  };
404
- var optionsFor = (nodeData) => Array.isArray(nodeData.options) ? nodeData.options : [];
405
- var optionForValue = (nodeData, value) => optionsFor(nodeData).find((option) => option.value === value || option.id === value);
406
- var optionLabel = (nodeData, value) => optionForValue(nodeData, value)?.label || value;
407
- var optionUuid = (nodeData, value) => optionForValue(nodeData, value)?.value || value;
754
+ var optionsFor2 = (nodeData) => Array.isArray(nodeData.options) ? nodeData.options : [];
755
+ var optionForValue2 = (nodeData, value) => optionsFor2(nodeData).find((option) => option.value === value || option.id === value);
756
+ var optionLabel = (nodeData, value) => optionForValue2(nodeData, value)?.label || value;
757
+ var optionUuid = (nodeData, value) => optionForValue2(nodeData, value)?.value || value;
408
758
  var validateOptionExists = (value, nodeData) => {
409
759
  if (!value) return { valid: true };
410
- if (optionsFor(nodeData).length === 0) return { valid: true };
411
- return optionForValue(nodeData, value) ? { valid: true } : { valid: false, error: "Selected option is not available" };
760
+ if (optionsFor2(nodeData).length === 0) return { valid: true };
761
+ return optionForValue2(nodeData, value) ? { valid: true } : { valid: false, error: "Selected option is not available" };
412
762
  };
413
763
  var validateOptionArray = (value, nodeData) => {
414
- if (optionsFor(nodeData).length === 0) return { valid: true };
415
- const invalid = value.find((item) => !optionForValue(nodeData, item));
764
+ if (optionsFor2(nodeData).length === 0) return { valid: true };
765
+ const invalid = value.find((item) => !optionForValue2(nodeData, item));
416
766
  return invalid ? { valid: false, error: "Selected option is not available" } : { valid: true };
417
767
  };
418
768
  var extractSingleChoiceValue = (value, nodeData) => [
@@ -486,8 +836,173 @@ var rankingLogic = {
486
836
  })
487
837
  };
488
838
 
839
+ // src/nodes/structuredChoice/manifest.ts
840
+ var defaultCondition8 = {
841
+ id: "root",
842
+ type: "group",
843
+ logicType: "AND",
844
+ children: []
845
+ };
846
+ var commonProperties3 = [
847
+ { name: "label", label: "Field Label", type: "text" },
848
+ { name: "description", label: "Description", type: "textarea" },
849
+ {
850
+ name: "condition",
851
+ label: "Logic Rule",
852
+ type: "condition",
853
+ defaultValue: defaultCondition8
854
+ }
855
+ ];
856
+ var matrixChoiceDefaultData = {
857
+ label: "Grid / Matrix",
858
+ description: "",
859
+ condition: defaultCondition8,
860
+ rows: [],
861
+ columns: [],
862
+ multiple: false
863
+ };
864
+ var cascadingChoiceDefaultData = {
865
+ label: "Multi-Step Select",
866
+ description: "",
867
+ condition: defaultCondition8,
868
+ steps: []
869
+ };
870
+ var matrixChoiceManifest = {
871
+ type: "matrixChoice",
872
+ label: "Grid / Matrix",
873
+ description: "Grid of rows and columns",
874
+ category: "choice",
875
+ dataType: "object",
876
+ defaultData: matrixChoiceDefaultData,
877
+ properties: [
878
+ ...commonProperties3,
879
+ { name: "rows", label: "Rows (Questions)", type: "options", defaultValue: [] },
880
+ { name: "columns", label: "Columns (Options)", type: "options", defaultValue: [] },
881
+ { name: "multiple", label: "Allow Multiple", type: "switch", defaultValue: false }
882
+ ]
883
+ };
884
+ var cascadingChoiceManifest = {
885
+ type: "cascadingChoice",
886
+ label: "Multi-Step Select",
887
+ description: "Conditional drill-down options",
888
+ category: "choice",
889
+ dataType: "array",
890
+ defaultData: cascadingChoiceDefaultData,
891
+ properties: [
892
+ ...commonProperties3,
893
+ { name: "steps", label: "Steps", type: "stepBuilder", defaultValue: [] }
894
+ ]
895
+ };
896
+
897
+ // src/nodes/structuredChoice/logic.ts
898
+ var isRecord2 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
899
+ var normalizeText = (value) => {
900
+ if (typeof value === "string") return value;
901
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
902
+ return "";
903
+ };
904
+ var optionKey = (item) => item.exportId || item.value || item.id || item.label;
905
+ var optionLabel2 = (item, fallback) => item?.label || fallback;
906
+ var findByKey = (items, key) => items.find((item) => item.exportId === key || item.value === key || item.id === key);
907
+ var normalizeMatrixValue = (rawValue) => {
908
+ if (!isRecord2(rawValue)) return {};
909
+ return Object.fromEntries(Object.entries(rawValue).map(([key, value]) => {
910
+ if (Array.isArray(value)) return [key, value.map(normalizeText).filter(Boolean)];
911
+ if (typeof value === "boolean") return [key, value];
912
+ return [key, normalizeText(value)];
913
+ }));
914
+ };
915
+ var splitMatrixCellKey = (cellKey, rows, columns) => {
916
+ const rowKeys = rows.map(optionKey).sort((a, b) => b.length - a.length);
917
+ for (const rowId of rowKeys) {
918
+ const prefix = `${rowId}_`;
919
+ if (!cellKey.startsWith(prefix)) continue;
920
+ const colId = cellKey.slice(prefix.length);
921
+ if (colId) return [rowId, colId];
922
+ }
923
+ const separatorIndex = cellKey.indexOf("_");
924
+ if (separatorIndex <= 0) return null;
925
+ return [cellKey.slice(0, separatorIndex), cellKey.slice(separatorIndex + 1)];
926
+ };
927
+ var extractMatrixValue = (value, nodeData) => {
928
+ const rows = Array.isArray(nodeData.rows) ? nodeData.rows : [];
929
+ const columns = Array.isArray(nodeData.columns) ? nodeData.columns : [];
930
+ const extracted = [];
931
+ for (const [key, selected] of Object.entries(value)) {
932
+ if (typeof selected === "boolean") {
933
+ if (!selected) continue;
934
+ const parts = splitMatrixCellKey(key, rows, columns);
935
+ if (!parts) continue;
936
+ const [rowId2, colId] = parts;
937
+ const row2 = findByKey(rows, rowId2);
938
+ const column = findByKey(columns, colId);
939
+ extracted.push({
940
+ columnKey: rowId2,
941
+ columnLabel: optionLabel2(row2, rowId2),
942
+ columnId: colId,
943
+ columnTechnicalId: colId,
944
+ columnText: optionLabel2(column, colId),
945
+ textValue: optionLabel2(column, colId)
946
+ });
947
+ continue;
948
+ }
949
+ const rowId = key;
950
+ const selectedColumns = Array.isArray(selected) ? selected : [selected];
951
+ const row = findByKey(rows, rowId);
952
+ for (const selectedColumn of selectedColumns) {
953
+ if (!selectedColumn) continue;
954
+ const column = findByKey(columns, selectedColumn);
955
+ extracted.push({
956
+ columnKey: rowId,
957
+ columnLabel: optionLabel2(row, rowId),
958
+ columnId: selectedColumn,
959
+ columnTechnicalId: selectedColumn,
960
+ columnText: optionLabel2(column, selectedColumn),
961
+ textValue: optionLabel2(column, selectedColumn)
962
+ });
963
+ }
964
+ }
965
+ return extracted;
966
+ };
967
+ var normalizeCascadingValue = (rawValue) => Array.isArray(rawValue) ? rawValue.map(normalizeText).filter(Boolean) : [];
968
+ var extractCascadingValue = (value, nodeData) => {
969
+ const steps = Array.isArray(nodeData.steps) ? nodeData.steps : [];
970
+ return value.map((optionId2, index) => {
971
+ const step = steps[index];
972
+ const stepId = step?.exportId || step?.id;
973
+ const option = step?.options?.find((item) => item.exportId === optionId2 || item.value === optionId2 || item.id === optionId2);
974
+ return {
975
+ columnKey: stepId || `level_${index + 1}`,
976
+ columnLabel: step?.title || `Level ${index + 1}`,
977
+ optionUuid: optionId2,
978
+ optionText: option?.label || optionId2,
979
+ textValue: option?.label || optionId2,
980
+ cascadeLevel: index + 1,
981
+ cascadeParentId: index > 0 ? value[index - 1] || null : null
982
+ };
983
+ });
984
+ };
985
+ var matrixChoiceLogic = {
986
+ type: "matrixChoice",
987
+ dataType: "object",
988
+ defaultData: matrixChoiceDefaultData,
989
+ defaultValue: {},
990
+ normalizeValue: normalizeMatrixValue,
991
+ validate: () => ({ valid: true }),
992
+ extractValue: extractMatrixValue
993
+ };
994
+ var cascadingChoiceLogic = {
995
+ type: "cascadingChoice",
996
+ dataType: "array",
997
+ defaultData: cascadingChoiceDefaultData,
998
+ defaultValue: [],
999
+ normalizeValue: normalizeCascadingValue,
1000
+ validate: () => ({ valid: true }),
1001
+ extractValue: extractCascadingValue
1002
+ };
1003
+
489
1004
  // src/nodes/textLike/manifest.ts
490
- var defaultCondition4 = {
1005
+ var defaultCondition9 = {
491
1006
  id: "root",
492
1007
  type: "group",
493
1008
  logicType: "AND",
@@ -496,20 +1011,20 @@ var defaultCondition4 = {
496
1011
  var baseTextData = {
497
1012
  label: "",
498
1013
  description: "",
499
- condition: defaultCondition4,
1014
+ condition: defaultCondition9,
500
1015
  minChars: 0,
501
1016
  maxChars: 0,
502
1017
  minWords: 0,
503
1018
  maxWords: 0
504
1019
  };
505
- var commonProperties3 = [
1020
+ var commonProperties4 = [
506
1021
  { name: "label", label: "Field Label", type: "text" },
507
1022
  { name: "description", label: "Description", type: "textarea" },
508
1023
  {
509
1024
  name: "condition",
510
1025
  label: "Logic Rule",
511
1026
  type: "condition",
512
- defaultValue: defaultCondition4
1027
+ defaultValue: defaultCondition9
513
1028
  }
514
1029
  ];
515
1030
  var textLimitProperties = [
@@ -548,7 +1063,7 @@ var textInputManifest = {
548
1063
  dataType: "text",
549
1064
  defaultData: textInputDefaultData,
550
1065
  properties: [
551
- ...commonProperties3,
1066
+ ...commonProperties4,
552
1067
  { name: "placeholder", label: "Placeholder", type: "text", placeholder: "e.g., Type here...", defaultValue: "" },
553
1068
  { name: "longAnswer", label: "Long Answer (Multi-line)", type: "switch", defaultValue: false },
554
1069
  ...textLimitProperties
@@ -562,7 +1077,7 @@ var numberInputManifest = {
562
1077
  dataType: "number",
563
1078
  defaultData: numberInputDefaultData,
564
1079
  properties: [
565
- ...commonProperties3,
1080
+ ...commonProperties4,
566
1081
  { name: "min", label: "Minimum Value", type: "number" },
567
1082
  { name: "max", label: "Maximum Value", type: "number" }
568
1083
  ]
@@ -575,7 +1090,7 @@ var zipCodeInputManifest = {
575
1090
  dataType: "text",
576
1091
  defaultData: zipCodeInputDefaultData,
577
1092
  properties: [
578
- ...commonProperties3,
1093
+ ...commonProperties4,
579
1094
  { name: "allowedZips", label: "Allowed Zip Codes", type: "fileTextarea", placeholder: "10001, 10002, 90210... (Leave empty to allow all)", helperText: "Validation: Only users entering these zip codes can proceed. Others will be blocked." }
580
1095
  ]
581
1096
  };
@@ -587,7 +1102,7 @@ var multiInputManifest = {
587
1102
  dataType: "object",
588
1103
  defaultData: multiInputDefaultData,
589
1104
  properties: [
590
- ...commonProperties3,
1105
+ ...commonProperties4,
591
1106
  { name: "fields", label: "Input Fields", type: "options", defaultValue: [], helperText: "Value column represents input type (text, number, email)" },
592
1107
  ...textLimitProperties
593
1108
  ]
@@ -760,19 +1275,38 @@ var logicRegistry = defineLogicRegistry({
760
1275
  multipleChoice: multipleChoiceLogic,
761
1276
  dropdown: dropdownLogic,
762
1277
  ranking: rankingLogic,
1278
+ cascadingChoice: cascadingChoiceLogic,
1279
+ matrixChoice: matrixChoiceLogic,
763
1280
  rating: ratingLogic,
764
1281
  slider: sliderLogic,
765
1282
  consent: consentLogic,
766
- plainText: plainTextLogic
1283
+ captcha: captchaLogic,
1284
+ image: imageLogic,
1285
+ video: videoLogic,
1286
+ audio: audioLogic,
1287
+ plainText: plainTextLogic,
1288
+ emojiRating: emojiRatingLogic,
1289
+ start: startLogic,
1290
+ end: endLogic,
1291
+ branch: branchLogic,
1292
+ validation: validationLogic
767
1293
  });
768
1294
  export {
1295
+ audioLogic,
1296
+ branchLogic,
1297
+ captchaLogic,
1298
+ cascadingChoiceLogic,
769
1299
  consentLogic,
770
1300
  createInitialData,
771
1301
  dateInputLogic,
772
1302
  defineLogicRegistry,
773
1303
  dropdownLogic,
774
1304
  emailInputLogic,
1305
+ emojiRatingLogic,
1306
+ endLogic,
1307
+ imageLogic,
775
1308
  logicRegistry,
1309
+ matrixChoiceLogic,
776
1310
  multiInputLogic,
777
1311
  multipleChoiceLogic,
778
1312
  numberInputLogic,
@@ -781,6 +1315,9 @@ export {
781
1315
  ratingLogic,
782
1316
  singleChoiceLogic,
783
1317
  sliderLogic,
1318
+ startLogic,
784
1319
  textInputLogic,
1320
+ validationLogic,
1321
+ videoLogic,
785
1322
  zipCodeInputLogic
786
1323
  };