@vltpkg/vsr 0.0.0-26 → 0.0.0-27
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/LICENSE +10 -114
- package/dist/README.md +1 -0
- package/dist/assets/public/favicon.ico +0 -0
- package/dist/assets/public/fonts/courier-bold-italic.ttf +0 -0
- package/dist/assets/public/fonts/courier-bold.ttf +0 -0
- package/dist/assets/public/fonts/courier-italic.ttf +0 -0
- package/dist/assets/public/fonts/courier-regular.ttf +0 -0
- package/dist/assets/public/fonts/geist-mono.ttf +0 -0
- package/dist/assets/public/fonts/inter.ttf +0 -0
- package/dist/assets/public/index.html +70 -0
- package/dist/assets/public/index.js +1300 -0
- package/dist/assets/public/index.js.map +7 -0
- package/dist/assets/public/main.css +1 -0
- package/dist/bin/vsr.js +771 -0
- package/dist/index.js +28283 -0
- package/dist/index.js.map +8 -0
- package/package.json +6 -49
- package/DEPLOY.md +0 -163
- package/config.ts +0 -221
- package/drizzle.config.js +0 -40
- package/info/COMPARISONS.md +0 -37
- package/info/CONFIGURATION.md +0 -143
- package/info/CONTRIBUTING.md +0 -32
- package/info/DATABASE_SETUP.md +0 -108
- package/info/GRANULAR_ACCESS_TOKENS.md +0 -160
- package/info/PROJECT_STRUCTURE.md +0 -291
- package/info/ROADMAP.md +0 -27
- package/info/SUPPORT.md +0 -39
- package/info/TESTING.md +0 -301
- package/info/USER_SUPPORT.md +0 -31
- package/scripts/build-assets.js +0 -31
- package/scripts/build-bin.js +0 -62
- package/scripts/prepack.js +0 -27
- package/src/bin/vsr.ts +0 -484
- package/src/db/client.ts +0 -590
- package/src/db/migrations/0000_faulty_ricochet.sql +0 -14
- package/src/db/migrations/0000_initial.sql +0 -29
- package/src/db/migrations/0001_uuid_validation.sql +0 -35
- package/src/db/migrations/0001_wealthy_magdalene.sql +0 -7
- package/src/db/migrations/drop.sql +0 -3
- package/src/db/migrations/meta/0000_snapshot.json +0 -104
- package/src/db/migrations/meta/0001_snapshot.json +0 -155
- package/src/db/migrations/meta/_journal.json +0 -20
- package/src/db/schema.ts +0 -43
- package/src/index.ts +0 -434
- package/src/middleware/config.ts +0 -79
- package/src/middleware/telemetry.ts +0 -43
- package/src/queue/index.ts +0 -97
- package/src/routes/access.ts +0 -852
- package/src/routes/docs.ts +0 -63
- package/src/routes/misc.ts +0 -469
- package/src/routes/packages.ts +0 -2823
- package/src/routes/ping.ts +0 -39
- package/src/routes/search.ts +0 -131
- package/src/routes/static.ts +0 -74
- package/src/routes/tokens.ts +0 -259
- package/src/routes/users.ts +0 -68
- package/src/utils/auth.ts +0 -202
- package/src/utils/cache.ts +0 -587
- package/src/utils/config.ts +0 -50
- package/src/utils/database.ts +0 -69
- package/src/utils/docs.ts +0 -146
- package/src/utils/packages.ts +0 -453
- package/src/utils/response.ts +0 -125
- package/src/utils/routes.ts +0 -64
- package/src/utils/spa.ts +0 -52
- package/src/utils/tracing.ts +0 -52
- package/src/utils/upstream.ts +0 -172
- package/test/access.test.ts +0 -705
- package/test/audit.test.ts +0 -828
- package/test/dashboard.test.ts +0 -693
- package/test/dist-tags.test.ts +0 -678
- package/test/manifest.test.ts +0 -436
- package/test/packument.test.ts +0 -530
- package/test/ping.test.ts +0 -41
- package/test/search.test.ts +0 -472
- package/test/setup.ts +0 -130
- package/test/static.test.ts +0 -646
- package/test/tokens.test.ts +0 -389
- package/test/utils/auth.test.ts +0 -214
- package/test/utils/packages.test.ts +0 -235
- package/test/utils/response.test.ts +0 -184
- package/test/whoami.test.ts +0 -119
- package/tsconfig.json +0 -16
- package/tsconfig.worker.json +0 -3
- package/typedoc.mjs +0 -2
- package/types.ts +0 -598
- package/vitest.config.ts +0 -25
- package/vlt.json.example +0 -56
- package/wrangler.json +0 -65
- /package/{src → dist}/assets/public/images/bg.png +0 -0
- /package/{src → dist}/assets/public/images/clients/logo-bun.png +0 -0
- /package/{src → dist}/assets/public/images/clients/logo-deno.png +0 -0
- /package/{src → dist}/assets/public/images/clients/logo-npm.png +0 -0
- /package/{src → dist}/assets/public/images/clients/logo-pnpm.png +0 -0
- /package/{src → dist}/assets/public/images/clients/logo-vlt.png +0 -0
- /package/{src → dist}/assets/public/images/clients/logo-yarn.png +0 -0
- /package/{src → dist}/assets/public/images/favicon/apple-touch-icon.png +0 -0
- /package/{src → dist}/assets/public/images/favicon/favicon-96x96.png +0 -0
- /package/{src → dist}/assets/public/images/favicon/favicon.ico +0 -0
- /package/{src → dist}/assets/public/images/favicon/favicon.svg +0 -0
- /package/{src → dist}/assets/public/images/favicon/site.webmanifest +0 -0
- /package/{src → dist}/assets/public/images/favicon/web-app-manifest-192x192.png +0 -0
- /package/{src → dist}/assets/public/images/favicon/web-app-manifest-512x512.png +0 -0
- /package/{src → dist}/assets/public/styles/styles.css +0 -0
- /package/{src → dist}/bin/demo/package.json +0 -0
- /package/{src → dist}/bin/demo/vlt.json +0 -0
package/test/dist-tags.test.ts
DELETED
|
@@ -1,678 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest'
|
|
2
|
-
import { env } from 'cloudflare:test'
|
|
3
|
-
import { app } from '../src/index.ts'
|
|
4
|
-
|
|
5
|
-
describe('Dist-Tags Endpoints', () => {
|
|
6
|
-
describe('Get Dist-Tags', () => {
|
|
7
|
-
describe('Unscoped Packages', () => {
|
|
8
|
-
it('should get dist-tags for unscoped packages', async () => {
|
|
9
|
-
const res = await app.request(
|
|
10
|
-
'/-/package/lodash/dist-tags',
|
|
11
|
-
{},
|
|
12
|
-
env,
|
|
13
|
-
)
|
|
14
|
-
expect([200, 404].includes(res.status)).toBe(true)
|
|
15
|
-
expect(res.headers.get('content-type')).toContain(
|
|
16
|
-
'application/json',
|
|
17
|
-
)
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('should return proper dist-tags structure', async () => {
|
|
21
|
-
const res = await app.request(
|
|
22
|
-
'/-/package/lodash/dist-tags',
|
|
23
|
-
{},
|
|
24
|
-
env,
|
|
25
|
-
)
|
|
26
|
-
if (res.status === 200) {
|
|
27
|
-
const data = (await res.json()) as any
|
|
28
|
-
expect(data).toBeDefined()
|
|
29
|
-
// Dist-tags structure should be { "latest": "1.0.0", "beta": "1.1.0-beta.1" }
|
|
30
|
-
}
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('should handle packages with no dist-tags', async () => {
|
|
34
|
-
const res = await app.request(
|
|
35
|
-
'/-/package/empty-package/dist-tags',
|
|
36
|
-
{},
|
|
37
|
-
env,
|
|
38
|
-
)
|
|
39
|
-
expect([200, 404].includes(res.status)).toBe(true)
|
|
40
|
-
})
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
describe('Scoped Packages', () => {
|
|
44
|
-
it('should get dist-tags for scoped packages', async () => {
|
|
45
|
-
const res = await app.request(
|
|
46
|
-
'/-/package/@types%2Fnode/dist-tags',
|
|
47
|
-
{},
|
|
48
|
-
env,
|
|
49
|
-
)
|
|
50
|
-
expect([200, 404].includes(res.status)).toBe(true)
|
|
51
|
-
expect(res.headers.get('content-type')).toContain(
|
|
52
|
-
'application/json',
|
|
53
|
-
)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('should handle URL-encoded scoped package names', async () => {
|
|
57
|
-
const res = await app.request(
|
|
58
|
-
'/-/package/@scope%2Fpackage/dist-tags',
|
|
59
|
-
{},
|
|
60
|
-
env,
|
|
61
|
-
)
|
|
62
|
-
expect([200, 404].includes(res.status)).toBe(true)
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('should return dist-tags for organization packages', async () => {
|
|
66
|
-
const res = await app.request(
|
|
67
|
-
'/-/package/@myorg%2Fmypackage/dist-tags',
|
|
68
|
-
{},
|
|
69
|
-
env,
|
|
70
|
-
)
|
|
71
|
-
expect([200, 404].includes(res.status)).toBe(true)
|
|
72
|
-
})
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
describe('Dist-Tags Response Format', () => {
|
|
76
|
-
it('should return dist-tags as key-value pairs', async () => {
|
|
77
|
-
const res = await app.request(
|
|
78
|
-
'/-/package/lodash/dist-tags',
|
|
79
|
-
{},
|
|
80
|
-
env,
|
|
81
|
-
)
|
|
82
|
-
if (res.status === 200) {
|
|
83
|
-
const data = (await res.json()) as any
|
|
84
|
-
expect(data).toBeDefined()
|
|
85
|
-
expect(typeof data).toBe('object')
|
|
86
|
-
}
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
it('should include latest tag by default', async () => {
|
|
90
|
-
const res = await app.request(
|
|
91
|
-
'/-/package/lodash/dist-tags',
|
|
92
|
-
{},
|
|
93
|
-
env,
|
|
94
|
-
)
|
|
95
|
-
if (res.status === 200) {
|
|
96
|
-
const data = (await res.json()) as any
|
|
97
|
-
// Most packages should have a 'latest' tag
|
|
98
|
-
expect(data).toBeDefined()
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
})
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
describe('Set Dist-Tags', () => {
|
|
105
|
-
describe('Create/Update Dist-Tags', () => {
|
|
106
|
-
it('should set dist-tag for unscoped packages', async () => {
|
|
107
|
-
const res = await app.request(
|
|
108
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
109
|
-
{
|
|
110
|
-
method: 'PUT',
|
|
111
|
-
headers: {
|
|
112
|
-
'Content-Type': 'application/json',
|
|
113
|
-
},
|
|
114
|
-
body: JSON.stringify('1.0.0-beta.1'),
|
|
115
|
-
},
|
|
116
|
-
env,
|
|
117
|
-
)
|
|
118
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
it('should set dist-tag for scoped packages', async () => {
|
|
122
|
-
const res = await app.request(
|
|
123
|
-
'/-/package/@myorg%2Fmypackage/dist-tags/beta',
|
|
124
|
-
{
|
|
125
|
-
method: 'PUT',
|
|
126
|
-
headers: {
|
|
127
|
-
'Content-Type': 'application/json',
|
|
128
|
-
},
|
|
129
|
-
body: JSON.stringify('2.0.0-beta.2'),
|
|
130
|
-
},
|
|
131
|
-
env,
|
|
132
|
-
)
|
|
133
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
it('should update existing dist-tags', async () => {
|
|
137
|
-
const res = await app.request(
|
|
138
|
-
'/-/package/mypackage/dist-tags/latest',
|
|
139
|
-
{
|
|
140
|
-
method: 'PUT',
|
|
141
|
-
headers: {
|
|
142
|
-
'Content-Type': 'application/json',
|
|
143
|
-
},
|
|
144
|
-
body: JSON.stringify('2.0.0'),
|
|
145
|
-
},
|
|
146
|
-
env,
|
|
147
|
-
)
|
|
148
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
it('should handle custom dist-tag names', async () => {
|
|
152
|
-
const res = await app.request(
|
|
153
|
-
'/-/package/mypackage/dist-tags/experimental',
|
|
154
|
-
{
|
|
155
|
-
method: 'PUT',
|
|
156
|
-
headers: {
|
|
157
|
-
'Content-Type': 'application/json',
|
|
158
|
-
},
|
|
159
|
-
body: JSON.stringify('3.0.0-alpha.1'),
|
|
160
|
-
},
|
|
161
|
-
env,
|
|
162
|
-
)
|
|
163
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
164
|
-
})
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
describe('Dist-Tag Validation', () => {
|
|
168
|
-
it('should validate semver versions', async () => {
|
|
169
|
-
const res = await app.request(
|
|
170
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
171
|
-
{
|
|
172
|
-
method: 'PUT',
|
|
173
|
-
headers: {
|
|
174
|
-
'Content-Type': 'application/json',
|
|
175
|
-
},
|
|
176
|
-
body: JSON.stringify('invalid-version'),
|
|
177
|
-
},
|
|
178
|
-
env,
|
|
179
|
-
)
|
|
180
|
-
expect([400, 401, 404].includes(res.status)).toBe(true)
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
it('should validate dist-tag names', async () => {
|
|
184
|
-
const res = await app.request(
|
|
185
|
-
'/-/package/mypackage/dist-tags/invalid..tag',
|
|
186
|
-
{
|
|
187
|
-
method: 'PUT',
|
|
188
|
-
headers: {
|
|
189
|
-
'Content-Type': 'application/json',
|
|
190
|
-
},
|
|
191
|
-
body: JSON.stringify('1.0.0'),
|
|
192
|
-
},
|
|
193
|
-
env,
|
|
194
|
-
)
|
|
195
|
-
expect([400, 401, 404].includes(res.status)).toBe(true)
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
it('should handle reserved dist-tag names', async () => {
|
|
199
|
-
const res = await app.request(
|
|
200
|
-
'/-/package/mypackage/dist-tags/package',
|
|
201
|
-
{
|
|
202
|
-
method: 'PUT',
|
|
203
|
-
headers: {
|
|
204
|
-
'Content-Type': 'application/json',
|
|
205
|
-
},
|
|
206
|
-
body: JSON.stringify('1.0.0'),
|
|
207
|
-
},
|
|
208
|
-
env,
|
|
209
|
-
)
|
|
210
|
-
expect([400, 401, 404].includes(res.status)).toBe(true)
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
it('should require version to exist in package', async () => {
|
|
214
|
-
const res = await app.request(
|
|
215
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
216
|
-
{
|
|
217
|
-
method: 'PUT',
|
|
218
|
-
headers: {
|
|
219
|
-
'Content-Type': 'application/json',
|
|
220
|
-
},
|
|
221
|
-
body: JSON.stringify('999.999.999'),
|
|
222
|
-
},
|
|
223
|
-
env,
|
|
224
|
-
)
|
|
225
|
-
expect([400, 401, 404].includes(res.status)).toBe(true)
|
|
226
|
-
})
|
|
227
|
-
})
|
|
228
|
-
|
|
229
|
-
describe('Authentication and Authorization', () => {
|
|
230
|
-
it('should require authentication for dist-tag modification', async () => {
|
|
231
|
-
const res = await app.request(
|
|
232
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
233
|
-
{
|
|
234
|
-
method: 'PUT',
|
|
235
|
-
headers: {
|
|
236
|
-
'Content-Type': 'application/json',
|
|
237
|
-
},
|
|
238
|
-
body: JSON.stringify('1.0.0-beta.1'),
|
|
239
|
-
},
|
|
240
|
-
env,
|
|
241
|
-
)
|
|
242
|
-
expect([200, 400, 401, 404].includes(res.status)).toBe(true)
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
it('should check package ownership for dist-tag changes', async () => {
|
|
246
|
-
const res = await app.request(
|
|
247
|
-
'/-/package/someone-elses-package/dist-tags/beta',
|
|
248
|
-
{
|
|
249
|
-
method: 'PUT',
|
|
250
|
-
headers: {
|
|
251
|
-
Authorization: 'Bearer test-admin-token-12345',
|
|
252
|
-
'Content-Type': 'application/json',
|
|
253
|
-
},
|
|
254
|
-
body: JSON.stringify('1.0.0-beta.1'),
|
|
255
|
-
},
|
|
256
|
-
env,
|
|
257
|
-
)
|
|
258
|
-
expect([200, 401, 403, 404].includes(res.status)).toBe(true)
|
|
259
|
-
})
|
|
260
|
-
|
|
261
|
-
it('should handle valid authentication for dist-tag changes', async () => {
|
|
262
|
-
const res = await app.request(
|
|
263
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
264
|
-
{
|
|
265
|
-
method: 'PUT',
|
|
266
|
-
headers: {
|
|
267
|
-
Authorization: 'Bearer test-admin-token-12345',
|
|
268
|
-
'Content-Type': 'application/json',
|
|
269
|
-
},
|
|
270
|
-
body: JSON.stringify('1.0.0-beta.1'),
|
|
271
|
-
},
|
|
272
|
-
env,
|
|
273
|
-
)
|
|
274
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
275
|
-
})
|
|
276
|
-
})
|
|
277
|
-
})
|
|
278
|
-
|
|
279
|
-
describe('Delete Dist-Tags', () => {
|
|
280
|
-
describe('Remove Dist-Tags', () => {
|
|
281
|
-
it('should delete dist-tag for unscoped packages', async () => {
|
|
282
|
-
const res = await app.request(
|
|
283
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
284
|
-
{
|
|
285
|
-
method: 'DELETE',
|
|
286
|
-
},
|
|
287
|
-
env,
|
|
288
|
-
)
|
|
289
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
290
|
-
})
|
|
291
|
-
|
|
292
|
-
it('should delete dist-tag for scoped packages', async () => {
|
|
293
|
-
const res = await app.request(
|
|
294
|
-
'/-/package/@myorg%2Fmypackage/dist-tags/beta',
|
|
295
|
-
{
|
|
296
|
-
method: 'DELETE',
|
|
297
|
-
},
|
|
298
|
-
env,
|
|
299
|
-
)
|
|
300
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
301
|
-
})
|
|
302
|
-
|
|
303
|
-
it('should handle deletion of non-existent dist-tags', async () => {
|
|
304
|
-
const res = await app.request(
|
|
305
|
-
'/-/package/mypackage/dist-tags/nonexistent',
|
|
306
|
-
{
|
|
307
|
-
method: 'DELETE',
|
|
308
|
-
},
|
|
309
|
-
env,
|
|
310
|
-
)
|
|
311
|
-
expect([404, 401].includes(res.status)).toBe(true)
|
|
312
|
-
})
|
|
313
|
-
|
|
314
|
-
it('should prevent deletion of latest tag', async () => {
|
|
315
|
-
const res = await app.request(
|
|
316
|
-
'/-/package/mypackage/dist-tags/latest',
|
|
317
|
-
{
|
|
318
|
-
method: 'DELETE',
|
|
319
|
-
},
|
|
320
|
-
env,
|
|
321
|
-
)
|
|
322
|
-
expect([400, 401, 404].includes(res.status)).toBe(true)
|
|
323
|
-
})
|
|
324
|
-
})
|
|
325
|
-
|
|
326
|
-
describe('Delete Authorization', () => {
|
|
327
|
-
it('should require authentication for dist-tag deletion', async () => {
|
|
328
|
-
const res = await app.request(
|
|
329
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
330
|
-
{
|
|
331
|
-
method: 'DELETE',
|
|
332
|
-
},
|
|
333
|
-
env,
|
|
334
|
-
)
|
|
335
|
-
expect([200, 400, 401, 404].includes(res.status)).toBe(true)
|
|
336
|
-
})
|
|
337
|
-
|
|
338
|
-
it('should check package ownership for dist-tag deletion', async () => {
|
|
339
|
-
const res = await app.request(
|
|
340
|
-
'/-/package/someone-elses-package/dist-tags/beta',
|
|
341
|
-
{
|
|
342
|
-
method: 'DELETE',
|
|
343
|
-
headers: {
|
|
344
|
-
Authorization: 'Bearer test-admin-token-12345',
|
|
345
|
-
},
|
|
346
|
-
},
|
|
347
|
-
env,
|
|
348
|
-
)
|
|
349
|
-
expect([200, 401, 403, 404].includes(res.status)).toBe(true)
|
|
350
|
-
})
|
|
351
|
-
|
|
352
|
-
it('should handle valid authentication for dist-tag deletion', async () => {
|
|
353
|
-
const res = await app.request(
|
|
354
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
355
|
-
{
|
|
356
|
-
method: 'DELETE',
|
|
357
|
-
headers: {
|
|
358
|
-
Authorization: 'Bearer test-admin-token-12345',
|
|
359
|
-
},
|
|
360
|
-
},
|
|
361
|
-
env,
|
|
362
|
-
)
|
|
363
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
364
|
-
})
|
|
365
|
-
})
|
|
366
|
-
})
|
|
367
|
-
|
|
368
|
-
describe('Error Handling', () => {
|
|
369
|
-
describe('Invalid Package Names', () => {
|
|
370
|
-
it('should handle invalid package names', async () => {
|
|
371
|
-
const res = await app.request(
|
|
372
|
-
'/-/package/invalid..package/dist-tags',
|
|
373
|
-
{},
|
|
374
|
-
env,
|
|
375
|
-
)
|
|
376
|
-
expect([400, 404].includes(res.status)).toBe(true)
|
|
377
|
-
})
|
|
378
|
-
|
|
379
|
-
it('should handle packages starting with dots', async () => {
|
|
380
|
-
const res = await app.request(
|
|
381
|
-
'/-/package/.hidden-package/dist-tags',
|
|
382
|
-
{},
|
|
383
|
-
env,
|
|
384
|
-
)
|
|
385
|
-
expect([400, 404].includes(res.status)).toBe(true)
|
|
386
|
-
})
|
|
387
|
-
|
|
388
|
-
it('should handle packages starting with underscores', async () => {
|
|
389
|
-
const res = await app.request(
|
|
390
|
-
'/-/package/_internal-package/dist-tags',
|
|
391
|
-
{},
|
|
392
|
-
env,
|
|
393
|
-
)
|
|
394
|
-
expect([400, 404].includes(res.status)).toBe(true)
|
|
395
|
-
})
|
|
396
|
-
})
|
|
397
|
-
|
|
398
|
-
describe('Invalid Request Bodies', () => {
|
|
399
|
-
it('should handle malformed JSON in dist-tag requests', async () => {
|
|
400
|
-
const res = await app.request(
|
|
401
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
402
|
-
{
|
|
403
|
-
method: 'PUT',
|
|
404
|
-
headers: {
|
|
405
|
-
'Content-Type': 'application/json',
|
|
406
|
-
},
|
|
407
|
-
body: 'invalid-json',
|
|
408
|
-
},
|
|
409
|
-
env,
|
|
410
|
-
)
|
|
411
|
-
expect([400, 401, 404].includes(res.status)).toBe(true)
|
|
412
|
-
})
|
|
413
|
-
|
|
414
|
-
it('should handle missing content-type header', async () => {
|
|
415
|
-
const res = await app.request(
|
|
416
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
417
|
-
{
|
|
418
|
-
method: 'PUT',
|
|
419
|
-
body: JSON.stringify('1.0.0-beta.1'),
|
|
420
|
-
},
|
|
421
|
-
env,
|
|
422
|
-
)
|
|
423
|
-
expect([400, 415, 401, 404].includes(res.status)).toBe(true)
|
|
424
|
-
})
|
|
425
|
-
|
|
426
|
-
it('should handle empty request body', async () => {
|
|
427
|
-
const res = await app.request(
|
|
428
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
429
|
-
{
|
|
430
|
-
method: 'PUT',
|
|
431
|
-
headers: {
|
|
432
|
-
'Content-Type': 'application/json',
|
|
433
|
-
},
|
|
434
|
-
body: '',
|
|
435
|
-
},
|
|
436
|
-
env,
|
|
437
|
-
)
|
|
438
|
-
expect([400, 401, 404].includes(res.status)).toBe(true)
|
|
439
|
-
})
|
|
440
|
-
})
|
|
441
|
-
|
|
442
|
-
describe('Non-existent Resources', () => {
|
|
443
|
-
it('should handle non-existent packages', async () => {
|
|
444
|
-
const res = await app.request(
|
|
445
|
-
'/-/package/nonexistent-package-12345/dist-tags',
|
|
446
|
-
{},
|
|
447
|
-
env,
|
|
448
|
-
)
|
|
449
|
-
expect(res.status).toBe(404)
|
|
450
|
-
})
|
|
451
|
-
|
|
452
|
-
it('should handle non-existent packages in dist-tag creation', async () => {
|
|
453
|
-
const res = await app.request(
|
|
454
|
-
'/-/package/nonexistent-package-12345/dist-tags/beta',
|
|
455
|
-
{
|
|
456
|
-
method: 'PUT',
|
|
457
|
-
headers: {
|
|
458
|
-
'Content-Type': 'application/json',
|
|
459
|
-
},
|
|
460
|
-
body: JSON.stringify('1.0.0-beta.1'),
|
|
461
|
-
},
|
|
462
|
-
env,
|
|
463
|
-
)
|
|
464
|
-
expect([401, 404].includes(res.status)).toBe(true)
|
|
465
|
-
})
|
|
466
|
-
})
|
|
467
|
-
})
|
|
468
|
-
|
|
469
|
-
describe('Dist-Tag Lifecycle', () => {
|
|
470
|
-
describe('Complete Dist-Tag Operations', () => {
|
|
471
|
-
it('should handle complete dist-tag lifecycle', async () => {
|
|
472
|
-
// Get initial dist-tags
|
|
473
|
-
const getRes1 = await app.request(
|
|
474
|
-
'/-/package/mypackage/dist-tags',
|
|
475
|
-
{},
|
|
476
|
-
env,
|
|
477
|
-
)
|
|
478
|
-
expect([200, 404].includes(getRes1.status)).toBe(true)
|
|
479
|
-
|
|
480
|
-
// Set a new dist-tag
|
|
481
|
-
const putRes = await app.request(
|
|
482
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
483
|
-
{
|
|
484
|
-
method: 'PUT',
|
|
485
|
-
headers: {
|
|
486
|
-
'Content-Type': 'application/json',
|
|
487
|
-
},
|
|
488
|
-
body: JSON.stringify('1.0.0-beta.1'),
|
|
489
|
-
},
|
|
490
|
-
env,
|
|
491
|
-
)
|
|
492
|
-
expect([200, 401, 404].includes(putRes.status)).toBe(true)
|
|
493
|
-
|
|
494
|
-
// Get updated dist-tags
|
|
495
|
-
const getRes2 = await app.request(
|
|
496
|
-
'/-/package/mypackage/dist-tags',
|
|
497
|
-
{},
|
|
498
|
-
env,
|
|
499
|
-
)
|
|
500
|
-
expect([200, 404].includes(getRes2.status)).toBe(true)
|
|
501
|
-
|
|
502
|
-
// Delete the dist-tag
|
|
503
|
-
const deleteRes = await app.request(
|
|
504
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
505
|
-
{
|
|
506
|
-
method: 'DELETE',
|
|
507
|
-
},
|
|
508
|
-
env,
|
|
509
|
-
)
|
|
510
|
-
expect([200, 401, 404].includes(deleteRes.status)).toBe(true)
|
|
511
|
-
})
|
|
512
|
-
})
|
|
513
|
-
|
|
514
|
-
describe('Multiple Dist-Tags', () => {
|
|
515
|
-
it('should handle multiple dist-tags for a package', async () => {
|
|
516
|
-
const tags = ['beta', 'alpha', 'rc', 'next']
|
|
517
|
-
|
|
518
|
-
for (const tag of tags) {
|
|
519
|
-
const res = await app.request(
|
|
520
|
-
`/-/package/mypackage/dist-tags/${tag}`,
|
|
521
|
-
{
|
|
522
|
-
method: 'PUT',
|
|
523
|
-
headers: {
|
|
524
|
-
'Content-Type': 'application/json',
|
|
525
|
-
},
|
|
526
|
-
body: JSON.stringify(`1.0.0-${tag}.1`),
|
|
527
|
-
},
|
|
528
|
-
env,
|
|
529
|
-
)
|
|
530
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
531
|
-
}
|
|
532
|
-
})
|
|
533
|
-
|
|
534
|
-
it('should handle concurrent dist-tag operations', async () => {
|
|
535
|
-
const promises = [
|
|
536
|
-
app.request(
|
|
537
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
538
|
-
{
|
|
539
|
-
method: 'PUT',
|
|
540
|
-
headers: {
|
|
541
|
-
'Content-Type': 'application/json',
|
|
542
|
-
},
|
|
543
|
-
body: JSON.stringify('1.0.0-beta.1'),
|
|
544
|
-
},
|
|
545
|
-
env,
|
|
546
|
-
),
|
|
547
|
-
app.request(
|
|
548
|
-
'/-/package/mypackage/dist-tags/alpha',
|
|
549
|
-
{
|
|
550
|
-
method: 'PUT',
|
|
551
|
-
headers: {
|
|
552
|
-
'Content-Type': 'application/json',
|
|
553
|
-
},
|
|
554
|
-
body: JSON.stringify('1.0.0-alpha.1'),
|
|
555
|
-
},
|
|
556
|
-
env,
|
|
557
|
-
),
|
|
558
|
-
]
|
|
559
|
-
|
|
560
|
-
const results = await Promise.all(promises)
|
|
561
|
-
results.forEach(res => {
|
|
562
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
563
|
-
})
|
|
564
|
-
})
|
|
565
|
-
})
|
|
566
|
-
})
|
|
567
|
-
|
|
568
|
-
describe('Response Headers and Caching', () => {
|
|
569
|
-
describe('Content-Type Headers', () => {
|
|
570
|
-
it('should set appropriate content-type headers', async () => {
|
|
571
|
-
const res = await app.request(
|
|
572
|
-
'/-/package/lodash/dist-tags',
|
|
573
|
-
{},
|
|
574
|
-
env,
|
|
575
|
-
)
|
|
576
|
-
if (res.status === 200) {
|
|
577
|
-
expect(res.headers.get('content-type')).toContain(
|
|
578
|
-
'application/json',
|
|
579
|
-
)
|
|
580
|
-
}
|
|
581
|
-
})
|
|
582
|
-
})
|
|
583
|
-
|
|
584
|
-
describe('Cache Control', () => {
|
|
585
|
-
it('should set appropriate cache-control headers for dist-tags', async () => {
|
|
586
|
-
const res = await app.request(
|
|
587
|
-
'/-/package/lodash/dist-tags',
|
|
588
|
-
{},
|
|
589
|
-
env,
|
|
590
|
-
)
|
|
591
|
-
if (res.status === 200) {
|
|
592
|
-
// Cache headers would be validated based on implementation
|
|
593
|
-
expect(res.status).toBe(200)
|
|
594
|
-
}
|
|
595
|
-
})
|
|
596
|
-
})
|
|
597
|
-
|
|
598
|
-
describe('ETag Headers', () => {
|
|
599
|
-
it('should include ETag headers for dist-tags', async () => {
|
|
600
|
-
const res = await app.request(
|
|
601
|
-
'/-/package/lodash/dist-tags',
|
|
602
|
-
{},
|
|
603
|
-
env,
|
|
604
|
-
)
|
|
605
|
-
if (res.status === 200) {
|
|
606
|
-
// ETag headers would be validated based on implementation
|
|
607
|
-
expect(res.status).toBe(200)
|
|
608
|
-
}
|
|
609
|
-
})
|
|
610
|
-
})
|
|
611
|
-
})
|
|
612
|
-
|
|
613
|
-
describe('Special Dist-Tag Cases', () => {
|
|
614
|
-
describe('Semantic Versioning', () => {
|
|
615
|
-
it('should handle prerelease versions', async () => {
|
|
616
|
-
const res = await app.request(
|
|
617
|
-
'/-/package/mypackage/dist-tags/beta',
|
|
618
|
-
{
|
|
619
|
-
method: 'PUT',
|
|
620
|
-
headers: {
|
|
621
|
-
'Content-Type': 'application/json',
|
|
622
|
-
},
|
|
623
|
-
body: JSON.stringify('1.0.0-beta.1+build.123'),
|
|
624
|
-
},
|
|
625
|
-
env,
|
|
626
|
-
)
|
|
627
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
628
|
-
})
|
|
629
|
-
|
|
630
|
-
it('should handle build metadata in versions', async () => {
|
|
631
|
-
const res = await app.request(
|
|
632
|
-
'/-/package/mypackage/dist-tags/build',
|
|
633
|
-
{
|
|
634
|
-
method: 'PUT',
|
|
635
|
-
headers: {
|
|
636
|
-
'Content-Type': 'application/json',
|
|
637
|
-
},
|
|
638
|
-
body: JSON.stringify('1.0.0+20230101.1'),
|
|
639
|
-
},
|
|
640
|
-
env,
|
|
641
|
-
)
|
|
642
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
643
|
-
})
|
|
644
|
-
})
|
|
645
|
-
|
|
646
|
-
describe('Tag Name Validation', () => {
|
|
647
|
-
it('should handle alphanumeric dist-tag names', async () => {
|
|
648
|
-
const res = await app.request(
|
|
649
|
-
'/-/package/mypackage/dist-tags/v2beta1',
|
|
650
|
-
{
|
|
651
|
-
method: 'PUT',
|
|
652
|
-
headers: {
|
|
653
|
-
'Content-Type': 'application/json',
|
|
654
|
-
},
|
|
655
|
-
body: JSON.stringify('2.0.0-beta.1'),
|
|
656
|
-
},
|
|
657
|
-
env,
|
|
658
|
-
)
|
|
659
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
660
|
-
})
|
|
661
|
-
|
|
662
|
-
it('should handle hyphenated dist-tag names', async () => {
|
|
663
|
-
const res = await app.request(
|
|
664
|
-
'/-/package/mypackage/dist-tags/long-term-support',
|
|
665
|
-
{
|
|
666
|
-
method: 'PUT',
|
|
667
|
-
headers: {
|
|
668
|
-
'Content-Type': 'application/json',
|
|
669
|
-
},
|
|
670
|
-
body: JSON.stringify('1.0.0'),
|
|
671
|
-
},
|
|
672
|
-
env,
|
|
673
|
-
)
|
|
674
|
-
expect([200, 401, 404].includes(res.status)).toBe(true)
|
|
675
|
-
})
|
|
676
|
-
})
|
|
677
|
-
})
|
|
678
|
-
})
|