@vltpkg/vsr 0.0.0-26

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 (93) hide show
  1. package/DEPLOY.md +163 -0
  2. package/LICENSE +119 -0
  3. package/README.md +314 -0
  4. package/config.ts +221 -0
  5. package/drizzle.config.js +40 -0
  6. package/info/COMPARISONS.md +37 -0
  7. package/info/CONFIGURATION.md +143 -0
  8. package/info/CONTRIBUTING.md +32 -0
  9. package/info/DATABASE_SETUP.md +108 -0
  10. package/info/GRANULAR_ACCESS_TOKENS.md +160 -0
  11. package/info/PROJECT_STRUCTURE.md +291 -0
  12. package/info/ROADMAP.md +27 -0
  13. package/info/SUPPORT.md +39 -0
  14. package/info/TESTING.md +301 -0
  15. package/info/USER_SUPPORT.md +31 -0
  16. package/package.json +77 -0
  17. package/scripts/build-assets.js +31 -0
  18. package/scripts/build-bin.js +62 -0
  19. package/scripts/prepack.js +27 -0
  20. package/src/assets/public/images/bg.png +0 -0
  21. package/src/assets/public/images/clients/logo-bun.png +0 -0
  22. package/src/assets/public/images/clients/logo-deno.png +0 -0
  23. package/src/assets/public/images/clients/logo-npm.png +0 -0
  24. package/src/assets/public/images/clients/logo-pnpm.png +0 -0
  25. package/src/assets/public/images/clients/logo-vlt.png +0 -0
  26. package/src/assets/public/images/clients/logo-yarn.png +0 -0
  27. package/src/assets/public/images/favicon/apple-touch-icon.png +0 -0
  28. package/src/assets/public/images/favicon/favicon-96x96.png +0 -0
  29. package/src/assets/public/images/favicon/favicon.ico +0 -0
  30. package/src/assets/public/images/favicon/favicon.svg +3 -0
  31. package/src/assets/public/images/favicon/site.webmanifest +21 -0
  32. package/src/assets/public/images/favicon/web-app-manifest-192x192.png +0 -0
  33. package/src/assets/public/images/favicon/web-app-manifest-512x512.png +0 -0
  34. package/src/assets/public/styles/styles.css +231 -0
  35. package/src/bin/demo/package.json +6 -0
  36. package/src/bin/demo/vlt.json +1 -0
  37. package/src/bin/vsr.ts +484 -0
  38. package/src/db/client.ts +590 -0
  39. package/src/db/migrations/0000_faulty_ricochet.sql +14 -0
  40. package/src/db/migrations/0000_initial.sql +29 -0
  41. package/src/db/migrations/0001_uuid_validation.sql +35 -0
  42. package/src/db/migrations/0001_wealthy_magdalene.sql +7 -0
  43. package/src/db/migrations/drop.sql +3 -0
  44. package/src/db/migrations/meta/0000_snapshot.json +104 -0
  45. package/src/db/migrations/meta/0001_snapshot.json +155 -0
  46. package/src/db/migrations/meta/_journal.json +20 -0
  47. package/src/db/schema.ts +43 -0
  48. package/src/index.ts +434 -0
  49. package/src/middleware/config.ts +79 -0
  50. package/src/middleware/telemetry.ts +43 -0
  51. package/src/queue/index.ts +97 -0
  52. package/src/routes/access.ts +852 -0
  53. package/src/routes/docs.ts +63 -0
  54. package/src/routes/misc.ts +469 -0
  55. package/src/routes/packages.ts +2823 -0
  56. package/src/routes/ping.ts +39 -0
  57. package/src/routes/search.ts +131 -0
  58. package/src/routes/static.ts +74 -0
  59. package/src/routes/tokens.ts +259 -0
  60. package/src/routes/users.ts +68 -0
  61. package/src/utils/auth.ts +202 -0
  62. package/src/utils/cache.ts +587 -0
  63. package/src/utils/config.ts +50 -0
  64. package/src/utils/database.ts +69 -0
  65. package/src/utils/docs.ts +146 -0
  66. package/src/utils/packages.ts +453 -0
  67. package/src/utils/response.ts +125 -0
  68. package/src/utils/routes.ts +64 -0
  69. package/src/utils/spa.ts +52 -0
  70. package/src/utils/tracing.ts +52 -0
  71. package/src/utils/upstream.ts +172 -0
  72. package/test/access.test.ts +705 -0
  73. package/test/audit.test.ts +828 -0
  74. package/test/dashboard.test.ts +693 -0
  75. package/test/dist-tags.test.ts +678 -0
  76. package/test/manifest.test.ts +436 -0
  77. package/test/packument.test.ts +530 -0
  78. package/test/ping.test.ts +41 -0
  79. package/test/search.test.ts +472 -0
  80. package/test/setup.ts +130 -0
  81. package/test/static.test.ts +646 -0
  82. package/test/tokens.test.ts +389 -0
  83. package/test/utils/auth.test.ts +214 -0
  84. package/test/utils/packages.test.ts +235 -0
  85. package/test/utils/response.test.ts +184 -0
  86. package/test/whoami.test.ts +119 -0
  87. package/tsconfig.json +16 -0
  88. package/tsconfig.worker.json +3 -0
  89. package/typedoc.mjs +2 -0
  90. package/types.ts +598 -0
  91. package/vitest.config.ts +25 -0
  92. package/vlt.json.example +56 -0
  93. package/wrangler.json +65 -0
@@ -0,0 +1,160 @@
1
+ # Granular Access Tokens
2
+
3
+ All tokens are considered "granular access tokens" (GATs). Token
4
+ entries in the database consist of 3 parts:
5
+
6
+ - `token` the unique token value
7
+ - `uuid` associative value representing a single user/scope
8
+ - `scope` value representing the granular access/privileges
9
+
10
+ #### `scope` as a JSON `Object`
11
+
12
+ A `scope` contains an array of privileges that define both the type(s)
13
+ of & access value(s) for a token.
14
+
15
+ > [!NOTE] Tokens can be associated with multiple "types" of access
16
+
17
+ - `type(s)`:
18
+ - `pkg:read` read associated packages
19
+ - `pkg:read+write` write associated packages (requires read access)
20
+ - `user:read` read associated user
21
+ - `user:read+write` write associated user (requires read access)
22
+ - `value(s)`:
23
+ - `*` an ANY selector for `user:` or `pkg:` access types
24
+ - `~<user>` user selector for the `user:` access type
25
+ - `@<scope>/<pkg>` package specific selector for the `pkg:` access
26
+ type
27
+ - `@<scope>/*` glob scope selector for `pkg:` access types
28
+
29
+ > [!NOTE]
30
+ >
31
+ > - user/org/team management via `@<scope>` is not supported at the
32
+ > moment
33
+
34
+ ### Granular Access Examples
35
+
36
+ ##### End-user/Subscriber Persona
37
+
38
+ - specific package read access
39
+ - individual user read+write access
40
+
41
+ ```json
42
+ [
43
+ {
44
+ "values": ["@organization/package-name"],
45
+ "types": {
46
+ "pkg": {
47
+ "read": true
48
+ }
49
+ }
50
+ },
51
+ {
52
+ "values": ["~johnsmith"],
53
+ "types": {
54
+ "user": {
55
+ "read": true,
56
+ "write": true
57
+ }
58
+ }
59
+ }
60
+ ]
61
+ ```
62
+
63
+ ##### Team Member/Maintainer Persona
64
+
65
+ - scoped package read+write access
66
+ - individual user read+write access
67
+
68
+ ```json
69
+ [
70
+ {
71
+ "values": ["@organization/*"],
72
+ "types": {
73
+ "pkg": {
74
+ "read": true
75
+ }
76
+ }
77
+ },
78
+ {
79
+ "values": ["~johnsmith"],
80
+ "types": {
81
+ "user": {
82
+ "read": true,
83
+ "write": true
84
+ }
85
+ }
86
+ }
87
+ ]
88
+ ```
89
+
90
+ ##### Package Publish CI Persona
91
+
92
+ - organization scoped packages read+write access
93
+ - individual user read+write access
94
+
95
+ ```json
96
+ [
97
+ {
98
+ "values": ["@organization/package-name"],
99
+ "types": {
100
+ "pkg": {
101
+ "read": true
102
+ }
103
+ }
104
+ },
105
+ {
106
+ "values": ["~johnsmith"],
107
+ "types": {
108
+ "user": {
109
+ "read": true,
110
+ "write": true
111
+ }
112
+ }
113
+ }
114
+ ]
115
+ ```
116
+
117
+ ##### Organization Admin Persona
118
+
119
+ - organization scoped package read+write access
120
+ - organization users read+write access
121
+
122
+ ```json
123
+ [
124
+ {
125
+ "values": ["@company/*"],
126
+ "types": {
127
+ "pkg": {
128
+ "read": true,
129
+ "write": true
130
+ },
131
+ "user": {
132
+ "read": true,
133
+ "write": true
134
+ }
135
+ }
136
+ }
137
+ ]
138
+ ```
139
+
140
+ ##### Registry Owner/Admin Persona
141
+
142
+ ```json
143
+ [
144
+ {
145
+ "values": ["*"],
146
+ "types": {
147
+ "pkg": {
148
+ "read": true,
149
+ "write": true
150
+ },
151
+ {
152
+ "user": {
153
+ "read": true,
154
+ "write": true
155
+ }
156
+ }
157
+ }
158
+ }
159
+ ]
160
+ ```
@@ -0,0 +1,291 @@
1
+ # VSR Project Directory Structure
2
+
3
+ **VSR** is a minimal "npm-compatible" registry that replicates core
4
+ features of `registry.npmjs.org` while adding new capabilities. It's
5
+ built to run on Cloudflare Workers with D1 database and R2 storage.
6
+
7
+ ## 📁 Root Directory
8
+
9
+ ```
10
+ registry/
11
+ ├── config.ts # Global application configuration
12
+ ├── package.json # NPM package definition & scripts
13
+ ├── wrangler.json # Cloudflare Workers deployment config
14
+ ├── drizzle.config.js # Database ORM configuration
15
+ ├── tsconfig.worker.json # TypeScript config for Workers environment
16
+ ├── types.ts # Shared TypeScript type definitions
17
+ ├── README.md # Project documentation & setup guide
18
+ ├── CONTRIBUTING.md # Development guidelines & workflow
19
+ ├── LICENSE # FSL-1.1-MIT license
20
+ └── src/ # Source code directory
21
+ ```
22
+
23
+ ### Configuration Files
24
+
25
+ - **`config.ts`** - Central configuration hub containing:
26
+ - API documentation settings
27
+ - Upstream registry definitions (npm, local)
28
+ - Authentication domains and redirect URIs
29
+ - Cookie options and security settings
30
+ - Development server configuration
31
+
32
+ - **`wrangler.json`** - Cloudflare Workers configuration:
33
+ - D1 database bindings for SQLite storage
34
+ - R2 bucket bindings for package tarballs
35
+ - Queue configurations for background processing
36
+ - Asset serving and development settings
37
+
38
+ - **`package.json`** - Project metadata and tooling:
39
+ - Build scripts for dist creation and asset copying
40
+ - Database management commands (push, migrate, studio)
41
+ - Development server orchestration
42
+ - TypeScript compilation for both Node.js and Workers
43
+
44
+ ## 📁 Source Code (`src/`)
45
+
46
+ ```
47
+ src/
48
+ ├── index.ts # Main application entry point
49
+ ├── api.ts # OpenAPI specification
50
+ ├── routes/ # HTTP route handlers
51
+ ├── utils/ # Shared utility functions
52
+ ├── db/ # Database layer
53
+ ├── assets/ # Static files & frontend
54
+ ├── bin/ # CLI executables
55
+ └── schemas/ # Validation schemas
56
+ ```
57
+
58
+ ### Core Application
59
+
60
+ - **`index.ts`** - Main Hono application setup:
61
+ - Middleware stack (auth, logging, CORS, security)
62
+ - Route mounting and organization
63
+ - Queue consumer for background package refreshing
64
+ - Health checks and API documentation endpoints
65
+
66
+ - **`api.ts`** - OpenAPI specification:
67
+ - REST API definitions for all endpoints
68
+ - Request/response schemas
69
+ - Authentication requirements
70
+ - Used by Scalar for auto-generated documentation
71
+
72
+ ## 📁 Route Handlers (`src/routes/`)
73
+
74
+ ```
75
+ routes/
76
+ ├── users.ts # User profile management
77
+ ├── tokens.ts # Authentication token CRUD
78
+ ├── packages.ts # Package operations (45KB - core logic)
79
+ ├── search.ts # Package search & discovery
80
+ ├── auth.ts # OAuth authentication flows
81
+ ├── access.ts # Access control & permissions
82
+ └── static.ts # Static asset serving
83
+ ```
84
+
85
+ ### Route Responsibilities
86
+
87
+ - **`packages.ts`** (Primary) - Core package registry functionality:
88
+ - Package publishing and unpublishing
89
+ - Version management and dist-tags
90
+ - Tarball upload/download via R2
91
+ - Upstream registry proxying for missing packages
92
+ - Package metadata validation and transformation
93
+
94
+ - **`tokens.ts`** - Granular Access Token (GAT) management:
95
+ - Token creation with scoped permissions
96
+ - CRUD operations for user tokens
97
+ - Scope validation (pkg:read/write, user:read/write)
98
+
99
+ - **`auth.ts`** - Authentication workflows:
100
+ - OAuth callback handling
101
+ - Session management
102
+ - Login/logout flows
103
+
104
+ - **`access.ts`** - Fine-grained access control:
105
+ - Package-level permissions
106
+ - Collaborator management
107
+ - Access list operations
108
+
109
+ - **`search.ts`** - Package discovery:
110
+ - Text-based package searching
111
+ - Filtering and pagination
112
+ - Integration with upstream registries
113
+
114
+ - **`users.ts`** - User management:
115
+ - Profile retrieval (`/-/whoami`)
116
+ - User information endpoints
117
+
118
+ - **`static.ts`** - Asset delivery:
119
+ - Favicon serving
120
+ - CSS stylesheet delivery
121
+ - Image asset routing
122
+ - robots.txt and manifest files
123
+
124
+ ## 📁 Utilities (`src/utils/`)
125
+
126
+ ```
127
+ utils/
128
+ ├── auth.ts # Authentication & token verification
129
+ ├── cache.ts # Package caching strategies (13KB)
130
+ ├── database.ts # Database connection middleware
131
+ ├── packages.ts # Package validation & processing (13KB)
132
+ ├── response.ts # HTTP response formatting
133
+ ├── routes.ts # Route middleware & guards
134
+ ├── spa.ts # Single Page Application serving
135
+ ├── tracing.ts # Request monitoring & performance
136
+ └── upstream.ts # Registry proxying & fallback
137
+ ```
138
+
139
+ ### Utility Functions
140
+
141
+ - **`cache.ts`** - Intelligent caching system:
142
+ - Package metadata caching from upstream registries
143
+ - Version-specific caching strategies
144
+ - Cache invalidation and refresh logic
145
+ - Background queue integration for cache warming
146
+
147
+ - **`packages.ts`** - Package processing utilities:
148
+ - NPM package validation
149
+ - Tarball extraction and analysis
150
+ - Manifest transformation and normalization
151
+ - Semver handling and version resolution
152
+
153
+ - **`upstream.ts`** - Multi-registry support:
154
+ - Configuration-driven upstream definitions
155
+ - Fallback logic for missing packages
156
+ - Request proxying and response transformation
157
+ - Error handling for upstream failures
158
+
159
+ - **`auth.ts`** - Security utilities:
160
+ - Bearer token verification
161
+ - Scope-based authorization
162
+ - JWT handling and validation
163
+
164
+ ## 📁 Database Layer (`src/db/`)
165
+
166
+ ```
167
+ db/
168
+ ├── client.ts # Database client & operations
169
+ ├── schema.ts # Drizzle schema definitions
170
+ └── migrations/ # Database migrations
171
+ ├── 0000_initial.sql # Base schema creation
172
+ ├── 0001_uuid_validation.sql # UUID constraints
173
+ ├── drop.sql # Development reset script
174
+ └── meta/ # Drizzle migration metadata
175
+ ├── _journal.json # Migration history
176
+ ├── 0000_snapshot.json # Schema snapshots
177
+ └── 0001_snapshot.json
178
+ ```
179
+
180
+ ### Database Architecture
181
+
182
+ - **`schema.ts`** - Core data model:
183
+ - `packages` table: Package metadata and tags
184
+ - `versions` table: Version-specific manifests
185
+ - `tokens` table: Authentication tokens with scoped permissions
186
+ - Origin tracking (local vs upstream)
187
+ - Caching timestamps for upstream data
188
+
189
+ - **`client.ts`** - Database operations:
190
+ - Drizzle ORM integration
191
+ - CRUD operations for all entities
192
+ - Transaction management
193
+ - Connection pooling for Workers environment
194
+
195
+ ## 📁 Static Assets (`src/assets/`)
196
+
197
+ ```
198
+ assets/
199
+ └── public/
200
+ ├── images/
201
+ │ ├── bg.png # Background image
202
+ │ ├── clients/ # Package manager logos
203
+ │ │ ├── logo-npm.png
204
+ │ │ ├── logo-yarn.png
205
+ │ │ ├── logo-pnpm.png
206
+ │ │ ├── logo-bun.png
207
+ │ │ ├── logo-deno.png
208
+ │ │ └── logo-vlt.png
209
+ │ └── favicon/ # Browser icons (multiple formats)
210
+ │ ├── favicon.ico
211
+ │ ├── favicon.svg
212
+ │ ├── apple-touch-icon.png
213
+ │ ├── favicon-96x96.png
214
+ │ ├── site.webmanifest
215
+ │ ├── web-app-manifest-192x192.png
216
+ │ └── web-app-manifest-512x512.png
217
+ └── styles/
218
+ └── styles.css # Application CSS
219
+ ```
220
+
221
+ ### Asset Organization
222
+
223
+ - **`images/clients/`** - Package manager branding:
224
+ - Logos for supported package managers
225
+ - Used in web interface for client recognition
226
+ - Consistent sizing and format
227
+
228
+ - **`images/favicon/`** - Browser integration:
229
+ - Multiple icon formats for cross-platform support
230
+ - Progressive Web App manifest
231
+ - Apple touch icons for iOS devices
232
+
233
+ ## 📁 CLI Tools (`src/bin/`)
234
+
235
+ ```
236
+ bin/
237
+ ├── vsr.ts # Main CLI entry point
238
+ └── demo/ # Demo project workspace
239
+ ├── package.json # Demo dependencies
240
+ └── vlt.json # VLT configuration
241
+ ```
242
+
243
+ ### Command Line Interface
244
+
245
+ - **`vsr.ts`** - Development server orchestration:
246
+ - Spawns both the vlt daemon (port 3000) and wrangler dev
247
+ (port 1337)
248
+ - Manages local development environment
249
+ - Debug mode for verbose logging
250
+ - Automatic path resolution for monorepo structure
251
+
252
+ - **`demo/`** - Testing workspace:
253
+ - Minimal project for vlt server requirements
254
+ - Used during development to simulate real package operations
255
+ - Contains basic package.json and vlt configuration
256
+
257
+ ## 📁 Validation (`src/schemas/`)
258
+
259
+ ```
260
+ schemas/
261
+ └── [Currently empty - reserved for future validation schemas]
262
+ ```
263
+
264
+ **Purpose**: Reserved directory for request/response validation
265
+ schemas, likely to be populated with Zod or similar validation
266
+ libraries.
267
+
268
+ ## 🏗️ Architecture Overview
269
+
270
+ ### Request Flow
271
+
272
+ 1. **Static Assets** → Direct serving via Cloudflare Workers
273
+ 2. **Package Requests** → Local DB check → Upstream fallback if needed
274
+ 3. **Authentication** → Bearer token validation → Scope checking
275
+ 4. **Publishing** → Validation → R2 storage → DB metadata update
276
+
277
+ ### Data Flow
278
+
279
+ - **Local Packages**: Stored in D1 (metadata) + R2 (tarballs)
280
+ - **Upstream Packages**: Cached in D1 with TTL, proxied from npm
281
+ - **Background Jobs**: Queue-based cache refresh for popular packages
282
+
283
+ ### Security Model
284
+
285
+ - **Granular Access Tokens**: Scoped permissions per package/user
286
+ - **Origin Tracking**: Distinguish local vs upstream packages
287
+ - **Scope Validation**: Package-level and user-level access control
288
+
289
+ This architecture provides a scalable, serverless npm registry that
290
+ can serve as both a private registry and an intelligent proxy to
291
+ upstream registries like npmjs.org.
@@ -0,0 +1,27 @@
1
+ ### Roadmap
2
+
3
+ #### v1.0.0
4
+
5
+ | Status | Feature |
6
+ | :----: | :---------------------------------------------------- |
7
+ | ⏳ | web: user login (ex. `npm login` / `--auth-type=web`) |
8
+ | ⏳ | web: user account management (`hosted`) |
9
+ | ⏳ | web: user registration (`hosted`) |
10
+ | ⏳ | web: admin user management (`hosted`) |
11
+ | ⏳ | web: package pages |
12
+ | ⏳ | web: search |
13
+ | ⏳ | api: rate-limiting |
14
+
15
+ #### v1.x
16
+
17
+ | Status | Feature |
18
+ | :----: | :---------------------------------------- |
19
+ | 🕤 | api: package insights (powered by socket) |
20
+ | 🕤 | api: audit (powered by socket) |
21
+ | 🕤 | mfa access provisioning |
22
+ | 🕤 | orgs |
23
+ | 🕤 | teams |
24
+ | 🕤 | staging |
25
+ | 🕤 | events/hooks |
26
+ | 🕤 | plugins/middleware |
27
+ | 🕤 | variants/distributions |
@@ -0,0 +1,39 @@
1
+ # Supported `npm` Client Commands
2
+
3
+ | Support | Commannd |
4
+ | :-----: | :-------------------------------------------------------------------------------------- |
5
+ | ✅ | `access` |
6
+ | ✅ | `access list packages` |
7
+ | ✅ | `access get status` |
8
+ | ✅ | `access set status` |
9
+ | 🕤 | `access set mfa` |
10
+ | ✅ | `access grant` |
11
+ | ✅ | `access revoke` |
12
+ | 🕤 | `adduser` - `PUT /-/org/@<org>/<user>`: Adds/updates a user (requires admin privileges) |
13
+ | ⏳ | `audit` |
14
+ | ✅ | `bugs` |
15
+ | ✅ | `dist-tag add` |
16
+ | ✅ | `dist-tag rm` |
17
+ | ✅ | `dist-tag ls` |
18
+ | ✅ | `deprecate` |
19
+ | ✅ | `docs` |
20
+ | ✅ | `exec` |
21
+ | ✅ | `install` |
22
+ | ⏳ | `login` |
23
+ | ⏳ | `logout` |
24
+ | 🕤 | `org` |
25
+ | ✅ | `outdated` |
26
+ | 🕤 | `owner add` |
27
+ | 🕤 | `owner rm` |
28
+ | 🕤 | `owner ls` |
29
+ | ✅ | `ping` |
30
+ | 🕤 | `profile enable-2fa` |
31
+ | 🕤 | `profile disable-2fa` |
32
+ | ✅ | `profile get` |
33
+ | 🕤 | `profile set` - `PUT /-/npm/v1/user`: Updates a user (requires auth) |
34
+ | ✅ | `publish` |
35
+ | ✅ | `repo` |
36
+ | ✅ | `search` |
37
+ | 🕤 | `team` |
38
+ | ✅ | `view` |
39
+ | ✅ | `whoami` |