@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.
@@ -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
- });