@orpc/contract 0.29.0 → 0.30.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/dist/index.js CHANGED
@@ -73,10 +73,13 @@ var DecoratedContractProcedure = class _DecoratedContractProcedure extends Contr
73
73
  outputExample: example
74
74
  });
75
75
  }
76
- errors(errorMap) {
76
+ errors(errors) {
77
77
  return new _DecoratedContractProcedure({
78
78
  ...this["~orpc"],
79
- errorMap
79
+ errorMap: {
80
+ ...this["~orpc"].errorMap,
81
+ ...errors
82
+ }
80
83
  });
81
84
  }
82
85
  };
@@ -100,6 +103,15 @@ var ContractRouterBuilder = class _ContractRouterBuilder {
100
103
  tags: [...this["~orpc"].tags ?? [], ...tags]
101
104
  });
102
105
  }
106
+ errors(errors) {
107
+ return new _ContractRouterBuilder({
108
+ ...this["~orpc"],
109
+ errorMap: {
110
+ ...this["~orpc"].errorMap,
111
+ ...errors
112
+ }
113
+ });
114
+ }
103
115
  router(router) {
104
116
  if (isContractProcedure(router)) {
105
117
  let decorated = DecoratedContractProcedure.decorate(router);
@@ -109,6 +121,7 @@ var ContractRouterBuilder = class _ContractRouterBuilder {
109
121
  if (this["~orpc"].prefix) {
110
122
  decorated = decorated.prefix(this["~orpc"].prefix);
111
123
  }
124
+ decorated = decorated.errors(this["~orpc"].errorMap);
112
125
  return decorated;
113
126
  }
114
127
  const adapted = {};
@@ -120,15 +133,31 @@ var ContractRouterBuilder = class _ContractRouterBuilder {
120
133
  };
121
134
 
122
135
  // src/builder.ts
123
- var ContractBuilder = class {
136
+ var ContractBuilder = class _ContractBuilder {
137
+ "~type" = "ContractBuilder";
138
+ "~orpc";
139
+ constructor(def) {
140
+ this["~orpc"] = def;
141
+ }
142
+ errors(errors) {
143
+ return new _ContractBuilder({
144
+ ...this["~orpc"],
145
+ errorMap: {
146
+ ...this["~orpc"].errorMap,
147
+ ...errors
148
+ }
149
+ });
150
+ }
124
151
  prefix(prefix) {
125
152
  return new ContractRouterBuilder({
126
- prefix
153
+ prefix,
154
+ errorMap: this["~orpc"].errorMap
127
155
  });
128
156
  }
129
157
  tag(...tags) {
130
158
  return new ContractRouterBuilder({
131
- tags
159
+ tags,
160
+ errorMap: this["~orpc"].errorMap
132
161
  });
133
162
  }
134
163
  route(route) {
@@ -136,7 +165,7 @@ var ContractBuilder = class {
136
165
  route,
137
166
  InputSchema: void 0,
138
167
  OutputSchema: void 0,
139
- errorMap: void 0
168
+ errorMap: this["~orpc"].errorMap
140
169
  });
141
170
  }
142
171
  input(schema, example) {
@@ -144,7 +173,7 @@ var ContractBuilder = class {
144
173
  InputSchema: schema,
145
174
  inputExample: example,
146
175
  OutputSchema: void 0,
147
- errorMap: void 0
176
+ errorMap: this["~orpc"].errorMap
148
177
  });
149
178
  }
150
179
  output(schema, example) {
@@ -152,18 +181,13 @@ var ContractBuilder = class {
152
181
  OutputSchema: schema,
153
182
  outputExample: example,
154
183
  InputSchema: void 0,
155
- errorMap: void 0
156
- });
157
- }
158
- errors(errorMap) {
159
- return new DecoratedContractProcedure({
160
- InputSchema: void 0,
161
- OutputSchema: void 0,
162
- errorMap
184
+ errorMap: this["~orpc"].errorMap
163
185
  });
164
186
  }
165
187
  router(router) {
166
- return router;
188
+ return new ContractRouterBuilder({
189
+ errorMap: this["~orpc"].errorMap
190
+ }).router(router);
167
191
  }
168
192
  };
169
193
 
@@ -358,7 +382,9 @@ var ValidationError = class extends Error {
358
382
  };
359
383
 
360
384
  // src/index.ts
361
- var oc = new ContractBuilder();
385
+ var oc = new ContractBuilder({
386
+ errorMap: {}
387
+ });
362
388
  export {
363
389
  COMMON_ORPC_ERROR_DEFS,
364
390
  ContractBuilder,
@@ -1,16 +1,23 @@
1
- import type { ErrorMap } from './error-map';
1
+ import type { ErrorMap, ErrorMapGuard, ErrorMapSuggestions, StrictErrorMap } from './error-map';
2
2
  import type { RouteOptions } from './procedure';
3
3
  import type { ContractRouter } from './router';
4
+ import type { AdaptedContractRouter } from './router-builder';
4
5
  import type { HTTPPath, Schema, SchemaInput, SchemaOutput } from './types';
5
6
  import { DecoratedContractProcedure } from './procedure-decorated';
6
7
  import { ContractRouterBuilder } from './router-builder';
7
- export declare class ContractBuilder {
8
- prefix(prefix: HTTPPath): ContractRouterBuilder;
9
- tag(...tags: string[]): ContractRouterBuilder;
10
- route(route: RouteOptions): DecoratedContractProcedure<undefined, undefined, undefined>;
11
- input<U extends Schema>(schema: U, example?: SchemaInput<U>): DecoratedContractProcedure<U, undefined, undefined>;
12
- output<U extends Schema>(schema: U, example?: SchemaOutput<U>): DecoratedContractProcedure<undefined, U, undefined>;
13
- errors<const U extends ErrorMap>(errorMap: U): DecoratedContractProcedure<undefined, undefined, U>;
14
- router<T extends ContractRouter>(router: T): T;
8
+ export type ContractBuilderDef<TErrorMap extends ErrorMap> = {
9
+ errorMap: TErrorMap;
10
+ };
11
+ export declare class ContractBuilder<TErrorMap extends ErrorMap> {
12
+ '~type': "ContractBuilder";
13
+ '~orpc': ContractBuilderDef<TErrorMap>;
14
+ constructor(def: ContractBuilderDef<TErrorMap>);
15
+ errors<const U extends ErrorMap & ErrorMapGuard<TErrorMap> & ErrorMapSuggestions>(errors: U): ContractBuilder<U & TErrorMap>;
16
+ prefix(prefix: HTTPPath): ContractRouterBuilder<TErrorMap>;
17
+ tag(...tags: string[]): ContractRouterBuilder<TErrorMap>;
18
+ route(route: RouteOptions): DecoratedContractProcedure<undefined, undefined, TErrorMap>;
19
+ input<U extends Schema>(schema: U, example?: SchemaInput<U>): DecoratedContractProcedure<U, undefined, TErrorMap>;
20
+ output<U extends Schema>(schema: U, example?: SchemaOutput<U>): DecoratedContractProcedure<undefined, U, TErrorMap>;
21
+ router<T extends ContractRouter<ErrorMap & Partial<StrictErrorMap<TErrorMap>>>>(router: T): AdaptedContractRouter<T, TErrorMap>;
15
22
  }
16
23
  //# sourceMappingURL=builder.d.ts.map
@@ -3,14 +3,56 @@ import type { Schema } from './types';
3
3
  export type ErrorMapItem<TDataSchema extends Schema> = {
4
4
  /**
5
5
  *
6
- * @default 200
6
+ * @default 500
7
7
  */
8
8
  status?: number;
9
9
  message?: string;
10
10
  description?: string;
11
11
  data?: TDataSchema;
12
12
  };
13
- export type ErrorMap = undefined | {
13
+ export interface ErrorMap {
14
+ [k: string]: ErrorMapItem<Schema>;
15
+ }
16
+ /**
17
+ * const U extends ErrorMap & ErrorMapGuard<TErrorMap> & ErrorMapSuggestions
18
+ *
19
+ * Purpose:
20
+ * - Helps `U` suggest `CommonORPCErrorCode` to the user when typing.
21
+ *
22
+ * Why not replace `ErrorMap` with `ErrorMapSuggestions`?
23
+ * - `ErrorMapSuggestions` has a drawback: it allows `undefined` values for items.
24
+ * - `ErrorMapGuard<TErrorMap>` uses `Partial`, which can introduce `undefined` values.
25
+ *
26
+ * This could lead to unintended behavior where `undefined` values override `TErrorMap`,
27
+ * potentially resulting in a `never` type after merging.
28
+ *
29
+ * Recommendation:
30
+ * - Use `ErrorMapSuggestions` to assist users in typing correctly but do not replace `ErrorMap`.
31
+ * - Ensure `ErrorMapGuard<TErrorMap>` is adjusted to prevent `undefined` values.
32
+ */
33
+ export type ErrorMapSuggestions = {
14
34
  [key in CommonORPCErrorCode | (string & {})]?: ErrorMapItem<Schema>;
15
35
  };
36
+ /**
37
+ * `U` extends `ErrorMap` & `ErrorMapGuard<TErrorMap>`
38
+ *
39
+ * `ErrorMapGuard` is a utility type that ensures `U` cannot redefine the structure of `TErrorMap`.
40
+ * It achieves this by setting each key in `TErrorMap` to `never`, effectively preventing any redefinition.
41
+ *
42
+ * Why not just use `Partial<TErrorMap>`?
43
+ * - Allowing users to redefine existing error map items would require using `StrictErrorMap`.
44
+ * - However, I prefer not to use `StrictErrorMap` frequently, due to perceived performance concerns,
45
+ * though this has not been benchmarked and is based on personal preference.
46
+ *
47
+ */
48
+ export type ErrorMapGuard<TErrorMap extends ErrorMap> = {
49
+ [K in keyof TErrorMap]?: never;
50
+ };
51
+ /**
52
+ * Since `undefined` has a specific meaning (it use default value),
53
+ * we ensure all additional properties in each item of the ErrorMap are explicitly set to `undefined`.
54
+ */
55
+ export type StrictErrorMap<T extends ErrorMap> = {
56
+ [K in keyof T]: T[K] & Partial<Record<Exclude<keyof ErrorMapItem<any>, keyof T[K]>, undefined>>;
57
+ };
16
58
  //# sourceMappingURL=error-map.d.ts.map
@@ -14,5 +14,5 @@ export * from './router';
14
14
  export * from './router-builder';
15
15
  export * from './router-client';
16
16
  export * from './types';
17
- export declare const oc: ContractBuilder;
17
+ export declare const oc: ContractBuilder<Record<never, never>>;
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { ErrorMap } from './error-map';
1
+ import type { ErrorMap, ErrorMapGuard, ErrorMapSuggestions } from './error-map';
2
2
  import type { RouteOptions } from './procedure';
3
3
  import type { HTTPPath, Schema, SchemaInput, SchemaOutput } from './types';
4
4
  import { ContractProcedure } from './procedure';
@@ -9,6 +9,6 @@ export declare class DecoratedContractProcedure<TInputSchema extends Schema, TOu
9
9
  unshiftTag(...tags: string[]): DecoratedContractProcedure<TInputSchema, TOutputSchema, TErrorMap>;
10
10
  input<U extends Schema>(schema: U, example?: SchemaInput<U>): DecoratedContractProcedure<U, TOutputSchema, TErrorMap>;
11
11
  output<U extends Schema>(schema: U, example?: SchemaOutput<U>): DecoratedContractProcedure<TInputSchema, U, TErrorMap>;
12
- errors<const U extends ErrorMap>(errorMap: U): DecoratedContractProcedure<TInputSchema, TOutputSchema, U>;
12
+ errors<const U extends ErrorMap & ErrorMapGuard<TErrorMap> & ErrorMapSuggestions>(errors: U): DecoratedContractProcedure<TInputSchema, TOutputSchema, TErrorMap & U>;
13
13
  }
14
14
  //# sourceMappingURL=procedure-decorated.d.ts.map
@@ -1,20 +1,23 @@
1
+ import type { ErrorMap, ErrorMapGuard, ErrorMapSuggestions, StrictErrorMap } from './error-map';
1
2
  import type { ContractProcedure } from './procedure';
2
3
  import type { ContractRouter } from './router';
3
4
  import type { HTTPPath } from './types';
4
5
  import { DecoratedContractProcedure } from './procedure-decorated';
5
- export type AdaptedContractRouter<TContract extends ContractRouter> = {
6
- [K in keyof TContract]: TContract[K] extends ContractProcedure<infer UInputSchema, infer UOutputSchema, infer UErrors> ? DecoratedContractProcedure<UInputSchema, UOutputSchema, UErrors> : TContract[K] extends ContractRouter ? AdaptedContractRouter<TContract[K]> : never;
6
+ export type AdaptedContractRouter<TContract extends ContractRouter<any>, TErrorMapExtra extends ErrorMap> = {
7
+ [K in keyof TContract]: TContract[K] extends ContractProcedure<infer UInputSchema, infer UOutputSchema, infer UErrors> ? DecoratedContractProcedure<UInputSchema, UOutputSchema, UErrors & TErrorMapExtra> : TContract[K] extends ContractRouter<any> ? AdaptedContractRouter<TContract[K], TErrorMapExtra> : never;
7
8
  };
8
- export interface ContractRouterBuilderDef {
9
+ export interface ContractRouterBuilderDef<TErrorMap extends ErrorMap> {
9
10
  prefix?: HTTPPath;
10
11
  tags?: string[];
12
+ errorMap: TErrorMap;
11
13
  }
12
- export declare class ContractRouterBuilder {
14
+ export declare class ContractRouterBuilder<TErrorMap extends ErrorMap> {
13
15
  '~type': "ContractProcedure";
14
- '~orpc': ContractRouterBuilderDef;
15
- constructor(def: ContractRouterBuilderDef);
16
- prefix(prefix: HTTPPath): ContractRouterBuilder;
17
- tag(...tags: string[]): ContractRouterBuilder;
18
- router<T extends ContractRouter>(router: T): AdaptedContractRouter<T>;
16
+ '~orpc': ContractRouterBuilderDef<TErrorMap>;
17
+ constructor(def: ContractRouterBuilderDef<TErrorMap>);
18
+ prefix(prefix: HTTPPath): ContractRouterBuilder<TErrorMap>;
19
+ tag(...tags: string[]): ContractRouterBuilder<TErrorMap>;
20
+ errors<const U extends ErrorMap & ErrorMapGuard<TErrorMap> & ErrorMapSuggestions>(errors: U): ContractRouterBuilder<U & TErrorMap>;
21
+ router<T extends ContractRouter<ErrorMap & Partial<StrictErrorMap<TErrorMap>>>>(router: T): AdaptedContractRouter<T, TErrorMap>;
19
22
  }
20
23
  //# sourceMappingURL=router-builder.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import type { ContractProcedure } from './procedure';
2
2
  import type { ContractProcedureClient } from './procedure-client';
3
3
  import type { ContractRouter } from './router';
4
- export type ContractRouterClient<TRouter extends ContractRouter, TClientContext> = TRouter extends ContractProcedure<infer UInputSchema, infer UOutputSchema, infer UErrorMap> ? ContractProcedureClient<TClientContext, UInputSchema, UOutputSchema, UErrorMap> : {
5
- [K in keyof TRouter]: TRouter[K] extends ContractRouter ? ContractRouterClient<TRouter[K], TClientContext> : never;
4
+ export type ContractRouterClient<TRouter extends ContractRouter<any>, TClientContext> = TRouter extends ContractProcedure<infer UInputSchema, infer UOutputSchema, infer UErrorMap> ? ContractProcedureClient<TClientContext, UInputSchema, UOutputSchema, UErrorMap> : {
5
+ [K in keyof TRouter]: TRouter[K] extends ContractRouter<any> ? ContractRouterClient<TRouter[K], TClientContext> : never;
6
6
  };
7
7
  //# sourceMappingURL=router-client.d.ts.map
@@ -1,12 +1,13 @@
1
- import type { ANY_CONTRACT_PROCEDURE, ContractProcedure } from './procedure';
1
+ import type { ErrorMap } from './error-map';
2
+ import type { ContractProcedure } from './procedure';
2
3
  import type { SchemaInput, SchemaOutput } from './types';
3
- export type ContractRouter = ANY_CONTRACT_PROCEDURE | {
4
- [k: string]: ContractRouter;
4
+ export type ContractRouter<T extends ErrorMap> = ContractProcedure<any, any, T> | {
5
+ [k: string]: ContractRouter<T>;
5
6
  };
6
- export type InferContractRouterInputs<T extends ContractRouter> = T extends ContractProcedure<infer UInputSchema, any, any> ? SchemaInput<UInputSchema> : {
7
- [K in keyof T]: T[K] extends ContractRouter ? InferContractRouterInputs<T[K]> : never;
7
+ export type InferContractRouterInputs<T extends ContractRouter<any>> = T extends ContractProcedure<infer UInputSchema, any, any> ? SchemaInput<UInputSchema> : {
8
+ [K in keyof T]: T[K] extends ContractRouter<any> ? InferContractRouterInputs<T[K]> : never;
8
9
  };
9
- export type InferContractRouterOutputs<T extends ContractRouter> = T extends ContractProcedure<any, infer UOutputSchema, any> ? SchemaOutput<UOutputSchema> : {
10
- [K in keyof T]: T[K] extends ContractRouter ? InferContractRouterOutputs<T[K]> : never;
10
+ export type InferContractRouterOutputs<T extends ContractRouter<any>> = T extends ContractProcedure<any, infer UOutputSchema, any> ? SchemaOutput<UOutputSchema> : {
11
+ [K in keyof T]: T[K] extends ContractRouter<any> ? InferContractRouterOutputs<T[K]> : never;
11
12
  };
12
13
  //# sourceMappingURL=router.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/contract",
3
3
  "type": "module",
4
- "version": "0.29.0",
4
+ "version": "0.30.0",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -30,7 +30,7 @@
30
30
  ],
31
31
  "dependencies": {
32
32
  "@standard-schema/spec": "1.0.0-beta.4",
33
- "@orpc/shared": "0.29.0"
33
+ "@orpc/shared": "0.30.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "arktype": "2.0.0-rc.26",