@sequoialabs/payload-plugin-reversia 0.1.5 → 0.1.6

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.
@@ -179,16 +179,23 @@ function describeTopLevelField(field) {
179
179
  }
180
180
  // Structured wrapper: group / array / blocks. Walk inside to collect
181
181
  // localized descendant leaves; emit a container only if any were found.
182
+ //
183
+ // When the top-level field itself is `localized: true`, ALL its inner
184
+ // translatable fields are inherently locale-specific (the whole container
185
+ // is stored per-locale). Payload may strip `localized: true` from inner
186
+ // fields in this case, so we pass `parentIsLocalized` to treat them as
187
+ // localized regardless.
188
+ const fieldIsLocalized = isLocalized(field);
182
189
  const innerLeaves = [];
183
190
  if (isGroupLikeField(field)) {
184
- collectLeaves(field.fields, [], innerLeaves);
191
+ collectLeaves(field.fields, [], innerLeaves, fieldIsLocalized);
185
192
  }
186
193
  else if (isArrayField(field)) {
187
- collectLeaves(field.fields, [{ kind: 'iterate' }], innerLeaves);
194
+ collectLeaves(field.fields, [{ kind: 'iterate' }], innerLeaves, fieldIsLocalized);
188
195
  }
189
196
  else if (isBlocksField(field)) {
190
197
  for (const block of field.blocks) {
191
- collectLeaves(block.fields, [{ kind: 'iterateBlock', blockSlug: block.slug }], innerLeaves);
198
+ collectLeaves(block.fields, [{ kind: 'iterateBlock', blockSlug: block.slug }], innerLeaves, fieldIsLocalized);
192
199
  }
193
200
  }
194
201
  else {
@@ -211,7 +218,7 @@ function describeTopLevelField(field) {
211
218
  hasRequiredLeaf: true,
212
219
  };
213
220
  }
214
- function collectLeaves(fields, parentSegments, out) {
221
+ function collectLeaves(fields, parentSegments, out, parentIsLocalized = false) {
215
222
  for (const field of fields) {
216
223
  if (!isNamed(field)) {
217
224
  if (isTabsField(field)) {
@@ -219,19 +226,23 @@ function collectLeaves(fields, parentSegments, out) {
219
226
  const tabSegments = 'name' in tab && typeof tab.name === 'string' && tab.name.length > 0
220
227
  ? [...parentSegments, { kind: 'key', name: tab.name }]
221
228
  : parentSegments;
222
- collectLeaves(tab.fields, tabSegments, out);
229
+ collectLeaves(tab.fields, tabSegments, out, parentIsLocalized);
223
230
  }
224
231
  }
225
232
  if ((field.type === 'row' || field.type === 'collapsible') &&
226
233
  'fields' in field &&
227
234
  Array.isArray(field.fields)) {
228
- collectLeaves(field.fields, parentSegments, out);
235
+ collectLeaves(field.fields, parentSegments, out, parentIsLocalized);
229
236
  }
230
237
  continue;
231
238
  }
232
239
  const segments = [...parentSegments, { kind: 'key', name: field.name }];
233
240
  const reversia = getReversiaCustom(field);
234
241
  const localized = isLocalized(field);
242
+ // Scalars (text, textarea, etc.) must be explicitly `localized: true` to
243
+ // be treated as translatable. Scalars inside a localized parent that
244
+ // aren't marked localized are structural (keys, enums) — translating
245
+ // "who" to "qui" would break app logic.
235
246
  if (localized && isScalarPayloadType(field.type)) {
236
247
  out.push({
237
248
  segments,
@@ -241,7 +252,12 @@ function collectLeaves(fields, parentSegments, out) {
241
252
  });
242
253
  continue;
243
254
  }
244
- if (localized && (field.type === 'richText' || field.type === 'json')) {
255
+ // RichText/json fields inherit localized status from their parent. Payload
256
+ // may strip `localized: true` from inner fields when the parent container
257
+ // is already localized (the whole container is per-locale, so inner
258
+ // localization is redundant). These are always translatable content.
259
+ const effectivelyLocalized = localized || parentIsLocalized;
260
+ if (effectivelyLocalized && (field.type === 'richText' || field.type === 'json')) {
245
261
  out.push({
246
262
  segments,
247
263
  kind: 'json',
@@ -251,16 +267,17 @@ function collectLeaves(fields, parentSegments, out) {
251
267
  continue;
252
268
  }
253
269
  if (isGroupLikeField(field)) {
254
- collectLeaves(field.fields, segments, out);
270
+ collectLeaves(field.fields, segments, out, parentIsLocalized);
255
271
  continue;
256
272
  }
257
273
  if (isArrayField(field)) {
258
- collectLeaves(field.fields, [...segments, { kind: 'iterate' }], out);
274
+ collectLeaves(field.fields, [...segments, { kind: 'iterate' }], out, parentIsLocalized || isLocalized(field));
259
275
  continue;
260
276
  }
261
277
  if (isBlocksField(field)) {
278
+ const blocksLocalized = parentIsLocalized || isLocalized(field);
262
279
  for (const block of field.blocks) {
263
- collectLeaves(block.fields, [...segments, { kind: 'iterateBlock', blockSlug: block.slug }], out);
280
+ collectLeaves(block.fields, [...segments, { kind: 'iterateBlock', blockSlug: block.slug }], out, blocksLocalized);
264
281
  }
265
282
  }
266
283
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sequoialabs/payload-plugin-reversia",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "author": {
5
5
  "name": "Jean Walrave",
6
6
  "email": "contact@reversia.tech",