ts-procedures 9.1.0 → 9.3.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/CHANGELOG.md +55 -0
- package/agent_config/claude-code/skills/ts-procedures/api-reference.md +29 -22
- package/agent_config/copilot/copilot-instructions.md +2 -0
- package/agent_config/cursor/cursorrules +2 -0
- package/build/codegen/bin/cli.d.ts +4 -0
- package/build/codegen/bin/cli.js +19 -0
- package/build/codegen/bin/cli.js.map +1 -1
- package/build/codegen/bin/cli.test.js +21 -0
- package/build/codegen/bin/cli.test.js.map +1 -1
- package/build/codegen/bin/flag-specs.js +3 -0
- package/build/codegen/bin/flag-specs.js.map +1 -1
- package/build/codegen/check-output.d.ts +28 -0
- package/build/codegen/check-output.js +216 -0
- package/build/codegen/check-output.js.map +1 -0
- package/build/codegen/check-output.test.d.ts +1 -0
- package/build/codegen/check-output.test.js +160 -0
- package/build/codegen/check-output.test.js.map +1 -0
- package/build/codegen/emit/api-route.js +1 -1
- package/build/codegen/emit/api-route.js.map +1 -1
- package/build/codegen/emit/context.d.ts +9 -0
- package/build/codegen/emit/http-stream-route.js +1 -1
- package/build/codegen/emit/http-stream-route.js.map +1 -1
- package/build/codegen/emit/rpc-route.js +1 -1
- package/build/codegen/emit/rpc-route.js.map +1 -1
- package/build/codegen/emit/scope-file.js +14 -0
- package/build/codegen/emit/scope-file.js.map +1 -1
- package/build/codegen/emit/stream-route.js +1 -1
- package/build/codegen/emit/stream-route.js.map +1 -1
- package/build/codegen/emit-scope.test.js +55 -0
- package/build/codegen/emit-scope.test.js.map +1 -1
- package/build/codegen/emit-types.js +19 -0
- package/build/codegen/emit-types.js.map +1 -1
- package/build/codegen/emit-types.test.js +34 -0
- package/build/codegen/emit-types.test.js.map +1 -1
- package/build/codegen/index.d.ts +14 -0
- package/build/codegen/index.js +11 -1
- package/build/codegen/index.js.map +1 -1
- package/build/codegen/targets/ts/name-collision.test.d.ts +1 -0
- package/build/codegen/targets/ts/name-collision.test.js +30 -0
- package/build/codegen/targets/ts/name-collision.test.js.map +1 -0
- package/build/codegen/targets/ts/run.js +13 -0
- package/build/codegen/targets/ts/run.js.map +1 -1
- package/build/core/create-http-stream.d.ts +3 -14
- package/build/core/create-http-stream.js.map +1 -1
- package/build/core/create-http.d.ts +2 -9
- package/build/core/create-http.js.map +1 -1
- package/build/core/create-http.test-d.d.ts +1 -0
- package/build/core/create-http.test-d.js +104 -0
- package/build/core/create-http.test-d.js.map +1 -0
- package/build/core/procedures.d.ts +6 -16
- package/build/core/types.d.ts +49 -4
- package/build/errors.d.ts +33 -0
- package/build/errors.js +91 -0
- package/build/errors.js.map +1 -0
- package/build/errors.test.d.ts +1 -0
- package/build/errors.test.js +122 -0
- package/build/errors.test.js.map +1 -0
- package/build/exports.d.ts +1 -1
- package/build/exports.js.map +1 -1
- package/build/implementations/http/doc-registry.d.ts +28 -0
- package/build/implementations/http/doc-registry.js +96 -0
- package/build/implementations/http/doc-registry.js.map +1 -0
- package/build/implementations/http/doc-registry.test.d.ts +1 -0
- package/build/implementations/http/doc-registry.test.js +516 -0
- package/build/implementations/http/doc-registry.test.js.map +1 -0
- package/build/implementations/http/error-taxonomy.d.ts +249 -0
- package/build/implementations/http/error-taxonomy.js +252 -0
- package/build/implementations/http/error-taxonomy.js.map +1 -0
- package/build/implementations/http/error-taxonomy.test.d.ts +1 -0
- package/build/implementations/http/error-taxonomy.test.js +399 -0
- package/build/implementations/http/error-taxonomy.test.js.map +1 -0
- package/build/implementations/http/express-rpc/error-taxonomy.test.d.ts +1 -0
- package/build/implementations/http/express-rpc/error-taxonomy.test.js +83 -0
- package/build/implementations/http/express-rpc/error-taxonomy.test.js.map +1 -0
- package/build/implementations/http/express-rpc/index.d.ts +125 -0
- package/build/implementations/http/express-rpc/index.js +216 -0
- package/build/implementations/http/express-rpc/index.js.map +1 -0
- package/build/implementations/http/express-rpc/index.test.d.ts +1 -0
- package/build/implementations/http/express-rpc/index.test.js +684 -0
- package/build/implementations/http/express-rpc/index.test.js.map +1 -0
- package/build/implementations/http/express-rpc/types.d.ts +11 -0
- package/build/implementations/http/express-rpc/types.js +2 -0
- package/build/implementations/http/express-rpc/types.js.map +1 -0
- package/build/implementations/http/hono-api/error-taxonomy.test.d.ts +1 -0
- package/build/implementations/http/hono-api/error-taxonomy.test.js +137 -0
- package/build/implementations/http/hono-api/error-taxonomy.test.js.map +1 -0
- package/build/implementations/http/hono-api/index.d.ts +151 -0
- package/build/implementations/http/hono-api/index.js +344 -0
- package/build/implementations/http/hono-api/index.js.map +1 -0
- package/build/implementations/http/hono-api/index.test.d.ts +1 -0
- package/build/implementations/http/hono-api/index.test.js +992 -0
- package/build/implementations/http/hono-api/index.test.js.map +1 -0
- package/build/implementations/http/hono-api/types.d.ts +13 -0
- package/build/implementations/http/hono-api/types.js +2 -0
- package/build/implementations/http/hono-api/types.js.map +1 -0
- package/build/implementations/http/hono-rpc/error-taxonomy.test.d.ts +1 -0
- package/build/implementations/http/hono-rpc/error-taxonomy.test.js +64 -0
- package/build/implementations/http/hono-rpc/error-taxonomy.test.js.map +1 -0
- package/build/implementations/http/hono-rpc/index.d.ts +130 -0
- package/build/implementations/http/hono-rpc/index.js +209 -0
- package/build/implementations/http/hono-rpc/index.js.map +1 -0
- package/build/implementations/http/hono-rpc/index.test.d.ts +1 -0
- package/build/implementations/http/hono-rpc/index.test.js +828 -0
- package/build/implementations/http/hono-rpc/index.test.js.map +1 -0
- package/build/implementations/http/hono-rpc/types.d.ts +11 -0
- package/build/implementations/http/hono-rpc/types.js +2 -0
- package/build/implementations/http/hono-rpc/types.js.map +1 -0
- package/build/implementations/http/hono-stream/error-taxonomy.test.d.ts +1 -0
- package/build/implementations/http/hono-stream/error-taxonomy.test.js +159 -0
- package/build/implementations/http/hono-stream/error-taxonomy.test.js.map +1 -0
- package/build/implementations/http/hono-stream/index.d.ts +171 -0
- package/build/implementations/http/hono-stream/index.js +415 -0
- package/build/implementations/http/hono-stream/index.js.map +1 -0
- package/build/implementations/http/hono-stream/index.test.d.ts +1 -0
- package/build/implementations/http/hono-stream/index.test.js +1383 -0
- package/build/implementations/http/hono-stream/index.test.js.map +1 -0
- package/build/implementations/http/hono-stream/types.d.ts +15 -0
- package/build/implementations/http/hono-stream/types.js +2 -0
- package/build/implementations/http/hono-stream/types.js.map +1 -0
- package/build/implementations/http/on-request-error.test.d.ts +1 -0
- package/build/implementations/http/on-request-error.test.js +173 -0
- package/build/implementations/http/on-request-error.test.js.map +1 -0
- package/build/implementations/http/route-errors.test.d.ts +1 -0
- package/build/implementations/http/route-errors.test.js +139 -0
- package/build/implementations/http/route-errors.test.js.map +1 -0
- package/build/implementations/types.d.ts +192 -0
- package/build/implementations/types.js +2 -0
- package/build/implementations/types.js.map +1 -0
- package/build/index.d.ts +165 -0
- package/build/index.js +258 -0
- package/build/index.js.map +1 -0
- package/build/index.test.d.ts +1 -0
- package/build/index.test.js +920 -0
- package/build/index.test.js.map +1 -0
- package/build/schema/extract-json-schema.d.ts +2 -0
- package/build/schema/extract-json-schema.js +12 -0
- package/build/schema/extract-json-schema.js.map +1 -0
- package/build/schema/extract-json-schema.test.d.ts +1 -0
- package/build/schema/extract-json-schema.test.js +23 -0
- package/build/schema/extract-json-schema.test.js.map +1 -0
- package/build/schema/parser.d.ts +28 -0
- package/build/schema/parser.js +170 -0
- package/build/schema/parser.js.map +1 -0
- package/build/schema/parser.test.d.ts +1 -0
- package/build/schema/parser.test.js +120 -0
- package/build/schema/parser.test.js.map +1 -0
- package/build/schema/resolve-schema-lib.d.ts +12 -0
- package/build/schema/resolve-schema-lib.js +11 -0
- package/build/schema/resolve-schema-lib.js.map +1 -0
- package/build/schema/resolve-schema-lib.test.d.ts +1 -0
- package/build/schema/resolve-schema-lib.test.js +17 -0
- package/build/schema/resolve-schema-lib.test.js.map +1 -0
- package/build/schema/types.d.ts +8 -0
- package/build/schema/types.js +2 -0
- package/build/schema/types.js.map +1 -0
- package/build/server/types.d.ts +6 -12
- package/build/stack-utils.d.ts +25 -0
- package/build/stack-utils.js +95 -0
- package/build/stack-utils.js.map +1 -0
- package/build/stack-utils.test.d.ts +1 -0
- package/build/stack-utils.test.js +80 -0
- package/build/stack-utils.test.js.map +1 -0
- package/docs/client-and-codegen.md +17 -0
- package/docs/core.md +1 -0
- package/docs/migration-v8-to-v9.md +12 -4
- package/package.json +1 -1
- package/src/codegen/bin/cli.test.ts +28 -0
- package/src/codegen/bin/cli.ts +26 -0
- package/src/codegen/bin/flag-specs.ts +3 -0
- package/src/codegen/check-output.test.ts +177 -0
- package/src/codegen/check-output.ts +262 -0
- package/src/codegen/emit/api-route.ts +1 -1
- package/src/codegen/emit/context.ts +9 -0
- package/src/codegen/emit/http-stream-route.ts +1 -1
- package/src/codegen/emit/rpc-route.ts +1 -1
- package/src/codegen/emit/scope-file.ts +17 -0
- package/src/codegen/emit/stream-route.ts +1 -1
- package/src/codegen/emit-scope.test.ts +60 -0
- package/src/codegen/emit-types.test.ts +36 -0
- package/src/codegen/emit-types.ts +20 -0
- package/src/codegen/index.ts +23 -1
- package/src/codegen/targets/ts/name-collision.test.ts +34 -0
- package/src/codegen/targets/ts/run.ts +16 -0
- package/src/core/create-http-stream.ts +11 -12
- package/src/core/create-http.test-d.ts +154 -0
- package/src/core/create-http.ts +11 -7
- package/src/core/types.ts +63 -4
- package/src/exports.ts +5 -0
- package/src/server/types.ts +8 -12
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { Type } from 'typebox'
|
|
2
|
+
import { describe, expectTypeOf, test } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import { Procedures } from './procedures.js'
|
|
5
|
+
import type { HttpReturn } from './create-http.js'
|
|
6
|
+
import type {
|
|
7
|
+
HttpReq,
|
|
8
|
+
HttpSchemaInput,
|
|
9
|
+
TCreateHttpConfig,
|
|
10
|
+
THttpReqInput,
|
|
11
|
+
THttpResInput,
|
|
12
|
+
} from './types.js'
|
|
13
|
+
import type { APIInput } from '../server/types.js'
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Type tests for HTTP input shape autocomplete / DX contract
|
|
17
|
+
// These guard the shapes that power IDE autocomplete for schema.req / schema.res.
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
describe('THttpReqInput / THttpResInput / APIInput', () => {
|
|
21
|
+
test('APIInput accepts only the four known channels', () => {
|
|
22
|
+
// Valid
|
|
23
|
+
const good: APIInput = {
|
|
24
|
+
pathParams: Type.Object({ id: Type.String() }),
|
|
25
|
+
query: Type.Object({}),
|
|
26
|
+
body: Type.Object({}),
|
|
27
|
+
headers: Type.Object({}),
|
|
28
|
+
}
|
|
29
|
+
expectTypeOf(good).toEqualTypeOf<APIInput>()
|
|
30
|
+
|
|
31
|
+
// Invalid channel should not be assignable
|
|
32
|
+
// @ts-expect-error - unknown channel name
|
|
33
|
+
const _bad: APIInput = { wrong: Type.Object({}) as any }
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
test('THttpResInput shape', () => {
|
|
37
|
+
const resShape: THttpResInput = {
|
|
38
|
+
body: Type.Object({ ok: Type.Boolean() }),
|
|
39
|
+
headers: Type.Object({ 'x-foo': Type.String() }),
|
|
40
|
+
}
|
|
41
|
+
expectTypeOf(resShape).toEqualTypeOf<THttpResInput>()
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
describe('TCreateHttpConfig shapes for literals', () => {
|
|
46
|
+
test('config literal gets the channel keys from the shape (autocomplete contract)', () => {
|
|
47
|
+
const cfg: TCreateHttpConfig = {
|
|
48
|
+
path: '/x',
|
|
49
|
+
method: 'get',
|
|
50
|
+
schema: {
|
|
51
|
+
req: {
|
|
52
|
+
// These keys should be suggested by the IDE
|
|
53
|
+
pathParams: Type.Object({ id: Type.String() }),
|
|
54
|
+
query: undefined,
|
|
55
|
+
},
|
|
56
|
+
res: {
|
|
57
|
+
body: Type.Object({}),
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
expectTypeOf(cfg).toEqualTypeOf<TCreateHttpConfig>()
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test('using satisfies APIInput on req is valid and preserves specific types', () => {
|
|
65
|
+
const req = {
|
|
66
|
+
pathParams: Type.Object({ id: Type.String() }),
|
|
67
|
+
query: Type.Object({ q: Type.Optional(Type.String()) }),
|
|
68
|
+
} satisfies APIInput
|
|
69
|
+
|
|
70
|
+
const cfg: TCreateHttpConfig<typeof req> = {
|
|
71
|
+
path: '/y',
|
|
72
|
+
method: 'get',
|
|
73
|
+
schema: { req },
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// The assignment succeeded, proving the shape accepted the keys
|
|
77
|
+
// (specific inference of TReq from literal is a bonus)
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
describe('handler inference via HttpReq / HttpReturn', () => {
|
|
82
|
+
const procs = Procedures()
|
|
83
|
+
|
|
84
|
+
test('full req shape produces correctly typed handler param', () => {
|
|
85
|
+
const { Get } = procs.CreateHttp(
|
|
86
|
+
'Get',
|
|
87
|
+
{
|
|
88
|
+
path: '/u/:id',
|
|
89
|
+
method: 'get',
|
|
90
|
+
schema: {
|
|
91
|
+
req: {
|
|
92
|
+
pathParams: Type.Object({ id: Type.String() }),
|
|
93
|
+
query: Type.Object({ verbose: Type.Optional(Type.Boolean()) }),
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
async (_ctx, req) => {
|
|
98
|
+
expectTypeOf(req).toEqualTypeOf<{
|
|
99
|
+
pathParams: { id: string }
|
|
100
|
+
query: { verbose?: boolean }
|
|
101
|
+
}>()
|
|
102
|
+
// no res schema => void
|
|
103
|
+
return undefined
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
type Handler = typeof Get
|
|
108
|
+
expectTypeOf<Parameters<Handler>[1]>().toEqualTypeOf<{
|
|
109
|
+
pathParams: { id: string }
|
|
110
|
+
query: { verbose?: boolean }
|
|
111
|
+
}>()
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
test('res with headers produces { body, headers } return shape', () => {
|
|
115
|
+
const { WithHeaders } = procs.CreateHttp(
|
|
116
|
+
'WithHeaders',
|
|
117
|
+
{
|
|
118
|
+
path: '/h',
|
|
119
|
+
method: 'get',
|
|
120
|
+
schema: {
|
|
121
|
+
res: {
|
|
122
|
+
body: Type.Object({ data: Type.String() }),
|
|
123
|
+
headers: Type.Object({ 'x-trace': Type.String() }),
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
async () => ({ body: { data: 'hi' }, headers: { 'x-trace': 'abc' } })
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
type R = Awaited<ReturnType<typeof WithHeaders>>
|
|
131
|
+
expectTypeOf<R>().toEqualTypeOf<{ body: { data: string }; headers: { 'x-trace': string } }>()
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
test('no schema.res yields void (204-style)', () => {
|
|
135
|
+
const { Logout } = procs.CreateHttp(
|
|
136
|
+
'Logout',
|
|
137
|
+
{ path: '/logout', method: 'post' },
|
|
138
|
+
async () => undefined
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
type R = Awaited<ReturnType<typeof Logout>>
|
|
142
|
+
expectTypeOf<R>().toEqualTypeOf<void>()
|
|
143
|
+
})
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
// Smoke test that HttpReq and HttpSchemaInput are exported and usable
|
|
147
|
+
test('HttpReq and HttpSchemaInput are exported and usable', () => {
|
|
148
|
+
type ExampleReq = HttpSchemaInput<THttpReqInput, { pathParams: { id: string } }>
|
|
149
|
+
expectTypeOf<ExampleReq>().toHaveProperty('pathParams')
|
|
150
|
+
|
|
151
|
+
// HttpReq resolves through Infer; we just check it doesn't error and has shape
|
|
152
|
+
type H = HttpReq<{ query: { q?: string } }>
|
|
153
|
+
expectTypeOf<H>().toHaveProperty('query')
|
|
154
|
+
})
|
package/src/core/create-http.ts
CHANGED
|
@@ -10,7 +10,15 @@ import {
|
|
|
10
10
|
validateReqChannels,
|
|
11
11
|
} from './internal.js'
|
|
12
12
|
import type { FactoryRuntime } from './internal.js'
|
|
13
|
-
import type {
|
|
13
|
+
import type {
|
|
14
|
+
HttpReq,
|
|
15
|
+
ProcedureResult,
|
|
16
|
+
TCreateHttpConfig,
|
|
17
|
+
THttpProcedureRegistration,
|
|
18
|
+
THttpReqInput,
|
|
19
|
+
THttpResInput,
|
|
20
|
+
TLocalContext,
|
|
21
|
+
} from './types.js'
|
|
14
22
|
|
|
15
23
|
/**
|
|
16
24
|
* The handler return shape is gated by the DECLARED response schema, not by
|
|
@@ -26,10 +34,6 @@ export type HttpReturn<TRes> =
|
|
|
26
34
|
: TRes extends { body: infer B } ? Infer<B>
|
|
27
35
|
: void
|
|
28
36
|
|
|
29
|
-
type HttpReq<TReq> = TReq extends Record<string, unknown>
|
|
30
|
-
? Prettify<{ [K in keyof TReq]: Infer<TReq[K]> }>
|
|
31
|
-
: undefined
|
|
32
|
-
|
|
33
37
|
export function makeCreateHttp<TContext>(runtime: FactoryRuntime<TContext, any>) {
|
|
34
38
|
/**
|
|
35
39
|
* Defines a REST-shaped HTTP procedure with per-channel input validation
|
|
@@ -40,8 +44,8 @@ export function makeCreateHttp<TContext>(runtime: FactoryRuntime<TContext, any>)
|
|
|
40
44
|
*/
|
|
41
45
|
return function CreateHttp<
|
|
42
46
|
TName extends string,
|
|
43
|
-
TReq extends
|
|
44
|
-
TRes extends
|
|
47
|
+
TReq extends THttpReqInput | undefined = undefined,
|
|
48
|
+
TRes extends THttpResInput | undefined = undefined,
|
|
45
49
|
TErrorKey extends string = string,
|
|
46
50
|
>(
|
|
47
51
|
name: TName,
|
package/src/core/types.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as AJV from 'ajv'
|
|
2
2
|
import type { ProcedureError } from './errors.js'
|
|
3
3
|
import type { SchemaAdapter } from '../schema/adapter.js'
|
|
4
|
-
import type { TJSONSchema } from '../schema/json-schema.js'
|
|
4
|
+
import type { Infer, Prettify, TJSONSchema } from '../schema/json-schema.js'
|
|
5
5
|
import type { Validate } from '../schema/compile.js'
|
|
6
6
|
|
|
7
7
|
export type TNoContextProvided = unknown
|
|
@@ -69,7 +69,64 @@ export type TStreamProcedureRegistration<TContext = unknown, TExtendedConfig = u
|
|
|
69
69
|
|
|
70
70
|
export type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head'
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Canonical shape for `schema.req` channels.
|
|
74
|
+
* Used both to constrain generics and to provide autocomplete when writing
|
|
75
|
+
* `CreateHttp` / `CreateHttpStream` config objects.
|
|
76
|
+
*
|
|
77
|
+
* Note: RPC `Create` / `CreateStream` use a flatter `schema: { params?, yieldType?, returnType? }`
|
|
78
|
+
* directly (no extra container generic), so they don't need an equivalent named input shape.
|
|
79
|
+
*/
|
|
80
|
+
export type THttpReqInput = {
|
|
81
|
+
pathParams?: unknown
|
|
82
|
+
query?: unknown
|
|
83
|
+
body?: unknown
|
|
84
|
+
headers?: unknown
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Canonical shape for `schema.res` on CreateHttp (CreateHttpStream only supports `headers`).
|
|
89
|
+
*/
|
|
90
|
+
export type THttpResInput = {
|
|
91
|
+
body?: unknown
|
|
92
|
+
headers?: unknown
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @internal Helper to surface literal channel keys for autocomplete
|
|
97
|
+
* while still threading the user's concrete generic schemas through for inference.
|
|
98
|
+
*/
|
|
99
|
+
export type HttpSchemaInput<Base, T> = Base & (T extends undefined ? {} : T)
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @internal Shared helper for typing the destructured `req` argument passed to
|
|
103
|
+
* CreateHttp / CreateHttpStream handlers. Mirrors the per-channel Infer.
|
|
104
|
+
*/
|
|
105
|
+
export type HttpReq<TReq> = TReq extends Record<string, unknown>
|
|
106
|
+
? Prettify<{ [K in keyof TReq]: Infer<TReq[K]> }>
|
|
107
|
+
: undefined
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Shape used for the `schema` option of `CreateHttpStream`.
|
|
111
|
+
* Reuses the same req input shape as CreateHttp for autocomplete consistency.
|
|
112
|
+
*/
|
|
113
|
+
export type THttpStreamSchema<
|
|
114
|
+
TReq extends THttpReqInput | undefined = undefined,
|
|
115
|
+
TYield = unknown,
|
|
116
|
+
TReturn = void,
|
|
117
|
+
TResHeaders = undefined,
|
|
118
|
+
> = {
|
|
119
|
+
req?: HttpSchemaInput<THttpReqInput, TReq>
|
|
120
|
+
yield?: TYield
|
|
121
|
+
returnType?: TReturn
|
|
122
|
+
res?: TResHeaders extends undefined ? undefined : { headers: TResHeaders }
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export type TCreateHttpConfig<
|
|
126
|
+
TReq extends THttpReqInput | undefined = undefined,
|
|
127
|
+
TRes extends THttpResInput | undefined = undefined,
|
|
128
|
+
TErrorKey extends string = string,
|
|
129
|
+
> = {
|
|
73
130
|
path: string
|
|
74
131
|
method: HttpMethod
|
|
75
132
|
successStatus?: number
|
|
@@ -78,8 +135,10 @@ export type TCreateHttpConfig<TReq, TRes, TErrorKey extends string = string> = {
|
|
|
78
135
|
description?: string
|
|
79
136
|
/** Optional — a no-input, no-output route (e.g. a 204 logout) may omit it. */
|
|
80
137
|
schema?: {
|
|
81
|
-
|
|
82
|
-
|
|
138
|
+
// HttpSchemaInput surfaces the channel keys for IDE autocomplete / excess-property checking
|
|
139
|
+
// while the generic part carries the caller's concrete schema (for Infer + handler typing).
|
|
140
|
+
req?: HttpSchemaInput<THttpReqInput, TReq>
|
|
141
|
+
res?: HttpSchemaInput<THttpResInput, TRes>
|
|
83
142
|
}
|
|
84
143
|
}
|
|
85
144
|
|
package/src/exports.ts
CHANGED
|
@@ -23,6 +23,11 @@ export type {
|
|
|
23
23
|
THttpProcedureRegistration,
|
|
24
24
|
THttpStreamProcedureRegistration,
|
|
25
25
|
TCreateHttpConfig,
|
|
26
|
+
THttpReqInput,
|
|
27
|
+
THttpResInput,
|
|
28
|
+
THttpStreamSchema,
|
|
29
|
+
HttpSchemaInput,
|
|
30
|
+
HttpReq,
|
|
26
31
|
TLocalContext,
|
|
27
32
|
TStreamContext,
|
|
28
33
|
TNoContextProvided,
|
package/src/server/types.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* guarantees byte-identical generated output vs v8. Do not change field names,
|
|
7
7
|
* optionality, or nesting without re-validating the codegen goldens.
|
|
8
8
|
*/
|
|
9
|
-
import type { ProcedureKind } from '../core/types.js'
|
|
9
|
+
import type { ProcedureKind, THttpReqInput } from '../core/types.js'
|
|
10
10
|
import type { ErrorTaxonomy } from './errors/taxonomy.js'
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -97,6 +97,9 @@ export interface APIHttpRouteDoc {
|
|
|
97
97
|
* Constrains `schema.req` channel names to valid HTTP input sources.
|
|
98
98
|
* Use with `satisfies` to catch typos at compile time:
|
|
99
99
|
*
|
|
100
|
+
* The same shape also powers autocomplete inside `schema.req` when using
|
|
101
|
+
* CreateHttp / CreateHttpStream.
|
|
102
|
+
*
|
|
100
103
|
* @example
|
|
101
104
|
* schema: {
|
|
102
105
|
* req: {
|
|
@@ -105,17 +108,10 @@ export interface APIHttpRouteDoc {
|
|
|
105
108
|
* } satisfies APIInput
|
|
106
109
|
* }
|
|
107
110
|
*/
|
|
108
|
-
export type APIInput<T extends
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
headers?: unknown
|
|
113
|
-
} = {
|
|
114
|
-
pathParams?: unknown
|
|
115
|
-
query?: unknown
|
|
116
|
-
body?: unknown
|
|
117
|
-
headers?: unknown
|
|
118
|
-
}> = T
|
|
111
|
+
export type APIInput<T extends THttpReqInput = THttpReqInput> = T
|
|
112
|
+
|
|
113
|
+
// Re-export the canonical input shapes (useful for advanced typing or custom wrappers)
|
|
114
|
+
export type { THttpReqInput, THttpResInput } from '../core/types.js'
|
|
119
115
|
|
|
120
116
|
export interface StreamHttpRouteDoc extends RPCConfig {
|
|
121
117
|
kind: 'stream'
|