payload 3.86.0 → 3.87.1
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 +4 -7
- 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/getNextJsHMRURL.d.ts +6 -0
- package/dist/utilities/getNextJsHMRURL.d.ts.map +1 -0
- package/dist/utilities/getNextJsHMRURL.js +33 -0
- package/dist/utilities/getNextJsHMRURL.js.map +1 -0
- package/dist/utilities/getNextJsHMRURL.spec.js +60 -0
- package/dist/utilities/getNextJsHMRURL.spec.js.map +1 -0
- package/dist/utilities/getNextVersion.d.ts +7 -0
- package/dist/utilities/getNextVersion.d.ts.map +1 -0
- package/dist/utilities/getNextVersion.js +20 -0
- package/dist/utilities/getNextVersion.js.map +1 -0
- package/dist/utilities/getNextVersion.spec.js +16 -0
- package/dist/utilities/getNextVersion.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 +4 -4
- package/dist/uploads/tempFile.d.ts +0 -7
- package/dist/uploads/tempFile.d.ts.map +0 -1
- package/dist/uploads/tempFile.js +0 -39
- package/dist/uploads/tempFile.js.map +0 -1
|
@@ -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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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getNextJsHMRURL.d.ts","sourceRoot":"","sources":["../../src/utilities/getNextJsHMRURL.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAO,MAYlC,CAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { compareVersions, parseVersion } from './dependencies/versionUtils.js';
|
|
2
|
+
import { getNextVersion } from './getNextVersion.js';
|
|
3
|
+
/** Next.js serves the dev HMR WebSocket on this path from 16.3 onwards. */ const modernHMRPath = '/_next/hmr';
|
|
4
|
+
/** Next.js served the dev HMR WebSocket on this path before 16.3. */ const legacyHMRPath = '/_next/webpack-hmr';
|
|
5
|
+
const firstModernHMRPathVersion = '16.3.0';
|
|
6
|
+
/**
|
|
7
|
+
* Builds the URL of the Next.js dev HMR WebSocket, on the path served by the
|
|
8
|
+
* installed Next.js version. `PAYLOAD_HMR_URL_OVERRIDE` is used verbatim.
|
|
9
|
+
*/ export const getNextJsHMRURL = ()=>{
|
|
10
|
+
if (process.env.PAYLOAD_HMR_URL_OVERRIDE) {
|
|
11
|
+
return process.env.PAYLOAD_HMR_URL_OVERRIDE;
|
|
12
|
+
}
|
|
13
|
+
const port = process.env.PORT || '3000';
|
|
14
|
+
const hasHTTPS = process.env.USE_HTTPS === 'true' || process.argv.includes('--experimental-https');
|
|
15
|
+
const protocol = hasHTTPS ? 'wss' : 'ws';
|
|
16
|
+
// The __NEXT_ASSET_PREFIX env variable is set for both assetPrefix and basePath (tested in Next.js 15.1.6)
|
|
17
|
+
const prefix = process.env.__NEXT_ASSET_PREFIX ?? '';
|
|
18
|
+
return `${protocol}://localhost:${port}${prefix}${getHMRPath()}`;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Pre-release identifiers are ignored, so that a `16.3.0-canary` build maps to the 16.3 path.
|
|
22
|
+
* An unreadable version uses the current path, as Payload being unable to resolve Next.js
|
|
23
|
+
* normally means it is not running under Next.js, where this strategy does not apply.
|
|
24
|
+
*/ const getHMRPath = ()=>{
|
|
25
|
+
const nextVersion = getNextVersion();
|
|
26
|
+
if (!nextVersion) {
|
|
27
|
+
return modernHMRPath;
|
|
28
|
+
}
|
|
29
|
+
const mainVersion = parseVersion(nextVersion).parts.join('.');
|
|
30
|
+
return compareVersions(mainVersion, firstModernHMRPathVersion) === 'lower' ? legacyHMRPath : modernHMRPath;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=getNextJsHMRURL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getNextJsHMRURL.ts"],"sourcesContent":["import { compareVersions, parseVersion } from './dependencies/versionUtils.js'\nimport { getNextVersion } from './getNextVersion.js'\n\n/** Next.js serves the dev HMR WebSocket on this path from 16.3 onwards. */\nconst modernHMRPath = '/_next/hmr'\n\n/** Next.js served the dev HMR WebSocket on this path before 16.3. */\nconst legacyHMRPath = '/_next/webpack-hmr'\n\nconst firstModernHMRPathVersion = '16.3.0'\n\n/**\n * Builds the URL of the Next.js dev HMR WebSocket, on the path served by the\n * installed Next.js version. `PAYLOAD_HMR_URL_OVERRIDE` is used verbatim.\n */\nexport const getNextJsHMRURL = (): string => {\n if (process.env.PAYLOAD_HMR_URL_OVERRIDE) {\n return process.env.PAYLOAD_HMR_URL_OVERRIDE\n }\n\n const port = process.env.PORT || '3000'\n const hasHTTPS = process.env.USE_HTTPS === 'true' || process.argv.includes('--experimental-https')\n const protocol = hasHTTPS ? 'wss' : 'ws'\n // The __NEXT_ASSET_PREFIX env variable is set for both assetPrefix and basePath (tested in Next.js 15.1.6)\n const prefix = process.env.__NEXT_ASSET_PREFIX ?? ''\n\n return `${protocol}://localhost:${port}${prefix}${getHMRPath()}`\n}\n\n/**\n * Pre-release identifiers are ignored, so that a `16.3.0-canary` build maps to the 16.3 path.\n * An unreadable version uses the current path, as Payload being unable to resolve Next.js\n * normally means it is not running under Next.js, where this strategy does not apply.\n */\nconst getHMRPath = (): string => {\n const nextVersion = getNextVersion()\n\n if (!nextVersion) {\n return modernHMRPath\n }\n\n const mainVersion = parseVersion(nextVersion).parts.join('.')\n\n return compareVersions(mainVersion, firstModernHMRPathVersion) === 'lower'\n ? legacyHMRPath\n : modernHMRPath\n}\n"],"names":["compareVersions","parseVersion","getNextVersion","modernHMRPath","legacyHMRPath","firstModernHMRPathVersion","getNextJsHMRURL","process","env","PAYLOAD_HMR_URL_OVERRIDE","port","PORT","hasHTTPS","USE_HTTPS","argv","includes","protocol","prefix","__NEXT_ASSET_PREFIX","getHMRPath","nextVersion","mainVersion","parts","join"],"mappings":"AAAA,SAASA,eAAe,EAAEC,YAAY,QAAQ,iCAAgC;AAC9E,SAASC,cAAc,QAAQ,sBAAqB;AAEpD,yEAAyE,GACzE,MAAMC,gBAAgB;AAEtB,mEAAmE,GACnE,MAAMC,gBAAgB;AAEtB,MAAMC,4BAA4B;AAElC;;;CAGC,GACD,OAAO,MAAMC,kBAAkB;IAC7B,IAAIC,QAAQC,GAAG,CAACC,wBAAwB,EAAE;QACxC,OAAOF,QAAQC,GAAG,CAACC,wBAAwB;IAC7C;IAEA,MAAMC,OAAOH,QAAQC,GAAG,CAACG,IAAI,IAAI;IACjC,MAAMC,WAAWL,QAAQC,GAAG,CAACK,SAAS,KAAK,UAAUN,QAAQO,IAAI,CAACC,QAAQ,CAAC;IAC3E,MAAMC,WAAWJ,WAAW,QAAQ;IACpC,2GAA2G;IAC3G,MAAMK,SAASV,QAAQC,GAAG,CAACU,mBAAmB,IAAI;IAElD,OAAO,GAAGF,SAAS,aAAa,EAAEN,OAAOO,SAASE,cAAc;AAClE,EAAC;AAED;;;;CAIC,GACD,MAAMA,aAAa;IACjB,MAAMC,cAAclB;IAEpB,IAAI,CAACkB,aAAa;QAChB,OAAOjB;IACT;IAEA,MAAMkB,cAAcpB,aAAamB,aAAaE,KAAK,CAACC,IAAI,CAAC;IAEzD,OAAOvB,gBAAgBqB,aAAahB,+BAA+B,UAC/DD,gBACAD;AACN"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
vi.mock('./getNextVersion.js', ()=>({
|
|
3
|
+
getNextVersion: vi.fn()
|
|
4
|
+
}));
|
|
5
|
+
const { getNextVersion } = await import('./getNextVersion.js');
|
|
6
|
+
const { getNextJsHMRURL } = await import('./getNextJsHMRURL.js');
|
|
7
|
+
const modernURL = 'ws://localhost:3000/_next/hmr';
|
|
8
|
+
const legacyURL = 'ws://localhost:3000/_next/webpack-hmr';
|
|
9
|
+
describe('getNextJsHMRURL', ()=>{
|
|
10
|
+
beforeEach(()=>{
|
|
11
|
+
vi.mocked(getNextVersion).mockReturnValue('16.3.0');
|
|
12
|
+
vi.stubEnv('PAYLOAD_HMR_URL_OVERRIDE', undefined);
|
|
13
|
+
vi.stubEnv('PORT', '3000');
|
|
14
|
+
});
|
|
15
|
+
afterEach(()=>{
|
|
16
|
+
vi.unstubAllEnvs();
|
|
17
|
+
});
|
|
18
|
+
it('should use the current HMR path on Next.js 16.3', ()=>{
|
|
19
|
+
expect(getNextJsHMRURL()).toBe(modernURL);
|
|
20
|
+
});
|
|
21
|
+
it('should use the current HMR path on Next.js versions above 16.3', ()=>{
|
|
22
|
+
vi.mocked(getNextVersion).mockReturnValue('17.0.1');
|
|
23
|
+
expect(getNextJsHMRURL()).toBe(modernURL);
|
|
24
|
+
});
|
|
25
|
+
it('should use the legacy HMR path on Next.js below 16.3', ()=>{
|
|
26
|
+
vi.mocked(getNextVersion).mockReturnValue('16.2.7');
|
|
27
|
+
expect(getNextJsHMRURL()).toBe(legacyURL);
|
|
28
|
+
});
|
|
29
|
+
it('should use the legacy HMR path on a Next.js 15 install', ()=>{
|
|
30
|
+
vi.mocked(getNextVersion).mockReturnValue('15.5.0');
|
|
31
|
+
expect(getNextJsHMRURL()).toBe(legacyURL);
|
|
32
|
+
});
|
|
33
|
+
it('should ignore pre-release identifiers when choosing the path', ()=>{
|
|
34
|
+
vi.mocked(getNextVersion).mockReturnValue('16.3.0-canary.12');
|
|
35
|
+
expect(getNextJsHMRURL()).toBe(modernURL);
|
|
36
|
+
});
|
|
37
|
+
it('should use the legacy HMR path on a pre-release below 16.3', ()=>{
|
|
38
|
+
vi.mocked(getNextVersion).mockReturnValue('16.2.0-canary.5');
|
|
39
|
+
expect(getNextJsHMRURL()).toBe(legacyURL);
|
|
40
|
+
});
|
|
41
|
+
it('should use the current HMR path when the Next.js version is unknown', ()=>{
|
|
42
|
+
vi.mocked(getNextVersion).mockReturnValue(undefined);
|
|
43
|
+
expect(getNextJsHMRURL()).toBe(modernURL);
|
|
44
|
+
});
|
|
45
|
+
it('should use PAYLOAD_HMR_URL_OVERRIDE whatever the version', ()=>{
|
|
46
|
+
vi.mocked(getNextVersion).mockReturnValue(undefined);
|
|
47
|
+
vi.stubEnv('PAYLOAD_HMR_URL_OVERRIDE', 'ws://localhost:4000/custom-hmr');
|
|
48
|
+
expect(getNextJsHMRURL()).toBe('ws://localhost:4000/custom-hmr');
|
|
49
|
+
});
|
|
50
|
+
it('should use the wss protocol when HTTPS is enabled', ()=>{
|
|
51
|
+
vi.stubEnv('USE_HTTPS', 'true');
|
|
52
|
+
expect(getNextJsHMRURL()).toBe('wss://localhost:3000/_next/hmr');
|
|
53
|
+
});
|
|
54
|
+
it('should include the Next.js asset prefix', ()=>{
|
|
55
|
+
vi.stubEnv('__NEXT_ASSET_PREFIX', '/base');
|
|
56
|
+
expect(getNextJsHMRURL()).toBe('ws://localhost:3000/base/_next/hmr');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
//# sourceMappingURL=getNextJsHMRURL.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getNextJsHMRURL.spec.ts"],"sourcesContent":["import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'\n\nvi.mock('./getNextVersion.js', () => ({ getNextVersion: vi.fn() }))\n\nconst { getNextVersion } = await import('./getNextVersion.js')\nconst { getNextJsHMRURL } = await import('./getNextJsHMRURL.js')\n\nconst modernURL = 'ws://localhost:3000/_next/hmr'\nconst legacyURL = 'ws://localhost:3000/_next/webpack-hmr'\n\ndescribe('getNextJsHMRURL', () => {\n beforeEach(() => {\n vi.mocked(getNextVersion).mockReturnValue('16.3.0')\n vi.stubEnv('PAYLOAD_HMR_URL_OVERRIDE', undefined)\n vi.stubEnv('PORT', '3000')\n })\n\n afterEach(() => {\n vi.unstubAllEnvs()\n })\n\n it('should use the current HMR path on Next.js 16.3', () => {\n expect(getNextJsHMRURL()).toBe(modernURL)\n })\n\n it('should use the current HMR path on Next.js versions above 16.3', () => {\n vi.mocked(getNextVersion).mockReturnValue('17.0.1')\n\n expect(getNextJsHMRURL()).toBe(modernURL)\n })\n\n it('should use the legacy HMR path on Next.js below 16.3', () => {\n vi.mocked(getNextVersion).mockReturnValue('16.2.7')\n\n expect(getNextJsHMRURL()).toBe(legacyURL)\n })\n\n it('should use the legacy HMR path on a Next.js 15 install', () => {\n vi.mocked(getNextVersion).mockReturnValue('15.5.0')\n\n expect(getNextJsHMRURL()).toBe(legacyURL)\n })\n\n it('should ignore pre-release identifiers when choosing the path', () => {\n vi.mocked(getNextVersion).mockReturnValue('16.3.0-canary.12')\n\n expect(getNextJsHMRURL()).toBe(modernURL)\n })\n\n it('should use the legacy HMR path on a pre-release below 16.3', () => {\n vi.mocked(getNextVersion).mockReturnValue('16.2.0-canary.5')\n\n expect(getNextJsHMRURL()).toBe(legacyURL)\n })\n\n it('should use the current HMR path when the Next.js version is unknown', () => {\n vi.mocked(getNextVersion).mockReturnValue(undefined)\n\n expect(getNextJsHMRURL()).toBe(modernURL)\n })\n\n it('should use PAYLOAD_HMR_URL_OVERRIDE whatever the version', () => {\n vi.mocked(getNextVersion).mockReturnValue(undefined)\n vi.stubEnv('PAYLOAD_HMR_URL_OVERRIDE', 'ws://localhost:4000/custom-hmr')\n\n expect(getNextJsHMRURL()).toBe('ws://localhost:4000/custom-hmr')\n })\n\n it('should use the wss protocol when HTTPS is enabled', () => {\n vi.stubEnv('USE_HTTPS', 'true')\n\n expect(getNextJsHMRURL()).toBe('wss://localhost:3000/_next/hmr')\n })\n\n it('should include the Next.js asset prefix', () => {\n vi.stubEnv('__NEXT_ASSET_PREFIX', '/base')\n\n expect(getNextJsHMRURL()).toBe('ws://localhost:3000/base/_next/hmr')\n })\n})\n"],"names":["afterEach","beforeEach","describe","expect","it","vi","mock","getNextVersion","fn","getNextJsHMRURL","modernURL","legacyURL","mocked","mockReturnValue","stubEnv","undefined","unstubAllEnvs","toBe"],"mappings":"AAAA,SAASA,SAAS,EAAEC,UAAU,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ,SAAQ;AAExEA,GAAGC,IAAI,CAAC,uBAAuB,IAAO,CAAA;QAAEC,gBAAgBF,GAAGG,EAAE;IAAG,CAAA;AAEhE,MAAM,EAAED,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC;AACxC,MAAM,EAAEE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC;AAEzC,MAAMC,YAAY;AAClB,MAAMC,YAAY;AAElBT,SAAS,mBAAmB;IAC1BD,WAAW;QACTI,GAAGO,MAAM,CAACL,gBAAgBM,eAAe,CAAC;QAC1CR,GAAGS,OAAO,CAAC,4BAA4BC;QACvCV,GAAGS,OAAO,CAAC,QAAQ;IACrB;IAEAd,UAAU;QACRK,GAAGW,aAAa;IAClB;IAEAZ,GAAG,mDAAmD;QACpDD,OAAOM,mBAAmBQ,IAAI,CAACP;IACjC;IAEAN,GAAG,kEAAkE;QACnEC,GAAGO,MAAM,CAACL,gBAAgBM,eAAe,CAAC;QAE1CV,OAAOM,mBAAmBQ,IAAI,CAACP;IACjC;IAEAN,GAAG,wDAAwD;QACzDC,GAAGO,MAAM,CAACL,gBAAgBM,eAAe,CAAC;QAE1CV,OAAOM,mBAAmBQ,IAAI,CAACN;IACjC;IAEAP,GAAG,0DAA0D;QAC3DC,GAAGO,MAAM,CAACL,gBAAgBM,eAAe,CAAC;QAE1CV,OAAOM,mBAAmBQ,IAAI,CAACN;IACjC;IAEAP,GAAG,gEAAgE;QACjEC,GAAGO,MAAM,CAACL,gBAAgBM,eAAe,CAAC;QAE1CV,OAAOM,mBAAmBQ,IAAI,CAACP;IACjC;IAEAN,GAAG,8DAA8D;QAC/DC,GAAGO,MAAM,CAACL,gBAAgBM,eAAe,CAAC;QAE1CV,OAAOM,mBAAmBQ,IAAI,CAACN;IACjC;IAEAP,GAAG,uEAAuE;QACxEC,GAAGO,MAAM,CAACL,gBAAgBM,eAAe,CAACE;QAE1CZ,OAAOM,mBAAmBQ,IAAI,CAACP;IACjC;IAEAN,GAAG,4DAA4D;QAC7DC,GAAGO,MAAM,CAACL,gBAAgBM,eAAe,CAACE;QAC1CV,GAAGS,OAAO,CAAC,4BAA4B;QAEvCX,OAAOM,mBAAmBQ,IAAI,CAAC;IACjC;IAEAb,GAAG,qDAAqD;QACtDC,GAAGS,OAAO,CAAC,aAAa;QAExBX,OAAOM,mBAAmBQ,IAAI,CAAC;IACjC;IAEAb,GAAG,2CAA2C;QAC5CC,GAAGS,OAAO,CAAC,uBAAuB;QAElCX,OAAOM,mBAAmBQ,IAAI,CAAC;IACjC;AACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads the version of the Next.js installed alongside the running app.
|
|
3
|
+
* Returns undefined if Next.js cannot be resolved, e.g. because Payload runs
|
|
4
|
+
* outside of Next.js or from a directory the app's dependencies are not visible from.
|
|
5
|
+
*/
|
|
6
|
+
export declare const getNextVersion: () => string | undefined;
|
|
7
|
+
//# sourceMappingURL=getNextVersion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getNextVersion.d.ts","sourceRoot":"","sources":["../../src/utilities/getNextVersion.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAAO,MAAM,GAAG,SAc1C,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import { resolveFrom } from './dependencies/resolveFrom.js';
|
|
3
|
+
/**
|
|
4
|
+
* Reads the version of the Next.js installed alongside the running app.
|
|
5
|
+
* Returns undefined if Next.js cannot be resolved, e.g. because Payload runs
|
|
6
|
+
* outside of Next.js or from a directory the app's dependencies are not visible from.
|
|
7
|
+
*/ export const getNextVersion = ()=>{
|
|
8
|
+
try {
|
|
9
|
+
const packageJSONPath = resolveFrom(process.cwd(), 'next/package.json', true);
|
|
10
|
+
if (!packageJSONPath) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
const { version } = JSON.parse(readFileSync(packageJSONPath, 'utf-8'));
|
|
14
|
+
return typeof version === 'string' ? version : undefined;
|
|
15
|
+
} catch (_) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=getNextVersion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getNextVersion.ts"],"sourcesContent":["import { readFileSync } from 'fs'\n\nimport { resolveFrom } from './dependencies/resolveFrom.js'\n\n/**\n * Reads the version of the Next.js installed alongside the running app.\n * Returns undefined if Next.js cannot be resolved, e.g. because Payload runs\n * outside of Next.js or from a directory the app's dependencies are not visible from.\n */\nexport const getNextVersion = (): string | undefined => {\n try {\n const packageJSONPath = resolveFrom(process.cwd(), 'next/package.json', true)\n\n if (!packageJSONPath) {\n return undefined\n }\n\n const { version } = JSON.parse(readFileSync(packageJSONPath, 'utf-8'))\n\n return typeof version === 'string' ? version : undefined\n } catch (_) {\n return undefined\n }\n}\n"],"names":["readFileSync","resolveFrom","getNextVersion","packageJSONPath","process","cwd","undefined","version","JSON","parse","_"],"mappings":"AAAA,SAASA,YAAY,QAAQ,KAAI;AAEjC,SAASC,WAAW,QAAQ,gCAA+B;AAE3D;;;;CAIC,GACD,OAAO,MAAMC,iBAAiB;IAC5B,IAAI;QACF,MAAMC,kBAAkBF,YAAYG,QAAQC,GAAG,IAAI,qBAAqB;QAExE,IAAI,CAACF,iBAAiB;YACpB,OAAOG;QACT;QAEA,MAAM,EAAEC,OAAO,EAAE,GAAGC,KAAKC,KAAK,CAACT,aAAaG,iBAAiB;QAE7D,OAAO,OAAOI,YAAY,WAAWA,UAAUD;IACjD,EAAE,OAAOI,GAAG;QACV,OAAOJ;IACT;AACF,EAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { getNextVersion } from './getNextVersion.js';
|
|
3
|
+
describe('getNextVersion', ()=>{
|
|
4
|
+
afterEach(()=>{
|
|
5
|
+
vi.restoreAllMocks();
|
|
6
|
+
});
|
|
7
|
+
it('should read the version of the installed Next.js', ()=>{
|
|
8
|
+
expect(getNextVersion()).toMatch(/^\d+\.\d+\.\d+/);
|
|
9
|
+
});
|
|
10
|
+
it('should return undefined when Next.js cannot be resolved', ()=>{
|
|
11
|
+
vi.spyOn(process, 'cwd').mockReturnValue('/');
|
|
12
|
+
expect(getNextVersion()).toBeUndefined();
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=getNextVersion.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getNextVersion.spec.ts"],"sourcesContent":["import { afterEach, describe, expect, it, vi } from 'vitest'\n\nimport { getNextVersion } from './getNextVersion.js'\n\ndescribe('getNextVersion', () => {\n afterEach(() => {\n vi.restoreAllMocks()\n })\n\n it('should read the version of the installed Next.js', () => {\n expect(getNextVersion()).toMatch(/^\\d+\\.\\d+\\.\\d+/)\n })\n\n it('should return undefined when Next.js cannot be resolved', () => {\n vi.spyOn(process, 'cwd').mockReturnValue('/')\n\n expect(getNextVersion()).toBeUndefined()\n })\n})\n"],"names":["afterEach","describe","expect","it","vi","getNextVersion","restoreAllMocks","toMatch","spyOn","process","mockReturnValue","toBeUndefined"],"mappings":"AAAA,SAASA,SAAS,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ,SAAQ;AAE5D,SAASC,cAAc,QAAQ,sBAAqB;AAEpDJ,SAAS,kBAAkB;IACzBD,UAAU;QACRI,GAAGE,eAAe;IACpB;IAEAH,GAAG,oDAAoD;QACrDD,OAAOG,kBAAkBE,OAAO,CAAC;IACnC;IAEAJ,GAAG,2DAA2D;QAC5DC,GAAGI,KAAK,CAACC,SAAS,OAAOC,eAAe,CAAC;QAEzCR,OAAOG,kBAAkBM,aAAa;IACxC;AACF"}
|
|
@@ -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"}
|