feat(den): document den-api with OpenAPI (#1371)

Generate an OpenAPI spec and Swagger UI from den-api's existing Hono and zod validators so the API stays self-describing. Add route metadata, typed responses, and hide API key creation endpoints from production docs.

Co-authored-by: src-opn <src-opn@users.noreply.github.com>
This commit is contained in:
Source Open
2026-04-06 13:48:10 -07:00
committed by GitHub
parent 4f1905882b
commit d9e5a33e62
22 changed files with 1790 additions and 81 deletions

163
pnpm-lock.yaml generated
View File

@@ -434,15 +434,27 @@ importers:
'@hono/node-server':
specifier: ^1.13.8
version: 1.19.11(hono@4.12.8)
'@hono/zod-validator':
specifier: ^0.7.6
version: 0.7.6(hono@4.12.8)(zod@4.3.6)
'@hono/standard-validator':
specifier: ^0.2.2
version: 0.2.2(@standard-schema/spec@1.1.0)(hono@4.12.8)
'@hono/swagger-ui':
specifier: ^0.6.1
version: 0.6.1(hono@4.12.8)
'@openwork-ee/den-db':
specifier: workspace:*
version: link:../../packages/den-db
'@openwork-ee/utils':
specifier: workspace:*
version: link:../../packages/utils
'@standard-community/standard-json':
specifier: ^0.3.5
version: 0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod@4.3.6)
'@standard-community/standard-openapi':
specifier: ^0.2.9
version: 0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6)
'@standard-schema/spec':
specifier: ^1.1.0
version: 1.1.0
better-auth:
specifier: ^1.5.6
version: 1.5.6(@opentelemetry/api@1.9.0)(drizzle-kit@0.31.9)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@planetscale/database@1.19.0)(bun-types@1.3.6)(kysely@0.28.15)(mysql2@3.17.4))(mysql2@3.17.4)(next@16.2.1(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.10)
@@ -455,10 +467,19 @@ importers:
hono:
specifier: ^4.7.2
version: 4.12.8
hono-openapi:
specifier: ^1.3.0
version: 1.3.0(@hono/standard-validator@0.2.2(@standard-schema/spec@1.1.0)(hono@4.12.8))(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod@4.3.6))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6))(@types/json-schema@7.0.15)(hono@4.12.8)(openapi-types@12.1.3)
openapi-types:
specifier: ^12.1.3
version: 12.1.3
zod:
specifier: ^4.3.6
version: 4.3.6
devDependencies:
'@types/json-schema':
specifier: ^7.0.15
version: 7.0.15
'@types/node':
specifier: ^20.11.30
version: 20.12.12
@@ -1663,11 +1684,16 @@ packages:
peerDependencies:
hono: ^4
'@hono/zod-validator@0.7.6':
resolution: {integrity: sha512-Io1B6d011Gj1KknV4rXYz4le5+5EubcWEU/speUjuw9XMMIaP3n78yXLhjd2A3PXaXaUwEAluOiAyLqhBEJgsw==}
'@hono/standard-validator@0.2.2':
resolution: {integrity: sha512-mJ7W84Bt/rSvoIl63Ynew+UZOHAzzRAoAXb3JaWuxAkM/Lzg+ZHTCUiz77KOtn2e623WNN8LkD57Dk0szqUrIw==}
peerDependencies:
'@standard-schema/spec': ^1.0.0
hono: '>=3.9.0'
zod: ^3.25.0 || ^4.0.0
'@hono/swagger-ui@0.6.1':
resolution: {integrity: sha512-sJTvldu1GPeEPfyeLG7gRj+W4vEuD+JDi+JjJ3TJs/DvMUtBLs0KJO5yokGegWWdy5qrbdnQGekbhgNRmPmYKQ==}
peerDependencies:
hono: '>=4.0.0'
'@iarna/toml@2.2.5':
resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
@@ -2965,6 +2991,67 @@ packages:
peerDependencies:
solid-js: ^1.8.6
'@standard-community/standard-json@0.3.5':
resolution: {integrity: sha512-4+ZPorwDRt47i+O7RjyuaxHRK/37QY/LmgxlGrRrSTLYoFatEOzvqIc85GTlM18SFZ5E91C+v0o/M37wZPpUHA==}
peerDependencies:
'@standard-schema/spec': ^1.0.0
'@types/json-schema': ^7.0.15
'@valibot/to-json-schema': ^1.3.0
arktype: ^2.1.20
effect: ^3.16.8
quansync: ^0.2.11
sury: ^10.0.0
typebox: ^1.0.17
valibot: ^1.1.0
zod: ^3.25.0 || ^4.0.0
zod-to-json-schema: ^3.24.5
peerDependenciesMeta:
'@valibot/to-json-schema':
optional: true
arktype:
optional: true
effect:
optional: true
sury:
optional: true
typebox:
optional: true
valibot:
optional: true
zod:
optional: true
zod-to-json-schema:
optional: true
'@standard-community/standard-openapi@0.2.9':
resolution: {integrity: sha512-htj+yldvN1XncyZi4rehbf9kLbu8os2Ke/rfqoZHCMHuw34kiF3LP/yQPdA0tQ940y8nDq3Iou8R3wG+AGGyvg==}
peerDependencies:
'@standard-community/standard-json': ^0.3.5
'@standard-schema/spec': ^1.0.0
arktype: ^2.1.20
effect: ^3.17.14
openapi-types: ^12.1.3
sury: ^10.0.0
typebox: ^1.0.0
valibot: ^1.1.0
zod: ^3.25.0 || ^4.0.0
zod-openapi: ^4
peerDependenciesMeta:
arktype:
optional: true
effect:
optional: true
sury:
optional: true
typebox:
optional: true
valibot:
optional: true
zod:
optional: true
zod-openapi:
optional: true
'@standard-schema/spec@1.1.0':
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
@@ -3328,6 +3415,9 @@ packages:
'@types/hast@3.0.4':
resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/mdast@4.0.4':
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
@@ -4373,6 +4463,21 @@ packages:
resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==}
engines: {node: '>=0.10.0'}
hono-openapi@1.3.0:
resolution: {integrity: sha512-xDvCWpWEIv0weEmnl3EjRQzqbHIO8LnfzMuYOCmbuyE5aes6aXxLg4vM3ybnoZD5TiTUkA6PuRQPJs3R7WRBig==}
peerDependencies:
'@hono/standard-validator': ^0.2.0
'@standard-community/standard-json': ^0.3.5
'@standard-community/standard-openapi': ^0.2.9
'@types/json-schema': ^7.0.15
hono: ^4.8.3
openapi-types: ^12.1.3
peerDependenciesMeta:
'@hono/standard-validator':
optional: true
hono:
optional: true
hono@4.12.8:
resolution: {integrity: sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==}
engines: {node: '>=16.9.0'}
@@ -4999,6 +5104,9 @@ packages:
resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
engines: {node: '>=14.0.0'}
openapi-types@12.1.3:
resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==}
p-finally@1.0.0:
resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==}
engines: {node: '>=4'}
@@ -5231,6 +5339,9 @@ packages:
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
quansync@0.2.11:
resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
@@ -7221,10 +7332,14 @@ snapshots:
dependencies:
hono: 4.12.8
'@hono/zod-validator@0.7.6(hono@4.12.8)(zod@4.3.6)':
'@hono/standard-validator@0.2.2(@standard-schema/spec@1.1.0)(hono@4.12.8)':
dependencies:
'@standard-schema/spec': 1.1.0
hono: 4.12.8
'@hono/swagger-ui@0.6.1(hono@4.12.8)':
dependencies:
hono: 4.12.8
zod: 4.3.6
'@iarna/toml@2.2.5': {}
@@ -8692,6 +8807,22 @@ snapshots:
dependencies:
solid-js: 1.9.9
'@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod@4.3.6)':
dependencies:
'@standard-schema/spec': 1.1.0
'@types/json-schema': 7.0.15
quansync: 0.2.11
optionalDependencies:
zod: 4.3.6
'@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6)':
dependencies:
'@standard-community/standard-json': 0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod@4.3.6)
'@standard-schema/spec': 1.1.0
openapi-types: 12.1.3
optionalDependencies:
zod: 4.3.6
'@standard-schema/spec@1.1.0': {}
'@swc/counter@0.1.3': {}
@@ -9034,6 +9165,8 @@ snapshots:
dependencies:
'@types/unist': 3.0.3
'@types/json-schema@7.0.15': {}
'@types/mdast@4.0.4':
dependencies:
'@types/unist': 3.0.3
@@ -10107,6 +10240,16 @@ snapshots:
dependencies:
parse-passwd: 1.0.0
hono-openapi@1.3.0(@hono/standard-validator@0.2.2(@standard-schema/spec@1.1.0)(hono@4.12.8))(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod@4.3.6))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6))(@types/json-schema@7.0.15)(hono@4.12.8)(openapi-types@12.1.3):
dependencies:
'@standard-community/standard-json': 0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod@4.3.6)
'@standard-community/standard-openapi': 0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6)
'@types/json-schema': 7.0.15
openapi-types: 12.1.3
optionalDependencies:
'@hono/standard-validator': 0.2.2(@standard-schema/spec@1.1.0)(hono@4.12.8)
hono: 4.12.8
hono@4.12.8: {}
html-entities@2.3.3: {}
@@ -10911,6 +11054,8 @@ snapshots:
on-exit-leak-free@2.1.2: {}
openapi-types@12.1.3: {}
p-finally@1.0.0: {}
p-limit@2.3.0:
@@ -11132,6 +11277,8 @@ snapshots:
proxy-from-env@1.1.0: {}
quansync@0.2.11: {}
queue-microtask@1.2.3: {}
quick-format-unescaped@4.0.4: {}