migrating more stuff into domain pkg

This commit is contained in:
Devin Zuczek
2026-07-09 00:56:38 -04:00
parent f0a273a3c4
commit 6e9d857ba6
23 changed files with 588 additions and 268 deletions
+1
View File
@@ -15,6 +15,7 @@
"test": "run-vitest"
},
"dependencies": {
"@repo/domain": "workspace:*",
"@repo/hono-helpers": "workspace:*",
"hono": "4.12.27",
"workers-tagged-logger": "1.0.1"
+4 -4
View File
@@ -1,8 +1,6 @@
import { Hono } from 'hono'
import { useWorkersLogger } from 'workers-tagged-logger'
import { logger, withNotFound, withOnError } from '@repo/hono-helpers'
import {
createAccount,
defaultAccount,
@@ -11,11 +9,13 @@ import {
getAccountsByIds,
searchAccounts,
updateAccount,
} from './accounts-db'
} from '@repo/domain'
import { logger, withNotFound, withOnError } from '@repo/hono-helpers'
import { validateAndGetAccountId } from './jwt'
import type { Context } from 'hono'
import type { Account } from './accounts-db'
import type { Account } from '@repo/domain'
import type { App } from './context'
/**
@@ -4,7 +4,7 @@ import { beforeAll, describe, expect, test } from 'vitest'
import '../../accounts.app'
import { SCHEMA_DDL } from '../../accounts-db'
import { SCHEMA_DDL } from '@repo/domain'
import type { Env } from '../../context'
+2 -2
View File
@@ -243,7 +243,7 @@
"EndTime": null,
"Key": "DataCollection.OneTimeData.Enabled",
"StartTime": null,
"Value": "true"
"Value": "false"
},
{
"EndTime": null,
@@ -279,7 +279,7 @@
"EndTime": null,
"Key": "Debug.TraceProbability",
"StartTime": null,
"Value": "0"
"Value": "1"
},
{
"EndTime": null,
+1 -1
View File
@@ -1,5 +1,5 @@
-- Accounts stored as a JSON blob with generated (virtual) columns for querying.
-- Generated from src/accounts-db.ts (SCHEMA_DDL) — keep in sync.
-- Generated from @repo/domain's accounts-db.ts (SCHEMA_DDL) — keep in sync.
CREATE TABLE IF NOT EXISTS accounts (
data TEXT NOT NULL,
+1 -1
View File
@@ -1,5 +1,5 @@
-- Store the player's avatar (set via the econ worker's /api/avatar/v2/set). It's
-- an opaque JSON payload that isn't queried, so a single nullable TEXT column on
-- the account row suffices. Kept in sync with SCHEMA_DDL in src/accounts-db.ts.
-- the account row suffices. Kept in sync with SCHEMA_DDL in @repo/domain's accounts-db.ts.
ALTER TABLE accounts ADD COLUMN avatar TEXT;
+1
View File
@@ -16,6 +16,7 @@
"test": "run-vitest"
},
"dependencies": {
"@repo/domain": "workspace:*",
"@repo/hono-helpers": "workspace:*",
"hono": "4.12.27",
"workers-tagged-logger": "1.0.1"
-173
View File
@@ -1,173 +0,0 @@
/**
* Account storage on the shared `recflare` D1 database. Each account is a single
* JSON blob in the `data` column; queryable fields (AccountId, Username) are
* SQLite generated (virtual) columns extracted from that JSON and indexed —
* the same JSON-blob pattern the `rooms` worker uses.
*
* The `auth` worker owns this schema/migration (see migrations/0001_accounts.sql,
* applied with its own `migrations_table` so it doesn't clash with the rooms
* migrations that share the database). Other workers bind the table read/write
* and keep these helpers in sync.
*/
/** Schema DDL (mirror of migrations 0001_accounts + 0002_avatar, sans seed INSERTs). */
export const SCHEMA_DDL: string[] = [
`CREATE TABLE IF NOT EXISTS accounts (
data TEXT NOT NULL,
avatar TEXT,
account_id INTEGER GENERATED ALWAYS AS (json_extract(data, '$.accountId')) VIRTUAL,
username_lower TEXT GENERATED ALWAYS AS (lower(json_extract(data, '$.username'))) VIRTUAL
)`,
`CREATE UNIQUE INDEX IF NOT EXISTS idx_accounts_account_id ON accounts (account_id)`,
`CREATE INDEX IF NOT EXISTS idx_accounts_username_lower ON accounts (username_lower)`,
]
/** Client-facing account shape (camelCase, exactly as the client's AccountDTO). */
export interface Account {
accountId: number
username: string
displayName: string
profileImage: string
isJunior: boolean
platforms: number
personalPronouns: number
identityFlags: number
createdAt: string
}
interface AccountRow {
data: string
}
const parseOne = (row: AccountRow | null): Account | null =>
row ? (JSON.parse(row.data) as Account) : null
const parseAll = (rows: AccountRow[]): Account[] => rows.map((r) => JSON.parse(r.data) as Account)
/** Word lists for auto-assigned usernames (players don't pick one on signup). */
const ADJECTIVES = [
'Swift',
'Brave',
'Clever',
'Happy',
'Mighty',
'Lucky',
'Sunny',
'Cosmic',
'Witty',
'Nimble',
'Jolly',
'Bold',
'Gentle',
'Fuzzy',
'Speedy',
'Shiny',
]
const NOUNS = [
'Fox',
'Otter',
'Falcon',
'Panda',
'Tiger',
'Comet',
'Maple',
'Pixel',
'Robin',
'Wolf',
'Koala',
'Dragon',
'Penguin',
'Badger',
'Heron',
'Lynx',
]
/** A random, readable username (e.g. "SwiftFox4821"). */
export function randomUsername(): string {
const adj = ADJECTIVES[Math.floor(Math.random() * ADJECTIVES.length)]
const noun = NOUNS[Math.floor(Math.random() * NOUNS.length)]
const n = Math.floor(Math.random() * 10000)
return `${adj}${noun}${n}`
}
/**
* Build a full account object from an id, applying default fallbacks for any
* column the caller doesn't override. Used both to synthesize accounts that
* aren't in the DB and as the base for a freshly created account.
*/
export function defaultAccount(id: number, overrides: Partial<Account> = {}): Account {
return {
accountId: id,
username: `Player${id}`,
displayName: `Player${id}`,
profileImage: 'DefaultProfileImage.jpg',
isJunior: false,
platforms: 0,
personalPronouns: 0,
identityFlags: 0,
createdAt: new Date().toISOString(),
...overrides,
}
}
/** Look up a single account by AccountId. */
export async function getAccount(db: D1Database, id: number): Promise<Account | null> {
return parseOne(
await db.prepare('SELECT data FROM accounts WHERE account_id = ?1').bind(id).first<AccountRow>()
)
}
/** Look up multiple accounts by AccountId (order not guaranteed). */
export async function getAccountsByIds(db: D1Database, ids: number[]): Promise<Account[]> {
if (ids.length === 0) return []
const placeholders = ids.map((_, i) => `?${i + 1}`).join(',')
const { results } = await db
.prepare(`SELECT data FROM accounts WHERE account_id IN (${placeholders})`)
.bind(...ids)
.all<AccountRow>()
return parseAll(results)
}
/**
* Create and persist a new account. The id is the next free integer (above the
* seeded system accounts); the username is auto-assigned (players don't choose
* one initially) and the display name defaults to it.
*/
export async function createAccount(
db: D1Database,
overrides: Partial<Account> = {}
): Promise<Account> {
const row = await db
.prepare('SELECT COALESCE(MAX(account_id), 1) + 1 AS next FROM accounts')
.first<{ next: number }>()
const id = row?.next ?? 2
const username = overrides.username ?? randomUsername()
const account = defaultAccount(id, { username, displayName: username, ...overrides })
await db.prepare('INSERT INTO accounts (data) VALUES (?1)').bind(JSON.stringify(account)).run()
return account
}
/**
* Read the account's stored password hash (`salt:hash`), or null when the account
* has none / doesn't exist. Kept in the account JSON blob but out of the public
* account DTO (which projects only known fields), so it never leaks.
*/
export async function getPasswordHash(db: D1Database, id: number): Promise<string | null> {
const row = await db
.prepare(
"SELECT json_extract(data, '$.passwordHash') AS hash FROM accounts WHERE account_id = ?1"
)
.bind(id)
.first<{ hash: string | null }>()
return row?.hash ?? null
}
/** Persist the account's password hash. Returns false when no such account exists. */
export async function setPasswordHash(db: D1Database, id: number, hash: string): Promise<boolean> {
const { meta } = await db
.prepare(
"UPDATE accounts SET data = json_set(data, '$.passwordHash', ?2) WHERE account_id = ?1"
)
.bind(id, hash)
.run()
return meta.changes > 0
}
+24 -4
View File
@@ -1,9 +1,9 @@
import { Hono } from 'hono'
import { useWorkersLogger } from 'workers-tagged-logger'
import { createAccount, getPasswordHash, RoomInstanceType, setPasswordHash } from '@repo/domain'
import { logger, withNotFound, withOnError } from '@repo/hono-helpers'
import { createAccount, getPasswordHash, setPasswordHash } from './accounts-db'
import { generateToken, TOKEN_TTL_SECONDS, validateAndGetAccountId } from './jwt'
import { hashPassword, verifyPassword } from './password'
import { consumeRefreshToken, issueRefreshToken } from './refresh-db'
@@ -65,7 +65,7 @@ async function placeNewPlayerInOrientation(env: App['Bindings'], accountId: numb
roomInstanceId: ORIENTATION_INSTANCE_ID,
roomId: ORIENTATION_ROOM_ID,
subRoomId: num(sub?.SubRoomId, 1),
roomInstanceType: 0,
roomInstanceType: RoomInstanceType.Public,
location: str(sub?.UnitySceneId),
dataBlob: str(sub?.DataBlob),
eventId: 0,
@@ -153,14 +153,23 @@ const app = new Hono<App>()
// Resolve the account this token is for:
// - create_account: mint + persist a brand-new account (auto-assigned random
// username — players don't pick one initially); the token's `sub` is its id.
// A `password` may be posted to establish the account's login credential.
// - refresh_token: redeem a stored (single-use) refresh token for its account +
// platform, so an expiring session renews without re-login.
// - otherwise: the request MUST post a valid account_id — never fall back to a
// stub account (issuing account 1 to anyone would be bad).
// - otherwise: a credential login. The request MUST post a valid account_id AND
// the account's correct `password`. An account with no password set can't be
// logged into by id (no credential to verify) — closing the account_id-only
// takeover. New accounts establish a password via create_account or
// /account/me/changepassword.
let accountId: string
if (grantType === 'create_account') {
const account = await createAccount(c.env.DB, { platforms: platformInt || 0 })
accountId = String(account.accountId)
// Establish the login password when one is posted (raw password never stored).
const password = typeof body.password === 'string' ? body.password : ''
if (password !== '') {
await setPasswordHash(c.env.DB, account.accountId, await hashPassword(password))
}
// Place the new player in Orientation (they don't explicitly matchmake into it).
await placeNewPlayerInOrientation(c.env, account.accountId)
} else if (grantType === 'refresh_token') {
@@ -183,6 +192,17 @@ const app = new Hono<App>()
400
)
}
// The account's password MUST be presented and match. An account with no
// stored hash has no credential to authenticate against, so login by id is
// refused — this closes the account_id-only takeover.
const storedHash = await getPasswordHash(c.env.DB, Number(posted))
const password = typeof body.password === 'string' ? body.password : ''
if (!storedHash || !(await verifyPassword(password, storedHash))) {
return c.json(
{ error: 'invalid_grant', error_description: 'invalid account_id or password' },
400
)
}
accountId = posted
}
+3 -3
View File
@@ -1,7 +1,7 @@
/**
* Password hashing for /account/me/changepassword. PBKDF2-SHA256 with a random
* per-password salt, stored as `salt:hash` (both base64). Not login-critical yet
* (login is account-id based), but we never store the raw password.
* Password hashing for /connect/token credential login and
* /account/me/changepassword. PBKDF2-SHA256 with a random per-password salt,
* stored as `salt:hash` (both base64). The raw password is never persisted.
*/
const ITERATIONS = 100_000
+57 -5
View File
@@ -4,7 +4,9 @@ import { beforeAll, describe, expect, test } from 'vitest'
import '../../auth.app'
import { SCHEMA_DDL } from '../../accounts-db'
import { SCHEMA_DDL } from '@repo/domain'
import { hashPassword } from '../../password'
import { REFRESH_SCHEMA_DDL } from '../../refresh-db'
import type { Env } from '../../context'
@@ -18,6 +20,10 @@ const ORIGIN = 'https://example.com'
// The Orientation room (RoomId 13) new accounts are placed into on signup.
const ORIENTATION_SCENE = 'c79709d8-a31b-48aa-9eb8-cc31ba9505e8'
// Credential login requires the account's password; seed a known one for the
// accounts the login tests authenticate as (42, 77).
const LOGIN_PASSWORD = 'correct-horse'
// Apply the accounts schema so create_account can persist (mirrors the migration),
// and seed the Orientation room (owned by the rooms worker) so signup can place
// the new player there.
@@ -26,6 +32,14 @@ beforeAll(async () => {
await adminSecretsStore(env.JWT_SECRET).create('test-signing-key')
for (const stmt of SCHEMA_DDL) await env.DB.prepare(stmt).run()
for (const stmt of REFRESH_SCHEMA_DDL) await env.DB.prepare(stmt).run()
// Seed the accounts the credential-login tests use, each with LOGIN_PASSWORD set.
const hash = await hashPassword(LOGIN_PASSWORD)
for (const id of [42, 77]) {
await env.DB.prepare('INSERT OR IGNORE INTO accounts (data) VALUES (?1)')
.bind(JSON.stringify({ accountId: id, username: `Player${id}`, passwordHash: hash }))
.run()
}
await env.DB.prepare(
`CREATE TABLE IF NOT EXISTS room (
data TEXT NOT NULL,
@@ -106,7 +120,7 @@ describe('auth worker routes', () => {
const res = await exports.default.fetch(`${ORIGIN}/connect/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'account_id=42&platform_id=steam-123',
body: `account_id=42&platform_id=steam-123&password=${LOGIN_PASSWORD}`,
})
expect(res.status).toBe(200)
const json = (await res.json()) as {
@@ -150,6 +164,42 @@ describe('auth worker routes', () => {
expect(res.status).toBe(400)
})
test('POST /connect/token rejects a credential login with the wrong password', async () => {
const res = await postToken('account_id=42&password=wrong-password')
expect(res.status).toBe(400)
expect(res.json.error).toBe('invalid_grant')
})
test('POST /connect/token rejects a credential login with no password', async () => {
const res = await postToken('account_id=42')
expect(res.status).toBe(400)
expect(res.json.error).toBe('invalid_grant')
})
test('POST /connect/token refuses login to an account with no password set', async () => {
// Account 999 exists but never set a password — it has no credential to verify,
// so login by id alone is refused (this is the closed takeover hole).
await env.DB.prepare('INSERT OR IGNORE INTO accounts (data) VALUES (?1)')
.bind(JSON.stringify({ accountId: 999, username: 'NoPass' }))
.run()
const res = await postToken('account_id=999&password=anything')
expect(res.status).toBe(400)
expect(res.json.error).toBe('invalid_grant')
})
test('POST /connect/token create_account can set a password used for later login', async () => {
const created = await postToken('grant_type=create_account&platform_id=steam-pw2&password=hunter2')
expect(created.status).toBe(200)
const sub = decodePayload(created.json.access_token as string).sub as string
// The password set at creation authenticates a subsequent credential login.
const ok = await postToken(`account_id=${sub}&password=hunter2`)
expect(ok.status).toBe(200)
// A wrong password for that same account is rejected.
const bad = await postToken(`account_id=${sub}&password=nope`)
expect(bad.status).toBe(400)
})
test('POST /connect/token grant_type=create_account persists a new account', async () => {
const payload = await tokenFor('grant_type=create_account&platform_id=steam-123')
// The token's sub is the new account id, allocated above the system accounts.
@@ -180,12 +230,14 @@ describe('auth worker routes', () => {
})
test('POST /connect/token maps the platform int to its enum name', async () => {
const payload = await tokenFor('account_id=42&platform=0')
const payload = await tokenFor(`account_id=42&platform=0&password=${LOGIN_PASSWORD}`)
expect(payload.platform).toBe('Steam')
})
test('POST /connect/token returns a refresh_token that redeems for a new token', async () => {
const login = await postToken('account_id=42&platform=0&platform_id=steam-123')
const login = await postToken(
`account_id=42&platform=0&platform_id=steam-123&password=${LOGIN_PASSWORD}`
)
expect(login.status).toBe(200)
const refreshToken = login.json.refresh_token as string
expect(typeof refreshToken).toBe('string')
@@ -205,7 +257,7 @@ describe('auth worker routes', () => {
})
test('POST /connect/token refresh_token is single-use (rejected on reuse)', async () => {
const login = await postToken('account_id=77&platform=0')
const login = await postToken(`account_id=77&platform=0&password=${LOGIN_PASSWORD}`)
const refreshToken = login.json.refresh_token as string
const first = await postToken(
+1 -1
View File
@@ -6,7 +6,7 @@
*
* The `auth` worker owns the accounts schema/migrations; econ only reads/writes
* the avatar column. SCHEMA_DDL mirrors the table so tests can build it without
* depending on the auth worker — keep it in sync with auth's accounts-db.ts.
* depending on the auth worker — keep it in sync with @repo/domain's accounts-db.ts.
*/
/** Schema DDL for tests — the accounts table including the avatar column. */
+1
View File
@@ -15,6 +15,7 @@
"test": "run-vitest"
},
"dependencies": {
"@repo/domain": "workspace:*",
"@repo/hono-helpers": "workspace:*",
"hono": "4.12.27",
"workers-tagged-logger": "1.0.1"
+3 -2
View File
@@ -1,6 +1,7 @@
import { Hono } from 'hono'
import { useWorkersLogger } from 'workers-tagged-logger'
import { RoomInstanceType } from '@repo/domain'
import { withNotFound, withOnError } from '@repo/hono-helpers'
import { validateAndGetAccountId } from './jwt'
@@ -149,7 +150,7 @@ function dormRoomInstance() {
roomInstanceId: 1,
roomId: 1,
subRoomId: 1,
roomInstanceType: 2,
roomInstanceType: RoomInstanceType.Dormroom,
location: '76d98498-60a1-430c-ab76-b54a29b7a163',
dataBlob: '',
eventId: 0,
@@ -189,7 +190,7 @@ function instanceFieldsFromRoom(room: Room) {
dataBlob: str(sub?.DataBlob),
name,
maxCapacity: num(sub?.MaxPlayers, 4),
roomInstanceType: room.IsDorm === true ? 2 : 0,
roomInstanceType: room.IsDorm === true ? RoomInstanceType.Dormroom : RoomInstanceType.Public,
isDorm: room.IsDorm === true,
}
}
+4 -2
View File
@@ -6,6 +6,8 @@
* sync with the rooms worker's.
*/
import { Accessibility, Role } from '@repo/domain'
/** A stored room — the parsed JSON blob (full client-facing room response). */
export type Room = Record<string, unknown>
@@ -84,12 +86,12 @@ export async function getOrCreateDormRoom(db: D1Database, accountId: number): Pr
const username = (await getUsername(db, accountId)) ?? `Player${accountId}`
const room: Room = {
...(template ?? { Accessibility: 2 }),
...(template ?? { Accessibility: Accessibility.Unlisted }),
RoomId: roomId,
Name: `@${username}'s Dorm`,
CreatorAccountId: accountId,
IsDorm: true,
Roles: [{ AccountId: accountId, Role: 255, LastChangedByAccountId: null, InvitedRole: 0 }],
Roles: [{ AccountId: accountId, Role: Role.Owner, LastChangedByAccountId: null, InvitedRole: 0 }],
SubRooms: [{ ...templateSub, CreatorAccountId: accountId }],
CreatedAt: new Date().toISOString(),
}
+5
View File
@@ -0,0 +1,5 @@
# domain
Shared domain enums and constants for the recflare workers. Single source of
truth for the numeric values the client (and our D1 JSON blobs) encode, so the
same magic numbers aren't re-hardcoded per worker.
+17
View File
@@ -0,0 +1,17 @@
{
"name": "@repo/domain",
"version": "0.1.0",
"private": true,
"sideEffects": false,
"type": "module",
"main": "src/index.ts",
"scripts": {
"check:lint": "run-oxlint",
"check:types": "run-tsc"
},
"devDependencies": {
"@cloudflare/workers-types": "4.20260630.1",
"@repo/tools": "workspace:*",
"@repo/typescript-config": "workspace:*"
}
}
@@ -4,10 +4,11 @@
* SQLite generated (virtual) columns extracted from that JSON and indexed
* the same JSON-blob pattern the `rooms` worker uses.
*
* The `auth` worker owns this schema/migration (see migrations/0001_accounts.sql,
* applied with its own `migrations_table` so it doesn't clash with the rooms
* migrations that share the database). Other workers bind the table read/write
* and keep these helpers in sync.
* The `auth` worker owns this schema/migration (see apps/auth/migrations/
* 0001_accounts.sql, applied with its own `migrations_table` so it doesn't clash
* with the rooms migrations that share the database). This module is the single
* source of truth for the helpers; the `auth` and `accounts` workers both import
* it from `@repo/domain` (each uses the subset it needs).
*/
/** Schema DDL (mirror of migrations 0001_accounts + 0002_avatar, sans seed INSERTs). */
@@ -41,6 +42,12 @@ export interface Account {
bio?: string
/** Remaining username changes; decremented by PUT /account/me/username. */
availableUsernameChanges?: number
/**
* PBKDF2 `salt:hash` for credential login; set via /account/me/changepassword
* or create_account. Kept in the JSON blob but never projected into a public
* DTO (the DTO builders pick only known fields), so it doesn't leak.
*/
passwordHash?: string
}
interface AccountRow {
@@ -217,3 +224,29 @@ export async function createAccount(
await db.prepare('INSERT INTO accounts (data) VALUES (?1)').bind(JSON.stringify(account)).run()
return account
}
/**
* Read the account's stored password hash (`salt:hash`), or null when the account
* has none / doesn't exist. Kept in the account JSON blob but out of the public
* account DTO (which projects only known fields), so it never leaks.
*/
export async function getPasswordHash(db: D1Database, id: number): Promise<string | null> {
const row = await db
.prepare(
"SELECT json_extract(data, '$.passwordHash') AS hash FROM accounts WHERE account_id = ?1"
)
.bind(id)
.first<{ hash: string | null }>()
return row?.hash ?? null
}
/** Persist the account's password hash. Returns false when no such account exists. */
export async function setPasswordHash(db: D1Database, id: number, hash: string): Promise<boolean> {
const { meta } = await db
.prepare(
"UPDATE accounts SET data = json_set(data, '$.passwordHash', ?2) WHERE account_id = ?1"
)
.bind(id, hash)
.run()
return meta.changes > 0
}
+32
View File
@@ -0,0 +1,32 @@
/**
* Domain enums — the numeric codes the Rec Room client encodes into the room /
* room-instance JSON we store in D1. Single source of truth so workers reference
* a name instead of re-hardcoding the integer. Regular (not `const`) enums, since
* the tsconfig sets `isolatedModules` (which disallows `const enum` across files).
*/
/** The kind of a room instance (live session), matching the client's `RoomInstanceType`. */
export enum RoomInstanceType {
Public = 0,
Private = 1,
Dormroom = 2,
Event = 3,
Meetup = 4,
Clubhouse = 5,
}
/** A room's (or image's) visibility, matching the client's `RoomAccessibility`. */
export enum Accessibility {
Private = 0,
Public = 1,
Unlisted = 2,
}
/**
* A room-role tier (the `Role` byte on a room's `Roles` entries). Named tiers we
* reference by value today — the owner (max byte) and co-owner.
*/
export enum Role {
CoOwner = 30,
Owner = 255,
}
+2
View File
@@ -0,0 +1,2 @@
export { RoomInstanceType, Accessibility, Role } from './enums'
export * from './accounts-db'
+8
View File
@@ -0,0 +1,8 @@
{
"extends": "@repo/typescript-config/workers-lib.json",
// domain has no vitest of its own, so pull in only the D1/Workers ambient types
// (drop @cloudflare/vitest-pool-workers/types that workers-lib.json adds).
"compilerOptions": {
"types": ["@cloudflare/workers-types"]
}
}
+20 -2
View File
@@ -48,11 +48,24 @@ HOST="$SUBDOMAIN.$DOMAIN"
# Secrets Store — RECFLARE_SECRETS_STORE: a single store id (all workers bind the
# one shared store for the JWT signing key).
CONFIG="wrangler.jsonc"
# Workers built with @cloudflare/vite-plugin (e.g. the React SPA in www) emit a
# deploy-ready config into dist/<dir>/ that carries the built worker
# (main: index.js), the resolved assets.directory, and no_bundle. The committed
# wrangler.jsonc leaves assets.directory out on purpose — the plugin fills it in —
# so deploying the source config fails with "assets ... missing the required
# directory property". Prefer the generated config when it exists. These workers
# have no D1/KV/Secrets bindings, so the id-splicing below is skipped.
VITE_CONFIG="dist/$DIR/wrangler.json"
if [ -f "$VITE_CONFIG" ]; then
CONFIG="$VITE_CONFIG"
fi
NEEDS_D1=$(grep -q '"database_id": *"local"' wrangler.jsonc 2>/dev/null && echo 1 || true)
NEEDS_KV=$(grep -q '"id": *"local"' wrangler.jsonc 2>/dev/null && echo 1 || true)
NEEDS_STORE=$(grep -q '"store_id": *"local"' wrangler.jsonc 2>/dev/null && echo 1 || true)
if [ -n "$NEEDS_D1" ] || [ -n "$NEEDS_KV" ] || [ -n "$NEEDS_STORE" ]; then
if [ "$CONFIG" = "wrangler.jsonc" ] && { [ -n "$NEEDS_D1" ] || [ -n "$NEEDS_KV" ] || [ -n "$NEEDS_STORE" ]; }; then
CONFIG="wrangler.generated.jsonc"
# Generated alongside the original so its relative paths (main, migrations_dir)
# still resolve. Gitignored; removed on exit so `wrangler dev` is unaffected.
@@ -116,6 +129,11 @@ if [ -n "$NEEDS_D1" ] || [ -n "$NEEDS_KV" ] || [ -n "$NEEDS_STORE" ]; then
fi
fi
# Vite-built configs set no_bundle (vite already bundled and minified), which is
# incompatible with --minify. Only pass --minify when wrangler does the bundling.
MINIFY="--minify"
[ "$CONFIG" = "$VITE_CONFIG" ] && MINIFY=""
# Deploy with wrangler using the extracted values as binding variables
echo "Deploying worker $NAME version $VERSION to $HOST"
wrangler deploy \
@@ -124,5 +142,5 @@ wrangler deploy \
--var SENTRY_RELEASE:"$VERSION" \
--var DOMAIN:"$DOMAIN" \
--domain "$HOST" \
--minify \
$MINIFY \
"$@"
+363 -63
View File
@@ -10,7 +10,7 @@ importers:
devDependencies:
'@babel/plugin-transform-explicit-resource-management':
specifier: 8.0.1
version: 8.0.1(@babel/core@7.28.5)
version: 8.0.1(@babel/core@7.29.7)
'@ianvs/prettier-plugin-sort-imports':
specifier: 4.7.1
version: 4.7.1(prettier@3.9.4)
@@ -49,10 +49,13 @@ importers:
version: 6.0.3
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
apps/accounts:
dependencies:
'@repo/domain':
specifier: workspace:*
version: link:../../packages/domain
'@repo/hono-helpers':
specifier: workspace:*
version: link:../../packages/hono-helpers
@@ -65,7 +68,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -77,7 +80,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
@@ -96,7 +99,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -108,13 +111,16 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
apps/auth:
dependencies:
'@repo/domain':
specifier: workspace:*
version: link:../../packages/domain
'@repo/hono-helpers':
specifier: workspace:*
version: link:../../packages/hono-helpers
@@ -127,7 +133,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -139,7 +145,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
@@ -158,7 +164,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -170,7 +176,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
@@ -189,7 +195,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -201,7 +207,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
@@ -220,7 +226,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -232,7 +238,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
@@ -251,7 +257,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -263,7 +269,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
@@ -282,7 +288,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -294,7 +300,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
@@ -316,7 +322,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -328,13 +334,16 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
apps/match:
dependencies:
'@repo/domain':
specifier: workspace:*
version: link:../../packages/domain
'@repo/hono-helpers':
specifier: workspace:*
version: link:../../packages/hono-helpers
@@ -347,7 +356,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -359,7 +368,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
@@ -378,7 +387,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -390,7 +399,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
@@ -409,7 +418,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -421,7 +430,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
@@ -440,7 +449,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -452,7 +461,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
@@ -471,7 +480,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -483,7 +492,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
@@ -502,7 +511,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
@@ -514,11 +523,75 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
apps/www:
dependencies:
'@repo/hono-helpers':
specifier: workspace:*
version: link:../../packages/hono-helpers
hono:
specifier: 4.12.27
version: 4.12.27
react:
specifier: 19.2.7
version: 19.2.7
react-dom:
specifier: 19.2.7
version: 19.2.7(react@19.2.7)
workers-tagged-logger:
specifier: 1.0.1
version: 1.0.1
devDependencies:
'@cloudflare/vite-plugin':
specifier: 1.42.0
version: 1.42.0(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))(workerd@1.20260625.1)(wrangler@4.105.0(@cloudflare/workers-types@4.20260630.1))
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@repo/tools':
specifier: workspace:*
version: link:../../packages/tools
'@repo/typescript-config':
specifier: workspace:*
version: link:../../packages/typescript-config
'@types/node':
specifier: 26.0.1
version: 26.0.1
'@types/react':
specifier: 19.2.17
version: 19.2.17
'@types/react-dom':
specifier: 19.2.3
version: 19.2.3(@types/react@19.2.17)
'@vitejs/plugin-react':
specifier: 5.2.0
version: 5.2.0(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
vite:
specifier: 6.4.3
version: 6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler:
specifier: 4.105.0
version: 4.105.0(@cloudflare/workers-types@4.20260630.1)
packages/domain:
devDependencies:
'@cloudflare/workers-types':
specifier: 4.20260630.1
version: 4.20260630.1
'@repo/tools':
specifier: workspace:*
version: link:../tools
'@repo/typescript-config':
specifier: workspace:*
version: link:../typescript-config
packages/hono-helpers:
dependencies:
'@hono/standard-validator':
@@ -539,7 +612,7 @@ importers:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: 0.16.20
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
version: 0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))
'@cloudflare/workers-types':
specifier: 4.20260630.1
version: 4.20260630.1
@@ -551,7 +624,7 @@ importers:
version: link:../typescript-config
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
packages/oxlint-config:
dependencies:
@@ -567,7 +640,7 @@ importers:
version: 26.0.1
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
packages/tools:
dependencies:
@@ -625,7 +698,7 @@ importers:
version: 1.3.14
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
packages/typescript-config: {}
@@ -655,7 +728,7 @@ importers:
version: link:../tools
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
turbo/generators:
dependencies:
@@ -680,7 +753,7 @@ importers:
version: link:../../packages/typescript-config
vitest:
specifier: 4.1.9
version: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
packages:
@@ -692,8 +765,8 @@ packages:
resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==}
engines: {node: '>=6.9.0'}
'@babel/core@7.28.5':
resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==}
'@babel/core@7.29.7':
resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==}
engines: {node: '>=6.9.0'}
'@babel/generator@7.29.7':
@@ -718,6 +791,10 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0
'@babel/helper-plugin-utils@7.29.7':
resolution: {integrity: sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==}
engines: {node: '>=6.9.0'}
'@babel/helper-plugin-utils@8.0.1':
resolution: {integrity: sha512-3PKFgjTyPlhFhorfP+SjKQxLViIL++zWjFOO4hGriYU+Bsm983DxEM1JmDRJVWXV0O9npu+xXRqz7Pbd3mh70g==}
engines: {node: ^22.18.0 || >=24.11.0}
@@ -757,6 +834,18 @@ packages:
peerDependencies:
'@babel/core': ^8.0.0
'@babel/plugin-transform-react-jsx-self@7.29.7':
resolution: {integrity: sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-transform-react-jsx-source@7.29.7':
resolution: {integrity: sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/template@7.29.7':
resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==}
engines: {node: '>=6.9.0'}
@@ -788,6 +877,13 @@ packages:
workerd:
optional: true
'@cloudflare/vite-plugin@1.42.0':
resolution: {integrity: sha512-U8Bpcn9l10NNCyYo6kMI2RPZhKRWU0i3udrS/+LHHBDSa61Ra6r7OaDY5LnZw86tOC5vZIKRUm5E51MKjOvfwg==}
hasBin: true
peerDependencies:
vite: ^6.1.0 || ^7.0.0 || ^8.0.0
wrangler: ^4.102.0
'@cloudflare/vitest-pool-workers@0.16.20':
resolution: {integrity: sha512-buw0YgsAMT7s60wcmyxbtciEJjMJzKcWzayDMPhWaqMqfQzW+0WPLV67Lobn4C80nkNQhYocEJPnrEhLWnOf+A==}
peerDependencies:
@@ -795,30 +891,60 @@ packages:
'@vitest/snapshot': ^4.1.0
vitest: ^4.1.0
'@cloudflare/workerd-darwin-64@1.20260617.1':
resolution: {integrity: sha512-jWwmgEVVWbsHNrLSNXzwjJaH90VzRxq1cWkQFUidxyeUPnMxemeNE8I9qFAfrpzGgE11e9sKDcE3ettJW08swQ==}
engines: {node: '>=16'}
cpu: [x64]
os: [darwin]
'@cloudflare/workerd-darwin-64@1.20260625.1':
resolution: {integrity: sha512-naCfBv0WnnTQIQPTniqMoUlklOIFjrAcSn1X+IAOhY8aFLF/xGYtFjs1eEE8sFib3ZuChGGpU23FFORVczqr0A==}
engines: {node: '>=16'}
cpu: [x64]
os: [darwin]
'@cloudflare/workerd-darwin-arm64@1.20260617.1':
resolution: {integrity: sha512-LHH7b565g9znfCUOkwbec6FG2rmRbsgCy6aJiU9KN662mNheWl5sw/iKleiFSiljPKQQP3HkjnC/NSkdgi/aSA==}
engines: {node: '>=16'}
cpu: [arm64]
os: [darwin]
'@cloudflare/workerd-darwin-arm64@1.20260625.1':
resolution: {integrity: sha512-jmH6zjp6Wrux46+qtFwDwrj+vd7s5bdwEqeGvdnwE0a4IEeAhKs0L42HQOyID+g5lkrHq9m55+AbhtmRAm63Pw==}
engines: {node: '>=16'}
cpu: [arm64]
os: [darwin]
'@cloudflare/workerd-linux-64@1.20260617.1':
resolution: {integrity: sha512-FMnaAKXe4Cfd8TQurCVd9fs2XQVBFRCsP+Id/SRdUv89MlwYu9zXfoyx6BxM+brPTIUK38SHbo8iaxiwzLi9JQ==}
engines: {node: '>=16'}
cpu: [x64]
os: [linux]
'@cloudflare/workerd-linux-64@1.20260625.1':
resolution: {integrity: sha512-MiQkpA/dX8d83Zp64pzHUKfd6ca4cvwxnNobSP6CnXvfESvnNI9pfa+nfwnParla36sPmnYntNkjR7NjRuDeKQ==}
engines: {node: '>=16'}
cpu: [x64]
os: [linux]
'@cloudflare/workerd-linux-arm64@1.20260617.1':
resolution: {integrity: sha512-MRoifFYcqbxxIIQy7PqO5tFY/qPFSnjXzakWl0sO93l+HLyG35jRAgOi6jfqa4kBxc7gKKtH861DcewjxUfkjA==}
engines: {node: '>=16'}
cpu: [arm64]
os: [linux]
'@cloudflare/workerd-linux-arm64@1.20260625.1':
resolution: {integrity: sha512-LxxW7Qv60Xvv37+w6gUSDpYZziyqMy+cZWd9IvSA5ehVgKAxmzEaYPMiSZlxk32nbIWL9u/tfjXYCOKJ4Lo+XQ==}
engines: {node: '>=16'}
cpu: [arm64]
os: [linux]
'@cloudflare/workerd-windows-64@1.20260617.1':
resolution: {integrity: sha512-rgBV9wQrv0OSKgCTTbhFUFY3sLGNANZ88aqaLvtmEn2gmbFVb1J4PDGochVUdB7NSEp4D/ghHva6/8SZmbONpw==}
engines: {node: '>=16'}
cpu: [x64]
os: [win32]
'@cloudflare/workerd-windows-64@1.20260625.1':
resolution: {integrity: sha512-LH6iIX1HHaTwVKV5VokDxxUErXJzQoNZFRwVm7Vx/3fB/ApcTcRCUaMqcxI4as94jEUqg+pmX5czOndiveohow==}
engines: {node: '>=16'}
@@ -1632,6 +1758,9 @@ packages:
'@poppinss/exception@1.2.2':
resolution: {integrity: sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==}
'@rolldown/pluginutils@1.0.0-rc.3':
resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==}
'@rollup/rollup-android-arm-eabi@4.62.2':
resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==}
cpu: [arm]
@@ -1807,6 +1936,18 @@ packages:
cpu: [arm64]
os: [win32]
'@types/babel__core@7.20.5':
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
'@types/babel__generator@7.27.0':
resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==}
'@types/babel__template@7.4.4':
resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
'@types/babel__traverse@7.28.0':
resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==}
'@types/bun@1.3.14':
resolution: {integrity: sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw==}
@@ -1828,6 +1969,14 @@ packages:
'@types/node@26.0.1':
resolution: {integrity: sha512-fc3KiUoBt6kie0N9bIW3E47vZsuaMf0PM2AaUpLCLT0s/LvX1nxAim6Fc049cNxODPpGm6qRAuUOB86SkRuPQw==}
'@types/react-dom@19.2.3':
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
peerDependencies:
'@types/react': ^19.2.0
'@types/react@19.2.17':
resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==}
'@typescript/native-preview-darwin-arm64@7.0.0-dev.20260629.1':
resolution: {integrity: sha512-wXRExZJweYoTzE4atRR7T5HwKJYkl6/KHxON0eF0iy2fvgLXDlyq4AQqhmV8mMx10PQKc/4sNbfhD4kjWWvm8A==}
engines: {node: '>=16.20.0'}
@@ -1875,6 +2024,12 @@ packages:
engines: {node: '>=16.20.0'}
hasBin: true
'@vitejs/plugin-react@5.2.0':
resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==}
engines: {node: ^20.19.0 || >=22.12.0}
peerDependencies:
vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
'@vitest/expect@4.1.9':
resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==}
@@ -1971,6 +2126,9 @@ packages:
resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
engines: {node: '>=18'}
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
debug@4.4.3:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
engines: {node: '>=6.0'}
@@ -2163,6 +2321,11 @@ packages:
memoize-one@6.0.0:
resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==}
miniflare@4.20260617.0:
resolution: {integrity: sha512-A+H5gcOCQZsKFg7/daZUtx8WHn4gGxwUfH1jnNDAisyAWSvvSZHe+GCeQWs16uthnUDcm72UQIQ1NXDJtnuo9Q==}
engines: {node: '>=22.0.0'}
hasBin: true
miniflare@4.20260625.0:
resolution: {integrity: sha512-3kKXwRUObJsnBYPBgR0NiNZYKF/yv8GFyha1cx2EeAEraxNODgRVcyeRo+F1ok1tg5Mg7iUpOWSkknQTHuFhwA==}
engines: {node: '>=22.0.0'}
@@ -2245,6 +2408,19 @@ packages:
engines: {node: '>=14'}
hasBin: true
react-dom@19.2.7:
resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==}
peerDependencies:
react: ^19.2.7
react-refresh@0.18.0:
resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==}
engines: {node: '>=0.10.0'}
react@19.2.7:
resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==}
engines: {node: '>=0.10.0'}
rollup@4.62.2:
resolution: {integrity: sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
@@ -2253,6 +2429,9 @@ packages:
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
scheduler@0.27.0:
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
@@ -2407,8 +2586,8 @@ packages:
peerDependencies:
browserslist: '>= 4.21.0'
vite@6.3.4:
resolution: {integrity: sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==}
vite@6.4.3:
resolution: {integrity: sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true
peerDependencies:
@@ -2493,6 +2672,11 @@ packages:
engines: {node: '>=8'}
hasBin: true
workerd@1.20260617.1:
resolution: {integrity: sha512-Re5pl6pdowt3ZmWUzGlOuB7jbRIIPetgKalmo4cYmucQnVhpo7/3e4MfpekbhLi2EhZZz5EY9NWRu8zFzuEZew==}
engines: {node: '>=16'}
hasBin: true
workerd@1.20260625.1:
resolution: {integrity: sha512-GApQvFX52SDM6L4u0+RRnUDB1wJOnEwoXjinkmOPtIyofWBxrlZckdegJSYc1leg++lLZ3+DQ4zMVmBqYVtzfA==}
engines: {node: '>=16'}
@@ -2566,12 +2750,12 @@ snapshots:
'@babel/compat-data@7.29.7': {}
'@babel/core@7.28.5':
'@babel/core@7.29.7':
dependencies:
'@babel/code-frame': 7.29.7
'@babel/generator': 7.29.7
'@babel/helper-compilation-targets': 7.29.7
'@babel/helper-module-transforms': 7.29.7(@babel/core@7.28.5)
'@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7)
'@babel/helpers': 7.29.7
'@babel/parser': 7.29.7
'@babel/template': 7.29.7
@@ -2611,18 +2795,20 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@babel/helper-module-transforms@7.29.7(@babel/core@7.28.5)':
'@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)':
dependencies:
'@babel/core': 7.28.5
'@babel/core': 7.29.7
'@babel/helper-module-imports': 7.29.7
'@babel/helper-validator-identifier': 7.29.7
'@babel/traverse': 7.29.7
transitivePeerDependencies:
- supports-color
'@babel/helper-plugin-utils@8.0.1(@babel/core@7.28.5)':
'@babel/helper-plugin-utils@7.29.7': {}
'@babel/helper-plugin-utils@8.0.1(@babel/core@7.29.7)':
dependencies:
'@babel/core': 7.28.5
'@babel/core': 7.29.7
'@babel/helper-string-parser@7.29.7': {}
@@ -2639,16 +2825,26 @@ snapshots:
dependencies:
'@babel/types': 7.29.7
'@babel/plugin-transform-destructuring@8.0.1(@babel/core@7.28.5)':
'@babel/plugin-transform-destructuring@8.0.1(@babel/core@7.29.7)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 8.0.1(@babel/core@7.28.5)
'@babel/core': 7.29.7
'@babel/helper-plugin-utils': 8.0.1(@babel/core@7.29.7)
'@babel/plugin-transform-explicit-resource-management@8.0.1(@babel/core@7.28.5)':
'@babel/plugin-transform-explicit-resource-management@8.0.1(@babel/core@7.29.7)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 8.0.1(@babel/core@7.28.5)
'@babel/plugin-transform-destructuring': 8.0.1(@babel/core@7.28.5)
'@babel/core': 7.29.7
'@babel/helper-plugin-utils': 8.0.1(@babel/core@7.29.7)
'@babel/plugin-transform-destructuring': 8.0.1(@babel/core@7.29.7)
'@babel/plugin-transform-react-jsx-self@7.29.7(@babel/core@7.29.7)':
dependencies:
'@babel/core': 7.29.7
'@babel/helper-plugin-utils': 7.29.7
'@babel/plugin-transform-react-jsx-source@7.29.7(@babel/core@7.29.7)':
dependencies:
'@babel/core': 7.29.7
'@babel/helper-plugin-utils': 7.29.7
'@babel/template@7.29.7':
dependencies:
@@ -2687,14 +2883,27 @@ snapshots:
optionalDependencies:
workerd: 1.20260625.1
'@cloudflare/vitest-pool-workers@0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))':
'@cloudflare/vite-plugin@1.42.0(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))(workerd@1.20260625.1)(wrangler@4.105.0(@cloudflare/workers-types@4.20260630.1))':
dependencies:
'@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260625.1)
miniflare: 4.20260617.0
unenv: 2.0.0-rc.24
vite: 6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)
wrangler: 4.105.0(@cloudflare/workers-types@4.20260630.1)
ws: 8.21.0
transitivePeerDependencies:
- bufferutil
- utf-8-validate
- workerd
'@cloudflare/vitest-pool-workers@0.16.20(@cloudflare/workers-types@4.20260630.1)(@vitest/runner@4.1.9)(@vitest/snapshot@4.1.9)(vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)))':
dependencies:
'@vitest/runner': 4.1.9
'@vitest/snapshot': 4.1.9
cjs-module-lexer: 1.2.3
esbuild: 0.28.1
miniflare: 4.20260625.0
vitest: 4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
vitest: 4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
wrangler: 4.105.0(@cloudflare/workers-types@4.20260630.1)
zod: 3.25.76
transitivePeerDependencies:
@@ -2702,18 +2911,33 @@ snapshots:
- bufferutil
- utf-8-validate
'@cloudflare/workerd-darwin-64@1.20260617.1':
optional: true
'@cloudflare/workerd-darwin-64@1.20260625.1':
optional: true
'@cloudflare/workerd-darwin-arm64@1.20260617.1':
optional: true
'@cloudflare/workerd-darwin-arm64@1.20260625.1':
optional: true
'@cloudflare/workerd-linux-64@1.20260617.1':
optional: true
'@cloudflare/workerd-linux-64@1.20260625.1':
optional: true
'@cloudflare/workerd-linux-arm64@1.20260617.1':
optional: true
'@cloudflare/workerd-linux-arm64@1.20260625.1':
optional: true
'@cloudflare/workerd-windows-64@1.20260617.1':
optional: true
'@cloudflare/workerd-windows-64@1.20260625.1':
optional: true
@@ -3247,6 +3471,8 @@ snapshots:
'@poppinss/exception@1.2.2': {}
'@rolldown/pluginutils@1.0.0-rc.3': {}
'@rollup/rollup-android-arm-eabi@4.62.2':
optional: true
@@ -3359,6 +3585,27 @@ snapshots:
'@turbo/windows-arm64@2.10.1':
optional: true
'@types/babel__core@7.20.5':
dependencies:
'@babel/parser': 7.29.7
'@babel/types': 7.29.7
'@types/babel__generator': 7.27.0
'@types/babel__template': 7.4.4
'@types/babel__traverse': 7.28.0
'@types/babel__generator@7.27.0':
dependencies:
'@babel/types': 7.29.7
'@types/babel__template@7.4.4':
dependencies:
'@babel/parser': 7.29.7
'@babel/types': 7.29.7
'@types/babel__traverse@7.28.0':
dependencies:
'@babel/types': 7.29.7
'@types/bun@1.3.14':
dependencies:
bun-types: 1.3.14
@@ -3385,6 +3632,14 @@ snapshots:
dependencies:
undici-types: 8.3.0
'@types/react-dom@19.2.3(@types/react@19.2.17)':
dependencies:
'@types/react': 19.2.17
'@types/react@19.2.17':
dependencies:
csstype: 3.2.3
'@typescript/native-preview-darwin-arm64@7.0.0-dev.20260629.1':
optional: true
@@ -3416,6 +3671,18 @@ snapshots:
'@typescript/native-preview-win32-arm64': 7.0.0-dev.20260629.1
'@typescript/native-preview-win32-x64': 7.0.0-dev.20260629.1
'@vitejs/plugin-react@5.2.0(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))':
dependencies:
'@babel/core': 7.29.7
'@babel/plugin-transform-react-jsx-self': 7.29.7(@babel/core@7.29.7)
'@babel/plugin-transform-react-jsx-source': 7.29.7(@babel/core@7.29.7)
'@rolldown/pluginutils': 1.0.0-rc.3
'@types/babel__core': 7.20.5
react-refresh: 0.18.0
vite: 6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)
transitivePeerDependencies:
- supports-color
'@vitest/expect@4.1.9':
dependencies:
'@standard-schema/spec': 1.1.0
@@ -3425,13 +3692,13 @@ snapshots:
chai: 6.2.2
tinyrainbow: 3.1.0
'@vitest/mocker@4.1.9(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))':
'@vitest/mocker@4.1.9(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))':
dependencies:
'@vitest/spy': 4.1.9
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
vite: 6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)
vite: 6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)
'@vitest/pretty-format@4.1.9':
dependencies:
@@ -3509,6 +3776,8 @@ snapshots:
cookie@1.0.2: {}
csstype@3.2.3: {}
debug@4.4.3:
dependencies:
ms: 2.1.3
@@ -3685,6 +3954,18 @@ snapshots:
memoize-one@6.0.0: {}
miniflare@4.20260617.0:
dependencies:
'@cspotcode/source-map-support': 0.8.1
sharp: 0.34.5
undici: 7.28.0
workerd: 1.20260617.1
ws: 8.21.0
youch: 4.1.0-beta.10
transitivePeerDependencies:
- bufferutil
- utf-8-validate
miniflare@4.20260625.0:
dependencies:
'@cspotcode/source-map-support': 0.8.1
@@ -3768,6 +4049,15 @@ snapshots:
prettier@3.9.4: {}
react-dom@19.2.7(react@19.2.7):
dependencies:
react: 19.2.7
scheduler: 0.27.0
react-refresh@0.18.0: {}
react@19.2.7: {}
rollup@4.62.2:
dependencies:
'@types/estree': 1.0.9
@@ -3801,6 +4091,8 @@ snapshots:
safer-buffer@2.1.2: {}
scheduler@0.27.0: {}
semver@6.3.1: {}
semver@7.8.5: {}
@@ -3956,7 +4248,7 @@ snapshots:
escalade: 3.2.0
picocolors: 1.1.1
vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0):
vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0):
dependencies:
esbuild: 0.25.12
fdir: 6.5.0(picomatch@4.0.4)
@@ -3972,10 +4264,10 @@ snapshots:
tsx: 4.22.4
yaml: 2.9.0
vitest@4.1.9(@types/node@26.0.1)(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)):
vitest@4.1.9(@types/node@26.0.1)(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)):
dependencies:
'@vitest/expect': 4.1.9
'@vitest/mocker': 4.1.9(vite@6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
'@vitest/mocker': 4.1.9(vite@6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0))
'@vitest/pretty-format': 4.1.9
'@vitest/runner': 4.1.9
'@vitest/snapshot': 4.1.9
@@ -3992,7 +4284,7 @@ snapshots:
tinyexec: 1.2.4
tinyglobby: 0.2.17
tinyrainbow: 3.1.0
vite: 6.3.4(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)
vite: 6.4.3(@types/node@26.0.1)(jiti@2.6.1)(lightningcss@1.29.2)(tsx@4.22.4)(yaml@2.9.0)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 26.0.1
@@ -4004,6 +4296,14 @@ snapshots:
siginfo: 2.0.0
stackback: 0.0.2
workerd@1.20260617.1:
optionalDependencies:
'@cloudflare/workerd-darwin-64': 1.20260617.1
'@cloudflare/workerd-darwin-arm64': 1.20260617.1
'@cloudflare/workerd-linux-64': 1.20260617.1
'@cloudflare/workerd-linux-arm64': 1.20260617.1
'@cloudflare/workerd-windows-64': 1.20260617.1
workerd@1.20260625.1:
optionalDependencies:
'@cloudflare/workerd-darwin-64': 1.20260625.1