@orpc/json-schema 2.0.0-beta.20 → 2.0.0-beta.22
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 +5 -5
- package/dist/index.mjs +107 -76
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -109,11 +109,10 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
109
109
|
<td align="center"><a href="https://github.com/valerii15298?ref=orpc" target="_blank" rel="noopener" title="Valerii Petryniak"><img src="https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&v=4" width="139" alt="Valerii Petryniak"/><br />Valerii Petryniak</a></td>
|
|
110
110
|
<td align="center"><a href="https://github.com/letstri?ref=orpc" target="_blank" rel="noopener" title="Valerii Strilets"><img src="https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&v=4" width="139" alt="Valerii Strilets"/><br />Valerii Strilets</a></td>
|
|
111
111
|
<td align="center"><a href="https://github.com/K-Mistele?ref=orpc" target="_blank" rel="noopener" title="Kyle Mistele"><img src="https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&v=4" width="139" alt="Kyle Mistele"/><br />Kyle Mistele</a></td>
|
|
112
|
-
<td align="center"><a href="https://github.com/R44VC0RP?ref=orpc" target="_blank" rel="noopener" title="Ryan Vogel"><img src="https://avatars.githubusercontent.com/u/89211796?u=1857347b9787d8d8a7ea5bfc333f96be92d5a683&v=4" width="139" alt="Ryan Vogel"/><br />Ryan Vogel</a></td>
|
|
113
112
|
<td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td>
|
|
113
|
+
<td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td>
|
|
114
114
|
</tr>
|
|
115
115
|
<tr>
|
|
116
|
-
<td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td>
|
|
117
116
|
<td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&v=4" width="139" alt="shota"/><br />shota</a></td>
|
|
118
117
|
</tr>
|
|
119
118
|
</table>
|
|
@@ -123,24 +122,23 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
123
122
|
<table>
|
|
124
123
|
<tr>
|
|
125
124
|
<td align="center"><a href="https://github.com/rhinodavid?ref=orpc" target="_blank" rel="noopener" title="David Walsh"><img src="https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&v=4" width="119" alt="David Walsh"/><br />David Walsh</a></td>
|
|
126
|
-
<td align="center"><a href="https://github.com/Nic13Gamer?ref=orpc" target="_blank" rel="noopener" title="Nicholas"><img src="https://avatars.githubusercontent.com/u/54724556?u=56a7ab430ce7a80d648ab6eba051d454a818ed0b&v=4" width="119" alt="Nicholas"/><br />Nicholas</a></td>
|
|
127
125
|
<td align="center"><a href="https://github.com/Robbe95?ref=orpc" target="_blank" rel="noopener" title="Robbe Vaes"><img src="https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&v=4" width="119" alt="Robbe Vaes"/><br />Robbe Vaes</a></td>
|
|
128
126
|
<td align="center"><a href="https://github.com/aidansunbury?ref=orpc" target="_blank" rel="noopener" title="Aidan Sunbury"><img src="https://avatars.githubusercontent.com/u/64103161?v=4" width="119" alt="Aidan Sunbury"/><br />Aidan Sunbury</a></td>
|
|
129
127
|
<td align="center"><a href="https://github.com/soonoo?ref=orpc" target="_blank" rel="noopener" title="soonoo"><img src="https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&v=4" width="119" alt="soonoo"/><br />soonoo</a></td>
|
|
130
128
|
<td align="center"><a href="https://github.com/kporten?ref=orpc" target="_blank" rel="noopener" title="Kevin Porten"><img src="https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&v=4" width="119" alt="Kevin Porten"/><br />Kevin Porten</a></td>
|
|
131
129
|
<td align="center"><a href="https://github.com/pumpkinlink?ref=orpc" target="_blank" rel="noopener" title="Denis"><img src="https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&v=4" width="119" alt="Denis"/><br />Denis</a></td>
|
|
130
|
+
<td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td>
|
|
132
131
|
</tr>
|
|
133
132
|
<tr>
|
|
134
|
-
<td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td>
|
|
135
133
|
<td align="center"><a href="https://github.com/thomasballinger?ref=orpc" target="_blank" rel="noopener" title="Tom Ballinger"><img src="https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&v=4" width="119" alt="Tom Ballinger"/><br />Tom Ballinger</a></td>
|
|
136
134
|
<td align="center"><a href="https://github.com/SSam0419?ref=orpc" target="_blank" rel="noopener" title="Sam"><img src="https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&v=4" width="119" alt="Sam"/><br />Sam</a></td>
|
|
137
135
|
<td align="center"><a href="https://github.com/Titoine?ref=orpc" target="_blank" rel="noopener" title="Titoine"><img src="https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&v=4" width="119" alt="Titoine"/><br />Titoine</a></td>
|
|
138
136
|
<td align="center"><a href="https://github.com/Mnigos?ref=orpc" target="_blank" rel="noopener" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&v=4" width="119" alt="Igor Makowski"/><br />Igor Makowski</a></td>
|
|
139
137
|
<td align="center"><a href="https://github.com/hanayashiki?ref=orpc" target="_blank" rel="noopener" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&v=4" width="119" alt="hanayashiki"/><br />hanayashiki</a></td>
|
|
140
138
|
<td align="center"><a href="https://github.com/ldub?ref=orpc" target="_blank" rel="noopener" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&v=4" width="119" alt="Lev Dubinets"/><br />Lev Dubinets</a></td>
|
|
139
|
+
<td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td>
|
|
141
140
|
</tr>
|
|
142
141
|
<tr>
|
|
143
|
-
<td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td>
|
|
144
142
|
<td align="center"><a href="https://github.com/piscis?ref=orpc" target="_blank" rel="noopener" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&v=4" width="119" alt="Alex"/><br />Alex</a></td>
|
|
145
143
|
<td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=29e91400dbd4a9c217048a8f59562c4f740498e6&v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td>
|
|
146
144
|
</tr>
|
|
@@ -173,6 +171,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
173
171
|
<a href="https://github.com/nguyenlc1993?ref=orpc" target="_blank" rel="noopener" title="Lê Cao Nguyên"><img src="https://avatars.githubusercontent.com/u/13871971?u=83c8b69d9e35b589c4e1f066cc113b1d9461386f&v=4" width="32" height="32" alt="Lê Cao Nguyên" /></a>
|
|
174
172
|
<a href="https://github.com/wobsoriano?ref=orpc" target="_blank" rel="noopener" title="Robert Soriano"><img src="https://avatars.githubusercontent.com/u/13049130?u=6d72104182e7c9ed25934815313fb69107332111&v=4" width="32" height="32" alt="Robert Soriano" /></a>
|
|
175
173
|
<a href="https://github.com/andrewpeters9?ref=orpc" target="_blank" rel="noopener" title="Andrew Peters"><img src="https://avatars.githubusercontent.com/u/36251325?v=4" width="32" height="32" alt="Andrew Peters" /></a>
|
|
174
|
+
<a href="https://github.com/R44VC0RP?ref=orpc" target="_blank" rel="noopener" title="Ryan Vogel"><img src="https://avatars.githubusercontent.com/u/89211796?u=1857347b9787d8d8a7ea5bfc333f96be92d5a683&v=4" width="32" height="32" alt="Ryan Vogel" /></a>
|
|
176
175
|
<a href="https://github.com/SKostyukovich?ref=orpc" target="_blank" rel="noopener" title="SKostyukovich"><img src="https://avatars.githubusercontent.com/u/10700067?v=4" width="32" height="32" alt="SKostyukovich" /></a>
|
|
177
176
|
<a href="https://github.com/peter-adam-dy?ref=orpc" target="_blank" rel="noopener" title="Peter Adam"><img src="https://avatars.githubusercontent.com/u/132129459?u=4f3dbbb3b443990b56acb7d6a5d11ed2c555f6db&v=4" width="32" height="32" alt="Peter Adam" /></a>
|
|
178
177
|
<a href="https://github.com/FabworksHQ?ref=orpc" target="_blank" rel="noopener" title="Fabworks"><img src="https://avatars.githubusercontent.com/u/160179500?v=4" width="32" height="32" alt="Fabworks" /></a>
|
|
@@ -185,6 +184,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
185
184
|
<a href="https://github.com/nattstack?ref=orpc" target="_blank" rel="noopener" title="natt"><img src="https://avatars.githubusercontent.com/u/31426677?u=fa9dbb8b3e66eb0ea3c88db5dc07f31c8c5418fe&v=4" width="32" height="32" alt="natt" /></a>
|
|
186
185
|
<a href="https://github.com/ChromeGG?ref=orpc" target="_blank" rel="noopener" title="Adam Tkaczyk"><img src="https://avatars.githubusercontent.com/u/39050595?u=a58ca6042a6950e94e6e92442db76ef584279bc0&v=4" width="32" height="32" alt="Adam Tkaczyk" /></a>
|
|
187
186
|
<a href="https://github.com/plancraft?ref=orpc" target="_blank" rel="noopener" title="plancraft"><img src="https://avatars.githubusercontent.com/u/46482287?v=4" width="32" height="32" alt="plancraft" /></a>
|
|
187
|
+
<a href="https://github.com/Nic13Gamer?ref=orpc" target="_blank" rel="noopener" title="Nicholas"><img src="https://avatars.githubusercontent.com/u/54724556?u=56a7ab430ce7a80d648ab6eba051d454a818ed0b&v=4" width="32" height="32" alt="Nicholas" /></a>
|
|
188
188
|
</p>
|
|
189
189
|
|
|
190
190
|
## References
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { get, isPlainObject,
|
|
1
|
+
import { get, isPlainObject, tryOrUndefined, toArray, isDeepEqual, omit, isTypescriptObject } from '@orpc/shared';
|
|
2
2
|
export { Format as JsonSchemaFormat, TypeName as JsonSchemaType } from 'json-schema-typed/draft-2020-12';
|
|
3
3
|
import { ORPCError, cloneORPCError } from '@orpc/client';
|
|
4
4
|
import { getProcedureContractOrThrow } from '@orpc/contract';
|
|
@@ -169,7 +169,12 @@ var JsonSchemaXNativeType = /* @__PURE__ */ ((JsonSchemaXNativeType2) => {
|
|
|
169
169
|
return JsonSchemaXNativeType2;
|
|
170
170
|
})(JsonSchemaXNativeType || {});
|
|
171
171
|
|
|
172
|
-
const
|
|
172
|
+
const UNSATISFIED = 0;
|
|
173
|
+
const LOOSELY_SATISFIED = 1;
|
|
174
|
+
const SATISFIED = 2;
|
|
175
|
+
function minSatisfaction(a, b) {
|
|
176
|
+
return a < b ? a : b;
|
|
177
|
+
}
|
|
173
178
|
class JsonSchemaCoercer {
|
|
174
179
|
coerce([schema, optional], value) {
|
|
175
180
|
if (optional && value === void 0) {
|
|
@@ -178,25 +183,29 @@ class JsonSchemaCoercer {
|
|
|
178
183
|
const [, coerced] = this.coerceInternal(schema, schema, value);
|
|
179
184
|
return coerced;
|
|
180
185
|
}
|
|
181
|
-
coerceInternal(rootSchema, schema, value) {
|
|
186
|
+
coerceInternal(rootSchema, schema, value, appliedRefs) {
|
|
182
187
|
if (typeof schema === "boolean") {
|
|
183
|
-
return [schema, value];
|
|
188
|
+
return [schema ? SATISFIED : UNSATISFIED, value];
|
|
184
189
|
}
|
|
185
190
|
if (Array.isArray(schema.type)) {
|
|
186
191
|
return this.coerceInternal(
|
|
187
192
|
rootSchema,
|
|
188
193
|
{ anyOf: schema.type.map((type) => ({ ...schema, type })) },
|
|
189
|
-
value
|
|
194
|
+
value,
|
|
195
|
+
appliedRefs
|
|
190
196
|
);
|
|
191
197
|
}
|
|
192
198
|
let coerced = value;
|
|
193
|
-
let satisfied =
|
|
199
|
+
let satisfied = SATISFIED;
|
|
194
200
|
if (typeof schema.$ref === "string") {
|
|
195
201
|
const resolved = schema.$ref.startsWith("#/") ? get(rootSchema, schema.$ref.slice("#/".length).split("/").map(decodeJsonPointerSegment)) : schema.$ref === "#" ? rootSchema : void 0;
|
|
196
|
-
if (resolved !== void 0) {
|
|
197
|
-
|
|
202
|
+
if (resolved !== void 0 && !appliedRefs?.has(resolved)) {
|
|
203
|
+
appliedRefs ??= /* @__PURE__ */ new Set();
|
|
204
|
+
appliedRefs.add(resolved);
|
|
205
|
+
const [subSatisfied, subCoerced] = this.coerceInternal(rootSchema, resolved, coerced, appliedRefs);
|
|
206
|
+
appliedRefs.delete(resolved);
|
|
198
207
|
coerced = subCoerced;
|
|
199
|
-
satisfied = subSatisfied;
|
|
208
|
+
satisfied = minSatisfaction(satisfied, subSatisfied);
|
|
200
209
|
}
|
|
201
210
|
}
|
|
202
211
|
const enumValues = schema.const !== void 0 ? [schema.const] : schema.enum;
|
|
@@ -210,24 +219,24 @@ class JsonSchemaCoercer {
|
|
|
210
219
|
if (enumValues.includes(booleanValue)) {
|
|
211
220
|
coerced = booleanValue;
|
|
212
221
|
} else {
|
|
213
|
-
satisfied =
|
|
222
|
+
satisfied = UNSATISFIED;
|
|
214
223
|
}
|
|
215
224
|
}
|
|
216
225
|
} else {
|
|
217
|
-
satisfied =
|
|
226
|
+
satisfied = UNSATISFIED;
|
|
218
227
|
}
|
|
219
228
|
}
|
|
220
229
|
if (schema.type) {
|
|
221
230
|
switch (schema.type) {
|
|
222
231
|
case "null": {
|
|
223
232
|
if (coerced !== null) {
|
|
224
|
-
satisfied =
|
|
233
|
+
satisfied = UNSATISFIED;
|
|
225
234
|
}
|
|
226
235
|
break;
|
|
227
236
|
}
|
|
228
237
|
case "string": {
|
|
229
238
|
if (typeof coerced !== "string") {
|
|
230
|
-
satisfied =
|
|
239
|
+
satisfied = UNSATISFIED;
|
|
231
240
|
}
|
|
232
241
|
break;
|
|
233
242
|
}
|
|
@@ -236,7 +245,7 @@ class JsonSchemaCoercer {
|
|
|
236
245
|
coerced = stringToNumber(coerced);
|
|
237
246
|
}
|
|
238
247
|
if (typeof coerced !== "number") {
|
|
239
|
-
satisfied =
|
|
248
|
+
satisfied = UNSATISFIED;
|
|
240
249
|
}
|
|
241
250
|
break;
|
|
242
251
|
}
|
|
@@ -245,7 +254,7 @@ class JsonSchemaCoercer {
|
|
|
245
254
|
coerced = stringToInteger(coerced);
|
|
246
255
|
}
|
|
247
256
|
if (typeof coerced !== "number" || !Number.isInteger(coerced)) {
|
|
248
|
-
satisfied =
|
|
257
|
+
satisfied = UNSATISFIED;
|
|
249
258
|
}
|
|
250
259
|
break;
|
|
251
260
|
}
|
|
@@ -254,7 +263,7 @@ class JsonSchemaCoercer {
|
|
|
254
263
|
coerced = stringToBoolean(coerced);
|
|
255
264
|
}
|
|
256
265
|
if (typeof coerced !== "boolean") {
|
|
257
|
-
satisfied =
|
|
266
|
+
satisfied = UNSATISFIED;
|
|
258
267
|
}
|
|
259
268
|
break;
|
|
260
269
|
}
|
|
@@ -266,26 +275,24 @@ class JsonSchemaCoercer {
|
|
|
266
275
|
const coercedItems = coerced.map((item, i) => {
|
|
267
276
|
const subSchema = prefixItemSchemas[i] ?? itemSchema;
|
|
268
277
|
if (subSchema === void 0) {
|
|
269
|
-
satisfied =
|
|
278
|
+
satisfied = minSatisfaction(satisfied, LOOSELY_SATISFIED);
|
|
270
279
|
return item;
|
|
271
280
|
}
|
|
272
281
|
const [subSatisfied, subCoerced] = this.coerceInternal(rootSchema, subSchema, item);
|
|
273
|
-
|
|
274
|
-
satisfied = false;
|
|
275
|
-
}
|
|
282
|
+
satisfied = minSatisfaction(satisfied, subSatisfied);
|
|
276
283
|
if (subCoerced !== item) {
|
|
277
284
|
shouldUseCoercedItems = true;
|
|
278
285
|
}
|
|
279
286
|
return subCoerced;
|
|
280
287
|
});
|
|
281
288
|
if (coercedItems.length < prefixItemSchemas.length) {
|
|
282
|
-
satisfied =
|
|
289
|
+
satisfied = UNSATISFIED;
|
|
283
290
|
}
|
|
284
291
|
if (shouldUseCoercedItems) {
|
|
285
292
|
coerced = coercedItems;
|
|
286
293
|
}
|
|
287
294
|
} else {
|
|
288
|
-
satisfied =
|
|
295
|
+
satisfied = UNSATISFIED;
|
|
289
296
|
}
|
|
290
297
|
break;
|
|
291
298
|
}
|
|
@@ -295,35 +302,36 @@ class JsonSchemaCoercer {
|
|
|
295
302
|
}
|
|
296
303
|
if (isPlainObject(coerced)) {
|
|
297
304
|
let shouldUseCoercedItems = false;
|
|
298
|
-
const coercedItems = {};
|
|
299
|
-
const patternProperties = Object.entries(schema.patternProperties ?? {}).
|
|
305
|
+
const coercedItems = { ...coerced };
|
|
306
|
+
const patternProperties = Object.entries(schema.patternProperties ?? {}).flatMap(([key, value2]) => {
|
|
307
|
+
const pattern = tryOrUndefined(() => new RegExp(key));
|
|
308
|
+
return pattern ? [[pattern, value2]] : [];
|
|
309
|
+
});
|
|
310
|
+
const propertySchemas = schema.properties;
|
|
300
311
|
for (const key in coerced) {
|
|
301
312
|
const value2 = coerced[key];
|
|
302
|
-
const subSchema =
|
|
303
|
-
if (value2
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
}
|
|
314
|
-
if (subCoerced !== value2) {
|
|
315
|
-
shouldUseCoercedItems = true;
|
|
313
|
+
const subSchema = (propertySchemas !== void 0 && Object.hasOwn(propertySchemas, key) ? propertySchemas[key] : void 0) ?? patternProperties.find(([pattern]) => pattern.test(key))?.[1] ?? schema.additionalProperties;
|
|
314
|
+
if (value2 !== void 0 || schema.required?.includes(key)) {
|
|
315
|
+
if (subSchema === void 0) {
|
|
316
|
+
satisfied = minSatisfaction(satisfied, LOOSELY_SATISFIED);
|
|
317
|
+
} else {
|
|
318
|
+
const [subSatisfied, subCoerced] = this.coerceInternal(rootSchema, subSchema, value2);
|
|
319
|
+
coercedItems[key] = subCoerced;
|
|
320
|
+
satisfied = minSatisfaction(satisfied, subSatisfied);
|
|
321
|
+
if (subCoerced !== value2) {
|
|
322
|
+
shouldUseCoercedItems = true;
|
|
323
|
+
}
|
|
316
324
|
}
|
|
317
325
|
}
|
|
318
326
|
}
|
|
319
327
|
if (schema.required?.some((key) => !Object.hasOwn(coercedItems, key))) {
|
|
320
|
-
satisfied =
|
|
328
|
+
satisfied = UNSATISFIED;
|
|
321
329
|
}
|
|
322
330
|
if (shouldUseCoercedItems) {
|
|
323
331
|
coerced = coercedItems;
|
|
324
332
|
}
|
|
325
333
|
} else {
|
|
326
|
-
satisfied =
|
|
334
|
+
satisfied = UNSATISFIED;
|
|
327
335
|
}
|
|
328
336
|
break;
|
|
329
337
|
}
|
|
@@ -336,7 +344,7 @@ class JsonSchemaCoercer {
|
|
|
336
344
|
coerced = stringToDate(coerced);
|
|
337
345
|
}
|
|
338
346
|
if (!(coerced instanceof Date)) {
|
|
339
|
-
satisfied =
|
|
347
|
+
satisfied = UNSATISFIED;
|
|
340
348
|
}
|
|
341
349
|
break;
|
|
342
350
|
}
|
|
@@ -350,7 +358,7 @@ class JsonSchemaCoercer {
|
|
|
350
358
|
break;
|
|
351
359
|
}
|
|
352
360
|
if (typeof coerced !== "bigint") {
|
|
353
|
-
satisfied =
|
|
361
|
+
satisfied = UNSATISFIED;
|
|
354
362
|
}
|
|
355
363
|
break;
|
|
356
364
|
}
|
|
@@ -359,7 +367,7 @@ class JsonSchemaCoercer {
|
|
|
359
367
|
coerced = stringToRegExp(coerced);
|
|
360
368
|
}
|
|
361
369
|
if (!(coerced instanceof RegExp)) {
|
|
362
|
-
satisfied =
|
|
370
|
+
satisfied = UNSATISFIED;
|
|
363
371
|
}
|
|
364
372
|
break;
|
|
365
373
|
}
|
|
@@ -368,7 +376,7 @@ class JsonSchemaCoercer {
|
|
|
368
376
|
coerced = stringToURL(coerced);
|
|
369
377
|
}
|
|
370
378
|
if (!(coerced instanceof URL)) {
|
|
371
|
-
satisfied =
|
|
379
|
+
satisfied = UNSATISFIED;
|
|
372
380
|
}
|
|
373
381
|
break;
|
|
374
382
|
}
|
|
@@ -377,7 +385,7 @@ class JsonSchemaCoercer {
|
|
|
377
385
|
coerced = arrayToSet(coerced);
|
|
378
386
|
}
|
|
379
387
|
if (!(coerced instanceof Set)) {
|
|
380
|
-
satisfied =
|
|
388
|
+
satisfied = UNSATISFIED;
|
|
381
389
|
}
|
|
382
390
|
break;
|
|
383
391
|
}
|
|
@@ -386,7 +394,7 @@ class JsonSchemaCoercer {
|
|
|
386
394
|
coerced = arrayToMap(coerced);
|
|
387
395
|
}
|
|
388
396
|
if (!(coerced instanceof Map)) {
|
|
389
|
-
satisfied =
|
|
397
|
+
satisfied = UNSATISFIED;
|
|
390
398
|
}
|
|
391
399
|
break;
|
|
392
400
|
}
|
|
@@ -394,54 +402,78 @@ class JsonSchemaCoercer {
|
|
|
394
402
|
}
|
|
395
403
|
if (schema.allOf) {
|
|
396
404
|
for (const subSchema of schema.allOf) {
|
|
397
|
-
const [subSatisfied, subCoerced] = this.coerceInternal(rootSchema, subSchema, coerced);
|
|
405
|
+
const [subSatisfied, subCoerced] = this.coerceInternal(rootSchema, subSchema, coerced, appliedRefs);
|
|
398
406
|
coerced = subCoerced;
|
|
399
|
-
|
|
400
|
-
satisfied = false;
|
|
401
|
-
}
|
|
407
|
+
satisfied = minSatisfaction(satisfied, subSatisfied);
|
|
402
408
|
}
|
|
403
409
|
}
|
|
404
410
|
for (const key of ["anyOf", "oneOf"]) {
|
|
405
411
|
if (schema[key]) {
|
|
406
|
-
let
|
|
412
|
+
let best;
|
|
407
413
|
for (const subSchema of schema[key]) {
|
|
408
|
-
const [subSatisfied, subCoerced] = this.coerceInternal(rootSchema, subSchema, coerced);
|
|
409
|
-
if (subSatisfied) {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
}
|
|
414
|
+
const [subSatisfied, subCoerced] = this.coerceInternal(rootSchema, subSchema, coerced, appliedRefs);
|
|
415
|
+
if (subSatisfied === UNSATISFIED) {
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
if (subCoerced === coerced) {
|
|
419
|
+
best = { satisfied: subSatisfied, value: subCoerced };
|
|
420
|
+
break;
|
|
416
421
|
}
|
|
422
|
+
if (!best || subSatisfied > best.satisfied) {
|
|
423
|
+
best = { satisfied: subSatisfied, value: subCoerced };
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (best) {
|
|
427
|
+
coerced = best.value;
|
|
428
|
+
satisfied = minSatisfaction(satisfied, best.satisfied);
|
|
429
|
+
} else {
|
|
430
|
+
satisfied = UNSATISFIED;
|
|
417
431
|
}
|
|
418
|
-
coerced = bestOptions ? bestOptions.coerced : coerced;
|
|
419
|
-
satisfied = bestOptions ? bestOptions.satisfied : false;
|
|
420
432
|
}
|
|
421
433
|
}
|
|
422
434
|
if (typeof schema.not !== "undefined") {
|
|
423
|
-
const [notSatisfied] = this.coerceInternal(rootSchema, schema.not, coerced);
|
|
424
|
-
if (notSatisfied) {
|
|
425
|
-
satisfied =
|
|
435
|
+
const [notSatisfied] = this.coerceInternal(rootSchema, schema.not, coerced, appliedRefs);
|
|
436
|
+
if (notSatisfied !== UNSATISFIED) {
|
|
437
|
+
satisfied = UNSATISFIED;
|
|
426
438
|
}
|
|
427
439
|
}
|
|
428
440
|
return [satisfied, coerced];
|
|
429
441
|
}
|
|
430
442
|
}
|
|
443
|
+
const NUMBER_PATTERN = /^-?(?:0|[1-9]\d*)(?:\.\d+)?$/;
|
|
431
444
|
function stringToNumber(value) {
|
|
432
|
-
|
|
433
|
-
|
|
445
|
+
if (!NUMBER_PATTERN.test(value)) {
|
|
446
|
+
return value;
|
|
447
|
+
}
|
|
448
|
+
const num = Number(value);
|
|
449
|
+
if (num < Number.MIN_SAFE_INTEGER || num > Number.MAX_SAFE_INTEGER) {
|
|
434
450
|
return value;
|
|
435
451
|
}
|
|
436
452
|
return num;
|
|
437
453
|
}
|
|
454
|
+
const INTEGER_PATTERN = /^-?(?:0|[1-9]\d*)$/;
|
|
438
455
|
function stringToInteger(value) {
|
|
439
|
-
|
|
440
|
-
|
|
456
|
+
if (!INTEGER_PATTERN.test(value)) {
|
|
457
|
+
return value;
|
|
458
|
+
}
|
|
459
|
+
const num = Number(value);
|
|
460
|
+
if (!Number.isSafeInteger(num)) {
|
|
441
461
|
return value;
|
|
442
462
|
}
|
|
443
463
|
return num;
|
|
444
464
|
}
|
|
465
|
+
function stringToBigInt(value) {
|
|
466
|
+
if (!INTEGER_PATTERN.test(value)) {
|
|
467
|
+
return value;
|
|
468
|
+
}
|
|
469
|
+
return BigInt(value);
|
|
470
|
+
}
|
|
471
|
+
function numberToBigInt(value) {
|
|
472
|
+
if (!Number.isInteger(value)) {
|
|
473
|
+
return value;
|
|
474
|
+
}
|
|
475
|
+
return BigInt(value);
|
|
476
|
+
}
|
|
445
477
|
function stringToBoolean(value) {
|
|
446
478
|
const lower = value.toLowerCase();
|
|
447
479
|
if (lower === "false" || lower === "off") {
|
|
@@ -452,21 +484,20 @@ function stringToBoolean(value) {
|
|
|
452
484
|
}
|
|
453
485
|
return value;
|
|
454
486
|
}
|
|
455
|
-
|
|
456
|
-
return tryOrUndefined(() => BigInt(value)) ?? value;
|
|
457
|
-
}
|
|
458
|
-
function numberToBigInt(value) {
|
|
459
|
-
return tryOrUndefined(() => BigInt(value)) ?? value;
|
|
460
|
-
}
|
|
487
|
+
const DATE_TIME_PATTERN = /^[+-]?\d{4,6}-\d{1,2}-\d{1,2}(?:[T ].*)?$/;
|
|
461
488
|
function stringToDate(value) {
|
|
489
|
+
if (!DATE_TIME_PATTERN.test(value)) {
|
|
490
|
+
return value;
|
|
491
|
+
}
|
|
462
492
|
const date = new Date(value);
|
|
463
|
-
if (Number.isNaN(date.getTime())
|
|
493
|
+
if (Number.isNaN(date.getTime())) {
|
|
464
494
|
return value;
|
|
465
495
|
}
|
|
466
496
|
return date;
|
|
467
497
|
}
|
|
498
|
+
const REGEXP_PATTERN = /^\/([\s\S]*)\/([a-z]*)$/;
|
|
468
499
|
function stringToRegExp(value) {
|
|
469
|
-
const match = value.match(
|
|
500
|
+
const match = value.match(REGEXP_PATTERN);
|
|
470
501
|
if (match) {
|
|
471
502
|
const [, pattern, flags] = match;
|
|
472
503
|
return tryOrUndefined(() => new RegExp(pattern, flags)) ?? value;
|
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.
|
|
4
|
+
"version": "2.0.0-beta.22",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://orpc.dev",
|
|
7
7
|
"repository": {
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@standard-schema/spec": "^1.1.0",
|
|
29
29
|
"json-schema-typed": "^8.0.2",
|
|
30
|
-
"@orpc/client": "2.0.0-beta.
|
|
31
|
-
"@orpc/
|
|
32
|
-
"@orpc/
|
|
33
|
-
"@orpc/server": "2.0.0-beta.
|
|
30
|
+
"@orpc/client": "2.0.0-beta.22",
|
|
31
|
+
"@orpc/shared": "2.0.0-beta.22",
|
|
32
|
+
"@orpc/contract": "2.0.0-beta.22",
|
|
33
|
+
"@orpc/server": "2.0.0-beta.22"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"zod": "^4.4.3"
|