Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions packages/contract/src/builder-variants.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { baseErrorMap, BaseMeta, inputSchema, outputSchema } from '../tests
import type { ContractBuilder } from './builder'
import type { ContractProcedureBuilder, ContractProcedureBuilderWithInput, ContractProcedureBuilderWithInputOutput, ContractProcedureBuilderWithOutput, ContractRouterBuilder } from './builder-variants'
import type { MergedErrorMap } from './error'
import type { MergedMeta } from './meta'
import type { ContractProcedure } from './procedure'
import type { EnhancedContractRouter } from './router-utils'
import type { Schema } from './schema'
Expand Down Expand Up @@ -40,6 +41,7 @@ describe('ContractProcedureBuilder', () => {
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
MergedMeta<BaseMeta, { readonly log: true }>,
BaseMeta
>
>()
Expand Down Expand Up @@ -121,6 +123,7 @@ describe('ContractProcedureBuilderWithInput', () => {
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
MergedMeta<BaseMeta, { readonly log: true }>,
BaseMeta
>
>()
Expand Down Expand Up @@ -188,6 +191,7 @@ describe('ContractProcedureBuilderWithOutput', () => {
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
MergedMeta<BaseMeta, { readonly log: true }>,
BaseMeta
>
>()
Expand Down Expand Up @@ -255,6 +259,7 @@ it('ContractProcedureBuilderWithInputOutput', () => {
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
MergedMeta<BaseMeta, { readonly log: true }>,
BaseMeta
>
>()
Expand Down
54 changes: 29 additions & 25 deletions packages/contract/src/builder-variants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { HTTPPath } from '@orpc/client'
import type { ErrorMap, MergedErrorMap } from './error'
import type { Meta } from './meta'
import type { MergedMeta, Meta } from './meta'
import type { ContractProcedure } from './procedure'
import type { Route } from './route'
import type { ContractRouter } from './router'
Expand All @@ -12,6 +12,7 @@ export interface ContractProcedureBuilder<
TOutputSchema extends AnySchema,
TErrorMap extends ErrorMap,
TMeta extends Meta,
TMetaDef extends Meta = TMeta,
> extends ContractProcedure<TInputSchema, TOutputSchema, TErrorMap, TMeta> {
/**
* Adds type-safe custom errors to the contract.
Expand All @@ -21,17 +22,17 @@ export interface ContractProcedureBuilder<
*/
errors<U extends ErrorMap>(
errors: U,
): ContractProcedureBuilder<TInputSchema, TOutputSchema, MergedErrorMap<TErrorMap, U>, TMeta>
): ContractProcedureBuilder<TInputSchema, TOutputSchema, MergedErrorMap<TErrorMap, U>, TMeta, TMetaDef>

/**
* Sets or updates the metadata for the contract.
* The provided metadata is spared-merged with any existing metadata in the contract.
*
* @see {@link https://orpc.dev/docs/metadata Metadata Docs}
*/
meta(
meta: TMeta,
): ContractProcedureBuilder<TInputSchema, TOutputSchema, TErrorMap, TMeta>
meta<const U extends Partial<TMetaDef>>(
meta: U,
): ContractProcedureBuilder<TInputSchema, TOutputSchema, TErrorMap, MergedMeta<TMeta, U>, TMetaDef>

/**
* Sets or updates the route definition for the contract.
Expand All @@ -43,7 +44,7 @@ export interface ContractProcedureBuilder<
*/
route(
route: Route,
): ContractProcedureBuilder<TInputSchema, TOutputSchema, TErrorMap, TMeta>
): ContractProcedureBuilder<TInputSchema, TOutputSchema, TErrorMap, TMeta, TMetaDef>

/**
* Defines the input validation schema for the contract.
Expand All @@ -52,7 +53,7 @@ export interface ContractProcedureBuilder<
*/
input<U extends AnySchema>(
schema: U,
): ContractProcedureBuilderWithInput<U, TOutputSchema, TErrorMap, TMeta>
): ContractProcedureBuilderWithInput<U, TOutputSchema, TErrorMap, TMeta, TMetaDef>

/**
* Defines the output validation schema for the contract.
Expand All @@ -61,14 +62,15 @@ export interface ContractProcedureBuilder<
*/
output<U extends AnySchema>(
schema: U,
): ContractProcedureBuilderWithOutput<TInputSchema, U, TErrorMap, TMeta>
): ContractProcedureBuilderWithOutput<TInputSchema, U, TErrorMap, TMeta, TMetaDef>
}

export interface ContractProcedureBuilderWithInput<
TInputSchema extends AnySchema,
TOutputSchema extends AnySchema,
TErrorMap extends ErrorMap,
TMeta extends Meta,
TMetaDef extends Meta = TMeta,
>extends ContractProcedure<TInputSchema, TOutputSchema, TErrorMap, TMeta> {
/**
* Adds type-safe custom errors to the contract.
Expand All @@ -78,17 +80,17 @@ export interface ContractProcedureBuilderWithInput<
*/
errors<U extends ErrorMap>(
errors: U,
): ContractProcedureBuilderWithInput<TInputSchema, TOutputSchema, MergedErrorMap<TErrorMap, U>, TMeta>
): ContractProcedureBuilderWithInput<TInputSchema, TOutputSchema, MergedErrorMap<TErrorMap, U>, TMeta, TMetaDef>

/**
* Sets or updates the metadata for the contract.
* The provided metadata is spared-merged with any existing metadata in the contract.
*
* @see {@link https://orpc.dev/docs/metadata Metadata Docs}
*/
meta(
meta: TMeta,
): ContractProcedureBuilderWithInput<TInputSchema, TOutputSchema, TErrorMap, TMeta>
meta<const U extends Partial<TMetaDef>>(
meta: U,
): ContractProcedureBuilderWithInput<TInputSchema, TOutputSchema, TErrorMap, MergedMeta<TMeta, U>, TMetaDef>

/**
* Sets or updates the route definition for the contract.
Expand All @@ -100,7 +102,7 @@ export interface ContractProcedureBuilderWithInput<
*/
route(
route: Route,
): ContractProcedureBuilderWithInput<TInputSchema, TOutputSchema, TErrorMap, TMeta>
): ContractProcedureBuilderWithInput<TInputSchema, TOutputSchema, TErrorMap, TMeta, TMetaDef>

/**
* Defines the output validation schema for the contract.
Expand All @@ -109,14 +111,15 @@ export interface ContractProcedureBuilderWithInput<
*/
output<U extends AnySchema>(
schema: U,
): ContractProcedureBuilderWithInputOutput<TInputSchema, U, TErrorMap, TMeta>
): ContractProcedureBuilderWithInputOutput<TInputSchema, U, TErrorMap, TMeta, TMetaDef>
}

export interface ContractProcedureBuilderWithOutput<
TInputSchema extends AnySchema,
TOutputSchema extends AnySchema,
TErrorMap extends ErrorMap,
TMeta extends Meta,
TMetaDef extends Meta = TMeta,
> extends ContractProcedure<TInputSchema, TOutputSchema, TErrorMap, TMeta> {
/**
* Adds type-safe custom errors to the contract.
Expand All @@ -126,17 +129,17 @@ export interface ContractProcedureBuilderWithOutput<
*/
errors<U extends ErrorMap>(
errors: U,
): ContractProcedureBuilderWithOutput<TInputSchema, TOutputSchema, MergedErrorMap<TErrorMap, U>, TMeta>
): ContractProcedureBuilderWithOutput<TInputSchema, TOutputSchema, MergedErrorMap<TErrorMap, U>, TMeta, TMetaDef>

/**
* Sets or updates the metadata for the contract.
* The provided metadata is spared-merged with any existing metadata in the contract.
*
* @see {@link https://orpc.dev/docs/metadata Metadata Docs}
*/
meta(
meta: TMeta,
): ContractProcedureBuilderWithOutput<TInputSchema, TOutputSchema, TErrorMap, TMeta>
meta<const U extends Partial<TMetaDef>>(
meta: U,
): ContractProcedureBuilderWithOutput<TInputSchema, TOutputSchema, TErrorMap, MergedMeta<TMeta, U>, TMetaDef>

/**
* Sets or updates the route definition for the contract.
Expand All @@ -148,7 +151,7 @@ export interface ContractProcedureBuilderWithOutput<
*/
route(
route: Route,
): ContractProcedureBuilderWithOutput<TInputSchema, TOutputSchema, TErrorMap, TMeta>
): ContractProcedureBuilderWithOutput<TInputSchema, TOutputSchema, TErrorMap, TMeta, TMetaDef>

/**
* Defines the input validation schema for the contract.
Expand All @@ -157,14 +160,15 @@ export interface ContractProcedureBuilderWithOutput<
*/
input<U extends AnySchema>(
schema: U,
): ContractProcedureBuilderWithInputOutput<U, TOutputSchema, TErrorMap, TMeta>
): ContractProcedureBuilderWithInputOutput<U, TOutputSchema, TErrorMap, TMeta, TMetaDef>
}

export interface ContractProcedureBuilderWithInputOutput<
TInputSchema extends AnySchema,
TOutputSchema extends AnySchema,
TErrorMap extends ErrorMap,
TMeta extends Meta,
TMetaDef extends Meta = TMeta,
> extends ContractProcedure<TInputSchema, TOutputSchema, TErrorMap, TMeta> {
/**
* Adds type-safe custom errors to the contract.
Expand All @@ -174,17 +178,17 @@ export interface ContractProcedureBuilderWithInputOutput<
*/
errors<U extends ErrorMap>(
errors: U,
): ContractProcedureBuilderWithInputOutput<TInputSchema, TOutputSchema, MergedErrorMap<TErrorMap, U>, TMeta>
): ContractProcedureBuilderWithInputOutput<TInputSchema, TOutputSchema, MergedErrorMap<TErrorMap, U>, TMeta, TMetaDef>

/**
* Sets or updates the metadata for the contract.
* The provided metadata is spared-merged with any existing metadata in the contract.
*
* @see {@link https://orpc.dev/docs/metadata Metadata Docs}
*/
meta(
meta: TMeta,
): ContractProcedureBuilderWithInputOutput<TInputSchema, TOutputSchema, TErrorMap, TMeta>
meta<const U extends Partial<TMetaDef>>(
meta: U,
): ContractProcedureBuilderWithInputOutput<TInputSchema, TOutputSchema, TErrorMap, MergedMeta<TMeta, U>, TMetaDef>

/**
* Sets or updates the route definition for the contract.
Expand All @@ -196,7 +200,7 @@ export interface ContractProcedureBuilderWithInputOutput<
*/
route(
route: Route,
): ContractProcedureBuilderWithInputOutput<TInputSchema, TOutputSchema, TErrorMap, TMeta>
): ContractProcedureBuilderWithInputOutput<TInputSchema, TOutputSchema, TErrorMap, TMeta, TMetaDef>
}

export interface ContractRouterBuilder<
Expand Down
2 changes: 2 additions & 0 deletions packages/contract/src/builder.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { baseErrorMap, BaseMeta, inputSchema, outputSchema } from '../tests
import type { ContractBuilder } from './builder'
import type { ContractProcedureBuilder, ContractProcedureBuilderWithInput, ContractProcedureBuilderWithOutput, ContractRouterBuilder } from './builder-variants'
import type { MergedErrorMap } from './error'
import type { MergedMeta } from './meta'
import type { ContractProcedure } from './procedure'
import type { EnhancedContractRouter } from './router-utils'
import type { Schema } from './schema'
Expand Down Expand Up @@ -70,6 +71,7 @@ describe('ContractBuilder', () => {
typeof inputSchema,
typeof outputSchema,
typeof baseErrorMap,
MergedMeta<BaseMeta, { readonly log: true }>,
BaseMeta
>
>()
Expand Down
27 changes: 14 additions & 13 deletions packages/contract/src/builder.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { HTTPPath } from '@orpc/client'
import type { ContractProcedureBuilder, ContractProcedureBuilderWithInput, ContractProcedureBuilderWithOutput, ContractRouterBuilder } from './builder-variants'
import type { ErrorMap, MergedErrorMap } from './error'
import type { Meta } from './meta'
import type { MergedMeta, Meta } from './meta'
import type { ContractProcedureDef } from './procedure'
import type { Route } from './route'
import type { ContractRouter } from './router'
Expand All @@ -26,6 +26,7 @@ export class ContractBuilder<
TOutputSchema extends AnySchema,
TErrorMap extends ErrorMap,
TMeta extends Meta,
TMetaDef extends Meta = TMeta,
> extends ContractProcedure<TInputSchema, TOutputSchema, TErrorMap, TMeta> {
/**
* This property holds the defined options for the contract.
Expand All @@ -46,7 +47,7 @@ export class ContractBuilder<
*/
$meta<U extends Meta>(
initialMeta: U,
): ContractBuilder<TInputSchema, TOutputSchema, TErrorMap, U & Record<never, never>> {
): ContractBuilder<TInputSchema, TOutputSchema, TErrorMap, U & Record<never, never>, U> {
/**
* We need `& Record<never, never>` to deal with `has no properties in common with type` error
*/
Expand All @@ -66,7 +67,7 @@ export class ContractBuilder<
*/
$route(
initialRoute: Route,
): ContractBuilder<TInputSchema, TOutputSchema, TErrorMap, TMeta> {
): ContractBuilder<TInputSchema, TOutputSchema, TErrorMap, TMeta, TMetaDef> {
Comment thread
elv1n marked this conversation as resolved.
return new ContractBuilder({
...this['~orpc'],
route: initialRoute,
Expand All @@ -80,7 +81,7 @@ export class ContractBuilder<
*/
$input<U extends AnySchema>(
initialInputSchema?: U,
): ContractBuilder<U, TOutputSchema, TErrorMap, TMeta> {
): ContractBuilder<U, TOutputSchema, TErrorMap, TMeta, TMetaDef> {
Comment thread
elv1n marked this conversation as resolved.
return new ContractBuilder({
...this['~orpc'],
inputSchema: initialInputSchema,
Expand All @@ -95,7 +96,7 @@ export class ContractBuilder<
*/
errors<U extends ErrorMap>(
errors: U,
): ContractBuilder<TInputSchema, TOutputSchema, MergedErrorMap<TErrorMap, U>, TMeta> {
): ContractBuilder<TInputSchema, TOutputSchema, MergedErrorMap<TErrorMap, U>, TMeta, TMetaDef> {
Comment thread
elv1n marked this conversation as resolved.
return new ContractBuilder({
...this['~orpc'],
errorMap: mergeErrorMap(this['~orpc'].errorMap, errors),
Expand All @@ -108,9 +109,9 @@ export class ContractBuilder<
*
* @see {@link https://orpc.dev/docs/metadata Metadata Docs}
*/
meta(
meta: TMeta,
): ContractProcedureBuilder<TInputSchema, TOutputSchema, TErrorMap, TMeta> {
meta<const U extends Partial<TMetaDef>>(
meta: U,
): ContractProcedureBuilder<TInputSchema, TOutputSchema, TErrorMap, MergedMeta<TMeta, U>, TMetaDef> {
Comment thread
elv1n marked this conversation as resolved.
return new ContractBuilder({
...this['~orpc'],
meta: mergeMeta(this['~orpc'].meta, meta),
Expand All @@ -127,7 +128,7 @@ export class ContractBuilder<
*/
route(
route: Route,
): ContractProcedureBuilder<TInputSchema, TOutputSchema, TErrorMap, TMeta> {
): ContractProcedureBuilder<TInputSchema, TOutputSchema, TErrorMap, TMeta, TMetaDef> {
return new ContractBuilder({
...this['~orpc'],
route: mergeRoute(this['~orpc'].route, route),
Expand All @@ -141,8 +142,8 @@ export class ContractBuilder<
*/
input<U extends AnySchema>(
schema: U,
): ContractProcedureBuilderWithInput<U, TOutputSchema, TErrorMap, TMeta> {
return new ContractBuilder({
): ContractProcedureBuilderWithInput<U, TOutputSchema, TErrorMap, TMeta, TMetaDef> {
return new ContractBuilder<U, TOutputSchema, TErrorMap, TMeta, TMetaDef>({
...this['~orpc'],
inputSchema: schema,
})
Expand All @@ -155,8 +156,8 @@ export class ContractBuilder<
*/
output<U extends AnySchema>(
schema: U,
): ContractProcedureBuilderWithOutput<TInputSchema, U, TErrorMap, TMeta> {
return new ContractBuilder({
): ContractProcedureBuilderWithOutput<TInputSchema, U, TErrorMap, TMeta, TMetaDef> {
return new ContractBuilder<TInputSchema, U, TErrorMap, TMeta, TMetaDef>({
...this['~orpc'],
outputSchema: schema,
})
Expand Down
8 changes: 7 additions & 1 deletion packages/contract/src/meta.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
export type Meta = Record<string, any>

export function mergeMeta<T extends Meta>(meta1: T, meta2: T): T {
/**
* Merges two meta types with override semantics matching runtime spread:
* keys in `U` replace keys in `T`.
*/
export type MergedMeta<T extends Meta, U extends Meta> = Omit<T, keyof U> & U

export function mergeMeta<T extends Meta, U extends Meta>(meta1: T, meta2: U): MergedMeta<T, U> {
return { ...meta1, ...meta2 }
}
Loading