@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.
Files changed (107) hide show
  1. package/LICENSE +10 -114
  2. package/dist/README.md +1 -0
  3. package/dist/assets/public/favicon.ico +0 -0
  4. package/dist/assets/public/fonts/courier-bold-italic.ttf +0 -0
  5. package/dist/assets/public/fonts/courier-bold.ttf +0 -0
  6. package/dist/assets/public/fonts/courier-italic.ttf +0 -0
  7. package/dist/assets/public/fonts/courier-regular.ttf +0 -0
  8. package/dist/assets/public/fonts/geist-mono.ttf +0 -0
  9. package/dist/assets/public/fonts/inter.ttf +0 -0
  10. package/dist/assets/public/index.html +70 -0
  11. package/dist/assets/public/index.js +1300 -0
  12. package/dist/assets/public/index.js.map +7 -0
  13. package/dist/assets/public/main.css +1 -0
  14. package/dist/bin/vsr.js +771 -0
  15. package/dist/index.js +28283 -0
  16. package/dist/index.js.map +8 -0
  17. package/package.json +6 -49
  18. package/DEPLOY.md +0 -163
  19. package/config.ts +0 -221
  20. package/drizzle.config.js +0 -40
  21. package/info/COMPARISONS.md +0 -37
  22. package/info/CONFIGURATION.md +0 -143
  23. package/info/CONTRIBUTING.md +0 -32
  24. package/info/DATABASE_SETUP.md +0 -108
  25. package/info/GRANULAR_ACCESS_TOKENS.md +0 -160
  26. package/info/PROJECT_STRUCTURE.md +0 -291
  27. package/info/ROADMAP.md +0 -27
  28. package/info/SUPPORT.md +0 -39
  29. package/info/TESTING.md +0 -301
  30. package/info/USER_SUPPORT.md +0 -31
  31. package/scripts/build-assets.js +0 -31
  32. package/scripts/build-bin.js +0 -62
  33. package/scripts/prepack.js +0 -27
  34. package/src/bin/vsr.ts +0 -484
  35. package/src/db/client.ts +0 -590
  36. package/src/db/migrations/0000_faulty_ricochet.sql +0 -14
  37. package/src/db/migrations/0000_initial.sql +0 -29
  38. package/src/db/migrations/0001_uuid_validation.sql +0 -35
  39. package/src/db/migrations/0001_wealthy_magdalene.sql +0 -7
  40. package/src/db/migrations/drop.sql +0 -3
  41. package/src/db/migrations/meta/0000_snapshot.json +0 -104
  42. package/src/db/migrations/meta/0001_snapshot.json +0 -155
  43. package/src/db/migrations/meta/_journal.json +0 -20
  44. package/src/db/schema.ts +0 -43
  45. package/src/index.ts +0 -434
  46. package/src/middleware/config.ts +0 -79
  47. package/src/middleware/telemetry.ts +0 -43
  48. package/src/queue/index.ts +0 -97
  49. package/src/routes/access.ts +0 -852
  50. package/src/routes/docs.ts +0 -63
  51. package/src/routes/misc.ts +0 -469
  52. package/src/routes/packages.ts +0 -2823
  53. package/src/routes/ping.ts +0 -39
  54. package/src/routes/search.ts +0 -131
  55. package/src/routes/static.ts +0 -74
  56. package/src/routes/tokens.ts +0 -259
  57. package/src/routes/users.ts +0 -68
  58. package/src/utils/auth.ts +0 -202
  59. package/src/utils/cache.ts +0 -587
  60. package/src/utils/config.ts +0 -50
  61. package/src/utils/database.ts +0 -69
  62. package/src/utils/docs.ts +0 -146
  63. package/src/utils/packages.ts +0 -453
  64. package/src/utils/response.ts +0 -125
  65. package/src/utils/routes.ts +0 -64
  66. package/src/utils/spa.ts +0 -52
  67. package/src/utils/tracing.ts +0 -52
  68. package/src/utils/upstream.ts +0 -172
  69. package/test/access.test.ts +0 -705
  70. package/test/audit.test.ts +0 -828
  71. package/test/dashboard.test.ts +0 -693
  72. package/test/dist-tags.test.ts +0 -678
  73. package/test/manifest.test.ts +0 -436
  74. package/test/packument.test.ts +0 -530
  75. package/test/ping.test.ts +0 -41
  76. package/test/search.test.ts +0 -472
  77. package/test/setup.ts +0 -130
  78. package/test/static.test.ts +0 -646
  79. package/test/tokens.test.ts +0 -389
  80. package/test/utils/auth.test.ts +0 -214
  81. package/test/utils/packages.test.ts +0 -235
  82. package/test/utils/response.test.ts +0 -184
  83. package/test/whoami.test.ts +0 -119
  84. package/tsconfig.json +0 -16
  85. package/tsconfig.worker.json +0 -3
  86. package/typedoc.mjs +0 -2
  87. package/types.ts +0 -598
  88. package/vitest.config.ts +0 -25
  89. package/vlt.json.example +0 -56
  90. package/wrangler.json +0 -65
  91. /package/{src → dist}/assets/public/images/bg.png +0 -0
  92. /package/{src → dist}/assets/public/images/clients/logo-bun.png +0 -0
  93. /package/{src → dist}/assets/public/images/clients/logo-deno.png +0 -0
  94. /package/{src → dist}/assets/public/images/clients/logo-npm.png +0 -0
  95. /package/{src → dist}/assets/public/images/clients/logo-pnpm.png +0 -0
  96. /package/{src → dist}/assets/public/images/clients/logo-vlt.png +0 -0
  97. /package/{src → dist}/assets/public/images/clients/logo-yarn.png +0 -0
  98. /package/{src → dist}/assets/public/images/favicon/apple-touch-icon.png +0 -0
  99. /package/{src → dist}/assets/public/images/favicon/favicon-96x96.png +0 -0
  100. /package/{src → dist}/assets/public/images/favicon/favicon.ico +0 -0
  101. /package/{src → dist}/assets/public/images/favicon/favicon.svg +0 -0
  102. /package/{src → dist}/assets/public/images/favicon/site.webmanifest +0 -0
  103. /package/{src → dist}/assets/public/images/favicon/web-app-manifest-192x192.png +0 -0
  104. /package/{src → dist}/assets/public/images/favicon/web-app-manifest-512x512.png +0 -0
  105. /package/{src → dist}/assets/public/styles/styles.css +0 -0
  106. /package/{src → dist}/bin/demo/package.json +0 -0
  107. /package/{src → dist}/bin/demo/vlt.json +0 -0
@@ -1,646 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { app } from '../src/index.ts'
3
-
4
- // Mock environment for testing
5
- const mockEnv = {
6
- DB: {
7
- // Minimal D1 interface to prevent database errors
8
- prepare: () => ({
9
- bind: () => ({
10
- get: () => Promise.resolve(null),
11
- all: () => Promise.resolve({ results: [] }),
12
- run: () => Promise.resolve({ success: true }),
13
- raw: () => Promise.resolve([]),
14
- }),
15
- get: () => Promise.resolve(null),
16
- all: () => Promise.resolve({ results: [] }),
17
- run: () => Promise.resolve({ success: true }),
18
- raw: () => Promise.resolve([]),
19
- }),
20
- batch: () => Promise.resolve([]),
21
- exec: () => Promise.resolve(),
22
- },
23
- BUCKET: {
24
- get: () => Promise.resolve(null),
25
- put: () => Promise.resolve(),
26
- delete: () => Promise.resolve(),
27
- },
28
- KV: {
29
- get: () => Promise.resolve(null),
30
- put: () => Promise.resolve(),
31
- delete: () => Promise.resolve(),
32
- },
33
- ASSETS: {
34
- // Mock assets binding
35
- fetch: () =>
36
- Promise.resolve(new Response('mock asset', { status: 200 })),
37
- },
38
- DAEMON_ENABLED: false,
39
- API_DOCS_ENABLED: false,
40
- }
41
-
42
- describe('Static Asset Endpoints', () => {
43
- describe('Public Assets', () => {
44
- describe('GET /public/*', () => {
45
- it('should serve static assets from public directory', async () => {
46
- const res = await app.request(
47
- '/public/styles/styles.css',
48
- {},
49
- mockEnv,
50
- )
51
- expect([200, 404].includes(res.status)).toBe(true)
52
- })
53
-
54
- it('should serve JavaScript assets', async () => {
55
- const res = await app.request(
56
- '/public/js/app.js',
57
- {},
58
- mockEnv,
59
- )
60
- expect([200, 404].includes(res.status)).toBe(true)
61
- })
62
-
63
- it('should serve image assets', async () => {
64
- const res = await app.request(
65
- '/public/images/logo.png',
66
- {},
67
- mockEnv,
68
- )
69
- expect([200, 404].includes(res.status)).toBe(true)
70
- })
71
-
72
- it('should serve font assets', async () => {
73
- const res = await app.request(
74
- '/public/fonts/inter.woff2',
75
- {},
76
- mockEnv,
77
- )
78
- expect([200, 404].includes(res.status)).toBe(true)
79
- })
80
-
81
- it('should handle nested public assets', async () => {
82
- const res = await app.request(
83
- '/public/assets/images/favicon/favicon.ico',
84
- {},
85
- mockEnv,
86
- )
87
- expect([200, 404].includes(res.status)).toBe(true)
88
- })
89
- })
90
-
91
- describe('Content-Type Headers', () => {
92
- it('should set correct content-type for CSS files', async () => {
93
- const res = await app.request(
94
- '/public/styles/styles.css',
95
- {},
96
- mockEnv,
97
- )
98
- if (res.status === 200) {
99
- expect(
100
- res.headers.get('content-type')?.includes('text/css'),
101
- ).toBeTruthy()
102
- }
103
- })
104
-
105
- it('should set correct content-type for JavaScript files', async () => {
106
- const res = await app.request(
107
- '/public/js/app.js',
108
- {},
109
- mockEnv,
110
- )
111
- if (res.status === 200) {
112
- expect(
113
- res.headers
114
- .get('content-type')
115
- ?.includes('application/javascript'),
116
- ).toBeTruthy()
117
- }
118
- })
119
-
120
- it('should set correct content-type for PNG images', async () => {
121
- const res = await app.request(
122
- '/public/images/logo.png',
123
- {},
124
- mockEnv,
125
- )
126
- if (res.status === 200) {
127
- expect(
128
- res.headers.get('content-type')?.includes('image/png'),
129
- ).toBeTruthy()
130
- }
131
- })
132
-
133
- it('should set correct content-type for SVG images', async () => {
134
- const res = await app.request(
135
- '/public/images/icon.svg',
136
- {},
137
- mockEnv,
138
- )
139
- if (res.status === 200) {
140
- expect(
141
- res.headers
142
- .get('content-type')
143
- ?.includes('image/svg+xml'),
144
- ).toBeTruthy()
145
- }
146
- })
147
- })
148
-
149
- describe('Cache Headers', () => {
150
- it('should set appropriate cache headers for static assets', async () => {
151
- const res = await app.request(
152
- '/public/styles/styles.css',
153
- {},
154
- mockEnv,
155
- )
156
- if (res.status === 200) {
157
- // Cache headers would be validated based on implementation
158
- expect(res.status).toBe(200)
159
- }
160
- })
161
-
162
- it('should set ETag headers for static assets', async () => {
163
- const res = await app.request(
164
- '/public/js/app.js',
165
- {},
166
- mockEnv,
167
- )
168
- if (res.status === 200) {
169
- // ETag headers would be validated based on implementation
170
- expect(res.status).toBe(200)
171
- }
172
- })
173
- })
174
- })
175
-
176
- describe('Special Static Files', () => {
177
- describe('GET /favicon.ico', () => {
178
- it('should serve favicon.ico', async () => {
179
- const res = await app.request('/favicon.ico', {}, mockEnv)
180
- expect([200, 404].includes(res.status)).toBe(true)
181
- })
182
-
183
- it('should set correct content-type for favicon', async () => {
184
- const res = await app.request('/favicon.ico', {}, mockEnv)
185
- if (res.status === 200) {
186
- expect(
187
- res.headers.get('content-type')?.includes('image/'),
188
- ).toBeTruthy()
189
- }
190
- })
191
-
192
- it('should handle HEAD requests for favicon', async () => {
193
- const res = await app.request(
194
- '/favicon.ico',
195
- { method: 'HEAD' },
196
- mockEnv,
197
- )
198
- expect([200, 404, 405].includes(res.status)).toBe(true)
199
- })
200
- })
201
-
202
- describe('GET /robots.txt', () => {
203
- it('should serve robots.txt', async () => {
204
- const res = await app.request('/robots.txt', {}, mockEnv)
205
- expect([200, 404].includes(res.status)).toBe(true)
206
- })
207
-
208
- it('should set correct content-type for robots.txt', async () => {
209
- const res = await app.request('/robots.txt', {}, mockEnv)
210
- if (res.status === 200) {
211
- expect(
212
- res.headers.get('content-type')?.includes('text/plain'),
213
- ).toBeTruthy()
214
- }
215
- })
216
-
217
- it('should contain valid robots.txt content', async () => {
218
- const res = await app.request('/robots.txt', {}, mockEnv)
219
- if (res.status === 200) {
220
- const content = await res.text()
221
- expect(content).toBeDefined()
222
- // Would validate robots.txt format based on implementation
223
- }
224
- })
225
- })
226
-
227
- describe('GET /manifest.json', () => {
228
- it('should serve PWA manifest.json', async () => {
229
- const res = await app.request('/manifest.json', {}, mockEnv)
230
- expect([200, 404].includes(res.status)).toBe(true)
231
- })
232
-
233
- it('should set correct content-type for manifest.json', async () => {
234
- const res = await app.request('/manifest.json', {}, mockEnv)
235
- if (res.status === 200) {
236
- expect(res.headers.get('content-type')).toContain(
237
- 'application/json',
238
- )
239
- }
240
- })
241
-
242
- it('should contain valid PWA manifest structure', async () => {
243
- const res = await app.request('/manifest.json', {}, mockEnv)
244
- if (res.status === 200) {
245
- const manifest = (await res.json()) as any
246
- expect(manifest).toBeDefined()
247
- // Would validate PWA manifest structure based on implementation
248
- }
249
- })
250
- })
251
- })
252
-
253
- describe('Catch-All Static Handler', () => {
254
- describe('GET /*', () => {
255
- it('should handle catch-all static asset requests', async () => {
256
- const res = await app.request(
257
- '/some-static-file.txt',
258
- {},
259
- mockEnv,
260
- )
261
- expect([200, 404].includes(res.status)).toBe(true)
262
- })
263
-
264
- it('should handle nested static asset paths', async () => {
265
- const res = await app.request(
266
- '/assets/css/main.css',
267
- {},
268
- mockEnv,
269
- )
270
- expect([200, 404].includes(res.status)).toBe(true)
271
- })
272
-
273
- it('should handle static assets with query parameters', async () => {
274
- const res = await app.request(
275
- '/assets/js/app.js?v=1.0.0',
276
- {},
277
- mockEnv,
278
- )
279
- expect([200, 404].includes(res.status)).toBe(true)
280
- })
281
-
282
- it('should handle static assets with hash fragments', async () => {
283
- const res = await app.request(
284
- '/assets/app.js#main',
285
- {},
286
- mockEnv,
287
- )
288
- expect([200, 404].includes(res.status)).toBe(true)
289
- })
290
- })
291
-
292
- describe('Security Considerations', () => {
293
- it('should prevent directory traversal attacks', async () => {
294
- const res = await app.request(
295
- '/../../etc/passwd',
296
- {},
297
- mockEnv,
298
- )
299
- expect([400, 404].includes(res.status)).toBe(true)
300
- })
301
-
302
- it('should handle encoded path traversal attempts', async () => {
303
- const res = await app.request(
304
- '/%2e%2e%2f%2e%2e%2fetc%2fpasswd',
305
- {},
306
- mockEnv,
307
- )
308
- expect([400, 404].includes(res.status)).toBe(true)
309
- })
310
-
311
- it('should handle null byte injection attempts', async () => {
312
- const res = await app.request('/file.txt%00.exe', {}, mockEnv)
313
- expect([400, 404].includes(res.status)).toBe(true)
314
- })
315
- })
316
- })
317
-
318
- describe('Error Handling', () => {
319
- describe('Non-existent Assets', () => {
320
- it('should return 404 for non-existent static assets', async () => {
321
- const res = await app.request(
322
- '/public/nonexistent-file.txt',
323
- {},
324
- mockEnv,
325
- )
326
- expect(res.status).toBe(404)
327
- })
328
-
329
- it('should return 404 for non-existent nested assets', async () => {
330
- const res = await app.request(
331
- '/public/deep/nested/nonexistent.js',
332
- {},
333
- mockEnv,
334
- )
335
- expect(res.status).toBe(404)
336
- })
337
-
338
- it('should handle malformed asset paths', async () => {
339
- const res = await app.request(
340
- '/public//double//slash.css',
341
- {},
342
- mockEnv,
343
- )
344
- expect([200, 404].includes(res.status)).toBe(true)
345
- })
346
- })
347
-
348
- describe('HTTP Method Validation', () => {
349
- it('should handle POST requests to static assets', async () => {
350
- const res = await app.request(
351
- '/public/styles/styles.css',
352
- { method: 'POST' },
353
- mockEnv,
354
- )
355
- expect([200, 404, 405].includes(res.status)).toBe(true)
356
- })
357
-
358
- it('should handle PUT requests to static assets', async () => {
359
- const res = await app.request(
360
- '/public/js/app.js',
361
- { method: 'PUT' },
362
- mockEnv,
363
- )
364
- expect([200, 404, 405].includes(res.status)).toBe(true)
365
- })
366
-
367
- it('should handle DELETE requests to static assets', async () => {
368
- const res = await app.request(
369
- '/public/images/logo.png',
370
- { method: 'DELETE' },
371
- mockEnv,
372
- )
373
- expect([200, 404, 405].includes(res.status)).toBe(true)
374
- })
375
- })
376
- })
377
-
378
- describe('Performance and Optimization', () => {
379
- describe('Compression', () => {
380
- it('should handle gzip compression for text assets', async () => {
381
- const res = await app.request(
382
- '/public/styles/styles.css',
383
- {
384
- headers: {
385
- 'Accept-Encoding': 'gzip, deflate, br',
386
- },
387
- },
388
- mockEnv,
389
- )
390
- if (res.status === 200) {
391
- // Compression headers would be validated based on implementation
392
- expect(res.status).toBe(200)
393
- }
394
- })
395
-
396
- it('should handle brotli compression for JavaScript assets', async () => {
397
- const res = await app.request(
398
- '/public/js/app.js',
399
- {
400
- headers: {
401
- 'Accept-Encoding': 'br, gzip, deflate',
402
- },
403
- },
404
- mockEnv,
405
- )
406
- if (res.status === 200) {
407
- // Compression headers would be validated based on implementation
408
- expect(res.status).toBe(200)
409
- }
410
- })
411
- })
412
-
413
- describe('Range Requests', () => {
414
- it('should handle range requests for large assets', async () => {
415
- const res = await app.request(
416
- '/public/videos/demo.mp4',
417
- {
418
- headers: {
419
- Range: 'bytes=0-1023',
420
- },
421
- },
422
- mockEnv,
423
- )
424
- expect([200, 206, 404, 416].includes(res.status)).toBe(true)
425
- })
426
-
427
- it('should handle invalid range requests', async () => {
428
- const res = await app.request(
429
- '/public/images/large-image.jpg',
430
- {
431
- headers: {
432
- Range: 'bytes=invalid-range',
433
- },
434
- },
435
- mockEnv,
436
- )
437
- expect([200, 400, 404, 416].includes(res.status)).toBe(true)
438
- })
439
- })
440
-
441
- describe('Conditional Requests', () => {
442
- it('should handle If-None-Match headers', async () => {
443
- const res = await app.request(
444
- '/public/styles/styles.css',
445
- {
446
- headers: {
447
- 'If-None-Match': '"some-etag-value"',
448
- },
449
- },
450
- mockEnv,
451
- )
452
- expect([200, 304, 404].includes(res.status)).toBe(true)
453
- })
454
-
455
- it('should handle If-Modified-Since headers', async () => {
456
- const res = await app.request(
457
- '/public/js/app.js',
458
- {
459
- headers: {
460
- 'If-Modified-Since': 'Wed, 21 Oct 2015 07:28:00 GMT',
461
- },
462
- },
463
- mockEnv,
464
- )
465
- expect([200, 304, 404].includes(res.status)).toBe(true)
466
- })
467
- })
468
- })
469
-
470
- describe('CORS and Security Headers', () => {
471
- describe('CORS Headers', () => {
472
- it('should handle CORS headers for static assets', async () => {
473
- const res = await app.request(
474
- '/public/styles/styles.css',
475
- {
476
- headers: {
477
- Origin: 'https://example.com',
478
- },
479
- },
480
- mockEnv,
481
- )
482
- if (res.status === 200) {
483
- // CORS headers would be validated based on implementation
484
- expect(res.status).toBe(200)
485
- }
486
- })
487
-
488
- it('should handle preflight requests for static assets', async () => {
489
- const res = await app.request(
490
- '/public/js/app.js',
491
- {
492
- method: 'OPTIONS',
493
- headers: {
494
- Origin: 'https://example.com',
495
- 'Access-Control-Request-Method': 'GET',
496
- },
497
- },
498
- mockEnv,
499
- )
500
- expect([200, 204, 404, 405].includes(res.status)).toBe(true)
501
- })
502
- })
503
-
504
- describe('Security Headers', () => {
505
- it('should include security headers for static assets', async () => {
506
- const res = await app.request(
507
- '/public/js/app.js',
508
- {},
509
- mockEnv,
510
- )
511
- if (res.status === 200) {
512
- // Security headers would be validated based on implementation
513
- expect(res.status).toBe(200)
514
- }
515
- })
516
-
517
- it('should set X-Content-Type-Options header', async () => {
518
- const res = await app.request(
519
- '/public/styles/styles.css',
520
- {},
521
- mockEnv,
522
- )
523
- if (res.status === 200) {
524
- // X-Content-Type-Options header would be validated
525
- expect(res.status).toBe(200)
526
- }
527
- })
528
- })
529
- })
530
-
531
- describe('Asset Types and Extensions', () => {
532
- describe('Web Assets', () => {
533
- it('should serve HTML files', async () => {
534
- const res = await app.request(
535
- '/public/index.html',
536
- {},
537
- mockEnv,
538
- )
539
- expect([200, 404].includes(res.status)).toBe(true)
540
- })
541
-
542
- it('should serve XML files', async () => {
543
- const res = await app.request(
544
- '/public/sitemap.xml',
545
- {},
546
- mockEnv,
547
- )
548
- expect([200, 404].includes(res.status)).toBe(true)
549
- })
550
-
551
- it('should serve JSON files', async () => {
552
- const res = await app.request(
553
- '/public/data.json',
554
- {},
555
- mockEnv,
556
- )
557
- expect([200, 404].includes(res.status)).toBe(true)
558
- })
559
- })
560
-
561
- describe('Media Assets', () => {
562
- it('should serve JPEG images', async () => {
563
- const res = await app.request(
564
- '/public/images/photo.jpg',
565
- {},
566
- mockEnv,
567
- )
568
- expect([200, 404].includes(res.status)).toBe(true)
569
- })
570
-
571
- it('should serve WebP images', async () => {
572
- const res = await app.request(
573
- '/public/images/modern.webp',
574
- {},
575
- mockEnv,
576
- )
577
- expect([200, 404].includes(res.status)).toBe(true)
578
- })
579
-
580
- it('should serve AVIF images', async () => {
581
- const res = await app.request(
582
- '/public/images/next-gen.avif',
583
- {},
584
- mockEnv,
585
- )
586
- expect([200, 404].includes(res.status)).toBe(true)
587
- })
588
-
589
- it('should serve video files', async () => {
590
- const res = await app.request(
591
- '/public/videos/demo.mp4',
592
- {},
593
- mockEnv,
594
- )
595
- expect([200, 404].includes(res.status)).toBe(true)
596
- })
597
-
598
- it('should serve audio files', async () => {
599
- const res = await app.request(
600
- '/public/audio/sound.mp3',
601
- {},
602
- mockEnv,
603
- )
604
- expect([200, 404].includes(res.status)).toBe(true)
605
- })
606
- })
607
-
608
- describe('Font Assets', () => {
609
- it('should serve WOFF fonts', async () => {
610
- const res = await app.request(
611
- '/public/fonts/font.woff',
612
- {},
613
- mockEnv,
614
- )
615
- expect([200, 404].includes(res.status)).toBe(true)
616
- })
617
-
618
- it('should serve WOFF2 fonts', async () => {
619
- const res = await app.request(
620
- '/public/fonts/font.woff2',
621
- {},
622
- mockEnv,
623
- )
624
- expect([200, 404].includes(res.status)).toBe(true)
625
- })
626
-
627
- it('should serve TTF fonts', async () => {
628
- const res = await app.request(
629
- '/public/fonts/font.ttf',
630
- {},
631
- mockEnv,
632
- )
633
- expect([200, 404].includes(res.status)).toBe(true)
634
- })
635
-
636
- it('should serve OTF fonts', async () => {
637
- const res = await app.request(
638
- '/public/fonts/font.otf',
639
- {},
640
- mockEnv,
641
- )
642
- expect([200, 404].includes(res.status)).toBe(true)
643
- })
644
- })
645
- })
646
- })