ts-procedures 7.2.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 +139 -53
- package/agent_config/claude-code/skills/ts-procedures/api-reference.md +208 -231
- 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 +36 -48
- package/agent_config/cursor/cursorrules +36 -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 +125 -115
- package/build/index.js +10 -222
- package/build/index.js.map +1 -1
- package/build/index.test.js +30 -822
- 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 +34 -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 +35 -1091
- package/src/index.ts +50 -474
- 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,320 +0,0 @@
|
|
|
1
|
-
import { Hono, Context } from 'hono'
|
|
2
|
-
import { kebabCase } from 'es-toolkit/string'
|
|
3
|
-
import { TProcedureRegistration } from '../../../index.js'
|
|
4
|
-
import {
|
|
5
|
-
ExtractConfig,
|
|
6
|
-
ExtractContext,
|
|
7
|
-
ProceduresFactory,
|
|
8
|
-
RPCConfig,
|
|
9
|
-
RPCHttpRouteDoc,
|
|
10
|
-
} from '../../types.js'
|
|
11
|
-
import {
|
|
12
|
-
ErrorTaxonomy,
|
|
13
|
-
ErrorTaxonomyEntry,
|
|
14
|
-
UnknownErrorConfig,
|
|
15
|
-
defineErrorTaxonomy,
|
|
16
|
-
resolveErrorResponse,
|
|
17
|
-
} from '../error-taxonomy.js'
|
|
18
|
-
import { castArray } from 'es-toolkit/compat'
|
|
19
|
-
import { HonoFactoryItem } from './types.js'
|
|
20
|
-
|
|
21
|
-
export type { RPCConfig, RPCHttpRouteDoc }
|
|
22
|
-
export { defineErrorTaxonomy }
|
|
23
|
-
export type { ErrorTaxonomy, ErrorTaxonomyEntry, UnknownErrorConfig }
|
|
24
|
-
|
|
25
|
-
export type HonoRPCAppBuilderConfig = {
|
|
26
|
-
/**
|
|
27
|
-
* An existing Hono application instance to use.
|
|
28
|
-
* If not provided, a new instance will be created.
|
|
29
|
-
*/
|
|
30
|
-
app?: Hono
|
|
31
|
-
/** Optional path prefix for all RPC routes. */
|
|
32
|
-
pathPrefix?: string
|
|
33
|
-
onRequestStart?: (c: Context) => void
|
|
34
|
-
onRequestEnd?: (c: Context) => void
|
|
35
|
-
onSuccess?: (procedure: TProcedureRegistration, c: Context) => void
|
|
36
|
-
/**
|
|
37
|
-
* Declarative error-to-response mapping (one of the two peer error modes).
|
|
38
|
-
* See hono-api for the full taxonomy contract. User entries take precedence
|
|
39
|
-
* over the framework default taxonomy.
|
|
40
|
-
*/
|
|
41
|
-
errors?: ErrorTaxonomy
|
|
42
|
-
/** Fallback serializer for errors not matched by the taxonomy. */
|
|
43
|
-
unknownError?: UnknownErrorConfig
|
|
44
|
-
/**
|
|
45
|
-
* Imperative error callback — the other peer error mode. Receives every
|
|
46
|
-
* error directly and returns the HTTP response. Use this when you want full
|
|
47
|
-
* control over the response shape, or alongside `errors` for the tail of
|
|
48
|
-
* errors the taxonomy doesn't cover.
|
|
49
|
-
*/
|
|
50
|
-
onError?: (
|
|
51
|
-
procedure: TProcedureRegistration,
|
|
52
|
-
c: Context,
|
|
53
|
-
error: Error
|
|
54
|
-
) => Response | Promise<Response>
|
|
55
|
-
/**
|
|
56
|
-
* Cross-cutting observer — fires for every caught error, BEFORE dispatch.
|
|
57
|
-
* Awaited. Cannot mutate the response. Intended for logging, tracing, and
|
|
58
|
-
* metrics. Thrown errors inside the observer are swallowed and logged.
|
|
59
|
-
*/
|
|
60
|
-
onRequestError?: (ctx: OnRequestErrorContext) => void | Promise<void>
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Context passed to the `onRequestError` observer.
|
|
65
|
-
*/
|
|
66
|
-
export type OnRequestErrorContext = {
|
|
67
|
-
err: unknown
|
|
68
|
-
procedure: TProcedureRegistration
|
|
69
|
-
raw: Context
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Builder class for creating a Hono application with RPC routes.
|
|
74
|
-
*
|
|
75
|
-
* Usage:
|
|
76
|
-
* const PublicRPC = Procedures<PublicRPCContext, RPCConfig>()
|
|
77
|
-
* const ProtectedRPC = Procedures<ProtectedRPCContext, RPCConfig>()
|
|
78
|
-
*
|
|
79
|
-
* const rpcApp = new HonoRPCAppBuilder()
|
|
80
|
-
* .register(PublicRPC, (c): Promise<PublicRPCContext> => { /* context resolution logic * / })
|
|
81
|
-
* .register(ProtectedRPC, (c): Promise<ProtectedRPCContext> => { /* context resolution logic * / })
|
|
82
|
-
* .build();
|
|
83
|
-
*
|
|
84
|
-
* const app = rpcApp.app; // Hono application
|
|
85
|
-
* const docs = rpcApp.docs; // RPC route documentation
|
|
86
|
-
*/
|
|
87
|
-
export class HonoRPCAppBuilder {
|
|
88
|
-
/**
|
|
89
|
-
* Constructor for HonoRPCAppBuilder.
|
|
90
|
-
*
|
|
91
|
-
* @param config
|
|
92
|
-
*/
|
|
93
|
-
constructor(readonly config?: HonoRPCAppBuilderConfig) {
|
|
94
|
-
if (config?.app) {
|
|
95
|
-
this._app = config.app
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (config?.onRequestStart) {
|
|
99
|
-
this._app.use('*', async (c, next) => {
|
|
100
|
-
config.onRequestStart!(c)
|
|
101
|
-
await next()
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (config?.onRequestEnd) {
|
|
106
|
-
this._app.use('*', async (c, next) => {
|
|
107
|
-
await next()
|
|
108
|
-
config.onRequestEnd!(c)
|
|
109
|
-
})
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Generates the RPC route path based on the RPC configuration.
|
|
115
|
-
* `RPCConfig.scope` can be a string or an array of strings to form nested paths.
|
|
116
|
-
*
|
|
117
|
-
* Example
|
|
118
|
-
* name: 'GetUser'
|
|
119
|
-
* scope: ['users', 'profile']
|
|
120
|
-
* version: 1
|
|
121
|
-
* path: /users/profile/get-user/1
|
|
122
|
-
* @param config
|
|
123
|
-
*/
|
|
124
|
-
static makeRPCHttpRoutePath({
|
|
125
|
-
name,
|
|
126
|
-
config,
|
|
127
|
-
prefix,
|
|
128
|
-
}: {
|
|
129
|
-
name: string
|
|
130
|
-
prefix?: string
|
|
131
|
-
config: RPCConfig
|
|
132
|
-
}) {
|
|
133
|
-
const normalizedPrefix = prefix ? (prefix.startsWith('/') ? prefix : `/${prefix}`) : ''
|
|
134
|
-
|
|
135
|
-
return `${normalizedPrefix}/${castArray(config.scope).map(kebabCase).join('/')}/${kebabCase(name)}/${String(config.version).trim()}`
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Instance method wrapper for makeRPCHttpRoutePath that uses the builder's pathPrefix.
|
|
140
|
-
* @param config - The RPC configuration
|
|
141
|
-
*/
|
|
142
|
-
makeRPCHttpRoutePath(name: string, config: RPCConfig): string {
|
|
143
|
-
return HonoRPCAppBuilder.makeRPCHttpRoutePath({
|
|
144
|
-
name,
|
|
145
|
-
config,
|
|
146
|
-
prefix: this.config?.pathPrefix,
|
|
147
|
-
})
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
private factories: HonoFactoryItem<any>[] = []
|
|
151
|
-
|
|
152
|
-
private _app: Hono = new Hono()
|
|
153
|
-
private _docs: (RPCHttpRouteDoc & object)[] = []
|
|
154
|
-
private _skipped: { name: string; reason: string }[] = []
|
|
155
|
-
|
|
156
|
-
get app(): Hono {
|
|
157
|
-
return this._app
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
get docs(): RPCHttpRouteDoc[] {
|
|
161
|
-
return this._docs
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Procedures that were skipped at `build()` time because they don't fit
|
|
166
|
-
* this builder (e.g. streaming procedures registered against an RPC
|
|
167
|
-
* builder). Surfaced via `DocSource.skippedProcedures` so DocRegistry can
|
|
168
|
-
* warn about coverage gaps.
|
|
169
|
-
*/
|
|
170
|
-
get skippedProcedures(): { name: string; reason: string }[] {
|
|
171
|
-
return this._skipped
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Registers a procedure factory with its context.
|
|
176
|
-
* @param factory - The procedure factory created by Procedures<Context, RPCConfig>()
|
|
177
|
-
* @param factoryContext - The context for procedure handlers. Can be a direct value,
|
|
178
|
-
* a sync function (c) => Context, or an async function (c) => Promise<Context>
|
|
179
|
-
* @param extendProcedureDoc - A custom function to extend the generated RPC route documentation for each procedure.
|
|
180
|
-
*/
|
|
181
|
-
register<TFactory extends ProceduresFactory>(
|
|
182
|
-
factory: TFactory,
|
|
183
|
-
factoryContext:
|
|
184
|
-
| ExtractContext<TFactory>
|
|
185
|
-
| ((c: Context) => ExtractContext<TFactory> | Promise<ExtractContext<TFactory>>),
|
|
186
|
-
extendProcedureDoc?: (params: {
|
|
187
|
-
/* RPC App builder base http route doc */
|
|
188
|
-
base: RPCHttpRouteDoc
|
|
189
|
-
/* Procedure registration */
|
|
190
|
-
procedure: TProcedureRegistration<any, ExtractConfig<TFactory>>
|
|
191
|
-
}) => Record<string, any>
|
|
192
|
-
): this {
|
|
193
|
-
this.factories.push({ factory, factoryContext, extendProcedureDoc } as HonoFactoryItem<any>)
|
|
194
|
-
return this
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Builds and returns the Hono application with registered RPC routes.
|
|
199
|
-
* @return Hono
|
|
200
|
-
*/
|
|
201
|
-
build(): Hono {
|
|
202
|
-
this.factories.forEach(({ factory, factoryContext, extendProcedureDoc }) => {
|
|
203
|
-
factory.getProcedures().forEach((procedure: TProcedureRegistration<any, RPCConfig>) => {
|
|
204
|
-
// Skip streaming procedures — RPC builder cannot serve them. Without
|
|
205
|
-
// this guard, the procedure would silently get a POST route that
|
|
206
|
-
// returns its async generator object as a JSON response, which is not
|
|
207
|
-
// a useful failure mode. Procedures meant to stream should be
|
|
208
|
-
// registered with HonoStreamAppBuilder.
|
|
209
|
-
if ((procedure as { isStream?: boolean }).isStream === true) {
|
|
210
|
-
const reason =
|
|
211
|
-
'Streaming procedure registered with HonoRPCAppBuilder — register it with HonoStreamAppBuilder instead.'
|
|
212
|
-
this._skipped.push({ name: procedure.name, reason })
|
|
213
|
-
console.warn(
|
|
214
|
-
`[ts-procedures hono-rpc] Skipping procedure "${procedure.name}": ${reason}`
|
|
215
|
-
)
|
|
216
|
-
return
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const route = this.buildRpcHttpRouteDoc(procedure, extendProcedureDoc)
|
|
220
|
-
|
|
221
|
-
this._docs.push(route)
|
|
222
|
-
|
|
223
|
-
this._app.post(route.path, async (c) => {
|
|
224
|
-
try {
|
|
225
|
-
const context =
|
|
226
|
-
typeof factoryContext === 'function'
|
|
227
|
-
? await factoryContext(c)
|
|
228
|
-
: (factoryContext as ExtractContext<typeof factory>)
|
|
229
|
-
|
|
230
|
-
// Hono uses c.req.json() for body parsing
|
|
231
|
-
const body = await c.req.json().catch(() => ({}))
|
|
232
|
-
const result = await procedure.handler({ ...context, signal: c.req.raw.signal }, body)
|
|
233
|
-
|
|
234
|
-
if (this.config?.onSuccess) {
|
|
235
|
-
this.config.onSuccess(procedure, c)
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Hono returns Response objects via c.json()
|
|
239
|
-
return c.json(result)
|
|
240
|
-
} catch (error) {
|
|
241
|
-
if (this.config?.onRequestError) {
|
|
242
|
-
try {
|
|
243
|
-
await this.config.onRequestError({ err: error, procedure, raw: c })
|
|
244
|
-
} catch (observerErr) {
|
|
245
|
-
console.error('[ts-procedures hono-rpc] onRequestError threw — swallowed:', observerErr)
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
if (this.config?.errors || this.config?.unknownError) {
|
|
249
|
-
const resolved = resolveErrorResponse({
|
|
250
|
-
err: error,
|
|
251
|
-
userTaxonomy: this.config.errors,
|
|
252
|
-
unknownError: this.config.unknownError,
|
|
253
|
-
procedure,
|
|
254
|
-
raw: c,
|
|
255
|
-
})
|
|
256
|
-
if (resolved) {
|
|
257
|
-
await resolved.runOnCatch()
|
|
258
|
-
return c.json(resolved.body, resolved.statusCode as never)
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
if (this.config?.onError) {
|
|
262
|
-
return this.config.onError(procedure, c, error as Error)
|
|
263
|
-
}
|
|
264
|
-
return c.json({ error: (error as Error).message }, 500)
|
|
265
|
-
}
|
|
266
|
-
})
|
|
267
|
-
})
|
|
268
|
-
})
|
|
269
|
-
|
|
270
|
-
return this._app
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Generates the RPC HTTP route for the given procedure.
|
|
275
|
-
* @param procedure
|
|
276
|
-
*/
|
|
277
|
-
private buildRpcHttpRouteDoc(
|
|
278
|
-
procedure: TProcedureRegistration<any, RPCConfig>,
|
|
279
|
-
extendProcedureDoc: HonoFactoryItem['extendProcedureDoc']
|
|
280
|
-
): RPCHttpRouteDoc {
|
|
281
|
-
const { config } = procedure
|
|
282
|
-
const path = HonoRPCAppBuilder.makeRPCHttpRoutePath({
|
|
283
|
-
name: procedure.name,
|
|
284
|
-
config,
|
|
285
|
-
prefix: this.config?.pathPrefix,
|
|
286
|
-
})
|
|
287
|
-
const method = 'post' as const // RPCs use POST method
|
|
288
|
-
const jsonSchema: { body?: Record<string, unknown>; response?: Record<string, unknown> } = {}
|
|
289
|
-
|
|
290
|
-
if (config.schema?.params) {
|
|
291
|
-
jsonSchema.body = config.schema.params
|
|
292
|
-
}
|
|
293
|
-
if (config.schema?.returnType) {
|
|
294
|
-
jsonSchema.response = config.schema.returnType
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
const base: RPCHttpRouteDoc = {
|
|
298
|
-
kind: 'rpc' as const,
|
|
299
|
-
name: procedure.name,
|
|
300
|
-
version: config.version,
|
|
301
|
-
scope: config.scope,
|
|
302
|
-
path,
|
|
303
|
-
method,
|
|
304
|
-
jsonSchema,
|
|
305
|
-
}
|
|
306
|
-
if (config.errors && config.errors.length > 0) {
|
|
307
|
-
base.errors = [...config.errors]
|
|
308
|
-
}
|
|
309
|
-
let extendedDoc: object = {}
|
|
310
|
-
|
|
311
|
-
if (extendProcedureDoc) {
|
|
312
|
-
extendedDoc = extendProcedureDoc({ base, procedure })
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return {
|
|
316
|
-
...extendedDoc,
|
|
317
|
-
...base,
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ExtractConfig, ExtractContext, RPCConfig, RPCHttpRouteDoc } from '../../types.js'
|
|
2
|
-
import { Procedures, TProcedureRegistration } from '../../../index.js'
|
|
3
|
-
import { Context } from 'hono'
|
|
4
|
-
|
|
5
|
-
export type HonoFactoryItem<TFactory = ReturnType<typeof Procedures<any, RPCConfig>>> = {
|
|
6
|
-
factory: TFactory
|
|
7
|
-
factoryContext:
|
|
8
|
-
| ExtractContext<TFactory>
|
|
9
|
-
| ((c: Context) => ExtractContext<TFactory> | Promise<ExtractContext<TFactory>>)
|
|
10
|
-
extendProcedureDoc?: (params: {
|
|
11
|
-
/* RPC App builder base http route doc */
|
|
12
|
-
base: RPCHttpRouteDoc
|
|
13
|
-
/* Procedure registration */
|
|
14
|
-
procedure: TProcedureRegistration<any, ExtractConfig<TFactory>>
|
|
15
|
-
}) => Record<string, any>
|
|
16
|
-
}
|