@payloadcms/plugin-form-builder 3.84.0-canary.1 → 3.84.0-canary.2
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/collections/FormSubmissions/hooks/handleUploads.d.ts +17 -0
- package/dist/collections/FormSubmissions/hooks/handleUploads.d.ts.map +1 -0
- package/dist/collections/FormSubmissions/hooks/handleUploads.js +274 -0
- package/dist/collections/FormSubmissions/hooks/handleUploads.js.map +1 -0
- package/dist/collections/FormSubmissions/index.d.ts.map +1 -1
- package/dist/collections/FormSubmissions/index.js +25 -0
- package/dist/collections/FormSubmissions/index.js.map +1 -1
- package/dist/collections/Forms/fields.d.ts +1 -2
- package/dist/collections/Forms/fields.d.ts.map +1 -1
- package/dist/collections/Forms/fields.js +102 -1
- package/dist/collections/Forms/fields.js.map +1 -1
- package/dist/collections/Forms/index.d.ts +2 -2
- package/dist/collections/Forms/index.d.ts.map +1 -1
- package/dist/collections/Forms/index.js +33 -1
- package/dist/collections/Forms/index.js.map +1 -1
- package/dist/exports/types.d.ts +1 -1
- package/dist/exports/types.d.ts.map +1 -1
- package/dist/exports/types.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +44 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CollectionBeforeChangeHook } from 'payload';
|
|
2
|
+
import type { FormBuilderPluginConfig } from '../../../types.js';
|
|
3
|
+
type BeforeChangeParams = Parameters<CollectionBeforeChangeHook>[0];
|
|
4
|
+
/**
|
|
5
|
+
* Handles upload fields in form submissions.
|
|
6
|
+
*
|
|
7
|
+
* This hook:
|
|
8
|
+
* 1. Checks req.files for files matching upload field names (supports multiple files per field)
|
|
9
|
+
* 2. Validates MIME types and file sizes before uploading
|
|
10
|
+
* 3. Creates media documents in the appropriate upload collection
|
|
11
|
+
* 4. Populates submissionUploads with proper Payload upload relationships
|
|
12
|
+
* 5. Strips upload fields from submissionData (they live in submissionUploads only)
|
|
13
|
+
* 6. Validates pre-uploaded file IDs for backwards compatibility
|
|
14
|
+
*/
|
|
15
|
+
export declare const handleUploads: (beforeChangeParams: BeforeChangeParams, formConfig: FormBuilderPluginConfig) => Promise<Partial<any>>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=handleUploads.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handleUploads.d.ts","sourceRoot":"","sources":["../../../../src/collections/FormSubmissions/hooks/handleUploads.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAK3B,MAAM,SAAS,CAAA;AAKhB,OAAO,KAAK,EACV,uBAAuB,EAIxB,MAAM,mBAAmB,CAAA;AAE1B,KAAK,kBAAkB,GAAG,UAAU,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAA;AAOnE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,uBACJ,kBAAkB,cAC1B,uBAAuB,0BAiSpC,CAAA"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { ValidationError } from 'payload';
|
|
2
|
+
import { validateMimeType } from 'payload/shared';
|
|
3
|
+
/**
|
|
4
|
+
* Handles upload fields in form submissions.
|
|
5
|
+
*
|
|
6
|
+
* This hook:
|
|
7
|
+
* 1. Checks req.files for files matching upload field names (supports multiple files per field)
|
|
8
|
+
* 2. Validates MIME types and file sizes before uploading
|
|
9
|
+
* 3. Creates media documents in the appropriate upload collection
|
|
10
|
+
* 4. Populates submissionUploads with proper Payload upload relationships
|
|
11
|
+
* 5. Strips upload fields from submissionData (they live in submissionUploads only)
|
|
12
|
+
* 6. Validates pre-uploaded file IDs for backwards compatibility
|
|
13
|
+
*/ export const handleUploads = async (beforeChangeParams, formConfig)=>{
|
|
14
|
+
const { data, operation, req } = beforeChangeParams;
|
|
15
|
+
const { payload } = req;
|
|
16
|
+
// Only handle on create
|
|
17
|
+
if (operation !== 'create') {
|
|
18
|
+
return data;
|
|
19
|
+
}
|
|
20
|
+
const { form: formID, submissionData } = data || {};
|
|
21
|
+
if (!formID || !submissionData) {
|
|
22
|
+
return data;
|
|
23
|
+
}
|
|
24
|
+
const formSlug = formConfig?.formOverrides?.slug || 'forms';
|
|
25
|
+
// Fetch the form to get field configurations
|
|
26
|
+
let form;
|
|
27
|
+
try {
|
|
28
|
+
form = await payload.findByID({
|
|
29
|
+
id: formID,
|
|
30
|
+
collection: formSlug,
|
|
31
|
+
req
|
|
32
|
+
});
|
|
33
|
+
} catch {
|
|
34
|
+
// If form doesn't exist, let the form relationship validation handle it
|
|
35
|
+
return data;
|
|
36
|
+
}
|
|
37
|
+
const formFields = form?.fields || [];
|
|
38
|
+
const uploadFields = formFields.filter((field)=>field.blockType === 'upload');
|
|
39
|
+
if (uploadFields.length === 0) {
|
|
40
|
+
return data;
|
|
41
|
+
}
|
|
42
|
+
const submissionDataArray = submissionData;
|
|
43
|
+
// Build a map of pre-uploaded file IDs for backwards-compat lookup
|
|
44
|
+
const submissionMap = new Map();
|
|
45
|
+
for(let i = 0; i < submissionDataArray.length; i++){
|
|
46
|
+
const item = submissionDataArray[i];
|
|
47
|
+
if (item) {
|
|
48
|
+
submissionMap.set(item.field, {
|
|
49
|
+
index: i,
|
|
50
|
+
value: item.value
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Get files from request (populated by addDataAndFileToRequest).
|
|
55
|
+
// Multiple files with the same field name are stored as an array by buildFields.
|
|
56
|
+
const requestFiles = req.files || {};
|
|
57
|
+
const errors = [];
|
|
58
|
+
// Accumulate upload items per field — one entry per upload field in the form
|
|
59
|
+
const uploadsByField = new Map();
|
|
60
|
+
// Track docs created during this hook so we can delete them if a later error causes rollback
|
|
61
|
+
const createdDocs = [];
|
|
62
|
+
for (const uploadField of uploadFields){
|
|
63
|
+
const { name, maxFileSize, mimeTypes, multiple, required, uploadCollection } = uploadField;
|
|
64
|
+
const fieldLabel = uploadField.label || name;
|
|
65
|
+
uploadsByField.set(name, []);
|
|
66
|
+
// Validate uploadCollection is configured in this plugin (defence-in-depth against tampered form docs)
|
|
67
|
+
if (!formConfig.uploadCollections?.includes(uploadCollection)) {
|
|
68
|
+
errors.push({
|
|
69
|
+
field: name,
|
|
70
|
+
message: `Upload collection "${uploadCollection}" is not configured in this plugin`
|
|
71
|
+
});
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
// Normalize: multiple files with the same field name arrive as an array
|
|
75
|
+
const rawFile = requestFiles[name];
|
|
76
|
+
const requestFileList = rawFile ? Array.isArray(rawFile) ? rawFile : [
|
|
77
|
+
rawFile
|
|
78
|
+
] : [];
|
|
79
|
+
const existingSubmission = submissionMap.get(name);
|
|
80
|
+
if (requestFileList.length > 0) {
|
|
81
|
+
// Guard: reject multiple files when the field doesn't allow them
|
|
82
|
+
if (!multiple && requestFileList.length > 1) {
|
|
83
|
+
errors.push({
|
|
84
|
+
field: name,
|
|
85
|
+
message: `${fieldLabel} does not allow multiple files`
|
|
86
|
+
});
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
// Direct file upload(s) from request
|
|
90
|
+
for (const requestFile of requestFileList){
|
|
91
|
+
// Validate MIME type before uploading
|
|
92
|
+
if (mimeTypes && mimeTypes.length > 0) {
|
|
93
|
+
const allowedPatterns = mimeTypes.map((m)=>m.mimeType);
|
|
94
|
+
if (!validateMimeType(requestFile.mimetype, allowedPatterns)) {
|
|
95
|
+
errors.push({
|
|
96
|
+
field: name,
|
|
97
|
+
message: `${fieldLabel}: File type "${requestFile.mimetype}" is not allowed. Allowed types: ${allowedPatterns.join(', ')}`
|
|
98
|
+
});
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Validate file size before uploading
|
|
103
|
+
if (maxFileSize && maxFileSize > 0 && requestFile.size > maxFileSize) {
|
|
104
|
+
const maxSizeMB = (maxFileSize / (1024 * 1024)).toFixed(2);
|
|
105
|
+
const fileSizeMB = (requestFile.size / (1024 * 1024)).toFixed(2);
|
|
106
|
+
errors.push({
|
|
107
|
+
field: name,
|
|
108
|
+
message: `${fieldLabel}: File size (${fileSizeMB}MB) exceeds maximum allowed size (${maxSizeMB}MB)`
|
|
109
|
+
});
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
// Create the media document.
|
|
113
|
+
// Note: payload.create writes the file to storage before the DB row exists. If
|
|
114
|
+
// the DB write throws, createdDocs never records the entry and the file on disk
|
|
115
|
+
// will not be cleaned up by the rollback loop below. Payload core owns that
|
|
116
|
+
// rollback path — we only clean up docs we successfully created here.
|
|
117
|
+
try {
|
|
118
|
+
const mediaDoc = await payload.create({
|
|
119
|
+
collection: uploadCollection,
|
|
120
|
+
data: {},
|
|
121
|
+
file: {
|
|
122
|
+
name: requestFile.name,
|
|
123
|
+
data: requestFile.data,
|
|
124
|
+
mimetype: requestFile.mimetype,
|
|
125
|
+
size: requestFile.size
|
|
126
|
+
},
|
|
127
|
+
req
|
|
128
|
+
});
|
|
129
|
+
createdDocs.push({
|
|
130
|
+
id: mediaDoc.id,
|
|
131
|
+
collection: uploadCollection
|
|
132
|
+
});
|
|
133
|
+
uploadsByField.get(name).push({
|
|
134
|
+
relationTo: uploadCollection,
|
|
135
|
+
value: mediaDoc.id
|
|
136
|
+
});
|
|
137
|
+
} catch (err) {
|
|
138
|
+
const errorMessage = err instanceof Error ? err.message : 'Unknown error';
|
|
139
|
+
errors.push({
|
|
140
|
+
field: name,
|
|
141
|
+
message: `${fieldLabel}: Failed to upload file - ${errorMessage}`
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
} else if (existingSubmission && existingSubmission.value) {
|
|
146
|
+
// Backwards compatibility: validate pre-uploaded file IDs
|
|
147
|
+
const submittedValue = existingSubmission.value;
|
|
148
|
+
const submittedValueStr = typeof submittedValue === 'string' || typeof submittedValue === 'number' ? String(submittedValue) : '';
|
|
149
|
+
if (!submittedValueStr) {
|
|
150
|
+
if (required) {
|
|
151
|
+
errors.push({
|
|
152
|
+
field: name,
|
|
153
|
+
message: `${fieldLabel} is required`
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
// Guard: reject comma-separated IDs when the field doesn't allow multiple files.
|
|
159
|
+
// Assumes IDs never contain literal commas — true for ObjectIDs/UUIDs and any numeric ID.
|
|
160
|
+
if (!multiple && submittedValueStr.includes(',')) {
|
|
161
|
+
errors.push({
|
|
162
|
+
field: name,
|
|
163
|
+
message: `${fieldLabel} does not allow multiple files`
|
|
164
|
+
});
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
// Parse file IDs (comma-separated for multiple files)
|
|
168
|
+
const fileIds = multiple ? submittedValueStr.split(',').map((id)=>id.trim()).filter(Boolean) : [
|
|
169
|
+
submittedValueStr
|
|
170
|
+
];
|
|
171
|
+
// Validate each file
|
|
172
|
+
for (const fileId of fileIds){
|
|
173
|
+
let fileDoc = null;
|
|
174
|
+
let fileIsValid = true;
|
|
175
|
+
try {
|
|
176
|
+
fileDoc = await payload.findByID({
|
|
177
|
+
id: fileId,
|
|
178
|
+
collection: uploadCollection,
|
|
179
|
+
req
|
|
180
|
+
});
|
|
181
|
+
} catch {
|
|
182
|
+
errors.push({
|
|
183
|
+
field: name,
|
|
184
|
+
message: `${fieldLabel}: File with ID "${fileId}" not found in collection "${uploadCollection}"`
|
|
185
|
+
});
|
|
186
|
+
fileIsValid = false;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (!fileDoc) {
|
|
190
|
+
errors.push({
|
|
191
|
+
field: name,
|
|
192
|
+
message: `${fieldLabel}: File with ID "${fileId}" not found`
|
|
193
|
+
});
|
|
194
|
+
fileIsValid = false;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
// Validate mimeType
|
|
198
|
+
if (mimeTypes && mimeTypes.length > 0) {
|
|
199
|
+
const allowedPatterns = mimeTypes.map((m)=>m.mimeType);
|
|
200
|
+
const fileMimeType = fileDoc.mimeType;
|
|
201
|
+
if (fileMimeType && !validateMimeType(fileMimeType, allowedPatterns)) {
|
|
202
|
+
errors.push({
|
|
203
|
+
field: name,
|
|
204
|
+
message: `${fieldLabel}: File type "${fileMimeType}" is not allowed. Allowed types: ${allowedPatterns.join(', ')}`
|
|
205
|
+
});
|
|
206
|
+
fileIsValid = false;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// Validate file size
|
|
211
|
+
if (maxFileSize && maxFileSize > 0) {
|
|
212
|
+
const fileSize = fileDoc.filesize;
|
|
213
|
+
if (fileSize && fileSize > maxFileSize) {
|
|
214
|
+
const maxSizeMB = (maxFileSize / (1024 * 1024)).toFixed(2);
|
|
215
|
+
const fileSizeMB = (fileSize / (1024 * 1024)).toFixed(2);
|
|
216
|
+
errors.push({
|
|
217
|
+
field: name,
|
|
218
|
+
message: `${fieldLabel}: File size (${fileSizeMB}MB) exceeds maximum allowed size (${maxSizeMB}MB)`
|
|
219
|
+
});
|
|
220
|
+
fileIsValid = false;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (fileIsValid) {
|
|
224
|
+
uploadsByField.get(name).push({
|
|
225
|
+
relationTo: uploadCollection,
|
|
226
|
+
value: fileDoc.id
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
} else if (required) {
|
|
231
|
+
// No file in request and no pre-uploaded file ID, but field is required
|
|
232
|
+
errors.push({
|
|
233
|
+
field: name,
|
|
234
|
+
message: `${fieldLabel} is required`
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (errors.length > 0) {
|
|
239
|
+
// Best-effort cleanup of any docs created before the error was detected
|
|
240
|
+
for (const doc of createdDocs){
|
|
241
|
+
try {
|
|
242
|
+
await payload.delete({
|
|
243
|
+
id: doc.id,
|
|
244
|
+
collection: doc.collection,
|
|
245
|
+
req
|
|
246
|
+
});
|
|
247
|
+
} catch {
|
|
248
|
+
// best-effort — don't mask the original validation error
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
throw new ValidationError({
|
|
252
|
+
collection: formConfig?.formSubmissionOverrides?.slug || 'form-submissions',
|
|
253
|
+
errors: errors.map((error)=>({
|
|
254
|
+
message: error.message,
|
|
255
|
+
path: error.field
|
|
256
|
+
}))
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
// Strip upload fields from submissionData — they are stored in submissionUploads only
|
|
260
|
+
const uploadFieldNames = new Set(uploadFields.map((f)=>f.name));
|
|
261
|
+
const cleanedSubmissionData = submissionDataArray.filter((item)=>!uploadFieldNames.has(item.field));
|
|
262
|
+
// One entry per upload field; omit fields with no successful uploads
|
|
263
|
+
const updatedSubmissionUploads = Array.from(uploadsByField.entries()).filter(([, items])=>items.length > 0).map(([field, value])=>({
|
|
264
|
+
field,
|
|
265
|
+
value
|
|
266
|
+
}));
|
|
267
|
+
return {
|
|
268
|
+
...data,
|
|
269
|
+
submissionData: cleanedSubmissionData,
|
|
270
|
+
submissionUploads: updatedSubmissionUploads
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
//# sourceMappingURL=handleUploads.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/collections/FormSubmissions/hooks/handleUploads.ts"],"sourcesContent":["import type {\n CollectionBeforeChangeHook,\n File,\n FileData,\n TypeWithID,\n UploadCollectionSlug,\n} from 'payload'\n\nimport { ValidationError } from 'payload'\nimport { validateMimeType } from 'payload/shared'\n\nimport type {\n FormBuilderPluginConfig,\n SubmissionUploadItem,\n SubmissionValue,\n UploadField,\n} from '../../../types.js'\n\ntype BeforeChangeParams = Parameters<CollectionBeforeChangeHook>[0]\n\ninterface UploadError {\n field: string\n message: string\n}\n\n/**\n * Handles upload fields in form submissions.\n *\n * This hook:\n * 1. Checks req.files for files matching upload field names (supports multiple files per field)\n * 2. Validates MIME types and file sizes before uploading\n * 3. Creates media documents in the appropriate upload collection\n * 4. Populates submissionUploads with proper Payload upload relationships\n * 5. Strips upload fields from submissionData (they live in submissionUploads only)\n * 6. Validates pre-uploaded file IDs for backwards compatibility\n */\nexport const handleUploads = async (\n beforeChangeParams: BeforeChangeParams,\n formConfig: FormBuilderPluginConfig,\n) => {\n const { data, operation, req } = beforeChangeParams\n const { payload } = req\n\n // Only handle on create\n if (operation !== 'create') {\n return data\n }\n\n const { form: formID, submissionData } = data || {}\n\n if (!formID || !submissionData) {\n return data\n }\n\n const formSlug = formConfig?.formOverrides?.slug || 'forms'\n\n // Fetch the form to get field configurations\n let form\n try {\n form = await payload.findByID({\n id: formID,\n collection: formSlug,\n req,\n })\n } catch {\n // If form doesn't exist, let the form relationship validation handle it\n return data\n }\n\n const formFields = form?.fields || []\n const uploadFields = formFields.filter(\n (field: { blockType: string }) => field.blockType === 'upload',\n ) as UploadField[]\n\n if (uploadFields.length === 0) {\n return data\n }\n\n const submissionDataArray = submissionData as SubmissionValue[]\n\n // Build a map of pre-uploaded file IDs for backwards-compat lookup\n const submissionMap = new Map<string, { index: number; value: unknown }>()\n for (let i = 0; i < submissionDataArray.length; i++) {\n const item = submissionDataArray[i]\n if (item) {\n submissionMap.set(item.field, { index: i, value: item.value })\n }\n }\n\n // Get files from request (populated by addDataAndFileToRequest).\n // Multiple files with the same field name are stored as an array by buildFields.\n const requestFiles = req.files || {}\n\n const errors: UploadError[] = []\n // Accumulate upload items per field — one entry per upload field in the form\n const uploadsByField = new Map<string, SubmissionUploadItem[]>()\n // Track docs created during this hook so we can delete them if a later error causes rollback\n const createdDocs: Array<{ collection: string; id: number | string }> = []\n\n for (const uploadField of uploadFields) {\n const { name, maxFileSize, mimeTypes, multiple, required, uploadCollection } = uploadField\n const fieldLabel = uploadField.label || name\n\n uploadsByField.set(name, [])\n\n // Validate uploadCollection is configured in this plugin (defence-in-depth against tampered form docs)\n if (!formConfig.uploadCollections?.includes(uploadCollection)) {\n errors.push({\n field: name,\n message: `Upload collection \"${uploadCollection}\" is not configured in this plugin`,\n })\n continue\n }\n\n // Normalize: multiple files with the same field name arrive as an array\n const rawFile = requestFiles[name]\n const requestFileList: File[] = rawFile ? (Array.isArray(rawFile) ? rawFile : [rawFile]) : []\n\n const existingSubmission = submissionMap.get(name)\n\n if (requestFileList.length > 0) {\n // Guard: reject multiple files when the field doesn't allow them\n if (!multiple && requestFileList.length > 1) {\n errors.push({\n field: name,\n message: `${fieldLabel} does not allow multiple files`,\n })\n continue\n }\n\n // Direct file upload(s) from request\n for (const requestFile of requestFileList) {\n // Validate MIME type before uploading\n if (mimeTypes && mimeTypes.length > 0) {\n const allowedPatterns = mimeTypes.map((m) => m.mimeType)\n\n if (!validateMimeType(requestFile.mimetype, allowedPatterns)) {\n errors.push({\n field: name,\n message: `${fieldLabel}: File type \"${requestFile.mimetype}\" is not allowed. Allowed types: ${allowedPatterns.join(', ')}`,\n })\n continue\n }\n }\n\n // Validate file size before uploading\n if (maxFileSize && maxFileSize > 0 && requestFile.size > maxFileSize) {\n const maxSizeMB = (maxFileSize / (1024 * 1024)).toFixed(2)\n const fileSizeMB = (requestFile.size / (1024 * 1024)).toFixed(2)\n\n errors.push({\n field: name,\n message: `${fieldLabel}: File size (${fileSizeMB}MB) exceeds maximum allowed size (${maxSizeMB}MB)`,\n })\n continue\n }\n\n // Create the media document.\n // Note: payload.create writes the file to storage before the DB row exists. If\n // the DB write throws, createdDocs never records the entry and the file on disk\n // will not be cleaned up by the rollback loop below. Payload core owns that\n // rollback path — we only clean up docs we successfully created here.\n try {\n const mediaDoc = await payload.create({\n collection: uploadCollection,\n data: {},\n file: {\n name: requestFile.name,\n data: requestFile.data,\n mimetype: requestFile.mimetype,\n size: requestFile.size,\n },\n req,\n })\n\n createdDocs.push({ id: mediaDoc.id, collection: uploadCollection })\n uploadsByField.get(name)!.push({ relationTo: uploadCollection, value: mediaDoc.id })\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Unknown error'\n\n errors.push({\n field: name,\n message: `${fieldLabel}: Failed to upload file - ${errorMessage}`,\n })\n }\n }\n } else if (existingSubmission && existingSubmission.value) {\n // Backwards compatibility: validate pre-uploaded file IDs\n const submittedValue = existingSubmission.value\n const submittedValueStr =\n typeof submittedValue === 'string' || typeof submittedValue === 'number'\n ? String(submittedValue)\n : ''\n\n if (!submittedValueStr) {\n if (required) {\n errors.push({ field: name, message: `${fieldLabel} is required` })\n }\n continue\n }\n\n // Guard: reject comma-separated IDs when the field doesn't allow multiple files.\n // Assumes IDs never contain literal commas — true for ObjectIDs/UUIDs and any numeric ID.\n if (!multiple && submittedValueStr.includes(',')) {\n errors.push({\n field: name,\n message: `${fieldLabel} does not allow multiple files`,\n })\n continue\n }\n\n // Parse file IDs (comma-separated for multiple files)\n const fileIds = multiple\n ? submittedValueStr\n .split(',')\n .map((id) => id.trim())\n .filter(Boolean)\n : [submittedValueStr]\n\n // Validate each file\n for (const fileId of fileIds) {\n let fileDoc: (FileData & TypeWithID) | null = null\n let fileIsValid = true\n\n try {\n fileDoc = (await payload.findByID({\n id: fileId,\n collection: uploadCollection,\n req,\n })) as FileData & TypeWithID\n } catch {\n errors.push({\n field: name,\n message: `${fieldLabel}: File with ID \"${fileId}\" not found in collection \"${uploadCollection}\"`,\n })\n fileIsValid = false\n continue\n }\n\n if (!fileDoc) {\n errors.push({\n field: name,\n message: `${fieldLabel}: File with ID \"${fileId}\" not found`,\n })\n fileIsValid = false\n continue\n }\n\n // Validate mimeType\n if (mimeTypes && mimeTypes.length > 0) {\n const allowedPatterns = mimeTypes.map((m) => m.mimeType)\n const fileMimeType = fileDoc.mimeType\n\n if (fileMimeType && !validateMimeType(fileMimeType, allowedPatterns)) {\n errors.push({\n field: name,\n message: `${fieldLabel}: File type \"${fileMimeType}\" is not allowed. Allowed types: ${allowedPatterns.join(', ')}`,\n })\n fileIsValid = false\n continue\n }\n }\n\n // Validate file size\n if (maxFileSize && maxFileSize > 0) {\n const fileSize = fileDoc.filesize\n\n if (fileSize && fileSize > maxFileSize) {\n const maxSizeMB = (maxFileSize / (1024 * 1024)).toFixed(2)\n const fileSizeMB = (fileSize / (1024 * 1024)).toFixed(2)\n\n errors.push({\n field: name,\n message: `${fieldLabel}: File size (${fileSizeMB}MB) exceeds maximum allowed size (${maxSizeMB}MB)`,\n })\n fileIsValid = false\n }\n }\n\n if (fileIsValid) {\n uploadsByField.get(name)!.push({ relationTo: uploadCollection, value: fileDoc.id })\n }\n }\n } else if (required) {\n // No file in request and no pre-uploaded file ID, but field is required\n errors.push({\n field: name,\n message: `${fieldLabel} is required`,\n })\n }\n }\n\n if (errors.length > 0) {\n // Best-effort cleanup of any docs created before the error was detected\n for (const doc of createdDocs) {\n try {\n await payload.delete({ id: doc.id, collection: doc.collection, req })\n } catch {\n // best-effort — don't mask the original validation error\n }\n }\n\n throw new ValidationError({\n collection: formConfig?.formSubmissionOverrides?.slug || 'form-submissions',\n errors: errors.map((error) => ({\n message: error.message,\n path: error.field,\n })),\n })\n }\n\n // Strip upload fields from submissionData — they are stored in submissionUploads only\n const uploadFieldNames = new Set(uploadFields.map((f) => f.name))\n const cleanedSubmissionData = submissionDataArray.filter(\n (item) => !uploadFieldNames.has(item.field),\n )\n\n // One entry per upload field; omit fields with no successful uploads\n const updatedSubmissionUploads = Array.from(uploadsByField.entries())\n .filter(([, items]) => items.length > 0)\n .map(([field, value]) => ({ field, value }))\n\n return {\n ...data,\n submissionData: cleanedSubmissionData,\n submissionUploads: updatedSubmissionUploads,\n }\n}\n"],"names":["ValidationError","validateMimeType","handleUploads","beforeChangeParams","formConfig","data","operation","req","payload","form","formID","submissionData","formSlug","formOverrides","slug","findByID","id","collection","formFields","fields","uploadFields","filter","field","blockType","length","submissionDataArray","submissionMap","Map","i","item","set","index","value","requestFiles","files","errors","uploadsByField","createdDocs","uploadField","name","maxFileSize","mimeTypes","multiple","required","uploadCollection","fieldLabel","label","uploadCollections","includes","push","message","rawFile","requestFileList","Array","isArray","existingSubmission","get","requestFile","allowedPatterns","map","m","mimeType","mimetype","join","size","maxSizeMB","toFixed","fileSizeMB","mediaDoc","create","file","relationTo","err","errorMessage","Error","submittedValue","submittedValueStr","String","fileIds","split","trim","Boolean","fileId","fileDoc","fileIsValid","fileMimeType","fileSize","filesize","doc","delete","formSubmissionOverrides","error","path","uploadFieldNames","Set","f","cleanedSubmissionData","has","updatedSubmissionUploads","from","entries","items","submissionUploads"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/collections/FormSubmissions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/collections/FormSubmissions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA8B,gBAAgB,EAAS,MAAM,SAAS,CAAA;AAElF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AAQ7D,eAAO,MAAM,4BAA4B,eAC3B,uBAAuB,KAClC,gBAiIF,CAAA"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { defaultPaymentFields } from './fields/defaultPaymentFields.js';
|
|
2
2
|
import { createCharge } from './hooks/createCharge.js';
|
|
3
|
+
import { handleUploads } from './hooks/handleUploads.js';
|
|
3
4
|
import { sendEmail } from './hooks/sendEmail.js';
|
|
4
5
|
// all settings can be overridden by the config
|
|
5
6
|
export const generateSubmissionCollection = (formConfig)=>{
|
|
6
7
|
const formSlug = formConfig?.formOverrides?.slug || 'forms';
|
|
7
8
|
const enablePaymentFields = Boolean(formConfig?.fields?.payment);
|
|
9
|
+
const uploadCollections = formConfig?.uploadCollections;
|
|
8
10
|
const defaultFields = [
|
|
9
11
|
{
|
|
10
12
|
name: 'form',
|
|
@@ -60,6 +62,26 @@ export const generateSubmissionCollection = (formConfig)=>{
|
|
|
60
62
|
}
|
|
61
63
|
]
|
|
62
64
|
},
|
|
65
|
+
...uploadCollections && uploadCollections.length > 0 ? [
|
|
66
|
+
{
|
|
67
|
+
name: 'submissionUploads',
|
|
68
|
+
type: 'array',
|
|
69
|
+
fields: [
|
|
70
|
+
{
|
|
71
|
+
name: 'field',
|
|
72
|
+
type: 'text',
|
|
73
|
+
required: true
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'value',
|
|
77
|
+
type: 'upload',
|
|
78
|
+
hasMany: true,
|
|
79
|
+
relationTo: uploadCollections,
|
|
80
|
+
required: true
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
] : [],
|
|
63
85
|
...enablePaymentFields ? [
|
|
64
86
|
defaultPaymentFields
|
|
65
87
|
] : []
|
|
@@ -87,6 +109,9 @@ export const generateSubmissionCollection = (formConfig)=>{
|
|
|
87
109
|
...formConfig?.formSubmissionOverrides?.hooks?.afterChange || []
|
|
88
110
|
],
|
|
89
111
|
beforeChange: [
|
|
112
|
+
...uploadCollections && uploadCollections.length > 0 ? [
|
|
113
|
+
(data)=>handleUploads(data, formConfig)
|
|
114
|
+
] : [],
|
|
90
115
|
(data)=>createCharge(data, formConfig),
|
|
91
116
|
...formConfig?.formSubmissionOverrides?.hooks?.beforeChange || []
|
|
92
117
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/collections/FormSubmissions/index.ts"],"sourcesContent":["import type { CollectionConfig, Field } from 'payload'\n\nimport type { FormBuilderPluginConfig } from '../../types.js'\n\nimport { defaultPaymentFields } from './fields/defaultPaymentFields.js'\nimport { createCharge } from './hooks/createCharge.js'\nimport { sendEmail } from './hooks/sendEmail.js'\n\n// all settings can be overridden by the config\nexport const generateSubmissionCollection = (\n formConfig: FormBuilderPluginConfig,\n): CollectionConfig => {\n const formSlug = formConfig?.formOverrides?.slug || 'forms'\n\n const enablePaymentFields = Boolean(formConfig?.fields?.payment)\n\n const defaultFields: Field[] = [\n {\n name: 'form',\n type: 'relationship',\n relationTo: formSlug,\n required: true,\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n validate: async (value, { req: { payload }, req }) => {\n /* Don't run in the client side */\n if (!payload) {\n return true\n }\n\n if (payload) {\n let _existingForm\n\n try {\n _existingForm = await payload.findByID({\n id: value,\n collection: formSlug,\n req,\n })\n\n return true\n } catch (_error) {\n return 'Cannot create this submission because this form does not exist.'\n }\n }\n },\n },\n {\n name: 'submissionData',\n type: 'array',\n fields: [\n {\n name: 'field',\n type: 'text',\n required: true,\n },\n {\n name: 'value',\n type: 'textarea',\n required: true,\n validate: (value: unknown) => {\n // TODO:\n // create a validation function that dynamically\n // relies on the field type and its options as configured.\n\n // How to access sibling data from this field?\n // Need the `name` of the field in order to validate it.\n\n // Might not be possible to use this validation function.\n // Instead, might need to do all validation in a `beforeValidate` collection hook.\n\n if (typeof value !== 'undefined') {\n return true\n }\n\n return 'This field is required.'\n },\n },\n ],\n },\n ...(enablePaymentFields ? [defaultPaymentFields] : []),\n ]\n\n const newConfig: CollectionConfig = {\n ...(formConfig?.formSubmissionOverrides || {}),\n slug: formConfig?.formSubmissionOverrides?.slug || 'form-submissions',\n access: {\n create: () => true,\n read: ({ req: { user } }) => !!user, // logged-in users,\n update: () => false,\n ...(formConfig?.formSubmissionOverrides?.access || {}),\n },\n admin: {\n ...(formConfig?.formSubmissionOverrides?.admin || {}),\n enableRichTextRelationship: false,\n },\n fields:\n formConfig?.formSubmissionOverrides?.fields &&\n typeof formConfig?.formSubmissionOverrides?.fields === 'function'\n ? formConfig.formSubmissionOverrides.fields({ defaultFields })\n : defaultFields,\n hooks: {\n ...(formConfig?.formSubmissionOverrides?.hooks || {}),\n afterChange: [\n (data) => sendEmail(data, formConfig),\n ...(formConfig?.formSubmissionOverrides?.hooks?.afterChange || []),\n ],\n beforeChange: [\n (data) => createCharge(data, formConfig),\n ...(formConfig?.formSubmissionOverrides?.hooks?.beforeChange || []),\n ],\n },\n }\n return newConfig\n}\n"],"names":["defaultPaymentFields","createCharge","sendEmail","generateSubmissionCollection","formConfig","formSlug","formOverrides","slug","enablePaymentFields","Boolean","fields","payment","defaultFields","name","type","relationTo","required","validate","value","req","payload","_existingForm","findByID","id","collection","_error","newConfig","formSubmissionOverrides","access","create","read","user","update","admin","enableRichTextRelationship","hooks","afterChange","data","beforeChange"],"mappings":"AAIA,SAASA,oBAAoB,QAAQ,mCAAkC;AACvE,SAASC,YAAY,QAAQ,0BAAyB;AACtD,SAASC,SAAS,QAAQ,uBAAsB;AAEhD,+CAA+C;AAC/C,OAAO,MAAMC,+BAA+B,CAC1CC;IAEA,MAAMC,WAAWD,YAAYE,eAAeC,QAAQ;IAEpD,MAAMC,sBAAsBC,QAAQL,YAAYM,QAAQC;IAExD,MAAMC,gBAAyB;QAC7B;YACEC,MAAM;YACNC,MAAM;YACNC,
|
|
1
|
+
{"version":3,"sources":["../../../src/collections/FormSubmissions/index.ts"],"sourcesContent":["import type { CollectionBeforeChangeHook, CollectionConfig, Field } from 'payload'\n\nimport type { FormBuilderPluginConfig } from '../../types.js'\n\nimport { defaultPaymentFields } from './fields/defaultPaymentFields.js'\nimport { createCharge } from './hooks/createCharge.js'\nimport { handleUploads } from './hooks/handleUploads.js'\nimport { sendEmail } from './hooks/sendEmail.js'\n\n// all settings can be overridden by the config\nexport const generateSubmissionCollection = (\n formConfig: FormBuilderPluginConfig,\n): CollectionConfig => {\n const formSlug = formConfig?.formOverrides?.slug || 'forms'\n\n const enablePaymentFields = Boolean(formConfig?.fields?.payment)\n\n const uploadCollections = formConfig?.uploadCollections\n\n const defaultFields: Field[] = [\n {\n name: 'form',\n type: 'relationship',\n relationTo: formSlug,\n required: true,\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n validate: async (value, { req: { payload }, req }) => {\n /* Don't run in the client side */\n if (!payload) {\n return true\n }\n\n if (payload) {\n let _existingForm\n\n try {\n _existingForm = await payload.findByID({\n id: value,\n collection: formSlug,\n req,\n })\n\n return true\n } catch (_error) {\n return 'Cannot create this submission because this form does not exist.'\n }\n }\n },\n },\n {\n name: 'submissionData',\n type: 'array',\n fields: [\n {\n name: 'field',\n type: 'text',\n required: true,\n },\n {\n name: 'value',\n type: 'textarea',\n required: true,\n validate: (value: unknown) => {\n // TODO:\n // create a validation function that dynamically\n // relies on the field type and its options as configured.\n\n // How to access sibling data from this field?\n // Need the `name` of the field in order to validate it.\n\n // Might not be possible to use this validation function.\n // Instead, might need to do all validation in a `beforeValidate` collection hook.\n\n if (typeof value !== 'undefined') {\n return true\n }\n\n return 'This field is required.'\n },\n },\n ],\n },\n ...(uploadCollections && uploadCollections.length > 0\n ? ([\n {\n name: 'submissionUploads',\n type: 'array',\n fields: [\n {\n name: 'field',\n type: 'text',\n required: true,\n },\n {\n name: 'value',\n type: 'upload',\n hasMany: true,\n relationTo: uploadCollections,\n required: true,\n },\n ],\n },\n ] as Field[])\n : []),\n ...(enablePaymentFields ? [defaultPaymentFields] : []),\n ]\n\n const newConfig: CollectionConfig = {\n ...(formConfig?.formSubmissionOverrides || {}),\n slug: formConfig?.formSubmissionOverrides?.slug || 'form-submissions',\n access: {\n create: () => true,\n read: ({ req: { user } }) => !!user, // logged-in users,\n update: () => false,\n ...(formConfig?.formSubmissionOverrides?.access || {}),\n },\n admin: {\n ...(formConfig?.formSubmissionOverrides?.admin || {}),\n enableRichTextRelationship: false,\n },\n fields:\n formConfig?.formSubmissionOverrides?.fields &&\n typeof formConfig?.formSubmissionOverrides?.fields === 'function'\n ? formConfig.formSubmissionOverrides.fields({ defaultFields })\n : defaultFields,\n hooks: {\n ...(formConfig?.formSubmissionOverrides?.hooks || {}),\n afterChange: [\n (data) => sendEmail(data, formConfig),\n ...(formConfig?.formSubmissionOverrides?.hooks?.afterChange || []),\n ],\n beforeChange: [\n ...(uploadCollections && uploadCollections.length > 0\n ? [(data: Parameters<CollectionBeforeChangeHook>[0]) => handleUploads(data, formConfig)]\n : []),\n (data) => createCharge(data, formConfig),\n ...(formConfig?.formSubmissionOverrides?.hooks?.beforeChange || []),\n ],\n },\n }\n return newConfig\n}\n"],"names":["defaultPaymentFields","createCharge","handleUploads","sendEmail","generateSubmissionCollection","formConfig","formSlug","formOverrides","slug","enablePaymentFields","Boolean","fields","payment","uploadCollections","defaultFields","name","type","relationTo","required","validate","value","req","payload","_existingForm","findByID","id","collection","_error","length","hasMany","newConfig","formSubmissionOverrides","access","create","read","user","update","admin","enableRichTextRelationship","hooks","afterChange","data","beforeChange"],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Block } from 'payload';
|
|
2
|
-
import type { FieldConfig } from '../../types.js';
|
|
3
2
|
export declare const fields: {
|
|
4
|
-
[key: string]: ((
|
|
3
|
+
[key: string]: ((arg?: any) => Block) | Block;
|
|
5
4
|
};
|
|
6
5
|
//# sourceMappingURL=fields.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../../src/collections/Forms/fields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../../src/collections/Forms/fields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAA+B,MAAM,SAAS,CAAA;AAgzBjE,eAAO,MAAM,MAAM,EAAE;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,CAAA;CAe9C,CAAA"}
|
|
@@ -691,6 +691,106 @@ const Message = {
|
|
|
691
691
|
singular: 'Message'
|
|
692
692
|
}
|
|
693
693
|
};
|
|
694
|
+
const Upload = (uploadCollections)=>{
|
|
695
|
+
return {
|
|
696
|
+
slug: 'upload',
|
|
697
|
+
fields: [
|
|
698
|
+
{
|
|
699
|
+
type: 'row',
|
|
700
|
+
fields: [
|
|
701
|
+
{
|
|
702
|
+
...name,
|
|
703
|
+
admin: {
|
|
704
|
+
width: '50%'
|
|
705
|
+
}
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
...label,
|
|
709
|
+
admin: {
|
|
710
|
+
width: '50%'
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
]
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
name: 'uploadCollection',
|
|
717
|
+
type: 'select',
|
|
718
|
+
admin: {
|
|
719
|
+
description: 'Select which upload collection to store files in'
|
|
720
|
+
},
|
|
721
|
+
label: 'Upload Collection',
|
|
722
|
+
options: uploadCollections.map((slug)=>({
|
|
723
|
+
label: slug,
|
|
724
|
+
value: slug
|
|
725
|
+
})),
|
|
726
|
+
required: true
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
name: 'mimeTypes',
|
|
730
|
+
type: 'array',
|
|
731
|
+
admin: {
|
|
732
|
+
description: 'Restrict allowed file types (e.g., image/*, application/pdf). Leave empty to allow all types.'
|
|
733
|
+
},
|
|
734
|
+
fields: [
|
|
735
|
+
{
|
|
736
|
+
name: 'mimeType',
|
|
737
|
+
type: 'text',
|
|
738
|
+
label: 'MIME Type',
|
|
739
|
+
required: true
|
|
740
|
+
}
|
|
741
|
+
],
|
|
742
|
+
label: 'Allowed File Types',
|
|
743
|
+
labels: {
|
|
744
|
+
plural: 'MIME Types',
|
|
745
|
+
singular: 'MIME Type'
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
type: 'row',
|
|
750
|
+
fields: [
|
|
751
|
+
{
|
|
752
|
+
...width,
|
|
753
|
+
admin: {
|
|
754
|
+
width: '50%'
|
|
755
|
+
}
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
name: 'maxFileSize',
|
|
759
|
+
type: 'number',
|
|
760
|
+
admin: {
|
|
761
|
+
description: 'Maximum file size in bytes. Leave empty for no limit.',
|
|
762
|
+
width: '50%'
|
|
763
|
+
},
|
|
764
|
+
label: 'Max File Size (bytes)'
|
|
765
|
+
}
|
|
766
|
+
]
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
type: 'row',
|
|
770
|
+
fields: [
|
|
771
|
+
{
|
|
772
|
+
...required,
|
|
773
|
+
admin: {
|
|
774
|
+
width: '50%'
|
|
775
|
+
}
|
|
776
|
+
},
|
|
777
|
+
{
|
|
778
|
+
name: 'multiple',
|
|
779
|
+
type: 'checkbox',
|
|
780
|
+
admin: {
|
|
781
|
+
width: '50%'
|
|
782
|
+
},
|
|
783
|
+
label: 'Allow Multiple Files'
|
|
784
|
+
}
|
|
785
|
+
]
|
|
786
|
+
}
|
|
787
|
+
],
|
|
788
|
+
labels: {
|
|
789
|
+
plural: 'Upload Fields',
|
|
790
|
+
singular: 'Upload'
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
};
|
|
694
794
|
export const fields = {
|
|
695
795
|
checkbox: Checkbox,
|
|
696
796
|
country: Country,
|
|
@@ -703,7 +803,8 @@ export const fields = {
|
|
|
703
803
|
select: Select,
|
|
704
804
|
state: State,
|
|
705
805
|
text: Text,
|
|
706
|
-
textarea: TextArea
|
|
806
|
+
textarea: TextArea,
|
|
807
|
+
upload: Upload
|
|
707
808
|
};
|
|
708
809
|
|
|
709
810
|
//# sourceMappingURL=fields.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/collections/Forms/fields.ts"],"sourcesContent":["import type { Block, Field } from 'payload'\n\nimport type { FieldConfig, PaymentFieldConfig } from '../../types.js'\n\nconst name: Field = {\n name: 'name',\n type: 'text',\n label: 'Name (lowercase, no special characters)',\n required: true,\n}\n\nconst label: Field = {\n name: 'label',\n type: 'text',\n label: 'Label',\n localized: true,\n}\n\nconst required: Field = {\n name: 'required',\n type: 'checkbox',\n label: 'Required',\n}\n\nconst width: Field = {\n name: 'width',\n type: 'number',\n label: 'Field Width (percentage)',\n}\n\nconst placeholder: Field = {\n name: 'placeholder',\n type: 'text',\n label: 'Placeholder',\n}\n\nconst Radio: Block = {\n slug: 'radio',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'defaultValue',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Default Value',\n localized: true,\n },\n ],\n },\n {\n name: 'options',\n type: 'array',\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'label',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Label',\n localized: true,\n required: true,\n },\n {\n name: 'value',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Value',\n required: true,\n },\n ],\n },\n ],\n label: 'Radio Attribute Options',\n labels: {\n plural: 'Options',\n singular: 'Option',\n },\n },\n required,\n ],\n labels: {\n plural: 'Radio Fields',\n singular: 'Radio',\n },\n}\n\nconst Select: Block = {\n slug: 'select',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'defaultValue',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Default Value',\n localized: true,\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...placeholder,\n },\n ],\n },\n {\n name: 'options',\n type: 'array',\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'label',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Label',\n localized: true,\n required: true,\n },\n {\n name: 'value',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Value',\n required: true,\n },\n ],\n },\n ],\n label: 'Select Attribute Options',\n labels: {\n plural: 'Options',\n singular: 'Option',\n },\n },\n required,\n ],\n labels: {\n plural: 'Select Fields',\n singular: 'Select',\n },\n}\n\nconst Text: Block = {\n slug: 'text',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'defaultValue',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Default Value',\n localized: true,\n },\n ],\n },\n required,\n ],\n labels: {\n plural: 'Text Fields',\n singular: 'Text',\n },\n}\n\nconst TextArea: Block = {\n slug: 'textarea',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'defaultValue',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Default Value',\n localized: true,\n },\n ],\n },\n required,\n ],\n labels: {\n plural: 'Text Area Fields',\n singular: 'Text Area',\n },\n}\n\nconst Number: Block = {\n slug: 'number',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'defaultValue',\n type: 'number',\n admin: {\n width: '50%',\n },\n label: 'Default Value',\n },\n ],\n },\n required,\n ],\n labels: {\n plural: 'Number Fields',\n singular: 'Number',\n },\n}\n\nconst Email: Block = {\n slug: 'email',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n width,\n required,\n ],\n labels: {\n plural: 'Email Fields',\n singular: 'Email',\n },\n}\n\nconst State: Block = {\n slug: 'state',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n width,\n required,\n ],\n labels: {\n plural: 'State Fields',\n singular: 'State',\n },\n}\n\nconst Country: Block = {\n slug: 'country',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n width,\n required,\n ],\n labels: {\n plural: 'Country Fields',\n singular: 'Country',\n },\n}\n\nconst Checkbox: Block = {\n slug: 'checkbox',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n ...required,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n name: 'defaultValue',\n type: 'checkbox',\n label: 'Checked by default',\n },\n ],\n labels: {\n plural: 'Checkbox Fields',\n singular: 'Checkbox',\n },\n}\n\nconst Date: Block = {\n slug: 'date',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n ...required,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n name: 'defaultValue',\n type: 'date',\n label: 'Default Value',\n },\n ],\n labels: {\n plural: 'Date Fields',\n singular: 'Date',\n },\n}\n\nconst Payment = (fieldConfig: PaymentFieldConfig): Block => {\n let paymentProcessorField = null\n if (fieldConfig?.paymentProcessor) {\n paymentProcessorField = {\n name: 'paymentProcessor',\n type: 'select',\n label: 'Payment Processor',\n options: [],\n ...fieldConfig.paymentProcessor,\n }\n }\n\n const fields = {\n slug: 'payment',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'basePrice',\n type: 'number',\n admin: {\n width: '50%',\n },\n label: 'Base Price',\n },\n ],\n },\n paymentProcessorField,\n {\n name: 'priceConditions',\n type: 'array',\n fields: [\n {\n name: 'fieldToUse',\n type: 'text',\n admin: {\n components: {\n Field: '@payloadcms/plugin-form-builder/client#DynamicFieldSelector',\n },\n },\n },\n {\n name: 'condition',\n type: 'select',\n defaultValue: 'hasValue',\n label: 'Condition',\n options: [\n {\n label: 'Has Any Value',\n value: 'hasValue',\n },\n {\n label: 'Equals',\n value: 'equals',\n },\n {\n label: 'Does Not Equal',\n value: 'notEquals',\n },\n ],\n },\n {\n name: 'valueForCondition',\n type: 'text',\n admin: {\n condition: (_: any, { condition }: any) =>\n condition === 'equals' || condition === 'notEquals',\n },\n label: 'Value',\n },\n {\n name: 'operator',\n type: 'select',\n defaultValue: 'add',\n options: [\n {\n label: 'Add',\n value: 'add',\n },\n {\n label: 'Subtract',\n value: 'subtract',\n },\n {\n label: 'Multiply',\n value: 'multiply',\n },\n {\n label: 'Divide',\n value: 'divide',\n },\n ],\n },\n {\n name: 'valueType',\n type: 'radio',\n admin: {\n width: '100%',\n },\n defaultValue: 'static',\n label: 'Value Type',\n options: [\n {\n label: 'Static Value',\n value: 'static',\n },\n {\n label: 'Value Of Field',\n value: 'valueOfField',\n },\n ],\n },\n {\n name: 'valueForOperator',\n type: 'text',\n admin: {\n components: {\n Field: '@payloadcms/plugin-form-builder/client#DynamicPriceSelector',\n },\n },\n label: 'Value',\n },\n ],\n label: 'Price Conditions',\n labels: {\n plural: 'Price Conditions',\n singular: 'Price Condition',\n },\n },\n required,\n ].filter(Boolean) as Field[],\n labels: {\n plural: 'Payment Fields',\n singular: 'Payment',\n },\n }\n\n return fields\n}\n\nconst Message: Block = {\n slug: 'message',\n fields: [\n {\n name: 'message',\n type: 'richText',\n localized: true,\n },\n ],\n labels: {\n plural: 'Message Blocks',\n singular: 'Message',\n },\n}\n\nexport const fields = {\n checkbox: Checkbox,\n country: Country,\n date: Date,\n email: Email,\n message: Message,\n number: Number,\n payment: Payment,\n radio: Radio,\n select: Select,\n state: State,\n text: Text,\n textarea: TextArea,\n} as {\n [key: string]: ((fieldConfig?: boolean | FieldConfig) => Block) | Block\n}\n"],"names":["name","type","label","required","localized","width","placeholder","Radio","slug","fields","admin","labels","plural","singular","Select","Text","TextArea","Number","Email","State","Country","Checkbox","Date","Payment","fieldConfig","paymentProcessorField","paymentProcessor","options","components","Field","defaultValue","value","condition","_","filter","Boolean","Message","checkbox","country","date","email","message","number","payment","radio","select","state","text","textarea"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/collections/Forms/fields.ts"],"sourcesContent":["import type { Block, Field, UploadCollectionSlug } from 'payload'\n\nimport type { PaymentFieldConfig } from '../../types.js'\n\nconst name: Field = {\n name: 'name',\n type: 'text',\n label: 'Name (lowercase, no special characters)',\n required: true,\n}\n\nconst label: Field = {\n name: 'label',\n type: 'text',\n label: 'Label',\n localized: true,\n}\n\nconst required: Field = {\n name: 'required',\n type: 'checkbox',\n label: 'Required',\n}\n\nconst width: Field = {\n name: 'width',\n type: 'number',\n label: 'Field Width (percentage)',\n}\n\nconst placeholder: Field = {\n name: 'placeholder',\n type: 'text',\n label: 'Placeholder',\n}\n\nconst Radio: Block = {\n slug: 'radio',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'defaultValue',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Default Value',\n localized: true,\n },\n ],\n },\n {\n name: 'options',\n type: 'array',\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'label',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Label',\n localized: true,\n required: true,\n },\n {\n name: 'value',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Value',\n required: true,\n },\n ],\n },\n ],\n label: 'Radio Attribute Options',\n labels: {\n plural: 'Options',\n singular: 'Option',\n },\n },\n required,\n ],\n labels: {\n plural: 'Radio Fields',\n singular: 'Radio',\n },\n}\n\nconst Select: Block = {\n slug: 'select',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'defaultValue',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Default Value',\n localized: true,\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...placeholder,\n },\n ],\n },\n {\n name: 'options',\n type: 'array',\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'label',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Label',\n localized: true,\n required: true,\n },\n {\n name: 'value',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Value',\n required: true,\n },\n ],\n },\n ],\n label: 'Select Attribute Options',\n labels: {\n plural: 'Options',\n singular: 'Option',\n },\n },\n required,\n ],\n labels: {\n plural: 'Select Fields',\n singular: 'Select',\n },\n}\n\nconst Text: Block = {\n slug: 'text',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'defaultValue',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Default Value',\n localized: true,\n },\n ],\n },\n required,\n ],\n labels: {\n plural: 'Text Fields',\n singular: 'Text',\n },\n}\n\nconst TextArea: Block = {\n slug: 'textarea',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'defaultValue',\n type: 'text',\n admin: {\n width: '50%',\n },\n label: 'Default Value',\n localized: true,\n },\n ],\n },\n required,\n ],\n labels: {\n plural: 'Text Area Fields',\n singular: 'Text Area',\n },\n}\n\nconst Number: Block = {\n slug: 'number',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'defaultValue',\n type: 'number',\n admin: {\n width: '50%',\n },\n label: 'Default Value',\n },\n ],\n },\n required,\n ],\n labels: {\n plural: 'Number Fields',\n singular: 'Number',\n },\n}\n\nconst Email: Block = {\n slug: 'email',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n width,\n required,\n ],\n labels: {\n plural: 'Email Fields',\n singular: 'Email',\n },\n}\n\nconst State: Block = {\n slug: 'state',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n width,\n required,\n ],\n labels: {\n plural: 'State Fields',\n singular: 'State',\n },\n}\n\nconst Country: Block = {\n slug: 'country',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n width,\n required,\n ],\n labels: {\n plural: 'Country Fields',\n singular: 'Country',\n },\n}\n\nconst Checkbox: Block = {\n slug: 'checkbox',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n ...required,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n name: 'defaultValue',\n type: 'checkbox',\n label: 'Checked by default',\n },\n ],\n labels: {\n plural: 'Checkbox Fields',\n singular: 'Checkbox',\n },\n}\n\nconst Date: Block = {\n slug: 'date',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n ...required,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n name: 'defaultValue',\n type: 'date',\n label: 'Default Value',\n },\n ],\n labels: {\n plural: 'Date Fields',\n singular: 'Date',\n },\n}\n\nconst Payment = (fieldConfig: PaymentFieldConfig): Block => {\n let paymentProcessorField = null\n if (fieldConfig?.paymentProcessor) {\n paymentProcessorField = {\n name: 'paymentProcessor',\n type: 'select',\n label: 'Payment Processor',\n options: [],\n ...fieldConfig.paymentProcessor,\n }\n }\n\n const fields = {\n slug: 'payment',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'basePrice',\n type: 'number',\n admin: {\n width: '50%',\n },\n label: 'Base Price',\n },\n ],\n },\n paymentProcessorField,\n {\n name: 'priceConditions',\n type: 'array',\n fields: [\n {\n name: 'fieldToUse',\n type: 'text',\n admin: {\n components: {\n Field: '@payloadcms/plugin-form-builder/client#DynamicFieldSelector',\n },\n },\n },\n {\n name: 'condition',\n type: 'select',\n defaultValue: 'hasValue',\n label: 'Condition',\n options: [\n {\n label: 'Has Any Value',\n value: 'hasValue',\n },\n {\n label: 'Equals',\n value: 'equals',\n },\n {\n label: 'Does Not Equal',\n value: 'notEquals',\n },\n ],\n },\n {\n name: 'valueForCondition',\n type: 'text',\n admin: {\n condition: (_: any, { condition }: any) =>\n condition === 'equals' || condition === 'notEquals',\n },\n label: 'Value',\n },\n {\n name: 'operator',\n type: 'select',\n defaultValue: 'add',\n options: [\n {\n label: 'Add',\n value: 'add',\n },\n {\n label: 'Subtract',\n value: 'subtract',\n },\n {\n label: 'Multiply',\n value: 'multiply',\n },\n {\n label: 'Divide',\n value: 'divide',\n },\n ],\n },\n {\n name: 'valueType',\n type: 'radio',\n admin: {\n width: '100%',\n },\n defaultValue: 'static',\n label: 'Value Type',\n options: [\n {\n label: 'Static Value',\n value: 'static',\n },\n {\n label: 'Value Of Field',\n value: 'valueOfField',\n },\n ],\n },\n {\n name: 'valueForOperator',\n type: 'text',\n admin: {\n components: {\n Field: '@payloadcms/plugin-form-builder/client#DynamicPriceSelector',\n },\n },\n label: 'Value',\n },\n ],\n label: 'Price Conditions',\n labels: {\n plural: 'Price Conditions',\n singular: 'Price Condition',\n },\n },\n required,\n ].filter(Boolean) as Field[],\n labels: {\n plural: 'Payment Fields',\n singular: 'Payment',\n },\n }\n\n return fields\n}\n\nconst Message: Block = {\n slug: 'message',\n fields: [\n {\n name: 'message',\n type: 'richText',\n localized: true,\n },\n ],\n labels: {\n plural: 'Message Blocks',\n singular: 'Message',\n },\n}\n\nconst Upload = (uploadCollections: UploadCollectionSlug[]): Block => {\n return {\n slug: 'upload',\n fields: [\n {\n type: 'row',\n fields: [\n {\n ...name,\n admin: {\n width: '50%',\n },\n },\n {\n ...label,\n admin: {\n width: '50%',\n },\n },\n ],\n },\n {\n name: 'uploadCollection',\n type: 'select',\n admin: {\n description: 'Select which upload collection to store files in',\n },\n label: 'Upload Collection',\n options: uploadCollections.map((slug) => ({ label: slug, value: slug })),\n required: true,\n },\n {\n name: 'mimeTypes',\n type: 'array',\n admin: {\n description:\n 'Restrict allowed file types (e.g., image/*, application/pdf). Leave empty to allow all types.',\n },\n fields: [\n {\n name: 'mimeType',\n type: 'text',\n label: 'MIME Type',\n required: true,\n },\n ],\n label: 'Allowed File Types',\n labels: {\n plural: 'MIME Types',\n singular: 'MIME Type',\n },\n },\n {\n type: 'row',\n fields: [\n {\n ...width,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'maxFileSize',\n type: 'number',\n admin: {\n description: 'Maximum file size in bytes. Leave empty for no limit.',\n width: '50%',\n },\n label: 'Max File Size (bytes)',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n ...required,\n admin: {\n width: '50%',\n },\n },\n {\n name: 'multiple',\n type: 'checkbox',\n admin: {\n width: '50%',\n },\n label: 'Allow Multiple Files',\n },\n ],\n },\n ],\n labels: {\n plural: 'Upload Fields',\n singular: 'Upload',\n },\n }\n}\n\nexport const fields: {\n [key: string]: ((arg?: any) => Block) | Block\n} = {\n checkbox: Checkbox,\n country: Country,\n date: Date,\n email: Email,\n message: Message,\n number: Number,\n payment: Payment,\n radio: Radio,\n select: Select,\n state: State,\n text: Text,\n textarea: TextArea,\n upload: Upload,\n}\n"],"names":["name","type","label","required","localized","width","placeholder","Radio","slug","fields","admin","labels","plural","singular","Select","Text","TextArea","Number","Email","State","Country","Checkbox","Date","Payment","fieldConfig","paymentProcessorField","paymentProcessor","options","components","Field","defaultValue","value","condition","_","filter","Boolean","Message","Upload","uploadCollections","description","map","checkbox","country","date","email","message","number","payment","radio","select","state","text","textarea","upload"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CollectionConfig } from 'payload';
|
|
1
|
+
import type { CollectionConfig, Config } from 'payload';
|
|
2
2
|
import type { FormBuilderPluginConfig } from '../../types.js';
|
|
3
|
-
export declare const generateFormCollection: (formConfig: FormBuilderPluginConfig) => CollectionConfig;
|
|
3
|
+
export declare const generateFormCollection: (formConfig: FormBuilderPluginConfig, collections?: Config["collections"]) => CollectionConfig;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/collections/Forms/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,gBAAgB,EAAS,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/collections/Forms/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,gBAAgB,EAAE,MAAM,EAAS,MAAM,SAAS,CAAA;AAIrE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AA+B7D,eAAO,MAAM,sBAAsB,eACrB,uBAAuB,gBACrB,MAAM,CAAC,aAAa,CAAC,KAClC,gBAqPF,CAAA"}
|
|
@@ -1,7 +1,30 @@
|
|
|
1
1
|
import { deepMergeWithSourceArrays } from 'payload';
|
|
2
2
|
import { fields } from './fields.js';
|
|
3
|
+
const applyUploadCollectionLabels = (args)=>{
|
|
4
|
+
const { block, collections, uploadCollections } = args;
|
|
5
|
+
const collectionsBySlug = new Map((collections || []).map((collection)=>[
|
|
6
|
+
collection.slug,
|
|
7
|
+
collection
|
|
8
|
+
]));
|
|
9
|
+
for (const field of block.fields){
|
|
10
|
+
if ('name' in field && field.name === 'uploadCollection' && field.type === 'select') {
|
|
11
|
+
// Replace the default slug labels with the source collection's labels.singular.
|
|
12
|
+
// Select option labels accept strings, locale records and label functions —
|
|
13
|
+
// Payload's admin resolves them at render time via getTranslation.
|
|
14
|
+
field.options = (uploadCollections || []).map((slug)=>{
|
|
15
|
+
const singular = collectionsBySlug.get(slug)?.labels?.singular;
|
|
16
|
+
return {
|
|
17
|
+
label: singular ?? slug,
|
|
18
|
+
value: slug
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return block;
|
|
25
|
+
};
|
|
3
26
|
// all settings can be overridden by the config
|
|
4
|
-
export const generateFormCollection = (formConfig)=>{
|
|
27
|
+
export const generateFormCollection = (formConfig, collections)=>{
|
|
5
28
|
const redirect = {
|
|
6
29
|
name: 'redirect',
|
|
7
30
|
type: 'group',
|
|
@@ -75,6 +98,15 @@ export const generateFormCollection = (formConfig)=>{
|
|
|
75
98
|
return deepMergeWithSourceArrays(block, fieldConfig);
|
|
76
99
|
}
|
|
77
100
|
if (typeof block === 'function') {
|
|
101
|
+
// Special handling for upload field - factory takes slug list; after it runs,
|
|
102
|
+
// inject resolved collection labels into the uploadCollection select.
|
|
103
|
+
if (fieldKey === 'upload') {
|
|
104
|
+
return applyUploadCollectionLabels({
|
|
105
|
+
block: block(formConfig.uploadCollections || []),
|
|
106
|
+
collections,
|
|
107
|
+
uploadCollections: formConfig.uploadCollections
|
|
108
|
+
});
|
|
109
|
+
}
|
|
78
110
|
return block(fieldConfig);
|
|
79
111
|
}
|
|
80
112
|
return block;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/collections/Forms/index.ts"],"sourcesContent":["import type { Block, CollectionConfig, Field } from 'payload'\n\nimport { deepMergeWithSourceArrays } from 'payload'\n\nimport type { FormBuilderPluginConfig } from '../../types.js'\n\nimport { fields } from './fields.js'\n\n// all settings can be overridden by the config\nexport const generateFormCollection = (formConfig: FormBuilderPluginConfig): CollectionConfig => {\n const redirect: Field = {\n name: 'redirect',\n type: 'group',\n admin: {\n condition: (_, siblingData) => siblingData?.confirmationType === 'redirect',\n hideGutter: true,\n },\n fields: [\n {\n name: 'url',\n type: 'text',\n label: 'URL to redirect to',\n required: true,\n },\n ],\n }\n\n if (formConfig.redirectRelationships) {\n redirect.fields.unshift({\n name: 'reference',\n type: 'relationship',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'reference',\n },\n label: 'Document to link to',\n maxDepth: 2,\n relationTo: formConfig.redirectRelationships,\n required: true,\n })\n\n redirect.fields.unshift({\n name: 'type',\n type: 'radio',\n admin: {\n layout: 'horizontal',\n },\n defaultValue: 'reference',\n options: [\n {\n label: 'Internal link',\n value: 'reference',\n },\n {\n label: 'Custom URL',\n value: 'custom',\n },\n ],\n })\n\n if (redirect.fields[2]!.type !== 'row') {\n redirect.fields[2]!.label = 'Custom URL'\n }\n\n redirect.fields[2]!.admin = {\n condition: (_, siblingData) => siblingData?.type === 'custom',\n }\n }\n\n const defaultFields: Field[] = [\n {\n name: 'title',\n type: 'text',\n required: true,\n },\n {\n name: 'fields',\n type: 'blocks',\n blocks: Object.entries(formConfig?.fields || {})\n .map(([fieldKey, fieldConfig]) => {\n // let the config enable/disable fields with either boolean values or objects\n if (fieldConfig !== false) {\n const block = fields[fieldKey]\n\n if (block === undefined && typeof fieldConfig === 'object') {\n return fieldConfig\n }\n\n if (typeof block === 'object' && typeof fieldConfig === 'object') {\n return deepMergeWithSourceArrays(block, fieldConfig)\n }\n\n if (typeof block === 'function') {\n return block(fieldConfig)\n }\n\n return block\n }\n\n return null\n })\n .filter(Boolean) as Block[],\n },\n {\n name: 'submitButtonLabel',\n type: 'text',\n localized: true,\n },\n {\n name: 'confirmationType',\n type: 'radio',\n admin: {\n description:\n 'Choose whether to display an on-page message or redirect to a different page after they submit the form.',\n layout: 'horizontal',\n },\n defaultValue: 'message',\n options: [\n {\n label: 'Message',\n value: 'message',\n },\n {\n label: 'Redirect',\n value: 'redirect',\n },\n ],\n },\n {\n name: 'confirmationMessage',\n type: 'richText',\n admin: {\n condition: (_, siblingData) => siblingData?.confirmationType === 'message',\n },\n localized: true,\n required: true,\n },\n redirect,\n {\n name: 'emails',\n type: 'array',\n access: {\n read: ({ req: { user } }) => !!user,\n },\n admin: {\n description:\n \"Send custom emails when the form submits. Use comma separated lists to send the same email to multiple recipients. To reference a value from this form, wrap that field's name with double curly brackets, i.e. {{firstName}}. You can use a wildcard {{*}} to output all data and {{*:table}} to format it as an HTML table in the email.\",\n },\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'emailTo',\n type: 'text',\n admin: {\n placeholder: '\"Email Sender\" <sender@email.com>',\n width: '100%',\n },\n label: 'Email To',\n },\n {\n name: 'cc',\n type: 'text',\n admin: {\n style: {\n maxWidth: '50%',\n },\n },\n label: 'CC',\n },\n {\n name: 'bcc',\n type: 'text',\n admin: {\n style: {\n maxWidth: '50%',\n },\n },\n label: 'BCC',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'replyTo',\n type: 'text',\n admin: {\n placeholder: '\"Reply To\" <reply-to@email.com>',\n width: '50%',\n },\n label: 'Reply To',\n },\n {\n name: 'emailFrom',\n type: 'text',\n admin: {\n placeholder: '\"Email From\" <email-from@email.com>',\n width: '50%',\n },\n label: 'Email From',\n },\n ],\n },\n {\n name: 'subject',\n type: 'text',\n defaultValue: \"You've received a new message.\",\n label: 'Subject',\n localized: true,\n required: true,\n },\n {\n name: 'message',\n type: 'richText',\n admin: {\n description: 'Enter the message that should be sent in this email.',\n },\n label: 'Message',\n localized: true,\n },\n ],\n },\n ]\n\n const config: CollectionConfig = {\n ...(formConfig?.formOverrides || {}),\n slug: formConfig?.formOverrides?.slug || 'forms',\n access: {\n read: () => true,\n ...(formConfig?.formOverrides?.access || {}),\n },\n admin: {\n enableRichTextRelationship: false,\n useAsTitle: 'title',\n ...(formConfig?.formOverrides?.admin || {}),\n },\n fields:\n formConfig?.formOverrides?.fields && typeof formConfig?.formOverrides?.fields === 'function'\n ? formConfig.formOverrides.fields({ defaultFields })\n : defaultFields,\n }\n\n return config\n}\n"],"names":["deepMergeWithSourceArrays","fields","generateFormCollection","formConfig","redirect","name","type","admin","condition","_","siblingData","confirmationType","hideGutter","label","required","redirectRelationships","unshift","maxDepth","relationTo","layout","defaultValue","options","value","defaultFields","blocks","Object","entries","map","fieldKey","fieldConfig","block","undefined","filter","Boolean","localized","description","access","read","req","user","placeholder","width","style","maxWidth","config","formOverrides","slug","enableRichTextRelationship","useAsTitle"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/collections/Forms/index.ts"],"sourcesContent":["import type { Block, CollectionConfig, Config, Field } from 'payload'\n\nimport { deepMergeWithSourceArrays } from 'payload'\n\nimport type { FormBuilderPluginConfig } from '../../types.js'\n\nimport { fields } from './fields.js'\n\nconst applyUploadCollectionLabels = (args: {\n block: Block\n collections: Config['collections']\n uploadCollections: FormBuilderPluginConfig['uploadCollections']\n}): Block => {\n const { block, collections, uploadCollections } = args\n const collectionsBySlug = new Map(\n (collections || []).map((collection) => [collection.slug, collection]),\n )\n\n for (const field of block.fields) {\n if ('name' in field && field.name === 'uploadCollection' && field.type === 'select') {\n // Replace the default slug labels with the source collection's labels.singular.\n // Select option labels accept strings, locale records and label functions —\n // Payload's admin resolves them at render time via getTranslation.\n field.options = (uploadCollections || []).map((slug) => {\n const singular = collectionsBySlug.get(slug)?.labels?.singular\n return { label: singular ?? slug, value: slug }\n })\n break\n }\n }\n\n return block\n}\n\n// all settings can be overridden by the config\nexport const generateFormCollection = (\n formConfig: FormBuilderPluginConfig,\n collections?: Config['collections'],\n): CollectionConfig => {\n const redirect: Field = {\n name: 'redirect',\n type: 'group',\n admin: {\n condition: (_, siblingData) => siblingData?.confirmationType === 'redirect',\n hideGutter: true,\n },\n fields: [\n {\n name: 'url',\n type: 'text',\n label: 'URL to redirect to',\n required: true,\n },\n ],\n }\n\n if (formConfig.redirectRelationships) {\n redirect.fields.unshift({\n name: 'reference',\n type: 'relationship',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'reference',\n },\n label: 'Document to link to',\n maxDepth: 2,\n relationTo: formConfig.redirectRelationships,\n required: true,\n })\n\n redirect.fields.unshift({\n name: 'type',\n type: 'radio',\n admin: {\n layout: 'horizontal',\n },\n defaultValue: 'reference',\n options: [\n {\n label: 'Internal link',\n value: 'reference',\n },\n {\n label: 'Custom URL',\n value: 'custom',\n },\n ],\n })\n\n if (redirect.fields[2]!.type !== 'row') {\n redirect.fields[2]!.label = 'Custom URL'\n }\n\n redirect.fields[2]!.admin = {\n condition: (_, siblingData) => siblingData?.type === 'custom',\n }\n }\n\n const defaultFields: Field[] = [\n {\n name: 'title',\n type: 'text',\n required: true,\n },\n {\n name: 'fields',\n type: 'blocks',\n blocks: Object.entries(formConfig?.fields || {})\n .map(([fieldKey, fieldConfig]) => {\n // let the config enable/disable fields with either boolean values or objects\n if (fieldConfig !== false) {\n const block = fields[fieldKey]\n\n if (block === undefined && typeof fieldConfig === 'object') {\n return fieldConfig\n }\n\n if (typeof block === 'object' && typeof fieldConfig === 'object') {\n return deepMergeWithSourceArrays(block, fieldConfig)\n }\n\n if (typeof block === 'function') {\n // Special handling for upload field - factory takes slug list; after it runs,\n // inject resolved collection labels into the uploadCollection select.\n if (fieldKey === 'upload') {\n return applyUploadCollectionLabels({\n block: block(formConfig.uploadCollections || []),\n collections,\n uploadCollections: formConfig.uploadCollections,\n })\n }\n return block(fieldConfig)\n }\n\n return block\n }\n\n return null\n })\n .filter(Boolean) as Block[],\n },\n {\n name: 'submitButtonLabel',\n type: 'text',\n localized: true,\n },\n {\n name: 'confirmationType',\n type: 'radio',\n admin: {\n description:\n 'Choose whether to display an on-page message or redirect to a different page after they submit the form.',\n layout: 'horizontal',\n },\n defaultValue: 'message',\n options: [\n {\n label: 'Message',\n value: 'message',\n },\n {\n label: 'Redirect',\n value: 'redirect',\n },\n ],\n },\n {\n name: 'confirmationMessage',\n type: 'richText',\n admin: {\n condition: (_, siblingData) => siblingData?.confirmationType === 'message',\n },\n localized: true,\n required: true,\n },\n redirect,\n {\n name: 'emails',\n type: 'array',\n access: {\n read: ({ req: { user } }) => !!user,\n },\n admin: {\n description:\n \"Send custom emails when the form submits. Use comma separated lists to send the same email to multiple recipients. To reference a value from this form, wrap that field's name with double curly brackets, i.e. {{firstName}}. You can use a wildcard {{*}} to output all data and {{*:table}} to format it as an HTML table in the email.\",\n },\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'emailTo',\n type: 'text',\n admin: {\n placeholder: '\"Email Sender\" <sender@email.com>',\n width: '100%',\n },\n label: 'Email To',\n },\n {\n name: 'cc',\n type: 'text',\n admin: {\n style: {\n maxWidth: '50%',\n },\n },\n label: 'CC',\n },\n {\n name: 'bcc',\n type: 'text',\n admin: {\n style: {\n maxWidth: '50%',\n },\n },\n label: 'BCC',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'replyTo',\n type: 'text',\n admin: {\n placeholder: '\"Reply To\" <reply-to@email.com>',\n width: '50%',\n },\n label: 'Reply To',\n },\n {\n name: 'emailFrom',\n type: 'text',\n admin: {\n placeholder: '\"Email From\" <email-from@email.com>',\n width: '50%',\n },\n label: 'Email From',\n },\n ],\n },\n {\n name: 'subject',\n type: 'text',\n defaultValue: \"You've received a new message.\",\n label: 'Subject',\n localized: true,\n required: true,\n },\n {\n name: 'message',\n type: 'richText',\n admin: {\n description: 'Enter the message that should be sent in this email.',\n },\n label: 'Message',\n localized: true,\n },\n ],\n },\n ]\n\n const config: CollectionConfig = {\n ...(formConfig?.formOverrides || {}),\n slug: formConfig?.formOverrides?.slug || 'forms',\n access: {\n read: () => true,\n ...(formConfig?.formOverrides?.access || {}),\n },\n admin: {\n enableRichTextRelationship: false,\n useAsTitle: 'title',\n ...(formConfig?.formOverrides?.admin || {}),\n },\n fields:\n formConfig?.formOverrides?.fields && typeof formConfig?.formOverrides?.fields === 'function'\n ? formConfig.formOverrides.fields({ defaultFields })\n : defaultFields,\n }\n\n return config\n}\n"],"names":["deepMergeWithSourceArrays","fields","applyUploadCollectionLabels","args","block","collections","uploadCollections","collectionsBySlug","Map","map","collection","slug","field","name","type","options","singular","get","labels","label","value","generateFormCollection","formConfig","redirect","admin","condition","_","siblingData","confirmationType","hideGutter","required","redirectRelationships","unshift","maxDepth","relationTo","layout","defaultValue","defaultFields","blocks","Object","entries","fieldKey","fieldConfig","undefined","filter","Boolean","localized","description","access","read","req","user","placeholder","width","style","maxWidth","config","formOverrides","enableRichTextRelationship","useAsTitle"],"mappings":"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"}
|
package/dist/exports/types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { BeforeEmail, BlockConfig, CheckboxField, CountryField, DateField, Email, EmailField, FieldConfig, FieldsConfig, FieldValues, Form, FormattedEmail, FormBuilderPluginConfig as PluginConfig, FormFieldBlock, FormSubmission, HandlePayment, isValidBlockConfig, MessageField, PaymentField, PaymentFieldConfig, PriceCondition, RadioField, Redirect, SelectField, SelectFieldOption, StateField, SubmissionValue, TextAreaField, TextField, } from '../types.js';
|
|
1
|
+
export type { BeforeEmail, BlockConfig, CheckboxField, CountryField, DateField, Email, EmailField, FieldConfig, FieldsConfig, FieldValues, Form, FormattedEmail, FormBuilderPluginConfig as PluginConfig, FormFieldBlock, FormSubmission, HandlePayment, isValidBlockConfig, MessageField, PaymentField, PaymentFieldConfig, PriceCondition, RadioField, Redirect, SelectField, SelectFieldOption, StateField, SubmissionValue, TextAreaField, TextField, UploadField, UploadFieldMimeType, } from '../types.js';
|
|
2
2
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/exports/types.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,WAAW,EACX,WAAW,EACX,aAAa,EACb,YAAY,EACZ,SAAS,EACT,KAAK,EACL,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,IAAI,EACJ,cAAc,EACd,uBAAuB,IAAI,YAAY,EACvC,cAAc,EACd,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,SAAS,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/exports/types.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,WAAW,EACX,WAAW,EACX,aAAa,EACb,YAAY,EACZ,SAAS,EACT,KAAK,EACL,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,IAAI,EACJ,cAAc,EACd,uBAAuB,IAAI,YAAY,EACvC,cAAc,EACd,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,SAAS,EACT,WAAW,EACX,mBAAmB,GACpB,MAAM,aAAa,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type {\n BeforeEmail,\n BlockConfig,\n CheckboxField,\n CountryField,\n DateField,\n Email,\n EmailField,\n FieldConfig,\n FieldsConfig,\n FieldValues,\n Form,\n FormattedEmail,\n FormBuilderPluginConfig as PluginConfig,\n FormFieldBlock,\n FormSubmission,\n HandlePayment,\n isValidBlockConfig,\n MessageField,\n PaymentField,\n PaymentFieldConfig,\n PriceCondition,\n RadioField,\n Redirect,\n SelectField,\n SelectFieldOption,\n StateField,\n SubmissionValue,\n TextAreaField,\n TextField,\n} from '../types.js'\n"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type {\n BeforeEmail,\n BlockConfig,\n CheckboxField,\n CountryField,\n DateField,\n Email,\n EmailField,\n FieldConfig,\n FieldsConfig,\n FieldValues,\n Form,\n FormattedEmail,\n FormBuilderPluginConfig as PluginConfig,\n FormFieldBlock,\n FormSubmission,\n HandlePayment,\n isValidBlockConfig,\n MessageField,\n PaymentField,\n PaymentFieldConfig,\n PriceCondition,\n RadioField,\n Redirect,\n SelectField,\n SelectFieldOption,\n StateField,\n SubmissionValue,\n TextAreaField,\n TextField,\n UploadField,\n UploadFieldMimeType,\n} from '../types.js'\n"],"names":[],"mappings":"AAAA,WAgCoB"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAKzD,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAEhE,eAAO,MAAM,iBAAiB,uBACP,uBAAuB,cACnC,MAAM,KAAG,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAKzD,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAEhE,eAAO,MAAM,iBAAiB,uBACP,uBAAuB,cACnC,MAAM,KAAG,MAsCjB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -16,14 +16,21 @@ export const formBuilderPlugin = (incomingFormConfig)=>(config)=>{
|
|
|
16
16
|
state: true,
|
|
17
17
|
text: true,
|
|
18
18
|
textarea: true,
|
|
19
|
+
upload: false,
|
|
19
20
|
...incomingFormConfig.fields
|
|
20
21
|
}
|
|
21
22
|
};
|
|
23
|
+
const isUploadFieldEnabled = formConfig.fields?.upload !== false;
|
|
24
|
+
const hasUploadCollections = Array.isArray(formConfig.uploadCollections) && formConfig.uploadCollections.length > 0;
|
|
25
|
+
if (isUploadFieldEnabled && !hasUploadCollections) {
|
|
26
|
+
// eslint-disable-next-line no-console
|
|
27
|
+
console.warn('[plugin-form-builder] fields.upload is enabled but uploadCollections is empty or missing. Upload fields will not be registered. Set uploadCollections to an array of upload-enabled collection slugs.');
|
|
28
|
+
}
|
|
22
29
|
return {
|
|
23
30
|
...config,
|
|
24
31
|
collections: [
|
|
25
32
|
...config?.collections || [],
|
|
26
|
-
generateFormCollection(formConfig),
|
|
33
|
+
generateFormCollection(formConfig, config?.collections),
|
|
27
34
|
generateSubmissionCollection(formConfig)
|
|
28
35
|
]
|
|
29
36
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Config } from 'payload'\n\nimport type { FormBuilderPluginConfig } from './types.js'\n\nimport { generateFormCollection } from './collections/Forms/index.js'\nimport { generateSubmissionCollection } from './collections/FormSubmissions/index.js'\n\nexport { fields } from './collections/Forms/fields.js'\nexport { getPaymentTotal } from './utilities/getPaymentTotal.js'\n\nexport const formBuilderPlugin =\n (incomingFormConfig: FormBuilderPluginConfig) =>\n (config: Config): Config => {\n const formConfig: FormBuilderPluginConfig = {\n ...incomingFormConfig,\n fields: {\n checkbox: true,\n country: true,\n email: true,\n message: true,\n number: true,\n payment: false,\n select: true,\n state: true,\n text: true,\n textarea: true,\n ...incomingFormConfig.fields,\n },\n }\n\n return {\n ...config,\n collections: [\n ...(config?.collections || []),\n generateFormCollection(formConfig),\n generateSubmissionCollection(formConfig),\n ],\n }\n }\n"],"names":["generateFormCollection","generateSubmissionCollection","fields","getPaymentTotal","formBuilderPlugin","incomingFormConfig","config","formConfig","checkbox","country","email","message","number","payment","select","state","text","textarea","collections"],"mappings":"AAIA,SAASA,sBAAsB,QAAQ,+BAA8B;AACrE,SAASC,4BAA4B,QAAQ,yCAAwC;AAErF,SAASC,MAAM,QAAQ,gCAA+B;AACtD,SAASC,eAAe,QAAQ,iCAAgC;AAEhE,OAAO,MAAMC,oBACX,CAACC,qBACD,CAACC;QACC,MAAMC,aAAsC;YAC1C,GAAGF,kBAAkB;YACrBH,QAAQ;gBACNM,UAAU;gBACVC,SAAS;gBACTC,OAAO;gBACPC,SAAS;gBACTC,QAAQ;gBACRC,SAAS;gBACTC,QAAQ;gBACRC,OAAO;gBACPC,MAAM;gBACNC,UAAU;
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Config } from 'payload'\n\nimport type { FormBuilderPluginConfig } from './types.js'\n\nimport { generateFormCollection } from './collections/Forms/index.js'\nimport { generateSubmissionCollection } from './collections/FormSubmissions/index.js'\n\nexport { fields } from './collections/Forms/fields.js'\nexport { getPaymentTotal } from './utilities/getPaymentTotal.js'\n\nexport const formBuilderPlugin =\n (incomingFormConfig: FormBuilderPluginConfig) =>\n (config: Config): Config => {\n const formConfig: FormBuilderPluginConfig = {\n ...incomingFormConfig,\n fields: {\n checkbox: true,\n country: true,\n email: true,\n message: true,\n number: true,\n payment: false,\n select: true,\n state: true,\n text: true,\n textarea: true,\n upload: false,\n ...incomingFormConfig.fields,\n },\n }\n\n const isUploadFieldEnabled = formConfig.fields?.upload !== false\n const hasUploadCollections =\n Array.isArray(formConfig.uploadCollections) && formConfig.uploadCollections.length > 0\n\n if (isUploadFieldEnabled && !hasUploadCollections) {\n // eslint-disable-next-line no-console\n console.warn(\n '[plugin-form-builder] fields.upload is enabled but uploadCollections is empty or missing. Upload fields will not be registered. Set uploadCollections to an array of upload-enabled collection slugs.',\n )\n }\n\n return {\n ...config,\n collections: [\n ...(config?.collections || []),\n generateFormCollection(formConfig, config?.collections),\n generateSubmissionCollection(formConfig),\n ],\n }\n }\n"],"names":["generateFormCollection","generateSubmissionCollection","fields","getPaymentTotal","formBuilderPlugin","incomingFormConfig","config","formConfig","checkbox","country","email","message","number","payment","select","state","text","textarea","upload","isUploadFieldEnabled","hasUploadCollections","Array","isArray","uploadCollections","length","console","warn","collections"],"mappings":"AAIA,SAASA,sBAAsB,QAAQ,+BAA8B;AACrE,SAASC,4BAA4B,QAAQ,yCAAwC;AAErF,SAASC,MAAM,QAAQ,gCAA+B;AACtD,SAASC,eAAe,QAAQ,iCAAgC;AAEhE,OAAO,MAAMC,oBACX,CAACC,qBACD,CAACC;QACC,MAAMC,aAAsC;YAC1C,GAAGF,kBAAkB;YACrBH,QAAQ;gBACNM,UAAU;gBACVC,SAAS;gBACTC,OAAO;gBACPC,SAAS;gBACTC,QAAQ;gBACRC,SAAS;gBACTC,QAAQ;gBACRC,OAAO;gBACPC,MAAM;gBACNC,UAAU;gBACVC,QAAQ;gBACR,GAAGb,mBAAmBH,MAAM;YAC9B;QACF;QAEA,MAAMiB,uBAAuBZ,WAAWL,MAAM,EAAEgB,WAAW;QAC3D,MAAME,uBACJC,MAAMC,OAAO,CAACf,WAAWgB,iBAAiB,KAAKhB,WAAWgB,iBAAiB,CAACC,MAAM,GAAG;QAEvF,IAAIL,wBAAwB,CAACC,sBAAsB;YACjD,sCAAsC;YACtCK,QAAQC,IAAI,CACV;QAEJ;QAEA,OAAO;YACL,GAAGpB,MAAM;YACTqB,aAAa;mBACPrB,QAAQqB,eAAe,EAAE;gBAC7B3B,uBAAuBO,YAAYD,QAAQqB;gBAC3C1B,6BAA6BM;aAC9B;QACH;IACF,EAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Block, CollectionBeforeChangeHook, CollectionConfig, Field, TypeWithID } from 'payload';
|
|
1
|
+
import type { Block, CollectionBeforeChangeHook, CollectionConfig, Field, TypeWithID, UploadCollectionSlug } from 'payload';
|
|
2
2
|
export interface BlockConfig {
|
|
3
3
|
block: Block;
|
|
4
4
|
validate?: (value: unknown) => boolean | string;
|
|
@@ -24,6 +24,7 @@ export interface FieldsConfig {
|
|
|
24
24
|
state?: boolean | FieldConfig;
|
|
25
25
|
text?: boolean | FieldConfig;
|
|
26
26
|
textarea?: boolean | FieldConfig;
|
|
27
|
+
upload?: boolean | FieldConfig;
|
|
27
28
|
}
|
|
28
29
|
type BeforeChangeParams<T extends TypeWithID = any> = Parameters<CollectionBeforeChangeHook<T>>[0];
|
|
29
30
|
export type BeforeEmail<T extends TypeWithID = any> = (emails: FormattedEmail[], beforeChangeParams: BeforeChangeParams<T>) => FormattedEmail[] | Promise<FormattedEmail[]>;
|
|
@@ -47,6 +48,11 @@ export type FormBuilderPluginConfig = {
|
|
|
47
48
|
} & Partial<Omit<CollectionConfig, 'fields'>>;
|
|
48
49
|
handlePayment?: HandlePayment;
|
|
49
50
|
redirectRelationships?: string[];
|
|
51
|
+
/**
|
|
52
|
+
* Upload-enabled collection slugs available for upload fields.
|
|
53
|
+
* Required when using upload fields.
|
|
54
|
+
*/
|
|
55
|
+
uploadCollections?: UploadCollectionSlug[];
|
|
50
56
|
};
|
|
51
57
|
export interface TextField {
|
|
52
58
|
blockName?: string;
|
|
@@ -162,7 +168,26 @@ export interface MessageField {
|
|
|
162
168
|
blockType: 'message';
|
|
163
169
|
message: object;
|
|
164
170
|
}
|
|
165
|
-
export
|
|
171
|
+
export interface UploadFieldMimeType {
|
|
172
|
+
mimeType: string;
|
|
173
|
+
}
|
|
174
|
+
export interface UploadField {
|
|
175
|
+
blockName?: string;
|
|
176
|
+
blockType: 'upload';
|
|
177
|
+
label?: string;
|
|
178
|
+
/** Maximum file size in bytes */
|
|
179
|
+
maxFileSize?: number;
|
|
180
|
+
/** Array of allowed MIME types (e.g., image/*, application/pdf) */
|
|
181
|
+
mimeTypes?: UploadFieldMimeType[];
|
|
182
|
+
/** Whether to allow multiple file uploads */
|
|
183
|
+
multiple?: boolean;
|
|
184
|
+
name: string;
|
|
185
|
+
required?: boolean;
|
|
186
|
+
/** The upload collection slug to store files in */
|
|
187
|
+
uploadCollection: UploadCollectionSlug;
|
|
188
|
+
width?: number;
|
|
189
|
+
}
|
|
190
|
+
export type FormFieldBlock = CheckboxField | CountryField | DateField | EmailField | MessageField | PaymentField | RadioField | SelectField | StateField | TextAreaField | TextField | UploadField;
|
|
166
191
|
export interface Email {
|
|
167
192
|
bcc?: string;
|
|
168
193
|
cc?: string;
|
|
@@ -203,9 +228,26 @@ export interface SubmissionValue {
|
|
|
203
228
|
field: string;
|
|
204
229
|
value: unknown;
|
|
205
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* A single polymorphic upload reference within a submissionUploads entry.
|
|
233
|
+
*/
|
|
234
|
+
export type SubmissionUploadItem = {
|
|
235
|
+
relationTo: string;
|
|
236
|
+
value: TypeWithID['id'];
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* Value stored in a submissionUploads array item.
|
|
240
|
+
* Always an array of polymorphic upload references (hasMany) so the schema is consistent
|
|
241
|
+
* regardless of whether the upload field allows single or multiple files.
|
|
242
|
+
*/
|
|
243
|
+
export type SubmissionUploadValue = SubmissionUploadItem[];
|
|
206
244
|
export interface FormSubmission {
|
|
207
245
|
form: Form | string;
|
|
208
246
|
submissionData: SubmissionValue[];
|
|
247
|
+
submissionUploads?: Array<{
|
|
248
|
+
field: string;
|
|
249
|
+
value: SubmissionUploadValue;
|
|
250
|
+
}>;
|
|
209
251
|
}
|
|
210
252
|
export {};
|
|
211
253
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,KAAK,EACL,UAAU,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n Block,\n CollectionBeforeChangeHook,\n CollectionConfig,\n Field,\n TypeWithID,\n} from 'payload'\n\nexport interface BlockConfig {\n block: Block\n validate?: (value: unknown) => boolean | string\n}\n\nexport function isValidBlockConfig(blockConfig: BlockConfig | string): blockConfig is BlockConfig {\n return (\n typeof blockConfig !== 'string' &&\n typeof blockConfig?.block?.slug === 'string' &&\n Array.isArray(blockConfig?.block?.fields)\n )\n}\n\nexport interface FieldValues {\n [key: string]: boolean | null | number | string | undefined\n}\n\nexport type PaymentFieldConfig = {\n paymentProcessor: Partial<SelectField>\n} & Partial<Field>\n\nexport type FieldConfig = Partial<Field> | PaymentFieldConfig\n\nexport interface FieldsConfig {\n [key: string]: boolean | FieldConfig | undefined\n checkbox?: boolean | FieldConfig\n country?: boolean | FieldConfig\n date?: boolean | FieldConfig\n email?: boolean | FieldConfig\n message?: boolean | FieldConfig\n number?: boolean | FieldConfig\n payment?: boolean | FieldConfig\n select?: boolean | FieldConfig\n state?: boolean | FieldConfig\n text?: boolean | FieldConfig\n textarea?: boolean | FieldConfig\n}\n\ntype BeforeChangeParams<T extends TypeWithID = any> = Parameters<CollectionBeforeChangeHook<T>>[0]\nexport type BeforeEmail<T extends TypeWithID = any> = (\n emails: FormattedEmail[],\n beforeChangeParams: BeforeChangeParams<T>,\n) => FormattedEmail[] | Promise<FormattedEmail[]>\nexport type HandlePayment = (data: any) => void\nexport type FieldsOverride = (args: { defaultFields: Field[] }) => Field[]\n\nexport type FormBuilderPluginConfig = {\n beforeEmail?: BeforeEmail\n /**\n * Set a default email address to send form submissions to if no email is provided in the form configuration\n * Falls back to the defaultFromAddress in the email configuration\n */\n defaultToEmail?: string\n fields?: FieldsConfig\n formOverrides?: { fields?: FieldsOverride } & Partial<Omit<CollectionConfig, 'fields'>>\n formSubmissionOverrides?: { fields?: FieldsOverride } & Partial<Omit<CollectionConfig, 'fields'>>\n handlePayment?: HandlePayment\n redirectRelationships?: string[]\n}\n\nexport interface TextField {\n blockName?: string\n blockType: 'text'\n defaultValue?: string\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface TextAreaField {\n blockName?: string\n blockType: 'textarea'\n defaultValue?: string\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface SelectFieldOption {\n label: string\n value: string\n}\n\nexport interface SelectField {\n blockName?: string\n blockType: 'select'\n defaultValue?: string\n label?: string\n name: string\n options: SelectFieldOption[]\n placeholder?: string\n required?: boolean\n width?: number\n}\n\nexport interface RadioField {\n blockName?: string\n blockType: 'radio'\n defaultValue?: string\n label?: string\n name: string\n options: SelectFieldOption[]\n placeholder?: string\n required?: boolean\n width?: number\n}\n\nexport interface PriceCondition {\n condition: 'equals' | 'hasValue' | 'notEquals'\n fieldToUse: string\n operator: 'add' | 'divide' | 'multiply' | 'subtract'\n valueForCondition: string\n valueForOperator: number | string // TODO: make this a number, see ./collections/Forms/DynamicPriceSelector.tsx\n valueType: 'static' | 'valueOfField'\n}\n\nexport interface PaymentField {\n basePrice: number\n blockName?: string\n blockType: 'payment'\n defaultValue?: string\n label?: string\n name: string\n paymentProcessor: string\n priceConditions: PriceCondition[]\n required?: boolean\n width?: number\n}\n\nexport interface EmailField {\n blockName?: string\n blockType: 'email'\n defaultValue?: string\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface DateField {\n blockName?: string\n blockType: 'date'\n defaultValue?: string\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface StateField {\n blockName?: string\n blockType: 'state'\n defaultValue?: string\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface CountryField {\n blockName?: string\n blockType: 'country'\n defaultValue?: string\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface CheckboxField {\n blockName?: string\n blockType: 'checkbox'\n defaultValue?: boolean\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface MessageField {\n blockName?: string\n blockType: 'message'\n message: object\n}\n\nexport type FormFieldBlock =\n | CheckboxField\n | CountryField\n | DateField\n | EmailField\n | MessageField\n | PaymentField\n | RadioField\n | SelectField\n | StateField\n | TextAreaField\n | TextField\n\nexport interface Email {\n bcc?: string\n cc?: string\n emailFrom: string\n emailTo: string\n message?: any // TODO: configure rich text type\n replyTo?: string\n subject: string\n}\n\nexport interface FormattedEmail {\n bcc?: string\n cc?: string\n from: string\n html: string\n replyTo: string\n subject: string\n to: string\n}\n\nexport interface Redirect {\n reference?: {\n relationTo: string\n value: string | unknown\n }\n type: 'custom' | 'reference'\n url: string\n}\n\nexport interface Form {\n confirmationMessage?: any // TODO: configure rich text type\n confirmationType: 'message' | 'redirect'\n emails: Email[]\n fields: FormFieldBlock[]\n id: string\n redirect?: Redirect\n submitButtonLabel?: string\n title: string\n}\n\nexport interface SubmissionValue {\n field: string\n value: unknown\n}\n\nexport interface FormSubmission {\n form: Form | string\n submissionData: SubmissionValue[]\n}\n"],"names":["isValidBlockConfig","blockConfig","block","slug","Array","isArray","fields"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n Block,\n CollectionBeforeChangeHook,\n CollectionConfig,\n Field,\n TypeWithID,\n UploadCollectionSlug,\n} from 'payload'\n\nexport interface BlockConfig {\n block: Block\n validate?: (value: unknown) => boolean | string\n}\n\nexport function isValidBlockConfig(blockConfig: BlockConfig | string): blockConfig is BlockConfig {\n return (\n typeof blockConfig !== 'string' &&\n typeof blockConfig?.block?.slug === 'string' &&\n Array.isArray(blockConfig?.block?.fields)\n )\n}\n\nexport interface FieldValues {\n [key: string]: boolean | null | number | string | undefined\n}\n\nexport type PaymentFieldConfig = {\n paymentProcessor: Partial<SelectField>\n} & Partial<Field>\n\nexport type FieldConfig = Partial<Field> | PaymentFieldConfig\n\nexport interface FieldsConfig {\n [key: string]: boolean | FieldConfig | undefined\n checkbox?: boolean | FieldConfig\n country?: boolean | FieldConfig\n date?: boolean | FieldConfig\n email?: boolean | FieldConfig\n message?: boolean | FieldConfig\n number?: boolean | FieldConfig\n payment?: boolean | FieldConfig\n select?: boolean | FieldConfig\n state?: boolean | FieldConfig\n text?: boolean | FieldConfig\n textarea?: boolean | FieldConfig\n upload?: boolean | FieldConfig\n}\n\ntype BeforeChangeParams<T extends TypeWithID = any> = Parameters<CollectionBeforeChangeHook<T>>[0]\nexport type BeforeEmail<T extends TypeWithID = any> = (\n emails: FormattedEmail[],\n beforeChangeParams: BeforeChangeParams<T>,\n) => FormattedEmail[] | Promise<FormattedEmail[]>\nexport type HandlePayment = (data: any) => void\nexport type FieldsOverride = (args: { defaultFields: Field[] }) => Field[]\n\nexport type FormBuilderPluginConfig = {\n beforeEmail?: BeforeEmail\n /**\n * Set a default email address to send form submissions to if no email is provided in the form configuration\n * Falls back to the defaultFromAddress in the email configuration\n */\n defaultToEmail?: string\n fields?: FieldsConfig\n formOverrides?: { fields?: FieldsOverride } & Partial<Omit<CollectionConfig, 'fields'>>\n formSubmissionOverrides?: { fields?: FieldsOverride } & Partial<Omit<CollectionConfig, 'fields'>>\n handlePayment?: HandlePayment\n redirectRelationships?: string[]\n /**\n * Upload-enabled collection slugs available for upload fields.\n * Required when using upload fields.\n */\n uploadCollections?: UploadCollectionSlug[]\n}\n\nexport interface TextField {\n blockName?: string\n blockType: 'text'\n defaultValue?: string\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface TextAreaField {\n blockName?: string\n blockType: 'textarea'\n defaultValue?: string\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface SelectFieldOption {\n label: string\n value: string\n}\n\nexport interface SelectField {\n blockName?: string\n blockType: 'select'\n defaultValue?: string\n label?: string\n name: string\n options: SelectFieldOption[]\n placeholder?: string\n required?: boolean\n width?: number\n}\n\nexport interface RadioField {\n blockName?: string\n blockType: 'radio'\n defaultValue?: string\n label?: string\n name: string\n options: SelectFieldOption[]\n placeholder?: string\n required?: boolean\n width?: number\n}\n\nexport interface PriceCondition {\n condition: 'equals' | 'hasValue' | 'notEquals'\n fieldToUse: string\n operator: 'add' | 'divide' | 'multiply' | 'subtract'\n valueForCondition: string\n valueForOperator: number | string // TODO: make this a number, see ./collections/Forms/DynamicPriceSelector.tsx\n valueType: 'static' | 'valueOfField'\n}\n\nexport interface PaymentField {\n basePrice: number\n blockName?: string\n blockType: 'payment'\n defaultValue?: string\n label?: string\n name: string\n paymentProcessor: string\n priceConditions: PriceCondition[]\n required?: boolean\n width?: number\n}\n\nexport interface EmailField {\n blockName?: string\n blockType: 'email'\n defaultValue?: string\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface DateField {\n blockName?: string\n blockType: 'date'\n defaultValue?: string\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface StateField {\n blockName?: string\n blockType: 'state'\n defaultValue?: string\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface CountryField {\n blockName?: string\n blockType: 'country'\n defaultValue?: string\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface CheckboxField {\n blockName?: string\n blockType: 'checkbox'\n defaultValue?: boolean\n label?: string\n name: string\n required?: boolean\n width?: number\n}\n\nexport interface MessageField {\n blockName?: string\n blockType: 'message'\n message: object\n}\n\nexport interface UploadFieldMimeType {\n mimeType: string\n}\n\nexport interface UploadField {\n blockName?: string\n blockType: 'upload'\n label?: string\n /** Maximum file size in bytes */\n maxFileSize?: number\n /** Array of allowed MIME types (e.g., image/*, application/pdf) */\n mimeTypes?: UploadFieldMimeType[]\n /** Whether to allow multiple file uploads */\n multiple?: boolean\n name: string\n required?: boolean\n /** The upload collection slug to store files in */\n uploadCollection: UploadCollectionSlug\n width?: number\n}\n\nexport type FormFieldBlock =\n | CheckboxField\n | CountryField\n | DateField\n | EmailField\n | MessageField\n | PaymentField\n | RadioField\n | SelectField\n | StateField\n | TextAreaField\n | TextField\n | UploadField\n\nexport interface Email {\n bcc?: string\n cc?: string\n emailFrom: string\n emailTo: string\n message?: any // TODO: configure rich text type\n replyTo?: string\n subject: string\n}\n\nexport interface FormattedEmail {\n bcc?: string\n cc?: string\n from: string\n html: string\n replyTo: string\n subject: string\n to: string\n}\n\nexport interface Redirect {\n reference?: {\n relationTo: string\n value: string | unknown\n }\n type: 'custom' | 'reference'\n url: string\n}\n\nexport interface Form {\n confirmationMessage?: any // TODO: configure rich text type\n confirmationType: 'message' | 'redirect'\n emails: Email[]\n fields: FormFieldBlock[]\n id: string\n redirect?: Redirect\n submitButtonLabel?: string\n title: string\n}\n\nexport interface SubmissionValue {\n field: string\n value: unknown\n}\n\n/**\n * A single polymorphic upload reference within a submissionUploads entry.\n */\nexport type SubmissionUploadItem = { relationTo: string; value: TypeWithID['id'] }\n\n/**\n * Value stored in a submissionUploads array item.\n * Always an array of polymorphic upload references (hasMany) so the schema is consistent\n * regardless of whether the upload field allows single or multiple files.\n */\nexport type SubmissionUploadValue = SubmissionUploadItem[]\n\nexport interface FormSubmission {\n form: Form | string\n submissionData: SubmissionValue[]\n submissionUploads?: Array<{ field: string; value: SubmissionUploadValue }>\n}\n"],"names":["isValidBlockConfig","blockConfig","block","slug","Array","isArray","fields"],"mappings":"AAcA,OAAO,SAASA,mBAAmBC,WAAiC;IAClE,OACE,OAAOA,gBAAgB,YACvB,OAAOA,aAAaC,OAAOC,SAAS,YACpCC,MAAMC,OAAO,CAACJ,aAAaC,OAAOI;AAEtC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/plugin-form-builder",
|
|
3
|
-
"version": "3.84.0-canary.
|
|
3
|
+
"version": "3.84.0-canary.2",
|
|
4
4
|
"description": "Form builder plugin for Payload CMS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"payload",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
],
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"escape-html": "^1.0.3",
|
|
56
|
-
"@payloadcms/ui": "3.84.0-canary.
|
|
56
|
+
"@payloadcms/ui": "3.84.0-canary.2"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@types/escape-html": "^1.0.4",
|
|
@@ -62,12 +62,12 @@
|
|
|
62
62
|
"copyfiles": "^2.4.1",
|
|
63
63
|
"cross-env": "^7.0.3",
|
|
64
64
|
"@payloadcms/eslint-config": "3.28.0",
|
|
65
|
-
"payload": "3.84.0-canary.
|
|
65
|
+
"payload": "3.84.0-canary.2"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
68
|
"react": "^19.0.1 || ^19.1.2 || ^19.2.1",
|
|
69
69
|
"react-dom": "^19.0.1 || ^19.1.2 || ^19.2.1",
|
|
70
|
-
"payload": "3.84.0-canary.
|
|
70
|
+
"payload": "3.84.0-canary.2"
|
|
71
71
|
},
|
|
72
72
|
"publishConfig": {
|
|
73
73
|
"registry": "https://registry.npmjs.org/"
|