surreal-zod 0.0.0-alpha.3 → 0.0.0-alpha.6

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.
@@ -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;
@@ -0,0 +1,6 @@
1
+ import type { SurrealZodTableFields } from "./schema";
2
+ import * as core from "zod/v4/core";
3
+
4
+ export const optionalFields = core.util.optionalKeys as (
5
+ fields: SurrealZodTableFields,
6
+ ) => string[];