@orpc/server 0.10.0 → 0.11.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.
Files changed (64) hide show
  1. package/dist/{chunk-TDFYNRZV.js → chunk-CVLK2PBB.js} +0 -1
  2. package/dist/fetch.js +1 -2
  3. package/dist/index.js +1 -2
  4. package/dist/src/adapters/fetch.d.ts +0 -1
  5. package/dist/src/builder.d.ts +0 -1
  6. package/dist/src/index.d.ts +0 -1
  7. package/dist/src/middleware.d.ts +0 -1
  8. package/dist/src/procedure-builder.d.ts +0 -1
  9. package/dist/src/procedure-caller.d.ts +0 -1
  10. package/dist/src/procedure-implementer.d.ts +0 -1
  11. package/dist/src/procedure.d.ts +0 -1
  12. package/dist/src/router-builder.d.ts +0 -1
  13. package/dist/src/router-caller.d.ts +0 -1
  14. package/dist/src/router-implementer.d.ts +0 -1
  15. package/dist/src/router.d.ts +0 -1
  16. package/dist/src/types.d.ts +0 -1
  17. package/dist/src/utils.d.ts +0 -1
  18. package/package.json +12 -16
  19. package/dist/chunk-TDFYNRZV.js.map +0 -1
  20. package/dist/fetch.js.map +0 -1
  21. package/dist/index.js.map +0 -1
  22. package/dist/src/adapters/fetch.d.ts.map +0 -1
  23. package/dist/src/builder.d.ts.map +0 -1
  24. package/dist/src/index.d.ts.map +0 -1
  25. package/dist/src/middleware.d.ts.map +0 -1
  26. package/dist/src/procedure-builder.d.ts.map +0 -1
  27. package/dist/src/procedure-caller.d.ts.map +0 -1
  28. package/dist/src/procedure-implementer.d.ts.map +0 -1
  29. package/dist/src/procedure.d.ts.map +0 -1
  30. package/dist/src/router-builder.d.ts.map +0 -1
  31. package/dist/src/router-caller.d.ts.map +0 -1
  32. package/dist/src/router-implementer.d.ts.map +0 -1
  33. package/dist/src/router.d.ts.map +0 -1
  34. package/dist/src/types.d.ts.map +0 -1
  35. package/dist/src/utils.d.ts.map +0 -1
  36. package/dist/tsconfig.tsbuildinfo +0 -1
  37. package/src/adapters/fetch.test.ts +0 -629
  38. package/src/adapters/fetch.ts +0 -290
  39. package/src/builder.test.ts +0 -371
  40. package/src/builder.ts +0 -238
  41. package/src/index.ts +0 -16
  42. package/src/middleware.test.ts +0 -260
  43. package/src/middleware.ts +0 -136
  44. package/src/procedure-builder.test.ts +0 -223
  45. package/src/procedure-builder.ts +0 -158
  46. package/src/procedure-caller.test.ts +0 -171
  47. package/src/procedure-caller.ts +0 -138
  48. package/src/procedure-implementer.test.ts +0 -220
  49. package/src/procedure-implementer.ts +0 -102
  50. package/src/procedure.test.ts +0 -317
  51. package/src/procedure.ts +0 -237
  52. package/src/router-builder.test.ts +0 -106
  53. package/src/router-builder.ts +0 -122
  54. package/src/router-caller.test.ts +0 -126
  55. package/src/router-caller.ts +0 -64
  56. package/src/router-implementer.test.ts +0 -116
  57. package/src/router-implementer.ts +0 -113
  58. package/src/router.test-d.ts +0 -48
  59. package/src/router.test.ts +0 -142
  60. package/src/router.ts +0 -91
  61. package/src/types.test.ts +0 -18
  62. package/src/types.ts +0 -13
  63. package/src/utils.test.ts +0 -16
  64. package/src/utils.ts +0 -16
@@ -1,116 +0,0 @@
1
- import { oc } from '@orpc/contract'
2
- import { z } from 'zod'
3
- import { os, RouterImplementer } from '.'
4
-
5
- const cp1 = oc.input(z.string()).output(z.string())
6
- const cp2 = oc.output(z.string())
7
- const cp3 = oc.route({ method: 'GET', path: '/test' })
8
- const cr = oc.router({
9
- p1: cp1,
10
- nested: oc.router({
11
- p2: cp2,
12
- }),
13
- nested2: {
14
- p3: cp3,
15
- },
16
- })
17
-
18
- const osw = os.context<{ auth: boolean }>().contract(cr)
19
-
20
- const p1 = osw.p1.func(() => {
21
- return 'unnoq'
22
- })
23
-
24
- const p2 = osw.nested.p2.func(() => {
25
- return 'unnoq'
26
- })
27
-
28
- const p3 = osw.nested2.p3.func(() => {
29
- return 'unnoq'
30
- })
31
-
32
- it('required all procedure match', () => {
33
- const implementer = new RouterImplementer<{ auth: boolean }, typeof cr>({
34
- contract: cr,
35
- })
36
-
37
- implementer.router({
38
- p1,
39
- nested: {
40
- p2: os.contract(cp2).func(() => ''),
41
- },
42
- nested2: {
43
- p3,
44
- },
45
- })
46
-
47
- expect(() => {
48
- implementer.router({
49
- // @ts-expect-error p1 is mismatch
50
- p1: os.func(() => {}),
51
- nested: {
52
- p2,
53
- },
54
- nested2: {
55
- p3,
56
- },
57
- })
58
- }).toThrowError('Mismatch implementation for procedure at [p1]')
59
-
60
- expect(() => {
61
- implementer.router({
62
- // @ts-expect-error p1 is mismatch
63
- p1: osw,
64
- nested: {
65
- p2,
66
- },
67
- nested2: {
68
- p3,
69
- },
70
- })
71
- }).toThrowError('Mismatch implementation for procedure at [p1]')
72
-
73
- expect(() => {
74
- implementer.router({
75
- // Not allow manual specification
76
- p1: os
77
- .input(z.string())
78
- .output(z.string())
79
- .func(() => 'unnoq'),
80
- nested: {
81
- p2,
82
- },
83
- nested2: {
84
- p3,
85
- },
86
- })
87
- }).toThrowError('Mismatch implementation for procedure at [p1]')
88
-
89
- expect(() => {
90
- // @ts-expect-error required all procedure match
91
- implementer.router({})
92
- }).toThrowError('Missing implementation for procedure at [p1]')
93
-
94
- expect(() => {
95
- implementer.router({
96
- p1,
97
- nested: {
98
- p2,
99
- },
100
- // @ts-expect-error missing p3
101
- nested2: {},
102
- })
103
- }).toThrowError('Missing implementation for procedure at [nested2.p3]')
104
-
105
- expect(() => {
106
- implementer.router({
107
- p1,
108
- nested: {
109
- p2,
110
- },
111
- nested2: {
112
- p3: p3.prefix('/test'),
113
- },
114
- })
115
- }).toThrowError('Mismatch implementation for procedure at [nested2.p3]')
116
- })
@@ -1,113 +0,0 @@
1
- import type { Middleware } from './middleware'
2
- import type { RouterWithContract } from './router'
3
- import type { Context } from './types'
4
- import {
5
- type ContractProcedure,
6
- type ContractRouter,
7
- isContractProcedure,
8
- } from '@orpc/contract'
9
- import { isProcedure } from './procedure'
10
- import { ProcedureImplementer } from './procedure-implementer'
11
-
12
- export class RouterImplementer<
13
- TContext extends Context,
14
- TContract extends ContractRouter,
15
- > {
16
- constructor(
17
- public zz$ri: {
18
- contract: TContract
19
- },
20
- ) {}
21
-
22
- router(
23
- router: RouterWithContract<TContext, TContract>,
24
- ): RouterWithContract<TContext, TContract> {
25
- assertRouterImplementation(this.zz$ri.contract, router)
26
-
27
- return router
28
- }
29
- }
30
-
31
- export type ChainedRouterImplementer<
32
- TContext extends Context,
33
- TContract extends ContractRouter,
34
- TExtraContext extends Context,
35
- > = {
36
- [K in keyof TContract]: TContract[K] extends ContractProcedure<
37
- infer UInputSchema,
38
- infer UOutputSchema
39
- >
40
- ? ProcedureImplementer<TContext, TExtraContext, UInputSchema, UOutputSchema>
41
- : TContract[K] extends ContractRouter
42
- ? ChainedRouterImplementer<TContext, TContract[K], TExtraContext>
43
- : never
44
- } & RouterImplementer<TContext, TContract>
45
-
46
- export function chainRouterImplementer<
47
- TContext extends Context,
48
- TContract extends ContractRouter,
49
- TExtraContext extends Context,
50
- >(
51
- contract: TContract,
52
- middlewares?: Middleware<any, any, any, any>[],
53
- ): ChainedRouterImplementer<TContext, TContract, TExtraContext> {
54
- const result: Record<string, unknown> = {}
55
-
56
- for (const key in contract) {
57
- const item = contract[key]
58
-
59
- if (isContractProcedure(item)) {
60
- result[key] = new ProcedureImplementer({
61
- contract: item,
62
- middlewares,
63
- })
64
- }
65
- else {
66
- result[key] = chainRouterImplementer(item as ContractRouter, middlewares)
67
- }
68
- }
69
-
70
- const implementer = new RouterImplementer({ contract })
71
-
72
- return Object.assign(implementer, result) as any
73
- }
74
-
75
- export function assertRouterImplementation(
76
- contract: ContractRouter,
77
- router: RouterWithContract<any, any>,
78
- path: string[] = [],
79
- ): void {
80
- for (const key in contract) {
81
- const currentPath = [...path, key]
82
- const contractItem = contract[key]
83
- const routerItem = router[key]
84
-
85
- if (!routerItem) {
86
- throw new Error(
87
- `Missing implementation for procedure at [${currentPath.join('.')}]`,
88
- )
89
- }
90
-
91
- if (isContractProcedure(contractItem)) {
92
- if (isProcedure(routerItem)) {
93
- if (routerItem.zz$p.contract !== contractItem) {
94
- throw new Error(
95
- `Mismatch implementation for procedure at [${currentPath.join('.')}]`,
96
- )
97
- }
98
- }
99
- else {
100
- throw new Error(
101
- `Mismatch implementation for procedure at [${currentPath.join('.')}]`,
102
- )
103
- }
104
- }
105
- else {
106
- assertRouterImplementation(
107
- contractItem as ContractRouter,
108
- routerItem as any,
109
- currentPath,
110
- )
111
- }
112
- }
113
- }
@@ -1,48 +0,0 @@
1
- import type { InferRouterInputs, InferRouterOutputs } from '.'
2
- import { z } from 'zod'
3
- import { os } from '.'
4
-
5
- const router = os.router({
6
- ping: os
7
- .input(z.object({ ping: z.string().transform(() => 1) }))
8
- .output(z.object({ pong: z.number().transform(() => '1') }))
9
- .func(() => ({ pong: 1 })),
10
- user: {
11
- find: os
12
- .input(z.object({ find: z.number().transform(() => '1') }))
13
- .func(() => ({ user: { id: 1 } }))
14
- ,
15
- },
16
- })
17
-
18
- it('InferRouterInputs', () => {
19
- type Inputs = InferRouterInputs<typeof router>
20
-
21
- expectTypeOf<Inputs>().toEqualTypeOf<{
22
- ping: {
23
- ping: string
24
- }
25
- user: {
26
- find: {
27
- find: number
28
- }
29
- }
30
- }>()
31
- })
32
-
33
- it('InferRouterOutputs', () => {
34
- type Outputs = InferRouterOutputs<typeof router>
35
-
36
- expectTypeOf<Outputs>().toEqualTypeOf<{
37
- ping: {
38
- pong: string
39
- }
40
- user: {
41
- find: {
42
- user: {
43
- id: number
44
- }
45
- }
46
- }
47
- }>()
48
- })
@@ -1,142 +0,0 @@
1
- import { oc } from '@orpc/contract'
2
- import { z } from 'zod'
3
- import { os, type RouterWithContract, toContractRouter } from '.'
4
-
5
- it('require procedure match context', () => {
6
- const osw = os.context<{ auth: boolean, userId: string }>()
7
-
8
- osw.router({
9
- ping: osw.context<{ auth: boolean }>().func(() => {
10
- return { pong: 'ping' }
11
- }),
12
-
13
- // @ts-expect-error userId is not match
14
- ping2: osw.context<{ userId: number }>().func(() => {
15
- return { name: 'unnoq' }
16
- }),
17
-
18
- nested: {
19
- ping: osw.context<{ auth: boolean }>().func(() => {
20
- return { pong: 'ping' }
21
- }),
22
-
23
- // @ts-expect-error userId is not match
24
- ping2: osw.context<{ userId: number }>().func(() => {
25
- return { name: 'unnoq' }
26
- }),
27
- },
28
- })
29
- })
30
-
31
- it('require match contract', () => {
32
- const pingContract = oc.route({ method: 'GET', path: '/ping' })
33
- const pongContract = oc.input(z.string()).output(z.string())
34
- const ping = os.contract(pingContract).func(() => {
35
- return 'ping'
36
- })
37
- const pong = os.contract(pongContract).func(() => {
38
- return 'pong'
39
- })
40
-
41
- const contract = oc.router({
42
- ping: pingContract,
43
- pong: pongContract,
44
-
45
- nested: oc.router({
46
- ping: pingContract,
47
- pong: pongContract,
48
- }),
49
- })
50
-
51
- const _1: RouterWithContract<undefined, typeof contract> = {
52
- ping,
53
- pong,
54
-
55
- nested: {
56
- ping,
57
- pong,
58
- },
59
- }
60
-
61
- const _2: RouterWithContract<undefined, typeof contract> = {
62
- ping,
63
- pong,
64
-
65
- nested: os.contract(contract.nested).router({
66
- ping,
67
- pong,
68
- }),
69
- }
70
-
71
- const _3: RouterWithContract<undefined, typeof contract> = {
72
- ping,
73
- pong,
74
-
75
- // @ts-expect-error missing nested.ping
76
- nested: {
77
- pong,
78
- },
79
- }
80
-
81
- const _4: RouterWithContract<undefined, typeof contract> = {
82
- ping,
83
- pong,
84
-
85
- nested: {
86
- ping,
87
- // @ts-expect-error nested.pong is mismatch
88
- pong: os.func(() => 'ping'),
89
- },
90
- }
91
-
92
- // @ts-expect-error missing pong
93
- const _5: RouterWithContract<undefined, typeof contract> = {
94
- ping,
95
-
96
- nested: {
97
- ping,
98
- pong,
99
- },
100
- }
101
- })
102
-
103
- it('toContractRouter', () => {
104
- const p1 = oc.input(z.string()).output(z.string())
105
- const p2 = oc.output(z.string())
106
- const p3 = oc.route({ method: 'GET', path: '/test' })
107
-
108
- const contract = oc.router({
109
- p1,
110
-
111
- nested: oc.router({
112
- p2,
113
- }),
114
-
115
- nested2: {
116
- p3,
117
- },
118
- })
119
-
120
- const osw = os.contract(contract)
121
-
122
- const router = osw.router({
123
- p1: osw.p1.func(() => {
124
- return 'unnoq'
125
- }),
126
-
127
- nested: osw.nested.router({
128
- p2: osw.nested.p2.func(() => {
129
- return 'unnoq'
130
- }),
131
- }),
132
-
133
- nested2: {
134
- p3: osw.nested2.p3.func(() => {
135
- return 'unnoq'
136
- }),
137
- },
138
- })
139
-
140
- expect(toContractRouter(router)).toEqual(contract)
141
- expect(toContractRouter(contract)).toEqual(contract)
142
- })
package/src/router.ts DELETED
@@ -1,91 +0,0 @@
1
- import type {
2
- ContractProcedure,
3
- ContractRouter,
4
- SchemaInput,
5
- SchemaOutput,
6
- } from '@orpc/contract'
7
- import type { Context } from './types'
8
- import {
9
- isContractProcedure,
10
- } from '@orpc/contract'
11
- import {
12
- type DecoratedProcedure,
13
- isProcedure,
14
- type Procedure,
15
- } from './procedure'
16
-
17
- export interface Router<TContext extends Context> {
18
- [k: string]: Procedure<TContext, any, any, any, any> | Router<TContext>
19
- }
20
-
21
- export type HandledRouter<TRouter extends Router<any>> = {
22
- [K in keyof TRouter]: TRouter[K] extends Procedure<
23
- infer UContext,
24
- infer UExtraContext,
25
- infer UInputSchema,
26
- infer UOutputSchema,
27
- infer UFuncOutput
28
- >
29
- ? DecoratedProcedure<
30
- UContext,
31
- UExtraContext,
32
- UInputSchema,
33
- UOutputSchema,
34
- UFuncOutput
35
- >
36
- : TRouter[K] extends Router<any>
37
- ? HandledRouter<TRouter[K]>
38
- : never
39
- }
40
-
41
- export type RouterWithContract<
42
- TContext extends Context,
43
- TContract extends ContractRouter,
44
- > = {
45
- [K in keyof TContract]: TContract[K] extends ContractProcedure<
46
- infer UInputSchema,
47
- infer UOutputSchema
48
- >
49
- ? Procedure<TContext, any, UInputSchema, UOutputSchema, any>
50
- : TContract[K] extends ContractRouter
51
- ? RouterWithContract<TContext, TContract[K]>
52
- : never
53
- }
54
-
55
- export function toContractRouter(
56
- router: ContractRouter | Router<any>,
57
- ): ContractRouter {
58
- const contract: ContractRouter = {}
59
-
60
- for (const key in router) {
61
- const item = router[key]
62
-
63
- if (isContractProcedure(item)) {
64
- contract[key] = item
65
- }
66
- else if (isProcedure(item)) {
67
- contract[key] = item.zz$p.contract
68
- }
69
- else {
70
- contract[key] = toContractRouter(item as any)
71
- }
72
- }
73
-
74
- return contract
75
- }
76
-
77
- export type InferRouterInputs<T extends Router<any>> = {
78
- [K in keyof T]: T[K] extends Procedure<any, any, infer UInputSchema, any, any>
79
- ? SchemaInput<UInputSchema>
80
- : T[K] extends Router<any>
81
- ? InferRouterInputs<T[K]>
82
- : never
83
- }
84
-
85
- export type InferRouterOutputs<T extends Router<any>> = {
86
- [K in keyof T]: T[K] extends Procedure<any, any, any, infer UOutputSchema, infer UFuncOutput>
87
- ? SchemaOutput<UOutputSchema, UFuncOutput>
88
- : T[K] extends Router<any>
89
- ? InferRouterOutputs<T[K]>
90
- : never
91
- }
package/src/types.test.ts DELETED
@@ -1,18 +0,0 @@
1
- import type { MergeContext } from './types'
2
-
3
- it('mergeContext', () => {
4
- expectTypeOf<MergeContext<undefined, undefined>>().toEqualTypeOf<undefined>()
5
- expectTypeOf<MergeContext<undefined, { foo: string }>>().toEqualTypeOf<{
6
- foo: string
7
- }>()
8
- expectTypeOf<MergeContext<{ foo: string }, undefined>>().toEqualTypeOf<{
9
- foo: string
10
- }>()
11
- expectTypeOf<MergeContext<{ foo: string }, { foo: string }>>().toEqualTypeOf<{
12
- foo: string
13
- }>()
14
- expectTypeOf<MergeContext<{ foo: string }, { bar: string }>>().toMatchTypeOf<{
15
- foo: string
16
- bar: string
17
- }>()
18
- })
package/src/types.ts DELETED
@@ -1,13 +0,0 @@
1
- import type { WELL_DEFINED_PROCEDURE } from './procedure'
2
-
3
- export type Context = Record<string, unknown> | undefined
4
-
5
- export type MergeContext<
6
- TA extends Context,
7
- TB extends Context,
8
- > = TA extends undefined ? TB : TB extends undefined ? TA : TA & TB
9
-
10
- export interface Meta {
11
- path: string[]
12
- procedure: WELL_DEFINED_PROCEDURE
13
- }
package/src/utils.test.ts DELETED
@@ -1,16 +0,0 @@
1
- import { mergeContext } from './utils'
2
-
3
- it('mergeContext', () => {
4
- expect(mergeContext(undefined, undefined)).toBe(undefined)
5
- expect(mergeContext(undefined, { foo: 'bar' })).toEqual({ foo: 'bar' })
6
- expect(mergeContext({ foo: 'bar' }, undefined)).toEqual({ foo: 'bar' })
7
- expect(mergeContext({ foo: 'bar' }, { foo: 'bar' })).toEqual({ foo: 'bar' })
8
- expect(mergeContext({ foo: 'bar' }, { bar: 'bar' })).toEqual({
9
- foo: 'bar',
10
- bar: 'bar',
11
- })
12
- expect(mergeContext({ foo: 'bar' }, { bar: 'bar', foo: 'bar1' })).toEqual({
13
- foo: 'bar1',
14
- bar: 'bar',
15
- })
16
- })
package/src/utils.ts DELETED
@@ -1,16 +0,0 @@
1
- import type { Context, MergeContext } from './types'
2
-
3
- export function mergeContext<A extends Context, B extends Context>(
4
- a: A,
5
- b: B,
6
- ): MergeContext<A, B> {
7
- if (!a)
8
- return b as any
9
- if (!b)
10
- return a as any
11
-
12
- return {
13
- ...a,
14
- ...b,
15
- } as any
16
- }