payload 3.71.1 → 3.72.0-internal.3e70d4c

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 (151) hide show
  1. package/dist/collections/config/sanitize.d.ts.map +1 -1
  2. package/dist/collections/config/sanitize.js +19 -4
  3. package/dist/collections/config/sanitize.js.map +1 -1
  4. package/dist/collections/endpoints/create.d.ts.map +1 -1
  5. package/dist/collections/endpoints/create.js +2 -1
  6. package/dist/collections/endpoints/create.js.map +1 -1
  7. package/dist/collections/endpoints/update.d.ts.map +1 -1
  8. package/dist/collections/endpoints/update.js +3 -1
  9. package/dist/collections/endpoints/update.js.map +1 -1
  10. package/dist/collections/endpoints/updateByID.d.ts.map +1 -1
  11. package/dist/collections/endpoints/updateByID.js +4 -2
  12. package/dist/collections/endpoints/updateByID.js.map +1 -1
  13. package/dist/collections/operations/create.d.ts +1 -0
  14. package/dist/collections/operations/create.d.ts.map +1 -1
  15. package/dist/collections/operations/create.js +23 -3
  16. package/dist/collections/operations/create.js.map +1 -1
  17. package/dist/collections/operations/local/create.d.ts +4 -0
  18. package/dist/collections/operations/local/create.d.ts.map +1 -1
  19. package/dist/collections/operations/local/create.js +2 -1
  20. package/dist/collections/operations/local/create.js.map +1 -1
  21. package/dist/collections/operations/local/update.d.ts +12 -0
  22. package/dist/collections/operations/local/update.d.ts.map +1 -1
  23. package/dist/collections/operations/local/update.js +3 -1
  24. package/dist/collections/operations/local/update.js.map +1 -1
  25. package/dist/collections/operations/update.d.ts +2 -0
  26. package/dist/collections/operations/update.d.ts.map +1 -1
  27. package/dist/collections/operations/update.js +4 -3
  28. package/dist/collections/operations/update.js.map +1 -1
  29. package/dist/collections/operations/updateByID.d.ts +2 -0
  30. package/dist/collections/operations/updateByID.d.ts.map +1 -1
  31. package/dist/collections/operations/updateByID.js +4 -3
  32. package/dist/collections/operations/updateByID.js.map +1 -1
  33. package/dist/collections/operations/utilities/update.d.ts +4 -3
  34. package/dist/collections/operations/utilities/update.d.ts.map +1 -1
  35. package/dist/collections/operations/utilities/update.js +81 -31
  36. package/dist/collections/operations/utilities/update.js.map +1 -1
  37. package/dist/config/types.d.ts +16 -0
  38. package/dist/config/types.d.ts.map +1 -1
  39. package/dist/config/types.js.map +1 -1
  40. package/dist/database/migrations/templates/localizeStatus.d.ts +10 -0
  41. package/dist/database/migrations/templates/localizeStatus.d.ts.map +1 -0
  42. package/dist/database/migrations/templates/localizeStatus.js +54 -0
  43. package/dist/database/migrations/templates/localizeStatus.js.map +1 -0
  44. package/dist/exports/migrations.d.ts +19 -0
  45. package/dist/exports/migrations.d.ts.map +1 -0
  46. package/dist/exports/migrations.js +19 -0
  47. package/dist/exports/migrations.js.map +1 -0
  48. package/dist/exports/shared.d.ts +1 -1
  49. package/dist/exports/shared.d.ts.map +1 -1
  50. package/dist/exports/shared.js +1 -1
  51. package/dist/exports/shared.js.map +1 -1
  52. package/dist/globals/config/sanitize.d.ts.map +1 -1
  53. package/dist/globals/config/sanitize.js +11 -1
  54. package/dist/globals/config/sanitize.js.map +1 -1
  55. package/dist/globals/endpoints/update.d.ts.map +1 -1
  56. package/dist/globals/endpoints/update.js +5 -1
  57. package/dist/globals/endpoints/update.js.map +1 -1
  58. package/dist/globals/operations/local/update.d.ts +10 -0
  59. package/dist/globals/operations/local/update.d.ts.map +1 -1
  60. package/dist/globals/operations/local/update.js +4 -2
  61. package/dist/globals/operations/local/update.js.map +1 -1
  62. package/dist/globals/operations/update.d.ts +2 -0
  63. package/dist/globals/operations/update.d.ts.map +1 -1
  64. package/dist/globals/operations/update.js +63 -15
  65. package/dist/globals/operations/update.js.map +1 -1
  66. package/dist/index.bundled.d.ts +102 -3
  67. package/dist/index.d.ts +2 -0
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +1 -0
  70. package/dist/index.js.map +1 -1
  71. package/dist/utilities/getVersionsConfig.d.ts +4 -0
  72. package/dist/utilities/getVersionsConfig.d.ts.map +1 -1
  73. package/dist/utilities/getVersionsConfig.js +7 -2
  74. package/dist/utilities/getVersionsConfig.js.map +1 -1
  75. package/dist/utilities/mergeLocalizedData.d.ts +20 -0
  76. package/dist/utilities/mergeLocalizedData.d.ts.map +1 -0
  77. package/dist/utilities/mergeLocalizedData.js +277 -0
  78. package/dist/utilities/mergeLocalizedData.js.map +1 -0
  79. package/dist/utilities/mergeLocalizedData.spec.js +784 -0
  80. package/dist/utilities/mergeLocalizedData.spec.js.map +1 -0
  81. package/dist/utilities/miniChalk.d.ts +15 -0
  82. package/dist/utilities/miniChalk.d.ts.map +1 -0
  83. package/dist/utilities/miniChalk.js +34 -0
  84. package/dist/utilities/miniChalk.js.map +1 -0
  85. package/dist/utilities/parseParams/index.d.ts +24 -20
  86. package/dist/utilities/parseParams/index.d.ts.map +1 -1
  87. package/dist/utilities/parseParams/index.js.map +1 -1
  88. package/dist/utilities/traverseForLocalizedFields.d.ts +3 -0
  89. package/dist/utilities/traverseForLocalizedFields.d.ts.map +1 -0
  90. package/dist/utilities/traverseForLocalizedFields.js +41 -0
  91. package/dist/utilities/traverseForLocalizedFields.js.map +1 -0
  92. package/dist/versions/baseFields.d.ts +3 -1
  93. package/dist/versions/baseFields.d.ts.map +1 -1
  94. package/dist/versions/baseFields.js +16 -15
  95. package/dist/versions/baseFields.js.map +1 -1
  96. package/dist/versions/drafts/replaceWithDraftIfAvailable.d.ts.map +1 -1
  97. package/dist/versions/drafts/replaceWithDraftIfAvailable.js +28 -2
  98. package/dist/versions/drafts/replaceWithDraftIfAvailable.js.map +1 -1
  99. package/dist/versions/migrations/localizeStatus/index.d.ts +12 -0
  100. package/dist/versions/migrations/localizeStatus/index.d.ts.map +1 -0
  101. package/dist/versions/migrations/localizeStatus/index.js +33 -0
  102. package/dist/versions/migrations/localizeStatus/index.js.map +1 -0
  103. package/dist/versions/migrations/localizeStatus/mongo/down.d.ts +9 -0
  104. package/dist/versions/migrations/localizeStatus/mongo/down.d.ts.map +1 -0
  105. package/dist/versions/migrations/localizeStatus/mongo/down.js +112 -0
  106. package/dist/versions/migrations/localizeStatus/mongo/down.js.map +1 -0
  107. package/dist/versions/migrations/localizeStatus/mongo/index.d.ts +8 -0
  108. package/dist/versions/migrations/localizeStatus/mongo/index.d.ts.map +1 -0
  109. package/dist/versions/migrations/localizeStatus/mongo/index.js +8 -0
  110. package/dist/versions/migrations/localizeStatus/mongo/index.js.map +1 -0
  111. package/dist/versions/migrations/localizeStatus/mongo/up.d.ts +9 -0
  112. package/dist/versions/migrations/localizeStatus/mongo/up.d.ts.map +1 -0
  113. package/dist/versions/migrations/localizeStatus/mongo/up.js +220 -0
  114. package/dist/versions/migrations/localizeStatus/mongo/up.js.map +1 -0
  115. package/dist/versions/migrations/localizeStatus/shared.d.ts +59 -0
  116. package/dist/versions/migrations/localizeStatus/shared.d.ts.map +1 -0
  117. package/dist/versions/migrations/localizeStatus/shared.js +122 -0
  118. package/dist/versions/migrations/localizeStatus/shared.js.map +1 -0
  119. package/dist/versions/migrations/localizeStatus/sql/down.d.ts +11 -0
  120. package/dist/versions/migrations/localizeStatus/sql/down.d.ts.map +1 -0
  121. package/dist/versions/migrations/localizeStatus/sql/down.js +213 -0
  122. package/dist/versions/migrations/localizeStatus/sql/down.js.map +1 -0
  123. package/dist/versions/migrations/localizeStatus/sql/index.d.ts +8 -0
  124. package/dist/versions/migrations/localizeStatus/sql/index.d.ts.map +1 -0
  125. package/dist/versions/migrations/localizeStatus/sql/index.js +8 -0
  126. package/dist/versions/migrations/localizeStatus/sql/index.js.map +1 -0
  127. package/dist/versions/migrations/localizeStatus/sql/migrateMainCollection.d.ts +13 -0
  128. package/dist/versions/migrations/localizeStatus/sql/migrateMainCollection.d.ts.map +1 -0
  129. package/dist/versions/migrations/localizeStatus/sql/migrateMainCollection.js +51 -0
  130. package/dist/versions/migrations/localizeStatus/sql/migrateMainCollection.js.map +1 -0
  131. package/dist/versions/migrations/localizeStatus/sql/migrateMainGlobal.d.ts +13 -0
  132. package/dist/versions/migrations/localizeStatus/sql/migrateMainGlobal.d.ts.map +1 -0
  133. package/dist/versions/migrations/localizeStatus/sql/migrateMainGlobal.js +54 -0
  134. package/dist/versions/migrations/localizeStatus/sql/migrateMainGlobal.js.map +1 -0
  135. package/dist/versions/migrations/localizeStatus/sql/up.d.ts +11 -0
  136. package/dist/versions/migrations/localizeStatus/sql/up.d.ts.map +1 -0
  137. package/dist/versions/migrations/localizeStatus/sql/up.js +277 -0
  138. package/dist/versions/migrations/localizeStatus/sql/up.js.map +1 -0
  139. package/dist/versions/saveSnapshot.d.ts.map +1 -1
  140. package/dist/versions/saveSnapshot.js +0 -1
  141. package/dist/versions/saveSnapshot.js.map +1 -1
  142. package/dist/versions/saveVersion.js +0 -3
  143. package/dist/versions/saveVersion.js.map +1 -1
  144. package/dist/versions/types.d.ts +18 -0
  145. package/dist/versions/types.d.ts.map +1 -1
  146. package/dist/versions/types.js.map +1 -1
  147. package/package.json +7 -2
  148. package/dist/uploads/imageResizer.d.ts +0 -40
  149. package/dist/uploads/imageResizer.d.ts.map +0 -1
  150. package/dist/uploads/imageResizer.js +0 -356
  151. package/dist/uploads/imageResizer.js.map +0 -1
@@ -0,0 +1,112 @@
1
+ import { hasLocalizeStatusEnabled } from '../../../../utilities/getVersionsConfig.js';
2
+ export async function down(args) {
3
+ const { collectionSlug, globalSlug, payload } = args;
4
+ if (!collectionSlug && !globalSlug) {
5
+ throw new Error('Either collectionSlug or globalSlug must be provided');
6
+ }
7
+ if (collectionSlug && globalSlug) {
8
+ throw new Error('Cannot provide both collectionSlug and globalSlug');
9
+ }
10
+ const entitySlug = collectionSlug || globalSlug;
11
+ // MongoDB collection names are case-insensitive and stored as lowercase
12
+ const versionsCollection = `_${entitySlug}_versions`.toLowerCase();
13
+ if (!payload.config.localization) {
14
+ throw new Error('Localization is not enabled in payload config');
15
+ }
16
+ const entityConfig = collectionSlug ? payload.config.collections.find((c)=>c.slug === collectionSlug) : payload.config.globals.find((g)=>g.slug === globalSlug);
17
+ if (!entityConfig) {
18
+ throw new Error(`${collectionSlug ? 'Collection' : 'Global'} not found: ${collectionSlug || globalSlug}`);
19
+ }
20
+ if (hasLocalizeStatusEnabled(entityConfig)) {
21
+ throw new Error(`${entitySlug} has localizeStatus enabled, cannot run down migration. ` + `Please disable localizeStatus in your config before rolling back this migration.`);
22
+ }
23
+ const defaultLocale = payload.config.localization.defaultLocale;
24
+ payload.logger.info({
25
+ msg: `Rolling back _status localization migration for ${collectionSlug ? 'collection' : 'global'}: ${entitySlug}`
26
+ });
27
+ // Get MongoDB connection
28
+ const connection = payload.db.connection;
29
+ payload.logger.info({
30
+ msg: 'Fetching all version documents...'
31
+ });
32
+ // Get all versions
33
+ const allVersions = await connection.collection(versionsCollection).find({}).toArray();
34
+ payload.logger.info({
35
+ msg: `Found ${allVersions.length} version documents`
36
+ });
37
+ // Update each version document: convert version._status from object to string
38
+ let updateCount = 0;
39
+ for (const doc of allVersions){
40
+ const currentStatus = doc.version?._status;
41
+ if (!currentStatus || typeof currentStatus === 'string') {
42
+ continue;
43
+ }
44
+ // Convert from { en: 'published', es: 'draft' } to 'published' (using default locale)
45
+ const statusValue = typeof currentStatus === 'object' ? currentStatus[defaultLocale] || 'draft' : 'draft';
46
+ await connection.collection(versionsCollection).updateOne({
47
+ _id: doc._id
48
+ }, {
49
+ $set: {
50
+ 'version._status': statusValue
51
+ }
52
+ });
53
+ updateCount++;
54
+ }
55
+ payload.logger.info({
56
+ msg: `Updated ${updateCount} version documents`
57
+ });
58
+ // Rollback main collection/global document status
59
+ if (collectionSlug) {
60
+ const mainCollection = collectionSlug;
61
+ const mainDoc = await connection.collection(mainCollection).findOne({});
62
+ if (mainDoc && '_status' in mainDoc && typeof mainDoc._status === 'object') {
63
+ payload.logger.info({
64
+ msg: `Rolling back main collection documents for: ${mainCollection}`
65
+ });
66
+ const allDocs = await connection.collection(mainCollection).find({}).toArray();
67
+ for (const doc of allDocs){
68
+ if (typeof doc._status === 'object' && !Array.isArray(doc._status)) {
69
+ // Convert from { en: 'published', es: 'draft' } to 'published' (using default locale)
70
+ const statusValue = doc._status[defaultLocale] || 'draft';
71
+ await connection.collection(mainCollection).updateOne({
72
+ _id: doc._id
73
+ }, {
74
+ $set: {
75
+ _status: statusValue
76
+ }
77
+ });
78
+ }
79
+ }
80
+ payload.logger.info({
81
+ msg: `Rolled back ${allDocs.length} collection documents`
82
+ });
83
+ }
84
+ } else if (globalSlug) {
85
+ const globalDoc = await connection.collection('globals').findOne({
86
+ globalType: globalSlug
87
+ });
88
+ if (globalDoc && '_status' in globalDoc && typeof globalDoc.status === 'object') {
89
+ payload.logger.info({
90
+ msg: `Rolling back main global document for: ${globalSlug}`
91
+ });
92
+ // Convert from { en: 'published', es: 'draft' } to 'published' (using default locale)
93
+ const statusValue = typeof globalDoc._status === 'object' && !Array.isArray(globalDoc._status) ? globalDoc._status[defaultLocale] || 'draft' : 'draft';
94
+ await connection.collection('globals').updateOne({
95
+ _id: globalDoc._id,
96
+ globalType: globalSlug
97
+ }, {
98
+ $set: {
99
+ _status: statusValue
100
+ }
101
+ });
102
+ payload.logger.info({
103
+ msg: 'Rolled back global document'
104
+ });
105
+ }
106
+ }
107
+ payload.logger.info({
108
+ msg: 'Rollback completed successfully'
109
+ });
110
+ }
111
+
112
+ //# sourceMappingURL=down.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/versions/migrations/localizeStatus/mongo/down.ts"],"sourcesContent":["import type { Payload } from '../../../../types/index.js'\n\nimport { hasLocalizeStatusEnabled } from '../../../../utilities/getVersionsConfig.js'\n\nexport type LocalizeStatusArgs = {\n collectionSlug?: string\n globalSlug?: string\n payload: Payload\n req?: any\n}\n\nexport async function down(args: LocalizeStatusArgs): Promise<void> {\n const { collectionSlug, globalSlug, payload } = args\n\n if (!collectionSlug && !globalSlug) {\n throw new Error('Either collectionSlug or globalSlug must be provided')\n }\n\n if (collectionSlug && globalSlug) {\n throw new Error('Cannot provide both collectionSlug and globalSlug')\n }\n\n const entitySlug = collectionSlug || globalSlug\n // MongoDB collection names are case-insensitive and stored as lowercase\n const versionsCollection = `_${entitySlug}_versions`.toLowerCase()\n\n if (!payload.config.localization) {\n throw new Error('Localization is not enabled in payload config')\n }\n\n const entityConfig = collectionSlug\n ? payload.config.collections.find((c) => c.slug === collectionSlug)\n : payload.config.globals.find((g) => g.slug === globalSlug!)\n\n if (!entityConfig) {\n throw new Error(\n `${collectionSlug ? 'Collection' : 'Global'} not found: ${collectionSlug || globalSlug}`,\n )\n }\n\n if (hasLocalizeStatusEnabled(entityConfig)) {\n throw new Error(\n `${entitySlug} has localizeStatus enabled, cannot run down migration. ` +\n `Please disable localizeStatus in your config before rolling back this migration.`,\n )\n }\n\n const defaultLocale = payload.config.localization.defaultLocale\n\n payload.logger.info({\n msg: `Rolling back _status localization migration for ${collectionSlug ? 'collection' : 'global'}: ${entitySlug}`,\n })\n\n // Get MongoDB connection\n const connection = (payload.db as any).connection\n\n payload.logger.info({ msg: 'Fetching all version documents...' })\n\n // Get all versions\n const allVersions = await connection.collection(versionsCollection).find({}).toArray()\n\n payload.logger.info({ msg: `Found ${allVersions.length} version documents` })\n\n // Update each version document: convert version._status from object to string\n let updateCount = 0\n for (const doc of allVersions) {\n const currentStatus = doc.version?._status\n\n if (!currentStatus || typeof currentStatus === 'string') {\n // Already rolled back or never migrated\n continue\n }\n\n // Convert from { en: 'published', es: 'draft' } to 'published' (using default locale)\n const statusValue =\n typeof currentStatus === 'object' ? currentStatus[defaultLocale] || 'draft' : 'draft'\n\n await connection.collection(versionsCollection).updateOne(\n { _id: doc._id },\n {\n $set: {\n 'version._status': statusValue,\n },\n },\n )\n\n updateCount++\n }\n\n payload.logger.info({ msg: `Updated ${updateCount} version documents` })\n\n // Rollback main collection/global document status\n if (collectionSlug) {\n const mainCollection = collectionSlug\n const mainDoc = await connection.collection(mainCollection).findOne({})\n\n if (mainDoc && '_status' in mainDoc && typeof mainDoc._status === 'object') {\n payload.logger.info({ msg: `Rolling back main collection documents for: ${mainCollection}` })\n\n const allDocs = await connection.collection(mainCollection).find({}).toArray()\n\n for (const doc of allDocs) {\n if (typeof doc._status === 'object' && !Array.isArray(doc._status)) {\n // Convert from { en: 'published', es: 'draft' } to 'published' (using default locale)\n const statusValue = doc._status[defaultLocale] || 'draft'\n\n await connection.collection(mainCollection).updateOne(\n { _id: doc._id },\n {\n $set: {\n _status: statusValue,\n },\n },\n )\n }\n }\n\n payload.logger.info({ msg: `Rolled back ${allDocs.length} collection documents` })\n }\n } else if (globalSlug) {\n const globalDoc = await connection.collection('globals').findOne({ globalType: globalSlug })\n\n if (globalDoc && '_status' in globalDoc && typeof globalDoc.status === 'object') {\n payload.logger.info({ msg: `Rolling back main global document for: ${globalSlug}` })\n\n // Convert from { en: 'published', es: 'draft' } to 'published' (using default locale)\n const statusValue =\n typeof globalDoc._status === 'object' && !Array.isArray(globalDoc._status)\n ? globalDoc._status[defaultLocale] || 'draft'\n : 'draft'\n\n await connection.collection('globals').updateOne(\n { _id: globalDoc._id, globalType: globalSlug },\n {\n $set: {\n _status: statusValue,\n },\n },\n )\n\n payload.logger.info({ msg: 'Rolled back global document' })\n }\n }\n\n payload.logger.info({ msg: 'Rollback completed successfully' })\n}\n"],"names":["hasLocalizeStatusEnabled","down","args","collectionSlug","globalSlug","payload","Error","entitySlug","versionsCollection","toLowerCase","config","localization","entityConfig","collections","find","c","slug","globals","g","defaultLocale","logger","info","msg","connection","db","allVersions","collection","toArray","length","updateCount","doc","currentStatus","version","_status","statusValue","updateOne","_id","$set","mainCollection","mainDoc","findOne","allDocs","Array","isArray","globalDoc","globalType","status"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { down } from './down.js';
2
+ import { up } from './up.js';
3
+ export declare const localizeStatus: {
4
+ down: typeof down;
5
+ up: typeof up;
6
+ };
7
+ export type { LocalizeStatusArgs } from './up.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/versions/migrations/localizeStatus/mongo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAE5B,eAAO,MAAM,cAAc;;;CAG1B,CAAA;AAED,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { down } from './down.js';
2
+ import { up } from './up.js';
3
+ export const localizeStatus = {
4
+ down,
5
+ up
6
+ };
7
+
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/versions/migrations/localizeStatus/mongo/index.ts"],"sourcesContent":["import { down } from './down.js'\nimport { up } from './up.js'\n\nexport const localizeStatus = {\n down,\n up,\n}\n\nexport type { LocalizeStatusArgs } from './up.js'\n"],"names":["down","up","localizeStatus"],"mappings":"AAAA,SAASA,IAAI,QAAQ,YAAW;AAChC,SAASC,EAAE,QAAQ,UAAS;AAE5B,OAAO,MAAMC,iBAAiB;IAC5BF;IACAC;AACF,EAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Payload } from '../../../../types/index.js';
2
+ export type LocalizeStatusArgs = {
3
+ collectionSlug?: string;
4
+ globalSlug?: string;
5
+ payload: Payload;
6
+ req?: any;
7
+ };
8
+ export declare function up(args: LocalizeStatusArgs): Promise<void>;
9
+ //# sourceMappingURL=up.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"up.d.ts","sourceRoot":"","sources":["../../../../../src/versions/migrations/localizeStatus/mongo/up.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AAIzD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,CAAC,EAAE,GAAG,CAAA;CACV,CAAA;AAED,wBAAsB,EAAE,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2PhE"}
@@ -0,0 +1,220 @@
1
+ import { calculateVersionLocaleStatuses } from '../shared.js';
2
+ export async function up(args) {
3
+ const { collectionSlug, globalSlug, payload, req } = args;
4
+ if (!collectionSlug && !globalSlug) {
5
+ throw new Error('Either collectionSlug or globalSlug must be provided');
6
+ }
7
+ if (collectionSlug && globalSlug) {
8
+ throw new Error('Cannot provide both collectionSlug and globalSlug');
9
+ }
10
+ const entitySlug = collectionSlug || globalSlug;
11
+ // MongoDB collection names are case-insensitive and stored as lowercase
12
+ const versionsCollection = `_${entitySlug}_versions`.toLowerCase();
13
+ if (!payload.config.localization) {
14
+ throw new Error('Localization is not enabled in payload config');
15
+ }
16
+ // Check if versions are enabled on this collection/global
17
+ let entityConfig;
18
+ if (collectionSlug) {
19
+ const collection = payload.config.collections.find((c)=>c.slug === collectionSlug);
20
+ if (collection) {
21
+ entityConfig = collection;
22
+ }
23
+ } else if (globalSlug) {
24
+ const global = payload.config.globals.find((g)=>g.slug === globalSlug);
25
+ if (global) {
26
+ entityConfig = global;
27
+ }
28
+ }
29
+ if (!entityConfig) {
30
+ throw new Error(`${collectionSlug ? 'Collection' : 'Global'} not found: ${collectionSlug || globalSlug}`);
31
+ }
32
+ payload.logger.info({
33
+ msg: `Starting _status localization migration for ${collectionSlug ? 'collection' : 'global'}: ${entitySlug}`
34
+ });
35
+ // Check if versions are enabled in config (skip if not)
36
+ if (!entityConfig.versions) {
37
+ payload.logger.info({
38
+ msg: `Skipping migration for ${collectionSlug ? 'collection' : 'global'}: ${entitySlug} - versions not enabled`
39
+ });
40
+ return;
41
+ }
42
+ // Get MongoDB connection
43
+ const connection = payload.db.connection;
44
+ // Get filtered locales if filterAvailableLocales is defined
45
+ let locales = payload.config.localization.localeCodes;
46
+ if (typeof payload.config.localization.filterAvailableLocales === 'function') {
47
+ const filteredLocaleObjects = await payload.config.localization.filterAvailableLocales({
48
+ locales: payload.config.localization.locales,
49
+ req
50
+ });
51
+ locales = filteredLocaleObjects.map((locale)=>locale.code);
52
+ }
53
+ payload.logger.info({
54
+ msg: `Locales: ${locales.join(', ')}`
55
+ });
56
+ // Check if version._status exists and is NOT already localized
57
+ const sampleDoc = await connection.collection(versionsCollection).findOne({});
58
+ if (!sampleDoc) {
59
+ payload.logger.info({
60
+ msg: 'No version documents found, nothing to migrate'
61
+ });
62
+ return;
63
+ }
64
+ // Check if _status is already localized
65
+ if (sampleDoc.version?._status && typeof sampleDoc.version._status === 'object' && !Array.isArray(sampleDoc.version._status)) {
66
+ payload.logger.info({
67
+ msg: 'version._status is already localized, migration already completed'
68
+ });
69
+ return;
70
+ }
71
+ // Validate that version._status exists and is a string
72
+ if (!sampleDoc.version || typeof sampleDoc.version._status !== 'string' || Array.isArray(sampleDoc.version._status)) {
73
+ throw new Error(`Migration aborted: version._status field not found or has unexpected format in ${versionsCollection}. ` + `This migration should only run on schemas that have NOT yet been migrated to per-locale status.`);
74
+ }
75
+ payload.logger.info({
76
+ msg: 'Fetching all version documents...'
77
+ });
78
+ // Get all versions, sorted chronologically
79
+ const allVersions = await connection.collection(versionsCollection).find({}).sort({
80
+ createdAt: 1,
81
+ parent: 1
82
+ }).toArray();
83
+ payload.logger.info({
84
+ msg: `Found ${allVersions.length} version documents`
85
+ });
86
+ // Transform MongoDB documents to VersionRecord format
87
+ const versionRecords = allVersions.map((doc)=>({
88
+ id: doc._id.toString(),
89
+ _status: doc.version._status,
90
+ createdAt: doc.createdAt,
91
+ parent: doc.parent?.toString(),
92
+ publishedLocale: doc.publishedLocale,
93
+ snapshot: doc.snapshot || false
94
+ }));
95
+ // Calculate status per locale using shared logic
96
+ const versionLocaleStatus = calculateVersionLocaleStatuses(versionRecords, locales, payload);
97
+ payload.logger.info({
98
+ msg: 'Updating version documents with per-locale status...'
99
+ });
100
+ // Update each version document
101
+ let updateCount = 0;
102
+ for (const doc of allVersions){
103
+ const versionId = doc._id.toString();
104
+ const localeStatusMap = versionLocaleStatus.get(versionId);
105
+ if (!localeStatusMap) {
106
+ payload.logger.warn({
107
+ msg: `No status map found for version ${versionId}, skipping`
108
+ });
109
+ continue;
110
+ }
111
+ // Build the new _status object: { en: 'published', es: 'draft', ... }
112
+ const newStatus = {};
113
+ for (const [locale, status] of localeStatusMap.entries()){
114
+ newStatus[locale] = status;
115
+ }
116
+ // Update the document: change version._status from string to object
117
+ await connection.collection(versionsCollection).updateOne({
118
+ _id: doc._id
119
+ }, {
120
+ $set: {
121
+ 'version._status': newStatus
122
+ }
123
+ });
124
+ updateCount++;
125
+ }
126
+ payload.logger.info({
127
+ msg: `Updated ${updateCount} version documents`
128
+ });
129
+ // Migrate main collection/global document _status to per-locale status object
130
+ // Only if it has a status field
131
+ if (collectionSlug) {
132
+ const mainCollection = collectionSlug;
133
+ const mainDoc = await connection.collection(mainCollection).findOne({});
134
+ if (mainDoc && '_status' in mainDoc) {
135
+ payload.logger.info({
136
+ msg: `Migrating main collection documents for: ${mainCollection}`
137
+ });
138
+ const allDocs = await connection.collection(mainCollection).find({}).toArray();
139
+ for (const doc of allDocs){
140
+ if (!doc._id) {
141
+ continue;
142
+ }
143
+ // Get the latest version for this document to determine status per locale
144
+ const latestVersions = await connection.collection(versionsCollection).find({
145
+ parent: doc._id
146
+ }).sort({
147
+ createdAt: -1
148
+ }).limit(1).toArray();
149
+ let statusObj = {};
150
+ if (latestVersions.length > 0 && latestVersions[0]?.version?._status) {
151
+ // Use the status from the latest version
152
+ statusObj = latestVersions[0].version._status;
153
+ } else {
154
+ // Fallback: set all locales to draft
155
+ for (const locale of locales){
156
+ statusObj[locale] = 'draft';
157
+ }
158
+ }
159
+ // Update main document
160
+ await connection.collection(mainCollection).updateOne({
161
+ _id: doc._id
162
+ }, {
163
+ $set: {
164
+ _status: statusObj
165
+ }
166
+ });
167
+ }
168
+ payload.logger.info({
169
+ msg: `Migrated ${allDocs.length} collection documents`
170
+ });
171
+ } else {
172
+ payload.logger.info({
173
+ msg: 'Skipping main document status migration (no status field found)'
174
+ });
175
+ }
176
+ } else if (globalSlug) {
177
+ // Globals are stored in a single 'globals' collection with globalType discriminator
178
+ const globalDoc = await connection.collection('globals').findOne({
179
+ globalType: globalSlug
180
+ });
181
+ if (globalDoc && '_status' in globalDoc && globalDoc._id) {
182
+ payload.logger.info({
183
+ msg: `Migrating main global document for: ${globalSlug}`
184
+ });
185
+ // Get the latest version for the global
186
+ const latestVersions = await connection.collection(versionsCollection).find({}).sort({
187
+ createdAt: -1
188
+ }).limit(1).toArray();
189
+ let statusObj = {};
190
+ if (latestVersions.length > 0 && latestVersions[0]?.version?._status) {
191
+ statusObj = latestVersions[0].version._status;
192
+ } else {
193
+ for (const locale of locales){
194
+ statusObj[locale] = 'draft';
195
+ }
196
+ }
197
+ // Update global document
198
+ await connection.collection('globals').updateOne({
199
+ _id: globalDoc._id,
200
+ globalType: globalSlug
201
+ }, {
202
+ $set: {
203
+ _status: statusObj
204
+ }
205
+ });
206
+ payload.logger.info({
207
+ msg: 'Migrated global document'
208
+ });
209
+ } else {
210
+ payload.logger.info({
211
+ msg: 'Skipping main document status migration (no status field found)'
212
+ });
213
+ }
214
+ }
215
+ payload.logger.info({
216
+ msg: 'Migration completed successfully'
217
+ });
218
+ }
219
+
220
+ //# sourceMappingURL=up.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/versions/migrations/localizeStatus/mongo/up.ts"],"sourcesContent":["import type { Payload } from '../../../../types/index.js'\n\nimport { calculateVersionLocaleStatuses, type VersionRecord } from '../shared.js'\n\nexport type LocalizeStatusArgs = {\n collectionSlug?: string\n globalSlug?: string\n payload: Payload\n req?: any\n}\n\nexport async function up(args: LocalizeStatusArgs): Promise<void> {\n const { collectionSlug, globalSlug, payload, req } = args\n\n if (!collectionSlug && !globalSlug) {\n throw new Error('Either collectionSlug or globalSlug must be provided')\n }\n\n if (collectionSlug && globalSlug) {\n throw new Error('Cannot provide both collectionSlug and globalSlug')\n }\n\n const entitySlug = collectionSlug || globalSlug\n // MongoDB collection names are case-insensitive and stored as lowercase\n const versionsCollection = `_${entitySlug}_versions`.toLowerCase()\n\n if (!payload.config.localization) {\n throw new Error('Localization is not enabled in payload config')\n }\n\n // Check if versions are enabled on this collection/global\n let entityConfig\n if (collectionSlug) {\n const collection = payload.config.collections.find((c) => c.slug === collectionSlug)\n if (collection) {\n entityConfig = collection\n }\n } else if (globalSlug) {\n const global = payload.config.globals.find((g) => g.slug === globalSlug)\n if (global) {\n entityConfig = global\n }\n }\n\n if (!entityConfig) {\n throw new Error(\n `${collectionSlug ? 'Collection' : 'Global'} not found: ${collectionSlug || globalSlug}`,\n )\n }\n\n payload.logger.info({\n msg: `Starting _status localization migration for ${collectionSlug ? 'collection' : 'global'}: ${entitySlug}`,\n })\n\n // Check if versions are enabled in config (skip if not)\n if (!entityConfig.versions) {\n payload.logger.info({\n msg: `Skipping migration for ${collectionSlug ? 'collection' : 'global'}: ${entitySlug} - versions not enabled`,\n })\n return\n }\n\n // Get MongoDB connection\n const connection = (payload.db as any).connection\n\n // Get filtered locales if filterAvailableLocales is defined\n let locales = payload.config.localization.localeCodes\n if (typeof payload.config.localization.filterAvailableLocales === 'function') {\n const filteredLocaleObjects = await payload.config.localization.filterAvailableLocales({\n locales: payload.config.localization.locales,\n req,\n })\n locales = filteredLocaleObjects.map((locale) => locale.code)\n }\n payload.logger.info({ msg: `Locales: ${locales.join(', ')}` })\n\n // Check if version._status exists and is NOT already localized\n const sampleDoc = await connection.collection(versionsCollection).findOne({})\n\n if (!sampleDoc) {\n payload.logger.info({ msg: 'No version documents found, nothing to migrate' })\n return\n }\n\n // Check if _status is already localized\n if (\n sampleDoc.version?._status &&\n typeof sampleDoc.version._status === 'object' &&\n !Array.isArray(sampleDoc.version._status)\n ) {\n payload.logger.info({\n msg: 'version._status is already localized, migration already completed',\n })\n return\n }\n\n // Validate that version._status exists and is a string\n if (\n !sampleDoc.version ||\n typeof sampleDoc.version._status !== 'string' ||\n Array.isArray(sampleDoc.version._status)\n ) {\n throw new Error(\n `Migration aborted: version._status field not found or has unexpected format in ${versionsCollection}. ` +\n `This migration should only run on schemas that have NOT yet been migrated to per-locale status.`,\n )\n }\n\n payload.logger.info({ msg: 'Fetching all version documents...' })\n\n // Get all versions, sorted chronologically\n const allVersions = await connection\n .collection(versionsCollection)\n .find({})\n .sort({ createdAt: 1, parent: 1 })\n .toArray()\n\n payload.logger.info({ msg: `Found ${allVersions.length} version documents` })\n\n // Transform MongoDB documents to VersionRecord format\n const versionRecords: VersionRecord[] = allVersions.map((doc: any) => ({\n id: doc._id.toString(),\n _status: doc.version._status as 'draft' | 'published',\n createdAt: doc.createdAt,\n parent: doc.parent?.toString(),\n publishedLocale: doc.publishedLocale,\n snapshot: doc.snapshot || false,\n }))\n\n // Calculate status per locale using shared logic\n const versionLocaleStatus = calculateVersionLocaleStatuses(versionRecords, locales, payload)\n\n payload.logger.info({ msg: 'Updating version documents with per-locale status...' })\n\n // Update each version document\n let updateCount = 0\n for (const doc of allVersions) {\n const versionId = doc._id.toString()\n const localeStatusMap = versionLocaleStatus.get(versionId)\n\n if (!localeStatusMap) {\n payload.logger.warn({ msg: `No status map found for version ${versionId}, skipping` })\n continue\n }\n\n // Build the new _status object: { en: 'published', es: 'draft', ... }\n const newStatus: Record<string, string> = {}\n for (const [locale, status] of localeStatusMap.entries()) {\n newStatus[locale] = status\n }\n\n // Update the document: change version._status from string to object\n await connection.collection(versionsCollection).updateOne(\n { _id: doc._id },\n {\n $set: {\n 'version._status': newStatus,\n },\n },\n )\n\n updateCount++\n }\n\n payload.logger.info({ msg: `Updated ${updateCount} version documents` })\n\n // Migrate main collection/global document _status to per-locale status object\n // Only if it has a status field\n if (collectionSlug) {\n const mainCollection = collectionSlug\n const mainDoc = await connection.collection(mainCollection).findOne({})\n\n if (mainDoc && '_status' in mainDoc) {\n payload.logger.info({ msg: `Migrating main collection documents for: ${mainCollection}` })\n\n const allDocs = await connection.collection(mainCollection).find({}).toArray()\n\n for (const doc of allDocs) {\n if (!doc._id) {\n continue\n }\n\n // Get the latest version for this document to determine status per locale\n const latestVersions = await connection\n .collection(versionsCollection)\n .find({ parent: doc._id })\n .sort({ createdAt: -1 })\n .limit(1)\n .toArray()\n\n let statusObj: Record<string, string> = {}\n\n if (latestVersions.length > 0 && latestVersions[0]?.version?._status) {\n // Use the status from the latest version\n statusObj = latestVersions[0].version._status\n } else {\n // Fallback: set all locales to draft\n for (const locale of locales) {\n statusObj[locale] = 'draft'\n }\n }\n\n // Update main document\n await connection.collection(mainCollection).updateOne(\n { _id: doc._id },\n {\n $set: {\n _status: statusObj,\n },\n },\n )\n }\n\n payload.logger.info({ msg: `Migrated ${allDocs.length} collection documents` })\n } else {\n payload.logger.info({\n msg: 'Skipping main document status migration (no status field found)',\n })\n }\n } else if (globalSlug) {\n // Globals are stored in a single 'globals' collection with globalType discriminator\n const globalDoc = await connection.collection('globals').findOne({ globalType: globalSlug })\n if (globalDoc && '_status' in globalDoc && globalDoc._id) {\n payload.logger.info({ msg: `Migrating main global document for: ${globalSlug}` })\n\n // Get the latest version for the global\n const latestVersions = await connection\n .collection(versionsCollection)\n .find({})\n .sort({ createdAt: -1 })\n .limit(1)\n .toArray()\n\n let statusObj: Record<string, string> = {}\n\n if (latestVersions.length > 0 && latestVersions[0]?.version?._status) {\n statusObj = latestVersions[0].version._status\n } else {\n for (const locale of locales) {\n statusObj[locale] = 'draft'\n }\n }\n\n // Update global document\n await connection.collection('globals').updateOne(\n { _id: globalDoc._id, globalType: globalSlug },\n {\n $set: {\n _status: statusObj,\n },\n },\n )\n\n payload.logger.info({ msg: 'Migrated global document' })\n } else {\n payload.logger.info({\n msg: 'Skipping main document status migration (no status field found)',\n })\n }\n }\n\n payload.logger.info({ msg: 'Migration completed successfully' })\n}\n"],"names":["calculateVersionLocaleStatuses","up","args","collectionSlug","globalSlug","payload","req","Error","entitySlug","versionsCollection","toLowerCase","config","localization","entityConfig","collection","collections","find","c","slug","global","globals","g","logger","info","msg","versions","connection","db","locales","localeCodes","filterAvailableLocales","filteredLocaleObjects","map","locale","code","join","sampleDoc","findOne","version","_status","Array","isArray","allVersions","sort","createdAt","parent","toArray","length","versionRecords","doc","id","_id","toString","publishedLocale","snapshot","versionLocaleStatus","updateCount","versionId","localeStatusMap","get","warn","newStatus","status","entries","updateOne","$set","mainCollection","mainDoc","allDocs","latestVersions","limit","statusObj","globalDoc","globalType"],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import type { Payload } from '../../../types/index.js';
2
+ /**
3
+ * Convert to snake_case (matches to-snake-case library behavior)
4
+ * Handles camelCase, PascalCase, and hyphens
5
+ */
6
+ export declare const toSnakeCase: (str: string) => string;
7
+ export type VersionRecord = {
8
+ _status: 'draft' | 'published';
9
+ created_at?: Date | string;
10
+ createdAt?: Date | string;
11
+ id: number | string;
12
+ parent: number | string;
13
+ published_locale?: string;
14
+ publishedLocale?: string;
15
+ snapshot?: boolean;
16
+ };
17
+ export type VersionLocaleStatusMap = Map<number | string, Map<string, 'draft' | 'published'>>;
18
+ /**
19
+ * Core logic for calculating the status of each locale for each version
20
+ * by processing version history chronologically.
21
+ *
22
+ * This works by:
23
+ * 1. Processing versions in chronological order (oldest first)
24
+ * 2. Tracking the cumulative published state for each document as we process versions
25
+ * 3. For each version, determining what status each locale should have based on:
26
+ * - Publish events with publishedLocale: mark that locale as published, version shows NEW state
27
+ * - Publish events without publishedLocale: mark all locales as published, version shows NEW state
28
+ * - Draft saves (_status='draft'): mark all locales as draft (unpublish everything)
29
+ * - Snapshots: preserve state AFTER publish (snapshots created after publishing specific locale)
30
+ *
31
+ * Snapshot creation flow when publishing one locale:
32
+ * 1. Merge incoming content with last published → update main table
33
+ * 2. Create snapshot object (preserves other locales' draft content + updates published locale)
34
+ * 3. Create publish version (_status='published', publishedLocale set)
35
+ * 4. Create snapshot version (_status='draft', snapshot=true)
36
+ * - Snapshot CONTENT is mixed (draft + published content)
37
+ * - Snapshot STATUS reflects which locales are actually published
38
+ *
39
+ * Example scenario:
40
+ * - V1: publish all locales (no snapshot) → state: {en: published, es: published, de: published}
41
+ * - V2: draft save → state: {en: draft, es: draft, de: draft}
42
+ * - V3: publish en only → state: {en: published, es: draft, de: draft}
43
+ * - V4: snapshot after publishing en → state: {en: published, es: draft, de: draft}
44
+ * - V5: publish all locales (no snapshot) → state: {en: published, es: published, de: published}
45
+ *
46
+ * @param versions - Array of version records (must be sorted by parent, then createdAt ASC)
47
+ * @param locales - Array of locale codes (e.g., ['en', 'es', 'pt'])
48
+ * @param payload - Payload instance for logging
49
+ * @returns Map of versionId -> Map of locale -> status
50
+ */
51
+ export declare function calculateVersionLocaleStatuses(versions: VersionRecord[], locales: string[], payload: Payload): VersionLocaleStatusMap;
52
+ /**
53
+ * Sorts version records by parent document, then by creation date (oldest first)
54
+ *
55
+ * @param versions - Array of version records
56
+ * @returns Sorted array of version records
57
+ */
58
+ export declare function sortVersionsChronologically(versions: VersionRecord[]): VersionRecord[];
59
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/versions/migrations/localizeStatus/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AAEtD;;;GAGG;AACH,eAAO,MAAM,WAAW,QAAS,MAAM,KAAG,MAMzC,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,OAAO,GAAG,WAAW,CAAA;IAC9B,UAAU,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;IAC1B,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;IACzB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,WAAW,CAAC,CAAC,CAAA;AAE7F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,aAAa,EAAE,EACzB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,OAAO,GACf,sBAAsB,CAoExB;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CActF"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Convert to snake_case (matches to-snake-case library behavior)
3
+ * Handles camelCase, PascalCase, and hyphens
4
+ */ export const toSnakeCase = (str)=>{
5
+ return str.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '').replace(/-/g, '_') // Convert hyphens to underscores
6
+ ;
7
+ };
8
+ /**
9
+ * Core logic for calculating the status of each locale for each version
10
+ * by processing version history chronologically.
11
+ *
12
+ * This works by:
13
+ * 1. Processing versions in chronological order (oldest first)
14
+ * 2. Tracking the cumulative published state for each document as we process versions
15
+ * 3. For each version, determining what status each locale should have based on:
16
+ * - Publish events with publishedLocale: mark that locale as published, version shows NEW state
17
+ * - Publish events without publishedLocale: mark all locales as published, version shows NEW state
18
+ * - Draft saves (_status='draft'): mark all locales as draft (unpublish everything)
19
+ * - Snapshots: preserve state AFTER publish (snapshots created after publishing specific locale)
20
+ *
21
+ * Snapshot creation flow when publishing one locale:
22
+ * 1. Merge incoming content with last published → update main table
23
+ * 2. Create snapshot object (preserves other locales' draft content + updates published locale)
24
+ * 3. Create publish version (_status='published', publishedLocale set)
25
+ * 4. Create snapshot version (_status='draft', snapshot=true)
26
+ * - Snapshot CONTENT is mixed (draft + published content)
27
+ * - Snapshot STATUS reflects which locales are actually published
28
+ *
29
+ * Example scenario:
30
+ * - V1: publish all locales (no snapshot) → state: {en: published, es: published, de: published}
31
+ * - V2: draft save → state: {en: draft, es: draft, de: draft}
32
+ * - V3: publish en only → state: {en: published, es: draft, de: draft}
33
+ * - V4: snapshot after publishing en → state: {en: published, es: draft, de: draft}
34
+ * - V5: publish all locales (no snapshot) → state: {en: published, es: published, de: published}
35
+ *
36
+ * @param versions - Array of version records (must be sorted by parent, then createdAt ASC)
37
+ * @param locales - Array of locale codes (e.g., ['en', 'es', 'pt'])
38
+ * @param payload - Payload instance for logging
39
+ * @returns Map of versionId -> Map of locale -> status
40
+ */ export function calculateVersionLocaleStatuses(versions, locales, payload) {
41
+ payload.logger.info({
42
+ msg: `Processing ${versions.length} version records`
43
+ });
44
+ // Track the cumulative published state for each document across all locales
45
+ // This represents what IS published at any given point in the version history
46
+ const documentPublishState = new Map();
47
+ // Map to store the final status for each version
48
+ const versionLocaleStatus = new Map();
49
+ // Process versions chronologically to build up status history
50
+ for (const version of versions){
51
+ const versionId = version.id;
52
+ const documentId = version.parent;
53
+ const status = version._status;
54
+ const publishedLocale = version.published_locale || version.publishedLocale;
55
+ const isSnapshot = version.snapshot === true;
56
+ // Initialize document state if first time seeing this document
57
+ if (!documentPublishState.has(documentId)) {
58
+ const localeMap = new Map();
59
+ for (const locale of locales){
60
+ localeMap.set(locale, 'draft');
61
+ }
62
+ documentPublishState.set(documentId, localeMap);
63
+ }
64
+ const currentPublishState = documentPublishState.get(documentId);
65
+ const versionStatusMap = new Map();
66
+ if (isSnapshot) {
67
+ // Snapshots are created AFTER publishing a specific locale
68
+ // Snapshot CONTENT is mixed: preserves other locales' draft content + new published locale content
69
+ // But snapshot STATUS should reflect publish state: which locales are published vs draft
70
+ // We use currentPublishState to track this, which has been updated by the previous publish
71
+ for (const [locale, publishedStatus] of currentPublishState.entries()){
72
+ versionStatusMap.set(locale, publishedStatus);
73
+ }
74
+ } else if (status === 'published') {
75
+ // This is a publish event
76
+ if (publishedLocale) {
77
+ // Publishing ONE locale - update the document's published state for that locale
78
+ currentPublishState.set(publishedLocale, 'published');
79
+ // This version should show the NEW state (after this publish)
80
+ for (const [locale, publishedStatus] of currentPublishState.entries()){
81
+ versionStatusMap.set(locale, publishedStatus);
82
+ }
83
+ } else {
84
+ // Publishing ALL locales - update all locales to published
85
+ for (const locale of locales){
86
+ currentPublishState.set(locale, 'published');
87
+ versionStatusMap.set(locale, 'published');
88
+ }
89
+ }
90
+ } else {
91
+ // This is a draft save - in the OLD system, _status='draft' meant unpublish ALL locales
92
+ for (const locale of locales){
93
+ currentPublishState.set(locale, 'draft');
94
+ versionStatusMap.set(locale, 'draft');
95
+ }
96
+ }
97
+ // Store the status for this version
98
+ versionLocaleStatus.set(versionId, versionStatusMap);
99
+ }
100
+ return versionLocaleStatus;
101
+ }
102
+ /**
103
+ * Sorts version records by parent document, then by creation date (oldest first)
104
+ *
105
+ * @param versions - Array of version records
106
+ * @returns Sorted array of version records
107
+ */ export function sortVersionsChronologically(versions) {
108
+ return versions.sort((a, b)=>{
109
+ // First sort by parent
110
+ const parentA = String(a.parent);
111
+ const parentB = String(b.parent);
112
+ if (parentA !== parentB) {
113
+ return parentA.localeCompare(parentB);
114
+ }
115
+ // Then sort by creation date
116
+ const dateA = new Date(a.created_at || a.createdAt || 0);
117
+ const dateB = new Date(b.created_at || b.createdAt || 0);
118
+ return dateA.getTime() - dateB.getTime();
119
+ });
120
+ }
121
+
122
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/versions/migrations/localizeStatus/shared.ts"],"sourcesContent":["import type { Payload } from '../../../types/index.js'\n\n/**\n * Convert to snake_case (matches to-snake-case library behavior)\n * Handles camelCase, PascalCase, and hyphens\n */\nexport const toSnakeCase = (str: string): string => {\n return str\n .replace(/([A-Z])/g, '_$1')\n .toLowerCase()\n .replace(/^_/, '')\n .replace(/-/g, '_') // Convert hyphens to underscores\n}\n\nexport type VersionRecord = {\n _status: 'draft' | 'published'\n created_at?: Date | string\n createdAt?: Date | string\n id: number | string\n parent: number | string\n published_locale?: string\n publishedLocale?: string\n snapshot?: boolean\n}\n\nexport type VersionLocaleStatusMap = Map<number | string, Map<string, 'draft' | 'published'>>\n\n/**\n * Core logic for calculating the status of each locale for each version\n * by processing version history chronologically.\n *\n * This works by:\n * 1. Processing versions in chronological order (oldest first)\n * 2. Tracking the cumulative published state for each document as we process versions\n * 3. For each version, determining what status each locale should have based on:\n * - Publish events with publishedLocale: mark that locale as published, version shows NEW state\n * - Publish events without publishedLocale: mark all locales as published, version shows NEW state\n * - Draft saves (_status='draft'): mark all locales as draft (unpublish everything)\n * - Snapshots: preserve state AFTER publish (snapshots created after publishing specific locale)\n *\n * Snapshot creation flow when publishing one locale:\n * 1. Merge incoming content with last published → update main table\n * 2. Create snapshot object (preserves other locales' draft content + updates published locale)\n * 3. Create publish version (_status='published', publishedLocale set)\n * 4. Create snapshot version (_status='draft', snapshot=true)\n * - Snapshot CONTENT is mixed (draft + published content)\n * - Snapshot STATUS reflects which locales are actually published\n *\n * Example scenario:\n * - V1: publish all locales (no snapshot) → state: {en: published, es: published, de: published}\n * - V2: draft save → state: {en: draft, es: draft, de: draft}\n * - V3: publish en only → state: {en: published, es: draft, de: draft}\n * - V4: snapshot after publishing en → state: {en: published, es: draft, de: draft}\n * - V5: publish all locales (no snapshot) → state: {en: published, es: published, de: published}\n *\n * @param versions - Array of version records (must be sorted by parent, then createdAt ASC)\n * @param locales - Array of locale codes (e.g., ['en', 'es', 'pt'])\n * @param payload - Payload instance for logging\n * @returns Map of versionId -> Map of locale -> status\n */\nexport function calculateVersionLocaleStatuses(\n versions: VersionRecord[],\n locales: string[],\n payload: Payload,\n): VersionLocaleStatusMap {\n payload.logger.info({ msg: `Processing ${versions.length} version records` })\n\n // Track the cumulative published state for each document across all locales\n // This represents what IS published at any given point in the version history\n const documentPublishState = new Map<number | string, Map<string, 'draft' | 'published'>>()\n\n // Map to store the final status for each version\n const versionLocaleStatus: VersionLocaleStatusMap = new Map()\n\n // Process versions chronologically to build up status history\n for (const version of versions) {\n const versionId = version.id\n const documentId = version.parent\n const status = version._status\n const publishedLocale = version.published_locale || version.publishedLocale\n const isSnapshot = version.snapshot === true\n\n // Initialize document state if first time seeing this document\n if (!documentPublishState.has(documentId)) {\n const localeMap = new Map<string, 'draft' | 'published'>()\n for (const locale of locales) {\n localeMap.set(locale, 'draft')\n }\n documentPublishState.set(documentId, localeMap)\n }\n\n const currentPublishState = documentPublishState.get(documentId)!\n const versionStatusMap = new Map<string, 'draft' | 'published'>()\n\n if (isSnapshot) {\n // Snapshots are created AFTER publishing a specific locale\n // Snapshot CONTENT is mixed: preserves other locales' draft content + new published locale content\n // But snapshot STATUS should reflect publish state: which locales are published vs draft\n // We use currentPublishState to track this, which has been updated by the previous publish\n for (const [locale, publishedStatus] of currentPublishState.entries()) {\n versionStatusMap.set(locale, publishedStatus)\n }\n } else if (status === 'published') {\n // This is a publish event\n if (publishedLocale) {\n // Publishing ONE locale - update the document's published state for that locale\n currentPublishState.set(publishedLocale, 'published')\n\n // This version should show the NEW state (after this publish)\n for (const [locale, publishedStatus] of currentPublishState.entries()) {\n versionStatusMap.set(locale, publishedStatus)\n }\n } else {\n // Publishing ALL locales - update all locales to published\n for (const locale of locales) {\n currentPublishState.set(locale, 'published')\n versionStatusMap.set(locale, 'published')\n }\n }\n } else {\n // This is a draft save - in the OLD system, _status='draft' meant unpublish ALL locales\n for (const locale of locales) {\n currentPublishState.set(locale, 'draft')\n versionStatusMap.set(locale, 'draft')\n }\n }\n\n // Store the status for this version\n versionLocaleStatus.set(versionId, versionStatusMap)\n }\n\n return versionLocaleStatus\n}\n\n/**\n * Sorts version records by parent document, then by creation date (oldest first)\n *\n * @param versions - Array of version records\n * @returns Sorted array of version records\n */\nexport function sortVersionsChronologically(versions: VersionRecord[]): VersionRecord[] {\n return versions.sort((a, b) => {\n // First sort by parent\n const parentA = String(a.parent)\n const parentB = String(b.parent)\n if (parentA !== parentB) {\n return parentA.localeCompare(parentB)\n }\n\n // Then sort by creation date\n const dateA = new Date(a.created_at || a.createdAt || 0)\n const dateB = new Date(b.created_at || b.createdAt || 0)\n return dateA.getTime() - dateB.getTime()\n })\n}\n"],"names":["toSnakeCase","str","replace","toLowerCase","calculateVersionLocaleStatuses","versions","locales","payload","logger","info","msg","length","documentPublishState","Map","versionLocaleStatus","version","versionId","id","documentId","parent","status","_status","publishedLocale","published_locale","isSnapshot","snapshot","has","localeMap","locale","set","currentPublishState","get","versionStatusMap","publishedStatus","entries","sortVersionsChronologically","sort","a","b","parentA","String","parentB","localeCompare","dateA","Date","created_at","createdAt","dateB","getTime"],"mappings":"AAEA;;;CAGC,GACD,OAAO,MAAMA,cAAc,CAACC;IAC1B,OAAOA,IACJC,OAAO,CAAC,YAAY,OACpBC,WAAW,GACXD,OAAO,CAAC,MAAM,IACdA,OAAO,CAAC,MAAM,KAAK,iCAAiC;;AACzD,EAAC;AAeD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCC,GACD,OAAO,SAASE,+BACdC,QAAyB,EACzBC,OAAiB,EACjBC,OAAgB;IAEhBA,QAAQC,MAAM,CAACC,IAAI,CAAC;QAAEC,KAAK,CAAC,WAAW,EAAEL,SAASM,MAAM,CAAC,gBAAgB,CAAC;IAAC;IAE3E,4EAA4E;IAC5E,8EAA8E;IAC9E,MAAMC,uBAAuB,IAAIC;IAEjC,iDAAiD;IACjD,MAAMC,sBAA8C,IAAID;IAExD,8DAA8D;IAC9D,KAAK,MAAME,WAAWV,SAAU;QAC9B,MAAMW,YAAYD,QAAQE,EAAE;QAC5B,MAAMC,aAAaH,QAAQI,MAAM;QACjC,MAAMC,SAASL,QAAQM,OAAO;QAC9B,MAAMC,kBAAkBP,QAAQQ,gBAAgB,IAAIR,QAAQO,eAAe;QAC3E,MAAME,aAAaT,QAAQU,QAAQ,KAAK;QAExC,+DAA+D;QAC/D,IAAI,CAACb,qBAAqBc,GAAG,CAACR,aAAa;YACzC,MAAMS,YAAY,IAAId;YACtB,KAAK,MAAMe,UAAUtB,QAAS;gBAC5BqB,UAAUE,GAAG,CAACD,QAAQ;YACxB;YACAhB,qBAAqBiB,GAAG,CAACX,YAAYS;QACvC;QAEA,MAAMG,sBAAsBlB,qBAAqBmB,GAAG,CAACb;QACrD,MAAMc,mBAAmB,IAAInB;QAE7B,IAAIW,YAAY;YACd,2DAA2D;YAC3D,mGAAmG;YACnG,yFAAyF;YACzF,2FAA2F;YAC3F,KAAK,MAAM,CAACI,QAAQK,gBAAgB,IAAIH,oBAAoBI,OAAO,GAAI;gBACrEF,iBAAiBH,GAAG,CAACD,QAAQK;YAC/B;QACF,OAAO,IAAIb,WAAW,aAAa;YACjC,0BAA0B;YAC1B,IAAIE,iBAAiB;gBACnB,gFAAgF;gBAChFQ,oBAAoBD,GAAG,CAACP,iBAAiB;gBAEzC,8DAA8D;gBAC9D,KAAK,MAAM,CAACM,QAAQK,gBAAgB,IAAIH,oBAAoBI,OAAO,GAAI;oBACrEF,iBAAiBH,GAAG,CAACD,QAAQK;gBAC/B;YACF,OAAO;gBACL,2DAA2D;gBAC3D,KAAK,MAAML,UAAUtB,QAAS;oBAC5BwB,oBAAoBD,GAAG,CAACD,QAAQ;oBAChCI,iBAAiBH,GAAG,CAACD,QAAQ;gBAC/B;YACF;QACF,OAAO;YACL,wFAAwF;YACxF,KAAK,MAAMA,UAAUtB,QAAS;gBAC5BwB,oBAAoBD,GAAG,CAACD,QAAQ;gBAChCI,iBAAiBH,GAAG,CAACD,QAAQ;YAC/B;QACF;QAEA,oCAAoC;QACpCd,oBAAoBe,GAAG,CAACb,WAAWgB;IACrC;IAEA,OAAOlB;AACT;AAEA;;;;;CAKC,GACD,OAAO,SAASqB,4BAA4B9B,QAAyB;IACnE,OAAOA,SAAS+B,IAAI,CAAC,CAACC,GAAGC;QACvB,uBAAuB;QACvB,MAAMC,UAAUC,OAAOH,EAAElB,MAAM;QAC/B,MAAMsB,UAAUD,OAAOF,EAAEnB,MAAM;QAC/B,IAAIoB,YAAYE,SAAS;YACvB,OAAOF,QAAQG,aAAa,CAACD;QAC/B;QAEA,6BAA6B;QAC7B,MAAME,QAAQ,IAAIC,KAAKP,EAAEQ,UAAU,IAAIR,EAAES,SAAS,IAAI;QACtD,MAAMC,QAAQ,IAAIH,KAAKN,EAAEO,UAAU,IAAIP,EAAEQ,SAAS,IAAI;QACtD,OAAOH,MAAMK,OAAO,KAAKD,MAAMC,OAAO;IACxC;AACF"}