@nextlyhq/plugin-form-builder 0.0.2-alpha.72 → 0.0.2-alpha.73
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/admin/index.d.ts +5 -1
- package/dist/admin/index.js +133 -4
- package/dist/admin/index.js.map +1 -1
- package/dist/{field-references-BshlgMcn.js → field-references-CtzGg51W.js} +272 -2
- package/dist/field-references-CtzGg51W.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +149 -12
- package/dist/index.js.map +1 -1
- package/dist/{types-BHReIA0j.d.ts → new-submissions-CzlhVGhH.d.ts} +34 -2
- package/package.json +12 -12
- package/dist/field-references-BshlgMcn.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as HiddenFormField, B as UrlFormField, C as FormHookContext, D as FormNotifications, E as FormNotificationItem, F as SelectFormField, G as isFormField, H as isCheckboxFormField, I as SubmissionDocument, J as isSelectFormField, K as isFormFieldType, L as TextFormField, M as PhoneFormField, N as RadioFormField, O as FormSettings, P as ResolvedFormBuilderConfig, R as TextareaFormField, S as FormFieldTypeId, T as FormNotification, U as isEmailFormField, V as ValidationRules, W as isFileFormField, Y as isTextFormField, _ as FormBuilderPluginOptions, a as BUILT_IN_FORM_FIELD_TYPES, b as FormField, c as ConditionalLogic, d as DateFormField, f as EmailConfig, g as FormAccess, h as FileFormField, i as AnyFormField, j as NumberFormField, k as FormSubmission, l as ConditionalLogicCondition, m as FieldBlockConfig, n as NewSubmissionRow, o as BaseFormField, p as EmailFormField, q as isKnownFormField, r as NewSubmissionsData, s as CheckboxFormField, t as NEW_SUBMISSIONS_WIDGET_ID, u as CustomFormField, v as FormConfig, w as FormHooks, x as FormFieldType, y as FormDocument, z as TimeFormField } from "./new-submissions-CzlhVGhH.js";
|
|
2
2
|
import { PluginDefinition } from "@nextlyhq/plugin-sdk";
|
|
3
3
|
import { CollectionConfig, PluginContext } from "nextly";
|
|
4
4
|
import { z } from "zod";
|
|
@@ -1385,5 +1385,5 @@ interface ExtendedCollectionConfig extends Omit<CollectionConfig, "admin"> {
|
|
|
1385
1385
|
*/
|
|
1386
1386
|
export declare function submissionsCollection(pluginConfig: ResolvedFormBuilderConfig): ExtendedCollectionConfig;
|
|
1387
1387
|
export declare const formBuilderPlugin: ReturnType<typeof formBuilder>["plugin"];
|
|
1388
|
-
export { type AnyFormField, BUILT_IN_FORM_FIELD_TYPES, type BaseFormField, type CSVExportOptions, type CheckboxFormField, type ComparisonOperator, type ConditionalLogic, type ConditionalLogicCondition, type CustomFormField, type DateFormField, type EmailConfig, type EmailFormField, type ExportedJSON, type FieldBlockConfig, type FileFormField, type FormAccess, type FormBuilderPluginOptions, type FormBuilderPluginResult, type FormConfig, type FormDocument, type FormField, type FormFieldOption, type FormFieldType, type FormFieldTypeId, type FormHookContext, type FormHooks, type FormNotification, type FormNotificationItem, type FormNotifications, type FormSettings, type FormSubmission, type FormValidationError, type FormValidationErrorCode, type FormValidationResult, type HiddenFormField, type JSONExportOptions, type NextlyPlugin, type NumberFormField, type PhoneFormField, type RadioFormField, type ResolvedFormBuilderConfig, type SelectFormField, type SpamCheckConfig, type SpamCheckOptions, type SpamCheckResult, type SubmissionDocument, type SubmitFormContext, type SubmitFormOptions, type SubmitFormResult, type TextFormField, type TextareaFormField, type TimeFormField, type UrlFormField, type ValidationRules, isCheckboxFormField, isEmailFormField, isFileFormField, isFormField, isFormFieldType, isKnownFormField, isSelectFormField, isTextFormField };
|
|
1388
|
+
export { type AnyFormField, BUILT_IN_FORM_FIELD_TYPES, type BaseFormField, type CSVExportOptions, type CheckboxFormField, type ComparisonOperator, type ConditionalLogic, type ConditionalLogicCondition, type CustomFormField, type DateFormField, type EmailConfig, type EmailFormField, type ExportedJSON, type FieldBlockConfig, type FileFormField, type FormAccess, type FormBuilderPluginOptions, type FormBuilderPluginResult, type FormConfig, type FormDocument, type FormField, type FormFieldOption, type FormFieldType, type FormFieldTypeId, type FormHookContext, type FormHooks, type FormNotification, type FormNotificationItem, type FormNotifications, type FormSettings, type FormSubmission, type FormValidationError, type FormValidationErrorCode, type FormValidationResult, type HiddenFormField, type JSONExportOptions, NEW_SUBMISSIONS_WIDGET_ID, type NewSubmissionRow, type NewSubmissionsData, type NextlyPlugin, type NumberFormField, type PhoneFormField, type RadioFormField, type ResolvedFormBuilderConfig, type SelectFormField, type SpamCheckConfig, type SpamCheckOptions, type SpamCheckResult, type SubmissionDocument, type SubmitFormContext, type SubmitFormOptions, type SubmitFormResult, type TextFormField, type TextareaFormField, type TimeFormField, type UrlFormField, type ValidationRules, isCheckboxFormField, isEmailFormField, isFileFormField, isFormField, isFormFieldType, isKnownFormField, isSelectFormField, isTextFormField };
|
|
1389
1389
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as isKnownFormField, D as isFileFormField, E as isEmailFormField, F as
|
|
1
|
+
import { A as isKnownFormField, D as isFileFormField, E as isEmailFormField, F as SCHEMA_ONLY_CONTEXT, I as SCHEMA_ONLY_READ, L as documentReachability, M as isTextFormField, N as NEW_SUBMISSIONS_WIDGET_ID, O as isFormField, P as readNewSubmissions, R as parseRedirectReference, S as ENFORCED_VALIDATION_RULES, T as isCheckboxFormField, _ as applyFormDefaults, a as exportToCSV, b as toTitleCase, c as generateExportFilename, d as getSupportedComparisonOperators, f as isValidComparisonOperator, g as applyFieldDefaults, h as DEFAULT_NOTIFICATION_SETTINGS, i as exportAndDownload, j as isSelectFormField, k as isFormFieldType, l as evaluateConditions, m as DEFAULT_FORM_SETTINGS, n as parseFieldRef, o as exportToJSON, p as normalizeFormSettings, r as downloadFile, s as formatExportValue, u as evaluateSingleCondition, v as createFormConfig, w as BUILT_IN_FORM_FIELD_TYPES, x as warnIfWebhooksConfigured, y as pluralize, z as pickedDocumentField } from "./field-references-CtzGg51W.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import { NextlyError, definePlugin, isLocaleSelector } from "@nextlyhq/plugin-sdk";
|
|
3
|
+
import { NextlyError, definePlugin, defineWidget, isLocaleSelector, rowsThatFit } from "@nextlyhq/plugin-sdk";
|
|
4
4
|
import { NO_SUCH_FORM, NextlyError as NextlyError$1, RateLimiter, buildPaginatedResponse, checkbox as checkbox$1, clampLimit, date as date$1, formAvailability, group, isPluginFieldTypeOnSurface, json, relationship, resolveRateLimitStore, respondAction, respondDoc, respondList, select as select$1, stripHtmlTags, text as text$1, textarea as textarea$1, trustedClientIp } from "nextly";
|
|
5
5
|
import { previewUrlFromTemplate } from "nextly/config";
|
|
6
6
|
import { z } from "zod";
|
|
@@ -686,6 +686,19 @@ function formsCollection(pluginConfig) {
|
|
|
686
686
|
|
|
687
687
|
// src/collections/submissions.ts
|
|
688
688
|
/**
|
|
689
|
+
* Whether a create keeps the `submittedAt` it names: only one made on the
|
|
690
|
+
* server with no request behind it (`req.http` absent), such as an import
|
|
691
|
+
* restoring old submissions with their dates, and only where it names one.
|
|
692
|
+
*
|
|
693
|
+
* A create a request produced, a visitor's through the public grant above
|
|
694
|
+
* all, is given the server's time whatever it says: the dashboard lists new
|
|
695
|
+
* submissions newest first by this field, and a date a visitor chose (one far
|
|
696
|
+
* in the future) would keep theirs ahead of every real submission.
|
|
697
|
+
*/
|
|
698
|
+
function trustedSubmittedAt(context) {
|
|
699
|
+
return context.req?.http === void 0 && Boolean(context.data?.submittedAt);
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
689
702
|
* Generate the Form Submissions collection configuration.
|
|
690
703
|
*
|
|
691
704
|
* Creates a collection for storing form submissions with:
|
|
@@ -750,6 +763,7 @@ function submissionsCollection(pluginConfig) {
|
|
|
750
763
|
value: "spam"
|
|
751
764
|
}
|
|
752
765
|
],
|
|
766
|
+
index: true,
|
|
753
767
|
admin: { description: "Track whether this submission has been reviewed" }
|
|
754
768
|
}),
|
|
755
769
|
text$1({
|
|
@@ -785,6 +799,7 @@ function submissionsCollection(pluginConfig) {
|
|
|
785
799
|
name: "submittedAt",
|
|
786
800
|
label: "Submitted At",
|
|
787
801
|
required: true,
|
|
802
|
+
index: true,
|
|
788
803
|
admin: {
|
|
789
804
|
readOnly: true,
|
|
790
805
|
description: "When the form was submitted"
|
|
@@ -841,7 +856,7 @@ function submissionsCollection(pluginConfig) {
|
|
|
841
856
|
hooks: {
|
|
842
857
|
beforeValidate: [(context) => {
|
|
843
858
|
const { data, operation } = context;
|
|
844
|
-
if (operation === "create" && data && !
|
|
859
|
+
if (operation === "create" && data && !trustedSubmittedAt(context)) data.submittedAt = /* @__PURE__ */ new Date();
|
|
845
860
|
return data;
|
|
846
861
|
}],
|
|
847
862
|
afterChange: [(context) => {
|
|
@@ -853,6 +868,106 @@ function submissionsCollection(pluginConfig) {
|
|
|
853
868
|
};
|
|
854
869
|
}
|
|
855
870
|
|
|
871
|
+
// src/dashboard/widget.ts
|
|
872
|
+
/**
|
|
873
|
+
* New form submissions: the form-builder plugin's dashboard widget, declared
|
|
874
|
+
* once with `defineWidget` and contributed under `contributes.dashboard`.
|
|
875
|
+
*
|
|
876
|
+
* Offered to a reader of both the forms and the submissions, and shown while
|
|
877
|
+
* at least one form is theirs to read; its card lists the new submissions of
|
|
878
|
+
* those forms, newest first, and stays on the dashboard with "No new
|
|
879
|
+
* submissions" while there are none. Its summary puts the card's own count in
|
|
880
|
+
* the dashboard's header. Core's default dashboard names it by its id
|
|
881
|
+
* (`NEW_SUBMISSIONS_WIDGET_ID`), so a site without this plugin has no such
|
|
882
|
+
* card and no such part.
|
|
883
|
+
*
|
|
884
|
+
* @module dashboard/widget
|
|
885
|
+
*/
|
|
886
|
+
/** The component the card is drawn by, as the admin's component map imports it. */
|
|
887
|
+
const CARD_COMPONENT = "@nextlyhq/plugin-form-builder/admin#NewSubmissionsCard";
|
|
888
|
+
/** A case for the preview page and the add panel's tile. */
|
|
889
|
+
const PREVIEW = {
|
|
890
|
+
items: [{
|
|
891
|
+
id: "preview-1",
|
|
892
|
+
title: "Ana Ruiz",
|
|
893
|
+
form: "Contact",
|
|
894
|
+
excerpt: "Could you send me your price list?",
|
|
895
|
+
at: "2026-01-05T09:30:00.000Z",
|
|
896
|
+
href: "/admin/collections/form-submissions/preview-1"
|
|
897
|
+
}, {
|
|
898
|
+
id: "preview-2",
|
|
899
|
+
title: "sam@example.com",
|
|
900
|
+
form: "Newsletter",
|
|
901
|
+
at: "2026-01-05T08:10:00.000Z",
|
|
902
|
+
href: "/admin/collections/form-submissions/preview-2"
|
|
903
|
+
}],
|
|
904
|
+
total: 2,
|
|
905
|
+
allHref: "/admin/collections/form-submissions",
|
|
906
|
+
collection: "form-submissions"
|
|
907
|
+
};
|
|
908
|
+
/**
|
|
909
|
+
* The widget, over the plugin's collections as it declares them and the
|
|
910
|
+
* submissions slug the admin knows them by once installed.
|
|
911
|
+
*
|
|
912
|
+
* `submissionsPath` is read when a card loads rather than when the widget is
|
|
913
|
+
* declared: the plugin learns the slug a site renamed its collection to only
|
|
914
|
+
* at `init`, after this declaration was made. Every link the card draws, its
|
|
915
|
+
* empty state's among them, is made from it, so none names a slug the site
|
|
916
|
+
* renamed away.
|
|
917
|
+
*/
|
|
918
|
+
function newSubmissionsWidget(declared, submissionsPath) {
|
|
919
|
+
return defineWidget({
|
|
920
|
+
id: NEW_SUBMISSIONS_WIDGET_ID,
|
|
921
|
+
title: "New form submissions",
|
|
922
|
+
description: "Form submissions nobody has opened yet, newest first.",
|
|
923
|
+
icon: "Inbox",
|
|
924
|
+
category: "Forms",
|
|
925
|
+
size: {
|
|
926
|
+
default: {
|
|
927
|
+
w: 6,
|
|
928
|
+
h: 3
|
|
929
|
+
},
|
|
930
|
+
max: {
|
|
931
|
+
w: 12,
|
|
932
|
+
h: 8
|
|
933
|
+
}
|
|
934
|
+
},
|
|
935
|
+
access: { collections: [declared.forms, declared.submissions] },
|
|
936
|
+
shows: async ({ services, signal }) => await services.count(declared.forms, {
|
|
937
|
+
status: "all",
|
|
938
|
+
signal
|
|
939
|
+
}) > 0,
|
|
940
|
+
skeleton: "list",
|
|
941
|
+
load: async ({ services, size, signal, scope }) => readNewSubmissions(services, declared, {
|
|
942
|
+
limit: rowsThatFit(size, { density: "default" }),
|
|
943
|
+
signal,
|
|
944
|
+
scope,
|
|
945
|
+
submissionsPath: submissionsPath()
|
|
946
|
+
}),
|
|
947
|
+
view: { component: CARD_COMPONENT },
|
|
948
|
+
isEmpty: () => false,
|
|
949
|
+
preview: [{
|
|
950
|
+
name: "Two new",
|
|
951
|
+
data: PREVIEW
|
|
952
|
+
}],
|
|
953
|
+
summary: {
|
|
954
|
+
label: "new submissions",
|
|
955
|
+
count: async ({ services, signal, scope }) => {
|
|
956
|
+
const { total, atLeast } = await readNewSubmissions(services, declared, {
|
|
957
|
+
limit: 0,
|
|
958
|
+
signal,
|
|
959
|
+
scope,
|
|
960
|
+
submissionsPath: submissionsPath()
|
|
961
|
+
});
|
|
962
|
+
return {
|
|
963
|
+
count: total,
|
|
964
|
+
atLeast: atLeast === true
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
|
|
856
971
|
// src/document-shapes.ts
|
|
857
972
|
/**
|
|
858
973
|
* Read a stored row as a submission.
|
|
@@ -2376,6 +2491,11 @@ function formBuilder(options = {}) {
|
|
|
2376
2491
|
const resolvedConfig = resolveConfig(options);
|
|
2377
2492
|
const formsCol = formsCollection(resolvedConfig);
|
|
2378
2493
|
const submissionsCol = submissionsCollection(resolvedConfig);
|
|
2494
|
+
let installedSubmissionsSlug = resolvedConfig.formSubmissionOverrides.slug;
|
|
2495
|
+
const newSubmissions = newSubmissionsWidget({
|
|
2496
|
+
forms: resolvedConfig.formOverrides.slug,
|
|
2497
|
+
submissions: resolvedConfig.formSubmissionOverrides.slug
|
|
2498
|
+
}, () => installedSubmissionsSlug);
|
|
2379
2499
|
return {
|
|
2380
2500
|
plugin: definePlugin({
|
|
2381
2501
|
name: "@nextlyhq/plugin-form-builder",
|
|
@@ -2393,6 +2513,11 @@ function formBuilder(options = {}) {
|
|
|
2393
2513
|
],
|
|
2394
2514
|
contributes: {
|
|
2395
2515
|
collections: [formsCol, submissionsCol],
|
|
2516
|
+
dashboard: { widgets: [newSubmissions] },
|
|
2517
|
+
publicGrants: [{
|
|
2518
|
+
collection: resolvedConfig.formSubmissionOverrides.slug,
|
|
2519
|
+
action: "create"
|
|
2520
|
+
}],
|
|
2396
2521
|
permissions: [{
|
|
2397
2522
|
action: "export",
|
|
2398
2523
|
resource: "submissions",
|
|
@@ -2503,6 +2628,7 @@ function formBuilder(options = {}) {
|
|
|
2503
2628
|
async init(nextly) {
|
|
2504
2629
|
const declaredSubmissionsSlug = resolvedConfig.formSubmissionOverrides.slug;
|
|
2505
2630
|
const submissionSlug = nextly.self.collections[declaredSubmissionsSlug] ?? declaredSubmissionsSlug;
|
|
2631
|
+
installedSubmissionsSlug = submissionSlug;
|
|
2506
2632
|
nextly.logger.info("Form Builder plugin initialized", {
|
|
2507
2633
|
formsCollection: resolvedConfig.formOverrides.slug,
|
|
2508
2634
|
submissionsCollection: submissionSlug,
|
|
@@ -2797,7 +2923,8 @@ async function prepareSubmissionForWrite(context, formsSlug, nextly) {
|
|
|
2797
2923
|
})) });
|
|
2798
2924
|
ctx.data = {
|
|
2799
2925
|
...submission,
|
|
2800
|
-
data: prepared.data
|
|
2926
|
+
data: prepared.data,
|
|
2927
|
+
...startingStatus(ctx, marks)
|
|
2801
2928
|
};
|
|
2802
2929
|
if (spam) {
|
|
2803
2930
|
ctx.data.status = "spam";
|
|
@@ -2807,6 +2934,21 @@ async function prepareSubmissionForWrite(context, formsSlug, nextly) {
|
|
|
2807
2934
|
return ctx.data;
|
|
2808
2935
|
}
|
|
2809
2936
|
/**
|
|
2937
|
+
* The status a submission a request created starts with: `new`, whatever the
|
|
2938
|
+
* request named, before the spam verdict may make it `spam`. The collection
|
|
2939
|
+
* grants public create and nothing restricts `status`, so a visitor posting
|
|
2940
|
+
* `read` or `archived` would otherwise file their submission where nobody
|
|
2941
|
+
* looks for one that was never opened.
|
|
2942
|
+
*
|
|
2943
|
+
* A create no request produced (an import, a seed, a job) keeps the status it
|
|
2944
|
+
* names, and so does this plugin's own handler storing content spam as
|
|
2945
|
+
* evidence (`keepAsEvidence`), which chose that status itself. An update is
|
|
2946
|
+
* left as it is.
|
|
2947
|
+
*/
|
|
2948
|
+
function startingStatus(ctx, marks) {
|
|
2949
|
+
return ctx.operation === "create" && ctx.req?.http && marks?.keepAsEvidence !== true ? { status: "new" } : {};
|
|
2950
|
+
}
|
|
2951
|
+
/**
|
|
2810
2952
|
* The fields a submission has to satisfy.
|
|
2811
2953
|
*
|
|
2812
2954
|
* The handler that already read this form hands it over rather than have the
|
|
@@ -3002,7 +3144,7 @@ async function sendNotificationEmails(input) {
|
|
|
3002
3144
|
*/
|
|
3003
3145
|
async function injectSubmissionCount(context, submissionSlug, nextly) {
|
|
3004
3146
|
const hook = context;
|
|
3005
|
-
if (hook.context?.[
|
|
3147
|
+
if (hook.context?.["formBuilder.schemaOnlyRead"] === true) return;
|
|
3006
3148
|
const records = Array.isArray(hook.data) ? hook.data : hook.data ? [hook.data] : [];
|
|
3007
3149
|
await Promise.all(records.map(async (record) => {
|
|
3008
3150
|
const form = record;
|
|
@@ -3017,16 +3159,11 @@ async function injectSubmissionCount(context, submissionSlug, nextly) {
|
|
|
3017
3159
|
}
|
|
3018
3160
|
}));
|
|
3019
3161
|
}
|
|
3020
|
-
/**
|
|
3021
|
-
* Tells the form's `afterRead` hook that this read wants the schema and nothing
|
|
3022
|
-
* else, so it can skip work whose only purpose is to be displayed.
|
|
3023
|
-
*/
|
|
3024
|
-
const SCHEMA_ONLY_READ = "formBuilder.schemaOnlyRead";
|
|
3025
3162
|
async function fetchParentForm(formsSlug, formId, nextly) {
|
|
3026
3163
|
try {
|
|
3027
3164
|
return await nextly.services.collections.findEntryById(formsSlug, formId, {
|
|
3028
3165
|
as: "system",
|
|
3029
|
-
context: {
|
|
3166
|
+
context: { ...SCHEMA_ONLY_CONTEXT }
|
|
3030
3167
|
});
|
|
3031
3168
|
} catch (err) {
|
|
3032
3169
|
if (!NextlyError.isNotFound(err)) throw err;
|
|
@@ -3953,5 +4090,5 @@ const hidden = (config) => ({
|
|
|
3953
4090
|
*/
|
|
3954
4091
|
const formBuilderPlugin = formBuilder().plugin;
|
|
3955
4092
|
|
|
3956
|
-
export { BUILT_IN_FORM_FIELD_TYPES, DEFAULT_FORM_SETTINGS, DEFAULT_NOTIFICATION_SETTINGS, RESERVED_FORM_SLUGS, applyFieldDefaults, applyFormDefaults, assertValidFormConfig, checkSpam, checkbox, createFormConfig, date, downloadFile, email, evaluateConditions, exportAndDownload, exportToCSV, exportToJSON, file, formBuilder, formBuilderPlugin, formatExportValue, formsCollection, generateExportFilename, generateZodSchema, getFormBuilderConfig, getFormSubmissionStats, getSupportedComparisonOperators, getValidationErrors, hidden, isCheckboxFormField, isEmailFormField, isFileFormField, isFormAcceptingSubmissions, isFormField, isFormFieldType, isKnownFormField, isSelectFormField, isTextFormField, isValidComparisonOperator, number, option, phone, pluralize, radio, select, submissionsCollection, submitForm, text, textarea, time, toTitleCase, transformFormData, url, validateFormConfig, validateFormData, validateSubmission };
|
|
4093
|
+
export { BUILT_IN_FORM_FIELD_TYPES, DEFAULT_FORM_SETTINGS, DEFAULT_NOTIFICATION_SETTINGS, NEW_SUBMISSIONS_WIDGET_ID, RESERVED_FORM_SLUGS, applyFieldDefaults, applyFormDefaults, assertValidFormConfig, checkSpam, checkbox, createFormConfig, date, downloadFile, email, evaluateConditions, exportAndDownload, exportToCSV, exportToJSON, file, formBuilder, formBuilderPlugin, formatExportValue, formsCollection, generateExportFilename, generateZodSchema, getFormBuilderConfig, getFormSubmissionStats, getSupportedComparisonOperators, getValidationErrors, hidden, isCheckboxFormField, isEmailFormField, isFileFormField, isFormAcceptingSubmissions, isFormField, isFormFieldType, isKnownFormField, isSelectFormField, isTextFormField, isValidComparisonOperator, number, option, phone, pluralize, radio, select, submissionsCollection, submitForm, text, textarea, time, toTitleCase, transformFormData, url, validateFormConfig, validateFormData, validateSubmission };
|
|
3957
4094
|
//# sourceMappingURL=index.js.map
|