bupkis 0.2.0 → 0.3.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.
- package/CHANGELOG.md +15 -0
- package/README.md +9 -9
- package/dist/commonjs/assertion/assertion-async.d.ts +2 -1
- package/dist/commonjs/assertion/assertion-async.d.ts.map +1 -1
- package/dist/commonjs/assertion/assertion-async.js +84 -2
- package/dist/commonjs/assertion/assertion-async.js.map +1 -1
- package/dist/commonjs/assertion/assertion-sync.d.ts +1 -1
- package/dist/commonjs/assertion/assertion-sync.d.ts.map +1 -1
- package/dist/commonjs/assertion/assertion-sync.js +5 -1
- package/dist/commonjs/assertion/assertion-sync.js.map +1 -1
- package/dist/commonjs/assertion/assertion-types.d.ts +6 -2
- package/dist/commonjs/assertion/assertion-types.d.ts.map +1 -1
- package/dist/commonjs/assertion/assertion.d.ts +1 -1
- package/dist/commonjs/assertion/assertion.d.ts.map +1 -1
- package/dist/commonjs/assertion/assertion.js +1 -14
- package/dist/commonjs/assertion/assertion.js.map +1 -1
- package/dist/commonjs/assertion/impl/async.d.ts +122 -21
- package/dist/commonjs/assertion/impl/async.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/async.js +112 -88
- package/dist/commonjs/assertion/impl/async.js.map +1 -1
- package/dist/commonjs/assertion/impl/callback.d.ts +104 -0
- package/dist/commonjs/assertion/impl/callback.d.ts.map +1 -0
- package/dist/commonjs/assertion/impl/callback.js +694 -0
- package/dist/commonjs/assertion/impl/callback.js.map +1 -0
- package/dist/commonjs/assertion/impl/index.d.ts +1 -1
- package/dist/commonjs/assertion/impl/index.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/index.js.map +1 -1
- package/dist/commonjs/assertion/impl/sync-esoteric.js +1 -1
- package/dist/commonjs/assertion/impl/sync-esoteric.js.map +1 -1
- package/dist/commonjs/assertion/impl/sync-parametric.d.ts +21 -18
- package/dist/commonjs/assertion/impl/sync-parametric.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/sync-parametric.js +31 -46
- package/dist/commonjs/assertion/impl/sync-parametric.js.map +1 -1
- package/dist/commonjs/assertion/impl/sync.d.ts +66 -19
- package/dist/commonjs/assertion/impl/sync.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/sync.js +4 -1
- package/dist/commonjs/assertion/impl/sync.js.map +1 -1
- package/dist/commonjs/bootstrap.d.ts +145 -41
- package/dist/commonjs/bootstrap.d.ts.map +1 -1
- package/dist/commonjs/bootstrap.js +2 -3
- package/dist/commonjs/bootstrap.js.map +1 -1
- package/dist/commonjs/constant.js +7 -1
- package/dist/commonjs/constant.js.map +1 -1
- package/dist/commonjs/error.d.ts +22 -2
- package/dist/commonjs/error.d.ts.map +1 -1
- package/dist/commonjs/error.js +44 -4
- package/dist/commonjs/error.js.map +1 -1
- package/dist/commonjs/expect.d.ts.map +1 -1
- package/dist/commonjs/expect.js +1 -1
- package/dist/commonjs/expect.js.map +1 -1
- package/dist/commonjs/guards.d.ts +23 -5
- package/dist/commonjs/guards.d.ts.map +1 -1
- package/dist/commonjs/guards.js +26 -24
- package/dist/commonjs/guards.js.map +1 -1
- package/dist/commonjs/index.d.ts +144 -40
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/schema.d.ts +18 -8
- package/dist/commonjs/schema.d.ts.map +1 -1
- package/dist/commonjs/schema.js +21 -11
- package/dist/commonjs/schema.js.map +1 -1
- package/dist/commonjs/types.d.ts +39 -8
- package/dist/commonjs/types.d.ts.map +1 -1
- package/dist/commonjs/util.d.ts +66 -50
- package/dist/commonjs/util.d.ts.map +1 -1
- package/dist/commonjs/util.js +169 -156
- package/dist/commonjs/util.js.map +1 -1
- package/dist/commonjs/value-to-schema.d.ts +122 -0
- package/dist/commonjs/value-to-schema.d.ts.map +1 -0
- package/dist/commonjs/value-to-schema.js +309 -0
- package/dist/commonjs/value-to-schema.js.map +1 -0
- package/dist/esm/assertion/assertion-async.d.ts +2 -1
- package/dist/esm/assertion/assertion-async.d.ts.map +1 -1
- package/dist/esm/assertion/assertion-async.js +85 -3
- package/dist/esm/assertion/assertion-async.js.map +1 -1
- package/dist/esm/assertion/assertion-sync.d.ts +1 -1
- package/dist/esm/assertion/assertion-sync.d.ts.map +1 -1
- package/dist/esm/assertion/assertion-sync.js +6 -2
- package/dist/esm/assertion/assertion-sync.js.map +1 -1
- package/dist/esm/assertion/assertion-types.d.ts +6 -2
- package/dist/esm/assertion/assertion-types.d.ts.map +1 -1
- package/dist/esm/assertion/assertion.d.ts +1 -1
- package/dist/esm/assertion/assertion.d.ts.map +1 -1
- package/dist/esm/assertion/assertion.js +1 -14
- package/dist/esm/assertion/assertion.js.map +1 -1
- package/dist/esm/assertion/impl/async.d.ts +122 -21
- package/dist/esm/assertion/impl/async.d.ts.map +1 -1
- package/dist/esm/assertion/impl/async.js +111 -87
- package/dist/esm/assertion/impl/async.js.map +1 -1
- package/dist/esm/assertion/impl/callback.d.ts +104 -0
- package/dist/esm/assertion/impl/callback.d.ts.map +1 -0
- package/dist/esm/assertion/impl/callback.js +691 -0
- package/dist/esm/assertion/impl/callback.js.map +1 -0
- package/dist/esm/assertion/impl/index.d.ts +1 -1
- package/dist/esm/assertion/impl/index.d.ts.map +1 -1
- package/dist/esm/assertion/impl/index.js +1 -1
- package/dist/esm/assertion/impl/index.js.map +1 -1
- package/dist/esm/assertion/impl/sync-esoteric.js +2 -2
- package/dist/esm/assertion/impl/sync-esoteric.js.map +1 -1
- package/dist/esm/assertion/impl/sync-parametric.d.ts +21 -18
- package/dist/esm/assertion/impl/sync-parametric.d.ts.map +1 -1
- package/dist/esm/assertion/impl/sync-parametric.js +31 -46
- package/dist/esm/assertion/impl/sync-parametric.js.map +1 -1
- package/dist/esm/assertion/impl/sync.d.ts +66 -19
- package/dist/esm/assertion/impl/sync.d.ts.map +1 -1
- package/dist/esm/assertion/impl/sync.js +3 -1
- package/dist/esm/assertion/impl/sync.js.map +1 -1
- package/dist/esm/bootstrap.d.ts +145 -41
- package/dist/esm/bootstrap.d.ts.map +1 -1
- package/dist/esm/bootstrap.js +1 -2
- package/dist/esm/bootstrap.js.map +1 -1
- package/dist/esm/constant.js +6 -0
- package/dist/esm/constant.js.map +1 -1
- package/dist/esm/error.d.ts +22 -2
- package/dist/esm/error.d.ts.map +1 -1
- package/dist/esm/error.js +43 -4
- package/dist/esm/error.js.map +1 -1
- package/dist/esm/expect.d.ts.map +1 -1
- package/dist/esm/expect.js +2 -2
- package/dist/esm/expect.js.map +1 -1
- package/dist/esm/guards.d.ts +23 -5
- package/dist/esm/guards.d.ts.map +1 -1
- package/dist/esm/guards.js +22 -21
- package/dist/esm/guards.js.map +1 -1
- package/dist/esm/index.d.ts +144 -40
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/schema.d.ts +18 -8
- package/dist/esm/schema.d.ts.map +1 -1
- package/dist/esm/schema.js +21 -11
- package/dist/esm/schema.js.map +1 -1
- package/dist/esm/types.d.ts +39 -8
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/util.d.ts +66 -50
- package/dist/esm/util.d.ts.map +1 -1
- package/dist/esm/util.js +153 -154
- package/dist/esm/util.js.map +1 -1
- package/dist/esm/value-to-schema.d.ts +122 -0
- package/dist/esm/value-to-schema.d.ts.map +1 -0
- package/dist/esm/value-to-schema.js +305 -0
- package/dist/esm/value-to-schema.js.map +1 -0
- package/package.json +16 -13
- package/src/assertion/assertion-async.ts +113 -3
- package/src/assertion/assertion-sync.ts +5 -2
- package/src/assertion/assertion-types.ts +14 -4
- package/src/assertion/assertion.ts +2 -17
- package/src/assertion/impl/async.ts +130 -90
- package/src/assertion/impl/callback.ts +882 -0
- package/src/assertion/impl/index.ts +1 -1
- package/src/assertion/impl/sync-esoteric.ts +2 -2
- package/src/assertion/impl/sync-parametric.ts +40 -48
- package/src/assertion/impl/sync.ts +3 -0
- package/src/bootstrap.ts +1 -2
- package/src/constant.ts +8 -0
- package/src/error.ts +57 -3
- package/src/expect.ts +6 -2
- package/src/guards.ts +45 -18
- package/src/index.ts +1 -0
- package/src/schema.ts +22 -11
- package/src/types.ts +40 -8
- package/src/util.ts +168 -223
- package/src/value-to-schema.ts +464 -0
package/dist/commonjs/util.js
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Utility functions
|
|
4
|
-
*
|
|
5
|
-
* This module provides core utility functions for checking if objects satisfy
|
|
6
|
-
* expected shapes, including `satisfies` for partial matching,
|
|
7
|
-
* `exhaustivelySatisfies` for exact matching, and `shallowSatisfiesShape` for
|
|
8
|
-
* converting shapes to Zod schemas. All functions handle circular references
|
|
9
|
-
* safely.
|
|
3
|
+
* Utility functions.
|
|
10
4
|
*
|
|
11
5
|
* @category API
|
|
12
6
|
* @example
|
|
@@ -17,178 +11,197 @@
|
|
|
17
11
|
*
|
|
18
12
|
* @packageDocumentation
|
|
19
13
|
*/
|
|
14
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(o, k2, desc);
|
|
21
|
+
}) : (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
o[k2] = m[k];
|
|
24
|
+
}));
|
|
25
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
26
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
27
|
+
};
|
|
20
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.
|
|
29
|
+
exports.hasKey = hasKey;
|
|
30
|
+
exports.hasValue = hasValue;
|
|
22
31
|
exports.keyBy = keyBy;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
__exportStar(require("./value-to-schema.js"), exports);
|
|
33
|
+
/**
|
|
34
|
+
* _Recursively_ searches within an object, array, or any nested structure to
|
|
35
|
+
* find whether a specific key exists.
|
|
36
|
+
*
|
|
37
|
+
* Handles circular references by tracking visited objects to prevent infinite
|
|
38
|
+
* recursion.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* const obj = { a: 1, b: { c: 2, d: [{ e: 3 }] } };
|
|
44
|
+
*
|
|
45
|
+
* hasKey(obj, 'c'); // true
|
|
46
|
+
* hasKey(obj, 'e'); // true
|
|
47
|
+
* hasKey(obj, 'x'); // false (key not found)
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @param obj The object, array, or value to search within
|
|
51
|
+
* @param key The key to search for
|
|
52
|
+
* @param visited Internal set for circular reference detection
|
|
53
|
+
* @returns True if the key is found anywhere in the structure, false otherwise
|
|
54
|
+
*/
|
|
55
|
+
function hasKey(obj, key, visited = new WeakSet()) {
|
|
56
|
+
// Handle primitives that can't contain keys
|
|
57
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
// Prevent infinite recursion with circular references
|
|
61
|
+
if (visited.has(obj)) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
visited.add(obj);
|
|
65
|
+
try {
|
|
66
|
+
// Check if this object has the key
|
|
67
|
+
if (Object.hasOwn(obj, key)) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
// Recursively search in object/array values
|
|
71
|
+
if (Array.isArray(obj)) {
|
|
72
|
+
// For arrays, search in each element
|
|
73
|
+
for (const item of obj) {
|
|
74
|
+
if (hasKey(item, key, visited)) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// For objects, search in each property value
|
|
81
|
+
for (const propValue of Object.values(obj)) {
|
|
82
|
+
if (hasKey(propValue, key, visited)) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
34
86
|
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
visited.delete(obj);
|
|
35
91
|
}
|
|
36
|
-
return result;
|
|
37
92
|
}
|
|
38
93
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
94
|
+
* _Recursively_ searches within an object, array, or any nested structure to
|
|
95
|
+
* find whether a specific value exists.
|
|
41
96
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* support for circular reference detection.
|
|
97
|
+
* Uses strict equality (===) to compare values, with special handling for empty
|
|
98
|
+
* objects. Handles circular references by tracking visited objects to prevent
|
|
99
|
+
* infinite recursion.
|
|
46
100
|
*
|
|
47
101
|
* @example
|
|
48
102
|
*
|
|
49
|
-
* ```
|
|
50
|
-
*
|
|
51
|
-
* valueToSchema('hello'); // z.string()
|
|
52
|
-
* valueToSchema(42); // z.number()
|
|
53
|
-
* valueToSchema(true); // z.boolean()
|
|
54
|
-
*
|
|
55
|
-
* // Objects
|
|
56
|
-
* valueToSchema({ name: 'John', age: 30 });
|
|
57
|
-
* // z.object({ name: z.string(), age: z.number() })
|
|
58
|
-
*
|
|
59
|
-
* // Arrays
|
|
60
|
-
* valueToSchema(['a', 'b', 'c']); // z.array(z.string())
|
|
61
|
-
* valueToSchema([1, 'mixed']); // z.array(z.union([z.number(), z.string()]))
|
|
103
|
+
* ```ts
|
|
104
|
+
* const obj = { a: 1, b: { c: 2, d: [{ e: 3 }] }, empty: {} };
|
|
62
105
|
*
|
|
63
|
-
* //
|
|
64
|
-
*
|
|
65
|
-
*
|
|
106
|
+
* hasValue(obj, 2); // true (found in obj.b.c)
|
|
107
|
+
* hasValue(obj, 3); // true (found in obj.b.d[0].e)
|
|
108
|
+
* hasValue(obj, {}); // true (found in obj.empty, matches empty objects)
|
|
109
|
+
* hasValue(obj, '1'); // false (strict equality, 1 !== '1')
|
|
110
|
+
* hasValue(obj, 999); // false (value not found)
|
|
66
111
|
* ```
|
|
67
112
|
*
|
|
68
|
-
* @param
|
|
69
|
-
* @param
|
|
70
|
-
*
|
|
71
|
-
* @
|
|
113
|
+
* @param obj The object, array, or value to search within
|
|
114
|
+
* @param value The value to search for (using strict equality, with special
|
|
115
|
+
* empty object handling)
|
|
116
|
+
* @param visited Internal set for circular reference detection
|
|
117
|
+
* @returns True if the value is found anywhere in the structure, false
|
|
118
|
+
* otherwise
|
|
72
119
|
*/
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return v4_1.z.unknown();
|
|
78
|
-
}
|
|
79
|
-
// Handle primitives
|
|
80
|
-
if (value === null) {
|
|
81
|
-
return v4_1.z.null();
|
|
120
|
+
function hasValue(obj, value, visited = new WeakSet()) {
|
|
121
|
+
// Direct value comparison
|
|
122
|
+
if (obj === value) {
|
|
123
|
+
return true;
|
|
82
124
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
125
|
+
// Special case: Check for empty objects
|
|
126
|
+
if (typeof obj === 'object' &&
|
|
127
|
+
obj !== null &&
|
|
128
|
+
!Array.isArray(obj) &&
|
|
129
|
+
typeof value === 'object' &&
|
|
130
|
+
value !== null &&
|
|
131
|
+
!Array.isArray(value)) {
|
|
132
|
+
const objKeys = Object.keys(obj);
|
|
133
|
+
const valueKeys = Object.keys(value);
|
|
134
|
+
// Both are empty objects
|
|
135
|
+
if (objKeys.length === 0 && valueKeys.length === 0) {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
88
138
|
}
|
|
89
|
-
|
|
90
|
-
|
|
139
|
+
// Handle primitives that can't contain nested values
|
|
140
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
141
|
+
return false;
|
|
91
142
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return literalPrimitives ? v4_1.z.literal(value) : v4_1.z.bigint();
|
|
96
|
-
case 'boolean':
|
|
97
|
-
return literalPrimitives ? v4_1.z.literal(value) : v4_1.z.boolean();
|
|
98
|
-
case 'function':
|
|
99
|
-
return schema_js_1.FunctionSchema;
|
|
100
|
-
case 'number':
|
|
101
|
-
return literalPrimitives ? v4_1.z.literal(value) : v4_1.z.number();
|
|
102
|
-
case 'string':
|
|
103
|
-
return literalPrimitives ? v4_1.z.literal(value) : v4_1.z.string();
|
|
104
|
-
case 'symbol':
|
|
105
|
-
return v4_1.z.symbol();
|
|
143
|
+
// Prevent infinite recursion with circular references
|
|
144
|
+
if (visited.has(obj)) {
|
|
145
|
+
return false;
|
|
106
146
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
//
|
|
110
|
-
if (
|
|
111
|
-
//
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
try {
|
|
116
|
-
// Handle built-in object types
|
|
117
|
-
if (value instanceof Date) {
|
|
118
|
-
return v4_1.z.date();
|
|
119
|
-
}
|
|
120
|
-
if (value instanceof RegExp) {
|
|
121
|
-
if (literalRegExp) {
|
|
122
|
-
return schema_js_1.RegExpSchema;
|
|
147
|
+
visited.add(obj);
|
|
148
|
+
try {
|
|
149
|
+
// Recursively search in object/array values
|
|
150
|
+
if (Array.isArray(obj)) {
|
|
151
|
+
// For arrays, search in each element
|
|
152
|
+
for (const item of obj) {
|
|
153
|
+
if (hasValue(item, value, visited)) {
|
|
154
|
+
return true;
|
|
123
155
|
}
|
|
124
|
-
return v4_1.z.coerce.string().regex(value);
|
|
125
|
-
}
|
|
126
|
-
if (value instanceof Map) {
|
|
127
|
-
return schema_js_1.StrongMapSchema;
|
|
128
|
-
}
|
|
129
|
-
if (value instanceof Set) {
|
|
130
|
-
return schema_js_1.StrongSetSchema;
|
|
131
|
-
}
|
|
132
|
-
if (value instanceof WeakMap) {
|
|
133
|
-
return v4_1.z.instanceof(WeakMap);
|
|
134
156
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if ((0, guards_js_1.isPromiseLike)(value)) {
|
|
142
|
-
return schema_js_1.WrappedPromiseLikeSchema;
|
|
143
|
-
}
|
|
144
|
-
// Handle arrays
|
|
145
|
-
if (Array.isArray(value)) {
|
|
146
|
-
if (value.length === 0) {
|
|
147
|
-
return v4_1.z.array(v4_1.z.unknown());
|
|
148
|
-
}
|
|
149
|
-
const elementSchemas = value.map((item) => (0, exports.valueToSchema)(item, {
|
|
150
|
-
...options,
|
|
151
|
-
_currentDepth: _currentDepth + 1,
|
|
152
|
-
}, visited));
|
|
153
|
-
if (allowMixedArrays) {
|
|
154
|
-
// Create a union of all unique element types
|
|
155
|
-
const uniqueSchemas = Array.from(new Set(elementSchemas.map((schema) => schema.constructor.name))).map((_, index) => elementSchemas[index]);
|
|
156
|
-
if (uniqueSchemas.length === 1) {
|
|
157
|
-
return v4_1.z.array(uniqueSchemas[0]);
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
return v4_1.z.array(v4_1.z.union(uniqueSchemas));
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
// Use the first element's schema for all elements
|
|
165
|
-
return v4_1.z.array(elementSchemas[0]);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
// Handle plain objects
|
|
169
|
-
if ((0, guards_js_1.isNonNullObject)(value)) {
|
|
170
|
-
const schemaShape = {};
|
|
171
|
-
for (const [key, val] of Object.entries(value)) {
|
|
172
|
-
if ((0, guards_js_1.isString)(key)) {
|
|
173
|
-
schemaShape[key] = (0, exports.valueToSchema)(val, {
|
|
174
|
-
...options,
|
|
175
|
-
_currentDepth: _currentDepth + 1,
|
|
176
|
-
}, visited);
|
|
177
|
-
}
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// For objects, search in each property value
|
|
160
|
+
for (const propValue of Object.values(obj)) {
|
|
161
|
+
if (hasValue(propValue, value, visited)) {
|
|
162
|
+
return true;
|
|
178
163
|
}
|
|
179
|
-
return strict
|
|
180
|
-
? v4_1.z.strictObject(schemaShape)
|
|
181
|
-
: v4_1.z.looseObject(schemaShape);
|
|
182
164
|
}
|
|
183
|
-
// Handle other object types (ArrayBuffer, etc.)
|
|
184
|
-
return v4_1.z.custom((val) => typeof val === 'object' && val !== null, { message: 'Expected an object' });
|
|
185
165
|
}
|
|
186
|
-
|
|
187
|
-
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
visited.delete(obj);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* _Recursively_ searches for a key-value pair within an object or array.
|
|
174
|
+
*
|
|
175
|
+
* Uses strict equality (===) to compare values. Handles circular references by
|
|
176
|
+
* tracking visited objects to prevent infinite recursion.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
*
|
|
180
|
+
* ```ts
|
|
181
|
+
* const obj = { a: 1, b: { c: 2, d: [{ e: 3 }] } };
|
|
182
|
+
*
|
|
183
|
+
* hasKeyValue(obj, 'c', 2); // true
|
|
184
|
+
* hasKeyValue(obj, 'e', 3); // true
|
|
185
|
+
* hasKeyValue(obj, 'a', '1'); // false (strict equality)
|
|
186
|
+
* hasKeyValue(obj, 'x', 1); // false (key not found)
|
|
187
|
+
* /**
|
|
188
|
+
* Maps an array of objects to an object keyed by the specified key.
|
|
189
|
+
*
|
|
190
|
+
* @param collection Array of objects
|
|
191
|
+
* @param key Name of key
|
|
192
|
+
* @returns Object mapping key values to objects
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
function keyBy(collection, key) {
|
|
196
|
+
const result = {};
|
|
197
|
+
for (const item of collection) {
|
|
198
|
+
const keyValue = item[key];
|
|
199
|
+
if (typeof keyValue === 'string' ||
|
|
200
|
+
typeof keyValue === 'number' ||
|
|
201
|
+
typeof keyValue === 'symbol') {
|
|
202
|
+
result[String(keyValue)] = item;
|
|
188
203
|
}
|
|
189
204
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
};
|
|
193
|
-
exports.valueToSchema = valueToSchema;
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
194
207
|
//# sourceMappingURL=util.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
/**
|
|
3
|
+
* Recursively converts an arbitrary value to a Zod v4 schema that would
|
|
4
|
+
* validate values with the same structure.
|
|
5
|
+
*
|
|
6
|
+
* This function analyzes the runtime value and generates a corresponding Zod
|
|
7
|
+
* schema that captures the value's structure and type information. It handles
|
|
8
|
+
* primitives, objects, arrays, functions, and various built-in types, with
|
|
9
|
+
* support for circular reference detection.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
*
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // Primitive types
|
|
15
|
+
* valueToSchema('hello'); // z.string()
|
|
16
|
+
* valueToSchema(42); // z.number()
|
|
17
|
+
* valueToSchema(true); // z.boolean()
|
|
18
|
+
*
|
|
19
|
+
* // Objects
|
|
20
|
+
* valueToSchema({ name: 'John', age: 30 });
|
|
21
|
+
* // z.object({ name: z.string(), age: z.number() })
|
|
22
|
+
*
|
|
23
|
+
* // Arrays
|
|
24
|
+
* valueToSchema(['a', 'b', 'c']); // z.array(z.string())
|
|
25
|
+
* valueToSchema([1, 'mixed']); // z.array(z.union([z.number(), z.string()]))
|
|
26
|
+
*
|
|
27
|
+
* // Nested structures
|
|
28
|
+
* valueToSchema({ users: [{ name: 'John' }] });
|
|
29
|
+
* // z.object({ users: z.array(z.object({ name: z.string() })) })
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @param value - The value to convert to a schema
|
|
33
|
+
* @param options - Configuration options for schema generation
|
|
34
|
+
* @param visited - Internal WeakSet for circular reference detection
|
|
35
|
+
* @returns A Zod schema that validates values matching the input's structure.
|
|
36
|
+
* This value is unfortunately untyped due to the complexity involved. But the
|
|
37
|
+
* schema works!
|
|
38
|
+
*/
|
|
39
|
+
export declare const valueToSchema: (value: unknown, options?: ValueToSchemaOptions, visited?: WeakSet<object>) => z.ZodType<any>;
|
|
40
|
+
/**
|
|
41
|
+
* Options for {@link valueToSchema}
|
|
42
|
+
*/
|
|
43
|
+
export interface ValueToSchemaOptions {
|
|
44
|
+
/**
|
|
45
|
+
* If `true`, treat empty objects `{}` as literal empty objects that only
|
|
46
|
+
* match objects with zero own properties
|
|
47
|
+
*
|
|
48
|
+
* @defaultValue false
|
|
49
|
+
*/
|
|
50
|
+
literalEmptyObjects?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* If `true`, use literal schema for primitive values instead of type schema
|
|
53
|
+
*
|
|
54
|
+
* @defaultValue false
|
|
55
|
+
*/
|
|
56
|
+
literalPrimitives?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* If `true`, treat `RegExp` literals as `RegExp` literals; otherwise treat as
|
|
59
|
+
* strings and attempt match
|
|
60
|
+
*
|
|
61
|
+
* @defaultValue false
|
|
62
|
+
*/
|
|
63
|
+
literalRegExp?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* If `true`, treat arrays as tuples wherever possible.
|
|
66
|
+
*
|
|
67
|
+
* Implies `false` for {@link noMixedArrays}.
|
|
68
|
+
*
|
|
69
|
+
* @defaultValue false
|
|
70
|
+
*/
|
|
71
|
+
literalTuples?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Maximum nesting depth to prevent stack overflow
|
|
74
|
+
*
|
|
75
|
+
* @defaultValue 10
|
|
76
|
+
*/
|
|
77
|
+
maxDepth?: number;
|
|
78
|
+
/**
|
|
79
|
+
* Whether to allow mixed types in arrays
|
|
80
|
+
*
|
|
81
|
+
* If {@link literalTuples} is `true`, this option is ignored and treated as
|
|
82
|
+
* `false`.
|
|
83
|
+
*
|
|
84
|
+
* @defaultValue false
|
|
85
|
+
*/
|
|
86
|
+
noMixedArrays?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* If `true`, will disallow unknown properties in parsed objects
|
|
89
|
+
*
|
|
90
|
+
* @defaultValue false
|
|
91
|
+
*/
|
|
92
|
+
strict?: boolean;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Predefined options for {@link valueToSchema} optimized for object satisfaction
|
|
96
|
+
* checks.
|
|
97
|
+
*
|
|
98
|
+
* Uses literal primitives and tuples for exact matching while allowing extra
|
|
99
|
+
* properties.
|
|
100
|
+
*/
|
|
101
|
+
export declare const valueToSchemaOptionsForSatisfies: Readonly<{
|
|
102
|
+
readonly literalEmptyObjects: true;
|
|
103
|
+
readonly literalPrimitives: true;
|
|
104
|
+
readonly literalRegExp: false;
|
|
105
|
+
readonly literalTuples: true;
|
|
106
|
+
readonly strict: false;
|
|
107
|
+
}>;
|
|
108
|
+
/**
|
|
109
|
+
* Predefined options for {@link valueToSchema} optimized for deep equality
|
|
110
|
+
* checks.
|
|
111
|
+
*
|
|
112
|
+
* Uses literal primitives, regexp, and tuples with strict validation for exact
|
|
113
|
+
* matching.
|
|
114
|
+
*/
|
|
115
|
+
export declare const valueToSchemaOptionsForDeepEqual: Readonly<{
|
|
116
|
+
readonly literalEmptyObjects: true;
|
|
117
|
+
readonly literalPrimitives: true;
|
|
118
|
+
readonly literalRegExp: true;
|
|
119
|
+
readonly literalTuples: true;
|
|
120
|
+
readonly strict: true;
|
|
121
|
+
}>;
|
|
122
|
+
//# sourceMappingURL=value-to-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value-to-schema.d.ts","sourceRoot":"","sources":["../../src/value-to-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAgB3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,eAAO,MAAM,aAAa,GACxB,OAAO,OAAO,EACd,UAAS,oBAAyB,EAClC,yBAA+B,KAC9B,CAAC,CAAC,OAAO,CAAC,GAAG,CAmTf,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IAQnC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC;;;;;;EAMH,CAAC;AAE3C;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC;;;;;;EAMH,CAAC"}
|