surreal-zod 0.0.0-alpha.4 → 0.0.0-alpha.7
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/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/surql.d.ts +1 -1
- package/lib/surql.js +17 -19
- package/lib/zod/schema.d.ts +97 -0
- package/lib/zod/schema.js +298 -0
- package/lib/zod/utils.d.ts +2 -0
- package/lib/zod/utils.js +2 -0
- package/package.json +2 -2
- package/src/index.ts +1 -1
- package/src/surql.ts +19 -19
- package/src/zod/schema.ts +669 -0
- package/src/zod/utils.ts +6 -0
- package/src/zod.ts +0 -302
|
@@ -0,0 +1,669 @@
|
|
|
1
|
+
import {
|
|
2
|
+
escapeIdent,
|
|
3
|
+
RecordId,
|
|
4
|
+
Surreal,
|
|
5
|
+
type RecordIdValue,
|
|
6
|
+
type Table,
|
|
7
|
+
} from "surrealdb";
|
|
8
|
+
import z4, { normalize } from "zod/v4";
|
|
9
|
+
import * as core from "zod/v4/core";
|
|
10
|
+
|
|
11
|
+
//////////////////////////////////////////////
|
|
12
|
+
//////////////////////////////////////////////
|
|
13
|
+
////////// //////////
|
|
14
|
+
////////// SurrealZodType //////////
|
|
15
|
+
////////// //////////
|
|
16
|
+
//////////////////////////////////////////////
|
|
17
|
+
//////////////////////////////////////////////
|
|
18
|
+
|
|
19
|
+
export interface SurrealZodTypeDef extends core.$ZodTypeDef {
|
|
20
|
+
surrealType?:
|
|
21
|
+
| "any"
|
|
22
|
+
| "unknown"
|
|
23
|
+
| "boolean"
|
|
24
|
+
| "string"
|
|
25
|
+
| "object"
|
|
26
|
+
| "record_id"
|
|
27
|
+
| "table";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface SurrealZodTypeInternals<out O = unknown, out I = unknown>
|
|
31
|
+
extends core.$ZodTypeInternals<O, I> {
|
|
32
|
+
def: SurrealZodTypeDef;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface SurrealZodType<
|
|
36
|
+
out O = unknown,
|
|
37
|
+
out I = unknown,
|
|
38
|
+
out Internals extends SurrealZodTypeInternals<O, I> = SurrealZodTypeInternals<
|
|
39
|
+
O,
|
|
40
|
+
I
|
|
41
|
+
>,
|
|
42
|
+
> extends core.$ZodType<O, I, Internals> {
|
|
43
|
+
_surreal: {};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface _SurrealZodType<
|
|
47
|
+
Internals extends core.$ZodTypeInternals = core.$ZodTypeInternals,
|
|
48
|
+
> extends SurrealZodType<any, any, Internals> {}
|
|
49
|
+
|
|
50
|
+
export const SurrealZodType: core.$constructor<SurrealZodType> =
|
|
51
|
+
core.$constructor("SurrealZodType", (inst, def) => {
|
|
52
|
+
// @ts-expect-error - unknown assertion error
|
|
53
|
+
core.$ZodType.init(inst, def);
|
|
54
|
+
inst._surreal = {};
|
|
55
|
+
|
|
56
|
+
inst;
|
|
57
|
+
|
|
58
|
+
return inst;
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
/////////////////////////////////////////////
|
|
62
|
+
/////////////////////////////////////////////
|
|
63
|
+
////////// //////////
|
|
64
|
+
////////// SurrealZodAny //////////
|
|
65
|
+
////////// //////////
|
|
66
|
+
/////////////////////////////////////////////
|
|
67
|
+
/////////////////////////////////////////////
|
|
68
|
+
|
|
69
|
+
export interface SurrealZodAny extends _SurrealZodType<core.$ZodAnyInternals> {}
|
|
70
|
+
|
|
71
|
+
export const SurrealZodAny: core.$constructor<SurrealZodAny> =
|
|
72
|
+
core.$constructor("SurrealZodAny", (inst, def) => {
|
|
73
|
+
// @ts-expect-error - unknown assertion error
|
|
74
|
+
core.$ZodAny.init(inst, def);
|
|
75
|
+
SurrealZodType.init(inst, def);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
export function any(): SurrealZodAny {
|
|
79
|
+
return core._any(SurrealZodAny);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/////////////////////////////////////////////////
|
|
83
|
+
/////////////////////////////////////////////////
|
|
84
|
+
////////// //////////
|
|
85
|
+
////////// SurrealZodUnknown //////////
|
|
86
|
+
////////// //////////
|
|
87
|
+
/////////////////////////////////////////////////
|
|
88
|
+
/////////////////////////////////////////////////
|
|
89
|
+
|
|
90
|
+
export interface SurrealZodUnknown
|
|
91
|
+
extends _SurrealZodType<core.$ZodUnknownInternals> {}
|
|
92
|
+
|
|
93
|
+
export const SurrealZodUnknown: core.$constructor<SurrealZodUnknown> =
|
|
94
|
+
core.$constructor("SurrealZodUnknown", (inst, def) => {
|
|
95
|
+
// @ts-expect-error - unknown assertion error
|
|
96
|
+
core.$ZodUnknown.init(inst, def);
|
|
97
|
+
SurrealZodType.init(inst, def);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
export function unknown(): SurrealZodUnknown {
|
|
101
|
+
return core._unknown(SurrealZodUnknown);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
///////////////////////////////////////////////
|
|
105
|
+
///////////////////////////////////////////////
|
|
106
|
+
////////// //////////
|
|
107
|
+
////////// SurrealZodNever //////////
|
|
108
|
+
////////// //////////
|
|
109
|
+
///////////////////////////////////////////////
|
|
110
|
+
///////////////////////////////////////////////
|
|
111
|
+
|
|
112
|
+
export interface SurrealZodNever
|
|
113
|
+
extends _SurrealZodType<core.$ZodNeverInternals> {}
|
|
114
|
+
|
|
115
|
+
export const SurrealZodNever: core.$constructor<SurrealZodNever> =
|
|
116
|
+
core.$constructor("SurrealZodNever", (inst, def) => {
|
|
117
|
+
// @ts-expect-error - unknown assertion error
|
|
118
|
+
core.$ZodNever.init(inst, def);
|
|
119
|
+
SurrealZodType.init(inst, def);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
export function never(params?: string | core.$ZodNeverParams): SurrealZodNever {
|
|
123
|
+
return core._never(SurrealZodNever, params);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/////////////////////////////////////////////////
|
|
127
|
+
/////////////////////////////////////////////////
|
|
128
|
+
////////// //////////
|
|
129
|
+
////////// SurrealZodBoolean //////////
|
|
130
|
+
////////// //////////
|
|
131
|
+
/////////////////////////////////////////////////
|
|
132
|
+
/////////////////////////////////////////////////
|
|
133
|
+
|
|
134
|
+
export interface SurrealZodBoolean
|
|
135
|
+
extends _SurrealZodType<core.$ZodBooleanInternals> {}
|
|
136
|
+
export const SurrealZodBoolean: core.$constructor<SurrealZodBoolean> =
|
|
137
|
+
core.$constructor("SurrealZodBoolean", (inst, def) => {
|
|
138
|
+
// @ts-expect-error - unknown assertion error
|
|
139
|
+
core.$ZodBoolean.init(inst, def);
|
|
140
|
+
SurrealZodType.init(inst, def);
|
|
141
|
+
// const originalDefault = inst.default;
|
|
142
|
+
// inst.default = (defaultValue?: any) => {
|
|
143
|
+
// if (typeof defaultValue === "function") {
|
|
144
|
+
// throw new TypeError(
|
|
145
|
+
// "Functions for default values are not supported in surreal-zod",
|
|
146
|
+
// );
|
|
147
|
+
// }
|
|
148
|
+
// return originalDefault(defaultValue);
|
|
149
|
+
// };
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
export function boolean(
|
|
153
|
+
params?: string | core.$ZodBooleanParams,
|
|
154
|
+
): SurrealZodBoolean {
|
|
155
|
+
return core._boolean(SurrealZodBoolean, params);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
////////////////////////////////////////////////
|
|
159
|
+
////////////////////////////////////////////////
|
|
160
|
+
////////// //////////
|
|
161
|
+
////////// SurrealZodString //////////
|
|
162
|
+
////////// //////////
|
|
163
|
+
////////////////////////////////////////////////
|
|
164
|
+
////////////////////////////////////////////////
|
|
165
|
+
|
|
166
|
+
export interface SurrealZodString
|
|
167
|
+
extends _SurrealZodType<core.$ZodStringInternals<string>> {}
|
|
168
|
+
export const SurrealZodString: core.$constructor<SurrealZodString> =
|
|
169
|
+
core.$constructor("SurrealZodString", (inst, def) => {
|
|
170
|
+
// @ts-expect-error - unknown assertion error
|
|
171
|
+
core.$ZodString.init(inst, def);
|
|
172
|
+
SurrealZodType.init(inst, def);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
export function string(
|
|
176
|
+
params?: string | core.$ZodStringParams,
|
|
177
|
+
): SurrealZodString {
|
|
178
|
+
return core._string(SurrealZodString, params);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
////////////////////////////////////////////////
|
|
182
|
+
////////////////////////////////////////////////
|
|
183
|
+
////////// //////////
|
|
184
|
+
////////// SurrealZodObject //////////
|
|
185
|
+
////////// //////////
|
|
186
|
+
////////////////////////////////////////////////
|
|
187
|
+
////////////////////////////////////////////////
|
|
188
|
+
|
|
189
|
+
export interface SurrealZodObject<
|
|
190
|
+
// @ts-expect-error - unknown assertion error
|
|
191
|
+
out Shape extends core.$ZodShape = core.$ZodLooseShape,
|
|
192
|
+
out Config extends core.$ZodObjectConfig = core.$strip,
|
|
193
|
+
> extends _SurrealZodType<core.$ZodObjectInternals<Shape, Config>>,
|
|
194
|
+
core.$ZodObject<Shape, Config> {}
|
|
195
|
+
|
|
196
|
+
export const SurrealZodObject: core.$constructor<SurrealZodObject> =
|
|
197
|
+
core.$constructor("SurrealZodObject", (inst, def) => {
|
|
198
|
+
// TODO: Inline implementation and use core instead
|
|
199
|
+
// @ts-expect-error - unknown assertion error
|
|
200
|
+
z4.ZodObject.init(inst, def);
|
|
201
|
+
SurrealZodType.init(inst, def);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
export function object<
|
|
205
|
+
T extends core.$ZodLooseShape = Partial<Record<never, core.SomeType>>,
|
|
206
|
+
>(
|
|
207
|
+
shape?: T,
|
|
208
|
+
params?: string | core.$ZodObjectParams,
|
|
209
|
+
): SurrealZodObject<core.util.Writeable<T>, core.$strip> {
|
|
210
|
+
const def: core.$ZodObjectDef = {
|
|
211
|
+
type: "object",
|
|
212
|
+
shape: shape ?? {},
|
|
213
|
+
...core.util.normalizeParams(params),
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
return new SurrealZodObject(def) as any;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
//////////////////////////////////////////////////
|
|
220
|
+
//////////////////////////////////////////////////
|
|
221
|
+
////////// //////////
|
|
222
|
+
////////// SurrealZodRecordId //////////
|
|
223
|
+
////////// //////////
|
|
224
|
+
//////////////////////////////////////////////////
|
|
225
|
+
//////////////////////////////////////////////////
|
|
226
|
+
|
|
227
|
+
export type SurrealZodRecordIdValue =
|
|
228
|
+
| core.$ZodAny
|
|
229
|
+
| core.$ZodUnknown
|
|
230
|
+
| core.$ZodString
|
|
231
|
+
| core.$ZodNumber
|
|
232
|
+
| core.$ZodObject
|
|
233
|
+
| core.$ZodArray;
|
|
234
|
+
// | core.$ZodObject;
|
|
235
|
+
|
|
236
|
+
export interface SurrealZodRecordIdDef<
|
|
237
|
+
Table extends string = string,
|
|
238
|
+
Id extends SurrealZodRecordIdValue = SurrealZodRecordIdValue,
|
|
239
|
+
> extends SurrealZodTypeDef {
|
|
240
|
+
surrealType: "record_id";
|
|
241
|
+
innerType: Id;
|
|
242
|
+
table?: Table[];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export type SurrealZodRecordIdValueOutput<T> = T extends {
|
|
246
|
+
_zod: {
|
|
247
|
+
output: any;
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
? T["_zod"]["output"]
|
|
251
|
+
: RecordIdValue;
|
|
252
|
+
|
|
253
|
+
export interface SurrealZodRecordIdInternals<
|
|
254
|
+
Table extends string = string,
|
|
255
|
+
Id extends SurrealZodRecordIdValue = SurrealZodRecordIdValue,
|
|
256
|
+
> extends SurrealZodTypeInternals<
|
|
257
|
+
RecordId<Table, SurrealZodRecordIdValueOutput<Id>>,
|
|
258
|
+
RecordIdValue
|
|
259
|
+
> {
|
|
260
|
+
def: SurrealZodRecordIdDef<Table, Id>;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export interface SurrealZodRecordId<
|
|
264
|
+
Table extends string = string,
|
|
265
|
+
Id extends SurrealZodRecordIdValue = SurrealZodRecordIdValue,
|
|
266
|
+
> extends _SurrealZodType<SurrealZodRecordIdInternals<Table, Id>> {
|
|
267
|
+
table<NewTable extends string | string[]>(
|
|
268
|
+
table: NewTable,
|
|
269
|
+
): SurrealZodRecordId<
|
|
270
|
+
NewTable extends string ? NewTable : NewTable[number],
|
|
271
|
+
Id
|
|
272
|
+
>;
|
|
273
|
+
|
|
274
|
+
type<NewType extends SurrealZodRecordIdValue>(
|
|
275
|
+
innerType: NewType,
|
|
276
|
+
): SurrealZodRecordId<Table, NewType>;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export const SurrealZodRecordId: core.$constructor<SurrealZodRecordId> =
|
|
280
|
+
core.$constructor("SurrealZodRecordId", (inst, def) => {
|
|
281
|
+
SurrealZodType.init(inst, def);
|
|
282
|
+
inst._surreal = true;
|
|
283
|
+
|
|
284
|
+
inst.table = (table) => {
|
|
285
|
+
return new SurrealZodRecordId({
|
|
286
|
+
...def,
|
|
287
|
+
table: Array.isArray(table) ? table : [table],
|
|
288
|
+
}) as any;
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
inst.type = (innerType) => {
|
|
292
|
+
return new SurrealZodRecordId({
|
|
293
|
+
...def,
|
|
294
|
+
innerType,
|
|
295
|
+
}) as any;
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
inst._zod.parse = (payload, ctx) => {
|
|
299
|
+
if (payload.value instanceof RecordId) {
|
|
300
|
+
if (def.table && !def.table.includes(payload.value.table.name)) {
|
|
301
|
+
payload.issues.push({
|
|
302
|
+
code: "invalid_value",
|
|
303
|
+
values: def.table,
|
|
304
|
+
input: payload.value.table.name,
|
|
305
|
+
message:
|
|
306
|
+
def.table.length > 1
|
|
307
|
+
? `Expected RecordId's table to be one of ${def.table.map(escapeIdent).join(" | ")} but found ${payload.value.table.name}`
|
|
308
|
+
: `Expected RecordId's table to be ${def.table[0]} but found ${payload.value.table.name}`,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (def.innerType) {
|
|
313
|
+
const schema = def.innerType._zod;
|
|
314
|
+
const result = schema.run(
|
|
315
|
+
{ value: payload.value.id, issues: [] },
|
|
316
|
+
ctx,
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
if (result instanceof Promise) {
|
|
320
|
+
return result.then((result) => {
|
|
321
|
+
if (result.issues.length) {
|
|
322
|
+
payload.issues.push(
|
|
323
|
+
...core.util.prefixIssues("id", result.issues),
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
payload.value = new RecordId(
|
|
327
|
+
payload.value.table.name,
|
|
328
|
+
result.value as any,
|
|
329
|
+
);
|
|
330
|
+
return payload;
|
|
331
|
+
});
|
|
332
|
+
} else if (result.issues.length) {
|
|
333
|
+
payload.issues.push(...core.util.prefixIssues("id", result.issues));
|
|
334
|
+
}
|
|
335
|
+
payload.value = new RecordId(
|
|
336
|
+
payload.value.table.name,
|
|
337
|
+
result.value as any,
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
} else {
|
|
341
|
+
payload.issues.push({
|
|
342
|
+
code: "invalid_type",
|
|
343
|
+
// TODO: Surreal specific issues
|
|
344
|
+
expected: "custom",
|
|
345
|
+
input: payload.value,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return payload;
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
return inst;
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
export function recordId<const W extends string | string[]>(
|
|
356
|
+
what?: W,
|
|
357
|
+
innerType?: SurrealZodRecordIdValue,
|
|
358
|
+
): SurrealZodRecordId<W extends string ? W : W[number]> {
|
|
359
|
+
return new SurrealZodRecordId({
|
|
360
|
+
// Zod would not be happy if we have a custom type here, so we use any
|
|
361
|
+
type: "any",
|
|
362
|
+
surrealType: "record_id",
|
|
363
|
+
table: what ? (Array.isArray(what) ? what : [what]) : undefined,
|
|
364
|
+
innerType: innerType ?? any(),
|
|
365
|
+
}) as any;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
///////////////////////////////////////////////
|
|
369
|
+
///////////////////////////////////////////////
|
|
370
|
+
////////// //////////
|
|
371
|
+
////////// SurrealZodTable //////////
|
|
372
|
+
////////// //////////
|
|
373
|
+
///////////////////////////////////////////////
|
|
374
|
+
///////////////////////////////////////////////
|
|
375
|
+
|
|
376
|
+
export type SurrealZodTableFields = {
|
|
377
|
+
readonly [key: string]: SurrealZodType;
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Normalizes the fields of a table schema to include the id field if it is not present.
|
|
382
|
+
* If the id field is present, it will be normalized using the table name and the inner type.
|
|
383
|
+
*/
|
|
384
|
+
export type NormalizedFields<
|
|
385
|
+
Name extends string = string,
|
|
386
|
+
Fields extends SurrealZodTableFields = SurrealZodTableFields,
|
|
387
|
+
> = Fields extends {
|
|
388
|
+
id: SurrealZodType;
|
|
389
|
+
}
|
|
390
|
+
? Fields["id"] extends SurrealZodRecordId<infer _N, infer T>
|
|
391
|
+
? Omit<Fields, "id"> & {
|
|
392
|
+
id: SurrealZodRecordId<Name, T>;
|
|
393
|
+
}
|
|
394
|
+
: Fields["id"] extends SurrealZodRecordIdValue
|
|
395
|
+
? Omit<Fields, "id"> & {
|
|
396
|
+
id: SurrealZodRecordId<Name, Fields["id"]>;
|
|
397
|
+
}
|
|
398
|
+
: Omit<Fields, "id"> & {
|
|
399
|
+
id: SurrealZodRecordId<Name>;
|
|
400
|
+
}
|
|
401
|
+
: Fields & {
|
|
402
|
+
id: SurrealZodRecordId<Name>;
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
export interface SurrealZodTableDef<
|
|
406
|
+
Name extends string = string,
|
|
407
|
+
Fields extends SurrealZodTableFields = SurrealZodTableFields,
|
|
408
|
+
> extends SurrealZodTypeDef {
|
|
409
|
+
surrealType: "table";
|
|
410
|
+
name: Name;
|
|
411
|
+
fields: NormalizedFields<Name, Fields>;
|
|
412
|
+
comment?: string;
|
|
413
|
+
catchall?: SurrealZodType;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
export interface SurrealZodTableInternals<
|
|
417
|
+
Name extends string = string,
|
|
418
|
+
Fields extends SurrealZodTableFields = SurrealZodTableFields,
|
|
419
|
+
> extends SurrealZodTypeInternals {
|
|
420
|
+
def: SurrealZodTableDef<Name, Fields>;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
export interface SurrealZodTable<
|
|
424
|
+
out Name extends string = string,
|
|
425
|
+
out Fields extends SurrealZodTableFields = SurrealZodTableFields,
|
|
426
|
+
> extends _SurrealZodType<SurrealZodTableInternals<Name, Fields>> {
|
|
427
|
+
name<NewName extends string>(name: NewName): SurrealZodTable<NewName, Fields>;
|
|
428
|
+
fields<NewFields extends SurrealZodTableFields>(
|
|
429
|
+
fields: NewFields,
|
|
430
|
+
): SurrealZodTable<Name, NewFields>;
|
|
431
|
+
comment(comment: string): this;
|
|
432
|
+
schemafull(): this;
|
|
433
|
+
schemaless(): this;
|
|
434
|
+
record(): this["_zod"]["def"]["fields"]["id"];
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function handleFieldResult(
|
|
438
|
+
result: core.ParsePayload,
|
|
439
|
+
final: core.ParsePayload,
|
|
440
|
+
field: PropertyKey,
|
|
441
|
+
input: Record<PropertyKey, unknown>,
|
|
442
|
+
) {
|
|
443
|
+
if (result.issues.length) {
|
|
444
|
+
final.issues.push(...core.util.prefixIssues(field, result.issues));
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (result.value === undefined) {
|
|
448
|
+
if (field in input) {
|
|
449
|
+
// @ts-expect-error: field not index-checked on final.value
|
|
450
|
+
final.value[field] = undefined;
|
|
451
|
+
}
|
|
452
|
+
} else {
|
|
453
|
+
// @ts-expect-error: field not index-checked on final.value
|
|
454
|
+
final.value[field] = result.value;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function handleCatchall(
|
|
459
|
+
promises: Promise<any>[],
|
|
460
|
+
input: Record<PropertyKey, unknown>,
|
|
461
|
+
payload: core.ParsePayload,
|
|
462
|
+
ctx: core.ParseContext,
|
|
463
|
+
def: ReturnType<typeof normalizeTableDef>,
|
|
464
|
+
inst: SurrealZodTable,
|
|
465
|
+
) {
|
|
466
|
+
const unrecognized: string[] = [];
|
|
467
|
+
const known = def.fieldNamesSet;
|
|
468
|
+
// biome-ignore lint/style/noNonNullAssertion: already asserted
|
|
469
|
+
const _catchall = def.catchall!._zod;
|
|
470
|
+
const type = _catchall.def.type;
|
|
471
|
+
for (const field in input) {
|
|
472
|
+
if (known.has(field)) continue;
|
|
473
|
+
if (type === "never") {
|
|
474
|
+
unrecognized.push(field);
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const result = _catchall.run({ value: input[field], issues: [] }, ctx);
|
|
479
|
+
if (result instanceof Promise) {
|
|
480
|
+
promises.push(
|
|
481
|
+
result.then((result) =>
|
|
482
|
+
handleFieldResult(result, payload, field, input),
|
|
483
|
+
),
|
|
484
|
+
);
|
|
485
|
+
} else {
|
|
486
|
+
handleFieldResult(result, payload, field, input);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
if (unrecognized.length) {
|
|
491
|
+
payload.issues.push({
|
|
492
|
+
code: "unrecognized_keys",
|
|
493
|
+
keys: unrecognized,
|
|
494
|
+
input,
|
|
495
|
+
inst,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
if (!promises.length) return payload;
|
|
500
|
+
return Promise.all(promises).then(() => payload);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function normalizeTableDef(def: SurrealZodTableDef) {
|
|
504
|
+
const fields = Object.keys(def.fields);
|
|
505
|
+
for (const field of fields) {
|
|
506
|
+
if (!def.fields[field]?._zod.traits.has("SurrealZodType")) {
|
|
507
|
+
throw new Error(
|
|
508
|
+
`Invalid field definition for "${field}": expected a Surreal Zod schema`,
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
if (def.fields.id) {
|
|
514
|
+
if (def.fields.id instanceof SurrealZodRecordId) {
|
|
515
|
+
def.fields.id = def.fields.id.table(def.name);
|
|
516
|
+
} else {
|
|
517
|
+
def.fields.id = recordId(def.name).type(def.fields.id);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
return {
|
|
522
|
+
...def,
|
|
523
|
+
fields: def.fields,
|
|
524
|
+
fieldNames: fields,
|
|
525
|
+
fieldNamesSet: new Set(fields),
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
export const SurrealZodTable: core.$constructor<SurrealZodTable> =
|
|
530
|
+
core.$constructor("SurrealZodTable", (inst, def) => {
|
|
531
|
+
SurrealZodType.init(inst, def);
|
|
532
|
+
|
|
533
|
+
const normalized = core.util.cached(() => normalizeTableDef(def));
|
|
534
|
+
const catchall = def.catchall;
|
|
535
|
+
let value: typeof normalized.value;
|
|
536
|
+
|
|
537
|
+
inst.name = (name) => {
|
|
538
|
+
return new SurrealZodTable({
|
|
539
|
+
...def,
|
|
540
|
+
name,
|
|
541
|
+
// biome-ignore lint/suspicious/noExplicitAny: false-positive
|
|
542
|
+
}) as any;
|
|
543
|
+
};
|
|
544
|
+
inst.fields = (fields) => {
|
|
545
|
+
return new SurrealZodTable({
|
|
546
|
+
...def,
|
|
547
|
+
fields: {
|
|
548
|
+
id: recordId(def.name),
|
|
549
|
+
...fields,
|
|
550
|
+
},
|
|
551
|
+
// biome-ignore lint/suspicious/noExplicitAny: false-positive
|
|
552
|
+
}) as any;
|
|
553
|
+
};
|
|
554
|
+
inst.comment = (comment) => {
|
|
555
|
+
return new SurrealZodTable({
|
|
556
|
+
...def,
|
|
557
|
+
comment,
|
|
558
|
+
});
|
|
559
|
+
};
|
|
560
|
+
inst.schemafull = () => {
|
|
561
|
+
return new SurrealZodTable({
|
|
562
|
+
...def,
|
|
563
|
+
catchall: never(),
|
|
564
|
+
});
|
|
565
|
+
};
|
|
566
|
+
inst.schemaless = () => {
|
|
567
|
+
return new SurrealZodTable({
|
|
568
|
+
...def,
|
|
569
|
+
catchall: unknown(),
|
|
570
|
+
});
|
|
571
|
+
};
|
|
572
|
+
inst.record = () => normalized.value.fields.id;
|
|
573
|
+
|
|
574
|
+
inst._zod.parse = (payload, ctx) => {
|
|
575
|
+
value ??= normalized.value;
|
|
576
|
+
const input = payload.value;
|
|
577
|
+
|
|
578
|
+
if (!core.util.isObject(input)) {
|
|
579
|
+
payload.issues.push({
|
|
580
|
+
expected: "object",
|
|
581
|
+
code: "invalid_type",
|
|
582
|
+
input,
|
|
583
|
+
inst,
|
|
584
|
+
});
|
|
585
|
+
return payload;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
payload.value = {};
|
|
589
|
+
const promises: Promise<any>[] = [];
|
|
590
|
+
const fields = value.fields;
|
|
591
|
+
|
|
592
|
+
for (const field of value.fieldNames) {
|
|
593
|
+
// biome-ignore lint/style/noNonNullAssertion: bounds already checked
|
|
594
|
+
const schema = fields[field]!;
|
|
595
|
+
const result = schema._zod.run(
|
|
596
|
+
{ value: input[field], issues: [] },
|
|
597
|
+
ctx,
|
|
598
|
+
);
|
|
599
|
+
if (result instanceof Promise) {
|
|
600
|
+
promises.push(
|
|
601
|
+
result.then((result) => {
|
|
602
|
+
handleFieldResult(result, payload, field, input);
|
|
603
|
+
}),
|
|
604
|
+
);
|
|
605
|
+
} else {
|
|
606
|
+
handleFieldResult(result, payload, field, input);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
if (!catchall) {
|
|
611
|
+
return promises.length
|
|
612
|
+
? Promise.all(promises).then(() => payload)
|
|
613
|
+
: payload;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
return handleCatchall(
|
|
617
|
+
promises,
|
|
618
|
+
input,
|
|
619
|
+
payload,
|
|
620
|
+
ctx,
|
|
621
|
+
normalized.value,
|
|
622
|
+
inst,
|
|
623
|
+
);
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
return inst;
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
export function table<Name extends string = string>(name: Name) {
|
|
630
|
+
return new SurrealZodTable({
|
|
631
|
+
type: "any",
|
|
632
|
+
surrealType: "table",
|
|
633
|
+
name,
|
|
634
|
+
fields: {
|
|
635
|
+
id: recordId(name),
|
|
636
|
+
},
|
|
637
|
+
catchall: unknown(),
|
|
638
|
+
}) as SurrealZodTable<Name>;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// export interface $SurrealZodRecordIdDef extends $ZodTypeDef {
|
|
642
|
+
// type: "recordId";
|
|
643
|
+
// }
|
|
644
|
+
|
|
645
|
+
// export interface _SurrealZodRecordId extends z4._$ZodType {}
|
|
646
|
+
|
|
647
|
+
// /** @internal */
|
|
648
|
+
// export const _SurrealZodRecordId: z4.$constructor<_SurrealZodRecordId> =
|
|
649
|
+
// // z4.$constructor("SurrealZodRecordId", (inst, def) => {});
|
|
650
|
+
// export interface $SurrealZodRecordIdInternals extends $ZodTypeInternals {}
|
|
651
|
+
|
|
652
|
+
// export interface $SurrealZodRecordId<
|
|
653
|
+
// T extends string = string,
|
|
654
|
+
// V extends RecordIdValue = RecordIdValue,
|
|
655
|
+
// > extends $ZodType {
|
|
656
|
+
// _zod: $SurrealZodRecordIdInternals;
|
|
657
|
+
// }
|
|
658
|
+
// // export const recordId = <S extends z4.$ZodType>(schema: S) => {};
|
|
659
|
+
|
|
660
|
+
// export type $SurrealZodTypes = $ZodString | $ZodNumber | $ZodObject;
|
|
661
|
+
// export type $SurrealZodTypeName = $SurrealZodTypes["_zod"]["def"]["type"];
|
|
662
|
+
|
|
663
|
+
export type SurrealZodTypes =
|
|
664
|
+
| SurrealZodAny
|
|
665
|
+
| SurrealZodBoolean
|
|
666
|
+
| SurrealZodString
|
|
667
|
+
| SurrealZodObject
|
|
668
|
+
| SurrealZodRecordId
|
|
669
|
+
| SurrealZodTable;
|