Your music, beautifully tracked. All yours. (coming soon) teal.fm
teal-fm atproto

Merge pull request #33 from teal-fm/pnpm-upgrade-part-2

PNPM upgrade part 2

authored by mmatt.net and committed by

GitHub 54e7a746 d5adebf1

+1059 -152
+2 -2
README.md
··· 9 9 To get started with this template, simply paste this command into your terminal: 10 10 11 11 ```bash 12 - bun install && bun install -g turbo && cp apps/aqua/.env.example apps/aqua/.env && 13 - bun run db:migrate 12 + pnpm install && pnpm install -g turbo && cp apps/aqua/.env.example apps/aqua/.env && 13 + pnpm run db:migrate 14 14 ``` 15 15 Running on a Mac may also require adding @libsql/darwin-x64 dependency 16 16
+6 -10
apps/aqua/package.json
··· 7 7 "dev": "tsx watch --clear-screen=false src/index.ts | pino-pretty", 8 8 "build": "tsup && cp -r public dist/", 9 9 "start": "node dist/index.cjs | pino-pretty", 10 - "lexgen": "lex gen-server ./src/lexicon ./lexicons/*", 11 10 "clean": "rimraf dist coverage", 12 - "check-types": "tsc --noEmit", 13 - "db:migrate": "drizzle-kit migrate", 14 - "db:seed": "drizzle-kit seed", 15 - "db:studio": "drizzle-kit studio" 11 + "check-types": "tsc --noEmit" 16 12 }, 17 13 "dependencies": { 18 14 "@atproto/api": "^0.13.15", ··· 22 18 "@atproto/oauth-client-node": "^0.2.1", 23 19 "@atproto/sync": "^0.1.5", 24 20 "@atproto/syntax": "^0.3.0", 25 - "@atproto/xrpc-server": "^0.6.4", 21 + "@atproto/xrpc-server": "^0.7.4", 26 22 "@braintree/sanitize-url": "^7.1.0", 23 + "drizzle-orm": "^0.38.3", 27 24 "@hono/node-server": "^1.13.7", 28 25 "@libsql/client": "^0.14.0", 29 26 "dotenv": "^16.4.5", 30 - "drizzle-orm": "^0.36.1", 31 27 "envalid": "^8.0.0", 32 28 "hono": "^4.6.9", 33 29 "jose": "^5.9.6", ··· 39 35 }, 40 36 "devDependencies": { 41 37 "@teal/tsconfig": "workspace:*", 42 - "@atproto/lex-cli": "^0.4.1", 38 + "@atproto/lex-cli": "^0.5.4", 43 39 "@types/node": "^20.17.6", 44 - "drizzle-kit": "^0.27.2", 45 - "pino-pretty": "^11.3.0", 40 + "drizzle-kit": "^0.30.1", 41 + "pino-pretty": "^13.0.0", 46 42 "rimraf": "^6.0.1", 47 43 "tsup": "^8.3.5", 48 44 "tsx": "^4.19.2",
-11
drizzle.config.ts
··· 1 - import { defineConfig } from "drizzle-kit"; 2 - 3 - export default defineConfig({ 4 - dialect: "sqlite", 5 - schema: "./packages/db/schema.ts", 6 - out: "./packages/db/.drizzle", 7 - casing: "snake_case", 8 - dbCredentials: { 9 - url: process.env.DATABASE_URL ?? "./db.sqlite", 10 - }, 11 - });
+5 -8
package.json
··· 8 8 "build": "pnpm turbo run build --filter='./packages/*' --filter='./apps/*'", 9 9 "typecheck": "pnpm -r exec tsc --noEmit", 10 10 "fix": "biome lint --apply . && biome format --write . && biome check . --apply", 11 - "lex:gen-server": "lex gen-server ./packages/lexicons/generated/server ./packages/lexicons/src/*", 12 - "lex:gen-api": "lex gen-api ./packages/lexicons/generated/api ./packages/lexicons/src/*", 13 - "lex:gen-md": "lex gen-md ./packages/lexicons/generated/md ./packages/lexicons/src/*", 14 - "db:studio": "drizzle-kit studio", 15 - "db:migrate": "drizzle-kit migrate", 16 - "db:seed": "drizzle-kit seed" 11 + "nuke": "rimraf node_modules */*/node_modules" 17 12 }, 18 13 "devDependencies": { 19 - "turbo": "^2.3.3", 20 - "biome": "^0.3.3" 14 + "@types/node": "^20.17.10", 15 + "biome": "^0.3.3", 16 + "rimraf": "^6.0.1", 17 + "turbo": "^2.3.3" 21 18 }, 22 19 "workspaces": [ 23 20 "apps/*",
+29
packages/db/.drizzle/0004_exotic_ironclad.sql
··· 1 + CREATE TABLE `follow` ( 2 + `follower` text PRIMARY KEY NOT NULL, 3 + `followed` text NOT NULL, 4 + `created_at` text NOT NULL 5 + ); 6 + --> statement-breakpoint 7 + CREATE TABLE `play` ( 8 + `uri` text PRIMARY KEY NOT NULL, 9 + `author_did` text NOT NULL, 10 + `created_at` text NOT NULL, 11 + `indexed_at` text NOT NULL, 12 + `track_name` text NOT NULL, 13 + `track_mb_id` text, 14 + `recording_mb_id` text, 15 + `duration` integer, 16 + `artist_name` text NOT NULL, 17 + `artist_mb_ids` text, 18 + `release_name` text, 19 + `release_mb_id` text, 20 + `isrc` text, 21 + `origin_url` text, 22 + `music_service_base_domain` text, 23 + `submission_client_agent` text, 24 + `played_time` text 25 + ); 26 + --> statement-breakpoint 27 + ALTER TABLE `teal_user` ADD `avatar` text NOT NULL;--> statement-breakpoint 28 + ALTER TABLE `teal_user` ADD `bio` text;--> statement-breakpoint 29 + ALTER TABLE `teal_user` DROP COLUMN `email`;
+12
packages/db/.drizzle/0005_conscious_johnny_blaze.sql
··· 1 + PRAGMA foreign_keys=OFF;--> statement-breakpoint 2 + CREATE TABLE `__new_follow` ( 3 + `rel_id` text PRIMARY KEY NOT NULL, 4 + `follower` text NOT NULL, 5 + `followed` text NOT NULL, 6 + `created_at` text NOT NULL 7 + ); 8 + --> statement-breakpoint 9 + INSERT INTO `__new_follow`("rel_id", "follower", "followed", "created_at") SELECT '0', "follower", "followed", "created_at" FROM `follow`;--> statement-breakpoint 10 + DROP TABLE `follow`;--> statement-breakpoint 11 + ALTER TABLE `__new_follow` RENAME TO `follow`;--> statement-breakpoint 12 + PRAGMA foreign_keys=ON;
+347
packages/db/.drizzle/meta/0004_snapshot.json
··· 1 + { 2 + "version": "6", 3 + "dialect": "sqlite", 4 + "id": "639ec806-61a1-448d-a922-1935bf8f6cf3", 5 + "prevId": "7710000b-44fd-4d23-a768-0117f22926c3", 6 + "tables": { 7 + "atp_session": { 8 + "name": "atp_session", 9 + "columns": { 10 + "key": { 11 + "name": "key", 12 + "type": "text", 13 + "primaryKey": true, 14 + "notNull": true, 15 + "autoincrement": false 16 + }, 17 + "session": { 18 + "name": "session", 19 + "type": "text", 20 + "primaryKey": false, 21 + "notNull": true, 22 + "autoincrement": false 23 + } 24 + }, 25 + "indexes": {}, 26 + "foreignKeys": {}, 27 + "compositePrimaryKeys": {}, 28 + "uniqueConstraints": {}, 29 + "checkConstraints": {} 30 + }, 31 + "auth_state": { 32 + "name": "auth_state", 33 + "columns": { 34 + "key": { 35 + "name": "key", 36 + "type": "text", 37 + "primaryKey": true, 38 + "notNull": true, 39 + "autoincrement": false 40 + }, 41 + "state": { 42 + "name": "state", 43 + "type": "text", 44 + "primaryKey": false, 45 + "notNull": true, 46 + "autoincrement": false 47 + } 48 + }, 49 + "indexes": {}, 50 + "foreignKeys": {}, 51 + "compositePrimaryKeys": {}, 52 + "uniqueConstraints": {}, 53 + "checkConstraints": {} 54 + }, 55 + "follow": { 56 + "name": "follow", 57 + "columns": { 58 + "follower": { 59 + "name": "follower", 60 + "type": "text", 61 + "primaryKey": true, 62 + "notNull": true, 63 + "autoincrement": false 64 + }, 65 + "followed": { 66 + "name": "followed", 67 + "type": "text", 68 + "primaryKey": true, 69 + "notNull": true, 70 + "autoincrement": false 71 + }, 72 + "created_at": { 73 + "name": "created_at", 74 + "type": "text", 75 + "primaryKey": false, 76 + "notNull": true, 77 + "autoincrement": false 78 + } 79 + }, 80 + "indexes": {}, 81 + "foreignKeys": {}, 82 + "compositePrimaryKeys": {}, 83 + "uniqueConstraints": {}, 84 + "checkConstraints": {} 85 + }, 86 + "play": { 87 + "name": "play", 88 + "columns": { 89 + "uri": { 90 + "name": "uri", 91 + "type": "text", 92 + "primaryKey": true, 93 + "notNull": true, 94 + "autoincrement": false 95 + }, 96 + "author_did": { 97 + "name": "author_did", 98 + "type": "text", 99 + "primaryKey": false, 100 + "notNull": true, 101 + "autoincrement": false 102 + }, 103 + "created_at": { 104 + "name": "created_at", 105 + "type": "text", 106 + "primaryKey": false, 107 + "notNull": true, 108 + "autoincrement": false 109 + }, 110 + "indexed_at": { 111 + "name": "indexed_at", 112 + "type": "text", 113 + "primaryKey": false, 114 + "notNull": true, 115 + "autoincrement": false 116 + }, 117 + "track_name": { 118 + "name": "track_name", 119 + "type": "text", 120 + "primaryKey": false, 121 + "notNull": true, 122 + "autoincrement": false 123 + }, 124 + "track_mb_id": { 125 + "name": "track_mb_id", 126 + "type": "text", 127 + "primaryKey": false, 128 + "notNull": false, 129 + "autoincrement": false 130 + }, 131 + "recording_mb_id": { 132 + "name": "recording_mb_id", 133 + "type": "text", 134 + "primaryKey": false, 135 + "notNull": false, 136 + "autoincrement": false 137 + }, 138 + "duration": { 139 + "name": "duration", 140 + "type": "integer", 141 + "primaryKey": false, 142 + "notNull": false, 143 + "autoincrement": false 144 + }, 145 + "artist_name": { 146 + "name": "artist_name", 147 + "type": "text", 148 + "primaryKey": false, 149 + "notNull": true, 150 + "autoincrement": false 151 + }, 152 + "artist_mb_ids": { 153 + "name": "artist_mb_ids", 154 + "type": "text", 155 + "primaryKey": false, 156 + "notNull": false, 157 + "autoincrement": false 158 + }, 159 + "release_name": { 160 + "name": "release_name", 161 + "type": "text", 162 + "primaryKey": false, 163 + "notNull": false, 164 + "autoincrement": false 165 + }, 166 + "release_mb_id": { 167 + "name": "release_mb_id", 168 + "type": "text", 169 + "primaryKey": false, 170 + "notNull": false, 171 + "autoincrement": false 172 + }, 173 + "isrc": { 174 + "name": "isrc", 175 + "type": "text", 176 + "primaryKey": false, 177 + "notNull": false, 178 + "autoincrement": false 179 + }, 180 + "origin_url": { 181 + "name": "origin_url", 182 + "type": "text", 183 + "primaryKey": false, 184 + "notNull": false, 185 + "autoincrement": false 186 + }, 187 + "music_service_base_domain": { 188 + "name": "music_service_base_domain", 189 + "type": "text", 190 + "primaryKey": false, 191 + "notNull": false, 192 + "autoincrement": false 193 + }, 194 + "submission_client_agent": { 195 + "name": "submission_client_agent", 196 + "type": "text", 197 + "primaryKey": false, 198 + "notNull": false, 199 + "autoincrement": false 200 + }, 201 + "played_time": { 202 + "name": "played_time", 203 + "type": "text", 204 + "primaryKey": false, 205 + "notNull": false, 206 + "autoincrement": false 207 + } 208 + }, 209 + "indexes": {}, 210 + "foreignKeys": {}, 211 + "compositePrimaryKeys": {}, 212 + "uniqueConstraints": {}, 213 + "checkConstraints": {} 214 + }, 215 + "status": { 216 + "name": "status", 217 + "columns": { 218 + "uri": { 219 + "name": "uri", 220 + "type": "text", 221 + "primaryKey": true, 222 + "notNull": true, 223 + "autoincrement": false 224 + }, 225 + "author_did": { 226 + "name": "author_did", 227 + "type": "text", 228 + "primaryKey": false, 229 + "notNull": true, 230 + "autoincrement": false 231 + }, 232 + "status": { 233 + "name": "status", 234 + "type": "text", 235 + "primaryKey": false, 236 + "notNull": true, 237 + "autoincrement": false 238 + }, 239 + "created_at": { 240 + "name": "created_at", 241 + "type": "text", 242 + "primaryKey": false, 243 + "notNull": true, 244 + "autoincrement": false 245 + }, 246 + "indexed_at": { 247 + "name": "indexed_at", 248 + "type": "text", 249 + "primaryKey": false, 250 + "notNull": true, 251 + "autoincrement": false 252 + } 253 + }, 254 + "indexes": {}, 255 + "foreignKeys": {}, 256 + "compositePrimaryKeys": {}, 257 + "uniqueConstraints": {}, 258 + "checkConstraints": {} 259 + }, 260 + "teal_session": { 261 + "name": "teal_session", 262 + "columns": { 263 + "key": { 264 + "name": "key", 265 + "type": "text", 266 + "primaryKey": true, 267 + "notNull": true, 268 + "autoincrement": false 269 + }, 270 + "session": { 271 + "name": "session", 272 + "type": "text", 273 + "primaryKey": false, 274 + "notNull": true, 275 + "autoincrement": false 276 + }, 277 + "provider": { 278 + "name": "provider", 279 + "type": "text", 280 + "primaryKey": false, 281 + "notNull": true, 282 + "autoincrement": false 283 + } 284 + }, 285 + "indexes": {}, 286 + "foreignKeys": {}, 287 + "compositePrimaryKeys": {}, 288 + "uniqueConstraints": {}, 289 + "checkConstraints": {} 290 + }, 291 + "teal_user": { 292 + "name": "teal_user", 293 + "columns": { 294 + "did": { 295 + "name": "did", 296 + "type": "text", 297 + "primaryKey": true, 298 + "notNull": true, 299 + "autoincrement": false 300 + }, 301 + "handle": { 302 + "name": "handle", 303 + "type": "text", 304 + "primaryKey": false, 305 + "notNull": true, 306 + "autoincrement": false 307 + }, 308 + "avatar": { 309 + "name": "avatar", 310 + "type": "text", 311 + "primaryKey": false, 312 + "notNull": true, 313 + "autoincrement": false 314 + }, 315 + "bio": { 316 + "name": "bio", 317 + "type": "text", 318 + "primaryKey": false, 319 + "notNull": false, 320 + "autoincrement": false 321 + }, 322 + "created_at": { 323 + "name": "created_at", 324 + "type": "text", 325 + "primaryKey": false, 326 + "notNull": true, 327 + "autoincrement": false 328 + } 329 + }, 330 + "indexes": {}, 331 + "foreignKeys": {}, 332 + "compositePrimaryKeys": {}, 333 + "uniqueConstraints": {}, 334 + "checkConstraints": {} 335 + } 336 + }, 337 + "views": {}, 338 + "enums": {}, 339 + "_meta": { 340 + "schemas": {}, 341 + "tables": {}, 342 + "columns": {} 343 + }, 344 + "internal": { 345 + "indexes": {} 346 + } 347 + }
+354
packages/db/.drizzle/meta/0005_snapshot.json
··· 1 + { 2 + "version": "6", 3 + "dialect": "sqlite", 4 + "id": "42a94e7a-c4c2-4bd5-92d9-ba8a829c0704", 5 + "prevId": "639ec806-61a1-448d-a922-1935bf8f6cf3", 6 + "tables": { 7 + "atp_session": { 8 + "name": "atp_session", 9 + "columns": { 10 + "key": { 11 + "name": "key", 12 + "type": "text", 13 + "primaryKey": true, 14 + "notNull": true, 15 + "autoincrement": false 16 + }, 17 + "session": { 18 + "name": "session", 19 + "type": "text", 20 + "primaryKey": false, 21 + "notNull": true, 22 + "autoincrement": false 23 + } 24 + }, 25 + "indexes": {}, 26 + "foreignKeys": {}, 27 + "compositePrimaryKeys": {}, 28 + "uniqueConstraints": {}, 29 + "checkConstraints": {} 30 + }, 31 + "auth_state": { 32 + "name": "auth_state", 33 + "columns": { 34 + "key": { 35 + "name": "key", 36 + "type": "text", 37 + "primaryKey": true, 38 + "notNull": true, 39 + "autoincrement": false 40 + }, 41 + "state": { 42 + "name": "state", 43 + "type": "text", 44 + "primaryKey": false, 45 + "notNull": true, 46 + "autoincrement": false 47 + } 48 + }, 49 + "indexes": {}, 50 + "foreignKeys": {}, 51 + "compositePrimaryKeys": {}, 52 + "uniqueConstraints": {}, 53 + "checkConstraints": {} 54 + }, 55 + "follow": { 56 + "name": "follow", 57 + "columns": { 58 + "rel_id": { 59 + "name": "rel_id", 60 + "type": "text", 61 + "primaryKey": true, 62 + "notNull": true, 63 + "autoincrement": false 64 + }, 65 + "follower": { 66 + "name": "follower", 67 + "type": "text", 68 + "primaryKey": false, 69 + "notNull": true, 70 + "autoincrement": false 71 + }, 72 + "followed": { 73 + "name": "followed", 74 + "type": "text", 75 + "primaryKey": false, 76 + "notNull": true, 77 + "autoincrement": false 78 + }, 79 + "created_at": { 80 + "name": "created_at", 81 + "type": "text", 82 + "primaryKey": false, 83 + "notNull": true, 84 + "autoincrement": false 85 + } 86 + }, 87 + "indexes": {}, 88 + "foreignKeys": {}, 89 + "compositePrimaryKeys": {}, 90 + "uniqueConstraints": {}, 91 + "checkConstraints": {} 92 + }, 93 + "play": { 94 + "name": "play", 95 + "columns": { 96 + "uri": { 97 + "name": "uri", 98 + "type": "text", 99 + "primaryKey": true, 100 + "notNull": true, 101 + "autoincrement": false 102 + }, 103 + "author_did": { 104 + "name": "author_did", 105 + "type": "text", 106 + "primaryKey": false, 107 + "notNull": true, 108 + "autoincrement": false 109 + }, 110 + "created_at": { 111 + "name": "created_at", 112 + "type": "text", 113 + "primaryKey": false, 114 + "notNull": true, 115 + "autoincrement": false 116 + }, 117 + "indexed_at": { 118 + "name": "indexed_at", 119 + "type": "text", 120 + "primaryKey": false, 121 + "notNull": true, 122 + "autoincrement": false 123 + }, 124 + "track_name": { 125 + "name": "track_name", 126 + "type": "text", 127 + "primaryKey": false, 128 + "notNull": true, 129 + "autoincrement": false 130 + }, 131 + "track_mb_id": { 132 + "name": "track_mb_id", 133 + "type": "text", 134 + "primaryKey": false, 135 + "notNull": false, 136 + "autoincrement": false 137 + }, 138 + "recording_mb_id": { 139 + "name": "recording_mb_id", 140 + "type": "text", 141 + "primaryKey": false, 142 + "notNull": false, 143 + "autoincrement": false 144 + }, 145 + "duration": { 146 + "name": "duration", 147 + "type": "integer", 148 + "primaryKey": false, 149 + "notNull": false, 150 + "autoincrement": false 151 + }, 152 + "artist_name": { 153 + "name": "artist_name", 154 + "type": "text", 155 + "primaryKey": false, 156 + "notNull": true, 157 + "autoincrement": false 158 + }, 159 + "artist_mb_ids": { 160 + "name": "artist_mb_ids", 161 + "type": "text", 162 + "primaryKey": false, 163 + "notNull": false, 164 + "autoincrement": false 165 + }, 166 + "release_name": { 167 + "name": "release_name", 168 + "type": "text", 169 + "primaryKey": false, 170 + "notNull": false, 171 + "autoincrement": false 172 + }, 173 + "release_mb_id": { 174 + "name": "release_mb_id", 175 + "type": "text", 176 + "primaryKey": false, 177 + "notNull": false, 178 + "autoincrement": false 179 + }, 180 + "isrc": { 181 + "name": "isrc", 182 + "type": "text", 183 + "primaryKey": false, 184 + "notNull": false, 185 + "autoincrement": false 186 + }, 187 + "origin_url": { 188 + "name": "origin_url", 189 + "type": "text", 190 + "primaryKey": false, 191 + "notNull": false, 192 + "autoincrement": false 193 + }, 194 + "music_service_base_domain": { 195 + "name": "music_service_base_domain", 196 + "type": "text", 197 + "primaryKey": false, 198 + "notNull": false, 199 + "autoincrement": false 200 + }, 201 + "submission_client_agent": { 202 + "name": "submission_client_agent", 203 + "type": "text", 204 + "primaryKey": false, 205 + "notNull": false, 206 + "autoincrement": false 207 + }, 208 + "played_time": { 209 + "name": "played_time", 210 + "type": "text", 211 + "primaryKey": false, 212 + "notNull": false, 213 + "autoincrement": false 214 + } 215 + }, 216 + "indexes": {}, 217 + "foreignKeys": {}, 218 + "compositePrimaryKeys": {}, 219 + "uniqueConstraints": {}, 220 + "checkConstraints": {} 221 + }, 222 + "status": { 223 + "name": "status", 224 + "columns": { 225 + "uri": { 226 + "name": "uri", 227 + "type": "text", 228 + "primaryKey": true, 229 + "notNull": true, 230 + "autoincrement": false 231 + }, 232 + "author_did": { 233 + "name": "author_did", 234 + "type": "text", 235 + "primaryKey": false, 236 + "notNull": true, 237 + "autoincrement": false 238 + }, 239 + "status": { 240 + "name": "status", 241 + "type": "text", 242 + "primaryKey": false, 243 + "notNull": true, 244 + "autoincrement": false 245 + }, 246 + "created_at": { 247 + "name": "created_at", 248 + "type": "text", 249 + "primaryKey": false, 250 + "notNull": true, 251 + "autoincrement": false 252 + }, 253 + "indexed_at": { 254 + "name": "indexed_at", 255 + "type": "text", 256 + "primaryKey": false, 257 + "notNull": true, 258 + "autoincrement": false 259 + } 260 + }, 261 + "indexes": {}, 262 + "foreignKeys": {}, 263 + "compositePrimaryKeys": {}, 264 + "uniqueConstraints": {}, 265 + "checkConstraints": {} 266 + }, 267 + "teal_session": { 268 + "name": "teal_session", 269 + "columns": { 270 + "key": { 271 + "name": "key", 272 + "type": "text", 273 + "primaryKey": true, 274 + "notNull": true, 275 + "autoincrement": false 276 + }, 277 + "session": { 278 + "name": "session", 279 + "type": "text", 280 + "primaryKey": false, 281 + "notNull": true, 282 + "autoincrement": false 283 + }, 284 + "provider": { 285 + "name": "provider", 286 + "type": "text", 287 + "primaryKey": false, 288 + "notNull": true, 289 + "autoincrement": false 290 + } 291 + }, 292 + "indexes": {}, 293 + "foreignKeys": {}, 294 + "compositePrimaryKeys": {}, 295 + "uniqueConstraints": {}, 296 + "checkConstraints": {} 297 + }, 298 + "teal_user": { 299 + "name": "teal_user", 300 + "columns": { 301 + "did": { 302 + "name": "did", 303 + "type": "text", 304 + "primaryKey": true, 305 + "notNull": true, 306 + "autoincrement": false 307 + }, 308 + "handle": { 309 + "name": "handle", 310 + "type": "text", 311 + "primaryKey": false, 312 + "notNull": true, 313 + "autoincrement": false 314 + }, 315 + "avatar": { 316 + "name": "avatar", 317 + "type": "text", 318 + "primaryKey": false, 319 + "notNull": true, 320 + "autoincrement": false 321 + }, 322 + "bio": { 323 + "name": "bio", 324 + "type": "text", 325 + "primaryKey": false, 326 + "notNull": false, 327 + "autoincrement": false 328 + }, 329 + "created_at": { 330 + "name": "created_at", 331 + "type": "text", 332 + "primaryKey": false, 333 + "notNull": true, 334 + "autoincrement": false 335 + } 336 + }, 337 + "indexes": {}, 338 + "foreignKeys": {}, 339 + "compositePrimaryKeys": {}, 340 + "uniqueConstraints": {}, 341 + "checkConstraints": {} 342 + } 343 + }, 344 + "views": {}, 345 + "enums": {}, 346 + "_meta": { 347 + "schemas": {}, 348 + "tables": {}, 349 + "columns": {} 350 + }, 351 + "internal": { 352 + "indexes": {} 353 + } 354 + }
+14
packages/db/.drizzle/meta/_journal.json
··· 29 29 "when": 1731093709171, 30 30 "tag": "0003_sharp_medusa", 31 31 "breakpoints": true 32 + }, 33 + { 34 + "idx": 4, 35 + "version": "6", 36 + "when": 1735101894454, 37 + "tag": "0004_exotic_ironclad", 38 + "breakpoints": true 39 + }, 40 + { 41 + "idx": 5, 42 + "version": "6", 43 + "when": 1735497040757, 44 + "tag": "0005_conscious_johnny_blaze", 45 + "breakpoints": true 32 46 } 33 47 ] 34 48 }
+10 -8
packages/db/connect.ts
··· 1 1 import { drizzle } from "drizzle-orm/libsql"; 2 - import * as schema from "@teal/db/schema"; 2 + import { createClient } from "@libsql/client"; 3 + import * as schema from "./schema"; 3 4 import process from "node:process"; 4 5 import path from "node:path"; 5 6 6 - console.log("Loading SQLite file at", path.join(process.cwd(), "./db.sqlite")); 7 + console.log("Loading SQLite file at", path.join(process.cwd(), "./../../db.sqlite")); 7 8 8 - export const db = drizzle({ 9 - connection: 10 - // default is in project root / db.sqlite 9 + const client = createClient({ 10 + url: 11 11 process.env.DATABASE_URL ?? 12 - "file:" + path.join(process.cwd(), "./db.sqlite"), 13 - // doesn't seem to work? 14 - //casing: "snake_case", 12 + "file:" + path.join(process.cwd(), "./../../db.sqlite"), 13 + }); 14 + 15 + export const db = drizzle(client, { 15 16 schema: schema, 16 17 }); 17 18 19 + // If you need to export the type: 18 20 export type Database = typeof db;
+11
packages/db/drizzle.config.ts
··· 1 + import { defineConfig } from "drizzle-kit"; 2 + 3 + export default defineConfig({ 4 + dialect: "sqlite", 5 + schema: "./schema.ts", 6 + out: "./.drizzle", 7 + casing: "snake_case", 8 + dbCredentials: { 9 + url: process.env.DATABASE_URL ?? "./../../db.sqlite", 10 + }, 11 + });
+3
packages/db/index.ts
··· 1 + // barrel file :) kms 2 + export * from "./connect"; 3 + export * from "./schema";
+16 -2
packages/db/package.json
··· 1 1 { 2 2 "name": "@teal/db", 3 + "version": "0.0.0", 4 + "private": true, 5 + "main": "index.js", 3 6 "type": "module", 7 + "scripts": { 8 + "db": "drizzle-kit", 9 + "db:generate": "drizzle-kit generate", 10 + "db:migrate": "drizzle-kit migrate", 11 + "db:studio": "drizzle-kit studio" 12 + }, 4 13 "dependencies": { 5 - "drizzle-kit": "^0.27.1", 6 - "drizzle-orm": "^0.36.0" 14 + "@libsql/client": "^0.14.0", 15 + "@teal/tsconfig": "workspace:*", 16 + "drizzle-kit": "^0.30.1", 17 + "drizzle-orm": "^0.38.3" 18 + }, 19 + "devDependencies": { 20 + "@types/node": "^20.17.6" 7 21 } 8 22 }
+56 -30
packages/db/schema.ts
··· 1 - import { sqliteTable, text } from "drizzle-orm/sqlite-core"; 2 - 3 - export type DatabaseSchema = { 4 - status: Status; 5 - auth_session: AuthSession; 6 - auth_state: AuthState; 7 - }; 1 + import { 2 + numeric, 3 + sqliteTable, 4 + text, 5 + customType, 6 + integer, 7 + } from "drizzle-orm/sqlite-core"; 8 8 9 - export type Status = { 10 - uri: string; 11 - authorDid: string; 12 - status: string; 13 - createdAt: string; 14 - indexedAt: string; 15 - }; 16 - 17 - export type AuthSession = { 18 - key: string; 19 - session: AuthSessionJson; 20 - }; 21 - 22 - export type AuthState = { 23 - key: string; 24 - state: AuthStateJson; 25 - }; 26 - 27 - type AuthStateJson = string; 28 - 29 - type AuthSessionJson = string; 9 + // string array custom type 10 + const json = <TData>() => 11 + customType<{ data: TData; driverData: string }>({ 12 + dataType() { 13 + return "text"; 14 + }, 15 + toDriver(value: TData): string { 16 + return JSON.stringify(value); 17 + }, 18 + })(); 30 19 31 20 // Tables 32 21 ··· 66 55 67 56 // follow relationship 68 57 export const follow = sqliteTable("follow", { 69 - follower: text().primaryKey(), 70 - followed: text().primaryKey(), 58 + relId: text().primaryKey(), 59 + follower: text().notNull(), 60 + followed: text().notNull(), 71 61 createdAt: text().notNull(), 72 62 }); 63 + 64 + // play 65 + export const play = sqliteTable("play", { 66 + uri: text().primaryKey(), 67 + authorDid: text().notNull(), 68 + createdAt: text().notNull(), 69 + indexedAt: text().notNull(), 70 + 71 + /** The name of the track */ 72 + trackName: text().notNull(), 73 + /** The Musicbrainz ID of the track */ 74 + trackMbId: text(), 75 + /** The Musicbrainz recording ID of the track */ 76 + recordingMbId: text(), 77 + /** The length of the track in seconds */ 78 + duration: integer(), 79 + /** The name of the artist */ 80 + artistName: text().notNull(), 81 + /** Array of Musicbrainz artist IDs */ 82 + // type of string[] 83 + artistMbIds: json<string[]>(), 84 + /** The name of the release/album */ 85 + releaseName: text(), 86 + /** The Musicbrainz release ID */ 87 + releaseMbId: text(), 88 + /** The ISRC code associated with the recording */ 89 + isrc: text(), 90 + /** The URL associated with this track */ 91 + originUrl: text(), 92 + /** The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. */ 93 + musicServiceBaseDomain: text(), 94 + /** A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b */ 95 + submissionClientAgent: text(), 96 + /** The unix timestamp of when the track was played */ 97 + playedTime: text(), 98 + });
+5 -2
packages/jetstring/package.json
··· 1 1 { 2 2 "name": "@teal/jetstring", 3 - "type": "module", 4 3 "scripts": { 5 4 "dev": "tsx watch src/index.ts | pino-pretty" 6 5 }, 7 6 "dependencies": { 7 + "@libsql/client": "^0.14.0", 8 8 "@skyware/jetstream": "^0.2.0", 9 - "@teal/db": "workspace:*" 9 + "@teal/db": "workspace:*", 10 + "@teal/lexicons": "workspace:*", 11 + "@teal/tsconfig": "workspace:*", 12 + "pino-pretty": "^13.0.0" 10 13 }, 11 14 "devDependencies": { 12 15 "tsup": "^8.3.5",
+60 -12
packages/jetstring/src/index.ts
··· 1 1 import type { Database } from "@teal/db/connect"; 2 2 import { db } from "@teal/db/connect"; 3 - import { status } from "@teal/db/schema"; 3 + import { status, play } from "@teal/db/schema"; 4 4 import { CommitCreateEvent, Jetstream } from "@skyware/jetstream"; 5 5 6 6 import { 7 7 Record as XyzStatusphereStatus, 8 8 isRecord as isStatusphereStatus, 9 - } from "@teal/lexicons/generated/server/types/xyz/statusphere/status"; 9 + } from "@teal/lexicons/src/types/xyz/statusphere/status"; 10 + 11 + import { 12 + Record as FmTealAlphaPlay, 13 + isRecord as isTealAlphaPlay, 14 + } from "@teal/lexicons/src/types/fm/teal/alpha/play"; 10 15 11 16 class Handler { 12 17 private static instance: Handler; ··· 25 30 if (isStatusphereStatus(msg) && msg.$type === "xyz.statusphere.status") { 26 31 if (record.commit.operation === "create") { 27 32 // serialize message as xyz.statusphere.status 28 - db.insert(status).values({ 29 - createdAt: new Date().getSeconds().toString(), 30 - indexedAt: new Date(record.time_us).getSeconds().toString(), 31 - status: msg.status, 32 - // the AT path 33 - uri: record.commit.rkey, 34 - authorDid: record.did, 35 - }); 33 + db.insert(status) 34 + .values({ 35 + createdAt: new Date().getTime().toString(), 36 + indexedAt: new Date(record.time_us).getTime().toString(), 37 + status: msg.status, 38 + // the AT path 39 + uri: record.commit.rkey, 40 + authorDid: record.did, 41 + }) 42 + .execute(); 36 43 } else { 37 - console.log("unsupported operation:", record.commit.operation); 44 + // TODO: sentry 45 + console.log( 46 + "unsupported operation for xyz.statusphere.status", 47 + record.commit.operation, 48 + ); 49 + } 50 + } else if (isTealAlphaPlay(msg) && msg.$type === "fm.teal.alpha.play") { 51 + if (record.commit.operation === "create") { 52 + // serialize message as fm.teal.alpha.play 53 + db.insert(play) 54 + .values({ 55 + createdAt: new Date().getTime().toString(), 56 + indexedAt: new Date(record.time_us).getTime().toString(), 57 + // the AT path 58 + uri: record.commit.rkey, 59 + authorDid: record.did, 60 + 61 + artistName: msg.artistName, 62 + trackName: msg.trackName, 63 + artistMbIds: msg.artistMbIds || [], 64 + trackMbId: msg.trackMbId || "", 65 + duration: msg.duration || null, 66 + isrc: msg.isrc || null, 67 + musicServiceBaseDomain: msg.musicServiceBaseDomain || "local", 68 + originUrl: msg.originUrl || null, 69 + playedTime: msg.playedTime ? msg.playedTime.toString() : undefined, 70 + recordingMbId: msg.recordingMbId || null, 71 + releaseMbId: msg.releaseMbId || null, 72 + releaseName: msg.releaseName || null, 73 + submissionClientAgent: 74 + msg.submissionClientAgent || "manual/unknown", 75 + }) 76 + .execute(); 77 + } else { 78 + // TODO: sentry 79 + console.log( 80 + "unsupported operation for fm.teal.alpha.play", 81 + record.commit.operation, 82 + ); 38 83 } 39 84 } else { 40 85 console.log("Unknown message type:", msg_type); ··· 110 155 // Main function to run the application 111 156 async function main() { 112 157 try { 113 - const streamer = Streamer.getInstance(["xyz.statusphere.status"]); 158 + const streamer = Streamer.getInstance([ 159 + "xyz.statusphere.status", 160 + "fm.teal.alpha.play", 161 + ]); 114 162 await streamer.start(); 115 163 116 164 // Keep the process running
packages/lexicons/generated/server/index.ts packages/lexicons/src/index.ts
+2 -2
packages/lexicons/generated/server/lexicons.ts packages/lexicons/src/lexicons.ts
··· 310 310 musicServiceBaseDomain: { 311 311 type: 'string', 312 312 description: 313 - 'The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com.', 313 + "The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if not provided.", 314 314 }, 315 315 submissionClientAgent: { 316 316 type: 'string', 317 317 maxLength: 256, 318 318 maxGraphemes: 2560, 319 319 description: 320 - 'A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b', 320 + "A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b (Linux; Android 13; SM-A715F). Defaults to 'manual/unknown' if not provided.", 321 321 }, 322 322 playedTime: { 323 323 type: 'string',
packages/lexicons/generated/server/types/app/bsky/actor/profile.ts packages/lexicons/src/types/app/bsky/actor/profile.ts
packages/lexicons/generated/server/types/app/bsky/richtext/facet.ts packages/lexicons/src/types/app/bsky/richtext/facet.ts
packages/lexicons/generated/server/types/fm/teal/alpha/actor/profile.ts packages/lexicons/src/types/fm/teal/alpha/actor/profile.ts
packages/lexicons/generated/server/types/fm/teal/alpha/actor/status.ts packages/lexicons/src/types/fm/teal/alpha/actor/status.ts
+2 -2
packages/lexicons/generated/server/types/fm/teal/alpha/play.ts packages/lexicons/src/types/fm/teal/alpha/play.ts
··· 27 27 isrc?: string 28 28 /** The URL associated with this track */ 29 29 originUrl?: string 30 - /** The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. */ 30 + /** The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if not provided. */ 31 31 musicServiceBaseDomain?: string 32 - /** A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b */ 32 + /** A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b (Linux; Android 13; SM-A715F). Defaults to 'manual/unknown' if not provided. */ 33 33 submissionClientAgent?: string 34 34 /** The unix timestamp of when the track was played */ 35 35 playedTime?: string
packages/lexicons/generated/server/types/xyz/statusphere/status.ts packages/lexicons/src/types/xyz/statusphere/status.ts
packages/lexicons/generated/server/util.ts packages/lexicons/src/util.ts
packages/lexicons/index.ts

This is a binary file and will not be displayed.

+7 -1
packages/lexicons/package.json
··· 1 1 { 2 2 "name": "@teal/lexicons", 3 3 "type": "module", 4 + "main": "./index.ts", 4 5 "dependencies": { 6 + "@atproto/lex-cli": "^0.5.4", 5 7 "@atproto/lexicon": "^0.4.2", 6 - "@atproto/xrpc-server": "^0.6.4" 8 + "@atproto/xrpc-server": "^0.7.4", 9 + "@teal/tsconfig": "workspace:*" 10 + }, 11 + "scripts": { 12 + "lex:gen-server": "lex gen-server ./src ./real/*" 7 13 } 8 14 }
packages/lexicons/src/app.bsky.actor.profile.json packages/lexicons/real/app.bsky.actor.profile.json
packages/lexicons/src/app.bsky.richtext.facet.json packages/lexicons/real/app.bsky.richtext.facet.json
packages/lexicons/src/fm.teal.alpha.actor.profile.json packages/lexicons/real/fm.teal.alpha.actor.profile.json
packages/lexicons/src/fm.teal.alpha.actor.status.json packages/lexicons/real/fm.teal.alpha.actor.status.json
+2 -2
packages/lexicons/src/fm.teal.alpha.play.json packages/lexicons/real/fm.teal.alpha.play.json
··· 64 64 }, 65 65 "musicServiceBaseDomain": { 66 66 "type": "string", 67 - "description": "The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com." 67 + "description": "The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if not provided." 68 68 }, 69 69 "submissionClientAgent": { 70 70 "type": "string", 71 71 "maxLength": 256, 72 72 "maxGraphemes": 2560, 73 - "description": "A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b" 73 + "description": "A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b (Linux; Android 13; SM-A715F). Defaults to 'manual/unknown' if not provided." 74 74 }, 75 75 "playedTime": { 76 76 "type": "string",
packages/lexicons/src/xyz.statusphere.status.json packages/lexicons/real/xyz.statusphere.status.json
+1 -1
packages/lexicons/tsconfig.json
··· 1 1 { 2 2 "extends": "@teal/tsconfig/base.json", 3 - "include": ["./generated/**/*.ts"] 3 + "include": ["./src/**/*.ts"] 4 4 }
+5 -1
packages/tsconfig/package.json
··· 1 1 { 2 2 "name": "@teal/tsconfig", 3 - "type": "module" 3 + "version": "0.0.0", 4 + "private": true, 5 + "publishConfig": { 6 + "access": "public" 7 + } 4 8 }
+107 -58
pnpm-lock.yaml
··· 8 8 9 9 .: 10 10 devDependencies: 11 + '@types/node': 12 + specifier: ^20.17.10 13 + version: 20.17.10 11 14 biome: 12 15 specifier: ^0.3.3 13 16 version: 0.3.3 17 + rimraf: 18 + specifier: ^6.0.1 19 + version: 6.0.1 14 20 turbo: 15 21 specifier: ^2.3.3 16 22 version: 2.3.3 ··· 39 45 specifier: ^0.3.0 40 46 version: 0.3.1 41 47 '@atproto/xrpc-server': 42 - specifier: ^0.6.4 43 - version: 0.6.4 48 + specifier: ^0.7.4 49 + version: 0.7.4 44 50 '@braintree/sanitize-url': 45 51 specifier: ^7.1.0 46 52 version: 7.1.0 ··· 60 66 specifier: ^16.4.5 61 67 version: 16.4.7 62 68 drizzle-orm: 63 - specifier: ^0.36.1 64 - version: 0.36.4(@libsql/client@0.14.0) 69 + specifier: ^0.38.3 70 + version: 0.38.3(@libsql/client@0.14.0) 65 71 envalid: 66 72 specifier: ^8.0.0 67 73 version: 8.0.0 ··· 82 88 version: 4.7.0 83 89 devDependencies: 84 90 '@atproto/lex-cli': 85 - specifier: ^0.4.1 86 - version: 0.4.1 91 + specifier: ^0.5.4 92 + version: 0.5.4 87 93 '@teal/tsconfig': 88 94 specifier: workspace:* 89 95 version: link:../../packages/tsconfig ··· 91 97 specifier: ^20.17.6 92 98 version: 20.17.9 93 99 drizzle-kit: 94 - specifier: ^0.27.2 95 - version: 0.27.2 100 + specifier: ^0.30.1 101 + version: 0.30.1 96 102 pino-pretty: 97 - specifier: ^11.3.0 98 - version: 11.3.0 103 + specifier: ^13.0.0 104 + version: 13.0.0 99 105 rimraf: 100 106 specifier: ^6.0.1 101 107 version: 6.0.1 ··· 111 117 112 118 packages/db: 113 119 dependencies: 120 + '@libsql/client': 121 + specifier: ^0.14.0 122 + version: 0.14.0 123 + '@teal/tsconfig': 124 + specifier: workspace:* 125 + version: link:../tsconfig 114 126 drizzle-kit: 115 - specifier: ^0.27.1 116 - version: 0.27.2 127 + specifier: ^0.30.1 128 + version: 0.30.1 117 129 drizzle-orm: 118 - specifier: ^0.36.0 119 - version: 0.36.4(@libsql/client@0.14.0) 130 + specifier: ^0.38.3 131 + version: 0.38.3(@libsql/client@0.14.0) 132 + devDependencies: 133 + '@types/node': 134 + specifier: ^20.17.6 135 + version: 20.17.9 120 136 121 137 packages/jetstring: 122 138 dependencies: 139 + '@libsql/client': 140 + specifier: ^0.14.0 141 + version: 0.14.0 123 142 '@skyware/jetstream': 124 143 specifier: ^0.2.0 125 144 version: 0.2.1(@atcute/client@2.0.6) 126 145 '@teal/db': 127 146 specifier: workspace:* 128 147 version: link:../db 148 + '@teal/lexicons': 149 + specifier: workspace:* 150 + version: link:../lexicons 151 + '@teal/tsconfig': 152 + specifier: workspace:* 153 + version: link:../tsconfig 154 + pino-pretty: 155 + specifier: ^13.0.0 156 + version: 13.0.0 129 157 devDependencies: 130 158 tsup: 131 159 specifier: ^8.3.5 ··· 139 167 140 168 packages/lexicons: 141 169 dependencies: 170 + '@atproto/lex-cli': 171 + specifier: ^0.5.4 172 + version: 0.5.4 142 173 '@atproto/lexicon': 143 174 specifier: ^0.4.2 144 175 version: 0.4.3 145 176 '@atproto/xrpc-server': 146 - specifier: ^0.6.4 147 - version: 0.6.4 177 + specifier: ^0.7.4 178 + version: 0.7.4 179 + '@teal/tsconfig': 180 + specifier: workspace:* 181 + version: link:../tsconfig 148 182 149 183 packages/matcher: {} 150 184 ··· 196 230 '@atproto/common@0.4.4': 197 231 resolution: {integrity: sha512-58tMbn6A1Zu296s/l3uIj8z9d7IRHpZvLOfsFRikaQaYrzhJpL2aPY4uFQ8GJcxnsxeUnxBCrQz9we5jVVJI5Q==} 198 232 233 + '@atproto/common@0.4.5': 234 + resolution: {integrity: sha512-LFAGqHcxCI5+b31Xgk+VQQtZU258iGPpHJzNeHVcdh6teIKZi4C2l6YV+m+3CEz+yYcfP7jjUmgqesx7l9Arsg==} 235 + 199 236 '@atproto/crypto@0.4.2': 200 237 resolution: {integrity: sha512-aeOfPQYCDbhn2hV06oBF2KXrWjf/BK4yL8lfANJKSmKl3tKWCkiW/moi643rUXXxSE72KtWtQeqvNFYnnFJ0ig==} 201 238 ··· 214 251 '@atproto/jwk@0.1.1': 215 252 resolution: {integrity: sha512-6h/bj1APUk7QcV9t/oA6+9DB5NZx9SZru9x+/pV5oHFI9Xz4ZuM5+dq1PfsJV54pZyqdnZ6W6M717cxoC7q7og==} 216 253 217 - '@atproto/lex-cli@0.4.1': 218 - resolution: {integrity: sha512-QP9mE8MYzXR2ydhCBb/mtGqKZjqpffqcpZCr7JM4mFOZPvXV8k7OqVP1h+T94JB/tGcGPhB750S6tqUH9VRLVg==} 254 + '@atproto/lex-cli@0.5.4': 255 + resolution: {integrity: sha512-mNEPeQLXl3iCXPO/FSo0BTfP00lx+9xEQpf9LEpDuKA6WCWjIB7WHzU2VLk26NSftzH3sf6zf+A2yZ+WWRbYpw==} 219 256 hasBin: true 220 257 221 258 '@atproto/lexicon@0.4.3': 222 259 resolution: {integrity: sha512-lFVZXe1S1pJP0dcxvJuHP3r/a+EAIBwwU7jUK+r8iLhIja+ml6NmYv8KeFHmIJATh03spEQ9s02duDmFVdCoXg==} 223 260 261 + '@atproto/lexicon@0.4.4': 262 + resolution: {integrity: sha512-QFEmr3rpj/RoAmfX9ALU/asBG/rsVtQZnw+9nOB1/AuIwoxXd+ZyndR6lVUc2+DL4GEjl6W2yvBru5xbQIZWyA==} 263 + 224 264 '@atproto/oauth-client-node@0.2.3': 225 265 resolution: {integrity: sha512-crHxZaP9T/i7O9fOhALcFtW1EP/tVblDnWoaIiZ3vL/hvVLwSUad/wvG2WPcVURzLSbigDInhn7rZZSzLxJacg==} 226 266 ··· 239 279 '@atproto/syntax@0.3.1': 240 280 resolution: {integrity: sha512-fzW0Mg1QUOVCWUD3RgEsDt6d1OZ6DdFmbKcDdbzUfh0t4rhtRAC05KbZYmxuMPWDAiJ4BbbQ5dkAc/mNypMXkw==} 241 281 242 - '@atproto/xrpc-server@0.6.4': 243 - resolution: {integrity: sha512-AL9okOTpJpxh3wJjT27RiPkp2IWIxDPCyyvuO1SJu0E9URGfWZL26SlT7/IR/tadZTJezr5+ZNuxhV0uhI+s1A==} 244 - 245 - '@atproto/xrpc-server@0.7.3': 246 - resolution: {integrity: sha512-x0qegkN6snrbXJO3v9h2kuh9e90g6ZZkDXv3COiraGS3yRTzIm6i4bMvDSfCI50+0xCNtPKOkpn8taRoRgkyiw==} 282 + '@atproto/xrpc-server@0.7.4': 283 + resolution: {integrity: sha512-MrAwxfJBQm/kCol3D8qc+vpQzBMzLqvtUbauSSfVVJ10PlGtxg4LlXqcjkAuhrjyrqp3dQH9LHuhDpgVQK+G3w==} 247 284 248 285 '@atproto/xrpc@0.6.4': 249 286 resolution: {integrity: sha512-9ZAJ8nsXTqC4XFyS0E1Wlg7bAvonhXQNQ3Ocs1L1LIwFLXvsw/4fNpIHXxvXvqTCVeyHLbImOnE9UiO1c/qIYA==} 250 287 288 + '@atproto/xrpc@0.6.5': 289 + resolution: {integrity: sha512-t6u8iPEVbWge5RhzKZDahSzNDYIAxUtop6Q/X/apAZY1rgreVU0/1sSvvRoRFH19d3UIKjYdLuwFqMi9w8nY3Q==} 290 + 251 291 '@braintree/sanitize-url@7.1.0': 252 292 resolution: {integrity: sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg==} 253 293 ··· 1073 1113 '@types/estree@1.0.6': 1074 1114 resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} 1075 1115 1116 + '@types/node@20.17.10': 1117 + resolution: {integrity: sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==} 1118 + 1076 1119 '@types/node@20.17.9': 1077 1120 resolution: {integrity: sha512-0JOXkRyLanfGPE2QRCwgxhzlBAvaRdCNMcvbd7jFfpmD4eEXll7LRwy5ymJmyeZqk7Nh7eD2LeUyQ68BbndmXw==} 1078 1121 ··· 1387 1430 resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} 1388 1431 engines: {node: '>=12'} 1389 1432 1390 - drizzle-kit@0.27.2: 1391 - resolution: {integrity: sha512-F6cFZ1wxa9XzFyeeQsp/0/lIzUbDuQjS8/njpYBDWa+wdWmXuY+Z/X2hHFK/9PGHZkv3c9mER+mVWfKlp/B6Vw==} 1433 + drizzle-kit@0.30.1: 1434 + resolution: {integrity: sha512-HmA/NeewvHywhJ2ENXD3KvOuM/+K2dGLJfxVfIHsGwaqKICJnS+Ke2L6UcSrSrtMJLJaT0Im1Qv4TFXfaZShyw==} 1392 1435 hasBin: true 1393 1436 1394 - drizzle-orm@0.36.4: 1395 - resolution: {integrity: sha512-1OZY3PXD7BR00Gl61UUOFihslDldfH4NFRH2MbP54Yxi0G/PKn4HfO65JYZ7c16DeP3SpM3Aw+VXVG9j6CRSXA==} 1437 + drizzle-orm@0.38.3: 1438 + resolution: {integrity: sha512-w41Y+PquMpSff/QDRGdItG0/aWca+/J3Sda9PPGkTxBtjWQvgU1jxlFBXdjog5tYvTu58uvi3PwR1NuCx0KeZg==} 1396 1439 peerDependencies: 1397 1440 '@aws-sdk/client-rds-data': '>=3' 1398 - '@cloudflare/workers-types': '>=3' 1441 + '@cloudflare/workers-types': '>=4' 1399 1442 '@electric-sql/pglite': '>=0.2.0' 1400 1443 '@libsql/client': '>=0.10.0' 1401 1444 '@libsql/client-wasm': '>=0.10.0' ··· 2112 2155 pino-abstract-transport@2.0.0: 2113 2156 resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} 2114 2157 2115 - pino-pretty@11.3.0: 2116 - resolution: {integrity: sha512-oXwn7ICywaZPHmu3epHGU2oJX4nPmKvHvB/bwrJHlGcbEWaVcotkpyVHMKLKmiVryWYByNp0jpgAcXpFJDXJzA==} 2158 + pino-pretty@13.0.0: 2159 + resolution: {integrity: sha512-cQBBIVG3YajgoUjo1FdKVRX6t9XPxwB9lcNJVD5GCnNM4Y6T12YYx8c6zEejxQsU0wrg9TwmDulcE9LR7qcJqA==} 2117 2160 hasBin: true 2118 2161 2119 2162 pino-std-serializers@6.2.2: ··· 2703 2746 multiformats: 9.9.0 2704 2747 pino: 8.21.0 2705 2748 2749 + '@atproto/common@0.4.5': 2750 + dependencies: 2751 + '@atproto/common-web': 0.3.1 2752 + '@ipld/dag-cbor': 7.0.3 2753 + cbor-x: 1.6.0 2754 + iso-datestring-validator: 2.2.2 2755 + multiformats: 9.9.0 2756 + pino: 8.21.0 2757 + 2706 2758 '@atproto/crypto@0.4.2': 2707 2759 dependencies: 2708 2760 '@noble/curves': 1.7.0 ··· 2736 2788 multiformats: 9.9.0 2737 2789 zod: 3.23.8 2738 2790 2739 - '@atproto/lex-cli@0.4.1': 2791 + '@atproto/lex-cli@0.5.4': 2740 2792 dependencies: 2741 - '@atproto/lexicon': 0.4.3 2793 + '@atproto/lexicon': 0.4.4 2742 2794 '@atproto/syntax': 0.3.1 2743 2795 chalk: 4.1.2 2744 2796 commander: 9.5.0 ··· 2748 2800 zod: 3.23.8 2749 2801 2750 2802 '@atproto/lexicon@0.4.3': 2803 + dependencies: 2804 + '@atproto/common-web': 0.3.1 2805 + '@atproto/syntax': 0.3.1 2806 + iso-datestring-validator: 2.2.2 2807 + multiformats: 9.9.0 2808 + zod: 3.23.8 2809 + 2810 + '@atproto/lexicon@0.4.4': 2751 2811 dependencies: 2752 2812 '@atproto/common-web': 0.3.1 2753 2813 '@atproto/syntax': 0.3.1 ··· 2806 2866 '@atproto/lexicon': 0.4.3 2807 2867 '@atproto/repo': 0.5.5 2808 2868 '@atproto/syntax': 0.3.1 2809 - '@atproto/xrpc-server': 0.7.3 2869 + '@atproto/xrpc-server': 0.7.4 2810 2870 multiformats: 9.9.0 2811 2871 p-queue: 6.6.2 2812 2872 transitivePeerDependencies: ··· 2817 2877 2818 2878 '@atproto/syntax@0.3.1': {} 2819 2879 2820 - '@atproto/xrpc-server@0.6.4': 2880 + '@atproto/xrpc-server@0.7.4': 2821 2881 dependencies: 2822 - '@atproto/common': 0.4.4 2882 + '@atproto/common': 0.4.5 2823 2883 '@atproto/crypto': 0.4.2 2824 - '@atproto/lexicon': 0.4.3 2825 - '@atproto/xrpc': 0.6.4 2884 + '@atproto/lexicon': 0.4.4 2885 + '@atproto/xrpc': 0.6.5 2826 2886 cbor-x: 1.6.0 2827 2887 express: 4.21.2 2828 2888 http-errors: 2.0.0 ··· 2836 2896 - supports-color 2837 2897 - utf-8-validate 2838 2898 2839 - '@atproto/xrpc-server@0.7.3': 2899 + '@atproto/xrpc@0.6.4': 2840 2900 dependencies: 2841 - '@atproto/common': 0.4.4 2842 - '@atproto/crypto': 0.4.2 2843 2901 '@atproto/lexicon': 0.4.3 2844 - '@atproto/xrpc': 0.6.4 2845 - cbor-x: 1.6.0 2846 - express: 4.21.2 2847 - http-errors: 2.0.0 2848 - mime-types: 2.1.35 2849 - rate-limiter-flexible: 2.4.2 2850 - uint8arrays: 3.0.0 2851 - ws: 8.18.0 2852 2902 zod: 3.23.8 2853 - transitivePeerDependencies: 2854 - - bufferutil 2855 - - supports-color 2856 - - utf-8-validate 2857 2903 2858 - '@atproto/xrpc@0.6.4': 2904 + '@atproto/xrpc@0.6.5': 2859 2905 dependencies: 2860 - '@atproto/lexicon': 0.4.3 2906 + '@atproto/lexicon': 0.4.4 2861 2907 zod: 3.23.8 2862 2908 2863 2909 '@braintree/sanitize-url@7.1.0': {} ··· 3369 3415 3370 3416 '@types/estree@1.0.6': {} 3371 3417 3418 + '@types/node@20.17.10': 3419 + dependencies: 3420 + undici-types: 6.19.8 3421 + 3372 3422 '@types/node@20.17.9': 3373 3423 dependencies: 3374 3424 undici-types: 6.19.8 ··· 3669 3719 3670 3720 dotenv@16.4.7: {} 3671 3721 3672 - drizzle-kit@0.27.2: 3722 + drizzle-kit@0.30.1: 3673 3723 dependencies: 3674 3724 '@drizzle-team/brocli': 0.10.2 3675 3725 '@esbuild-kit/esm-loader': 2.6.5 ··· 3678 3728 transitivePeerDependencies: 3679 3729 - supports-color 3680 3730 3681 - drizzle-orm@0.36.4(@libsql/client@0.14.0): 3731 + drizzle-orm@0.38.3(@libsql/client@0.14.0): 3682 3732 optionalDependencies: 3683 3733 '@libsql/client': 0.14.0 3684 3734 ··· 4387 4437 dependencies: 4388 4438 split2: 4.2.0 4389 4439 4390 - pino-pretty@11.3.0: 4440 + pino-pretty@13.0.0: 4391 4441 dependencies: 4392 4442 colorette: 2.0.20 4393 4443 dateformat: 4.6.3 ··· 4399 4449 on-exit-leak-free: 2.1.2 4400 4450 pino-abstract-transport: 2.0.0 4401 4451 pump: 3.0.2 4402 - readable-stream: 4.5.2 4403 4452 secure-json-parse: 2.7.0 4404 4453 sonic-boom: 4.2.0 4405 4454 strip-json-comments: 3.1.1
+3
turbo.json
··· 14 14 "dev": { 15 15 "persistent": true, 16 16 "cache": false 17 + }, 18 + "db:migrate": { 19 + "cache": false 17 20 } 18 21 } 19 22 }