payload 3.78.0-internal.5219978 → 3.78.0-internal.ab11ffa
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.
- package/dist/bin/migrate.js +1 -1
- package/dist/bin/migrate.js.map +1 -1
- package/dist/database/createDatabaseAdapter.d.ts +1 -1
- package/dist/database/createDatabaseAdapter.d.ts.map +1 -1
- package/dist/database/createDatabaseAdapter.js +2 -3
- package/dist/database/createDatabaseAdapter.js.map +1 -1
- package/dist/database/migrations/createMigration.js +2 -2
- package/dist/database/migrations/createMigration.js.map +1 -1
- package/dist/database/migrations/readMigrationFiles.d.ts.map +1 -1
- package/dist/database/migrations/readMigrationFiles.js +5 -6
- package/dist/database/migrations/readMigrationFiles.js.map +1 -1
- package/dist/database/types.d.ts +4 -1
- package/dist/database/types.d.ts.map +1 -1
- package/dist/database/types.js.map +1 -1
- package/dist/index.bundled.d.ts +5 -2
- package/dist/utilities/addDataAndFileToRequest.d.ts.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.js +7 -5
- package/dist/utilities/addDataAndFileToRequest.js.map +1 -1
- package/dist/utilities/filterDataToSelectedLocales.d.ts.map +1 -1
- package/dist/utilities/filterDataToSelectedLocales.js +7 -1
- package/dist/utilities/filterDataToSelectedLocales.js.map +1 -1
- package/dist/utilities/filterDataToSelectedLocales.spec.js +193 -0
- package/dist/utilities/filterDataToSelectedLocales.spec.js.map +1 -0
- package/dist/utilities/mergeLocalizedData.d.ts.map +1 -1
- package/dist/utilities/mergeLocalizedData.js +7 -1
- package/dist/utilities/mergeLocalizedData.js.map +1 -1
- package/dist/utilities/mergeLocalizedData.spec.js +163 -0
- package/dist/utilities/mergeLocalizedData.spec.js.map +1 -1
- package/dist/versions/saveVersion.js +1 -1
- package/dist/versions/saveVersion.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { filterDataToSelectedLocales } from './filterDataToSelectedLocales.js';
|
|
3
|
+
describe('filterDataToSelectedLocales', ()=>{
|
|
4
|
+
const selectedLocales = [
|
|
5
|
+
'en'
|
|
6
|
+
];
|
|
7
|
+
const configBlockReferences = [];
|
|
8
|
+
describe('block metadata preservation', ()=>{
|
|
9
|
+
it('should preserve blockType, id, and blockName on non-localized blocks', ()=>{
|
|
10
|
+
const fields = [
|
|
11
|
+
{
|
|
12
|
+
name: 'layout',
|
|
13
|
+
type: 'blocks',
|
|
14
|
+
blocks: [
|
|
15
|
+
{
|
|
16
|
+
slug: 'content',
|
|
17
|
+
fields: [
|
|
18
|
+
{
|
|
19
|
+
name: 'richText',
|
|
20
|
+
type: 'richText',
|
|
21
|
+
localized: true
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
];
|
|
28
|
+
const docWithLocales = {
|
|
29
|
+
layout: [
|
|
30
|
+
{
|
|
31
|
+
blockType: 'content',
|
|
32
|
+
id: 'abc123',
|
|
33
|
+
blockName: 'My Block',
|
|
34
|
+
richText: {
|
|
35
|
+
en: 'English',
|
|
36
|
+
es: 'Spanish'
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
};
|
|
41
|
+
const result = filterDataToSelectedLocales({
|
|
42
|
+
configBlockReferences: [],
|
|
43
|
+
docWithLocales,
|
|
44
|
+
fields,
|
|
45
|
+
selectedLocales
|
|
46
|
+
});
|
|
47
|
+
expect(result.layout).toHaveLength(1);
|
|
48
|
+
expect(result.layout[0].blockType).toBe('content');
|
|
49
|
+
expect(result.layout[0].id).toBe('abc123');
|
|
50
|
+
expect(result.layout[0].blockName).toBe('My Block');
|
|
51
|
+
expect(result.layout[0].richText).toEqual({
|
|
52
|
+
en: 'English'
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
it('should preserve blockType and id when block has no blockName', ()=>{
|
|
56
|
+
const fields = [
|
|
57
|
+
{
|
|
58
|
+
name: 'layout',
|
|
59
|
+
type: 'blocks',
|
|
60
|
+
blocks: [
|
|
61
|
+
{
|
|
62
|
+
slug: 'text',
|
|
63
|
+
fields: [
|
|
64
|
+
{
|
|
65
|
+
name: 'text',
|
|
66
|
+
type: 'text',
|
|
67
|
+
localized: true
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
];
|
|
74
|
+
const docWithLocales = {
|
|
75
|
+
layout: [
|
|
76
|
+
{
|
|
77
|
+
blockType: 'text',
|
|
78
|
+
id: 'def456',
|
|
79
|
+
text: {
|
|
80
|
+
en: 'English',
|
|
81
|
+
es: 'Spanish'
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
};
|
|
86
|
+
const result = filterDataToSelectedLocales({
|
|
87
|
+
configBlockReferences: [],
|
|
88
|
+
docWithLocales,
|
|
89
|
+
fields,
|
|
90
|
+
selectedLocales
|
|
91
|
+
});
|
|
92
|
+
expect(result.layout).toHaveLength(1);
|
|
93
|
+
expect(result.layout[0].blockType).toBe('text');
|
|
94
|
+
expect(result.layout[0].id).toBe('def456');
|
|
95
|
+
expect(result.layout[0].text).toEqual({
|
|
96
|
+
en: 'English'
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
it('should preserve blockType and id with configBlockReferences', ()=>{
|
|
100
|
+
const fields = [
|
|
101
|
+
{
|
|
102
|
+
name: 'layout',
|
|
103
|
+
type: 'blocks',
|
|
104
|
+
blocks: [],
|
|
105
|
+
blockReferences: [
|
|
106
|
+
'content'
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
];
|
|
110
|
+
const result = filterDataToSelectedLocales({
|
|
111
|
+
configBlockReferences: [
|
|
112
|
+
{
|
|
113
|
+
slug: 'content',
|
|
114
|
+
fields: [
|
|
115
|
+
{
|
|
116
|
+
name: 'body',
|
|
117
|
+
type: 'text',
|
|
118
|
+
localized: true
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
],
|
|
123
|
+
docWithLocales: {
|
|
124
|
+
layout: [
|
|
125
|
+
{
|
|
126
|
+
blockType: 'content',
|
|
127
|
+
id: 'ref123',
|
|
128
|
+
body: {
|
|
129
|
+
en: 'English',
|
|
130
|
+
es: 'Spanish'
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
fields,
|
|
136
|
+
selectedLocales
|
|
137
|
+
});
|
|
138
|
+
expect(result.layout).toHaveLength(1);
|
|
139
|
+
expect(result.layout[0].blockType).toBe('content');
|
|
140
|
+
expect(result.layout[0].id).toBe('ref123');
|
|
141
|
+
expect(result.layout[0].body).toEqual({
|
|
142
|
+
en: 'English'
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
describe('simple fields', ()=>{
|
|
147
|
+
it('should filter localized field values to selected locales', ()=>{
|
|
148
|
+
const fields = [
|
|
149
|
+
{
|
|
150
|
+
name: 'title',
|
|
151
|
+
type: 'text',
|
|
152
|
+
localized: true
|
|
153
|
+
}
|
|
154
|
+
];
|
|
155
|
+
const docWithLocales = {
|
|
156
|
+
title: {
|
|
157
|
+
en: 'English Title',
|
|
158
|
+
es: 'Spanish Title',
|
|
159
|
+
de: 'German Title'
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const result = filterDataToSelectedLocales({
|
|
163
|
+
configBlockReferences: [],
|
|
164
|
+
docWithLocales,
|
|
165
|
+
fields,
|
|
166
|
+
selectedLocales
|
|
167
|
+
});
|
|
168
|
+
expect(result.title).toEqual({
|
|
169
|
+
en: 'English Title'
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
it('should pass through non-localized fields as-is', ()=>{
|
|
173
|
+
const fields = [
|
|
174
|
+
{
|
|
175
|
+
name: 'slug',
|
|
176
|
+
type: 'text'
|
|
177
|
+
}
|
|
178
|
+
];
|
|
179
|
+
const docWithLocales = {
|
|
180
|
+
slug: 'my-slug'
|
|
181
|
+
};
|
|
182
|
+
const result = filterDataToSelectedLocales({
|
|
183
|
+
configBlockReferences: [],
|
|
184
|
+
docWithLocales,
|
|
185
|
+
fields,
|
|
186
|
+
selectedLocales
|
|
187
|
+
});
|
|
188
|
+
expect(result.slug).toBe('my-slug');
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
//# sourceMappingURL=filterDataToSelectedLocales.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/filterDataToSelectedLocales.spec.ts"],"sourcesContent":["import type { Field } from '../fields/config/types.js'\n\nimport { describe, expect, it } from 'vitest'\n\nimport { filterDataToSelectedLocales } from './filterDataToSelectedLocales.js'\n\ndescribe('filterDataToSelectedLocales', () => {\n const selectedLocales = ['en']\n const configBlockReferences = []\n\n describe('block metadata preservation', () => {\n it('should preserve blockType, id, and blockName on non-localized blocks', () => {\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [\n {\n slug: 'content',\n fields: [\n {\n name: 'richText',\n type: 'richText',\n localized: true,\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n layout: [\n {\n blockType: 'content',\n id: 'abc123',\n blockName: 'My Block',\n richText: { en: 'English', es: 'Spanish' },\n },\n ],\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.layout).toHaveLength(1)\n expect(result.layout[0].blockType).toBe('content')\n expect(result.layout[0].id).toBe('abc123')\n expect(result.layout[0].blockName).toBe('My Block')\n expect(result.layout[0].richText).toEqual({ en: 'English' })\n })\n\n it('should preserve blockType and id when block has no blockName', () => {\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [\n {\n slug: 'text',\n fields: [\n {\n name: 'text',\n type: 'text',\n localized: true,\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n layout: [\n {\n blockType: 'text',\n id: 'def456',\n text: { en: 'English', es: 'Spanish' },\n },\n ],\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.layout).toHaveLength(1)\n expect(result.layout[0].blockType).toBe('text')\n expect(result.layout[0].id).toBe('def456')\n expect(result.layout[0].text).toEqual({ en: 'English' })\n })\n\n it('should preserve blockType and id with configBlockReferences', () => {\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [],\n blockReferences: ['content'],\n },\n ]\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [\n {\n slug: 'content',\n fields: [\n {\n name: 'body',\n type: 'text',\n localized: true,\n },\n ],\n },\n ],\n docWithLocales: {\n layout: [\n {\n blockType: 'content',\n id: 'ref123',\n body: { en: 'English', es: 'Spanish' },\n },\n ],\n },\n fields,\n selectedLocales,\n })\n\n expect(result.layout).toHaveLength(1)\n expect(result.layout[0].blockType).toBe('content')\n expect(result.layout[0].id).toBe('ref123')\n expect(result.layout[0].body).toEqual({ en: 'English' })\n })\n })\n\n describe('simple fields', () => {\n it('should filter localized field values to selected locales', () => {\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n ]\n\n const docWithLocales = {\n title: {\n en: 'English Title',\n es: 'Spanish Title',\n de: 'German Title',\n },\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.title).toEqual({ en: 'English Title' })\n })\n\n it('should pass through non-localized fields as-is', () => {\n const fields: Field[] = [\n {\n name: 'slug',\n type: 'text',\n },\n ]\n\n const docWithLocales = {\n slug: 'my-slug',\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.slug).toBe('my-slug')\n })\n })\n})\n"],"names":["describe","expect","it","filterDataToSelectedLocales","selectedLocales","configBlockReferences","fields","name","type","blocks","slug","localized","docWithLocales","layout","blockType","id","blockName","richText","en","es","result","toHaveLength","toBe","toEqual","text","blockReferences","body","title","de"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mergeLocalizedData.d.ts","sourceRoot":"","sources":["../../src/utilities/mergeLocalizedData.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,KAAK,EAAkB,MAAM,2BAA2B,CAAA;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAiCnD,KAAK,8BAA8B,GAAG;IACpC,qBAAqB,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAA;IAChD,eAAe,EAAE,UAAU,CAAA;IAC3B,cAAc,EAAE,UAAU,CAAA;IAC1B,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,eAAe,EAAE,MAAM,EAAE,CAAA;CAC1B,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,MAAM,EACN,iBAAyB,EACzB,eAAe,GAChB,EAAE,8BAA8B,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"mergeLocalizedData.d.ts","sourceRoot":"","sources":["../../src/utilities/mergeLocalizedData.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,KAAK,EAAkB,MAAM,2BAA2B,CAAA;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAiCnD,KAAK,8BAA8B,GAAG;IACpC,qBAAqB,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAA;IAChD,eAAe,EAAE,UAAU,CAAA;IAC3B,cAAc,EAAE,UAAU,CAAA;IAC1B,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,eAAe,EAAE,MAAM,EAAE,CAAA;CAC1B,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,MAAM,EACN,iBAAyB,EACzB,eAAe,GAChB,EAAE,8BAA8B,GAAG,UAAU,CAiS7C"}
|
|
@@ -126,7 +126,7 @@ import { fieldAffectsData, fieldShouldBeLocalized, tabHasName } from '../fields/
|
|
|
126
126
|
}
|
|
127
127
|
if (block) {
|
|
128
128
|
const blockData = Array.isArray(existingValue) && existingValue[index] ? existingValue[index] : {};
|
|
129
|
-
|
|
129
|
+
const merged = mergeLocalizedData({
|
|
130
130
|
configBlockReferences,
|
|
131
131
|
dataWithLocales: newBlockData,
|
|
132
132
|
docWithLocales: blockData,
|
|
@@ -134,6 +134,12 @@ import { fieldAffectsData, fieldShouldBeLocalized, tabHasName } from '../fields/
|
|
|
134
134
|
parentIsLocalized,
|
|
135
135
|
selectedLocales
|
|
136
136
|
});
|
|
137
|
+
// blockType, id, blockName are set by Payload internally
|
|
138
|
+
// and not part of block.fields, so they must be preserved explicitly
|
|
139
|
+
merged.blockType = newBlockData.blockType;
|
|
140
|
+
merged.id = newBlockData.id;
|
|
141
|
+
merged.blockName = newBlockData.blockName;
|
|
142
|
+
return merged;
|
|
137
143
|
}
|
|
138
144
|
return newBlockData;
|
|
139
145
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/mergeLocalizedData.ts"],"sourcesContent":["import type { Block, Field, FlattenedBlock } from '../fields/config/types.js'\nimport type { SanitizedConfig } from '../index.js'\nimport type { JsonObject } from '../types/index.js'\n\nimport { fieldAffectsData, fieldShouldBeLocalized, tabHasName } from '../fields/config/types.js'\n\n/**\n * Collects field names at the current data level, recursing through pass-through fields\n * (row, collapsible, unnamed group, unnamed tab) but stopping at named fields.\n */\nfunction collectFlattenedFieldNames(fields: Field[]): Set<string> {\n const names = new Set<string>()\n for (const field of fields) {\n if (fieldAffectsData(field)) {\n names.add(field.name)\n } else if ('fields' in field && Array.isArray(field.fields)) {\n // Pass-through fields (row, collapsible, unnamed group)\n for (const name of collectFlattenedFieldNames(field.fields)) {\n names.add(name)\n }\n } else if (field.type === 'tabs') {\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n names.add(tab.name)\n } else {\n for (const name of collectFlattenedFieldNames(tab.fields)) {\n names.add(name)\n }\n }\n }\n }\n }\n return names\n}\n\ntype MergeDataToSelectedLocalesArgs = {\n configBlockReferences: SanitizedConfig['blocks']\n dataWithLocales: JsonObject\n docWithLocales: JsonObject\n fields: Field[]\n parentIsLocalized?: boolean\n selectedLocales: string[]\n}\n\n/**\n * Merges data from dataWithLocales onto docWithLocales for specified locales.\n * For localized fields, merges only the specified locales while preserving others.\n * For non-localized fields, keeps existing values from docWithLocales unchanged.\n * Returns a new object without mutating the original.\n */\nexport function mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales,\n fields,\n parentIsLocalized = false,\n selectedLocales,\n}: MergeDataToSelectedLocalesArgs): JsonObject {\n if (!docWithLocales || typeof docWithLocales !== 'object') {\n return dataWithLocales || docWithLocales\n }\n\n const result: JsonObject = { ...docWithLocales }\n\n for (const field of fields) {\n if (fieldAffectsData(field)) {\n // If the parent is localized, all children are inherently \"localized\"\n if (parentIsLocalized && dataWithLocales[field.name]) {\n result[field.name] = dataWithLocales[field.name]\n continue\n }\n\n const fieldIsLocalized = fieldShouldBeLocalized({ field, parentIsLocalized })\n\n switch (field.type) {\n case 'array': {\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n // If localized, handle locale keys\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const updatedArray: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue) {\n updatedArray[locale] = newValue[locale]\n }\n }\n\n result[field.name] = updatedArray\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n } else if (Array.isArray(newValue)) {\n // Non-localized array - still process children for any localized fields\n result[field.name] = newValue.map((newItem: JsonObject, index: number) => {\n const existingItem = existingValue?.[index] || {}\n\n return mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newItem,\n docWithLocales: existingItem,\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n })\n }\n }\n break\n }\n\n case 'blocks': {\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n // If localized, handle locale keys\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const updatedData: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue) {\n updatedData[locale] = newValue[locale]\n }\n }\n\n result[field.name] = updatedData\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n } else if (Array.isArray(newValue)) {\n // Non-localized blocks - still process children for any localized fields\n result[field.name] = newValue.map((newBlockData: JsonObject, index: number) => {\n let block: Block | FlattenedBlock | undefined\n if (configBlockReferences && field.blockReferences) {\n for (const blockOrReference of field.blockReferences) {\n if (typeof blockOrReference === 'string') {\n block = configBlockReferences.find((b) => b.slug === newBlockData.blockType)\n } else {\n block = blockOrReference\n }\n }\n } else if (field.blocks) {\n block = field.blocks.find((b) => b.slug === newBlockData.blockType)\n }\n\n if (block) {\n const blockData =\n Array.isArray(existingValue) && existingValue[index]\n ? (existingValue[index] as JsonObject)\n : {}\n\n return mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newBlockData,\n docWithLocales: blockData,\n fields: block?.fields || [],\n parentIsLocalized,\n selectedLocales,\n })\n }\n\n return newBlockData\n })\n }\n }\n break\n }\n\n case 'group': {\n if (fieldAffectsData(field) && field.name) {\n // Named groups create a nested data structure\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const groupData: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue && typeof newValue[locale] === 'object') {\n groupData[locale] = newValue[locale]\n }\n }\n\n result[field.name] = groupData\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n } else if (typeof newValue === 'object' && !Array.isArray(newValue)) {\n // Non-localized group - still process children for any localized fields\n result[field.name] = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newValue,\n docWithLocales: existingValue || {},\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n }\n }\n }\n break\n }\n\n default: {\n // For all other data-affecting fields (text, number, select, etc.)\n if (fieldIsLocalized) {\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name] || {}\n\n // If localized, handle locale keys\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const merged: Record<string, unknown> = { ...existingValue }\n\n for (const locale of selectedLocales) {\n if (locale in newValue) {\n merged[locale] = newValue[locale]\n }\n }\n\n result[field.name] = merged\n } else if (parentIsLocalized) {\n // Child of localized parent - replace with new value\n result[field.name] = newValue\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n }\n } else if (parentIsLocalized) {\n result[field.name] = dataWithLocales[field.name]\n } else {\n result[field.name] =\n field.name in dataWithLocales\n ? dataWithLocales[field.name]\n : docWithLocales[field.name]\n }\n break\n }\n }\n } else {\n // Layout-only fields that don't affect data structure\n switch (field.type) {\n case 'collapsible':\n case 'group':\n case 'row': {\n // These pass through the same data level\n const merged = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales,\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n // Only copy fields that belong to this layout field to avoid overwriting already-processed fields\n const fieldNames = collectFlattenedFieldNames(field.fields)\n for (const name of fieldNames) {\n if (name in merged) {\n result[name] = merged[name]\n }\n }\n break\n }\n\n case 'tabs': {\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n // Named tabs create a nested data structure and can be localized\n const tabIsLocalized = fieldShouldBeLocalized({ field: tab, parentIsLocalized })\n\n if (tab.name in dataWithLocales) {\n const newValue = dataWithLocales[tab.name]\n const existingValue = docWithLocales[tab.name]\n\n if (tabIsLocalized) {\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const merged: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue && typeof newValue[locale] === 'object') {\n merged[locale] = newValue[locale]\n }\n }\n\n result[tab.name] = merged\n } else {\n // Preserve existing value if new value is not a valid object\n result[tab.name] = existingValue\n }\n } else if (typeof newValue === 'object' && !Array.isArray(newValue)) {\n // Non-localized tab - still process children for any localized fields\n result[tab.name] = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newValue as JsonObject,\n docWithLocales: existingValue || {},\n fields: tab.fields,\n parentIsLocalized,\n selectedLocales,\n })\n }\n }\n } else {\n // Unnamed tabs pass through the same data level\n const merged = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales,\n fields: tab.fields,\n parentIsLocalized,\n selectedLocales,\n })\n // Only copy fields that belong to this tab to avoid overwriting already-processed fields\n const tabFieldNames = collectFlattenedFieldNames(tab.fields)\n for (const name of tabFieldNames) {\n if (name in merged) {\n result[name] = merged[name]\n }\n }\n }\n }\n break\n }\n }\n }\n }\n\n return result\n}\n"],"names":["fieldAffectsData","fieldShouldBeLocalized","tabHasName","collectFlattenedFieldNames","fields","names","Set","field","add","name","Array","isArray","type","tab","tabs","mergeLocalizedData","configBlockReferences","dataWithLocales","docWithLocales","parentIsLocalized","selectedLocales","result","fieldIsLocalized","newValue","existingValue","updatedArray","locale","map","newItem","index","existingItem","updatedData","newBlockData","block","blockReferences","blockOrReference","find","b","slug","blockType","blocks","blockData","groupData","merged","fieldNames","tabIsLocalized","tabFieldNames"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/mergeLocalizedData.ts"],"sourcesContent":["import type { Block, Field, FlattenedBlock } from '../fields/config/types.js'\nimport type { SanitizedConfig } from '../index.js'\nimport type { JsonObject } from '../types/index.js'\n\nimport { fieldAffectsData, fieldShouldBeLocalized, tabHasName } from '../fields/config/types.js'\n\n/**\n * Collects field names at the current data level, recursing through pass-through fields\n * (row, collapsible, unnamed group, unnamed tab) but stopping at named fields.\n */\nfunction collectFlattenedFieldNames(fields: Field[]): Set<string> {\n const names = new Set<string>()\n for (const field of fields) {\n if (fieldAffectsData(field)) {\n names.add(field.name)\n } else if ('fields' in field && Array.isArray(field.fields)) {\n // Pass-through fields (row, collapsible, unnamed group)\n for (const name of collectFlattenedFieldNames(field.fields)) {\n names.add(name)\n }\n } else if (field.type === 'tabs') {\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n names.add(tab.name)\n } else {\n for (const name of collectFlattenedFieldNames(tab.fields)) {\n names.add(name)\n }\n }\n }\n }\n }\n return names\n}\n\ntype MergeDataToSelectedLocalesArgs = {\n configBlockReferences: SanitizedConfig['blocks']\n dataWithLocales: JsonObject\n docWithLocales: JsonObject\n fields: Field[]\n parentIsLocalized?: boolean\n selectedLocales: string[]\n}\n\n/**\n * Merges data from dataWithLocales onto docWithLocales for specified locales.\n * For localized fields, merges only the specified locales while preserving others.\n * For non-localized fields, keeps existing values from docWithLocales unchanged.\n * Returns a new object without mutating the original.\n */\nexport function mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales,\n fields,\n parentIsLocalized = false,\n selectedLocales,\n}: MergeDataToSelectedLocalesArgs): JsonObject {\n if (!docWithLocales || typeof docWithLocales !== 'object') {\n return dataWithLocales || docWithLocales\n }\n\n const result: JsonObject = { ...docWithLocales }\n\n for (const field of fields) {\n if (fieldAffectsData(field)) {\n // If the parent is localized, all children are inherently \"localized\"\n if (parentIsLocalized && dataWithLocales[field.name]) {\n result[field.name] = dataWithLocales[field.name]\n continue\n }\n\n const fieldIsLocalized = fieldShouldBeLocalized({ field, parentIsLocalized })\n\n switch (field.type) {\n case 'array': {\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n // If localized, handle locale keys\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const updatedArray: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue) {\n updatedArray[locale] = newValue[locale]\n }\n }\n\n result[field.name] = updatedArray\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n } else if (Array.isArray(newValue)) {\n // Non-localized array - still process children for any localized fields\n result[field.name] = newValue.map((newItem: JsonObject, index: number) => {\n const existingItem = existingValue?.[index] || {}\n\n return mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newItem,\n docWithLocales: existingItem,\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n })\n }\n }\n break\n }\n\n case 'blocks': {\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n // If localized, handle locale keys\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const updatedData: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue) {\n updatedData[locale] = newValue[locale]\n }\n }\n\n result[field.name] = updatedData\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n } else if (Array.isArray(newValue)) {\n // Non-localized blocks - still process children for any localized fields\n result[field.name] = newValue.map((newBlockData: JsonObject, index: number) => {\n let block: Block | FlattenedBlock | undefined\n if (configBlockReferences && field.blockReferences) {\n for (const blockOrReference of field.blockReferences) {\n if (typeof blockOrReference === 'string') {\n block = configBlockReferences.find((b) => b.slug === newBlockData.blockType)\n } else {\n block = blockOrReference\n }\n }\n } else if (field.blocks) {\n block = field.blocks.find((b) => b.slug === newBlockData.blockType)\n }\n\n if (block) {\n const blockData =\n Array.isArray(existingValue) && existingValue[index]\n ? (existingValue[index] as JsonObject)\n : {}\n\n const merged = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newBlockData,\n docWithLocales: blockData,\n fields: block?.fields || [],\n parentIsLocalized,\n selectedLocales,\n })\n\n // blockType, id, blockName are set by Payload internally\n // and not part of block.fields, so they must be preserved explicitly\n merged.blockType = newBlockData.blockType\n merged.id = newBlockData.id\n merged.blockName = newBlockData.blockName\n\n return merged\n }\n\n return newBlockData\n })\n }\n }\n break\n }\n\n case 'group': {\n if (fieldAffectsData(field) && field.name) {\n // Named groups create a nested data structure\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const groupData: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue && typeof newValue[locale] === 'object') {\n groupData[locale] = newValue[locale]\n }\n }\n\n result[field.name] = groupData\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n } else if (typeof newValue === 'object' && !Array.isArray(newValue)) {\n // Non-localized group - still process children for any localized fields\n result[field.name] = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newValue,\n docWithLocales: existingValue || {},\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n }\n }\n }\n break\n }\n\n default: {\n // For all other data-affecting fields (text, number, select, etc.)\n if (fieldIsLocalized) {\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name] || {}\n\n // If localized, handle locale keys\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const merged: Record<string, unknown> = { ...existingValue }\n\n for (const locale of selectedLocales) {\n if (locale in newValue) {\n merged[locale] = newValue[locale]\n }\n }\n\n result[field.name] = merged\n } else if (parentIsLocalized) {\n // Child of localized parent - replace with new value\n result[field.name] = newValue\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n }\n } else if (parentIsLocalized) {\n result[field.name] = dataWithLocales[field.name]\n } else {\n result[field.name] =\n field.name in dataWithLocales\n ? dataWithLocales[field.name]\n : docWithLocales[field.name]\n }\n break\n }\n }\n } else {\n // Layout-only fields that don't affect data structure\n switch (field.type) {\n case 'collapsible':\n case 'group':\n case 'row': {\n // These pass through the same data level\n const merged = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales,\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n // Only copy fields that belong to this layout field to avoid overwriting already-processed fields\n const fieldNames = collectFlattenedFieldNames(field.fields)\n for (const name of fieldNames) {\n if (name in merged) {\n result[name] = merged[name]\n }\n }\n break\n }\n\n case 'tabs': {\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n // Named tabs create a nested data structure and can be localized\n const tabIsLocalized = fieldShouldBeLocalized({ field: tab, parentIsLocalized })\n\n if (tab.name in dataWithLocales) {\n const newValue = dataWithLocales[tab.name]\n const existingValue = docWithLocales[tab.name]\n\n if (tabIsLocalized) {\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const merged: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue && typeof newValue[locale] === 'object') {\n merged[locale] = newValue[locale]\n }\n }\n\n result[tab.name] = merged\n } else {\n // Preserve existing value if new value is not a valid object\n result[tab.name] = existingValue\n }\n } else if (typeof newValue === 'object' && !Array.isArray(newValue)) {\n // Non-localized tab - still process children for any localized fields\n result[tab.name] = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newValue as JsonObject,\n docWithLocales: existingValue || {},\n fields: tab.fields,\n parentIsLocalized,\n selectedLocales,\n })\n }\n }\n } else {\n // Unnamed tabs pass through the same data level\n const merged = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales,\n fields: tab.fields,\n parentIsLocalized,\n selectedLocales,\n })\n // Only copy fields that belong to this tab to avoid overwriting already-processed fields\n const tabFieldNames = collectFlattenedFieldNames(tab.fields)\n for (const name of tabFieldNames) {\n if (name in merged) {\n result[name] = merged[name]\n }\n }\n }\n }\n break\n }\n }\n }\n }\n\n return result\n}\n"],"names":["fieldAffectsData","fieldShouldBeLocalized","tabHasName","collectFlattenedFieldNames","fields","names","Set","field","add","name","Array","isArray","type","tab","tabs","mergeLocalizedData","configBlockReferences","dataWithLocales","docWithLocales","parentIsLocalized","selectedLocales","result","fieldIsLocalized","newValue","existingValue","updatedArray","locale","map","newItem","index","existingItem","updatedData","newBlockData","block","blockReferences","blockOrReference","find","b","slug","blockType","blocks","blockData","merged","id","blockName","groupData","fieldNames","tabIsLocalized","tabFieldNames"],"mappings":"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"}
|
|
@@ -940,6 +940,169 @@ describe('mergeLocalizedData', ()=>{
|
|
|
940
940
|
});
|
|
941
941
|
});
|
|
942
942
|
});
|
|
943
|
+
describe('block metadata preservation', ()=>{
|
|
944
|
+
it('should preserve blockType, id, and blockName when existing doc has no blocks', ()=>{
|
|
945
|
+
// Reproduces the bug where autosave creates a doc without blocks,
|
|
946
|
+
// then blocks are added and publishSpecificLocale drops metadata
|
|
947
|
+
const fields = [
|
|
948
|
+
{
|
|
949
|
+
name: 'layout',
|
|
950
|
+
type: 'blocks',
|
|
951
|
+
blocks: [
|
|
952
|
+
{
|
|
953
|
+
slug: 'content',
|
|
954
|
+
fields: [
|
|
955
|
+
{
|
|
956
|
+
name: 'richText',
|
|
957
|
+
type: 'richText',
|
|
958
|
+
localized: true
|
|
959
|
+
}
|
|
960
|
+
]
|
|
961
|
+
}
|
|
962
|
+
]
|
|
963
|
+
}
|
|
964
|
+
];
|
|
965
|
+
// Main doc has no blocks (autosave wrote before blocks were added)
|
|
966
|
+
const docWithLocales = {};
|
|
967
|
+
const dataWithLocales = {
|
|
968
|
+
layout: [
|
|
969
|
+
{
|
|
970
|
+
blockType: 'content',
|
|
971
|
+
id: 'abc123',
|
|
972
|
+
blockName: 'My Content Block',
|
|
973
|
+
richText: {
|
|
974
|
+
en: 'Hello'
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
]
|
|
978
|
+
};
|
|
979
|
+
const result = mergeLocalizedData({
|
|
980
|
+
configBlockReferences: [],
|
|
981
|
+
dataWithLocales,
|
|
982
|
+
docWithLocales,
|
|
983
|
+
fields,
|
|
984
|
+
selectedLocales: [
|
|
985
|
+
'en'
|
|
986
|
+
]
|
|
987
|
+
});
|
|
988
|
+
expect(result.layout).toHaveLength(1);
|
|
989
|
+
expect(result.layout[0].blockType).toBe('content');
|
|
990
|
+
expect(result.layout[0].id).toBe('abc123');
|
|
991
|
+
expect(result.layout[0].blockName).toBe('My Content Block');
|
|
992
|
+
});
|
|
993
|
+
it('should preserve blockType and id when existing doc has undefined for block field', ()=>{
|
|
994
|
+
const fields = [
|
|
995
|
+
{
|
|
996
|
+
name: 'layout',
|
|
997
|
+
type: 'blocks',
|
|
998
|
+
blocks: [
|
|
999
|
+
{
|
|
1000
|
+
slug: 'text',
|
|
1001
|
+
fields: [
|
|
1002
|
+
{
|
|
1003
|
+
name: 'text',
|
|
1004
|
+
type: 'text',
|
|
1005
|
+
localized: true
|
|
1006
|
+
}
|
|
1007
|
+
]
|
|
1008
|
+
}
|
|
1009
|
+
]
|
|
1010
|
+
}
|
|
1011
|
+
];
|
|
1012
|
+
// existingValue is undefined (field not present in existing doc)
|
|
1013
|
+
const docWithLocales = {
|
|
1014
|
+
layout: undefined
|
|
1015
|
+
};
|
|
1016
|
+
const dataWithLocales = {
|
|
1017
|
+
layout: [
|
|
1018
|
+
{
|
|
1019
|
+
blockType: 'text',
|
|
1020
|
+
id: 'def456',
|
|
1021
|
+
text: {
|
|
1022
|
+
en: 'English text',
|
|
1023
|
+
es: 'Spanish text'
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
]
|
|
1027
|
+
};
|
|
1028
|
+
const result = mergeLocalizedData({
|
|
1029
|
+
configBlockReferences: [],
|
|
1030
|
+
dataWithLocales,
|
|
1031
|
+
docWithLocales,
|
|
1032
|
+
fields,
|
|
1033
|
+
selectedLocales: [
|
|
1034
|
+
'en'
|
|
1035
|
+
]
|
|
1036
|
+
});
|
|
1037
|
+
expect(result.layout).toHaveLength(1);
|
|
1038
|
+
expect(result.layout[0].blockType).toBe('text');
|
|
1039
|
+
expect(result.layout[0].id).toBe('def456');
|
|
1040
|
+
expect(result.layout[0].text).toEqual({
|
|
1041
|
+
en: 'English text'
|
|
1042
|
+
});
|
|
1043
|
+
});
|
|
1044
|
+
it('should preserve blockType when existing doc already has blocks', ()=>{
|
|
1045
|
+
// Ensures the fix doesn't break the happy path
|
|
1046
|
+
const fields = [
|
|
1047
|
+
{
|
|
1048
|
+
name: 'layout',
|
|
1049
|
+
type: 'blocks',
|
|
1050
|
+
blocks: [
|
|
1051
|
+
{
|
|
1052
|
+
slug: 'content',
|
|
1053
|
+
fields: [
|
|
1054
|
+
{
|
|
1055
|
+
name: 'body',
|
|
1056
|
+
type: 'text',
|
|
1057
|
+
localized: true
|
|
1058
|
+
}
|
|
1059
|
+
]
|
|
1060
|
+
}
|
|
1061
|
+
]
|
|
1062
|
+
}
|
|
1063
|
+
];
|
|
1064
|
+
const docWithLocales = {
|
|
1065
|
+
layout: [
|
|
1066
|
+
{
|
|
1067
|
+
blockType: 'content',
|
|
1068
|
+
id: 'existing-id',
|
|
1069
|
+
body: {
|
|
1070
|
+
en: 'Old English',
|
|
1071
|
+
es: 'Old Spanish'
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
]
|
|
1075
|
+
};
|
|
1076
|
+
const dataWithLocales = {
|
|
1077
|
+
layout: [
|
|
1078
|
+
{
|
|
1079
|
+
blockType: 'content',
|
|
1080
|
+
id: 'existing-id',
|
|
1081
|
+
body: {
|
|
1082
|
+
en: 'New English',
|
|
1083
|
+
es: 'New Spanish'
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
]
|
|
1087
|
+
};
|
|
1088
|
+
const result = mergeLocalizedData({
|
|
1089
|
+
configBlockReferences: [],
|
|
1090
|
+
dataWithLocales,
|
|
1091
|
+
docWithLocales,
|
|
1092
|
+
fields,
|
|
1093
|
+
selectedLocales: [
|
|
1094
|
+
'en'
|
|
1095
|
+
]
|
|
1096
|
+
});
|
|
1097
|
+
expect(result.layout).toHaveLength(1);
|
|
1098
|
+
expect(result.layout[0].blockType).toBe('content');
|
|
1099
|
+
expect(result.layout[0].id).toBe('existing-id');
|
|
1100
|
+
expect(result.layout[0].body).toEqual({
|
|
1101
|
+
en: 'New English',
|
|
1102
|
+
es: 'Old Spanish'
|
|
1103
|
+
});
|
|
1104
|
+
});
|
|
1105
|
+
});
|
|
943
1106
|
});
|
|
944
1107
|
|
|
945
1108
|
//# sourceMappingURL=mergeLocalizedData.spec.js.map
|