@open-aih/payload-ddb 3.1.0 → 4.1.0

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.
Files changed (162) hide show
  1. package/README.md +141 -18
  2. package/dist/count.d.ts.map +1 -1
  3. package/dist/count.js +4 -2
  4. package/dist/count.js.map +1 -1
  5. package/dist/countGlobalVersions.d.ts.map +1 -1
  6. package/dist/countGlobalVersions.js +6 -1
  7. package/dist/countGlobalVersions.js.map +1 -1
  8. package/dist/countVersions.d.ts.map +1 -1
  9. package/dist/countVersions.js +6 -1
  10. package/dist/countVersions.js.map +1 -1
  11. package/dist/create.d.ts.map +1 -1
  12. package/dist/create.js +31 -15
  13. package/dist/create.js.map +1 -1
  14. package/dist/createGlobal.d.ts.map +1 -1
  15. package/dist/createGlobal.js +2 -14
  16. package/dist/createGlobal.js.map +1 -1
  17. package/dist/createGlobalVersion.d.ts +1 -1
  18. package/dist/createGlobalVersion.d.ts.map +1 -1
  19. package/dist/createGlobalVersion.js +3 -41
  20. package/dist/createGlobalVersion.js.map +1 -1
  21. package/dist/createVersion.d.ts +6 -5
  22. package/dist/createVersion.d.ts.map +1 -1
  23. package/dist/createVersion.js +8 -48
  24. package/dist/createVersion.js.map +1 -1
  25. package/dist/deleteMany.d.ts +1 -6
  26. package/dist/deleteMany.d.ts.map +1 -1
  27. package/dist/deleteMany.js +8 -19
  28. package/dist/deleteMany.js.map +1 -1
  29. package/dist/deleteOne.d.ts.map +1 -1
  30. package/dist/deleteOne.js +20 -24
  31. package/dist/deleteOne.js.map +1 -1
  32. package/dist/deleteVersions.d.ts.map +1 -1
  33. package/dist/deleteVersions.js +8 -14
  34. package/dist/deleteVersions.js.map +1 -1
  35. package/dist/find.d.ts.map +1 -1
  36. package/dist/find.js +15 -2
  37. package/dist/find.js.map +1 -1
  38. package/dist/findDistinct.d.ts.map +1 -1
  39. package/dist/findDistinct.js +3 -1
  40. package/dist/findDistinct.js.map +1 -1
  41. package/dist/findGlobal.d.ts.map +1 -1
  42. package/dist/findGlobal.js +3 -2
  43. package/dist/findGlobal.js.map +1 -1
  44. package/dist/findGlobalVersions.d.ts.map +1 -1
  45. package/dist/findGlobalVersions.js +10 -2
  46. package/dist/findGlobalVersions.js.map +1 -1
  47. package/dist/findOne.d.ts.map +1 -1
  48. package/dist/findOne.js +17 -6
  49. package/dist/findOne.js.map +1 -1
  50. package/dist/findVersions.d.ts.map +1 -1
  51. package/dist/findVersions.js +10 -2
  52. package/dist/findVersions.js.map +1 -1
  53. package/dist/index.d.ts +2 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +7 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/queryDrafts.d.ts.map +1 -1
  58. package/dist/queryDrafts.js +24 -4
  59. package/dist/queryDrafts.js.map +1 -1
  60. package/dist/updateGlobal.d.ts +5 -4
  61. package/dist/updateGlobal.d.ts.map +1 -1
  62. package/dist/updateGlobal.js +22 -36
  63. package/dist/updateGlobal.js.map +1 -1
  64. package/dist/updateGlobalVersion.d.ts.map +1 -1
  65. package/dist/updateGlobalVersion.js +3 -49
  66. package/dist/updateGlobalVersion.js.map +1 -1
  67. package/dist/updateJobs.d.ts +21 -0
  68. package/dist/updateJobs.d.ts.map +1 -0
  69. package/dist/updateJobs.js +83 -0
  70. package/dist/updateJobs.js.map +1 -0
  71. package/dist/updateMany.d.ts +9 -3
  72. package/dist/updateMany.d.ts.map +1 -1
  73. package/dist/updateMany.js +47 -30
  74. package/dist/updateMany.js.map +1 -1
  75. package/dist/updateOne.d.ts +6 -1
  76. package/dist/updateOne.d.ts.map +1 -1
  77. package/dist/updateOne.js +49 -49
  78. package/dist/updateOne.js.map +1 -1
  79. package/dist/updateVersion.d.ts.map +1 -1
  80. package/dist/updateVersion.js +3 -52
  81. package/dist/updateVersion.js.map +1 -1
  82. package/dist/upsert.d.ts +6 -0
  83. package/dist/upsert.d.ts.map +1 -1
  84. package/dist/upsert.js +57 -41
  85. package/dist/upsert.js.map +1 -1
  86. package/dist/utilities/backfillUniqueGuards.d.ts +42 -0
  87. package/dist/utilities/backfillUniqueGuards.d.ts.map +1 -0
  88. package/dist/utilities/backfillUniqueGuards.js +39 -0
  89. package/dist/utilities/backfillUniqueGuards.js.map +1 -0
  90. package/dist/utilities/buildFilterExpression.d.ts +29 -14
  91. package/dist/utilities/buildFilterExpression.d.ts.map +1 -1
  92. package/dist/utilities/buildFilterExpression.js +55 -14
  93. package/dist/utilities/buildFilterExpression.js.map +1 -1
  94. package/dist/utilities/castWhere.d.ts +84 -0
  95. package/dist/utilities/castWhere.d.ts.map +1 -0
  96. package/dist/utilities/castWhere.js +254 -0
  97. package/dist/utilities/castWhere.js.map +1 -0
  98. package/dist/utilities/findFirst.d.ts +3 -2
  99. package/dist/utilities/findFirst.d.ts.map +1 -1
  100. package/dist/utilities/findFirst.js +14 -46
  101. package/dist/utilities/findFirst.js.map +1 -1
  102. package/dist/utilities/geo.d.ts +36 -0
  103. package/dist/utilities/geo.d.ts.map +1 -0
  104. package/dist/utilities/geo.js +108 -0
  105. package/dist/utilities/geo.js.map +1 -0
  106. package/dist/utilities/mapWithConcurrency.d.ts +12 -0
  107. package/dist/utilities/mapWithConcurrency.d.ts.map +1 -0
  108. package/dist/utilities/mapWithConcurrency.js +32 -0
  109. package/dist/utilities/mapWithConcurrency.js.map +1 -0
  110. package/dist/utilities/matchesWhere.d.ts +25 -5
  111. package/dist/utilities/matchesWhere.d.ts.map +1 -1
  112. package/dist/utilities/matchesWhere.js +150 -38
  113. package/dist/utilities/matchesWhere.js.map +1 -1
  114. package/dist/utilities/operators.d.ts +22 -12
  115. package/dist/utilities/operators.d.ts.map +1 -1
  116. package/dist/utilities/operators.js +36 -31
  117. package/dist/utilities/operators.js.map +1 -1
  118. package/dist/utilities/optimistic.d.ts +29 -0
  119. package/dist/utilities/optimistic.d.ts.map +1 -0
  120. package/dist/utilities/optimistic.js +58 -0
  121. package/dist/utilities/optimistic.js.map +1 -0
  122. package/dist/utilities/prepareWhere.d.ts +63 -0
  123. package/dist/utilities/prepareWhere.d.ts.map +1 -0
  124. package/dist/utilities/prepareWhere.js +198 -0
  125. package/dist/utilities/prepareWhere.js.map +1 -0
  126. package/dist/utilities/queryCount.d.ts +6 -3
  127. package/dist/utilities/queryCount.d.ts.map +1 -1
  128. package/dist/utilities/queryCount.js +16 -45
  129. package/dist/utilities/queryCount.js.map +1 -1
  130. package/dist/utilities/queryMatching.d.ts +8 -7
  131. package/dist/utilities/queryMatching.d.ts.map +1 -1
  132. package/dist/utilities/queryMatching.js +17 -54
  133. package/dist/utilities/queryMatching.js.map +1 -1
  134. package/dist/utilities/queryPartition.d.ts +26 -0
  135. package/dist/utilities/queryPartition.d.ts.map +1 -0
  136. package/dist/utilities/queryPartition.js +55 -0
  137. package/dist/utilities/queryPartition.js.map +1 -0
  138. package/dist/utilities/resolveJoins.d.ts +37 -0
  139. package/dist/utilities/resolveJoins.d.ts.map +1 -0
  140. package/dist/utilities/resolveJoins.js +195 -0
  141. package/dist/utilities/resolveJoins.js.map +1 -0
  142. package/dist/utilities/stripInternalKeys.d.ts +17 -3
  143. package/dist/utilities/stripInternalKeys.d.ts.map +1 -1
  144. package/dist/utilities/stripInternalKeys.js +25 -4
  145. package/dist/utilities/stripInternalKeys.js.map +1 -1
  146. package/dist/utilities/uniqueGuards.d.ts +39 -0
  147. package/dist/utilities/uniqueGuards.d.ts.map +1 -0
  148. package/dist/utilities/uniqueGuards.js +106 -0
  149. package/dist/utilities/uniqueGuards.js.map +1 -0
  150. package/dist/utilities/updateVersionRow.d.ts +19 -0
  151. package/dist/utilities/updateVersionRow.d.ts.map +1 -0
  152. package/dist/utilities/updateVersionRow.js +40 -0
  153. package/dist/utilities/updateVersionRow.js.map +1 -0
  154. package/dist/utilities/writeErrors.d.ts +11 -0
  155. package/dist/utilities/writeErrors.d.ts.map +1 -0
  156. package/dist/utilities/writeErrors.js +27 -0
  157. package/dist/utilities/writeErrors.js.map +1 -0
  158. package/dist/utilities/writeItems.d.ts +124 -0
  159. package/dist/utilities/writeItems.d.ts.map +1 -0
  160. package/dist/utilities/writeItems.js +383 -0
  161. package/dist/utilities/writeItems.js.map +1 -0
  162. package/package.json +21 -14
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/findOne.ts"],"sourcesContent":["import type { FindOne } from 'payload'\n\nimport type { DynamoAdapter } from './types.js'\n\nimport { collectionHasDrafts, fetchDraftsOnlySupplements } from './utilities/draftsFallback.js'\nimport { findFirst } from './utilities/findFirst.js'\n\n/**\n * Locate one doc in `collection` matching `where`. For drafts-enabled\n * collections, fall back to the `latest=true` version row when no main\n * partition row matches — that's how drafts-only docs (saved but never\n * published) become findable.\n */\nexport const findOne: FindOne = async function findOne(\n this: DynamoAdapter,\n { collection, where },\n) {\n const partition = this.resolvePartition(collection)\n const found = await findFirst(this, { partition, where })\n if (found) return found as never\n\n if (collectionHasDrafts(this, collection)) {\n const supplements = await fetchDraftsOnlySupplements(this, collection, [], where)\n if (supplements.length > 0) return supplements[0] as never\n }\n\n return null as never\n}\n"],"names":["collectionHasDrafts","fetchDraftsOnlySupplements","findFirst","findOne","collection","where","partition","resolvePartition","found","supplements","length"],"mappings":"AAIA,SAASA,mBAAmB,EAAEC,0BAA0B,QAAQ,gCAA+B;AAC/F,SAASC,SAAS,QAAQ,2BAA0B;AAEpD;;;;;CAKC,GACD,OAAO,MAAMC,UAAmB,eAAeA,QAE7C,EAAEC,UAAU,EAAEC,KAAK,EAAE;IAErB,MAAMC,YAAY,IAAI,CAACC,gBAAgB,CAACH;IACxC,MAAMI,QAAQ,MAAMN,UAAU,IAAI,EAAE;QAAEI;QAAWD;IAAM;IACvD,IAAIG,OAAO,OAAOA;IAElB,IAAIR,oBAAoB,IAAI,EAAEI,aAAa;QACzC,MAAMK,cAAc,MAAMR,2BAA2B,IAAI,EAAEG,YAAY,EAAE,EAAEC;QAC3E,IAAII,YAAYC,MAAM,GAAG,GAAG,OAAOD,WAAW,CAAC,EAAE;IACnD;IAEA,OAAO;AACT,EAAC"}
1
+ {"version":3,"sources":["../src/findOne.ts"],"sourcesContent":["import type { FindOne } from 'payload'\n\nimport type { DynamoAdapter } from './types.js'\n\nimport { collectionHasDrafts, fetchDraftsOnlySupplements } from './utilities/draftsFallback.js'\nimport { findFirst } from './utilities/findFirst.js'\nimport { prepareCollectionWhere } from './utilities/prepareWhere.js'\nimport { resolveJoins } from './utilities/resolveJoins.js'\n\n/**\n * Locate one doc in `collection` matching `where`. For drafts-enabled\n * collections, fall back to the `latest=true` version row when no main\n * partition row matches — that's how drafts-only docs (saved but never\n * published) become findable.\n */\nexport const findOne: FindOne = async function findOne(\n this: DynamoAdapter,\n { collection, joins, locale, where: rawWhere },\n) {\n const where = await prepareCollectionWhere(this, collection, rawWhere, locale)\n const partition = this.resolvePartition(collection)\n\n let doc = await findFirst(this, { partition, where })\n if (!doc && collectionHasDrafts(this, collection)) {\n const supplements = await fetchDraftsOnlySupplements(this, collection, [], where)\n doc = supplements[0] ?? null\n }\n if (!doc) return null as never\n\n await resolveJoins(this, { collectionSlug: collection, docs: [doc], joins, locale })\n return doc as never\n}\n"],"names":["collectionHasDrafts","fetchDraftsOnlySupplements","findFirst","prepareCollectionWhere","resolveJoins","findOne","collection","joins","locale","where","rawWhere","partition","resolvePartition","doc","supplements","collectionSlug","docs"],"mappings":"AAIA,SAASA,mBAAmB,EAAEC,0BAA0B,QAAQ,gCAA+B;AAC/F,SAASC,SAAS,QAAQ,2BAA0B;AACpD,SAASC,sBAAsB,QAAQ,8BAA6B;AACpE,SAASC,YAAY,QAAQ,8BAA6B;AAE1D;;;;;CAKC,GACD,OAAO,MAAMC,UAAmB,eAAeA,QAE7C,EAAEC,UAAU,EAAEC,KAAK,EAAEC,MAAM,EAAEC,OAAOC,QAAQ,EAAE;IAE9C,MAAMD,QAAQ,MAAMN,uBAAuB,IAAI,EAAEG,YAAYI,UAAUF;IACvE,MAAMG,YAAY,IAAI,CAACC,gBAAgB,CAACN;IAExC,IAAIO,MAAM,MAAMX,UAAU,IAAI,EAAE;QAAES;QAAWF;IAAM;IACnD,IAAI,CAACI,OAAOb,oBAAoB,IAAI,EAAEM,aAAa;QACjD,MAAMQ,cAAc,MAAMb,2BAA2B,IAAI,EAAEK,YAAY,EAAE,EAAEG;QAC3EI,MAAMC,WAAW,CAAC,EAAE,IAAI;IAC1B;IACA,IAAI,CAACD,KAAK,OAAO;IAEjB,MAAMT,aAAa,IAAI,EAAE;QAAEW,gBAAgBT;QAAYU,MAAM;YAACH;SAAI;QAAEN;QAAOC;IAAO;IAClF,OAAOK;AACT,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"findVersions.d.ts","sourceRoot":"","sources":["../src/findVersions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,SAAS,CAAA;AAO1D;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,YAsC1B,CAAA"}
1
+ {"version":3,"file":"findVersions.d.ts","sourceRoot":"","sources":["../src/findVersions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,SAAS,CAAA;AAQ1D;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,YA0C1B,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import { applySorts } from './utilities/applySorts.js';
2
+ import { prepareSort, prepareVersionsWhere } from './utilities/prepareWhere.js';
2
3
  import { queryMatching } from './utilities/queryMatching.js';
3
4
  /**
4
5
  * Same shape as `find` but routed at the versions partition. Could share
@@ -6,10 +7,17 @@ import { queryMatching } from './utilities/queryMatching.js';
6
7
  * helper, but keeping them separate makes per-method tweaks (e.g.
7
8
  * version-only filters, eventual draft-aware logic) easier to land without
8
9
  * refactoring.
9
- */ export const findVersions = async function findVersions({ collection, limit = 10, page = 1, pagination = true, sort, where }) {
10
+ */ export const findVersions = async function findVersions({ collection, limit = 10, locale, page = 1, pagination = true, sort, where: rawWhere }) {
11
+ const where = await prepareVersionsWhere(this, {
12
+ kind: 'collection',
13
+ slug: collection
14
+ }, rawWhere, locale);
10
15
  const partition = this.resolveVersionsPartition(collection);
11
16
  const matched = await queryMatching(this, partition, where);
12
- applySorts(matched, sort);
17
+ applySorts(matched, prepareSort(this, {
18
+ kind: 'collectionVersions',
19
+ slug: collection
20
+ }, sort, locale));
13
21
  const totalDocs = matched.length;
14
22
  // `limit: 0` disables the cap. When pagination is false, limit/page still
15
23
  // control the slice (e.g. enforceMaxVersions fetches page max+1 with limit 1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/findVersions.ts"],"sourcesContent":["import type { FindVersions, PaginatedDocs } from 'payload'\n\nimport type { DynamoAdapter } from './types.js'\n\nimport { applySorts } from './utilities/applySorts.js'\nimport { queryMatching } from './utilities/queryMatching.js'\n\n/**\n * Same shape as `find` but routed at the versions partition. Could share\n * more code with `find` via a `paginatedQuery(adapter, partition, args)`\n * helper, but keeping them separate makes per-method tweaks (e.g.\n * version-only filters, eventual draft-aware logic) easier to land without\n * refactoring.\n */\nexport const findVersions: FindVersions = async function findVersions(\n this: DynamoAdapter,\n { collection, limit = 10, page = 1, pagination = true, sort, where },\n) {\n const partition = this.resolveVersionsPartition(collection)\n const matched = await queryMatching(this, partition, where)\n applySorts(matched, sort)\n\n const totalDocs = matched.length\n // `limit: 0` disables the cap. When pagination is false, limit/page still\n // control the slice (e.g. enforceMaxVersions fetches page max+1 with limit 1\n // to find the oldest doc to prune). The pagination flag only gates whether\n // we compute meaningful total-count metadata.\n const useLimit = limit > 0\n const safePage = useLimit ? Math.max(1, page) : 1\n\n const start = useLimit ? (safePage - 1) * limit : 0\n const end = useLimit ? start + limit : totalDocs\n const docs = matched.slice(start, end)\n\n const effectiveLimit = useLimit ? limit : totalDocs\n const totalPages = pagination && useLimit ? Math.max(1, Math.ceil(totalDocs / limit)) : 1\n const hasNextPage = pagination && useLimit && safePage < totalPages\n const hasPrevPage = pagination && useLimit && safePage > 1\n\n const result: PaginatedDocs<Record<string, unknown>> = {\n docs,\n hasNextPage,\n hasPrevPage,\n limit: effectiveLimit,\n nextPage: hasNextPage ? safePage + 1 : null,\n page: safePage,\n pagingCounter: useLimit ? (safePage - 1) * limit + 1 : 1,\n prevPage: hasPrevPage ? safePage - 1 : null,\n totalDocs,\n totalPages,\n }\n return result as never\n}\n"],"names":["applySorts","queryMatching","findVersions","collection","limit","page","pagination","sort","where","partition","resolveVersionsPartition","matched","totalDocs","length","useLimit","safePage","Math","max","start","end","docs","slice","effectiveLimit","totalPages","ceil","hasNextPage","hasPrevPage","result","nextPage","pagingCounter","prevPage"],"mappings":"AAIA,SAASA,UAAU,QAAQ,4BAA2B;AACtD,SAASC,aAAa,QAAQ,+BAA8B;AAE5D;;;;;;CAMC,GACD,OAAO,MAAMC,eAA6B,eAAeA,aAEvD,EAAEC,UAAU,EAAEC,QAAQ,EAAE,EAAEC,OAAO,CAAC,EAAEC,aAAa,IAAI,EAAEC,IAAI,EAAEC,KAAK,EAAE;IAEpE,MAAMC,YAAY,IAAI,CAACC,wBAAwB,CAACP;IAChD,MAAMQ,UAAU,MAAMV,cAAc,IAAI,EAAEQ,WAAWD;IACrDR,WAAWW,SAASJ;IAEpB,MAAMK,YAAYD,QAAQE,MAAM;IAChC,0EAA0E;IAC1E,6EAA6E;IAC7E,2EAA2E;IAC3E,8CAA8C;IAC9C,MAAMC,WAAWV,QAAQ;IACzB,MAAMW,WAAWD,WAAWE,KAAKC,GAAG,CAAC,GAAGZ,QAAQ;IAEhD,MAAMa,QAAQJ,WAAW,AAACC,CAAAA,WAAW,CAAA,IAAKX,QAAQ;IAClD,MAAMe,MAAML,WAAWI,QAAQd,QAAQQ;IACvC,MAAMQ,OAAOT,QAAQU,KAAK,CAACH,OAAOC;IAElC,MAAMG,iBAAiBR,WAAWV,QAAQQ;IAC1C,MAAMW,aAAajB,cAAcQ,WAAWE,KAAKC,GAAG,CAAC,GAAGD,KAAKQ,IAAI,CAACZ,YAAYR,UAAU;IACxF,MAAMqB,cAAcnB,cAAcQ,YAAYC,WAAWQ;IACzD,MAAMG,cAAcpB,cAAcQ,YAAYC,WAAW;IAEzD,MAAMY,SAAiD;QACrDP;QACAK;QACAC;QACAtB,OAAOkB;QACPM,UAAUH,cAAcV,WAAW,IAAI;QACvCV,MAAMU;QACNc,eAAef,WAAW,AAACC,CAAAA,WAAW,CAAA,IAAKX,QAAQ,IAAI;QACvD0B,UAAUJ,cAAcX,WAAW,IAAI;QACvCH;QACAW;IACF;IACA,OAAOI;AACT,EAAC"}
1
+ {"version":3,"sources":["../src/findVersions.ts"],"sourcesContent":["import type { FindVersions, PaginatedDocs } from 'payload'\n\nimport type { DynamoAdapter } from './types.js'\n\nimport { applySorts } from './utilities/applySorts.js'\nimport { prepareSort, prepareVersionsWhere } from './utilities/prepareWhere.js'\nimport { queryMatching } from './utilities/queryMatching.js'\n\n/**\n * Same shape as `find` but routed at the versions partition. Could share\n * more code with `find` via a `paginatedQuery(adapter, partition, args)`\n * helper, but keeping them separate makes per-method tweaks (e.g.\n * version-only filters, eventual draft-aware logic) easier to land without\n * refactoring.\n */\nexport const findVersions: FindVersions = async function findVersions(\n this: DynamoAdapter,\n { collection, limit = 10, locale, page = 1, pagination = true, sort, where: rawWhere },\n) {\n const where = await prepareVersionsWhere(this, { kind: 'collection', slug: collection }, rawWhere, locale)\n const partition = this.resolveVersionsPartition(collection)\n const matched = await queryMatching(this, partition, where)\n applySorts(\n matched,\n prepareSort(this, { kind: 'collectionVersions', slug: collection }, sort, locale),\n )\n\n const totalDocs = matched.length\n // `limit: 0` disables the cap. When pagination is false, limit/page still\n // control the slice (e.g. enforceMaxVersions fetches page max+1 with limit 1\n // to find the oldest doc to prune). The pagination flag only gates whether\n // we compute meaningful total-count metadata.\n const useLimit = limit > 0\n const safePage = useLimit ? Math.max(1, page) : 1\n\n const start = useLimit ? (safePage - 1) * limit : 0\n const end = useLimit ? start + limit : totalDocs\n const docs = matched.slice(start, end)\n\n const effectiveLimit = useLimit ? limit : totalDocs\n const totalPages = pagination && useLimit ? Math.max(1, Math.ceil(totalDocs / limit)) : 1\n const hasNextPage = pagination && useLimit && safePage < totalPages\n const hasPrevPage = pagination && useLimit && safePage > 1\n\n const result: PaginatedDocs<Record<string, unknown>> = {\n docs,\n hasNextPage,\n hasPrevPage,\n limit: effectiveLimit,\n nextPage: hasNextPage ? safePage + 1 : null,\n page: safePage,\n pagingCounter: useLimit ? (safePage - 1) * limit + 1 : 1,\n prevPage: hasPrevPage ? safePage - 1 : null,\n totalDocs,\n totalPages,\n }\n return result as never\n}\n"],"names":["applySorts","prepareSort","prepareVersionsWhere","queryMatching","findVersions","collection","limit","locale","page","pagination","sort","where","rawWhere","kind","slug","partition","resolveVersionsPartition","matched","totalDocs","length","useLimit","safePage","Math","max","start","end","docs","slice","effectiveLimit","totalPages","ceil","hasNextPage","hasPrevPage","result","nextPage","pagingCounter","prevPage"],"mappings":"AAIA,SAASA,UAAU,QAAQ,4BAA2B;AACtD,SAASC,WAAW,EAAEC,oBAAoB,QAAQ,8BAA6B;AAC/E,SAASC,aAAa,QAAQ,+BAA8B;AAE5D;;;;;;CAMC,GACD,OAAO,MAAMC,eAA6B,eAAeA,aAEvD,EAAEC,UAAU,EAAEC,QAAQ,EAAE,EAAEC,MAAM,EAAEC,OAAO,CAAC,EAAEC,aAAa,IAAI,EAAEC,IAAI,EAAEC,OAAOC,QAAQ,EAAE;IAEtF,MAAMD,QAAQ,MAAMT,qBAAqB,IAAI,EAAE;QAAEW,MAAM;QAAcC,MAAMT;IAAW,GAAGO,UAAUL;IACnG,MAAMQ,YAAY,IAAI,CAACC,wBAAwB,CAACX;IAChD,MAAMY,UAAU,MAAMd,cAAc,IAAI,EAAEY,WAAWJ;IACrDX,WACEiB,SACAhB,YAAY,IAAI,EAAE;QAAEY,MAAM;QAAsBC,MAAMT;IAAW,GAAGK,MAAMH;IAG5E,MAAMW,YAAYD,QAAQE,MAAM;IAChC,0EAA0E;IAC1E,6EAA6E;IAC7E,2EAA2E;IAC3E,8CAA8C;IAC9C,MAAMC,WAAWd,QAAQ;IACzB,MAAMe,WAAWD,WAAWE,KAAKC,GAAG,CAAC,GAAGf,QAAQ;IAEhD,MAAMgB,QAAQJ,WAAW,AAACC,CAAAA,WAAW,CAAA,IAAKf,QAAQ;IAClD,MAAMmB,MAAML,WAAWI,QAAQlB,QAAQY;IACvC,MAAMQ,OAAOT,QAAQU,KAAK,CAACH,OAAOC;IAElC,MAAMG,iBAAiBR,WAAWd,QAAQY;IAC1C,MAAMW,aAAapB,cAAcW,WAAWE,KAAKC,GAAG,CAAC,GAAGD,KAAKQ,IAAI,CAACZ,YAAYZ,UAAU;IACxF,MAAMyB,cAActB,cAAcW,YAAYC,WAAWQ;IACzD,MAAMG,cAAcvB,cAAcW,YAAYC,WAAW;IAEzD,MAAMY,SAAiD;QACrDP;QACAK;QACAC;QACA1B,OAAOsB;QACPM,UAAUH,cAAcV,WAAW,IAAI;QACvCb,MAAMa;QACNc,eAAef,WAAW,AAACC,CAAAA,WAAW,CAAA,IAAKf,QAAQ,IAAI;QACvD8B,UAAUJ,cAAcX,WAAW,IAAI;QACvCH;QACAW;IACF;IACA,OAAOI;AACT,EAAC"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import type { DatabaseAdapterObj } from 'payload';
2
2
  import type { Args, DynamoAdapter } from './types.js';
3
3
  export type { Args, DynamoAdapter } from './types.js';
4
+ export { backfillUniqueGuards } from './utilities/backfillUniqueGuards.js';
5
+ export type { UniqueBackfillReport } from './utilities/backfillUniqueGuards.js';
4
6
  export { scrubUnknownFields } from './utilities/scrubUnknownFields.js';
5
7
  export type { ScrubReport } from './utilities/scrubUnknownFields.js';
6
8
  export declare function dynamoAdapter(args?: Args): DatabaseAdapterObj<DynamoAdapter>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAW,MAAM,SAAS,CAAA;AAI1D,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AA6BrD,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAA;AAMpE,wBAAgB,aAAa,CAAC,IAAI,GAAE,IAAS,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAuEhF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAW,MAAM,SAAS,CAAA;AAI1D,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AA8BrD,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAA;AAC1E,YAAY,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAA;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAA;AAMpE,wBAAgB,aAAa,CAAC,IAAI,GAAE,IAAS,GAAG,kBAAkB,CAAC,aAAa,CAAC,CA0EhF"}
package/dist/index.js CHANGED
@@ -21,10 +21,12 @@ import { init } from './init.js';
21
21
  import { queryDrafts } from './queryDrafts.js';
22
22
  import { updateGlobal } from './updateGlobal.js';
23
23
  import { updateGlobalVersion } from './updateGlobalVersion.js';
24
+ import { updateJobs } from './updateJobs.js';
24
25
  import { updateMany } from './updateMany.js';
25
26
  import { updateOne } from './updateOne.js';
26
27
  import { updateVersion } from './updateVersion.js';
27
28
  import { upsert } from './upsert.js';
29
+ export { backfillUniqueGuards } from './utilities/backfillUniqueGuards.js';
28
30
  export { scrubUnknownFields } from './utilities/scrubUnknownFields.js';
29
31
  const NAME = 'dynamodb';
30
32
  const PACKAGE_NAME = '@aih-software/payload-ddb';
@@ -52,6 +54,10 @@ export function dynamoAdapter(args = {}) {
52
54
  ownsClient: !args.client,
53
55
  tableName,
54
56
  ensureTables: args.ensureTables ?? false,
57
+ // `createDatabaseAdapter` falls back to 'migrations' when this is unset.
58
+ ...args.migrationDir ? {
59
+ migrationDir: args.migrationDir
60
+ } : {},
55
61
  resolvePartition,
56
62
  resolveVersionsPartition,
57
63
  // ----- lifecycle -----
@@ -82,6 +88,7 @@ export function dynamoAdapter(args = {}) {
82
88
  queryDrafts,
83
89
  updateGlobal,
84
90
  updateGlobalVersion,
91
+ updateJobs,
85
92
  updateMany,
86
93
  updateOne,
87
94
  updateVersion,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { DatabaseAdapterObj, Payload } from 'payload'\n\nimport { createDatabaseAdapter } from 'payload'\n\nimport type { Args, DynamoAdapter } from './types.js'\n\nimport { connect } from './connect.js'\nimport { count } from './count.js'\nimport { countGlobalVersions } from './countGlobalVersions.js'\nimport { countVersions } from './countVersions.js'\nimport { create } from './create.js'\nimport { createGlobal } from './createGlobal.js'\nimport { createGlobalVersion } from './createGlobalVersion.js'\nimport { createVersion } from './createVersion.js'\nimport { deleteMany } from './deleteMany.js'\nimport { deleteOne } from './deleteOne.js'\nimport { deleteVersions } from './deleteVersions.js'\nimport { destroy } from './destroy.js'\nimport { find } from './find.js'\nimport { findDistinct } from './findDistinct.js'\nimport { findGlobal } from './findGlobal.js'\nimport { findGlobalVersions } from './findGlobalVersions.js'\nimport { findOne } from './findOne.js'\nimport { findVersions } from './findVersions.js'\nimport { init } from './init.js'\nimport { queryDrafts } from './queryDrafts.js'\nimport { updateGlobal } from './updateGlobal.js'\nimport { updateGlobalVersion } from './updateGlobalVersion.js'\nimport { updateMany } from './updateMany.js'\nimport { updateOne } from './updateOne.js'\nimport { updateVersion } from './updateVersion.js'\nimport { upsert } from './upsert.js'\n\nexport type { Args, DynamoAdapter } from './types.js'\nexport { scrubUnknownFields } from './utilities/scrubUnknownFields.js'\nexport type { ScrubReport } from './utilities/scrubUnknownFields.js'\n\nconst NAME = 'dynamodb'\nconst PACKAGE_NAME = '@aih-software/payload-ddb'\nconst DEFAULT_TABLE_NAME = 'payload'\n\nexport function dynamoAdapter(args: Args = {}): DatabaseAdapterObj<DynamoAdapter> {\n function adapterInit({ payload }: { payload: Payload }): DynamoAdapter {\n const tableName = args.tableName ?? DEFAULT_TABLE_NAME\n\n const resolvePartition = (slug: string): string => slug\n const resolveVersionsPartition = (slug: string): string => `${slug}_versions`\n\n return createDatabaseAdapter<DynamoAdapter>({\n name: NAME,\n packageName: PACKAGE_NAME,\n defaultIDType: 'text',\n payload,\n\n // ----- adapter-specific state -----\n clientConfig: args.clientConfig ?? {},\n translateConfig: args.translateConfig ?? {\n marshallOptions: {\n removeUndefinedValues: true,\n convertClassInstanceToMap: true,\n },\n },\n client: args.client,\n docClient: undefined,\n ownsClient: !args.client,\n tableName,\n ensureTables: args.ensureTables ?? false,\n resolvePartition,\n resolveVersionsPartition,\n\n // ----- lifecycle -----\n connect,\n destroy,\n init,\n\n // ----- transactions (no-op until DynamoDB transact-writes are wired) -----\n beginTransaction: async () => null,\n commitTransaction: async () => {},\n rollbackTransaction: async () => {},\n\n // ----- methods -----\n count,\n countGlobalVersions,\n countVersions,\n create,\n createGlobal,\n createGlobalVersion,\n createVersion,\n deleteMany,\n deleteOne,\n deleteVersions,\n find,\n findDistinct,\n findGlobal,\n findGlobalVersions,\n findOne,\n findVersions,\n queryDrafts,\n updateGlobal,\n updateGlobalVersion,\n updateMany,\n updateOne,\n updateVersion,\n upsert,\n })\n }\n\n return {\n name: NAME,\n defaultIDType: 'text',\n init: adapterInit,\n }\n}\n"],"names":["createDatabaseAdapter","connect","count","countGlobalVersions","countVersions","create","createGlobal","createGlobalVersion","createVersion","deleteMany","deleteOne","deleteVersions","destroy","find","findDistinct","findGlobal","findGlobalVersions","findOne","findVersions","init","queryDrafts","updateGlobal","updateGlobalVersion","updateMany","updateOne","updateVersion","upsert","scrubUnknownFields","NAME","PACKAGE_NAME","DEFAULT_TABLE_NAME","dynamoAdapter","args","adapterInit","payload","tableName","resolvePartition","slug","resolveVersionsPartition","name","packageName","defaultIDType","clientConfig","translateConfig","marshallOptions","removeUndefinedValues","convertClassInstanceToMap","client","docClient","undefined","ownsClient","ensureTables","beginTransaction","commitTransaction","rollbackTransaction"],"mappings":"AAEA,SAASA,qBAAqB,QAAQ,UAAS;AAI/C,SAASC,OAAO,QAAQ,eAAc;AACtC,SAASC,KAAK,QAAQ,aAAY;AAClC,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,aAAa,QAAQ,qBAAoB;AAClD,SAASC,MAAM,QAAQ,cAAa;AACpC,SAASC,YAAY,QAAQ,oBAAmB;AAChD,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,aAAa,QAAQ,qBAAoB;AAClD,SAASC,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,SAAS,QAAQ,iBAAgB;AAC1C,SAASC,cAAc,QAAQ,sBAAqB;AACpD,SAASC,OAAO,QAAQ,eAAc;AACtC,SAASC,IAAI,QAAQ,YAAW;AAChC,SAASC,YAAY,QAAQ,oBAAmB;AAChD,SAASC,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,OAAO,QAAQ,eAAc;AACtC,SAASC,YAAY,QAAQ,oBAAmB;AAChD,SAASC,IAAI,QAAQ,YAAW;AAChC,SAASC,WAAW,QAAQ,mBAAkB;AAC9C,SAASC,YAAY,QAAQ,oBAAmB;AAChD,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,SAAS,QAAQ,iBAAgB;AAC1C,SAASC,aAAa,QAAQ,qBAAoB;AAClD,SAASC,MAAM,QAAQ,cAAa;AAGpC,SAASC,kBAAkB,QAAQ,oCAAmC;AAGtE,MAAMC,OAAO;AACb,MAAMC,eAAe;AACrB,MAAMC,qBAAqB;AAE3B,OAAO,SAASC,cAAcC,OAAa,CAAC,CAAC;IAC3C,SAASC,YAAY,EAAEC,OAAO,EAAwB;QACpD,MAAMC,YAAYH,KAAKG,SAAS,IAAIL;QAEpC,MAAMM,mBAAmB,CAACC,OAAyBA;QACnD,MAAMC,2BAA2B,CAACD,OAAyB,GAAGA,KAAK,SAAS,CAAC;QAE7E,OAAOrC,sBAAqC;YAC1CuC,MAAMX;YACNY,aAAaX;YACbY,eAAe;YACfP;YAEA,qCAAqC;YACrCQ,cAAcV,KAAKU,YAAY,IAAI,CAAC;YACpCC,iBAAiBX,KAAKW,eAAe,IAAI;gBACvCC,iBAAiB;oBACfC,uBAAuB;oBACvBC,2BAA2B;gBAC7B;YACF;YACAC,QAAQf,KAAKe,MAAM;YACnBC,WAAWC;YACXC,YAAY,CAAClB,KAAKe,MAAM;YACxBZ;YACAgB,cAAcnB,KAAKmB,YAAY,IAAI;YACnCf;YACAE;YAEA,wBAAwB;YACxBrC;YACAW;YACAO;YAEA,4EAA4E;YAC5EiC,kBAAkB,UAAY;YAC9BC,mBAAmB,WAAa;YAChCC,qBAAqB,WAAa;YAElC,sBAAsB;YACtBpD;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAE;YACAC;YACAC;YACAC;YACAC;YACAC;YACAE;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;QACF;IACF;IAEA,OAAO;QACLa,MAAMX;QACNa,eAAe;QACftB,MAAMc;IACR;AACF"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { DatabaseAdapterObj, Payload } from 'payload'\n\nimport { createDatabaseAdapter } from 'payload'\n\nimport type { Args, DynamoAdapter } from './types.js'\n\nimport { connect } from './connect.js'\nimport { count } from './count.js'\nimport { countGlobalVersions } from './countGlobalVersions.js'\nimport { countVersions } from './countVersions.js'\nimport { create } from './create.js'\nimport { createGlobal } from './createGlobal.js'\nimport { createGlobalVersion } from './createGlobalVersion.js'\nimport { createVersion } from './createVersion.js'\nimport { deleteMany } from './deleteMany.js'\nimport { deleteOne } from './deleteOne.js'\nimport { deleteVersions } from './deleteVersions.js'\nimport { destroy } from './destroy.js'\nimport { find } from './find.js'\nimport { findDistinct } from './findDistinct.js'\nimport { findGlobal } from './findGlobal.js'\nimport { findGlobalVersions } from './findGlobalVersions.js'\nimport { findOne } from './findOne.js'\nimport { findVersions } from './findVersions.js'\nimport { init } from './init.js'\nimport { queryDrafts } from './queryDrafts.js'\nimport { updateGlobal } from './updateGlobal.js'\nimport { updateGlobalVersion } from './updateGlobalVersion.js'\nimport { updateJobs } from './updateJobs.js'\nimport { updateMany } from './updateMany.js'\nimport { updateOne } from './updateOne.js'\nimport { updateVersion } from './updateVersion.js'\nimport { upsert } from './upsert.js'\n\nexport type { Args, DynamoAdapter } from './types.js'\nexport { backfillUniqueGuards } from './utilities/backfillUniqueGuards.js'\nexport type { UniqueBackfillReport } from './utilities/backfillUniqueGuards.js'\nexport { scrubUnknownFields } from './utilities/scrubUnknownFields.js'\nexport type { ScrubReport } from './utilities/scrubUnknownFields.js'\n\nconst NAME = 'dynamodb'\nconst PACKAGE_NAME = '@aih-software/payload-ddb'\nconst DEFAULT_TABLE_NAME = 'payload'\n\nexport function dynamoAdapter(args: Args = {}): DatabaseAdapterObj<DynamoAdapter> {\n function adapterInit({ payload }: { payload: Payload }): DynamoAdapter {\n const tableName = args.tableName ?? DEFAULT_TABLE_NAME\n\n const resolvePartition = (slug: string): string => slug\n const resolveVersionsPartition = (slug: string): string => `${slug}_versions`\n\n return createDatabaseAdapter<DynamoAdapter>({\n name: NAME,\n packageName: PACKAGE_NAME,\n defaultIDType: 'text',\n payload,\n\n // ----- adapter-specific state -----\n clientConfig: args.clientConfig ?? {},\n translateConfig: args.translateConfig ?? {\n marshallOptions: {\n removeUndefinedValues: true,\n convertClassInstanceToMap: true,\n },\n },\n client: args.client,\n docClient: undefined,\n ownsClient: !args.client,\n tableName,\n ensureTables: args.ensureTables ?? false,\n // `createDatabaseAdapter` falls back to 'migrations' when this is unset.\n ...(args.migrationDir ? { migrationDir: args.migrationDir } : {}),\n resolvePartition,\n resolveVersionsPartition,\n\n // ----- lifecycle -----\n connect,\n destroy,\n init,\n\n // ----- transactions (no-op until DynamoDB transact-writes are wired) -----\n beginTransaction: async () => null,\n commitTransaction: async () => {},\n rollbackTransaction: async () => {},\n\n // ----- methods -----\n count,\n countGlobalVersions,\n countVersions,\n create,\n createGlobal,\n createGlobalVersion,\n createVersion,\n deleteMany,\n deleteOne,\n deleteVersions,\n find,\n findDistinct,\n findGlobal,\n findGlobalVersions,\n findOne,\n findVersions,\n queryDrafts,\n updateGlobal,\n updateGlobalVersion,\n updateJobs,\n updateMany,\n updateOne,\n updateVersion,\n upsert,\n })\n }\n\n return {\n name: NAME,\n defaultIDType: 'text',\n init: adapterInit,\n }\n}\n"],"names":["createDatabaseAdapter","connect","count","countGlobalVersions","countVersions","create","createGlobal","createGlobalVersion","createVersion","deleteMany","deleteOne","deleteVersions","destroy","find","findDistinct","findGlobal","findGlobalVersions","findOne","findVersions","init","queryDrafts","updateGlobal","updateGlobalVersion","updateJobs","updateMany","updateOne","updateVersion","upsert","backfillUniqueGuards","scrubUnknownFields","NAME","PACKAGE_NAME","DEFAULT_TABLE_NAME","dynamoAdapter","args","adapterInit","payload","tableName","resolvePartition","slug","resolveVersionsPartition","name","packageName","defaultIDType","clientConfig","translateConfig","marshallOptions","removeUndefinedValues","convertClassInstanceToMap","client","docClient","undefined","ownsClient","ensureTables","migrationDir","beginTransaction","commitTransaction","rollbackTransaction"],"mappings":"AAEA,SAASA,qBAAqB,QAAQ,UAAS;AAI/C,SAASC,OAAO,QAAQ,eAAc;AACtC,SAASC,KAAK,QAAQ,aAAY;AAClC,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,aAAa,QAAQ,qBAAoB;AAClD,SAASC,MAAM,QAAQ,cAAa;AACpC,SAASC,YAAY,QAAQ,oBAAmB;AAChD,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,aAAa,QAAQ,qBAAoB;AAClD,SAASC,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,SAAS,QAAQ,iBAAgB;AAC1C,SAASC,cAAc,QAAQ,sBAAqB;AACpD,SAASC,OAAO,QAAQ,eAAc;AACtC,SAASC,IAAI,QAAQ,YAAW;AAChC,SAASC,YAAY,QAAQ,oBAAmB;AAChD,SAASC,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,OAAO,QAAQ,eAAc;AACtC,SAASC,YAAY,QAAQ,oBAAmB;AAChD,SAASC,IAAI,QAAQ,YAAW;AAChC,SAASC,WAAW,QAAQ,mBAAkB;AAC9C,SAASC,YAAY,QAAQ,oBAAmB;AAChD,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,SAAS,QAAQ,iBAAgB;AAC1C,SAASC,aAAa,QAAQ,qBAAoB;AAClD,SAASC,MAAM,QAAQ,cAAa;AAGpC,SAASC,oBAAoB,QAAQ,sCAAqC;AAE1E,SAASC,kBAAkB,QAAQ,oCAAmC;AAGtE,MAAMC,OAAO;AACb,MAAMC,eAAe;AACrB,MAAMC,qBAAqB;AAE3B,OAAO,SAASC,cAAcC,OAAa,CAAC,CAAC;IAC3C,SAASC,YAAY,EAAEC,OAAO,EAAwB;QACpD,MAAMC,YAAYH,KAAKG,SAAS,IAAIL;QAEpC,MAAMM,mBAAmB,CAACC,OAAyBA;QACnD,MAAMC,2BAA2B,CAACD,OAAyB,GAAGA,KAAK,SAAS,CAAC;QAE7E,OAAOvC,sBAAqC;YAC1CyC,MAAMX;YACNY,aAAaX;YACbY,eAAe;YACfP;YAEA,qCAAqC;YACrCQ,cAAcV,KAAKU,YAAY,IAAI,CAAC;YACpCC,iBAAiBX,KAAKW,eAAe,IAAI;gBACvCC,iBAAiB;oBACfC,uBAAuB;oBACvBC,2BAA2B;gBAC7B;YACF;YACAC,QAAQf,KAAKe,MAAM;YACnBC,WAAWC;YACXC,YAAY,CAAClB,KAAKe,MAAM;YACxBZ;YACAgB,cAAcnB,KAAKmB,YAAY,IAAI;YACnC,yEAAyE;YACzE,GAAInB,KAAKoB,YAAY,GAAG;gBAAEA,cAAcpB,KAAKoB,YAAY;YAAC,IAAI,CAAC,CAAC;YAChEhB;YACAE;YAEA,wBAAwB;YACxBvC;YACAW;YACAO;YAEA,4EAA4E;YAC5EoC,kBAAkB,UAAY;YAC9BC,mBAAmB,WAAa;YAChCC,qBAAqB,WAAa;YAElC,sBAAsB;YACtBvD;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAE;YACAC;YACAC;YACAC;YACAC;YACAC;YACAE;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;QACF;IACF;IAEA,OAAO;QACLc,MAAMX;QACNa,eAAe;QACfxB,MAAMgB;IACR;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"queryDrafts.d.ts","sourceRoot":"","sources":["../src/queryDrafts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,WAAW,EAAS,MAAM,SAAS,CAAA;AA6ChE,eAAO,MAAM,WAAW,EAAE,WAsEzB,CAAA"}
1
+ {"version":3,"file":"queryDrafts.d.ts","sourceRoot":"","sources":["../src/queryDrafts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,WAAW,EAAS,MAAM,SAAS,CAAA;AAwDhE,eAAO,MAAM,WAAW,EAAE,WA4EzB,CAAA"}
@@ -1,6 +1,8 @@
1
1
  import { applySorts } from './utilities/applySorts.js';
2
2
  import { matchesWhere } from './utilities/matchesWhere.js';
3
+ import { prepareCollectionWhere, prepareSort } from './utilities/prepareWhere.js';
3
4
  import { queryMatching } from './utilities/queryMatching.js';
5
+ import { resolveJoins } from './utilities/resolveJoins.js';
4
6
  /**
5
7
  * Return the latest version of every doc as a paginated, doc-shaped result.
6
8
  *
@@ -22,6 +24,11 @@ import { queryMatching } from './utilities/queryMatching.js';
22
24
  // transforming e.g. `{ slug: { equals: 'x' } }` → `{ 'version.slug': { equals: 'x' } }`.
23
25
  // But we project versionData flat to the top level, so those prefixed paths
24
26
  // never resolve. Strip the leading `version.` to match the projected shape.
27
+ //
28
+ // The same core rewrite turns a doc-level `id` filter into `parent` (the
29
+ // version row's pointer to its doc). The projected docs carry that value as
30
+ // `id` again, so map it back — otherwise an `id` filter on a drafts query
31
+ // tests a `parent` key that no projected doc has, and matches nothing.
25
32
  function stripVersionPrefix(where) {
26
33
  if (!where || typeof where !== 'object') return where;
27
34
  const result = {};
@@ -30,13 +37,17 @@ function stripVersionPrefix(where) {
30
37
  if (Array.isArray(value)) {
31
38
  result[key] = value.map((sub)=>stripVersionPrefix(sub)).filter(Boolean);
32
39
  }
40
+ } else if (key.startsWith('version.')) {
41
+ // Checked first: a doc field that is itself named `parent` arrives as
42
+ // `version.parent` and must stay `parent`.
43
+ result[key.slice(8)] = value;
33
44
  } else {
34
- result[key.startsWith('version.') ? key.slice(8) : key] = value;
45
+ result[key === 'parent' ? 'id' : key] = value;
35
46
  }
36
47
  }
37
48
  return result;
38
49
  }
39
- export const queryDrafts = async function queryDrafts({ collection, limit = 10, page = 1, pagination = true, sort, where }) {
50
+ export const queryDrafts = async function queryDrafts({ collection, joins, limit = 10, locale, page = 1, pagination = true, sort, where }) {
40
51
  const versionsPartition = this.resolveVersionsPartition(collection);
41
52
  const docsPartition = this.resolvePartition(collection);
42
53
  const [latestRows, mainRows] = await Promise.all([
@@ -72,15 +83,24 @@ export const queryDrafts = async function queryDrafts({ collection, limit = 10,
72
83
  // to the top level above, so those prefixed paths never resolve via
73
84
  // getByPath. Strip the leading `version.` from every field key so the
74
85
  // in-memory filter matches the projected shape.
75
- const normalizedWhere = stripVersionPrefix(where);
86
+ const normalizedWhere = await prepareCollectionWhere(this, collection, stripVersionPrefix(where) ?? undefined, locale);
76
87
  const matched = normalizedWhere ? projected.filter((doc)=>matchesWhere(doc, normalizedWhere)) : projected;
77
- applySorts(matched, sort);
88
+ applySorts(matched, prepareSort(this, {
89
+ kind: 'collection',
90
+ slug: collection
91
+ }, sort, locale));
78
92
  const totalDocs = matched.length;
79
93
  const useLimit = limit > 0;
80
94
  const safePage = useLimit ? Math.max(1, page) : 1;
81
95
  const start = useLimit ? (safePage - 1) * limit : 0;
82
96
  const end = useLimit ? start + limit : totalDocs;
83
97
  const docs = matched.slice(start, end);
98
+ await resolveJoins(this, {
99
+ collectionSlug: collection,
100
+ docs,
101
+ joins,
102
+ locale
103
+ });
84
104
  const effectiveLimit = useLimit ? limit : totalDocs;
85
105
  const totalPages = pagination && useLimit ? Math.max(1, Math.ceil(totalDocs / limit)) : 1;
86
106
  const hasNextPage = pagination && useLimit && safePage < totalPages;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/queryDrafts.ts"],"sourcesContent":["import type { PaginatedDocs, QueryDrafts, Where } from 'payload'\n\nimport type { DynamoAdapter } from './types.js'\n\nimport { applySorts } from './utilities/applySorts.js'\nimport { matchesWhere } from './utilities/matchesWhere.js'\nimport { queryMatching } from './utilities/queryMatching.js'\n\n/**\n * Return the latest version of every doc as a paginated, doc-shaped result.\n *\n * Strategy:\n * 1. Query the versions partition for `latest=true` rows (one per parent).\n * 2. Project each row's `version` payload up to top-level so the result\n * looks like a doc — this lets the user's `where` / `sort` operate in\n * doc-field terms instead of `version.x` paths.\n * 3. Fill in any docs that have a row in the *main* partition but no\n * `latest=true` version row. This covers two cases:\n * - documents created before versioning was enabled\n * - data orphaned by historical adapter bugs that dropped version writes\n * 4. Apply `where` post-projection, sort, paginate.\n *\n * No `_status` filter is applied — `queryDrafts` returns the latest version\n * regardless of draft/published state. Payload's higher-level code decides\n * how to use the result.\n */\n// Payload core calls appendVersionToQueryKey before invoking queryDrafts,\n// transforming e.g. `{ slug: { equals: 'x' } }` → `{ 'version.slug': { equals: 'x' } }`.\n// But we project versionData flat to the top level, so those prefixed paths\n// never resolve. Strip the leading `version.` to match the projected shape.\nfunction stripVersionPrefix(where: Where | null | undefined): Where | null | undefined {\n if (!where || typeof where !== 'object') return where\n const result: Where = {}\n for (const [key, value] of Object.entries(where)) {\n if (key === 'and' || key === 'or') {\n if (Array.isArray(value)) {\n result[key] = value.map((sub) => stripVersionPrefix(sub as Where)).filter(Boolean) as Where[]\n }\n } else {\n result[key.startsWith('version.') ? key.slice(8) : key] = value as Where[string]\n }\n }\n return result\n}\n\nexport const queryDrafts: QueryDrafts = async function queryDrafts(\n this: DynamoAdapter,\n { collection, limit = 10, page = 1, pagination = true, sort, where },\n) {\n const versionsPartition = this.resolveVersionsPartition(collection)\n const docsPartition = this.resolvePartition(collection)\n\n const [latestRows, mainRows] = await Promise.all([\n queryMatching(this, versionsPartition, { latest: { equals: true } }),\n queryMatching(this, docsPartition, undefined),\n ])\n\n // Latest-version rows win. We key by parent id so `mainRows` only fills\n // entries that have no version backing.\n const docsByParent = new Map<unknown, Record<string, unknown>>()\n for (const row of latestRows) {\n const version = row['version']\n if (!version || typeof version !== 'object') continue\n docsByParent.set(row['parent'], {\n ...(version as Record<string, unknown>),\n id: row['parent'],\n })\n }\n\n for (const doc of mainRows) {\n if (!docsByParent.has(doc['id'])) {\n docsByParent.set(doc['id'], doc)\n }\n }\n\n const projected = [...docsByParent.values()]\n // Payload core calls appendVersionToQueryKey before invoking queryDrafts,\n // which transforms e.g. `{ slug: { equals: 'x' } }` into\n // `{ 'version.slug': { equals: 'x' } }`. But we project versionData flat\n // to the top level above, so those prefixed paths never resolve via\n // getByPath. Strip the leading `version.` from every field key so the\n // in-memory filter matches the projected shape.\n const normalizedWhere = stripVersionPrefix(where)\n const matched = normalizedWhere\n ? projected.filter((doc) => matchesWhere(doc, normalizedWhere))\n : projected\n\n applySorts(matched, sort)\n\n const totalDocs = matched.length\n const useLimit = limit > 0\n const safePage = useLimit ? Math.max(1, page) : 1\n\n const start = useLimit ? (safePage - 1) * limit : 0\n const end = useLimit ? start + limit : totalDocs\n const docs = matched.slice(start, end)\n\n const effectiveLimit = useLimit ? limit : totalDocs\n const totalPages = pagination && useLimit ? Math.max(1, Math.ceil(totalDocs / limit)) : 1\n const hasNextPage = pagination && useLimit && safePage < totalPages\n const hasPrevPage = pagination && useLimit && safePage > 1\n\n const result: PaginatedDocs<Record<string, unknown>> = {\n docs,\n hasNextPage,\n hasPrevPage,\n limit: effectiveLimit,\n nextPage: hasNextPage ? safePage + 1 : null,\n page: safePage,\n pagingCounter: useLimit ? (safePage - 1) * limit + 1 : 1,\n prevPage: hasPrevPage ? safePage - 1 : null,\n totalDocs,\n totalPages,\n }\n return result as never\n}\n"],"names":["applySorts","matchesWhere","queryMatching","stripVersionPrefix","where","result","key","value","Object","entries","Array","isArray","map","sub","filter","Boolean","startsWith","slice","queryDrafts","collection","limit","page","pagination","sort","versionsPartition","resolveVersionsPartition","docsPartition","resolvePartition","latestRows","mainRows","Promise","all","latest","equals","undefined","docsByParent","Map","row","version","set","id","doc","has","projected","values","normalizedWhere","matched","totalDocs","length","useLimit","safePage","Math","max","start","end","docs","effectiveLimit","totalPages","ceil","hasNextPage","hasPrevPage","nextPage","pagingCounter","prevPage"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/queryDrafts.ts"],"sourcesContent":["import type { PaginatedDocs, QueryDrafts, Where } from 'payload'\n\nimport type { DynamoAdapter } from './types.js'\n\nimport { applySorts } from './utilities/applySorts.js'\nimport { matchesWhere } from './utilities/matchesWhere.js'\nimport { prepareCollectionWhere, prepareSort } from './utilities/prepareWhere.js'\nimport { queryMatching } from './utilities/queryMatching.js'\nimport { resolveJoins } from './utilities/resolveJoins.js'\n\n/**\n * Return the latest version of every doc as a paginated, doc-shaped result.\n *\n * Strategy:\n * 1. Query the versions partition for `latest=true` rows (one per parent).\n * 2. Project each row's `version` payload up to top-level so the result\n * looks like a doc — this lets the user's `where` / `sort` operate in\n * doc-field terms instead of `version.x` paths.\n * 3. Fill in any docs that have a row in the *main* partition but no\n * `latest=true` version row. This covers two cases:\n * - documents created before versioning was enabled\n * - data orphaned by historical adapter bugs that dropped version writes\n * 4. Apply `where` post-projection, sort, paginate.\n *\n * No `_status` filter is applied — `queryDrafts` returns the latest version\n * regardless of draft/published state. Payload's higher-level code decides\n * how to use the result.\n */\n// Payload core calls appendVersionToQueryKey before invoking queryDrafts,\n// transforming e.g. `{ slug: { equals: 'x' } }` → `{ 'version.slug': { equals: 'x' } }`.\n// But we project versionData flat to the top level, so those prefixed paths\n// never resolve. Strip the leading `version.` to match the projected shape.\n//\n// The same core rewrite turns a doc-level `id` filter into `parent` (the\n// version row's pointer to its doc). The projected docs carry that value as\n// `id` again, so map it back — otherwise an `id` filter on a drafts query\n// tests a `parent` key that no projected doc has, and matches nothing.\nfunction stripVersionPrefix(where: Where | null | undefined): Where | null | undefined {\n if (!where || typeof where !== 'object') return where\n const result: Where = {}\n for (const [key, value] of Object.entries(where)) {\n if (key === 'and' || key === 'or') {\n if (Array.isArray(value)) {\n result[key] = value.map((sub) => stripVersionPrefix(sub as Where)).filter(Boolean) as Where[]\n }\n } else if (key.startsWith('version.')) {\n // Checked first: a doc field that is itself named `parent` arrives as\n // `version.parent` and must stay `parent`.\n result[key.slice(8)] = value as Where[string]\n } else {\n result[key === 'parent' ? 'id' : key] = value as Where[string]\n }\n }\n return result\n}\n\nexport const queryDrafts: QueryDrafts = async function queryDrafts(\n this: DynamoAdapter,\n { collection, joins, limit = 10, locale, page = 1, pagination = true, sort, where },\n) {\n const versionsPartition = this.resolveVersionsPartition(collection)\n const docsPartition = this.resolvePartition(collection)\n\n const [latestRows, mainRows] = await Promise.all([\n queryMatching(this, versionsPartition, { latest: { equals: true } }),\n queryMatching(this, docsPartition, undefined),\n ])\n\n // Latest-version rows win. We key by parent id so `mainRows` only fills\n // entries that have no version backing.\n const docsByParent = new Map<unknown, Record<string, unknown>>()\n for (const row of latestRows) {\n const version = row['version']\n if (!version || typeof version !== 'object') continue\n docsByParent.set(row['parent'], {\n ...(version as Record<string, unknown>),\n id: row['parent'],\n })\n }\n\n for (const doc of mainRows) {\n if (!docsByParent.has(doc['id'])) {\n docsByParent.set(doc['id'], doc)\n }\n }\n\n const projected = [...docsByParent.values()]\n // Payload core calls appendVersionToQueryKey before invoking queryDrafts,\n // which transforms e.g. `{ slug: { equals: 'x' } }` into\n // `{ 'version.slug': { equals: 'x' } }`. But we project versionData flat\n // to the top level above, so those prefixed paths never resolve via\n // getByPath. Strip the leading `version.` from every field key so the\n // in-memory filter matches the projected shape.\n const normalizedWhere = await prepareCollectionWhere(\n this,\n collection,\n stripVersionPrefix(where) ?? undefined,\n locale,\n )\n const matched = normalizedWhere\n ? projected.filter((doc) => matchesWhere(doc, normalizedWhere))\n : projected\n\n applySorts(matched, prepareSort(this, { kind: 'collection', slug: collection }, sort, locale))\n\n const totalDocs = matched.length\n const useLimit = limit > 0\n const safePage = useLimit ? Math.max(1, page) : 1\n\n const start = useLimit ? (safePage - 1) * limit : 0\n const end = useLimit ? start + limit : totalDocs\n const docs = matched.slice(start, end)\n await resolveJoins(this, { collectionSlug: collection, docs, joins, locale })\n\n const effectiveLimit = useLimit ? limit : totalDocs\n const totalPages = pagination && useLimit ? Math.max(1, Math.ceil(totalDocs / limit)) : 1\n const hasNextPage = pagination && useLimit && safePage < totalPages\n const hasPrevPage = pagination && useLimit && safePage > 1\n\n const result: PaginatedDocs<Record<string, unknown>> = {\n docs,\n hasNextPage,\n hasPrevPage,\n limit: effectiveLimit,\n nextPage: hasNextPage ? safePage + 1 : null,\n page: safePage,\n pagingCounter: useLimit ? (safePage - 1) * limit + 1 : 1,\n prevPage: hasPrevPage ? safePage - 1 : null,\n totalDocs,\n totalPages,\n }\n return result as never\n}\n"],"names":["applySorts","matchesWhere","prepareCollectionWhere","prepareSort","queryMatching","resolveJoins","stripVersionPrefix","where","result","key","value","Object","entries","Array","isArray","map","sub","filter","Boolean","startsWith","slice","queryDrafts","collection","joins","limit","locale","page","pagination","sort","versionsPartition","resolveVersionsPartition","docsPartition","resolvePartition","latestRows","mainRows","Promise","all","latest","equals","undefined","docsByParent","Map","row","version","set","id","doc","has","projected","values","normalizedWhere","matched","kind","slug","totalDocs","length","useLimit","safePage","Math","max","start","end","docs","collectionSlug","effectiveLimit","totalPages","ceil","hasNextPage","hasPrevPage","nextPage","pagingCounter","prevPage"],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  import type { UpdateGlobal } from 'payload';
2
2
  /**
3
- * Read-merge-write for the global's singleton row. Per Payload's contract,
4
- * if the global doesn't exist callers should use `createGlobal` first — we
5
- * surface the missing case as `null` cast (matching `updateOne`) rather than
6
- * silently upserting, which would mask programmer errors.
3
+ * Read-merge-write for the global's singleton row, retried if the row changes
4
+ * between the read and the write. Per Payload's contract, if the global
5
+ * doesn't exist callers should use `createGlobal` first — we surface the
6
+ * missing case as `null` cast (matching `updateOne`) rather than silently
7
+ * upserting, which would mask programmer errors.
7
8
  */
8
9
  export declare const updateGlobal: UpdateGlobal;
9
10
  //# sourceMappingURL=updateGlobal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"updateGlobal.d.ts","sourceRoot":"","sources":["../src/updateGlobal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAU3C;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAAE,YAuC1B,CAAA"}
1
+ {"version":3,"file":"updateGlobal.d.ts","sourceRoot":"","sources":["../src/updateGlobal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAQ3C;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,YAkB1B,CAAA"}
@@ -1,45 +1,31 @@
1
- import { GetCommand, PutCommand } from '@aws-sdk/lib-dynamodb';
2
- import { normalizeForDynamo } from './utilities/normalizeForDynamo.js';
1
+ import { getById, writeWithRetry } from './utilities/optimistic.js';
3
2
  import { projectForGlobal } from './utilities/resolveSchema.js';
4
- import { stripInternalKeys } from './utilities/stripInternalKeys.js';
3
+ import { putItem } from './utilities/writeItems.js';
5
4
  /**
6
- * Read-merge-write for the global's singleton row. Per Payload's contract,
7
- * if the global doesn't exist callers should use `createGlobal` first — we
8
- * surface the missing case as `null` cast (matching `updateOne`) rather than
9
- * silently upserting, which would mask programmer errors.
5
+ * Read-merge-write for the global's singleton row, retried if the row changes
6
+ * between the read and the write. Per Payload's contract, if the global
7
+ * doesn't exist callers should use `createGlobal` first — we surface the
8
+ * missing case as `null` cast (matching `updateOne`) rather than silently
9
+ * upserting, which would mask programmer errors.
10
10
  */ export const updateGlobal = async function updateGlobal({ slug, data, returning }) {
11
- const docClient = this.docClient;
12
- if (!docClient) {
13
- throw new Error('payload-ddb: docClient is not initialized — call connect() first.');
14
- }
15
11
  const partition = this.resolvePartition(slug);
16
- const result = await docClient.send(new GetCommand({
17
- TableName: this.tableName,
18
- Key: {
19
- pk: partition,
20
- sk: slug
21
- },
22
- ConsistentRead: true
23
- }));
24
- if (!result.Item) {
12
+ const read = ()=>getById(this, partition, slug);
13
+ const updated = await writeWithRetry(await read(), read, async (existing)=>{
14
+ const merged = {
15
+ ...existing,
16
+ ...data,
17
+ id: slug
18
+ };
19
+ const projected = projectForGlobal(this, slug, merged);
20
+ await putItem(this, partition, projected, {
21
+ replaces: existing
22
+ });
23
+ return projected;
24
+ });
25
+ if (!updated || returning === false) {
25
26
  return null;
26
27
  }
27
- const existing = stripInternalKeys(result.Item);
28
- const merged = {
29
- ...existing,
30
- ...data,
31
- id: slug
32
- };
33
- const projected = projectForGlobal(this, slug, merged);
34
- await docClient.send(new PutCommand({
35
- TableName: this.tableName,
36
- Item: normalizeForDynamo({
37
- ...projected,
38
- pk: partition,
39
- sk: slug
40
- })
41
- }));
42
- return returning === false ? null : projected;
28
+ return updated;
43
29
  };
44
30
 
45
31
  //# sourceMappingURL=updateGlobal.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/updateGlobal.ts"],"sourcesContent":["import type { UpdateGlobal } from 'payload'\n\nimport { GetCommand, PutCommand } from '@aws-sdk/lib-dynamodb'\n\nimport type { DynamoAdapter } from './types.js'\n\nimport { normalizeForDynamo } from './utilities/normalizeForDynamo.js'\nimport { projectForGlobal } from './utilities/resolveSchema.js'\nimport { stripInternalKeys } from './utilities/stripInternalKeys.js'\n\n/**\n * Read-merge-write for the global's singleton row. Per Payload's contract,\n * if the global doesn't exist callers should use `createGlobal` first — we\n * surface the missing case as `null` cast (matching `updateOne`) rather than\n * silently upserting, which would mask programmer errors.\n */\nexport const updateGlobal: UpdateGlobal = async function updateGlobal(\n this: DynamoAdapter,\n { slug, data, returning },\n) {\n const docClient = this.docClient\n if (!docClient) {\n throw new Error('payload-ddb: docClient is not initialized — call connect() first.')\n }\n\n const partition = this.resolvePartition(slug)\n\n const result = await docClient.send(\n new GetCommand({\n TableName: this.tableName,\n Key: { pk: partition, sk: slug },\n ConsistentRead: true,\n }),\n )\n\n if (!result.Item) {\n return null as never\n }\n\n const existing = stripInternalKeys(result.Item)\n const merged: Record<string, unknown> = { ...existing, ...data, id: slug }\n const projected = projectForGlobal(this, slug, merged)\n\n await docClient.send(\n new PutCommand({\n TableName: this.tableName,\n Item: normalizeForDynamo({\n ...projected,\n pk: partition,\n sk: slug,\n }),\n }),\n )\n\n return returning === false ? (null as never) : (projected as never)\n}\n"],"names":["GetCommand","PutCommand","normalizeForDynamo","projectForGlobal","stripInternalKeys","updateGlobal","slug","data","returning","docClient","Error","partition","resolvePartition","result","send","TableName","tableName","Key","pk","sk","ConsistentRead","Item","existing","merged","id","projected"],"mappings":"AAEA,SAASA,UAAU,EAAEC,UAAU,QAAQ,wBAAuB;AAI9D,SAASC,kBAAkB,QAAQ,oCAAmC;AACtE,SAASC,gBAAgB,QAAQ,+BAA8B;AAC/D,SAASC,iBAAiB,QAAQ,mCAAkC;AAEpE;;;;;CAKC,GACD,OAAO,MAAMC,eAA6B,eAAeA,aAEvD,EAAEC,IAAI,EAAEC,IAAI,EAAEC,SAAS,EAAE;IAEzB,MAAMC,YAAY,IAAI,CAACA,SAAS;IAChC,IAAI,CAACA,WAAW;QACd,MAAM,IAAIC,MAAM;IAClB;IAEA,MAAMC,YAAY,IAAI,CAACC,gBAAgB,CAACN;IAExC,MAAMO,SAAS,MAAMJ,UAAUK,IAAI,CACjC,IAAId,WAAW;QACbe,WAAW,IAAI,CAACC,SAAS;QACzBC,KAAK;YAAEC,IAAIP;YAAWQ,IAAIb;QAAK;QAC/Bc,gBAAgB;IAClB;IAGF,IAAI,CAACP,OAAOQ,IAAI,EAAE;QAChB,OAAO;IACT;IAEA,MAAMC,WAAWlB,kBAAkBS,OAAOQ,IAAI;IAC9C,MAAME,SAAkC;QAAE,GAAGD,QAAQ;QAAE,GAAGf,IAAI;QAAEiB,IAAIlB;IAAK;IACzE,MAAMmB,YAAYtB,iBAAiB,IAAI,EAAEG,MAAMiB;IAE/C,MAAMd,UAAUK,IAAI,CAClB,IAAIb,WAAW;QACbc,WAAW,IAAI,CAACC,SAAS;QACzBK,MAAMnB,mBAAmB;YACvB,GAAGuB,SAAS;YACZP,IAAIP;YACJQ,IAAIb;QACN;IACF;IAGF,OAAOE,cAAc,QAAS,OAAkBiB;AAClD,EAAC"}
1
+ {"version":3,"sources":["../src/updateGlobal.ts"],"sourcesContent":["import type { UpdateGlobal } from 'payload'\n\nimport type { DynamoAdapter } from './types.js'\n\nimport { getById, writeWithRetry } from './utilities/optimistic.js'\nimport { projectForGlobal } from './utilities/resolveSchema.js'\nimport { putItem } from './utilities/writeItems.js'\n\n/**\n * Read-merge-write for the global's singleton row, retried if the row changes\n * between the read and the write. Per Payload's contract, if the global\n * doesn't exist callers should use `createGlobal` first — we surface the\n * missing case as `null` cast (matching `updateOne`) rather than silently\n * upserting, which would mask programmer errors.\n */\nexport const updateGlobal: UpdateGlobal = async function updateGlobal(\n this: DynamoAdapter,\n { slug, data, returning },\n) {\n const partition = this.resolvePartition(slug)\n const read = () => getById(this, partition, slug)\n\n const updated = await writeWithRetry(await read(), read, async (existing) => {\n const merged: Record<string, unknown> = { ...existing, ...data, id: slug }\n const projected = projectForGlobal(this, slug, merged)\n await putItem(this, partition, projected, { replaces: existing })\n return projected\n })\n\n if (!updated || returning === false) {\n return null as never\n }\n return updated as never\n}\n"],"names":["getById","writeWithRetry","projectForGlobal","putItem","updateGlobal","slug","data","returning","partition","resolvePartition","read","updated","existing","merged","id","projected","replaces"],"mappings":"AAIA,SAASA,OAAO,EAAEC,cAAc,QAAQ,4BAA2B;AACnE,SAASC,gBAAgB,QAAQ,+BAA8B;AAC/D,SAASC,OAAO,QAAQ,4BAA2B;AAEnD;;;;;;CAMC,GACD,OAAO,MAAMC,eAA6B,eAAeA,aAEvD,EAAEC,IAAI,EAAEC,IAAI,EAAEC,SAAS,EAAE;IAEzB,MAAMC,YAAY,IAAI,CAACC,gBAAgB,CAACJ;IACxC,MAAMK,OAAO,IAAMV,QAAQ,IAAI,EAAEQ,WAAWH;IAE5C,MAAMM,UAAU,MAAMV,eAAe,MAAMS,QAAQA,MAAM,OAAOE;QAC9D,MAAMC,SAAkC;YAAE,GAAGD,QAAQ;YAAE,GAAGN,IAAI;YAAEQ,IAAIT;QAAK;QACzE,MAAMU,YAAYb,iBAAiB,IAAI,EAAEG,MAAMQ;QAC/C,MAAMV,QAAQ,IAAI,EAAEK,WAAWO,WAAW;YAAEC,UAAUJ;QAAS;QAC/D,OAAOG;IACT;IAEA,IAAI,CAACJ,WAAWJ,cAAc,OAAO;QACnC,OAAO;IACT;IACA,OAAOI;AACT,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"updateGlobalVersion.d.ts","sourceRoot":"","sources":["../src/updateGlobalVersion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAWlD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,mBAwDjC,CAAA"}
1
+ {"version":3,"file":"updateGlobalVersion.d.ts","sourceRoot":"","sources":["../src/updateGlobalVersion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAMlD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,mBAKjC,CAAA"}
@@ -1,59 +1,13 @@
1
- import { GetCommand, PutCommand } from '@aws-sdk/lib-dynamodb';
2
- import { findFirst } from './utilities/findFirst.js';
3
- import { normalizeForDynamo } from './utilities/normalizeForDynamo.js';
4
- import { projectVersionRow } from './utilities/resolveSchema.js';
5
- import { stripInternalKeys } from './utilities/stripInternalKeys.js';
1
+ import { updateVersionRow } from './utilities/updateVersionRow.js';
6
2
  /**
7
3
  * Same read-merge-write semantics as `updateVersion`. Doesn't cascade
8
4
  * `latest` flips for the same reason: Payload owns that contract by issuing
9
5
  * paired updates.
10
6
  */ export const updateGlobalVersion = async function updateGlobalVersion(args) {
11
- const docClient = this.docClient;
12
- if (!docClient) {
13
- throw new Error('payload-ddb: docClient is not initialized — call connect() first.');
14
- }
15
- const partition = this.resolveVersionsPartition(args.global);
16
- let target = null;
17
- if (args.id !== undefined && args.id !== null) {
18
- const result = await docClient.send(new GetCommand({
19
- TableName: this.tableName,
20
- Key: {
21
- pk: partition,
22
- sk: String(args.id)
23
- },
24
- ConsistentRead: true
25
- }));
26
- target = result.Item ? stripInternalKeys(result.Item) : null;
27
- } else if (args.where) {
28
- target = await findFirst(this, {
29
- partition,
30
- where: args.where
31
- });
32
- }
33
- if (!target) {
34
- return null;
35
- }
36
- const merged = {
37
- ...target,
38
- ...args.versionData,
39
- id: target['id']
40
- };
41
- const projected = projectVersionRow(this, {
7
+ return updateVersionRow(this, {
42
8
  kind: 'global',
43
9
  slug: args.global
44
- }, merged);
45
- await docClient.send(new PutCommand({
46
- TableName: this.tableName,
47
- Item: normalizeForDynamo({
48
- ...projected,
49
- pk: partition,
50
- sk: String(projected['id'])
51
- })
52
- }));
53
- if (args.returning === false) {
54
- return null;
55
- }
56
- return projected;
10
+ }, args);
57
11
  };
58
12
 
59
13
  //# sourceMappingURL=updateGlobalVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/updateGlobalVersion.ts"],"sourcesContent":["import type { UpdateGlobalVersion } from 'payload'\n\nimport { GetCommand, PutCommand } from '@aws-sdk/lib-dynamodb'\n\nimport type { DynamoAdapter } from './types.js'\n\nimport { findFirst } from './utilities/findFirst.js'\nimport { normalizeForDynamo } from './utilities/normalizeForDynamo.js'\nimport { projectVersionRow } from './utilities/resolveSchema.js'\nimport { stripInternalKeys } from './utilities/stripInternalKeys.js'\n\n/**\n * Same read-merge-write semantics as `updateVersion`. Doesn't cascade\n * `latest` flips for the same reason: Payload owns that contract by issuing\n * paired updates.\n */\nexport const updateGlobalVersion: UpdateGlobalVersion = async function updateGlobalVersion(\n this: DynamoAdapter,\n args,\n) {\n const docClient = this.docClient\n if (!docClient) {\n throw new Error('payload-ddb: docClient is not initialized — call connect() first.')\n }\n\n const partition = this.resolveVersionsPartition(args.global)\n\n let target: null | Record<string, unknown> = null\n\n if (args.id !== undefined && args.id !== null) {\n const result = await docClient.send(\n new GetCommand({\n TableName: this.tableName,\n Key: { pk: partition, sk: String(args.id) },\n ConsistentRead: true,\n }),\n )\n target = result.Item ? stripInternalKeys(result.Item) : null\n } else if (args.where) {\n target = await findFirst(this, { partition, where: args.where })\n }\n\n if (!target) {\n return null as never\n }\n\n const merged: Record<string, unknown> = {\n ...target,\n ...args.versionData,\n id: target['id'],\n }\n const projected = projectVersionRow(\n this,\n { kind: 'global', slug: args.global },\n merged,\n )\n\n await docClient.send(\n new PutCommand({\n TableName: this.tableName,\n Item: normalizeForDynamo({\n ...projected,\n pk: partition,\n sk: String(projected['id']),\n }),\n }),\n )\n\n if (args.returning === false) {\n return null as never\n }\n return projected as never\n}\n"],"names":["GetCommand","PutCommand","findFirst","normalizeForDynamo","projectVersionRow","stripInternalKeys","updateGlobalVersion","args","docClient","Error","partition","resolveVersionsPartition","global","target","id","undefined","result","send","TableName","tableName","Key","pk","sk","String","ConsistentRead","Item","where","merged","versionData","projected","kind","slug","returning"],"mappings":"AAEA,SAASA,UAAU,EAAEC,UAAU,QAAQ,wBAAuB;AAI9D,SAASC,SAAS,QAAQ,2BAA0B;AACpD,SAASC,kBAAkB,QAAQ,oCAAmC;AACtE,SAASC,iBAAiB,QAAQ,+BAA8B;AAChE,SAASC,iBAAiB,QAAQ,mCAAkC;AAEpE;;;;CAIC,GACD,OAAO,MAAMC,sBAA2C,eAAeA,oBAErEC,IAAI;IAEJ,MAAMC,YAAY,IAAI,CAACA,SAAS;IAChC,IAAI,CAACA,WAAW;QACd,MAAM,IAAIC,MAAM;IAClB;IAEA,MAAMC,YAAY,IAAI,CAACC,wBAAwB,CAACJ,KAAKK,MAAM;IAE3D,IAAIC,SAAyC;IAE7C,IAAIN,KAAKO,EAAE,KAAKC,aAAaR,KAAKO,EAAE,KAAK,MAAM;QAC7C,MAAME,SAAS,MAAMR,UAAUS,IAAI,CACjC,IAAIjB,WAAW;YACbkB,WAAW,IAAI,CAACC,SAAS;YACzBC,KAAK;gBAAEC,IAAIX;gBAAWY,IAAIC,OAAOhB,KAAKO,EAAE;YAAE;YAC1CU,gBAAgB;QAClB;QAEFX,SAASG,OAAOS,IAAI,GAAGpB,kBAAkBW,OAAOS,IAAI,IAAI;IAC1D,OAAO,IAAIlB,KAAKmB,KAAK,EAAE;QACrBb,SAAS,MAAMX,UAAU,IAAI,EAAE;YAAEQ;YAAWgB,OAAOnB,KAAKmB,KAAK;QAAC;IAChE;IAEA,IAAI,CAACb,QAAQ;QACX,OAAO;IACT;IAEA,MAAMc,SAAkC;QACtC,GAAGd,MAAM;QACT,GAAGN,KAAKqB,WAAW;QACnBd,IAAID,MAAM,CAAC,KAAK;IAClB;IACA,MAAMgB,YAAYzB,kBAChB,IAAI,EACJ;QAAE0B,MAAM;QAAUC,MAAMxB,KAAKK,MAAM;IAAC,GACpCe;IAGF,MAAMnB,UAAUS,IAAI,CAClB,IAAIhB,WAAW;QACbiB,WAAW,IAAI,CAACC,SAAS;QACzBM,MAAMtB,mBAAmB;YACvB,GAAG0B,SAAS;YACZR,IAAIX;YACJY,IAAIC,OAAOM,SAAS,CAAC,KAAK;QAC5B;IACF;IAGF,IAAItB,KAAKyB,SAAS,KAAK,OAAO;QAC5B,OAAO;IACT;IACA,OAAOH;AACT,EAAC"}
1
+ {"version":3,"sources":["../src/updateGlobalVersion.ts"],"sourcesContent":["import type { UpdateGlobalVersion } from 'payload'\n\nimport type { DynamoAdapter } from './types.js'\n\nimport { updateVersionRow } from './utilities/updateVersionRow.js'\n\n/**\n * Same read-merge-write semantics as `updateVersion`. Doesn't cascade\n * `latest` flips for the same reason: Payload owns that contract by issuing\n * paired updates.\n */\nexport const updateGlobalVersion: UpdateGlobalVersion = async function updateGlobalVersion(\n this: DynamoAdapter,\n args,\n) {\n return updateVersionRow(this, { kind: 'global', slug: args.global }, args) as never\n}\n"],"names":["updateVersionRow","updateGlobalVersion","args","kind","slug","global"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,kCAAiC;AAElE;;;;CAIC,GACD,OAAO,MAAMC,sBAA2C,eAAeA,oBAErEC,IAAI;IAEJ,OAAOF,iBAAiB,IAAI,EAAE;QAAEG,MAAM;QAAUC,MAAMF,KAAKG,MAAM;IAAC,GAAGH;AACvE,EAAC"}
@@ -0,0 +1,21 @@
1
+ import type { UpdateJobs } from 'payload';
2
+ /**
3
+ * Update rows of Payload's jobs queue (`payload-jobs`).
4
+ *
5
+ * The queue calls this to *claim* work: "set `processing: true` on up to N
6
+ * jobs where `processing` is false". With several workers polling at once,
7
+ * that only stays correct if a job can be claimed once. Each write is
8
+ * therefore conditional on its row being unchanged since it was read; a
9
+ * worker that loses the race re-reads the job, sees it no longer matches
10
+ * `where`, and leaves it out of its result instead of running it a second
11
+ * time. (Core's generic fallback for this method reads and then overwrites,
12
+ * so two workers could both walk away with the same job.)
13
+ *
14
+ * `data` is merged onto each row, with two queue-specific rules taken from
15
+ * Payload's Mongo adapter:
16
+ * - `log: { $push: entry }` appends to the job's log instead of replacing it;
17
+ * a non-empty array replaces it; anything else leaves the log alone.
18
+ * - a missing or `null` `updatedAt` means "now".
19
+ */
20
+ export declare const updateJobs: UpdateJobs;
21
+ //# sourceMappingURL=updateJobs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateJobs.d.ts","sourceRoot":"","sources":["../src/updateJobs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAgBzC;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,UAAU,EAAE,UAyCxB,CAAA"}
@@ -0,0 +1,83 @@
1
+ import { applySorts } from './utilities/applySorts.js';
2
+ import { mapWithConcurrency } from './utilities/mapWithConcurrency.js';
3
+ import { matchesWhere } from './utilities/matchesWhere.js';
4
+ import { getById, writeWithRetry } from './utilities/optimistic.js';
5
+ import { prepareCollectionWhere, prepareSort } from './utilities/prepareWhere.js';
6
+ import { queryMatching } from './utilities/queryMatching.js';
7
+ import { projectForCollection } from './utilities/resolveSchema.js';
8
+ import { putItem, WRITE_CONCURRENCY } from './utilities/writeItems.js';
9
+ /** Slug of Payload's jobs collection (core doesn't export the constant). */ const JOBS_COLLECTION = 'payload-jobs';
10
+ /**
11
+ * Update rows of Payload's jobs queue (`payload-jobs`).
12
+ *
13
+ * The queue calls this to *claim* work: "set `processing: true` on up to N
14
+ * jobs where `processing` is false". With several workers polling at once,
15
+ * that only stays correct if a job can be claimed once. Each write is
16
+ * therefore conditional on its row being unchanged since it was read; a
17
+ * worker that loses the race re-reads the job, sees it no longer matches
18
+ * `where`, and leaves it out of its result instead of running it a second
19
+ * time. (Core's generic fallback for this method reads and then overwrites,
20
+ * so two workers could both walk away with the same job.)
21
+ *
22
+ * `data` is merged onto each row, with two queue-specific rules taken from
23
+ * Payload's Mongo adapter:
24
+ * - `log: { $push: entry }` appends to the job's log instead of replacing it;
25
+ * a non-empty array replaces it; anything else leaves the log alone.
26
+ * - a missing or `null` `updatedAt` means "now".
27
+ */ export const updateJobs = async function updateJobs({ id, data, limit, returning, sort, where: rawWhere }) {
28
+ const collection = JOBS_COLLECTION;
29
+ const partition = this.resolvePartition(collection);
30
+ const byId = id !== undefined && id !== null;
31
+ const where = byId ? undefined : await prepareCollectionWhere(this, collection, rawWhere);
32
+ let targets;
33
+ if (byId) {
34
+ const job = await getById(this, partition, id);
35
+ targets = job ? [
36
+ job
37
+ ] : [];
38
+ } else {
39
+ const matched = await queryMatching(this, partition, where);
40
+ const defaultSort = this.payload.collections?.[collection]?.config.defaultSort;
41
+ applySorts(matched, prepareSort(this, {
42
+ kind: 'collection',
43
+ slug: collection
44
+ }, sort ?? defaultSort ?? '-createdAt'));
45
+ targets = limit && limit > 0 ? matched.slice(0, limit) : matched;
46
+ }
47
+ const updated = await mapWithConcurrency(targets, WRITE_CONCURRENCY, (target)=>writeWithRetry(target, async ()=>{
48
+ const fresh = await getById(this, partition, target['id']);
49
+ // Someone else changed it out from under us — if it no longer
50
+ // qualifies, it isn't ours to update.
51
+ return fresh && (!where || matchesWhere(fresh, where)) ? fresh : null;
52
+ }, async (current)=>{
53
+ const projected = projectForCollection(this, collection, applyJobData(current, data));
54
+ await putItem(this, partition, projected, {
55
+ replaces: current
56
+ });
57
+ return projected;
58
+ }));
59
+ return returning === false ? null : updated.filter((job)=>job !== null);
60
+ };
61
+ function applyJobData(current, data) {
62
+ const { log, updatedAt, ...rest } = data;
63
+ const merged = {
64
+ ...current,
65
+ ...rest,
66
+ id: current['id'],
67
+ updatedAt: updatedAt ?? new Date().toISOString()
68
+ };
69
+ if (Array.isArray(log)) {
70
+ if (log.length > 0) merged['log'] = log;
71
+ } else if (log && typeof log === 'object' && '$push' in log) {
72
+ const pushed = log.$push;
73
+ merged['log'] = [
74
+ ...Array.isArray(current['log']) ? current['log'] : [],
75
+ ...Array.isArray(pushed) ? pushed : [
76
+ pushed
77
+ ]
78
+ ];
79
+ }
80
+ return merged;
81
+ }
82
+
83
+ //# sourceMappingURL=updateJobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/updateJobs.ts"],"sourcesContent":["import type { UpdateJobs } from 'payload'\n\nimport type { DynamoAdapter } from './types.js'\n\nimport { applySorts } from './utilities/applySorts.js'\nimport { mapWithConcurrency } from './utilities/mapWithConcurrency.js'\nimport { matchesWhere } from './utilities/matchesWhere.js'\nimport { getById, writeWithRetry } from './utilities/optimistic.js'\nimport { prepareCollectionWhere, prepareSort } from './utilities/prepareWhere.js'\nimport { queryMatching } from './utilities/queryMatching.js'\nimport { projectForCollection } from './utilities/resolveSchema.js'\nimport { putItem, WRITE_CONCURRENCY } from './utilities/writeItems.js'\n\n/** Slug of Payload's jobs collection (core doesn't export the constant). */\nconst JOBS_COLLECTION = 'payload-jobs'\n\n/**\n * Update rows of Payload's jobs queue (`payload-jobs`).\n *\n * The queue calls this to *claim* work: \"set `processing: true` on up to N\n * jobs where `processing` is false\". With several workers polling at once,\n * that only stays correct if a job can be claimed once. Each write is\n * therefore conditional on its row being unchanged since it was read; a\n * worker that loses the race re-reads the job, sees it no longer matches\n * `where`, and leaves it out of its result instead of running it a second\n * time. (Core's generic fallback for this method reads and then overwrites,\n * so two workers could both walk away with the same job.)\n *\n * `data` is merged onto each row, with two queue-specific rules taken from\n * Payload's Mongo adapter:\n * - `log: { $push: entry }` appends to the job's log instead of replacing it;\n * a non-empty array replaces it; anything else leaves the log alone.\n * - a missing or `null` `updatedAt` means \"now\".\n */\nexport const updateJobs: UpdateJobs = async function updateJobs(\n this: DynamoAdapter,\n { id, data, limit, returning, sort, where: rawWhere },\n) {\n const collection = JOBS_COLLECTION\n const partition = this.resolvePartition(collection)\n const byId = id !== undefined && id !== null\n const where = byId ? undefined : await prepareCollectionWhere(this, collection, rawWhere)\n\n let targets: Record<string, unknown>[]\n if (byId) {\n const job = await getById(this, partition, id)\n targets = job ? [job] : []\n } else {\n const matched = await queryMatching(this, partition, where)\n const defaultSort = this.payload.collections?.[collection]?.config.defaultSort\n applySorts(\n matched,\n prepareSort(this, { kind: 'collection', slug: collection }, sort ?? defaultSort ?? '-createdAt'),\n )\n targets = limit && limit > 0 ? matched.slice(0, limit) : matched\n }\n\n const updated = await mapWithConcurrency(targets, WRITE_CONCURRENCY, (target) =>\n writeWithRetry(\n target,\n async () => {\n const fresh = await getById(this, partition, target['id'])\n // Someone else changed it out from under us — if it no longer\n // qualifies, it isn't ours to update.\n return fresh && (!where || matchesWhere(fresh, where)) ? fresh : null\n },\n async (current) => {\n const projected = projectForCollection(this, collection, applyJobData(current, data))\n await putItem(this, partition, projected, { replaces: current })\n return projected\n },\n ),\n )\n\n return returning === false ? null : (updated.filter((job) => job !== null) as never)\n}\n\nfunction applyJobData(\n current: Record<string, unknown>,\n data: Record<string, unknown>,\n): Record<string, unknown> {\n const { log, updatedAt, ...rest } = data\n const merged: Record<string, unknown> = {\n ...current,\n ...rest,\n id: current['id'],\n updatedAt: updatedAt ?? new Date().toISOString(),\n }\n\n if (Array.isArray(log)) {\n if (log.length > 0) merged['log'] = log\n } else if (log && typeof log === 'object' && '$push' in log) {\n const pushed = (log as { $push: unknown }).$push\n merged['log'] = [\n ...(Array.isArray(current['log']) ? current['log'] : []),\n ...(Array.isArray(pushed) ? pushed : [pushed]),\n ]\n }\n\n return merged\n}\n"],"names":["applySorts","mapWithConcurrency","matchesWhere","getById","writeWithRetry","prepareCollectionWhere","prepareSort","queryMatching","projectForCollection","putItem","WRITE_CONCURRENCY","JOBS_COLLECTION","updateJobs","id","data","limit","returning","sort","where","rawWhere","collection","partition","resolvePartition","byId","undefined","targets","job","matched","defaultSort","payload","collections","config","kind","slug","slice","updated","target","fresh","current","projected","applyJobData","replaces","filter","log","updatedAt","rest","merged","Date","toISOString","Array","isArray","length","pushed","$push"],"mappings":"AAIA,SAASA,UAAU,QAAQ,4BAA2B;AACtD,SAASC,kBAAkB,QAAQ,oCAAmC;AACtE,SAASC,YAAY,QAAQ,8BAA6B;AAC1D,SAASC,OAAO,EAAEC,cAAc,QAAQ,4BAA2B;AACnE,SAASC,sBAAsB,EAAEC,WAAW,QAAQ,8BAA6B;AACjF,SAASC,aAAa,QAAQ,+BAA8B;AAC5D,SAASC,oBAAoB,QAAQ,+BAA8B;AACnE,SAASC,OAAO,EAAEC,iBAAiB,QAAQ,4BAA2B;AAEtE,0EAA0E,GAC1E,MAAMC,kBAAkB;AAExB;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,MAAMC,aAAyB,eAAeA,WAEnD,EAAEC,EAAE,EAAEC,IAAI,EAAEC,KAAK,EAAEC,SAAS,EAAEC,IAAI,EAAEC,OAAOC,QAAQ,EAAE;IAErD,MAAMC,aAAaT;IACnB,MAAMU,YAAY,IAAI,CAACC,gBAAgB,CAACF;IACxC,MAAMG,OAAOV,OAAOW,aAAaX,OAAO;IACxC,MAAMK,QAAQK,OAAOC,YAAY,MAAMnB,uBAAuB,IAAI,EAAEe,YAAYD;IAEhF,IAAIM;IACJ,IAAIF,MAAM;QACR,MAAMG,MAAM,MAAMvB,QAAQ,IAAI,EAAEkB,WAAWR;QAC3CY,UAAUC,MAAM;YAACA;SAAI,GAAG,EAAE;IAC5B,OAAO;QACL,MAAMC,UAAU,MAAMpB,cAAc,IAAI,EAAEc,WAAWH;QACrD,MAAMU,cAAc,IAAI,CAACC,OAAO,CAACC,WAAW,EAAE,CAACV,WAAW,EAAEW,OAAOH;QACnE5B,WACE2B,SACArB,YAAY,IAAI,EAAE;YAAE0B,MAAM;YAAcC,MAAMb;QAAW,GAAGH,QAAQW,eAAe;QAErFH,UAAUV,SAASA,QAAQ,IAAIY,QAAQO,KAAK,CAAC,GAAGnB,SAASY;IAC3D;IAEA,MAAMQ,UAAU,MAAMlC,mBAAmBwB,SAASf,mBAAmB,CAAC0B,SACpEhC,eACEgC,QACA;YACE,MAAMC,QAAQ,MAAMlC,QAAQ,IAAI,EAAEkB,WAAWe,MAAM,CAAC,KAAK;YACzD,8DAA8D;YAC9D,sCAAsC;YACtC,OAAOC,SAAU,CAAA,CAACnB,SAAShB,aAAamC,OAAOnB,MAAK,IAAKmB,QAAQ;QACnE,GACA,OAAOC;YACL,MAAMC,YAAY/B,qBAAqB,IAAI,EAAEY,YAAYoB,aAAaF,SAASxB;YAC/E,MAAML,QAAQ,IAAI,EAAEY,WAAWkB,WAAW;gBAAEE,UAAUH;YAAQ;YAC9D,OAAOC;QACT;IAIJ,OAAOvB,cAAc,QAAQ,OAAQmB,QAAQO,MAAM,CAAC,CAAChB,MAAQA,QAAQ;AACvE,EAAC;AAED,SAASc,aACPF,OAAgC,EAChCxB,IAA6B;IAE7B,MAAM,EAAE6B,GAAG,EAAEC,SAAS,EAAE,GAAGC,MAAM,GAAG/B;IACpC,MAAMgC,SAAkC;QACtC,GAAGR,OAAO;QACV,GAAGO,IAAI;QACPhC,IAAIyB,OAAO,CAAC,KAAK;QACjBM,WAAWA,aAAa,IAAIG,OAAOC,WAAW;IAChD;IAEA,IAAIC,MAAMC,OAAO,CAACP,MAAM;QACtB,IAAIA,IAAIQ,MAAM,GAAG,GAAGL,MAAM,CAAC,MAAM,GAAGH;IACtC,OAAO,IAAIA,OAAO,OAAOA,QAAQ,YAAY,WAAWA,KAAK;QAC3D,MAAMS,SAAS,AAACT,IAA2BU,KAAK;QAChDP,MAAM,CAAC,MAAM,GAAG;eACVG,MAAMC,OAAO,CAACZ,OAAO,CAAC,MAAM,IAAIA,OAAO,CAAC,MAAM,GAAG,EAAE;eACnDW,MAAMC,OAAO,CAACE,UAAUA,SAAS;gBAACA;aAAO;SAC9C;IACH;IAEA,OAAON;AACT"}