zero-swift 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2230 @@
1
+ // src/drift.ts
2
+ import { pathToFileURL } from "node:url";
3
+ import {
4
+ createBuilder,
5
+ defineMutator,
6
+ defineMutators,
7
+ isMutator,
8
+ isQuery,
9
+ mustGetMutator,
10
+ mustGetQuery,
11
+ Zero
12
+ } from "@rocicorp/zero";
13
+
14
+ // ../shared/src/map.ts
15
+ function hasNative(name) {
16
+ return typeof Map.prototype[name] === "function" && typeof WeakMap.prototype[name] === "function";
17
+ }
18
+ function getOrInsertPolyfill(map, key, defaultValue) {
19
+ const existing = map.get(key);
20
+ if (existing !== void 0) {
21
+ return existing;
22
+ }
23
+ map.set(key, defaultValue);
24
+ return defaultValue;
25
+ }
26
+ function getOrInsertComputedPolyfill(map, key, compute) {
27
+ const existing = map.get(key);
28
+ if (existing !== void 0) {
29
+ return existing;
30
+ }
31
+ const value = compute(key);
32
+ map.set(key, value);
33
+ return value;
34
+ }
35
+ function getOrInsertNative(map, key, defaultValue) {
36
+ return map.getOrInsert(key, defaultValue);
37
+ }
38
+ function getOrInsertComputedNative(map, key, compute) {
39
+ return map.getOrInsertComputed(key, compute);
40
+ }
41
+ var getOrInsert = hasNative("getOrInsert") ? getOrInsertNative : getOrInsertPolyfill;
42
+ var getOrInsertComputed = hasNative("getOrInsertComputed") ? getOrInsertComputedNative : getOrInsertComputedPolyfill;
43
+
44
+ // ../../node_modules/.pnpm/compare-utf8@0.2.3/node_modules/compare-utf8/src/index.js
45
+ var surrogateRe = /[\uD800-\uDFFF]/;
46
+ var BISECT_MIN_LENGTH = 64;
47
+ function compareSlow(a, b) {
48
+ const aLength = a.length;
49
+ const bLength = b.length;
50
+ const length = aLength > bLength ? bLength : aLength;
51
+ let i = 0;
52
+ if (length >= BISECT_MIN_LENGTH) {
53
+ let lo = 0;
54
+ let hi = length;
55
+ while (lo < hi) {
56
+ const mid = lo + hi + 1 >>> 1;
57
+ if (a.slice(0, mid) === b.slice(0, mid)) {
58
+ lo = mid;
59
+ } else {
60
+ hi = mid - 1;
61
+ }
62
+ }
63
+ i = lo;
64
+ }
65
+ for (; i < length; i++) {
66
+ const ac = a.charCodeAt(i);
67
+ const bc = b.charCodeAt(i);
68
+ if (ac !== bc) {
69
+ if (i > 0) {
70
+ const prev = a.charCodeAt(i - 1);
71
+ if (prev >= 55296 && prev <= 56319) {
72
+ const d = (
73
+ /** @type {number} */
74
+ a.codePointAt(i - 1) - /** @type {number} */
75
+ b.codePointAt(i - 1)
76
+ );
77
+ if (d !== 0) return d;
78
+ }
79
+ }
80
+ if ((ac < 55296 || ac > 57343) && (bc < 55296 || bc > 57343)) {
81
+ return ac - bc;
82
+ }
83
+ return (
84
+ /** @type {number} */
85
+ a.codePointAt(i) - /** @type {number} */
86
+ b.codePointAt(i)
87
+ );
88
+ }
89
+ }
90
+ return aLength - bLength;
91
+ }
92
+ function compareUTF8(a, b) {
93
+ if (a === b) return 0;
94
+ if (a < b) {
95
+ return surrogateRe.test(a) ? compareSlow(a, b) : -1;
96
+ }
97
+ return surrogateRe.test(b) ? compareSlow(a, b) : 1;
98
+ }
99
+
100
+ // ../shared/src/asserts.ts
101
+ function assert(b, msg) {
102
+ if (!b) {
103
+ throw new Error(typeof msg === "string" ? msg : msg());
104
+ }
105
+ }
106
+ function unreachable(_) {
107
+ throw new Error("Unreachable");
108
+ }
109
+
110
+ // ../shared/src/deep-merge.ts
111
+ function isPlainObject(value) {
112
+ return typeof value === "object" && value !== null;
113
+ }
114
+
115
+ // ../shared/src/must.ts
116
+ function must(v, msg) {
117
+ if (v == null) {
118
+ throw new Error(msg ?? `Unexpected ${v} value`);
119
+ }
120
+ return v;
121
+ }
122
+
123
+ // ../../node_modules/.pnpm/@badrap+valita@0.5.5/node_modules/@badrap/valita/dist/index.js
124
+ function customError(error) {
125
+ return {
126
+ ok: false,
127
+ code: "custom_error",
128
+ path: typeof error === "object" ? error.path : void 0,
129
+ message: typeof error === "string" ? error : error?.message ?? "validation failed",
130
+ error
131
+ };
132
+ }
133
+ function expectedType(expected) {
134
+ return {
135
+ ok: false,
136
+ code: "invalid_type",
137
+ message: `expected ${separatedList(expected, "or")}`,
138
+ expected
139
+ };
140
+ }
141
+ function expectedLiteral(literals) {
142
+ return {
143
+ ok: false,
144
+ code: "invalid_literal",
145
+ message: `expected ${separatedList(literals.map(formatLiteral), "or")}`,
146
+ expected: literals
147
+ };
148
+ }
149
+ var UnrecognizedKeysIssue = class {
150
+ ok = false;
151
+ code = "unrecognized_keys";
152
+ keys;
153
+ constructor(keys) {
154
+ this.keys = keys;
155
+ }
156
+ get message() {
157
+ const keys = this.keys;
158
+ if (keys.length === 1) {
159
+ return `unrecognized key ${formatLiteral(keys[0])}`;
160
+ } else if (keys.length < 8) {
161
+ return `unrecognized keys ${separatedList(keys.map(formatLiteral), "and")}`;
162
+ } else {
163
+ return `unrecognized keys ${keys.map(formatLiteral).join(",")} and ${keys.length - 6} others`;
164
+ }
165
+ }
166
+ };
167
+ function unrecognizedKeys(keys) {
168
+ return new UnrecognizedKeysIssue(keys);
169
+ }
170
+ function invalidUnion(tree) {
171
+ return {
172
+ ok: false,
173
+ code: "invalid_union",
174
+ message: "validation failed",
175
+ tree
176
+ };
177
+ }
178
+ var ISSUE_EXPECTED_NOTHING = expectedType([]);
179
+ var ISSUE_EXPECTED_STRING = expectedType(["string"]);
180
+ var ISSUE_EXPECTED_NUMBER = expectedType(["number"]);
181
+ var ISSUE_EXPECTED_BIGINT = expectedType(["bigint"]);
182
+ var ISSUE_EXPECTED_BOOLEAN = expectedType(["boolean"]);
183
+ var ISSUE_EXPECTED_UNDEFINED = expectedType(["undefined"]);
184
+ var ISSUE_EXPECTED_NULL = expectedType(["null"]);
185
+ var ISSUE_EXPECTED_OBJECT = expectedType(["object"]);
186
+ var ISSUE_EXPECTED_ARRAY = expectedType(["array"]);
187
+ var ISSUE_MISSING_VALUE = {
188
+ ok: false,
189
+ code: "missing_value",
190
+ message: "missing value"
191
+ };
192
+ function joinIssues(left, right) {
193
+ return left ? { ok: false, code: "join", left, right } : right;
194
+ }
195
+ function prependPath(key, tree) {
196
+ return { ok: false, code: "prepend", key, tree };
197
+ }
198
+ function cloneIssueWithPath(tree, path2) {
199
+ const code = tree.code;
200
+ switch (code) {
201
+ case "invalid_type":
202
+ return {
203
+ path: path2,
204
+ message: tree.message,
205
+ code,
206
+ expected: tree.expected
207
+ };
208
+ case "invalid_literal":
209
+ return {
210
+ path: path2,
211
+ message: tree.message,
212
+ code,
213
+ expected: tree.expected
214
+ };
215
+ case "missing_value":
216
+ return {
217
+ path: path2,
218
+ message: tree.message,
219
+ code
220
+ };
221
+ case "invalid_length": {
222
+ return {
223
+ path: path2,
224
+ message: tree.message,
225
+ code,
226
+ minLength: tree.minLength,
227
+ maxLength: tree.maxLength
228
+ };
229
+ }
230
+ case "unrecognized_keys": {
231
+ return {
232
+ path: path2,
233
+ message: tree.message,
234
+ code,
235
+ keys: tree.keys
236
+ };
237
+ }
238
+ case "invalid_union":
239
+ return {
240
+ code,
241
+ path: path2,
242
+ message: tree.message,
243
+ issues: collectIssues(tree.tree)
244
+ };
245
+ case "custom_error":
246
+ if (tree.path !== void 0) {
247
+ path2.push(...tree.path);
248
+ }
249
+ return {
250
+ path: path2,
251
+ message: tree.message,
252
+ code
253
+ };
254
+ }
255
+ }
256
+ function collectIssues(tree, path2 = [], issues = []) {
257
+ for (; ; ) {
258
+ if (tree.code === "join") {
259
+ collectIssues(tree.left, path2.slice(), issues);
260
+ tree = tree.right;
261
+ } else if (tree.code === "prepend") {
262
+ path2.push(tree.key);
263
+ tree = tree.tree;
264
+ } else {
265
+ issues.push(cloneIssueWithPath(tree, path2));
266
+ return issues;
267
+ }
268
+ }
269
+ }
270
+ function separatedList(list, sep) {
271
+ if (list.length === 0) {
272
+ return "nothing";
273
+ } else if (list.length === 1) {
274
+ return list[0];
275
+ } else {
276
+ return `${list.slice(0, -1).join(", ")} ${sep} ${list[list.length - 1]}`;
277
+ }
278
+ }
279
+ function formatLiteral(value) {
280
+ return typeof value === "bigint" ? `${value}n` : JSON.stringify(value);
281
+ }
282
+ function countIssues(tree) {
283
+ let count = 0;
284
+ for (; ; ) {
285
+ if (tree.code === "join") {
286
+ count += countIssues(tree.left);
287
+ tree = tree.right;
288
+ } else if (tree.code === "prepend") {
289
+ tree = tree.tree;
290
+ } else {
291
+ return count + 1;
292
+ }
293
+ }
294
+ }
295
+ function formatIssueTree(tree) {
296
+ let path2 = "";
297
+ let count = 0;
298
+ for (; ; ) {
299
+ if (tree.code === "join") {
300
+ count += countIssues(tree.right);
301
+ tree = tree.left;
302
+ } else if (tree.code === "prepend") {
303
+ path2 += `.${tree.key}`;
304
+ tree = tree.tree;
305
+ } else {
306
+ break;
307
+ }
308
+ }
309
+ if (tree.code === "custom_error" && tree.path) {
310
+ path2 += "." + tree.path.join(".");
311
+ }
312
+ let msg = `${tree.code} at ${path2 || "."} (${tree.message})`;
313
+ if (count === 1) {
314
+ msg += ` (+ 1 other issue)`;
315
+ } else if (count > 1) {
316
+ msg += ` (+ ${count} other issues)`;
317
+ }
318
+ return msg;
319
+ }
320
+ var ValitaError = class extends Error {
321
+ #issueTree;
322
+ #issues;
323
+ #message;
324
+ constructor(issueTree) {
325
+ super();
326
+ this.#issueTree = issueTree;
327
+ }
328
+ get issues() {
329
+ return this.#issues ??= collectIssues(this.#issueTree);
330
+ }
331
+ get message() {
332
+ return this.#message ??= formatIssueTree(this.#issueTree);
333
+ }
334
+ };
335
+ ValitaError.prototype.name = "ValitaError";
336
+ var OkImpl = class {
337
+ ok = true;
338
+ value;
339
+ static {
340
+ this.prototype.issues = void 0;
341
+ }
342
+ constructor(value) {
343
+ this.value = value;
344
+ }
345
+ };
346
+ var ErrImpl = class {
347
+ ok = false;
348
+ /** @internal */
349
+ _issueTree;
350
+ #message;
351
+ #issues;
352
+ constructor(issueTree) {
353
+ this._issueTree = issueTree;
354
+ }
355
+ get issues() {
356
+ return this.#issues ??= collectIssues(this._issueTree);
357
+ }
358
+ get message() {
359
+ return this.#message ??= formatIssueTree(this._issueTree);
360
+ }
361
+ throw() {
362
+ throw new ValitaError(this._issueTree);
363
+ }
364
+ };
365
+ function ok(value) {
366
+ return new OkImpl(value);
367
+ }
368
+ function err(error) {
369
+ return new ErrImpl(customError(error));
370
+ }
371
+ function isObject(v) {
372
+ return typeof v === "object" && v !== null && !Array.isArray(v);
373
+ }
374
+ var FLAG_FORBID_EXTRA_KEYS = 1 << 0;
375
+ var FLAG_STRIP_EXTRA_KEYS = 1 << 1;
376
+ var FLAG_MISSING_VALUE = 1 << 2;
377
+ var TAG_UNKNOWN = 0;
378
+ var TAG_NEVER = 1;
379
+ var TAG_STRING = 2;
380
+ var TAG_NUMBER = 3;
381
+ var TAG_BIGINT = 4;
382
+ var TAG_BOOLEAN = 5;
383
+ var TAG_NULL = 6;
384
+ var TAG_UNDEFINED = 7;
385
+ var TAG_LITERAL = 8;
386
+ var TAG_OPTIONAL = 9;
387
+ var TAG_OBJECT = 10;
388
+ var TAG_ARRAY = 11;
389
+ var TAG_UNION = 12;
390
+ var TAG_SIMPLE_UNION = 13;
391
+ var TAG_TRANSFORM = 14;
392
+ var TAG_OTHER = 15;
393
+ var taggedMatcher = (tag, match) => {
394
+ return { tag, match };
395
+ };
396
+ function callMatcher(matcher, value, flags) {
397
+ switch (matcher.tag) {
398
+ case TAG_UNKNOWN:
399
+ return void 0;
400
+ case TAG_NEVER:
401
+ return ISSUE_EXPECTED_NOTHING;
402
+ case TAG_STRING:
403
+ return typeof value === "string" ? void 0 : ISSUE_EXPECTED_STRING;
404
+ case TAG_NUMBER:
405
+ return typeof value === "number" ? void 0 : ISSUE_EXPECTED_NUMBER;
406
+ case TAG_BIGINT:
407
+ return typeof value === "bigint" ? void 0 : ISSUE_EXPECTED_BIGINT;
408
+ case TAG_BOOLEAN:
409
+ return typeof value === "boolean" ? void 0 : ISSUE_EXPECTED_BOOLEAN;
410
+ case TAG_NULL:
411
+ return value === null ? void 0 : ISSUE_EXPECTED_NULL;
412
+ case TAG_UNDEFINED:
413
+ return value === void 0 ? void 0 : ISSUE_EXPECTED_UNDEFINED;
414
+ case TAG_LITERAL:
415
+ return matcher.match(value, flags);
416
+ case TAG_OPTIONAL:
417
+ return matcher.match(value, flags);
418
+ case TAG_OBJECT:
419
+ return matcher.match(value, flags);
420
+ case TAG_ARRAY:
421
+ return matcher.match(value, flags);
422
+ case TAG_UNION:
423
+ return matcher.match(value, flags);
424
+ case TAG_SIMPLE_UNION:
425
+ return matcher.match(value, flags);
426
+ case TAG_TRANSFORM:
427
+ return matcher.match(value, flags);
428
+ default:
429
+ return matcher.match(value, flags);
430
+ }
431
+ }
432
+ var MATCHER_SYMBOL = /* @__PURE__ */ Symbol.for("@valita/internal");
433
+ var AbstractType = class {
434
+ #standard;
435
+ get "~standard"() {
436
+ return this.#standard ??= {
437
+ version: 1,
438
+ vendor: "@badrap/valita",
439
+ validate: (value, options) => {
440
+ return this.try(value, options?.libraryOptions);
441
+ }
442
+ };
443
+ }
444
+ /**
445
+ * Parse a value without throwing.
446
+ */
447
+ try(v, options) {
448
+ const r = callMatcher(this[MATCHER_SYMBOL], v, options === void 0 ? FLAG_FORBID_EXTRA_KEYS : options.mode === "strip" ? FLAG_STRIP_EXTRA_KEYS : options.mode === "passthrough" ? 0 : FLAG_FORBID_EXTRA_KEYS);
449
+ return r === void 0 || r.ok ? new OkImpl(r === void 0 ? v : r.value) : new ErrImpl(r);
450
+ }
451
+ /**
452
+ * Parse a value. Throw a ValitaError on failure.
453
+ */
454
+ parse(v, options) {
455
+ const r = callMatcher(this[MATCHER_SYMBOL], v, options === void 0 ? FLAG_FORBID_EXTRA_KEYS : options.mode === "strip" ? FLAG_STRIP_EXTRA_KEYS : options.mode === "passthrough" ? 0 : FLAG_FORBID_EXTRA_KEYS);
456
+ if (r === void 0 || r.ok) {
457
+ return r === void 0 ? v : r.value;
458
+ }
459
+ throw new ValitaError(r);
460
+ }
461
+ /**
462
+ * Derive a new validator that uses the provided predicate function to
463
+ * perform custom validation for the source validator's output values.
464
+ *
465
+ * The predicate function should return `true` when the source
466
+ * type's output value is valid, `false` otherwise. The checked value
467
+ * itself won't get modified or replaced, and is returned as-is on
468
+ * validation success.
469
+ *
470
+ * @example A validator that accepts only numeric strings.
471
+ * ```ts
472
+ * const numericString = v.string().assert((s) => /^\d+$/.test(s))
473
+ * numericString.parse("1");
474
+ * // "1"
475
+ * numericString.parse("foo");
476
+ * // ValitaError: custom_error at . (validation failed)
477
+ * ```
478
+ *
479
+ * You can also _refine_ the output type by passing in a
480
+ * [type predicate](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates).
481
+ * Note that the type predicate must have a compatible input type.
482
+ *
483
+ * @example A validator with its output type refined to `Date`.
484
+ * ```ts
485
+ * const dateType = v.unknown().assert((v): v is Date => v instanceof Date);
486
+ * ```
487
+ *
488
+ * You can also pass in a custom failure messages.
489
+ *
490
+ * @example A validator that rejects non-integers with a custom error.
491
+ * ```ts
492
+ * const integer = v.number().assert((n) => Number.isInteger(n), "not an integer");
493
+ * integer.parse(1);
494
+ * // 1
495
+ * integer.parse(1.5);
496
+ * // ValitaError: custom_error at . (not an integer)
497
+ * ```
498
+ *
499
+ * @param func - The assertion predicate function.
500
+ * @param [error] - A custom error for situations when the assertion
501
+ * predicate returns `false`.
502
+ */
503
+ assert(func, error) {
504
+ const err2 = customError(error);
505
+ return new TransformType(this, (v, flags) => func(v, flagsToOptions(flags)) ? void 0 : err2);
506
+ }
507
+ map(func) {
508
+ return new TransformType(this, (v, flags) => ({
509
+ ok: true,
510
+ value: func(v, flagsToOptions(flags))
511
+ }));
512
+ }
513
+ chain(input) {
514
+ if (typeof input === "function") {
515
+ return new TransformType(this, (v, flags) => {
516
+ const r = input(v, flagsToOptions(flags));
517
+ return r.ok ? r : r._issueTree;
518
+ });
519
+ }
520
+ return new TransformType(this, (v, flags) => callMatcher(input[MATCHER_SYMBOL], v, flags));
521
+ }
522
+ /**
523
+ * Apply a function to this type and return its result.
524
+ *
525
+ * The function is called immediately with this type as its argument.
526
+ *
527
+ * Useful for applying reusable type modifiers.
528
+ *
529
+ * @example
530
+ * ```ts
531
+ * function nullish<T extends Type>() {
532
+ * return t.nullable().optional();
533
+ * }
534
+ *
535
+ * const strings = v.string().as(nullish);
536
+ * ```
537
+ *
538
+ * @param func - The function to apply to this type.
539
+ * @returns The function's result.
540
+ */
541
+ as(func) {
542
+ return func(this);
543
+ }
544
+ };
545
+ var Type = class extends AbstractType {
546
+ optional(defaultFn) {
547
+ const optional = new Optional(this);
548
+ if (!defaultFn) {
549
+ return optional;
550
+ }
551
+ return new TransformType(optional, (v) => {
552
+ return v === void 0 ? { ok: true, value: defaultFn() } : void 0;
553
+ });
554
+ }
555
+ nullable(defaultFn) {
556
+ const nullable = new SimpleUnion([null_(), this]);
557
+ if (!defaultFn) {
558
+ return nullable;
559
+ }
560
+ return new TransformType(nullable, (v) => {
561
+ return v === null ? { ok: true, value: defaultFn() } : void 0;
562
+ });
563
+ }
564
+ _toTerminals(func) {
565
+ func(this);
566
+ }
567
+ };
568
+ var SimpleUnion = class extends Type {
569
+ name = "union";
570
+ options;
571
+ #matcher;
572
+ constructor(options) {
573
+ super();
574
+ this.options = options;
575
+ }
576
+ get [MATCHER_SYMBOL]() {
577
+ if (this.#matcher !== void 0) {
578
+ return this.#matcher;
579
+ }
580
+ const options = this.options.map((o) => o[MATCHER_SYMBOL]);
581
+ return this.#matcher ??= taggedMatcher(TAG_SIMPLE_UNION, (v, flags) => {
582
+ let issue = ISSUE_EXPECTED_NOTHING;
583
+ for (const option of options) {
584
+ const result = callMatcher(option, v, flags);
585
+ if (result === void 0 || result.ok) {
586
+ return result;
587
+ }
588
+ issue = result;
589
+ }
590
+ return issue;
591
+ });
592
+ }
593
+ _toTerminals(func) {
594
+ for (const option of this.options) {
595
+ option._toTerminals(func);
596
+ }
597
+ }
598
+ };
599
+ var Optional = class extends AbstractType {
600
+ name = "optional";
601
+ type;
602
+ #matcher;
603
+ constructor(type) {
604
+ super();
605
+ this.type = type;
606
+ }
607
+ optional(defaultFn) {
608
+ if (!defaultFn) {
609
+ return this;
610
+ }
611
+ return new TransformType(this, (v) => {
612
+ return v === void 0 ? { ok: true, value: defaultFn() } : void 0;
613
+ });
614
+ }
615
+ get [MATCHER_SYMBOL]() {
616
+ if (this.#matcher !== void 0) {
617
+ return this.#matcher;
618
+ }
619
+ const matcher = this.type[MATCHER_SYMBOL];
620
+ return this.#matcher = taggedMatcher(TAG_OPTIONAL, (v, flags) => v === void 0 || flags & FLAG_MISSING_VALUE ? void 0 : callMatcher(matcher, v, flags));
621
+ }
622
+ _toTerminals(func) {
623
+ func(this);
624
+ func(undefined_());
625
+ this.type._toTerminals(func);
626
+ }
627
+ };
628
+ function setBit(bits, index) {
629
+ if (typeof bits !== "number") {
630
+ const idx = index >> 5;
631
+ for (let i = bits.length; i <= idx; i++) {
632
+ bits.push(0);
633
+ }
634
+ bits[idx] |= 1 << index % 32;
635
+ return bits;
636
+ } else if (index < 32) {
637
+ return bits | 1 << index;
638
+ } else {
639
+ return setBit([bits, 0], index);
640
+ }
641
+ }
642
+ function getBit(bits, index) {
643
+ if (typeof bits === "number") {
644
+ return index < 32 ? bits >>> index & 1 : 0;
645
+ } else {
646
+ return bits[index >> 5] >>> index % 32 & 1;
647
+ }
648
+ }
649
+ var ObjectType = class _ObjectType extends Type {
650
+ name = "object";
651
+ shape;
652
+ restType;
653
+ #matcher;
654
+ constructor(shape, restType) {
655
+ super();
656
+ this.shape = shape;
657
+ this.restType = restType;
658
+ }
659
+ get [MATCHER_SYMBOL]() {
660
+ if (this.#matcher !== void 0) {
661
+ return this.#matcher;
662
+ }
663
+ const func = createObjectMatcher(this.shape, this.restType);
664
+ return this.#matcher = taggedMatcher(TAG_OBJECT, (v, flags) => isObject(v) ? func(v, flags) : ISSUE_EXPECTED_OBJECT);
665
+ }
666
+ rest(restType) {
667
+ return new _ObjectType(this.shape, restType);
668
+ }
669
+ extend(shape) {
670
+ return new _ObjectType({ ...this.shape, ...shape }, this.restType);
671
+ }
672
+ pick(...keys) {
673
+ const shape = {};
674
+ for (const key of keys) {
675
+ set(shape, key, this.shape[key]);
676
+ }
677
+ return new _ObjectType(shape, void 0);
678
+ }
679
+ omit(...keys) {
680
+ const shape = { ...this.shape };
681
+ for (const key of keys) {
682
+ delete shape[key];
683
+ }
684
+ return new _ObjectType(shape, this.restType);
685
+ }
686
+ partial() {
687
+ const shape = {};
688
+ for (const key of Object.keys(this.shape)) {
689
+ set(shape, key, this.shape[key].optional());
690
+ }
691
+ const rest = this.restType?.optional();
692
+ return new _ObjectType(shape, rest);
693
+ }
694
+ };
695
+ function set(obj, key, value) {
696
+ if (key === "__proto__") {
697
+ Object.defineProperty(obj, key, {
698
+ value,
699
+ writable: true,
700
+ enumerable: true,
701
+ configurable: true
702
+ });
703
+ } else {
704
+ obj[key] = value;
705
+ }
706
+ }
707
+ function createObjectMatcher(shape, rest) {
708
+ const indexedEntries = Object.keys(shape).map((key, index) => {
709
+ const type = shape[key];
710
+ let optional = false;
711
+ type._toTerminals((t) => {
712
+ optional ||= t.name === "optional";
713
+ });
714
+ return {
715
+ key,
716
+ index,
717
+ matcher: type[MATCHER_SYMBOL],
718
+ optional,
719
+ missing: prependPath(key, ISSUE_MISSING_VALUE)
720
+ };
721
+ });
722
+ const keyedEntries = /* @__PURE__ */ Object.create(null);
723
+ for (const entry of indexedEntries) {
724
+ keyedEntries[entry.key] = entry;
725
+ }
726
+ const restMatcher = rest?.[MATCHER_SYMBOL];
727
+ const clone = (obj, enumeratedBits, indexedBits) => {
728
+ const output = {};
729
+ if (restMatcher === void 0) {
730
+ for (let m = 0; m < indexedEntries.length; m++) {
731
+ if (getBit(enumeratedBits, m) || getBit(indexedBits, m)) {
732
+ const k = indexedEntries[m].key;
733
+ set(output, k, obj[k]);
734
+ }
735
+ }
736
+ return output;
737
+ }
738
+ for (const k in obj) {
739
+ set(output, k, obj[k]);
740
+ }
741
+ if (indexedBits) {
742
+ for (let m = 0; m < indexedEntries.length; m++) {
743
+ if (getBit(indexedBits, m)) {
744
+ const k = indexedEntries[m].key;
745
+ set(output, k, obj[k]);
746
+ }
747
+ }
748
+ }
749
+ return output;
750
+ };
751
+ const fastPath = indexedEntries.length === 0 && rest?.name === "unknown";
752
+ return (obj, flags) => {
753
+ if (fastPath) {
754
+ return void 0;
755
+ }
756
+ let output = void 0;
757
+ let issues = void 0;
758
+ let unrecognized = void 0;
759
+ let enumeratedBits = 0;
760
+ let indexedBits = 0;
761
+ let seenCount = 0;
762
+ if (flags & (FLAG_FORBID_EXTRA_KEYS | FLAG_STRIP_EXTRA_KEYS) || restMatcher !== void 0) {
763
+ for (const key in obj) {
764
+ const value = obj[key];
765
+ const entry = keyedEntries[key];
766
+ if (entry === void 0 && restMatcher === void 0) {
767
+ if (flags & FLAG_FORBID_EXTRA_KEYS) {
768
+ if (unrecognized === void 0) {
769
+ unrecognized = [key];
770
+ } else {
771
+ unrecognized.push(key);
772
+ }
773
+ } else if (flags & FLAG_STRIP_EXTRA_KEYS && issues === void 0 && output === void 0) {
774
+ output = clone(obj, enumeratedBits, indexedBits);
775
+ }
776
+ continue;
777
+ }
778
+ const r = entry === void 0 ? callMatcher(restMatcher, value, flags) : callMatcher(entry.matcher, value, flags);
779
+ if (r === void 0) {
780
+ if (output !== void 0 && issues === void 0) {
781
+ set(output, key, value);
782
+ }
783
+ } else if (!r.ok) {
784
+ issues = joinIssues(issues, prependPath(key, r));
785
+ } else if (issues === void 0) {
786
+ output ??= clone(obj, enumeratedBits, indexedBits);
787
+ set(output, key, r.value);
788
+ }
789
+ if (entry !== void 0) {
790
+ seenCount++;
791
+ enumeratedBits = setBit(enumeratedBits, entry.index);
792
+ }
793
+ }
794
+ }
795
+ if (seenCount < indexedEntries.length) {
796
+ for (let i = 0; i < indexedEntries.length; i++) {
797
+ if (getBit(enumeratedBits, i)) {
798
+ continue;
799
+ }
800
+ const entry = indexedEntries[i];
801
+ const value = obj[entry.key];
802
+ let extraFlags = 0;
803
+ if (value === void 0 && !(entry.key in obj)) {
804
+ if (!entry.optional) {
805
+ issues = joinIssues(issues, entry.missing);
806
+ continue;
807
+ }
808
+ extraFlags = FLAG_MISSING_VALUE;
809
+ }
810
+ const r = callMatcher(entry.matcher, value, flags | extraFlags);
811
+ if (r === void 0) {
812
+ if (output !== void 0 && issues === void 0 && !extraFlags) {
813
+ set(output, entry.key, value);
814
+ }
815
+ } else if (!r.ok) {
816
+ issues = joinIssues(issues, prependPath(entry.key, r));
817
+ } else if (issues === void 0) {
818
+ output ??= clone(obj, enumeratedBits, indexedBits);
819
+ set(output, entry.key, r.value);
820
+ }
821
+ if (extraFlags === 0) {
822
+ indexedBits = setBit(indexedBits, i);
823
+ }
824
+ }
825
+ }
826
+ if (unrecognized !== void 0) {
827
+ return joinIssues(issues, unrecognizedKeys(unrecognized));
828
+ } else if (issues !== void 0) {
829
+ return issues;
830
+ } else {
831
+ return output && { ok: true, value: output };
832
+ }
833
+ };
834
+ }
835
+ var ArrayOrTupleType = class _ArrayOrTupleType extends Type {
836
+ name = "array";
837
+ prefix;
838
+ restType;
839
+ suffix;
840
+ #matcher;
841
+ constructor(prefix, rest, suffix) {
842
+ super();
843
+ this.prefix = prefix;
844
+ this.restType = rest;
845
+ this.suffix = suffix;
846
+ }
847
+ get [MATCHER_SYMBOL]() {
848
+ if (this.#matcher !== void 0) {
849
+ return this.#matcher;
850
+ }
851
+ const prefix = this.prefix.map((t) => t[MATCHER_SYMBOL]);
852
+ const suffix = this.suffix.map((t) => t[MATCHER_SYMBOL]);
853
+ const rest = this.restType?.[MATCHER_SYMBOL] ?? taggedMatcher(1, () => ISSUE_MISSING_VALUE);
854
+ const minLength = prefix.length + suffix.length;
855
+ const maxLength = this.restType ? Infinity : minLength;
856
+ let message = `expected an array`;
857
+ if (minLength > 0) {
858
+ if (maxLength === minLength) {
859
+ message += `with ${minLength === 1 ? "item" : "items"}`;
860
+ } else if (maxLength < Infinity) {
861
+ message += `with between ${minLength} and ${maxLength} items`;
862
+ } else {
863
+ message += `with at least ${minLength === 1 ? "item" : "items"}`;
864
+ }
865
+ } else if (maxLength < Infinity) {
866
+ message += `with at most ${maxLength === 1 ? "item" : "items"}`;
867
+ }
868
+ const invalidLength = {
869
+ ok: false,
870
+ code: "invalid_length",
871
+ message,
872
+ minLength,
873
+ maxLength: maxLength === Infinity ? void 0 : maxLength
874
+ };
875
+ return this.#matcher = taggedMatcher(TAG_ARRAY, (arr, flags) => {
876
+ if (!Array.isArray(arr)) {
877
+ return ISSUE_EXPECTED_ARRAY;
878
+ }
879
+ const length = arr.length;
880
+ if (length < minLength || length > maxLength) {
881
+ return invalidLength;
882
+ }
883
+ const headEnd = prefix.length;
884
+ const tailStart = arr.length - suffix.length;
885
+ let issueTree = void 0;
886
+ let output = arr;
887
+ for (let i = 0; i < arr.length; i++) {
888
+ const entry = i < headEnd ? prefix[i] : i >= tailStart ? suffix[i - tailStart] : rest;
889
+ const r = callMatcher(entry, arr[i], flags);
890
+ if (r !== void 0) {
891
+ if (r.ok) {
892
+ if (output === arr) {
893
+ output = arr.slice();
894
+ }
895
+ output[i] = r.value;
896
+ } else {
897
+ issueTree = joinIssues(issueTree, prependPath(i, r));
898
+ }
899
+ }
900
+ }
901
+ if (issueTree) {
902
+ return issueTree;
903
+ } else if (arr === output) {
904
+ return void 0;
905
+ } else {
906
+ return { ok: true, value: output };
907
+ }
908
+ });
909
+ }
910
+ concat(type) {
911
+ if (this.restType) {
912
+ if (type.restType) {
913
+ throw new TypeError("can not concatenate two variadic types");
914
+ }
915
+ return new _ArrayOrTupleType(this.prefix, this.restType, [
916
+ ...this.suffix,
917
+ ...type.prefix,
918
+ ...type.suffix
919
+ ]);
920
+ } else if (type.restType) {
921
+ return new _ArrayOrTupleType([...this.prefix, ...this.suffix, ...type.prefix], type.restType, type.suffix);
922
+ } else {
923
+ return new _ArrayOrTupleType([...this.prefix, ...this.suffix, ...type.prefix, ...type.suffix], type.restType, type.suffix);
924
+ }
925
+ }
926
+ };
927
+ function toInputType(v) {
928
+ const type = typeof v;
929
+ if (type !== "object") {
930
+ return type;
931
+ } else if (v === null) {
932
+ return "null";
933
+ } else if (Array.isArray(v)) {
934
+ return "array";
935
+ } else {
936
+ return type;
937
+ }
938
+ }
939
+ function dedup(arr) {
940
+ return [...new Set(arr)];
941
+ }
942
+ function groupTerminals(terminals) {
943
+ const order = /* @__PURE__ */ new Map();
944
+ const literals = /* @__PURE__ */ new Map();
945
+ const types = /* @__PURE__ */ new Map();
946
+ const unknowns = [];
947
+ const optionals = [];
948
+ const expectedTypes = [];
949
+ for (const { root, terminal } of terminals) {
950
+ order.set(root, order.get(root) ?? order.size);
951
+ if (terminal.name === "never") {
952
+ } else if (terminal.name === "optional") {
953
+ optionals.push(root);
954
+ } else if (terminal.name === "unknown") {
955
+ unknowns.push(root);
956
+ } else if (terminal.name === "literal") {
957
+ const roots = literals.get(terminal.value) ?? [];
958
+ roots.push(root);
959
+ literals.set(terminal.value, roots);
960
+ expectedTypes.push(toInputType(terminal.value));
961
+ } else {
962
+ const roots = types.get(terminal.name) ?? [];
963
+ roots.push(root);
964
+ types.set(terminal.name, roots);
965
+ expectedTypes.push(terminal.name);
966
+ }
967
+ }
968
+ const byOrder = (a, b) => {
969
+ return (order.get(a) ?? 0) - (order.get(b) ?? 0);
970
+ };
971
+ for (const [value, roots] of literals) {
972
+ const options = types.get(toInputType(value));
973
+ if (options) {
974
+ options.push(...roots);
975
+ literals.delete(value);
976
+ } else {
977
+ literals.set(value, dedup(roots.concat(unknowns)).sort(byOrder));
978
+ }
979
+ }
980
+ for (const [type, roots] of types) {
981
+ types.set(type, dedup(roots.concat(unknowns)).sort(byOrder));
982
+ }
983
+ return {
984
+ types,
985
+ literals,
986
+ unknowns: dedup(unknowns).sort(byOrder),
987
+ optionals: dedup(optionals).sort(byOrder),
988
+ expectedTypes: dedup(expectedTypes)
989
+ };
990
+ }
991
+ function createObjectKeyMatcher(objects, key) {
992
+ const list = [];
993
+ for (const { root, terminal } of objects) {
994
+ terminal.shape[key]._toTerminals((t) => {
995
+ list.push({ root, terminal: t });
996
+ });
997
+ }
998
+ const { types, literals, optionals, unknowns, expectedTypes } = groupTerminals(list);
999
+ if (unknowns.length > 0 || optionals.length > 1) {
1000
+ return void 0;
1001
+ }
1002
+ for (const roots of literals.values()) {
1003
+ if (roots.length > 1) {
1004
+ return void 0;
1005
+ }
1006
+ }
1007
+ for (const roots of types.values()) {
1008
+ if (roots.length > 1) {
1009
+ return void 0;
1010
+ }
1011
+ }
1012
+ const missingValue = prependPath(key, ISSUE_MISSING_VALUE);
1013
+ const issue = prependPath(key, types.size === 0 ? expectedLiteral([...literals.keys()]) : expectedType(expectedTypes));
1014
+ const byLiteral = literals.size > 0 ? /* @__PURE__ */ new Map() : void 0;
1015
+ if (byLiteral) {
1016
+ for (const [literal2, options] of literals) {
1017
+ byLiteral.set(literal2, options[0][MATCHER_SYMBOL]);
1018
+ }
1019
+ }
1020
+ const byType = types.size > 0 ? {} : void 0;
1021
+ if (byType) {
1022
+ for (const [type, options] of types) {
1023
+ byType[type] = options[0][MATCHER_SYMBOL];
1024
+ }
1025
+ }
1026
+ const optional = optionals[0]?.[MATCHER_SYMBOL];
1027
+ return (obj, flags) => {
1028
+ const value = obj[key];
1029
+ if (value === void 0 && !(key in obj)) {
1030
+ return optional === void 0 ? missingValue : callMatcher(optional, obj, flags);
1031
+ }
1032
+ const option = byType?.[toInputType(value)] ?? byLiteral?.get(value);
1033
+ return option ? callMatcher(option, obj, flags) : issue;
1034
+ };
1035
+ }
1036
+ function createUnionObjectMatcher(terminals) {
1037
+ const objects = [];
1038
+ const keyCounts = /* @__PURE__ */ new Map();
1039
+ for (const { root, terminal } of terminals) {
1040
+ if (terminal.name === "unknown") {
1041
+ return void 0;
1042
+ }
1043
+ if (terminal.name === "object") {
1044
+ for (const key in terminal.shape) {
1045
+ keyCounts.set(key, (keyCounts.get(key) ?? 0) + 1);
1046
+ }
1047
+ objects.push({ root, terminal });
1048
+ }
1049
+ }
1050
+ if (objects.length < 2) {
1051
+ return void 0;
1052
+ }
1053
+ for (const [key, count] of keyCounts) {
1054
+ if (count === objects.length) {
1055
+ const matcher = createObjectKeyMatcher(objects, key);
1056
+ if (matcher) {
1057
+ return matcher;
1058
+ }
1059
+ }
1060
+ }
1061
+ return void 0;
1062
+ }
1063
+ function createUnionBaseMatcher(terminals) {
1064
+ const { expectedTypes, literals, types, unknowns, optionals } = groupTerminals(terminals);
1065
+ const issue = types.size === 0 && unknowns.length === 0 ? expectedLiteral([...literals.keys()]) : expectedType(expectedTypes);
1066
+ const byLiteral = literals.size > 0 ? /* @__PURE__ */ new Map() : void 0;
1067
+ if (byLiteral) {
1068
+ for (const [literal2, options] of literals) {
1069
+ byLiteral.set(literal2, options.map((t) => t[MATCHER_SYMBOL]));
1070
+ }
1071
+ }
1072
+ const byType = types.size > 0 ? {} : void 0;
1073
+ if (byType) {
1074
+ for (const [type, options] of types) {
1075
+ byType[type] = options.map((t) => t[MATCHER_SYMBOL]);
1076
+ }
1077
+ }
1078
+ const optionalMatchers = optionals.map((t) => t[MATCHER_SYMBOL]);
1079
+ const unknownMatchers = unknowns.map((t) => t[MATCHER_SYMBOL]);
1080
+ return (value, flags) => {
1081
+ const options = flags & FLAG_MISSING_VALUE ? optionalMatchers : byType?.[toInputType(value)] ?? byLiteral?.get(value) ?? unknownMatchers;
1082
+ let count = 0;
1083
+ let issueTree = issue;
1084
+ for (let i = 0; i < options.length; i++) {
1085
+ const r = callMatcher(options[i], value, flags);
1086
+ if (r === void 0 || r.ok) {
1087
+ return r;
1088
+ }
1089
+ issueTree = count > 0 ? joinIssues(issueTree, r) : r;
1090
+ count++;
1091
+ }
1092
+ if (count > 1) {
1093
+ return invalidUnion(issueTree);
1094
+ }
1095
+ return issueTree;
1096
+ };
1097
+ }
1098
+ var UnionType = class extends Type {
1099
+ name = "union";
1100
+ options;
1101
+ #matcher;
1102
+ constructor(options) {
1103
+ super();
1104
+ this.options = options;
1105
+ }
1106
+ _toTerminals(func) {
1107
+ for (const option of this.options) {
1108
+ option._toTerminals(func);
1109
+ }
1110
+ }
1111
+ get [MATCHER_SYMBOL]() {
1112
+ if (this.#matcher !== void 0) {
1113
+ return this.#matcher;
1114
+ }
1115
+ const flattened = [];
1116
+ for (const option of this.options) {
1117
+ option._toTerminals((terminal) => {
1118
+ flattened.push({ root: option, terminal });
1119
+ });
1120
+ }
1121
+ const base = createUnionBaseMatcher(flattened);
1122
+ const object2 = createUnionObjectMatcher(flattened);
1123
+ return this.#matcher = taggedMatcher(TAG_UNION, (v, f) => object2 !== void 0 && isObject(v) ? object2(v, f) : base(v, f));
1124
+ }
1125
+ };
1126
+ var STRICT = Object.freeze({ mode: "strict" });
1127
+ var STRIP = Object.freeze({ mode: "strip" });
1128
+ var PASSTHROUGH = Object.freeze({ mode: "passthrough" });
1129
+ function flagsToOptions(flags) {
1130
+ return flags & FLAG_FORBID_EXTRA_KEYS ? STRICT : flags & FLAG_STRIP_EXTRA_KEYS ? STRIP : PASSTHROUGH;
1131
+ }
1132
+ var TransformType = class _TransformType extends Type {
1133
+ name = "transform";
1134
+ #transformed;
1135
+ #transform;
1136
+ #matcher;
1137
+ constructor(transformed, transform) {
1138
+ super();
1139
+ this.#transformed = transformed;
1140
+ this.#transform = transform;
1141
+ }
1142
+ get [MATCHER_SYMBOL]() {
1143
+ if (this.#matcher !== void 0) {
1144
+ return this.#matcher;
1145
+ }
1146
+ const chain = [];
1147
+ let next = this;
1148
+ while (next instanceof _TransformType) {
1149
+ chain.push(next.#transform);
1150
+ next = next.#transformed;
1151
+ }
1152
+ chain.reverse();
1153
+ const matcher = next[MATCHER_SYMBOL];
1154
+ const undef = ok(void 0);
1155
+ return this.#matcher = taggedMatcher(TAG_TRANSFORM, (v, flags) => {
1156
+ let result = callMatcher(matcher, v, flags);
1157
+ if (result !== void 0 && !result.ok) {
1158
+ return result;
1159
+ }
1160
+ let current;
1161
+ if (result !== void 0) {
1162
+ current = result.value;
1163
+ } else if (flags & FLAG_MISSING_VALUE) {
1164
+ current = void 0;
1165
+ result = undef;
1166
+ } else {
1167
+ current = v;
1168
+ }
1169
+ for (let i = 0; i < chain.length; i++) {
1170
+ const r = chain[i](current, flags);
1171
+ if (r !== void 0) {
1172
+ if (!r.ok) {
1173
+ return r;
1174
+ }
1175
+ current = r.value;
1176
+ result = r;
1177
+ }
1178
+ }
1179
+ return result;
1180
+ });
1181
+ }
1182
+ _toTerminals(func) {
1183
+ this.#transformed._toTerminals(func);
1184
+ }
1185
+ };
1186
+ var LazyType = class extends Type {
1187
+ name = "lazy";
1188
+ #definer;
1189
+ #type;
1190
+ #matcher;
1191
+ #recursing = false;
1192
+ constructor(definer) {
1193
+ super();
1194
+ this.#definer = definer;
1195
+ }
1196
+ get type() {
1197
+ return this.#type ??= this.#definer();
1198
+ }
1199
+ get [MATCHER_SYMBOL]() {
1200
+ if (this.#matcher !== void 0) {
1201
+ return this.#matcher;
1202
+ }
1203
+ const matcher = taggedMatcher(TAG_OTHER, (value, flags) => {
1204
+ const typeMatcher = this.type[MATCHER_SYMBOL];
1205
+ matcher.tag = typeMatcher.tag;
1206
+ matcher.match = typeMatcher.match;
1207
+ this.#matcher = typeMatcher;
1208
+ return callMatcher(typeMatcher, value, flags);
1209
+ });
1210
+ return this.#matcher = matcher;
1211
+ }
1212
+ _toTerminals(func) {
1213
+ if (!this.#recursing) {
1214
+ this.#recursing = true;
1215
+ try {
1216
+ this.type._toTerminals(func);
1217
+ } finally {
1218
+ this.#recursing = false;
1219
+ }
1220
+ }
1221
+ }
1222
+ };
1223
+ function singleton(name, tag, match) {
1224
+ const matcher = taggedMatcher(tag, match);
1225
+ class SimpleType extends Type {
1226
+ name;
1227
+ constructor() {
1228
+ super();
1229
+ this.name = name;
1230
+ }
1231
+ get [MATCHER_SYMBOL]() {
1232
+ return matcher;
1233
+ }
1234
+ }
1235
+ const instance = new SimpleType();
1236
+ return /* @__NO_SIDE_EFFECTS__ */ () => instance;
1237
+ }
1238
+ var unknown = /* @__PURE__ */ singleton("unknown", TAG_UNKNOWN, () => void 0);
1239
+ var string = /* @__PURE__ */ singleton("string", TAG_STRING, (v) => typeof v === "string" ? void 0 : ISSUE_EXPECTED_STRING);
1240
+ var number = /* @__PURE__ */ singleton("number", TAG_NUMBER, (v) => typeof v === "number" ? void 0 : ISSUE_EXPECTED_NUMBER);
1241
+ var boolean = /* @__PURE__ */ singleton("boolean", TAG_BOOLEAN, (v) => typeof v === "boolean" ? void 0 : ISSUE_EXPECTED_BOOLEAN);
1242
+ var null_ = /* @__PURE__ */ singleton("null", TAG_NULL, (v) => v === null ? void 0 : ISSUE_EXPECTED_NULL);
1243
+ var undefined_ = /* @__PURE__ */ singleton("undefined", TAG_UNDEFINED, (v) => v === void 0 ? void 0 : ISSUE_EXPECTED_UNDEFINED);
1244
+ var LiteralType = class extends Type {
1245
+ name = "literal";
1246
+ value;
1247
+ #matcher;
1248
+ constructor(value) {
1249
+ super();
1250
+ this.value = value;
1251
+ }
1252
+ get [MATCHER_SYMBOL]() {
1253
+ if (this.#matcher !== void 0) {
1254
+ return this.#matcher;
1255
+ }
1256
+ const value = this.value;
1257
+ const issue = expectedLiteral([value]);
1258
+ return this.#matcher ??= taggedMatcher(TAG_LITERAL, (v) => v === value ? void 0 : issue);
1259
+ }
1260
+ };
1261
+ var literal = (value) => {
1262
+ return /* @__PURE__ */ new LiteralType(value);
1263
+ };
1264
+ var object = (obj) => {
1265
+ return /* @__PURE__ */ new ObjectType(obj, void 0);
1266
+ };
1267
+ var record = (valueType) => {
1268
+ return /* @__PURE__ */ new ObjectType({}, valueType ?? unknown());
1269
+ };
1270
+ var array = (item) => {
1271
+ return /* @__PURE__ */ new ArrayOrTupleType([], item ?? unknown(), []);
1272
+ };
1273
+ var tuple = (items) => {
1274
+ return /* @__PURE__ */ new ArrayOrTupleType(items, void 0, []);
1275
+ };
1276
+ var union = (...options) => {
1277
+ return /* @__PURE__ */ new UnionType(options);
1278
+ };
1279
+ var lazy = (definer) => {
1280
+ return new LazyType(definer);
1281
+ };
1282
+
1283
+ // ../shared/src/valita.ts
1284
+ var STRICT2 = { mode: "strict" };
1285
+ function strict(schema) {
1286
+ const type = unknown().chain((value) => schema.try(value, STRICT2));
1287
+ return Object.assign(type, { strict: schema });
1288
+ }
1289
+ function readonly(t) {
1290
+ return t;
1291
+ }
1292
+ function readonlyObject(t) {
1293
+ return object(t);
1294
+ }
1295
+ function readonlyArray(t) {
1296
+ return array(t);
1297
+ }
1298
+ function readonlyRecord(t) {
1299
+ return record(t);
1300
+ }
1301
+ var AbstractType2 = Object.getPrototypeOf(
1302
+ Object.getPrototypeOf(string().optional())
1303
+ ).constructor;
1304
+ function literalUnion(...literals) {
1305
+ return union(...literals.map(literal));
1306
+ }
1307
+
1308
+ // ../shared/src/config.ts
1309
+ var isProd = process.env.NODE_ENV === "production";
1310
+
1311
+ // ../shared/src/has-own.ts
1312
+ var { hasOwn } = Object;
1313
+
1314
+ // ../shared/src/json.ts
1315
+ function isJSONValue(v, path2) {
1316
+ switch (typeof v) {
1317
+ case "boolean":
1318
+ case "number":
1319
+ case "string":
1320
+ return true;
1321
+ case "object":
1322
+ if (v === null) {
1323
+ return true;
1324
+ }
1325
+ if (Array.isArray(v)) {
1326
+ return isJSONArray(v, path2);
1327
+ }
1328
+ return objectIsJSONObject(v, path2);
1329
+ }
1330
+ return false;
1331
+ }
1332
+ function isJSONObject(v, path2) {
1333
+ if (typeof v !== "object" || v === null) {
1334
+ return false;
1335
+ }
1336
+ return objectIsJSONObject(v, path2);
1337
+ }
1338
+ function objectIsJSONObject(v, path2) {
1339
+ for (const k in v) {
1340
+ if (hasOwn(v, k)) {
1341
+ path2.push(k);
1342
+ const value = v[k];
1343
+ if (value !== void 0 && !isJSONValue(value, path2)) {
1344
+ return false;
1345
+ }
1346
+ path2.pop();
1347
+ }
1348
+ }
1349
+ return true;
1350
+ }
1351
+ function isJSONArray(v, path2) {
1352
+ for (let i = 0; i < v.length; i++) {
1353
+ path2.push(i);
1354
+ if (!isJSONValue(v[i], path2)) {
1355
+ return false;
1356
+ }
1357
+ path2.pop();
1358
+ }
1359
+ return true;
1360
+ }
1361
+
1362
+ // ../shared/src/json-schema.ts
1363
+ var path = [];
1364
+ var jsonSchema = unknown().chain((v) => {
1365
+ if (isProd) {
1366
+ return ok(v);
1367
+ }
1368
+ const rv = isJSONValue(v, path) ? ok(v) : err({
1369
+ message: `Not a JSON value`,
1370
+ path: path.slice()
1371
+ });
1372
+ path.length = 0;
1373
+ return rv;
1374
+ });
1375
+ var jsonObjectSchema = unknown().chain((v) => {
1376
+ if (isProd) {
1377
+ return ok(v);
1378
+ }
1379
+ const rv = isJSONObject(v, path) ? ok(v) : err({
1380
+ message: `Not a JSON object`,
1381
+ path: path.slice()
1382
+ });
1383
+ path.length = 0;
1384
+ return rv;
1385
+ });
1386
+
1387
+ // ../zero-protocol/src/data.ts
1388
+ var valueSchema = union(jsonSchema, undefined_());
1389
+ var rowSchema = readonlyRecord(valueSchema);
1390
+
1391
+ // ../zero-protocol/src/ast.ts
1392
+ var selectorSchema = string();
1393
+ var orderingElementSchema = readonly(
1394
+ tuple([selectorSchema, literalUnion("asc", "desc")])
1395
+ );
1396
+ var orderingSchema = readonlyArray(orderingElementSchema);
1397
+ var primitiveSchema = union(
1398
+ string(),
1399
+ number(),
1400
+ boolean(),
1401
+ null_()
1402
+ );
1403
+ var equalityOpsSchema = literalUnion("=", "!=", "IS", "IS NOT");
1404
+ var orderOpsSchema = literalUnion("<", ">", "<=", ">=");
1405
+ var likeOpsSchema = literalUnion(
1406
+ "LIKE",
1407
+ "NOT LIKE",
1408
+ "ILIKE",
1409
+ "NOT ILIKE"
1410
+ );
1411
+ var inOpsSchema = literalUnion("IN", "NOT IN");
1412
+ var simpleOperatorSchema = union(
1413
+ equalityOpsSchema,
1414
+ orderOpsSchema,
1415
+ likeOpsSchema,
1416
+ inOpsSchema
1417
+ );
1418
+ var literalReferenceSchema = readonlyObject({
1419
+ type: literal("literal"),
1420
+ value: union(
1421
+ string(),
1422
+ number(),
1423
+ boolean(),
1424
+ null_(),
1425
+ readonlyArray(union(string(), number(), boolean()))
1426
+ )
1427
+ });
1428
+ var columnReferenceSchema = readonlyObject({
1429
+ type: literal("column"),
1430
+ name: string()
1431
+ });
1432
+ var parameterReferenceSchema = readonlyObject({
1433
+ type: literal("static"),
1434
+ // The "namespace" of the injected parameter.
1435
+ // Write authorization will send the value of a row
1436
+ // prior to the mutation being run (preMutationRow).
1437
+ // Read and write authorization will both send the
1438
+ // current authentication data (authData).
1439
+ anchor: literalUnion("authData", "preMutationRow"),
1440
+ field: union(string(), array(string()))
1441
+ });
1442
+ var conditionValueSchema = union(
1443
+ literalReferenceSchema,
1444
+ columnReferenceSchema,
1445
+ parameterReferenceSchema
1446
+ );
1447
+ var simpleConditionSchema = readonlyObject({
1448
+ type: literal("simple"),
1449
+ op: simpleOperatorSchema,
1450
+ left: conditionValueSchema,
1451
+ right: union(parameterReferenceSchema, literalReferenceSchema)
1452
+ });
1453
+ var correlatedSubqueryConditionOperatorSchema = literalUnion("EXISTS", "NOT EXISTS");
1454
+ var correlatedSubqueryConditionSchema = readonlyObject({
1455
+ type: literal("correlatedSubquery"),
1456
+ related: lazy(() => correlatedSubquerySchema),
1457
+ op: correlatedSubqueryConditionOperatorSchema,
1458
+ flip: boolean().optional(),
1459
+ scalar: boolean().optional()
1460
+ });
1461
+ var conditionSchema = union(
1462
+ simpleConditionSchema,
1463
+ lazy(() => conjunctionSchema),
1464
+ lazy(() => disjunctionSchema),
1465
+ correlatedSubqueryConditionSchema
1466
+ );
1467
+ var conjunctionSchema = readonlyObject({
1468
+ type: literal("and"),
1469
+ conditions: readonlyArray(conditionSchema)
1470
+ });
1471
+ var disjunctionSchema = readonlyObject({
1472
+ type: literal("or"),
1473
+ conditions: readonlyArray(conditionSchema)
1474
+ });
1475
+ var compoundKeySchema = readonly(
1476
+ // oxlint-disable-next-line e18e/prefer-spread-syntax
1477
+ tuple([string()]).concat(array(string()))
1478
+ );
1479
+ var correlationSchema = readonlyObject({
1480
+ parentField: compoundKeySchema,
1481
+ childField: compoundKeySchema
1482
+ });
1483
+ var correlatedSubquerySchemaOmitSubquery = readonlyObject({
1484
+ correlation: correlationSchema,
1485
+ hidden: boolean().optional(),
1486
+ system: literalUnion("permissions", "client", "test").optional()
1487
+ });
1488
+ var correlatedSubquerySchema = correlatedSubquerySchemaOmitSubquery.extend({
1489
+ subquery: lazy(() => astSchema)
1490
+ });
1491
+ var astSchema = readonlyObject({
1492
+ schema: string().optional(),
1493
+ table: string(),
1494
+ alias: string().optional(),
1495
+ where: conditionSchema.optional(),
1496
+ related: readonlyArray(correlatedSubquerySchema).optional(),
1497
+ limit: number().optional(),
1498
+ orderBy: orderingSchema.optional(),
1499
+ start: object({
1500
+ row: rowSchema,
1501
+ exclusive: boolean()
1502
+ }).optional()
1503
+ });
1504
+ var MAX_AST_DEPTH = 50;
1505
+ function exceedsASTDepth(ast, maxDepth = MAX_AST_DEPTH) {
1506
+ return astExceedsDepth(ast, 0, maxDepth);
1507
+ }
1508
+ function astExceedsDepth(ast, depth, maxDepth) {
1509
+ if (depth > maxDepth) {
1510
+ return true;
1511
+ }
1512
+ if (!isPlainObject(ast)) {
1513
+ return false;
1514
+ }
1515
+ const { where, related } = ast;
1516
+ return conditionExceedsDepth(where, depth, maxDepth) || Array.isArray(related) && related.some(
1517
+ (r) => isPlainObject(r) && astExceedsDepth(r.subquery, depth + 1, maxDepth)
1518
+ );
1519
+ }
1520
+ function conditionExceedsDepth(cond, depth, maxDepth) {
1521
+ if (depth > maxDepth) {
1522
+ return true;
1523
+ }
1524
+ if (!isPlainObject(cond)) {
1525
+ return false;
1526
+ }
1527
+ const { conditions, related } = cond;
1528
+ return Array.isArray(conditions) && conditions.some((c) => conditionExceedsDepth(c, depth + 1, maxDepth)) || isPlainObject(related) && astExceedsDepth(related.subquery, depth + 1, maxDepth);
1529
+ }
1530
+ var depthBoundedAstSchema = Object.assign(
1531
+ unknown().chain(
1532
+ (value, options) => exceedsASTDepth(value) ? err(`AST exceeds the maximum depth of ${MAX_AST_DEPTH}`) : astSchema.try(value, options)
1533
+ ),
1534
+ // A transform serializes as just its name. Show astSchema too, so a change
1535
+ // to it still changes the hash in protocol-version.test.ts.
1536
+ { depthBounded: astSchema }
1537
+ );
1538
+ var strictASTSchema = strict(depthBoundedAstSchema);
1539
+ function asNormalized(ast) {
1540
+ return ast;
1541
+ }
1542
+ var normalizeCache = /* @__PURE__ */ new WeakMap();
1543
+ function normalizeAST(ast) {
1544
+ return getOrInsertComputed(normalizeCache, ast, normalizeASTUncached);
1545
+ }
1546
+ function normalizeASTUncached(ast) {
1547
+ const { where, related } = ast;
1548
+ return normalizedAST({
1549
+ ...ast,
1550
+ where: where && normalizeSubqueries(where),
1551
+ related: related?.map(
1552
+ (r) => normalizedRelated({ ...r, subquery: normalizeAST(r.subquery) })
1553
+ )
1554
+ });
1555
+ }
1556
+ function normalizeSubqueries(cond) {
1557
+ switch (cond.type) {
1558
+ case "simple":
1559
+ return cond;
1560
+ case "correlatedSubquery":
1561
+ return {
1562
+ ...cond,
1563
+ related: {
1564
+ ...cond.related,
1565
+ subquery: normalizeAST(cond.related.subquery)
1566
+ }
1567
+ };
1568
+ default:
1569
+ return {
1570
+ type: cond.type,
1571
+ conditions: cond.conditions.map(normalizeSubqueries)
1572
+ };
1573
+ }
1574
+ }
1575
+ function normalizedAST(ast) {
1576
+ const { schema, table, alias, where, related, start, limit, orderBy } = ast;
1577
+ return asNormalized({
1578
+ schema,
1579
+ table,
1580
+ alias,
1581
+ where: where === void 0 ? void 0 : normalizeCondition(where),
1582
+ related: related === void 0 ? void 0 : normalizeRelated(related),
1583
+ start,
1584
+ limit,
1585
+ orderBy
1586
+ });
1587
+ }
1588
+ var normalizedConditions = /* @__PURE__ */ new WeakSet();
1589
+ function normalizeRelated(related) {
1590
+ for (let i = 1; i < related.length; i++) {
1591
+ if (cmpRelated(related[i - 1], related[i]) > 0) {
1592
+ return related.toSorted(cmpRelated);
1593
+ }
1594
+ }
1595
+ return related;
1596
+ }
1597
+ function normalizedRelated(related) {
1598
+ const { correlation, hidden, subquery, system } = related;
1599
+ return {
1600
+ correlation: {
1601
+ parentField: correlation.parentField,
1602
+ childField: correlation.childField
1603
+ },
1604
+ hidden,
1605
+ subquery,
1606
+ system
1607
+ };
1608
+ }
1609
+ function normalizeValuePosition(v) {
1610
+ switch (v.type) {
1611
+ case "literal":
1612
+ return { type: "literal", value: v.value };
1613
+ case "column":
1614
+ return { type: "column", name: v.name };
1615
+ default:
1616
+ return { type: "static", anchor: v.anchor, field: v.field };
1617
+ }
1618
+ }
1619
+ function normalizeCondition(cond) {
1620
+ if (normalizedConditions.has(cond)) {
1621
+ return cond;
1622
+ }
1623
+ if (cond.type === "simple") {
1624
+ const normalized2 = {
1625
+ type: "simple",
1626
+ op: cond.op,
1627
+ left: normalizeValuePosition(cond.left),
1628
+ right: normalizeValuePosition(cond.right)
1629
+ };
1630
+ normalizedConditions.add(normalized2);
1631
+ return normalized2;
1632
+ }
1633
+ if (cond.type === "correlatedSubquery") {
1634
+ const normalized2 = {
1635
+ type: "correlatedSubquery",
1636
+ related: normalizedRelated(cond.related),
1637
+ op: cond.op,
1638
+ flip: cond.flip,
1639
+ scalar: cond.scalar
1640
+ };
1641
+ normalizedConditions.add(normalized2);
1642
+ return normalized2;
1643
+ }
1644
+ const conditions = [];
1645
+ for (const c of cond.conditions) {
1646
+ const n = normalizeCondition(c);
1647
+ if (n.type === cond.type) {
1648
+ conditions.push(...n.conditions);
1649
+ } else {
1650
+ conditions.push(n);
1651
+ }
1652
+ }
1653
+ if (conditions.length === 1) {
1654
+ return conditions[0];
1655
+ }
1656
+ conditions.sort(cmpCondition);
1657
+ const normalized = { type: cond.type, conditions };
1658
+ normalizedConditions.add(normalized);
1659
+ return normalized;
1660
+ }
1661
+ function cmpCondition(a, b) {
1662
+ if (a.type === "simple") {
1663
+ if (b.type !== "simple") {
1664
+ return -1;
1665
+ }
1666
+ return compareValuePosition(a.left, b.left) || compareUTF8MaybeNull(a.op, b.op) || compareValuePosition(a.right, b.right);
1667
+ }
1668
+ if (b.type === "simple") {
1669
+ return 1;
1670
+ }
1671
+ if (a.type === "correlatedSubquery") {
1672
+ if (b.type !== "correlatedSubquery") {
1673
+ return -1;
1674
+ }
1675
+ return cmpRelated(a.related, b.related) || compareUTF8MaybeNull(a.op, b.op) || cmpOptionalBool(a.flip, b.flip) || cmpOptionalBool(a.scalar, b.scalar);
1676
+ }
1677
+ if (b.type === "correlatedSubquery") {
1678
+ return -1;
1679
+ }
1680
+ const val = compareUTF8MaybeNull(a.type, b.type);
1681
+ if (val !== 0) {
1682
+ return val;
1683
+ }
1684
+ for (let l = 0, r = 0; l < a.conditions.length && r < b.conditions.length; l++, r++) {
1685
+ const val2 = cmpCondition(a.conditions[l], b.conditions[r]);
1686
+ if (val2 !== 0) {
1687
+ return val2;
1688
+ }
1689
+ }
1690
+ return a.conditions.length - b.conditions.length;
1691
+ }
1692
+ function compareValuePosition(a, b) {
1693
+ if (a.type !== b.type) {
1694
+ return compareUTF8(a.type, b.type);
1695
+ }
1696
+ switch (a.type) {
1697
+ case "literal":
1698
+ assert(b.type === "literal", "Expected literal type for comparison");
1699
+ return cmpLiteralValue(a.value, b.value);
1700
+ case "column":
1701
+ assert(b.type === "column", "Expected column type for comparison");
1702
+ return compareUTF8(a.name, b.name);
1703
+ case "static":
1704
+ assert(b.type === "static", "Expected static type for comparison");
1705
+ return compareUTF8(a.anchor, b.anchor) || cmpLiteralValue(a.field, b.field);
1706
+ }
1707
+ }
1708
+ var LITERAL_VALUE_TYPES = ["object", "boolean", "number", "string"];
1709
+ function literalValueType(value) {
1710
+ return Array.isArray(value) ? LITERAL_VALUE_TYPES.length : LITERAL_VALUE_TYPES.indexOf(typeof value);
1711
+ }
1712
+ function cmpLiteralValue(a, b) {
1713
+ const type = literalValueType(a) - literalValueType(b);
1714
+ if (type !== 0) {
1715
+ return type;
1716
+ }
1717
+ if (Array.isArray(a)) {
1718
+ assert(Array.isArray(b), "Expected array for comparison");
1719
+ for (let i = 0; i < a.length && i < b.length; i++) {
1720
+ const val = cmpLiteralValue(a[i], b[i]);
1721
+ if (val !== 0) {
1722
+ return val;
1723
+ }
1724
+ }
1725
+ return a.length - b.length;
1726
+ }
1727
+ switch (typeof a) {
1728
+ case "string":
1729
+ assert(typeof b === "string", "Expected string for comparison");
1730
+ return compareUTF8(a, b);
1731
+ case "number":
1732
+ assert(typeof b === "number", "Expected number for comparison");
1733
+ return a < b ? -1 : a > b ? 1 : 0;
1734
+ case "boolean":
1735
+ assert(typeof b === "boolean", "Expected boolean for comparison");
1736
+ return Number(a) - Number(b);
1737
+ default:
1738
+ return 0;
1739
+ }
1740
+ }
1741
+ function cmpRelated(a, b) {
1742
+ return compareUTF8(must(a.subquery.alias), must(b.subquery.alias));
1743
+ }
1744
+ function compareUTF8MaybeNull(a, b) {
1745
+ if (a !== null && b !== null) {
1746
+ return compareUTF8(a, b);
1747
+ }
1748
+ if (b !== null) {
1749
+ return -1;
1750
+ }
1751
+ if (a !== null) {
1752
+ return 1;
1753
+ }
1754
+ return 0;
1755
+ }
1756
+ function cmpOptionalBool(a, b) {
1757
+ const toNum = (v) => v === void 0 ? 0 : v ? 2 : 1;
1758
+ return toNum(a) - toNum(b);
1759
+ }
1760
+
1761
+ // ../shared/src/xxhash32.ts
1762
+ var PRIME32_1 = 2654435761;
1763
+ var PRIME32_2 = 2246822519;
1764
+ var PRIME32_3 = 3266489917;
1765
+ var PRIME32_5 = 374761393;
1766
+ function round32(acc, word) {
1767
+ acc = acc + Math.imul(word, PRIME32_2) | 0;
1768
+ acc = acc << 13 | acc >>> 19;
1769
+ return Math.imul(acc, PRIME32_1);
1770
+ }
1771
+ function avalanche32(acc) {
1772
+ acc ^= acc >>> 15;
1773
+ acc = Math.imul(acc, PRIME32_2);
1774
+ acc ^= acc >>> 13;
1775
+ acc = Math.imul(acc, PRIME32_3);
1776
+ acc ^= acc >>> 16;
1777
+ return acc >>> 0;
1778
+ }
1779
+
1780
+ // ../shared/src/hash.ts
1781
+ var MAX_WORDS = 4;
1782
+ var accs = new Int32Array(MAX_WORDS);
1783
+ var stripes = new Int32Array(MAX_WORDS * 4);
1784
+ var digests = new Uint32Array(MAX_WORDS);
1785
+ var wideView = new DataView(new ArrayBuffer(16));
1786
+
1787
+ // ../zero-protocol/src/query-hash-visitor.ts
1788
+ var h1 = 0;
1789
+ var h2 = 0;
1790
+ function mix(w) {
1791
+ h1 = round32(h1, w);
1792
+ h2 = round32(h2, w);
1793
+ }
1794
+ function mixString(s) {
1795
+ const n = s.length;
1796
+ mix(n | STR_MARK);
1797
+ let i = 0;
1798
+ for (; i + 1 < n; i += 2) {
1799
+ mix(s.charCodeAt(i) | s.charCodeAt(i + 1) << 16);
1800
+ }
1801
+ if (i < n) {
1802
+ mix(s.charCodeAt(i));
1803
+ }
1804
+ }
1805
+ var numView = new DataView(new ArrayBuffer(8));
1806
+ function mixNumber(n) {
1807
+ if ((n | 0) === n) {
1808
+ mix(n);
1809
+ } else {
1810
+ numView.setFloat64(0, n, true);
1811
+ mix(numView.getInt32(0, true));
1812
+ mix(numView.getInt32(4, true));
1813
+ }
1814
+ }
1815
+ var TAG_NULL2 = 4097;
1816
+ var TAG_FALSE = 4098;
1817
+ var TAG_TRUE = 4099;
1818
+ var TAG_INT = 4100;
1819
+ var TAG_FLOAT = 4101;
1820
+ var TAG_ARR = 4103;
1821
+ var TAG_OBJ = 4104;
1822
+ var TAG_END = 4105;
1823
+ var TAG_UNDEF = 4106;
1824
+ var TAG_LITERAL2 = 8193;
1825
+ var TAG_COLUMN = 8194;
1826
+ var TAG_STATIC = 8195;
1827
+ var TAG_SIMPLE = 8196;
1828
+ var TAG_SUBQUERY = 8197;
1829
+ var TAG_AND = 8198;
1830
+ var TAG_OR = 8199;
1831
+ var TAG_SYSTEM_PERMISSIONS = 8202;
1832
+ var TAG_SYSTEM_CLIENT = 8203;
1833
+ var TAG_SYSTEM_TEST = 8204;
1834
+ var STR_MARK = 1073741824;
1835
+ function reset() {
1836
+ h1 = PRIME32_5;
1837
+ h2 = PRIME32_1;
1838
+ }
1839
+ function finalize() {
1840
+ return avalanche32(h1).toString(36).padStart(7, "0") + avalanche32(h2).toString(36).padStart(7, "0");
1841
+ }
1842
+ function visitValue(v) {
1843
+ switch (typeof v) {
1844
+ case "string":
1845
+ mixString(v);
1846
+ return;
1847
+ case "number":
1848
+ if (!Number.isFinite(v)) {
1849
+ mix(TAG_NULL2);
1850
+ return;
1851
+ }
1852
+ mix((v | 0) === v ? TAG_INT : TAG_FLOAT);
1853
+ mixNumber(v);
1854
+ return;
1855
+ case "boolean":
1856
+ mix(v ? TAG_TRUE : TAG_FALSE);
1857
+ return;
1858
+ case "object": {
1859
+ if (v === null) {
1860
+ mix(TAG_NULL2);
1861
+ return;
1862
+ }
1863
+ if (Array.isArray(v)) {
1864
+ mix(TAG_ARR);
1865
+ for (let i = 0; i < v.length; i++) {
1866
+ const e = v[i];
1867
+ visitValue(e === void 0 ? null : e);
1868
+ }
1869
+ mix(TAG_END);
1870
+ return;
1871
+ }
1872
+ mix(TAG_OBJ);
1873
+ const keys = Object.keys(v).sort();
1874
+ for (const k of keys) {
1875
+ const val = v[k];
1876
+ if (val === void 0) {
1877
+ continue;
1878
+ }
1879
+ mixString(k);
1880
+ visitValue(val);
1881
+ }
1882
+ mix(TAG_END);
1883
+ return;
1884
+ }
1885
+ default:
1886
+ return;
1887
+ }
1888
+ }
1889
+ function visitOptionalString(s) {
1890
+ if (s === void 0) {
1891
+ mix(TAG_UNDEF);
1892
+ } else {
1893
+ mixString(s);
1894
+ }
1895
+ }
1896
+ function mixOptionalSystem(system) {
1897
+ if (system === void 0) {
1898
+ mix(TAG_UNDEF);
1899
+ } else {
1900
+ mixSystem(system);
1901
+ }
1902
+ }
1903
+ function mixSystem(system) {
1904
+ switch (system) {
1905
+ case "permissions":
1906
+ mix(TAG_SYSTEM_PERMISSIONS);
1907
+ break;
1908
+ case "client":
1909
+ mix(TAG_SYSTEM_CLIENT);
1910
+ break;
1911
+ case "test":
1912
+ mix(TAG_SYSTEM_TEST);
1913
+ break;
1914
+ default:
1915
+ unreachable(system);
1916
+ }
1917
+ }
1918
+ function visitCompoundKey(k) {
1919
+ mix(k.length);
1920
+ for (let i = 0; i < k.length; i++) {
1921
+ mixString(k[i]);
1922
+ }
1923
+ }
1924
+ function visitOrdering(o) {
1925
+ if (o === void 0) {
1926
+ mix(TAG_UNDEF);
1927
+ return;
1928
+ }
1929
+ mix(o.length);
1930
+ for (let i = 0; i < o.length; i++) {
1931
+ const [field, dir] = o[i];
1932
+ mixString(field);
1933
+ mix(dir === "asc" ? TAG_TRUE : TAG_FALSE);
1934
+ }
1935
+ }
1936
+ function visitValuePosition(v) {
1937
+ switch (v.type) {
1938
+ case "literal":
1939
+ mix(TAG_LITERAL2);
1940
+ visitValue(v.value);
1941
+ return;
1942
+ case "column":
1943
+ mix(TAG_COLUMN);
1944
+ mixString(v.name);
1945
+ return;
1946
+ case "static": {
1947
+ mix(TAG_STATIC);
1948
+ mixString(v.anchor);
1949
+ if (typeof v.field === "string") {
1950
+ mixString(v.field);
1951
+ } else {
1952
+ visitCompoundKey(v.field);
1953
+ }
1954
+ return;
1955
+ }
1956
+ default:
1957
+ unreachable(v);
1958
+ }
1959
+ }
1960
+ function visitCondition(c) {
1961
+ switch (c.type) {
1962
+ case "simple":
1963
+ mix(TAG_SIMPLE);
1964
+ mixString(c.op);
1965
+ visitValuePosition(c.left);
1966
+ visitValuePosition(c.right);
1967
+ return;
1968
+ case "correlatedSubquery":
1969
+ mix(TAG_SUBQUERY);
1970
+ mixString(c.op);
1971
+ mix(c.flip === void 0 ? TAG_UNDEF : c.flip ? TAG_TRUE : TAG_FALSE);
1972
+ mix(c.scalar === void 0 ? TAG_UNDEF : c.scalar ? TAG_TRUE : TAG_FALSE);
1973
+ visitCorrelatedSubquery(c.related);
1974
+ return;
1975
+ default: {
1976
+ c.type;
1977
+ mix(c.type === "and" ? TAG_AND : TAG_OR);
1978
+ const conds = c.conditions;
1979
+ mix(conds.length);
1980
+ for (let i = 0; i < conds.length; i++) {
1981
+ visitCondition(conds[i]);
1982
+ }
1983
+ return;
1984
+ }
1985
+ }
1986
+ }
1987
+ function visitCorrelatedSubquery(csq) {
1988
+ visitCompoundKey(csq.correlation.parentField);
1989
+ visitCompoundKey(csq.correlation.childField);
1990
+ mix(csq.hidden === void 0 ? TAG_UNDEF : csq.hidden ? TAG_TRUE : TAG_FALSE);
1991
+ mixOptionalSystem(csq.system);
1992
+ visitAST(csq.subquery);
1993
+ }
1994
+ function visitAST(ast) {
1995
+ mix(TAG_OBJ);
1996
+ visitOptionalString(ast.schema);
1997
+ mixString(ast.table);
1998
+ visitOptionalString(ast.alias);
1999
+ if (ast.where === void 0) {
2000
+ mix(TAG_UNDEF);
2001
+ } else {
2002
+ visitCondition(ast.where);
2003
+ }
2004
+ const related = ast.related;
2005
+ if (related === void 0) {
2006
+ mix(TAG_UNDEF);
2007
+ } else {
2008
+ mix(related.length);
2009
+ for (let i = 0; i < related.length; i++) {
2010
+ visitCorrelatedSubquery(related[i]);
2011
+ }
2012
+ }
2013
+ const start = ast.start;
2014
+ if (start === void 0) {
2015
+ mix(TAG_UNDEF);
2016
+ } else {
2017
+ mix(start.exclusive ? TAG_TRUE : TAG_FALSE);
2018
+ visitValue(start.row);
2019
+ }
2020
+ if (ast.limit === void 0) {
2021
+ mix(TAG_UNDEF);
2022
+ } else {
2023
+ mix(TAG_INT);
2024
+ mixNumber(ast.limit);
2025
+ }
2026
+ visitOrdering(ast.orderBy);
2027
+ mix(TAG_END);
2028
+ }
2029
+ function hashAST(ast) {
2030
+ const s1 = h1;
2031
+ const s2 = h2;
2032
+ try {
2033
+ reset();
2034
+ visitAST(ast);
2035
+ return finalize();
2036
+ } finally {
2037
+ h1 = s1;
2038
+ h2 = s2;
2039
+ }
2040
+ }
2041
+
2042
+ // ../zero-protocol/src/query-hash.ts
2043
+ var hashCache = /* @__PURE__ */ new WeakMap();
2044
+ function hashOfAST(ast) {
2045
+ return hashOfNormalizedAST(normalizeAST(ast));
2046
+ }
2047
+ function hashOfNormalizedAST(ast) {
2048
+ return getOrInsertComputed(hashCache, ast, hashAST);
2049
+ }
2050
+
2051
+ // src/drift.ts
2052
+ var seedName = "__drift.seed";
2053
+ var dayMs = 24 * 60 * 60 * 1e3;
2054
+ var offlineWarning = "Zero starting up with no server URL. No data will be synced.";
2055
+ async function recordDriftFile(path2) {
2056
+ const module = await import(pathToFileURL(path2).href);
2057
+ if (!module.default?.querySamples || !module.default.mutatorSamples) {
2058
+ throw new Error(`${path2} does not export drift samples by default`);
2059
+ }
2060
+ return recordDrift(module.default);
2061
+ }
2062
+ async function recordDrift(samples) {
2063
+ const { schema, queries, mutators } = samples;
2064
+ const querySamples = samples.querySamples.map((sample) => {
2065
+ const query = mustGetQuery(queries, sample.name);
2066
+ const { ast } = query.fn({
2067
+ args: sample.args,
2068
+ ctx: sample.context
2069
+ });
2070
+ return {
2071
+ name: sample.name,
2072
+ args: sample.args === void 0 ? [] : [sample.args],
2073
+ context: sample.context ?? null,
2074
+ ast: json(ast),
2075
+ hash: hashOfAST(ast)
2076
+ };
2077
+ });
2078
+ const mutatorSamples = [];
2079
+ const { warn } = console;
2080
+ console.warn = (...args) => {
2081
+ if (args[0] !== offlineWarning) warn(...args);
2082
+ };
2083
+ try {
2084
+ for (const [i, sample] of samples.mutatorSamples.entries()) {
2085
+ const result = await runMutator(schema, mutators, sample, 0);
2086
+ const again = await runMutator(schema, mutators, sample, dayMs);
2087
+ if (JSON.stringify(again) !== JSON.stringify(result)) {
2088
+ throw new Error(
2089
+ `mutator ${sample.name} sample ${i} does something else when run again a day later. Pass IDs and timestamps as arguments.`
2090
+ );
2091
+ }
2092
+ mutatorSamples.push({
2093
+ ...sample,
2094
+ context: sample.context ?? null,
2095
+ seed: sample.seed ?? {},
2096
+ ...result
2097
+ });
2098
+ }
2099
+ } finally {
2100
+ console.warn = warn;
2101
+ }
2102
+ const vectors = {
2103
+ queries: names(queries, isQuery, (q) => q.queryName),
2104
+ mutators: names(mutators, isMutator, (m) => m.mutatorName),
2105
+ querySamples,
2106
+ mutatorSamples
2107
+ };
2108
+ return JSON.stringify(vectors, null, 2) + "\n";
2109
+ }
2110
+ async function seed({
2111
+ tx,
2112
+ args
2113
+ }) {
2114
+ for (const [table, rows2] of Object.entries(args)) {
2115
+ for (const row of rows2) {
2116
+ await tx.mutate[table].upsert(row);
2117
+ }
2118
+ }
2119
+ }
2120
+ async function runMutator(schema, mutators, sample, shiftMs) {
2121
+ const registry = defineMutators(mutators, {
2122
+ __drift: { seed: defineMutator(seed) }
2123
+ });
2124
+ const zero = new Zero({
2125
+ schema,
2126
+ mutators: registry,
2127
+ userID: "drift",
2128
+ storageKey: `drift-${Math.random().toString(36).slice(2)}`,
2129
+ kvStore: "mem",
2130
+ context: sample.context,
2131
+ // The mutators' errors are what the samples record, not news.
2132
+ logSink: { log() {
2133
+ } }
2134
+ });
2135
+ try {
2136
+ const call = (name, args) => zero.mutate(
2137
+ mustGetMutator(registry, name)(...args === void 0 ? [] : [args])
2138
+ );
2139
+ await call(seedName, sample.seed ?? {}).client;
2140
+ const before = await rows(zero, schema);
2141
+ const { now } = Date;
2142
+ Date.now = () => now() + shiftMs;
2143
+ let outcome;
2144
+ try {
2145
+ outcome = await call(sample.name, sample.args).client;
2146
+ } finally {
2147
+ Date.now = now;
2148
+ }
2149
+ const after = await rows(zero, schema);
2150
+ return { outcome: json(outcome), changes: diff(schema, before, after) };
2151
+ } finally {
2152
+ await zero.close();
2153
+ }
2154
+ }
2155
+ async function rows(zero, schema) {
2156
+ const builder = createBuilder(schema);
2157
+ const out = /* @__PURE__ */ new Map();
2158
+ for (const [table, { primaryKey }] of Object.entries(schema.tables)) {
2159
+ const data = await zero.run(builder[table]);
2160
+ out.set(
2161
+ table,
2162
+ new Map(
2163
+ data.map((row) => [
2164
+ JSON.stringify(primaryKey.map((c) => row[c] ?? null)),
2165
+ json(row)
2166
+ ])
2167
+ )
2168
+ );
2169
+ }
2170
+ return out;
2171
+ }
2172
+ function diff(schema, before, after) {
2173
+ const changes = [];
2174
+ for (const [table, { primaryKey }] of Object.entries(schema.tables)) {
2175
+ const old = before.get(table) ?? /* @__PURE__ */ new Map();
2176
+ const now = after.get(table) ?? /* @__PURE__ */ new Map();
2177
+ const keys = [.../* @__PURE__ */ new Set([...old.keys(), ...now.keys()])].toSorted(
2178
+ (a, b) => Buffer.compare(Buffer.from(a), Buffer.from(b))
2179
+ );
2180
+ for (const key of keys) {
2181
+ const o = old.get(key);
2182
+ const n = now.get(key);
2183
+ if (n !== void 0) {
2184
+ if (o === void 0 || !sameJSON(o, n)) {
2185
+ changes.push({ table, op: "put", row: n });
2186
+ }
2187
+ } else if (o !== void 0) {
2188
+ changes.push({
2189
+ table,
2190
+ op: "del",
2191
+ id: Object.fromEntries(primaryKey.map((c) => [c, o[c] ?? null]))
2192
+ });
2193
+ }
2194
+ }
2195
+ }
2196
+ return changes;
2197
+ }
2198
+ function sameJSON(a, b) {
2199
+ if (a === b) return true;
2200
+ if (typeof a !== "object" || typeof b !== "object" || !a || !b) return false;
2201
+ if (Array.isArray(a) || Array.isArray(b)) {
2202
+ return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((v, i) => sameJSON(v, b[i]));
2203
+ }
2204
+ const ak = Object.keys(a);
2205
+ const bo = b;
2206
+ return ak.length === Object.keys(b).length && ak.every(
2207
+ (k) => k in bo && sameJSON(a[k], bo[k])
2208
+ );
2209
+ }
2210
+ function names(registry, isLeaf, name) {
2211
+ const out = [];
2212
+ const walk = (node) => {
2213
+ if (isLeaf(node)) {
2214
+ out.push(name(node));
2215
+ } else if (node && typeof node === "object") {
2216
+ for (const [key, child] of Object.entries(node)) {
2217
+ if (key !== "~") walk(child);
2218
+ }
2219
+ }
2220
+ };
2221
+ walk(registry);
2222
+ return out.sort();
2223
+ }
2224
+ function json(v) {
2225
+ return v === void 0 ? null : JSON.parse(JSON.stringify(v));
2226
+ }
2227
+ export {
2228
+ recordDrift,
2229
+ recordDriftFile
2230
+ };