ts-procedures 7.3.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -3
- package/agent_config/claude-code/agents/ts-procedures-architect.md +6 -8
- package/agent_config/claude-code/skills/ts-procedures/SKILL.md +30 -33
- package/agent_config/claude-code/skills/ts-procedures/anti-patterns.md +104 -53
- package/agent_config/claude-code/skills/ts-procedures/api-reference.md +205 -232
- package/agent_config/claude-code/skills/ts-procedures/patterns.md +80 -153
- package/agent_config/claude-code/skills/ts-procedures-review/SKILL.md +1 -1
- package/agent_config/claude-code/skills/ts-procedures-review/checklist.md +4 -5
- package/agent_config/claude-code/skills/ts-procedures-scaffold/SKILL.md +4 -7
- package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono.md +223 -0
- package/agent_config/copilot/copilot-instructions.md +34 -48
- package/agent_config/cursor/cursorrules +34 -48
- package/build/client/call.js +4 -1
- package/build/client/call.js.map +1 -1
- package/build/client/call.test.js +23 -0
- package/build/client/call.test.js.map +1 -1
- package/build/client/fetch-adapter.js +3 -1
- package/build/client/fetch-adapter.js.map +1 -1
- package/build/client/fetch-adapter.test.js +11 -1
- package/build/client/fetch-adapter.test.js.map +1 -1
- package/build/client/index.test.js +7 -7
- package/build/client/index.test.js.map +1 -1
- package/build/client/request-builder.d.ts +1 -1
- package/build/client/request-builder.js +2 -2
- package/build/client/request-builder.js.map +1 -1
- package/build/client/stream.js +13 -2
- package/build/client/stream.js.map +1 -1
- package/build/client/stream.test.js +32 -7
- package/build/client/stream.test.js.map +1 -1
- package/build/client/typed-error-dispatch.test.js +8 -92
- package/build/client/typed-error-dispatch.test.js.map +1 -1
- package/build/client/types.d.ts +21 -3
- package/build/codegen/bin/cli.js +0 -0
- package/build/codegen/e2e.test.js +87 -23
- package/build/codegen/e2e.test.js.map +1 -1
- package/build/codegen/emit-errors.integration.test.js +1 -1
- package/build/codegen/emit-errors.integration.test.js.map +1 -1
- package/build/codegen/emit-scope.js +308 -47
- package/build/codegen/emit-scope.js.map +1 -1
- package/build/codegen/emit-scope.test.js +363 -110
- package/build/codegen/emit-scope.test.js.map +1 -1
- package/build/codegen/pipeline.test.js +7 -7
- package/build/codegen/pipeline.test.js.map +1 -1
- package/build/codegen/resolve-envelope.js +1 -1
- package/build/codegen/resolve-envelope.js.map +1 -1
- package/build/codegen/resolve-envelope.test.js +5 -5
- package/build/codegen/resolve-envelope.test.js.map +1 -1
- package/build/codegen/targets/_shared/route-slots.d.ts +8 -3
- package/build/codegen/targets/_shared/route-slots.js +49 -8
- package/build/codegen/targets/_shared/route-slots.js.map +1 -1
- package/build/codegen/targets/_shared/route-slots.test.js +99 -26
- package/build/codegen/targets/_shared/route-slots.test.js.map +1 -1
- package/build/codegen/targets/kotlin/emit-route-kotlin.test.js +88 -17
- package/build/codegen/targets/kotlin/emit-route-kotlin.test.js.map +1 -1
- package/build/codegen/targets/kotlin/emit-scope-kotlin.test.js +9 -6
- package/build/codegen/targets/kotlin/emit-scope-kotlin.test.js.map +1 -1
- package/build/codegen/targets/kotlin/integration.test.js +6 -0
- package/build/codegen/targets/kotlin/integration.test.js.map +1 -1
- package/build/codegen/targets/swift/access-level.test.js +8 -11
- package/build/codegen/targets/swift/access-level.test.js.map +1 -1
- package/build/codegen/targets/swift/emit-route-swift.test.js +91 -20
- package/build/codegen/targets/swift/emit-route-swift.test.js.map +1 -1
- package/build/codegen/targets/swift/emit-scope-swift.test.js +12 -9
- package/build/codegen/targets/swift/emit-scope-swift.test.js.map +1 -1
- package/build/codegen/targets/swift/integration.test.js +6 -0
- package/build/codegen/targets/swift/integration.test.js.map +1 -1
- package/build/create-http-stream.d.ts +58 -0
- package/build/create-http-stream.js +122 -0
- package/build/create-http-stream.js.map +1 -0
- package/build/create-http-stream.test.js +88 -0
- package/build/create-http-stream.test.js.map +1 -0
- package/build/create-http.d.ts +49 -0
- package/build/create-http.js +108 -0
- package/build/create-http.js.map +1 -0
- package/build/create-http.test.js +137 -0
- package/build/create-http.test.js.map +1 -0
- package/build/create-stream.d.ts +35 -0
- package/build/create-stream.js +123 -0
- package/build/create-stream.js.map +1 -0
- package/build/create-stream.test.js +428 -0
- package/build/create-stream.test.js.map +1 -0
- package/build/create.d.ts +28 -0
- package/build/create.js +82 -0
- package/build/create.js.map +1 -0
- package/build/create.test.js +483 -0
- package/build/create.test.js.map +1 -0
- package/build/exports.d.ts +2 -0
- package/build/implementations/http/astro/index.test.js +20 -12
- package/build/implementations/http/astro/index.test.js.map +1 -1
- package/build/implementations/http/doc-registry.js +1 -1
- package/build/implementations/http/doc-registry.js.map +1 -1
- package/build/implementations/http/doc-registry.test.js +36 -5
- package/build/implementations/http/doc-registry.test.js.map +1 -1
- package/build/implementations/http/error-dispatch.d.ts +76 -0
- package/build/implementations/http/error-dispatch.js +77 -0
- package/build/implementations/http/error-dispatch.js.map +1 -0
- package/build/implementations/http/error-dispatch.test.js +254 -0
- package/build/implementations/http/error-dispatch.test.js.map +1 -0
- package/build/implementations/http/error-taxonomy.d.ts +5 -5
- package/build/implementations/http/hono/docs/http-doc.d.ts +6 -0
- package/build/implementations/http/hono/docs/http-doc.js +42 -0
- package/build/implementations/http/hono/docs/http-doc.js.map +1 -0
- package/build/implementations/http/hono/docs/http-stream-doc.d.ts +6 -0
- package/build/implementations/http/hono/docs/http-stream-doc.js +40 -0
- package/build/implementations/http/hono/docs/http-stream-doc.js.map +1 -0
- package/build/implementations/http/hono/docs/rpc-doc.d.ts +6 -0
- package/build/implementations/http/hono/docs/rpc-doc.js +24 -0
- package/build/implementations/http/hono/docs/rpc-doc.js.map +1 -0
- package/build/implementations/http/hono/docs/stream-doc.d.ts +6 -0
- package/build/implementations/http/hono/docs/stream-doc.js +42 -0
- package/build/implementations/http/hono/docs/stream-doc.js.map +1 -0
- package/build/implementations/http/hono/handlers/http-stream.d.ts +10 -0
- package/build/implementations/http/hono/handlers/http-stream.js +123 -0
- package/build/implementations/http/hono/handlers/http-stream.js.map +1 -0
- package/build/implementations/http/hono/handlers/http-stream.test.js +128 -0
- package/build/implementations/http/hono/handlers/http-stream.test.js.map +1 -0
- package/build/implementations/http/hono/handlers/http.d.ts +10 -0
- package/build/implementations/http/hono/handlers/http.js +115 -0
- package/build/implementations/http/hono/handlers/http.js.map +1 -0
- package/build/implementations/http/hono/handlers/http.test.js +118 -0
- package/build/implementations/http/hono/handlers/http.test.js.map +1 -0
- package/build/implementations/http/hono/handlers/rpc.d.ts +11 -0
- package/build/implementations/http/hono/handlers/rpc.js +32 -0
- package/build/implementations/http/hono/handlers/rpc.js.map +1 -0
- package/build/implementations/http/hono/handlers/rpc.test.js +73 -0
- package/build/implementations/http/hono/handlers/rpc.test.js.map +1 -0
- package/build/implementations/http/hono/handlers/stream.d.ts +23 -0
- package/build/implementations/http/hono/handlers/stream.js +147 -0
- package/build/implementations/http/hono/handlers/stream.js.map +1 -0
- package/build/implementations/http/hono/handlers/stream.test.d.ts +1 -0
- package/build/implementations/http/hono/handlers/stream.test.js +177 -0
- package/build/implementations/http/hono/handlers/stream.test.js.map +1 -0
- package/build/implementations/http/hono/index.d.ts +57 -0
- package/build/implementations/http/hono/index.js +149 -0
- package/build/implementations/http/hono/index.js.map +1 -0
- package/build/implementations/http/hono/index.test.d.ts +1 -0
- package/build/implementations/http/hono/index.test.js +274 -0
- package/build/implementations/http/hono/index.test.js.map +1 -0
- package/build/implementations/http/hono/path.d.ts +17 -0
- package/build/implementations/http/hono/path.js +39 -0
- package/build/implementations/http/hono/path.js.map +1 -0
- package/build/implementations/http/hono/path.test.d.ts +1 -0
- package/build/implementations/http/hono/path.test.js +83 -0
- package/build/implementations/http/hono/path.test.js.map +1 -0
- package/build/implementations/http/hono/types.d.ts +51 -0
- package/build/implementations/http/hono/types.js.map +1 -0
- package/build/implementations/http/on-request-error.test.js +6 -96
- package/build/implementations/http/on-request-error.test.js.map +1 -1
- package/build/implementations/http/route-errors.test.js +11 -59
- package/build/implementations/http/route-errors.test.js.map +1 -1
- package/build/implementations/types.d.ts +43 -9
- package/build/index.d.ts +124 -124
- package/build/index.js +10 -221
- package/build/index.js.map +1 -1
- package/build/index.test.js +20 -919
- package/build/index.test.js.map +1 -1
- package/build/migration.test.d.ts +1 -0
- package/build/migration.test.js +34 -0
- package/build/migration.test.js.map +1 -0
- package/build/schema/compute-schema.d.ts +11 -3
- package/build/schema/compute-schema.js +13 -7
- package/build/schema/compute-schema.js.map +1 -1
- package/build/schema/parser.d.ts +11 -3
- package/build/schema/parser.js +49 -9
- package/build/schema/parser.js.map +1 -1
- package/build/stack-utils.js +8 -0
- package/build/stack-utils.js.map +1 -1
- package/build/types.d.ts +142 -0
- package/build/types.js.map +1 -0
- package/docs/astro-adapter.md +5 -5
- package/docs/core.md +15 -17
- package/docs/http-integrations.md +83 -170
- package/docs/streaming.md +3 -60
- package/docs/superpowers/plans/2026-05-07-astro-adapter.md +2 -7
- package/docs/superpowers/plans/2026-05-08-create-http.md +3355 -0
- package/docs/superpowers/plans/2026-05-08-hono-app-builder-convergence.md +3365 -0
- package/docs/superpowers/specs/2026-05-07-astro-adapter-design.md +1 -3
- package/docs/superpowers/specs/2026-05-08-create-http-design.md +409 -0
- package/docs/superpowers/specs/2026-05-08-hono-app-builder-convergence-design.md +411 -0
- package/package.json +4 -22
- package/src/client/call.test.ts +26 -0
- package/src/client/call.ts +4 -1
- package/src/client/fetch-adapter.test.ts +14 -1
- package/src/client/fetch-adapter.ts +3 -1
- package/src/client/index.test.ts +7 -7
- package/src/client/request-builder.ts +2 -2
- package/src/client/stream.test.ts +39 -7
- package/src/client/stream.ts +16 -2
- package/src/client/typed-error-dispatch.test.ts +7 -97
- package/src/client/types.ts +21 -3
- package/src/codegen/__fixtures__/users-envelope.json +119 -38
- package/src/codegen/e2e.test.ts +98 -24
- package/src/codegen/emit-errors.integration.test.ts +1 -1
- package/src/codegen/emit-scope.test.ts +395 -110
- package/src/codegen/emit-scope.ts +350 -55
- package/src/codegen/pipeline.test.ts +7 -7
- package/src/codegen/resolve-envelope.test.ts +5 -5
- package/src/codegen/resolve-envelope.ts +1 -1
- package/src/codegen/targets/_shared/route-slots.test.ts +109 -26
- package/src/codegen/targets/_shared/route-slots.ts +48 -11
- package/src/codegen/targets/kotlin/__fixtures__/users-golden.kt +73 -0
- package/src/codegen/targets/kotlin/emit-route-kotlin.test.ts +100 -17
- package/src/codegen/targets/kotlin/emit-scope-kotlin.test.ts +9 -6
- package/src/codegen/targets/kotlin/integration.test.ts +19 -0
- package/src/codegen/targets/swift/__fixtures__/users-golden.swift +79 -0
- package/src/codegen/targets/swift/access-level.test.ts +8 -11
- package/src/codegen/targets/swift/emit-route-swift.test.ts +103 -20
- package/src/codegen/targets/swift/emit-scope-swift.test.ts +12 -9
- package/src/codegen/targets/swift/integration.test.ts +17 -0
- package/src/create-http-stream.test.ts +97 -0
- package/src/create-http-stream.ts +191 -0
- package/src/create-http.test.ts +163 -0
- package/src/create-http.ts +211 -0
- package/src/create-stream.test.ts +565 -0
- package/src/create-stream.ts +228 -0
- package/src/create.test.ts +658 -0
- package/src/create.ts +172 -0
- package/src/exports.ts +2 -0
- package/src/implementations/http/README.md +135 -95
- package/src/implementations/http/astro/README.md +4 -5
- package/src/implementations/http/astro/index.test.ts +25 -18
- package/src/implementations/http/doc-registry.test.ts +42 -5
- package/src/implementations/http/doc-registry.ts +1 -1
- package/src/implementations/http/error-dispatch.test.ts +283 -0
- package/src/implementations/http/error-dispatch.ts +176 -0
- package/src/implementations/http/error-taxonomy.ts +5 -5
- package/src/implementations/http/hono/docs/http-doc.ts +43 -0
- package/src/implementations/http/hono/docs/http-stream-doc.ts +44 -0
- package/src/implementations/http/hono/docs/rpc-doc.ts +34 -0
- package/src/implementations/http/hono/docs/stream-doc.ts +53 -0
- package/src/implementations/http/hono/handlers/http-stream.test.ts +150 -0
- package/src/implementations/http/hono/handlers/http-stream.ts +152 -0
- package/src/implementations/http/hono/handlers/http.test.ts +130 -0
- package/src/implementations/http/hono/handlers/http.ts +147 -0
- package/src/implementations/http/hono/handlers/rpc.test.ts +81 -0
- package/src/implementations/http/hono/handlers/rpc.ts +54 -0
- package/src/implementations/http/hono/handlers/stream.test.ts +198 -0
- package/src/implementations/http/hono/handlers/stream.ts +208 -0
- package/src/implementations/http/hono/index.test.ts +329 -0
- package/src/implementations/http/hono/index.ts +204 -0
- package/src/implementations/http/hono/path.test.ts +96 -0
- package/src/implementations/http/hono/path.ts +59 -0
- package/src/implementations/http/hono/types.ts +93 -0
- package/src/implementations/http/on-request-error.test.ts +10 -116
- package/src/implementations/http/route-errors.test.ts +11 -77
- package/src/implementations/types.ts +44 -9
- package/src/index.test.ts +22 -1249
- package/src/index.ts +49 -485
- package/src/migration.test.ts +48 -0
- package/src/schema/compute-schema.ts +26 -12
- package/src/schema/parser.ts +62 -12
- package/src/stack-utils.ts +8 -0
- package/src/types.ts +133 -0
- package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/express-rpc.md +0 -137
- package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-api.md +0 -173
- package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-rpc.md +0 -142
- package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-stream.md +0 -147
- package/build/implementations/http/express-rpc/error-taxonomy.test.js +0 -83
- package/build/implementations/http/express-rpc/error-taxonomy.test.js.map +0 -1
- package/build/implementations/http/express-rpc/index.d.ts +0 -125
- package/build/implementations/http/express-rpc/index.js +0 -216
- package/build/implementations/http/express-rpc/index.js.map +0 -1
- package/build/implementations/http/express-rpc/index.test.js +0 -684
- package/build/implementations/http/express-rpc/index.test.js.map +0 -1
- package/build/implementations/http/express-rpc/types.d.ts +0 -11
- package/build/implementations/http/express-rpc/types.js.map +0 -1
- package/build/implementations/http/hono-api/error-taxonomy.test.js +0 -137
- package/build/implementations/http/hono-api/error-taxonomy.test.js.map +0 -1
- package/build/implementations/http/hono-api/index.d.ts +0 -151
- package/build/implementations/http/hono-api/index.js +0 -344
- package/build/implementations/http/hono-api/index.js.map +0 -1
- package/build/implementations/http/hono-api/index.test.js +0 -992
- package/build/implementations/http/hono-api/index.test.js.map +0 -1
- package/build/implementations/http/hono-api/types.d.ts +0 -13
- package/build/implementations/http/hono-api/types.js.map +0 -1
- package/build/implementations/http/hono-rpc/error-taxonomy.test.js +0 -64
- package/build/implementations/http/hono-rpc/error-taxonomy.test.js.map +0 -1
- package/build/implementations/http/hono-rpc/index.d.ts +0 -130
- package/build/implementations/http/hono-rpc/index.js +0 -209
- package/build/implementations/http/hono-rpc/index.js.map +0 -1
- package/build/implementations/http/hono-rpc/index.test.js +0 -828
- package/build/implementations/http/hono-rpc/index.test.js.map +0 -1
- package/build/implementations/http/hono-rpc/types.d.ts +0 -11
- package/build/implementations/http/hono-rpc/types.js +0 -2
- package/build/implementations/http/hono-rpc/types.js.map +0 -1
- package/build/implementations/http/hono-stream/error-taxonomy.test.js +0 -159
- package/build/implementations/http/hono-stream/error-taxonomy.test.js.map +0 -1
- package/build/implementations/http/hono-stream/index.d.ts +0 -171
- package/build/implementations/http/hono-stream/index.js +0 -415
- package/build/implementations/http/hono-stream/index.js.map +0 -1
- package/build/implementations/http/hono-stream/index.test.js +0 -1383
- package/build/implementations/http/hono-stream/index.test.js.map +0 -1
- package/build/implementations/http/hono-stream/types.d.ts +0 -15
- package/build/implementations/http/hono-stream/types.js +0 -2
- package/build/implementations/http/hono-stream/types.js.map +0 -1
- package/src/implementations/http/express-rpc/README.md +0 -280
- package/src/implementations/http/express-rpc/error-taxonomy.test.ts +0 -103
- package/src/implementations/http/express-rpc/index.test.ts +0 -957
- package/src/implementations/http/express-rpc/index.ts +0 -327
- package/src/implementations/http/express-rpc/types.ts +0 -16
- package/src/implementations/http/hono-api/README.md +0 -284
- package/src/implementations/http/hono-api/error-taxonomy.test.ts +0 -179
- package/src/implementations/http/hono-api/index.test.ts +0 -1341
- package/src/implementations/http/hono-api/index.ts +0 -519
- package/src/implementations/http/hono-api/types.ts +0 -16
- package/src/implementations/http/hono-rpc/README.md +0 -357
- package/src/implementations/http/hono-rpc/error-taxonomy.test.ts +0 -82
- package/src/implementations/http/hono-rpc/index.test.ts +0 -1107
- package/src/implementations/http/hono-rpc/index.ts +0 -320
- package/src/implementations/http/hono-rpc/types.ts +0 -16
- package/src/implementations/http/hono-stream/README.md +0 -559
- package/src/implementations/http/hono-stream/error-taxonomy.test.ts +0 -178
- package/src/implementations/http/hono-stream/index.test.ts +0 -1804
- package/src/implementations/http/hono-stream/index.ts +0 -622
- package/src/implementations/http/hono-stream/types.ts +0 -20
- /package/build/{implementations/http/express-rpc/error-taxonomy.test.d.ts → create-http-stream.test.d.ts} +0 -0
- /package/build/{implementations/http/express-rpc/index.test.d.ts → create-http.test.d.ts} +0 -0
- /package/build/{implementations/http/hono-api/error-taxonomy.test.d.ts → create-stream.test.d.ts} +0 -0
- /package/build/{implementations/http/hono-api/index.test.d.ts → create.test.d.ts} +0 -0
- /package/build/implementations/http/{hono-rpc/error-taxonomy.test.d.ts → error-dispatch.test.d.ts} +0 -0
- /package/build/implementations/http/{hono-rpc/index.test.d.ts → hono/handlers/http-stream.test.d.ts} +0 -0
- /package/build/implementations/http/{hono-stream/error-taxonomy.test.d.ts → hono/handlers/http.test.d.ts} +0 -0
- /package/build/implementations/http/{hono-stream/index.test.d.ts → hono/handlers/rpc.test.d.ts} +0 -0
- /package/build/implementations/http/{express-rpc → hono}/types.js +0 -0
- /package/build/{implementations/http/hono-api/types.js → types.js} +0 -0
|
@@ -1,519 +0,0 @@
|
|
|
1
|
-
import { Hono, Context } from 'hono'
|
|
2
|
-
import { TProcedureRegistration } from '../../../index.js'
|
|
3
|
-
import {
|
|
4
|
-
ExtractConfig,
|
|
5
|
-
ExtractContext,
|
|
6
|
-
ProceduresFactory,
|
|
7
|
-
APIConfig,
|
|
8
|
-
APIHttpRouteDoc,
|
|
9
|
-
APIInput,
|
|
10
|
-
HttpMethod,
|
|
11
|
-
} from '../../types.js'
|
|
12
|
-
import {
|
|
13
|
-
ErrorTaxonomy,
|
|
14
|
-
ErrorTaxonomyEntry,
|
|
15
|
-
UnknownErrorConfig,
|
|
16
|
-
defineErrorTaxonomy,
|
|
17
|
-
resolveErrorResponse,
|
|
18
|
-
} from '../error-taxonomy.js'
|
|
19
|
-
import { HonoAPIFactoryItem } from './types.js'
|
|
20
|
-
|
|
21
|
-
export type { APIConfig, APIHttpRouteDoc, APIInput, HttpMethod }
|
|
22
|
-
export { defineErrorTaxonomy }
|
|
23
|
-
export type { ErrorTaxonomy, ErrorTaxonomyEntry, UnknownErrorConfig }
|
|
24
|
-
|
|
25
|
-
// ================
|
|
26
|
-
// Query string parsing
|
|
27
|
-
// ================
|
|
28
|
-
|
|
29
|
-
export type QueryParser = (queryString: string) => Record<string, unknown>
|
|
30
|
-
|
|
31
|
-
/** Default query parser using native URLSearchParams. */
|
|
32
|
-
function parseQueryNative(queryString: string): Record<string, unknown> {
|
|
33
|
-
const searchParams = new URLSearchParams(queryString)
|
|
34
|
-
const result: Record<string, unknown> = {}
|
|
35
|
-
for (const key of new Set(searchParams.keys())) {
|
|
36
|
-
const values = searchParams.getAll(key)
|
|
37
|
-
result[key] = values.length > 1 ? values : values[0]
|
|
38
|
-
}
|
|
39
|
-
return result
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** Extract path parameter names from a route pattern (e.g., '/users/:id' → ['id']) */
|
|
43
|
-
function extractPathParamNames(path: string): string[] {
|
|
44
|
-
const matches = path.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g)
|
|
45
|
-
return matches ? matches.map((m) => m.slice(1)) : []
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** Default success status codes by HTTP method */
|
|
49
|
-
function defaultSuccessStatus(method: HttpMethod): number {
|
|
50
|
-
switch (method) {
|
|
51
|
-
case 'post':
|
|
52
|
-
return 201
|
|
53
|
-
case 'delete':
|
|
54
|
-
return 204
|
|
55
|
-
default:
|
|
56
|
-
return 200
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** HTTP methods that typically carry a request body */
|
|
61
|
-
const BODY_METHODS: HttpMethod[] = ['post', 'put', 'patch']
|
|
62
|
-
|
|
63
|
-
/** Extracts the raw query string from a URL and runs it through the resolved parser. */
|
|
64
|
-
function extractQuery(url: string, queryParser: QueryParser): Record<string, unknown> {
|
|
65
|
-
const questionMark = url.indexOf('?')
|
|
66
|
-
if (questionMark === -1) return {}
|
|
67
|
-
const rawQuery = url.slice(questionMark + 1)
|
|
68
|
-
if (!rawQuery) return {}
|
|
69
|
-
return queryParser(rawQuery)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// ================
|
|
73
|
-
// Builder
|
|
74
|
-
// ================
|
|
75
|
-
|
|
76
|
-
export type HonoAPIAppBuilderConfig = {
|
|
77
|
-
/**
|
|
78
|
-
* An existing Hono application instance to use.
|
|
79
|
-
* If not provided, a new instance will be created.
|
|
80
|
-
*/
|
|
81
|
-
app?: Hono
|
|
82
|
-
/** Optional path prefix for all API routes. */
|
|
83
|
-
pathPrefix?: string
|
|
84
|
-
/**
|
|
85
|
-
* Custom query string parser. Receives the raw query string (without '?').
|
|
86
|
-
*
|
|
87
|
-
* Default: native `URLSearchParams`. The default handles:
|
|
88
|
-
* - flat keys: `?page=2&limit=10` → `{ page: '2', limit: '10' }`
|
|
89
|
-
* - repeated keys: `?tag=a&tag=b` → `{ tag: ['a', 'b'] }`
|
|
90
|
-
*
|
|
91
|
-
* The default does NOT parse any of these — the bracket/dot syntax is kept
|
|
92
|
-
* as part of the literal key name, not interpreted:
|
|
93
|
-
* - bracket objects: `?user[name]=John` → `{ 'user[name]': 'John' }`
|
|
94
|
-
* - bracket arrays: `?tags[]=a&tags[]=b` → `{ 'tags[]': ['a', 'b'] }`
|
|
95
|
-
* - dot paths: `?user.name=John` → `{ 'user.name': 'John' }`
|
|
96
|
-
* - comma-split arrays: `?tags=a,b,c` → `{ tags: 'a,b,c' }`
|
|
97
|
-
*
|
|
98
|
-
* For any of the above, install `qs` and opt in explicitly:
|
|
99
|
-
* `queryParser: (raw) => qs.parse(raw) as Record<string, unknown>`
|
|
100
|
-
*/
|
|
101
|
-
queryParser?: QueryParser
|
|
102
|
-
onRequestStart?: (c: Context) => void
|
|
103
|
-
onRequestEnd?: (c: Context) => void
|
|
104
|
-
onSuccess?: (procedure: TProcedureRegistration, c: Context) => void
|
|
105
|
-
/**
|
|
106
|
-
* Declarative error-to-response mapping (one of the two peer error modes).
|
|
107
|
-
* When a thrown error matches an entry (by `class` or `match`), the builder
|
|
108
|
-
* serializes it automatically. User entries are checked before the framework
|
|
109
|
-
* defaults (`ProcedureValidationError`, `ProcedureYieldValidationError`,
|
|
110
|
-
* `ProcedureError`).
|
|
111
|
-
*/
|
|
112
|
-
errors?: ErrorTaxonomy
|
|
113
|
-
/**
|
|
114
|
-
* Fallback serializer for errors not matched by the taxonomy. Used together
|
|
115
|
-
* with `errors` for apps that want declarative dispatch plus a well-defined
|
|
116
|
-
* shape for unexpected errors.
|
|
117
|
-
*/
|
|
118
|
-
unknownError?: UnknownErrorConfig
|
|
119
|
-
/**
|
|
120
|
-
* Imperative error callback — the other peer error mode. Receives every
|
|
121
|
-
* error directly and returns the HTTP response. Use this when you want full
|
|
122
|
-
* control over the response shape, or alongside `errors` for the tail of
|
|
123
|
-
* errors the taxonomy doesn't cover.
|
|
124
|
-
*/
|
|
125
|
-
onError?: (
|
|
126
|
-
procedure: TProcedureRegistration,
|
|
127
|
-
c: Context,
|
|
128
|
-
error: Error
|
|
129
|
-
) => Response | Promise<Response>
|
|
130
|
-
/**
|
|
131
|
-
* Cross-cutting observer — fires for every caught error, BEFORE dispatch to
|
|
132
|
-
* the taxonomy or `onError`. Awaited. Cannot mutate the response. Intended
|
|
133
|
-
* for logging, tracing, and metrics (Sentry, Datadog, OpenTelemetry). Any
|
|
134
|
-
* error thrown inside the observer is swallowed and logged so the primary
|
|
135
|
-
* dispatch flow is never disrupted.
|
|
136
|
-
*/
|
|
137
|
-
onRequestError?: (ctx: OnRequestErrorContext) => void | Promise<void>
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Context passed to the `onRequestError` observer. `raw` is the Hono
|
|
142
|
-
* `Context` for the in-flight request.
|
|
143
|
-
*/
|
|
144
|
-
export type OnRequestErrorContext = {
|
|
145
|
-
err: unknown
|
|
146
|
-
procedure: TProcedureRegistration
|
|
147
|
-
raw: Context
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Builder class for creating a Hono application with REST-style API routes.
|
|
152
|
-
*
|
|
153
|
-
* Uses `schema.input` for per-channel type safety:
|
|
154
|
-
* - `input.pathParams` → validated path parameters
|
|
155
|
-
* - `input.query` → validated query string parameters
|
|
156
|
-
* - `input.body` → validated request body
|
|
157
|
-
* - `input.headers` → validated request headers
|
|
158
|
-
*
|
|
159
|
-
* Usage:
|
|
160
|
-
* const API = Procedures<MyContext, APIConfig>()
|
|
161
|
-
*
|
|
162
|
-
* API.Create('GetUser', {
|
|
163
|
-
* path: '/users/:id',
|
|
164
|
-
* method: 'get',
|
|
165
|
-
* schema: {
|
|
166
|
-
* input: {
|
|
167
|
-
* pathParams: Type.Object({ id: Type.String() }),
|
|
168
|
-
* query: Type.Object({ include: Type.Optional(Type.String()) }),
|
|
169
|
-
* },
|
|
170
|
-
* returnType: Type.Object({ id: Type.String(), name: Type.String() }),
|
|
171
|
-
* }
|
|
172
|
-
* }, async (ctx, { pathParams, query }) => {
|
|
173
|
-
* return { id: pathParams.id, name: 'John' }
|
|
174
|
-
* })
|
|
175
|
-
*
|
|
176
|
-
* const apiApp = new HonoAPIAppBuilder()
|
|
177
|
-
* .register(API, (c) => ({ ... }))
|
|
178
|
-
* .build()
|
|
179
|
-
*/
|
|
180
|
-
export class HonoAPIAppBuilder {
|
|
181
|
-
constructor(readonly config?: HonoAPIAppBuilderConfig) {
|
|
182
|
-
if (config?.app) {
|
|
183
|
-
this._app = config.app
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (config?.onRequestStart) {
|
|
187
|
-
this._app.use('*', async (c, next) => {
|
|
188
|
-
config.onRequestStart!(c)
|
|
189
|
-
await next()
|
|
190
|
-
})
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (config?.onRequestEnd) {
|
|
194
|
-
this._app.use('*', async (c, next) => {
|
|
195
|
-
await next()
|
|
196
|
-
config.onRequestEnd!(c)
|
|
197
|
-
})
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
private factories: HonoAPIFactoryItem<any>[] = []
|
|
202
|
-
|
|
203
|
-
private _app: Hono = new Hono()
|
|
204
|
-
private _docs: (APIHttpRouteDoc & object)[] = []
|
|
205
|
-
|
|
206
|
-
get app(): Hono {
|
|
207
|
-
return this._app
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
get docs(): APIHttpRouteDoc[] {
|
|
211
|
-
return this._docs
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Registers a procedure factory with its context.
|
|
216
|
-
* @param factory - The procedure factory created by Procedures<Context, APIConfig>()
|
|
217
|
-
* @param factoryContext - Context for handlers. Direct value, sync function, or async function.
|
|
218
|
-
* @param extendProcedureDoc - Custom function to extend the generated route documentation.
|
|
219
|
-
*/
|
|
220
|
-
register<TFactory extends ProceduresFactory>(
|
|
221
|
-
factory: TFactory,
|
|
222
|
-
factoryContext:
|
|
223
|
-
| ExtractContext<TFactory>
|
|
224
|
-
| ((c: Context) => ExtractContext<TFactory> | Promise<ExtractContext<TFactory>>),
|
|
225
|
-
extendProcedureDoc?: (params: {
|
|
226
|
-
base: APIHttpRouteDoc
|
|
227
|
-
procedure: TProcedureRegistration<any, ExtractConfig<TFactory>>
|
|
228
|
-
}) => Record<string, any>
|
|
229
|
-
): this {
|
|
230
|
-
this.factories.push({ factory, factoryContext, extendProcedureDoc } as HonoAPIFactoryItem<any>)
|
|
231
|
-
return this
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Resolves the full path for a route, combining pathPrefix and the procedure's path.
|
|
236
|
-
*/
|
|
237
|
-
private resolveFullPath(procedurePath: string): string {
|
|
238
|
-
const prefix = this.config?.pathPrefix
|
|
239
|
-
const normalizedPrefix = prefix ? (prefix.startsWith('/') ? prefix : `/${prefix}`) : ''
|
|
240
|
-
const normalizedPath = procedurePath.startsWith('/') ? procedurePath : `/${procedurePath}`
|
|
241
|
-
return `${normalizedPrefix}${normalizedPath}`
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Builds and returns the Hono application with registered API routes.
|
|
246
|
-
*/
|
|
247
|
-
build(): Hono {
|
|
248
|
-
const queryParser = this.config?.queryParser ?? parseQueryNative
|
|
249
|
-
|
|
250
|
-
this.factories.forEach(({ factory, factoryContext, extendProcedureDoc }) => {
|
|
251
|
-
factory.getProcedures().map((procedure: TProcedureRegistration<any, APIConfig>) => {
|
|
252
|
-
const { config } = procedure
|
|
253
|
-
const fullPath = this.resolveFullPath(config.path)
|
|
254
|
-
const inputSchema = procedure.config.schema?.input
|
|
255
|
-
|
|
256
|
-
// Validate consistency: path params in path template must match schema.input.pathParams
|
|
257
|
-
this.validatePathParamConsistency(procedure.name, config.path, inputSchema)
|
|
258
|
-
|
|
259
|
-
const route = this.buildApiHttpRouteDoc(procedure, fullPath, extendProcedureDoc)
|
|
260
|
-
this._docs.push(route)
|
|
261
|
-
|
|
262
|
-
const method = config.method as HttpMethod
|
|
263
|
-
const handler = this.createRouteHandler(procedure, factoryContext, config, inputSchema, queryParser)
|
|
264
|
-
|
|
265
|
-
this._app.on(method.toUpperCase(), fullPath, handler)
|
|
266
|
-
})
|
|
267
|
-
})
|
|
268
|
-
|
|
269
|
-
return this._app
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Validates that path parameter names in the path template match the schema.input.pathParams declaration.
|
|
274
|
-
*/
|
|
275
|
-
private validatePathParamConsistency(
|
|
276
|
-
procedureName: string,
|
|
277
|
-
path: string,
|
|
278
|
-
inputSchema?: Record<string, unknown>
|
|
279
|
-
): void {
|
|
280
|
-
// Only validate when schema.input is used; schema.params (flat mode) skips this check
|
|
281
|
-
if (!inputSchema) return
|
|
282
|
-
|
|
283
|
-
const pathParamNames = extractPathParamNames(path)
|
|
284
|
-
|
|
285
|
-
if (pathParamNames.length > 0 && !inputSchema.pathParams) {
|
|
286
|
-
throw new Error(
|
|
287
|
-
`Path "${path}" has path parameters [${pathParamNames.join(', ')}] but schema.input.pathParams is not defined for procedure "${procedureName}". ` +
|
|
288
|
-
`Define schema.input.pathParams to validate path parameters.`
|
|
289
|
-
)
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (inputSchema.pathParams && pathParamNames.length === 0) {
|
|
293
|
-
throw new Error(
|
|
294
|
-
`schema.input.pathParams is defined for procedure "${procedureName}" but path "${path}" has no path parameters. ` +
|
|
295
|
-
`Remove schema.input.pathParams or add path parameters to the path.`
|
|
296
|
-
)
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Deep validation: verify schema property names match the :param names in the path
|
|
300
|
-
if (inputSchema.pathParams && pathParamNames.length > 0) {
|
|
301
|
-
const pathParamsJsonSchema = inputSchema.pathParams as Record<string, unknown>
|
|
302
|
-
const schemaProperties = pathParamsJsonSchema.properties as Record<string, unknown> | undefined
|
|
303
|
-
|
|
304
|
-
if (schemaProperties) {
|
|
305
|
-
const schemaKeys = Object.keys(schemaProperties)
|
|
306
|
-
const missingInSchema = pathParamNames.filter((p) => !schemaKeys.includes(p))
|
|
307
|
-
const extraInSchema = schemaKeys.filter((k) => !pathParamNames.includes(k))
|
|
308
|
-
|
|
309
|
-
if (missingInSchema.length > 0 || extraInSchema.length > 0) {
|
|
310
|
-
const parts: string[] = []
|
|
311
|
-
if (missingInSchema.length > 0) {
|
|
312
|
-
parts.push(`path has [${missingInSchema.join(', ')}] but they are missing from schema`)
|
|
313
|
-
}
|
|
314
|
-
if (extraInSchema.length > 0) {
|
|
315
|
-
parts.push(`schema has [${extraInSchema.join(', ')}] but they are not in the path`)
|
|
316
|
-
}
|
|
317
|
-
throw new Error(
|
|
318
|
-
`Path param mismatch for procedure "${procedureName}": ${parts.join('; ')}. ` +
|
|
319
|
-
`Path "${path}" expects [${pathParamNames.join(', ')}], schema defines [${schemaKeys.join(', ')}].`
|
|
320
|
-
)
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* Creates the async route handler for a procedure.
|
|
328
|
-
*/
|
|
329
|
-
private createRouteHandler(
|
|
330
|
-
procedure: TProcedureRegistration<any, APIConfig>,
|
|
331
|
-
factoryContext: HonoAPIFactoryItem['factoryContext'],
|
|
332
|
-
config: APIConfig,
|
|
333
|
-
inputSchema: Record<string, unknown> | undefined,
|
|
334
|
-
queryParser: QueryParser
|
|
335
|
-
) {
|
|
336
|
-
const successStatus = config.successStatus ?? defaultSuccessStatus(config.method)
|
|
337
|
-
|
|
338
|
-
return async (c: Context) => {
|
|
339
|
-
try {
|
|
340
|
-
const context =
|
|
341
|
-
typeof factoryContext === 'function'
|
|
342
|
-
? await factoryContext(c)
|
|
343
|
-
: (factoryContext as any)
|
|
344
|
-
|
|
345
|
-
let params: unknown
|
|
346
|
-
|
|
347
|
-
if (inputSchema) {
|
|
348
|
-
// schema.input mode: build structured params from HTTP sources
|
|
349
|
-
params = await this.extractInputParams(c, config.method, inputSchema, queryParser)
|
|
350
|
-
} else if (procedure.config.schema?.params) {
|
|
351
|
-
// schema.params mode: extract from body or query based on method
|
|
352
|
-
if (BODY_METHODS.includes(config.method)) {
|
|
353
|
-
params = await c.req.json().catch(() => ({}))
|
|
354
|
-
} else {
|
|
355
|
-
params = extractQuery(c.req.url, queryParser)
|
|
356
|
-
}
|
|
357
|
-
} else {
|
|
358
|
-
params = await c.req.json().catch(() => undefined)
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
const result = await procedure.handler({ ...context, signal: c.req.raw.signal }, params)
|
|
362
|
-
|
|
363
|
-
if (this.config?.onSuccess) {
|
|
364
|
-
this.config.onSuccess(procedure, c)
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// 204 No Content returns no body
|
|
368
|
-
if (successStatus === 204) {
|
|
369
|
-
return c.body(null, 204)
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
return c.json(result, successStatus as any)
|
|
373
|
-
} catch (error) {
|
|
374
|
-
// Observer fires first — cross-cutting, cannot alter dispatch or the
|
|
375
|
-
// response. Swallow any throw from the observer so instrumentation
|
|
376
|
-
// bugs never break the primary error-response flow.
|
|
377
|
-
if (this.config?.onRequestError) {
|
|
378
|
-
try {
|
|
379
|
-
await this.config.onRequestError({ err: error, procedure, raw: c })
|
|
380
|
-
} catch (observerErr) {
|
|
381
|
-
console.error('[ts-procedures hono-api] onRequestError threw — swallowed:', observerErr)
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
// Dispatch: taxonomy → onError → hard default. The two modes are
|
|
386
|
-
// peers; apps configure whichever fits (or both, in which case the
|
|
387
|
-
// taxonomy handles what it covers and `onError` handles the tail).
|
|
388
|
-
if (this.config?.errors || this.config?.unknownError) {
|
|
389
|
-
const resolved = resolveErrorResponse({
|
|
390
|
-
err: error,
|
|
391
|
-
userTaxonomy: this.config.errors,
|
|
392
|
-
unknownError: this.config.unknownError,
|
|
393
|
-
procedure,
|
|
394
|
-
raw: c,
|
|
395
|
-
})
|
|
396
|
-
if (resolved) {
|
|
397
|
-
await resolved.runOnCatch()
|
|
398
|
-
return c.json(resolved.body, resolved.statusCode as never)
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
if (this.config?.onError) {
|
|
402
|
-
return this.config.onError(procedure, c, error as Error)
|
|
403
|
-
}
|
|
404
|
-
return c.json({ error: (error as Error).message }, 500)
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* Extracts and assembles structured input params from HTTP request sources.
|
|
411
|
-
* Each channel (pathParams, query, body, headers) is extracted from its HTTP source.
|
|
412
|
-
* The core validates each channel independently via schema.input validators.
|
|
413
|
-
*/
|
|
414
|
-
private async extractInputParams(
|
|
415
|
-
c: Context,
|
|
416
|
-
method: HttpMethod,
|
|
417
|
-
inputSchema: Record<string, unknown>,
|
|
418
|
-
queryParser: QueryParser
|
|
419
|
-
): Promise<Record<string, unknown>> {
|
|
420
|
-
const params: Record<string, unknown> = {}
|
|
421
|
-
const channelNames = Object.keys(inputSchema)
|
|
422
|
-
|
|
423
|
-
for (const channel of channelNames) {
|
|
424
|
-
switch (channel) {
|
|
425
|
-
case 'pathParams':
|
|
426
|
-
params.pathParams = c.req.param()
|
|
427
|
-
break
|
|
428
|
-
|
|
429
|
-
case 'query':
|
|
430
|
-
params.query = extractQuery(c.req.url, queryParser)
|
|
431
|
-
break
|
|
432
|
-
|
|
433
|
-
case 'body':
|
|
434
|
-
if (BODY_METHODS.includes(method)) {
|
|
435
|
-
params.body = await c.req.json().catch(() => ({}))
|
|
436
|
-
}
|
|
437
|
-
break
|
|
438
|
-
|
|
439
|
-
case 'headers': {
|
|
440
|
-
// Pass all request headers; AJV's removeAdditional strips non-declared keys
|
|
441
|
-
const headersObj: Record<string, string> = {}
|
|
442
|
-
c.req.raw.headers.forEach((value, key) => {
|
|
443
|
-
headersObj[key] = value
|
|
444
|
-
})
|
|
445
|
-
params.headers = headersObj
|
|
446
|
-
break
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
default:
|
|
450
|
-
// Unknown channel — pass through empty. Core validation will catch mismatches.
|
|
451
|
-
params[channel] = undefined
|
|
452
|
-
break
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
return params
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
/**
|
|
460
|
-
* Generates the API HTTP route documentation for the given procedure.
|
|
461
|
-
*/
|
|
462
|
-
private buildApiHttpRouteDoc(
|
|
463
|
-
procedure: TProcedureRegistration<any, APIConfig>,
|
|
464
|
-
fullPath: string,
|
|
465
|
-
extendProcedureDoc?: HonoAPIFactoryItem['extendProcedureDoc']
|
|
466
|
-
): APIHttpRouteDoc {
|
|
467
|
-
const { config } = procedure
|
|
468
|
-
const inputSchema = config.schema?.input
|
|
469
|
-
const jsonSchema: APIHttpRouteDoc['jsonSchema'] = {}
|
|
470
|
-
|
|
471
|
-
// Populate per-channel JSON schemas from schema.input
|
|
472
|
-
if (inputSchema) {
|
|
473
|
-
if (inputSchema.pathParams) jsonSchema.pathParams = inputSchema.pathParams as Record<string, unknown>
|
|
474
|
-
if (inputSchema.query) jsonSchema.query = inputSchema.query as Record<string, unknown>
|
|
475
|
-
if (inputSchema.body) jsonSchema.body = inputSchema.body as Record<string, unknown>
|
|
476
|
-
if (inputSchema.headers) jsonSchema.headers = inputSchema.headers as Record<string, unknown>
|
|
477
|
-
} else if (config.schema?.params) {
|
|
478
|
-
// Fallback: schema.params treated as body/query depending on method
|
|
479
|
-
if (BODY_METHODS.includes(config.method)) {
|
|
480
|
-
jsonSchema.body = config.schema.params
|
|
481
|
-
} else {
|
|
482
|
-
jsonSchema.query = config.schema.params
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
if (config.schema?.returnType) {
|
|
487
|
-
jsonSchema.response = config.schema.returnType
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
const base: APIHttpRouteDoc = {
|
|
491
|
-
kind: 'api',
|
|
492
|
-
name: procedure.name,
|
|
493
|
-
scope: config.scope,
|
|
494
|
-
path: config.path,
|
|
495
|
-
method: config.method,
|
|
496
|
-
fullPath,
|
|
497
|
-
jsonSchema,
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
if (config.successStatus) {
|
|
501
|
-
base.successStatus = config.successStatus
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
if (config.errors && config.errors.length > 0) {
|
|
505
|
-
base.errors = [...config.errors]
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
let extendedDoc: object = {}
|
|
509
|
-
|
|
510
|
-
if (extendProcedureDoc) {
|
|
511
|
-
extendedDoc = extendProcedureDoc({ base, procedure })
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
return {
|
|
515
|
-
...extendedDoc,
|
|
516
|
-
...base,
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ExtractConfig, ExtractContext, APIConfig, APIHttpRouteDoc } from '../../types.js'
|
|
2
|
-
import { Procedures, TProcedureRegistration } from '../../../index.js'
|
|
3
|
-
import { Context } from 'hono'
|
|
4
|
-
|
|
5
|
-
export type HonoAPIFactoryItem<TFactory = ReturnType<typeof Procedures<any, APIConfig>>> = {
|
|
6
|
-
factory: TFactory
|
|
7
|
-
factoryContext:
|
|
8
|
-
| ExtractContext<TFactory>
|
|
9
|
-
| ((c: Context) => ExtractContext<TFactory> | Promise<ExtractContext<TFactory>>)
|
|
10
|
-
extendProcedureDoc?: (params: {
|
|
11
|
-
/** API App builder base http route doc */
|
|
12
|
-
base: APIHttpRouteDoc
|
|
13
|
-
/** Procedure registration */
|
|
14
|
-
procedure: TProcedureRegistration<any, ExtractConfig<TFactory>>
|
|
15
|
-
}) => Record<string, any>
|
|
16
|
-
}
|