@nextlyhq/plugin-form-builder 0.0.2-alpha.68 → 0.0.2-alpha.69

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.
@@ -1,703 +0,0 @@
1
- // src/types.ts
2
- var BUILT_IN_FORM_FIELD_TYPES = [
3
- "text",
4
- "email",
5
- "number",
6
- "phone",
7
- "url",
8
- "textarea",
9
- "select",
10
- "checkbox",
11
- "radio",
12
- "file",
13
- "date",
14
- "time",
15
- "hidden"
16
- ];
17
- var BUILT_IN_FORM_FIELD_TYPES_SET = new Set(
18
- BUILT_IN_FORM_FIELD_TYPES
19
- );
20
- function isKnownFormField(field) {
21
- return BUILT_IN_FORM_FIELD_TYPES_SET.has(field.type);
22
- }
23
- function isFormField(value) {
24
- return typeof value === "object" && value !== null && "type" in value && "name" in value && "label" in value;
25
- }
26
- function isFormFieldType(field, type) {
27
- return field.type === type;
28
- }
29
- function isTextFormField(field) {
30
- return field.type === "text";
31
- }
32
- function isEmailFormField(field) {
33
- return field.type === "email";
34
- }
35
- function isSelectFormField(field) {
36
- return field.type === "select";
37
- }
38
- function isCheckboxFormField(field) {
39
- return field.type === "checkbox";
40
- }
41
- function isFileFormField(field) {
42
- return field.type === "file";
43
- }
44
-
45
- // src/config/removed-options.ts
46
- var warned = /* @__PURE__ */ new Set();
47
- function warnIfWebhooksConfigured(config) {
48
- const notifications = config.notifications;
49
- if (typeof notifications !== "object" || notifications === null) return;
50
- if (!("webhooks" in notifications) || warned.has(config.slug)) return;
51
- warned.add(config.slug);
52
- console.warn(
53
- `[form-builder] Form "${config.slug}" sets notifications.webhooks, which the Form Builder no longer reads, so those webhooks are not sent. Subscribe an endpoint to Nextly's form.submission.created webhook instead: https://nextlyhq.com/docs/plugins/form-builder#webhooks`
54
- );
55
- }
56
-
57
- // src/config/defaults.ts
58
- var DEFAULT_FORM_SETTINGS = {
59
- submitButtonText: "Submit",
60
- confirmationType: "message",
61
- successMessage: "Thank you for your submission!",
62
- allowMultipleSubmissions: true
63
- };
64
- var DEFAULT_NOTIFICATION_SETTINGS = {
65
- enabled: true,
66
- replyTo: true
67
- };
68
- function toTitleCase(str) {
69
- return str.replace(/[-_]/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
70
- }
71
- function pluralize(singular) {
72
- if (singular.endsWith("y") && !/[aeiou]y$/i.test(singular)) {
73
- return singular.slice(0, -1) + "ies";
74
- }
75
- if (singular.endsWith("s") || singular.endsWith("x") || singular.endsWith("z") || singular.endsWith("ch") || singular.endsWith("sh")) {
76
- return singular + "es";
77
- }
78
- return singular + "s";
79
- }
80
- function applyFormDefaults(config) {
81
- warnIfWebhooksConfigured(config);
82
- const singularLabel = config.labels?.singular || toTitleCase(config.slug);
83
- return {
84
- ...config,
85
- // Generate labels from slug if not provided
86
- labels: {
87
- singular: singularLabel,
88
- plural: config.labels?.plural || pluralize(singularLabel)
89
- },
90
- // Apply settings defaults
91
- settings: {
92
- submitButtonText: config.settings?.submitButtonText || DEFAULT_FORM_SETTINGS.submitButtonText,
93
- confirmationType: config.settings?.confirmationType || DEFAULT_FORM_SETTINGS.confirmationType,
94
- successMessage: config.settings?.successMessage || DEFAULT_FORM_SETTINGS.successMessage,
95
- allowMultipleSubmissions: config.settings?.allowMultipleSubmissions ?? DEFAULT_FORM_SETTINGS.allowMultipleSubmissions,
96
- // Preserve other settings that don't have defaults
97
- redirectUrl: config.settings?.redirectUrl,
98
- redirectRelation: config.settings?.redirectRelation,
99
- honeypotEnabled: config.settings?.honeypotEnabled,
100
- captchaEnabled: config.settings?.captchaEnabled,
101
- captchaSiteKey: config.settings?.captchaSiteKey
102
- },
103
- // Apply notification defaults if notifications are configured
104
- notifications: config.notifications ? {
105
- enabled: config.notifications.enabled ?? DEFAULT_NOTIFICATION_SETTINGS.enabled,
106
- recipients: config.notifications.recipients || [],
107
- subject: config.notifications.subject || `New submission for ${singularLabel}`,
108
- replyTo: config.notifications.replyTo ?? DEFAULT_NOTIFICATION_SETTINGS.replyTo,
109
- template: config.notifications.template
110
- } : void 0,
111
- // Apply access defaults
112
- access: {
113
- // Default: anyone can submit the form
114
- submit: config.access?.submit || (() => true),
115
- // Default: only authenticated users can view submissions
116
- read: config.access?.read || (({ req }) => !!req.user)
117
- }
118
- };
119
- }
120
- function applyFieldDefaults(field) {
121
- const label = field.label || (field.name ? toTitleCase(field.name.replace(/([A-Z])/g, " $1").trim()) : "");
122
- return {
123
- ...field,
124
- label,
125
- required: field.required ?? false
126
- };
127
- }
128
- function createFormConfig(slug, fields, options) {
129
- return applyFormDefaults({
130
- slug,
131
- fields,
132
- ...options
133
- });
134
- }
135
-
136
- // src/utils/evaluate-conditions.ts
137
- function isEmptyValue(value) {
138
- if (value === void 0 || value === null) {
139
- return true;
140
- }
141
- if (typeof value === "string" && value.trim() === "") {
142
- return true;
143
- }
144
- if (Array.isArray(value) && value.length === 0) {
145
- return true;
146
- }
147
- return false;
148
- }
149
- function toNumber(value) {
150
- if (typeof value === "number") {
151
- return value;
152
- }
153
- if (typeof value === "string") {
154
- const trimmed = value.trim();
155
- if (trimmed === "") {
156
- return NaN;
157
- }
158
- return Number(trimmed);
159
- }
160
- return NaN;
161
- }
162
- function toString(value) {
163
- if (value === void 0 || value === null) {
164
- return "";
165
- }
166
- if (typeof value === "string") {
167
- return value;
168
- }
169
- if (Array.isArray(value)) {
170
- return value.join(", ");
171
- }
172
- if (typeof value === "object") {
173
- return JSON.stringify(value);
174
- }
175
- return String(value);
176
- }
177
- function compareValues(operator, fieldValue, conditionValue) {
178
- switch (operator) {
179
- case "equals": {
180
- if (Array.isArray(fieldValue)) {
181
- if (Array.isArray(conditionValue)) {
182
- if (fieldValue.length !== conditionValue.length) {
183
- return false;
184
- }
185
- return fieldValue.every((v, i) => v === conditionValue[i]);
186
- }
187
- return fieldValue.includes(conditionValue);
188
- }
189
- return toString(fieldValue) === toString(conditionValue);
190
- }
191
- case "notEquals": {
192
- if (Array.isArray(fieldValue)) {
193
- if (Array.isArray(conditionValue)) {
194
- if (fieldValue.length !== conditionValue.length) {
195
- return true;
196
- }
197
- return !fieldValue.every((v, i) => v === conditionValue[i]);
198
- }
199
- return !fieldValue.includes(conditionValue);
200
- }
201
- return toString(fieldValue) !== toString(conditionValue);
202
- }
203
- case "contains": {
204
- const fieldStr = toString(fieldValue).toLowerCase();
205
- const conditionStr = toString(conditionValue).toLowerCase();
206
- if (Array.isArray(fieldValue)) {
207
- return fieldValue.some(
208
- (v) => toString(v).toLowerCase().includes(conditionStr)
209
- );
210
- }
211
- return fieldStr.includes(conditionStr);
212
- }
213
- case "isEmpty": {
214
- return isEmptyValue(fieldValue);
215
- }
216
- case "isNotEmpty": {
217
- return !isEmptyValue(fieldValue);
218
- }
219
- case "greaterThan": {
220
- const fieldNum = toNumber(fieldValue);
221
- const conditionNum = toNumber(conditionValue);
222
- if (!Number.isNaN(fieldNum) && !Number.isNaN(conditionNum)) {
223
- return fieldNum > conditionNum;
224
- }
225
- return toString(fieldValue) > toString(conditionValue);
226
- }
227
- case "lessThan": {
228
- const fieldNum = toNumber(fieldValue);
229
- const conditionNum = toNumber(conditionValue);
230
- if (!Number.isNaN(fieldNum) && !Number.isNaN(conditionNum)) {
231
- return fieldNum < conditionNum;
232
- }
233
- return toString(fieldValue) < toString(conditionValue);
234
- }
235
- default: {
236
- console.warn(
237
- `[evaluateConditions] Unknown comparison operator: ${String(operator)}`
238
- );
239
- return false;
240
- }
241
- }
242
- }
243
- function evaluateSingleCondition(condition, formData) {
244
- const { field, comparison, value: conditionValue } = condition;
245
- const fieldValue = getNestedValue(formData, field);
246
- return compareValues(comparison, fieldValue, conditionValue);
247
- }
248
- function getNestedValue(obj, path) {
249
- if (!path) {
250
- return void 0;
251
- }
252
- if (!path.includes(".")) {
253
- return obj[path];
254
- }
255
- const parts = path.split(".");
256
- let current = obj;
257
- for (const part of parts) {
258
- if (current === void 0 || current === null) {
259
- return void 0;
260
- }
261
- if (typeof current !== "object") {
262
- return void 0;
263
- }
264
- current = current[part];
265
- }
266
- return current;
267
- }
268
- function evaluateConditions(logic, formData) {
269
- if (!logic || !logic.enabled) {
270
- return true;
271
- }
272
- const { action, operator, conditions } = logic;
273
- if (!conditions || conditions.length === 0) {
274
- return true;
275
- }
276
- const results = conditions.map(
277
- (condition) => evaluateSingleCondition(condition, formData)
278
- );
279
- let conditionsMet;
280
- if (operator === "OR") {
281
- conditionsMet = results.some((result) => result);
282
- } else {
283
- conditionsMet = results.every((result) => result);
284
- }
285
- if (action === "hide") {
286
- return !conditionsMet;
287
- }
288
- return conditionsMet;
289
- }
290
- function isValidComparisonOperator(operator) {
291
- const validOperators = [
292
- "equals",
293
- "notEquals",
294
- "contains",
295
- "isEmpty",
296
- "isNotEmpty",
297
- "greaterThan",
298
- "lessThan"
299
- ];
300
- return validOperators.includes(operator);
301
- }
302
- function getSupportedComparisonOperators() {
303
- return [
304
- "equals",
305
- "notEquals",
306
- "contains",
307
- "isEmpty",
308
- "isNotEmpty",
309
- "greaterThan",
310
- "lessThan"
311
- ];
312
- }
313
-
314
- // src/utils/export-formats.ts
315
- var UTF8_BOM = "\uFEFF";
316
- function safeString(value) {
317
- if (typeof value === "object" && value !== null) {
318
- return JSON.stringify(value);
319
- }
320
- return String(value);
321
- }
322
- function formatExportValue(value, field) {
323
- if (value === null || value === void 0) {
324
- return "";
325
- }
326
- if (field) {
327
- switch (field.type) {
328
- case "checkbox":
329
- return value ? "Yes" : "No";
330
- case "select":
331
- if (Array.isArray(value)) {
332
- return value.join(", ");
333
- }
334
- return safeString(value);
335
- case "file":
336
- if (Array.isArray(value)) {
337
- return value.map((v) => safeString(v)).join(", ");
338
- }
339
- return safeString(value);
340
- case "date":
341
- if (value instanceof Date) {
342
- return value.toISOString().split("T")[0];
343
- }
344
- if (typeof value === "string") {
345
- const parsed = new Date(value);
346
- if (!isNaN(parsed.getTime())) {
347
- return parsed.toISOString().split("T")[0];
348
- }
349
- }
350
- return safeString(value);
351
- case "time":
352
- return safeString(value);
353
- case "hidden":
354
- return safeString(value);
355
- default:
356
- break;
357
- }
358
- }
359
- if (Array.isArray(value)) {
360
- return value.join(", ");
361
- }
362
- if (typeof value === "boolean") {
363
- return value ? "Yes" : "No";
364
- }
365
- if (value instanceof Date) {
366
- return value.toISOString();
367
- }
368
- return safeString(value);
369
- }
370
- function formatDate(date, format = "iso") {
371
- if (!date) return "";
372
- const d = typeof date === "string" ? new Date(date) : date;
373
- if (isNaN(d.getTime())) {
374
- return "";
375
- }
376
- return format === "iso" ? d.toISOString() : d.toLocaleString();
377
- }
378
- function escapeCSVValue(value, delimiter = ",") {
379
- const isFormulaLike = /^[=+\-@\t\r]/.test(value) && !/^-?\d+(\.\d+)?$/.test(value);
380
- const escapedFormula = isFormulaLike ? `'${value}` : value;
381
- const needsQuoting = escapedFormula.includes(delimiter) || escapedFormula.includes('"') || escapedFormula.includes("\n") || escapedFormula.includes("\r");
382
- if (!needsQuoting) {
383
- return escapedFormula;
384
- }
385
- const escaped = escapedFormula.replace(/"/g, '""');
386
- return `"${escaped}"`;
387
- }
388
- function exportToCSV(submissions, form, options = {}) {
389
- const {
390
- includeMetadata = true,
391
- delimiter = ",",
392
- includeBOM = true,
393
- dateFormat = "iso"
394
- } = options;
395
- const exportableFields = form.fields;
396
- const headers = [];
397
- for (const field of exportableFields) {
398
- headers.push(field.label);
399
- }
400
- if (includeMetadata) {
401
- headers.push("ID", "Status", "Submitted At", "IP Address", "User Agent");
402
- }
403
- const rows = [];
404
- for (const submission of submissions) {
405
- const row = [];
406
- const data = submission.data;
407
- for (const field of exportableFields) {
408
- const value = data[field.name];
409
- const formatted = formatExportValue(value, field);
410
- row.push(escapeCSVValue(formatted, delimiter));
411
- }
412
- if (includeMetadata) {
413
- row.push(escapeCSVValue(submission.id, delimiter));
414
- row.push(escapeCSVValue(submission.status, delimiter));
415
- row.push(
416
- escapeCSVValue(
417
- formatDate(submission.submittedAt, dateFormat),
418
- delimiter
419
- )
420
- );
421
- row.push(escapeCSVValue(submission.ipAddress || "", delimiter));
422
- row.push(escapeCSVValue(submission.userAgent || "", delimiter));
423
- }
424
- rows.push(row);
425
- }
426
- const escapedHeaders = headers.map((h) => escapeCSVValue(h, delimiter));
427
- const lines = [
428
- escapedHeaders.join(delimiter),
429
- ...rows.map((row) => row.join(delimiter))
430
- ];
431
- const csvContent = lines.join("\r\n");
432
- return includeBOM ? UTF8_BOM + csvContent : csvContent;
433
- }
434
- function exportToJSON(submissions, form, options = {}) {
435
- const {
436
- includeMetadata = true,
437
- includeFormDefinition = true,
438
- indent = 2
439
- } = options;
440
- const exportableFields = form.fields;
441
- const formDefinition = includeFormDefinition ? {
442
- id: form.id,
443
- name: form.name,
444
- slug: form.slug,
445
- fields: exportableFields.map((f) => ({
446
- name: f.name,
447
- label: f.label,
448
- type: f.type
449
- }))
450
- } : void 0;
451
- const exportedSubmissions = submissions.map((submission) => {
452
- const data = submission.data;
453
- const fieldData = {};
454
- for (const field of exportableFields) {
455
- const value = data[field.name];
456
- fieldData[field.name] = value;
457
- }
458
- if (includeMetadata) {
459
- return {
460
- ...fieldData,
461
- _metadata: {
462
- id: submission.id,
463
- status: submission.status,
464
- submittedAt: submission.submittedAt,
465
- ipAddress: submission.ipAddress || null,
466
- userAgent: submission.userAgent || null,
467
- createdAt: submission.createdAt,
468
- updatedAt: submission.updatedAt
469
- }
470
- };
471
- }
472
- return fieldData;
473
- });
474
- const exportData = {
475
- exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
476
- totalSubmissions: submissions.length,
477
- submissions: exportedSubmissions
478
- };
479
- if (formDefinition) {
480
- exportData.form = formDefinition;
481
- }
482
- return JSON.stringify(exportData, null, indent);
483
- }
484
- function downloadFile(content, filename, mimeType) {
485
- if (typeof window === "undefined" || typeof document === "undefined") {
486
- throw new Error("downloadFile is only available in browser environments");
487
- }
488
- const blob = new Blob([content], { type: mimeType });
489
- const url = URL.createObjectURL(blob);
490
- const link = document.createElement("a");
491
- link.href = url;
492
- link.download = filename;
493
- document.body.appendChild(link);
494
- link.click();
495
- document.body.removeChild(link);
496
- URL.revokeObjectURL(url);
497
- }
498
- function generateExportFilename(formSlug, format) {
499
- const safeSlug = formSlug.toLowerCase().replace(/[^a-z0-9_-]+/g, "-") || "form";
500
- const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
501
- return `${safeSlug}-submissions-${date}.${format}`;
502
- }
503
- function exportAndDownload(submissions, form, format, options) {
504
- const filename = generateExportFilename(form.slug, format);
505
- if (format === "csv") {
506
- const content = exportToCSV(submissions, form, options);
507
- downloadFile(content, filename, "text/csv;charset=utf-8");
508
- } else {
509
- const content = exportToJSON(submissions, form, options);
510
- downloadFile(content, filename, "application/json");
511
- }
512
- }
513
-
514
- // src/utils/redirect-reference.ts
515
- function parseRedirectReference(value, collections) {
516
- if (value == null) return null;
517
- if (typeof value === "string") {
518
- const id2 = value.trim();
519
- return id2 && collections.length === 1 ? { collection: collections[0], id: id2 } : null;
520
- }
521
- if (typeof value !== "object" || Array.isArray(value)) return null;
522
- const record = value;
523
- const relationTo = record.relationTo;
524
- const inner = record.value;
525
- if (typeof relationTo === "string" && relationTo.trim()) {
526
- const id2 = referenceId(inner);
527
- return id2 ? { collection: relationTo.trim(), id: id2 } : null;
528
- }
529
- const id = referenceId(record);
530
- if (!id) return null;
531
- return collections.length === 1 ? { collection: collections[0], id } : null;
532
- }
533
- function referenceId(value) {
534
- if (typeof value === "string") return value.trim() || null;
535
- if (value !== null && typeof value === "object" && !Array.isArray(value)) {
536
- const { id } = value;
537
- if (typeof id === "string" && id) return id;
538
- }
539
- return null;
540
- }
541
- var PUBLISH_LIFECYCLE_FIELD = "firstPublishedAt";
542
- function hasPublishLifecycle(document2) {
543
- return PUBLISH_LIFECYCLE_FIELD in document2;
544
- }
545
- function documentReachability(document2, collectionIsLocalized) {
546
- if (!hasPublishLifecycle(document2)) return "reachable";
547
- if (document2.status === "published") return "reachable";
548
- if (collectionIsLocalized === false) return "unreachable";
549
- return "unknown";
550
- }
551
- function pickedDocumentField(settings) {
552
- if (settings.confirmationType === "relationship") return "redirectPage";
553
- if (settings.confirmationType === "redirect" && !settings.redirectUrl && settings.redirectRelation != null) {
554
- return "redirectRelation";
555
- }
556
- return null;
557
- }
558
-
559
- // src/utils/enforced-validation.ts
560
- var ENFORCED_VALIDATION_RULES = {
561
- text: ["minLength", "maxLength", "pattern", "message"],
562
- // Length bounds are deliberately absent: the email schema applies its own
563
- // format check and a pattern, and reads neither `minLength` nor `maxLength`.
564
- email: ["pattern", "message"],
565
- number: ["min", "max", "message"],
566
- phone: ["pattern", "message"],
567
- url: ["pattern", "message"],
568
- // No pattern: the textarea schema reads only the two length bounds.
569
- textarea: ["minLength", "maxLength", "message"],
570
- select: ["message"],
571
- checkbox: ["message"],
572
- radio: ["message"],
573
- // A file's size limit is stored on the field itself, not under `validation`.
574
- file: ["message"],
575
- // The date schema reads `field.min`/`field.max` — top level, not `validation`
576
- // — so a `validation.min` written here would never be consulted.
577
- date: ["message"],
578
- time: ["message"],
579
- hidden: ["message"]
580
- };
581
- function enforcedValidationRules(type) {
582
- return ENFORCED_VALIDATION_RULES[type] ?? [];
583
- }
584
-
585
- // src/utils/form-settings.ts
586
- function asOptionalBoolean(value) {
587
- return typeof value === "boolean" ? value : void 0;
588
- }
589
- function asOptionalString(value) {
590
- return typeof value === "string" && value !== "" ? value : void 0;
591
- }
592
- function normalizeFormSettings(raw) {
593
- if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
594
- return { ...DEFAULT_FORM_SETTINGS };
595
- }
596
- const source = raw;
597
- const legacyMessage = asOptionalString(source.confirmationMessage);
598
- const legacyCaptcha = source.captcha && typeof source.captcha === "object" ? source.captcha : void 0;
599
- const confirmationType = source.confirmationType === "redirect" || source.confirmationType === "relationship" ? source.confirmationType : "message";
600
- return {
601
- submitButtonText: asOptionalString(source.submitButtonText) ?? DEFAULT_FORM_SETTINGS.submitButtonText,
602
- confirmationType,
603
- successMessage: asOptionalString(source.successMessage) ?? legacyMessage ?? DEFAULT_FORM_SETTINGS.successMessage,
604
- redirectUrl: asOptionalString(source.redirectUrl),
605
- redirectPage: source.redirectPage ?? void 0,
606
- redirectRelation: source.redirectRelation && typeof source.redirectRelation === "object" ? source.redirectRelation : void 0,
607
- allowMultipleSubmissions: asOptionalBoolean(source.allowMultipleSubmissions) ?? DEFAULT_FORM_SETTINGS.allowMultipleSubmissions,
608
- honeypotEnabled: asOptionalBoolean(source.honeypotEnabled),
609
- captchaEnabled: asOptionalBoolean(source.captchaEnabled) ?? asOptionalBoolean(legacyCaptcha?.enabled),
610
- captchaSiteKey: asOptionalString(source.captchaSiteKey) ?? asOptionalString(legacyCaptcha?.siteKey)
611
- };
612
- }
613
-
614
- // src/utils/field-references.ts
615
- var FIELD_REF_PATTERN = /^\{\{(\w+)\}\}$/;
616
- function parseFieldRef(value) {
617
- if (!value) return null;
618
- const match = value.match(FIELD_REF_PATTERN);
619
- return match ? match[1] : null;
620
- }
621
- function referencesInTemplate(template, fieldName) {
622
- const pattern = new RegExp(
623
- `\\{\\{\\s*${fieldName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*\\}\\}`
624
- );
625
- return pattern.test(template);
626
- }
627
- function findFieldReferences(fieldName, fields, notifications) {
628
- const references = [];
629
- for (const field of fields) {
630
- if (field.name === fieldName) continue;
631
- if (!field.conditionalLogic?.enabled) continue;
632
- const conditions = field.conditionalLogic.conditions ?? [];
633
- if (conditions.some((condition) => condition.field === fieldName)) {
634
- references.push({ kind: "condition", label: field.label || field.name });
635
- }
636
- }
637
- for (const notification of notifications) {
638
- if (!notification.enabled) continue;
639
- const templates = [
640
- notification.to,
641
- ...notification.cc ?? [],
642
- ...notification.bcc ?? [],
643
- notification.replyTo
644
- ].filter((value) => typeof value === "string");
645
- const referencedByTemplate = templates.some(
646
- (template) => referencesInTemplate(template, fieldName)
647
- );
648
- const referencedByCondition = notification.condition?.field === fieldName;
649
- if (referencedByTemplate || referencedByCondition) {
650
- references.push({
651
- kind: "notification",
652
- label: notification.name || "Notification"
653
- });
654
- }
655
- }
656
- return references;
657
- }
658
- function buildFieldReferenceMap(fields, notifications) {
659
- const map = /* @__PURE__ */ new Map();
660
- for (const field of fields) {
661
- map.set(field.name, findFieldReferences(field.name, fields, notifications));
662
- }
663
- return map;
664
- }
665
-
666
- export {
667
- parseRedirectReference,
668
- documentReachability,
669
- pickedDocumentField,
670
- BUILT_IN_FORM_FIELD_TYPES,
671
- isKnownFormField,
672
- isFormField,
673
- isFormFieldType,
674
- isTextFormField,
675
- isEmailFormField,
676
- isSelectFormField,
677
- isCheckboxFormField,
678
- isFileFormField,
679
- ENFORCED_VALIDATION_RULES,
680
- enforcedValidationRules,
681
- warnIfWebhooksConfigured,
682
- DEFAULT_FORM_SETTINGS,
683
- DEFAULT_NOTIFICATION_SETTINGS,
684
- toTitleCase,
685
- pluralize,
686
- applyFormDefaults,
687
- applyFieldDefaults,
688
- createFormConfig,
689
- normalizeFormSettings,
690
- evaluateSingleCondition,
691
- evaluateConditions,
692
- isValidComparisonOperator,
693
- getSupportedComparisonOperators,
694
- formatExportValue,
695
- exportToCSV,
696
- exportToJSON,
697
- downloadFile,
698
- generateExportFilename,
699
- exportAndDownload,
700
- parseFieldRef,
701
- buildFieldReferenceMap
702
- };
703
- //# sourceMappingURL=chunk-X5WLJLAR.js.map