@alteran/astro 0.3.9 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +19 -30
  3. package/index.js +34 -28
  4. package/migrations/0007_bored_spitfire.sql +26 -0
  5. package/migrations/0008_furry_ozymandias.sql +2 -0
  6. package/migrations/meta/0007_snapshot.json +534 -0
  7. package/migrations/meta/0008_snapshot.json +548 -0
  8. package/migrations/meta/_journal.json +14 -0
  9. package/package.json +10 -9
  10. package/src/app.ts +8 -4
  11. package/src/db/account.ts +25 -6
  12. package/src/db/dal.ts +34 -23
  13. package/src/db/repo.ts +35 -35
  14. package/src/db/schema.ts +5 -1
  15. package/src/db/seed.ts +5 -13
  16. package/src/entrypoints/server.ts +2 -22
  17. package/src/handlers/root.ts +4 -4
  18. package/src/lib/account-state.ts +156 -0
  19. package/src/lib/actor.ts +28 -12
  20. package/src/lib/appview/auth-policy.ts +66 -0
  21. package/src/lib/appview/did-resolver.ts +233 -0
  22. package/src/lib/appview/proxy.ts +221 -0
  23. package/src/lib/appview/service-config.ts +61 -0
  24. package/src/lib/appview/service-jwt.ts +93 -0
  25. package/src/lib/appview/types.ts +25 -0
  26. package/src/lib/appview.ts +5 -532
  27. package/src/lib/auth-errors.ts +24 -0
  28. package/src/lib/auth.ts +63 -15
  29. package/src/lib/blockstore-gc.ts +2 -1
  30. package/src/lib/cache.ts +30 -4
  31. package/src/lib/chat.ts +14 -8
  32. package/src/lib/commit.ts +26 -36
  33. package/src/lib/config.ts +26 -15
  34. package/src/lib/did-document.ts +32 -0
  35. package/src/lib/errors.ts +54 -0
  36. package/src/lib/feed.ts +18 -19
  37. package/src/lib/firehose/frames.ts +87 -47
  38. package/src/lib/firehose/validation.ts +3 -3
  39. package/src/lib/jwt.ts +85 -177
  40. package/src/lib/labeler.ts +43 -30
  41. package/src/lib/logger.ts +4 -0
  42. package/src/lib/mst/block-map.ts +172 -0
  43. package/src/lib/mst/blockstore.ts +56 -93
  44. package/src/lib/mst/index.ts +1 -0
  45. package/src/lib/mst/leaf.ts +25 -0
  46. package/src/lib/mst/mst.ts +81 -237
  47. package/src/lib/mst/serialize.ts +97 -0
  48. package/src/lib/mst/types.ts +21 -0
  49. package/src/lib/oauth/clients.ts +67 -0
  50. package/src/lib/oauth/dpop-errors.ts +15 -0
  51. package/src/lib/oauth/dpop.ts +150 -0
  52. package/src/lib/oauth/resource.ts +199 -0
  53. package/src/lib/oauth/store.ts +77 -0
  54. package/src/lib/preferences.ts +9 -34
  55. package/src/lib/refresh-session.ts +161 -0
  56. package/src/lib/relay.ts +10 -8
  57. package/src/lib/secrets.ts +6 -7
  58. package/src/lib/sequencer.ts +12 -3
  59. package/src/lib/service-auth.ts +184 -0
  60. package/src/lib/session-tokens.ts +28 -76
  61. package/src/lib/streaming-car.ts +3 -0
  62. package/src/lib/tracing.ts +4 -3
  63. package/src/lib/util.ts +65 -15
  64. package/src/middleware.ts +1 -1
  65. package/src/pages/.well-known/did.json.ts +27 -30
  66. package/src/pages/.well-known/oauth-authorization-server.ts +31 -0
  67. package/src/pages/.well-known/oauth-protected-resource.ts +22 -0
  68. package/src/pages/debug/record.ts +1 -1
  69. package/src/pages/debug/sequencer.ts +28 -0
  70. package/src/pages/oauth/authorize.ts +78 -0
  71. package/src/pages/oauth/consent.ts +80 -0
  72. package/src/pages/oauth/par.ts +121 -0
  73. package/src/pages/oauth/token.ts +158 -0
  74. package/src/pages/xrpc/[...nsid].ts +61 -0
  75. package/src/pages/xrpc/app.bsky.actor.getPreferences.ts +12 -13
  76. package/src/pages/xrpc/app.bsky.actor.putPreferences.ts +23 -23
  77. package/src/pages/xrpc/app.bsky.unspecced.getAgeAssuranceState.ts +9 -2
  78. package/src/pages/xrpc/chat.bsky.convo.getLog.ts +9 -2
  79. package/src/pages/xrpc/chat.bsky.convo.listConvos.ts +9 -2
  80. package/src/pages/xrpc/com.atproto.identity.getRecommendedDidCredentials.ts +43 -41
  81. package/src/pages/xrpc/com.atproto.identity.requestPlcOperationSignature.ts +10 -3
  82. package/src/pages/xrpc/com.atproto.identity.resolveHandle.ts +40 -9
  83. package/src/pages/xrpc/com.atproto.identity.signPlcOperation.ts +41 -29
  84. package/src/pages/xrpc/com.atproto.identity.submitPlcOperation.ts +20 -6
  85. package/src/pages/xrpc/com.atproto.identity.updateHandle.ts +1 -1
  86. package/src/pages/xrpc/com.atproto.repo.applyWrites.ts +101 -11
  87. package/src/pages/xrpc/com.atproto.repo.createRecord.ts +44 -14
  88. package/src/pages/xrpc/com.atproto.repo.deleteRecord.ts +41 -13
  89. package/src/pages/xrpc/com.atproto.repo.describeRepo.ts +2 -2
  90. package/src/pages/xrpc/com.atproto.repo.getRecord.ts +14 -1
  91. package/src/pages/xrpc/com.atproto.repo.listMissingBlobs.ts +14 -6
  92. package/src/pages/xrpc/com.atproto.repo.listRecords.ts +1 -1
  93. package/src/pages/xrpc/com.atproto.repo.putRecord.ts +42 -14
  94. package/src/pages/xrpc/com.atproto.repo.uploadBlob.ts +76 -15
  95. package/src/pages/xrpc/com.atproto.server.checkAccountStatus.ts +20 -8
  96. package/src/pages/xrpc/com.atproto.server.createSession.ts +31 -11
  97. package/src/pages/xrpc/com.atproto.server.describeServer.ts +1 -1
  98. package/src/pages/xrpc/com.atproto.server.getServiceAuth.ts +12 -5
  99. package/src/pages/xrpc/com.atproto.server.getSession.ts +22 -8
  100. package/src/pages/xrpc/com.atproto.server.refreshSession.ts +30 -72
  101. package/src/pages/xrpc/com.atproto.sync.getBlob.ts +71 -22
  102. package/src/pages/xrpc/com.atproto.sync.getCheckout.json.ts +1 -1
  103. package/src/pages/xrpc/com.atproto.sync.getCheckout.ts +1 -1
  104. package/src/pages/xrpc/com.atproto.sync.getHead.ts +7 -2
  105. package/src/pages/xrpc/com.atproto.sync.getLatestCommit.ts +1 -1
  106. package/src/pages/xrpc/com.atproto.sync.getRecord.ts +5 -27
  107. package/src/pages/xrpc/com.atproto.sync.getRepo.json.ts +1 -1
  108. package/src/pages/xrpc/com.atproto.sync.getRepo.ts +50 -5
  109. package/src/pages/xrpc/com.atproto.sync.getRepoStatus.ts +58 -0
  110. package/src/pages/xrpc/com.atproto.sync.listBlobs.ts +1 -1
  111. package/src/pages/xrpc/com.atproto.sync.listRepos.ts +5 -3
  112. package/src/services/car.ts +207 -55
  113. package/src/services/r2-blob-store.ts +1 -1
  114. package/src/services/repo/blockstore-ops.ts +29 -0
  115. package/src/services/repo/operations.ts +133 -0
  116. package/src/services/repo-manager.ts +202 -253
  117. package/src/worker/runtime.ts +53 -8
  118. package/src/worker/sequencer/broadcast.ts +91 -0
  119. package/src/worker/sequencer/cid-helpers.ts +39 -0
  120. package/src/worker/sequencer/payload.ts +84 -0
  121. package/src/worker/sequencer/types.ts +36 -0
  122. package/src/worker/sequencer/upgrade.ts +141 -0
  123. package/src/worker/sequencer.ts +263 -405
  124. package/types/env.d.ts +15 -3
  125. package/src/pages/xrpc/app.bsky.actor.getProfile.ts +0 -49
  126. package/src/pages/xrpc/app.bsky.actor.getProfiles.ts +0 -51
  127. package/src/pages/xrpc/app.bsky.feed.getActorFeeds.ts +0 -25
  128. package/src/pages/xrpc/app.bsky.feed.getAuthorFeed.ts +0 -42
  129. package/src/pages/xrpc/app.bsky.feed.getFeedGenerators.ts +0 -25
  130. package/src/pages/xrpc/app.bsky.feed.getPostThread.ts +0 -37
  131. package/src/pages/xrpc/app.bsky.feed.getPosts.ts +0 -26
  132. package/src/pages/xrpc/app.bsky.feed.getSuggestedFeeds.ts +0 -23
  133. package/src/pages/xrpc/app.bsky.feed.getTimeline.ts +0 -47
  134. package/src/pages/xrpc/app.bsky.graph.getFollowers.ts +0 -29
  135. package/src/pages/xrpc/app.bsky.graph.getFollows.ts +0 -29
  136. package/src/pages/xrpc/app.bsky.notification.getUnreadCount.ts +0 -20
  137. package/src/pages/xrpc/app.bsky.notification.listNotifications.ts +0 -27
  138. package/src/pages/xrpc/app.bsky.unspecced.getSuggestedFeeds.ts +0 -23
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Rawkode Academy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Alteran
2
2
 
3
+ > [!WARNING]
4
+ > This project was built using agentic coding tools and is currently undergoing a systematic review by a human in their spare time. Nobody should use this project as their PDS yet.
5
+
3
6
  ## Astro Integration
4
7
 
5
8
  This repository now ships an Astro integration that turns any Cloudflare Worker-backed Astro app into a single-user ATProto Personal Data Server. Install the package (or link it locally), then add the integration to your `astro.config.mjs`:
@@ -111,15 +114,15 @@ This project uses Drizzle Kit for database schema management and migrations.
111
114
  ### Migration Workflow
112
115
 
113
116
  1. **Modify Schema**: Edit [`src/db/schema.ts`](src/db/schema.ts:1) to add/modify tables or indexes
114
- 2. **Generate Migration**: Run `bun run db:generate` to create a new migration file in `drizzle/`
115
- 3. **Review Migration**: Check the generated SQL in `drizzle/XXXX_*.sql`
117
+ 2. **Generate Migration**: Run `bun run db:generate` to create a new migration file in `migrations/`
118
+ 3. **Review Migration**: Check the generated SQL in `migrations/XXXX_*.sql`
116
119
  4. **Apply Locally**: Run `bun run db:apply:local` to apply to local D1 database
117
120
  5. **Apply to Production**: Run `wrangler d1 migrations apply pds --remote` after deployment
118
121
 
119
122
  ### Migration Versioning
120
123
 
121
124
  - Migrations are versioned sequentially (0000, 0001, 0002, etc.)
122
- - Each migration is tracked in `drizzle/meta/_journal.json`
125
+ - Each migration is tracked in `migrations/meta/_journal.json`
123
126
  - Migrations are applied in order and cannot be skipped
124
127
  - Applied migrations are recorded in D1's `_cf_KV` table
125
128
 
@@ -181,7 +184,7 @@ Set these secrets for each environment using `wrangler secret put <NAME> --env <
181
184
  | `USER_PASSWORD` | Login password | Strong password |
182
185
  | `ACCESS_TOKEN` | JWT access token secret | Random 32+ char string |
183
186
  | `REFRESH_TOKEN` | JWT refresh token secret | Random 32+ char string |
184
- | `REPO_SIGNING_KEY` | Ed25519 signing key (base64) | From `generate-signing-key.ts` |
187
+ | `REPO_SIGNING_KEY` | secp256k1 signing key (hex or base64 32 bytes). Used for commits and service-auth | From `scripts/setup-secrets.ts` |
185
188
 
186
189
  **Generate secrets:**
187
190
  ```bash
@@ -189,9 +192,6 @@ Set these secrets for each environment using `wrangler secret put <NAME> --env <
189
192
  # Generates all required secrets and prints wrangler commands
190
193
  bun run scripts/setup-secrets.ts --env production --did did:web:example.com --handle user.example.com
191
194
 
192
- # Or generate only the repo signing key
193
- bun run scripts/generate-signing-key.ts
194
-
195
195
  # After generation, set secrets (example for production)
196
196
  wrangler secret put PDS_DID --env production
197
197
  wrangler secret put PDS_HANDLE --env production
@@ -199,8 +199,6 @@ wrangler secret put USER_PASSWORD --env production
199
199
  wrangler secret put ACCESS_TOKEN --env production
200
200
  wrangler secret put REFRESH_TOKEN --env production
201
201
  wrangler secret put REPO_SIGNING_KEY --env production
202
- # Optional: publish public key for DID document
203
- wrangler secret put REPO_SIGNING_KEY_PUBLIC --env production
204
202
  ```
205
203
 
206
204
  ### Using Cloudflare Secret Store (optional)
@@ -333,7 +331,7 @@ This PDS now implements full AT Protocol core compliance with:
333
331
  - ✅ D1 blockstore integration
334
332
 
335
333
  ### Signed Commits
336
- - ✅ Ed25519 cryptographic signatures
334
+ - ✅ secp256k1 cryptographic signatures
337
335
  - ✅ AT Protocol v3 commit structure
338
336
  - ✅ TID-based revisions
339
337
  - ✅ Commit chain tracking
@@ -358,31 +356,26 @@ This PDS now implements full AT Protocol core compliance with:
358
356
  # Recommended: bootstrap all secrets (prints wrangler commands)
359
357
  bun run scripts/setup-secrets.ts --env production --did did:web:example.com --handle user.example.com
360
358
 
361
- # Alternative: generate only the repo signing key
362
- bun run scripts/generate-signing-key.ts
359
+ # Alternatively, supply your own secp256k1 key (32‑byte hex/base64)
363
360
  ```
364
361
 
365
362
  ### 2. Configure Secrets
366
363
 
367
364
  **Required Secrets:**
368
365
  ```bash
369
- wrangler secret put REPO_SIGNING_KEY # From step 1
370
- wrangler secret put PDS_DID # Your DID
371
- wrangler secret put PDS_HANDLE # Your handle
372
- wrangler secret put USER_PASSWORD # Login password
366
+ wrangler secret put REPO_SIGNING_KEY # secp256k1 (from setup-secrets)
367
+ wrangler secret put PDS_DID # Your DID
368
+ wrangler secret put PDS_HANDLE # Your handle
369
+ wrangler secret put USER_PASSWORD # Login password
373
370
  wrangler secret put REFRESH_TOKEN
374
371
  wrangler secret put REFRESH_TOKEN_SECRET
375
- # Optional: publish raw public key for DID document
376
- wrangler secret put REPO_SIGNING_KEY_PUBLIC
377
372
  ```
378
373
 
379
374
  **For Local Development (.dev.vars):**
380
375
  ```env
381
376
  PDS_DID=did:plc:your-did-here
382
377
  PDS_HANDLE=your-handle.bsky.social
383
- REPO_SIGNING_KEY=<base64-key-from-step-1>
384
- # Optional: publish raw 32-byte public key in did.json
385
- REPO_SIGNING_KEY_PUBLIC=<base64-raw-public-key>
378
+ REPO_SIGNING_KEY=<hex-secp256k1-private-key>
386
379
  USER_PASSWORD=your-password
387
380
  REFRESH_TOKEN=your-access-secret
388
381
  REFRESH_TOKEN_SECRET=your-refresh-secret
@@ -458,7 +451,7 @@ curl "http://localhost:4321/xrpc/com.atproto.repo.listRecords?repo=did:example:s
458
451
  - [`PROGRESS.md`](PROGRESS.md) - Development progress notes
459
452
 
460
453
  Repo signing key (REQUIRED)
461
- - Generate an Ed25519 signing key: `bun run scripts/generate-signing-key.ts`
454
+
462
455
  - Store as `REPO_SIGNING_KEY` secret (base64-encoded private key)
463
456
 
464
457
  ## P1 Implementation - Production Readiness 🚀
@@ -470,7 +463,7 @@ This PDS now includes production-grade features for security, observability, and
470
463
  - ✅ **Token rotation** on every refresh
471
464
  - ✅ **Automatic token cleanup** (lazy cleanup on 1% of requests)
472
465
  - ✅ **Account lockout** after 5 failed login attempts (15-minute lockout)
473
- - ✅ **EdDSA (Ed25519) JWT signing** support (in addition to HS256)
466
+
474
467
  - ✅ **Proper JWT claims**: `sub`, `aud`, `iat`, `exp`, `jti`, `scope`
475
468
  - ✅ **Production CORS validation** (no wildcard in production)
476
469
 
@@ -490,15 +483,11 @@ This PDS now includes production-grade features for security, observability, and
490
483
 
491
484
  **JWT Configuration:**
492
485
  ```bash
493
- # Algorithm selection (HS256 or EdDSA)
486
+ # Service-auth uses ES256K (secp256k1) exclusively
494
487
  PDS_HOSTNAME=your-pds.example.com
495
488
  PDS_ACCESS_TTL_SEC=3600 # 1 hour
496
489
  PDS_REFRESH_TTL_SEC=2592000 # 30 days
497
- JWT_ALGORITHM=HS256 # or EdDSA
498
-
499
- # For EdDSA (optional)
500
- JWT_ED25519_PRIVATE_KEY=<base64-encoded-key>
501
- JWT_ED25519_PUBLIC_KEY=<base64-encoded-key>
490
+ # No JWT_ALGORITHM flag; ES256K is always used for AppView service tokens
502
491
  ```
503
492
 
504
493
  **CORS Configuration:**
@@ -560,7 +549,7 @@ Returns `503` if any dependency is unhealthy.
560
549
 
561
550
  1. **Never use wildcard CORS in production** - Set explicit origins in `PDS_CORS_ORIGIN`
562
551
  2. **Use strong secrets** - Generate cryptographically secure values for all secrets
563
- 3. **Enable EdDSA signing** - More secure than HS256 for production
552
+ 3. **Use ES256K (secp256k1) signing**
564
553
  4. **Monitor failed login attempts** - Check logs for suspicious activity
565
554
  5. **Set appropriate token TTLs** - Balance security and user experience
566
555
 
package/index.js CHANGED
@@ -36,6 +36,7 @@ const CORE_ROUTES = [
36
36
  { pattern: '/xrpc/com.atproto.sync.getLatestCommit', entrypoint: './src/pages/xrpc/com.atproto.sync.getLatestCommit.ts' },
37
37
  { pattern: '/xrpc/com.atproto.sync.getRecord', entrypoint: './src/pages/xrpc/com.atproto.sync.getRecord.ts' },
38
38
  { pattern: '/xrpc/com.atproto.sync.getRepo', entrypoint: './src/pages/xrpc/com.atproto.sync.getRepo.ts' },
39
+ { pattern: '/xrpc/com.atproto.sync.getRepoStatus', entrypoint: './src/pages/xrpc/com.atproto.sync.getRepoStatus.ts' },
39
40
  { pattern: '/xrpc/com.atproto.sync.getRepo.json', entrypoint: './src/pages/xrpc/com.atproto.sync.getRepo.json.ts' },
40
41
  { pattern: '/xrpc/com.atproto.sync.getRepo.range', entrypoint: './src/pages/xrpc/com.atproto.sync.getRepo.range.ts' },
41
42
  { pattern: '/xrpc/com.atproto.sync.listBlobs', entrypoint: './src/pages/xrpc/com.atproto.sync.listBlobs.ts' },
@@ -43,22 +44,14 @@ const CORE_ROUTES = [
43
44
  // Additional atproto endpoints
44
45
  { pattern: '/xrpc/com.atproto.identity.signPlcOperation', entrypoint: './src/pages/xrpc/com.atproto.identity.signPlcOperation.ts' },
45
46
  { pattern: '/xrpc/com.atproto.server.getServiceAuth', entrypoint: './src/pages/xrpc/com.atproto.server.getServiceAuth.ts' },
46
- // AppView proxy endpoints (bsky)
47
- { pattern: '/xrpc/app.bsky.actor.getProfile', entrypoint: './src/pages/xrpc/app.bsky.actor.getProfile.ts' },
48
- { pattern: '/xrpc/app.bsky.actor.getProfiles', entrypoint: './src/pages/xrpc/app.bsky.actor.getProfiles.ts' },
47
+ // AppView proxy endpoints (bsky) — local-only where required
49
48
  { pattern: '/xrpc/app.bsky.actor.getPreferences', entrypoint: './src/pages/xrpc/app.bsky.actor.getPreferences.ts' },
50
49
  { pattern: '/xrpc/app.bsky.actor.putPreferences', entrypoint: './src/pages/xrpc/app.bsky.actor.putPreferences.ts' },
51
- { pattern: '/xrpc/app.bsky.feed.getAuthorFeed', entrypoint: './src/pages/xrpc/app.bsky.feed.getAuthorFeed.ts' },
52
- { pattern: '/xrpc/app.bsky.feed.getPostThread', entrypoint: './src/pages/xrpc/app.bsky.feed.getPostThread.ts' },
53
- { pattern: '/xrpc/app.bsky.feed.getPosts', entrypoint: './src/pages/xrpc/app.bsky.feed.getPosts.ts' },
54
- { pattern: '/xrpc/app.bsky.feed.getTimeline', entrypoint: './src/pages/xrpc/app.bsky.feed.getTimeline.ts' },
55
- { pattern: '/xrpc/app.bsky.graph.getFollowers', entrypoint: './src/pages/xrpc/app.bsky.graph.getFollowers.ts' },
56
- { pattern: '/xrpc/app.bsky.graph.getFollows', entrypoint: './src/pages/xrpc/app.bsky.graph.getFollows.ts' },
57
50
  { pattern: '/xrpc/app.bsky.labeler.getServices', entrypoint: './src/pages/xrpc/app.bsky.labeler.getServices.ts' },
58
- { pattern: '/xrpc/app.bsky.notification.getUnreadCount', entrypoint: './src/pages/xrpc/app.bsky.notification.getUnreadCount.ts' },
59
- { pattern: '/xrpc/app.bsky.notification.listNotifications', entrypoint: './src/pages/xrpc/app.bsky.notification.listNotifications.ts' },
60
51
  { pattern: '/xrpc/app.bsky.unspecced.getAgeAssuranceState', entrypoint: './src/pages/xrpc/app.bsky.unspecced.getAgeAssuranceState.ts' },
61
52
  { pattern: '/xrpc/app.bsky.unspecced.getConfig', entrypoint: './src/pages/xrpc/app.bsky.unspecced.getConfig.ts' },
53
+ // Catchall for proxied XRPC endpoints (app.bsky.*, chat.bsky.*, tools.ozone.*)
54
+ { pattern: '/xrpc/[...nsid]', entrypoint: './src/pages/xrpc/[...nsid].ts' },
62
55
  // Chat endpoints (proxied)
63
56
  { pattern: '/xrpc/chat.bsky.convo.getLog', entrypoint: './src/pages/xrpc/chat.bsky.convo.getLog.ts' },
64
57
  { pattern: '/xrpc/chat.bsky.convo.listConvos', entrypoint: './src/pages/xrpc/chat.bsky.convo.listConvos.ts' },
@@ -75,6 +68,7 @@ const DEBUG_ROUTES = [
75
68
  { pattern: '/debug/db/commits', entrypoint: './src/pages/debug/db/commits.ts' },
76
69
  { pattern: '/debug/gc/blobs', entrypoint: './src/pages/debug/gc/blobs.ts' },
77
70
  { pattern: '/debug/record', entrypoint: './src/pages/debug/record.ts' },
71
+ { pattern: '/debug/sequencer', entrypoint: './src/pages/debug/sequencer.ts' },
78
72
  ];
79
73
 
80
74
  const pkgRoot = new URL('.', import.meta.url);
@@ -133,23 +127,35 @@ export default function alteran(options = {}) {
133
127
  enforce: 'post',
134
128
  apply: 'build',
135
129
  transform(code, id) {
136
- if (!id.includes('@astrojs-ssr-virtual-entry')) return null;
137
- if (!code.includes('const _exports = createExports')) return null;
138
- if (code.includes("const Sequencer = _exports['Sequencer'];")) return null;
139
-
140
- const replacedInit = code.replace(
141
- 'const __astrojsSsrVirtualEntry = _exports.default;',
142
- "const Sequencer = _exports['Sequencer'];\nconst __astrojsSsrVirtualEntry = _exports.default;"
143
- );
144
-
145
- if (replacedInit === code) return null;
146
-
147
- const replacedExport = replacedInit.replace(
148
- 'export { __astrojsSsrVirtualEntry as default, pageMap };',
149
- 'export { Sequencer, __astrojsSsrVirtualEntry as default, pageMap };'
150
- );
151
-
152
- return { code: replacedExport, map: null };
130
+ if (code.includes("_exports['Sequencer']") || code.includes('_exports.Sequencer')) {
131
+ return null;
132
+ }
133
+
134
+ // Astro 6: virtual:astro:legacy-ssr-entry — the resolved id is `\0virtual:astro:legacy-ssr-entry`.
135
+ // The body is a thin wrapper that re-exports `_exports.default`; we tack on a named Sequencer export.
136
+ if (id.includes('virtual:astro:legacy-ssr-entry')) {
137
+ return {
138
+ code: `${code}\nexport const Sequencer = _exports['Sequencer'];\n`,
139
+ map: null,
140
+ };
141
+ }
142
+
143
+ // Astro 5: @astrojs-ssr-virtual-entry the body assigns `_exports` and exports a default; patch both.
144
+ if (id.includes('@astrojs-ssr-virtual-entry')) {
145
+ if (!code.includes('const _exports = createExports')) return null;
146
+ const withSequencer = code.replace(
147
+ 'const __astrojsSsrVirtualEntry = _exports.default;',
148
+ "const Sequencer = _exports['Sequencer'];\nconst __astrojsSsrVirtualEntry = _exports.default;",
149
+ );
150
+ if (withSequencer === code) return null;
151
+ const reexported = withSequencer.replace(
152
+ 'export { __astrojsSsrVirtualEntry as default, pageMap };',
153
+ 'export { Sequencer, __astrojsSsrVirtualEntry as default, pageMap };',
154
+ );
155
+ return { code: reexported, map: null };
156
+ }
157
+
158
+ return null;
153
159
  },
154
160
  });
155
161
 
@@ -0,0 +1,26 @@
1
+ CREATE TABLE `account` (
2
+ `did` text PRIMARY KEY NOT NULL,
3
+ `handle` text NOT NULL,
4
+ `password_scrypt` text,
5
+ `email` text,
6
+ `created_at` integer NOT NULL,
7
+ `updated_at` integer NOT NULL
8
+ );
9
+ --> statement-breakpoint
10
+ CREATE UNIQUE INDEX `account_handle_unique` ON `account` (`handle`);--> statement-breakpoint
11
+ CREATE TABLE `refresh_token` (
12
+ `id` text PRIMARY KEY NOT NULL,
13
+ `did` text NOT NULL,
14
+ `expires_at` integer NOT NULL,
15
+ `app_password_name` text,
16
+ `next_id` text
17
+ );
18
+ --> statement-breakpoint
19
+ CREATE INDEX `refresh_token_did_idx` ON `refresh_token` (`did`);--> statement-breakpoint
20
+ CREATE TABLE `secret` (
21
+ `key` text PRIMARY KEY NOT NULL,
22
+ `value` text NOT NULL,
23
+ `updated_at` integer NOT NULL
24
+ );
25
+ --> statement-breakpoint
26
+ DROP TABLE `token_revocation`;
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `account_state` ADD `status` text;--> statement-breakpoint
2
+ ALTER TABLE `account_state` ADD `suspended_until` integer;