chore: add zod-openapi stack, multipart schema, and PUBLIC_BASE_URL

- bump hono to ^4.12.0, add zod ^4.0.0 and @hono/zod-openapi ^1.4.0
- migration 0002: attachment_upload_sessions + attachment_upload_parts
- wrangler/env: PUBLIC_BASE_URL for public file URLs

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude
2026-07-02 09:08:42 -07:00
parent 20666d13e7
commit db5a499e5c
5 changed files with 109 additions and 13 deletions

View File

@@ -0,0 +1,30 @@
-- 0002_upload_sessions.sql — 分片上传会话与分片记录(纯增量,不改既有表)
CREATE TABLE attachment_upload_sessions (
id TEXT PRIMARY KEY,
attachment_id TEXT NOT NULL,
user_id TEXT NOT NULL,
object_key TEXT NOT NULL,
upload_id TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'active',
content_type TEXT NOT NULL,
part_count INTEGER NOT NULL DEFAULT 0,
byte_size INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL,
completed_at TEXT,
aborted_at TEXT
);
CREATE INDEX idx_upload_sessions_active ON attachment_upload_sessions(user_id, attachment_id, status);
CREATE TABLE attachment_upload_parts (
session_id TEXT NOT NULL,
user_id TEXT NOT NULL,
attachment_id TEXT NOT NULL,
part_number INTEGER NOT NULL,
etag TEXT NOT NULL,
byte_size INTEGER NOT NULL,
created_at TEXT NOT NULL,
PRIMARY KEY (session_id, part_number)
);
CREATE INDEX idx_upload_parts_order ON attachment_upload_parts(session_id, part_number);

View File

@@ -14,7 +14,9 @@
"ready": "pnpm typecheck && pnpm test"
},
"dependencies": {
"hono": "^4.8.0"
"@hono/zod-openapi": "^1.4.0",
"hono": "^4.12.0",
"zod": "^4.0.0"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20260601.0",

84
pnpm-lock.yaml generated
View File

@@ -8,9 +8,15 @@ importers:
.:
dependencies:
'@hono/zod-openapi':
specifier: ^1.4.0
version: 1.4.0(hono@4.12.27)(zod@4.4.3)
hono:
specifier: ^4.8.0
specifier: ^4.12.0
version: 4.12.27
zod:
specifier: ^4.0.0
version: 4.4.3
devDependencies:
'@cloudflare/workers-types':
specifier: ^4.20260601.0
@@ -20,13 +26,18 @@ importers:
version: 5.9.3
vitest:
specifier: ^3.2.0
version: 3.2.6
version: 3.2.6(yaml@2.9.0)
wrangler:
specifier: ^4.20.0
version: 4.106.0(@cloudflare/workers-types@4.20260702.1)
packages:
'@asteasolutions/zod-to-openapi@8.5.0':
resolution: {integrity: sha512-SABbKiObg5dLRiTFnqiW1WWwGcg1BJfmHtT2asIBnBHg6Smy/Ms2KHc650+JI4Hw7lSkdiNebEGXpwoxfben8Q==}
peerDependencies:
zod: ^4.0.0
'@cloudflare/kv-asset-handler@0.5.0':
resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==}
engines: {node: '>=22.0.0'}
@@ -236,6 +247,19 @@ packages:
cpu: [x64]
os: [win32]
'@hono/zod-openapi@1.4.0':
resolution: {integrity: sha512-AFchqR1N/NxfI4hUOSGI2/g8zLROxA1OE7Oh5JJFlTaGxhrdRyH+93gd0tIBpb0z8s9r8hUoNnaOBfHbdb4NMw==}
engines: {node: '>=16.0.0'}
peerDependencies:
hono: '>=4.10.0'
zod: ^4.0.0
'@hono/zod-validator@0.8.0':
resolution: {integrity: sha512-5uS4S1/LKtZQYvD4BtpPUFkOv8d1wNxHHrChm26buMiEYc1FrHWvDUaKVBwkiVtvSExHSpLGDvcnpI2Copyj9w==}
peerDependencies:
hono: '>=4.10.0'
zod: ^3.25.0 || ^4.0.0
'@img/colour@1.1.0':
resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
engines: {node: '>=18'}
@@ -693,6 +717,9 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
openapi3-ts@4.6.0:
resolution: {integrity: sha512-a4sfn6L2sIShhtzJqmjGrARvxAW/3F2BJDdyRVvNF9VhAsZSh5hSyI3a9TNvmzBxXmq66nY5LNT5bQcBxYAZZg==}
path-to-regexp@6.3.0:
resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
@@ -890,14 +917,27 @@ packages:
utf-8-validate:
optional: true
yaml@2.9.0:
resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==}
engines: {node: '>= 14.6'}
hasBin: true
youch-core@0.3.3:
resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==}
youch@4.1.0-beta.10:
resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==}
zod@4.4.3:
resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
snapshots:
'@asteasolutions/zod-to-openapi@8.5.0(zod@4.4.3)':
dependencies:
openapi3-ts: 4.6.0
zod: 4.4.3
'@cloudflare/kv-asset-handler@0.5.0': {}
'@cloudflare/unenv-preset@2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260630.1)':
@@ -1010,6 +1050,19 @@ snapshots:
'@esbuild/win32-x64@0.28.1':
optional: true
'@hono/zod-openapi@1.4.0(hono@4.12.27)(zod@4.4.3)':
dependencies:
'@asteasolutions/zod-to-openapi': 8.5.0(zod@4.4.3)
'@hono/zod-validator': 0.8.0(hono@4.12.27)(zod@4.4.3)
hono: 4.12.27
openapi3-ts: 4.6.0
zod: 4.4.3
'@hono/zod-validator@0.8.0(hono@4.12.27)(zod@4.4.3)':
dependencies:
hono: 4.12.27
zod: 4.4.3
'@img/colour@1.1.0': {}
'@img/sharp-darwin-arm64@0.34.5':
@@ -1223,13 +1276,13 @@ snapshots:
chai: 5.3.3
tinyrainbow: 2.0.0
'@vitest/mocker@3.2.6(vite@7.3.6)':
'@vitest/mocker@3.2.6(vite@7.3.6(yaml@2.9.0))':
dependencies:
'@vitest/spy': 3.2.6
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
vite: 7.3.6
vite: 7.3.6(yaml@2.9.0)
'@vitest/pretty-format@3.2.6':
dependencies:
@@ -1357,6 +1410,10 @@ snapshots:
nanoid@3.3.15: {}
openapi3-ts@4.6.0:
dependencies:
yaml: 2.9.0
path-to-regexp@6.3.0: {}
pathe@2.0.3: {}
@@ -1477,13 +1534,13 @@ snapshots:
dependencies:
pathe: 2.0.3
vite-node@3.2.4:
vite-node@3.2.4(yaml@2.9.0):
dependencies:
cac: 6.7.14
debug: 4.4.3
es-module-lexer: 1.7.0
pathe: 2.0.3
vite: 7.3.6
vite: 7.3.6(yaml@2.9.0)
transitivePeerDependencies:
- '@types/node'
- jiti
@@ -1498,7 +1555,7 @@ snapshots:
- tsx
- yaml
vite@7.3.6:
vite@7.3.6(yaml@2.9.0):
dependencies:
esbuild: 0.28.1
fdir: 6.5.0(picomatch@4.0.4)
@@ -1508,12 +1565,13 @@ snapshots:
tinyglobby: 0.2.17
optionalDependencies:
fsevents: 2.3.3
yaml: 2.9.0
vitest@3.2.6:
vitest@3.2.6(yaml@2.9.0):
dependencies:
'@types/chai': 5.2.3
'@vitest/expect': 3.2.6
'@vitest/mocker': 3.2.6(vite@7.3.6)
'@vitest/mocker': 3.2.6(vite@7.3.6(yaml@2.9.0))
'@vitest/pretty-format': 3.2.6
'@vitest/runner': 3.2.6
'@vitest/snapshot': 3.2.6
@@ -1531,8 +1589,8 @@ snapshots:
tinyglobby: 0.2.17
tinypool: 1.1.1
tinyrainbow: 2.0.0
vite: 7.3.6
vite-node: 3.2.4
vite: 7.3.6(yaml@2.9.0)
vite-node: 3.2.4(yaml@2.9.0)
why-is-node-running: 2.3.0
transitivePeerDependencies:
- jiti
@@ -1580,6 +1638,8 @@ snapshots:
ws@8.21.0: {}
yaml@2.9.0: {}
youch-core@0.3.3:
dependencies:
'@poppinss/exception': 1.2.3
@@ -1592,3 +1652,5 @@ snapshots:
'@speed-highlight/core': 1.2.17
cookie: 1.1.1
youch-core: 0.3.3
zod@4.4.3: {}

View File

@@ -7,4 +7,5 @@ export interface Env {
DB: D1Database;
ATTACHMENTS: R2Bucket;
MAX_UPLOAD_BYTES?: string;
PUBLIC_BASE_URL?: string;
}

View File

@@ -35,6 +35,7 @@
}
],
"vars": {
"MAX_UPLOAD_BYTES": "52428800"
"MAX_UPLOAD_BYTES": "52428800",
"PUBLIC_BASE_URL": "https://cfw-attachment.bowong.cc"
}
}