@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
package/src/index.ts DELETED
@@ -1,434 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-assignment */
2
- import { OPEN_API_CONFIG } from '../config.ts'
3
- import { OpenAPIHono } from '@hono/zod-openapi'
4
- import { requestId } from 'hono/request-id'
5
- import { bearerAuth } from 'hono/bearer-auth'
6
- import { except } from 'hono/combine'
7
- import { logger } from 'hono/logger'
8
- import { secureHeaders } from 'hono/secure-headers'
9
- import { trimTrailingSlash } from 'hono/trailing-slash'
10
- import { telemetryMiddleware } from './middleware/telemetry.ts'
11
- import { configMiddleware } from './middleware/config.ts'
12
- import { getApp } from './utils/spa.ts'
13
- import { verifyToken } from './utils/auth.ts'
14
- import { mountDatabase } from './utils/database.ts'
15
- import { jsonResponseHandler } from './utils/response.ts'
16
- import { requiresToken } from './utils/routes.ts'
17
- import {
18
- getUsername,
19
- getUserProfile,
20
- userProfileRoute,
21
- whoamiRoute,
22
- } from './routes/users.ts'
23
- import { pingRoute, handlePing } from './routes/ping.ts'
24
- import { getDocs } from './routes/docs.ts'
25
- import {
26
- getToken,
27
- putToken,
28
- postToken,
29
- deleteToken,
30
- getTokensRoute,
31
- createTokenRoute,
32
- updateTokenRoute,
33
- deleteTokenRoute,
34
- } from './routes/tokens.ts'
35
- import {
36
- getPackageDistTags,
37
- putPackageDistTag,
38
- deletePackageDistTag,
39
- handleRootPackageRoute,
40
- handlePackagePublish,
41
- handlePackageVersion,
42
- handlePackageTarball,
43
- handleUpstreamPackage,
44
- handleUpstreamScopedTarball,
45
- handleUpstreamScopedVersion,
46
- handleUpstreamEncodedScoped,
47
- handleUpstreamUnified,
48
- handleUpstreamTarball,
49
- // Local package route definitions
50
- getPackageRoute,
51
- getPackageVersionRoute,
52
- getPackageTarballRoute,
53
- publishPackageRoute,
54
- getPackageDistTagsRoute,
55
- putPackageDistTagRoute,
56
- deletePackageDistTagRoute,
57
- // Upstream package route definitions
58
- getUpstreamPackageRoute,
59
- getUpstreamScopedPackageVersionRoute,
60
- getUpstreamPackageTarballRoute,
61
- getUpstreamScopedPackageTarballRoute,
62
- getUpstreamEncodedScopedPackageRoute,
63
- getUpstreamUnifiedRoute,
64
- } from './routes/packages.ts'
65
- import {
66
- listPackagesAccess,
67
- getPackageAccessStatus,
68
- setPackageAccessStatus,
69
- grantPackageAccess,
70
- revokePackageAccess,
71
- // OpenAPI route definitions
72
- getPackageAccessRoute,
73
- setPackageAccessRoute,
74
- getScopedPackageAccessRoute,
75
- setScopedPackageAccessRoute,
76
- listPackagesAccessRoute,
77
- grantPackageAccessRoute,
78
- revokePackageAccessRoute,
79
- grantScopedPackageAccessRoute,
80
- revokeScopedPackageAccessRoute,
81
- } from './routes/access.ts'
82
- import {
83
- searchPackages,
84
- searchPackagesRoute,
85
- } from './routes/search.ts'
86
- import {
87
- auditRoute,
88
- auditQuickRoute,
89
- advisoriesBulkRoute,
90
- dashboardDataRoute,
91
- appDataRoute,
92
- handleDashboardData,
93
- handleAppData,
94
- handleSecurityAudit,
95
- // Compatibility redirect routes
96
- searchRedirectRoute,
97
- userRedirectRoute,
98
- tokensRedirectRoute,
99
- createTokenRedirectRoute,
100
- updateTokenRedirectRoute,
101
- deleteTokenRedirectRoute,
102
- } from './routes/misc.ts'
103
-
104
- import { sessionMonitor } from './utils/tracing.ts'
105
- import type { createDatabaseOperations } from './db/client.ts'
106
- import {
107
- handleStaticAssets,
108
- handleFavicon,
109
- handleRobots,
110
- handleManifest,
111
- } from './routes/static.ts'
112
- import type { Environment } from '../types.ts'
113
- import type { Context } from 'hono'
114
-
115
- // Import queue handler from dedicated module
116
- import { queue } from './queue/index.ts'
117
-
118
- // ---------------------------------------------------------
119
- // App Initialization
120
- // ("strict mode" is turned off to ensure that routes like
121
- // `/hello` & `/hello/` are handled the same way - ref.
122
- // https://hono.dev/docs/api/hono#strict-mode)
123
- // ---------------------------------------------------------
124
-
125
- const app = new OpenAPIHono<{
126
- Bindings: Environment
127
- Variables: {
128
- db: ReturnType<typeof createDatabaseOperations>
129
- }
130
- }>({ strict: false })
131
-
132
- // ---------------------------------------------------------
133
- // Middleware
134
- // ---------------------------------------------------------
135
-
136
- app.use(trimTrailingSlash())
137
- app.use('*', requestId())
138
- app.use('*', logger())
139
- app.use('*', configMiddleware)
140
- app.use('*', telemetryMiddleware)
141
- app.use('*', secureHeaders())
142
- app.use('*', jsonResponseHandler())
143
- app.use('*', except(['/-/ping', '/-/docs'], mountDatabase as any))
144
- app.use('*', sessionMonitor)
145
-
146
- // ---------------------------------------------------------
147
- // Home
148
- // (Single Page Application or API Docs)
149
- // ---------------------------------------------------------
150
-
151
- app.get('/', async c => {
152
- // If daemon is disabled and API docs are enabled, redirect to docs
153
- // This provides a better user experience when the daemon isn't available
154
- if (!c.env.DAEMON_ENABLED && c.env.API_DOCS_ENABLED) {
155
- return c.redirect('/-/docs', 302)
156
- }
157
-
158
- // If daemon is enabled, show the GUI (projects will be available)
159
- if (c.env.DAEMON_ENABLED) {
160
- return c.html(await getApp(c.env.ASSETS))
161
- }
162
-
163
- // Fallback: show docs if available, otherwise show GUI
164
- if (c.env.API_DOCS_ENABLED) {
165
- return c.redirect('/-/docs', 302)
166
- } else {
167
- return c.html(await getApp(c.env.ASSETS))
168
- }
169
- })
170
-
171
- // ---------------------------------------------------------
172
- // Documentation
173
- // ---------------------------------------------------------
174
-
175
- // Mount API documentation routes
176
- app.doc('/-/api', OPEN_API_CONFIG)
177
- app.get('/-/docs', getDocs)
178
-
179
- // ---------------------------------------------------------
180
- // Health Check
181
- // ---------------------------------------------------------
182
-
183
- // Pattern: /-/ping
184
- app.openapi(pingRoute, handlePing as any)
185
-
186
- // ---------------------------------------------------------
187
- // Authorization Verification Middleware
188
- // ---------------------------------------------------------
189
-
190
- // Custom auth middleware that checks if token is required
191
- app.use('*', async (c, next) => {
192
- if (requiresToken(c)) {
193
- // Token is required, apply bearer auth
194
- return bearerAuth({ verifyToken: verifyToken as any })(c, next)
195
- } else {
196
- // Token not required, skip auth
197
- await next()
198
- }
199
- })
200
-
201
- // ---------------------------------------------------------
202
- // User Routes
203
- // ---------------------------------------------------------
204
-
205
- // Pattern: /-/whoami
206
- app.openapi(whoamiRoute, getUsername)
207
- // Pattern: /-/user
208
- app.openapi(userProfileRoute, getUserProfile)
209
-
210
- // ---------------------------------------------------------
211
- // Daemon Project Routes - only local use
212
- // ---------------------------------------------------------
213
-
214
- // Pattern: /dashboard.json
215
- app.openapi(dashboardDataRoute, handleDashboardData as any)
216
-
217
- // Pattern: /app-data.json
218
- app.openapi(appDataRoute, handleAppData as any)
219
-
220
- // ---------------------------------------------------------
221
- // Token Routes
222
- // ---------------------------------------------------------
223
-
224
- // Pattern: /-/tokens
225
- app.openapi(getTokensRoute, getToken as any)
226
- // Pattern: /-/tokens
227
- app.openapi(createTokenRoute, postToken as any)
228
- // Pattern: /-/tokens
229
- app.openapi(updateTokenRoute, putToken as any)
230
- // Pattern: /-/tokens/{token}
231
- app.openapi(deleteTokenRoute, deleteToken as any)
232
-
233
- // ---------------------------------------------------------
234
- // Dist-tag Routes
235
- // ---------------------------------------------------------
236
-
237
- // Pattern: /-/package/{pkg}/dist-tags
238
- app.openapi(getPackageDistTagsRoute, getPackageDistTags as any)
239
- // Pattern: /-/package/{pkg}/dist-tags/{tag}
240
- app.openapi(putPackageDistTagRoute, putPackageDistTag as any)
241
- // Pattern: /-/package/{pkg}/dist-tags/{tag}
242
- app.openapi(deletePackageDistTagRoute, deletePackageDistTag as any)
243
-
244
- // ---------------------------------------------------------
245
- // Access Control Routes
246
- // ---------------------------------------------------------
247
-
248
- // Pattern: /-/package/{pkg}/access (unscoped packages)
249
- app.openapi(getPackageAccessRoute, getPackageAccessStatus as any)
250
- app.openapi(setPackageAccessRoute, setPackageAccessStatus as any)
251
-
252
- // Pattern: /-/package/{scope}%2f{pkg}/access (scoped packages)
253
- app.openapi(
254
- getScopedPackageAccessRoute,
255
- getPackageAccessStatus as any,
256
- )
257
- app.openapi(
258
- setScopedPackageAccessRoute,
259
- setPackageAccessStatus as any,
260
- )
261
-
262
- // Pattern: /-/package/list
263
- app.openapi(listPackagesAccessRoute, listPackagesAccess as any)
264
-
265
- // Pattern: /-/package/{pkg}/collaborators/{username} (unscoped packages)
266
- app.openapi(grantPackageAccessRoute, grantPackageAccess as any)
267
- app.openapi(revokePackageAccessRoute, revokePackageAccess as any)
268
-
269
- // Pattern: /-/package/{scope}%2f{pkg}/collaborators/{username} (scoped packages)
270
- app.openapi(grantScopedPackageAccessRoute, grantPackageAccess as any)
271
- app.openapi(
272
- revokeScopedPackageAccessRoute,
273
- revokePackageAccess as any,
274
- )
275
-
276
- // ---------------------------------------------------------
277
- // Search Packages
278
- // ---------------------------------------------------------
279
-
280
- // Pattern: /-/search
281
- app.openapi(searchPackagesRoute, searchPackages as any)
282
-
283
- // ---------------------------------------------------------
284
- // Handle Audit Requests
285
- // ---------------------------------------------------------
286
-
287
- // Pattern: /-/npm/audit (security audit - not implemented)
288
- app.openapi(auditRoute, handleSecurityAudit as any)
289
-
290
- // ---------------------------------------------------------
291
- // NPM Compatibility Routes (Legacy API Redirects)
292
- // (maximizes backwards compatibility with npm clients)
293
- // ---------------------------------------------------------
294
-
295
- // Pattern: /-/v1/search → /-/search
296
- app.openapi(searchRedirectRoute, (c: Context) =>
297
- c.redirect('/-/search', 308),
298
- )
299
-
300
- // Pattern: /-/npm/v1/user → /-/user
301
- app.openapi(userRedirectRoute, (c: Context) =>
302
- c.redirect('/-/user', 308),
303
- )
304
-
305
- // Pattern: /-/npm/v1/tokens → /-/tokens (GET)
306
- app.openapi(tokensRedirectRoute, (c: Context) =>
307
- c.redirect('/-/tokens', 308),
308
- )
309
-
310
- // Pattern: /-/npm/v1/tokens → /-/tokens (POST)
311
- app.openapi(createTokenRedirectRoute, (c: Context) =>
312
- c.redirect('/-/tokens', 308),
313
- )
314
-
315
- // Pattern: /-/npm/v1/tokens → /-/tokens (PUT)
316
- app.openapi(updateTokenRedirectRoute, (c: Context) =>
317
- c.redirect('/-/tokens', 308),
318
- )
319
-
320
- // Pattern: /-/npm/v1/tokens/token/{token} → /-/tokens/{token} (DELETE)
321
- app.openapi(deleteTokenRedirectRoute, (c: Context) => {
322
- return c.redirect(`/-/tokens/${c.req.param('token')}`, 308)
323
- })
324
-
325
- // Pattern: /-/npm/v1/security/audits/quick → /-/npm/audit
326
- app.openapi(auditQuickRoute, (c: Context) => {
327
- return c.redirect('/-/npm/audit', 308)
328
- })
329
-
330
- // Pattern: /-/npm/v1/security/advisories/bulk → /-/npm/audit
331
- app.openapi(advisoriesBulkRoute, (c: Context) => {
332
- return c.redirect('/-/npm/audit', 308)
333
- })
334
-
335
- // ---------------------------------------------------------
336
- // Upstream Utility Routes
337
- // (Registry utility endpoints for upstream registries)
338
- // (MUST come before upstream package routes to avoid conflicts)
339
- // ---------------------------------------------------------
340
-
341
- // Pattern: /{upstream}/-/ping (upstream registry ping)
342
- app.get('/:upstream/-/ping', handlePing)
343
-
344
- // Pattern: /{upstream}/-/docs (upstream registry docs)
345
- app.get('/:upstream/-/docs', getDocs)
346
-
347
- // Pattern: /{upstream}/-/whoami (upstream registry whoami)
348
- app.get('/:upstream/-/whoami', getUsername)
349
-
350
- // Pattern: /{upstream}/-/user (upstream registry user profile)
351
- app.get('/:upstream/-/user', getUserProfile)
352
-
353
- // Pattern: /{upstream}/-/tokens (upstream registry token management)
354
- app.get('/:upstream/-/tokens', getToken)
355
- app.post('/:upstream/-/tokens', postToken)
356
- app.put('/:upstream/-/tokens', putToken)
357
- app.delete('/:upstream/-/tokens/:token', deleteToken)
358
-
359
- // Pattern: /{upstream}/-/search (upstream registry search)
360
- app.get('/:upstream/-/search', searchPackages)
361
-
362
- // Pattern: /{upstream}/-/npm/audit (upstream registry audit)
363
- app.post('/:upstream/-/npm/audit', handleSecurityAudit)
364
-
365
- // ---------------------------------------------------------
366
- // Upstream Package Routes
367
- // (must come before catch-all package routes)
368
- // ---------------------------------------------------------
369
-
370
- // Pattern: /{upstream}/@{scope}/{pkg}/-/{tarball} (scoped package tarball)
371
- app.openapi(
372
- getUpstreamScopedPackageTarballRoute,
373
- handleUpstreamScopedTarball as any,
374
- )
375
- // Pattern: /{upstream}/@{scope}/{pkg}/{version} (scoped package version)
376
- app.openapi(
377
- getUpstreamScopedPackageVersionRoute,
378
- handleUpstreamScopedVersion as any,
379
- )
380
- // Pattern: /{upstream}/{pkg}/-/{tarball} (unscoped package tarball)
381
- app.openapi(
382
- getUpstreamPackageTarballRoute,
383
- handleUpstreamTarball as any,
384
- )
385
- // Pattern: /{upstream}/@{scope}%2f{pkg} (URL-encoded scoped package)
386
- app.openapi(
387
- getUpstreamEncodedScopedPackageRoute,
388
- handleUpstreamEncodedScoped as any,
389
- )
390
- // Pattern: /{upstream}/{param2}/{param3} (unified handler for ambiguous 3-segment paths)
391
- app.openapi(getUpstreamUnifiedRoute, handleUpstreamUnified as any)
392
- // Pattern: /{upstream}/{pkg} (unscoped package manifest)
393
- app.openapi(getUpstreamPackageRoute, handleUpstreamPackage as any)
394
-
395
- // Pattern: /-/npm/v1/security/advisories/bulk → /-/npm/audit
396
- app.openapi(advisoriesBulkRoute, async (c: Context) => {
397
- return c.redirect('/-/npm/audit', 308)
398
- })
399
-
400
- // ---------------------------------------------------------
401
- // Local Package Routes
402
- // (catch-all patterns, must come after upstream routes)
403
- // ---------------------------------------------------------
404
-
405
- // Pattern: /{pkg} (package publishing via PUT)
406
- app.openapi(publishPackageRoute, handlePackagePublish as any)
407
- // Pattern: /{pkg}/-/{tarball} (package tarball download)
408
- app.openapi(getPackageTarballRoute, handlePackageTarball as any)
409
- // Pattern: /{pkg}/{version} (specific package version)
410
- app.openapi(getPackageVersionRoute, handlePackageVersion as any)
411
- // Pattern: /{pkg} (package manifest/packument)
412
- app.openapi(getPackageRoute, handleRootPackageRoute as any)
413
-
414
- // ---------------------------------------------------------
415
- // Handle Static Assets
416
- // ---------------------------------------------------------
417
-
418
- // Pattern: /public/* (static assets from public directory)
419
- app.get('/public/*', handleStaticAssets)
420
- // Pattern: /favicon.ico (browser favicon)
421
- app.get('/favicon.ico', handleFavicon)
422
- // Pattern: /robots.txt (web crawler instructions)
423
- app.get('/robots.txt', handleRobots)
424
- // Pattern: /manifest.json (PWA web app manifest)
425
- app.get('/manifest.json', handleManifest)
426
- // Pattern: /* (catch-all for any other static assets)
427
- app.get('/*', handleStaticAssets)
428
-
429
- export { app }
430
-
431
- export default {
432
- fetch: app.fetch,
433
- queue,
434
- }
@@ -1,79 +0,0 @@
1
- import type { Context } from 'hono'
2
- import {
3
- API_DOCS_ENABLED,
4
- DAEMON_ENABLED,
5
- DAEMON_PORT,
6
- DAEMON_URL,
7
- DEBUG_ENABLED,
8
- TELEMETRY_ENABLED,
9
- SENTRY_CONFIG,
10
- PORT,
11
- VERSION,
12
- URL,
13
- } from '../../config.ts'
14
-
15
- /**
16
- * Runtime configuration resolver - can be used outside of routes
17
- * Checks environment variables and falls back to defaults
18
- */
19
- export function resolveConfig(env?: any) {
20
- const getBooleanFromEnv = (
21
- key: string,
22
- defaultValue: boolean,
23
- ): boolean => {
24
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
25
- const value = env?.[key]
26
- return typeof value === 'string' ?
27
- value.toLowerCase() === 'true'
28
- : defaultValue
29
- }
30
-
31
- return {
32
- // Daemon configuration
33
- DAEMON_ENABLED: getBooleanFromEnv('ARG_DAEMON', DAEMON_ENABLED),
34
-
35
- // Telemetry configuration
36
- TELEMETRY_ENABLED: getBooleanFromEnv(
37
- 'ARG_TELEMETRY',
38
- TELEMETRY_ENABLED,
39
- ),
40
-
41
- // Debug configuration
42
- DEBUG_ENABLED: getBooleanFromEnv('ARG_DEBUG', DEBUG_ENABLED),
43
-
44
- // Static config values (pass through)
45
- API_DOCS_ENABLED,
46
- DAEMON_PORT,
47
- DAEMON_URL,
48
- SENTRY_CONFIG,
49
- PORT,
50
- VERSION,
51
- URL,
52
- }
53
- }
54
-
55
- /**
56
- * Configuration middleware that enriches the context with computed config values
57
- * Merges compile-time defaults with runtime environment variables
58
- */
59
- export async function configMiddleware(
60
- c: Context,
61
- next: () => Promise<void>,
62
- ): Promise<void> {
63
- // Use the resolver to get computed config
64
- const runtimeConfig = resolveConfig(c.env)
65
-
66
- // Initialize global config if not already done
67
- const { initializeGlobalConfig } = await import(
68
- '../utils/config.ts'
69
- )
70
- initializeGlobalConfig(c.env)
71
-
72
- // Enrich the context environment with computed values
73
- // Ensure c.env exists (it might be undefined in test environments)
74
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
75
- c.env = c.env || {}
76
- Object.assign(c.env, runtimeConfig)
77
-
78
- await next()
79
- }
@@ -1,43 +0,0 @@
1
- import { sentry } from '@hono/sentry'
2
- import type { Context } from 'hono'
3
- import type { HonoContext } from '../../types.ts'
4
-
5
- /**
6
- * Telemetry middleware that conditionally applies Sentry based on configuration
7
- * Relies on configMiddleware to have already enriched c.env with TELEMETRY_ENABLED
8
- */
9
- export async function telemetryMiddleware(
10
- c: HonoContext,
11
- next: () => Promise<void>,
12
- ) {
13
- // Check if telemetry is enabled via the enriched config
14
- if (c.env.TELEMETRY_ENABLED) {
15
- // Apply Sentry middleware dynamically
16
- const sentryMiddleware = sentry({
17
- dsn: c.env.SENTRY?.dsn ?? c.env.SENTRY_CONFIG?.dsn ?? '',
18
- environment:
19
- c.env.SENTRY?.environment ??
20
- c.env.SENTRY_CONFIG?.environment ??
21
- 'development',
22
- sendDefaultPii: c.env.SENTRY_CONFIG?.sendDefaultPii ?? true,
23
- sampleRate: c.env.SENTRY_CONFIG?.sampleRate ?? 1.0,
24
- tracesSampleRate: c.env.SENTRY_CONFIG?.tracesSampleRate ?? 0.1,
25
- beforeSend(event, _hint) {
26
- // Filter out expected errors to reduce noise
27
- if (
28
- event.exception?.values?.[0]?.value?.includes('404') ||
29
- event.exception?.values?.[0]?.value?.includes('not found')
30
- ) {
31
- return null
32
- }
33
- return event
34
- },
35
- })
36
-
37
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
38
- return sentryMiddleware(c as Context, next)
39
- } else {
40
- // Skip Sentry when telemetry is disabled
41
- return next()
42
- }
43
- }
@@ -1,97 +0,0 @@
1
- import type { QueueBatch, Environment } from '../../types.ts'
2
- import { createDatabaseOperations } from '../db/client.ts'
3
- import {
4
- getUpstreamConfig,
5
- buildUpstreamUrl,
6
- } from '../utils/upstream.ts'
7
-
8
- /**
9
- * Queue handler for background cache refresh jobs
10
- *
11
- * Processes queue messages to refresh package and version cache data
12
- * from upstream registries. This runs in the background to keep
13
- * cached data fresh without blocking user requests.
14
- */
15
- export async function queue(batch: QueueBatch, env: Environment) {
16
- if (!env.DB) {
17
- throw new Error('Database not available')
18
- }
19
- const db = createDatabaseOperations(env.DB)
20
-
21
- for (const message of batch.messages) {
22
- try {
23
- const {
24
- type,
25
- packageName,
26
- spec,
27
- upstream,
28
- options: _options,
29
- } = message.body
30
-
31
- if (type === 'package_refresh' && packageName) {
32
- // Handle package refresh - refetch from upstream and cache
33
- const upstreamConfig = getUpstreamConfig(upstream)
34
- if (upstreamConfig) {
35
- const upstreamUrl = buildUpstreamUrl(
36
- upstreamConfig,
37
- packageName,
38
- )
39
- const response = await fetch(upstreamUrl, {
40
- headers: { Accept: 'application/json' },
41
- })
42
-
43
- if (response.ok) {
44
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
45
- const upstreamData = (await response.json()) as Record<
46
- string,
47
- any
48
- >
49
-
50
- // Cache the package metadata
51
- if (upstreamData['dist-tags']) {
52
- await db.upsertCachedPackage(
53
- packageName,
54
- upstreamData['dist-tags'] as Record<string, string>,
55
- upstream,
56
- new Date().toISOString(),
57
- )
58
- }
59
-
60
- // Cache all versions
61
- if (upstreamData.versions) {
62
- const versionPromises = Object.entries(
63
- upstreamData.versions as Record<string, any>,
64
- ).map(async ([version, manifest]) => {
65
- try {
66
- await db.upsertCachedVersion(
67
- `${packageName}@${version}`,
68
- manifest as Record<string, any>,
69
- upstream,
70
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
71
- (manifest.publishedAt as string) ||
72
- new Date().toISOString(),
73
- )
74
- } catch (_error) {
75
- // Silently fail individual versions
76
- }
77
- })
78
- await Promise.allSettled(versionPromises)
79
- }
80
- }
81
- }
82
- } else if (type === 'version_refresh' && spec) {
83
- // Handle version refresh - similar logic for individual versions
84
- // (This would be implemented if needed)
85
- }
86
-
87
- // Acknowledge successful processing
88
- message.ack()
89
- } catch (error) {
90
- // Retry failed messages
91
- // TODO: Replace with proper logging system
92
- // eslint-disable-next-line no-console
93
- console.error('Queue processing error:', error)
94
- message.retry()
95
- }
96
- }
97
- }