payload 4.0.0-internal.cd69eef → 4.0.0-internal.d1cc1d3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/RichText.d.ts +1 -1
- package/dist/admin/RichText.d.ts.map +1 -1
- package/dist/admin/RichText.js.map +1 -1
- package/dist/admin/functions/index.d.ts +10 -8
- package/dist/admin/functions/index.d.ts.map +1 -1
- package/dist/admin/functions/index.js.map +1 -1
- package/dist/admin/types.d.ts +2 -2
- package/dist/admin/types.d.ts.map +1 -1
- package/dist/admin/types.js.map +1 -1
- package/dist/auth/endpoints/login.d.ts.map +1 -1
- package/dist/auth/endpoints/login.js +2 -11
- package/dist/auth/endpoints/login.js.map +1 -1
- package/dist/auth/loginWithCookie.d.ts +33 -0
- package/dist/auth/loginWithCookie.d.ts.map +1 -0
- package/dist/auth/loginWithCookie.js +34 -0
- package/dist/auth/loginWithCookie.js.map +1 -0
- package/dist/auth/serverFunctions/cookies.d.ts +47 -0
- package/dist/auth/serverFunctions/cookies.d.ts.map +1 -0
- package/dist/auth/serverFunctions/cookies.js +52 -0
- package/dist/auth/serverFunctions/cookies.js.map +1 -0
- package/dist/auth/serverFunctions/login.d.ts +29 -0
- package/dist/auth/serverFunctions/login.d.ts.map +1 -0
- package/dist/auth/serverFunctions/login.js +63 -0
- package/dist/auth/serverFunctions/login.js.map +1 -0
- package/dist/auth/serverFunctions/logout.d.ts +17 -0
- package/dist/auth/serverFunctions/logout.d.ts.map +1 -0
- package/dist/auth/serverFunctions/logout.js +58 -0
- package/dist/auth/serverFunctions/logout.js.map +1 -0
- package/dist/auth/serverFunctions/refresh.d.ts +17 -0
- package/dist/auth/serverFunctions/refresh.d.ts.map +1 -0
- package/dist/auth/serverFunctions/refresh.js +61 -0
- package/dist/auth/serverFunctions/refresh.js.map +1 -0
- package/dist/collections/config/client.d.ts +2 -3
- package/dist/collections/config/client.d.ts.map +1 -1
- package/dist/collections/config/client.js +5 -7
- package/dist/collections/config/client.js.map +1 -1
- package/dist/collections/config/defaults.d.ts.map +1 -1
- package/dist/collections/config/defaults.js +1 -0
- package/dist/collections/config/defaults.js.map +1 -1
- package/dist/collections/config/sanitize.d.ts +3 -8
- package/dist/collections/config/sanitize.d.ts.map +1 -1
- package/dist/collections/config/sanitize.js +2 -6
- package/dist/collections/config/sanitize.js.map +1 -1
- package/dist/collections/config/types.d.ts +1 -1
- package/dist/collections/config/types.d.ts.map +1 -1
- package/dist/collections/config/types.js.map +1 -1
- package/dist/collections/config/useAsTitle.spec.js +27 -27
- package/dist/collections/config/useAsTitle.spec.js.map +1 -1
- package/dist/collections/operations/create.d.ts.map +1 -1
- package/dist/collections/operations/create.js +10 -0
- package/dist/collections/operations/create.js.map +1 -1
- package/dist/collections/operations/restoreVersion.d.ts.map +1 -1
- package/dist/collections/operations/restoreVersion.js +7 -4
- package/dist/collections/operations/restoreVersion.js.map +1 -1
- package/dist/collections/operations/updateByID.js +1 -0
- package/dist/collections/operations/updateByID.js.map +1 -1
- package/dist/config/build.js +1 -1
- package/dist/config/build.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +5 -2
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/orderable/index.d.ts +1 -1
- package/dist/config/orderable/index.d.ts.map +1 -1
- package/dist/config/orderable/index.js +2 -2
- package/dist/config/orderable/index.js.map +1 -1
- package/dist/config/sanitize.d.ts +1 -1
- package/dist/config/sanitize.d.ts.map +1 -1
- package/dist/config/sanitize.js +33 -40
- package/dist/config/sanitize.js.map +1 -1
- package/dist/config/types.d.ts +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/database/createDatabaseAdapter.d.ts +1 -1
- package/dist/database/createDatabaseAdapter.d.ts.map +1 -1
- package/dist/database/createDatabaseAdapter.js +0 -2
- package/dist/database/createDatabaseAdapter.js.map +1 -1
- package/dist/database/types.d.ts +6 -0
- package/dist/database/types.d.ts.map +1 -1
- package/dist/database/types.js.map +1 -1
- package/dist/exports/auth.d.ts +5 -0
- package/dist/exports/auth.d.ts.map +1 -0
- package/dist/exports/auth.js +6 -0
- package/dist/exports/auth.js.map +1 -0
- package/dist/exports/internal.d.ts +2 -0
- package/dist/exports/internal.d.ts.map +1 -1
- package/dist/exports/internal.js +3 -1
- package/dist/exports/internal.js.map +1 -1
- package/dist/fields/baseFields/slug/duplicateContext.d.ts +11 -0
- package/dist/fields/baseFields/slug/duplicateContext.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/duplicateContext.js +21 -0
- package/dist/fields/baseFields/slug/duplicateContext.js.map +1 -0
- package/dist/fields/baseFields/slug/fillEmptyLocalizedSlugs.d.ts +22 -0
- package/dist/fields/baseFields/slug/fillEmptyLocalizedSlugs.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/fillEmptyLocalizedSlugs.js +63 -0
- package/dist/fields/baseFields/slug/fillEmptyLocalizedSlugs.js.map +1 -0
- package/dist/fields/baseFields/slug/generateSlug.d.ts +13 -8
- package/dist/fields/baseFields/slug/generateSlug.d.ts.map +1 -1
- package/dist/fields/baseFields/slug/generateSlug.js +98 -45
- package/dist/fields/baseFields/slug/generateSlug.js.map +1 -1
- package/dist/fields/baseFields/slug/generateSlugBeforeDuplicate.d.ts +18 -0
- package/dist/fields/baseFields/slug/generateSlugBeforeDuplicate.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/generateSlugBeforeDuplicate.js +20 -0
- package/dist/fields/baseFields/slug/generateSlugBeforeDuplicate.js.map +1 -0
- package/dist/fields/baseFields/slug/getSlugFallbackValue.d.ts +22 -0
- package/dist/fields/baseFields/slug/getSlugFallbackValue.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/getSlugFallbackValue.js +23 -0
- package/dist/fields/baseFields/slug/getSlugFallbackValue.js.map +1 -0
- package/dist/fields/baseFields/slug/hasValue.d.ts +3 -0
- package/dist/fields/baseFields/slug/hasValue.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/hasValue.js +3 -0
- package/dist/fields/baseFields/slug/hasValue.js.map +1 -0
- package/dist/fields/config/reservedFieldNames.spec.js +18 -18
- package/dist/fields/config/reservedFieldNames.spec.js.map +1 -1
- package/dist/fields/config/sanitize.d.ts +3 -9
- package/dist/fields/config/sanitize.d.ts.map +1 -1
- package/dist/fields/config/sanitize.js +33 -34
- package/dist/fields/config/sanitize.js.map +1 -1
- package/dist/fields/config/sanitize.spec.js +128 -105
- package/dist/fields/config/sanitize.spec.js.map +1 -1
- package/dist/fields/config/types.d.ts +4 -3
- package/dist/fields/config/types.d.ts.map +1 -1
- package/dist/fields/config/types.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/promise.d.ts.map +1 -1
- package/dist/fields/hooks/beforeValidate/promise.js +5 -3
- package/dist/fields/hooks/beforeValidate/promise.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/stripNullRows.d.ts +10 -0
- package/dist/fields/hooks/beforeValidate/stripNullRows.d.ts.map +1 -0
- package/dist/fields/hooks/beforeValidate/stripNullRows.js +18 -0
- package/dist/fields/hooks/beforeValidate/stripNullRows.js.map +1 -0
- package/dist/fields/validations.d.ts.map +1 -1
- package/dist/fields/validations.js +7 -8
- package/dist/fields/validations.js.map +1 -1
- package/dist/fields/validations.spec.js +61 -37
- package/dist/fields/validations.spec.js.map +1 -1
- package/dist/globals/config/sanitize.d.ts +2 -7
- package/dist/globals/config/sanitize.d.ts.map +1 -1
- package/dist/globals/config/sanitize.js +2 -6
- package/dist/globals/config/sanitize.js.map +1 -1
- package/dist/globals/config/sanitize.spec.js +6 -6
- package/dist/globals/config/sanitize.spec.js.map +1 -1
- package/dist/globals/operations/countGlobalVersions.d.ts.map +1 -1
- package/dist/globals/operations/countGlobalVersions.js +1 -0
- package/dist/globals/operations/countGlobalVersions.js.map +1 -1
- package/dist/index.bundled.d.ts +247 -178
- package/dist/index.d.ts +49 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/query-presets/constraints.js +1 -1
- package/dist/query-presets/constraints.js.map +1 -1
- package/dist/queues/config/collection.d.ts.map +1 -1
- package/dist/queues/config/collection.js +37 -43
- package/dist/queues/config/collection.js.map +1 -1
- package/dist/queues/config/global.d.ts +5 -6
- package/dist/queues/config/global.d.ts.map +1 -1
- package/dist/queues/config/global.js +1 -1
- package/dist/queues/config/global.js.map +1 -1
- package/dist/queues/config/types/index.d.ts +29 -24
- package/dist/queues/config/types/index.d.ts.map +1 -1
- package/dist/queues/config/types/index.js.map +1 -1
- package/dist/queues/config/types/taskTypes.d.ts +4 -7
- package/dist/queues/config/types/taskTypes.d.ts.map +1 -1
- package/dist/queues/config/types/taskTypes.js.map +1 -1
- package/dist/queues/config/types/workflowJSONTypes.d.ts +10 -9
- package/dist/queues/config/types/workflowJSONTypes.d.ts.map +1 -1
- package/dist/queues/config/types/workflowJSONTypes.js.map +1 -1
- package/dist/queues/config/types/workflowTypes.d.ts +11 -58
- package/dist/queues/config/types/workflowTypes.d.ts.map +1 -1
- package/dist/queues/config/types/workflowTypes.js.map +1 -1
- package/dist/queues/endpoints/handleSchedules.js +1 -1
- package/dist/queues/endpoints/handleSchedules.js.map +1 -1
- package/dist/queues/errors/handleTaskError.js +4 -4
- package/dist/queues/errors/handleTaskError.js.map +1 -1
- package/dist/queues/errors/handleWorkflowError.js +1 -1
- package/dist/queues/errors/handleWorkflowError.js.map +1 -1
- package/dist/queues/errors/index.d.ts +6 -0
- package/dist/queues/errors/index.d.ts.map +1 -1
- package/dist/queues/errors/index.js +5 -0
- package/dist/queues/errors/index.js.map +1 -1
- package/dist/queues/localAPI.d.ts +4 -4
- package/dist/queues/localAPI.d.ts.map +1 -1
- package/dist/queues/localAPI.js +63 -66
- package/dist/queues/localAPI.js.map +1 -1
- package/dist/queues/operations/handleSchedules/countRunnableOrActiveJobsForQueue.d.ts +4 -4
- package/dist/queues/operations/handleSchedules/countRunnableOrActiveJobsForQueue.d.ts.map +1 -1
- package/dist/queues/operations/handleSchedules/countRunnableOrActiveJobsForQueue.js.map +1 -1
- package/dist/queues/operations/handleSchedules/index.d.ts +1 -1
- package/dist/queues/operations/handleSchedules/index.d.ts.map +1 -1
- package/dist/queues/operations/handleSchedules/index.js +1 -1
- package/dist/queues/operations/handleSchedules/index.js.map +1 -1
- package/dist/queues/operations/runJobs/heartbeat.d.ts +13 -0
- package/dist/queues/operations/runJobs/heartbeat.d.ts.map +1 -0
- package/dist/queues/operations/runJobs/heartbeat.js +66 -0
- package/dist/queues/operations/runJobs/heartbeat.js.map +1 -0
- package/dist/queues/operations/runJobs/index.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/index.js +133 -84
- package/dist/queues/operations/runJobs/index.js.map +1 -1
- package/dist/queues/operations/runJobs/runJSONJob/index.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/runJSONJob/index.js +6 -3
- package/dist/queues/operations/runJobs/runJSONJob/index.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js +5 -5
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.d.ts +2 -1
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.js +39 -8
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/importHandlerPath.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/index.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/runJob/index.js +4 -4
- package/dist/queues/operations/runJobs/runJob/index.js.map +1 -1
- package/dist/queues/utilities/updateJob.d.ts.map +1 -1
- package/dist/queues/utilities/updateJob.js +3 -0
- package/dist/queues/utilities/updateJob.js.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/uploads/checkFileRestrictions.d.ts +1 -1
- package/dist/uploads/checkFileRestrictions.d.ts.map +1 -1
- package/dist/uploads/checkFileRestrictions.js +15 -1
- package/dist/uploads/checkFileRestrictions.js.map +1 -1
- package/dist/uploads/endpoints/uploadInstructions.d.ts +12 -0
- package/dist/uploads/endpoints/uploadInstructions.d.ts.map +1 -1
- package/dist/uploads/endpoints/uploadInstructions.js +66 -20
- package/dist/uploads/endpoints/uploadInstructions.js.map +1 -1
- package/dist/uploads/generateFileData.js +4 -1
- package/dist/uploads/generateFileData.js.map +1 -1
- package/dist/uploads/getFileFromUploadInstructions.d.ts +8 -0
- package/dist/uploads/getFileFromUploadInstructions.d.ts.map +1 -0
- package/dist/uploads/getFileFromUploadInstructions.js +62 -0
- package/dist/uploads/getFileFromUploadInstructions.js.map +1 -0
- package/dist/uploads/getImageSize.d.ts +12 -1
- package/dist/uploads/getImageSize.d.ts.map +1 -1
- package/dist/uploads/getImageSize.js +20 -18
- package/dist/uploads/getImageSize.js.map +1 -1
- package/dist/uploads/getImageSize.spec.js +298 -0
- package/dist/uploads/getImageSize.spec.js.map +1 -0
- package/dist/uploads/probeImageSize.d.ts +39 -0
- package/dist/uploads/probeImageSize.d.ts.map +1 -0
- package/dist/uploads/probeImageSize.js +374 -0
- package/dist/uploads/probeImageSize.js.map +1 -0
- package/dist/uploads/probeImageSize.spec.js +366 -0
- package/dist/uploads/probeImageSize.spec.js.map +1 -0
- package/dist/uploads/stagedUpload.d.ts +27 -0
- package/dist/uploads/stagedUpload.d.ts.map +1 -0
- package/dist/uploads/stagedUpload.js +197 -0
- package/dist/uploads/stagedUpload.js.map +1 -0
- package/dist/uploads/types.d.ts +41 -13
- package/dist/uploads/types.d.ts.map +1 -1
- package/dist/uploads/types.js.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.d.ts.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.js +12 -46
- package/dist/utilities/addDataAndFileToRequest.js.map +1 -1
- package/dist/utilities/configToJSONSchema.spec.js +33 -33
- package/dist/utilities/configToJSONSchema.spec.js.map +1 -1
- package/dist/utilities/fieldValueExists.d.ts +29 -0
- package/dist/utilities/fieldValueExists.d.ts.map +1 -0
- package/dist/utilities/fieldValueExists.js +27 -0
- package/dist/utilities/fieldValueExists.js.map +1 -0
- package/dist/utilities/getUniqueFieldValue.d.ts +27 -0
- package/dist/utilities/getUniqueFieldValue.d.ts.map +1 -0
- package/dist/utilities/getUniqueFieldValue.js +26 -0
- package/dist/utilities/getUniqueFieldValue.js.map +1 -0
- package/dist/versions/deleteScheduledPublishJobs.js +2 -2
- package/dist/versions/deleteScheduledPublishJobs.js.map +1 -1
- package/dist/versions/payloadPackageList.d.ts.map +1 -1
- package/dist/versions/payloadPackageList.js +0 -1
- package/dist/versions/payloadPackageList.js.map +1 -1
- package/package.json +8 -3
- package/dist/database/defaultUpdateJobs.d.ts +0 -3
- package/dist/database/defaultUpdateJobs.d.ts.map +0 -1
- package/dist/database/defaultUpdateJobs.js +0 -41
- package/dist/database/defaultUpdateJobs.js.map +0 -1
- package/dist/fields/baseFields/slug/countVersions.d.ts +0 -13
- package/dist/fields/baseFields/slug/countVersions.d.ts.map +0 -1
- package/dist/fields/baseFields/slug/countVersions.js +0 -27
- package/dist/fields/baseFields/slug/countVersions.js.map +0 -1
- package/dist/uploads/tempFile.d.ts +0 -7
- package/dist/uploads/tempFile.d.ts.map +0 -1
- package/dist/uploads/tempFile.js +0 -39
- package/dist/uploads/tempFile.js.map +0 -1
|
@@ -12,7 +12,7 @@ describe('reservedFieldNames - collections -', ()=>{
|
|
|
12
12
|
fields: [],
|
|
13
13
|
upload: true
|
|
14
14
|
};
|
|
15
|
-
it('should throw on file',
|
|
15
|
+
it('should throw on file', ()=>{
|
|
16
16
|
const fields = [
|
|
17
17
|
{
|
|
18
18
|
name: 'file',
|
|
@@ -20,8 +20,8 @@ describe('reservedFieldNames - collections -', ()=>{
|
|
|
20
20
|
label: 'some-collection'
|
|
21
21
|
}
|
|
22
22
|
];
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
expect(()=>{
|
|
24
|
+
sanitizeCollection(// @ts-expect-error
|
|
25
25
|
{
|
|
26
26
|
...config,
|
|
27
27
|
collections: [
|
|
@@ -34,9 +34,9 @@ describe('reservedFieldNames - collections -', ()=>{
|
|
|
34
34
|
...collectionWithUploads,
|
|
35
35
|
fields
|
|
36
36
|
});
|
|
37
|
-
}).
|
|
37
|
+
}).toThrow(ReservedFieldName);
|
|
38
38
|
});
|
|
39
|
-
it('should not throw on a custom field',
|
|
39
|
+
it('should not throw on a custom field', ()=>{
|
|
40
40
|
const fields = [
|
|
41
41
|
{
|
|
42
42
|
name: 'customField',
|
|
@@ -44,8 +44,8 @@ describe('reservedFieldNames - collections -', ()=>{
|
|
|
44
44
|
label: 'some-collection'
|
|
45
45
|
}
|
|
46
46
|
];
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
expect(()=>{
|
|
48
|
+
sanitizeCollection(// @ts-expect-error
|
|
49
49
|
{
|
|
50
50
|
...config,
|
|
51
51
|
collections: [
|
|
@@ -71,7 +71,7 @@ describe('reservedFieldNames - collections -', ()=>{
|
|
|
71
71
|
},
|
|
72
72
|
fields: []
|
|
73
73
|
};
|
|
74
|
-
it('should throw on hash',
|
|
74
|
+
it('should throw on hash', ()=>{
|
|
75
75
|
const fields = [
|
|
76
76
|
{
|
|
77
77
|
name: 'hash',
|
|
@@ -79,8 +79,8 @@ describe('reservedFieldNames - collections -', ()=>{
|
|
|
79
79
|
label: 'some-collection'
|
|
80
80
|
}
|
|
81
81
|
];
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
expect(()=>{
|
|
83
|
+
sanitizeCollection(// @ts-expect-error
|
|
84
84
|
{
|
|
85
85
|
...config,
|
|
86
86
|
collections: [
|
|
@@ -93,9 +93,9 @@ describe('reservedFieldNames - collections -', ()=>{
|
|
|
93
93
|
...collectionWithAuth,
|
|
94
94
|
fields
|
|
95
95
|
});
|
|
96
|
-
}).
|
|
96
|
+
}).toThrow(ReservedFieldName);
|
|
97
97
|
});
|
|
98
|
-
it('should throw on salt',
|
|
98
|
+
it('should throw on salt', ()=>{
|
|
99
99
|
const fields = [
|
|
100
100
|
{
|
|
101
101
|
name: 'salt',
|
|
@@ -103,8 +103,8 @@ describe('reservedFieldNames - collections -', ()=>{
|
|
|
103
103
|
label: 'some-collection'
|
|
104
104
|
}
|
|
105
105
|
];
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
expect(()=>{
|
|
107
|
+
sanitizeCollection(// @ts-expect-error
|
|
108
108
|
{
|
|
109
109
|
...config,
|
|
110
110
|
collections: [
|
|
@@ -117,9 +117,9 @@ describe('reservedFieldNames - collections -', ()=>{
|
|
|
117
117
|
...collectionWithAuth,
|
|
118
118
|
fields
|
|
119
119
|
});
|
|
120
|
-
}).
|
|
120
|
+
}).toThrow(ReservedFieldName);
|
|
121
121
|
});
|
|
122
|
-
it('should not throw on a custom field',
|
|
122
|
+
it('should not throw on a custom field', ()=>{
|
|
123
123
|
const fields = [
|
|
124
124
|
{
|
|
125
125
|
name: 'customField',
|
|
@@ -127,8 +127,8 @@ describe('reservedFieldNames - collections -', ()=>{
|
|
|
127
127
|
label: 'some-collection'
|
|
128
128
|
}
|
|
129
129
|
];
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
expect(()=>{
|
|
131
|
+
sanitizeCollection(// @ts-expect-error
|
|
132
132
|
{
|
|
133
133
|
...config,
|
|
134
134
|
collections: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fields/config/reservedFieldNames.spec.ts"],"sourcesContent":["import type { Config } from '../../config/types.js'\nimport type { CollectionConfig, Field } from '../../index.js'\n\nimport { ReservedFieldName } from '../../errors/index.js'\nimport { sanitizeCollection } from '../../collections/config/sanitize.js'\nimport { describe, it, expect } from 'vitest'\n\ndescribe('reservedFieldNames - collections -', () => {\n const config = {\n collections: [],\n globals: [],\n } as Partial<Config>\n\n describe('uploads -', () => {\n const collectionWithUploads: CollectionConfig = {\n slug: 'collection-with-uploads',\n fields: [],\n upload: true,\n }\n\n it('should throw on file',
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/config/reservedFieldNames.spec.ts"],"sourcesContent":["import type { Config } from '../../config/types.js'\nimport type { CollectionConfig, Field } from '../../index.js'\n\nimport { ReservedFieldName } from '../../errors/index.js'\nimport { sanitizeCollection } from '../../collections/config/sanitize.js'\nimport { describe, it, expect } from 'vitest'\n\ndescribe('reservedFieldNames - collections -', () => {\n const config = {\n collections: [],\n globals: [],\n } as Partial<Config>\n\n describe('uploads -', () => {\n const collectionWithUploads: CollectionConfig = {\n slug: 'collection-with-uploads',\n fields: [],\n upload: true,\n }\n\n it('should throw on file', () => {\n const fields: Field[] = [\n {\n name: 'file',\n type: 'text',\n label: 'some-collection',\n },\n ]\n\n expect(() => {\n sanitizeCollection(\n // @ts-expect-error\n {\n ...config,\n collections: [\n {\n ...collectionWithUploads,\n fields,\n },\n ],\n },\n {\n ...collectionWithUploads,\n fields,\n },\n )\n }).toThrow(ReservedFieldName)\n })\n\n it('should not throw on a custom field', () => {\n const fields: Field[] = [\n {\n name: 'customField',\n type: 'text',\n label: 'some-collection',\n },\n ]\n\n expect(() => {\n sanitizeCollection(\n // @ts-expect-error\n {\n ...config,\n collections: [\n {\n ...collectionWithUploads,\n fields,\n },\n ],\n },\n {\n ...collectionWithUploads,\n fields,\n },\n )\n }).not.toThrow()\n })\n })\n\n describe('auth -', () => {\n const collectionWithAuth: CollectionConfig = {\n slug: 'collection-with-auth',\n auth: {\n loginWithUsername: true,\n useAPIKey: true,\n verify: true,\n },\n fields: [],\n }\n\n it('should throw on hash', () => {\n const fields: Field[] = [\n {\n name: 'hash',\n type: 'text',\n label: 'some-collection',\n },\n ]\n\n expect(() => {\n sanitizeCollection(\n // @ts-expect-error\n {\n ...config,\n collections: [\n {\n ...collectionWithAuth,\n fields,\n },\n ],\n },\n {\n ...collectionWithAuth,\n fields,\n },\n )\n }).toThrow(ReservedFieldName)\n })\n\n it('should throw on salt', () => {\n const fields: Field[] = [\n {\n name: 'salt',\n type: 'text',\n label: 'some-collection',\n },\n ]\n\n expect(() => {\n sanitizeCollection(\n // @ts-expect-error\n {\n ...config,\n collections: [\n {\n ...collectionWithAuth,\n fields,\n },\n ],\n },\n {\n ...collectionWithAuth,\n fields,\n },\n )\n }).toThrow(ReservedFieldName)\n })\n\n it('should not throw on a custom field', () => {\n const fields: Field[] = [\n {\n name: 'customField',\n type: 'text',\n label: 'some-collection',\n },\n ]\n\n expect(() => {\n sanitizeCollection(\n // @ts-expect-error\n {\n ...config,\n collections: [\n {\n ...collectionWithAuth,\n fields,\n },\n ],\n },\n {\n ...collectionWithAuth,\n fields,\n },\n )\n }).not.toThrow()\n })\n })\n})\n"],"names":["ReservedFieldName","sanitizeCollection","describe","it","expect","config","collections","globals","collectionWithUploads","slug","fields","upload","name","type","label","toThrow","not","collectionWithAuth","auth","loginWithUsername","useAPIKey","verify"],"mappings":"AAGA,SAASA,iBAAiB,QAAQ,wBAAuB;AACzD,SAASC,kBAAkB,QAAQ,uCAAsC;AACzE,SAASC,QAAQ,EAAEC,EAAE,EAAEC,MAAM,QAAQ,SAAQ;AAE7CF,SAAS,sCAAsC;IAC7C,MAAMG,SAAS;QACbC,aAAa,EAAE;QACfC,SAAS,EAAE;IACb;IAEAL,SAAS,aAAa;QACpB,MAAMM,wBAA0C;YAC9CC,MAAM;YACNC,QAAQ,EAAE;YACVC,QAAQ;QACV;QAEAR,GAAG,wBAAwB;YACzB,MAAMO,SAAkB;gBACtB;oBACEE,MAAM;oBACNC,MAAM;oBACNC,OAAO;gBACT;aACD;YAEDV,OAAO;gBACLH,mBACE,mBAAmB;gBACnB;oBACE,GAAGI,MAAM;oBACTC,aAAa;wBACX;4BACE,GAAGE,qBAAqB;4BACxBE;wBACF;qBACD;gBACH,GACA;oBACE,GAAGF,qBAAqB;oBACxBE;gBACF;YAEJ,GAAGK,OAAO,CAACf;QACb;QAEAG,GAAG,sCAAsC;YACvC,MAAMO,SAAkB;gBACtB;oBACEE,MAAM;oBACNC,MAAM;oBACNC,OAAO;gBACT;aACD;YAEDV,OAAO;gBACLH,mBACE,mBAAmB;gBACnB;oBACE,GAAGI,MAAM;oBACTC,aAAa;wBACX;4BACE,GAAGE,qBAAqB;4BACxBE;wBACF;qBACD;gBACH,GACA;oBACE,GAAGF,qBAAqB;oBACxBE;gBACF;YAEJ,GAAGM,GAAG,CAACD,OAAO;QAChB;IACF;IAEAb,SAAS,UAAU;QACjB,MAAMe,qBAAuC;YAC3CR,MAAM;YACNS,MAAM;gBACJC,mBAAmB;gBACnBC,WAAW;gBACXC,QAAQ;YACV;YACAX,QAAQ,EAAE;QACZ;QAEAP,GAAG,wBAAwB;YACzB,MAAMO,SAAkB;gBACtB;oBACEE,MAAM;oBACNC,MAAM;oBACNC,OAAO;gBACT;aACD;YAEDV,OAAO;gBACLH,mBACE,mBAAmB;gBACnB;oBACE,GAAGI,MAAM;oBACTC,aAAa;wBACX;4BACE,GAAGW,kBAAkB;4BACrBP;wBACF;qBACD;gBACH,GACA;oBACE,GAAGO,kBAAkB;oBACrBP;gBACF;YAEJ,GAAGK,OAAO,CAACf;QACb;QAEAG,GAAG,wBAAwB;YACzB,MAAMO,SAAkB;gBACtB;oBACEE,MAAM;oBACNC,MAAM;oBACNC,OAAO;gBACT;aACD;YAEDV,OAAO;gBACLH,mBACE,mBAAmB;gBACnB;oBACE,GAAGI,MAAM;oBACTC,aAAa;wBACX;4BACE,GAAGW,kBAAkB;4BACrBP;wBACF;qBACD;gBACH,GACA;oBACE,GAAGO,kBAAkB;oBACrBP;gBACF;YAEJ,GAAGK,OAAO,CAACf;QACb;QAEAG,GAAG,sCAAsC;YACvC,MAAMO,SAAkB;gBACtB;oBACEE,MAAM;oBACNC,MAAM;oBACNC,OAAO;gBACT;aACD;YAEDV,OAAO;gBACLH,mBACE,mBAAmB;gBACnB;oBACE,GAAGI,MAAM;oBACTC,aAAa;wBACX;4BACE,GAAGW,kBAAkB;4BACrBP;wBACF;qBACD;gBACH,GACA;oBACE,GAAGO,kBAAkB;oBACrBP;gBACF;YAEJ,GAAGM,GAAG,CAACD,OAAO;QAChB;IACF;AACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CollectionConfig, SanitizedJoin, SanitizedJoins } from '../../collections/config/types.js';
|
|
2
|
-
import type { Config
|
|
2
|
+
import type { Config } from '../../config/types.js';
|
|
3
3
|
import type { GlobalConfig } from '../../globals/config/types.js';
|
|
4
4
|
import type { OrderableJoinInfo } from './sanitizeJoinField.js';
|
|
5
5
|
import type { Field } from './types.js';
|
|
@@ -39,11 +39,6 @@ type SanitizeFieldsArgs = {
|
|
|
39
39
|
* @default false
|
|
40
40
|
*/
|
|
41
41
|
requireFieldLevelRichTextEditor?: boolean;
|
|
42
|
-
/**
|
|
43
|
-
* If this property is set, RichText fields won't be sanitized immediately. Instead, they will be added to this array as promises
|
|
44
|
-
* so that you can sanitize them together, after the config has been sanitized.
|
|
45
|
-
*/
|
|
46
|
-
richTextSanitizationPromises?: Array<(config: SanitizedConfig) => Promise<void>>;
|
|
47
42
|
/**
|
|
48
43
|
* If not null, will validate that upload and relationship fields do not relate to a collection that is not in this array.
|
|
49
44
|
* This validation will be skipped if validRelationships is null.
|
|
@@ -78,7 +73,6 @@ export type SanitizeFieldArgs = {
|
|
|
78
73
|
parentSchemaPath: string;
|
|
79
74
|
polymorphicJoins?: SanitizedJoin[];
|
|
80
75
|
requireFieldLevelRichTextEditor: boolean;
|
|
81
|
-
richTextSanitizationPromises?: Array<(config: SanitizedConfig) => Promise<void>>;
|
|
82
76
|
validRelationships: null | string[];
|
|
83
77
|
};
|
|
84
78
|
type SanitizeFieldResult = {
|
|
@@ -96,7 +90,7 @@ type SanitizeFieldResult = {
|
|
|
96
90
|
*
|
|
97
91
|
* @returns Result containing any fields to insert after this one
|
|
98
92
|
*/
|
|
99
|
-
export declare const sanitizeField: ({ collectionConfig, config, existingFieldNames, field, globalConfig, index, isTopLevelField, joinPath, joins, orderableJoins, parentIndexPath, parentIsLocalized, parentSchemaPath, polymorphicJoins, requireFieldLevelRichTextEditor,
|
|
100
|
-
export declare const sanitizeFields: ({ collectionConfig, config, existingFieldNames, fields, globalConfig, isTopLevelField, joinPath, joins, orderableJoins, parentIndexPath, parentIsLocalized, parentSchemaPath, polymorphicJoins, requireFieldLevelRichTextEditor,
|
|
93
|
+
export declare const sanitizeField: ({ collectionConfig, config, existingFieldNames, field, globalConfig, index, isTopLevelField, joinPath, joins, orderableJoins, parentIndexPath, parentIsLocalized, parentSchemaPath, polymorphicJoins, requireFieldLevelRichTextEditor, validRelationships, }: SanitizeFieldArgs) => SanitizeFieldResult;
|
|
94
|
+
export declare const sanitizeFields: ({ collectionConfig, config, existingFieldNames, fields, globalConfig, isTopLevelField, joinPath, joins, orderableJoins, parentIndexPath, parentIsLocalized, parentSchemaPath, polymorphicJoins, requireFieldLevelRichTextEditor, validRelationships, }: SanitizeFieldsArgs) => Field[];
|
|
101
95
|
export {};
|
|
102
96
|
//# sourceMappingURL=sanitize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../../src/fields/config/sanitize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,cAAc,EACf,MAAM,mCAAmC,CAAA;AAC1C,OAAO,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../../src/fields/config/sanitize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,cAAc,EACf,MAAM,mCAAmC,CAAA;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,uBAAuB,CAAA;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAgCvC,KAAK,kBAAkB,GAAG;IACxB,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAChC,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB;;OAEG;IACH,cAAc,CAAC,EAAE,iBAAiB,EAAE,CAAA;IACpC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iBAAiB,EAAE,OAAO,CAAA;IAC1B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,aAAa,EAAE,CAAA;IAClC;;;;OAIG;IACH,+BAA+B,CAAC,EAAE,OAAO,CAAA;IACzC;;;OAGG;IACH,kBAAkB,EAAE,IAAI,GAAG,MAAM,EAAE,CAAA;CACpC,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC/B,KAAK,EAAE,KAAK,CAAA;IACZ,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,eAAe,EAAE,OAAO,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB;;OAEG;IACH,cAAc,CAAC,EAAE,iBAAiB,EAAE,CAAA;IACpC,eAAe,EAAE,MAAM,CAAA;IACvB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,gBAAgB,EAAE,MAAM,CAAA;IACxB,gBAAgB,CAAC,EAAE,aAAa,EAAE,CAAA;IAClC,+BAA+B,EAAE,OAAO,CAAA;IACxC,kBAAkB,EAAE,IAAI,GAAG,MAAM,EAAE,CAAA;CACpC,CAAA;AAED,KAAK,mBAAmB,GAAG;IACzB;;OAEG;IACH,cAAc,CAAC,EAAE,KAAK,EAAE,CAAA;CACzB,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,iQAiBvB,iBAAiB,KAAG,mBAgetB,CAAA;AAED,eAAO,MAAM,cAAc,2PAgBxB,kBAAkB,KAAG,KAAK,EAoC5B,CAAA"}
|
|
@@ -6,6 +6,7 @@ import { validateTimezones } from '../../utilities/validateTimezones.js';
|
|
|
6
6
|
import { baseBlockFields } from '../baseFields/baseBlockFields.js';
|
|
7
7
|
import { baseIDField } from '../baseFields/baseIDField.js';
|
|
8
8
|
import { generateSlug } from '../baseFields/slug/generateSlug.js';
|
|
9
|
+
import { generateSlugBeforeDuplicate } from '../baseFields/slug/generateSlugBeforeDuplicate.js';
|
|
9
10
|
import { baseTimezoneField } from '../baseFields/timezone/baseField.js';
|
|
10
11
|
import { defaultTimezones } from '../baseFields/timezone/defaultTimezones.js';
|
|
11
12
|
import { getFieldPaths } from '../getFieldPaths.js';
|
|
@@ -22,7 +23,7 @@ import { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } f
|
|
|
22
23
|
* - Recursive sanitization of nested fields
|
|
23
24
|
*
|
|
24
25
|
* @returns Result containing any fields to insert after this one
|
|
25
|
-
*/ export const sanitizeField =
|
|
26
|
+
*/ export const sanitizeField = ({ collectionConfig, config, existingFieldNames, field, globalConfig, index, isTopLevelField, joinPath, joins, orderableJoins, parentIndexPath, parentIsLocalized, parentSchemaPath, polymorphicJoins, requireFieldLevelRichTextEditor, validRelationships })=>{
|
|
26
27
|
const result = {};
|
|
27
28
|
if ('_sanitized' in field && field._sanitized === true) {
|
|
28
29
|
return result;
|
|
@@ -115,9 +116,9 @@ import { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } f
|
|
|
115
116
|
// Slug field: apply defaults, attach generation hook, expose slugify to the server fn.
|
|
116
117
|
if (field.type === 'slug') {
|
|
117
118
|
const useAsSlug = field.useAsSlug;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
// Required by default so the admin marks the slug as required. The value is always populated by
|
|
120
|
+
// the field hooks (source or id fallback), and validations.slug permits empty so the fallback
|
|
121
|
+
// isn't blocked before it runs.
|
|
121
122
|
if (typeof field.required === 'undefined') {
|
|
122
123
|
field.required = true;
|
|
123
124
|
}
|
|
@@ -144,11 +145,21 @@ import { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } f
|
|
|
144
145
|
field.hooks.beforeChange = [
|
|
145
146
|
generateSlug({
|
|
146
147
|
name: field.name,
|
|
148
|
+
localized: field.localized,
|
|
147
149
|
slugify: field.slugify,
|
|
148
150
|
useAsSlug
|
|
149
151
|
}),
|
|
150
152
|
...field.hooks.beforeChange || []
|
|
151
153
|
];
|
|
154
|
+
// Own the slug on duplicate — the copy takes a fresh `<singular>-<N>` fallback rather than the
|
|
155
|
+
// generic ` - Copy` default, which isn't collision-safe across repeated duplicates of the same
|
|
156
|
+
// source. Runs per-locale for a localized slug.
|
|
157
|
+
field.hooks.beforeDuplicate = [
|
|
158
|
+
generateSlugBeforeDuplicate({
|
|
159
|
+
name: field.name
|
|
160
|
+
}),
|
|
161
|
+
...field.hooks.beforeDuplicate || []
|
|
162
|
+
];
|
|
152
163
|
}
|
|
153
164
|
// Array ID field
|
|
154
165
|
if (field.type === 'array' && field.fields) {
|
|
@@ -206,28 +217,20 @@ import { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } f
|
|
|
206
217
|
}
|
|
207
218
|
// Make sure that the richText field has an editor
|
|
208
219
|
if (field.type === 'richText') {
|
|
209
|
-
|
|
210
|
-
if (
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
throw new MissingEditorProp(field) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor
|
|
216
|
-
;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
if (typeof field.editor === 'function') {
|
|
220
|
-
field.editor = await field.editor({
|
|
221
|
-
config: _config,
|
|
222
|
-
isRoot: requireFieldLevelRichTextEditor,
|
|
223
|
-
parentIsLocalized: parentIsLocalized || field.localized
|
|
224
|
-
});
|
|
220
|
+
if (!field.editor) {
|
|
221
|
+
if (config.editor && !requireFieldLevelRichTextEditor) {
|
|
222
|
+
field.editor = config.editor;
|
|
223
|
+
} else {
|
|
224
|
+
throw new MissingEditorProp(field) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor
|
|
225
|
+
;
|
|
225
226
|
}
|
|
226
|
-
}
|
|
227
|
-
if (
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
227
|
+
}
|
|
228
|
+
if (typeof field.editor === 'function') {
|
|
229
|
+
field.editor = field.editor({
|
|
230
|
+
config: config,
|
|
231
|
+
isRoot: requireFieldLevelRichTextEditor,
|
|
232
|
+
parentIsLocalized: parentIsLocalized || field.localized
|
|
233
|
+
});
|
|
231
234
|
}
|
|
232
235
|
}
|
|
233
236
|
if (field.type === 'blocks' && field.blocks) {
|
|
@@ -247,7 +250,7 @@ import { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } f
|
|
|
247
250
|
block._sanitized = true;
|
|
248
251
|
block.fields = block.fields.concat(baseBlockFields);
|
|
249
252
|
block.labels = !block.labels ? formatLabels(block.slug) : block.labels;
|
|
250
|
-
block.fields =
|
|
253
|
+
block.fields = sanitizeFields({
|
|
251
254
|
collectionConfig,
|
|
252
255
|
config,
|
|
253
256
|
existingFieldNames: new Set(),
|
|
@@ -257,13 +260,12 @@ import { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } f
|
|
|
257
260
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
258
261
|
parentSchemaPath: schemaPath + '.' + block.slug,
|
|
259
262
|
requireFieldLevelRichTextEditor,
|
|
260
|
-
richTextSanitizationPromises,
|
|
261
263
|
validRelationships
|
|
262
264
|
});
|
|
263
265
|
}
|
|
264
266
|
}
|
|
265
267
|
if ('fields' in field && field.fields) {
|
|
266
|
-
field.fields =
|
|
268
|
+
field.fields = sanitizeFields({
|
|
267
269
|
collectionConfig,
|
|
268
270
|
config,
|
|
269
271
|
existingFieldNames: fieldAffectsData ? new Set() : existingFieldNames,
|
|
@@ -277,7 +279,6 @@ import { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } f
|
|
|
277
279
|
parentSchemaPath: schemaPath,
|
|
278
280
|
polymorphicJoins,
|
|
279
281
|
requireFieldLevelRichTextEditor,
|
|
280
|
-
richTextSanitizationPromises,
|
|
281
282
|
validRelationships
|
|
282
283
|
});
|
|
283
284
|
}
|
|
@@ -297,7 +298,7 @@ import { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } f
|
|
|
297
298
|
if ('admin' in tab && tab.admin?.condition && typeof tab.admin.condition === 'function' && !tab.id) {
|
|
298
299
|
tab.id = tabSchemaPath;
|
|
299
300
|
}
|
|
300
|
-
tab.fields =
|
|
301
|
+
tab.fields = sanitizeFields({
|
|
301
302
|
collectionConfig,
|
|
302
303
|
config,
|
|
303
304
|
existingFieldNames: isNamedTab ? new Set() : existingFieldNames,
|
|
@@ -311,7 +312,6 @@ import { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } f
|
|
|
311
312
|
parentSchemaPath: tabSchemaPath,
|
|
312
313
|
polymorphicJoins,
|
|
313
314
|
requireFieldLevelRichTextEditor,
|
|
314
|
-
richTextSanitizationPromises,
|
|
315
315
|
validRelationships
|
|
316
316
|
});
|
|
317
317
|
field.tabs[j] = tab;
|
|
@@ -400,13 +400,13 @@ import { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } f
|
|
|
400
400
|
}
|
|
401
401
|
return result;
|
|
402
402
|
};
|
|
403
|
-
export const sanitizeFields =
|
|
403
|
+
export const sanitizeFields = ({ collectionConfig, config, existingFieldNames = new Set(), fields, globalConfig, isTopLevelField = true, joinPath = '', joins, orderableJoins, parentIndexPath = '', parentIsLocalized, parentSchemaPath = '', polymorphicJoins, requireFieldLevelRichTextEditor = false, validRelationships })=>{
|
|
404
404
|
if (!fields) {
|
|
405
405
|
return [];
|
|
406
406
|
}
|
|
407
407
|
for(let i = 0; i < fields.length; i++){
|
|
408
408
|
const field = fields[i];
|
|
409
|
-
const result =
|
|
409
|
+
const result = sanitizeField({
|
|
410
410
|
collectionConfig,
|
|
411
411
|
config,
|
|
412
412
|
existingFieldNames,
|
|
@@ -422,7 +422,6 @@ export const sanitizeFields = async ({ collectionConfig, config, existingFieldNa
|
|
|
422
422
|
parentSchemaPath,
|
|
423
423
|
polymorphicJoins,
|
|
424
424
|
requireFieldLevelRichTextEditor,
|
|
425
|
-
richTextSanitizationPromises,
|
|
426
425
|
validRelationships
|
|
427
426
|
});
|
|
428
427
|
fields[i] = field;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fields/config/sanitize.ts"],"sourcesContent":["import type {\n CollectionConfig,\n SanitizedJoin,\n SanitizedJoins,\n} from '../../collections/config/types.js'\nimport type { Config, SanitizedConfig } from '../../config/types.js'\nimport type { GlobalConfig } from '../../globals/config/types.js'\nimport type { OrderableJoinInfo } from './sanitizeJoinField.js'\nimport type { Field } from './types.js'\n\nimport {\n DuplicateFieldName,\n InvalidConfiguration,\n InvalidFieldName,\n InvalidFieldRelationship,\n MissingEditorProp,\n MissingFieldType,\n} from '../../errors/index.js'\nimport { ReservedFieldName } from '../../errors/ReservedFieldName.js'\nimport { flattenAllFields } from '../../utilities/flattenAllFields.js'\nimport { formatLabels, toWords } from '../../utilities/formatLabels.js'\nimport { validateTimezones } from '../../utilities/validateTimezones.js'\nimport { baseBlockFields } from '../baseFields/baseBlockFields.js'\nimport { baseIDField } from '../baseFields/baseIDField.js'\nimport { generateSlug } from '../baseFields/slug/generateSlug.js'\nimport { baseTimezoneField } from '../baseFields/timezone/baseField.js'\nimport { defaultTimezones } from '../baseFields/timezone/defaultTimezones.js'\nimport { getFieldPaths } from '../getFieldPaths.js'\nimport { setDefaultBeforeDuplicate } from '../setDefaultBeforeDuplicate.js'\nimport { validations } from '../validations.js'\nimport {\n reservedAPIKeyFieldNames,\n reservedBaseAuthFieldNames,\n reservedBaseUploadFieldNames,\n reservedVerifyFieldNames,\n} from './reservedFieldNames.js'\nimport { sanitizeJoinField } from './sanitizeJoinField.js'\nimport { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } from './types.js'\n\ntype SanitizeFieldsArgs = {\n collectionConfig?: CollectionConfig\n config: Config\n existingFieldNames?: Set<string>\n fields: Field[]\n globalConfig?: GlobalConfig\n /**\n * Used to prevent unnecessary sanitization of fields that are not top-level.\n */\n isTopLevelField?: boolean\n joinPath?: string\n /**\n * When not passed in, assume that join are not supported (globals, arrays, blocks)\n */\n joins?: SanitizedJoins\n /**\n * Tracker for orderable join fields - populated during sanitization\n */\n orderableJoins?: OrderableJoinInfo[]\n /**\n * A string of '-' separated indexes representing where\n * to find this field in a given field schema array.\n */\n parentIndexPath?: string\n parentIsLocalized: boolean\n /**\n * Path for parent fields relative to their position in the schema.\n */\n parentSchemaPath?: string\n polymorphicJoins?: SanitizedJoin[]\n /**\n * If true, a richText field will require an editor property to be set, as the sanitizeFields function will not add it from the payload config if not present.\n *\n * @default false\n */\n requireFieldLevelRichTextEditor?: boolean\n /**\n * If this property is set, RichText fields won't be sanitized immediately. Instead, they will be added to this array as promises\n * so that you can sanitize them together, after the config has been sanitized.\n */\n richTextSanitizationPromises?: Array<(config: SanitizedConfig) => Promise<void>>\n /**\n * If not null, will validate that upload and relationship fields do not relate to a collection that is not in this array.\n * This validation will be skipped if validRelationships is null.\n */\n validRelationships: null | string[]\n}\n\nexport type SanitizeFieldArgs = {\n collectionConfig?: CollectionConfig\n config: Config\n existingFieldNames: Set<string>\n field: Field\n globalConfig?: GlobalConfig\n /**\n * The index of this field in the parent fields array\n */\n index: number\n /**\n * Used to prevent unnecessary sanitization of fields that are not top-level.\n */\n isTopLevelField: boolean\n joinPath: string\n /**\n * When not passed in, assume that joins are not supported (globals, arrays, blocks)\n */\n joins?: SanitizedJoins\n /**\n * Tracker for orderable join fields - populated during sanitization\n */\n orderableJoins?: OrderableJoinInfo[]\n parentIndexPath: string\n parentIsLocalized: boolean\n parentSchemaPath: string\n polymorphicJoins?: SanitizedJoin[]\n requireFieldLevelRichTextEditor: boolean\n richTextSanitizationPromises?: Array<(config: SanitizedConfig) => Promise<void>>\n validRelationships: null | string[]\n}\n\ntype SanitizeFieldResult = {\n /**\n * Fields to insert after this field (e.g., timezone field)\n */\n fieldsToInsert?: Field[]\n}\n\n/**\n * Sanitize a single field. Handles all per-field logic including:\n * - Validation setup\n * - Hooks/access/admin defaults\n * - Type-specific handling\n * - Recursive sanitization of nested fields\n *\n * @returns Result containing any fields to insert after this one\n */\nexport const sanitizeField = async ({\n collectionConfig,\n config,\n existingFieldNames,\n field,\n globalConfig,\n index,\n isTopLevelField,\n joinPath,\n joins,\n orderableJoins,\n parentIndexPath,\n parentIsLocalized,\n parentSchemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n}: SanitizeFieldArgs): Promise<SanitizeFieldResult> => {\n const result: SanitizeFieldResult = {}\n\n if ('_sanitized' in field && field._sanitized === true) {\n return result\n }\n\n if ('_sanitized' in field) {\n field._sanitized = true\n }\n\n if (!field.type) {\n throw new MissingFieldType(field)\n }\n\n const fieldAffectsData = _fieldAffectsData(field)\n\n const { indexPath, schemaPath } = getFieldPaths({\n field,\n index,\n parentIndexPath,\n parentSchemaPath,\n })\n\n // Reserved field name checks\n if (isTopLevelField && fieldAffectsData && field.name) {\n if (collectionConfig && collectionConfig.upload) {\n if (reservedBaseUploadFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n }\n\n if (\n collectionConfig &&\n collectionConfig.auth &&\n typeof collectionConfig.auth === 'object' &&\n !collectionConfig.auth.disableLocalStrategy\n ) {\n if (reservedBaseAuthFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n\n if (collectionConfig.auth.verify) {\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n if (reservedAPIKeyFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n if (reservedVerifyFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n }\n }\n }\n\n // Invalid field name check\n if (fieldAffectsData && field.name.includes('.')) {\n throw new InvalidFieldName(field, field.name)\n }\n\n // Auto-label\n if (\n 'name' in field &&\n field.name &&\n typeof field.label !== 'object' &&\n typeof field.label !== 'string' &&\n typeof field.label !== 'function' &&\n field.label !== false\n ) {\n field.label = toWords(field.name)\n }\n\n // Checkbox default\n if (\n field.type === 'checkbox' &&\n typeof field.defaultValue === 'undefined' &&\n field.required === true\n ) {\n field.defaultValue = false\n }\n\n // Join field sanitization\n if (field.type === 'join') {\n sanitizeJoinField({\n config,\n field,\n joinPath,\n joins,\n orderableJoins,\n parentIsLocalized,\n polymorphicJoins,\n })\n }\n\n // Relationship/upload validation\n if (field.type === 'relationship' || field.type === 'upload') {\n if (Array.isArray(field.relationTo) && field.relationTo.length === 0) {\n throw new Error(\n `Field \"${field.name}\" of type \"${field.type}\" has an empty relationTo array. At least one collection must be specified.`,\n )\n }\n\n if (validRelationships) {\n const relationships = Array.isArray(field.relationTo) ? field.relationTo : [field.relationTo]\n\n relationships.forEach((relationship: string) => {\n if (!validRelationships.includes(relationship)) {\n throw new InvalidFieldRelationship(field, relationship)\n }\n })\n }\n }\n\n // Upload isSortable default\n if (field.type === 'upload') {\n if (!field.admin || !('isSortable' in field.admin)) {\n field.admin = {\n isSortable: true,\n ...field.admin,\n }\n }\n }\n\n // Slug field: apply defaults, attach generation hook, expose slugify to the server fn.\n if (field.type === 'slug') {\n const useAsSlug = field.useAsSlug\n\n if (!useAsSlug) {\n throw new InvalidConfiguration(\n `The slug field \"${field.name}\" is missing the required \"useAsSlug\" property, which must name the field to generate the slug from.`,\n )\n }\n\n if (typeof field.required === 'undefined') {\n field.required = true\n }\n if (typeof field.unique === 'undefined') {\n field.unique = true\n }\n if (typeof field.index === 'undefined') {\n field.index = true\n }\n\n field.admin = {\n position: 'sidebar',\n ...field.admin,\n }\n\n // The slugifyHandler server function resolves the custom slugify by field path.\n if (field.slugify) {\n field.custom = {\n ...field.custom,\n slugify: field.slugify,\n }\n }\n\n if (!field.hooks) {\n field.hooks = {}\n }\n field.hooks.beforeChange = [\n generateSlug({ name: field.name, slugify: field.slugify, useAsSlug }),\n ...(field.hooks.beforeChange || []),\n ]\n }\n\n // Array ID field\n if (field.type === 'array' && field.fields) {\n const hasCustomID = field.fields.some((f) => 'name' in f && f.name === 'id')\n if (!hasCustomID) {\n field.fields.push(baseIDField)\n }\n }\n\n // Blocks/array labels\n if ((field.type === 'blocks' || field.type === 'array') && field.label) {\n field.labels = field.labels || formatLabels(field.name)\n }\n\n if (fieldAffectsData) {\n if (existingFieldNames.has(field.name)) {\n throw new DuplicateFieldName(field.name)\n } else if (!['blockName', 'id'].includes(field.name)) {\n existingFieldNames.add(field.name)\n }\n\n if (typeof field.localized !== 'undefined') {\n if (!config.localization) {\n delete field.localized\n }\n }\n\n if (typeof field.validate === 'undefined') {\n if ('virtual' in field && field.virtual) {\n field.validate = (): true => true\n } else {\n const defaultValidate = validations[field.type as keyof typeof validations]\n if (defaultValidate) {\n field.validate = (val: any, options: any) =>\n defaultValidate(val, { ...field, ...options })\n } else {\n field.validate = (): true => true\n }\n }\n }\n\n if (!field.hooks) {\n field.hooks = {}\n }\n\n if (!field.access) {\n field.access = {}\n }\n\n setDefaultBeforeDuplicate(field, parentIsLocalized)\n }\n\n if (!field.admin) {\n field.admin = {}\n }\n\n if ('virtual' in field && field.virtual && field.admin.readOnly !== false && fieldAffectsData) {\n field.admin.readOnly = true\n }\n\n // Make sure that the richText field has an editor\n if (field.type === 'richText') {\n const sanitizeRichText = async (_config: SanitizedConfig) => {\n if (!field.editor) {\n if (_config.editor && !requireFieldLevelRichTextEditor) {\n // config.editor should be sanitized at this point\n field.editor = _config.editor\n } else {\n throw new MissingEditorProp(field) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor\n }\n }\n\n if (typeof field.editor === 'function') {\n field.editor = await field.editor({\n config: _config,\n isRoot: requireFieldLevelRichTextEditor,\n parentIsLocalized: (parentIsLocalized || field.localized)!,\n })\n }\n }\n if (richTextSanitizationPromises) {\n richTextSanitizationPromises.push(sanitizeRichText)\n } else {\n await sanitizeRichText(config as unknown as SanitizedConfig)\n }\n }\n\n if (field.type === 'blocks' && field.blocks) {\n const blockSlugs: string[] = []\n\n for (const block of field.blocks) {\n const blockSlug = typeof block === 'string' ? block : block.slug\n\n if (blockSlugs.includes(blockSlug)) {\n throw new DuplicateFieldName(blockSlug)\n }\n\n blockSlugs.push(blockSlug)\n\n if (typeof block === 'string') {\n continue\n }\n\n if (block._sanitized === true) {\n continue\n }\n\n block._sanitized = true\n block.fields = block.fields.concat(baseBlockFields)\n block.labels = !block.labels ? formatLabels(block.slug) : block.labels\n\n block.fields = await sanitizeFields({\n collectionConfig,\n config,\n existingFieldNames: new Set(),\n fields: block.fields,\n isTopLevelField: false,\n parentIndexPath: '',\n parentIsLocalized: (parentIsLocalized || field.localized)!,\n parentSchemaPath: schemaPath + '.' + block.slug,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n })\n }\n }\n\n if ('fields' in field && field.fields) {\n field.fields = await sanitizeFields({\n collectionConfig,\n config,\n existingFieldNames: fieldAffectsData ? new Set() : existingFieldNames,\n fields: field.fields,\n isTopLevelField: isTopLevelField && !fieldAffectsData,\n joinPath: fieldAffectsData ? `${joinPath ? joinPath + '.' : ''}${field.name}` : joinPath,\n joins,\n orderableJoins,\n parentIndexPath: fieldAffectsData ? '' : indexPath,\n parentIsLocalized: parentIsLocalized || fieldIsLocalized(field),\n parentSchemaPath: schemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n })\n }\n\n if (field.type === 'tabs') {\n for (let j = 0; j < field.tabs.length; j++) {\n const tab = field.tabs[j]!\n\n const isNamedTab = tabHasName(tab)\n\n if (isNamedTab && typeof tab.label === 'undefined') {\n tab.label = toWords(tab.name)\n }\n\n const { indexPath: tabIndexPath, schemaPath: tabSchemaPath } = getFieldPaths({\n field: tab,\n index: j,\n parentIndexPath: indexPath,\n parentSchemaPath: schemaPath,\n })\n\n if (\n 'admin' in tab &&\n tab.admin?.condition &&\n typeof tab.admin.condition === 'function' &&\n !tab.id\n ) {\n tab.id = tabSchemaPath\n }\n\n tab.fields = await sanitizeFields({\n collectionConfig,\n config,\n existingFieldNames: isNamedTab ? new Set() : existingFieldNames,\n fields: tab.fields,\n isTopLevelField: isTopLevelField && !isNamedTab,\n joinPath: isNamedTab ? `${joinPath ? joinPath + '.' : ''}${tab.name}` : joinPath,\n joins,\n orderableJoins,\n parentIndexPath: isNamedTab ? '' : tabIndexPath,\n parentIsLocalized: parentIsLocalized || (isNamedTab && tab.localized)!,\n parentSchemaPath: tabSchemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n })\n\n field.tabs[j] = tab\n }\n }\n\n if (field.type === 'ui') {\n const existing = field.admin.disabled\n if (existing === undefined) {\n field.admin.disabled = { bulkEdit: true }\n } else if (\n existing !== true &&\n typeof existing === 'object' &&\n existing.bulkEdit === undefined\n ) {\n field.admin.disabled = { ...existing, bulkEdit: true }\n }\n }\n\n // Timezone field insertion\n if (field.type === 'date' && field.timezone) {\n const name = field.name + '_tz'\n\n let defaultTimezone =\n field.timezone && typeof field.timezone === 'object'\n ? field.timezone.defaultTimezone\n : config.admin?.timezones?.defaultTimezone\n\n const required =\n field.required ||\n (field.timezone && typeof field.timezone === 'object' && field.timezone.required)\n\n const supportedTimezones =\n field.timezone && typeof field.timezone === 'object' && field.timezone.supportedTimezones\n ? field.timezone.supportedTimezones\n : config.admin?.timezones?.supportedTimezones\n\n const options =\n typeof supportedTimezones === 'function'\n ? supportedTimezones({ defaultTimezones })\n : supportedTimezones\n\n validateTimezones({\n source: `field \"${field.name}\" timezone.supportedTimezones`,\n timezones: options,\n })\n\n if (options && options.length === 1 && options[0]?.value) {\n defaultTimezone = options[0].value\n }\n\n // Generate label for timezone field\n const timezoneLabel = typeof field.label === 'string' ? `${field.label} Tz` : toWords(name)\n\n const baseField = baseTimezoneField({\n name,\n defaultValue: defaultTimezone,\n label: timezoneLabel,\n options,\n required,\n })\n\n // Apply override if provided\n const timezoneField =\n typeof field.timezone === 'object' && typeof field.timezone.override === 'function'\n ? field.timezone.override({ baseField })\n : baseField\n\n result.fieldsToInsert = [timezoneField]\n }\n\n // Virtual field handling\n if ('virtual' in field && typeof field.virtual === 'string') {\n const virtualField = field\n const configFields = (collectionConfig || globalConfig)?.fields\n if (configFields) {\n let flattenFields = flattenAllFields({ fields: configFields })\n const paths = field.virtual.split('.')\n let isHasMany = false\n\n for (const [idx, segment] of paths.entries()) {\n const foundField = flattenFields.find((e) => e.name === segment)\n if (!foundField) {\n break\n }\n\n if (\n foundField.type === 'group' ||\n foundField.type === 'tab' ||\n foundField.type === 'array'\n ) {\n flattenFields = foundField.flattenedFields\n } else if (\n (foundField.type === 'relationship' || foundField.type === 'upload') &&\n idx !== paths.length - 1 &&\n typeof foundField.relationTo === 'string'\n ) {\n if (\n foundField.hasMany &&\n (virtualField.type === 'text' ||\n virtualField.type === 'number' ||\n virtualField.type === 'select')\n ) {\n if (isHasMany) {\n throw new InvalidConfiguration(\n `Virtual field ${virtualField.name} in ${globalConfig ? `global ${globalConfig.slug}` : `collection ${collectionConfig?.slug}`} references 2 or more hasMany relationships on the path ${virtualField.virtual} which is not allowed.`,\n )\n }\n\n isHasMany = true\n virtualField.hasMany = true\n }\n const relatedCollection = config.collections?.find(\n (e) => e.slug === foundField.relationTo,\n )\n if (relatedCollection) {\n flattenFields = flattenAllFields({ fields: relatedCollection.fields })\n }\n }\n }\n }\n }\n\n return result\n}\n\nexport const sanitizeFields = async ({\n collectionConfig,\n config,\n existingFieldNames = new Set(),\n fields,\n globalConfig,\n isTopLevelField = true,\n joinPath = '',\n joins,\n orderableJoins,\n parentIndexPath = '',\n parentIsLocalized,\n parentSchemaPath = '',\n polymorphicJoins,\n requireFieldLevelRichTextEditor = false,\n richTextSanitizationPromises,\n validRelationships,\n}: SanitizeFieldsArgs): Promise<Field[]> => {\n if (!fields) {\n return []\n }\n\n for (let i = 0; i < fields.length; i++) {\n const field = fields[i]!\n\n const result = await sanitizeField({\n collectionConfig,\n config,\n existingFieldNames,\n field,\n globalConfig,\n index: i,\n isTopLevelField,\n joinPath,\n joins,\n orderableJoins,\n parentIndexPath,\n parentIsLocalized,\n parentSchemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n })\n\n fields[i] = field\n\n if (result.fieldsToInsert?.length) {\n fields.splice(i + 1, 0, ...result.fieldsToInsert)\n i += result.fieldsToInsert.length\n }\n }\n\n return fields\n}\n"],"names":["DuplicateFieldName","InvalidConfiguration","InvalidFieldName","InvalidFieldRelationship","MissingEditorProp","MissingFieldType","ReservedFieldName","flattenAllFields","formatLabels","toWords","validateTimezones","baseBlockFields","baseIDField","generateSlug","baseTimezoneField","defaultTimezones","getFieldPaths","setDefaultBeforeDuplicate","validations","reservedAPIKeyFieldNames","reservedBaseAuthFieldNames","reservedBaseUploadFieldNames","reservedVerifyFieldNames","sanitizeJoinField","fieldAffectsData","_fieldAffectsData","fieldIsLocalized","tabHasName","sanitizeField","collectionConfig","config","existingFieldNames","field","globalConfig","index","isTopLevelField","joinPath","joins","orderableJoins","parentIndexPath","parentIsLocalized","parentSchemaPath","polymorphicJoins","requireFieldLevelRichTextEditor","richTextSanitizationPromises","validRelationships","result","_sanitized","type","indexPath","schemaPath","name","upload","includes","auth","disableLocalStrategy","verify","label","defaultValue","required","Array","isArray","relationTo","length","Error","relationships","forEach","relationship","admin","isSortable","useAsSlug","unique","position","slugify","custom","hooks","beforeChange","fields","hasCustomID","some","f","push","labels","has","add","localized","localization","validate","virtual","defaultValidate","val","options","access","readOnly","sanitizeRichText","_config","editor","isRoot","blocks","blockSlugs","block","blockSlug","slug","concat","sanitizeFields","Set","j","tabs","tab","isNamedTab","tabIndexPath","tabSchemaPath","condition","id","existing","disabled","undefined","bulkEdit","timezone","defaultTimezone","timezones","supportedTimezones","source","value","timezoneLabel","baseField","timezoneField","override","fieldsToInsert","virtualField","configFields","flattenFields","paths","split","isHasMany","idx","segment","entries","foundField","find","e","flattenedFields","hasMany","relatedCollection","collections","i","splice"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/config/sanitize.ts"],"sourcesContent":["import type {\n CollectionConfig,\n SanitizedJoin,\n SanitizedJoins,\n} from '../../collections/config/types.js'\nimport type { Config, SanitizedConfig } from '../../config/types.js'\nimport type { GlobalConfig } from '../../globals/config/types.js'\nimport type { OrderableJoinInfo } from './sanitizeJoinField.js'\nimport type { Field } from './types.js'\n\nimport {\n DuplicateFieldName,\n InvalidConfiguration,\n InvalidFieldName,\n InvalidFieldRelationship,\n MissingEditorProp,\n MissingFieldType,\n} from '../../errors/index.js'\nimport { ReservedFieldName } from '../../errors/ReservedFieldName.js'\nimport { flattenAllFields } from '../../utilities/flattenAllFields.js'\nimport { formatLabels, toWords } from '../../utilities/formatLabels.js'\nimport { validateTimezones } from '../../utilities/validateTimezones.js'\nimport { baseBlockFields } from '../baseFields/baseBlockFields.js'\nimport { baseIDField } from '../baseFields/baseIDField.js'\nimport { generateSlug } from '../baseFields/slug/generateSlug.js'\nimport { generateSlugBeforeDuplicate } from '../baseFields/slug/generateSlugBeforeDuplicate.js'\nimport { baseTimezoneField } from '../baseFields/timezone/baseField.js'\nimport { defaultTimezones } from '../baseFields/timezone/defaultTimezones.js'\nimport { getFieldPaths } from '../getFieldPaths.js'\nimport { setDefaultBeforeDuplicate } from '../setDefaultBeforeDuplicate.js'\nimport { validations } from '../validations.js'\nimport {\n reservedAPIKeyFieldNames,\n reservedBaseAuthFieldNames,\n reservedBaseUploadFieldNames,\n reservedVerifyFieldNames,\n} from './reservedFieldNames.js'\nimport { sanitizeJoinField } from './sanitizeJoinField.js'\nimport { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } from './types.js'\n\ntype SanitizeFieldsArgs = {\n collectionConfig?: CollectionConfig\n config: Config\n existingFieldNames?: Set<string>\n fields: Field[]\n globalConfig?: GlobalConfig\n /**\n * Used to prevent unnecessary sanitization of fields that are not top-level.\n */\n isTopLevelField?: boolean\n joinPath?: string\n /**\n * When not passed in, assume that join are not supported (globals, arrays, blocks)\n */\n joins?: SanitizedJoins\n /**\n * Tracker for orderable join fields - populated during sanitization\n */\n orderableJoins?: OrderableJoinInfo[]\n /**\n * A string of '-' separated indexes representing where\n * to find this field in a given field schema array.\n */\n parentIndexPath?: string\n parentIsLocalized: boolean\n /**\n * Path for parent fields relative to their position in the schema.\n */\n parentSchemaPath?: string\n polymorphicJoins?: SanitizedJoin[]\n /**\n * If true, a richText field will require an editor property to be set, as the sanitizeFields function will not add it from the payload config if not present.\n *\n * @default false\n */\n requireFieldLevelRichTextEditor?: boolean\n /**\n * If not null, will validate that upload and relationship fields do not relate to a collection that is not in this array.\n * This validation will be skipped if validRelationships is null.\n */\n validRelationships: null | string[]\n}\n\nexport type SanitizeFieldArgs = {\n collectionConfig?: CollectionConfig\n config: Config\n existingFieldNames: Set<string>\n field: Field\n globalConfig?: GlobalConfig\n /**\n * The index of this field in the parent fields array\n */\n index: number\n /**\n * Used to prevent unnecessary sanitization of fields that are not top-level.\n */\n isTopLevelField: boolean\n joinPath: string\n /**\n * When not passed in, assume that joins are not supported (globals, arrays, blocks)\n */\n joins?: SanitizedJoins\n /**\n * Tracker for orderable join fields - populated during sanitization\n */\n orderableJoins?: OrderableJoinInfo[]\n parentIndexPath: string\n parentIsLocalized: boolean\n parentSchemaPath: string\n polymorphicJoins?: SanitizedJoin[]\n requireFieldLevelRichTextEditor: boolean\n validRelationships: null | string[]\n}\n\ntype SanitizeFieldResult = {\n /**\n * Fields to insert after this field (e.g., timezone field)\n */\n fieldsToInsert?: Field[]\n}\n\n/**\n * Sanitize a single field. Handles all per-field logic including:\n * - Validation setup\n * - Hooks/access/admin defaults\n * - Type-specific handling\n * - Recursive sanitization of nested fields\n *\n * @returns Result containing any fields to insert after this one\n */\nexport const sanitizeField = ({\n collectionConfig,\n config,\n existingFieldNames,\n field,\n globalConfig,\n index,\n isTopLevelField,\n joinPath,\n joins,\n orderableJoins,\n parentIndexPath,\n parentIsLocalized,\n parentSchemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n validRelationships,\n}: SanitizeFieldArgs): SanitizeFieldResult => {\n const result: SanitizeFieldResult = {}\n\n if ('_sanitized' in field && field._sanitized === true) {\n return result\n }\n\n if ('_sanitized' in field) {\n field._sanitized = true\n }\n\n if (!field.type) {\n throw new MissingFieldType(field)\n }\n\n const fieldAffectsData = _fieldAffectsData(field)\n\n const { indexPath, schemaPath } = getFieldPaths({\n field,\n index,\n parentIndexPath,\n parentSchemaPath,\n })\n\n // Reserved field name checks\n if (isTopLevelField && fieldAffectsData && field.name) {\n if (collectionConfig && collectionConfig.upload) {\n if (reservedBaseUploadFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n }\n\n if (\n collectionConfig &&\n collectionConfig.auth &&\n typeof collectionConfig.auth === 'object' &&\n !collectionConfig.auth.disableLocalStrategy\n ) {\n if (reservedBaseAuthFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n\n if (collectionConfig.auth.verify) {\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n if (reservedAPIKeyFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n if (reservedVerifyFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n }\n }\n }\n\n // Invalid field name check\n if (fieldAffectsData && field.name.includes('.')) {\n throw new InvalidFieldName(field, field.name)\n }\n\n // Auto-label\n if (\n 'name' in field &&\n field.name &&\n typeof field.label !== 'object' &&\n typeof field.label !== 'string' &&\n typeof field.label !== 'function' &&\n field.label !== false\n ) {\n field.label = toWords(field.name)\n }\n\n // Checkbox default\n if (\n field.type === 'checkbox' &&\n typeof field.defaultValue === 'undefined' &&\n field.required === true\n ) {\n field.defaultValue = false\n }\n\n // Join field sanitization\n if (field.type === 'join') {\n sanitizeJoinField({\n config,\n field,\n joinPath,\n joins,\n orderableJoins,\n parentIsLocalized,\n polymorphicJoins,\n })\n }\n\n // Relationship/upload validation\n if (field.type === 'relationship' || field.type === 'upload') {\n if (Array.isArray(field.relationTo) && field.relationTo.length === 0) {\n throw new Error(\n `Field \"${field.name}\" of type \"${field.type}\" has an empty relationTo array. At least one collection must be specified.`,\n )\n }\n\n if (validRelationships) {\n const relationships = Array.isArray(field.relationTo) ? field.relationTo : [field.relationTo]\n\n relationships.forEach((relationship: string) => {\n if (!validRelationships.includes(relationship)) {\n throw new InvalidFieldRelationship(field, relationship)\n }\n })\n }\n }\n\n // Upload isSortable default\n if (field.type === 'upload') {\n if (!field.admin || !('isSortable' in field.admin)) {\n field.admin = {\n isSortable: true,\n ...field.admin,\n }\n }\n }\n\n // Slug field: apply defaults, attach generation hook, expose slugify to the server fn.\n if (field.type === 'slug') {\n const useAsSlug = field.useAsSlug\n\n // Required by default so the admin marks the slug as required. The value is always populated by\n // the field hooks (source or id fallback), and validations.slug permits empty so the fallback\n // isn't blocked before it runs.\n if (typeof field.required === 'undefined') {\n field.required = true\n }\n\n if (typeof field.unique === 'undefined') {\n field.unique = true\n }\n\n if (typeof field.index === 'undefined') {\n field.index = true\n }\n\n field.admin = {\n position: 'sidebar',\n ...field.admin,\n }\n\n // The slugifyHandler server function resolves the custom slugify by field path.\n if (field.slugify) {\n field.custom = {\n ...field.custom,\n slugify: field.slugify,\n }\n }\n\n if (!field.hooks) {\n field.hooks = {}\n }\n\n field.hooks.beforeChange = [\n generateSlug({\n name: field.name,\n localized: field.localized,\n slugify: field.slugify,\n useAsSlug,\n }),\n ...(field.hooks.beforeChange || []),\n ]\n\n // Own the slug on duplicate — the copy takes a fresh `<singular>-<N>` fallback rather than the\n // generic ` - Copy` default, which isn't collision-safe across repeated duplicates of the same\n // source. Runs per-locale for a localized slug.\n field.hooks.beforeDuplicate = [\n generateSlugBeforeDuplicate({ name: field.name }),\n ...(field.hooks.beforeDuplicate || []),\n ]\n }\n\n // Array ID field\n if (field.type === 'array' && field.fields) {\n const hasCustomID = field.fields.some((f) => 'name' in f && f.name === 'id')\n if (!hasCustomID) {\n field.fields.push(baseIDField)\n }\n }\n\n // Blocks/array labels\n if ((field.type === 'blocks' || field.type === 'array') && field.label) {\n field.labels = field.labels || formatLabels(field.name)\n }\n\n if (fieldAffectsData) {\n if (existingFieldNames.has(field.name)) {\n throw new DuplicateFieldName(field.name)\n } else if (!['blockName', 'id'].includes(field.name)) {\n existingFieldNames.add(field.name)\n }\n\n if (typeof field.localized !== 'undefined') {\n if (!config.localization) {\n delete field.localized\n }\n }\n\n if (typeof field.validate === 'undefined') {\n if ('virtual' in field && field.virtual) {\n field.validate = (): true => true\n } else {\n const defaultValidate = validations[field.type as keyof typeof validations]\n if (defaultValidate) {\n field.validate = (val: any, options: any) =>\n defaultValidate(val, { ...field, ...options })\n } else {\n field.validate = (): true => true\n }\n }\n }\n\n if (!field.hooks) {\n field.hooks = {}\n }\n\n if (!field.access) {\n field.access = {}\n }\n\n setDefaultBeforeDuplicate(field, parentIsLocalized)\n }\n\n if (!field.admin) {\n field.admin = {}\n }\n\n if ('virtual' in field && field.virtual && field.admin.readOnly !== false && fieldAffectsData) {\n field.admin.readOnly = true\n }\n\n // Make sure that the richText field has an editor\n if (field.type === 'richText') {\n if (!field.editor) {\n if (config.editor && !requireFieldLevelRichTextEditor) {\n field.editor = config.editor\n } else {\n throw new MissingEditorProp(field) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor\n }\n }\n\n if (typeof field.editor === 'function') {\n field.editor = field.editor({\n config: config as unknown as SanitizedConfig,\n isRoot: requireFieldLevelRichTextEditor,\n parentIsLocalized: (parentIsLocalized || field.localized)!,\n })\n }\n }\n\n if (field.type === 'blocks' && field.blocks) {\n const blockSlugs: string[] = []\n\n for (const block of field.blocks) {\n const blockSlug = typeof block === 'string' ? block : block.slug\n\n if (blockSlugs.includes(blockSlug)) {\n throw new DuplicateFieldName(blockSlug)\n }\n\n blockSlugs.push(blockSlug)\n\n if (typeof block === 'string') {\n continue\n }\n\n if (block._sanitized === true) {\n continue\n }\n\n block._sanitized = true\n block.fields = block.fields.concat(baseBlockFields)\n block.labels = !block.labels ? formatLabels(block.slug) : block.labels\n\n block.fields = sanitizeFields({\n collectionConfig,\n config,\n existingFieldNames: new Set(),\n fields: block.fields,\n isTopLevelField: false,\n parentIndexPath: '',\n parentIsLocalized: (parentIsLocalized || field.localized)!,\n parentSchemaPath: schemaPath + '.' + block.slug,\n requireFieldLevelRichTextEditor,\n validRelationships,\n })\n }\n }\n\n if ('fields' in field && field.fields) {\n field.fields = sanitizeFields({\n collectionConfig,\n config,\n existingFieldNames: fieldAffectsData ? new Set() : existingFieldNames,\n fields: field.fields,\n isTopLevelField: isTopLevelField && !fieldAffectsData,\n joinPath: fieldAffectsData ? `${joinPath ? joinPath + '.' : ''}${field.name}` : joinPath,\n joins,\n orderableJoins,\n parentIndexPath: fieldAffectsData ? '' : indexPath,\n parentIsLocalized: parentIsLocalized || fieldIsLocalized(field),\n parentSchemaPath: schemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n validRelationships,\n })\n }\n\n if (field.type === 'tabs') {\n for (let j = 0; j < field.tabs.length; j++) {\n const tab = field.tabs[j]!\n\n const isNamedTab = tabHasName(tab)\n\n if (isNamedTab && typeof tab.label === 'undefined') {\n tab.label = toWords(tab.name)\n }\n\n const { indexPath: tabIndexPath, schemaPath: tabSchemaPath } = getFieldPaths({\n field: tab,\n index: j,\n parentIndexPath: indexPath,\n parentSchemaPath: schemaPath,\n })\n\n if (\n 'admin' in tab &&\n tab.admin?.condition &&\n typeof tab.admin.condition === 'function' &&\n !tab.id\n ) {\n tab.id = tabSchemaPath\n }\n\n tab.fields = sanitizeFields({\n collectionConfig,\n config,\n existingFieldNames: isNamedTab ? new Set() : existingFieldNames,\n fields: tab.fields,\n isTopLevelField: isTopLevelField && !isNamedTab,\n joinPath: isNamedTab ? `${joinPath ? joinPath + '.' : ''}${tab.name}` : joinPath,\n joins,\n orderableJoins,\n parentIndexPath: isNamedTab ? '' : tabIndexPath,\n parentIsLocalized: parentIsLocalized || (isNamedTab && tab.localized)!,\n parentSchemaPath: tabSchemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n validRelationships,\n })\n\n field.tabs[j] = tab\n }\n }\n\n if (field.type === 'ui') {\n const existing = field.admin.disabled\n if (existing === undefined) {\n field.admin.disabled = { bulkEdit: true }\n } else if (\n existing !== true &&\n typeof existing === 'object' &&\n existing.bulkEdit === undefined\n ) {\n field.admin.disabled = { ...existing, bulkEdit: true }\n }\n }\n\n // Timezone field insertion\n if (field.type === 'date' && field.timezone) {\n const name = field.name + '_tz'\n\n let defaultTimezone =\n field.timezone && typeof field.timezone === 'object'\n ? field.timezone.defaultTimezone\n : config.admin?.timezones?.defaultTimezone\n\n const required =\n field.required ||\n (field.timezone && typeof field.timezone === 'object' && field.timezone.required)\n\n const supportedTimezones =\n field.timezone && typeof field.timezone === 'object' && field.timezone.supportedTimezones\n ? field.timezone.supportedTimezones\n : config.admin?.timezones?.supportedTimezones\n\n const options =\n typeof supportedTimezones === 'function'\n ? supportedTimezones({ defaultTimezones })\n : supportedTimezones\n\n validateTimezones({\n source: `field \"${field.name}\" timezone.supportedTimezones`,\n timezones: options,\n })\n\n if (options && options.length === 1 && options[0]?.value) {\n defaultTimezone = options[0].value\n }\n\n // Generate label for timezone field\n const timezoneLabel = typeof field.label === 'string' ? `${field.label} Tz` : toWords(name)\n\n const baseField = baseTimezoneField({\n name,\n defaultValue: defaultTimezone,\n label: timezoneLabel,\n options,\n required,\n })\n\n // Apply override if provided\n const timezoneField =\n typeof field.timezone === 'object' && typeof field.timezone.override === 'function'\n ? field.timezone.override({ baseField })\n : baseField\n\n result.fieldsToInsert = [timezoneField]\n }\n\n // Virtual field handling\n if ('virtual' in field && typeof field.virtual === 'string') {\n const virtualField = field\n const configFields = (collectionConfig || globalConfig)?.fields\n if (configFields) {\n let flattenFields = flattenAllFields({ fields: configFields })\n const paths = field.virtual.split('.')\n let isHasMany = false\n\n for (const [idx, segment] of paths.entries()) {\n const foundField = flattenFields.find((e) => e.name === segment)\n if (!foundField) {\n break\n }\n\n if (\n foundField.type === 'group' ||\n foundField.type === 'tab' ||\n foundField.type === 'array'\n ) {\n flattenFields = foundField.flattenedFields\n } else if (\n (foundField.type === 'relationship' || foundField.type === 'upload') &&\n idx !== paths.length - 1 &&\n typeof foundField.relationTo === 'string'\n ) {\n if (\n foundField.hasMany &&\n (virtualField.type === 'text' ||\n virtualField.type === 'number' ||\n virtualField.type === 'select')\n ) {\n if (isHasMany) {\n throw new InvalidConfiguration(\n `Virtual field ${virtualField.name} in ${globalConfig ? `global ${globalConfig.slug}` : `collection ${collectionConfig?.slug}`} references 2 or more hasMany relationships on the path ${virtualField.virtual} which is not allowed.`,\n )\n }\n\n isHasMany = true\n virtualField.hasMany = true\n }\n const relatedCollection = config.collections?.find(\n (e) => e.slug === foundField.relationTo,\n )\n if (relatedCollection) {\n flattenFields = flattenAllFields({ fields: relatedCollection.fields })\n }\n }\n }\n }\n }\n\n return result\n}\n\nexport const sanitizeFields = ({\n collectionConfig,\n config,\n existingFieldNames = new Set(),\n fields,\n globalConfig,\n isTopLevelField = true,\n joinPath = '',\n joins,\n orderableJoins,\n parentIndexPath = '',\n parentIsLocalized,\n parentSchemaPath = '',\n polymorphicJoins,\n requireFieldLevelRichTextEditor = false,\n validRelationships,\n}: SanitizeFieldsArgs): Field[] => {\n if (!fields) {\n return []\n }\n\n for (let i = 0; i < fields.length; i++) {\n const field = fields[i]!\n\n const result = sanitizeField({\n collectionConfig,\n config,\n existingFieldNames,\n field,\n globalConfig,\n index: i,\n isTopLevelField,\n joinPath,\n joins,\n orderableJoins,\n parentIndexPath,\n parentIsLocalized,\n parentSchemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n validRelationships,\n })\n\n fields[i] = field\n\n if (result.fieldsToInsert?.length) {\n fields.splice(i + 1, 0, ...result.fieldsToInsert)\n i += result.fieldsToInsert.length\n }\n }\n\n return fields\n}\n"],"names":["DuplicateFieldName","InvalidConfiguration","InvalidFieldName","InvalidFieldRelationship","MissingEditorProp","MissingFieldType","ReservedFieldName","flattenAllFields","formatLabels","toWords","validateTimezones","baseBlockFields","baseIDField","generateSlug","generateSlugBeforeDuplicate","baseTimezoneField","defaultTimezones","getFieldPaths","setDefaultBeforeDuplicate","validations","reservedAPIKeyFieldNames","reservedBaseAuthFieldNames","reservedBaseUploadFieldNames","reservedVerifyFieldNames","sanitizeJoinField","fieldAffectsData","_fieldAffectsData","fieldIsLocalized","tabHasName","sanitizeField","collectionConfig","config","existingFieldNames","field","globalConfig","index","isTopLevelField","joinPath","joins","orderableJoins","parentIndexPath","parentIsLocalized","parentSchemaPath","polymorphicJoins","requireFieldLevelRichTextEditor","validRelationships","result","_sanitized","type","indexPath","schemaPath","name","upload","includes","auth","disableLocalStrategy","verify","label","defaultValue","required","Array","isArray","relationTo","length","Error","relationships","forEach","relationship","admin","isSortable","useAsSlug","unique","position","slugify","custom","hooks","beforeChange","localized","beforeDuplicate","fields","hasCustomID","some","f","push","labels","has","add","localization","validate","virtual","defaultValidate","val","options","access","readOnly","editor","isRoot","blocks","blockSlugs","block","blockSlug","slug","concat","sanitizeFields","Set","j","tabs","tab","isNamedTab","tabIndexPath","tabSchemaPath","condition","id","existing","disabled","undefined","bulkEdit","timezone","defaultTimezone","timezones","supportedTimezones","source","value","timezoneLabel","baseField","timezoneField","override","fieldsToInsert","virtualField","configFields","flattenFields","paths","split","isHasMany","idx","segment","entries","foundField","find","e","flattenedFields","hasMany","relatedCollection","collections","i","splice"],"mappings":"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"}
|