Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(server)!: rewrite implementer #108

Closed
wants to merge 48 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
38b6f9c
wip
unnoq Jan 21, 2025
7466fc9
types tests
unnoq Jan 21, 2025
94f3807
wip
unnoq Jan 21, 2025
4334ae7
100% test coverage
unnoq Jan 21, 2025
626e20c
fix types
unnoq Jan 21, 2025
4602ac1
fix types
unnoq Jan 21, 2025
c8f0385
remove ~type and decorated method
unnoq Jan 22, 2025
0ed75dd
procedure builders
unnoq Jan 22, 2025
663d709
rename
unnoq Jan 22, 2025
393db2e
router builders
unnoq Jan 22, 2025
eb11c01
builder
unnoq Jan 22, 2025
9824dc7
remove redundant method
unnoq Jan 23, 2025
29fd6c3
Merge branch 'feat/contract-server/rewrite-builders' into feat/server…
unnoq Jan 23, 2025
b03e277
wip
unnoq Jan 23, 2025
2012c4d
router
unnoq Jan 23, 2025
f4a4ad7
wip
unnoq Jan 23, 2025
a35df81
fix isLazy
unnoq Jan 23, 2025
6b5be80
procedure tests
unnoq Jan 23, 2025
5b4687c
router tests
unnoq Jan 23, 2025
8bc8a81
builder tests
unnoq Jan 23, 2025
8244588
100% test coverage
unnoq Jan 23, 2025
7af70f6
wip
unnoq Jan 24, 2025
060d0d1
fixed
unnoq Jan 24, 2025
b61377d
fix types tests
unnoq Jan 24, 2025
0eb2fd6
Merge branch 'feat/contract-server/rewrite-builders' into feat/server…
unnoq Jan 24, 2025
eda140a
wip
unnoq Jan 24, 2025
8d0889d
fix types
unnoq Jan 24, 2025
2dc8f9c
ORPCErrorConstructorMap
unnoq Jan 24, 2025
89e4620
improve
unnoq Jan 26, 2025
6bf49a5
Merge branch 'feat/contract-server/rewrite-builders' into feat/server…
unnoq Jan 26, 2025
d3800e3
wip
unnoq Jan 27, 2025
166292f
improve
unnoq Jan 27, 2025
65b2694
Merge branch 'feat/contract-server/rewrite-builders' into feat/server…
unnoq Jan 27, 2025
f134317
improve
unnoq Jan 27, 2025
d499baf
Merge branch 'feat/contract-server/rewrite-builders' into feat/server…
unnoq Jan 27, 2025
5151a1a
wip
unnoq Jan 28, 2025
e25dff7
improve
unnoq Jan 28, 2025
81d7046
Merge branch 'feat/contract-server/rewrite-builders' into feat/server…
unnoq Jan 28, 2025
9ff7001
improve
unnoq Jan 30, 2025
2b953c8
fix
unnoq Jan 30, 2025
76fc5ca
prefix lazy
unnoq Jan 30, 2025
1a69163
fix
unnoq Jan 30, 2025
4e20085
procedure implementer
unnoq Jan 30, 2025
9f99892
type tests
unnoq Jan 30, 2025
0357bcb
tests
unnoq Jan 30, 2025
6ba9b11
index
unnoq Jan 30, 2025
8340e13
variants tests
unnoq Jan 30, 2025
03b08b4
setRouterContract
unnoq Jan 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default antfu({
'react-refresh/only-export-components': 'off',
'react/prefer-destructuring-assignment': 'off',
'react/no-context-provider': 'off',
'ts/method-signature-style': ['error', 'method'],
},
}, {
files: ['**/*.test.ts', '**/*.test.tsx', '**/*.test-d.ts', '**/*.test-d.tsx', 'apps/content/examples/**', 'playgrounds/**'],
Expand Down
2 changes: 1 addition & 1 deletion packages/contract/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
},
"dependencies": {
"@orpc/shared": "workspace:*",
"@standard-schema/spec": "1.0.0-beta.4"
"@standard-schema/spec": "1.0.0-rc.0"
},
"devDependencies": {
"arktype": "2.0.0-rc.26",
Expand Down
330 changes: 330 additions & 0 deletions packages/contract/src/builder-variants.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,330 @@
import type { OmitChainMethodDeep } from '@orpc/shared'
import type { ContractBuilder } from './builder'
import type { ContractProcedureBuilder, ContractProcedureBuilderWithInput, ContractProcedureBuilderWithInputOutput, ContractProcedureBuilderWithOutput, ContractRouterBuilder } from './builder-variants'
import type { MergedErrorMap } from './error-map'
import type { ContractProcedure } from './procedure'
import type { AdaptedContractRouter } from './router'
import { type baseErrorMap, type BaseMeta, generalSchema, type inputSchema, type outputSchema, ping, pong } from '../tests/shared'

const generalBuilder = {} as ContractBuilder<typeof inputSchema, typeof outputSchema, typeof baseErrorMap, BaseMeta>

describe('ContractProcedureBuilder', () => {
const builder = {} as ContractProcedureBuilder<typeof inputSchema, typeof outputSchema, typeof baseErrorMap, BaseMeta>

it('backward compatibility', () => {
const expected = {} as OmitChainMethodDeep<typeof generalBuilder, '$meta' | '$route' | 'prefix' | 'tag' | 'router'>

expectTypeOf(builder).toMatchTypeOf(expected)
expectTypeOf<keyof typeof builder>().toEqualTypeOf<keyof typeof expected>()
})

it('.errors', () => {
expectTypeOf(builder.errors({ INVALID: { message: 'invalid' }, OVERRIDE: { message: 'override' } })).toEqualTypeOf<
ContractProcedureBuilder<
typeof inputSchema,
typeof outputSchema,
MergedErrorMap<typeof baseErrorMap, { INVALID: { message: string }, OVERRIDE: { message: string } }>,
BaseMeta
>
>()

// @ts-expect-error - schema is invalid
builder.errors({ TOO_MANY_REQUESTS: { data: {} } })
})

it('.meta', () => {
expectTypeOf(builder.meta({ log: true })).toEqualTypeOf<
ContractProcedureBuilder<
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
BaseMeta
>
>()

// @ts-expect-error - invalid meta
builder.meta({ meta: 'INVALID' })
})

it('.route', () => {
expectTypeOf(builder.route({ method: 'GET' })).toEqualTypeOf<
ContractProcedureBuilder<
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
BaseMeta
>
>()

// @ts-expect-error - invalid method
builder.route({ method: 'INVALID' })
})

it('.input', () => {
expectTypeOf(builder.input(generalSchema)).toEqualTypeOf<
ContractProcedureBuilderWithInput<
typeof generalSchema,
typeof outputSchema,
typeof baseErrorMap,
BaseMeta
>
>()

// @ts-expect-error - schema is invalid
builder.input({})
})

it('.output', () => {
expectTypeOf(builder.output(generalSchema)).toEqualTypeOf<
ContractProcedureBuilderWithOutput<
typeof inputSchema,
typeof generalSchema,
typeof baseErrorMap,
BaseMeta
>
>()

// @ts-expect-error - schema is invalid
builder.output({})
})
})

describe('ContractProcedureBuilderWithInput', () => {
const builder = {} as ContractProcedureBuilderWithInput<typeof inputSchema, typeof outputSchema, typeof baseErrorMap, BaseMeta>

it('backward compatibility', () => {
const expected = {} as OmitChainMethodDeep<typeof generalBuilder, '$meta' | '$route' | 'prefix' | 'tag' | 'router' | 'input'>

expectTypeOf(builder).toMatchTypeOf(expected)
expectTypeOf<keyof typeof builder>().toEqualTypeOf<keyof typeof expected>()
})

it('.errors', () => {
expectTypeOf(builder.errors({ INVALID: { message: 'invalid' }, OVERRIDE: { message: 'override' } })).toEqualTypeOf<
ContractProcedureBuilderWithInput<
typeof inputSchema,
typeof outputSchema,
MergedErrorMap<typeof baseErrorMap, { INVALID: { message: string }, OVERRIDE: { message: string } }>,
BaseMeta
>
>()

// @ts-expect-error - schema is invalid
builder.errors({ TOO_MANY_REQUESTS: { data: {} } })
})

it('.meta', () => {
expectTypeOf(builder.meta({ log: true })).toEqualTypeOf<
ContractProcedureBuilderWithInput<
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
BaseMeta
>
>()

// @ts-expect-error - invalid meta
builder.meta({ meta: 'INVALID' })
})

it('.route', () => {
expectTypeOf(builder.route({ method: 'GET' })).toEqualTypeOf<
ContractProcedureBuilderWithInput<
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
BaseMeta
>
>()

// @ts-expect-error - invalid method
builder.route({ method: 'INVALID' })
})

it('.output', () => {
expectTypeOf(builder.output(generalSchema)).toEqualTypeOf<
ContractProcedureBuilderWithInputOutput<
typeof inputSchema,
typeof generalSchema,
typeof baseErrorMap,
BaseMeta
>
>()

// @ts-expect-error - schema is invalid
builder.output({})
})
})

describe('ContractProcedureBuilderWithOutput', () => {
const builder = {} as ContractProcedureBuilderWithOutput<typeof inputSchema, typeof outputSchema, typeof baseErrorMap, BaseMeta>

it('backward compatibility', () => {
const expected = {} as OmitChainMethodDeep<typeof generalBuilder, '$meta' | '$route' | 'prefix' | 'tag' | 'router' | 'output'>

expectTypeOf(builder).toMatchTypeOf(expected)
expectTypeOf<keyof typeof builder>().toEqualTypeOf<keyof typeof expected>()
})

it('.errors', () => {
expectTypeOf(builder.errors({ INVALID: { message: 'invalid' }, OVERRIDE: { message: 'override' } })).toEqualTypeOf<
ContractProcedureBuilderWithOutput<
typeof inputSchema,
typeof outputSchema,
MergedErrorMap<typeof baseErrorMap, { INVALID: { message: string }, OVERRIDE: { message: string } }>,
BaseMeta
>
>()

// @ts-expect-error - schema is invalid
builder.errors({ TOO_MANY_REQUESTS: { data: {} } })
})

it('.meta', () => {
expectTypeOf(builder.meta({ log: true })).toEqualTypeOf<
ContractProcedureBuilderWithOutput<
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
BaseMeta
>
>()

// @ts-expect-error - invalid meta
builder.meta({ meta: 'INVALID' })
})

it('.route', () => {
expectTypeOf(builder.route({ method: 'GET' })).toEqualTypeOf<
ContractProcedureBuilderWithOutput<
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
BaseMeta
>
>()

// @ts-expect-error - invalid method
builder.route({ method: 'INVALID' })
})

it('.input', () => {
expectTypeOf(builder.input(generalSchema)).toEqualTypeOf<
ContractProcedureBuilderWithInputOutput<
typeof generalSchema,
typeof outputSchema,
typeof baseErrorMap,
BaseMeta
>
>()

// @ts-expect-error - schema is invalid
builder.input({})
})
})

it('ContractProcedureBuilderWithInputOutput', () => {
const builder = {} as ContractProcedureBuilderWithInputOutput<typeof inputSchema, typeof outputSchema, typeof baseErrorMap, BaseMeta>

it('backward compatibility', () => {
const expected = {} as OmitChainMethodDeep<typeof generalBuilder, '$meta' | '$route' | 'prefix' | 'tag' | 'router' | 'input' | 'output'>

expectTypeOf(builder).toMatchTypeOf(expected)
expectTypeOf<keyof typeof builder>().toEqualTypeOf<keyof typeof expected>()
})

it('.errors', () => {
expectTypeOf(builder.errors({ INVALID: { message: 'invalid' }, OVERRIDE: { message: 'override' } })).toEqualTypeOf<
ContractProcedureBuilderWithInputOutput<
typeof inputSchema,
typeof outputSchema,
MergedErrorMap<typeof baseErrorMap, { INVALID: { message: string }, OVERRIDE: { message: string } }>,
BaseMeta
>
>()

// @ts-expect-error - schema is invalid
builder.errors({ TOO_MANY_REQUESTS: { data: {} } })
})

it('.meta', () => {
expectTypeOf(builder.meta({ log: true })).toEqualTypeOf<
ContractProcedureBuilderWithInputOutput<
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
BaseMeta
>
>()

// @ts-expect-error - invalid meta
builder.meta({ meta: 'INVALID' })
})

it('.route', () => {
expectTypeOf(builder.route({ method: 'GET' })).toEqualTypeOf<
ContractProcedureBuilderWithInputOutput<
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
BaseMeta
>
>()

// @ts-expect-error - invalid method
builder.route({ method: 'INVALID' })
})
})

describe('ContractRouterBuilder', () => {
const builder = {} as ContractRouterBuilder<typeof baseErrorMap, BaseMeta>

it('backward compatibility', () => {
const expected = {} as OmitChainMethodDeep<typeof generalBuilder, '$meta' | '$route' | 'route' | 'meta' | 'input' | 'output'>

// expectTypeOf(builder).toMatchTypeOf(expected)
expectTypeOf<keyof typeof builder>().toEqualTypeOf<keyof typeof expected>()
})

it('.prefix', () => {
expectTypeOf(builder.prefix('/api')).toEqualTypeOf<
ContractRouterBuilder<typeof baseErrorMap, BaseMeta>
>()

// @ts-expect-error - invalid prefix
builder.prefix(1)
})

it('.tag', () => {
expectTypeOf(builder.tag('tag1', 'tag2')).toEqualTypeOf<
ContractRouterBuilder<typeof baseErrorMap, BaseMeta>
>()

// @ts-expect-error - invalid tag
builder.tag(1)
})

it('.router', () => {
const router = {
ping,
pong,
}

expectTypeOf(builder.router(router)).toEqualTypeOf<
AdaptedContractRouter<typeof router, typeof baseErrorMap>
>()

// @ts-expect-error - invalid router
builder.router(123)

builder.router({
// @ts-expect-error - conflict meta def
ping: {} as ContractProcedure<
undefined,
typeof outputSchema,
typeof baseErrorMap,
{ mode?: number }
>,
})
})
})
Loading
Loading