Skip to content

Commit 28fb496

Browse files
0.7.1
1 parent 7b81f41 commit 28fb496

File tree

10 files changed

+284
-25
lines changed

10 files changed

+284
-25
lines changed

build_npm.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ await emptyDir( './npm' )
66
await build( {
77
package: {
88
name: 'zod_utilz',
9-
version: '0.7.0',
9+
version: '0.7.1',
1010
author: 'JacobWeisenburger',
1111
description: 'Framework agnostic utilities for Zod',
1212
license: 'MIT',
@@ -15,10 +15,13 @@ await build( {
1515
repository: 'https://github.com/JacobWeisenburger/zod_utilz',
1616
homepage: 'https://github.com/JacobWeisenburger/zod_utilz',
1717
},
18+
typeCheck: false,
19+
test: false,
20+
skipSourceOutput: true,
1821
entryPoints: [ './mod.ts' ],
1922
importMap: './import_map.json',
2023
outDir: './npm',
21-
shims: { deno: true, undici: true },
24+
shims: { undici: true },
2225
mappings: {
2326
'https://deno.land/x/zod@v3.21.4/mod.ts': {
2427
name: 'zod',

deno.lock

Lines changed: 176 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

import_map.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
"@type-challenges/utils": "npm:@type-challenges/utils",
44
"tsd": "npm:tsd@0.25.0",
55
"zod": "https://deno.land/x/zod@v3.21.4/mod.ts",
6-
"lodash": "https://cdn.skypack.dev/lodash?dts",
76
"dnt": "https://deno.land/x/dnt@0.33.0/mod.ts",
87
"std/": "https://deno.land/std@0.167.0/",
98
"path": "https://deno.land/std@0.150.0/path/mod.ts",

src/lib/mapValues.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
type ObjectIterator<Obj, Result> =
2+
( value: Obj[ keyof Obj ], key: string, collection: Obj ) => Result
3+
4+
export const mapValues = <Obj extends object, Result>
5+
( fn: ObjectIterator<Obj, Result> ) => ( obj?: Obj ) => {
6+
if ( !obj ) return {}
7+
const map = Object.keys( obj ).reduce( ( map, key ) => {
8+
map.set( key, fn( obj[ key ], key, obj ) )
9+
return map
10+
}, new Map )
11+
return Object.fromEntries( map )
12+
}

src/lib/omit.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const omit = <Obj extends Record<string, unknown>>
2+
( obj: Obj, keys: ( keyof Obj | string )[] ) => {
3+
if ( keys.length === 0 ) return obj
4+
const entries = Object.entries( obj ) as [ keyof Obj, unknown ][]
5+
return Object.fromEntries(
6+
entries.filter( ( [ key ] ) => !keys.includes( key ) )
7+
)
8+
}

src/lib/omit_test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { omit } from './omit.ts'
2+
import { assertEquals } from 'std/testing/asserts.ts'
3+
4+
const obj = {
5+
foo: 'foo',
6+
bar: 42,
7+
baz: true,
8+
}
9+
10+
Deno.test( 'omit', () => {
11+
assertEquals(
12+
omit( obj, [] ),
13+
obj
14+
)
15+
assertEquals(
16+
omit( obj, [ 'foo' ] ),
17+
{ bar: 42, baz: true }
18+
)
19+
assertEquals(
20+
omit( obj, [ 'foo', 'bar' ] ),
21+
{ baz: true }
22+
)
23+
} )

src/lib/pick.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const pick = <Obj extends Record<string, unknown>>
2+
( obj: Obj, keys: ( keyof Obj )[] ) => {
3+
if ( keys.length === 0 ) return {}
4+
const entries = Object.entries( obj ) as [ keyof Obj, unknown ][]
5+
return Object.fromEntries(
6+
entries.filter( ( [ key ] ) => keys.includes( key ) )
7+
)
8+
}

src/lib/pick_test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { pick } from './pick.ts'
2+
import { assertEquals } from 'std/testing/asserts.ts'
3+
4+
const obj = {
5+
foo: 'foo',
6+
bar: 42,
7+
baz: true,
8+
}
9+
10+
Deno.test( 'pick', () => {
11+
assertEquals(
12+
pick( obj, [] ),
13+
{}
14+
)
15+
assertEquals(
16+
pick( obj, [ 'foo' ] ),
17+
{ foo: 'foo' }
18+
)
19+
assertEquals(
20+
pick( obj, [ 'foo', 'bar' ] ),
21+
{ foo: 'foo', bar: 42 }
22+
)
23+
} )

src/partialSafeParse.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { z } from 'zod'
2-
import { mapValues, omit, pick } from 'lodash'
32
import { zu } from '../mod.ts'
3+
import { mapValues } from './lib/mapValues.ts'
4+
import { pick } from './lib/pick.ts'
5+
import { omit } from './lib/omit.ts'
46

57
/**
68
partialSafeParse allows you to get the valid fields even if there was an error in another field
@@ -45,11 +47,11 @@ export function partialSafeParse<Schema extends z.AnyZodObject> (
4547
const inputObj = input as z.infer<Schema>
4648
const keysWithInvalidData = Object.keys( fieldErrors ?? {} )
4749
const validInput = omit( inputObj, keysWithInvalidData )
48-
const invalidData = pick( inputObj, keysWithInvalidData )
50+
const invalidData = pick( inputObj, keysWithInvalidData ) as Partial<z.infer<Schema>>
4951

5052
const validData = schema
51-
.omit( mapValues( fieldErrors, () => true as const ) )
52-
.parse( validInput )
53+
.omit( mapValues( () => true )( fieldErrors ) )
54+
.parse( validInput ) as Partial<z.infer<Schema>>
5355

5456
return {
5557
...result,

src/partialSafeParse_test.ts

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,28 @@ Deno.test( 'partialSafeParse', async t => {
9595
)
9696
} )
9797

98+
await t.step( `Readme Example`, () => {
99+
const userSchema = z.object( { name: z.string(), age: z.number() } )
100+
const result = zu.partialSafeParse( userSchema, { name: null, age: 42 } )
101+
assertObjectMatch(
102+
result,
103+
{
104+
successType: 'partial',
105+
validData: { age: 42 },
106+
invalidData: { name: null },
107+
}
108+
)
109+
assertEquals(
110+
result.error?.flatten().fieldErrors ?? {},
111+
{
112+
name: [ 'Expected string, received null' ],
113+
}
114+
)
115+
} )
116+
117+
118+
119+
98120
// await t.step( `with useURLSearchParams`, () => {
99121
// const params = new URLSearchParams( 'foo=foo&bar=42' )
100122
// const schema = zu.useURLSearchParams(
@@ -122,23 +144,6 @@ Deno.test( 'partialSafeParse', async t => {
122144
// // )
123145
// } )
124146

125-
await t.step( `Readme Example`, () => {
126-
const userSchema = z.object( { name: z.string(), age: z.number() } )
127-
const result = zu.partialSafeParse( userSchema, { name: null, age: 42 } )
128-
assertObjectMatch(
129-
result,
130-
{
131-
successType: 'partial',
132-
validData: { age: 42 },
133-
invalidData: { name: null },
134-
}
135-
)
136-
assertEquals(
137-
result.error?.flatten().fieldErrors ?? {},
138-
{
139-
name: [ 'Expected string, received null' ],
140-
}
141-
)
142-
} )
147+
143148

144149
} )

0 commit comments

Comments
 (0)