zodselect 1.0.11 → 1.0.13
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,19 @@
|
|
|
1
|
+
import { ZodType, ZodUnion } from 'zod';
|
|
2
|
+
import { ZodSelect } from './select.js';
|
|
3
|
+
export type ZodSelectAll<T extends ZodType<object> | ZodUnion> = {
|
|
4
|
+
[K in keyof ZodSelect<T, true>]-?: true;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Produces a runtime select-all object for the given Zod schema.
|
|
8
|
+
*
|
|
9
|
+
* Every top-level key is set to `true`, which tells the server to include
|
|
10
|
+
* that field in the response. For union schemas the result is the merged
|
|
11
|
+
* set of keys across all variants.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const select = buildSelectObject(AuthenticationService);
|
|
16
|
+
* // { name: true, type: true, isEnabled: true, ... }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildSelectObject<T extends ZodType<object> | ZodUnion>(schema: T): ZodSelectAll<T>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getInnerType, isZodObject, isZodUnion } from './utilities.js';
|
|
2
|
+
/**
|
|
3
|
+
* Produces a runtime select-all object for the given Zod schema.
|
|
4
|
+
*
|
|
5
|
+
* Every top-level key is set to `true`, which tells the server to include
|
|
6
|
+
* that field in the response. For union schemas the result is the merged
|
|
7
|
+
* set of keys across all variants.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const select = buildSelectObject(AuthenticationService);
|
|
12
|
+
* // { name: true, type: true, isEnabled: true, ... }
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export function buildSelectObject(schema) {
|
|
16
|
+
const result = {};
|
|
17
|
+
collectKeys(schema, result);
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
function collectKeys(schema, result) {
|
|
21
|
+
schema = getInnerType(schema);
|
|
22
|
+
if (isZodObject(schema)) {
|
|
23
|
+
for (const key in schema.shape) {
|
|
24
|
+
result[key] = true;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
else if (isZodUnion(schema)) {
|
|
28
|
+
for (const option of schema.options) {
|
|
29
|
+
collectKeys(option, result);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else if (schema.def.type === 'intersection') {
|
|
33
|
+
collectKeys(schema.def.left, result);
|
|
34
|
+
collectKeys(schema.def.right, result);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { strict as assert } from 'assert';
|
|
2
|
+
import { describe, it } from 'node:test';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { buildSelectObject } from './build-select-object.js';
|
|
5
|
+
describe('.buildSelectObject()', () => {
|
|
6
|
+
it('should return all keys set to true for a flat object', () => {
|
|
7
|
+
const schema = z.object({
|
|
8
|
+
age: z.number(),
|
|
9
|
+
name: z.string()
|
|
10
|
+
});
|
|
11
|
+
assert.deepStrictEqual(buildSelectObject(schema), { age: true, name: true });
|
|
12
|
+
});
|
|
13
|
+
it('should merge keys from all union members', () => {
|
|
14
|
+
const schema = z.union([
|
|
15
|
+
z.object({ type: z.literal('a'), valueA: z.string() }),
|
|
16
|
+
z.object({ type: z.literal('b'), valueB: z.number() })
|
|
17
|
+
]);
|
|
18
|
+
assert.deepStrictEqual(buildSelectObject(schema), {
|
|
19
|
+
type: true,
|
|
20
|
+
valueA: true,
|
|
21
|
+
valueB: true
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
it('should merge keys from an intersection', () => {
|
|
25
|
+
const schema = z.intersection(z.object({ a: z.string() }), z.object({ b: z.number() }));
|
|
26
|
+
assert.deepStrictEqual(buildSelectObject(schema), { a: true, b: true });
|
|
27
|
+
});
|
|
28
|
+
it('should unwrap optional/nullable wrappers', () => {
|
|
29
|
+
const inner = z.object({ id: z.string(), value: z.number() });
|
|
30
|
+
const schema = inner.optional();
|
|
31
|
+
assert.deepStrictEqual(buildSelectObject(schema), { id: true, value: true });
|
|
32
|
+
});
|
|
33
|
+
it('should unwrap lazy schemas', () => {
|
|
34
|
+
const schema = z.lazy(() => z.object({ bar: z.number(), foo: z.string() }));
|
|
35
|
+
assert.deepStrictEqual(buildSelectObject(schema), { bar: true, foo: true });
|
|
36
|
+
});
|
|
37
|
+
it('should handle nested unions inside intersection', () => {
|
|
38
|
+
const schema = z.intersection(z.union([
|
|
39
|
+
z.object({ a: z.string() }),
|
|
40
|
+
z.object({ b: z.number() })
|
|
41
|
+
]), z.object({ c: z.boolean() }));
|
|
42
|
+
assert.deepStrictEqual(buildSelectObject(schema), {
|
|
43
|
+
a: true,
|
|
44
|
+
b: true,
|
|
45
|
+
c: true
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
it('should only collect top-level keys (not nested)', () => {
|
|
49
|
+
const schema = z.object({
|
|
50
|
+
active: z.boolean(),
|
|
51
|
+
user: z.object({
|
|
52
|
+
age: z.number(),
|
|
53
|
+
name: z.string()
|
|
54
|
+
})
|
|
55
|
+
});
|
|
56
|
+
assert.deepStrictEqual(buildSelectObject(schema), { active: true, user: true });
|
|
57
|
+
});
|
|
58
|
+
});
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zodselect",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "Type-safe selection utility built on top of Zod. Allows for strongly typed field selection, schema merging, and runtime refinement for frontend or backend use.",
|
|
5
5
|
"author": "SecureDataSystems",
|
|
6
6
|
"license": "MIT",
|