Openstatus www.openstatus.dev

Embed db (#1462)

* trying-embed-replica

* use embedd db

* 😭

* ci: apply automated fixes

* rename

* use regular db

* ci: apply automated fixes

* 😭

* 😭

* connect to turso

* 🤗

* 🔥

* wip docker compose

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

authored by

Thibault Le Ouay
autofix-ci[bot]
and committed by
GitHub
9cc6569d 29ed807e

+604 -91
+10
apps/server/docker-compose.yaml
··· 1 + name: server 2 + services: 3 + server: 4 + build: 5 + context: ../.. 6 + dockerfile: apps/server/Dockerfile 7 + ports: 8 + - 3000:3000 9 + image: server 10 + command: .
+49 -3
apps/workflows/Dockerfile
··· 45 45 --from=install \ 46 46 --link \ 47 47 "/app/node_modules" "/app/node_modules" 48 - RUN bun build --compile --sourcemap --format=cjs src/index.ts --outfile=app 48 + RUN bun build --compile --target bun --sourcemap --format=cjs src/index.ts --outfile=app --external '@libsql/*' --external libsql 49 + 50 + # ca-certs 51 + FROM debian@sha256:f807f4b16002c623115b0247dca6a55711c6b1ae821dc64fb8a2339e4ce2115d AS ca-certs 52 + LABEL \ 53 + org.opencontainers.image.base.digest="sha256:f807f4b16002c623115b0247dca6a55711c6b1ae821dc64fb8a2339e4ce2115d" \ 54 + org.opencontainers.image.base.name="docker.io/debian:bullseye-slim" 55 + RUN apt update && apt install -y ca-certificates && update-ca-certificates 56 + 57 + # docker 58 + FROM oven/bun@sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025 AS docker 59 + LABEL \ 60 + org.opencontainers.image.base.digest="sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025" \ 61 + org.opencontainers.image.base.name="docker.io/oven/bun:latest" 62 + WORKDIR /app/apps/workflows 63 + COPY \ 64 + --link \ 65 + "." "/app/" 66 + RUN bun run src/build-docker.ts 67 + 68 + # libsql 69 + FROM oven/bun@sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025 AS libsql 70 + LABEL \ 71 + org.opencontainers.image.base.digest="sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025" \ 72 + org.opencontainers.image.base.name="docker.io/oven/bun:latest" 73 + WORKDIR /app/ 74 + COPY \ 75 + --from=docker \ 76 + --link \ 77 + "/app/apps/build-docker/package.json" "/app/package.json" 78 + RUN bun install 49 79 50 80 # runtime 51 81 FROM debian@sha256:f807f4b16002c623115b0247dca6a55711c6b1ae821dc64fb8a2339e4ce2115d AS runtime ··· 53 83 io.dofigen.version="2.5.0" \ 54 84 org.opencontainers.image.base.digest="sha256:f807f4b16002c623115b0247dca6a55711c6b1ae821dc64fb8a2339e4ce2115d" \ 55 85 org.opencontainers.image.base.name="docker.io/debian:bullseye-slim" 86 + WORKDIR /app/ 56 87 COPY \ 57 88 --from=build \ 58 89 --chown=1000:1000 \ 59 90 --chmod=555 \ 60 91 --link \ 61 - "/app/apps/workflows/app" "/bin/" 92 + "/app/apps/workflows/app" "/app/apps/workflows/" 93 + COPY \ 94 + --from=libsql \ 95 + --chown=1000:1000 \ 96 + --link \ 97 + "/app/node_modules" "/app/packages/db/node_modules" 98 + COPY \ 99 + --from=libsql \ 100 + --chown=1000:1000 \ 101 + --link \ 102 + "/app/node_modules" "/app/node_modules" 103 + COPY \ 104 + --from=ca-certs \ 105 + --chown=1000:1000 \ 106 + --link \ 107 + "/etc/ssl/certs/ca-certificates.crt" "/etc/ssl/certs/" 62 108 USER 1000:1000 63 109 EXPOSE 3000 64 - ENTRYPOINT ["/bin/app"] 110 + ENTRYPOINT ["/app/apps/workflows/app"]
+26
apps/workflows/docker-compose.yaml
··· 1 + name: workflows-test 2 + services: 3 + workflows-test: 4 + build: 5 + context: ../.. 6 + dockerfile: apps/workflows/Dockerfile 7 + environment: 8 + - DATABASE_URL=http://host.docker.internal:8081 9 + - DATABASE_AUTH_TOKEN=test 10 + - RESEND_API_KEY=test 11 + - UPSTASH_REDIS_REST_URL=test 12 + - UPSTASH_REDIS_REST_TOKEN=test 13 + - NODE_ENV=production 14 + - GCP_PROJECT_ID=test 15 + extra_hosts: 16 + - "host.docker.internal:host-gateway" 17 + 18 + ports: 19 + - 3000:3000 20 + - 8081:8081 21 + volumes: 22 + - type: bind 23 + source: ./data 24 + target: /app/data 25 + image: workflows-test 26 + command: .
+105 -23
apps/workflows/dofigen.lock
··· 12 12 - /packages/error 13 13 - /packages/tracker 14 14 builders: 15 + libsql: 16 + fromImage: 17 + path: oven/bun 18 + digest: sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025 19 + label: 20 + org.opencontainers.image.base.name: docker.io/oven/bun:latest 21 + org.opencontainers.image.base.digest: sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025 22 + workdir: /app/ 23 + copy: 24 + - fromBuilder: docker 25 + paths: 26 + - /app/apps/build-docker/package.json 27 + target: /app/package.json 28 + run: 29 + - bun install 30 + docker: 31 + fromImage: 32 + path: oven/bun 33 + digest: sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025 34 + label: 35 + org.opencontainers.image.base.digest: sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025 36 + org.opencontainers.image.base.name: docker.io/oven/bun:latest 37 + workdir: /app/apps/workflows 38 + copy: 39 + - paths: 40 + - . 41 + target: /app/ 42 + run: 43 + - bun run src/build-docker.ts 44 + build: 45 + fromImage: 46 + path: oven/bun 47 + digest: sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025 48 + label: 49 + org.opencontainers.image.base.digest: sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025 50 + org.opencontainers.image.base.name: docker.io/oven/bun:latest 51 + workdir: /app/apps/workflows 52 + env: 53 + NODE_ENV: production 54 + copy: 55 + - paths: 56 + - . 57 + target: /app/ 58 + - fromBuilder: install 59 + paths: 60 + - /app/node_modules 61 + target: /app/node_modules 62 + run: 63 + - bun build --compile --target bun --sourcemap --format=cjs src/index.ts --outfile=app --external '@libsql/*' --external libsql 15 64 install: 16 65 fromImage: 17 66 path: oven/bun ··· 63 112 source: packages/tinybird/package.json 64 113 - target: packages/upstash/package.json 65 114 source: packages/upstash/package.json 66 - build: 115 + ca-certs: 67 116 fromImage: 68 - path: oven/bun 69 - digest: sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025 117 + path: debian 118 + digest: sha256:f807f4b16002c623115b0247dca6a55711c6b1ae821dc64fb8a2339e4ce2115d 70 119 label: 71 - org.opencontainers.image.base.name: docker.io/oven/bun:latest 72 - org.opencontainers.image.base.digest: sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025 73 - workdir: /app/apps/workflows 74 - env: 75 - NODE_ENV: production 76 - copy: 77 - - paths: 78 - - . 79 - target: /app/ 80 - - fromBuilder: install 81 - paths: 82 - - /app/node_modules 83 - target: /app/node_modules 120 + org.opencontainers.image.base.name: docker.io/debian:bullseye-slim 121 + org.opencontainers.image.base.digest: sha256:f807f4b16002c623115b0247dca6a55711c6b1ae821dc64fb8a2339e4ce2115d 84 122 run: 85 - - bun build --compile --sourcemap --format=cjs src/index.ts --outfile=app 123 + - apk update && apk upgrade --available && apk add ca-certificates && update-ca-certificates 86 124 fromImage: 87 125 path: debian 88 126 digest: sha256:f807f4b16002c623115b0247dca6a55711c6b1ae821dc64fb8a2339e4ce2115d ··· 90 128 org.opencontainers.image.base.name: docker.io/debian:bullseye-slim 91 129 org.opencontainers.image.base.digest: sha256:f807f4b16002c623115b0247dca6a55711c6b1ae821dc64fb8a2339e4ce2115d 92 130 io.dofigen.version: 2.5.0 131 + workdir: /app/ 93 132 copy: 94 133 - fromBuilder: build 95 134 paths: 96 135 - /app/apps/workflows/app 97 - target: /bin/ 136 + target: /app/apps/workflows/ 98 137 chmod: '555' 138 + - fromBuilder: libsql 139 + paths: 140 + - /app/node_modules 141 + target: /app/packages/db/node_modules 142 + - fromBuilder: libsql 143 + paths: 144 + - /app/node_modules 145 + target: /app/node_modules 146 + - fromBuilder: ca-certs 147 + paths: 148 + - /etc/ssl/certs/ca-certificates.crt 149 + target: /etc/ssl/certs/ 99 150 entrypoint: 100 - - /bin/app 151 + - /app/apps/workflows/app 101 152 expose: 102 153 - port: 3000 103 154 images: ··· 112 163 digest: sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025 113 164 resources: 114 165 dofigen.yml: 115 - hash: 9be6075fa415f4f265964fb4db272498168c362211b09cdca638a0bd3ee00746 166 + hash: 4c0cfc9f42824ef083d401f675c335053cd0458addbcdf987bd0cd2713a31d42 116 167 content: | 117 168 ignore: 118 169 - node_modules ··· 168 219 # Compile the TypeScript application 169 220 env: 170 221 NODE_ENV: production 171 - run: bun build --compile --sourcemap --format=cjs src/index.ts --outfile=app 222 + run: bun build --compile --target bun --sourcemap --format=cjs src/index.ts --outfile=app --external '@libsql/*' --external libsql 223 + 224 + docker: 225 + fromImage: oven/bun 226 + workdir: /app/apps/workflows 227 + copy: 228 + - . /app/ 229 + run: bun run src/build-docker.ts 230 + 231 + libsql: 232 + fromImage: oven/bun 233 + workdir: /app/ 234 + copy: 235 + - fromBuilder: docker 236 + source: /app/apps/build-docker/package.json 237 + target: /app/package.json 238 + run: bun install 239 + 240 + ca-certs: 241 + fromImage: debian:bullseye-slim 242 + run: apk update && apk upgrade --available && apk add ca-certificates && update-ca-certificates 243 + 172 244 fromImage: debian:bullseye-slim 245 + workdir: /app/ 173 246 copy: 174 247 - fromBuilder: build 175 248 source: /app/apps/workflows/app 176 - target: /bin/ 249 + target: /app/apps/workflows/ 177 250 chmod: "555" 251 + - fromBuilder: libsql 252 + source: /app/node_modules 253 + target: /app/packages/db/node_modules 254 + - fromBuilder: libsql 255 + source: /app/node_modules 256 + target: /app/node_modules 257 + - fromBuilder: ca-certs 258 + source: /etc/ssl/certs/ca-certificates.crt 259 + target: /etc/ssl/certs/ 178 260 expose: 3000 179 - entrypoint: /bin/app 261 + entrypoint: /app/apps/workflows/app
+34 -3
apps/workflows/dofigen.yml
··· 52 52 # Compile the TypeScript application 53 53 env: 54 54 NODE_ENV: production 55 - run: bun build --compile --sourcemap --format=cjs src/index.ts --outfile=app 55 + run: bun build --compile --target bun --sourcemap --format=cjs src/index.ts --outfile=app --external '@libsql/*' --external libsql 56 + 57 + docker: 58 + fromImage: oven/bun 59 + workdir: /app/apps/workflows 60 + copy: 61 + - . /app/ 62 + run: bun run src/build-docker.ts 63 + 64 + libsql: 65 + fromImage: oven/bun 66 + workdir: /app/ 67 + copy: 68 + - fromBuilder: docker 69 + source: /app/apps/build-docker/package.json 70 + target: /app/package.json 71 + run: bun install 72 + 73 + ca-certs: 74 + fromImage: debian:bullseye-slim 75 + run: apt update && apt install -y ca-certificates && update-ca-certificates 76 + 56 77 fromImage: debian:bullseye-slim 78 + workdir: /app/ 57 79 copy: 58 80 - fromBuilder: build 59 81 source: /app/apps/workflows/app 60 - target: /bin/ 82 + target: /app/apps/workflows/ 61 83 chmod: "555" 84 + - fromBuilder: libsql 85 + source: /app/node_modules 86 + target: /app/packages/db/node_modules 87 + - fromBuilder: libsql 88 + source: /app/node_modules 89 + target: /app/node_modules 90 + - fromBuilder: ca-certs 91 + source: /etc/ssl/certs/ca-certificates.crt 92 + target: /etc/ssl/certs/ 62 93 expose: 3000 63 - entrypoint: /bin/app 94 + entrypoint: /app/apps/workflows/app
+7 -2
apps/workflows/fly.toml
··· 19 19 force_https = true 20 20 auto_stop_machines = "suspend" 21 21 auto_start_machines = true 22 - min_machines_running = 1 22 + min_machines_running = 2 23 23 processes = ["app"] 24 24 25 25 [http_service.concurrency] ··· 39 39 40 40 [env] 41 41 NODE_ENV = "production" 42 - PORT = "3000" 42 + PORT = "3000" 43 + 44 + 45 + [[mounts]] 46 + source = "libsql_data" 47 + destination = "/app/data"
+3
apps/workflows/package.json
··· 8 8 "dependencies": { 9 9 "@google-cloud/tasks": "4.0.1", 10 10 "@hono/sentry": "1.2.2", 11 + "@libsql/client": "0.15.15", 11 12 "@openstatus/db": "workspace:*", 12 13 "@openstatus/emails": "workspace:*", 13 14 "@openstatus/notification-discord": "workspace:*", ··· 18 19 "@openstatus/notification-slack": "workspace:*", 19 20 "@openstatus/notification-twillio-sms": "workspace:*", 20 21 "@openstatus/notification-webhook": "workspace:*", 22 + "@openstatus/regions": "workspace:*", 21 23 "@openstatus/tinybird": "workspace:*", 22 24 "@openstatus/upstash": "workspace:*", 23 25 "@openstatus/utils": "workspace:*", 24 26 "@upstash/qstash": "2.6.2", 27 + "drizzle-orm": "0.44.4", 25 28 "hono": "4.5.3", 26 29 "limiter": "^3.0.0", 27 30 "zod": "3.24.2"
+33
apps/workflows/src/build-docker.ts
··· 1 + import path from "node:path"; 2 + 3 + // Create package.json that contains @libsql/client as dependency. It will be used to create node_modules and copy them alongside compiled server https://github.com/oven-sh/bun/issues/18909 4 + type PackageJson = Record<"name" | "description" | "version", string> & 5 + Record<"dependencies", Record<string, string>>; 6 + const packageJson: PackageJson = await Bun.file( 7 + path.join(__dirname, "../../../packages/db", "package.json"), 8 + ).json(); 9 + 10 + const extractDependenciesNames = ["@libsql/client"]; 11 + const extractedDependencies = extractDependenciesNames.reduce( 12 + (acc, cur) => { 13 + if (packageJson.dependencies[cur]) { 14 + acc[cur] = packageJson.dependencies[cur]; 15 + } 16 + 17 + return acc; 18 + }, 19 + {} as Record<string, string>, 20 + ); 21 + 22 + const packageJsonBuild = { 23 + name: packageJson.name, 24 + description: packageJson.description, 25 + version: packageJson.version, 26 + // type: "module", 27 + dependencies: extractedDependencies, 28 + }; 29 + 30 + await Bun.write( 31 + "../build-docker/package.json", 32 + JSON.stringify(packageJsonBuild, null, 2), 33 + );
+106 -49
apps/workflows/src/cron/checker.ts
··· 2 2 import type { google } from "@google-cloud/tasks/build/protos/protos"; 3 3 import { z } from "zod"; 4 4 5 - import { and, db, eq, gte, lte, notInArray } from "@openstatus/db"; 5 + import { and, eq, gte, lte, notInArray } from "@openstatus/db"; 6 6 import { 7 + type MonitorStatus, 7 8 maintenance, 8 9 maintenancesToMonitors, 9 10 monitor, 10 - type monitorStatusSchema, 11 11 monitorStatusTable, 12 12 selectMonitorSchema, 13 13 selectMonitorStatusSchema, 14 14 } from "@openstatus/db/src/schema"; 15 + import type { Region } from "@openstatus/db/src/schema/constants"; 16 + import { regionDict } from "@openstatus/regions"; 17 + import { db } from "../lib/db"; 15 18 16 19 import type { monitorPeriodicitySchema } from "@openstatus/db/src/schema/constants"; 17 - import type { httpPayloadSchema, tpcPayloadSchema } from "@openstatus/utils"; 20 + import { 21 + type httpPayloadSchema, 22 + type tpcPayloadSchema, 23 + transformHeaders, 24 + } from "@openstatus/utils"; 18 25 import { env } from "../env"; 19 26 20 27 export const isAuthorizedDomain = (url: string) => { ··· 72 79 73 80 const monitors = z.array(selectMonitorSchema).safeParse(result); 74 81 const allResult = []; 75 - 76 82 if (!monitors.success) { 77 83 console.error(`Error while fetching the monitors ${monitors.error.errors}`); 78 84 throw new Error("Error while fetching the monitors"); 79 85 } 80 86 81 87 for (const row of monitors.data) { 88 + // const selectedRegions = row.regions.length > 0 ? row.regions : ["ams"]; 89 + 82 90 const result = await db 83 91 .select() 84 92 .from(monitorStatusTable) 85 93 .where(eq(monitorStatusTable.monitorId, row.id)) 86 94 .all(); 87 95 const monitorStatus = z.array(selectMonitorStatusSchema).safeParse(result); 88 - 89 96 if (!monitorStatus.success) { 90 97 console.error( 91 98 `Error while fetching the monitor status ${monitorStatus.error.errors}`, ··· 97 104 const status = 98 105 monitorStatus.data.find((m) => region === m.region)?.status || "active"; 99 106 107 + const r = regionDict[region as keyof typeof regionDict]; 108 + 109 + if (!r) { 110 + console.error(`Invalid region ${region}`); 111 + continue; 112 + } 113 + if (r.deprecated) { 114 + // Let's uncomment this when we are ready to remove deprecated regions 115 + // We should not use deprecated regions anymore 116 + console.error(`Deprecated region ${region}`); 117 + continue; 118 + } 100 119 const response = createCronTask({ 101 - monitor: row, 120 + row, 102 121 timestamp, 103 122 client, 104 123 parent, ··· 106 125 region, 107 126 }); 108 127 allResult.push(response); 109 - 110 - // REMINDER: vercel.json cron doesn't support seconds - so we need to schedule another task in 30s 111 128 if (periodicity === "30s") { 129 + // we schedule another task in 30s 130 + const scheduledAt = timestamp + 30 * 1000; 112 131 const response = createCronTask({ 113 - monitor: row, 114 - timestamp: timestamp + 30 * 1000, // we schedule another task in 30s 132 + row, 133 + timestamp: scheduledAt, 115 134 client, 116 135 parent, 117 136 status, ··· 131 150 `End cron for ${periodicity} with ${allResult.length} jobs with ${success} success and ${failed} failed`, 132 151 ); 133 152 } 134 - 135 - async function createCronTask({ 136 - monitor, 153 + // timestamp needs to be in ms 154 + const createCronTask = async ({ 155 + row, 137 156 timestamp, 138 157 client, 139 158 parent, 140 159 status, 141 160 region, 142 161 }: { 143 - monitor: z.infer<typeof selectMonitorSchema>; 144 - status: z.infer<typeof monitorStatusSchema>; 145 - /** 146 - * timestamp needs to be in ms 147 - */ 162 + row: z.infer<typeof selectMonitorSchema>; 148 163 timestamp: number; 149 164 client: CloudTasksClient; 150 165 parent: string; 151 - region: string; 152 - }) { 166 + status: MonitorStatus; 167 + region: Region; 168 + }) => { 153 169 let payload: 154 170 | z.infer<typeof httpPayloadSchema> 155 171 | z.infer<typeof tpcPayloadSchema> 156 172 | null = null; 157 - let url: string | null = null; 158 173 159 174 // 160 - if (monitor.jobType === "http") { 175 + if (row.jobType === "http") { 161 176 payload = { 162 - workspaceId: String(monitor.workspaceId), 163 - monitorId: String(monitor.id), 164 - url: monitor.url, 165 - method: monitor.method || "GET", 177 + workspaceId: String(row.workspaceId), 178 + monitorId: String(row.id), 179 + url: row.url, 180 + method: row.method || "GET", 166 181 cronTimestamp: timestamp, 167 - body: monitor.body, 168 - headers: monitor.headers, 182 + body: row.body, 183 + headers: row.headers, 169 184 status: status, 170 - assertions: monitor.assertions ? JSON.parse(monitor.assertions) : null, 171 - degradedAfter: monitor.degradedAfter, 172 - timeout: monitor.timeout, 185 + assertions: row.assertions ? JSON.parse(row.assertions) : null, 186 + degradedAfter: row.degradedAfter, 187 + timeout: row.timeout, 173 188 trigger: "cron", 174 - retry: monitor.retry || 3, 175 - followRedirects: true, 176 - } satisfies z.infer<typeof httpPayloadSchema>; 177 - url = `https://openstatus-checker.fly.dev/checker/http?monitor_id=${monitor.id}`; 189 + otelConfig: row.otelEndpoint 190 + ? { 191 + endpoint: row.otelEndpoint, 192 + headers: transformHeaders(row.otelHeaders), 193 + } 194 + : undefined, 195 + retry: row.retry || 3, 196 + followRedirects: row.followRedirects || true, 197 + }; 178 198 } 179 - if (monitor.jobType === "tcp") { 199 + if (row.jobType === "tcp") { 180 200 payload = { 181 - workspaceId: String(monitor.workspaceId), 182 - monitorId: String(monitor.id), 183 - uri: monitor.url, 201 + workspaceId: String(row.workspaceId), 202 + monitorId: String(row.id), 203 + uri: row.url, 184 204 status: status, 185 - assertions: monitor.assertions ? JSON.parse(monitor.assertions) : null, 205 + assertions: row.assertions ? JSON.parse(row.assertions) : null, 186 206 cronTimestamp: timestamp, 187 - degradedAfter: monitor.degradedAfter, 188 - timeout: monitor.timeout, 207 + degradedAfter: row.degradedAfter, 208 + timeout: row.timeout, 189 209 trigger: "cron", 190 - retry: monitor.retry || 3, 191 - } satisfies z.infer<typeof tpcPayloadSchema>; 192 - url = `https://openstatus-checker.fly.dev/checker/tcp?monitor_id=${monitor.id}`; 210 + retry: row.retry || 3, 211 + otelConfig: row.otelEndpoint 212 + ? { 213 + endpoint: row.otelEndpoint, 214 + headers: transformHeaders(row.otelHeaders), 215 + } 216 + : undefined, 217 + }; 193 218 } 194 219 195 - if (!payload || !url) { 220 + if (!payload) { 196 221 throw new Error("Invalid jobType"); 197 222 } 198 - 223 + const regionInfo = regionDict[region]; 224 + let regionHeader = {}; 225 + if (regionInfo.provider === "fly") { 226 + regionHeader = { "fly-prefer-region": region }; 227 + } 228 + if (regionInfo.provider === "koyeb") { 229 + regionHeader = { "X-KOYEB-REGION-OVERRIDE": region.replace("koyeb_", "") }; 230 + } 231 + if (regionInfo.provider === "railway") { 232 + regionHeader = { "railway-region": region.replace("railway_", "") }; 233 + } 199 234 const newTask: google.cloud.tasks.v2beta3.ITask = { 200 235 httpRequest: { 201 236 headers: { 202 237 "Content-Type": "application/json", // Set content type to ensure compatibility your application's request parsing 203 - "fly-prefer-region": region, // Specify the region you want the request to be sent to 238 + ...regionHeader, 204 239 Authorization: `Basic ${env().CRON_SECRET}`, 205 240 }, 206 241 httpMethod: "POST", 207 - url, 242 + url: generateUrl({ row, region }), 208 243 body: Buffer.from(JSON.stringify(payload)).toString("base64"), 209 244 }, 210 245 scheduleTime: { ··· 214 249 215 250 const request = { parent: parent, task: newTask }; 216 251 return client.createTask(request); 252 + }; 253 + 254 + function generateUrl({ 255 + row, 256 + region, 257 + }: { 258 + row: z.infer<typeof selectMonitorSchema>; 259 + region: Region; 260 + }) { 261 + const regionInfo = regionDict[region]; 262 + 263 + switch (regionInfo.provider) { 264 + case "fly": 265 + return `https://openstatus-checker.fly.dev/checker/${row.jobType}?monitor_id=${row.id}`; 266 + case "koyeb": 267 + return `https://openstatus-checker.koyeb.app/checker/${row.jobType}?monitor_id=${row.id}`; 268 + case "railway": 269 + return `https://railway-proxy-production-9cb1.up.railway.app/checker/${row.jobType}?monitor_id=${row.id}`; 270 + 271 + default: 272 + throw new Error("Invalid jobType"); 273 + } 217 274 }
+2 -1
apps/workflows/src/cron/emails.ts
··· 1 1 import { and, gte, lte } from "@openstatus/db"; 2 - import { db } from "@openstatus/db/src/db"; 2 + import { db } from "@openstatus/db"; 3 3 import { user } from "@openstatus/db/src/schema"; 4 4 import { EmailClient } from "@openstatus/emails"; 5 5 import { env } from "../env"; 6 + // import { db } from "../lib/db"; 6 7 7 8 const email = new EmailClient({ apiKey: env().RESEND_API_KEY }); 8 9
+2 -1
apps/workflows/src/cron/monitor.ts
··· 2 2 import type { google } from "@google-cloud/tasks/build/protos/protos"; 3 3 import { 4 4 and, 5 - db, 5 + // db, 6 6 desc, 7 7 eq, 8 8 isNull, ··· 21 21 import { RateLimiter } from "limiter"; 22 22 import { z } from "zod"; 23 23 import { env } from "../env"; 24 + import { db } from "../lib/db"; 24 25 25 26 const redis = Redis.fromEnv(); 26 27
+19
apps/workflows/src/lib/db.ts
··· 1 + import { drizzle } from "drizzle-orm/libsql"; 2 + 3 + import { createClient } from "@libsql/client"; 4 + import { schema } from "@openstatus/db"; 5 + import { env } from "../env"; 6 + 7 + const file = 8 + env().NODE_ENV === "development" ? "dev.db" : "/app/data/replica.db"; 9 + const client = createClient({ 10 + url: `file:${file}`, 11 + syncUrl: env().DATABASE_URL, 12 + authToken: env().DATABASE_AUTH_TOKEN, 13 + syncInterval: 60, 14 + }); 15 + 16 + export const db = drizzle({ 17 + client: client, 18 + schema, 19 + });
+59
docker-compose.yaml
··· 1 + services: 2 + internal-server: 3 + build: 4 + context: . 5 + dockerfile: apps/workflows/Dockerfile 6 + environment: 7 + - DATABASE_URL=http://libsql:8080 8 + - DATABASE_AUTH_TOKEN="basic:token" 9 + - RESEND_API_KEY=test 10 + - UPSTASH_REDIS_REST_URL=test 11 + - UPSTASH_REDIS_REST_TOKEN=test 12 + - NODE_ENV=production 13 + - GCP_PROJECT_ID=test 14 + extra_hosts: 15 + - "host.docker.internal:host-gateway" 16 + 17 + ports: 18 + - 3000:3000 19 + volumes: 20 + - type: bind 21 + source: ./data 22 + target: /app/data 23 + image: workflows-test 24 + command: . 25 + libsql: 26 + image: ghcr.io/tursodatabase/libsql-server:latest 27 + ports: 28 + - 8080:8080 29 + - 5001:5001 30 + api: 31 + build: 32 + context: . 33 + dockerfile: apps/server/Dockerfile 34 + ports: 35 + - 3001:3000 36 + image: server 37 + environment: 38 + - DATABASE_URL=http://libsql-1:8080 39 + - DATABASE_AUTH_TOKEN="basic:token" 40 + - UPSTASH_REDIS_REST_URL=test 41 + - UPSTASH_REDIS_REST_TOKEN=test 42 + - NODE_ENV=production 43 + - NEXT_PUBLIC_OPENPANEL_CLIENT_ID=test 44 + - OPENPANEL_CLIENT_SECRET=test 45 + - RESEND_API_KEY=test 46 + command: . 47 + # dashboard: 48 + # build: 49 + # context: . 50 + # dockerfile: apps/dashboard/Dockerfile 51 + # ports: 52 + # - 3002:3000 53 + # image: dashboard 54 + # environment: 55 + # - API_URL=http://host.docker.internal:3001 56 + # - NEXT_PUBLIC_OPENPANEL_CLIENT_ID=test 57 + # - OPENPANEL_CLIENT_SECRET=test 58 + # - NODE_ENV=production 59 + # command: .
+1 -1
packages/db/package.json
··· 13 13 "dev": "turso dev --db-file ../../openstatus-dev.db" 14 14 }, 15 15 "dependencies": { 16 - "@libsql/client": "0.15.14", 16 + "@libsql/client": "0.15.15", 17 17 "@openstatus/assertions": "workspace:*", 18 18 "@openstatus/regions": "workspace:*", 19 19 "@t3-oss/env-core": "0.7.1",
+2
packages/db/src/index.ts
··· 2 2 export * from "drizzle-orm"; 3 3 export * from "./db"; 4 4 export * from "./utils"; 5 + // doing this because the external module not working see : https://github.com/vercel/next.js/issues/43433 6 + // export * from "./sync-db";
+17
packages/db/src/sync-db.ts
··· 1 + import { drizzle } from "drizzle-orm/libsql"; 2 + 3 + import { createClient } from "@libsql/client"; 4 + import { env } from "../env.mjs"; 5 + import * as schema from "./schema"; 6 + 7 + const client = createClient({ 8 + url: "file:/app/data/replica.db", 9 + syncUrl: env.DATABASE_URL, 10 + authToken: env.DATABASE_AUTH_TOKEN, 11 + syncInterval: 60, 12 + }); 13 + 14 + export const syncDB = drizzle({ 15 + client: client, 16 + schema, 17 + });
+129 -8
pnpm-lock.yaml
··· 27 27 specifier: 5.7.2 28 28 version: 5.7.2 29 29 30 + apps/build-docker: 31 + dependencies: 32 + '@libsql/client': 33 + specifier: 0.15.15 34 + version: 0.15.15(bufferutil@4.0.8)(utf-8-validate@6.0.5) 35 + 30 36 apps/dashboard: 31 37 dependencies: 32 38 '@auth/core': ··· 1088 1094 '@hono/sentry': 1089 1095 specifier: 1.2.2 1090 1096 version: 1.2.2(hono@4.5.3) 1097 + '@libsql/client': 1098 + specifier: 0.15.15 1099 + version: 0.15.15(bufferutil@4.0.8)(utf-8-validate@6.0.5) 1091 1100 '@openstatus/db': 1092 1101 specifier: workspace:* 1093 1102 version: link:../../packages/db ··· 1118 1127 '@openstatus/notification-webhook': 1119 1128 specifier: workspace:* 1120 1129 version: link:../../packages/notifications/webhook 1130 + '@openstatus/regions': 1131 + specifier: workspace:* 1132 + version: link:../../packages/regions 1121 1133 '@openstatus/tinybird': 1122 1134 specifier: workspace:* 1123 1135 version: link:../../packages/tinybird ··· 1130 1142 '@upstash/qstash': 1131 1143 specifier: 2.6.2 1132 1144 version: 2.6.2 1145 + drizzle-orm: 1146 + specifier: 0.44.4 1147 + version: 0.44.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.15.15(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(better-sqlite3@11.7.0)(bun-types@1.2.22(@types/react@19.2.2)) 1133 1148 hono: 1134 1149 specifier: 4.5.3 1135 1150 version: 4.5.3 ··· 1273 1288 packages/db: 1274 1289 dependencies: 1275 1290 '@libsql/client': 1276 - specifier: 0.15.14 1277 - version: 0.15.14(bufferutil@4.0.8)(utf-8-validate@6.0.5) 1291 + specifier: 0.15.15 1292 + version: 0.15.15(bufferutil@4.0.8)(utf-8-validate@6.0.5) 1278 1293 '@openstatus/assertions': 1279 1294 specifier: workspace:* 1280 1295 version: link:../assertions ··· 1286 1301 version: 0.7.1(typescript@5.7.2)(zod@3.24.2) 1287 1302 drizzle-orm: 1288 1303 specifier: 0.44.4 1289 - version: 0.44.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.15.14(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(better-sqlite3@11.7.0)(bun-types@1.2.22(@types/react@19.2.2)) 1304 + version: 0.44.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.15.15(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(better-sqlite3@11.7.0)(bun-types@1.2.22(@types/react@19.2.2)) 1290 1305 drizzle-zod: 1291 1306 specifier: 0.5.1 1292 - version: 0.5.1(drizzle-orm@0.44.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.15.14(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(better-sqlite3@11.7.0)(bun-types@1.2.22(@types/react@19.2.2)))(zod@3.24.2) 1307 + version: 0.5.1(drizzle-orm@0.44.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.15.15(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(better-sqlite3@11.7.0)(bun-types@1.2.22(@types/react@19.2.2)))(zod@3.24.2) 1293 1308 zod: 1294 1309 specifier: 3.24.2 1295 1310 version: 3.24.2 ··· 3609 3624 '@libsql/client@0.15.14': 3610 3625 resolution: {integrity: sha512-oXeFYcSyAsYWvpWVmynrwNwb+NHNHtMfSIVdfQTF1B9RsgDXQE5YCDP3SS0i1FA8nuLWy2trFDVwP1b2LNdNPQ==} 3611 3626 3627 + '@libsql/client@0.15.15': 3628 + resolution: {integrity: sha512-twC0hQxPNHPKfeOv3sNT6u2pturQjLcI+CnpTM0SjRpocEGgfiZ7DWKXLNnsothjyJmDqEsBQJ5ztq9Wlu470w==} 3629 + 3612 3630 '@libsql/client@0.15.9': 3613 3631 resolution: {integrity: sha512-VT3do0a0vwYVaNcp/y05ikkKS3OrFR5UeEf5SUuYZVgKVl1Nc1k9ajoYSsOid8AD/vlhLDB5yFQaV4HmT/OB9w==} 3614 3632 ··· 3623 3641 cpu: [arm64] 3624 3642 os: [darwin] 3625 3643 3644 + '@libsql/darwin-arm64@0.5.22': 3645 + resolution: {integrity: sha512-4B8ZlX3nIDPndfct7GNe0nI3Yw6ibocEicWdC4fvQbSs/jdq/RC2oCsoJxJ4NzXkvktX70C1J4FcmmoBy069UA==} 3646 + cpu: [arm64] 3647 + os: [darwin] 3648 + 3626 3649 '@libsql/darwin-x64@0.5.20': 3627 3650 resolution: {integrity: sha512-19l0oEW/r2kZxDJg+w53C0kq7eFFKpeKDEjV/FAAkBfQwJoGqS4sep9u1fK1X3KzOF5rB8cVyIrQGk+6ibzUeQ==} 3628 3651 cpu: [x64] 3629 3652 os: [darwin] 3630 3653 3654 + '@libsql/darwin-x64@0.5.22': 3655 + resolution: {integrity: sha512-ny2HYWt6lFSIdNFzUFIJ04uiW6finXfMNJ7wypkAD8Pqdm6nAByO+Fdqu8t7sD0sqJGeUCiOg480icjyQ2/8VA==} 3656 + cpu: [x64] 3657 + os: [darwin] 3658 + 3631 3659 '@libsql/hrana-client@0.7.0': 3632 3660 resolution: {integrity: sha512-OF8fFQSkbL7vJY9rfuegK1R7sPgQ6kFMkDamiEccNUvieQ+3urzfDFI616oPl8V7T9zRmnTkSjMOImYCAVRVuw==} 3633 3661 ··· 3643 3671 cpu: [arm] 3644 3672 os: [linux] 3645 3673 3674 + '@libsql/linux-arm-gnueabihf@0.5.22': 3675 + resolution: {integrity: sha512-3Uo3SoDPJe/zBnyZKosziRGtszXaEtv57raWrZIahtQDsjxBVjuzYQinCm9LRCJCUT5t2r5Z5nLDPJi2CwZVoA==} 3676 + cpu: [arm] 3677 + os: [linux] 3678 + 3646 3679 '@libsql/linux-arm-musleabihf@0.5.20': 3647 3680 resolution: {integrity: sha512-VGqyvg0k3bg0JMMHCR0XrqBseFU9syWRxEbC0Aluipkw5Xsb+DSr9cNvMtGUbGDg2pEfkY/DDa9hTlst6K7P5w==} 3681 + cpu: [arm] 3682 + os: [linux] 3683 + 3684 + '@libsql/linux-arm-musleabihf@0.5.22': 3685 + resolution: {integrity: sha512-LCsXh07jvSojTNJptT9CowOzwITznD+YFGGW+1XxUr7fS+7/ydUrpDfsMX7UqTqjm7xG17eq86VkWJgHJfvpNg==} 3648 3686 cpu: [arm] 3649 3687 os: [linux] 3650 3688 ··· 3653 3691 cpu: [arm64] 3654 3692 os: [linux] 3655 3693 3694 + '@libsql/linux-arm64-gnu@0.5.22': 3695 + resolution: {integrity: sha512-KSdnOMy88c9mpOFKUEzPskSaF3VLflfSUCBwas/pn1/sV3pEhtMF6H8VUCd2rsedwoukeeCSEONqX7LLnQwRMA==} 3696 + cpu: [arm64] 3697 + os: [linux] 3698 + 3656 3699 '@libsql/linux-arm64-musl@0.5.20': 3657 3700 resolution: {integrity: sha512-Xb112/q3/Z6lKKhwJgR2QVRYtRQblEB69VbStIVjKKw5RZv+r77ZSOHfsR3RHL+R66VN431+DLJBV0+B+AImQw==} 3658 3701 cpu: [arm64] 3659 3702 os: [linux] 3660 3703 3704 + '@libsql/linux-arm64-musl@0.5.22': 3705 + resolution: {integrity: sha512-mCHSMAsDTLK5YH//lcV3eFEgiR23Ym0U9oEvgZA0667gqRZg/2px+7LshDvErEKv2XZ8ixzw3p1IrBzLQHGSsw==} 3706 + cpu: [arm64] 3707 + os: [linux] 3708 + 3661 3709 '@libsql/linux-x64-gnu@0.5.20': 3662 3710 resolution: {integrity: sha512-fHUaOYx7cVqbqPLqOIArfPsuWnu+jk9ETR0gt/8rH1J6pW5qhdDWn3B35Hk/ZmzNacBFSWZnHxxhWnZMWYVnVA==} 3663 3711 cpu: [x64] 3664 3712 os: [linux] 3665 3713 3714 + '@libsql/linux-x64-gnu@0.5.22': 3715 + resolution: {integrity: sha512-kNBHaIkSg78Y4BqAdgjcR2mBilZXs4HYkAmi58J+4GRwDQZh5fIUWbnQvB9f95DkWUIGVeenqLRFY2pcTmlsew==} 3716 + cpu: [x64] 3717 + os: [linux] 3718 + 3666 3719 '@libsql/linux-x64-musl@0.5.20': 3667 3720 resolution: {integrity: sha512-EpT1Va1L/y2w0Sj75lxRmaTyX/MD32eKpZiz++3mrE2zRTYAURo9GEbglvSC6Y5aRnLcHPx6XmR25wigRb8WZg==} 3668 3721 cpu: [x64] 3669 3722 os: [linux] 3670 3723 3724 + '@libsql/linux-x64-musl@0.5.22': 3725 + resolution: {integrity: sha512-UZ4Xdxm4pu3pQXjvfJiyCzZop/9j/eA2JjmhMaAhe3EVLH2g11Fy4fwyUp9sT1QJYR1kpc2JLuybPM0kuXv/Tg==} 3726 + cpu: [x64] 3727 + os: [linux] 3728 + 3671 3729 '@libsql/win32-x64-msvc@0.5.20': 3672 3730 resolution: {integrity: sha512-3/G5/SZWXmOCaNwEwDdiXEpjeY7NGx1khPjON1yi3BViKrb2TJiiHHn6zpCN7+ZWNibQFZylkETSTURRlealNA==} 3673 3731 cpu: [x64] 3674 3732 os: [win32] 3675 3733 3734 + '@libsql/win32-x64-msvc@0.5.22': 3735 + resolution: {integrity: sha512-Fj0j8RnBpo43tVZUVoNK6BV/9AtDUM5S7DF3LB4qTYg1LMSZqi3yeCneUTLJD6XomQJlZzbI4mst89yspVSAnA==} 3736 + cpu: [x64] 3737 + os: [win32] 3738 + 3676 3739 '@mapbox/hast-util-table-cell-style@0.2.0': 3677 3740 resolution: {integrity: sha512-gqaTIGC8My3LVSnU38IwjHVKJC94HSonjvFHDk8/aSrApL8v4uWgm8zJkK7MJIIbHuNOr/+Mv2KkQKcxs6LEZA==} 3678 3741 engines: {node: '>=12'} ··· 8835 8898 8836 8899 libsql@0.5.20: 8837 8900 resolution: {integrity: sha512-hkWCsiwTbNsrKeWqPh91ZZEcLDo0+WUnFv2QzITD33F7Er9KOlr7N2SGfNjAbnkciN+iPJ7g108Jkno1JFmzTw==} 8901 + cpu: [x64, arm64, wasm32, arm] 8902 + os: [darwin, linux, win32] 8903 + 8904 + libsql@0.5.22: 8905 + resolution: {integrity: sha512-NscWthMQt7fpU8lqd7LXMvT9pi+KhhmTHAJWUB/Lj6MWa0MKFv0F2V4C6WKKpjCVZl0VwcDz4nOI3CyaT1DDiA==} 8838 8906 cpu: [x64, arm64, wasm32, arm] 8839 8907 os: [darwin, linux, win32] 8840 8908 ··· 14107 14175 - bufferutil 14108 14176 - utf-8-validate 14109 14177 14178 + '@libsql/client@0.15.15(bufferutil@4.0.8)(utf-8-validate@6.0.5)': 14179 + dependencies: 14180 + '@libsql/core': 0.15.14 14181 + '@libsql/hrana-client': 0.7.0(bufferutil@4.0.8)(utf-8-validate@6.0.5) 14182 + js-base64: 3.7.7 14183 + libsql: 0.5.22 14184 + promise-limit: 2.7.0 14185 + transitivePeerDependencies: 14186 + - bufferutil 14187 + - utf-8-validate 14188 + 14110 14189 '@libsql/client@0.15.9(bufferutil@4.0.8)(utf-8-validate@6.0.5)': 14111 14190 dependencies: 14112 14191 '@libsql/core': 0.15.14 ··· 14128 14207 js-base64: 3.7.7 14129 14208 14130 14209 '@libsql/darwin-arm64@0.5.20': 14210 + optional: true 14211 + 14212 + '@libsql/darwin-arm64@0.5.22': 14131 14213 optional: true 14132 14214 14133 14215 '@libsql/darwin-x64@0.5.20': 14134 14216 optional: true 14135 14217 14218 + '@libsql/darwin-x64@0.5.22': 14219 + optional: true 14220 + 14136 14221 '@libsql/hrana-client@0.7.0(bufferutil@4.0.8)(utf-8-validate@6.0.5)': 14137 14222 dependencies: 14138 14223 '@libsql/isomorphic-fetch': 0.3.1 ··· 14156 14241 '@libsql/linux-arm-gnueabihf@0.5.20': 14157 14242 optional: true 14158 14243 14244 + '@libsql/linux-arm-gnueabihf@0.5.22': 14245 + optional: true 14246 + 14159 14247 '@libsql/linux-arm-musleabihf@0.5.20': 14160 14248 optional: true 14161 14249 14250 + '@libsql/linux-arm-musleabihf@0.5.22': 14251 + optional: true 14252 + 14162 14253 '@libsql/linux-arm64-gnu@0.5.20': 14163 14254 optional: true 14164 14255 14256 + '@libsql/linux-arm64-gnu@0.5.22': 14257 + optional: true 14258 + 14165 14259 '@libsql/linux-arm64-musl@0.5.20': 14166 14260 optional: true 14167 14261 14262 + '@libsql/linux-arm64-musl@0.5.22': 14263 + optional: true 14264 + 14168 14265 '@libsql/linux-x64-gnu@0.5.20': 14169 14266 optional: true 14170 14267 14268 + '@libsql/linux-x64-gnu@0.5.22': 14269 + optional: true 14270 + 14171 14271 '@libsql/linux-x64-musl@0.5.20': 14172 14272 optional: true 14173 14273 14274 + '@libsql/linux-x64-musl@0.5.22': 14275 + optional: true 14276 + 14174 14277 '@libsql/win32-x64-msvc@0.5.20': 14278 + optional: true 14279 + 14280 + '@libsql/win32-x64-msvc@0.5.22': 14175 14281 optional: true 14176 14282 14177 14283 '@mapbox/hast-util-table-cell-style@0.2.0': ··· 18724 18830 transitivePeerDependencies: 18725 18831 - supports-color 18726 18832 18727 - drizzle-orm@0.44.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.15.14(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(better-sqlite3@11.7.0)(bun-types@1.2.22(@types/react@19.2.2)): 18833 + drizzle-orm@0.44.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.15.15(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(better-sqlite3@11.7.0)(bun-types@1.2.22(@types/react@19.2.2)): 18728 18834 optionalDependencies: 18729 18835 '@cloudflare/workers-types': 4.20250303.0 18730 - '@libsql/client': 0.15.14(bufferutil@4.0.8)(utf-8-validate@6.0.5) 18836 + '@libsql/client': 0.15.15(bufferutil@4.0.8)(utf-8-validate@6.0.5) 18731 18837 '@libsql/client-wasm': 0.14.0 18732 18838 '@opentelemetry/api': 1.9.0 18733 18839 '@types/pg': 8.11.10 18734 18840 better-sqlite3: 11.7.0 18735 18841 bun-types: 1.2.22(@types/react@19.2.2) 18736 18842 18737 - drizzle-zod@0.5.1(drizzle-orm@0.44.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.15.14(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(better-sqlite3@11.7.0)(bun-types@1.2.22(@types/react@19.2.2)))(zod@3.24.2): 18843 + drizzle-zod@0.5.1(drizzle-orm@0.44.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.15.15(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(better-sqlite3@11.7.0)(bun-types@1.2.22(@types/react@19.2.2)))(zod@3.24.2): 18738 18844 dependencies: 18739 - drizzle-orm: 0.44.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.15.14(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(better-sqlite3@11.7.0)(bun-types@1.2.22(@types/react@19.2.2)) 18845 + drizzle-orm: 0.44.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.15.15(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(better-sqlite3@11.7.0)(bun-types@1.2.22(@types/react@19.2.2)) 18740 18846 zod: 3.24.2 18741 18847 18742 18848 dset@3.1.4: {} ··· 20190 20296 '@libsql/linux-x64-gnu': 0.5.20 20191 20297 '@libsql/linux-x64-musl': 0.5.20 20192 20298 '@libsql/win32-x64-msvc': 0.5.20 20299 + 20300 + libsql@0.5.22: 20301 + dependencies: 20302 + '@neon-rs/load': 0.0.4 20303 + detect-libc: 2.0.2 20304 + optionalDependencies: 20305 + '@libsql/darwin-arm64': 0.5.22 20306 + '@libsql/darwin-x64': 0.5.22 20307 + '@libsql/linux-arm-gnueabihf': 0.5.22 20308 + '@libsql/linux-arm-musleabihf': 0.5.22 20309 + '@libsql/linux-arm64-gnu': 0.5.22 20310 + '@libsql/linux-arm64-musl': 0.5.22 20311 + '@libsql/linux-x64-gnu': 0.5.22 20312 + '@libsql/linux-x64-musl': 0.5.22 20313 + '@libsql/win32-x64-msvc': 0.5.22 20193 20314 20194 20315 lightningcss-darwin-arm64@1.30.1: 20195 20316 optional: true