payload 4.0.0-beta.3 → 4.0.0-beta.4
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/adapters/router.d.ts +1 -1
- package/dist/admin/adapters/router.d.ts.map +1 -1
- package/dist/admin/adapters/router.js.map +1 -1
- package/dist/admin/initAdminContext.js.map +1 -1
- package/dist/auth/getFieldsToSign.js.map +1 -1
- package/dist/auth/loginWithCookie.js.map +1 -1
- package/dist/auth/serverFunctions/cookies.js.map +1 -1
- package/dist/auth/serverFunctions/login.js.map +1 -1
- package/dist/cli/defineCLICommand.js +1 -1
- package/dist/cli/defineCLICommand.js.map +1 -1
- package/dist/collections/config/client.js.map +1 -1
- package/dist/collections/operations/findByID.js.map +1 -1
- package/dist/collections/operations/findVersionByID.js.map +1 -1
- package/dist/collections/operations/findVersions.js.map +1 -1
- package/dist/collections/operations/local/findDistinct.js.map +1 -1
- package/dist/collections/operations/renameFile.js +1 -1
- package/dist/collections/operations/renameFile.js.map +1 -1
- package/dist/collections/operations/utilities/update.js +1 -1
- package/dist/collections/operations/utilities/update.js.map +1 -1
- package/dist/collections/operations/validate.js +4 -4
- package/dist/collections/operations/validate.js.map +1 -1
- package/dist/config/definePlugin.js.map +1 -1
- package/dist/config/sanitize.js +2 -2
- package/dist/config/sanitize.js.map +1 -1
- package/dist/exports/build-config.d.ts +9 -0
- package/dist/exports/build-config.d.ts.map +1 -0
- package/dist/exports/build-config.js +38 -0
- package/dist/exports/build-config.js.map +1 -0
- package/dist/fields/config/client.js.map +1 -1
- package/dist/fields/hooks/afterChange/promise.js.map +1 -1
- package/dist/fields/validations.d.ts.map +1 -1
- package/dist/fields/validations.js +4 -1
- package/dist/fields/validations.js.map +1 -1
- package/dist/globals/operations/local/findOne.js.map +1 -1
- package/dist/globals/operations/local/update.js.map +1 -1
- package/dist/globals/operations/restoreVersion.d.ts +2 -3
- package/dist/globals/operations/restoreVersion.d.ts.map +1 -1
- package/dist/globals/operations/restoreVersion.js +22 -15
- package/dist/globals/operations/restoreVersion.js.map +1 -1
- package/dist/globals/operations/validate.js +1 -1
- package/dist/globals/operations/validate.js.map +1 -1
- package/dist/hierarchy/createFolderField.js.map +1 -1
- package/dist/hierarchy/resolveHierarchyCollections.js +2 -2
- package/dist/hierarchy/resolveHierarchyCollections.js.map +1 -1
- package/dist/hierarchy/utils/computePaths.d.ts.map +1 -1
- package/dist/hierarchy/utils/computePaths.js.map +1 -1
- package/dist/index.bundled.d.ts +12 -3
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js +1 -1
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js.map +1 -1
- package/dist/uploads/fileVersioning/archive.js.map +1 -1
- package/dist/uploads/fileVersioning/resolveHistoricalFile.js.map +1 -1
- package/dist/uploads/generateFileData.d.ts.map +1 -1
- package/dist/uploads/generateFileData.js.map +1 -1
- package/dist/uploads/getFileFromUploadInstructions.js.map +1 -1
- package/dist/uploads/safeFetch.js.map +1 -1
- package/dist/uploads/stagedUpload.js.map +1 -1
- package/dist/uploads/transformers/handleDynamicFileRequest.js +11 -2
- package/dist/uploads/transformers/handleDynamicFileRequest.js.map +1 -1
- package/dist/utilities/addSelectGenericsToGeneretedTypes.d.ts.map +1 -1
- package/dist/utilities/addSelectGenericsToGeneretedTypes.js +0 -1
- package/dist/utilities/addSelectGenericsToGeneretedTypes.js.map +1 -1
- package/dist/utilities/appendDateTimezoneSelectFields.js.map +1 -1
- package/dist/utilities/cloneValidationRequest.js.map +1 -1
- package/dist/utilities/createPayloadRequest.js.map +1 -1
- package/dist/utilities/deepCopyObject.js.map +1 -1
- package/dist/utilities/documentMatchingWhereExists.js +1 -1
- package/dist/utilities/documentMatchingWhereExists.js.map +1 -1
- package/dist/utilities/filterDataToSelectedLocales.js.map +1 -1
- package/dist/utilities/getEntityPermissions/getEntityPermissions.d.ts.map +1 -1
- package/dist/utilities/getEntityPermissions/getEntityPermissions.js +1 -0
- package/dist/utilities/getEntityPermissions/getEntityPermissions.js.map +1 -1
- package/dist/utilities/getEntityPermissions/populateFieldPermissions.js.map +1 -1
- package/dist/utilities/parseParams/index.js.map +1 -1
- package/dist/utilities/parseValidationLocale.js.map +1 -1
- package/dist/utilities/sanitizePopulateParam.js.map +1 -1
- package/dist/utilities/telemetry/featureInfo/getFeatureInfo.js.map +1 -1
- package/dist/versions/allLocalesPublicationStatus.js.map +1 -1
- package/package.json +11 -9
- package/skills/payload/reference/PLUGIN-DEVELOPMENT.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/uploads/stagedUpload.ts"],"sourcesContent":["import { jwtVerify } from 'jose/jwt/verify'\nimport { randomUUID } from 'node:crypto'\nimport fs from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport type { PayloadHandler } from '../config/types.js'\nimport type { PayloadRequest } from '../types/index.js'\nimport type { File, UploadInstructions, UploadInstructionsRequest } from './types.js'\n\nimport { jwtSign } from '../auth/jwt.js'\nimport { APIError, Forbidden } from '../errors/index.js'\nimport { formatAdminURL } from '../utilities/formatAdminURL.js'\nimport { checkFileRestrictions } from './checkFileRestrictions.js'\n\n/**\n * Creates a signed, one-hour URL where the client can send the file bytes. The returned file value\n * is later passed to a document create or update request.\n */\nexport const generateStagedUploadInstructions = async ({\n collectionSlug,\n docPrefix,\n filename,\n filesize,\n mimeType,\n req,\n}: { req: PayloadRequest } & UploadInstructionsRequest): Promise<UploadInstructions> => {\n await removeExpiredUploads(req, collectionSlug)\n\n const { token: uploadId } = await jwtSign({\n fieldsToSign: {\n id: randomUUID(),\n collectionSlug,\n docPrefix,\n filename,\n filesize,\n mimeType,\n user: getUser(req),\n },\n secret: req.payload.secret,\n tokenExpiration,\n })\n\n return {\n type: 'http',\n file: {\n filename,\n mimeType,\n size: filesize,\n uploadReference: { uploadId },\n },\n request: {\n headers: {\n 'Content-Length': String(filesize),\n 'Content-Type': mimeType,\n },\n method: 'PUT',\n url: formatAdminURL({\n apiRoute: req.payload.config.routes.api,\n path: `/upload-instructions/${uploadId}`,\n serverURL: req.payload.config.serverURL,\n }),\n },\n }\n}\n\n/**\n * Saves the bytes sent to a signed upload URL. The file is written as a partial file first and only\n * becomes available when its size exactly matches the size in the upload ID.\n */\nexport const uploadStagedFile: PayloadHandler = async (req) => {\n const upload = await verifyUploadID(req, req.routeParams?.uploadId)\n const directory = await getUploadDirectory(req, upload.collectionSlug)\n const uploadPath = path.join(directory, upload.id)\n const temporaryPath = `${uploadPath}.${randomUUID()}.part`\n const file = await fs.open(temporaryPath, 'wx')\n let uploadedSize = 0\n\n try {\n try {\n const reader = req.body?.getReader()\n\n while (reader) {\n const { done, value } = await reader.read()\n\n if (done) {\n break\n }\n\n uploadedSize += value.byteLength\n if (uploadedSize > upload.filesize) {\n throw new APIError('Uploaded file is larger than expected.', 400)\n }\n\n let offset = 0\n while (offset < value.byteLength) {\n const { bytesWritten } = await file.write(value, offset)\n offset += bytesWritten\n }\n }\n\n if (uploadedSize !== upload.filesize) {\n throw new APIError('Uploaded file size does not match the expected size.', 400)\n }\n } finally {\n await file.close()\n }\n\n const collection = req.payload.collections[upload.collectionSlug]!.config\n await checkFileRestrictions({\n collection,\n file: {\n name: upload.filename,\n data: Buffer.alloc(0),\n mimetype: upload.mimeType,\n size: upload.filesize,\n tempFilePath: temporaryPath,\n },\n req,\n })\n\n await fs.rename(temporaryPath, uploadPath)\n } catch (error) {\n await fs.rm(temporaryPath, { force: true })\n throw error\n }\n\n return new Response(null, { status: 204 })\n}\n\n/** Removes a temporary upload that the client no longer needs. */\nexport const deleteStagedFile: PayloadHandler = async (req) => {\n const upload = await verifyUploadID(req, req.routeParams?.uploadId)\n const directory = await getUploadDirectory(req, upload.collectionSlug)\n\n await fs.rm(path.join(directory, upload.id), { force: true })\n\n return new Response(null, { status: 204 })\n}\n\n/**\n * Loads a completed staged file for a document request. Only the same user and collection can use\n * it, and the temporary file is deleted after it is read.\n */\nexport const getStagedFile = async ({\n collectionSlug,\n req,\n uploadReference,\n}: {\n collectionSlug: string\n req: PayloadRequest\n uploadReference: unknown\n}): Promise<File> => {\n if (\n !uploadReference ||\n typeof uploadReference !== 'object' ||\n Array.isArray(uploadReference) ||\n !('uploadId' in uploadReference) ||\n typeof uploadReference.uploadId !== 'string'\n ) {\n throw new APIError('Invalid staged upload.', 400)\n }\n\n const { uploadId } = uploadReference\n const upload = await verifyUploadID(req, uploadId)\n\n if (upload.collectionSlug !== collectionSlug || upload.user !== getUser(req)) {\n throw new Forbidden(req.t)\n }\n\n const directory = await getUploadDirectory(req, upload.collectionSlug)\n const tempFilePath = path.join(directory, upload.id)\n let data: Buffer\n\n try {\n data = await fs.readFile(tempFilePath)\n } catch {\n throw new APIError('Staged upload was not found.', 400)\n }\n\n if (data.length !== upload.filesize) {\n await fs.rm(tempFilePath, { force: true })\n throw new APIError('Staged upload is incomplete.', 400)\n }\n\n await fs.rm(tempFilePath, { force: true })\n\n return {\n name: upload.filename,\n data,\n mimetype: upload.mimeType,\n size: data.length,\n }\n}\n\n/**\n * Staged uploads hold a file temporarily until a document create or update uses it. The signed\n * upload ID remembers which file and user the upload belongs to.\n */\nconst tokenExpiration = 60 * 60\n\n/** The file details stored inside the signed upload ID. */\ntype StagedUploadToken = {\n id: string\n user: null | string\n} & UploadInstructionsRequest\n\nconst getUser = (req: PayloadRequest) =>\n req.user ? `${req.user.collection}:${String(req.user.id)}` : null\n\n/** Returns the hidden folder where temporary uploads for this collection are stored. */\nconst getUploadDirectory = async (req: PayloadRequest, collectionSlug: string) => {\n const upload = req.payload.collections[collectionSlug]?.config.upload\n const directory = path.resolve(\n upload && !upload.disableLocalStorage\n ? upload.staticDir || collectionSlug\n : req.payload.config.upload.tempFileDir || os.tmpdir(),\n '.payload-staged-uploads',\n )\n\n await fs.mkdir(directory, { recursive: true })\n\n return directory\n}\n\n/** Removes temporary files older than the one-hour upload window. */\nconst removeExpiredUploads = async (req: PayloadRequest, collectionSlug: string) => {\n const directory = await getUploadDirectory(req, collectionSlug)\n const expiresBefore = Date.now() - tokenExpiration * 1000\n\n for (const filename of await fs.readdir(directory)) {\n const filePath = path.join(directory, filename)\n const stats = await fs.stat(filePath).catch(() => null)\n\n if (stats && stats.mtimeMs < expiresBefore) {\n await fs.rm(filePath, { force: true })\n }\n }\n}\n\n/** Verifies that an upload ID was signed by Payload, has not expired, and contains valid details. */\nconst verifyUploadID = async (\n req: PayloadRequest,\n uploadID: unknown,\n): Promise<StagedUploadToken> => {\n try {\n if (typeof uploadID !== 'string') {\n throw new Error()\n }\n\n const secret = new TextEncoder().encode(req.payload.secret)\n const { payload } = await jwtVerify<StagedUploadToken>(uploadID, secret)\n\n if (\n typeof payload.id !== 'string' ||\n !/^[\\da-f-]{36}$/i.test(payload.id) ||\n typeof payload.collectionSlug !== 'string' ||\n typeof payload.filename !== 'string' ||\n !Number.isSafeInteger(payload.filesize) ||\n payload.filesize < 0 ||\n typeof payload.mimeType !== 'string' ||\n (payload.user !== null && typeof payload.user !== 'string')\n ) {\n throw new Error()\n }\n\n return payload as StagedUploadToken\n } catch {\n throw new APIError('Invalid or expired staged upload.', 400)\n }\n}\n"],"names":["jwtVerify","randomUUID","fs","os","path","jwtSign","APIError","Forbidden","formatAdminURL","checkFileRestrictions","generateStagedUploadInstructions","collectionSlug","docPrefix","filename","filesize","mimeType","req","removeExpiredUploads","token","uploadId","fieldsToSign","id","user","getUser","secret","payload","tokenExpiration","type","file","size","uploadReference","request","headers","String","method","url","apiRoute","config","routes","api","serverURL","uploadStagedFile","upload","verifyUploadID","routeParams","directory","getUploadDirectory","uploadPath","join","temporaryPath","open","uploadedSize","reader","body","getReader","done","value","read","byteLength","offset","bytesWritten","write","close","collection","collections","name","data","Buffer","alloc","mimetype","tempFilePath","rename","error","rm","force","Response","status","deleteStagedFile","getStagedFile","Array","isArray","t","readFile","length","resolve","disableLocalStorage","staticDir","tempFileDir","tmpdir","mkdir","recursive","expiresBefore","Date","now","readdir","filePath","stats","stat","catch","mtimeMs","uploadID","Error","TextEncoder","encode","test","Number","isSafeInteger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/stagedUpload.ts"],"sourcesContent":["import { jwtVerify } from 'jose/jwt/verify'\nimport { randomUUID } from 'node:crypto'\nimport fs from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport type { PayloadHandler } from '../config/types.js'\nimport type { PayloadRequest } from '../types/index.js'\nimport type { File, UploadInstructions, UploadInstructionsRequest } from './types.js'\n\nimport { jwtSign } from '../auth/jwt.js'\nimport { APIError, Forbidden } from '../errors/index.js'\nimport { formatAdminURL } from '../utilities/formatAdminURL.js'\nimport { checkFileRestrictions } from './checkFileRestrictions.js'\n\n/**\n * Creates a signed, one-hour URL where the client can send the file bytes. The returned file value\n * is later passed to a document create or update request.\n */\nexport const generateStagedUploadInstructions = async ({\n collectionSlug,\n docPrefix,\n filename,\n filesize,\n mimeType,\n req,\n}: { req: PayloadRequest } & UploadInstructionsRequest): Promise<UploadInstructions> => {\n await removeExpiredUploads(req, collectionSlug)\n\n const { token: uploadId } = await jwtSign({\n fieldsToSign: {\n id: randomUUID(),\n collectionSlug,\n docPrefix,\n filename,\n filesize,\n mimeType,\n user: getUser(req),\n },\n secret: req.payload.secret,\n tokenExpiration,\n })\n\n return {\n type: 'http',\n file: {\n filename,\n mimeType,\n size: filesize,\n uploadReference: { uploadId },\n },\n request: {\n headers: {\n 'Content-Length': String(filesize),\n 'Content-Type': mimeType,\n },\n method: 'PUT',\n url: formatAdminURL({\n apiRoute: req.payload.config.routes.api,\n path: `/upload-instructions/${uploadId}`,\n serverURL: req.payload.config.serverURL,\n }),\n },\n }\n}\n\n/**\n * Saves the bytes sent to a signed upload URL. The file is written as a partial file first and only\n * becomes available when its size exactly matches the size in the upload ID.\n */\nexport const uploadStagedFile: PayloadHandler = async (req) => {\n const upload = await verifyUploadID(req, req.routeParams?.uploadId)\n const directory = await getUploadDirectory(req, upload.collectionSlug)\n const uploadPath = path.join(directory, upload.id)\n const temporaryPath = `${uploadPath}.${randomUUID()}.part`\n const file = await fs.open(temporaryPath, 'wx')\n let uploadedSize = 0\n\n try {\n try {\n const reader = req.body?.getReader()\n\n while (reader) {\n const { done, value } = await reader.read()\n\n if (done) {\n break\n }\n\n uploadedSize += value.byteLength\n if (uploadedSize > upload.filesize) {\n throw new APIError('Uploaded file is larger than expected.', 400)\n }\n\n let offset = 0\n while (offset < value.byteLength) {\n const { bytesWritten } = await file.write(value, offset)\n offset += bytesWritten\n }\n }\n\n if (uploadedSize !== upload.filesize) {\n throw new APIError('Uploaded file size does not match the expected size.', 400)\n }\n } finally {\n await file.close()\n }\n\n const collection = req.payload.collections[upload.collectionSlug]!.config\n await checkFileRestrictions({\n collection,\n file: {\n name: upload.filename,\n data: Buffer.alloc(0),\n mimetype: upload.mimeType,\n size: upload.filesize,\n tempFilePath: temporaryPath,\n },\n req,\n })\n\n await fs.rename(temporaryPath, uploadPath)\n } catch (error) {\n await fs.rm(temporaryPath, { force: true })\n throw error\n }\n\n return new Response(null, { status: 204 })\n}\n\n/** Removes a temporary upload that the client no longer needs. */\nexport const deleteStagedFile: PayloadHandler = async (req) => {\n const upload = await verifyUploadID(req, req.routeParams?.uploadId)\n const directory = await getUploadDirectory(req, upload.collectionSlug)\n\n await fs.rm(path.join(directory, upload.id), { force: true })\n\n return new Response(null, { status: 204 })\n}\n\n/**\n * Loads a completed staged file for a document request. Only the same user and collection can use\n * it, and the temporary file is deleted after it is read.\n */\nexport const getStagedFile = async ({\n collectionSlug,\n req,\n uploadReference,\n}: {\n collectionSlug: string\n req: PayloadRequest\n uploadReference: unknown\n}): Promise<File> => {\n if (\n !uploadReference ||\n typeof uploadReference !== 'object' ||\n Array.isArray(uploadReference) ||\n !('uploadId' in uploadReference) ||\n typeof uploadReference.uploadId !== 'string'\n ) {\n throw new APIError('Invalid staged upload.', 400)\n }\n\n const { uploadId } = uploadReference\n const upload = await verifyUploadID(req, uploadId)\n\n if (upload.collectionSlug !== collectionSlug || upload.user !== getUser(req)) {\n throw new Forbidden(req.t)\n }\n\n const directory = await getUploadDirectory(req, upload.collectionSlug)\n const tempFilePath = path.join(directory, upload.id)\n let data: Buffer\n\n try {\n data = await fs.readFile(tempFilePath)\n } catch {\n throw new APIError('Staged upload was not found.', 400)\n }\n\n if (data.length !== upload.filesize) {\n await fs.rm(tempFilePath, { force: true })\n throw new APIError('Staged upload is incomplete.', 400)\n }\n\n await fs.rm(tempFilePath, { force: true })\n\n return {\n name: upload.filename,\n data,\n mimetype: upload.mimeType,\n size: data.length,\n }\n}\n\n/**\n * Staged uploads hold a file temporarily until a document create or update uses it. The signed\n * upload ID remembers which file and user the upload belongs to.\n */\nconst tokenExpiration = 60 * 60\n\n/** The file details stored inside the signed upload ID. */\ntype StagedUploadToken = {\n id: string\n user: null | string\n} & UploadInstructionsRequest\n\nconst getUser = (req: PayloadRequest) =>\n req.user ? `${req.user.collection}:${String(req.user.id)}` : null\n\n/** Returns the hidden folder where temporary uploads for this collection are stored. */\nconst getUploadDirectory = async (req: PayloadRequest, collectionSlug: string) => {\n const upload = req.payload.collections[collectionSlug]?.config.upload\n const directory = path.resolve(\n upload && !upload.disableLocalStorage\n ? upload.staticDir || collectionSlug\n : req.payload.config.upload.tempFileDir || os.tmpdir(),\n '.payload-staged-uploads',\n )\n\n await fs.mkdir(directory, { recursive: true })\n\n return directory\n}\n\n/** Removes temporary files older than the one-hour upload window. */\nconst removeExpiredUploads = async (req: PayloadRequest, collectionSlug: string) => {\n const directory = await getUploadDirectory(req, collectionSlug)\n const expiresBefore = Date.now() - tokenExpiration * 1000\n\n for (const filename of await fs.readdir(directory)) {\n const filePath = path.join(directory, filename)\n const stats = await fs.stat(filePath).catch(() => null)\n\n if (stats && stats.mtimeMs < expiresBefore) {\n await fs.rm(filePath, { force: true })\n }\n }\n}\n\n/** Verifies that an upload ID was signed by Payload, has not expired, and contains valid details. */\nconst verifyUploadID = async (\n req: PayloadRequest,\n uploadID: unknown,\n): Promise<StagedUploadToken> => {\n try {\n if (typeof uploadID !== 'string') {\n throw new Error()\n }\n\n const secret = new TextEncoder().encode(req.payload.secret)\n const { payload } = await jwtVerify<StagedUploadToken>(uploadID, secret)\n\n if (\n typeof payload.id !== 'string' ||\n !/^[\\da-f-]{36}$/i.test(payload.id) ||\n typeof payload.collectionSlug !== 'string' ||\n typeof payload.filename !== 'string' ||\n !Number.isSafeInteger(payload.filesize) ||\n payload.filesize < 0 ||\n typeof payload.mimeType !== 'string' ||\n (payload.user !== null && typeof payload.user !== 'string')\n ) {\n throw new Error()\n }\n\n return payload\n } catch {\n throw new APIError('Invalid or expired staged upload.', 400)\n }\n}\n"],"names":["jwtVerify","randomUUID","fs","os","path","jwtSign","APIError","Forbidden","formatAdminURL","checkFileRestrictions","generateStagedUploadInstructions","collectionSlug","docPrefix","filename","filesize","mimeType","req","removeExpiredUploads","token","uploadId","fieldsToSign","id","user","getUser","secret","payload","tokenExpiration","type","file","size","uploadReference","request","headers","String","method","url","apiRoute","config","routes","api","serverURL","uploadStagedFile","upload","verifyUploadID","routeParams","directory","getUploadDirectory","uploadPath","join","temporaryPath","open","uploadedSize","reader","body","getReader","done","value","read","byteLength","offset","bytesWritten","write","close","collection","collections","name","data","Buffer","alloc","mimetype","tempFilePath","rename","error","rm","force","Response","status","deleteStagedFile","getStagedFile","Array","isArray","t","readFile","length","resolve","disableLocalStorage","staticDir","tempFileDir","tmpdir","mkdir","recursive","expiresBefore","Date","now","readdir","filePath","stats","stat","catch","mtimeMs","uploadID","Error","TextEncoder","encode","test","Number","isSafeInteger"],"mappings":"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"}
|
|
@@ -119,7 +119,7 @@ import { withFileTransformAccessContext } from './withFileTransformAccessContext
|
|
|
119
119
|
if (result.response) {
|
|
120
120
|
if (handedOutResponse && result.response !== handedOutResponse) {
|
|
121
121
|
await discardResponse(handedOutResponse);
|
|
122
|
-
} else if (previousResponse && result.response !== previousResponse) {
|
|
122
|
+
} else if (!handedOutResponse && previousResponse && result.response !== previousResponse) {
|
|
123
123
|
await discardResponse(previousResponse);
|
|
124
124
|
}
|
|
125
125
|
currentResponse = result.response;
|
|
@@ -169,7 +169,16 @@ import { withFileTransformAccessContext } from './withFileTransformAccessContext
|
|
|
169
169
|
if (!response.body) {
|
|
170
170
|
return response;
|
|
171
171
|
}
|
|
172
|
-
|
|
172
|
+
const stream = new TransformStream({
|
|
173
|
+
start (controller) {
|
|
174
|
+
// Pipe abort waits for pending writes, which can stall on an abandoned reader.
|
|
175
|
+
// Error the transform to unblock those writes before the pipe cancels its source.
|
|
176
|
+
signal.addEventListener('abort', ()=>controller.error(signal.reason), {
|
|
177
|
+
once: true
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
return new Response(response.body.pipeThrough(stream, {
|
|
173
182
|
signal
|
|
174
183
|
}), {
|
|
175
184
|
headers: response.headers,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/uploads/transformers/handleDynamicFileRequest.ts"],"sourcesContent":["import type { Collection } from '../../collections/config/types.js'\nimport type { PayloadRequest } from '../../types/index.js'\nimport type { ResolvedUploadDocument } from './resolveUploadDocument.js'\nimport type { UploadTransformer } from './types.js'\n\nimport { Forbidden } from '../../errors/Forbidden.js'\nimport { NotFound } from '../../errors/NotFound.js'\nimport { TransformerContractError } from '../../errors/TransformerContractError.js'\nimport { checkFileAccess } from '../checkFileAccess.js'\nimport { retrieveFileResponse } from '../endpoints/getFile.js'\nimport { createLazySourceGetter } from './createLazySourceGetter.js'\nimport { finalizeFileResponse } from './finalizeFileResponse.js'\nimport { getSourceFileResponse } from './getSourceFileResponse.js'\nimport { getCandidateTransformers, planTransformerPipeline } from './planTransformerPipeline.js'\nimport { getRequestedFile, resolveUploadDocument } from './resolveUploadDocument.js'\nimport { withFileTransformAccessContext } from './withFileTransformAccessContext.js'\n\n/**\n * Orchestrates a dynamic file request end to end: resolve the document, plan the\n * request-capable transformer pipeline from the requested file's authoritative\n * MIME type (the primary file or the matched image size), enforce\n * transform-aware read access, then run every eligible transformer in declaration\n * order against a lazily-fetched source. Called from `getFileHandler` only when at\n * least one transformer is configured — the zero-transformer path never reaches\n * this function.\n */\nexport async function handleDynamicFileRequest({\n collection,\n filename,\n prefix,\n req,\n}: {\n collection: Collection\n filename: string\n prefix?: string\n req: PayloadRequest\n}): Promise<Response> {\n const resolvedDocument = await resolveUploadDocument({ collection, filename, prefix, req })\n\n if (!resolvedDocument) {\n // There's no mimeType to plan a pipeline from, so both access modes must pass\n // before admitting the file doesn't exist — otherwise the status code would leak\n // file existence to an access function keyed on req.fileTransform.\n for (const isTransform of [true, false]) {\n await withFileTransformAccessContext({\n callback: () => checkFileAccess({ collection, filename, prefix, req }),\n isTransform,\n req,\n })\n }\n throw new NotFound(req.t)\n }\n\n if (\n resolvedDocument.original?.filename === filename &&\n (resolvedDocument.filename !== filename || req.searchParams.size === 0)\n ) {\n const permittedDocument = await withFileTransformAccessContext({\n callback: () => checkFileAccess({ collection, filename, prefix, req }),\n isTransform: false,\n req,\n })\n\n return retrieveFileResponse({\n collection,\n doc: (permittedDocument ?? resolvedDocument) as ResolvedUploadDocument,\n filename,\n prefix,\n req,\n })\n }\n\n const { document, pipeline } = await authorizeDocument({\n collection,\n filename,\n prefix,\n req,\n resolvedDocument,\n })\n\n const requestedFile = getRequestedFile({ document, filename })\n\n const source = createLazySourceGetter({\n retrieve: () => getSourceFileResponse({ collection, document, filename, prefix, req }),\n })\n\n let currentResponse: Response | undefined\n // Each stage has its own controller so a discarded body can be closed even when the\n // transformer locked it with a reader. Every remaining controller is aborted on failure.\n const handedOutBodyControllers = new Map<Response, AbortController>()\n\n const discardResponse = async (response: Response): Promise<void> => {\n await cancelUnusedBody(response)\n handedOutBodyControllers.get(response)?.abort()\n handedOutBodyControllers.delete(response)\n }\n\n try {\n for (const transformer of pipeline) {\n const previousResponse = currentResponse\n let handedOutResponse: Response | undefined\n const handedOutBodyController = new AbortController()\n const stageSource = createLazySourceGetter({\n retrieve: async () => {\n handedOutResponse = withAbortableBody({\n response: currentResponse ?? (await source.get()),\n signal: handedOutBodyController.signal,\n })\n handedOutBodyControllers.set(handedOutResponse, handedOutBodyController)\n\n return handedOutResponse\n },\n })\n\n const result = await transformer.handleRequest!({\n collectionSlug: collection.config.slug,\n documentID: document.id,\n filename: requestedFile.filename,\n getSourceFile: stageSource.get,\n mimeType: requestedFile.mimeType,\n req,\n })\n\n if (result.response) {\n if (handedOutResponse && result.response !== handedOutResponse) {\n await discardResponse(handedOutResponse)\n } else if (previousResponse && result.response !== previousResponse) {\n await discardResponse(previousResponse)\n }\n\n currentResponse = result.response\n } else if (stageSource.wasCalled()) {\n throw new TransformerContractError(\n 'A transformer that consumes its source must return a response.',\n )\n }\n\n if (result.status === 'complete') {\n return finalizeFileResponse({ collection, req, response: currentResponse! })\n }\n }\n } catch (err) {\n req.payload.logger.error({ err, msg: 'Error running the file transformer pipeline' })\n for (const handedOutBodyController of handedOutBodyControllers.values()) {\n handedOutBodyController.abort(err)\n }\n await cancelUnusedBody(currentResponse)\n throw err\n }\n\n if (currentResponse) {\n return finalizeFileResponse({ collection, req, response: currentResponse })\n }\n\n // No transformer produced a response — serve the original file through the\n // normal path (Range/ETag/redirect support, existing `modifyResponseHeaders` order).\n return retrieveFileResponse({ collection, doc: document, filename, prefix, req })\n}\n\n/**\n * Re-wraps `response` so its body can be cancelled through `signal`, closing the underlying\n * source stream (file handle, storage connection) regardless of who holds a reader on it.\n */\nfunction withAbortableBody({\n response,\n signal,\n}: {\n response: Response\n signal: AbortSignal\n}): Response {\n if (!response.body) {\n return response\n }\n\n return new Response(response.body.pipeThrough(new TransformStream(), { signal }), {\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n })\n}\n\n/**\n * Cancels a response body nothing has started reading. A locked body was handed to a transformer\n * through `withAbortableBody`, and is closed by aborting its signal instead.\n */\nasync function cancelUnusedBody(response: Response | undefined): Promise<void> {\n if (!response?.body || response.body.locked) {\n return\n }\n\n try {\n await response.body.cancel()\n } catch {\n // A clean-up failure must not replace the pipeline result or error.\n }\n}\n\nfunction planRequestPipeline({\n collection,\n document,\n filename,\n req,\n}: {\n collection: Collection\n document: ResolvedUploadDocument\n filename: string\n req: PayloadRequest\n}): Promise<UploadTransformer[]> {\n return planTransformerPipeline({\n args: {\n collectionSlug: collection.config.slug,\n documentID: document.id,\n mimeType: getRequestedFile({ document, filename }).mimeType,\n operation: 'request',\n req,\n },\n capability: 'handleRequest',\n transformers: req.payload.config.upload.transformers,\n })\n}\n\ntype AccessResult = { document?: ResolvedUploadDocument; isAllowed: true } | { isAllowed: false }\n\n/**\n * Decides which document is served and which pipeline runs, checking read access\n * before any application-defined transformer code (`canTransform`) executes.\n *\n * 1. The first access mode comes from MIME matching alone: a transform-aware check\n * when any transformer could handle the file, otherwise an ordinary read.\n * 2. If the transform-aware check is denied, an ordinary read may still be allowed\n * (e.g. public originals, signed-in-only variants), so that mode is tried next.\n * 3. Only once a check has passed does `canTransform` plan the real pipeline.\n * 4. The access mode the final pipeline requires must itself have passed — a\n * \"variants only\" policy must not leak the original when no transformer applies.\n *\n * `resolveUploadDocument` is unfiltered, so without a `prefix` it can match a\n * document the user can't read that shares the filename (filenames are only\n * unique per prefix). Whenever `checkFileAccess` returns a document, that\n * authorized document is the one served — storage adapters trust `doc` to\n * resolve the object key.\n */\nasync function authorizeDocument({\n collection,\n filename,\n prefix,\n req,\n resolvedDocument,\n}: {\n collection: Collection\n filename: string\n prefix?: string\n req: PayloadRequest\n resolvedDocument: ResolvedUploadDocument\n}): Promise<{ document: ResolvedUploadDocument; pipeline: UploadTransformer[] }> {\n const accessResults = new Map<boolean, Promise<AccessResult>>()\n\n const checkAccess = ({ isTransform }: { isTransform: boolean }): Promise<AccessResult> => {\n if (!accessResults.has(isTransform)) {\n accessResults.set(\n isTransform,\n withFileTransformAccessContext({\n callback: () => checkFileAccess({ collection, filename, prefix, req }),\n isTransform,\n req,\n }).then(\n (document) => ({\n document: document as ResolvedUploadDocument | undefined,\n isAllowed: true as const,\n }),\n (err: unknown) => {\n if (err instanceof Forbidden) {\n return { isAllowed: false as const }\n }\n\n throw err\n },\n ),\n )\n }\n\n return accessResults.get(isTransform)!\n }\n\n const hasCandidateTransformers =\n getCandidateTransformers({\n capability: 'handleRequest',\n mimeType: getRequestedFile({ document: resolvedDocument, filename }).mimeType,\n transformers: req.payload.config.upload.transformers,\n }).length > 0\n\n let isTransformAccess = hasCandidateTransformers\n let access = await checkAccess({ isTransform: isTransformAccess })\n\n if (!access.isAllowed && isTransformAccess) {\n isTransformAccess = false\n access = await checkAccess({ isTransform: isTransformAccess })\n }\n\n if (!access.isAllowed) {\n throw new Forbidden(req.t)\n }\n\n const document =\n access.document && access.document.id !== resolvedDocument.id\n ? access.document\n : resolvedDocument\n\n const pipeline = await planRequestPipeline({ collection, document, filename, req })\n const isTransform = pipeline.length > 0\n\n if (isTransform !== isTransformAccess) {\n const requiredAccess = await checkAccess({ isTransform })\n\n if (\n !requiredAccess.isAllowed ||\n (requiredAccess.document && requiredAccess.document.id !== document.id)\n ) {\n throw new Forbidden(req.t)\n }\n }\n\n return { document, pipeline }\n}\n"],"names":["Forbidden","NotFound","TransformerContractError","checkFileAccess","retrieveFileResponse","createLazySourceGetter","finalizeFileResponse","getSourceFileResponse","getCandidateTransformers","planTransformerPipeline","getRequestedFile","resolveUploadDocument","withFileTransformAccessContext","handleDynamicFileRequest","collection","filename","prefix","req","resolvedDocument","isTransform","callback","t","original","searchParams","size","permittedDocument","doc","document","pipeline","authorizeDocument","requestedFile","source","retrieve","currentResponse","handedOutBodyControllers","Map","discardResponse","response","cancelUnusedBody","get","abort","delete","transformer","previousResponse","handedOutResponse","handedOutBodyController","AbortController","stageSource","withAbortableBody","signal","set","result","handleRequest","collectionSlug","config","slug","documentID","id","getSourceFile","mimeType","wasCalled","status","err","payload","logger","error","msg","values","body","Response","pipeThrough","TransformStream","headers","statusText","locked","cancel","planRequestPipeline","args","operation","capability","transformers","upload","accessResults","checkAccess","has","then","isAllowed","hasCandidateTransformers","length","isTransformAccess","access","requiredAccess"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/uploads/transformers/handleDynamicFileRequest.ts"],"sourcesContent":["import type { Collection } from '../../collections/config/types.js'\nimport type { PayloadRequest } from '../../types/index.js'\nimport type { ResolvedUploadDocument } from './resolveUploadDocument.js'\nimport type { UploadTransformer } from './types.js'\n\nimport { Forbidden } from '../../errors/Forbidden.js'\nimport { NotFound } from '../../errors/NotFound.js'\nimport { TransformerContractError } from '../../errors/TransformerContractError.js'\nimport { checkFileAccess } from '../checkFileAccess.js'\nimport { retrieveFileResponse } from '../endpoints/getFile.js'\nimport { createLazySourceGetter } from './createLazySourceGetter.js'\nimport { finalizeFileResponse } from './finalizeFileResponse.js'\nimport { getSourceFileResponse } from './getSourceFileResponse.js'\nimport { getCandidateTransformers, planTransformerPipeline } from './planTransformerPipeline.js'\nimport { getRequestedFile, resolveUploadDocument } from './resolveUploadDocument.js'\nimport { withFileTransformAccessContext } from './withFileTransformAccessContext.js'\n\n/**\n * Orchestrates a dynamic file request end to end: resolve the document, plan the\n * request-capable transformer pipeline from the requested file's authoritative\n * MIME type (the primary file or the matched image size), enforce\n * transform-aware read access, then run every eligible transformer in declaration\n * order against a lazily-fetched source. Called from `getFileHandler` only when at\n * least one transformer is configured — the zero-transformer path never reaches\n * this function.\n */\nexport async function handleDynamicFileRequest({\n collection,\n filename,\n prefix,\n req,\n}: {\n collection: Collection\n filename: string\n prefix?: string\n req: PayloadRequest\n}): Promise<Response> {\n const resolvedDocument = await resolveUploadDocument({ collection, filename, prefix, req })\n\n if (!resolvedDocument) {\n // There's no mimeType to plan a pipeline from, so both access modes must pass\n // before admitting the file doesn't exist — otherwise the status code would leak\n // file existence to an access function keyed on req.fileTransform.\n for (const isTransform of [true, false]) {\n await withFileTransformAccessContext({\n callback: () => checkFileAccess({ collection, filename, prefix, req }),\n isTransform,\n req,\n })\n }\n throw new NotFound(req.t)\n }\n\n if (\n resolvedDocument.original?.filename === filename &&\n (resolvedDocument.filename !== filename || req.searchParams.size === 0)\n ) {\n const permittedDocument = await withFileTransformAccessContext({\n callback: () => checkFileAccess({ collection, filename, prefix, req }),\n isTransform: false,\n req,\n })\n\n return retrieveFileResponse({\n collection,\n doc: permittedDocument ?? resolvedDocument,\n filename,\n prefix,\n req,\n })\n }\n\n const { document, pipeline } = await authorizeDocument({\n collection,\n filename,\n prefix,\n req,\n resolvedDocument,\n })\n\n const requestedFile = getRequestedFile({ document, filename })\n\n const source = createLazySourceGetter({\n retrieve: () => getSourceFileResponse({ collection, document, filename, prefix, req }),\n })\n\n let currentResponse: Response | undefined\n // Each stage has its own controller so a discarded body can be closed even when the\n // transformer locked it with a reader. Every remaining controller is aborted on failure.\n const handedOutBodyControllers = new Map<Response, AbortController>()\n\n const discardResponse = async (response: Response): Promise<void> => {\n await cancelUnusedBody(response)\n handedOutBodyControllers.get(response)?.abort()\n handedOutBodyControllers.delete(response)\n }\n\n try {\n for (const transformer of pipeline) {\n const previousResponse = currentResponse\n let handedOutResponse: Response | undefined\n const handedOutBodyController = new AbortController()\n const stageSource = createLazySourceGetter({\n retrieve: async () => {\n handedOutResponse = withAbortableBody({\n response: currentResponse ?? (await source.get()),\n signal: handedOutBodyController.signal,\n })\n handedOutBodyControllers.set(handedOutResponse, handedOutBodyController)\n\n return handedOutResponse\n },\n })\n\n const result = await transformer.handleRequest!({\n collectionSlug: collection.config.slug,\n documentID: document.id,\n filename: requestedFile.filename,\n getSourceFile: stageSource.get,\n mimeType: requestedFile.mimeType,\n req,\n })\n\n if (result.response) {\n if (handedOutResponse && result.response !== handedOutResponse) {\n await discardResponse(handedOutResponse)\n } else if (!handedOutResponse && previousResponse && result.response !== previousResponse) {\n await discardResponse(previousResponse)\n }\n\n currentResponse = result.response\n } else if (stageSource.wasCalled()) {\n throw new TransformerContractError(\n 'A transformer that consumes its source must return a response.',\n )\n }\n\n if (result.status === 'complete') {\n return finalizeFileResponse({ collection, req, response: currentResponse! })\n }\n }\n } catch (err) {\n req.payload.logger.error({ err, msg: 'Error running the file transformer pipeline' })\n for (const handedOutBodyController of handedOutBodyControllers.values()) {\n handedOutBodyController.abort(err)\n }\n await cancelUnusedBody(currentResponse)\n throw err\n }\n\n if (currentResponse) {\n return finalizeFileResponse({ collection, req, response: currentResponse })\n }\n\n // No transformer produced a response — serve the original file through the\n // normal path (Range/ETag/redirect support, existing `modifyResponseHeaders` order).\n return retrieveFileResponse({ collection, doc: document, filename, prefix, req })\n}\n\n/**\n * Re-wraps `response` so its body can be cancelled through `signal`, closing the underlying\n * source stream (file handle, storage connection) regardless of who holds a reader on it.\n */\nfunction withAbortableBody({\n response,\n signal,\n}: {\n response: Response\n signal: AbortSignal\n}): Response {\n if (!response.body) {\n return response\n }\n\n const stream = new TransformStream({\n start(controller) {\n // Pipe abort waits for pending writes, which can stall on an abandoned reader.\n // Error the transform to unblock those writes before the pipe cancels its source.\n signal.addEventListener('abort', () => controller.error(signal.reason), { once: true })\n },\n })\n\n return new Response(response.body.pipeThrough(stream, { signal }), {\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n })\n}\n\n/**\n * Cancels a response body nothing has started reading. A locked body was handed to a transformer\n * through `withAbortableBody`, and is closed by aborting its signal instead.\n */\nasync function cancelUnusedBody(response: Response | undefined): Promise<void> {\n if (!response?.body || response.body.locked) {\n return\n }\n\n try {\n await response.body.cancel()\n } catch {\n // A clean-up failure must not replace the pipeline result or error.\n }\n}\n\nfunction planRequestPipeline({\n collection,\n document,\n filename,\n req,\n}: {\n collection: Collection\n document: ResolvedUploadDocument\n filename: string\n req: PayloadRequest\n}): Promise<UploadTransformer[]> {\n return planTransformerPipeline({\n args: {\n collectionSlug: collection.config.slug,\n documentID: document.id,\n mimeType: getRequestedFile({ document, filename }).mimeType,\n operation: 'request',\n req,\n },\n capability: 'handleRequest',\n transformers: req.payload.config.upload.transformers,\n })\n}\n\ntype AccessResult = { document?: ResolvedUploadDocument; isAllowed: true } | { isAllowed: false }\n\n/**\n * Decides which document is served and which pipeline runs, checking read access\n * before any application-defined transformer code (`canTransform`) executes.\n *\n * 1. The first access mode comes from MIME matching alone: a transform-aware check\n * when any transformer could handle the file, otherwise an ordinary read.\n * 2. If the transform-aware check is denied, an ordinary read may still be allowed\n * (e.g. public originals, signed-in-only variants), so that mode is tried next.\n * 3. Only once a check has passed does `canTransform` plan the real pipeline.\n * 4. The access mode the final pipeline requires must itself have passed — a\n * \"variants only\" policy must not leak the original when no transformer applies.\n *\n * `resolveUploadDocument` is unfiltered, so without a `prefix` it can match a\n * document the user can't read that shares the filename (filenames are only\n * unique per prefix). Whenever `checkFileAccess` returns a document, that\n * authorized document is the one served — storage adapters trust `doc` to\n * resolve the object key.\n */\nasync function authorizeDocument({\n collection,\n filename,\n prefix,\n req,\n resolvedDocument,\n}: {\n collection: Collection\n filename: string\n prefix?: string\n req: PayloadRequest\n resolvedDocument: ResolvedUploadDocument\n}): Promise<{ document: ResolvedUploadDocument; pipeline: UploadTransformer[] }> {\n const accessResults = new Map<boolean, Promise<AccessResult>>()\n\n const checkAccess = ({ isTransform }: { isTransform: boolean }): Promise<AccessResult> => {\n if (!accessResults.has(isTransform)) {\n accessResults.set(\n isTransform,\n withFileTransformAccessContext({\n callback: () => checkFileAccess({ collection, filename, prefix, req }),\n isTransform,\n req,\n }).then(\n (document) => ({\n document: document as ResolvedUploadDocument | undefined,\n isAllowed: true as const,\n }),\n (err: unknown) => {\n if (err instanceof Forbidden) {\n return { isAllowed: false as const }\n }\n\n throw err\n },\n ),\n )\n }\n\n return accessResults.get(isTransform)!\n }\n\n const hasCandidateTransformers =\n getCandidateTransformers({\n capability: 'handleRequest',\n mimeType: getRequestedFile({ document: resolvedDocument, filename }).mimeType,\n transformers: req.payload.config.upload.transformers,\n }).length > 0\n\n let isTransformAccess = hasCandidateTransformers\n let access = await checkAccess({ isTransform: isTransformAccess })\n\n if (!access.isAllowed && isTransformAccess) {\n isTransformAccess = false\n access = await checkAccess({ isTransform: isTransformAccess })\n }\n\n if (!access.isAllowed) {\n throw new Forbidden(req.t)\n }\n\n const document =\n access.document && access.document.id !== resolvedDocument.id\n ? access.document\n : resolvedDocument\n\n const pipeline = await planRequestPipeline({ collection, document, filename, req })\n const isTransform = pipeline.length > 0\n\n if (isTransform !== isTransformAccess) {\n const requiredAccess = await checkAccess({ isTransform })\n\n if (\n !requiredAccess.isAllowed ||\n (requiredAccess.document && requiredAccess.document.id !== document.id)\n ) {\n throw new Forbidden(req.t)\n }\n }\n\n return { document, pipeline }\n}\n"],"names":["Forbidden","NotFound","TransformerContractError","checkFileAccess","retrieveFileResponse","createLazySourceGetter","finalizeFileResponse","getSourceFileResponse","getCandidateTransformers","planTransformerPipeline","getRequestedFile","resolveUploadDocument","withFileTransformAccessContext","handleDynamicFileRequest","collection","filename","prefix","req","resolvedDocument","isTransform","callback","t","original","searchParams","size","permittedDocument","doc","document","pipeline","authorizeDocument","requestedFile","source","retrieve","currentResponse","handedOutBodyControllers","Map","discardResponse","response","cancelUnusedBody","get","abort","delete","transformer","previousResponse","handedOutResponse","handedOutBodyController","AbortController","stageSource","withAbortableBody","signal","set","result","handleRequest","collectionSlug","config","slug","documentID","id","getSourceFile","mimeType","wasCalled","status","err","payload","logger","error","msg","values","body","stream","TransformStream","start","controller","addEventListener","reason","once","Response","pipeThrough","headers","statusText","locked","cancel","planRequestPipeline","args","operation","capability","transformers","upload","accessResults","checkAccess","has","then","isAllowed","hasCandidateTransformers","length","isTransformAccess","access","requiredAccess"],"mappings":"AAKA,SAASA,SAAS,QAAQ,4BAA2B;AACrD,SAASC,QAAQ,QAAQ,2BAA0B;AACnD,SAASC,wBAAwB,QAAQ,2CAA0C;AACnF,SAASC,eAAe,QAAQ,wBAAuB;AACvD,SAASC,oBAAoB,QAAQ,0BAAyB;AAC9D,SAASC,sBAAsB,QAAQ,8BAA6B;AACpE,SAASC,oBAAoB,QAAQ,4BAA2B;AAChE,SAASC,qBAAqB,QAAQ,6BAA4B;AAClE,SAASC,wBAAwB,EAAEC,uBAAuB,QAAQ,+BAA8B;AAChG,SAASC,gBAAgB,EAAEC,qBAAqB,QAAQ,6BAA4B;AACpF,SAASC,8BAA8B,QAAQ,sCAAqC;AAEpF;;;;;;;;CAQC,GACD,OAAO,eAAeC,yBAAyB,EAC7CC,UAAU,EACVC,QAAQ,EACRC,MAAM,EACNC,GAAG,EAMJ;IACC,MAAMC,mBAAmB,MAAMP,sBAAsB;QAAEG;QAAYC;QAAUC;QAAQC;IAAI;IAEzF,IAAI,CAACC,kBAAkB;QACrB,8EAA8E;QAC9E,iFAAiF;QACjF,mEAAmE;QACnE,KAAK,MAAMC,eAAe;YAAC;YAAM;SAAM,CAAE;YACvC,MAAMP,+BAA+B;gBACnCQ,UAAU,IAAMjB,gBAAgB;wBAAEW;wBAAYC;wBAAUC;wBAAQC;oBAAI;gBACpEE;gBACAF;YACF;QACF;QACA,MAAM,IAAIhB,SAASgB,IAAII,CAAC;IAC1B;IAEA,IACEH,iBAAiBI,QAAQ,EAAEP,aAAaA,YACvCG,CAAAA,iBAAiBH,QAAQ,KAAKA,YAAYE,IAAIM,YAAY,CAACC,IAAI,KAAK,CAAA,GACrE;QACA,MAAMC,oBAAoB,MAAMb,+BAA+B;YAC7DQ,UAAU,IAAMjB,gBAAgB;oBAAEW;oBAAYC;oBAAUC;oBAAQC;gBAAI;YACpEE,aAAa;YACbF;QACF;QAEA,OAAOb,qBAAqB;YAC1BU;YACAY,KAAKD,qBAAqBP;YAC1BH;YACAC;YACAC;QACF;IACF;IAEA,MAAM,EAAEU,QAAQ,EAAEC,QAAQ,EAAE,GAAG,MAAMC,kBAAkB;QACrDf;QACAC;QACAC;QACAC;QACAC;IACF;IAEA,MAAMY,gBAAgBpB,iBAAiB;QAAEiB;QAAUZ;IAAS;IAE5D,MAAMgB,SAAS1B,uBAAuB;QACpC2B,UAAU,IAAMzB,sBAAsB;gBAAEO;gBAAYa;gBAAUZ;gBAAUC;gBAAQC;YAAI;IACtF;IAEA,IAAIgB;IACJ,oFAAoF;IACpF,yFAAyF;IACzF,MAAMC,2BAA2B,IAAIC;IAErC,MAAMC,kBAAkB,OAAOC;QAC7B,MAAMC,iBAAiBD;QACvBH,yBAAyBK,GAAG,CAACF,WAAWG;QACxCN,yBAAyBO,MAAM,CAACJ;IAClC;IAEA,IAAI;QACF,KAAK,MAAMK,eAAed,SAAU;YAClC,MAAMe,mBAAmBV;YACzB,IAAIW;YACJ,MAAMC,0BAA0B,IAAIC;YACpC,MAAMC,cAAc1C,uBAAuB;gBACzC2B,UAAU;oBACRY,oBAAoBI,kBAAkB;wBACpCX,UAAUJ,mBAAoB,MAAMF,OAAOQ,GAAG;wBAC9CU,QAAQJ,wBAAwBI,MAAM;oBACxC;oBACAf,yBAAyBgB,GAAG,CAACN,mBAAmBC;oBAEhD,OAAOD;gBACT;YACF;YAEA,MAAMO,SAAS,MAAMT,YAAYU,aAAa,CAAE;gBAC9CC,gBAAgBvC,WAAWwC,MAAM,CAACC,IAAI;gBACtCC,YAAY7B,SAAS8B,EAAE;gBACvB1C,UAAUe,cAAcf,QAAQ;gBAChC2C,eAAeX,YAAYR,GAAG;gBAC9BoB,UAAU7B,cAAc6B,QAAQ;gBAChC1C;YACF;YAEA,IAAIkC,OAAOd,QAAQ,EAAE;gBACnB,IAAIO,qBAAqBO,OAAOd,QAAQ,KAAKO,mBAAmB;oBAC9D,MAAMR,gBAAgBQ;gBACxB,OAAO,IAAI,CAACA,qBAAqBD,oBAAoBQ,OAAOd,QAAQ,KAAKM,kBAAkB;oBACzF,MAAMP,gBAAgBO;gBACxB;gBAEAV,kBAAkBkB,OAAOd,QAAQ;YACnC,OAAO,IAAIU,YAAYa,SAAS,IAAI;gBAClC,MAAM,IAAI1D,yBACR;YAEJ;YAEA,IAAIiD,OAAOU,MAAM,KAAK,YAAY;gBAChC,OAAOvD,qBAAqB;oBAAEQ;oBAAYG;oBAAKoB,UAAUJ;gBAAiB;YAC5E;QACF;IACF,EAAE,OAAO6B,KAAK;QACZ7C,IAAI8C,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC;YAAEH;YAAKI,KAAK;QAA8C;QACnF,KAAK,MAAMrB,2BAA2BX,yBAAyBiC,MAAM,GAAI;YACvEtB,wBAAwBL,KAAK,CAACsB;QAChC;QACA,MAAMxB,iBAAiBL;QACvB,MAAM6B;IACR;IAEA,IAAI7B,iBAAiB;QACnB,OAAO3B,qBAAqB;YAAEQ;YAAYG;YAAKoB,UAAUJ;QAAgB;IAC3E;IAEA,2EAA2E;IAC3E,qFAAqF;IACrF,OAAO7B,qBAAqB;QAAEU;QAAYY,KAAKC;QAAUZ;QAAUC;QAAQC;IAAI;AACjF;AAEA;;;CAGC,GACD,SAAS+B,kBAAkB,EACzBX,QAAQ,EACRY,MAAM,EAIP;IACC,IAAI,CAACZ,SAAS+B,IAAI,EAAE;QAClB,OAAO/B;IACT;IAEA,MAAMgC,SAAS,IAAIC,gBAAgB;QACjCC,OAAMC,UAAU;YACd,+EAA+E;YAC/E,kFAAkF;YAClFvB,OAAOwB,gBAAgB,CAAC,SAAS,IAAMD,WAAWP,KAAK,CAAChB,OAAOyB,MAAM,GAAG;gBAAEC,MAAM;YAAK;QACvF;IACF;IAEA,OAAO,IAAIC,SAASvC,SAAS+B,IAAI,CAACS,WAAW,CAACR,QAAQ;QAAEpB;IAAO,IAAI;QACjE6B,SAASzC,SAASyC,OAAO;QACzBjB,QAAQxB,SAASwB,MAAM;QACvBkB,YAAY1C,SAAS0C,UAAU;IACjC;AACF;AAEA;;;CAGC,GACD,eAAezC,iBAAiBD,QAA8B;IAC5D,IAAI,CAACA,UAAU+B,QAAQ/B,SAAS+B,IAAI,CAACY,MAAM,EAAE;QAC3C;IACF;IAEA,IAAI;QACF,MAAM3C,SAAS+B,IAAI,CAACa,MAAM;IAC5B,EAAE,OAAM;IACN,oEAAoE;IACtE;AACF;AAEA,SAASC,oBAAoB,EAC3BpE,UAAU,EACVa,QAAQ,EACRZ,QAAQ,EACRE,GAAG,EAMJ;IACC,OAAOR,wBAAwB;QAC7B0E,MAAM;YACJ9B,gBAAgBvC,WAAWwC,MAAM,CAACC,IAAI;YACtCC,YAAY7B,SAAS8B,EAAE;YACvBE,UAAUjD,iBAAiB;gBAAEiB;gBAAUZ;YAAS,GAAG4C,QAAQ;YAC3DyB,WAAW;YACXnE;QACF;QACAoE,YAAY;QACZC,cAAcrE,IAAI8C,OAAO,CAACT,MAAM,CAACiC,MAAM,CAACD,YAAY;IACtD;AACF;AAIA;;;;;;;;;;;;;;;;;CAiBC,GACD,eAAezD,kBAAkB,EAC/Bf,UAAU,EACVC,QAAQ,EACRC,MAAM,EACNC,GAAG,EACHC,gBAAgB,EAOjB;IACC,MAAMsE,gBAAgB,IAAIrD;IAE1B,MAAMsD,cAAc,CAAC,EAAEtE,WAAW,EAA4B;QAC5D,IAAI,CAACqE,cAAcE,GAAG,CAACvE,cAAc;YACnCqE,cAActC,GAAG,CACf/B,aACAP,+BAA+B;gBAC7BQ,UAAU,IAAMjB,gBAAgB;wBAAEW;wBAAYC;wBAAUC;wBAAQC;oBAAI;gBACpEE;gBACAF;YACF,GAAG0E,IAAI,CACL,CAAChE,WAAc,CAAA;oBACbA,UAAUA;oBACViE,WAAW;gBACb,CAAA,GACA,CAAC9B;gBACC,IAAIA,eAAe9D,WAAW;oBAC5B,OAAO;wBAAE4F,WAAW;oBAAe;gBACrC;gBAEA,MAAM9B;YACR;QAGN;QAEA,OAAO0B,cAAcjD,GAAG,CAACpB;IAC3B;IAEA,MAAM0E,2BACJrF,yBAAyB;QACvB6E,YAAY;QACZ1B,UAAUjD,iBAAiB;YAAEiB,UAAUT;YAAkBH;QAAS,GAAG4C,QAAQ;QAC7E2B,cAAcrE,IAAI8C,OAAO,CAACT,MAAM,CAACiC,MAAM,CAACD,YAAY;IACtD,GAAGQ,MAAM,GAAG;IAEd,IAAIC,oBAAoBF;IACxB,IAAIG,SAAS,MAAMP,YAAY;QAAEtE,aAAa4E;IAAkB;IAEhE,IAAI,CAACC,OAAOJ,SAAS,IAAIG,mBAAmB;QAC1CA,oBAAoB;QACpBC,SAAS,MAAMP,YAAY;YAAEtE,aAAa4E;QAAkB;IAC9D;IAEA,IAAI,CAACC,OAAOJ,SAAS,EAAE;QACrB,MAAM,IAAI5F,UAAUiB,IAAII,CAAC;IAC3B;IAEA,MAAMM,WACJqE,OAAOrE,QAAQ,IAAIqE,OAAOrE,QAAQ,CAAC8B,EAAE,KAAKvC,iBAAiBuC,EAAE,GACzDuC,OAAOrE,QAAQ,GACfT;IAEN,MAAMU,WAAW,MAAMsD,oBAAoB;QAAEpE;QAAYa;QAAUZ;QAAUE;IAAI;IACjF,MAAME,cAAcS,SAASkE,MAAM,GAAG;IAEtC,IAAI3E,gBAAgB4E,mBAAmB;QACrC,MAAME,iBAAiB,MAAMR,YAAY;YAAEtE;QAAY;QAEvD,IACE,CAAC8E,eAAeL,SAAS,IACxBK,eAAetE,QAAQ,IAAIsE,eAAetE,QAAQ,CAAC8B,EAAE,KAAK9B,SAAS8B,EAAE,EACtE;YACA,MAAM,IAAIzD,UAAUiB,IAAII,CAAC;QAC3B;IACF;IAEA,OAAO;QAAEM;QAAUC;IAAS;AAC9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addSelectGenericsToGeneretedTypes.d.ts","sourceRoot":"","sources":["../../src/utilities/addSelectGenericsToGeneretedTypes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC,gCAE3C;IACD,sBAAsB,EAAE,MAAM,CAAA;CAC/B,
|
|
1
|
+
{"version":3,"file":"addSelectGenericsToGeneretedTypes.d.ts","sourceRoot":"","sources":["../../src/utilities/addSelectGenericsToGeneretedTypes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC,gCAE3C;IACD,sBAAsB,EAAE,MAAM,CAAA;CAC/B,WAmDA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/addSelectGenericsToGeneretedTypes.ts"],"sourcesContent":["export const addSelectGenericsToGeneratedTypes = ({\n compiledGeneratedTypes,\n}: {\n compiledGeneratedTypes: string\n}) => {\n const modifiedLines: string[] = []\n\n let isCollectionsSelectToken = false\n let isSelectTypeToken = false\n\n for (const line of compiledGeneratedTypes.split('\\n')) {\n let newLine = line\n if (line === ` collectionsSelect: {` || line === ` globalsSelect: {`) {\n isCollectionsSelectToken = true\n }\n\n if (isCollectionsSelectToken) {\n if (line === ' };') {\n isCollectionsSelectToken = false\n } else {\n // replace <posts: PostsSelect;> with <posts: PostsSelect<true> | PostsSelect<false;>\n newLine = line.replace(/(['\"]?\\w+['\"]?):\\s*(\\w+);/g, (_, variable, type) => {\n return `${variable}: ${type}<false> | ${type}<true>;`\n })\n }\n }\n\n
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/addSelectGenericsToGeneretedTypes.ts"],"sourcesContent":["export const addSelectGenericsToGeneratedTypes = ({\n compiledGeneratedTypes,\n}: {\n compiledGeneratedTypes: string\n}) => {\n const modifiedLines: string[] = []\n\n let isCollectionsSelectToken = false\n let isSelectTypeToken = false\n\n for (const line of compiledGeneratedTypes.split('\\n')) {\n let newLine = line\n if (line === ` collectionsSelect: {` || line === ` globalsSelect: {`) {\n isCollectionsSelectToken = true\n }\n\n if (isCollectionsSelectToken) {\n if (line === ' };') {\n isCollectionsSelectToken = false\n } else {\n // replace <posts: PostsSelect;> with <posts: PostsSelect<true> | PostsSelect<false;>\n newLine = line.replace(/(['\"]?\\w+['\"]?):\\s*(\\w+);/g, (_, variable, type) => {\n return `${variable}: ${type}<false> | ${type}<true>;`\n })\n }\n }\n\n if (line.match(/via the `definition` \"([\\w-]+_select)\"/g)) {\n isSelectTypeToken = true\n }\n\n if (isSelectTypeToken) {\n if (line.startsWith('export interface')) {\n // add generic to the interface\n newLine = line.replace(/(export interface\\s+\\w+)(\\s*\\{)/g, '$1<T extends boolean = true>$2')\n } else {\n newLine = line\n // replace booleans with T on the line\n .replace(/(?<!\\?)\\bboolean\\b/g, 'T')\n // replace interface names like CtaBlock to CtaBlock<T>\n .replace(\n /\\b(\\w+)\\s*\\|\\s*(\\w+)\\b/g,\n (_match, left, right) => `${left} | ${right}<${left}>`,\n )\n\n if (line === '}') {\n isSelectTypeToken = false\n }\n }\n }\n\n modifiedLines.push(newLine)\n }\n\n return modifiedLines.join('\\n')\n}\n"],"names":["addSelectGenericsToGeneratedTypes","compiledGeneratedTypes","modifiedLines","isCollectionsSelectToken","isSelectTypeToken","line","split","newLine","replace","_","variable","type","match","startsWith","_match","left","right","push","join"],"mappings":"AAAA,OAAO,MAAMA,oCAAoC,CAAC,EAChDC,sBAAsB,EAGvB;IACC,MAAMC,gBAA0B,EAAE;IAElC,IAAIC,2BAA2B;IAC/B,IAAIC,oBAAoB;IAExB,KAAK,MAAMC,QAAQJ,uBAAuBK,KAAK,CAAC,MAAO;QACrD,IAAIC,UAAUF;QACd,IAAIA,SAAS,CAAC,sBAAsB,CAAC,IAAIA,SAAS,CAAC,kBAAkB,CAAC,EAAE;YACtEF,2BAA2B;QAC7B;QAEA,IAAIA,0BAA0B;YAC5B,IAAIE,SAAS,QAAQ;gBACnBF,2BAA2B;YAC7B,OAAO;gBACL,qFAAqF;gBACrFI,UAAUF,KAAKG,OAAO,CAAC,8BAA8B,CAACC,GAAGC,UAAUC;oBACjE,OAAO,GAAGD,SAAS,EAAE,EAAEC,KAAK,UAAU,EAAEA,KAAK,OAAO,CAAC;gBACvD;YACF;QACF;QAEA,IAAIN,KAAKO,KAAK,CAAC,4CAA4C;YACzDR,oBAAoB;QACtB;QAEA,IAAIA,mBAAmB;YACrB,IAAIC,KAAKQ,UAAU,CAAC,qBAAqB;gBACvC,+BAA+B;gBAC/BN,UAAUF,KAAKG,OAAO,CAAC,oCAAoC;YAC7D,OAAO;gBACLD,UAAUF,IACR,sCAAsC;iBACrCG,OAAO,CAAC,uBAAuB,IAChC,uDAAuD;iBACtDA,OAAO,CACN,2BACA,CAACM,QAAQC,MAAMC,QAAU,GAAGD,KAAK,GAAG,EAAEC,MAAM,CAAC,EAAED,KAAK,CAAC,CAAC;gBAG1D,IAAIV,SAAS,KAAK;oBAChBD,oBAAoB;gBACtB;YACF;QACF;QAEAF,cAAce,IAAI,CAACV;IACrB;IAEA,OAAOL,cAAcgB,IAAI,CAAC;AAC5B,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/appendDateTimezoneSelectFields.ts"],"sourcesContent":["import type { FlattenedField } from '../fields/config/types.js'\nimport type { SelectType } from '../types/index.js'\n\n/**\n * Mutates the incoming select object to append `{name}_tz` siblings for any date\n * field with `timezone` enabled that has been requested in the select. Without\n * this, the List View's Select API would omit the timezone sibling and\n * cells would render dates in the server's timezone.\n */\nexport const appendDateTimezoneSelectFields = ({\n fields,\n select,\n}: {\n fields: FlattenedField[]\n select: SelectType\n}) => {\n if (!select) {\n return\n }\n\n for (const field of fields) {\n if (!('name' in field)) {\n continue\n }\n\n const value = select[field.name]\n\n if (field.type === 'date' && field.timezone && value) {\n select[`${field.name}_tz`] = true\n continue\n }\n\n if (!value || typeof value !== 'object') {\n continue\n }\n\n if ('flattenedFields' in field) {\n appendDateTimezoneSelectFields({\n fields: field.flattenedFields,\n select: value
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/appendDateTimezoneSelectFields.ts"],"sourcesContent":["import type { FlattenedField } from '../fields/config/types.js'\nimport type { SelectType } from '../types/index.js'\n\n/**\n * Mutates the incoming select object to append `{name}_tz` siblings for any date\n * field with `timezone` enabled that has been requested in the select. Without\n * this, the List View's Select API would omit the timezone sibling and\n * cells would render dates in the server's timezone.\n */\nexport const appendDateTimezoneSelectFields = ({\n fields,\n select,\n}: {\n fields: FlattenedField[]\n select: SelectType\n}) => {\n if (!select) {\n return\n }\n\n for (const field of fields) {\n if (!('name' in field)) {\n continue\n }\n\n const value = select[field.name]\n\n if (field.type === 'date' && field.timezone && value) {\n select[`${field.name}_tz`] = true\n continue\n }\n\n if (!value || typeof value !== 'object') {\n continue\n }\n\n if ('flattenedFields' in field) {\n appendDateTimezoneSelectFields({\n fields: field.flattenedFields,\n select: value,\n })\n continue\n }\n\n if (field.type === 'blocks') {\n const blocks = field.blocks as Array<\n | {\n flattenedFields: FlattenedField[]\n slug: string\n }\n | string\n >\n\n for (const block of blocks) {\n if (typeof block === 'string') {\n continue\n }\n const blockSelect = value[block.slug]\n if (blockSelect && typeof blockSelect === 'object') {\n appendDateTimezoneSelectFields({\n fields: block.flattenedFields,\n select: blockSelect,\n })\n }\n }\n }\n }\n}\n"],"names":["appendDateTimezoneSelectFields","fields","select","field","value","name","type","timezone","flattenedFields","blocks","block","blockSelect","slug"],"mappings":"AAGA;;;;;CAKC,GACD,OAAO,MAAMA,iCAAiC,CAAC,EAC7CC,MAAM,EACNC,MAAM,EAIP;IACC,IAAI,CAACA,QAAQ;QACX;IACF;IAEA,KAAK,MAAMC,SAASF,OAAQ;QAC1B,IAAI,CAAE,CAAA,UAAUE,KAAI,GAAI;YACtB;QACF;QAEA,MAAMC,QAAQF,MAAM,CAACC,MAAME,IAAI,CAAC;QAEhC,IAAIF,MAAMG,IAAI,KAAK,UAAUH,MAAMI,QAAQ,IAAIH,OAAO;YACpDF,MAAM,CAAC,GAAGC,MAAME,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG;YAC7B;QACF;QAEA,IAAI,CAACD,SAAS,OAAOA,UAAU,UAAU;YACvC;QACF;QAEA,IAAI,qBAAqBD,OAAO;YAC9BH,+BAA+B;gBAC7BC,QAAQE,MAAMK,eAAe;gBAC7BN,QAAQE;YACV;YACA;QACF;QAEA,IAAID,MAAMG,IAAI,KAAK,UAAU;YAC3B,MAAMG,SAASN,MAAMM,MAAM;YAQ3B,KAAK,MAAMC,SAASD,OAAQ;gBAC1B,IAAI,OAAOC,UAAU,UAAU;oBAC7B;gBACF;gBACA,MAAMC,cAAcP,KAAK,CAACM,MAAME,IAAI,CAAC;gBACrC,IAAID,eAAe,OAAOA,gBAAgB,UAAU;oBAClDX,+BAA+B;wBAC7BC,QAAQS,MAAMF,eAAe;wBAC7BN,QAAQS;oBACV;gBACF;YACF;QACF;IACF;AACF,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/cloneValidationRequest.ts"],"sourcesContent":["import type { RequestContext, User } from '../index.js'\nimport type { PayloadRequest } from '../types/index.js'\n\nconst sharedValidationRequestProperties = new Set([\n 'i18n',\n 'payload',\n 'server',\n 'signal',\n 't',\n 'transactionID',\n])\n\nexport function cloneValidationContext({\n context,\n}: {\n context: RequestContext | undefined\n}): RequestContext | undefined {\n return cloneValidationValue(context)\n}\n\nexport function cloneValidationData<TData>({ data }: { data: TData }): TData {\n return cloneValidationValue(data)\n}\n\nexport function cloneValidationRequest({\n request,\n}: {\n request: Partial<PayloadRequest> | undefined\n}): Partial<PayloadRequest> {\n if (!request) {\n return {}\n }\n\n const payloadRequest: Partial<PayloadRequest> = request\n const fetchRequest: Request | undefined =\n typeof Request !== 'undefined' && request instanceof Request ? request : undefined\n const canCloneFetchRequest = fetchRequest && !fetchRequest.bodyUsed\n let clonedRequest: Record<string, unknown>\n\n if (canCloneFetchRequest) {\n clonedRequest = fetchRequest.clone() as unknown as Record<string, unknown>\n } else {\n clonedRequest = {}\n }\n\n for (const [key, value] of Object.entries(payloadRequest)) {\n if (key === 'payloadDataLoader') {\n continue\n }\n\n if (key === 'file') {\n clonedRequest.file = cloneValidationFile(payloadRequest.file)\n continue\n }\n\n if (key === 'files') {\n clonedRequest.files = cloneValidationFiles(payloadRequest.files)\n continue\n }\n\n clonedRequest[key] = sharedValidationRequestProperties.has(key)\n ? value\n : cloneValidationValue(value)\n }\n\n Object.assign(clonedRequest, {\n context: cloneValidationValue(payloadRequest.context ?? {}),\n query: cloneValidationValue(payloadRequest.query ?? {}),\n routeParams: cloneValidationValue(payloadRequest.routeParams ?? {}),\n })\n\n if (!canCloneFetchRequest) {\n Object.assign(clonedRequest, {\n headers: cloneValidationValue(payloadRequest.headers),\n method: payloadRequest.method,\n signal: payloadRequest.signal,\n url: payloadRequest.url,\n })\n }\n\n return clonedRequest as Partial<PayloadRequest>\n}\n\nexport function cloneValidationUser({\n user,\n}: {\n user: null | undefined | User\n}): null | undefined | User {\n return cloneValidationValue(user)\n}\n\nfunction cloneValidationFile(file: PayloadRequest['file']): PayloadRequest['file'] {\n if (!file) {\n return file\n }\n\n const { data, ...metadata } = file\n\n return {\n ...cloneValidationValue(metadata),\n data,\n }\n}\n\nfunction cloneValidationFiles(files: PayloadRequest['files']): PayloadRequest['files'] {\n if (!files) {\n return files\n }\n\n return Object.fromEntries(\n Object.entries(files).map(([fieldName, fileOrFiles]) => [\n fieldName,\n Array.isArray(fileOrFiles)\n ? fileOrFiles.map((file) => cloneValidationFile(file)!)\n : cloneValidationFile(fileOrFiles)!,\n ]),\n )\n}\n\nfunction cloneValidationValue<T>(value: T, cache = new WeakMap<object, unknown>()): T {\n if ((typeof value !== 'object' && typeof value !== 'function') || value === null) {\n return value\n }\n\n if (typeof value === 'function' || value instanceof Promise) {\n return value\n }\n\n const objectValue = value as object\n const cachedValue = cache.get(objectValue)\n\n if (cachedValue) {\n return cachedValue as T\n }\n\n if (value instanceof Headers) {\n return new Headers(value) as T\n }\n\n if (value instanceof URLSearchParams) {\n return new URLSearchParams(value) as T\n }\n\n if (value instanceof URL) {\n return new URL(value) as T\n }\n\n if (value instanceof Date) {\n return new Date(value) as T\n }\n\n if (value instanceof RegExp) {\n return new RegExp(value.source, value.flags) as T\n }\n\n if (value instanceof ArrayBuffer) {\n return value.slice(0) as T\n }\n\n if (ArrayBuffer.isView(value)) {\n if (Buffer.isBuffer(value)) {\n return Buffer.from(value) as T\n }\n\n if (value instanceof DataView) {\n return new DataView(value.buffer.slice(0), value.byteOffset, value.byteLength) as T\n }\n\n return new (value.constructor as new (input: typeof value) => typeof value)(value)\n }\n\n if (value instanceof Map) {\n const clonedMap = new Map()\n cache.set(objectValue, clonedMap)\n for (const [key, mapValue] of value) {\n clonedMap.set(cloneValidationValue(key, cache), cloneValidationValue(mapValue, cache))\n }\n return clonedMap as T\n }\n\n if (value instanceof Set) {\n const clonedSet = new Set()\n cache.set(objectValue, clonedSet)\n for (const setValue of value) {\n clonedSet.add(cloneValidationValue(setValue, cache))\n }\n return clonedSet as T\n }\n\n if (typeof Blob !== 'undefined' && value instanceof Blob) {\n return value\n }\n\n const prototype = Object.getPrototypeOf(value)\n\n if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {\n return value\n }\n\n const clonedValue: Record<PropertyKey, unknown> | unknown[] = Array.isArray(value)\n ? []\n : Object.create(prototype)\n cache.set(objectValue, clonedValue)\n\n for (const key of Reflect.ownKeys(value)) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key)\n\n if (descriptor?.enumerable) {\n ;(clonedValue as Record<PropertyKey, unknown>)[key] = cloneValidationValue(\n (value as Record<PropertyKey, unknown>)[key],\n cache,\n )\n }\n }\n\n return clonedValue as T\n}\n"],"names":["sharedValidationRequestProperties","Set","cloneValidationContext","context","cloneValidationValue","cloneValidationData","data","cloneValidationRequest","request","payloadRequest","fetchRequest","Request","undefined","canCloneFetchRequest","bodyUsed","clonedRequest","clone","key","value","Object","entries","file","cloneValidationFile","files","cloneValidationFiles","has","assign","query","routeParams","headers","method","signal","url","cloneValidationUser","user","metadata","fromEntries","map","fieldName","fileOrFiles","Array","isArray","cache","WeakMap","Promise","objectValue","cachedValue","get","Headers","URLSearchParams","URL","Date","RegExp","source","flags","ArrayBuffer","slice","isView","Buffer","isBuffer","from","DataView","buffer","byteOffset","byteLength","Map","clonedMap","set","mapValue","clonedSet","setValue","add","Blob","prototype","getPrototypeOf","clonedValue","create","Reflect","ownKeys","descriptor","getOwnPropertyDescriptor","enumerable"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/cloneValidationRequest.ts"],"sourcesContent":["import type { RequestContext, User } from '../index.js'\nimport type { PayloadRequest } from '../types/index.js'\n\nconst sharedValidationRequestProperties = new Set([\n 'i18n',\n 'payload',\n 'server',\n 'signal',\n 't',\n 'transactionID',\n])\n\nexport function cloneValidationContext({\n context,\n}: {\n context: RequestContext | undefined\n}): RequestContext | undefined {\n return cloneValidationValue(context)\n}\n\nexport function cloneValidationData<TData>({ data }: { data: TData }): TData {\n return cloneValidationValue(data)\n}\n\nexport function cloneValidationRequest({\n request,\n}: {\n request: Partial<PayloadRequest> | undefined\n}): Partial<PayloadRequest> {\n if (!request) {\n return {}\n }\n\n const payloadRequest: Partial<PayloadRequest> = request\n const fetchRequest: Request | undefined =\n typeof Request !== 'undefined' && request instanceof Request ? request : undefined\n const canCloneFetchRequest = fetchRequest && !fetchRequest.bodyUsed\n let clonedRequest: Record<string, unknown>\n\n if (canCloneFetchRequest) {\n clonedRequest = fetchRequest.clone() as unknown as Record<string, unknown>\n } else {\n clonedRequest = {}\n }\n\n for (const [key, value] of Object.entries(payloadRequest)) {\n if (key === 'payloadDataLoader') {\n continue\n }\n\n if (key === 'file') {\n clonedRequest.file = cloneValidationFile(payloadRequest.file)\n continue\n }\n\n if (key === 'files') {\n clonedRequest.files = cloneValidationFiles(payloadRequest.files)\n continue\n }\n\n clonedRequest[key] = sharedValidationRequestProperties.has(key)\n ? value\n : cloneValidationValue(value)\n }\n\n Object.assign(clonedRequest, {\n context: cloneValidationValue(payloadRequest.context ?? {}),\n query: cloneValidationValue(payloadRequest.query ?? {}),\n routeParams: cloneValidationValue(payloadRequest.routeParams ?? {}),\n })\n\n if (!canCloneFetchRequest) {\n Object.assign(clonedRequest, {\n headers: cloneValidationValue(payloadRequest.headers),\n method: payloadRequest.method,\n signal: payloadRequest.signal,\n url: payloadRequest.url,\n })\n }\n\n return clonedRequest\n}\n\nexport function cloneValidationUser({\n user,\n}: {\n user: null | undefined | User\n}): null | undefined | User {\n return cloneValidationValue(user)\n}\n\nfunction cloneValidationFile(file: PayloadRequest['file']): PayloadRequest['file'] {\n if (!file) {\n return file\n }\n\n const { data, ...metadata } = file\n\n return {\n ...cloneValidationValue(metadata),\n data,\n }\n}\n\nfunction cloneValidationFiles(files: PayloadRequest['files']): PayloadRequest['files'] {\n if (!files) {\n return files\n }\n\n return Object.fromEntries(\n Object.entries(files).map(([fieldName, fileOrFiles]) => [\n fieldName,\n Array.isArray(fileOrFiles)\n ? fileOrFiles.map((file) => cloneValidationFile(file)!)\n : cloneValidationFile(fileOrFiles)!,\n ]),\n )\n}\n\nfunction cloneValidationValue<T>(value: T, cache = new WeakMap<object, unknown>()): T {\n if ((typeof value !== 'object' && typeof value !== 'function') || value === null) {\n return value\n }\n\n if (typeof value === 'function' || value instanceof Promise) {\n return value\n }\n\n const objectValue = value as object\n const cachedValue = cache.get(objectValue)\n\n if (cachedValue) {\n return cachedValue as T\n }\n\n if (value instanceof Headers) {\n return new Headers(value) as T\n }\n\n if (value instanceof URLSearchParams) {\n return new URLSearchParams(value) as T\n }\n\n if (value instanceof URL) {\n return new URL(value) as T\n }\n\n if (value instanceof Date) {\n return new Date(value) as T\n }\n\n if (value instanceof RegExp) {\n return new RegExp(value.source, value.flags) as T\n }\n\n if (value instanceof ArrayBuffer) {\n return value.slice(0) as T\n }\n\n if (ArrayBuffer.isView(value)) {\n if (Buffer.isBuffer(value)) {\n return Buffer.from(value) as T\n }\n\n if (value instanceof DataView) {\n return new DataView(value.buffer.slice(0), value.byteOffset, value.byteLength) as T\n }\n\n return new (value.constructor as new (input: typeof value) => typeof value)(value)\n }\n\n if (value instanceof Map) {\n const clonedMap = new Map()\n cache.set(objectValue, clonedMap)\n for (const [key, mapValue] of value) {\n clonedMap.set(cloneValidationValue(key, cache), cloneValidationValue(mapValue, cache))\n }\n return clonedMap as T\n }\n\n if (value instanceof Set) {\n const clonedSet = new Set()\n cache.set(objectValue, clonedSet)\n for (const setValue of value) {\n clonedSet.add(cloneValidationValue(setValue, cache))\n }\n return clonedSet as T\n }\n\n if (typeof Blob !== 'undefined' && value instanceof Blob) {\n return value\n }\n\n const prototype = Object.getPrototypeOf(value)\n\n if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {\n return value\n }\n\n const clonedValue: Record<PropertyKey, unknown> | unknown[] = Array.isArray(value)\n ? []\n : Object.create(prototype)\n cache.set(objectValue, clonedValue)\n\n for (const key of Reflect.ownKeys(value)) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key)\n\n if (descriptor?.enumerable) {\n ;(clonedValue as Record<PropertyKey, unknown>)[key] = cloneValidationValue(\n (value as Record<PropertyKey, unknown>)[key],\n cache,\n )\n }\n }\n\n return clonedValue as T\n}\n"],"names":["sharedValidationRequestProperties","Set","cloneValidationContext","context","cloneValidationValue","cloneValidationData","data","cloneValidationRequest","request","payloadRequest","fetchRequest","Request","undefined","canCloneFetchRequest","bodyUsed","clonedRequest","clone","key","value","Object","entries","file","cloneValidationFile","files","cloneValidationFiles","has","assign","query","routeParams","headers","method","signal","url","cloneValidationUser","user","metadata","fromEntries","map","fieldName","fileOrFiles","Array","isArray","cache","WeakMap","Promise","objectValue","cachedValue","get","Headers","URLSearchParams","URL","Date","RegExp","source","flags","ArrayBuffer","slice","isView","Buffer","isBuffer","from","DataView","buffer","byteOffset","byteLength","Map","clonedMap","set","mapValue","clonedSet","setValue","add","Blob","prototype","getPrototypeOf","clonedValue","create","Reflect","ownKeys","descriptor","getOwnPropertyDescriptor","enumerable"],"mappings":"AAGA,MAAMA,oCAAoC,IAAIC,IAAI;IAChD;IACA;IACA;IACA;IACA;IACA;CACD;AAED,OAAO,SAASC,uBAAuB,EACrCC,OAAO,EAGR;IACC,OAAOC,qBAAqBD;AAC9B;AAEA,OAAO,SAASE,oBAA2B,EAAEC,IAAI,EAAmB;IAClE,OAAOF,qBAAqBE;AAC9B;AAEA,OAAO,SAASC,uBAAuB,EACrCC,OAAO,EAGR;IACC,IAAI,CAACA,SAAS;QACZ,OAAO,CAAC;IACV;IAEA,MAAMC,iBAA0CD;IAChD,MAAME,eACJ,OAAOC,YAAY,eAAeH,mBAAmBG,UAAUH,UAAUI;IAC3E,MAAMC,uBAAuBH,gBAAgB,CAACA,aAAaI,QAAQ;IACnE,IAAIC;IAEJ,IAAIF,sBAAsB;QACxBE,gBAAgBL,aAAaM,KAAK;IACpC,OAAO;QACLD,gBAAgB,CAAC;IACnB;IAEA,KAAK,MAAM,CAACE,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACX,gBAAiB;QACzD,IAAIQ,QAAQ,qBAAqB;YAC/B;QACF;QAEA,IAAIA,QAAQ,QAAQ;YAClBF,cAAcM,IAAI,GAAGC,oBAAoBb,eAAeY,IAAI;YAC5D;QACF;QAEA,IAAIJ,QAAQ,SAAS;YACnBF,cAAcQ,KAAK,GAAGC,qBAAqBf,eAAec,KAAK;YAC/D;QACF;QAEAR,aAAa,CAACE,IAAI,GAAGjB,kCAAkCyB,GAAG,CAACR,OACvDC,QACAd,qBAAqBc;IAC3B;IAEAC,OAAOO,MAAM,CAACX,eAAe;QAC3BZ,SAASC,qBAAqBK,eAAeN,OAAO,IAAI,CAAC;QACzDwB,OAAOvB,qBAAqBK,eAAekB,KAAK,IAAI,CAAC;QACrDC,aAAaxB,qBAAqBK,eAAemB,WAAW,IAAI,CAAC;IACnE;IAEA,IAAI,CAACf,sBAAsB;QACzBM,OAAOO,MAAM,CAACX,eAAe;YAC3Bc,SAASzB,qBAAqBK,eAAeoB,OAAO;YACpDC,QAAQrB,eAAeqB,MAAM;YAC7BC,QAAQtB,eAAesB,MAAM;YAC7BC,KAAKvB,eAAeuB,GAAG;QACzB;IACF;IAEA,OAAOjB;AACT;AAEA,OAAO,SAASkB,oBAAoB,EAClCC,IAAI,EAGL;IACC,OAAO9B,qBAAqB8B;AAC9B;AAEA,SAASZ,oBAAoBD,IAA4B;IACvD,IAAI,CAACA,MAAM;QACT,OAAOA;IACT;IAEA,MAAM,EAAEf,IAAI,EAAE,GAAG6B,UAAU,GAAGd;IAE9B,OAAO;QACL,GAAGjB,qBAAqB+B,SAAS;QACjC7B;IACF;AACF;AAEA,SAASkB,qBAAqBD,KAA8B;IAC1D,IAAI,CAACA,OAAO;QACV,OAAOA;IACT;IAEA,OAAOJ,OAAOiB,WAAW,CACvBjB,OAAOC,OAAO,CAACG,OAAOc,GAAG,CAAC,CAAC,CAACC,WAAWC,YAAY,GAAK;YACtDD;YACAE,MAAMC,OAAO,CAACF,eACVA,YAAYF,GAAG,CAAC,CAAChB,OAASC,oBAAoBD,SAC9CC,oBAAoBiB;SACzB;AAEL;AAEA,SAASnC,qBAAwBc,KAAQ,EAAEwB,QAAQ,IAAIC,SAA0B;IAC/E,IAAI,AAAC,OAAOzB,UAAU,YAAY,OAAOA,UAAU,cAAeA,UAAU,MAAM;QAChF,OAAOA;IACT;IAEA,IAAI,OAAOA,UAAU,cAAcA,iBAAiB0B,SAAS;QAC3D,OAAO1B;IACT;IAEA,MAAM2B,cAAc3B;IACpB,MAAM4B,cAAcJ,MAAMK,GAAG,CAACF;IAE9B,IAAIC,aAAa;QACf,OAAOA;IACT;IAEA,IAAI5B,iBAAiB8B,SAAS;QAC5B,OAAO,IAAIA,QAAQ9B;IACrB;IAEA,IAAIA,iBAAiB+B,iBAAiB;QACpC,OAAO,IAAIA,gBAAgB/B;IAC7B;IAEA,IAAIA,iBAAiBgC,KAAK;QACxB,OAAO,IAAIA,IAAIhC;IACjB;IAEA,IAAIA,iBAAiBiC,MAAM;QACzB,OAAO,IAAIA,KAAKjC;IAClB;IAEA,IAAIA,iBAAiBkC,QAAQ;QAC3B,OAAO,IAAIA,OAAOlC,MAAMmC,MAAM,EAAEnC,MAAMoC,KAAK;IAC7C;IAEA,IAAIpC,iBAAiBqC,aAAa;QAChC,OAAOrC,MAAMsC,KAAK,CAAC;IACrB;IAEA,IAAID,YAAYE,MAAM,CAACvC,QAAQ;QAC7B,IAAIwC,OAAOC,QAAQ,CAACzC,QAAQ;YAC1B,OAAOwC,OAAOE,IAAI,CAAC1C;QACrB;QAEA,IAAIA,iBAAiB2C,UAAU;YAC7B,OAAO,IAAIA,SAAS3C,MAAM4C,MAAM,CAACN,KAAK,CAAC,IAAItC,MAAM6C,UAAU,EAAE7C,MAAM8C,UAAU;QAC/E;QAEA,OAAO,IAAK9C,MAAM,WAAW,CAA+CA;IAC9E;IAEA,IAAIA,iBAAiB+C,KAAK;QACxB,MAAMC,YAAY,IAAID;QACtBvB,MAAMyB,GAAG,CAACtB,aAAaqB;QACvB,KAAK,MAAM,CAACjD,KAAKmD,SAAS,IAAIlD,MAAO;YACnCgD,UAAUC,GAAG,CAAC/D,qBAAqBa,KAAKyB,QAAQtC,qBAAqBgE,UAAU1B;QACjF;QACA,OAAOwB;IACT;IAEA,IAAIhD,iBAAiBjB,KAAK;QACxB,MAAMoE,YAAY,IAAIpE;QACtByC,MAAMyB,GAAG,CAACtB,aAAawB;QACvB,KAAK,MAAMC,YAAYpD,MAAO;YAC5BmD,UAAUE,GAAG,CAACnE,qBAAqBkE,UAAU5B;QAC/C;QACA,OAAO2B;IACT;IAEA,IAAI,OAAOG,SAAS,eAAetD,iBAAiBsD,MAAM;QACxD,OAAOtD;IACT;IAEA,MAAMuD,YAAYtD,OAAOuD,cAAc,CAACxD;IAExC,IAAI,CAACsB,MAAMC,OAAO,CAACvB,UAAUuD,cAActD,OAAOsD,SAAS,IAAIA,cAAc,MAAM;QACjF,OAAOvD;IACT;IAEA,MAAMyD,cAAwDnC,MAAMC,OAAO,CAACvB,SACxE,EAAE,GACFC,OAAOyD,MAAM,CAACH;IAClB/B,MAAMyB,GAAG,CAACtB,aAAa8B;IAEvB,KAAK,MAAM1D,OAAO4D,QAAQC,OAAO,CAAC5D,OAAQ;QACxC,MAAM6D,aAAa5D,OAAO6D,wBAAwB,CAAC9D,OAAOD;QAE1D,IAAI8D,YAAYE,YAAY;;YACxBN,WAA4C,CAAC1D,IAAI,GAAGb,qBACpD,AAACc,KAAsC,CAACD,IAAI,EAC5CyB;QAEJ;IACF;IAEA,OAAOiC;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/createPayloadRequest.ts"],"sourcesContent":["import type { Payload, RequestContext, TypedLocale, User } from '../index.js'\nimport type { PayloadRequest } from '../types/index.js'\n\nimport { getDataLoader } from '../collections/dataloader.js'\nimport { getLocalI18n } from '../translations/getLocalI18n.js'\nimport { sanitizeFallbackLocale } from '../utilities/sanitizeFallbackLocale.js'\n\nfunction getRequestContext(\n req: Partial<PayloadRequest> = { context: null } as unknown as PayloadRequest,\n context: RequestContext = {},\n): RequestContext {\n if (req.context) {\n if (Object.keys(req.context).length === 0 && req.context.constructor === Object) {\n // if req.context is `{}` avoid unnecessary spread\n return context\n } else {\n return { ...req.context, ...context }\n }\n } else {\n return context\n }\n}\n\nconst attachFakeURLProperties = (req: Partial<PayloadRequest>, urlSuffix?: string) => {\n /**\n * *NOTE*\n * If no URL is provided, the local API was called outside\n * the context of a request. Therefore we create a fake URL object.\n * `ts-expect-error` is used below for properties that are 'read-only'.\n * Since they do not exist yet we can safely ignore the error.\n */\n let urlObject: undefined | URL\n\n function getURLObject() {\n if (urlObject) {\n return urlObject\n }\n\n const fallbackURL = `http://${req.host || 'localhost'}${urlSuffix || ''}`\n\n const urlToUse =\n req?.url ||\n (req.payload?.config?.serverURL\n ? `${req.payload?.config.serverURL}${urlSuffix || ''}`\n : fallbackURL)\n\n try {\n urlObject = new URL(urlToUse)\n } catch (_err) {\n req.payload?.logger.error(\n `Failed to create URL object from URL: ${urlToUse}, falling back to ${fallbackURL}`,\n )\n\n urlObject = new URL(fallbackURL)\n }\n\n return urlObject\n }\n\n if (!req.host) {\n req.host = getURLObject().host\n }\n\n if (!req.protocol) {\n req.protocol = getURLObject().protocol\n }\n\n if (!req.pathname) {\n req.pathname = getURLObject().pathname\n }\n\n if (!req.searchParams) {\n // @ts-expect-error eslint-disable-next-line no-param-reassign\n req.searchParams = getURLObject().searchParams\n }\n\n if (!req.origin) {\n // @ts-expect-error eslint-disable-next-line no-param-reassign\n req.origin = getURLObject().origin\n }\n\n if (!req?.url) {\n // @ts-expect-error eslint-disable-next-line no-param-reassign\n req.url = getURLObject().href\n }\n}\n\nexport type CreatePayloadRequestArgs = {\n context?: RequestContext\n depth?: number\n fallbackLocale?: false | TypedLocale\n locale?: string\n payload: Payload\n req?: Partial<PayloadRequest>\n urlSuffix?: string\n user?: null | User\n}\n\ntype CreatePayloadRequest = (args: CreatePayloadRequestArgs) => Promise<PayloadRequest>\n\nexport const createPayloadRequest: CreatePayloadRequest = async ({\n context,\n depth,\n fallbackLocale,\n locale: localeArg,\n payload,\n req = {}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/createPayloadRequest.ts"],"sourcesContent":["import type { Payload, RequestContext, TypedLocale, User } from '../index.js'\nimport type { PayloadRequest } from '../types/index.js'\n\nimport { getDataLoader } from '../collections/dataloader.js'\nimport { getLocalI18n } from '../translations/getLocalI18n.js'\nimport { sanitizeFallbackLocale } from '../utilities/sanitizeFallbackLocale.js'\n\nfunction getRequestContext(\n req: Partial<PayloadRequest> = { context: null } as unknown as PayloadRequest,\n context: RequestContext = {},\n): RequestContext {\n if (req.context) {\n if (Object.keys(req.context).length === 0 && req.context.constructor === Object) {\n // if req.context is `{}` avoid unnecessary spread\n return context\n } else {\n return { ...req.context, ...context }\n }\n } else {\n return context\n }\n}\n\nconst attachFakeURLProperties = (req: Partial<PayloadRequest>, urlSuffix?: string) => {\n /**\n * *NOTE*\n * If no URL is provided, the local API was called outside\n * the context of a request. Therefore we create a fake URL object.\n * `ts-expect-error` is used below for properties that are 'read-only'.\n * Since they do not exist yet we can safely ignore the error.\n */\n let urlObject: undefined | URL\n\n function getURLObject() {\n if (urlObject) {\n return urlObject\n }\n\n const fallbackURL = `http://${req.host || 'localhost'}${urlSuffix || ''}`\n\n const urlToUse =\n req?.url ||\n (req.payload?.config?.serverURL\n ? `${req.payload?.config.serverURL}${urlSuffix || ''}`\n : fallbackURL)\n\n try {\n urlObject = new URL(urlToUse)\n } catch (_err) {\n req.payload?.logger.error(\n `Failed to create URL object from URL: ${urlToUse}, falling back to ${fallbackURL}`,\n )\n\n urlObject = new URL(fallbackURL)\n }\n\n return urlObject\n }\n\n if (!req.host) {\n req.host = getURLObject().host\n }\n\n if (!req.protocol) {\n req.protocol = getURLObject().protocol\n }\n\n if (!req.pathname) {\n req.pathname = getURLObject().pathname\n }\n\n if (!req.searchParams) {\n // @ts-expect-error eslint-disable-next-line no-param-reassign\n req.searchParams = getURLObject().searchParams\n }\n\n if (!req.origin) {\n // @ts-expect-error eslint-disable-next-line no-param-reassign\n req.origin = getURLObject().origin\n }\n\n if (!req?.url) {\n // @ts-expect-error eslint-disable-next-line no-param-reassign\n req.url = getURLObject().href\n }\n}\n\nexport type CreatePayloadRequestArgs = {\n context?: RequestContext\n depth?: number\n fallbackLocale?: false | TypedLocale\n locale?: string\n payload: Payload\n req?: Partial<PayloadRequest>\n urlSuffix?: string\n user?: null | User\n}\n\ntype CreatePayloadRequest = (args: CreatePayloadRequestArgs) => Promise<PayloadRequest>\n\nexport const createPayloadRequest: CreatePayloadRequest = async ({\n context,\n depth,\n fallbackLocale,\n locale: localeArg,\n payload,\n req = {},\n urlSuffix,\n user,\n}): Promise<PayloadRequest> => {\n const localization = payload.config?.localization\n\n if (localization) {\n const locale = localeArg === '*' ? 'all' : localeArg\n const defaultLocale = localization.defaultLocale\n const localeCandidate = locale || req?.locale || req?.query?.locale\n\n req.locale =\n localeCandidate && typeof localeCandidate === 'string' ? localeCandidate : defaultLocale\n\n const sanitizedFallback = sanitizeFallbackLocale({\n fallbackLocale: fallbackLocale!,\n locale: req.locale,\n localization,\n })\n\n req.fallbackLocale = sanitizedFallback!\n }\n\n const i18n =\n req?.i18n ||\n (await getLocalI18n({ config: payload.config, language: payload.config.i18n.fallbackLanguage }))\n\n if (!req.headers) {\n req.headers = new Headers()\n }\n\n req.context = getRequestContext(req, context)\n req.payloadAPI = req?.payloadAPI || 'local'\n req.payload = payload\n req.i18n = i18n\n req.t = i18n.t\n req.user = user === undefined ? (req?.user ?? null) : user\n\n // Ensure user.collection is set for auth-related access control\n // TODO (4.0): Instead of silently falling back, throw an error if user.collection is missing\n if (req.user && !req.user.collection) {\n req.user = { ...req.user, collection: payload.config.admin.user }\n }\n\n req.payloadDataLoader = req?.payloadDataLoader || getDataLoader(req as PayloadRequest)\n req.routeParams = req?.routeParams || {}\n req.query = req?.query || {}\n\n if (typeof depth !== 'undefined') {\n req.query.depth = depth\n }\n\n attachFakeURLProperties(req, urlSuffix)\n\n return req as PayloadRequest\n}\n"],"names":["getDataLoader","getLocalI18n","sanitizeFallbackLocale","getRequestContext","req","context","Object","keys","length","attachFakeURLProperties","urlSuffix","urlObject","getURLObject","fallbackURL","host","urlToUse","url","payload","config","serverURL","URL","_err","logger","error","protocol","pathname","searchParams","origin","href","createPayloadRequest","depth","fallbackLocale","locale","localeArg","user","localization","defaultLocale","localeCandidate","query","sanitizedFallback","i18n","language","fallbackLanguage","headers","Headers","payloadAPI","t","undefined","collection","admin","payloadDataLoader","routeParams"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/deepCopyObject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { JsonValue } from '../types/index.js'\n\n/*\nMain deepCopyObject handling - from rfdc: https://github.com/davidmarkclements/rfdc/blob/master/index.js\n\nCopyright 2019 \"David Mark Clements <david.mark.clements@gmail.com>\"\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and\nto permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions\nof the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\nTO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\nTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\nCONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n*/\n\nfunction copyBuffer(cur: any) {\n if (cur instanceof Buffer) {\n return Buffer.from(cur)\n }\n\n return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)\n}\n\nconst constructorHandlers = new Map()\nconstructorHandlers.set(Date, (o: any) => new Date(o))\nconstructorHandlers.set(Map, (o: any, fn: any) => new Map(cloneArray<any>(Array.from(o), fn)))\nconstructorHandlers.set(Set, (o: any, fn: any) => new Set(cloneArray(Array.from(o), fn)))\nconstructorHandlers.set(RegExp, (regex: RegExp) => new RegExp(regex.source, regex.flags))\n\nlet handler: ((o: any, fn: any) => any) | null = null\n\nfunction cloneArray<T extends object>(a: T, fn: (o: any) => any): T {\n const keys = Object.keys(a)\n const a2 = new Array(keys.length) as T\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i] as keyof typeof a\n const cur = a[k] as any\n if (typeof cur !== 'object' || cur === null) {\n setClonedValue({ key: k, target: a2, value: cur })\n } else if (cur instanceof RegExp) {\n setClonedValue({ key: k, target: a2, value: new RegExp(cur.source, cur.flags) })\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n setClonedValue({ key: k, target: a2, value: handler(cur, fn) })\n } else if (ArrayBuffer.isView(cur)) {\n setClonedValue({ key: k, target: a2, value: copyBuffer(cur) })\n } else {\n setClonedValue({ key: k, target: a2, value: fn(cur) })\n }\n }\n return a2\n}\n\nexport const deepCopyObject = <T>(o: T): T => {\n if (typeof o !== 'object' || o === null) {\n return o\n }\n if (Array.isArray(o)) {\n return cloneArray(o, deepCopyObject)\n }\n if (o instanceof RegExp) {\n return new RegExp(o.source, o.flags) as T\n }\n\n if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {\n return handler(o, deepCopyObject)\n }\n const o2 = {} as Record<PropertyKey, any> & T\n for (const k in o) {\n if (Object.hasOwnProperty.call(o, k) === false) {\n continue\n }\n const cur = o[k]\n if (typeof cur !== 'object' || cur === null) {\n setClonedValue({ key: k, target: o2, value: cur })\n } else if (cur instanceof RegExp) {\n setClonedValue({ key: k, target: o2, value: new RegExp(cur.source, cur.flags) })\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n setClonedValue({ key: k, target: o2, value: handler(cur, deepCopyObject) })\n } else if (ArrayBuffer.isView(cur)) {\n setClonedValue({ key: k, target: o2, value: copyBuffer(cur) })\n } else {\n setClonedValue({ key: k, target: o2, value: deepCopyObject(cur) })\n }\n }\n return o2\n}\n\n/*\nFast deepCopyObjectSimple handling - from fast-json-clone: https://github.com/rhysd/fast-json-clone\n\nBenchmark: https://github.com/AlessioGr/fastest-deep-clone-json/blob/main/test/benchmark.js\n*/\n\n/**\n * A deepCopyObject implementation which only works for JSON objects and arrays, and is faster than\n * JSON.parse(JSON.stringify(obj))\n *\n * @param value The JSON value to be cloned. There are two invariants. 1) It must not contain circles\n * as JSON does not allow it. This function will cause infinite loop for such values by\n * design. 2) It must contain JSON values only. Other values like `Date`, `Regexp`, `Map`,\n * `Set`, `Buffer`, ... are not allowed.\n * @returns The cloned JSON value.\n */\nexport function deepCopyObjectSimple<T extends JsonValue>(value: T, filterUndefined = false): T {\n if (typeof value !== 'object' || value === null) {\n return value\n } else if (Array.isArray(value)) {\n const clone = new Array(value.length)\n\n for (let index = 0; index < value.length; index++) {\n if (!Object.hasOwn(value, index)) {\n continue\n }\n\n const element = value[index]\n setClonedValue({\n key: index,\n target: clone,\n value:\n typeof element !== 'object' || element === null\n ? element\n : deepCopyObjectSimple(element, filterUndefined),\n })\n }\n\n return clone as T\n } else {\n if (value instanceof Date) {\n return new Date(value) as unknown as T\n }\n // BSON ObjectId instances expose extra enumerable properties (e.g. `buffer`) via `for...in`\n // that corrupt the copy. Detect BSON types early and convert them to their string representation.\n if ('_bsontype' in value && typeof (value as any).toHexString === 'function') {\n return (value as any).toHexString() as unknown as T\n }\n const ret: { [key: string]: T } = {}\n const objectValue = value as Record<string, T>\n for (const k of Object.keys(objectValue)) {\n const v = objectValue[k]\n if (filterUndefined && v === undefined) {\n continue\n }\n setClonedValue({\n key: k,\n target: ret,\n value:\n typeof v !== 'object' || v === null\n ? v\n : (deepCopyObjectSimple(v as T, filterUndefined) as any),\n })\n }\n return ret as unknown as T\n }\n}\n\nexport function deepCopyObjectSimpleWithoutReactComponents<T extends JsonValue>(\n value: T,\n opts: {\n excludeFiles?: boolean\n } = {},\n): T {\n if (\n typeof value === 'object' &&\n value !== null &&\n '$$typeof' in value &&\n typeof value.$$typeof === 'symbol'\n ) {\n return undefined!\n } else if (typeof value !== 'object' || value === null) {\n return value\n } else if (Array.isArray(value)) {\n const clone = new Array(value.length)\n\n for (let index = 0; index < value.length; index++) {\n if (!Object.hasOwn(value, index)) {\n continue\n }\n\n const element = value[index]\n setClonedValue({\n key: index,\n target: clone,\n value:\n typeof element !== 'object' || element === null\n ? element\n : deepCopyObjectSimpleWithoutReactComponents(element, opts),\n })\n }\n\n return clone as T\n } else {\n // Handle File objects by returning them as-is (don't serialize to plain object) or exclude if excludeFiles is provided\n if (value instanceof File) {\n if (opts.excludeFiles) {\n return undefined!\n }\n\n return value as unknown as T\n }\n if (value instanceof Date) {\n return new Date(value) as unknown as T\n }\n if ('_bsontype' in value && typeof (value as any).toHexString === 'function') {\n return (value as any).toHexString() as unknown as T\n }\n const ret: { [key: string]: T } = {}\n const objectValue = value as Record<string, T>\n for (const k of Object.keys(objectValue)) {\n const v = objectValue[k]\n setClonedValue({\n key: k,\n target: ret,\n value:\n typeof v !== 'object' || v === null\n ? v\n : (deepCopyObjectSimpleWithoutReactComponents(v as T, opts) as any),\n })\n }\n return ret as unknown as T\n }\n}\n\n/**\n * A deepCopyObject implementation which is slower than deepCopyObject, but more correct.\n * Can be used if correctness is more important than speed. Supports circular dependencies\n */\nexport function deepCopyObjectComplex<T>(object: T, cache: WeakMap<any, any> = new WeakMap()): T {\n if (object === null) {\n return null!\n }\n\n if (cache.has(object)) {\n return cache.get(object)\n }\n\n // Handle File\n if (object instanceof File) {\n return object as unknown as T\n }\n\n // Handle Date\n if (object instanceof Date) {\n return new Date(object.getTime()) as unknown as T\n }\n\n // Handle RegExp\n if (object instanceof RegExp) {\n return new RegExp(object.source, object.flags) as unknown as T\n }\n\n // Handle Map\n if (object instanceof Map) {\n const clonedMap = new Map()\n cache.set(object, clonedMap)\n for (const [key, value] of object.entries()) {\n clonedMap.set(key, deepCopyObjectComplex(value, cache))\n }\n return clonedMap as unknown as T\n }\n\n // Handle Set\n if (object instanceof Set) {\n const clonedSet = new Set()\n cache.set(object, clonedSet)\n for (const value of object.values()) {\n clonedSet.add(deepCopyObjectComplex(value, cache))\n }\n return clonedSet as unknown as T\n }\n\n // Handle Array and Object\n if (typeof object === 'object' && object !== null) {\n if ('$$typeof' in object && typeof object.$$typeof === 'symbol') {\n return object\n }\n\n const clonedObject: any = Array.isArray(object)\n ? []\n : Object.create(Object.getPrototypeOf(object))\n cache.set(object, clonedObject)\n\n for (const key in object) {\n if (\n Object.prototype.hasOwnProperty.call(object, key) ||\n Object.getOwnPropertySymbols(object).includes(key as any)\n ) {\n setClonedValue({\n key,\n target: clonedObject,\n value: deepCopyObjectComplex(object[key], cache),\n })\n }\n }\n\n return clonedObject as T\n }\n\n // Handle all other cases\n return object\n}\n\nfunction setClonedValue<TTarget extends Record<PropertyKey, any>>({\n key,\n target,\n value,\n}: {\n key: PropertyKey\n target: TTarget\n value: any\n}): TTarget {\n if (key === '__proto__' || (!Object.hasOwn(target, key) && key in target)) {\n Object.defineProperty(target, key, {\n configurable: true,\n enumerable: true,\n value,\n writable: true,\n })\n } else if (!Reflect.set(target, key, value)) {\n throw new TypeError(`Cannot assign to property ${String(key)}`)\n }\n\n return target\n}\n"],"names":["copyBuffer","cur","Buffer","from","buffer","slice","byteOffset","length","constructorHandlers","Map","set","Date","o","fn","cloneArray","Array","Set","RegExp","regex","source","flags","handler","a","keys","Object","a2","i","k","setClonedValue","key","target","value","get","ArrayBuffer","isView","deepCopyObject","isArray","o2","hasOwnProperty","call","deepCopyObjectSimple","filterUndefined","clone","index","hasOwn","element","toHexString","ret","objectValue","v","undefined","deepCopyObjectSimpleWithoutReactComponents","opts","$$typeof","File","excludeFiles","deepCopyObjectComplex","object","cache","WeakMap","has","getTime","clonedMap","entries","clonedSet","values","add","clonedObject","create","getPrototypeOf","prototype","getOwnPropertySymbols","includes","defineProperty","configurable","enumerable","writable","Reflect","TypeError","String"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/deepCopyObject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { JsonValue } from '../types/index.js'\n\n/*\nMain deepCopyObject handling - from rfdc: https://github.com/davidmarkclements/rfdc/blob/master/index.js\n\nCopyright 2019 \"David Mark Clements <david.mark.clements@gmail.com>\"\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and\nto permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions\nof the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\nTO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\nTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\nCONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n*/\n\nfunction copyBuffer(cur: any) {\n if (cur instanceof Buffer) {\n return Buffer.from(cur)\n }\n\n return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)\n}\n\nconst constructorHandlers = new Map()\nconstructorHandlers.set(Date, (o: any) => new Date(o))\nconstructorHandlers.set(Map, (o: any, fn: any) => new Map(cloneArray<any>(Array.from(o), fn)))\nconstructorHandlers.set(Set, (o: any, fn: any) => new Set(cloneArray(Array.from(o), fn)))\nconstructorHandlers.set(RegExp, (regex: RegExp) => new RegExp(regex.source, regex.flags))\n\nlet handler: ((o: any, fn: any) => any) | null = null\n\nfunction cloneArray<T extends object>(a: T, fn: (o: any) => any): T {\n const keys = Object.keys(a)\n const a2 = new Array(keys.length) as T\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i] as keyof typeof a\n const cur = a[k] as any\n if (typeof cur !== 'object' || cur === null) {\n setClonedValue({ key: k, target: a2, value: cur })\n } else if (cur instanceof RegExp) {\n setClonedValue({ key: k, target: a2, value: new RegExp(cur.source, cur.flags) })\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n setClonedValue({ key: k, target: a2, value: handler(cur, fn) })\n } else if (ArrayBuffer.isView(cur)) {\n setClonedValue({ key: k, target: a2, value: copyBuffer(cur) })\n } else {\n setClonedValue({ key: k, target: a2, value: fn(cur) })\n }\n }\n return a2\n}\n\nexport const deepCopyObject = <T>(o: T): T => {\n if (typeof o !== 'object' || o === null) {\n return o\n }\n if (Array.isArray(o)) {\n return cloneArray(o, deepCopyObject)\n }\n if (o instanceof RegExp) {\n return new RegExp(o.source, o.flags) as T\n }\n\n if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {\n return handler(o, deepCopyObject)\n }\n const o2 = {} as Record<PropertyKey, any> & T\n for (const k in o) {\n if (Object.hasOwnProperty.call(o, k) === false) {\n continue\n }\n const cur = o[k]\n if (typeof cur !== 'object' || cur === null) {\n setClonedValue({ key: k, target: o2, value: cur })\n } else if (cur instanceof RegExp) {\n setClonedValue({ key: k, target: o2, value: new RegExp(cur.source, cur.flags) })\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n setClonedValue({ key: k, target: o2, value: handler(cur, deepCopyObject) })\n } else if (ArrayBuffer.isView(cur)) {\n setClonedValue({ key: k, target: o2, value: copyBuffer(cur) })\n } else {\n setClonedValue({ key: k, target: o2, value: deepCopyObject(cur) })\n }\n }\n return o2\n}\n\n/*\nFast deepCopyObjectSimple handling - from fast-json-clone: https://github.com/rhysd/fast-json-clone\n\nBenchmark: https://github.com/AlessioGr/fastest-deep-clone-json/blob/main/test/benchmark.js\n*/\n\n/**\n * A deepCopyObject implementation which only works for JSON objects and arrays, and is faster than\n * JSON.parse(JSON.stringify(obj))\n *\n * @param value The JSON value to be cloned. There are two invariants. 1) It must not contain circles\n * as JSON does not allow it. This function will cause infinite loop for such values by\n * design. 2) It must contain JSON values only. Other values like `Date`, `Regexp`, `Map`,\n * `Set`, `Buffer`, ... are not allowed.\n * @returns The cloned JSON value.\n */\nexport function deepCopyObjectSimple<T extends JsonValue>(value: T, filterUndefined = false): T {\n if (typeof value !== 'object' || value === null) {\n return value\n } else if (Array.isArray(value)) {\n const clone = new Array(value.length)\n\n for (let index = 0; index < value.length; index++) {\n if (!Object.hasOwn(value, index)) {\n continue\n }\n\n const element = value[index]\n setClonedValue({\n key: index,\n target: clone,\n value:\n typeof element !== 'object' || element === null\n ? element\n : deepCopyObjectSimple(element, filterUndefined),\n })\n }\n\n return clone as T\n } else {\n if (value instanceof Date) {\n return new Date(value) as unknown as T\n }\n // BSON ObjectId instances expose extra enumerable properties (e.g. `buffer`) via `for...in`\n // that corrupt the copy. Detect BSON types early and convert them to their string representation.\n if ('_bsontype' in value && typeof (value as any).toHexString === 'function') {\n return (value as any).toHexString()\n }\n const ret: { [key: string]: T } = {}\n const objectValue = value as Record<string, T>\n for (const k of Object.keys(objectValue)) {\n const v = objectValue[k]\n if (filterUndefined && v === undefined) {\n continue\n }\n setClonedValue({\n key: k,\n target: ret,\n value:\n typeof v !== 'object' || v === null\n ? v\n : (deepCopyObjectSimple(v as T, filterUndefined) as any),\n })\n }\n return ret as unknown as T\n }\n}\n\nexport function deepCopyObjectSimpleWithoutReactComponents<T extends JsonValue>(\n value: T,\n opts: {\n excludeFiles?: boolean\n } = {},\n): T {\n if (\n typeof value === 'object' &&\n value !== null &&\n '$$typeof' in value &&\n typeof value.$$typeof === 'symbol'\n ) {\n return undefined!\n } else if (typeof value !== 'object' || value === null) {\n return value\n } else if (Array.isArray(value)) {\n const clone = new Array(value.length)\n\n for (let index = 0; index < value.length; index++) {\n if (!Object.hasOwn(value, index)) {\n continue\n }\n\n const element = value[index]\n setClonedValue({\n key: index,\n target: clone,\n value:\n typeof element !== 'object' || element === null\n ? element\n : deepCopyObjectSimpleWithoutReactComponents(element, opts),\n })\n }\n\n return clone as T\n } else {\n // Handle File objects by returning them as-is (don't serialize to plain object) or exclude if excludeFiles is provided\n if (value instanceof File) {\n if (opts.excludeFiles) {\n return undefined!\n }\n\n return value\n }\n if (value instanceof Date) {\n return new Date(value) as unknown as T\n }\n if ('_bsontype' in value && typeof (value as any).toHexString === 'function') {\n return (value as any).toHexString()\n }\n const ret: { [key: string]: T } = {}\n const objectValue = value as Record<string, T>\n for (const k of Object.keys(objectValue)) {\n const v = objectValue[k]\n setClonedValue({\n key: k,\n target: ret,\n value:\n typeof v !== 'object' || v === null\n ? v\n : (deepCopyObjectSimpleWithoutReactComponents(v as T, opts) as any),\n })\n }\n return ret as unknown as T\n }\n}\n\n/**\n * A deepCopyObject implementation which is slower than deepCopyObject, but more correct.\n * Can be used if correctness is more important than speed. Supports circular dependencies\n */\nexport function deepCopyObjectComplex<T>(object: T, cache: WeakMap<any, any> = new WeakMap()): T {\n if (object === null) {\n return null!\n }\n\n if (cache.has(object)) {\n return cache.get(object)\n }\n\n // Handle File\n if (object instanceof File) {\n return object\n }\n\n // Handle Date\n if (object instanceof Date) {\n return new Date(object.getTime()) as unknown as T\n }\n\n // Handle RegExp\n if (object instanceof RegExp) {\n return new RegExp(object.source, object.flags) as unknown as T\n }\n\n // Handle Map\n if (object instanceof Map) {\n const clonedMap = new Map()\n cache.set(object, clonedMap)\n for (const [key, value] of object.entries()) {\n clonedMap.set(key, deepCopyObjectComplex(value, cache))\n }\n return clonedMap as unknown as T\n }\n\n // Handle Set\n if (object instanceof Set) {\n const clonedSet = new Set()\n cache.set(object, clonedSet)\n for (const value of object.values()) {\n clonedSet.add(deepCopyObjectComplex(value, cache))\n }\n return clonedSet as unknown as T\n }\n\n // Handle Array and Object\n if (typeof object === 'object' && object !== null) {\n if ('$$typeof' in object && typeof object.$$typeof === 'symbol') {\n return object\n }\n\n const clonedObject: any = Array.isArray(object)\n ? []\n : Object.create(Object.getPrototypeOf(object))\n cache.set(object, clonedObject)\n\n for (const key in object) {\n if (\n Object.prototype.hasOwnProperty.call(object, key) ||\n Object.getOwnPropertySymbols(object).includes(key as any)\n ) {\n setClonedValue({\n key,\n target: clonedObject,\n value: deepCopyObjectComplex(object[key], cache),\n })\n }\n }\n\n return clonedObject as T\n }\n\n // Handle all other cases\n return object\n}\n\nfunction setClonedValue<TTarget extends Record<PropertyKey, any>>({\n key,\n target,\n value,\n}: {\n key: PropertyKey\n target: TTarget\n value: any\n}): TTarget {\n if (key === '__proto__' || (!Object.hasOwn(target, key) && key in target)) {\n Object.defineProperty(target, key, {\n configurable: true,\n enumerable: true,\n value,\n writable: true,\n })\n } else if (!Reflect.set(target, key, value)) {\n throw new TypeError(`Cannot assign to property ${String(key)}`)\n }\n\n return target\n}\n"],"names":["copyBuffer","cur","Buffer","from","buffer","slice","byteOffset","length","constructorHandlers","Map","set","Date","o","fn","cloneArray","Array","Set","RegExp","regex","source","flags","handler","a","keys","Object","a2","i","k","setClonedValue","key","target","value","get","ArrayBuffer","isView","deepCopyObject","isArray","o2","hasOwnProperty","call","deepCopyObjectSimple","filterUndefined","clone","index","hasOwn","element","toHexString","ret","objectValue","v","undefined","deepCopyObjectSimpleWithoutReactComponents","opts","$$typeof","File","excludeFiles","deepCopyObjectComplex","object","cache","WeakMap","has","getTime","clonedMap","entries","clonedSet","values","add","clonedObject","create","getPrototypeOf","prototype","getOwnPropertySymbols","includes","defineProperty","configurable","enumerable","writable","Reflect","TypeError","String"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/documentMatchingWhereExists.ts"],"sourcesContent":["import type { DefaultDocumentIDType, Locale } from '../index.js'\nimport type { PayloadRequest, Where } from '../types/index.js'\n\nimport { isolateObjectProperty } from './isolateObjectProperty.js'\n\nexport type DocumentMatchingWhereExistsArgs = {\n collection: string\n /**\n * When true, also matches documents whose value only exists in a draft version. A versioned\n * collection keeps draft data in `_versions`, which the main-collection query — and the unique\n * index — would miss.\n */\n draftsEnabled?: boolean\n /** Exclude this document, so a document does not conflict with itself on update. */\n id?: DefaultDocumentIDType\n locale?: Locale['code']\n overrideAccess?: boolean\n req: PayloadRequest\n where: Where\n}\n\n/** Whether another document in `collection` matches `where`. */\nexport const documentMatchingWhereExists = async ({\n id,\n collection,\n draftsEnabled,\n locale,\n overrideAccess = false,\n req,\n where,\n}: DocumentMatchingWhereExistsArgs): Promise<boolean> => {\n const queryReq = isolateObjectProperty(req, ['query', 'transactionID'])\n queryReq.query = { ...req.query }\n delete queryReq.transactionID\n const includeTrashed = Boolean(req.payload.collections[collection]?.config.trash)\n\n const { docs } = await req.payload.find({\n collection,\n depth: 0,\n disableErrors: true,\n draft: Boolean(draftsEnabled),\n limit: 2,\n locale
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/documentMatchingWhereExists.ts"],"sourcesContent":["import type { DefaultDocumentIDType, Locale } from '../index.js'\nimport type { PayloadRequest, Where } from '../types/index.js'\n\nimport { isolateObjectProperty } from './isolateObjectProperty.js'\n\nexport type DocumentMatchingWhereExistsArgs = {\n collection: string\n /**\n * When true, also matches documents whose value only exists in a draft version. A versioned\n * collection keeps draft data in `_versions`, which the main-collection query — and the unique\n * index — would miss.\n */\n draftsEnabled?: boolean\n /** Exclude this document, so a document does not conflict with itself on update. */\n id?: DefaultDocumentIDType\n locale?: Locale['code']\n overrideAccess?: boolean\n req: PayloadRequest\n where: Where\n}\n\n/** Whether another document in `collection` matches `where`. */\nexport const documentMatchingWhereExists = async ({\n id,\n collection,\n draftsEnabled,\n locale,\n overrideAccess = false,\n req,\n where,\n}: DocumentMatchingWhereExistsArgs): Promise<boolean> => {\n const queryReq = isolateObjectProperty(req, ['query', 'transactionID'])\n queryReq.query = { ...req.query }\n delete queryReq.transactionID\n const includeTrashed = Boolean(req.payload.collections[collection]?.config.trash)\n\n const { docs } = await req.payload.find({\n collection,\n depth: 0,\n disableErrors: true,\n draft: Boolean(draftsEnabled),\n limit: 2,\n locale,\n overrideAccess,\n pagination: false,\n req: queryReq,\n trash: includeTrashed,\n where,\n })\n\n return docs.some((doc) => doc.id !== id)\n}\n"],"names":["isolateObjectProperty","documentMatchingWhereExists","id","collection","draftsEnabled","locale","overrideAccess","req","where","queryReq","query","transactionID","includeTrashed","Boolean","payload","collections","config","trash","docs","find","depth","disableErrors","draft","limit","pagination","some","doc"],"mappings":"AAGA,SAASA,qBAAqB,QAAQ,6BAA4B;AAkBlE,8DAA8D,GAC9D,OAAO,MAAMC,8BAA8B,OAAO,EAChDC,EAAE,EACFC,UAAU,EACVC,aAAa,EACbC,MAAM,EACNC,iBAAiB,KAAK,EACtBC,GAAG,EACHC,KAAK,EAC2B;IAChC,MAAMC,WAAWT,sBAAsBO,KAAK;QAAC;QAAS;KAAgB;IACtEE,SAASC,KAAK,GAAG;QAAE,GAAGH,IAAIG,KAAK;IAAC;IAChC,OAAOD,SAASE,aAAa;IAC7B,MAAMC,iBAAiBC,QAAQN,IAAIO,OAAO,CAACC,WAAW,CAACZ,WAAW,EAAEa,OAAOC;IAE3E,MAAM,EAAEC,IAAI,EAAE,GAAG,MAAMX,IAAIO,OAAO,CAACK,IAAI,CAAC;QACtChB;QACAiB,OAAO;QACPC,eAAe;QACfC,OAAOT,QAAQT;QACfmB,OAAO;QACPlB;QACAC;QACAkB,YAAY;QACZjB,KAAKE;QACLQ,OAAOL;QACPJ;IACF;IAEA,OAAOU,KAAKO,IAAI,CAAC,CAACC,MAAQA,IAAIxB,EAAE,KAAKA;AACvC,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/filterDataToSelectedLocales.ts"],"sourcesContent":["import type { Block, Field, FlattenedBlock } from '../fields/config/types.js'\nimport type { SanitizedConfig } from '../index.js'\nimport type { JsonObject } from '../types/index.js'\n\nimport { fieldAffectsData, fieldShouldBeLocalized, tabHasName } from '../fields/config/types.js'\n\ntype FilterDataToSelectedLocalesArgs = {\n configBlockReferences: SanitizedConfig['blocks']\n docWithLocales: JsonObject\n fields: Field[]\n parentIsLocalized?: boolean\n selectedLocales: string[]\n}\n\n/**\n * Filters a locale map to selected locales and applies a transform to each locale's value.\n */\nfunction filterLocaleMap(\n localeMap: Record<string, unknown>,\n selectedLocales: string[],\n transform: (value: unknown) => unknown,\n): Record<string, unknown> {\n const filtered: Record<string, unknown> = {}\n const localesToInclude =\n selectedLocales && selectedLocales.length > 0 ? selectedLocales : Object.keys(localeMap)\n\n for (const locale of localesToInclude) {\n if (locale in localeMap) {\n filtered[locale] = transform(localeMap[locale])\n }\n }\n\n return Object.keys(filtered).length > 0 ? filtered : {}\n}\n\n/**\n * Filters localized field data to only include specified locales.\n * For non-localized fields, returns all data as-is.\n * For localized fields, if selectedLocales is provided, returns only those locales.\n * If selectedLocales is not provided and field is localized, returns all locales.\n */\nexport function filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales,\n fields,\n parentIsLocalized = false,\n selectedLocales,\n}: FilterDataToSelectedLocalesArgs): JsonObject {\n if (!docWithLocales || typeof docWithLocales !== 'object') {\n return docWithLocales\n }\n\n const result: JsonObject = {}\n\n for (const field of fields) {\n if (fieldAffectsData(field)) {\n const fieldIsLocalized = fieldShouldBeLocalized({ field, parentIsLocalized })\n\n switch (field.type) {\n case 'array': {\n if (!(field.name in docWithLocales)) {\n break\n }\n\n const arrayValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n if (arrayValue && typeof arrayValue === 'object' && !Array.isArray(arrayValue)) {\n result[field.name] = filterLocaleMap(arrayValue, selectedLocales, (localeRows) =>\n Array.isArray(localeRows)\n ? localeRows.map((item: JsonObject) =>\n filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales: item,\n fields: field.fields,\n parentIsLocalized: fieldIsLocalized,\n selectedLocales,\n }),\n )\n : localeRows,\n )\n }\n } else if (Array.isArray(arrayValue)) {\n result[field.name] = arrayValue.map((item: JsonObject) =>\n filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales: item,\n fields: field.fields,\n parentIsLocalized: fieldIsLocalized,\n selectedLocales,\n }),\n )\n }\n\n break\n }\n\n case 'blocks': {\n if (!(field.name in docWithLocales)) {\n break\n }\n\n const blocksValue = docWithLocales[field.name]\n\n const processBlockRows = (rows: unknown): unknown => {\n if (!Array.isArray(rows)) {\n return rows\n }\n\n return rows.map((blockData: JsonObject) => {\n const blockOrSlug = field.blocks.find((b) => {\n const slug = typeof b === 'string' ? b : b.slug\n return slug === blockData.blockType\n })\n const block: Block | FlattenedBlock | undefined =\n typeof blockOrSlug === 'string'\n ? configBlockReferences?.find((b) => b.slug === blockOrSlug)\n : blockOrSlug\n\n if (block) {\n const filtered = filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales: blockData,\n fields: block?.fields || [],\n parentIsLocalized: fieldIsLocalized,\n selectedLocales,\n })\n\n // blockType, id, blockName are set by Payload internally\n // and not part of block.fields, so they must be preserved explicitly\n filtered.blockType = blockData.blockType\n filtered.id = blockData.id\n filtered.blockName = blockData.blockName\n\n return filtered\n }\n\n return blockData\n })\n }\n\n if (fieldIsLocalized) {\n if (blocksValue && typeof blocksValue === 'object' && !Array.isArray(blocksValue)) {\n result[field.name] = filterLocaleMap(blocksValue, selectedLocales, (localeRows) =>\n processBlockRows(localeRows),\n )\n }\n } else if (Array.isArray(blocksValue)) {\n result[field.name] = processBlockRows(blocksValue)\n }\n\n break\n }\n\n case 'group': {\n if (field.name in docWithLocales && typeof docWithLocales[field.name] === 'object') {\n const groupValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n if (groupValue && typeof groupValue === 'object' && !Array.isArray(groupValue)) {\n result[field.name] = filterLocaleMap(groupValue, selectedLocales, (localeValue) => {\n if (\n localeValue &&\n typeof localeValue === 'object' &&\n !Array.isArray(localeValue)\n ) {\n return filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales: localeValue as JsonObject,\n fields: field.fields,\n parentIsLocalized: fieldIsLocalized,\n selectedLocales,\n })\n }\n return localeValue\n })\n }\n } else if (typeof groupValue === 'object' && !Array.isArray(groupValue)) {\n result[field.name] = filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales: groupValue as JsonObject,\n fields: field.fields,\n parentIsLocalized: fieldIsLocalized,\n selectedLocales,\n })\n }\n } else {\n // Unnamed groups pass through the same data level\n const nestedResult = filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales,\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n Object.assign(result, nestedResult)\n }\n break\n }\n\n default: {\n if (field.name in docWithLocales) {\n const value = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n result[field.name] = filterLocaleMap(\n value,\n selectedLocales,\n (localeValue) => localeValue,\n )\n }\n } else {\n result[field.name] = value\n }\n }\n break\n }\n }\n } else {\n // Layout-only fields that don't affect data structure\n switch (field.type) {\n case 'collapsible':\n case 'group':\n case 'row': {\n // These pass through the same data level\n const nestedResult = filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales,\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n Object.assign(result, nestedResult)\n break\n }\n\n case 'tabs': {\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n // Named tabs create a nested data structure\n if (tab.name in docWithLocales && typeof docWithLocales[tab.name] === 'object') {\n result[tab.name] = filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales: docWithLocales[tab.name],\n fields: tab.fields,\n parentIsLocalized,\n selectedLocales,\n })\n }\n } else {\n // Unnamed tabs pass through the same data level\n const nestedResult = filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales,\n fields: tab.fields,\n parentIsLocalized,\n selectedLocales,\n })\n Object.assign(result, nestedResult)\n }\n }\n break\n }\n }\n }\n }\n\n return result\n}\n"],"names":["fieldAffectsData","fieldShouldBeLocalized","tabHasName","filterLocaleMap","localeMap","selectedLocales","transform","filtered","localesToInclude","length","Object","keys","locale","filterDataToSelectedLocales","configBlockReferences","docWithLocales","fields","parentIsLocalized","result","field","fieldIsLocalized","type","name","arrayValue","Array","isArray","localeRows","map","item","blocksValue","processBlockRows","rows","blockData","blockOrSlug","blocks","find","b","slug","blockType","block","id","blockName","groupValue","localeValue","nestedResult","assign","value","tab","tabs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/filterDataToSelectedLocales.ts"],"sourcesContent":["import type { Block, Field, FlattenedBlock } from '../fields/config/types.js'\nimport type { SanitizedConfig } from '../index.js'\nimport type { JsonObject } from '../types/index.js'\n\nimport { fieldAffectsData, fieldShouldBeLocalized, tabHasName } from '../fields/config/types.js'\n\ntype FilterDataToSelectedLocalesArgs = {\n configBlockReferences: SanitizedConfig['blocks']\n docWithLocales: JsonObject\n fields: Field[]\n parentIsLocalized?: boolean\n selectedLocales: string[]\n}\n\n/**\n * Filters a locale map to selected locales and applies a transform to each locale's value.\n */\nfunction filterLocaleMap(\n localeMap: Record<string, unknown>,\n selectedLocales: string[],\n transform: (value: unknown) => unknown,\n): Record<string, unknown> {\n const filtered: Record<string, unknown> = {}\n const localesToInclude =\n selectedLocales && selectedLocales.length > 0 ? selectedLocales : Object.keys(localeMap)\n\n for (const locale of localesToInclude) {\n if (locale in localeMap) {\n filtered[locale] = transform(localeMap[locale])\n }\n }\n\n return Object.keys(filtered).length > 0 ? filtered : {}\n}\n\n/**\n * Filters localized field data to only include specified locales.\n * For non-localized fields, returns all data as-is.\n * For localized fields, if selectedLocales is provided, returns only those locales.\n * If selectedLocales is not provided and field is localized, returns all locales.\n */\nexport function filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales,\n fields,\n parentIsLocalized = false,\n selectedLocales,\n}: FilterDataToSelectedLocalesArgs): JsonObject {\n if (!docWithLocales || typeof docWithLocales !== 'object') {\n return docWithLocales\n }\n\n const result: JsonObject = {}\n\n for (const field of fields) {\n if (fieldAffectsData(field)) {\n const fieldIsLocalized = fieldShouldBeLocalized({ field, parentIsLocalized })\n\n switch (field.type) {\n case 'array': {\n if (!(field.name in docWithLocales)) {\n break\n }\n\n const arrayValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n if (arrayValue && typeof arrayValue === 'object' && !Array.isArray(arrayValue)) {\n result[field.name] = filterLocaleMap(arrayValue, selectedLocales, (localeRows) =>\n Array.isArray(localeRows)\n ? localeRows.map((item: JsonObject) =>\n filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales: item,\n fields: field.fields,\n parentIsLocalized: fieldIsLocalized,\n selectedLocales,\n }),\n )\n : localeRows,\n )\n }\n } else if (Array.isArray(arrayValue)) {\n result[field.name] = arrayValue.map((item: JsonObject) =>\n filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales: item,\n fields: field.fields,\n parentIsLocalized: fieldIsLocalized,\n selectedLocales,\n }),\n )\n }\n\n break\n }\n\n case 'blocks': {\n if (!(field.name in docWithLocales)) {\n break\n }\n\n const blocksValue = docWithLocales[field.name]\n\n const processBlockRows = (rows: unknown): unknown => {\n if (!Array.isArray(rows)) {\n return rows\n }\n\n return rows.map((blockData: JsonObject) => {\n const blockOrSlug = field.blocks.find((b) => {\n const slug = typeof b === 'string' ? b : b.slug\n return slug === blockData.blockType\n })\n const block: Block | FlattenedBlock | undefined =\n typeof blockOrSlug === 'string'\n ? configBlockReferences?.find((b) => b.slug === blockOrSlug)\n : blockOrSlug\n\n if (block) {\n const filtered = filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales: blockData,\n fields: block?.fields || [],\n parentIsLocalized: fieldIsLocalized,\n selectedLocales,\n })\n\n // blockType, id, blockName are set by Payload internally\n // and not part of block.fields, so they must be preserved explicitly\n filtered.blockType = blockData.blockType\n filtered.id = blockData.id\n filtered.blockName = blockData.blockName\n\n return filtered\n }\n\n return blockData\n })\n }\n\n if (fieldIsLocalized) {\n if (blocksValue && typeof blocksValue === 'object' && !Array.isArray(blocksValue)) {\n result[field.name] = filterLocaleMap(blocksValue, selectedLocales, (localeRows) =>\n processBlockRows(localeRows),\n )\n }\n } else if (Array.isArray(blocksValue)) {\n result[field.name] = processBlockRows(blocksValue)\n }\n\n break\n }\n\n case 'group': {\n if (field.name in docWithLocales && typeof docWithLocales[field.name] === 'object') {\n const groupValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n if (groupValue && typeof groupValue === 'object' && !Array.isArray(groupValue)) {\n result[field.name] = filterLocaleMap(groupValue, selectedLocales, (localeValue) => {\n if (\n localeValue &&\n typeof localeValue === 'object' &&\n !Array.isArray(localeValue)\n ) {\n return filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales: localeValue,\n fields: field.fields,\n parentIsLocalized: fieldIsLocalized,\n selectedLocales,\n })\n }\n return localeValue\n })\n }\n } else if (typeof groupValue === 'object' && !Array.isArray(groupValue)) {\n result[field.name] = filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales: groupValue as JsonObject,\n fields: field.fields,\n parentIsLocalized: fieldIsLocalized,\n selectedLocales,\n })\n }\n } else {\n // Unnamed groups pass through the same data level\n const nestedResult = filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales,\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n Object.assign(result, nestedResult)\n }\n break\n }\n\n default: {\n if (field.name in docWithLocales) {\n const value = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n result[field.name] = filterLocaleMap(\n value,\n selectedLocales,\n (localeValue) => localeValue,\n )\n }\n } else {\n result[field.name] = value\n }\n }\n break\n }\n }\n } else {\n // Layout-only fields that don't affect data structure\n switch (field.type) {\n case 'collapsible':\n case 'group':\n case 'row': {\n // These pass through the same data level\n const nestedResult = filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales,\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n Object.assign(result, nestedResult)\n break\n }\n\n case 'tabs': {\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n // Named tabs create a nested data structure\n if (tab.name in docWithLocales && typeof docWithLocales[tab.name] === 'object') {\n result[tab.name] = filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales: docWithLocales[tab.name],\n fields: tab.fields,\n parentIsLocalized,\n selectedLocales,\n })\n }\n } else {\n // Unnamed tabs pass through the same data level\n const nestedResult = filterDataToSelectedLocales({\n configBlockReferences,\n docWithLocales,\n fields: tab.fields,\n parentIsLocalized,\n selectedLocales,\n })\n Object.assign(result, nestedResult)\n }\n }\n break\n }\n }\n }\n }\n\n return result\n}\n"],"names":["fieldAffectsData","fieldShouldBeLocalized","tabHasName","filterLocaleMap","localeMap","selectedLocales","transform","filtered","localesToInclude","length","Object","keys","locale","filterDataToSelectedLocales","configBlockReferences","docWithLocales","fields","parentIsLocalized","result","field","fieldIsLocalized","type","name","arrayValue","Array","isArray","localeRows","map","item","blocksValue","processBlockRows","rows","blockData","blockOrSlug","blocks","find","b","slug","blockType","block","id","blockName","groupValue","localeValue","nestedResult","assign","value","tab","tabs"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getEntityPermissions.d.ts","sourceRoot":"","sources":["../../../src/utilities/getEntityPermissions/getEntityPermissions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EAEpB,gBAAgB,EAEjB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,yBAAyB,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAC9F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAS,MAAM,sBAAsB,CAAA;AAQ5F,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAC7C,SAAS,EACT,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAC7C,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,UAAU,CAAA;AAE/C,KAAK,UAAU,CAAC,WAAW,SAAS,YAAY,GAAG,QAAQ,IAAI,WAAW,SAAS,QAAQ,GACvF,gBAAgB,GAChB,oBAAoB,CAAA;AAExB,KAAK,IAAI,CAAC,WAAW,SAAS,YAAY,GAAG,QAAQ,IAAI;IACvD,0BAA0B,EAAE,0BAA0B,CAAA;IACtD;;OAEG;IACH,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,MAAM,EAAE,WAAW,SAAS,YAAY,GAAG,yBAAyB,GAAG,qBAAqB,CAAA;IAC5F,UAAU,EAAE,WAAW,CAAA;IACvB;;OAEG;IACH,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,GAAG,EAAE,cAAc,CAAA;CACpB,GAAG,CACA;IACE,SAAS,EAAE,KAAK,CAAA;IAChB,EAAE,CAAC,EAAE,KAAK,CAAA;CACX,GACD;IACE,SAAS,EAAE,IAAI,CAAA;IACf,EAAE,EAAE,WAAW,SAAS,YAAY,GAAG,qBAAqB,GAAG,SAAS,CAAA;CACzE,CACJ,CAAA;AAaD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,oBAAoB,CAAC,WAAW,SAAS,YAAY,GAAG,QAAQ,EACpF,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,GACtB,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"getEntityPermissions.d.ts","sourceRoot":"","sources":["../../../src/utilities/getEntityPermissions/getEntityPermissions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EAEpB,gBAAgB,EAEjB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,yBAAyB,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAC9F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAS,MAAM,sBAAsB,CAAA;AAQ5F,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAC7C,SAAS,EACT,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAC7C,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,UAAU,CAAA;AAE/C,KAAK,UAAU,CAAC,WAAW,SAAS,YAAY,GAAG,QAAQ,IAAI,WAAW,SAAS,QAAQ,GACvF,gBAAgB,GAChB,oBAAoB,CAAA;AAExB,KAAK,IAAI,CAAC,WAAW,SAAS,YAAY,GAAG,QAAQ,IAAI;IACvD,0BAA0B,EAAE,0BAA0B,CAAA;IACtD;;OAEG;IACH,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,MAAM,EAAE,WAAW,SAAS,YAAY,GAAG,yBAAyB,GAAG,qBAAqB,CAAA;IAC5F,UAAU,EAAE,WAAW,CAAA;IACvB;;OAEG;IACH,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,GAAG,EAAE,cAAc,CAAA;CACpB,GAAG,CACA;IACE,SAAS,EAAE,KAAK,CAAA;IAChB,EAAE,CAAC,EAAE,KAAK,CAAA;CACX,GACD;IACE,SAAS,EAAE,IAAI,CAAA;IACf,EAAE,EAAE,WAAW,SAAS,YAAY,GAAG,qBAAqB,GAAG,SAAS,CAAA;CACzE,CACJ,CAAA;AAaD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,oBAAoB,CAAC,WAAW,SAAS,YAAY,GAAG,QAAQ,EACpF,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,GACtB,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAwKlC"}
|
|
@@ -133,6 +133,7 @@ const topLevelGlobalPermissions = [
|
|
|
133
133
|
// Await all where query DB calls in parallel
|
|
134
134
|
await Promise.all(wherePromises);
|
|
135
135
|
populateFieldPermissions({
|
|
136
|
+
id,
|
|
136
137
|
blockReferencesPermissions,
|
|
137
138
|
collection: entityType === 'collection' ? entity : null,
|
|
138
139
|
data,
|