@payloadcms/drizzle 4.0.0-internal.40de3ec → 4.0.0-internal.4c792ad

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 (58) hide show
  1. package/dist/exports/postgres.d.ts +1 -0
  2. package/dist/exports/postgres.d.ts.map +1 -1
  3. package/dist/exports/postgres.js +1 -0
  4. package/dist/exports/postgres.js.map +1 -1
  5. package/dist/exports/sqlite.d.ts +1 -0
  6. package/dist/exports/sqlite.d.ts.map +1 -1
  7. package/dist/exports/sqlite.js +1 -0
  8. package/dist/exports/sqlite.js.map +1 -1
  9. package/dist/find/traverseFields.js +0 -1
  10. package/dist/find/traverseFields.js.map +1 -1
  11. package/dist/index.d.ts +1 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +0 -1
  14. package/dist/index.js.map +1 -1
  15. package/dist/postgres/predefinedMigrations/localize-status/index.d.ts +11 -0
  16. package/dist/postgres/predefinedMigrations/localize-status/index.d.ts.map +1 -0
  17. package/dist/postgres/predefinedMigrations/localize-status/index.js +296 -0
  18. package/dist/postgres/predefinedMigrations/localize-status/index.js.map +1 -0
  19. package/dist/postgres/predefinedMigrations/localize-status/migrateMainCollection.d.ts +13 -0
  20. package/dist/postgres/predefinedMigrations/localize-status/migrateMainCollection.d.ts.map +1 -0
  21. package/dist/postgres/predefinedMigrations/localize-status/migrateMainCollection.js +51 -0
  22. package/dist/postgres/predefinedMigrations/localize-status/migrateMainCollection.js.map +1 -0
  23. package/dist/postgres/predefinedMigrations/localize-status/migrateMainGlobal.d.ts +13 -0
  24. package/dist/postgres/predefinedMigrations/localize-status/migrateMainGlobal.d.ts.map +1 -0
  25. package/dist/postgres/predefinedMigrations/localize-status/migrateMainGlobal.js +54 -0
  26. package/dist/postgres/predefinedMigrations/localize-status/migrateMainGlobal.js.map +1 -0
  27. package/dist/schema/traverseFields.js.map +1 -1
  28. package/dist/sqlite/predefinedMigrations/localize-status/index.d.ts +28 -0
  29. package/dist/sqlite/predefinedMigrations/localize-status/index.d.ts.map +1 -0
  30. package/dist/sqlite/predefinedMigrations/localize-status/index.js +198 -0
  31. package/dist/sqlite/predefinedMigrations/localize-status/index.js.map +1 -0
  32. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainCollection.d.ts +12 -0
  33. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainCollection.d.ts.map +1 -0
  34. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainCollection.js +24 -0
  35. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainCollection.js.map +1 -0
  36. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainGlobal.d.ts +12 -0
  37. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainGlobal.d.ts.map +1 -0
  38. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainGlobal.js +28 -0
  39. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainGlobal.js.map +1 -0
  40. package/dist/transform/write/traverseFields.js +0 -1
  41. package/dist/transform/write/traverseFields.js.map +1 -1
  42. package/dist/types.d.ts +0 -4
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/types.js +1 -3
  45. package/dist/types.js.map +1 -1
  46. package/dist/upsertRow/handleUpsertError.d.ts.map +1 -1
  47. package/dist/upsertRow/handleUpsertError.js +2 -1
  48. package/dist/upsertRow/handleUpsertError.js.map +1 -1
  49. package/dist/upsertRow/handleUpsertError.spec.js +42 -0
  50. package/dist/upsertRow/handleUpsertError.spec.js.map +1 -0
  51. package/dist/upsertRow/index.d.ts.map +1 -1
  52. package/dist/upsertRow/index.js +5 -2
  53. package/dist/upsertRow/index.js.map +1 -1
  54. package/package.json +3 -3
  55. package/dist/find/chainMethods.d.ts +0 -20
  56. package/dist/find/chainMethods.d.ts.map +0 -1
  57. package/dist/find/chainMethods.js +0 -16
  58. package/dist/find/chainMethods.js.map +0 -1
@@ -0,0 +1,296 @@
1
+ import { calculateVersionLocaleStatuses } from 'payload/migrations';
2
+ import toSnakeCase from 'to-snake-case';
3
+ import { migrateMainCollectionStatus } from './migrateMainCollection.js';
4
+ import { migrateMainGlobalStatus } from './migrateMainGlobal.js';
5
+ export async function migratePostgresLocalizeStatus(args) {
6
+ const { collectionSlug, db, globalSlug, payload, req, sql } = args;
7
+ const schemaName = db.schemaName ?? 'public';
8
+ if (!collectionSlug && !globalSlug) {
9
+ throw new Error('Either collectionSlug or globalSlug must be provided');
10
+ }
11
+ if (collectionSlug && globalSlug) {
12
+ throw new Error('Cannot provide both collectionSlug and globalSlug');
13
+ }
14
+ const entitySlug = collectionSlug || globalSlug;
15
+ // Convert camelCase slugs to snake_case and add version prefix/suffix
16
+ const versionsTable = collectionSlug ? `_${toSnakeCase(collectionSlug)}_v` : `_${toSnakeCase(globalSlug)}_v`;
17
+ const localesTable = `${versionsTable}_locales`;
18
+ if (!payload.config.localization) {
19
+ throw new Error('Localization is not enabled in payload config');
20
+ }
21
+ // Check if versions are enabled on this collection/global
22
+ let entityConfig;
23
+ if (collectionSlug) {
24
+ const collection = payload.config.collections.find((c)=>c.slug === collectionSlug);
25
+ if (collection) {
26
+ entityConfig = collection;
27
+ }
28
+ } else if (globalSlug) {
29
+ const global = payload.config.globals.find((g)=>g.slug === globalSlug);
30
+ if (global) {
31
+ entityConfig = global;
32
+ }
33
+ }
34
+ if (!entityConfig) {
35
+ throw new Error(`${collectionSlug ? 'Collection' : 'Global'} not found: ${collectionSlug || globalSlug}`);
36
+ }
37
+ payload.logger.info({
38
+ msg: `Starting _status localization migration for ${collectionSlug ? 'collection' : 'global'}: ${entitySlug}`
39
+ });
40
+ // Get filtered locales if filterAvailableLocales is defined
41
+ let locales = payload.config.localization.localeCodes;
42
+ if (typeof payload.config.localization.filterAvailableLocales === 'function') {
43
+ const filteredLocaleObjects = await payload.config.localization.filterAvailableLocales({
44
+ locales: payload.config.localization.locales,
45
+ req
46
+ });
47
+ locales = filteredLocaleObjects.map((locale)=>locale.code);
48
+ }
49
+ payload.logger.info({
50
+ msg: `Locales: ${locales.join(', ')}`
51
+ });
52
+ // Check if versions are enabled in config (skip if not)
53
+ if (!entityConfig.versions) {
54
+ payload.logger.info({
55
+ msg: `Skipping migration for ${collectionSlug ? 'collection' : 'global'}: ${entitySlug} - versions not enabled`
56
+ });
57
+ return;
58
+ }
59
+ // Validate that version__status column exists before proceeding
60
+ const columnCheckResult = await db.execute({
61
+ drizzle: db.drizzle,
62
+ sql: sql`
63
+ SELECT EXISTS (
64
+ SELECT FROM information_schema.columns
65
+ WHERE table_schema = ${schemaName}
66
+ AND table_name = ${versionsTable}
67
+ AND column_name = 'version__status'
68
+ ) as exists
69
+ `
70
+ });
71
+ if (!columnCheckResult.rows[0]?.exists) {
72
+ throw new Error(`Migration aborted: version__status column not found in ${versionsTable} table. ` + `This migration should only run on schemas that have NOT yet been migrated to per-locale status. ` + `If you've already run this migration, no action is needed.`);
73
+ }
74
+ // 1. Check if the locales table exists
75
+ const localesTableCheckResult = await db.execute({
76
+ drizzle: db.drizzle,
77
+ sql: sql`
78
+ SELECT EXISTS (
79
+ SELECT FROM information_schema.tables
80
+ WHERE table_schema = ${schemaName}
81
+ AND table_name = ${localesTable}
82
+ ) as exists
83
+ `
84
+ });
85
+ const localesTableExists = localesTableCheckResult.rows[0]?.exists;
86
+ if (!localesTableExists) {
87
+ // SCENARIO 1: Create the locales table (first localized field in versions)
88
+ payload.logger.info({
89
+ msg: `Creating new locales table: ${localesTable}`
90
+ });
91
+ await db.execute({
92
+ drizzle: db.drizzle,
93
+ sql: sql`
94
+ CREATE TABLE ${sql.identifier(localesTable)} (
95
+ id SERIAL PRIMARY KEY,
96
+ _locale VARCHAR NOT NULL,
97
+ _parent_id INTEGER NOT NULL,
98
+ version__status VARCHAR,
99
+ UNIQUE(_locale, _parent_id),
100
+ FOREIGN KEY (_parent_id) REFERENCES ${sql.identifier(versionsTable)}(id) ON DELETE CASCADE
101
+ )
102
+ `
103
+ });
104
+ // Create one row per locale per version record
105
+ // Simple approach: copy the same status to all locales
106
+ for (const locale of locales){
107
+ const inserted = await db.execute({
108
+ drizzle: db.drizzle,
109
+ sql: sql`
110
+ INSERT INTO ${sql.identifier(localesTable)} (_locale, _parent_id, version__status)
111
+ SELECT ${locale}, id, version__status
112
+ FROM ${sql.identifier(versionsTable)}
113
+ RETURNING id
114
+ `
115
+ });
116
+ payload.logger.info({
117
+ msg: `Inserted ${inserted.length} rows for locale: ${locale}`
118
+ });
119
+ }
120
+ } else {
121
+ // SCENARIO 2: Add version__status column to existing locales table
122
+ payload.logger.info({
123
+ msg: `Adding version__status column to existing table: ${localesTable}`
124
+ });
125
+ await db.execute({
126
+ drizzle: db.drizzle,
127
+ sql: sql`
128
+ ALTER TABLE ${sql.identifier(localesTable)} ADD COLUMN version__status VARCHAR
129
+ `
130
+ });
131
+ // INTELLIGENT DATA MIGRATION using historical publishedLocale data
132
+ payload.logger.info({
133
+ msg: 'Processing version history to determine status per locale...'
134
+ });
135
+ // First, get the list of locales that actually exist in the locales table
136
+ // This is important because the config may have more locales defined than what's in the OLD schema
137
+ const existingLocalesResult = await db.execute({
138
+ drizzle: db.drizzle,
139
+ sql: sql`
140
+ SELECT DISTINCT _locale
141
+ FROM ${sql.identifier(localesTable)}
142
+ ORDER BY _locale
143
+ `
144
+ });
145
+ const existingLocales = existingLocalesResult.rows.map((row)=>row._locale);
146
+ payload.logger.info({
147
+ msg: `Found existing locales in table: ${existingLocales.join(', ')}`
148
+ });
149
+ // Check if the snapshot column exists (only present on DBs that used publishSpecificLocale)
150
+ const snapshotColumnCheckResult = await db.execute({
151
+ drizzle: db.drizzle,
152
+ sql: sql`
153
+ SELECT EXISTS (
154
+ SELECT FROM information_schema.columns
155
+ WHERE table_schema = ${schemaName}
156
+ AND table_name = ${versionsTable}
157
+ AND column_name = 'snapshot'
158
+ ) as exists
159
+ `
160
+ });
161
+ const hasSnapshotColumn = snapshotColumnCheckResult.rows[0]?.exists === true;
162
+ // Get all version records grouped by parent document, ordered chronologically
163
+ const versionsResult = await db.execute({
164
+ drizzle: db.drizzle,
165
+ sql: hasSnapshotColumn ? sql`
166
+ SELECT id, parent_id as parent, version__status as _status, published_locale, snapshot, created_at
167
+ FROM ${sql.identifier(versionsTable)}
168
+ ORDER BY parent_id, created_at ASC
169
+ ` : sql`
170
+ SELECT id, parent_id as parent, version__status as _status, published_locale, created_at
171
+ FROM ${sql.identifier(versionsTable)}
172
+ ORDER BY parent_id, created_at ASC
173
+ `
174
+ });
175
+ // Use shared function to calculate version locale statuses
176
+ // Only process locales that actually exist in the locales table
177
+ const versionLocaleStatus = calculateVersionLocaleStatuses(versionsResult.rows, existingLocales, payload);
178
+ // Now update the locales table with the calculated status for each version
179
+ payload.logger.info({
180
+ msg: 'Updating locales table with calculated statuses...'
181
+ });
182
+ let updateCount = 0;
183
+ for (const [versionId, localeMap] of versionLocaleStatus.entries()){
184
+ for (const [locale, status] of localeMap.entries()){
185
+ await db.execute({
186
+ drizzle: db.drizzle,
187
+ sql: sql`
188
+ UPDATE ${sql.identifier(localesTable)}
189
+ SET version__status = ${status}
190
+ WHERE _parent_id = ${versionId}
191
+ AND _locale = ${locale}
192
+ `
193
+ });
194
+ updateCount++;
195
+ }
196
+ }
197
+ payload.logger.info({
198
+ msg: `Updated ${updateCount} locale rows with status`
199
+ });
200
+ }
201
+ // 3. Drop the old version__status column from main versions table
202
+ await db.execute({
203
+ drizzle: db.drizzle,
204
+ sql: sql`
205
+ ALTER TABLE ${sql.identifier(versionsTable)} DROP COLUMN version__status
206
+ `
207
+ });
208
+ // 4. Create and populate _status column in main collection/global locales table
209
+ // With localizeStatus enabled, _status is a localized field stored in the collection's locales table
210
+ // We need to create this column and populate it based on the latest version status per locale
211
+ const mainTable = collectionSlug ? toSnakeCase(collectionSlug) : toSnakeCase(globalSlug);
212
+ const mainLocalesTable = `${mainTable}_locales`;
213
+ const localesTableCheck = await db.execute({
214
+ drizzle: db.drizzle,
215
+ sql: sql`
216
+ SELECT EXISTS (
217
+ SELECT FROM information_schema.tables
218
+ WHERE table_schema = ${schemaName}
219
+ AND table_name = ${mainLocalesTable}
220
+ ) as exists
221
+ `
222
+ });
223
+ if (localesTableCheck.rows[0]?.exists) {
224
+ // Check if _status column already exists in the locales table
225
+ const statusColumnCheck = await db.execute({
226
+ drizzle: db.drizzle,
227
+ sql: sql`
228
+ SELECT EXISTS (
229
+ SELECT FROM information_schema.columns
230
+ WHERE table_schema = ${schemaName}
231
+ AND table_name = ${mainLocalesTable}
232
+ AND column_name = '_status'
233
+ ) as exists
234
+ `
235
+ });
236
+ if (!statusColumnCheck.rows[0]?.exists) {
237
+ // Add _status column to locales table
238
+ await db.execute({
239
+ drizzle: db.drizzle,
240
+ sql: sql`
241
+ ALTER TABLE ${sql.identifier(mainLocalesTable)}
242
+ ADD COLUMN _status VARCHAR DEFAULT 'draft'
243
+ `
244
+ });
245
+ }
246
+ // Now populate the _status values from the latest version
247
+ if (collectionSlug) {
248
+ await migrateMainCollectionStatus({
249
+ collectionSlug,
250
+ db,
251
+ locales,
252
+ payload,
253
+ sql,
254
+ versionsTable
255
+ });
256
+ } else if (globalSlug) {
257
+ await migrateMainGlobalStatus({
258
+ db,
259
+ globalSlug,
260
+ locales,
261
+ payload,
262
+ sql,
263
+ versionsTable
264
+ });
265
+ }
266
+ } else {
267
+ payload.logger.info({
268
+ msg: `No locales table found: ${mainLocalesTable} (collection/global not localized)`
269
+ });
270
+ }
271
+ // 5. Drop _status from main table if it exists (it will be in locales table now)
272
+ const mainTableStatusCheck = await db.execute({
273
+ drizzle: db.drizzle,
274
+ sql: sql`
275
+ SELECT EXISTS (
276
+ SELECT FROM information_schema.columns
277
+ WHERE table_schema = ${schemaName}
278
+ AND table_name = ${mainTable}
279
+ AND column_name = '_status'
280
+ ) as exists
281
+ `
282
+ });
283
+ if (mainTableStatusCheck.rows[0]?.exists) {
284
+ await db.execute({
285
+ drizzle: db.drizzle,
286
+ sql: sql`
287
+ ALTER TABLE ${sql.identifier(mainTable)} DROP COLUMN _status
288
+ `
289
+ });
290
+ }
291
+ payload.logger.info({
292
+ msg: 'Migration completed successfully'
293
+ });
294
+ }
295
+
296
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/postgres/predefinedMigrations/localize-status/index.ts"],"sourcesContent":["import type { Payload } from 'payload'\n\nimport { calculateVersionLocaleStatuses } from 'payload/migrations'\nimport toSnakeCase from 'to-snake-case'\n\nimport { migrateMainCollectionStatus } from './migrateMainCollection.js'\nimport { migrateMainGlobalStatus } from './migrateMainGlobal.js'\n\nexport type LocalizeStatusArgs = {\n collectionSlug?: string\n db: any\n globalSlug?: string\n payload: Payload\n req?: any\n sql: any\n}\n\nexport async function migratePostgresLocalizeStatus(args: LocalizeStatusArgs): Promise<void> {\n const { collectionSlug, db, globalSlug, payload, req, sql } = args\n const schemaName = db.schemaName ?? 'public'\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 // Convert camelCase slugs to snake_case and add version prefix/suffix\n const versionsTable = collectionSlug\n ? `_${toSnakeCase(collectionSlug)}_v`\n : `_${toSnakeCase(globalSlug!)}_v`\n const localesTable = `${versionsTable}_locales`\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 // 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 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 // Validate that version__status column exists before proceeding\n const columnCheckResult = await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n SELECT EXISTS (\n SELECT FROM information_schema.columns\n WHERE table_schema = ${schemaName}\n AND table_name = ${versionsTable}\n AND column_name = 'version__status'\n ) as exists\n `,\n })\n\n if (!columnCheckResult.rows[0]?.exists) {\n throw new Error(\n `Migration aborted: version__status column not found in ${versionsTable} table. ` +\n `This migration should only run on schemas that have NOT yet been migrated to per-locale status. ` +\n `If you've already run this migration, no action is needed.`,\n )\n }\n\n // 1. Check if the locales table exists\n const localesTableCheckResult = await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n SELECT EXISTS (\n SELECT FROM information_schema.tables\n WHERE table_schema = ${schemaName}\n AND table_name = ${localesTable}\n ) as exists\n `,\n })\n\n const localesTableExists = localesTableCheckResult.rows[0]?.exists\n\n if (!localesTableExists) {\n // SCENARIO 1: Create the locales table (first localized field in versions)\n payload.logger.info({ msg: `Creating new locales table: ${localesTable}` })\n\n await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n CREATE TABLE ${sql.identifier(localesTable)} (\n id SERIAL PRIMARY KEY,\n _locale VARCHAR NOT NULL,\n _parent_id INTEGER NOT NULL,\n version__status VARCHAR,\n UNIQUE(_locale, _parent_id),\n FOREIGN KEY (_parent_id) REFERENCES ${sql.identifier(versionsTable)}(id) ON DELETE CASCADE\n )\n `,\n })\n\n // Create one row per locale per version record\n // Simple approach: copy the same status to all locales\n for (const locale of locales) {\n const inserted = await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n INSERT INTO ${sql.identifier(localesTable)} (_locale, _parent_id, version__status)\n SELECT ${locale}, id, version__status\n FROM ${sql.identifier(versionsTable)}\n RETURNING id\n `,\n })\n payload.logger.info({\n msg: `Inserted ${inserted.length} rows for locale: ${locale}`,\n })\n }\n } else {\n // SCENARIO 2: Add version__status column to existing locales table\n payload.logger.info({ msg: `Adding version__status column to existing table: ${localesTable}` })\n\n await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n ALTER TABLE ${sql.identifier(localesTable)} ADD COLUMN version__status VARCHAR\n `,\n })\n\n // INTELLIGENT DATA MIGRATION using historical publishedLocale data\n payload.logger.info({ msg: 'Processing version history to determine status per locale...' })\n\n // First, get the list of locales that actually exist in the locales table\n // This is important because the config may have more locales defined than what's in the OLD schema\n const existingLocalesResult = await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n SELECT DISTINCT _locale\n FROM ${sql.identifier(localesTable)}\n ORDER BY _locale\n `,\n })\n const existingLocales = existingLocalesResult.rows.map((row: any) => row._locale as string)\n payload.logger.info({\n msg: `Found existing locales in table: ${existingLocales.join(', ')}`,\n })\n\n // Check if the snapshot column exists (only present on DBs that used publishSpecificLocale)\n const snapshotColumnCheckResult = await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n SELECT EXISTS (\n SELECT FROM information_schema.columns\n WHERE table_schema = ${schemaName}\n AND table_name = ${versionsTable}\n AND column_name = 'snapshot'\n ) as exists\n `,\n })\n const hasSnapshotColumn = snapshotColumnCheckResult.rows[0]?.exists === true\n\n // Get all version records grouped by parent document, ordered chronologically\n const versionsResult = await db.execute({\n drizzle: db.drizzle,\n sql: hasSnapshotColumn\n ? sql`\n SELECT id, parent_id as parent, version__status as _status, published_locale, snapshot, created_at\n FROM ${sql.identifier(versionsTable)}\n ORDER BY parent_id, created_at ASC\n `\n : sql`\n SELECT id, parent_id as parent, version__status as _status, published_locale, created_at\n FROM ${sql.identifier(versionsTable)}\n ORDER BY parent_id, created_at ASC\n `,\n })\n\n // Use shared function to calculate version locale statuses\n // Only process locales that actually exist in the locales table\n const versionLocaleStatus = calculateVersionLocaleStatuses(\n versionsResult.rows,\n existingLocales,\n payload,\n )\n\n // Now update the locales table with the calculated status for each version\n payload.logger.info({ msg: 'Updating locales table with calculated statuses...' })\n\n let updateCount = 0\n for (const [versionId, localeMap] of versionLocaleStatus.entries()) {\n for (const [locale, status] of localeMap.entries()) {\n await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n UPDATE ${sql.identifier(localesTable)}\n SET version__status = ${status}\n WHERE _parent_id = ${versionId}\n AND _locale = ${locale}\n `,\n })\n updateCount++\n }\n }\n\n payload.logger.info({ msg: `Updated ${updateCount} locale rows with status` })\n }\n\n // 3. Drop the old version__status column from main versions table\n await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n ALTER TABLE ${sql.identifier(versionsTable)} DROP COLUMN version__status\n `,\n })\n\n // 4. Create and populate _status column in main collection/global locales table\n // With localizeStatus enabled, _status is a localized field stored in the collection's locales table\n // We need to create this column and populate it based on the latest version status per locale\n const mainTable = collectionSlug ? toSnakeCase(collectionSlug) : toSnakeCase(globalSlug!)\n const mainLocalesTable = `${mainTable}_locales`\n\n const localesTableCheck = await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n SELECT EXISTS (\n SELECT FROM information_schema.tables\n WHERE table_schema = ${schemaName}\n AND table_name = ${mainLocalesTable}\n ) as exists\n `,\n })\n\n if (localesTableCheck.rows[0]?.exists) {\n // Check if _status column already exists in the locales table\n const statusColumnCheck = await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n SELECT EXISTS (\n SELECT FROM information_schema.columns\n WHERE table_schema = ${schemaName}\n AND table_name = ${mainLocalesTable}\n AND column_name = '_status'\n ) as exists\n `,\n })\n\n if (!statusColumnCheck.rows[0]?.exists) {\n // Add _status column to locales table\n await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n ALTER TABLE ${sql.identifier(mainLocalesTable)}\n ADD COLUMN _status VARCHAR DEFAULT 'draft'\n `,\n })\n }\n\n // Now populate the _status values from the latest version\n if (collectionSlug) {\n await migrateMainCollectionStatus({\n collectionSlug,\n db,\n locales,\n payload,\n sql,\n versionsTable,\n })\n } else if (globalSlug) {\n await migrateMainGlobalStatus({ db, globalSlug, locales, payload, sql, versionsTable })\n }\n } else {\n payload.logger.info({\n msg: `No locales table found: ${mainLocalesTable} (collection/global not localized)`,\n })\n }\n\n // 5. Drop _status from main table if it exists (it will be in locales table now)\n const mainTableStatusCheck = await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n SELECT EXISTS (\n SELECT FROM information_schema.columns\n WHERE table_schema = ${schemaName}\n AND table_name = ${mainTable}\n AND column_name = '_status'\n ) as exists\n `,\n })\n\n if (mainTableStatusCheck.rows[0]?.exists) {\n await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n ALTER TABLE ${sql.identifier(mainTable)} DROP COLUMN _status\n `,\n })\n }\n\n payload.logger.info({ msg: 'Migration completed successfully' })\n}\n"],"names":["calculateVersionLocaleStatuses","toSnakeCase","migrateMainCollectionStatus","migrateMainGlobalStatus","migratePostgresLocalizeStatus","args","collectionSlug","db","globalSlug","payload","req","sql","schemaName","Error","entitySlug","versionsTable","localesTable","config","localization","entityConfig","collection","collections","find","c","slug","global","globals","g","logger","info","msg","locales","localeCodes","filterAvailableLocales","filteredLocaleObjects","map","locale","code","join","versions","columnCheckResult","execute","drizzle","rows","exists","localesTableCheckResult","localesTableExists","identifier","inserted","length","existingLocalesResult","existingLocales","row","_locale","snapshotColumnCheckResult","hasSnapshotColumn","versionsResult","versionLocaleStatus","updateCount","versionId","localeMap","entries","status","mainTable","mainLocalesTable","localesTableCheck","statusColumnCheck","mainTableStatusCheck"],"mappings":"AAEA,SAASA,8BAA8B,QAAQ,qBAAoB;AACnE,OAAOC,iBAAiB,gBAAe;AAEvC,SAASC,2BAA2B,QAAQ,6BAA4B;AACxE,SAASC,uBAAuB,QAAQ,yBAAwB;AAWhE,OAAO,eAAeC,8BAA8BC,IAAwB;IAC1E,MAAM,EAAEC,cAAc,EAAEC,EAAE,EAAEC,UAAU,EAAEC,OAAO,EAAEC,GAAG,EAAEC,GAAG,EAAE,GAAGN;IAC9D,MAAMO,aAAaL,GAAGK,UAAU,IAAI;IAEpC,IAAI,CAACN,kBAAkB,CAACE,YAAY;QAClC,MAAM,IAAIK,MAAM;IAClB;IAEA,IAAIP,kBAAkBE,YAAY;QAChC,MAAM,IAAIK,MAAM;IAClB;IAEA,MAAMC,aAAaR,kBAAkBE;IACrC,sEAAsE;IACtE,MAAMO,gBAAgBT,iBAClB,CAAC,CAAC,EAAEL,YAAYK,gBAAgB,EAAE,CAAC,GACnC,CAAC,CAAC,EAAEL,YAAYO,YAAa,EAAE,CAAC;IACpC,MAAMQ,eAAe,GAAGD,cAAc,QAAQ,CAAC;IAE/C,IAAI,CAACN,QAAQQ,MAAM,CAACC,YAAY,EAAE;QAChC,MAAM,IAAIL,MAAM;IAClB;IAEA,0DAA0D;IAC1D,IAAIM;IACJ,IAAIb,gBAAgB;QAClB,MAAMc,aAAaX,QAAQQ,MAAM,CAACI,WAAW,CAACC,IAAI,CAAC,CAACC,IAAMA,EAAEC,IAAI,KAAKlB;QACrE,IAAIc,YAAY;YACdD,eAAeC;QACjB;IACF,OAAO,IAAIZ,YAAY;QACrB,MAAMiB,SAAShB,QAAQQ,MAAM,CAACS,OAAO,CAACJ,IAAI,CAAC,CAACK,IAAMA,EAAEH,IAAI,KAAKhB;QAC7D,IAAIiB,QAAQ;YACVN,eAAeM;QACjB;IACF;IAEA,IAAI,CAACN,cAAc;QACjB,MAAM,IAAIN,MACR,GAAGP,iBAAiB,eAAe,SAAS,YAAY,EAAEA,kBAAkBE,YAAY;IAE5F;IAEAC,QAAQmB,MAAM,CAACC,IAAI,CAAC;QAClBC,KAAK,CAAC,4CAA4C,EAAExB,iBAAiB,eAAe,SAAS,EAAE,EAAEQ,YAAY;IAC/G;IAEA,4DAA4D;IAC5D,IAAIiB,UAAUtB,QAAQQ,MAAM,CAACC,YAAY,CAACc,WAAW;IACrD,IAAI,OAAOvB,QAAQQ,MAAM,CAACC,YAAY,CAACe,sBAAsB,KAAK,YAAY;QAC5E,MAAMC,wBAAwB,MAAMzB,QAAQQ,MAAM,CAACC,YAAY,CAACe,sBAAsB,CAAC;YACrFF,SAAStB,QAAQQ,MAAM,CAACC,YAAY,CAACa,OAAO;YAC5CrB;QACF;QACAqB,UAAUG,sBAAsBC,GAAG,CAAC,CAACC,SAAWA,OAAOC,IAAI;IAC7D;IACA5B,QAAQmB,MAAM,CAACC,IAAI,CAAC;QAAEC,KAAK,CAAC,SAAS,EAAEC,QAAQO,IAAI,CAAC,OAAO;IAAC;IAE5D,wDAAwD;IACxD,IAAI,CAACnB,aAAaoB,QAAQ,EAAE;QAC1B9B,QAAQmB,MAAM,CAACC,IAAI,CAAC;YAClBC,KAAK,CAAC,uBAAuB,EAAExB,iBAAiB,eAAe,SAAS,EAAE,EAAEQ,WAAW,uBAAuB,CAAC;QACjH;QACA;IACF;IAEA,gEAAgE;IAChE,MAAM0B,oBAAoB,MAAMjC,GAAGkC,OAAO,CAAC;QACzCC,SAASnC,GAAGmC,OAAO;QACnB/B,KAAKA,GAAG,CAAC;;;6BAGgB,EAAEC,WAAW;yBACjB,EAAEG,cAAc;;;IAGrC,CAAC;IACH;IAEA,IAAI,CAACyB,kBAAkBG,IAAI,CAAC,EAAE,EAAEC,QAAQ;QACtC,MAAM,IAAI/B,MACR,CAAC,uDAAuD,EAAEE,cAAc,QAAQ,CAAC,GAC/E,CAAC,gGAAgG,CAAC,GAClG,CAAC,0DAA0D,CAAC;IAElE;IAEA,uCAAuC;IACvC,MAAM8B,0BAA0B,MAAMtC,GAAGkC,OAAO,CAAC;QAC/CC,SAASnC,GAAGmC,OAAO;QACnB/B,KAAKA,GAAG,CAAC;;;6BAGgB,EAAEC,WAAW;yBACjB,EAAEI,aAAa;;IAEpC,CAAC;IACH;IAEA,MAAM8B,qBAAqBD,wBAAwBF,IAAI,CAAC,EAAE,EAAEC;IAE5D,IAAI,CAACE,oBAAoB;QACvB,2EAA2E;QAC3ErC,QAAQmB,MAAM,CAACC,IAAI,CAAC;YAAEC,KAAK,CAAC,4BAA4B,EAAEd,cAAc;QAAC;QAEzE,MAAMT,GAAGkC,OAAO,CAAC;YACfC,SAASnC,GAAGmC,OAAO;YACnB/B,KAAKA,GAAG,CAAC;qBACM,EAAEA,IAAIoC,UAAU,CAAC/B,cAAc;;;;;;8CAMN,EAAEL,IAAIoC,UAAU,CAAChC,eAAe;;MAExE,CAAC;QACH;QAEA,+CAA+C;QAC/C,uDAAuD;QACvD,KAAK,MAAMqB,UAAUL,QAAS;YAC5B,MAAMiB,WAAW,MAAMzC,GAAGkC,OAAO,CAAC;gBAChCC,SAASnC,GAAGmC,OAAO;gBACnB/B,KAAKA,GAAG,CAAC;sBACK,EAAEA,IAAIoC,UAAU,CAAC/B,cAAc;iBACpC,EAAEoB,OAAO;eACX,EAAEzB,IAAIoC,UAAU,CAAChC,eAAe;;QAEvC,CAAC;YACH;YACAN,QAAQmB,MAAM,CAACC,IAAI,CAAC;gBAClBC,KAAK,CAAC,SAAS,EAAEkB,SAASC,MAAM,CAAC,kBAAkB,EAAEb,QAAQ;YAC/D;QACF;IACF,OAAO;QACL,mEAAmE;QACnE3B,QAAQmB,MAAM,CAACC,IAAI,CAAC;YAAEC,KAAK,CAAC,iDAAiD,EAAEd,cAAc;QAAC;QAE9F,MAAMT,GAAGkC,OAAO,CAAC;YACfC,SAASnC,GAAGmC,OAAO;YACnB/B,KAAKA,GAAG,CAAC;oBACK,EAAEA,IAAIoC,UAAU,CAAC/B,cAAc;MAC7C,CAAC;QACH;QAEA,mEAAmE;QACnEP,QAAQmB,MAAM,CAACC,IAAI,CAAC;YAAEC,KAAK;QAA+D;QAE1F,0EAA0E;QAC1E,mGAAmG;QACnG,MAAMoB,wBAAwB,MAAM3C,GAAGkC,OAAO,CAAC;YAC7CC,SAASnC,GAAGmC,OAAO;YACnB/B,KAAKA,GAAG,CAAC;;aAEF,EAAEA,IAAIoC,UAAU,CAAC/B,cAAc;;MAEtC,CAAC;QACH;QACA,MAAMmC,kBAAkBD,sBAAsBP,IAAI,CAACR,GAAG,CAAC,CAACiB,MAAaA,IAAIC,OAAO;QAChF5C,QAAQmB,MAAM,CAACC,IAAI,CAAC;YAClBC,KAAK,CAAC,iCAAiC,EAAEqB,gBAAgBb,IAAI,CAAC,OAAO;QACvE;QAEA,4FAA4F;QAC5F,MAAMgB,4BAA4B,MAAM/C,GAAGkC,OAAO,CAAC;YACjDC,SAASnC,GAAGmC,OAAO;YACnB/B,KAAKA,GAAG,CAAC;;;+BAGgB,EAAEC,WAAW;2BACjB,EAAEG,cAAc;;;MAGrC,CAAC;QACH;QACA,MAAMwC,oBAAoBD,0BAA0BX,IAAI,CAAC,EAAE,EAAEC,WAAW;QAExE,8EAA8E;QAC9E,MAAMY,iBAAiB,MAAMjD,GAAGkC,OAAO,CAAC;YACtCC,SAASnC,GAAGmC,OAAO;YACnB/B,KAAK4C,oBACD5C,GAAG,CAAC;;eAEC,EAAEA,IAAIoC,UAAU,CAAChC,eAAe;;QAEvC,CAAC,GACCJ,GAAG,CAAC;;eAEC,EAAEA,IAAIoC,UAAU,CAAChC,eAAe;;QAEvC,CAAC;QACL;QAEA,2DAA2D;QAC3D,gEAAgE;QAChE,MAAM0C,sBAAsBzD,+BAC1BwD,eAAeb,IAAI,EACnBQ,iBACA1C;QAGF,2EAA2E;QAC3EA,QAAQmB,MAAM,CAACC,IAAI,CAAC;YAAEC,KAAK;QAAqD;QAEhF,IAAI4B,cAAc;QAClB,KAAK,MAAM,CAACC,WAAWC,UAAU,IAAIH,oBAAoBI,OAAO,GAAI;YAClE,KAAK,MAAM,CAACzB,QAAQ0B,OAAO,IAAIF,UAAUC,OAAO,GAAI;gBAClD,MAAMtD,GAAGkC,OAAO,CAAC;oBACfC,SAASnC,GAAGmC,OAAO;oBACnB/B,KAAKA,GAAG,CAAC;mBACA,EAAEA,IAAIoC,UAAU,CAAC/B,cAAc;kCAChB,EAAE8C,OAAO;+BACZ,EAAEH,UAAU;0BACjB,EAAEvB,OAAO;UACzB,CAAC;gBACH;gBACAsB;YACF;QACF;QAEAjD,QAAQmB,MAAM,CAACC,IAAI,CAAC;YAAEC,KAAK,CAAC,QAAQ,EAAE4B,YAAY,wBAAwB,CAAC;QAAC;IAC9E;IAEA,kEAAkE;IAClE,MAAMnD,GAAGkC,OAAO,CAAC;QACfC,SAASnC,GAAGmC,OAAO;QACnB/B,KAAKA,GAAG,CAAC;kBACK,EAAEA,IAAIoC,UAAU,CAAChC,eAAe;IAC9C,CAAC;IACH;IAEA,gFAAgF;IAChF,qGAAqG;IACrG,8FAA8F;IAC9F,MAAMgD,YAAYzD,iBAAiBL,YAAYK,kBAAkBL,YAAYO;IAC7E,MAAMwD,mBAAmB,GAAGD,UAAU,QAAQ,CAAC;IAE/C,MAAME,oBAAoB,MAAM1D,GAAGkC,OAAO,CAAC;QACzCC,SAASnC,GAAGmC,OAAO;QACnB/B,KAAKA,GAAG,CAAC;;;6BAGgB,EAAEC,WAAW;yBACjB,EAAEoD,iBAAiB;;IAExC,CAAC;IACH;IAEA,IAAIC,kBAAkBtB,IAAI,CAAC,EAAE,EAAEC,QAAQ;QACrC,8DAA8D;QAC9D,MAAMsB,oBAAoB,MAAM3D,GAAGkC,OAAO,CAAC;YACzCC,SAASnC,GAAGmC,OAAO;YACnB/B,KAAKA,GAAG,CAAC;;;+BAGgB,EAAEC,WAAW;2BACjB,EAAEoD,iBAAiB;;;MAGxC,CAAC;QACH;QAEA,IAAI,CAACE,kBAAkBvB,IAAI,CAAC,EAAE,EAAEC,QAAQ;YACtC,sCAAsC;YACtC,MAAMrC,GAAGkC,OAAO,CAAC;gBACfC,SAASnC,GAAGmC,OAAO;gBACnB/B,KAAKA,GAAG,CAAC;sBACK,EAAEA,IAAIoC,UAAU,CAACiB,kBAAkB;;QAEjD,CAAC;YACH;QACF;QAEA,0DAA0D;QAC1D,IAAI1D,gBAAgB;YAClB,MAAMJ,4BAA4B;gBAChCI;gBACAC;gBACAwB;gBACAtB;gBACAE;gBACAI;YACF;QACF,OAAO,IAAIP,YAAY;YACrB,MAAML,wBAAwB;gBAAEI;gBAAIC;gBAAYuB;gBAAStB;gBAASE;gBAAKI;YAAc;QACvF;IACF,OAAO;QACLN,QAAQmB,MAAM,CAACC,IAAI,CAAC;YAClBC,KAAK,CAAC,wBAAwB,EAAEkC,iBAAiB,kCAAkC,CAAC;QACtF;IACF;IAEA,iFAAiF;IACjF,MAAMG,uBAAuB,MAAM5D,GAAGkC,OAAO,CAAC;QAC5CC,SAASnC,GAAGmC,OAAO;QACnB/B,KAAKA,GAAG,CAAC;;;6BAGgB,EAAEC,WAAW;yBACjB,EAAEmD,UAAU;;;IAGjC,CAAC;IACH;IAEA,IAAII,qBAAqBxB,IAAI,CAAC,EAAE,EAAEC,QAAQ;QACxC,MAAMrC,GAAGkC,OAAO,CAAC;YACfC,SAASnC,GAAGmC,OAAO;YACnB/B,KAAKA,GAAG,CAAC;oBACK,EAAEA,IAAIoC,UAAU,CAACgB,WAAW;MAC1C,CAAC;QACH;IACF;IAEAtD,QAAQmB,MAAM,CAACC,IAAI,CAAC;QAAEC,KAAK;IAAmC;AAChE"}
@@ -0,0 +1,13 @@
1
+ import type { Payload } from 'payload';
2
+ /**
3
+ * Migrates main collection documents from _status to per-locale status object
4
+ */
5
+ export declare function migrateMainCollectionStatus({ collectionSlug, db, locales, payload, sql, versionsTable, }: {
6
+ collectionSlug: string;
7
+ db: any;
8
+ locales: string[];
9
+ payload: Payload;
10
+ sql: any;
11
+ versionsTable: string;
12
+ }): Promise<void>;
13
+ //# sourceMappingURL=migrateMainCollection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrateMainCollection.d.ts","sourceRoot":"","sources":["../../../../src/postgres/predefinedMigrations/localize-status/migrateMainCollection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAItC;;GAEG;AACH,wBAAsB,2BAA2B,CAAC,EAChD,cAAc,EACd,EAAE,EACF,OAAO,EACP,OAAO,EACP,GAAG,EACH,aAAa,GACd,EAAE;IACD,cAAc,EAAE,MAAM,CAAA;IACtB,EAAE,EAAE,GAAG,CAAA;IACP,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,EAAE,GAAG,CAAA;IACR,aAAa,EAAE,MAAM,CAAA;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+ChB"}
@@ -0,0 +1,51 @@
1
+ import toSnakeCase from 'to-snake-case';
2
+ /**
3
+ * Migrates main collection documents from _status to per-locale status object
4
+ */ export async function migrateMainCollectionStatus({ collectionSlug, db, locales, payload, sql, versionsTable }) {
5
+ const mainTable = toSnakeCase(collectionSlug);
6
+ const mainLocalesTable = `${mainTable}_locales`;
7
+ payload.logger.info({
8
+ msg: `Migrating main collection locales for: ${mainLocalesTable}`
9
+ });
10
+ // Get all documents
11
+ const documents = await db.execute({
12
+ drizzle: db.drizzle,
13
+ sql: sql`
14
+ SELECT DISTINCT id
15
+ FROM ${sql.identifier(mainTable)}
16
+ `
17
+ });
18
+ for (const doc of documents.rows){
19
+ // For each locale, get the latest version status
20
+ for (const locale of locales){
21
+ const latestVersionStatus = await db.execute({
22
+ drizzle: db.drizzle,
23
+ sql: sql`
24
+ SELECT l.version__status as _status
25
+ FROM ${sql.identifier(versionsTable)} v
26
+ JOIN ${sql.raw(`${versionsTable}_locales`)} l ON l._parent_id = v.id
27
+ WHERE v.parent_id = ${doc.id}
28
+ AND l._locale = ${locale}
29
+ ORDER BY v.created_at DESC
30
+ LIMIT 1
31
+ `
32
+ });
33
+ const status = latestVersionStatus.rows[0]?._status || 'draft';
34
+ // Update the main collection's locales table with this status
35
+ await db.execute({
36
+ drizzle: db.drizzle,
37
+ sql: sql`
38
+ UPDATE ${sql.identifier(mainLocalesTable)}
39
+ SET _status = ${status}
40
+ WHERE _parent_id = ${doc.id}
41
+ AND _locale = ${locale}
42
+ `
43
+ });
44
+ }
45
+ }
46
+ payload.logger.info({
47
+ msg: `Migrated ${documents.rows.length} collection documents`
48
+ });
49
+ }
50
+
51
+ //# sourceMappingURL=migrateMainCollection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/postgres/predefinedMigrations/localize-status/migrateMainCollection.ts"],"sourcesContent":["import type { Payload } from 'payload'\n\nimport toSnakeCase from 'to-snake-case'\n\n/**\n * Migrates main collection documents from _status to per-locale status object\n */\nexport async function migrateMainCollectionStatus({\n collectionSlug,\n db,\n locales,\n payload,\n sql,\n versionsTable,\n}: {\n collectionSlug: string\n db: any\n locales: string[]\n payload: Payload\n sql: any\n versionsTable: string\n}): Promise<void> {\n const mainTable = toSnakeCase(collectionSlug)\n const mainLocalesTable = `${mainTable}_locales`\n\n payload.logger.info({ msg: `Migrating main collection locales for: ${mainLocalesTable}` })\n\n // Get all documents\n const documents = await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n SELECT DISTINCT id\n FROM ${sql.identifier(mainTable)}\n `,\n })\n\n for (const doc of documents.rows) {\n // For each locale, get the latest version status\n for (const locale of locales) {\n const latestVersionStatus = await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n SELECT l.version__status as _status\n FROM ${sql.identifier(versionsTable)} v\n JOIN ${sql.raw(`${versionsTable}_locales`)} l ON l._parent_id = v.id\n WHERE v.parent_id = ${doc.id}\n AND l._locale = ${locale}\n ORDER BY v.created_at DESC\n LIMIT 1\n `,\n })\n\n const status = latestVersionStatus.rows[0]?._status || 'draft'\n\n // Update the main collection's locales table with this status\n await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n UPDATE ${sql.identifier(mainLocalesTable)}\n SET _status = ${status}\n WHERE _parent_id = ${doc.id}\n AND _locale = ${locale}\n `,\n })\n }\n }\n\n payload.logger.info({ msg: `Migrated ${documents.rows.length} collection documents` })\n}\n"],"names":["toSnakeCase","migrateMainCollectionStatus","collectionSlug","db","locales","payload","sql","versionsTable","mainTable","mainLocalesTable","logger","info","msg","documents","execute","drizzle","identifier","doc","rows","locale","latestVersionStatus","raw","id","status","_status","length"],"mappings":"AAEA,OAAOA,iBAAiB,gBAAe;AAEvC;;CAEC,GACD,OAAO,eAAeC,4BAA4B,EAChDC,cAAc,EACdC,EAAE,EACFC,OAAO,EACPC,OAAO,EACPC,GAAG,EACHC,aAAa,EAQd;IACC,MAAMC,YAAYR,YAAYE;IAC9B,MAAMO,mBAAmB,GAAGD,UAAU,QAAQ,CAAC;IAE/CH,QAAQK,MAAM,CAACC,IAAI,CAAC;QAAEC,KAAK,CAAC,uCAAuC,EAAEH,kBAAkB;IAAC;IAExF,oBAAoB;IACpB,MAAMI,YAAY,MAAMV,GAAGW,OAAO,CAAC;QACjCC,SAASZ,GAAGY,OAAO;QACnBT,KAAKA,GAAG,CAAC;;WAEF,EAAEA,IAAIU,UAAU,CAACR,WAAW;IACnC,CAAC;IACH;IAEA,KAAK,MAAMS,OAAOJ,UAAUK,IAAI,CAAE;QAChC,iDAAiD;QACjD,KAAK,MAAMC,UAAUf,QAAS;YAC5B,MAAMgB,sBAAsB,MAAMjB,GAAGW,OAAO,CAAC;gBAC3CC,SAASZ,GAAGY,OAAO;gBACnBT,KAAKA,GAAG,CAAC;;eAEF,EAAEA,IAAIU,UAAU,CAACT,eAAe;eAChC,EAAED,IAAIe,GAAG,CAAC,GAAGd,cAAc,QAAQ,CAAC,EAAE;8BACvB,EAAEU,IAAIK,EAAE,CAAC;0BACb,EAAEH,OAAO;;;QAG3B,CAAC;YACH;YAEA,MAAMI,SAASH,oBAAoBF,IAAI,CAAC,EAAE,EAAEM,WAAW;YAEvD,8DAA8D;YAC9D,MAAMrB,GAAGW,OAAO,CAAC;gBACfC,SAASZ,GAAGY,OAAO;gBACnBT,KAAKA,GAAG,CAAC;iBACA,EAAEA,IAAIU,UAAU,CAACP,kBAAkB;wBAC5B,EAAEc,OAAO;6BACJ,EAAEN,IAAIK,EAAE,CAAC;wBACd,EAAEH,OAAO;QACzB,CAAC;YACH;QACF;IACF;IAEAd,QAAQK,MAAM,CAACC,IAAI,CAAC;QAAEC,KAAK,CAAC,SAAS,EAAEC,UAAUK,IAAI,CAACO,MAAM,CAAC,qBAAqB,CAAC;IAAC;AACtF"}
@@ -0,0 +1,13 @@
1
+ import type { Payload } from 'payload';
2
+ /**
3
+ * Migrates main global document from _status to per-locale status object
4
+ */
5
+ export declare function migrateMainGlobalStatus({ db, globalSlug, locales, payload, sql, versionsTable, }: {
6
+ db: any;
7
+ globalSlug: string;
8
+ locales: string[];
9
+ payload: Payload;
10
+ sql: any;
11
+ versionsTable: string;
12
+ }): Promise<void>;
13
+ //# sourceMappingURL=migrateMainGlobal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrateMainGlobal.d.ts","sourceRoot":"","sources":["../../../../src/postgres/predefinedMigrations/localize-status/migrateMainGlobal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAItC;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,EAC5C,EAAE,EACF,UAAU,EACV,OAAO,EACP,OAAO,EACP,GAAG,EACH,aAAa,GACd,EAAE;IACD,EAAE,EAAE,GAAG,CAAA;IACP,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,EAAE,GAAG,CAAA;IACR,aAAa,EAAE,MAAM,CAAA;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkDhB"}
@@ -0,0 +1,54 @@
1
+ import toSnakeCase from 'to-snake-case';
2
+ /**
3
+ * Migrates main global document from _status to per-locale status object
4
+ */ export async function migrateMainGlobalStatus({ db, globalSlug, locales, payload, sql, versionsTable }) {
5
+ const globalTable = toSnakeCase(globalSlug);
6
+ const globalLocalesTable = `${globalTable}_locales`;
7
+ payload.logger.info({
8
+ msg: `Migrating main global locales for: ${globalLocalesTable}`
9
+ });
10
+ // For each locale, get the latest version status
11
+ for (const locale of locales){
12
+ const latestVersionStatus = await db.execute({
13
+ drizzle: db.drizzle,
14
+ sql: sql`
15
+ SELECT l.version__status as _status
16
+ FROM ${sql.identifier(versionsTable)} v
17
+ JOIN ${sql.raw(`${versionsTable}_locales`)} l ON l._parent_id = v.id
18
+ WHERE l._locale = ${locale}
19
+ ORDER BY v.created_at DESC
20
+ LIMIT 1
21
+ `
22
+ });
23
+ const status = latestVersionStatus.rows[0]?._status || 'draft';
24
+ // Get the global document ID from the globals table
25
+ const globalDoc = await db.execute({
26
+ drizzle: db.drizzle,
27
+ sql: sql`
28
+ SELECT id FROM ${sql.identifier(globalTable)} LIMIT 1
29
+ `
30
+ });
31
+ if (globalDoc.rows.length === 0) {
32
+ payload.logger.warn({
33
+ msg: `No global document found for ${globalSlug}, skipping`
34
+ });
35
+ continue;
36
+ }
37
+ const globalId = globalDoc.rows[0].id;
38
+ // Update the global's locales table with this status
39
+ await db.execute({
40
+ drizzle: db.drizzle,
41
+ sql: sql`
42
+ UPDATE ${sql.identifier(globalLocalesTable)}
43
+ SET _status = ${status}
44
+ WHERE _parent_id = ${globalId}
45
+ AND _locale = ${locale}
46
+ `
47
+ });
48
+ }
49
+ payload.logger.info({
50
+ msg: 'Migrated global document'
51
+ });
52
+ }
53
+
54
+ //# sourceMappingURL=migrateMainGlobal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/postgres/predefinedMigrations/localize-status/migrateMainGlobal.ts"],"sourcesContent":["import type { Payload } from 'payload'\n\nimport toSnakeCase from 'to-snake-case'\n\n/**\n * Migrates main global document from _status to per-locale status object\n */\nexport async function migrateMainGlobalStatus({\n db,\n globalSlug,\n locales,\n payload,\n sql,\n versionsTable,\n}: {\n db: any\n globalSlug: string\n locales: string[]\n payload: Payload\n sql: any\n versionsTable: string\n}): Promise<void> {\n const globalTable = toSnakeCase(globalSlug)\n const globalLocalesTable = `${globalTable}_locales`\n\n payload.logger.info({ msg: `Migrating main global locales for: ${globalLocalesTable}` })\n\n // For each locale, get the latest version status\n for (const locale of locales) {\n const latestVersionStatus = await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n SELECT l.version__status as _status\n FROM ${sql.identifier(versionsTable)} v\n JOIN ${sql.raw(`${versionsTable}_locales`)} l ON l._parent_id = v.id\n WHERE l._locale = ${locale}\n ORDER BY v.created_at DESC\n LIMIT 1\n `,\n })\n\n const status = latestVersionStatus.rows[0]?._status || 'draft'\n\n // Get the global document ID from the globals table\n const globalDoc = await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n SELECT id FROM ${sql.identifier(globalTable)} LIMIT 1\n `,\n })\n\n if (globalDoc.rows.length === 0) {\n payload.logger.warn({ msg: `No global document found for ${globalSlug}, skipping` })\n continue\n }\n\n const globalId = globalDoc.rows[0].id\n\n // Update the global's locales table with this status\n await db.execute({\n drizzle: db.drizzle,\n sql: sql`\n UPDATE ${sql.identifier(globalLocalesTable)}\n SET _status = ${status}\n WHERE _parent_id = ${globalId}\n AND _locale = ${locale}\n `,\n })\n }\n\n payload.logger.info({ msg: 'Migrated global document' })\n}\n"],"names":["toSnakeCase","migrateMainGlobalStatus","db","globalSlug","locales","payload","sql","versionsTable","globalTable","globalLocalesTable","logger","info","msg","locale","latestVersionStatus","execute","drizzle","identifier","raw","status","rows","_status","globalDoc","length","warn","globalId","id"],"mappings":"AAEA,OAAOA,iBAAiB,gBAAe;AAEvC;;CAEC,GACD,OAAO,eAAeC,wBAAwB,EAC5CC,EAAE,EACFC,UAAU,EACVC,OAAO,EACPC,OAAO,EACPC,GAAG,EACHC,aAAa,EAQd;IACC,MAAMC,cAAcR,YAAYG;IAChC,MAAMM,qBAAqB,GAAGD,YAAY,QAAQ,CAAC;IAEnDH,QAAQK,MAAM,CAACC,IAAI,CAAC;QAAEC,KAAK,CAAC,mCAAmC,EAAEH,oBAAoB;IAAC;IAEtF,iDAAiD;IACjD,KAAK,MAAMI,UAAUT,QAAS;QAC5B,MAAMU,sBAAsB,MAAMZ,GAAGa,OAAO,CAAC;YAC3CC,SAASd,GAAGc,OAAO;YACnBV,KAAKA,GAAG,CAAC;;aAEF,EAAEA,IAAIW,UAAU,CAACV,eAAe;aAChC,EAAED,IAAIY,GAAG,CAAC,GAAGX,cAAc,QAAQ,CAAC,EAAE;0BACzB,EAAEM,OAAO;;;MAG7B,CAAC;QACH;QAEA,MAAMM,SAASL,oBAAoBM,IAAI,CAAC,EAAE,EAAEC,WAAW;QAEvD,oDAAoD;QACpD,MAAMC,YAAY,MAAMpB,GAAGa,OAAO,CAAC;YACjCC,SAASd,GAAGc,OAAO;YACnBV,KAAKA,GAAG,CAAC;uBACQ,EAAEA,IAAIW,UAAU,CAACT,aAAa;MAC/C,CAAC;QACH;QAEA,IAAIc,UAAUF,IAAI,CAACG,MAAM,KAAK,GAAG;YAC/BlB,QAAQK,MAAM,CAACc,IAAI,CAAC;gBAAEZ,KAAK,CAAC,6BAA6B,EAAET,WAAW,UAAU,CAAC;YAAC;YAClF;QACF;QAEA,MAAMsB,WAAWH,UAAUF,IAAI,CAAC,EAAE,CAACM,EAAE;QAErC,qDAAqD;QACrD,MAAMxB,GAAGa,OAAO,CAAC;YACfC,SAASd,GAAGc,OAAO;YACnBV,KAAKA,GAAG,CAAC;eACA,EAAEA,IAAIW,UAAU,CAACR,oBAAoB;sBAC9B,EAAEU,OAAO;2BACJ,EAAEM,SAAS;sBAChB,EAAEZ,OAAO;MACzB,CAAC;QACH;IACF;IAEAR,QAAQK,MAAM,CAACC,IAAI,CAAC;QAAEC,KAAK;IAA2B;AACxD"}