@orpc/contract 0.0.0-next.e9dc36e → 0.0.0-next.ee0aeaf

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.
@@ -1,179 +0,0 @@
1
- import { z } from 'zod'
2
- import { type DecoratedContractProcedure, oc } from '.'
3
-
4
- describe('define a procedure', () => {
5
- it('use route method', () => {
6
- const procedure = oc.route({
7
- method: 'GET',
8
- path: '/users/{id}',
9
- deprecated: true,
10
- summary: 'Get user',
11
- description: 'Get user by id',
12
- tags: ['bbbb'],
13
- })
14
-
15
- expectTypeOf(procedure).toEqualTypeOf<
16
- DecoratedContractProcedure<undefined, undefined>
17
- >()
18
-
19
- expect(procedure.zz$cp).toMatchObject({
20
- method: 'GET',
21
- path: '/users/{id}',
22
- deprecated: true,
23
- summary: 'Get user',
24
- description: 'Get user by id',
25
- tags: ['bbbb'],
26
- })
27
- })
28
-
29
- it('use input method', () => {
30
- const schema = z.object({
31
- id: z.string(),
32
- })
33
-
34
- const procedure = oc.input(schema, { id: '123' })
35
-
36
- expectTypeOf(procedure).toEqualTypeOf<
37
- DecoratedContractProcedure<typeof schema, undefined>
38
- >()
39
-
40
- expect(procedure.zz$cp).toMatchObject({
41
- InputSchema: schema,
42
- inputExample: { id: '123' },
43
- })
44
- })
45
-
46
- it('use output method', () => {
47
- const schema = z.object({ id: z.string() })
48
-
49
- const procedure = oc.output(schema, { id: '123' })
50
-
51
- expectTypeOf(procedure).toEqualTypeOf<
52
- DecoratedContractProcedure<undefined, typeof schema>
53
- >()
54
-
55
- expect(procedure.zz$cp).toMatchObject({
56
- OutputSchema: schema,
57
- outputExample: { id: '123' },
58
- })
59
- })
60
- })
61
-
62
- describe('define a router', () => {
63
- it('simple', () => {
64
- const schema1 = z.string()
65
- const schema2 = z.object({ id: z.string() })
66
- const ping = oc.output(schema1)
67
- const find = oc.output(schema2)
68
-
69
- const router = oc.router({
70
- ping,
71
- user: {
72
- find,
73
- },
74
- user2: oc.router({
75
- find,
76
- }),
77
- })
78
-
79
- expectTypeOf(router).toMatchTypeOf<{
80
- ping: typeof ping
81
- user: {
82
- find: typeof find
83
- }
84
- user2: {
85
- find: typeof find
86
- }
87
- }>()
88
-
89
- expect(router).toMatchObject({
90
- ping,
91
- user: {
92
- find,
93
- },
94
- user2: {
95
- find,
96
- },
97
- })
98
- })
99
-
100
- it('with prefix', () => {
101
- const schema1 = z.string()
102
- const schema2 = z.object({ id: z.string() })
103
- const ping = oc.output(schema1)
104
- const find = oc.output(schema2)
105
-
106
- const router = oc.router({
107
- ping: ping.prefix('/ping'),
108
- user: {
109
- find,
110
- },
111
- user2: oc
112
- .prefix('/internal')
113
- .prefix('/user2')
114
- .router({
115
- find2: find.prefix('/find2'),
116
- }),
117
- })
118
-
119
- expectTypeOf(router).toMatchTypeOf<{
120
- ping: typeof ping
121
- user: {
122
- find: typeof find
123
- }
124
- user2: {
125
- find2: typeof find
126
- }
127
- }>()
128
-
129
- expect(router).toMatchObject({
130
- ping: ping.prefix('/ping'),
131
- user: {
132
- find,
133
- },
134
- user2: {
135
- find2: find.prefix('/internal/user2/find2'),
136
- },
137
- })
138
- })
139
-
140
- it('with tags', () => {
141
- const schema1 = z.string()
142
- const schema2 = z.object({ id: z.string() })
143
- const ping = oc.output(schema1)
144
- const find = oc.output(schema2)
145
-
146
- const router = oc.router({
147
- ping: ping.prefix('/ping'),
148
- user: {
149
- find,
150
- },
151
- user2: oc
152
- .tags('user')
153
- .tags('internal')
154
- .router({
155
- find2: find.prefix('/find2'),
156
- }),
157
- })
158
-
159
- expectTypeOf(router).toMatchTypeOf<{
160
- ping: typeof ping
161
- user: {
162
- find: typeof find
163
- }
164
- user2: {
165
- find2: typeof find
166
- }
167
- }>()
168
-
169
- expect(router).toMatchObject({
170
- ping: ping.prefix('/ping'),
171
- user: {
172
- find,
173
- },
174
- user2: {
175
- find2: find.addTags('user', 'internal'),
176
- },
177
- })
178
- })
179
- })
package/src/builder.ts DELETED
@@ -1,52 +0,0 @@
1
- import type { ContractRouter } from './router'
2
- import type { HTTPPath, Schema, SchemaInput, SchemaOutput } from './types'
3
- import { DecoratedContractProcedure, type RouteOptions } from './procedure'
4
- import { ContractRouterBuilder } from './router-builder'
5
-
6
- export class ContractBuilder {
7
- prefix(prefix: HTTPPath): ContractRouterBuilder {
8
- return new ContractRouterBuilder({
9
- prefix,
10
- })
11
- }
12
-
13
- tags(...tags: string[]): ContractRouterBuilder {
14
- return new ContractRouterBuilder({
15
- tags,
16
- })
17
- }
18
-
19
- route(opts: RouteOptions): DecoratedContractProcedure<undefined, undefined> {
20
- return new DecoratedContractProcedure({
21
- InputSchema: undefined,
22
- OutputSchema: undefined,
23
- ...opts,
24
- })
25
- }
26
-
27
- input<USchema extends Schema>(
28
- schema: USchema,
29
- example?: SchemaInput<USchema>,
30
- ): DecoratedContractProcedure<USchema, undefined> {
31
- return new DecoratedContractProcedure({
32
- InputSchema: schema,
33
- inputExample: example,
34
- OutputSchema: undefined,
35
- })
36
- }
37
-
38
- output<USchema extends Schema>(
39
- schema: USchema,
40
- example?: SchemaOutput<USchema>,
41
- ): DecoratedContractProcedure<undefined, USchema> {
42
- return new DecoratedContractProcedure({
43
- InputSchema: undefined,
44
- OutputSchema: schema,
45
- outputExample: example,
46
- })
47
- }
48
-
49
- router<T extends ContractRouter>(router: T): T {
50
- return router
51
- }
52
- }
package/src/constants.ts DELETED
@@ -1,2 +0,0 @@
1
- export const ORPC_HEADER = 'x-orpc-transformer'
2
- export const ORPC_HEADER_VALUE = 't'
package/src/index.ts DELETED
@@ -1,12 +0,0 @@
1
- /** unnoq */
2
-
3
- import { ContractBuilder } from './builder'
4
-
5
- export * from './builder'
6
- export * from './constants'
7
- export * from './procedure'
8
- export * from './router'
9
- export * from './types'
10
- export * from './utils'
11
-
12
- export const oc = new ContractBuilder()
@@ -1,99 +0,0 @@
1
- import type { DecoratedContractProcedure } from './procedure'
2
- import { z } from 'zod'
3
- import { isContractProcedure, oc } from '.'
4
-
5
- it('prefix method', () => {
6
- const os = oc
7
- const p1 = os.route({
8
- method: 'GET',
9
- path: '/ping',
10
- })
11
- const p2 = os.input(z.object({}))
12
-
13
- expect(p1.prefix('/prefix').zz$cp.path).toEqual('/prefix/ping')
14
- expect(p2.prefix('/prefix').zz$cp.path).toEqual(undefined)
15
-
16
- expect(p1.prefix('/1').prefix('/2').zz$cp.path).toEqual('/2/1/ping')
17
- expect(p2.prefix('/1').prefix('/2').zz$cp.path).toEqual(undefined)
18
- })
19
-
20
- it('route method', () => {
21
- const p = oc
22
- .route({
23
- method: 'POST',
24
- })
25
- .route({
26
- method: 'GET',
27
- path: '/abc',
28
- deprecated: true,
29
- description: 'abc',
30
- summary: 'abc',
31
- tags: ['user'],
32
- })
33
-
34
- expectTypeOf(p).toEqualTypeOf<
35
- DecoratedContractProcedure<undefined, undefined>
36
- >()
37
-
38
- expect(p.zz$cp).toMatchObject({
39
- method: 'GET',
40
- path: '/abc',
41
- deprecated: true,
42
- description: 'abc',
43
- summary: 'abc',
44
- tags: ['user'],
45
- })
46
- })
47
-
48
- it('input method', () => {
49
- const schema = z.string()
50
- const p = oc.route({}).input(schema)
51
-
52
- expectTypeOf(p).toEqualTypeOf<
53
- DecoratedContractProcedure<typeof schema, undefined>
54
- >()
55
-
56
- expect(p.zz$cp).toMatchObject({
57
- InputSchema: schema,
58
- inputExample: undefined,
59
- })
60
- })
61
-
62
- it('output method', () => {
63
- const schema = z.string()
64
- const p = oc.route({}).output(schema)
65
-
66
- expectTypeOf(p).toEqualTypeOf<
67
- DecoratedContractProcedure<undefined, typeof schema>
68
- >()
69
-
70
- expect(p.zz$cp).toMatchObject({
71
- OutputSchema: schema,
72
- outputExample: undefined,
73
- })
74
- })
75
-
76
- it('addTags method', () => {
77
- const schema = z.string()
78
- const p = oc.route({}).output(schema)
79
-
80
- expect(p.zz$cp.tags).toBe(undefined)
81
-
82
- const p2 = p.addTags('foo', 'bar')
83
-
84
- expect(p2.zz$cp.tags).toEqual(['foo', 'bar'])
85
-
86
- const p3 = p2.addTags('baz')
87
-
88
- expect(p3.zz$cp.tags).toEqual(['foo', 'bar', 'baz'])
89
- })
90
-
91
- it('isContractProcedure function', () => {
92
- expect(isContractProcedure(oc)).toBe(false)
93
- expect(isContractProcedure(oc.router({}))).toBe(false)
94
- expect(isContractProcedure(oc.route({}))).toBe(true)
95
-
96
- expect(isContractProcedure(oc.router({ prefix: oc.route({}) }).prefix)).toBe(
97
- true,
98
- )
99
- })
package/src/procedure.ts DELETED
@@ -1,125 +0,0 @@
1
- import type {
2
- HTTPMethod,
3
- HTTPPath,
4
- Schema,
5
- SchemaInput,
6
- SchemaOutput,
7
- } from './types'
8
-
9
- export interface RouteOptions {
10
- method?: HTTPMethod
11
- path?: HTTPPath
12
- summary?: string
13
- description?: string
14
- deprecated?: boolean
15
- tags?: string[]
16
- }
17
-
18
- export class ContractProcedure<
19
- TInputSchema extends Schema,
20
- TOutputSchema extends Schema,
21
- > {
22
- constructor(
23
- public zz$cp: {
24
- path?: HTTPPath
25
- method?: HTTPMethod
26
- summary?: string
27
- description?: string
28
- deprecated?: boolean
29
- tags?: string[]
30
- InputSchema: TInputSchema
31
- inputExample?: SchemaOutput<TInputSchema>
32
- OutputSchema: TOutputSchema
33
- outputExample?: SchemaOutput<TOutputSchema>
34
- },
35
- ) {}
36
- }
37
-
38
- export class DecoratedContractProcedure<
39
- TInputSchema extends Schema,
40
- TOutputSchema extends Schema,
41
- > extends ContractProcedure<TInputSchema, TOutputSchema> {
42
- static decorate<TInputSchema extends Schema, TOutputSchema extends Schema>(
43
- cp: ContractProcedure<TInputSchema, TOutputSchema>,
44
- ): DecoratedContractProcedure<TInputSchema, TOutputSchema> {
45
- if (cp instanceof DecoratedContractProcedure)
46
- return cp
47
- return new DecoratedContractProcedure(cp.zz$cp)
48
- }
49
-
50
- route(
51
- opts: RouteOptions,
52
- ): DecoratedContractProcedure<TInputSchema, TOutputSchema> {
53
- return new DecoratedContractProcedure({
54
- ...this.zz$cp,
55
- ...opts,
56
- method: opts.method,
57
- path: opts.path,
58
- })
59
- }
60
-
61
- prefix(
62
- prefix: HTTPPath,
63
- ): DecoratedContractProcedure<TInputSchema, TOutputSchema> {
64
- if (!this.zz$cp.path)
65
- return this
66
-
67
- return new DecoratedContractProcedure({
68
- ...this.zz$cp,
69
- path: `${prefix}${this.zz$cp.path}`,
70
- })
71
- }
72
-
73
- addTags(
74
- ...tags: string[]
75
- ): DecoratedContractProcedure<TInputSchema, TOutputSchema> {
76
- if (!tags.length)
77
- return this
78
-
79
- return new DecoratedContractProcedure({
80
- ...this.zz$cp,
81
- tags: [...(this.zz$cp.tags ?? []), ...tags],
82
- })
83
- }
84
-
85
- input<USchema extends Schema>(
86
- schema: USchema,
87
- example?: SchemaInput<USchema>,
88
- ): DecoratedContractProcedure<USchema, TOutputSchema> {
89
- return new DecoratedContractProcedure({
90
- ...this.zz$cp,
91
- InputSchema: schema,
92
- inputExample: example,
93
- })
94
- }
95
-
96
- output<USchema extends Schema>(
97
- schema: USchema,
98
- example?: SchemaOutput<USchema>,
99
- ): DecoratedContractProcedure<TInputSchema, USchema> {
100
- return new DecoratedContractProcedure({
101
- ...this.zz$cp,
102
- OutputSchema: schema,
103
- outputExample: example,
104
- })
105
- }
106
- }
107
-
108
- export type WELL_DEFINED_CONTRACT_PROCEDURE = ContractProcedure<Schema, Schema>
109
-
110
- export function isContractProcedure(
111
- item: unknown,
112
- ): item is WELL_DEFINED_CONTRACT_PROCEDURE {
113
- if (item instanceof ContractProcedure)
114
- return true
115
-
116
- return (
117
- (typeof item === 'object' || typeof item === 'function')
118
- && item !== null
119
- && 'zz$cp' in item
120
- && typeof item.zz$cp === 'object'
121
- && item.zz$cp !== null
122
- && 'InputSchema' in item.zz$cp
123
- && 'OutputSchema' in item.zz$cp
124
- )
125
- }
@@ -1,70 +0,0 @@
1
- import { z } from 'zod'
2
- import { ContractProcedure, DecoratedContractProcedure, oc } from '.'
3
- import { ContractRouterBuilder } from './router-builder'
4
-
5
- it('prefix method', () => {
6
- expect(oc.prefix('/1').prefix('/2').zz$crb.prefix).toEqual('/1/2')
7
- })
8
-
9
- it('tags method', () => {
10
- expect(oc.tags('1').tags('2').zz$crb.tags).toEqual(['1', '2'])
11
- })
12
-
13
- it('define a router', () => {
14
- const ping = oc.route({ method: 'GET', path: '/ping' })
15
- const pong = oc.input(z.object({ id: z.string() }))
16
-
17
- const router = oc.router({
18
- ping,
19
- pong,
20
-
21
- internal: oc
22
- .prefix('/internal')
23
- .tags('internal')
24
- .router({
25
- ping,
26
- pong,
27
-
28
- nested: {
29
- ping,
30
- },
31
- }),
32
- })
33
-
34
- expect(router.ping.zz$cp.path).toEqual('/ping')
35
- expect(router.pong.zz$cp.path).toEqual(undefined)
36
-
37
- expect(router.internal.ping.zz$cp.path).toEqual('/internal/ping')
38
- expect(router.internal.pong.zz$cp.path).toEqual(undefined)
39
- expect(router.internal.nested.ping.zz$cp.path).toEqual('/internal/ping')
40
-
41
- expect(router.internal.ping.zz$cp.tags).toEqual(['internal'])
42
- expect(router.internal.pong.zz$cp.tags).toEqual(['internal'])
43
- expect(router.internal.nested.ping.zz$cp.tags).toEqual(['internal'])
44
- })
45
-
46
- it('router: decorate items', () => {
47
- const builder = new ContractRouterBuilder({})
48
-
49
- const ping = new ContractProcedure({
50
- InputSchema: undefined,
51
- OutputSchema: undefined,
52
- })
53
-
54
- const decorated = new DecoratedContractProcedure({
55
- InputSchema: undefined,
56
- OutputSchema: undefined,
57
- method: 'GET',
58
- path: '/ping',
59
- })
60
-
61
- const router = builder.router({ ping, nested: { ping } })
62
-
63
- expectTypeOf(router).toEqualTypeOf<{
64
- ping: typeof decorated
65
- nested: { ping: typeof decorated }
66
- }>()
67
-
68
- expect(router.ping).instanceOf(DecoratedContractProcedure)
69
- expect(router.nested.ping).instanceOf(DecoratedContractProcedure)
70
- })
@@ -1,46 +0,0 @@
1
- import type { ContractRouter, HandledContractRouter } from './router'
2
- import type { HTTPPath } from './types'
3
- import { DecoratedContractProcedure, isContractProcedure } from './procedure'
4
-
5
- export class ContractRouterBuilder {
6
- constructor(public zz$crb: { prefix?: HTTPPath, tags?: string[] }) {}
7
-
8
- prefix(prefix: HTTPPath): ContractRouterBuilder {
9
- return new ContractRouterBuilder({
10
- ...this.zz$crb,
11
- prefix: `${this.zz$crb.prefix ?? ''}${prefix}`,
12
- })
13
- }
14
-
15
- tags(...tags: string[]): ContractRouterBuilder {
16
- if (!tags.length)
17
- return this
18
-
19
- return new ContractRouterBuilder({
20
- ...this.zz$crb,
21
- tags: [...(this.zz$crb.tags ?? []), ...tags],
22
- })
23
- }
24
-
25
- router<T extends ContractRouter>(router: T): HandledContractRouter<T> {
26
- const handled: ContractRouter = {}
27
-
28
- for (const key in router) {
29
- const item = router[key]
30
- if (isContractProcedure(item)) {
31
- const decorated = DecoratedContractProcedure.decorate(item).addTags(
32
- ...(this.zz$crb.tags ?? []),
33
- )
34
-
35
- handled[key] = this.zz$crb.prefix
36
- ? decorated.prefix(this.zz$crb.prefix)
37
- : decorated
38
- }
39
- else {
40
- handled[key] = this.router(item as ContractRouter)
41
- }
42
- }
43
-
44
- return handled as HandledContractRouter<T>
45
- }
46
- }
@@ -1,63 +0,0 @@
1
- import type { InferContractRouterInputs, InferContractRouterOutputs } from '.'
2
- import { z } from 'zod'
3
- import { oc } from '.'
4
-
5
- const router = {
6
- ping: oc.route({
7
- method: 'GET',
8
- path: '/ping',
9
- })
10
- .input(z.object({
11
- ping: z.string().transform(() => 1),
12
- }))
13
- .output(z.object({
14
- pong: z.string().transform(() => 1),
15
- })),
16
- user: {
17
- find: oc.route({
18
- method: 'GET',
19
- path: '/users/{id}',
20
- })
21
- .input(z.object({
22
- find: z.number().transform(() => '1'),
23
- }))
24
- .output(z.object({
25
- user: z.object({
26
- id: z.number().transform(() => '1'),
27
- }),
28
- }))
29
- ,
30
- },
31
- }
32
-
33
- it('InferContractRouterInputs', () => {
34
- type Inputs = InferContractRouterInputs<typeof router>
35
-
36
- expectTypeOf<Inputs>().toEqualTypeOf<{
37
- ping: {
38
- ping: string
39
- }
40
- user: {
41
- find: {
42
- find: number
43
- }
44
- }
45
- }>()
46
- })
47
-
48
- it('InferContractRouterOutputs', () => {
49
- type Outputs = InferContractRouterOutputs<typeof router>
50
-
51
- expectTypeOf<Outputs>().toEqualTypeOf<{
52
- ping: {
53
- pong: number
54
- }
55
- user: {
56
- find: {
57
- user: {
58
- id: string
59
- }
60
- }
61
- }
62
- }>()
63
- })
@@ -1,24 +0,0 @@
1
- import { eachContractRouterLeaf, oc } from '.'
2
-
3
- it('each router leaf', () => {
4
- const router = {
5
- ping: oc.route({
6
- method: 'GET',
7
- path: '/ping',
8
- }),
9
- user: {
10
- find: oc.route({
11
- method: 'GET',
12
- path: '/users/{id}',
13
- }),
14
- },
15
- }
16
-
17
- const calls: string[] = []
18
-
19
- eachContractRouterLeaf(router, (procedure, path) => {
20
- calls.push(path.join('.'))
21
- })
22
-
23
- expect(calls).toEqual(['ping', 'user.find'])
24
- })