@payloadcms/plugin-import-export 4.0.0-internal.b8e7c89 → 4.0.0-internal.bf4bcce

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 (146) hide show
  1. package/dist/components/CollectionField/index.d.ts +3 -2
  2. package/dist/components/CollectionField/index.d.ts.map +1 -1
  3. package/dist/components/CollectionField/index.js.map +1 -1
  4. package/dist/components/ExportListMenuItem/index.d.ts.map +1 -1
  5. package/dist/components/ExportListMenuItem/index.js +14 -12
  6. package/dist/components/ExportListMenuItem/index.js.map +1 -1
  7. package/dist/components/ExportPreview/index.css +0 -3
  8. package/dist/components/ExportPreview/index.d.ts.map +1 -1
  9. package/dist/components/ExportPreview/index.js +11 -1
  10. package/dist/components/ExportPreview/index.js.map +1 -1
  11. package/dist/components/FieldsToExport/index.d.ts +3 -2
  12. package/dist/components/FieldsToExport/index.d.ts.map +1 -1
  13. package/dist/components/FieldsToExport/index.js +18 -15
  14. package/dist/components/FieldsToExport/index.js.map +1 -1
  15. package/dist/components/FieldsToExport/reduceFields.d.ts +6 -0
  16. package/dist/components/FieldsToExport/reduceFields.d.ts.map +1 -1
  17. package/dist/components/FieldsToExport/reduceFields.js +4 -0
  18. package/dist/components/FieldsToExport/reduceFields.js.map +1 -1
  19. package/dist/components/FormatField/index.d.ts +3 -2
  20. package/dist/components/FormatField/index.d.ts.map +1 -1
  21. package/dist/components/FormatField/index.js.map +1 -1
  22. package/dist/components/ImportListMenuItem/index.d.ts.map +1 -1
  23. package/dist/components/ImportListMenuItem/index.js +14 -12
  24. package/dist/components/ImportListMenuItem/index.js.map +1 -1
  25. package/dist/components/ImportPreview/index.css +0 -3
  26. package/dist/components/ImportPreview/index.d.ts.map +1 -1
  27. package/dist/components/ImportPreview/index.js +27 -8
  28. package/dist/components/ImportPreview/index.js.map +1 -1
  29. package/dist/components/LimitField/index.d.ts +3 -2
  30. package/dist/components/LimitField/index.d.ts.map +1 -1
  31. package/dist/components/LimitField/index.js.map +1 -1
  32. package/dist/components/LocaleField/index.d.ts +3 -2
  33. package/dist/components/LocaleField/index.d.ts.map +1 -1
  34. package/dist/components/LocaleField/index.js.map +1 -1
  35. package/dist/components/Page/index.d.ts +3 -2
  36. package/dist/components/Page/index.d.ts.map +1 -1
  37. package/dist/components/Page/index.js.map +1 -1
  38. package/dist/components/RelationshipCell/getRelationshipGroupKey.d.ts +7 -0
  39. package/dist/components/RelationshipCell/getRelationshipGroupKey.d.ts.map +1 -0
  40. package/dist/components/RelationshipCell/getRelationshipGroupKey.js +3 -0
  41. package/dist/components/RelationshipCell/getRelationshipGroupKey.js.map +1 -0
  42. package/dist/components/RelationshipCell/getRelationshipGroups.d.ts +43 -0
  43. package/dist/components/RelationshipCell/getRelationshipGroups.d.ts.map +1 -0
  44. package/dist/components/RelationshipCell/getRelationshipGroups.js +109 -0
  45. package/dist/components/RelationshipCell/getRelationshipGroups.js.map +1 -0
  46. package/dist/components/RelationshipCell/index.css +30 -0
  47. package/dist/components/RelationshipCell/index.d.ts +15 -0
  48. package/dist/components/RelationshipCell/index.d.ts.map +1 -0
  49. package/dist/components/RelationshipCell/index.js +57 -0
  50. package/dist/components/RelationshipCell/index.js.map +1 -0
  51. package/dist/components/SortBy/index.d.ts +3 -2
  52. package/dist/components/SortBy/index.d.ts.map +1 -1
  53. package/dist/components/SortBy/index.js.map +1 -1
  54. package/dist/components/SortOrder/index.d.ts +3 -2
  55. package/dist/components/SortOrder/index.d.ts.map +1 -1
  56. package/dist/components/SortOrder/index.js.map +1 -1
  57. package/dist/export/batchProcessor.d.ts +2 -1
  58. package/dist/export/batchProcessor.d.ts.map +1 -1
  59. package/dist/export/batchProcessor.js +6 -2
  60. package/dist/export/batchProcessor.js.map +1 -1
  61. package/dist/export/createExport.d.ts +2 -0
  62. package/dist/export/createExport.d.ts.map +1 -1
  63. package/dist/export/createExport.js +6 -1
  64. package/dist/export/createExport.js.map +1 -1
  65. package/dist/export/getCreateExportCollectionTask.d.ts.map +1 -1
  66. package/dist/export/getCreateExportCollectionTask.js +11 -0
  67. package/dist/export/getCreateExportCollectionTask.js.map +1 -1
  68. package/dist/export/getExportCollection.d.ts.map +1 -1
  69. package/dist/export/getExportCollection.js +5 -0
  70. package/dist/export/getExportCollection.js.map +1 -1
  71. package/dist/export/handleDownload.d.ts.map +1 -1
  72. package/dist/export/handleDownload.js +7 -3
  73. package/dist/export/handleDownload.js.map +1 -1
  74. package/dist/export/handlePreview.d.ts.map +1 -1
  75. package/dist/export/handlePreview.js +23 -4
  76. package/dist/export/handlePreview.js.map +1 -1
  77. package/dist/exports/types.d.ts +1 -1
  78. package/dist/exports/types.d.ts.map +1 -1
  79. package/dist/exports/types.js.map +1 -1
  80. package/dist/import/batchProcessor.d.ts +2 -1
  81. package/dist/import/batchProcessor.d.ts.map +1 -1
  82. package/dist/import/batchProcessor.js +15 -8
  83. package/dist/import/batchProcessor.js.map +1 -1
  84. package/dist/import/createImport.d.ts +3 -2
  85. package/dist/import/createImport.d.ts.map +1 -1
  86. package/dist/import/createImport.js +8 -1
  87. package/dist/import/createImport.js.map +1 -1
  88. package/dist/import/getCreateImportCollectionTask.d.ts.map +1 -1
  89. package/dist/import/getCreateImportCollectionTask.js +5 -2
  90. package/dist/import/getCreateImportCollectionTask.js.map +1 -1
  91. package/dist/import/getImportCollection.d.ts.map +1 -1
  92. package/dist/import/getImportCollection.js +2 -0
  93. package/dist/import/getImportCollection.js.map +1 -1
  94. package/dist/import/handlePreview.d.ts.map +1 -1
  95. package/dist/import/handlePreview.js +5 -1
  96. package/dist/import/handlePreview.js.map +1 -1
  97. package/dist/types.d.ts +17 -1
  98. package/dist/types.d.ts.map +1 -1
  99. package/dist/types.js.map +1 -1
  100. package/dist/utilities/getExportFieldFunctions.js +64 -27
  101. package/dist/utilities/getExportFieldFunctions.js.map +1 -1
  102. package/dist/utilities/getSelect.d.ts.map +1 -1
  103. package/dist/utilities/getSelect.js +4 -2
  104. package/dist/utilities/getSelect.js.map +1 -1
  105. package/dist/utilities/getSubmittedFormValues.d.ts +12 -0
  106. package/dist/utilities/getSubmittedFormValues.d.ts.map +1 -0
  107. package/dist/utilities/getSubmittedFormValues.js +24 -0
  108. package/dist/utilities/getSubmittedFormValues.js.map +1 -0
  109. package/dist/utilities/setNestedValue.d.ts.map +1 -1
  110. package/dist/utilities/setNestedValue.js +20 -6
  111. package/dist/utilities/setNestedValue.js.map +1 -1
  112. package/package.json +10 -10
  113. package/dist/components/FieldsToExport/reduceFields.spec.js +0 -239
  114. package/dist/components/FieldsToExport/reduceFields.spec.js.map +0 -1
  115. package/dist/utilities/applyFieldHooks.spec.js +0 -205
  116. package/dist/utilities/applyFieldHooks.spec.js.map +0 -1
  117. package/dist/utilities/buildDisabledFieldRegex.spec.js +0 -64
  118. package/dist/utilities/buildDisabledFieldRegex.spec.js.map +0 -1
  119. package/dist/utilities/fieldPath.d.ts +0 -2
  120. package/dist/utilities/fieldPath.d.ts.map +0 -1
  121. package/dist/utilities/fieldPath.js +0 -8
  122. package/dist/utilities/fieldPath.js.map +0 -1
  123. package/dist/utilities/fieldToRegex.spec.js +0 -151
  124. package/dist/utilities/fieldToRegex.spec.js.map +0 -1
  125. package/dist/utilities/filterToSelectedFields.spec.js +0 -204
  126. package/dist/utilities/filterToSelectedFields.spec.js.map +0 -1
  127. package/dist/utilities/flattenObject.spec.js +0 -158
  128. package/dist/utilities/flattenObject.spec.js.map +0 -1
  129. package/dist/utilities/getExportFieldFunctions.spec.js +0 -50
  130. package/dist/utilities/getExportFieldFunctions.spec.js.map +0 -1
  131. package/dist/utilities/getImportFieldFunctions.spec.js +0 -167
  132. package/dist/utilities/getImportFieldFunctions.spec.js.map +0 -1
  133. package/dist/utilities/getSchemaColumns.spec.js +0 -157
  134. package/dist/utilities/getSchemaColumns.spec.js.map +0 -1
  135. package/dist/utilities/getSelect.spec.js +0 -70
  136. package/dist/utilities/getSelect.spec.js.map +0 -1
  137. package/dist/utilities/parseCSV.spec.js +0 -195
  138. package/dist/utilities/parseCSV.spec.js.map +0 -1
  139. package/dist/utilities/processRichTextField.spec.js +0 -308
  140. package/dist/utilities/processRichTextField.spec.js.map +0 -1
  141. package/dist/utilities/setNestedValue.spec.js +0 -164
  142. package/dist/utilities/setNestedValue.spec.js.map +0 -1
  143. package/dist/utilities/siblingDoc.spec.js +0 -278
  144. package/dist/utilities/siblingDoc.spec.js.map +0 -1
  145. package/dist/utilities/unflattenObject.spec.js +0 -819
  146. package/dist/utilities/unflattenObject.spec.js.map +0 -1
@@ -1,308 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { processRichTextField } from './processRichTextField.js';
3
- // Minimal helpers to keep assertions readable
4
- const asRecord = (v)=>v;
5
- const asArray = (v)=>v;
6
- // ─── Fixtures ────────────────────────────────────────────────────────────────
7
- const textNode = (overrides = {})=>({
8
- detail: 0,
9
- format: 0,
10
- mode: 'normal',
11
- text: 'Hello',
12
- type: 'text',
13
- version: 1,
14
- ...overrides
15
- });
16
- const paragraphNode = (children = [
17
- textNode()
18
- ])=>({
19
- children,
20
- direction: 'ltr',
21
- format: '',
22
- indent: 0,
23
- type: 'paragraph',
24
- version: 1
25
- });
26
- const lexicalDoc = (children = [
27
- paragraphNode()
28
- ])=>({
29
- children,
30
- direction: 'ltr',
31
- format: '',
32
- indent: 0,
33
- type: 'root',
34
- version: 1
35
- });
36
- // ─── Primitive pass-through ──────────────────────────────────────────────────
37
- describe('processRichTextField — primitive pass-through', ()=>{
38
- it('should return null unchanged', ()=>{
39
- expect(processRichTextField(null)).toBeNull();
40
- });
41
- it('should return undefined unchanged', ()=>{
42
- expect(processRichTextField(undefined)).toBeUndefined();
43
- });
44
- it('should return a number unchanged', ()=>{
45
- expect(processRichTextField(42)).toBe(42);
46
- });
47
- it('should return false unchanged', ()=>{
48
- expect(processRichTextField(false)).toBe(false);
49
- });
50
- });
51
- // ─── String input (the recovered-from-missed-hook path) ─────────────────────
52
- describe('processRichTextField — JSON string input', ()=>{
53
- it('should parse a valid JSON string into an object', ()=>{
54
- const doc = lexicalDoc();
55
- expect(processRichTextField(JSON.stringify(doc))).toEqual(doc);
56
- });
57
- it('should return an unparseable string unchanged', ()=>{
58
- expect(processRichTextField('not json')).toBe('not json');
59
- });
60
- it('should return an empty string unchanged', ()=>{
61
- expect(processRichTextField('')).toBe('');
62
- });
63
- it('should parse a string and still convert numeric string properties', ()=>{
64
- const node = {
65
- type: 'text',
66
- detail: '0',
67
- format: '3',
68
- indent: '0',
69
- version: '1',
70
- text: 'hi'
71
- };
72
- const result = asRecord(processRichTextField(JSON.stringify(node)));
73
- expect(result.detail).toBe(0);
74
- expect(result.format).toBe(3);
75
- expect(result.indent).toBe(0);
76
- expect(result.version).toBe(1);
77
- });
78
- });
79
- // ─── Numeric property coercion ───────────────────────────────────────────────
80
- describe('processRichTextField — numeric property coercion', ()=>{
81
- it('should convert detail, format, indent, version from strings to numbers', ()=>{
82
- const input = textNode({
83
- detail: '0',
84
- format: '0',
85
- indent: '0',
86
- version: '1'
87
- });
88
- const result = asRecord(processRichTextField(input));
89
- expect(result.detail).toBe(0);
90
- expect(result.format).toBe(0);
91
- expect(result.indent).toBe(0);
92
- expect(result.version).toBe(1);
93
- });
94
- it('should convert start and value from strings to numbers (list/listitem nodes)', ()=>{
95
- const listItemNode = {
96
- type: 'listitem',
97
- start: '1',
98
- value: '2',
99
- version: '1'
100
- };
101
- const result = asRecord(processRichTextField(listItemNode));
102
- expect(result.start).toBe(1);
103
- expect(result.value).toBe(2);
104
- });
105
- it('should convert textFormat and textStyle from strings to numbers', ()=>{
106
- const input = {
107
- type: 'text',
108
- textFormat: '4',
109
- textStyle: '0',
110
- version: '1',
111
- text: 'x'
112
- };
113
- const result = asRecord(processRichTextField(input));
114
- expect(result.textFormat).toBe(4);
115
- expect(result.textStyle).toBe(0);
116
- });
117
- it('should leave a non-numeric string in a numeric-property slot unchanged', ()=>{
118
- // Lexical paragraph format can be "" (empty) or alignment strings
119
- const input = paragraphNode();
120
- const result = asRecord(processRichTextField(input));
121
- expect(result.format).toBe('');
122
- });
123
- it('should leave already-numeric values unchanged', ()=>{
124
- const input = textNode({
125
- detail: 0,
126
- format: 3,
127
- version: 1
128
- });
129
- const result = asRecord(processRichTextField(input));
130
- expect(result.detail).toBe(0);
131
- expect(result.format).toBe(3);
132
- expect(result.version).toBe(1);
133
- });
134
- it('should not convert boolean values on numeric-property keys', ()=>{
135
- const input = {
136
- type: 'custom',
137
- format: true,
138
- version: '1'
139
- };
140
- const result = asRecord(processRichTextField(input));
141
- expect(result.format).toBe(true);
142
- expect(result.version).toBe(1);
143
- });
144
- });
145
- // ─── Recursive children processing ──────────────────────────────────────────
146
- describe('processRichTextField — recursive children', ()=>{
147
- it('should recursively convert numeric strings inside children arrays', ()=>{
148
- const input = paragraphNode([
149
- textNode({
150
- detail: '0',
151
- format: '0',
152
- version: '1'
153
- })
154
- ]);
155
- const result = asRecord(processRichTextField(input));
156
- const child = asRecord(asArray(result.children)[0]);
157
- expect(child.detail).toBe(0);
158
- expect(child.format).toBe(0);
159
- expect(child.version).toBe(1);
160
- });
161
- it('should handle three levels of nesting (root → paragraph → text)', ()=>{
162
- const input = lexicalDoc([
163
- paragraphNode([
164
- textNode({
165
- version: '1',
166
- format: '2'
167
- })
168
- ])
169
- ]);
170
- const result = asRecord(processRichTextField(input));
171
- const paragraph = asRecord(asArray(result.children)[0]);
172
- const text = asRecord(asArray(paragraph.children)[0]);
173
- expect(text.version).toBe(1);
174
- expect(text.format).toBe(2);
175
- });
176
- it('should handle multiple children at the same level', ()=>{
177
- const input = lexicalDoc([
178
- paragraphNode([
179
- textNode({
180
- text: 'Bold',
181
- format: '1'
182
- }),
183
- textNode({
184
- text: ' normal',
185
- format: '0'
186
- })
187
- ]),
188
- paragraphNode([
189
- textNode({
190
- text: 'Second para',
191
- version: '1'
192
- })
193
- ])
194
- ]);
195
- const result = asRecord(processRichTextField(input));
196
- const firstPara = asRecord(asArray(result.children)[0]);
197
- const secondPara = asRecord(asArray(result.children)[1]);
198
- const bold = asRecord(asArray(firstPara.children)[0]);
199
- const normal = asRecord(asArray(firstPara.children)[1]);
200
- const secondText = asRecord(asArray(secondPara.children)[0]);
201
- expect(bold.format).toBe(1);
202
- expect(normal.format).toBe(0);
203
- expect(secondText.version).toBe(1);
204
- });
205
- it('should skip null and non-object entries in children without throwing', ()=>{
206
- const input = {
207
- type: 'root',
208
- version: 1,
209
- children: [
210
- null,
211
- undefined,
212
- 'stray',
213
- textNode()
214
- ]
215
- };
216
- const result = asRecord(processRichTextField(input));
217
- const children = asArray(result.children);
218
- expect(children[0]).toBeNull();
219
- expect(children[1]).toBeUndefined();
220
- expect(children[2]).toBe('stray');
221
- expect(asRecord(children[3]).type).toBe('text');
222
- });
223
- });
224
- // ─── Nested non-children objects ─────────────────────────────────────────────
225
- describe('processRichTextField — nested non-children objects', ()=>{
226
- it('should recurse into plain nested objects (e.g. decorator node data)', ()=>{
227
- const input = {
228
- type: 'decorator',
229
- version: '1',
230
- data: {
231
- detail: '2',
232
- label: 'keep me'
233
- }
234
- };
235
- const result = asRecord(processRichTextField(input));
236
- const data = asRecord(result.data);
237
- expect(result.version).toBe(1);
238
- expect(data.detail).toBe(2);
239
- expect(data.label).toBe('keep me');
240
- });
241
- });
242
- // ─── Full Lexical document round-trips ───────────────────────────────────────
243
- describe('processRichTextField — full document', ()=>{
244
- it('should produce a stable result when called on an already-processed object', ()=>{
245
- const doc = lexicalDoc();
246
- const firstPass = processRichTextField(doc);
247
- const secondPass = processRichTextField(firstPass);
248
- expect(secondPass).toEqual(firstPass);
249
- });
250
- it('should fully round-trip a complex Lexical document serialised to JSON', ()=>{
251
- const doc = lexicalDoc([
252
- paragraphNode([
253
- textNode({
254
- text: 'Bold',
255
- format: '1',
256
- detail: '0',
257
- indent: '0',
258
- version: '1'
259
- }),
260
- textNode({
261
- text: ' normal',
262
- format: '0',
263
- version: '1'
264
- })
265
- ]),
266
- {
267
- type: 'list',
268
- listType: 'number',
269
- start: '1',
270
- version: '1',
271
- indent: '0',
272
- direction: 'ltr',
273
- children: [
274
- {
275
- type: 'listitem',
276
- value: '1',
277
- detail: '0',
278
- format: '0',
279
- version: '1',
280
- text: 'Item A'
281
- },
282
- {
283
- type: 'listitem',
284
- value: '2',
285
- detail: '0',
286
- format: '0',
287
- version: '1',
288
- text: 'Item B'
289
- }
290
- ]
291
- }
292
- ]);
293
- const result = asRecord(processRichTextField(JSON.stringify(doc)));
294
- const para = asRecord(asArray(result.children)[0]);
295
- const boldText = asRecord(asArray(para.children)[0]);
296
- expect(boldText.format).toBe(1);
297
- expect(boldText.detail).toBe(0);
298
- const list = asRecord(asArray(result.children)[1]);
299
- expect(list.start).toBe(1);
300
- expect(list.indent).toBe(0);
301
- const itemA = asRecord(asArray(list.children)[0]);
302
- const itemB = asRecord(asArray(list.children)[1]);
303
- expect(itemA.value).toBe(1);
304
- expect(itemB.value).toBe(2);
305
- });
306
- });
307
-
308
- //# sourceMappingURL=processRichTextField.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utilities/processRichTextField.spec.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport { processRichTextField } from './processRichTextField.js'\n\n// Minimal helpers to keep assertions readable\nconst asRecord = (v: unknown) => v as Record<string, unknown>\nconst asArray = (v: unknown) => v as unknown[]\n\n// ─── Fixtures ────────────────────────────────────────────────────────────────\n\nconst textNode = (overrides: Record<string, unknown> = {}) => ({\n detail: 0,\n format: 0,\n mode: 'normal',\n text: 'Hello',\n type: 'text',\n version: 1,\n ...overrides,\n})\n\nconst paragraphNode = (children: unknown[] = [textNode()]) => ({\n children,\n direction: 'ltr',\n format: '',\n indent: 0,\n type: 'paragraph',\n version: 1,\n})\n\nconst lexicalDoc = (children: unknown[] = [paragraphNode()]) => ({\n children,\n direction: 'ltr',\n format: '',\n indent: 0,\n type: 'root',\n version: 1,\n})\n\n// ─── Primitive pass-through ──────────────────────────────────────────────────\n\ndescribe('processRichTextField — primitive pass-through', () => {\n it('should return null unchanged', () => {\n expect(processRichTextField(null)).toBeNull()\n })\n\n it('should return undefined unchanged', () => {\n expect(processRichTextField(undefined)).toBeUndefined()\n })\n\n it('should return a number unchanged', () => {\n expect(processRichTextField(42)).toBe(42)\n })\n\n it('should return false unchanged', () => {\n expect(processRichTextField(false)).toBe(false)\n })\n})\n\n// ─── String input (the recovered-from-missed-hook path) ─────────────────────\n\ndescribe('processRichTextField — JSON string input', () => {\n it('should parse a valid JSON string into an object', () => {\n const doc = lexicalDoc()\n expect(processRichTextField(JSON.stringify(doc))).toEqual(doc)\n })\n\n it('should return an unparseable string unchanged', () => {\n expect(processRichTextField('not json')).toBe('not json')\n })\n\n it('should return an empty string unchanged', () => {\n expect(processRichTextField('')).toBe('')\n })\n\n it('should parse a string and still convert numeric string properties', () => {\n const node = { type: 'text', detail: '0', format: '3', indent: '0', version: '1', text: 'hi' }\n const result = asRecord(processRichTextField(JSON.stringify(node)))\n expect(result.detail).toBe(0)\n expect(result.format).toBe(3)\n expect(result.indent).toBe(0)\n expect(result.version).toBe(1)\n })\n})\n\n// ─── Numeric property coercion ───────────────────────────────────────────────\n\ndescribe('processRichTextField — numeric property coercion', () => {\n it('should convert detail, format, indent, version from strings to numbers', () => {\n const input = textNode({ detail: '0', format: '0', indent: '0', version: '1' })\n const result = asRecord(processRichTextField(input))\n expect(result.detail).toBe(0)\n expect(result.format).toBe(0)\n expect(result.indent).toBe(0)\n expect(result.version).toBe(1)\n })\n\n it('should convert start and value from strings to numbers (list/listitem nodes)', () => {\n const listItemNode = { type: 'listitem', start: '1', value: '2', version: '1' }\n const result = asRecord(processRichTextField(listItemNode))\n expect(result.start).toBe(1)\n expect(result.value).toBe(2)\n })\n\n it('should convert textFormat and textStyle from strings to numbers', () => {\n const input = { type: 'text', textFormat: '4', textStyle: '0', version: '1', text: 'x' }\n const result = asRecord(processRichTextField(input))\n expect(result.textFormat).toBe(4)\n expect(result.textStyle).toBe(0)\n })\n\n it('should leave a non-numeric string in a numeric-property slot unchanged', () => {\n // Lexical paragraph format can be \"\" (empty) or alignment strings\n const input = paragraphNode()\n const result = asRecord(processRichTextField(input))\n expect(result.format).toBe('')\n })\n\n it('should leave already-numeric values unchanged', () => {\n const input = textNode({ detail: 0, format: 3, version: 1 })\n const result = asRecord(processRichTextField(input))\n expect(result.detail).toBe(0)\n expect(result.format).toBe(3)\n expect(result.version).toBe(1)\n })\n\n it('should not convert boolean values on numeric-property keys', () => {\n const input = { type: 'custom', format: true, version: '1' }\n const result = asRecord(processRichTextField(input))\n expect(result.format).toBe(true)\n expect(result.version).toBe(1)\n })\n})\n\n// ─── Recursive children processing ──────────────────────────────────────────\n\ndescribe('processRichTextField — recursive children', () => {\n it('should recursively convert numeric strings inside children arrays', () => {\n const input = paragraphNode([textNode({ detail: '0', format: '0', version: '1' })])\n const result = asRecord(processRichTextField(input))\n const child = asRecord(asArray(result.children)[0])\n expect(child.detail).toBe(0)\n expect(child.format).toBe(0)\n expect(child.version).toBe(1)\n })\n\n it('should handle three levels of nesting (root → paragraph → text)', () => {\n const input = lexicalDoc([paragraphNode([textNode({ version: '1', format: '2' })])])\n const result = asRecord(processRichTextField(input))\n const paragraph = asRecord(asArray(result.children)[0])\n const text = asRecord(asArray(paragraph.children)[0])\n expect(text.version).toBe(1)\n expect(text.format).toBe(2)\n })\n\n it('should handle multiple children at the same level', () => {\n const input = lexicalDoc([\n paragraphNode([\n textNode({ text: 'Bold', format: '1' }),\n textNode({ text: ' normal', format: '0' }),\n ]),\n paragraphNode([textNode({ text: 'Second para', version: '1' })]),\n ])\n const result = asRecord(processRichTextField(input))\n const firstPara = asRecord(asArray(result.children)[0])\n const secondPara = asRecord(asArray(result.children)[1])\n const bold = asRecord(asArray(firstPara.children)[0])\n const normal = asRecord(asArray(firstPara.children)[1])\n const secondText = asRecord(asArray(secondPara.children)[0])\n expect(bold.format).toBe(1)\n expect(normal.format).toBe(0)\n expect(secondText.version).toBe(1)\n })\n\n it('should skip null and non-object entries in children without throwing', () => {\n const input = { type: 'root', version: 1, children: [null, undefined, 'stray', textNode()] }\n const result = asRecord(processRichTextField(input))\n const children = asArray(result.children)\n expect(children[0]).toBeNull()\n expect(children[1]).toBeUndefined()\n expect(children[2]).toBe('stray')\n expect(asRecord(children[3]).type).toBe('text')\n })\n})\n\n// ─── Nested non-children objects ─────────────────────────────────────────────\n\ndescribe('processRichTextField — nested non-children objects', () => {\n it('should recurse into plain nested objects (e.g. decorator node data)', () => {\n const input = {\n type: 'decorator',\n version: '1',\n data: { detail: '2', label: 'keep me' },\n }\n const result = asRecord(processRichTextField(input))\n const data = asRecord(result.data)\n expect(result.version).toBe(1)\n expect(data.detail).toBe(2)\n expect(data.label).toBe('keep me')\n })\n})\n\n// ─── Full Lexical document round-trips ───────────────────────────────────────\n\ndescribe('processRichTextField — full document', () => {\n it('should produce a stable result when called on an already-processed object', () => {\n const doc = lexicalDoc()\n const firstPass = processRichTextField(doc)\n const secondPass = processRichTextField(firstPass)\n expect(secondPass).toEqual(firstPass)\n })\n\n it('should fully round-trip a complex Lexical document serialised to JSON', () => {\n const doc = lexicalDoc([\n paragraphNode([\n textNode({ text: 'Bold', format: '1', detail: '0', indent: '0', version: '1' }),\n textNode({ text: ' normal', format: '0', version: '1' }),\n ]),\n {\n type: 'list',\n listType: 'number',\n start: '1',\n version: '1',\n indent: '0',\n direction: 'ltr',\n children: [\n { type: 'listitem', value: '1', detail: '0', format: '0', version: '1', text: 'Item A' },\n { type: 'listitem', value: '2', detail: '0', format: '0', version: '1', text: 'Item B' },\n ],\n },\n ])\n\n const result = asRecord(processRichTextField(JSON.stringify(doc)))\n\n const para = asRecord(asArray(result.children)[0])\n const boldText = asRecord(asArray(para.children)[0])\n expect(boldText.format).toBe(1)\n expect(boldText.detail).toBe(0)\n\n const list = asRecord(asArray(result.children)[1])\n expect(list.start).toBe(1)\n expect(list.indent).toBe(0)\n\n const itemA = asRecord(asArray(list.children)[0])\n const itemB = asRecord(asArray(list.children)[1])\n expect(itemA.value).toBe(1)\n expect(itemB.value).toBe(2)\n })\n})\n"],"names":["describe","expect","it","processRichTextField","asRecord","v","asArray","textNode","overrides","detail","format","mode","text","type","version","paragraphNode","children","direction","indent","lexicalDoc","toBeNull","undefined","toBeUndefined","toBe","doc","JSON","stringify","toEqual","node","result","input","listItemNode","start","value","textFormat","textStyle","child","paragraph","firstPara","secondPara","bold","normal","secondText","data","label","firstPass","secondPass","listType","para","boldText","list","itemA","itemB"],"mappings":"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"}
@@ -1,164 +0,0 @@
1
- import { APIError } from 'payload';
2
- import { describe, expect, it } from 'vitest';
3
- import { setNestedValue } from './setNestedValue.js';
4
- const unsupportedSegments = [
5
- '__proto__',
6
- 'constructor',
7
- 'prototype'
8
- ];
9
- const unsupportedPaths = unsupportedSegments.flatMap((segment)=>[
10
- `${segment}.value`,
11
- `group.${segment}.value`,
12
- `group.${segment}`,
13
- `items.${segment}.0.value`,
14
- `items.0.${segment}.value`,
15
- `items.0.${segment}`
16
- ]);
17
- describe('setNestedValue', ()=>{
18
- it.each(unsupportedPaths)('rejects invalid field path %s without changing the target', (path)=>{
19
- const target = {
20
- stable: {
21
- value: true
22
- }
23
- };
24
- const objectPrototypeBefore = Object.getOwnPropertyDescriptors(Object.prototype);
25
- const targetPrototypeBefore = Object.getPrototypeOf(target);
26
- try {
27
- setNestedValue(target, path, true);
28
- expect.fail('Expected setNestedValue to reject the invalid field path');
29
- } catch (error) {
30
- expect(error).toBeInstanceOf(APIError);
31
- if (error instanceof APIError) {
32
- expect(error.status).toBe(400);
33
- expect(error.isPublic).toBe(true);
34
- }
35
- }
36
- expect(target).toEqual({
37
- stable: {
38
- value: true
39
- }
40
- });
41
- expect(Object.getPrototypeOf(target)).toBe(targetPrototypeBefore);
42
- expect(Object.getOwnPropertyDescriptors(Object.prototype)).toEqual(objectPrototypeBefore);
43
- });
44
- it('rejects field paths with out-of-range array indexes', ()=>{
45
- const source = {
46
- items: [
47
- {
48
- value: true
49
- }
50
- ]
51
- };
52
- const target = {};
53
- expect(()=>setNestedValue(target, 'items.4294967294.value', true, source)).toThrow(APIError);
54
- expect(target).toEqual({
55
- items: []
56
- });
57
- });
58
- it('supports out-of-order array indexes that exist in the source document', ()=>{
59
- const source = {
60
- items: [
61
- {
62
- value: 'first'
63
- },
64
- {
65
- value: 'second'
66
- },
67
- {
68
- value: 'third'
69
- }
70
- ]
71
- };
72
- const target = {};
73
- setNestedValue(target, 'items.2.value', 'third', source);
74
- expect(target).toEqual({
75
- items: [
76
- undefined,
77
- undefined,
78
- {
79
- value: 'third'
80
- }
81
- ]
82
- });
83
- });
84
- it.each([
85
- '-1',
86
- '+1',
87
- '01',
88
- ' 1',
89
- '1 ',
90
- '1e2',
91
- '0x10',
92
- 'Infinity',
93
- '9007199254740992'
94
- ])('treats noncanonical numeric segment %s as an object key', (segment)=>{
95
- const target = {};
96
- setNestedValue(target, `items.${segment}.value`, 'example');
97
- expect(Array.isArray(target.items)).toBe(false);
98
- expect(target).toEqual({
99
- items: {
100
- [segment]: {
101
- value: 'example'
102
- }
103
- }
104
- });
105
- });
106
- it('builds nested objects and arrays', ()=>{
107
- const target = {};
108
- setNestedValue(target, 'group.items.0.title', 'first');
109
- setNestedValue(target, 'group.items.0.description', 'description');
110
- setNestedValue(target, 'group.items.1.title', 'second');
111
- expect(target).toEqual({
112
- group: {
113
- items: [
114
- {
115
- description: 'description',
116
- title: 'first'
117
- },
118
- {
119
- title: 'second'
120
- }
121
- ]
122
- }
123
- });
124
- const group = target.group;
125
- const items = group.items;
126
- expect(Object.getPrototypeOf(group)).toBeNull();
127
- expect(Array.isArray(items)).toBe(true);
128
- expect(Object.getPrototypeOf(items[0])).toBeNull();
129
- expect(Object.getPrototypeOf(items[1])).toBeNull();
130
- });
131
- it('supports nested arrays using numeric lookahead', ()=>{
132
- const target = {};
133
- setNestedValue(target, 'matrix.0.1.value', 'nested');
134
- expect(target).toEqual({
135
- matrix: [
136
- [
137
- undefined,
138
- {
139
- value: 'nested'
140
- }
141
- ]
142
- ]
143
- });
144
- });
145
- it('creates own containers instead of traversing inherited properties', ()=>{
146
- const inheritedGroup = {
147
- inherited: true
148
- };
149
- const target = Object.create({
150
- group: inheritedGroup
151
- });
152
- setNestedValue(target, 'group.value', 'own');
153
- expect(Object.prototype.hasOwnProperty.call(target, 'group')).toBe(true);
154
- expect(target.group).toEqual({
155
- value: 'own'
156
- });
157
- expect(Object.getPrototypeOf(target.group)).toBeNull();
158
- expect(inheritedGroup).toEqual({
159
- inherited: true
160
- });
161
- });
162
- });
163
-
164
- //# sourceMappingURL=setNestedValue.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utilities/setNestedValue.spec.ts"],"sourcesContent":["import { APIError } from 'payload'\nimport { describe, expect, it } from 'vitest'\n\nimport { setNestedValue } from './setNestedValue.js'\n\nconst unsupportedSegments = ['__proto__', 'constructor', 'prototype']\nconst unsupportedPaths = unsupportedSegments.flatMap((segment) => [\n `${segment}.value`,\n `group.${segment}.value`,\n `group.${segment}`,\n `items.${segment}.0.value`,\n `items.0.${segment}.value`,\n `items.0.${segment}`,\n])\n\ndescribe('setNestedValue', () => {\n it.each(unsupportedPaths)('rejects invalid field path %s without changing the target', (path) => {\n const target = { stable: { value: true } }\n const objectPrototypeBefore = Object.getOwnPropertyDescriptors(Object.prototype)\n const targetPrototypeBefore = Object.getPrototypeOf(target)\n\n try {\n setNestedValue(target, path, true)\n expect.fail('Expected setNestedValue to reject the invalid field path')\n } catch (error) {\n expect(error).toBeInstanceOf(APIError)\n\n if (error instanceof APIError) {\n expect(error.status).toBe(400)\n expect(error.isPublic).toBe(true)\n }\n }\n\n expect(target).toEqual({ stable: { value: true } })\n expect(Object.getPrototypeOf(target)).toBe(targetPrototypeBefore)\n expect(Object.getOwnPropertyDescriptors(Object.prototype)).toEqual(objectPrototypeBefore)\n })\n\n it('rejects field paths with out-of-range array indexes', () => {\n const source = { items: [{ value: true }] }\n const target: Record<string, unknown> = {}\n\n expect(() => setNestedValue(target, 'items.4294967294.value', true, source)).toThrow(APIError)\n expect(target).toEqual({ items: [] })\n })\n\n it('supports out-of-order array indexes that exist in the source document', () => {\n const source = { items: [{ value: 'first' }, { value: 'second' }, { value: 'third' }] }\n const target: Record<string, unknown> = {}\n\n setNestedValue(target, 'items.2.value', 'third', source)\n\n expect(target).toEqual({ items: [undefined, undefined, { value: 'third' }] })\n })\n\n it.each(['-1', '+1', '01', ' 1', '1 ', '1e2', '0x10', 'Infinity', '9007199254740992'])(\n 'treats noncanonical numeric segment %s as an object key',\n (segment) => {\n const target: Record<string, unknown> = {}\n\n setNestedValue(target, `items.${segment}.value`, 'example')\n\n expect(Array.isArray(target.items)).toBe(false)\n expect(target).toEqual({ items: { [segment]: { value: 'example' } } })\n },\n )\n\n it('builds nested objects and arrays', () => {\n const target: Record<string, unknown> = {}\n\n setNestedValue(target, 'group.items.0.title', 'first')\n setNestedValue(target, 'group.items.0.description', 'description')\n setNestedValue(target, 'group.items.1.title', 'second')\n\n expect(target).toEqual({\n group: {\n items: [{ description: 'description', title: 'first' }, { title: 'second' }],\n },\n })\n\n const group = target.group as Record<string, unknown>\n const items = group.items as Record<string, unknown>[]\n\n expect(Object.getPrototypeOf(group)).toBeNull()\n expect(Array.isArray(items)).toBe(true)\n expect(Object.getPrototypeOf(items[0])).toBeNull()\n expect(Object.getPrototypeOf(items[1])).toBeNull()\n })\n\n it('supports nested arrays using numeric lookahead', () => {\n const target: Record<string, unknown> = {}\n\n setNestedValue(target, 'matrix.0.1.value', 'nested')\n\n expect(target).toEqual({\n matrix: [[undefined, { value: 'nested' }]],\n })\n })\n\n it('creates own containers instead of traversing inherited properties', () => {\n const inheritedGroup = { inherited: true }\n const target = Object.create({ group: inheritedGroup }) as Record<string, unknown>\n\n setNestedValue(target, 'group.value', 'own')\n\n expect(Object.prototype.hasOwnProperty.call(target, 'group')).toBe(true)\n expect(target.group).toEqual({ value: 'own' })\n expect(Object.getPrototypeOf(target.group)).toBeNull()\n expect(inheritedGroup).toEqual({ inherited: true })\n })\n})\n"],"names":["APIError","describe","expect","it","setNestedValue","unsupportedSegments","unsupportedPaths","flatMap","segment","each","path","target","stable","value","objectPrototypeBefore","Object","getOwnPropertyDescriptors","prototype","targetPrototypeBefore","getPrototypeOf","fail","error","toBeInstanceOf","status","toBe","isPublic","toEqual","source","items","toThrow","undefined","Array","isArray","group","description","title","toBeNull","matrix","inheritedGroup","inherited","create","hasOwnProperty","call"],"mappings":"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"}