payload 3.86.0 → 3.87.0
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/collections/operations/count.d.ts.map +1 -1
- package/dist/collections/operations/count.js +1 -0
- package/dist/collections/operations/count.js.map +1 -1
- package/dist/collections/operations/updateByID.d.ts.map +1 -1
- package/dist/collections/operations/updateByID.js +1 -0
- package/dist/collections/operations/updateByID.js.map +1 -1
- package/dist/fields/config/types.js +1 -1
- package/dist/fields/config/types.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/promise.d.ts.map +1 -1
- package/dist/fields/hooks/beforeValidate/promise.js +5 -3
- package/dist/fields/hooks/beforeValidate/promise.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/stripNullRows.d.ts +10 -0
- package/dist/fields/hooks/beforeValidate/stripNullRows.d.ts.map +1 -0
- package/dist/fields/hooks/beforeValidate/stripNullRows.js +18 -0
- package/dist/fields/hooks/beforeValidate/stripNullRows.js.map +1 -0
- package/dist/fields/hooks/beforeValidate/traverseFields.d.ts.map +1 -1
- package/dist/fields/hooks/beforeValidate/traverseFields.js +2 -0
- package/dist/fields/hooks/beforeValidate/traverseFields.js.map +1 -1
- package/dist/folders/utils/getFoldersAndDocumentsFromJoin.d.ts.map +1 -1
- package/dist/folders/utils/getFoldersAndDocumentsFromJoin.js +1 -0
- package/dist/folders/utils/getFoldersAndDocumentsFromJoin.js.map +1 -1
- package/dist/globals/operations/countGlobalVersions.d.ts.map +1 -1
- package/dist/globals/operations/countGlobalVersions.js +1 -0
- package/dist/globals/operations/countGlobalVersions.js.map +1 -1
- package/dist/index.bundled.d.ts +71 -15
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/uploads/generateFileData.js +4 -1
- package/dist/uploads/generateFileData.js.map +1 -1
- package/dist/uploads/getImageSize.d.ts +12 -1
- package/dist/uploads/getImageSize.d.ts.map +1 -1
- package/dist/uploads/getImageSize.js +20 -18
- package/dist/uploads/getImageSize.js.map +1 -1
- package/dist/uploads/getImageSize.spec.js +298 -0
- package/dist/uploads/getImageSize.spec.js.map +1 -0
- package/dist/uploads/probeImageSize.d.ts +39 -0
- package/dist/uploads/probeImageSize.d.ts.map +1 -0
- package/dist/uploads/probeImageSize.js +374 -0
- package/dist/uploads/probeImageSize.js.map +1 -0
- package/dist/uploads/probeImageSize.spec.js +366 -0
- package/dist/uploads/probeImageSize.spec.js.map +1 -0
- package/dist/utilities/parseParams/index.d.ts +2 -3
- package/dist/utilities/parseParams/index.d.ts.map +1 -1
- package/dist/utilities/parseParams/index.js.map +1 -1
- package/dist/utilities/traverseFields.d.ts.map +1 -1
- package/dist/utilities/traverseFields.js +20 -22
- package/dist/utilities/traverseFields.js.map +1 -1
- package/dist/utilities/traverseFields.spec.js +112 -0
- package/dist/utilities/traverseFields.spec.js.map +1 -1
- package/dist/utilities/unflattenData.d.ts +3 -0
- package/dist/utilities/unflattenData.d.ts.map +1 -0
- package/dist/utilities/unflattenData.js +14 -0
- package/dist/utilities/unflattenData.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { probeImageSize } from './probeImageSize.js';
|
|
6
|
+
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const fixturesDir = path.resolve(dirname, '../../../../test/uploads');
|
|
8
|
+
const readFixture = (name)=>readFileSync(path.join(fixturesDir, name));
|
|
9
|
+
// Packs `{ length, value }` fields into a little-endian, LSB-first bitstream,
|
|
10
|
+
// matching the JPEG XL `SizeHeader` bit layout.
|
|
11
|
+
const packJXLBits = (fields)=>{
|
|
12
|
+
const bits = [];
|
|
13
|
+
for (const { length, value } of fields){
|
|
14
|
+
for(let i = 0; i < length; i++){
|
|
15
|
+
bits.push(value >> i & 1);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const bytes = Buffer.alloc(Math.ceil(bits.length / 8));
|
|
19
|
+
bits.forEach((bit, i)=>{
|
|
20
|
+
if (bit) {
|
|
21
|
+
bytes[Math.floor(i / 8)] |= 1 << i % 8;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return bytes;
|
|
25
|
+
};
|
|
26
|
+
// Encodes a non-small `SizeHeader` dimension: a 2-bit size class selecting
|
|
27
|
+
// how many extra bits follow, then `value - 1` in that many bits.
|
|
28
|
+
const packJXLDimension = (value)=>{
|
|
29
|
+
const n = value - 1;
|
|
30
|
+
const sizeClasses = [
|
|
31
|
+
9,
|
|
32
|
+
13,
|
|
33
|
+
18,
|
|
34
|
+
30
|
|
35
|
+
];
|
|
36
|
+
const classIndex = sizeClasses.findIndex((extraBits)=>n < 2 ** extraBits);
|
|
37
|
+
return [
|
|
38
|
+
{
|
|
39
|
+
length: 2,
|
|
40
|
+
value: classIndex
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
length: sizeClasses[classIndex],
|
|
44
|
+
value: n
|
|
45
|
+
}
|
|
46
|
+
];
|
|
47
|
+
};
|
|
48
|
+
const encodeJXLCodestream = (width, height)=>{
|
|
49
|
+
const body = packJXLBits([
|
|
50
|
+
{
|
|
51
|
+
length: 1,
|
|
52
|
+
value: 0
|
|
53
|
+
},
|
|
54
|
+
...packJXLDimension(height),
|
|
55
|
+
{
|
|
56
|
+
length: 3,
|
|
57
|
+
value: 0
|
|
58
|
+
},
|
|
59
|
+
...packJXLDimension(width)
|
|
60
|
+
]);
|
|
61
|
+
return Buffer.concat([
|
|
62
|
+
Buffer.from([
|
|
63
|
+
0xff,
|
|
64
|
+
0x0a
|
|
65
|
+
]),
|
|
66
|
+
body
|
|
67
|
+
]);
|
|
68
|
+
};
|
|
69
|
+
const encodeSmallJXLCodestream = (width, height)=>{
|
|
70
|
+
const body = packJXLBits([
|
|
71
|
+
{
|
|
72
|
+
length: 1,
|
|
73
|
+
value: 1
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
length: 5,
|
|
77
|
+
value: height / 8 - 1
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
length: 3,
|
|
81
|
+
value: 0
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
length: 5,
|
|
85
|
+
value: width / 8 - 1
|
|
86
|
+
}
|
|
87
|
+
]);
|
|
88
|
+
return Buffer.concat([
|
|
89
|
+
Buffer.from([
|
|
90
|
+
0xff,
|
|
91
|
+
0x0a
|
|
92
|
+
]),
|
|
93
|
+
body
|
|
94
|
+
]);
|
|
95
|
+
};
|
|
96
|
+
const jxlBox = (type, payload)=>{
|
|
97
|
+
const box = Buffer.alloc(8 + payload.length);
|
|
98
|
+
box.writeUInt32BE(box.length, 0);
|
|
99
|
+
box.write(type, 4, 'ascii');
|
|
100
|
+
payload.copy(box, 8);
|
|
101
|
+
return box;
|
|
102
|
+
};
|
|
103
|
+
// The fixed 12-byte JXL container signature box
|
|
104
|
+
const jxlSignatureBox = Buffer.from([
|
|
105
|
+
0x00,
|
|
106
|
+
0x00,
|
|
107
|
+
0x00,
|
|
108
|
+
0x0c,
|
|
109
|
+
0x4a,
|
|
110
|
+
0x58,
|
|
111
|
+
0x4c,
|
|
112
|
+
0x20,
|
|
113
|
+
0x0d,
|
|
114
|
+
0x0a,
|
|
115
|
+
0x87,
|
|
116
|
+
0x0a
|
|
117
|
+
]);
|
|
118
|
+
const jxlFtypBox = jxlBox('ftyp', Buffer.concat([
|
|
119
|
+
Buffer.from('jxl '),
|
|
120
|
+
Buffer.alloc(4),
|
|
121
|
+
Buffer.from('jxl ')
|
|
122
|
+
]));
|
|
123
|
+
describe('probeImageSize', ()=>{
|
|
124
|
+
// Expected dimensions verified against the previous `image-size` implementation
|
|
125
|
+
const cases = [
|
|
126
|
+
{
|
|
127
|
+
file: 'test-image.png',
|
|
128
|
+
height: 800,
|
|
129
|
+
width: 800
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
file: 'small.png',
|
|
133
|
+
height: 80,
|
|
134
|
+
width: 320
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
file: 'image with spaces.png',
|
|
138
|
+
height: 1600,
|
|
139
|
+
width: 1600
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
file: 'test-image.jpg',
|
|
143
|
+
height: 800,
|
|
144
|
+
width: 800
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
file: 'test-image.tiff',
|
|
148
|
+
height: 100,
|
|
149
|
+
width: 200
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
file: 'image.svg',
|
|
153
|
+
height: 260,
|
|
154
|
+
width: 260
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
file: 'svgWithXml.svg',
|
|
158
|
+
height: 1,
|
|
159
|
+
width: 1
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
file: 'corrupt.svg',
|
|
163
|
+
height: 400,
|
|
164
|
+
width: 400
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
file: 'animated.webp',
|
|
168
|
+
height: 200,
|
|
169
|
+
width: 200
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
file: 'non-animated.webp',
|
|
173
|
+
height: 420,
|
|
174
|
+
width: 900
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
file: 'test-image-avif.avif',
|
|
178
|
+
height: 800,
|
|
179
|
+
width: 800
|
|
180
|
+
}
|
|
181
|
+
];
|
|
182
|
+
it.each(cases)('should read dimensions for $file', ({ file, height, width })=>{
|
|
183
|
+
expect(probeImageSize(readFixture(file))).toEqual({
|
|
184
|
+
height,
|
|
185
|
+
width
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
it('should return the largest image for a HEIF file embedding a thumbnail', ()=>{
|
|
189
|
+
// Apple HEIC files place a small thumbnail `ispe` before the full-resolution
|
|
190
|
+
// primary `ispe` inside `ipco`; the primary (largest) must win.
|
|
191
|
+
const box = (type, payload)=>{
|
|
192
|
+
const b = Buffer.alloc(8 + payload.length);
|
|
193
|
+
b.writeUInt32BE(b.length, 0);
|
|
194
|
+
b.write(type, 4, 'ascii');
|
|
195
|
+
payload.copy(b, 8);
|
|
196
|
+
return b;
|
|
197
|
+
};
|
|
198
|
+
const ispe = (width, height)=>{
|
|
199
|
+
const payload = Buffer.alloc(12) // 4 bytes version/flags + width + height
|
|
200
|
+
;
|
|
201
|
+
payload.writeUInt32BE(width, 4);
|
|
202
|
+
payload.writeUInt32BE(height, 8);
|
|
203
|
+
return box('ispe', payload);
|
|
204
|
+
};
|
|
205
|
+
const ipco = box('ipco', Buffer.concat([
|
|
206
|
+
ispe(80, 80),
|
|
207
|
+
ispe(400, 300)
|
|
208
|
+
]));
|
|
209
|
+
const iprp = box('iprp', ipco);
|
|
210
|
+
const meta = box('meta', Buffer.concat([
|
|
211
|
+
Buffer.alloc(4),
|
|
212
|
+
iprp
|
|
213
|
+
]));
|
|
214
|
+
const ftyp = box('ftyp', Buffer.from('avif '));
|
|
215
|
+
const heif = Buffer.concat([
|
|
216
|
+
ftyp,
|
|
217
|
+
meta
|
|
218
|
+
]);
|
|
219
|
+
expect(probeImageSize(heif)).toEqual({
|
|
220
|
+
height: 300,
|
|
221
|
+
width: 400
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
it('should throw on an unsupported file type', ()=>{
|
|
225
|
+
expect(()=>probeImageSize(Buffer.from('not an image'))).toThrow();
|
|
226
|
+
});
|
|
227
|
+
it('should read dimensions for a BMP file', ()=>{
|
|
228
|
+
const bmp = Buffer.alloc(54);
|
|
229
|
+
bmp.write('BM', 0, 'ascii');
|
|
230
|
+
bmp.writeUInt32LE(54, 10); // pixel data offset
|
|
231
|
+
bmp.writeUInt32LE(40, 14); // BITMAPINFOHEADER size
|
|
232
|
+
bmp.writeInt32LE(64, 18); // width
|
|
233
|
+
bmp.writeInt32LE(-48, 22); // height stored negative for a top-down bitmap
|
|
234
|
+
expect(probeImageSize(bmp)).toEqual({
|
|
235
|
+
height: 48,
|
|
236
|
+
width: 64
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
it('should read dimensions for an ICO file, picking the largest embedded image', ()=>{
|
|
240
|
+
const ico = Buffer.alloc(24);
|
|
241
|
+
ico.writeUInt16LE(1, 2); // type: 1 = icon
|
|
242
|
+
ico.writeUInt16LE(2, 4); // image count
|
|
243
|
+
ico[6] = 16; // entry 0: 16x16
|
|
244
|
+
ico[7] = 16;
|
|
245
|
+
ico[22] = 32; // entry 1: 32x32
|
|
246
|
+
ico[23] = 32;
|
|
247
|
+
expect(probeImageSize(ico)).toEqual({
|
|
248
|
+
height: 32,
|
|
249
|
+
width: 32
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
it('should read dimensions for a CUR file', ()=>{
|
|
253
|
+
const cur = Buffer.alloc(22);
|
|
254
|
+
cur.writeUInt16LE(2, 2); // type: 2 = cursor
|
|
255
|
+
cur.writeUInt16LE(1, 4); // image count
|
|
256
|
+
cur[6] = 24;
|
|
257
|
+
cur[7] = 24;
|
|
258
|
+
expect(probeImageSize(cur)).toEqual({
|
|
259
|
+
height: 24,
|
|
260
|
+
width: 24
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
it('should not hang on a malformed HEIF buffer with a zero-size box', ()=>{
|
|
264
|
+
// Reproduces the CVE-2025-71319 trigger: an ISO-BMFF box whose size field is
|
|
265
|
+
// zero inside a container would loop forever in the unpatched `image-size`.
|
|
266
|
+
const makeBox = (type, payload)=>{
|
|
267
|
+
const box = Buffer.alloc(8 + payload.length);
|
|
268
|
+
box.writeUInt32BE(box.length, 0);
|
|
269
|
+
box.write(type, 4, 'ascii');
|
|
270
|
+
payload.copy(box, 8);
|
|
271
|
+
return box;
|
|
272
|
+
};
|
|
273
|
+
const zeroSizeBox = Buffer.alloc(8);
|
|
274
|
+
zeroSizeBox.write('ipco', 4, 'ascii'); // size field left as 0
|
|
275
|
+
const meta = makeBox('meta', Buffer.concat([
|
|
276
|
+
Buffer.alloc(4),
|
|
277
|
+
zeroSizeBox
|
|
278
|
+
]));
|
|
279
|
+
const ftyp = makeBox('ftyp', Buffer.from('avif '));
|
|
280
|
+
const malformed = Buffer.concat([
|
|
281
|
+
ftyp,
|
|
282
|
+
meta
|
|
283
|
+
]);
|
|
284
|
+
expect(()=>probeImageSize(malformed)).toThrow();
|
|
285
|
+
});
|
|
286
|
+
it('should read dimensions for a bare JPEG XL codestream', ()=>{
|
|
287
|
+
expect(probeImageSize(encodeJXLCodestream(1920, 1080))).toEqual({
|
|
288
|
+
height: 1080,
|
|
289
|
+
width: 1920
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
it('should read dimensions for a small bare JPEG XL codestream', ()=>{
|
|
293
|
+
expect(probeImageSize(encodeSmallJXLCodestream(64, 48))).toEqual({
|
|
294
|
+
height: 48,
|
|
295
|
+
width: 64
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
it('should read dimensions for a JPEG XL container with a single jxlc box', ()=>{
|
|
299
|
+
const jxlc = jxlBox('jxlc', encodeJXLCodestream(640, 480));
|
|
300
|
+
const container = Buffer.concat([
|
|
301
|
+
jxlSignatureBox,
|
|
302
|
+
jxlFtypBox,
|
|
303
|
+
jxlc
|
|
304
|
+
]);
|
|
305
|
+
expect(probeImageSize(container)).toEqual({
|
|
306
|
+
height: 480,
|
|
307
|
+
width: 640
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
it('should reassemble a JPEG XL codestream split across jxlp boxes', ()=>{
|
|
311
|
+
const codestream = encodeJXLCodestream(800, 600);
|
|
312
|
+
const splitPoint = 3;
|
|
313
|
+
// Each jxlp payload is prefixed with a 4-byte partial-codestream index
|
|
314
|
+
const jxlp0 = jxlBox('jxlp', Buffer.concat([
|
|
315
|
+
Buffer.from([
|
|
316
|
+
0,
|
|
317
|
+
0,
|
|
318
|
+
0,
|
|
319
|
+
0
|
|
320
|
+
]),
|
|
321
|
+
codestream.subarray(0, splitPoint)
|
|
322
|
+
]));
|
|
323
|
+
const jxlp1 = jxlBox('jxlp', Buffer.concat([
|
|
324
|
+
Buffer.from([
|
|
325
|
+
0,
|
|
326
|
+
0,
|
|
327
|
+
0,
|
|
328
|
+
1
|
|
329
|
+
]),
|
|
330
|
+
codestream.subarray(splitPoint)
|
|
331
|
+
]));
|
|
332
|
+
const container = Buffer.concat([
|
|
333
|
+
jxlSignatureBox,
|
|
334
|
+
jxlFtypBox,
|
|
335
|
+
jxlp0,
|
|
336
|
+
jxlp1
|
|
337
|
+
]);
|
|
338
|
+
expect(probeImageSize(container)).toEqual({
|
|
339
|
+
height: 600,
|
|
340
|
+
width: 800
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
it('should throw rather than hang on a JPEG XL container with a truncated jxlc box', ()=>{
|
|
344
|
+
const truncatedJxlc = Buffer.alloc(8);
|
|
345
|
+
truncatedJxlc.write('jxlc', 4, 'ascii'); // size field left as 0: extends to end of buffer, no payload left
|
|
346
|
+
const container = Buffer.concat([
|
|
347
|
+
jxlSignatureBox,
|
|
348
|
+
jxlFtypBox,
|
|
349
|
+
truncatedJxlc
|
|
350
|
+
]);
|
|
351
|
+
expect(()=>probeImageSize(container)).toThrow();
|
|
352
|
+
});
|
|
353
|
+
it('should not hang on a JPEG XL container with thousands of unrelated boxes', ()=>{
|
|
354
|
+
const unrelatedBoxes = Buffer.concat(Array.from({
|
|
355
|
+
length: 5000
|
|
356
|
+
}, ()=>jxlBox('free', Buffer.alloc(0))));
|
|
357
|
+
const container = Buffer.concat([
|
|
358
|
+
jxlSignatureBox,
|
|
359
|
+
jxlFtypBox,
|
|
360
|
+
unrelatedBoxes
|
|
361
|
+
]);
|
|
362
|
+
expect(()=>probeImageSize(container)).toThrow();
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
//# sourceMappingURL=probeImageSize.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/probeImageSize.spec.ts"],"sourcesContent":["import { readFileSync } from 'fs'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport { describe, expect, it } from 'vitest'\n\nimport { probeImageSize } from './probeImageSize.js'\n\nconst dirname = path.dirname(fileURLToPath(import.meta.url))\nconst fixturesDir = path.resolve(dirname, '../../../../test/uploads')\n\nconst readFixture = (name: string) => readFileSync(path.join(fixturesDir, name))\n\n// Packs `{ length, value }` fields into a little-endian, LSB-first bitstream,\n// matching the JPEG XL `SizeHeader` bit layout.\nconst packJXLBits = (fields: Array<{ length: number; value: number }>): Buffer => {\n const bits: number[] = []\n for (const { length, value } of fields) {\n for (let i = 0; i < length; i++) {\n bits.push((value >> i) & 1)\n }\n }\n\n const bytes = Buffer.alloc(Math.ceil(bits.length / 8))\n bits.forEach((bit, i) => {\n if (bit) {\n bytes[Math.floor(i / 8)]! |= 1 << i % 8\n }\n })\n\n return bytes\n}\n\n// Encodes a non-small `SizeHeader` dimension: a 2-bit size class selecting\n// how many extra bits follow, then `value - 1` in that many bits.\nconst packJXLDimension = (value: number): Array<{ length: number; value: number }> => {\n const n = value - 1\n const sizeClasses = [9, 13, 18, 30]\n const classIndex = sizeClasses.findIndex((extraBits) => n < 2 ** extraBits)\n\n return [\n { length: 2, value: classIndex },\n { length: sizeClasses[classIndex]!, value: n },\n ]\n}\n\nconst encodeJXLCodestream = (width: number, height: number): Buffer => {\n const body = packJXLBits([\n { length: 1, value: 0 }, // isSmallImage = false\n ...packJXLDimension(height),\n { length: 3, value: 0 }, // widthMode = 0 (explicit dimension)\n ...packJXLDimension(width),\n ])\n\n return Buffer.concat([Buffer.from([0xff, 0x0a]), body])\n}\n\nconst encodeSmallJXLCodestream = (width: number, height: number): Buffer => {\n const body = packJXLBits([\n { length: 1, value: 1 }, // isSmallImage = true\n { length: 5, value: height / 8 - 1 },\n { length: 3, value: 0 }, // widthMode = 0 (explicit dimension)\n { length: 5, value: width / 8 - 1 },\n ])\n\n return Buffer.concat([Buffer.from([0xff, 0x0a]), body])\n}\n\nconst jxlBox = (type: string, payload: Buffer): Buffer => {\n const box = Buffer.alloc(8 + payload.length)\n box.writeUInt32BE(box.length, 0)\n box.write(type, 4, 'ascii')\n payload.copy(box, 8)\n return box\n}\n\n// The fixed 12-byte JXL container signature box\nconst jxlSignatureBox = Buffer.from([\n 0x00, 0x00, 0x00, 0x0c, 0x4a, 0x58, 0x4c, 0x20, 0x0d, 0x0a, 0x87, 0x0a,\n])\nconst jxlFtypBox = jxlBox(\n 'ftyp',\n Buffer.concat([Buffer.from('jxl '), Buffer.alloc(4), Buffer.from('jxl ')]),\n)\n\ndescribe('probeImageSize', () => {\n // Expected dimensions verified against the previous `image-size` implementation\n const cases: Array<{ file: string; height: number; width: number }> = [\n { file: 'test-image.png', height: 800, width: 800 },\n { file: 'small.png', height: 80, width: 320 },\n { file: 'image with spaces.png', height: 1600, width: 1600 },\n { file: 'test-image.jpg', height: 800, width: 800 },\n { file: 'test-image.tiff', height: 100, width: 200 },\n { file: 'image.svg', height: 260, width: 260 },\n { file: 'svgWithXml.svg', height: 1, width: 1 },\n { file: 'corrupt.svg', height: 400, width: 400 },\n { file: 'animated.webp', height: 200, width: 200 },\n { file: 'non-animated.webp', height: 420, width: 900 },\n { file: 'test-image-avif.avif', height: 800, width: 800 },\n ]\n\n it.each(cases)('should read dimensions for $file', ({ file, height, width }) => {\n expect(probeImageSize(readFixture(file))).toEqual({ height, width })\n })\n\n it('should return the largest image for a HEIF file embedding a thumbnail', () => {\n // Apple HEIC files place a small thumbnail `ispe` before the full-resolution\n // primary `ispe` inside `ipco`; the primary (largest) must win.\n const box = (type: string, payload: Buffer) => {\n const b = Buffer.alloc(8 + payload.length)\n b.writeUInt32BE(b.length, 0)\n b.write(type, 4, 'ascii')\n payload.copy(b, 8)\n return b\n }\n const ispe = (width: number, height: number) => {\n const payload = Buffer.alloc(12) // 4 bytes version/flags + width + height\n payload.writeUInt32BE(width, 4)\n payload.writeUInt32BE(height, 8)\n return box('ispe', payload)\n }\n const ipco = box('ipco', Buffer.concat([ispe(80, 80), ispe(400, 300)]))\n const iprp = box('iprp', ipco)\n const meta = box('meta', Buffer.concat([Buffer.alloc(4), iprp]))\n const ftyp = box('ftyp', Buffer.from('avif '))\n const heif = Buffer.concat([ftyp, meta])\n\n expect(probeImageSize(heif)).toEqual({ height: 300, width: 400 })\n })\n\n it('should throw on an unsupported file type', () => {\n expect(() => probeImageSize(Buffer.from('not an image'))).toThrow()\n })\n\n it('should read dimensions for a BMP file', () => {\n const bmp = Buffer.alloc(54)\n bmp.write('BM', 0, 'ascii')\n bmp.writeUInt32LE(54, 10) // pixel data offset\n bmp.writeUInt32LE(40, 14) // BITMAPINFOHEADER size\n bmp.writeInt32LE(64, 18) // width\n bmp.writeInt32LE(-48, 22) // height stored negative for a top-down bitmap\n\n expect(probeImageSize(bmp)).toEqual({ height: 48, width: 64 })\n })\n\n it('should read dimensions for an ICO file, picking the largest embedded image', () => {\n const ico = Buffer.alloc(24)\n ico.writeUInt16LE(1, 2) // type: 1 = icon\n ico.writeUInt16LE(2, 4) // image count\n ico[6] = 16 // entry 0: 16x16\n ico[7] = 16\n ico[22] = 32 // entry 1: 32x32\n ico[23] = 32\n\n expect(probeImageSize(ico)).toEqual({ height: 32, width: 32 })\n })\n\n it('should read dimensions for a CUR file', () => {\n const cur = Buffer.alloc(22)\n cur.writeUInt16LE(2, 2) // type: 2 = cursor\n cur.writeUInt16LE(1, 4) // image count\n cur[6] = 24\n cur[7] = 24\n\n expect(probeImageSize(cur)).toEqual({ height: 24, width: 24 })\n })\n\n it('should not hang on a malformed HEIF buffer with a zero-size box', () => {\n // Reproduces the CVE-2025-71319 trigger: an ISO-BMFF box whose size field is\n // zero inside a container would loop forever in the unpatched `image-size`.\n const makeBox = (type: string, payload: Buffer) => {\n const box = Buffer.alloc(8 + payload.length)\n box.writeUInt32BE(box.length, 0)\n box.write(type, 4, 'ascii')\n payload.copy(box, 8)\n return box\n }\n const zeroSizeBox = Buffer.alloc(8)\n zeroSizeBox.write('ipco', 4, 'ascii') // size field left as 0\n const meta = makeBox('meta', Buffer.concat([Buffer.alloc(4), zeroSizeBox]))\n const ftyp = makeBox('ftyp', Buffer.from('avif '))\n const malformed = Buffer.concat([ftyp, meta])\n\n expect(() => probeImageSize(malformed)).toThrow()\n })\n\n it('should read dimensions for a bare JPEG XL codestream', () => {\n expect(probeImageSize(encodeJXLCodestream(1920, 1080))).toEqual({ height: 1080, width: 1920 })\n })\n\n it('should read dimensions for a small bare JPEG XL codestream', () => {\n expect(probeImageSize(encodeSmallJXLCodestream(64, 48))).toEqual({ height: 48, width: 64 })\n })\n\n it('should read dimensions for a JPEG XL container with a single jxlc box', () => {\n const jxlc = jxlBox('jxlc', encodeJXLCodestream(640, 480))\n const container = Buffer.concat([jxlSignatureBox, jxlFtypBox, jxlc])\n\n expect(probeImageSize(container)).toEqual({ height: 480, width: 640 })\n })\n\n it('should reassemble a JPEG XL codestream split across jxlp boxes', () => {\n const codestream = encodeJXLCodestream(800, 600)\n const splitPoint = 3\n // Each jxlp payload is prefixed with a 4-byte partial-codestream index\n const jxlp0 = jxlBox(\n 'jxlp',\n Buffer.concat([Buffer.from([0, 0, 0, 0]), codestream.subarray(0, splitPoint)]),\n )\n const jxlp1 = jxlBox(\n 'jxlp',\n Buffer.concat([Buffer.from([0, 0, 0, 1]), codestream.subarray(splitPoint)]),\n )\n const container = Buffer.concat([jxlSignatureBox, jxlFtypBox, jxlp0, jxlp1])\n\n expect(probeImageSize(container)).toEqual({ height: 600, width: 800 })\n })\n\n it('should throw rather than hang on a JPEG XL container with a truncated jxlc box', () => {\n const truncatedJxlc = Buffer.alloc(8)\n truncatedJxlc.write('jxlc', 4, 'ascii') // size field left as 0: extends to end of buffer, no payload left\n const container = Buffer.concat([jxlSignatureBox, jxlFtypBox, truncatedJxlc])\n\n expect(() => probeImageSize(container)).toThrow()\n })\n\n it('should not hang on a JPEG XL container with thousands of unrelated boxes', () => {\n const unrelatedBoxes = Buffer.concat(\n Array.from({ length: 5000 }, () => jxlBox('free', Buffer.alloc(0))),\n )\n const container = Buffer.concat([jxlSignatureBox, jxlFtypBox, unrelatedBoxes])\n\n expect(() => probeImageSize(container)).toThrow()\n })\n})\n"],"names":["readFileSync","path","fileURLToPath","describe","expect","it","probeImageSize","dirname","url","fixturesDir","resolve","readFixture","name","join","packJXLBits","fields","bits","length","value","i","push","bytes","Buffer","alloc","Math","ceil","forEach","bit","floor","packJXLDimension","n","sizeClasses","classIndex","findIndex","extraBits","encodeJXLCodestream","width","height","body","concat","from","encodeSmallJXLCodestream","jxlBox","type","payload","box","writeUInt32BE","write","copy","jxlSignatureBox","jxlFtypBox","cases","file","each","toEqual","b","ispe","ipco","iprp","meta","ftyp","heif","toThrow","bmp","writeUInt32LE","writeInt32LE","ico","writeUInt16LE","cur","makeBox","zeroSizeBox","malformed","jxlc","container","codestream","splitPoint","jxlp0","subarray","jxlp1","truncatedJxlc","unrelatedBoxes","Array"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { JoinQuery, PopulateType, SelectType, Where } from '../../types/index.js';
|
|
2
2
|
import type { JoinParams } from '../sanitizeJoinParams.js';
|
|
3
|
-
type RawParams = {
|
|
3
|
+
export type RawParams = {
|
|
4
4
|
[key: string]: unknown;
|
|
5
5
|
autosave?: string;
|
|
6
6
|
data?: string;
|
|
@@ -23,7 +23,7 @@ type RawParams = {
|
|
|
23
23
|
unpublishAllLocales?: string;
|
|
24
24
|
where?: string | Where;
|
|
25
25
|
};
|
|
26
|
-
type ParsedParams = {
|
|
26
|
+
export type ParsedParams = {
|
|
27
27
|
autosave?: boolean;
|
|
28
28
|
data?: Record<string, unknown>;
|
|
29
29
|
depth?: number;
|
|
@@ -55,5 +55,4 @@ export declare const numberParams: string[];
|
|
|
55
55
|
* c. `sort` provided as a comma-separated string or array is converted to an array of strings
|
|
56
56
|
*/
|
|
57
57
|
export declare const parseParams: (params: RawParams) => ParsedParams;
|
|
58
|
-
export {};
|
|
59
58
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utilities/parseParams/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAS1D,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utilities/parseParams/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAS1D,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAE3B,eAAO,MAAM,aAAa,UAOzB,CAAA;AAED,eAAO,MAAM,YAAY,UAA6B,CAAA;AAEtD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,WAAY,SAAS,KAAG,YA2C/C,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utilities/parseParams/index.ts"],"sourcesContent":["import type { JoinQuery, PopulateType, SelectType, Where } from '../../types/index.js'\nimport type { JoinParams } from '../sanitizeJoinParams.js'\n\nimport { isNumber } from '../isNumber.js'\nimport { parseBooleanString } from '../parseBooleanString.js'\nimport { sanitizeJoinParams } from '../sanitizeJoinParams.js'\nimport { sanitizePopulateParam } from '../sanitizePopulateParam.js'\nimport { sanitizeSelectParam } from '../sanitizeSelectParam.js'\nimport { sanitizeSortParams } from '../sanitizeSortParams.js'\n\
|
|
1
|
+
{"version":3,"sources":["../../../src/utilities/parseParams/index.ts"],"sourcesContent":["import type { JoinQuery, PopulateType, SelectType, Where } from '../../types/index.js'\nimport type { JoinParams } from '../sanitizeJoinParams.js'\n\nimport { isNumber } from '../isNumber.js'\nimport { parseBooleanString } from '../parseBooleanString.js'\nimport { sanitizeJoinParams } from '../sanitizeJoinParams.js'\nimport { sanitizePopulateParam } from '../sanitizePopulateParam.js'\nimport { sanitizeSelectParam } from '../sanitizeSelectParam.js'\nimport { sanitizeSortParams } from '../sanitizeSortParams.js'\n\nexport type RawParams = {\n [key: string]: unknown\n autosave?: string\n data?: string\n depth?: string\n draft?: string\n field?: string\n flattenLocales?: string\n joins?: JoinParams\n limit?: string\n overrideLock?: string\n page?: string\n pagination?: string\n populate?: unknown\n publishAllLocales?: string\n publishSpecificLocale?: string\n select?: unknown\n selectedLocales?: string\n sort?: string | string[]\n trash?: string\n unpublishAllLocales?: string\n where?: string | Where\n}\n\nexport type ParsedParams = {\n autosave?: boolean\n data?: Record<string, unknown>\n depth?: number\n draft?: boolean\n field?: string\n flattenLocales?: boolean\n joins?: JoinQuery\n limit?: number\n overrideLock?: boolean\n page?: number\n pagination?: boolean\n populate?: PopulateType\n publishAllLocales?: boolean\n publishSpecificLocale?: string\n select?: SelectType\n selectedLocales?: string[]\n sort?: string[]\n trash?: boolean\n unpublishAllLocales?: boolean\n where?: Where\n} & Record<string, unknown>\n\nexport const booleanParams = [\n 'autosave',\n 'draft',\n 'trash',\n 'overrideLock',\n 'pagination',\n 'flattenLocales',\n]\n\nexport const numberParams = ['depth', 'limit', 'page']\n\n/**\n * Takes raw query parameters and parses them into the correct types that Payload expects.\n * Examples:\n * a. `draft` provided as a string of \"true\" is converted to a boolean\n * b. `depth` provided as a string of \"0\" is converted to a number\n * c. `sort` provided as a comma-separated string or array is converted to an array of strings\n */\nexport const parseParams = (params: RawParams): ParsedParams => {\n const parsedParams = (params || {}) as ParsedParams\n\n // iterate through known params to make this very fast\n for (const key of booleanParams) {\n if (key in params) {\n parsedParams[key] = parseBooleanString(params[key] as boolean | string)\n }\n }\n\n for (const key of numberParams) {\n if (key in params) {\n if (isNumber(params[key])) {\n parsedParams[key] = Number(params[key])\n }\n }\n }\n\n if ('populate' in params) {\n parsedParams.populate = sanitizePopulateParam(params.populate)\n }\n\n if ('select' in params) {\n parsedParams.select = sanitizeSelectParam(params.select)\n }\n\n if ('joins' in params) {\n parsedParams.joins = sanitizeJoinParams(params.joins as JoinParams)\n }\n\n if ('sort' in params) {\n parsedParams.sort = sanitizeSortParams(params.sort)\n }\n\n if ('data' in params && typeof params.data === 'string' && params.data.length > 0) {\n parsedParams.data = JSON.parse(params.data)\n }\n\n if ('where' in params && typeof params.where === 'string' && params.where.length > 0) {\n parsedParams.where = JSON.parse(params.where) as Where\n }\n\n return parsedParams\n}\n"],"names":["isNumber","parseBooleanString","sanitizeJoinParams","sanitizePopulateParam","sanitizeSelectParam","sanitizeSortParams","booleanParams","numberParams","parseParams","params","parsedParams","key","Number","populate","select","joins","sort","data","length","JSON","parse","where"],"mappings":"AAGA,SAASA,QAAQ,QAAQ,iBAAgB;AACzC,SAASC,kBAAkB,QAAQ,2BAA0B;AAC7D,SAASC,kBAAkB,QAAQ,2BAA0B;AAC7D,SAASC,qBAAqB,QAAQ,8BAA6B;AACnE,SAASC,mBAAmB,QAAQ,4BAA2B;AAC/D,SAASC,kBAAkB,QAAQ,2BAA0B;AAiD7D,OAAO,MAAMC,gBAAgB;IAC3B;IACA;IACA;IACA;IACA;IACA;CACD,CAAA;AAED,OAAO,MAAMC,eAAe;IAAC;IAAS;IAAS;CAAO,CAAA;AAEtD;;;;;;CAMC,GACD,OAAO,MAAMC,cAAc,CAACC;IAC1B,MAAMC,eAAgBD,UAAU,CAAC;IAEjC,sDAAsD;IACtD,KAAK,MAAME,OAAOL,cAAe;QAC/B,IAAIK,OAAOF,QAAQ;YACjBC,YAAY,CAACC,IAAI,GAAGV,mBAAmBQ,MAAM,CAACE,IAAI;QACpD;IACF;IAEA,KAAK,MAAMA,OAAOJ,aAAc;QAC9B,IAAII,OAAOF,QAAQ;YACjB,IAAIT,SAASS,MAAM,CAACE,IAAI,GAAG;gBACzBD,YAAY,CAACC,IAAI,GAAGC,OAAOH,MAAM,CAACE,IAAI;YACxC;QACF;IACF;IAEA,IAAI,cAAcF,QAAQ;QACxBC,aAAaG,QAAQ,GAAGV,sBAAsBM,OAAOI,QAAQ;IAC/D;IAEA,IAAI,YAAYJ,QAAQ;QACtBC,aAAaI,MAAM,GAAGV,oBAAoBK,OAAOK,MAAM;IACzD;IAEA,IAAI,WAAWL,QAAQ;QACrBC,aAAaK,KAAK,GAAGb,mBAAmBO,OAAOM,KAAK;IACtD;IAEA,IAAI,UAAUN,QAAQ;QACpBC,aAAaM,IAAI,GAAGX,mBAAmBI,OAAOO,IAAI;IACpD;IAEA,IAAI,UAAUP,UAAU,OAAOA,OAAOQ,IAAI,KAAK,YAAYR,OAAOQ,IAAI,CAACC,MAAM,GAAG,GAAG;QACjFR,aAAaO,IAAI,GAAGE,KAAKC,KAAK,CAACX,OAAOQ,IAAI;IAC5C;IAEA,IAAI,WAAWR,UAAU,OAAOA,OAAOY,KAAK,KAAK,YAAYZ,OAAOY,KAAK,CAACH,MAAM,GAAG,GAAG;QACpFR,aAAaW,KAAK,GAAGF,KAAKC,KAAK,CAACX,OAAOY,KAAK;IAC9C;IAEA,OAAOX;AACT,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"traverseFields.d.ts","sourceRoot":"","sources":["../../src/utilities/traverseFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,KAAK,EAAkC,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAsGlG,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,EAAE;IAC1C;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,UAAU,CAAA;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,IAAI,CAAA;IACjB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAA;IAC7C;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAA;CACxC,KAAK,OAAO,GAAG,IAAI,CAAA;AAEpB,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,sBAAsB,CAAA;IAChC,aAAa,CAAC,EAAE,CAAC,MAAM,UAAU,CAAC,sBAAsB,CAAC,CAAC,EAAE,CAAA;IAC5D,MAAM,CAAC,EAAE,MAAM,GAAG,eAAe,CAAA;IACjC,MAAM,EAAE,CAAC,KAAK,GAAG,UAAU,CAAC,EAAE,CAAA;IAC9B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAA;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAA;CACxC,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,oJAYxB,kBAAkB,KAAG,
|
|
1
|
+
{"version":3,"file":"traverseFields.d.ts","sourceRoot":"","sources":["../../src/utilities/traverseFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,KAAK,EAAkC,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAsGlG,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,EAAE;IAC1C;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,UAAU,CAAA;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,IAAI,CAAA;IACjB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAA;IAC7C;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAA;CACxC,KAAK,OAAO,GAAG,IAAI,CAAA;AAEpB,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,sBAAsB,CAAA;IAChC,aAAa,CAAC,EAAE,CAAC,MAAM,UAAU,CAAC,sBAAsB,CAAC,CAAC,EAAE,CAAA;IAC5D,MAAM,CAAC,EAAE,MAAM,GAAG,eAAe,CAAA;IACjC,MAAM,EAAE,CAAC,KAAK,GAAG,UAAU,CAAC,EAAE,CAAA;IAC9B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAA;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAA;CACxC,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,oJAYxB,kBAAkB,KAAG,IAgWvB,CAAA"}
|
|
@@ -69,7 +69,7 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
69
69
|
* @param fillEmpty fill empty properties to use this without data
|
|
70
70
|
* @param ref the data or any artifacts assigned in the callback during field recursion
|
|
71
71
|
* @param parentRef the data or any artifacts assigned in the callback during field recursion one level up
|
|
72
|
-
*/ export const traverseFields = ({ callback, callbackStack: _callbackStack = [], config, fields, fillEmpty = true, isTopLevel = true, leavesFirst = false, parentIsLocalized, parentPath = '', parentRef = {}, ref = {} })=>{
|
|
72
|
+
*/ export const traverseFields = ({ callback, callbackStack: _callbackStack = [], config, fields, fillEmpty = true, isTopLevel = true, leavesFirst = false, parentIsLocalized = false, parentPath = '', parentRef = {}, ref = {} })=>{
|
|
73
73
|
const fieldsMatched = fields.some((field)=>{
|
|
74
74
|
let callbackStack = [];
|
|
75
75
|
if (!isTopLevel) {
|
|
@@ -85,7 +85,7 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
85
85
|
if (!leavesFirst && callback && callback({
|
|
86
86
|
field,
|
|
87
87
|
next,
|
|
88
|
-
parentIsLocalized
|
|
88
|
+
parentIsLocalized,
|
|
89
89
|
parentPath,
|
|
90
90
|
parentRef,
|
|
91
91
|
ref
|
|
@@ -95,7 +95,7 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
95
95
|
callbackStack.push(()=>callback({
|
|
96
96
|
field,
|
|
97
97
|
next,
|
|
98
|
-
parentIsLocalized
|
|
98
|
+
parentIsLocalized,
|
|
99
99
|
parentPath,
|
|
100
100
|
parentRef,
|
|
101
101
|
ref
|
|
@@ -109,6 +109,10 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
109
109
|
let currentParentRef = parentRef;
|
|
110
110
|
if (field.type === 'tabs' && 'tabs' in field) {
|
|
111
111
|
for (const tab of field.tabs){
|
|
112
|
+
const tabIsLocalized = fieldShouldBeLocalized({
|
|
113
|
+
field: tab,
|
|
114
|
+
parentIsLocalized
|
|
115
|
+
});
|
|
112
116
|
let tabRef = ref;
|
|
113
117
|
if (skip) {
|
|
114
118
|
return false;
|
|
@@ -116,7 +120,7 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
116
120
|
if ('name' in tab && tab.name) {
|
|
117
121
|
if (!ref[tab.name] || typeof ref[tab.name] !== 'object') {
|
|
118
122
|
if (fillEmpty) {
|
|
119
|
-
if (
|
|
123
|
+
if (tabIsLocalized) {
|
|
120
124
|
;
|
|
121
125
|
ref[tab.name] = {
|
|
122
126
|
en: {}
|
|
@@ -135,7 +139,7 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
135
139
|
type: 'tab'
|
|
136
140
|
},
|
|
137
141
|
next,
|
|
138
|
-
parentIsLocalized
|
|
142
|
+
parentIsLocalized,
|
|
139
143
|
parentPath,
|
|
140
144
|
parentRef: currentParentRef,
|
|
141
145
|
ref: tabRef
|
|
@@ -148,14 +152,14 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
148
152
|
type: 'tab'
|
|
149
153
|
},
|
|
150
154
|
next,
|
|
151
|
-
parentIsLocalized
|
|
155
|
+
parentIsLocalized,
|
|
152
156
|
parentPath,
|
|
153
157
|
parentRef: currentParentRef,
|
|
154
158
|
ref: tabRef
|
|
155
159
|
}));
|
|
156
160
|
}
|
|
157
161
|
tabRef = tabRef[tab.name];
|
|
158
|
-
if (
|
|
162
|
+
if (tabIsLocalized) {
|
|
159
163
|
for(const key in tabRef){
|
|
160
164
|
if (tabRef[key] && typeof tabRef[key] === 'object') {
|
|
161
165
|
traverseFields({
|
|
@@ -181,7 +185,7 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
181
185
|
type: 'tab'
|
|
182
186
|
},
|
|
183
187
|
next,
|
|
184
|
-
parentIsLocalized
|
|
188
|
+
parentIsLocalized,
|
|
185
189
|
parentPath,
|
|
186
190
|
parentRef: currentParentRef,
|
|
187
191
|
ref: tabRef
|
|
@@ -194,14 +198,14 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
194
198
|
type: 'tab'
|
|
195
199
|
},
|
|
196
200
|
next,
|
|
197
|
-
parentIsLocalized
|
|
201
|
+
parentIsLocalized,
|
|
198
202
|
parentPath,
|
|
199
203
|
parentRef: currentParentRef,
|
|
200
204
|
ref: tabRef
|
|
201
205
|
}));
|
|
202
206
|
}
|
|
203
207
|
}
|
|
204
|
-
if (!
|
|
208
|
+
if (!tabIsLocalized) {
|
|
205
209
|
traverseFields({
|
|
206
210
|
callback,
|
|
207
211
|
callbackStack,
|
|
@@ -210,7 +214,7 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
210
214
|
fillEmpty,
|
|
211
215
|
isTopLevel: false,
|
|
212
216
|
leavesFirst,
|
|
213
|
-
parentIsLocalized
|
|
217
|
+
parentIsLocalized,
|
|
214
218
|
parentPath: tabHasName(tab) ? `${parentPath}${tab.name}.` : parentPath,
|
|
215
219
|
parentRef: currentParentRef,
|
|
216
220
|
ref: tabRef
|
|
@@ -230,7 +234,7 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
230
234
|
if (field.type === 'group' || field.type === 'tab') {
|
|
231
235
|
if (fieldShouldBeLocalized({
|
|
232
236
|
field,
|
|
233
|
-
parentIsLocalized
|
|
237
|
+
parentIsLocalized
|
|
234
238
|
})) {
|
|
235
239
|
;
|
|
236
240
|
ref[field.name] = {
|
|
@@ -243,7 +247,7 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
243
247
|
} else if (field.type === 'array' || field.type === 'blocks') {
|
|
244
248
|
if (fieldShouldBeLocalized({
|
|
245
249
|
field,
|
|
246
|
-
parentIsLocalized
|
|
250
|
+
parentIsLocalized
|
|
247
251
|
})) {
|
|
248
252
|
;
|
|
249
253
|
ref[field.name] = {
|
|
@@ -262,7 +266,7 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
262
266
|
}
|
|
263
267
|
if ((field.type === 'tab' || field.type === 'group') && fieldShouldBeLocalized({
|
|
264
268
|
field,
|
|
265
|
-
parentIsLocalized
|
|
269
|
+
parentIsLocalized
|
|
266
270
|
}) && currentRef && typeof currentRef === 'object') {
|
|
267
271
|
if (fieldAffectsData(field)) {
|
|
268
272
|
for(const key in currentRef){
|
|
@@ -299,15 +303,9 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
299
303
|
return;
|
|
300
304
|
}
|
|
301
305
|
if ((field.type === 'blocks' || field.type === 'array') && currentRef && typeof currentRef === 'object') {
|
|
302
|
-
// TODO: `?? field.localized ?? false` shouldn't be necessary, but right now it
|
|
303
|
-
// is so that all fields are correctly traversed in copyToLocale and
|
|
304
|
-
// therefore pass the localization integration tests.
|
|
305
|
-
// I tried replacing the `!parentIsLocalized` condition with `parentIsLocalized === false`
|
|
306
|
-
// in `fieldShouldBeLocalized`, but several tests failed. We must be calling it with incorrect
|
|
307
|
-
// parameters somewhere.
|
|
308
306
|
if (fieldShouldBeLocalized({
|
|
309
307
|
field,
|
|
310
|
-
parentIsLocalized
|
|
308
|
+
parentIsLocalized
|
|
311
309
|
})) {
|
|
312
310
|
if (Array.isArray(currentRef)) {
|
|
313
311
|
traverseArrayOrBlocksField({
|
|
@@ -351,7 +349,7 @@ const traverseArrayOrBlocksField = ({ callback, callbackStack, config, data, fie
|
|
|
351
349
|
field,
|
|
352
350
|
fillEmpty,
|
|
353
351
|
leavesFirst,
|
|
354
|
-
parentIsLocalized
|
|
352
|
+
parentIsLocalized,
|
|
355
353
|
parentPath,
|
|
356
354
|
parentRef: currentParentRef
|
|
357
355
|
});
|