UNPKG

payload

Version:

Node, React, Headless CMS and Application Framework built on Next.js

297 lines (296 loc) • 11.8 kB
// @ts-strict-ignore import crypto from 'crypto'; import { ensureUsernameOrEmail } from '../../auth/ensureUsernameOrEmail.js'; import executeAccess from '../../auth/executeAccess.js'; import { sendVerificationEmail } from '../../auth/sendVerificationEmail.js'; import { registerLocalStrategy } from '../../auth/strategies/local/register.js'; import { getDuplicateDocumentData } from '../../duplicateDocument/index.js'; import { afterChange } from '../../fields/hooks/afterChange/index.js'; import { afterRead } from '../../fields/hooks/afterRead/index.js'; import { beforeChange } from '../../fields/hooks/beforeChange/index.js'; import { beforeValidate } from '../../fields/hooks/beforeValidate/index.js'; import { generateFileData } from '../../uploads/generateFileData.js'; import { unlinkTempFiles } from '../../uploads/unlinkTempFiles.js'; import { uploadFiles } from '../../uploads/uploadFiles.js'; import { commitTransaction } from '../../utilities/commitTransaction.js'; import { initTransaction } from '../../utilities/initTransaction.js'; import { killTransaction } from '../../utilities/killTransaction.js'; import sanitizeInternalFields from '../../utilities/sanitizeInternalFields.js'; import { sanitizeSelect } from '../../utilities/sanitizeSelect.js'; import { saveVersion } from '../../versions/saveVersion.js'; import { buildAfterOperation } from './utils.js'; export const createOperation = async (incomingArgs)=>{ let args = incomingArgs; try { const shouldCommit = !args.disableTransaction && await initTransaction(args.req); ensureUsernameOrEmail({ authOptions: args.collection.config.auth, collectionSlug: args.collection.config.slug, data: args.data, operation: 'create', req: args.req }); // ///////////////////////////////////// // beforeOperation - Collection // ///////////////////////////////////// if (args.collection.config.hooks.beforeOperation?.length) { for (const hook of args.collection.config.hooks.beforeOperation){ args = await hook({ args, collection: args.collection.config, context: args.req.context, operation: 'create', req: args.req }) || args; } } const { autosave = false, collection: { config: collectionConfig }, collection, depth, disableVerificationEmail, draft = false, duplicateFromID, overrideAccess, overwriteExistingFiles = false, populate, req: { fallbackLocale, locale, payload, payload: { config } }, req, select: incomingSelect, showHiddenFields } = args; let { data } = args; const shouldSaveDraft = Boolean(draft && collectionConfig.versions.drafts); let duplicatedFromDocWithLocales = {}; let duplicatedFromDoc = {}; if (duplicateFromID) { const duplicateResult = await getDuplicateDocumentData({ id: duplicateFromID, collectionConfig, draftArg: shouldSaveDraft, overrideAccess, req, shouldSaveDraft }); duplicatedFromDoc = duplicateResult.duplicatedFromDoc; duplicatedFromDocWithLocales = duplicateResult.duplicatedFromDocWithLocales; } // ///////////////////////////////////// // Access // ///////////////////////////////////// if (!overrideAccess) { await executeAccess({ data, req }, collectionConfig.access.create); } // ///////////////////////////////////// // Generate data for all files and sizes // ///////////////////////////////////// const { data: newFileData, files: filesToUpload } = await generateFileData({ collection, config, data, isDuplicating: Boolean(duplicateFromID), operation: 'create', originalDoc: duplicatedFromDoc, overwriteExistingFiles, req, throwOnMissingFile: !shouldSaveDraft && collection.config.upload.filesRequiredOnCreate !== false }); data = newFileData; // ///////////////////////////////////// // beforeValidate - Fields // ///////////////////////////////////// data = await beforeValidate({ collection: collectionConfig, context: req.context, data, doc: duplicatedFromDoc, global: null, operation: 'create', overrideAccess, req }); // ///////////////////////////////////// // beforeValidate - Collections // ///////////////////////////////////// if (collectionConfig.hooks.beforeValidate?.length) { for (const hook of collectionConfig.hooks.beforeValidate){ data = await hook({ collection: collectionConfig, context: req.context, data, operation: 'create', originalDoc: duplicatedFromDoc, req }) || data; } } // ///////////////////////////////////// // beforeChange - Collection // ///////////////////////////////////// if (collectionConfig.hooks?.beforeChange?.length) { for (const hook of collectionConfig.hooks.beforeChange){ data = await hook({ collection: collectionConfig, context: req.context, data, operation: 'create', originalDoc: duplicatedFromDoc, req }) || data; } } // ///////////////////////////////////// // beforeChange - Fields // ///////////////////////////////////// const resultWithLocales = await beforeChange({ collection: collectionConfig, context: req.context, data, doc: duplicatedFromDoc, docWithLocales: duplicatedFromDocWithLocales, global: null, operation: 'create', req, skipValidation: shouldSaveDraft && collectionConfig.versions.drafts && !collectionConfig.versions.drafts.validate }); // ///////////////////////////////////// // Write files to local storage // ///////////////////////////////////// if (!collectionConfig.upload.disableLocalStorage) { await uploadFiles(payload, filesToUpload, req); } // ///////////////////////////////////// // Create // ///////////////////////////////////// let doc; const select = sanitizeSelect({ forceSelect: collectionConfig.forceSelect, select: incomingSelect }); if (collectionConfig.auth && !collectionConfig.auth.disableLocalStrategy) { if (collectionConfig.auth.verify) { resultWithLocales._verified = Boolean(resultWithLocales._verified) || false; resultWithLocales._verificationToken = crypto.randomBytes(20).toString('hex'); } doc = await registerLocalStrategy({ collection: collectionConfig, doc: resultWithLocales, password: data.password, payload: req.payload, req, select }); } else { doc = await payload.db.create({ collection: collectionConfig.slug, data: resultWithLocales, req, select }); } const verificationToken = doc._verificationToken; let result = sanitizeInternalFields(doc); // ///////////////////////////////////// // Create version // ///////////////////////////////////// if (collectionConfig.versions) { await saveVersion({ id: result.id, autosave, collection: collectionConfig, docWithLocales: result, payload, req }); } // ///////////////////////////////////// // Send verification email if applicable // ///////////////////////////////////// if (collectionConfig.auth && collectionConfig.auth.verify && result.email) { await sendVerificationEmail({ collection: { config: collectionConfig }, config: payload.config, disableEmail: disableVerificationEmail, email: payload.email, req, token: verificationToken, user: result }); } // ///////////////////////////////////// // afterRead - Fields // ///////////////////////////////////// result = await afterRead({ collection: collectionConfig, context: req.context, depth, doc: result, draft, fallbackLocale, global: null, locale, overrideAccess, populate, req, select, showHiddenFields }); // ///////////////////////////////////// // afterRead - Collection // ///////////////////////////////////// if (collectionConfig.hooks?.afterRead?.length) { for (const hook of collectionConfig.hooks.afterRead){ result = await hook({ collection: collectionConfig, context: req.context, doc: result, req }) || result; } } // ///////////////////////////////////// // afterChange - Fields // ///////////////////////////////////// result = await afterChange({ collection: collectionConfig, context: req.context, data, doc: result, global: null, operation: 'create', previousDoc: {}, req }); // ///////////////////////////////////// // afterChange - Collection // ///////////////////////////////////// if (collectionConfig.hooks?.afterChange?.length) { for (const hook of collectionConfig.hooks.afterChange){ result = await hook({ collection: collectionConfig, context: req.context, doc: result, operation: 'create', previousDoc: {}, req: args.req }) || result; } } // ///////////////////////////////////// // afterOperation - Collection // ///////////////////////////////////// result = await buildAfterOperation({ args, collection: collectionConfig, operation: 'create', result }); await unlinkTempFiles({ collectionConfig, config, req }); // ///////////////////////////////////// // Return results // ///////////////////////////////////// if (shouldCommit) { await commitTransaction(req); } return result; } catch (error) { await killTransaction(args.req); throw error; } }; //# sourceMappingURL=create.js.map