{"version":3,"sources":["../../../src/collections/operations/update.ts"],"sourcesContent":["import type { DeepPartial } from 'ts-essentials'\n\nimport { status as httpStatus } from 'http-status'\n\nimport type { AccessResult } from '../../config/types.js'\nimport type { PayloadRequest, PopulateType, SelectType, Sort, Where } from '../../types/index.js'\nimport type {\n  BulkOperationResult,\n  Collection,\n  DataFromCollectionSlug,\n  RequiredDataFromCollectionSlug,\n  SelectFromCollectionSlug,\n} from '../config/types.js'\n\nimport { executeAccess } from '../../auth/executeAccess.js'\nimport { combineQueries } from '../../database/combineQueries.js'\nimport { validateQueryPaths } from '../../database/queryValidation/validateQueryPaths.js'\nimport { sanitizeWhereQuery } from '../../database/sanitizeWhereQuery.js'\nimport { APIError } from '../../errors/index.js'\nimport { type CollectionSlug, deepCopyObjectSimple, type FindOptions } from '../../index.js'\nimport { generateFileData } from '../../uploads/generateFileData.js'\nimport { unlinkTempFiles } from '../../uploads/unlinkTempFiles.js'\nimport { appendNonTrashedFilter } from '../../utilities/appendNonTrashedFilter.js'\nimport { commitTransaction } from '../../utilities/commitTransaction.js'\nimport { hasDraftsEnabled } from '../../utilities/getVersionsConfig.js'\nimport { initTransaction } from '../../utilities/initTransaction.js'\nimport { isErrorPublic } from '../../utilities/isErrorPublic.js'\nimport { killTransaction } from '../../utilities/killTransaction.js'\nimport { sanitizeSelect } from '../../utilities/sanitizeSelect.js'\nimport { buildVersionCollectionFields } from '../../versions/buildCollectionFields.js'\nimport { appendVersionToQueryKey } from '../../versions/drafts/appendVersionToQueryKey.js'\nimport { getQueryDraftsSort } from '../../versions/drafts/getQueryDraftsSort.js'\nimport { buildAfterOperation } from './utilities/buildAfterOperation.js'\nimport { buildBeforeOperation } from './utilities/buildBeforeOperation.js'\nimport { sanitizeSortQuery } from './utilities/sanitizeSortQuery.js'\nimport { updateDocument } from './utilities/update.js'\n\nexport type Arguments<TSlug extends CollectionSlug> = {\n  autosave?: boolean\n  collection: Collection\n  data: DeepPartial<RequiredDataFromCollectionSlug<TSlug>>\n  depth?: number\n  disableTransaction?: boolean\n  disableVerificationEmail?: boolean\n  draft?: boolean\n  limit?: number\n  overrideAccess?: boolean\n  overrideLock?: boolean\n  overwriteExistingFiles?: boolean\n  populate?: PopulateType\n  publishAllLocales?: boolean\n  publishSpecificLocale?: string\n  req: PayloadRequest\n  showHiddenFields?: boolean\n  /**\n   * Sort the documents, can be a string or an array of strings\n   * @example '-createdAt' // Sort DESC by createdAt\n   * @example ['group', '-createdAt'] // sort by 2 fields, ASC group and DESC createdAt\n   */\n  sort?: Sort\n  trash?: boolean\n  unpublishAllLocales?: boolean\n  where: Where\n} & Pick<FindOptions<TSlug, SelectType>, 'select'>\n\nexport const updateOperation = async <\n  TSlug extends CollectionSlug,\n  TSelect extends SelectFromCollectionSlug<TSlug>,\n>(\n  incomingArgs: Arguments<TSlug>,\n): Promise<BulkOperationResult<TSlug, TSelect>> => {\n  let args = incomingArgs\n\n  if (args.collection.config.disableBulkEdit && !args.overrideAccess) {\n    throw new APIError(`Collection ${args.collection.config.slug} has disabled bulk edit`, 403)\n  }\n\n  try {\n    const shouldCommit = !args.disableTransaction && (await initTransaction(args.req))\n\n    // /////////////////////////////////////\n    // beforeOperation - Collection\n    // /////////////////////////////////////\n\n    args = await buildBeforeOperation({\n      args,\n      collection: args.collection.config,\n      operation: 'update',\n      overrideAccess: args.overrideAccess!,\n    })\n\n    const {\n      autosave = false,\n      collection: { config: collectionConfig },\n      collection,\n      depth,\n      draft: draftArg = false,\n      limit = 0,\n      overrideAccess,\n      overrideLock,\n      overwriteExistingFiles = false,\n      populate,\n      publishAllLocales,\n      publishSpecificLocale,\n      req: {\n        fallbackLocale,\n        locale,\n        payload: { config },\n        payload,\n      },\n      req,\n      select: incomingSelect,\n      showHiddenFields,\n      sort: incomingSort,\n      trash = false,\n      unpublishAllLocales,\n      where,\n    } = args\n\n    if (!where) {\n      throw new APIError(\"Missing 'where' query of documents to update.\", httpStatus.BAD_REQUEST)\n    }\n\n    const { data: bulkUpdateData } = args\n    const shouldSaveDraft = Boolean(draftArg && hasDraftsEnabled(collectionConfig))\n\n    // /////////////////////////////////////\n    // Access\n    // /////////////////////////////////////\n\n    let accessResult: AccessResult\n    if (!overrideAccess) {\n      accessResult = await executeAccess({ req }, collectionConfig.access.update)\n    }\n\n    await validateQueryPaths({\n      collectionConfig,\n      overrideAccess: overrideAccess!,\n      req,\n      where,\n    })\n\n    // /////////////////////////////////////\n    // Retrieve documents\n    // /////////////////////////////////////\n\n    let fullWhere = combineQueries(where, accessResult!)\n\n    const isTrashAttempt =\n      collectionConfig.trash &&\n      typeof bulkUpdateData === 'object' &&\n      bulkUpdateData !== null &&\n      'deletedAt' in bulkUpdateData &&\n      bulkUpdateData.deletedAt != null\n\n    // Enforce delete access if performing a soft-delete (trash)\n    if (isTrashAttempt && !overrideAccess) {\n      // Pass data so access function can check data.deletedAt to know it's a trash attempt\n      const deleteAccessResult = await executeAccess(\n        { data: bulkUpdateData, req },\n        collectionConfig.access.delete,\n      )\n      fullWhere = combineQueries(fullWhere, deleteAccessResult)\n    }\n\n    // Exclude trashed documents when trash: false\n    fullWhere = appendNonTrashedFilter({\n      enableTrash: collectionConfig.trash,\n      trash,\n      where: fullWhere,\n    })\n\n    sanitizeWhereQuery({ fields: collectionConfig.flattenedFields, payload, where: fullWhere })\n\n    const sort = sanitizeSortQuery({\n      fields: collection.config.flattenedFields,\n      sort: incomingSort,\n    })\n\n    let docs\n\n    if (hasDraftsEnabled(collectionConfig) && (shouldSaveDraft || isTrashAttempt)) {\n      const versionsWhere = appendVersionToQueryKey(fullWhere)\n\n      await validateQueryPaths({\n        collectionConfig: collection.config,\n        overrideAccess: overrideAccess!,\n        req,\n        versionFields: buildVersionCollectionFields(payload.config, collection.config, true),\n        where: appendVersionToQueryKey(where),\n      })\n\n      const query = await payload.db.queryDrafts<DataFromCollectionSlug<TSlug>>({\n        collection: collectionConfig.slug,\n        limit,\n        locale: locale!,\n        pagination: false,\n        req,\n        sort: getQueryDraftsSort({ collectionConfig, sort }),\n        where: versionsWhere,\n      })\n\n      docs = query.docs\n    } else {\n      const query = await payload.db.find({\n        collection: collectionConfig.slug,\n        limit,\n        locale: locale!,\n        pagination: false,\n        req,\n        sort,\n        where: fullWhere,\n      })\n\n      docs = query.docs\n    }\n\n    // /////////////////////////////////////\n    // Generate data for all files and sizes\n    // /////////////////////////////////////\n\n    const { data, files: filesToUpload } = await generateFileData({\n      collection,\n      config,\n      data: bulkUpdateData,\n      operation: 'update',\n      overwriteExistingFiles,\n      req,\n      throwOnMissingFile: false,\n    })\n\n    const errors: BulkOperationResult<TSlug, TSelect>['errors'] = []\n\n    const promises = docs.map(async (docWithLocales) => {\n      const { id } = docWithLocales\n\n      try {\n        // Each document gets its own transaction when singleTransaction is enabled\n        let docShouldCommit = false\n        if (req.payload.db.bulkOperationsSingleTransaction) {\n          docShouldCommit = await initTransaction(req)\n        }\n\n        const select = sanitizeSelect({\n          fields: collectionConfig.flattenedFields,\n          forceSelect: collectionConfig.forceSelect,\n          select: incomingSelect,\n        })\n\n        // ///////////////////////////////////////////////\n        // Update document, runs all document level hooks\n        // ///////////////////////////////////////////////\n        let updatedDoc = await updateDocument({\n          id,\n          autosave,\n          collectionConfig,\n          config,\n          data: deepCopyObjectSimple(data),\n          depth: depth!,\n          docWithLocales,\n          draftArg,\n          fallbackLocale: fallbackLocale!,\n          filesToUpload,\n          locale: locale!,\n          overrideAccess: overrideAccess!,\n          overrideLock: overrideLock!,\n          payload,\n          populate,\n          publishAllLocales,\n          publishSpecificLocale,\n          req,\n          select: select!,\n          showHiddenFields: showHiddenFields!,\n          unpublishAllLocales,\n        })\n\n        // /////////////////////////////////////\n        // Add collection property for auth collections\n        // /////////////////////////////////////\n\n        if (collectionConfig.auth) {\n          updatedDoc = { ...updatedDoc, collection: collectionConfig.slug }\n        }\n\n        if (docShouldCommit) {\n          await commitTransaction(req)\n        }\n\n        return updatedDoc\n      } catch (error) {\n        const isPublic = error instanceof Error ? isErrorPublic(error, config) : false\n\n        if (req.payload.db.bulkOperationsSingleTransaction) {\n          await killTransaction(req)\n        }\n        errors.push({\n          id,\n          isPublic,\n          message: error instanceof Error ? error.message : 'Unknown error',\n        })\n      }\n      return null\n    })\n\n    await unlinkTempFiles({\n      collectionConfig,\n      config,\n      req,\n    })\n\n    // Process sequentially when using single transaction mode to avoid shared state issues\n    // Process in parallel when using one transaction for better performance\n    let awaitedDocs: (DataFromCollectionSlug<TSlug> | null)[]\n    if (req.payload.db.bulkOperationsSingleTransaction) {\n      awaitedDocs = []\n      for (const promise of promises) {\n        awaitedDocs.push(await promise)\n      }\n    } else {\n      awaitedDocs = await Promise.all(promises)\n    }\n\n    let result = {\n      docs: awaitedDocs.filter(Boolean),\n      errors,\n    }\n\n    // /////////////////////////////////////\n    // afterOperation - Collection\n    // /////////////////////////////////////\n\n    result = await buildAfterOperation({\n      args,\n      collection: collectionConfig,\n      operation: 'update',\n      overrideAccess,\n      // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n      result,\n    })\n\n    if (shouldCommit) {\n      await commitTransaction(req)\n    }\n\n    // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n    return result\n  } catch (error: unknown) {\n    await killTransaction(args.req)\n    throw error\n  }\n}\n"],"names":["status","httpStatus","executeAccess","combineQueries","validateQueryPaths","sanitizeWhereQuery","APIError","deepCopyObjectSimple","generateFileData","unlinkTempFiles","appendNonTrashedFilter","commitTransaction","hasDraftsEnabled","initTransaction","isErrorPublic","killTransaction","sanitizeSelect","buildVersionCollectionFields","appendVersionToQueryKey","getQueryDraftsSort","buildAfterOperation","buildBeforeOperation","sanitizeSortQuery","updateDocument","updateOperation","incomingArgs","args","collection","config","disableBulkEdit","overrideAccess","slug","shouldCommit","disableTransaction","req","operation","autosave","collectionConfig","depth","draft","draftArg","limit","overrideLock","overwriteExistingFiles","populate","publishAllLocales","publishSpecificLocale","fallbackLocale","locale","payload","select","incomingSelect","showHiddenFields","sort","incomingSort","trash","unpublishAllLocales","where","BAD_REQUEST","data","bulkUpdateData","shouldSaveDraft","Boolean","accessResult","access","update","fullWhere","isTrashAttempt","deletedAt","deleteAccessResult","delete","enableTrash","fields","flattenedFields","docs","versionsWhere","versionFields","query","db","queryDrafts","pagination","find","files","filesToUpload","throwOnMissingFile","errors","promises","map","docWithLocales","id","docShouldCommit","bulkOperationsSingleTransaction","forceSelect","updatedDoc","auth","error","isPublic","Error","push","message","awaitedDocs","promise","Promise","all","result","filter"],"mappings":"AAEA,SAASA,UAAUC,UAAU,QAAQ,cAAa;AAYlD,SAASC,aAAa,QAAQ,8BAA6B;AAC3D,SAASC,cAAc,QAAQ,mCAAkC;AACjE,SAASC,kBAAkB,QAAQ,uDAAsD;AACzF,SAASC,kBAAkB,QAAQ,uCAAsC;AACzE,SAASC,QAAQ,QAAQ,wBAAuB;AAChD,SAA8BC,oBAAoB,QAA0B,iBAAgB;AAC5F,SAASC,gBAAgB,QAAQ,oCAAmC;AACpE,SAASC,eAAe,QAAQ,mCAAkC;AAClE,SAASC,sBAAsB,QAAQ,4CAA2C;AAClF,SAASC,iBAAiB,QAAQ,uCAAsC;AACxE,SAASC,gBAAgB,QAAQ,uCAAsC;AACvE,SAASC,eAAe,QAAQ,qCAAoC;AACpE,SAASC,aAAa,QAAQ,mCAAkC;AAChE,SAASC,eAAe,QAAQ,qCAAoC;AACpE,SAASC,cAAc,QAAQ,oCAAmC;AAClE,SAASC,4BAA4B,QAAQ,0CAAyC;AACtF,SAASC,uBAAuB,QAAQ,mDAAkD;AAC1F,SAASC,kBAAkB,QAAQ,8CAA6C;AAChF,SAASC,mBAAmB,QAAQ,qCAAoC;AACxE,SAASC,oBAAoB,QAAQ,sCAAqC;AAC1E,SAASC,iBAAiB,QAAQ,mCAAkC;AACpE,SAASC,cAAc,QAAQ,wBAAuB;AA8BtD,OAAO,MAAMC,kBAAkB,OAI7BC;IAEA,IAAIC,OAAOD;IAEX,IAAIC,KAAKC,UAAU,CAACC,MAAM,CAACC,eAAe,IAAI,CAACH,KAAKI,cAAc,EAAE;QAClE,MAAM,IAAIxB,SAAS,CAAC,WAAW,EAAEoB,KAAKC,UAAU,CAACC,MAAM,CAACG,IAAI,CAAC,uBAAuB,CAAC,EAAE;IACzF;IAEA,IAAI;QACF,MAAMC,eAAe,CAACN,KAAKO,kBAAkB,IAAK,MAAMpB,gBAAgBa,KAAKQ,GAAG;QAEhF,wCAAwC;QACxC,+BAA+B;QAC/B,wCAAwC;QAExCR,OAAO,MAAML,qBAAqB;YAChCK;YACAC,YAAYD,KAAKC,UAAU,CAACC,MAAM;YAClCO,WAAW;YACXL,gBAAgBJ,KAAKI,cAAc;QACrC;QAEA,MAAM,EACJM,WAAW,KAAK,EAChBT,YAAY,EAAEC,QAAQS,gBAAgB,EAAE,EACxCV,UAAU,EACVW,KAAK,EACLC,OAAOC,WAAW,KAAK,EACvBC,QAAQ,CAAC,EACTX,cAAc,EACdY,YAAY,EACZC,yBAAyB,KAAK,EAC9BC,QAAQ,EACRC,iBAAiB,EACjBC,qBAAqB,EACrBZ,KAAK,EACHa,cAAc,EACdC,MAAM,EACNC,SAAS,EAAErB,MAAM,EAAE,EACnBqB,OAAO,EACR,EACDf,GAAG,EACHgB,QAAQC,cAAc,EACtBC,gBAAgB,EAChBC,MAAMC,YAAY,EAClBC,QAAQ,KAAK,EACbC,mBAAmB,EACnBC,KAAK,EACN,GAAG/B;QAEJ,IAAI,CAAC+B,OAAO;YACV,MAAM,IAAInD,SAAS,iDAAiDL,WAAWyD,WAAW;QAC5F;QAEA,MAAM,EAAEC,MAAMC,cAAc,EAAE,GAAGlC;QACjC,MAAMmC,kBAAkBC,QAAQtB,YAAY5B,iBAAiByB;QAE7D,wCAAwC;QACxC,SAAS;QACT,wCAAwC;QAExC,IAAI0B;QACJ,IAAI,CAACjC,gBAAgB;YACnBiC,eAAe,MAAM7D,cAAc;gBAAEgC;YAAI,GAAGG,iBAAiB2B,MAAM,CAACC,MAAM;QAC5E;QAEA,MAAM7D,mBAAmB;YACvBiC;YACAP,gBAAgBA;YAChBI;YACAuB;QACF;QAEA,wCAAwC;QACxC,qBAAqB;QACrB,wCAAwC;QAExC,IAAIS,YAAY/D,eAAesD,OAAOM;QAEtC,MAAMI,iBACJ9B,iBAAiBkB,KAAK,IACtB,OAAOK,mBAAmB,YAC1BA,mBAAmB,QACnB,eAAeA,kBACfA,eAAeQ,SAAS,IAAI;QAE9B,4DAA4D;QAC5D,IAAID,kBAAkB,CAACrC,gBAAgB;YACrC,qFAAqF;YACrF,MAAMuC,qBAAqB,MAAMnE,cAC/B;gBAAEyD,MAAMC;gBAAgB1B;YAAI,GAC5BG,iBAAiB2B,MAAM,CAACM,MAAM;YAEhCJ,YAAY/D,eAAe+D,WAAWG;QACxC;QAEA,8CAA8C;QAC9CH,YAAYxD,uBAAuB;YACjC6D,aAAalC,iBAAiBkB,KAAK;YACnCA;YACAE,OAAOS;QACT;QAEA7D,mBAAmB;YAAEmE,QAAQnC,iBAAiBoC,eAAe;YAAExB;YAASQ,OAAOS;QAAU;QAEzF,MAAMb,OAAO/B,kBAAkB;YAC7BkD,QAAQ7C,WAAWC,MAAM,CAAC6C,eAAe;YACzCpB,MAAMC;QACR;QAEA,IAAIoB;QAEJ,IAAI9D,iBAAiByB,qBAAsBwB,CAAAA,mBAAmBM,cAAa,GAAI;YAC7E,MAAMQ,gBAAgBzD,wBAAwBgD;YAE9C,MAAM9D,mBAAmB;gBACvBiC,kBAAkBV,WAAWC,MAAM;gBACnCE,gBAAgBA;gBAChBI;gBACA0C,eAAe3D,6BAA6BgC,QAAQrB,MAAM,EAAED,WAAWC,MAAM,EAAE;gBAC/E6B,OAAOvC,wBAAwBuC;YACjC;YAEA,MAAMoB,QAAQ,MAAM5B,QAAQ6B,EAAE,CAACC,WAAW,CAAgC;gBACxEpD,YAAYU,iBAAiBN,IAAI;gBACjCU;gBACAO,QAAQA;gBACRgC,YAAY;gBACZ9C;gBACAmB,MAAMlC,mBAAmB;oBAAEkB;oBAAkBgB;gBAAK;gBAClDI,OAAOkB;YACT;YAEAD,OAAOG,MAAMH,IAAI;QACnB,OAAO;YACL,MAAMG,QAAQ,MAAM5B,QAAQ6B,EAAE,CAACG,IAAI,CAAC;gBAClCtD,YAAYU,iBAAiBN,IAAI;gBACjCU;gBACAO,QAAQA;gBACRgC,YAAY;gBACZ9C;gBACAmB;gBACAI,OAAOS;YACT;YAEAQ,OAAOG,MAAMH,IAAI;QACnB;QAEA,wCAAwC;QACxC,wCAAwC;QACxC,wCAAwC;QAExC,MAAM,EAAEf,IAAI,EAAEuB,OAAOC,aAAa,EAAE,GAAG,MAAM3E,iBAAiB;YAC5DmB;YACAC;YACA+B,MAAMC;YACNzB,WAAW;YACXQ;YACAT;YACAkD,oBAAoB;QACtB;QAEA,MAAMC,SAAwD,EAAE;QAEhE,MAAMC,WAAWZ,KAAKa,GAAG,CAAC,OAAOC;YAC/B,MAAM,EAAEC,EAAE,EAAE,GAAGD;YAEf,IAAI;gBACF,2EAA2E;gBAC3E,IAAIE,kBAAkB;gBACtB,IAAIxD,IAAIe,OAAO,CAAC6B,EAAE,CAACa,+BAA+B,EAAE;oBAClDD,kBAAkB,MAAM7E,gBAAgBqB;gBAC1C;gBAEA,MAAMgB,SAASlC,eAAe;oBAC5BwD,QAAQnC,iBAAiBoC,eAAe;oBACxCmB,aAAavD,iBAAiBuD,WAAW;oBACzC1C,QAAQC;gBACV;gBAEA,kDAAkD;gBAClD,iDAAiD;gBACjD,kDAAkD;gBAClD,IAAI0C,aAAa,MAAMtE,eAAe;oBACpCkE;oBACArD;oBACAC;oBACAT;oBACA+B,MAAMpD,qBAAqBoD;oBAC3BrB,OAAOA;oBACPkD;oBACAhD;oBACAO,gBAAgBA;oBAChBoC;oBACAnC,QAAQA;oBACRlB,gBAAgBA;oBAChBY,cAAcA;oBACdO;oBACAL;oBACAC;oBACAC;oBACAZ;oBACAgB,QAAQA;oBACRE,kBAAkBA;oBAClBI;gBACF;gBAEA,wCAAwC;gBACxC,+CAA+C;gBAC/C,wCAAwC;gBAExC,IAAInB,iBAAiByD,IAAI,EAAE;oBACzBD,aAAa;wBAAE,GAAGA,UAAU;wBAAElE,YAAYU,iBAAiBN,IAAI;oBAAC;gBAClE;gBAEA,IAAI2D,iBAAiB;oBACnB,MAAM/E,kBAAkBuB;gBAC1B;gBAEA,OAAO2D;YACT,EAAE,OAAOE,OAAO;gBACd,MAAMC,WAAWD,iBAAiBE,QAAQnF,cAAciF,OAAOnE,UAAU;gBAEzE,IAAIM,IAAIe,OAAO,CAAC6B,EAAE,CAACa,+BAA+B,EAAE;oBAClD,MAAM5E,gBAAgBmB;gBACxB;gBACAmD,OAAOa,IAAI,CAAC;oBACVT;oBACAO;oBACAG,SAASJ,iBAAiBE,QAAQF,MAAMI,OAAO,GAAG;gBACpD;YACF;YACA,OAAO;QACT;QAEA,MAAM1F,gBAAgB;YACpB4B;YACAT;YACAM;QACF;QAEA,uFAAuF;QACvF,wEAAwE;QACxE,IAAIkE;QACJ,IAAIlE,IAAIe,OAAO,CAAC6B,EAAE,CAACa,+BAA+B,EAAE;YAClDS,cAAc,EAAE;YAChB,KAAK,MAAMC,WAAWf,SAAU;gBAC9Bc,YAAYF,IAAI,CAAC,MAAMG;YACzB;QACF,OAAO;YACLD,cAAc,MAAME,QAAQC,GAAG,CAACjB;QAClC;QAEA,IAAIkB,SAAS;YACX9B,MAAM0B,YAAYK,MAAM,CAAC3C;YACzBuB;QACF;QAEA,wCAAwC;QACxC,8BAA8B;QAC9B,wCAAwC;QAExCmB,SAAS,MAAMpF,oBAAoB;YACjCM;YACAC,YAAYU;YACZF,WAAW;YACXL;YACA,oFAAoF;YACpF0E;QACF;QAEA,IAAIxE,cAAc;YAChB,MAAMrB,kBAAkBuB;QAC1B;QAEA,oFAAoF;QACpF,OAAOsE;IACT,EAAE,OAAOT,OAAgB;QACvB,MAAMhF,gBAAgBW,KAAKQ,GAAG;QAC9B,MAAM6D;IACR;AACF,EAAC"}