@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.
- package/README.md +220 -0
- package/dist/collections/FormSubmissions/hooks/createCharge.d.ts +3 -0
- package/dist/collections/FormSubmissions/hooks/createCharge.js +58 -0
- package/dist/collections/FormSubmissions/hooks/createCharge.js.map +1 -0
- package/dist/collections/FormSubmissions/hooks/sendEmail.d.ts +3 -0
- package/dist/collections/FormSubmissions/hooks/sendEmail.js +152 -0
- package/dist/collections/FormSubmissions/hooks/sendEmail.js.map +1 -0
- package/dist/collections/FormSubmissions/index.d.ts +3 -0
- package/dist/collections/FormSubmissions/index.js +147 -0
- package/dist/collections/FormSubmissions/index.js.map +1 -0
- package/dist/collections/Forms/DynamicFieldSelector.d.ts +3 -0
- package/dist/collections/Forms/DynamicFieldSelector.js +66 -0
- package/dist/collections/Forms/DynamicFieldSelector.js.map +1 -0
- package/dist/collections/Forms/DynamicPriceSelector.d.ts +3 -0
- package/dist/collections/Forms/DynamicPriceSelector.js +81 -0
- package/dist/collections/Forms/DynamicPriceSelector.js.map +1 -0
- package/dist/collections/Forms/fields.d.ts +6 -0
- package/dist/collections/Forms/fields.js +457 -0
- package/dist/collections/Forms/fields.js.map +1 -0
- package/dist/collections/Forms/index.d.ts +3 -0
- package/dist/collections/Forms/index.js +212 -0
- package/dist/collections/Forms/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/mocks/serverModule.d.ts +2 -0
- package/dist/mocks/serverModule.js +4 -0
- package/dist/mocks/serverModule.js.map +1 -0
- package/dist/types.d.ts +160 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/utilities/getPaymentTotal.d.ts +4 -0
- package/dist/utilities/getPaymentTotal.js +44 -0
- package/dist/utilities/getPaymentTotal.js.map +1 -0
- package/dist/utilities/replaceDoubleCurlys.d.ts +7 -0
- package/dist/utilities/replaceDoubleCurlys.js +20 -0
- package/dist/utilities/replaceDoubleCurlys.js.map +1 -0
- package/dist/utilities/serializeRichText.d.ts +10 -0
- package/dist/utilities/serializeRichText.js +49 -0
- package/dist/utilities/serializeRichText.js.map +1 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Payload Form Builder Plugin
|
|
2
|
+
|
|
3
|
+
[](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
|
+

|
|
216
|
+

|
|
217
|
+

|
|
218
|
+

|
|
219
|
+

|
|
220
|
+

|
|
@@ -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,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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0EAAiE;AAEjE,8EAA6E;AAE7E,IAAM,SAAS,GAAG,UAAO,gBAAqB,EAAE,UAAsB;;;;;gBAElE,SAAS,GAEP,gBAAgB,UAFT,EACT,IAAI,GACF,gBAAgB,KADd,CACe;qBAEjB,CAAA,SAAS,KAAK,QAAQ,CAAA,EAAtB,yBAAsB;gBAGhB,gBAAgB,GAKpB,gBAAgB,QALI,EAGpB,YAEA,gBAAgB,YAFT,CAEU;gBAEf,KAGF,IAAI,IAAI,EAAE,EAFN,MAAM,UAAA,EACZ,oCAAc,CACD;gBAET,KAGF,UAAU,IAAI,EAAE,EAFlB,WAAW,iBAAA,EACX,aAAa,mBAAA,CACM;;;;gBAGN,qBAAM,SAAO,CAAC,QAAQ,CAAC;wBAClC,EAAE,EAAE,MAAM;wBACV,UAAU,EAAE,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,IAAI,KAAI,OAAO;qBAC3C,CAAC,EAAA;;gBAHI,IAAI,GAAG,SAGX;qBAEE,IAAI,EAAJ,wBAAI;gBAEJ,MAAM,GACJ,IAAI,OADA,CACC;qBAEL,MAAM,EAAN,wBAAM;gBACF,eAAe,GAAqB,MAAM,CAAC,GAAG,CAAC,UAAC,KAAY;oBAE9D,IAAA,OAAO,GAKL,KAAK,QALA,EACP,OAAO,GAIL,KAAK,QAJA,EACP,OAAO,GAGL,KAAK,QAHA,EACP,SAAS,GAEP,KAAK,UAFE,EACA,YAAY,GACnB,KAAK,QADc,CACb;oBAEV,IAAM,EAAE,GAAG,IAAA,yCAAmB,EAAC,OAAO,EAAE,gBAAc,CAAC,CAAC;oBACxD,IAAM,IAAI,GAAG,IAAA,yCAAmB,EAAC,SAAS,EAAE,gBAAc,CAAC,CAAC;oBAC5D,IAAM,OAAO,GAAG,IAAA,yCAAmB,EAAC,YAAY,IAAI,SAAS,EAAE,gBAAc,CAAC,CAAC;oBAE/E,IAAI,EAAE,IAAI,IAAI,EAAE;wBACd,OAAO,CAAC;4BACN,EAAE,IAAA;4BACF,IAAI,MAAA;4BACJ,OAAO,SAAA;4BACP,OAAO,EAAE,IAAA,yCAAmB,EAAC,OAAO,EAAE,gBAAc,CAAC;4BACrD,IAAI,EAAE,eAAQ,IAAA,6BAAS,EAAC,OAAO,EAAE,gBAAc,CAAC,CAAE;yBACnD,CAAC,CAAC;qBACJ;oBACD,OAAO,IAAI,CAAA;gBACb,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAEf,YAAY,GAAG,eAAe,CAAA;qBAE9B,CAAA,OAAO,WAAW,KAAK,UAAU,CAAA,EAAjC,wBAAiC;gBACpB,qBAAM,WAAW,CAAC,eAAe,CAAC,EAAA;;gBAAjD,YAAY,GAAG,SAAkC,CAAC;;;gBAG9C,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,UAAC,EAAiB;oBAAf,IAAA,IAAI,UAAA,EAAK,IAAI,cAAf,QAAiB,CAAF;oBAAO,OAAA,cAAM,IAAI,EAAG,CAAA;iBAAA,CAAC,CAAA;gBAElE,qBAAM,OAAO,CAAC,GAAG,CACf,YAAY,CAAC,GAAG,CAAC,UAAO,KAAK;;;;;oCACnB,EAAE,GAAK,KAAK,GAAV,CAAW;;;;oCAEE,qBAAM,SAAO,CAAC,SAAS,CAAC,KAAK,CAAC,EAAA;;oCAA7C,YAAY,GAAG,SAA8B;oCACnD,sBAAO,YAAY,EAAC;;;oCAEpB,OAAO,CAAC,KAAK,CAAC,gDAAyC,EAAE,sBAAmB,CAAC,CAAC;oCAC9E,OAAO,CAAC,KAAK,CAAC,KAAG,CAAC,CAAC;;;;;yBAEtB,CAAC,CACH,EAAA;;gBAXD,SAWC,CAAC;;;;gBAGJ,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;;;;;gBAGnC,OAAO,CAAC,KAAK,CAAC,wEAAiE,gBAAgB,MAAG,CAAC,CAAC;gBACpG,OAAO,CAAC,KAAK,CAAC,KAAG,CAAC,CAAC;;qBAIvB,sBAAO,IAAI,EAAC;;;KACb,CAAC;AAEF,kBAAe,SAAS,CAAC"}
|
|
@@ -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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"}
|