@payloadcms/plugin-form-builder 1.0.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.
Files changed (41) hide show
  1. package/README.md +220 -0
  2. package/dist/collections/FormSubmissions/hooks/createCharge.d.ts +3 -0
  3. package/dist/collections/FormSubmissions/hooks/createCharge.js +58 -0
  4. package/dist/collections/FormSubmissions/hooks/createCharge.js.map +1 -0
  5. package/dist/collections/FormSubmissions/hooks/sendEmail.d.ts +3 -0
  6. package/dist/collections/FormSubmissions/hooks/sendEmail.js +152 -0
  7. package/dist/collections/FormSubmissions/hooks/sendEmail.js.map +1 -0
  8. package/dist/collections/FormSubmissions/index.d.ts +3 -0
  9. package/dist/collections/FormSubmissions/index.js +147 -0
  10. package/dist/collections/FormSubmissions/index.js.map +1 -0
  11. package/dist/collections/Forms/DynamicFieldSelector.d.ts +3 -0
  12. package/dist/collections/Forms/DynamicFieldSelector.js +66 -0
  13. package/dist/collections/Forms/DynamicFieldSelector.js.map +1 -0
  14. package/dist/collections/Forms/DynamicPriceSelector.d.ts +3 -0
  15. package/dist/collections/Forms/DynamicPriceSelector.js +81 -0
  16. package/dist/collections/Forms/DynamicPriceSelector.js.map +1 -0
  17. package/dist/collections/Forms/fields.d.ts +6 -0
  18. package/dist/collections/Forms/fields.js +457 -0
  19. package/dist/collections/Forms/fields.js.map +1 -0
  20. package/dist/collections/Forms/index.d.ts +3 -0
  21. package/dist/collections/Forms/index.js +212 -0
  22. package/dist/collections/Forms/index.js.map +1 -0
  23. package/dist/index.d.ts +5 -0
  24. package/dist/index.js +52 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/mocks/serverModule.d.ts +2 -0
  27. package/dist/mocks/serverModule.js +4 -0
  28. package/dist/mocks/serverModule.js.map +1 -0
  29. package/dist/types.d.ts +160 -0
  30. package/dist/types.js +11 -0
  31. package/dist/types.js.map +1 -0
  32. package/dist/utilities/getPaymentTotal.d.ts +4 -0
  33. package/dist/utilities/getPaymentTotal.js +44 -0
  34. package/dist/utilities/getPaymentTotal.js.map +1 -0
  35. package/dist/utilities/replaceDoubleCurlys.d.ts +7 -0
  36. package/dist/utilities/replaceDoubleCurlys.js +20 -0
  37. package/dist/utilities/replaceDoubleCurlys.js.map +1 -0
  38. package/dist/utilities/serializeRichText.d.ts +10 -0
  39. package/dist/utilities/serializeRichText.js +49 -0
  40. package/dist/utilities/serializeRichText.js.map +1 -0
  41. package/package.json +40 -0
package/README.md ADDED
@@ -0,0 +1,220 @@
1
+ # Payload Form Builder Plugin
2
+
3
+ [![NPM](https://img.shields.io/npm/v/@payloadcms/plugin-form-builder)](https://www.npmjs.com/package/@payloadcms/plugin-form-builder)
4
+
5
+ A plugin for [Payload CMS](https://github.com/payloadcms/payload) to easily allow your admin editors to build and manage forms from the admin panel.
6
+
7
+ Core features:
8
+ - Creates a `forms` collection where you can:
9
+ - Build dynamic forms with any number of fields
10
+ - Add payment fields that can handle dynamic prices
11
+ - Build completely custom and dynamic emails
12
+ - Creates a `formSubmissions` collection that:
13
+ - Validates and saves the form data submitted by your frontend
14
+ - Sends emails (if applicable)
15
+ - Handles payment processing (if applicable)
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ yarn add @payloadcms/plugin-form-builder
21
+ # OR
22
+ npm i @payloadcms/plugin-form-builder
23
+ ```
24
+
25
+ ## Basic Usage
26
+
27
+ In the `plugins` array of your [Payload config](https://payloadcms.com/docs/configuration/overview), call the plugin with [options](#options):
28
+
29
+ ```js
30
+ import { buildConfig } from 'payload/config';
31
+ import formBuilder from '@payloadcms/plugin-form-builder';
32
+
33
+ const config = buildConfig({
34
+ collections: [
35
+ {
36
+ slug: 'pages',
37
+ fields: []
38
+ }
39
+ ],
40
+ plugins: [
41
+ formBuilder()
42
+ ]
43
+ });
44
+
45
+ export default config;
46
+ ```
47
+
48
+ ### Options
49
+
50
+ - `fields`
51
+ An object of field types to allow your admin editors to build forms with. Pass either a boolean value or a partial [Payload Block](https://payloadcms.com/docs/fields/blocks#block-configs) to override default settings. See [Fields](#fields) for more details.
52
+
53
+ ```
54
+ fields: {
55
+ text: true,
56
+ select: true,
57
+ email: true,
58
+ state: true,
59
+ country: true,
60
+ checkbox: true,
61
+ number: true,
62
+ message: true,
63
+ payment: false
64
+ }
65
+ ```
66
+
67
+ You can also provide your own custom field definitions by passing a new [Payload Block](https://payloadcms.com/docs/fields/blocks#block-configs) object into `fields`.
68
+
69
+
70
+ - `redirectRelationships`
71
+
72
+ An array of collection slugs that, when enabled, are populated as options in form redirect fields.
73
+
74
+ ```
75
+ redirectRelationships: ['pages']
76
+ ```
77
+
78
+ - `handlePayment`
79
+
80
+ A [beforeChange]([beforeChange](https://payloadcms.com/docs/hooks/globals#beforechange)) hook that is called upon form submissions. You can integrate into any third-party payment processing API here. There is a `getPaymentTotal` function that will calculate the total cost after all conditions have been applied.
81
+
82
+ ```
83
+ import { getPaymentTotal } from '@payloadcms/plugin-form-builder';
84
+ ...
85
+ handlePayment: async ({ form, submissionData }) => {
86
+ // first calculate the price
87
+ const paymentField = form.fields?.find((field) => field.blockType === 'payment');
88
+ const price = getPaymentTotal({
89
+ basePrice: paymentField.basePrice,
90
+ priceConditions: paymentField.priceConditions,
91
+ fieldValues: submissionData,
92
+ });
93
+ // then asynchronously process the payment here
94
+ }
95
+ ```
96
+
97
+ - `beforeEmail`
98
+
99
+ A [beforeChange]([beforeChange](https://payloadcms.com/docs/hooks/globals#beforechange)) hook that is called just after emails are prepared, but before they are sent. This is a great place to inject your own HTML template to add custom styles.
100
+
101
+ ```
102
+ beforeEmails: (emailsToSend) => {
103
+ // modify the emails in any way before they are sent
104
+ return emails.map((email) => ({
105
+ ...email,
106
+ html: email.html // transform the html in any way you'd like (maybe wrap it in an html template?)
107
+ }))
108
+ };
109
+ ```
110
+
111
+ - `formOverrides`
112
+
113
+ Override anything on the form collection by sending a [Payload Collection Config](https://payloadcms.com/docs/configuration/collections). Your overrides will be merged into the default `forms` collection.
114
+
115
+ ```
116
+ formOverrides: {
117
+ slug: 'contact-forms'
118
+ }
119
+ ```
120
+
121
+ - `formSubmissionOverrides`
122
+ By default, this plugin relies on [Payload access control](https://payloadcms.com/docs/access-control/collections) to restrict the `update` and `read` operations. This is because anyone should be able to create a form submission, even from a public-facing website - but no one should be able to update a submission one it has been created, or read a submission unless they have permission.
123
+
124
+ You can override access control and anything else on the form submission collection by sending a [Payload Collection Config](https://payloadcms.com/docs/configuration/collections). Your overrides will be merged into the default `formSubmissions` collection.
125
+
126
+ ```
127
+ formSubmissionOverrides: {
128
+ slug: 'leads'
129
+ }
130
+ ```
131
+
132
+ ## Fields
133
+
134
+ Each form field is defined as a [Payload Block](https://payloadcms.com/docs/fields/blocks) with the following subfields:
135
+
136
+ - Text
137
+ - `name`: string
138
+ - `label`: string
139
+ - `defaultValue`: string
140
+ - `width`: string
141
+ - `required`: checkbox
142
+ - Select
143
+ - `name`: string
144
+ - `label`: string
145
+ - `defaultValue`: string
146
+ - `width`: string
147
+ - `options`: array
148
+ - `required`: checkbox
149
+ - Email
150
+ - `name`: string
151
+ - `label`: string
152
+ - `defaultValue`: string
153
+ - `width`: string
154
+ - `required`: checkbox
155
+ - State
156
+ - `name`: string
157
+ - `label`: string
158
+ - `defaultValue`: string
159
+ - `width`: string
160
+ - `required`: checkbox
161
+ - Country
162
+ - `name`: string
163
+ - `label`: string
164
+ - `defaultValue`: string
165
+ - `width`: string
166
+ - `required`: checkbox
167
+ - Checkbox
168
+ - `name`: string
169
+ - `label`: string
170
+ - `defaultValue`: checkbox
171
+ - `width`: string
172
+ - `required`: checkbox
173
+ - Number
174
+ - `name`: string
175
+ - `label`: string
176
+ - `defaultValue`: number
177
+ - `width`: string
178
+ - `required`: checkbox
179
+ - Message
180
+ - `message`: richText
181
+ - Payment
182
+ - `name`: string
183
+ - `label`: string
184
+ - `defaultValue`: number
185
+ - `width`: string
186
+ - `required`: checkbox
187
+ - `priceConditions`: array
188
+ - `fieldToUse`: relationship, dynamically populated based on the fields in your form
189
+ - `condition`: string - `equals`, `notEquals` | `hasValue`
190
+ - `valueForOperator`: string - only if `condition` is `equals` or `notEquals`
191
+ - `operator`: string - `add`, `subtract`, `multiply`, `divide`
192
+ - `valueType`: string - `static`, `valueOfField`
193
+ - `value`: string - only if `valueType` is `static`
194
+
195
+ ## Email
196
+
197
+ This plugin relies on the [email configuration](https://payloadcms.com/docs/email/overview) defined in your `payload.init()`. It will read from your config and attempt to send your emails using the credentials provided.
198
+
199
+ ## TypeScript
200
+
201
+ All types can be directly imported:
202
+ ```js
203
+ import {
204
+ FormConfig,
205
+ Form,
206
+ FormSubmission,
207
+ FieldsConfig,
208
+ BeforePayment,
209
+ HandlePayment
210
+ } from '@payloadcms/plugin-form-builder/dist/types';
211
+ ```
212
+
213
+ ## Screenshots
214
+
215
+ ![screenshot 1](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-1.jpg?raw=true)
216
+ ![screenshot 2](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-2.jpg?raw=true)
217
+ ![screenshot 3](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-3.jpg?raw=true)
218
+ ![screenshot 4](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-4.jpg?raw=true)
219
+ ![screenshot 5](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-5.jpg?raw=true)
220
+ ![screenshot 6](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-6.jpg?raw=true)
@@ -0,0 +1,3 @@
1
+ import { FormConfig } from "../../../types";
2
+ declare const createCharge: (beforeChangeData: any, formConfig: FormConfig) => Promise<any>;
3
+ export default createCharge;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var createCharge = function (beforeChangeData, formConfig) { return __awaiter(void 0, void 0, void 0, function () {
40
+ var operation, data, dataWithPaymentDetails, handlePayment;
41
+ return __generator(this, function (_a) {
42
+ switch (_a.label) {
43
+ case 0:
44
+ operation = beforeChangeData.operation, data = beforeChangeData.data;
45
+ dataWithPaymentDetails = data;
46
+ if (!(operation === 'create')) return [3 /*break*/, 2];
47
+ handlePayment = (formConfig || {}).handlePayment;
48
+ if (!(typeof handlePayment === 'function')) return [3 /*break*/, 2];
49
+ return [4 /*yield*/, handlePayment(beforeChangeData)];
50
+ case 1:
51
+ dataWithPaymentDetails = _a.sent();
52
+ _a.label = 2;
53
+ case 2: return [2 /*return*/, dataWithPaymentDetails];
54
+ }
55
+ });
56
+ }); };
57
+ exports.default = createCharge;
58
+ //# sourceMappingURL=createCharge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createCharge.js","sourceRoot":"","sources":["../../../../src/collections/FormSubmissions/hooks/createCharge.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,IAAM,YAAY,GAAG,UAAO,gBAAqB,EAAE,UAAsB;;;;;gBAErE,SAAS,GAEP,gBAAgB,UAFT,EACT,IAAI,GACF,gBAAgB,KADd,CACe;gBAEjB,sBAAsB,GAAG,IAAI,CAAC;qBAE9B,CAAA,SAAS,KAAK,QAAQ,CAAA,EAAtB,wBAAsB;gBAEtB,aAAa,GACX,CAAA,UAAU,IAAI,EAAE,CAAA,cADL,CACM;qBAEjB,CAAA,OAAO,aAAa,KAAK,UAAU,CAAA,EAAnC,wBAAmC;gBACZ,qBAAM,aAAa,CAAC,gBAAgB,CAAC,EAAA;;gBAA9D,sBAAsB,GAAG,SAAqC,CAAC;;oBAInE,sBAAO,sBAAsB,EAAC;;;KAC/B,CAAC;AAEF,kBAAe,YAAY,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { FormConfig } from '../../../types';
2
+ declare const sendEmail: (beforeChangeData: any, formConfig: FormConfig) => Promise<any>;
3
+ export default sendEmail;
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (_) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __rest = (this && this.__rest) || function (s, e) {
50
+ var t = {};
51
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
52
+ t[p] = s[p];
53
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
54
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
55
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
56
+ t[p[i]] = s[p[i]];
57
+ }
58
+ return t;
59
+ };
60
+ Object.defineProperty(exports, "__esModule", { value: true });
61
+ var serializeRichText_1 = require("../../../utilities/serializeRichText");
62
+ var replaceDoubleCurlys_1 = require("../../../utilities/replaceDoubleCurlys");
63
+ var sendEmail = function (beforeChangeData, formConfig) { return __awaiter(void 0, void 0, void 0, function () {
64
+ var operation, data, formSubmissionID, payload_1, _a, formID, submissionData_1, _b, beforeEmail, formOverrides, form, emails, formattedEmails, emailsToSend, log, err_1;
65
+ return __generator(this, function (_c) {
66
+ switch (_c.label) {
67
+ case 0:
68
+ operation = beforeChangeData.operation, data = beforeChangeData.data;
69
+ if (!(operation === 'create')) return [3 /*break*/, 10];
70
+ formSubmissionID = beforeChangeData.data.id, payload_1 = beforeChangeData.req.payload;
71
+ _a = data || {}, formID = _a.form, submissionData_1 = _a.submissionData;
72
+ _b = formConfig || {}, beforeEmail = _b.beforeEmail, formOverrides = _b.formOverrides;
73
+ _c.label = 1;
74
+ case 1:
75
+ _c.trys.push([1, 9, , 10]);
76
+ return [4 /*yield*/, payload_1.findByID({
77
+ id: formID,
78
+ collection: (formOverrides === null || formOverrides === void 0 ? void 0 : formOverrides.slug) || 'forms',
79
+ })];
80
+ case 2:
81
+ form = _c.sent();
82
+ if (!form) return [3 /*break*/, 7];
83
+ emails = form.emails;
84
+ if (!emails) return [3 /*break*/, 6];
85
+ formattedEmails = emails.map(function (email) {
86
+ var message = email.message, subject = email.subject, emailTo = email.emailTo, emailFrom = email.emailFrom, emailReplyTo = email.replyTo;
87
+ var to = (0, replaceDoubleCurlys_1.replaceDoubleCurlys)(emailTo, submissionData_1);
88
+ var from = (0, replaceDoubleCurlys_1.replaceDoubleCurlys)(emailFrom, submissionData_1);
89
+ var replyTo = (0, replaceDoubleCurlys_1.replaceDoubleCurlys)(emailReplyTo || emailFrom, submissionData_1);
90
+ if (to && from) {
91
+ return ({
92
+ to: to,
93
+ from: from,
94
+ replyTo: replyTo,
95
+ subject: (0, replaceDoubleCurlys_1.replaceDoubleCurlys)(subject, submissionData_1),
96
+ html: "<div>".concat((0, serializeRichText_1.serialize)(message, submissionData_1))
97
+ });
98
+ }
99
+ return null;
100
+ }).filter(Boolean);
101
+ emailsToSend = formattedEmails;
102
+ if (!(typeof beforeEmail === 'function')) return [3 /*break*/, 4];
103
+ return [4 /*yield*/, beforeEmail(formattedEmails)];
104
+ case 3:
105
+ emailsToSend = _c.sent();
106
+ _c.label = 4;
107
+ case 4:
108
+ log = emailsToSend.map(function (_a) {
109
+ var html = _a.html, rest = __rest(_a, ["html"]);
110
+ return (__assign({}, rest));
111
+ });
112
+ return [4 /*yield*/, Promise.all(emailsToSend.map(function (email) { return __awaiter(void 0, void 0, void 0, function () {
113
+ var to, emailPromise, err_2;
114
+ return __generator(this, function (_a) {
115
+ switch (_a.label) {
116
+ case 0:
117
+ to = email.to;
118
+ _a.label = 1;
119
+ case 1:
120
+ _a.trys.push([1, 3, , 4]);
121
+ return [4 /*yield*/, payload_1.sendEmail(email)];
122
+ case 2:
123
+ emailPromise = _a.sent();
124
+ return [2 /*return*/, emailPromise];
125
+ case 3:
126
+ err_2 = _a.sent();
127
+ console.error("Error while sending email to address: ".concat(to, ". Email not sent."));
128
+ console.error(err_2);
129
+ return [3 /*break*/, 4];
130
+ case 4: return [2 /*return*/];
131
+ }
132
+ });
133
+ }); }))];
134
+ case 5:
135
+ _c.sent();
136
+ _c.label = 6;
137
+ case 6: return [3 /*break*/, 8];
138
+ case 7:
139
+ console.log('No emails to send.');
140
+ _c.label = 8;
141
+ case 8: return [3 /*break*/, 10];
142
+ case 9:
143
+ err_1 = _c.sent();
144
+ console.error("Error while sending one or more emails in form submission id: ".concat(formSubmissionID, "."));
145
+ console.error(err_1);
146
+ return [3 /*break*/, 10];
147
+ case 10: return [2 /*return*/, data];
148
+ }
149
+ });
150
+ }); };
151
+ exports.default = sendEmail;
152
+ //# sourceMappingURL=sendEmail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendEmail.js","sourceRoot":"","sources":["../../../../src/collections/FormSubmissions/hooks/sendEmail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { CollectionConfig } from 'payload/types';
2
+ import { FormConfig } from '../../types';
3
+ export declare const generateSubmissionCollection: (formConfig: FormConfig) => CollectionConfig;
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
14
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
15
+ if (ar || !(i in from)) {
16
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
17
+ ar[i] = from[i];
18
+ }
19
+ }
20
+ return to.concat(ar || Array.prototype.slice.call(from));
21
+ };
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.generateSubmissionCollection = void 0;
27
+ var sendEmail_1 = __importDefault(require("./hooks/sendEmail"));
28
+ var createCharge_1 = __importDefault(require("./hooks/createCharge"));
29
+ // all settings can be overridden by the config
30
+ var generateSubmissionCollection = function (formConfig) {
31
+ var _a, _b, _c, _d, _e, _f, _g;
32
+ var newConfig = {
33
+ slug: ((_a = formConfig === null || formConfig === void 0 ? void 0 : formConfig.formSubmissionOverrides) === null || _a === void 0 ? void 0 : _a.slug) || 'formSubmissions',
34
+ access: __assign({ create: function () { return true; }, update: function () { return false; }, read: function (_a) {
35
+ var user = _a.req.user;
36
+ return !!user;
37
+ } }, ((_b = formConfig === null || formConfig === void 0 ? void 0 : formConfig.formSubmissionOverrides) === null || _b === void 0 ? void 0 : _b.access) || {}),
38
+ admin: {
39
+ enableRichTextRelationship: false
40
+ },
41
+ hooks: __assign({ beforeChange: __spreadArray([
42
+ function (data) { return (0, createCharge_1.default)(data, formConfig); },
43
+ function (data) { return (0, sendEmail_1.default)(data, formConfig); }
44
+ ], ((_d = (_c = formConfig === null || formConfig === void 0 ? void 0 : formConfig.formSubmissionOverrides) === null || _c === void 0 ? void 0 : _c.hooks) === null || _d === void 0 ? void 0 : _d.beforeChange) || [], true) }, ((_e = formConfig === null || formConfig === void 0 ? void 0 : formConfig.formSubmissionOverrides) === null || _e === void 0 ? void 0 : _e.hooks) || {}),
45
+ fields: __spreadArray([
46
+ {
47
+ name: 'form',
48
+ type: 'relationship',
49
+ relationTo: 'forms',
50
+ required: true,
51
+ admin: {
52
+ readOnly: true
53
+ },
54
+ },
55
+ {
56
+ name: 'submissionData',
57
+ type: 'array',
58
+ admin: {
59
+ readOnly: true
60
+ },
61
+ fields: [
62
+ {
63
+ name: 'field',
64
+ type: 'text',
65
+ required: true,
66
+ },
67
+ {
68
+ name: 'value',
69
+ type: 'text',
70
+ required: true,
71
+ validate: function (value) {
72
+ // TODO:
73
+ // create a validation function that dynamically
74
+ // relies on the field type and its options as configured.
75
+ // How to access sibling data from this field?
76
+ // Need the `name` of the field in order to validate it.
77
+ // Might not be possible to use this validation function.
78
+ // Instead, might need to do all validation in a `beforeValidate` collection hook.
79
+ if (typeof value !== 'undefined') {
80
+ return true;
81
+ }
82
+ return 'This field is required.';
83
+ },
84
+ },
85
+ ],
86
+ }
87
+ ], ((_f = formConfig === null || formConfig === void 0 ? void 0 : formConfig.formSubmissionOverrides) === null || _f === void 0 ? void 0 : _f.fields) || [], true),
88
+ };
89
+ var paymentFieldConfig = (_g = formConfig === null || formConfig === void 0 ? void 0 : formConfig.fields) === null || _g === void 0 ? void 0 : _g.payment;
90
+ if (paymentFieldConfig) {
91
+ newConfig.fields.push({
92
+ name: 'payment',
93
+ type: 'group',
94
+ admin: {
95
+ readOnly: true
96
+ },
97
+ fields: [
98
+ {
99
+ name: 'field',
100
+ label: 'Field',
101
+ type: 'text'
102
+ },
103
+ {
104
+ name: 'status',
105
+ label: 'Status',
106
+ type: 'text'
107
+ },
108
+ {
109
+ name: 'amount',
110
+ type: 'number',
111
+ admin: {
112
+ description: 'Amount in cents'
113
+ }
114
+ },
115
+ {
116
+ name: 'paymentProcessor',
117
+ type: 'text',
118
+ },
119
+ {
120
+ name: 'creditCard',
121
+ label: 'Credit Card',
122
+ type: 'group',
123
+ fields: [
124
+ {
125
+ name: 'token',
126
+ label: 'token',
127
+ type: 'text'
128
+ },
129
+ {
130
+ name: 'brand',
131
+ label: 'Brand',
132
+ type: 'text'
133
+ },
134
+ {
135
+ name: 'number',
136
+ label: 'Number',
137
+ type: 'text'
138
+ }
139
+ ]
140
+ }
141
+ ]
142
+ });
143
+ }
144
+ return newConfig;
145
+ };
146
+ exports.generateSubmissionCollection = generateSubmissionCollection;
147
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/collections/FormSubmissions/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { TextField } from 'payload/dist/fields/config/types';
3
+ export declare const DynamicFieldSelector: React.FC<TextField>;