@nextlyhq/plugin-form-builder 0.0.2-alpha.75 → 0.0.2-alpha.76

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,6 +1,37 @@
1
1
  import "@nextlyhq/plugin-sdk";
2
2
  import { CollectionConfig, FieldDefinition, RequestContext } from "nextly";
3
3
  import { ComponentType } from "react";
4
+ /** The widget's id, the one core's default names. */
5
+ declare const NEW_SUBMISSIONS_WIDGET_ID = "form-builder/new-submissions";
6
+ /** One new submission, as the card draws it. */
7
+ interface NewSubmissionRow {
8
+ id: string;
9
+ /** The submitter's name or email, or "Submission" where the form has neither answered. */
10
+ title: string;
11
+ /** The form's name, where the reader may read it. */
12
+ form?: string;
13
+ /** The first line of the first text answer not already the title. */
14
+ excerpt?: string;
15
+ /** When it was submitted, as an ISO string. */
16
+ at?: string;
17
+ /** The submission, in the admin. */
18
+ href: string;
19
+ }
20
+ /** The card's data: its "Number of entries" of rows, how many new submissions there are, and their list. */
21
+ interface NewSubmissionsData {
22
+ items: NewSubmissionRow[];
23
+ /** How many new submissions the reader may read, in all. */
24
+ total: number;
25
+ /** `total` is a floor: there are at least this many. */
26
+ atLeast?: true;
27
+ /** Every submission, in the admin. */
28
+ allHref: string;
29
+ /**
30
+ * The submissions collection's slug as the site installed it, the one a
31
+ * row is marked read in when it is opened.
32
+ */
33
+ collection: string;
34
+ }
4
35
  /**
5
36
  * Reading the document a form's redirect setting points at.
6
37
  *
@@ -53,8 +84,11 @@ interface EmailConfig {
53
84
  * the `form-builder.beforeEmail` D63 filter seam.
54
85
  */
55
86
  interface FormEmailNotification {
56
- /** Resolved recipient address. */
57
- to: string;
87
+ /**
88
+ * Resolved recipient address, or the addresses of a team notification
89
+ * that has several. A notification with one recipient keeps a string.
90
+ */
91
+ to: string | string[];
58
92
  /** Email template slug to render. */
59
93
  templateSlug: string;
60
94
  /** Template variables (submitted data + form metadata). */
@@ -74,6 +108,14 @@ interface FormEmailNotification {
74
108
  bcc?: string[];
75
109
  /** Source notification id; undefined for filter-injected emails. */
76
110
  notificationId?: string;
111
+ /**
112
+ * The files that go with this email, by media id: the notification's own
113
+ * choice of file fields. Absent on a filter-injected email, which takes the
114
+ * files of the fields marked to attach to notification emails.
115
+ */
116
+ attachments?: Array<{
117
+ mediaId: string;
118
+ }>;
77
119
  }
78
120
  /**
79
121
  * A single email notification rule stored on a form.
@@ -96,10 +138,25 @@ interface FormNotification {
96
138
  * the template/provider default.
97
139
  */
98
140
  senderEmail?: string;
141
+ /**
142
+ * Which preset the notification started from: one to the team, or a
143
+ * confirmation to the person who submitted. Absent on rules saved before
144
+ * presets, which read by their recipient.
145
+ */
146
+ kind?: "team" | "visitor";
99
147
  /** How the recipient address is determined */
100
148
  recipientType: "static" | "field";
101
- /** Recipient: static email address or a {{fieldName}} reference */
149
+ /**
150
+ * Recipient: static email address or a {{fieldName}} reference. A team
151
+ * notification with several addresses keeps them in `recipients`; this
152
+ * then holds the first, for readers that know only one.
153
+ */
102
154
  to: string;
155
+ /**
156
+ * A team notification's addresses. Absent on rules saved before several
157
+ * were allowed, whose single `to` reads as a list of one.
158
+ */
159
+ recipients?: string[];
103
160
  /** CC email addresses */
104
161
  cc: string[];
105
162
  /** BCC email addresses */
@@ -116,6 +173,20 @@ interface FormNotification {
116
173
  * multi-condition tree without a migration.
117
174
  */
118
175
  condition?: ConditionalLogicCondition;
176
+ /**
177
+ * Several send conditions: all must hold, or any one. Takes the place of
178
+ * `condition`, which reads as a list of one under `all` when this is absent.
179
+ */
180
+ conditions?: {
181
+ match: "all" | "any";
182
+ list: ConditionalLogicCondition[];
183
+ };
184
+ /**
185
+ * The names of the form's file fields whose files go with this email.
186
+ * Absent on rules saved before it, which attach exactly the file fields
187
+ * marked to attach to notification emails.
188
+ */
189
+ attachFields?: string[];
119
190
  /** Slug of the email template to use */
120
191
  templateSlug?: string;
121
192
  }
@@ -168,6 +239,12 @@ interface SubmissionDocument {
168
239
  userAgent?: string;
169
240
  /** Which spam check flagged this, when one did. */
170
241
  spamReason?: string | null;
242
+ /**
243
+ * What it was asked, as the write seam stored it (`utils/asked-fields`):
244
+ * its fields' labels and option labels at the time. Absent on a
245
+ * submission stored before submissions kept it.
246
+ */
247
+ asked?: unknown;
171
248
  submittedAt: Date;
172
249
  createdAt: Date;
173
250
  updatedAt: Date;
@@ -197,6 +274,7 @@ interface FormFieldToggles {
197
274
  date: boolean | Partial<FieldBlockConfig>;
198
275
  time: boolean | Partial<FieldBlockConfig>;
199
276
  hidden: boolean | Partial<FieldBlockConfig>;
277
+ consent: boolean | Partial<FieldBlockConfig>;
200
278
  }
201
279
  /** What a host may override on a collection this plugin contributes. */
202
280
  type CollectionOverrides = Partial<CollectionConfig> & {
@@ -554,7 +632,7 @@ interface FormConfig {
554
632
  * Form field type (discriminated union).
555
633
  * Uses the `type` property as the discriminant.
556
634
  */
557
- type FormField = TextFormField | EmailFormField | NumberFormField | PhoneFormField | UrlFormField | TextareaFormField | SelectFormField | CheckboxFormField | RadioFormField | FileFormField | DateFormField | TimeFormField | HiddenFormField;
635
+ type FormField = TextFormField | EmailFormField | NumberFormField | PhoneFormField | UrlFormField | TextareaFormField | SelectFormField | CheckboxFormField | RadioFormField | FileFormField | DateFormField | TimeFormField | HiddenFormField | ConsentFormField;
558
636
  /**
559
637
  * A form field of a built-in type OR a plugin-contributed type. Stored form
560
638
  * data and the builder work with this; `isKnownFormField` narrows it back to
@@ -565,7 +643,7 @@ type AnyFormField = FormField | CustomFormField;
565
643
  /**
566
644
  * All available built-in form field type identifiers.
567
645
  */
568
- type FormFieldType = "text" | "email" | "number" | "phone" | "url" | "textarea" | "select" | "checkbox" | "radio" | "file" | "date" | "time" | "hidden";
646
+ type FormFieldType = "text" | "email" | "number" | "phone" | "url" | "textarea" | "select" | "checkbox" | "radio" | "file" | "date" | "time" | "hidden" | "consent";
569
647
  /**
570
648
  * A form field's type on the wire: a built-in or a plugin-contributed type id
571
649
  * that opted into the forms surface. The `(string & {})` arm admits the plugin
@@ -756,6 +834,25 @@ interface HiddenFormField extends Omit<BaseFormField, "type"> {
756
834
  type: "hidden";
757
835
  defaultValue?: string;
758
836
  }
837
+ /**
838
+ * A box the visitor ticks to agree to a text, such as a privacy policy. It is
839
+ * always required, and its answer keeps the text the visitor was shown, so a
840
+ * later change to the text does not change what an earlier visitor agreed to.
841
+ */
842
+ interface ConsentFormField extends Omit<BaseFormField, "type"> {
843
+ type: "consent";
844
+ /** What the visitor agrees to, shown beside the box and stored with it. */
845
+ agreementText: string;
846
+ }
847
+ /**
848
+ * A consent field's stored answer: whether the visitor agreed, and the text
849
+ * the form showed them. Made by the server from the form, never taken from
850
+ * the visitor, and never changed by an edit of the submission.
851
+ */
852
+ interface ConsentAnswer {
853
+ agreed: boolean;
854
+ text: string;
855
+ }
759
856
  interface ValidationRules {
760
857
  /** Custom error message */
761
858
  errorMessage?: string;
@@ -997,9 +1094,10 @@ interface ResolvedFormBuilderConfig {
997
1094
  /**
998
1095
  * Whether each redirect target collection is localized, keyed by slug.
999
1096
  *
1000
- * Resolved at `init` from the collection's own registered metadata rather
1001
- * than asked for in options, because the collection already declares it and
1002
- * a second declaration drifts.
1097
+ * Resolved at `init` from the collection's own declaration rather than
1098
+ * asked for in options, because the collection already declares it and a
1099
+ * second declaration drifts: the configuration's for a collection code
1100
+ * declares, the registry row's for one made in the Schema Builder.
1003
1101
  *
1004
1102
  * It decides whether a target's main-row `status` answers for the document:
1005
1103
  * a localized collection publishes on a locale companion, so the row reads
@@ -1074,36 +1172,5 @@ declare function isCheckboxFormField(field: FormField): field is CheckboxFormFie
1074
1172
  * Type guard for file field.
1075
1173
  */
1076
1174
  declare function isFileFormField(field: FormField): field is FileFormField;
1077
- /** The widget's id, the one core's default names. */
1078
- declare const NEW_SUBMISSIONS_WIDGET_ID = "form-builder/new-submissions";
1079
- /** One new submission, as the card draws it. */
1080
- interface NewSubmissionRow {
1081
- id: string;
1082
- /** The submitter's name or email, or "Submission" where the form has neither answered. */
1083
- title: string;
1084
- /** The form's name, where the reader may read it. */
1085
- form?: string;
1086
- /** The first line of the first text answer not already the title. */
1087
- excerpt?: string;
1088
- /** When it was submitted, as an ISO string. */
1089
- at?: string;
1090
- /** The submission, in the admin. */
1091
- href: string;
1092
- }
1093
- /** The card's data: its "Number of entries" of rows, how many new submissions there are, and their list. */
1094
- interface NewSubmissionsData {
1095
- items: NewSubmissionRow[];
1096
- /** How many new submissions the reader may read, in all. */
1097
- total: number;
1098
- /** `total` is a floor: there are at least this many. */
1099
- atLeast?: true;
1100
- /** Every submission, in the admin. */
1101
- allHref: string;
1102
- /**
1103
- * The submissions collection's slug as the site installed it, the one a
1104
- * row is marked read in when it is opened.
1105
- */
1106
- collection: string;
1107
- }
1108
- export { HiddenFormField as A, UrlFormField as B, FormHookContext as C, FormNotifications as D, FormNotificationItem as E, SelectFormField as F, isFormField as G, isCheckboxFormField as H, SubmissionDocument as I, isSelectFormField as J, isFormFieldType as K, TextFormField as L, PhoneFormField as M, RadioFormField as N, FormSettings as O, ResolvedFormBuilderConfig as P, TextareaFormField as R, FormFieldTypeId as S, FormNotification as T, isEmailFormField as U, ValidationRules as V, isFileFormField as W, isTextFormField as Y, FormBuilderPluginOptions as _, BUILT_IN_FORM_FIELD_TYPES as a, FormField as b, ConditionalLogic as c, DateFormField as d, EmailConfig as f, FormAccess as g, FileFormField as h, AnyFormField as i, NumberFormField as j, FormSubmission as k, ConditionalLogicCondition as l, FieldBlockConfig as m, NewSubmissionRow as n, BaseFormField as o, EmailFormField as p, isKnownFormField as q, NewSubmissionsData as r, CheckboxFormField as s, NEW_SUBMISSIONS_WIDGET_ID as t, CustomFormField as u, FormConfig as v, FormHooks as w, FormFieldType as x, FormDocument as y, TimeFormField as z };
1109
- //# sourceMappingURL=new-submissions-DGiIhdBF.d.ts.map
1175
+ export { NumberFormField as A, ValidationRules as B, FormHooks as C, FormSettings as D, FormNotifications as E, SubmissionDocument as F, isFormFieldType as G, isEmailFormField as H, TextFormField as I, isTextFormField as J, isKnownFormField as K, TextareaFormField as L, RadioFormField as M, ResolvedFormBuilderConfig as N, FormSubmission as O, SelectFormField as P, TimeFormField as R, FormHookContext as S, FormNotificationItem as T, isFileFormField as U, isCheckboxFormField as V, isFormField as W, NewSubmissionRow as X, NEW_SUBMISSIONS_WIDGET_ID as Y, NewSubmissionsData as Z, FormConfig as _, ConditionalLogic as a, FormFieldType as b, ConsentFormField as c, EmailConfig as d, EmailFormField as f, FormBuilderPluginOptions as g, FormAccess as h, CheckboxFormField as i, PhoneFormField as j, HiddenFormField as k, CustomFormField as l, FileFormField as m, BUILT_IN_FORM_FIELD_TYPES as n, ConditionalLogicCondition as o, FieldBlockConfig as p, isSelectFormField as q, BaseFormField as r, ConsentAnswer as s, AnyFormField as t, DateFormField as u, FormDocument as v, FormNotification as w, FormFieldTypeId as x, FormField as y, UrlFormField as z };
1176
+ //# sourceMappingURL=types-XdBrUfi1.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextlyhq/plugin-form-builder",
3
- "version": "0.0.2-alpha.75",
3
+ "version": "0.0.2-alpha.76",
4
4
  "description": "Visual form builder plugin for Nextly with Code-First and Schema Builder support",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,20 +30,20 @@
30
30
  "zod": "^4.6.7"
31
31
  },
32
32
  "peerDependencies": {
33
- "@nextlyhq/admin": "0.0.2-alpha.75",
34
- "@nextlyhq/plugin-sdk": "0.0.2-alpha.75",
35
- "@nextlyhq/ui": "^0.0.2-alpha.75",
33
+ "@nextlyhq/admin": "0.0.2-alpha.76",
34
+ "@nextlyhq/plugin-sdk": "0.0.2-alpha.76",
35
+ "@nextlyhq/ui": "^0.0.2-alpha.76",
36
36
  "@tanstack/react-query": ">=5.0.0",
37
37
  "lucide-react": ">=0.400.0",
38
38
  "next": "^16.4.1",
39
- "nextly": "0.0.2-alpha.75",
39
+ "nextly": "0.0.2-alpha.76",
40
40
  "react": "^19.3.0"
41
41
  },
42
42
  "devDependencies": {
43
- "@nextlyhq/admin": "0.0.2-alpha.75",
44
- "@nextlyhq/plugin-sdk": "0.0.2-alpha.75",
45
- "@nextlyhq/tsconfig": "0.0.2-alpha.75",
46
- "@nextlyhq/ui": "0.0.2-alpha.75",
43
+ "@nextlyhq/admin": "0.0.2-alpha.76",
44
+ "@nextlyhq/plugin-sdk": "0.0.2-alpha.76",
45
+ "@nextlyhq/tsconfig": "0.0.2-alpha.76",
46
+ "@nextlyhq/ui": "0.0.2-alpha.76",
47
47
  "@tanstack/react-query": "^5.62.0",
48
48
  "@testing-library/jest-dom": "^6.9.1",
49
49
  "@testing-library/react": "^16.3.0",
@@ -52,7 +52,7 @@
52
52
  "@types/react": "19.3.0",
53
53
  "jsdom": "^27.1.0",
54
54
  "lucide-react": "^0.544.0",
55
- "nextly": "0.0.2-alpha.75",
55
+ "nextly": "0.0.2-alpha.76",
56
56
  "react": "19.3.1",
57
57
  "react-dom": "19.3.1",
58
58
  "tsdown": "^0.23.1",