@orpc/json-schema 2.0.0-beta.42 → 2.0.0-beta.44

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/README.md CHANGED
@@ -17,7 +17,7 @@
17
17
  <img alt="Discord" src="https://img.shields.io/discord/1308966753044398161?color=7389D8&label&logo=discord&logoColor=ffffff" />
18
18
  </a>
19
19
  <a href="https://deepwiki.com/middleapi/orpc">
20
- <img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki">
20
+ <img alt="Ask DeepWiki" src="https://img.shields.io/badge/Ask-DeepWiki-blue" />
21
21
  </a>
22
22
  </div>
23
23
 
@@ -95,14 +95,6 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
95
95
  </tr>
96
96
  </table>
97
97
 
98
- ### Special Sponsors
99
-
100
- <table>
101
- <tr>
102
- <td align="center"><a href="http://twitter.com/rauchg?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Guillermo Rauch"><img src="https://avatars.githubusercontent.com/u/13041?u=1ee8d111657cdd02ff6d253df00978d17ee6d722&amp;v=4" width="279" alt="Guillermo Rauch"/><br />Guillermo Rauch</a></td>
103
- </tr>
104
- </table>
105
-
106
98
  ### Premium Sponsors
107
99
 
108
100
  <table>
@@ -178,7 +170,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
178
170
  </tr>
179
171
  </table>
180
172
 
181
- With thanks to [38 past sponsors](https://orpc.dev/sponsors#past-sponsors) who helped get oRPC here.
173
+ With thanks to [39 past sponsors](https://orpc.dev/sponsors#past-sponsors) who helped get oRPC here.
182
174
 
183
175
  ## References
184
176
 
package/dist/index.d.mts CHANGED
@@ -60,9 +60,33 @@ declare enum JsonSchemaXNativeType {
60
60
  Map = "map"
61
61
  }
62
62
 
63
+ interface JsonSchemaCoercerOptions {
64
+ /**
65
+ * Maximum digits, excluding a leading `-`, of a string coerced to `bigint`. Longer strings are left unchanged.
66
+ * `Number.POSITIVE_INFINITY` disables it.
67
+ *
68
+ * @default 4300
69
+ */
70
+ maxBigIntDigits?: number | undefined;
71
+ /**
72
+ * Maximum coercion steps per input value, where a step applies one schema to one value.
73
+ * Inputs with fewer than 100 values are budgeted as 100. Past the budget the whole input is left uncoerced,
74
+ * so validation still runs and reports any mismatch.
75
+ *
76
+ * @default 1000
77
+ */
78
+ maxStepsPerValue?: number | undefined;
79
+ }
63
80
  declare class JsonSchemaCoercer {
81
+ private readonly nativeCoerceOptions;
82
+ private readonly maxStepsPerValue;
83
+ /** Reused between calls, since building a context is slow until V8 warms up. */
84
+ private idleContext;
85
+ constructor(options?: JsonSchemaCoercerOptions);
64
86
  coerce([schema, optional]: [schema: JsonSchema, optional: boolean], value: unknown): unknown;
65
87
  private coerceInternal;
88
+ private coerceRef;
89
+ private extendBudget;
66
90
  }
67
91
 
68
92
  /**
@@ -203,7 +227,7 @@ declare function hoistRecursiveRefToDef(schema: JsonSchema): JsonSchema;
203
227
  */
204
228
  declare function resolveJsonSchemaRootLocalRef(schema: JsonSchema, $defs?: Exclude<JsonSchema, boolean>['$defs']): JsonSchema;
205
229
 
206
- interface SmartCoercionHandlerPluginOptions {
230
+ interface SmartCoercionHandlerPluginOptions extends JsonSchemaCoercerOptions {
207
231
  converters?: undefined | JsonSchemaConverter[];
208
232
  }
209
233
  /**
@@ -222,7 +246,7 @@ declare class SmartCoercionHandlerPlugin<T extends Context> implements StandardH
222
246
  private coerceValue;
223
247
  }
224
248
 
225
- interface SmartCoercionLinkPluginOptions {
249
+ interface SmartCoercionLinkPluginOptions extends JsonSchemaCoercerOptions {
226
250
  converters?: undefined | JsonSchemaConverter[];
227
251
  }
228
252
  /**
@@ -260,4 +284,4 @@ declare class StandardJsonSchemaConverter implements JsonSchemaConverter {
260
284
  }
261
285
 
262
286
  export { DelegatingJsonSchemaConverter, JsonSchemaCoercer, JsonSchemaFormat, JsonSchemaType, JsonSchemaXNativeType, SmartCoercionHandlerPlugin, SmartCoercionLinkPlugin, StandardJsonSchemaConverter, combineJsonObjectSchemaEntries, combineJsonSchemasWithComposition, decodeJsonPointerSegment, deduplicateJsonSchemas, encodeJsonPointerSegment, ensureJsonSchemaObject, extractJsonObjectSchemaEntries, flattenJsonUnionSchema, hoistRecursiveRefToDef, isJsonArraySchema, isJsonFileSchema, isJsonObjectSchema, isJsonPrimitiveSchema, isStandardSchemaOptional, isUnconstrainedSchema, mapJsonSchemaRefs, matchArrayableJsonSchema, resolveJsonSchemaRootLocalRef, visitJsonSchemaRefs };
263
- export type { JsonArraySchema, JsonFileSchema, JsonObjectSchema, JsonObjectSchemaEntry, JsonSchema, JsonSchemaConverter, JsonSchemaConverterDirection, JsonSchemaKeywords, SmartCoercionHandlerPluginOptions, SmartCoercionLinkPluginOptions };
287
+ export type { JsonArraySchema, JsonFileSchema, JsonObjectSchema, JsonObjectSchemaEntry, JsonSchema, JsonSchemaCoercerOptions, JsonSchemaConverter, JsonSchemaConverterDirection, JsonSchemaKeywords, SmartCoercionHandlerPluginOptions, SmartCoercionLinkPluginOptions };
package/dist/index.d.ts CHANGED
@@ -60,9 +60,33 @@ declare enum JsonSchemaXNativeType {
60
60
  Map = "map"
61
61
  }
62
62
 
63
+ interface JsonSchemaCoercerOptions {
64
+ /**
65
+ * Maximum digits, excluding a leading `-`, of a string coerced to `bigint`. Longer strings are left unchanged.
66
+ * `Number.POSITIVE_INFINITY` disables it.
67
+ *
68
+ * @default 4300
69
+ */
70
+ maxBigIntDigits?: number | undefined;
71
+ /**
72
+ * Maximum coercion steps per input value, where a step applies one schema to one value.
73
+ * Inputs with fewer than 100 values are budgeted as 100. Past the budget the whole input is left uncoerced,
74
+ * so validation still runs and reports any mismatch.
75
+ *
76
+ * @default 1000
77
+ */
78
+ maxStepsPerValue?: number | undefined;
79
+ }
63
80
  declare class JsonSchemaCoercer {
81
+ private readonly nativeCoerceOptions;
82
+ private readonly maxStepsPerValue;
83
+ /** Reused between calls, since building a context is slow until V8 warms up. */
84
+ private idleContext;
85
+ constructor(options?: JsonSchemaCoercerOptions);
64
86
  coerce([schema, optional]: [schema: JsonSchema, optional: boolean], value: unknown): unknown;
65
87
  private coerceInternal;
88
+ private coerceRef;
89
+ private extendBudget;
66
90
  }
67
91
 
68
92
  /**
@@ -203,7 +227,7 @@ declare function hoistRecursiveRefToDef(schema: JsonSchema): JsonSchema;
203
227
  */
204
228
  declare function resolveJsonSchemaRootLocalRef(schema: JsonSchema, $defs?: Exclude<JsonSchema, boolean>['$defs']): JsonSchema;
205
229
 
206
- interface SmartCoercionHandlerPluginOptions {
230
+ interface SmartCoercionHandlerPluginOptions extends JsonSchemaCoercerOptions {
207
231
  converters?: undefined | JsonSchemaConverter[];
208
232
  }
209
233
  /**
@@ -222,7 +246,7 @@ declare class SmartCoercionHandlerPlugin<T extends Context> implements StandardH
222
246
  private coerceValue;
223
247
  }
224
248
 
225
- interface SmartCoercionLinkPluginOptions {
249
+ interface SmartCoercionLinkPluginOptions extends JsonSchemaCoercerOptions {
226
250
  converters?: undefined | JsonSchemaConverter[];
227
251
  }
228
252
  /**
@@ -260,4 +284,4 @@ declare class StandardJsonSchemaConverter implements JsonSchemaConverter {
260
284
  }
261
285
 
262
286
  export { DelegatingJsonSchemaConverter, JsonSchemaCoercer, JsonSchemaFormat, JsonSchemaType, JsonSchemaXNativeType, SmartCoercionHandlerPlugin, SmartCoercionLinkPlugin, StandardJsonSchemaConverter, combineJsonObjectSchemaEntries, combineJsonSchemasWithComposition, decodeJsonPointerSegment, deduplicateJsonSchemas, encodeJsonPointerSegment, ensureJsonSchemaObject, extractJsonObjectSchemaEntries, flattenJsonUnionSchema, hoistRecursiveRefToDef, isJsonArraySchema, isJsonFileSchema, isJsonObjectSchema, isJsonPrimitiveSchema, isStandardSchemaOptional, isUnconstrainedSchema, mapJsonSchemaRefs, matchArrayableJsonSchema, resolveJsonSchemaRootLocalRef, visitJsonSchemaRefs };
263
- export type { JsonArraySchema, JsonFileSchema, JsonObjectSchema, JsonObjectSchemaEntry, JsonSchema, JsonSchemaConverter, JsonSchemaConverterDirection, JsonSchemaKeywords, SmartCoercionHandlerPluginOptions, SmartCoercionLinkPluginOptions };
287
+ export type { JsonArraySchema, JsonFileSchema, JsonObjectSchema, JsonObjectSchemaEntry, JsonSchema, JsonSchemaCoercerOptions, JsonSchemaConverter, JsonSchemaConverterDirection, JsonSchemaKeywords, SmartCoercionHandlerPluginOptions, SmartCoercionLinkPluginOptions };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { setOwn, get, isPlainObject, tryOrUndefined, getOwn, toArray, isDeepEqual, omit, isTypescriptObject } from '@orpc/shared';
1
+ import { setOwn, get, DEFAULT_MAX_BIGINT_DIGITS, isPlainObject, tryOrUndefined, getOwn, toArray, isTypescriptObject, parseBigIntString, isDeepEqual, omit } from '@orpc/shared';
2
2
  import { ORPCError, cloneORPCError } from '@orpc/client';
3
3
  import { getProcedureContractOrThrow } from '@orpc/contract';
4
4
 
@@ -215,7 +215,7 @@ const NATIVE_TYPES = /* @__PURE__ */ new Map([
215
215
  [JsonSchemaXNativeType.BigInt, {
216
216
  types: ["string", "integer", "number"],
217
217
  is: (value) => typeof value === "bigint",
218
- coerce: (value) => typeof value === "string" ? stringToBigInt(value) : typeof value === "number" ? numberToBigInt(value) : value
218
+ coerce: (value, { maxBigIntDigits }) => typeof value === "string" ? stringToBigInt(value, maxBigIntDigits) : typeof value === "number" ? numberToBigInt(value) : value
219
219
  }],
220
220
  [JsonSchemaXNativeType.Url, {
221
221
  types: ["string"],
@@ -238,21 +238,58 @@ const NATIVE_TYPES = /* @__PURE__ */ new Map([
238
238
  function minSatisfaction(a, b) {
239
239
  return a < b ? a : b;
240
240
  }
241
+ const MIN_BUDGETED_VALUES = 100;
242
+ function createContext() {
243
+ return { rootSchema: true, memo: void 0, memoize: false, steps: 0, maxSteps: 0, input: void 0 };
244
+ }
245
+ class CoercionBudgetExceededError extends Error {
246
+ }
241
247
  class JsonSchemaCoercer {
248
+ nativeCoerceOptions;
249
+ maxStepsPerValue;
250
+ /** Reused between calls, since building a context is slow until V8 warms up. */
251
+ idleContext = createContext();
252
+ constructor(options = {}) {
253
+ this.nativeCoerceOptions = {
254
+ maxBigIntDigits: options.maxBigIntDigits ?? DEFAULT_MAX_BIGINT_DIGITS
255
+ };
256
+ this.maxStepsPerValue = options.maxStepsPerValue ?? 1e3;
257
+ }
242
258
  coerce([schema, optional], value) {
243
259
  if (optional && value === void 0) {
244
260
  return value;
245
261
  }
246
- const [, coerced] = this.coerceInternal(schema, schema, value);
247
- return coerced;
262
+ const context = this.idleContext ?? createContext();
263
+ this.idleContext = void 0;
264
+ context.rootSchema = schema;
265
+ context.memoize = false;
266
+ context.steps = 0;
267
+ context.maxSteps = this.maxStepsPerValue * MIN_BUDGETED_VALUES;
268
+ context.input = value;
269
+ try {
270
+ const [, coerced] = this.coerceInternal(context, schema, value);
271
+ return coerced;
272
+ } catch (error) {
273
+ if (error instanceof CoercionBudgetExceededError) {
274
+ return value;
275
+ }
276
+ throw error;
277
+ } finally {
278
+ context.memo = void 0;
279
+ context.input = void 0;
280
+ this.idleContext = context;
281
+ }
248
282
  }
249
- coerceInternal(rootSchema, schema, value, appliedRefs) {
283
+ coerceInternal(context, schema, value, appliedRefs) {
284
+ if (++context.steps > context.maxSteps) {
285
+ this.extendBudget(context);
286
+ }
250
287
  if (typeof schema === "boolean") {
251
288
  return [schema ? SATISFIED : UNSATISFIED, value];
252
289
  }
253
290
  if (Array.isArray(schema.type)) {
254
291
  return this.coerceInternal(
255
- rootSchema,
292
+ context,
256
293
  { anyOf: schema.type.map((type) => ({ ...schema, type })) },
257
294
  value,
258
295
  appliedRefs
@@ -261,12 +298,12 @@ class JsonSchemaCoercer {
261
298
  let coerced = value;
262
299
  let satisfied = SATISFIED;
263
300
  if (typeof schema.$ref === "string") {
264
- const resolved = schema.$ref.startsWith("#/") ? get(rootSchema, schema.$ref.slice("#/".length).split("/").map(decodeJsonPointerSegment)) : schema.$ref === "#" ? rootSchema : void 0;
301
+ const resolved = schema.$ref.startsWith("#/") ? get(context.rootSchema, schema.$ref.slice("#/".length).split("/").map(decodeJsonPointerSegment)) : schema.$ref === "#" ? context.rootSchema : void 0;
265
302
  if (resolved !== void 0 && !appliedRefs?.has(resolved)) {
266
- appliedRefs ??= /* @__PURE__ */ new Set();
267
- appliedRefs.add(resolved);
268
- const [subSatisfied, subCoerced] = this.coerceInternal(rootSchema, resolved, coerced, appliedRefs);
269
- appliedRefs.delete(resolved);
303
+ if (schema.type === "object" || schema.type === "array") {
304
+ context.memoize = true;
305
+ }
306
+ const [subSatisfied, subCoerced] = this.coerceRef(context, resolved, coerced, appliedRefs);
270
307
  coerced = subCoerced;
271
308
  satisfied = minSatisfaction(satisfied, subSatisfied);
272
309
  }
@@ -292,7 +329,7 @@ class JsonSchemaCoercer {
292
329
  const declaredNativeType = NATIVE_TYPES.get(schema["x-native-type"]);
293
330
  const nativeType = schema.type === void 0 || declaredNativeType?.types.includes(schema.type) ? declaredNativeType : void 0;
294
331
  if (nativeType && !nativeType.afterTypeCheck) {
295
- coerced = nativeType.coerce(coerced);
332
+ coerced = nativeType.coerce(coerced, this.nativeCoerceOptions);
296
333
  }
297
334
  if (schema.type && !nativeType?.is(coerced)) {
298
335
  switch (schema.type) {
@@ -346,7 +383,7 @@ class JsonSchemaCoercer {
346
383
  satisfied = minSatisfaction(satisfied, LOOSELY_SATISFIED);
347
384
  return item;
348
385
  }
349
- const [subSatisfied, subCoerced] = this.coerceInternal(rootSchema, subSchema, item);
386
+ const [subSatisfied, subCoerced] = this.coerceInternal(context, subSchema, item);
350
387
  satisfied = minSatisfaction(satisfied, subSatisfied);
351
388
  if (subCoerced !== item) {
352
389
  shouldUseCoercedItems = true;
@@ -383,7 +420,7 @@ class JsonSchemaCoercer {
383
420
  if (subSchema === void 0) {
384
421
  satisfied = minSatisfaction(satisfied, LOOSELY_SATISFIED);
385
422
  } else {
386
- const [subSatisfied, subCoerced] = this.coerceInternal(rootSchema, subSchema, value2);
423
+ const [subSatisfied, subCoerced] = this.coerceInternal(context, subSchema, value2);
387
424
  coercedItems[key] = subCoerced;
388
425
  satisfied = minSatisfaction(satisfied, subSatisfied);
389
426
  if (subCoerced !== value2) {
@@ -407,24 +444,26 @@ class JsonSchemaCoercer {
407
444
  }
408
445
  if (nativeType) {
409
446
  if (nativeType.afterTypeCheck) {
410
- coerced = nativeType.coerce(coerced);
447
+ coerced = nativeType.coerce(coerced, this.nativeCoerceOptions);
411
448
  }
412
449
  if (!nativeType.is(coerced)) {
413
450
  satisfied = UNSATISFIED;
414
451
  }
415
452
  }
416
453
  if (schema.allOf) {
454
+ context.memoize = true;
417
455
  for (const subSchema of schema.allOf) {
418
- const [subSatisfied, subCoerced] = this.coerceInternal(rootSchema, subSchema, coerced, appliedRefs);
456
+ const [subSatisfied, subCoerced] = this.coerceInternal(context, subSchema, coerced, appliedRefs);
419
457
  coerced = subCoerced;
420
458
  satisfied = minSatisfaction(satisfied, subSatisfied);
421
459
  }
422
460
  }
423
461
  for (const key of ["anyOf", "oneOf"]) {
424
462
  if (schema[key]) {
463
+ context.memoize = true;
425
464
  let best;
426
465
  for (const subSchema of schema[key]) {
427
- const [subSatisfied, subCoerced] = this.coerceInternal(rootSchema, subSchema, coerced, appliedRefs);
466
+ const [subSatisfied, subCoerced] = this.coerceInternal(context, subSchema, coerced, appliedRefs);
428
467
  if (subSatisfied === UNSATISFIED) {
429
468
  continue;
430
469
  }
@@ -445,13 +484,64 @@ class JsonSchemaCoercer {
445
484
  }
446
485
  }
447
486
  if (typeof schema.not !== "undefined") {
448
- const [notSatisfied] = this.coerceInternal(rootSchema, schema.not, coerced, appliedRefs);
487
+ context.memoize = true;
488
+ const [notSatisfied] = this.coerceInternal(context, schema.not, coerced, appliedRefs);
449
489
  if (notSatisfied !== UNSATISFIED) {
450
490
  satisfied = UNSATISFIED;
451
491
  }
452
492
  }
453
493
  return [satisfied, coerced];
454
494
  }
495
+ coerceRef(context, resolved, value, appliedRefs) {
496
+ let memo;
497
+ if (context.memoize && !appliedRefs?.size && isTypescriptObject(value)) {
498
+ context.memo ??= /* @__PURE__ */ new Map();
499
+ memo = context.memo.get(resolved);
500
+ if (!memo) {
501
+ memo = /* @__PURE__ */ new Map();
502
+ context.memo.set(resolved, memo);
503
+ }
504
+ const cached = memo.get(value);
505
+ if (cached) {
506
+ return cached;
507
+ }
508
+ }
509
+ appliedRefs ??= /* @__PURE__ */ new Set();
510
+ appliedRefs.add(resolved);
511
+ const result = this.coerceInternal(context, resolved, value, appliedRefs);
512
+ appliedRefs.delete(resolved);
513
+ memo?.set(value, result);
514
+ return result;
515
+ }
516
+ extendBudget(context) {
517
+ const limit = 2 * context.steps / this.maxStepsPerValue;
518
+ context.maxSteps = this.maxStepsPerValue * Math.max(countValues(context.input, limit), MIN_BUDGETED_VALUES);
519
+ if (context.steps > context.maxSteps) {
520
+ throw new CoercionBudgetExceededError();
521
+ }
522
+ }
523
+ }
524
+ function countValues(input, limit) {
525
+ const walked = /* @__PURE__ */ new Set();
526
+ const stack = [input];
527
+ let count = 1;
528
+ while (stack.length) {
529
+ const value = stack.pop();
530
+ if ((Array.isArray(value) || isPlainObject(value)) && !walked.has(value)) {
531
+ walked.add(value);
532
+ const items = Array.isArray(value) ? value : Object.values(value);
533
+ for (let i = 0; i < items.length; i++) {
534
+ if (++count >= limit) {
535
+ return count;
536
+ }
537
+ const item = items[i];
538
+ if (isTypescriptObject(item)) {
539
+ stack.push(item);
540
+ }
541
+ }
542
+ }
543
+ }
544
+ return count;
455
545
  }
456
546
  const NUMBER_PATTERN = /^-?(?:0|[1-9]\d*)(?:\.\d+)?$/;
457
547
  function stringToNumber(value) {
@@ -475,11 +565,8 @@ function stringToInteger(value) {
475
565
  }
476
566
  return num;
477
567
  }
478
- function stringToBigInt(value) {
479
- if (!INTEGER_PATTERN.test(value)) {
480
- return value;
481
- }
482
- return BigInt(value);
568
+ function stringToBigInt(value, maxDigits) {
569
+ return parseBigIntString(value, maxDigits) ?? value;
483
570
  }
484
571
  function numberToBigInt(value) {
485
572
  if (!Number.isInteger(value)) {
@@ -497,7 +584,7 @@ function stringToBoolean(value) {
497
584
  }
498
585
  return value;
499
586
  }
500
- const DATE_TIME_PATTERN = /^(?!-0{6})(?:[+-]\d{2})?\d{4}-\d{2}-\d{2}(?:[T ].*)?$/;
587
+ const DATE_TIME_PATTERN = /^(?!-0{6})(?:[+-]\d{2})?\d{4}-\d{2}-\d{2}(?:[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:?\d{2})?)?$/;
501
588
  const DAYS_IN_MONTH = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
502
589
  function stringToDate(value) {
503
590
  if (!DATE_TIME_PATTERN.test(value)) {
@@ -902,7 +989,7 @@ class SmartCoercionHandlerPlugin {
902
989
  ...toArray(options.converters),
903
990
  new StandardJsonSchemaConverter()
904
991
  ]);
905
- this.coercer = new JsonSchemaCoercer();
992
+ this.coercer = new JsonSchemaCoercer(options);
906
993
  }
907
994
  init(options) {
908
995
  return {
@@ -940,7 +1027,7 @@ class SmartCoercionLinkPlugin {
940
1027
  ...toArray(options.converters),
941
1028
  new StandardJsonSchemaConverter()
942
1029
  ]);
943
- this.coercer = new JsonSchemaCoercer();
1030
+ this.coercer = new JsonSchemaCoercer(options);
944
1031
  }
945
1032
  name = "~smart-coercion";
946
1033
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/json-schema",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.42",
4
+ "version": "2.0.0-beta.44",
5
5
  "description": "JSON Schema conversion and smart request coercion for oRPC and OpenAPI",
6
6
  "license": "MIT",
7
7
  "funding": [
@@ -36,14 +36,14 @@
36
36
  ],
37
37
  "dependencies": {
38
38
  "@openapi-spec/types": "~0.3.0",
39
- "@orpc/client": "2.0.0-beta.42",
40
- "@orpc/contract": "2.0.0-beta.42",
41
- "@orpc/server": "2.0.0-beta.42",
42
- "@orpc/shared": "2.0.0-beta.42",
39
+ "@orpc/client": "2.0.0-beta.44",
40
+ "@orpc/contract": "2.0.0-beta.44",
41
+ "@orpc/server": "2.0.0-beta.44",
42
+ "@orpc/shared": "2.0.0-beta.44",
43
43
  "@standard-schema/spec": "^1.1.0"
44
44
  },
45
45
  "devDependencies": {
46
- "zod": "^4.5.4"
46
+ "zod": "^4.6.5"
47
47
  },
48
48
  "scripts": {
49
49
  "type:check": "tsc -b"