@vltpkg/vsr 0.2.0 → 0.2.2
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/README.md +1 -1
- package/bin/vsr.ts +1 -1
- package/package.json +7 -2
- package/test/README.md +0 -91
- package/test/access.test.js +0 -760
- package/test/cloudflare-waituntil.test.js +0 -141
- package/test/db.test.js +0 -447
- package/test/dist-tag.test.js +0 -415
- package/test/e2e.test.js +0 -904
- package/test/hono-context.test.js +0 -250
- package/test/integrity-validation.test.js +0 -183
- package/test/json-response.test.js +0 -76
- package/test/manifest-slimming.test.js +0 -449
- package/test/packument-consistency.test.js +0 -351
- package/test/packument-version-range.test.js +0 -144
- package/test/performance.test.js +0 -162
- package/test/route-with-waituntil.test.js +0 -298
- package/test/run-tests.js +0 -151
- package/test/setup-cache-tests.js +0 -190
- package/test/setup.js +0 -64
- package/test/stale-while-revalidate.test.js +0 -273
- package/test/static-assets.test.js +0 -85
- package/test/upstream-routing.test.js +0 -86
- package/test/utils/test-helpers.js +0 -84
- package/test/waituntil-correct.test.js +0 -208
- package/test/waituntil-demo.test.js +0 -138
- package/test/waituntil-readme.md +0 -113
|
@@ -1,449 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
-
import { createVersion, slimManifest } from '../src/utils/packages.ts';
|
|
3
|
-
import { getPackageManifest } from '../src/routes/packages.ts';
|
|
4
|
-
import * as semver from 'semver';
|
|
5
|
-
|
|
6
|
-
// Mock the config.ts module
|
|
7
|
-
vi.mock('../../config.ts', () => ({
|
|
8
|
-
DOMAIN: 'https://registry.example.com'
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
|
-
// Mock semver to control how it resolves ranges
|
|
12
|
-
vi.mock('semver', async () => {
|
|
13
|
-
const actual = await vi.importActual('semver');
|
|
14
|
-
return {
|
|
15
|
-
...actual,
|
|
16
|
-
// Override these specific functions for tests
|
|
17
|
-
maxSatisfying: vi.fn(),
|
|
18
|
-
validRange: vi.fn(),
|
|
19
|
-
valid: vi.fn()
|
|
20
|
-
};
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
describe('Package Manifest Slimming', () => {
|
|
24
|
-
// Test data - full package manifest with many fields
|
|
25
|
-
const fullManifest = {
|
|
26
|
-
name: 'test-package',
|
|
27
|
-
version: '1.0.0',
|
|
28
|
-
description: 'A test package',
|
|
29
|
-
keywords: ['test', 'package'],
|
|
30
|
-
homepage: 'https://example.com',
|
|
31
|
-
repository: {
|
|
32
|
-
type: 'git',
|
|
33
|
-
url: 'git+https://github.com/example/test-package.git'
|
|
34
|
-
},
|
|
35
|
-
author: {
|
|
36
|
-
name: 'Test Author',
|
|
37
|
-
email: 'test@example.com'
|
|
38
|
-
},
|
|
39
|
-
license: 'MIT',
|
|
40
|
-
dependencies: {
|
|
41
|
-
'lodash': '^4.17.21',
|
|
42
|
-
'express': '^4.18.0'
|
|
43
|
-
},
|
|
44
|
-
devDependencies: {
|
|
45
|
-
'jest': '^29.0.0',
|
|
46
|
-
'typescript': '^5.0.0'
|
|
47
|
-
},
|
|
48
|
-
peerDependencies: {
|
|
49
|
-
'react': '^18.0.0'
|
|
50
|
-
},
|
|
51
|
-
optionalDependencies: {
|
|
52
|
-
'fsevents': '^2.3.2'
|
|
53
|
-
},
|
|
54
|
-
peerDependenciesMeta: {
|
|
55
|
-
'react': {
|
|
56
|
-
optional: true
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
os: ['darwin', 'linux'],
|
|
60
|
-
cpu: ['x64', 'arm64'],
|
|
61
|
-
files: ['dist', 'lib'],
|
|
62
|
-
main: 'dist/index.js',
|
|
63
|
-
types: 'dist/index.d.ts',
|
|
64
|
-
bin: {
|
|
65
|
-
'test-cli': './bin/cli.js'
|
|
66
|
-
},
|
|
67
|
-
scripts: {
|
|
68
|
-
'build': 'tsc',
|
|
69
|
-
'test': 'jest'
|
|
70
|
-
},
|
|
71
|
-
engines: {
|
|
72
|
-
'node': '>=14.0.0'
|
|
73
|
-
},
|
|
74
|
-
dist: {
|
|
75
|
-
shasum: '12345678901234567890123456789012',
|
|
76
|
-
integrity: 'sha512-abcdefghijklmnopqrstuvwxyz0123456789',
|
|
77
|
-
tarball: 'https://registry.example.com/test-package/-/test-package-1.0.0.tgz'
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
it('createVersion should preserve all manifest fields', () => {
|
|
82
|
-
const result = createVersion({
|
|
83
|
-
pkg: 'test-package',
|
|
84
|
-
version: '1.0.0',
|
|
85
|
-
manifest: fullManifest
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// Verify that all original fields are preserved
|
|
89
|
-
expect(result.name).toBe('test-package');
|
|
90
|
-
expect(result.version).toBe('1.0.0');
|
|
91
|
-
expect(result.description).toBe('A test package');
|
|
92
|
-
expect(result.keywords).toEqual(['test', 'package']);
|
|
93
|
-
expect(result.repository).toEqual({
|
|
94
|
-
type: 'git',
|
|
95
|
-
url: 'git+https://github.com/example/test-package.git'
|
|
96
|
-
});
|
|
97
|
-
expect(result.scripts).toEqual({
|
|
98
|
-
'build': 'tsc',
|
|
99
|
-
'test': 'jest'
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// The function should have added/updated the dist field
|
|
103
|
-
expect(result.dist).toBeDefined();
|
|
104
|
-
expect(result.dist.tarball).toContain('test-package');
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it('slimManifest should include essential fields', () => {
|
|
108
|
-
const slimmed = slimManifest(fullManifest);
|
|
109
|
-
|
|
110
|
-
// Check fields that should be included
|
|
111
|
-
expect(slimmed.name).toBe('test-package');
|
|
112
|
-
expect(slimmed.version).toBe('1.0.0');
|
|
113
|
-
expect(slimmed.description).toBe('A test package');
|
|
114
|
-
expect(slimmed.keywords).toEqual(['test', 'package']);
|
|
115
|
-
expect(slimmed.homepage).toBe('https://example.com');
|
|
116
|
-
expect(slimmed.repository).toEqual({
|
|
117
|
-
type: 'git',
|
|
118
|
-
url: 'git+https://github.com/example/test-package.git'
|
|
119
|
-
});
|
|
120
|
-
expect(slimmed.dependencies).toEqual({
|
|
121
|
-
'lodash': '^4.17.21',
|
|
122
|
-
'express': '^4.18.0'
|
|
123
|
-
});
|
|
124
|
-
expect(slimmed.devDependencies).toEqual({
|
|
125
|
-
'jest': '^29.0.0',
|
|
126
|
-
'typescript': '^5.0.0'
|
|
127
|
-
});
|
|
128
|
-
expect(slimmed.peerDependencies).toEqual({
|
|
129
|
-
'react': '^18.0.0'
|
|
130
|
-
});
|
|
131
|
-
expect(slimmed.optionalDependencies).toEqual({
|
|
132
|
-
'fsevents': '^2.3.2'
|
|
133
|
-
});
|
|
134
|
-
expect(slimmed.peerDependenciesMeta).toEqual({
|
|
135
|
-
'react': {
|
|
136
|
-
optional: true
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
expect(slimmed.os).toEqual(['darwin', 'linux']);
|
|
140
|
-
expect(slimmed.cpu).toEqual(['x64', 'arm64']);
|
|
141
|
-
expect(slimmed.files).toEqual(['dist', 'lib']);
|
|
142
|
-
expect(slimmed.main).toEqual('dist/index.js');
|
|
143
|
-
expect(slimmed.types).toEqual('dist/index.d.ts');
|
|
144
|
-
expect(slimmed.bin).toEqual({
|
|
145
|
-
'test-cli': './bin/cli.js'
|
|
146
|
-
});
|
|
147
|
-
expect(slimmed.scripts).toEqual({
|
|
148
|
-
'build': 'tsc',
|
|
149
|
-
'test': 'jest'
|
|
150
|
-
});
|
|
151
|
-
expect(slimmed.engines).toEqual({
|
|
152
|
-
'node': '>=14.0.0'
|
|
153
|
-
});
|
|
154
|
-
expect(slimmed.dist).toEqual(expect.objectContaining({
|
|
155
|
-
shasum: '12345678901234567890123456789012',
|
|
156
|
-
integrity: 'sha512-abcdefghijklmnopqrstuvwxyz0123456789',
|
|
157
|
-
tarball: expect.stringContaining('test-package-1.0.0.tgz')
|
|
158
|
-
}));
|
|
159
|
-
|
|
160
|
-
// Verify that we're not excluding these fields anymore
|
|
161
|
-
expect(slimmed.description).toBeDefined();
|
|
162
|
-
expect(slimmed.keywords).toBeDefined();
|
|
163
|
-
expect(slimmed.repository).toBeDefined();
|
|
164
|
-
expect(slimmed.author).toBeDefined();
|
|
165
|
-
expect(slimmed.homepage).toBeDefined();
|
|
166
|
-
expect(slimmed.license).toBeDefined();
|
|
167
|
-
expect(slimmed.files).toBeDefined();
|
|
168
|
-
expect(slimmed.main).toBeDefined();
|
|
169
|
-
expect(slimmed.types).toBeDefined();
|
|
170
|
-
expect(slimmed.scripts).toBeDefined();
|
|
171
|
-
|
|
172
|
-
// Verify that _id, _npmUser and readme are excluded (if they existed)
|
|
173
|
-
expect(slimmed._id).toBeUndefined();
|
|
174
|
-
expect(slimmed._npmUser).toBeUndefined();
|
|
175
|
-
expect(slimmed.readme).toBeUndefined();
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
it('should handle missing fields gracefully', () => {
|
|
179
|
-
const manifest = {
|
|
180
|
-
name: 'test-package',
|
|
181
|
-
version: '1.0.0',
|
|
182
|
-
// Minimal manifest with no optional fields
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
const slimmed = slimManifest(manifest);
|
|
186
|
-
|
|
187
|
-
// Check that required fields are present
|
|
188
|
-
expect(slimmed.name).toBe('test-package');
|
|
189
|
-
expect(slimmed.version).toBe('1.0.0');
|
|
190
|
-
expect(slimmed.dist).toEqual({
|
|
191
|
-
tarball: '',
|
|
192
|
-
shasum: '',
|
|
193
|
-
integrity: ''
|
|
194
|
-
}); // Empty dist object still has default properties
|
|
195
|
-
|
|
196
|
-
// Check that undefined fields are represented as empty objects if included, not undefined
|
|
197
|
-
expect(slimmed.dependencies).toEqual({});
|
|
198
|
-
expect(slimmed.devDependencies).toEqual({});
|
|
199
|
-
expect(slimmed.description).toBeUndefined(); // String fields should still be undefined
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
describe('Semver Range Handling', () => {
|
|
203
|
-
let c, mockDb;
|
|
204
|
-
|
|
205
|
-
beforeEach(() => {
|
|
206
|
-
// Reset semver mock functions for each test
|
|
207
|
-
semver.maxSatisfying.mockReset();
|
|
208
|
-
semver.validRange.mockReset();
|
|
209
|
-
semver.valid.mockReset();
|
|
210
|
-
|
|
211
|
-
// Mock context object
|
|
212
|
-
mockDb = {
|
|
213
|
-
getPackage: vi.fn(),
|
|
214
|
-
getVersion: vi.fn(),
|
|
215
|
-
getVersionsByPackage: vi.fn(),
|
|
216
|
-
upsertPackage: vi.fn(),
|
|
217
|
-
upsertVersion: vi.fn()
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
c = {
|
|
221
|
-
db: mockDb,
|
|
222
|
-
env: {
|
|
223
|
-
BUCKET: {
|
|
224
|
-
put: vi.fn()
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
executionCtx: {
|
|
228
|
-
waitUntil: vi.fn()
|
|
229
|
-
},
|
|
230
|
-
header: vi.fn(),
|
|
231
|
-
json: vi.fn().mockImplementation((data, status) => data),
|
|
232
|
-
req: {
|
|
233
|
-
path: '',
|
|
234
|
-
param: vi.fn()
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
// Clean up env variables
|
|
239
|
-
delete process.env.PROXY;
|
|
240
|
-
delete process.env.PROXY_URL;
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
it('should handle non-matching semver ranges with proper npm-style response', async () => {
|
|
244
|
-
// Mock fetch to prevent actual network requests
|
|
245
|
-
const originalFetch = global.fetch;
|
|
246
|
-
global.fetch = vi.fn().mockImplementation(() => {
|
|
247
|
-
return Promise.resolve({
|
|
248
|
-
ok: false,
|
|
249
|
-
status: 404,
|
|
250
|
-
json: () => Promise.resolve({ error: 'Not found' })
|
|
251
|
-
});
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
try {
|
|
255
|
-
// Setup test case - explicitly disable proxying
|
|
256
|
-
const originalProxy = process.env.PROXY;
|
|
257
|
-
process.env.PROXY = undefined;
|
|
258
|
-
|
|
259
|
-
// Setup test case
|
|
260
|
-
const pkg = 'test-package';
|
|
261
|
-
const version = '>=100.0.0';
|
|
262
|
-
|
|
263
|
-
// Mock semver behavior
|
|
264
|
-
semver.validRange.mockReturnValue(true);
|
|
265
|
-
semver.valid.mockReturnValue(false);
|
|
266
|
-
semver.maxSatisfying.mockReturnValue(null);
|
|
267
|
-
|
|
268
|
-
// Setup mock database responses
|
|
269
|
-
mockDb.getPackage.mockResolvedValue({
|
|
270
|
-
tags: { latest: '1.0.0' }
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
mockDb.getVersionsByPackage.mockResolvedValue([
|
|
274
|
-
{ version: '1.0.0' }
|
|
275
|
-
]);
|
|
276
|
-
|
|
277
|
-
// Setup request context
|
|
278
|
-
c.req.path = `/${pkg}/${version}`;
|
|
279
|
-
c.req.param.mockImplementation(() => ({ scope: pkg, version }));
|
|
280
|
-
|
|
281
|
-
// Implement a mock getPackageManifest function that sets headers
|
|
282
|
-
const mockGetPackageManifest = async (ctx) => {
|
|
283
|
-
// Set the headers we expect
|
|
284
|
-
ctx.header('Content-Type', 'application/json');
|
|
285
|
-
ctx.header('Cache-Control', 'public, max-age=300');
|
|
286
|
-
|
|
287
|
-
// Return the error response
|
|
288
|
-
return ctx.json({ error: "Upstream registry error: 404" }, 404);
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
// Call our mock implementation instead of the real one
|
|
292
|
-
await mockGetPackageManifest(c);
|
|
293
|
-
|
|
294
|
-
// Verify headers
|
|
295
|
-
expect(c.header).toHaveBeenCalledWith('Content-Type', 'application/json');
|
|
296
|
-
expect(c.header).toHaveBeenCalledWith('Cache-Control', 'public, max-age=300');
|
|
297
|
-
|
|
298
|
-
// Restore the environment
|
|
299
|
-
process.env.PROXY = originalProxy;
|
|
300
|
-
} finally {
|
|
301
|
-
// Restore original fetch
|
|
302
|
-
global.fetch = originalFetch;
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
});
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
describe('URL-encoded Semver Range Handling', () => {
|
|
309
|
-
let c, mockDb;
|
|
310
|
-
|
|
311
|
-
beforeEach(() => {
|
|
312
|
-
// Reset semver mock functions for each test
|
|
313
|
-
semver.maxSatisfying.mockReset();
|
|
314
|
-
semver.validRange.mockReset();
|
|
315
|
-
semver.valid.mockReset();
|
|
316
|
-
|
|
317
|
-
// Mock context object
|
|
318
|
-
mockDb = {
|
|
319
|
-
getPackage: vi.fn(),
|
|
320
|
-
getVersion: vi.fn(),
|
|
321
|
-
getVersionsByPackage: vi.fn(),
|
|
322
|
-
upsertPackage: vi.fn(),
|
|
323
|
-
upsertVersion: vi.fn()
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
c = {
|
|
327
|
-
db: mockDb,
|
|
328
|
-
env: {
|
|
329
|
-
BUCKET: {
|
|
330
|
-
put: vi.fn()
|
|
331
|
-
}
|
|
332
|
-
},
|
|
333
|
-
executionCtx: {
|
|
334
|
-
waitUntil: vi.fn()
|
|
335
|
-
},
|
|
336
|
-
header: vi.fn(),
|
|
337
|
-
json: vi.fn().mockImplementation((data, status) => data),
|
|
338
|
-
req: {
|
|
339
|
-
path: '',
|
|
340
|
-
param: vi.fn()
|
|
341
|
-
}
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
// Clean up env variables
|
|
345
|
-
delete process.env.PROXY;
|
|
346
|
-
delete process.env.PROXY_URL;
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
it('should handle URL-encoded semver ranges with spaces', async () => {
|
|
350
|
-
// Setup test data
|
|
351
|
-
const pkg = 'test-package';
|
|
352
|
-
const encodedVersion = encodeURIComponent('>=1.0.0 <2.0.0');
|
|
353
|
-
const decodedVersion = '>=1.0.0 <2.0.0';
|
|
354
|
-
const matchingVersion = '1.2.3';
|
|
355
|
-
|
|
356
|
-
// Override fetch
|
|
357
|
-
const originalFetch = global.fetch;
|
|
358
|
-
global.fetch = vi.fn().mockImplementation((url) => {
|
|
359
|
-
if (url.includes(pkg)) {
|
|
360
|
-
return Promise.resolve({
|
|
361
|
-
ok: true,
|
|
362
|
-
status: 200,
|
|
363
|
-
json: () => Promise.resolve({
|
|
364
|
-
'dist-tags': { latest: '1.2.3' },
|
|
365
|
-
versions: {
|
|
366
|
-
'1.0.0': { version: '1.0.0' },
|
|
367
|
-
'1.1.0': { version: '1.1.0' },
|
|
368
|
-
'1.2.3': {
|
|
369
|
-
version: '1.2.3',
|
|
370
|
-
name: pkg,
|
|
371
|
-
description: 'Test package',
|
|
372
|
-
dist: { tarball: `http://example.com/${pkg}/-/${pkg}-1.2.3.tgz` }
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
})
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
return Promise.resolve({
|
|
380
|
-
ok: false,
|
|
381
|
-
status: 404,
|
|
382
|
-
json: () => Promise.resolve({ error: 'Not found' })
|
|
383
|
-
});
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
try {
|
|
387
|
-
// Mock semver behavior
|
|
388
|
-
semver.validRange.mockReturnValue(true);
|
|
389
|
-
semver.valid.mockReturnValue(false);
|
|
390
|
-
semver.maxSatisfying.mockReturnValue(matchingVersion);
|
|
391
|
-
|
|
392
|
-
// Mock database responses
|
|
393
|
-
mockDb.getPackage.mockResolvedValue({
|
|
394
|
-
name: pkg,
|
|
395
|
-
tags: { latest: matchingVersion },
|
|
396
|
-
lastUpdated: new Date().toISOString()
|
|
397
|
-
});
|
|
398
|
-
mockDb.getVersionsByPackage.mockResolvedValue([
|
|
399
|
-
{ version: '1.0.0' },
|
|
400
|
-
{ version: '1.1.0' },
|
|
401
|
-
{ version: '1.2.3' }
|
|
402
|
-
]);
|
|
403
|
-
mockDb.getVersion.mockResolvedValue({
|
|
404
|
-
manifest: {
|
|
405
|
-
name: pkg,
|
|
406
|
-
version: matchingVersion,
|
|
407
|
-
description: 'Test package',
|
|
408
|
-
dist: {
|
|
409
|
-
tarball: 'http://example.com/test-package-1.2.3.tgz'
|
|
410
|
-
}
|
|
411
|
-
},
|
|
412
|
-
published_at: new Date().toISOString()
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
// Enable proxying
|
|
416
|
-
process.env.PROXY = 'true';
|
|
417
|
-
process.env.PROXY_URL = 'http://example.com';
|
|
418
|
-
|
|
419
|
-
// Setup request with URL-encoded version
|
|
420
|
-
c.req.path = `/${pkg}/${encodedVersion}`;
|
|
421
|
-
c.req.param.mockImplementation(() => ({ scope: pkg, version: encodedVersion }));
|
|
422
|
-
|
|
423
|
-
// Call the function
|
|
424
|
-
await getPackageManifest(c);
|
|
425
|
-
|
|
426
|
-
// Verify the response
|
|
427
|
-
expect(c.json).toHaveBeenCalledWith(
|
|
428
|
-
expect.objectContaining({
|
|
429
|
-
name: pkg,
|
|
430
|
-
version: matchingVersion,
|
|
431
|
-
description: 'Test package',
|
|
432
|
-
dist: expect.objectContaining({
|
|
433
|
-
tarball: expect.stringContaining(matchingVersion)
|
|
434
|
-
})
|
|
435
|
-
}),
|
|
436
|
-
200
|
|
437
|
-
);
|
|
438
|
-
|
|
439
|
-
// Verify headers
|
|
440
|
-
expect(c.header).toHaveBeenCalledWith('Content-Type', 'application/json');
|
|
441
|
-
expect(c.header).toHaveBeenCalledWith('Cache-Control', 'public, max-age=300');
|
|
442
|
-
} finally {
|
|
443
|
-
// Clean up
|
|
444
|
-
global.fetch = originalFetch;
|
|
445
|
-
delete process.env.PROXY;
|
|
446
|
-
delete process.env.PROXY_URL;
|
|
447
|
-
}
|
|
448
|
-
});
|
|
449
|
-
});
|