Skip to content

Commit

Permalink
0.7.1
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobWeisenburger committed Mar 11, 2023
1 parent 7b81f41 commit 28fb496
Show file tree
Hide file tree
Showing 10 changed files with 284 additions and 25 deletions.
7 changes: 5 additions & 2 deletions build_npm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ await emptyDir( './npm' )
await build( {
package: {
name: 'zod_utilz',
version: '0.7.0',
version: '0.7.1',
author: 'JacobWeisenburger',
description: 'Framework agnostic utilities for Zod',
license: 'MIT',
Expand All @@ -15,10 +15,13 @@ await build( {
repository: 'https://github.com/JacobWeisenburger/zod_utilz',
homepage: 'https://github.com/JacobWeisenburger/zod_utilz',
},
typeCheck: false,
test: false,
skipSourceOutput: true,
entryPoints: [ './mod.ts' ],
importMap: './import_map.json',
outDir: './npm',
shims: { deno: true, undici: true },
shims: { undici: true },
mappings: {
'https://deno.land/x/zod@v3.21.4/mod.ts': {
name: 'zod',
Expand Down
176 changes: 176 additions & 0 deletions deno.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion import_map.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"@type-challenges/utils": "npm:@type-challenges/utils",
"tsd": "npm:tsd@0.25.0",
"zod": "https://deno.land/x/zod@v3.21.4/mod.ts",
"lodash": "https://cdn.skypack.dev/lodash?dts",
"dnt": "https://deno.land/x/dnt@0.33.0/mod.ts",
"std/": "https://deno.land/std@0.167.0/",
"path": "https://deno.land/std@0.150.0/path/mod.ts",
Expand Down
12 changes: 12 additions & 0 deletions src/lib/mapValues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
type ObjectIterator<Obj, Result> =
( value: Obj[ keyof Obj ], key: string, collection: Obj ) => Result

export const mapValues = <Obj extends object, Result>
( fn: ObjectIterator<Obj, Result> ) => ( obj?: Obj ) => {
if ( !obj ) return {}
const map = Object.keys( obj ).reduce( ( map, key ) => {
map.set( key, fn( obj[ key ], key, obj ) )
return map
}, new Map )
return Object.fromEntries( map )
}
8 changes: 8 additions & 0 deletions src/lib/omit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const omit = <Obj extends Record<string, unknown>>
( obj: Obj, keys: ( keyof Obj | string )[] ) => {
if ( keys.length === 0 ) return obj
const entries = Object.entries( obj ) as [ keyof Obj, unknown ][]
return Object.fromEntries(
entries.filter( ( [ key ] ) => !keys.includes( key ) )
)
}
23 changes: 23 additions & 0 deletions src/lib/omit_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { omit } from './omit.ts'
import { assertEquals } from 'std/testing/asserts.ts'

const obj = {
foo: 'foo',
bar: 42,
baz: true,
}

Deno.test( 'omit', () => {
assertEquals(
omit( obj, [] ),
obj
)
assertEquals(
omit( obj, [ 'foo' ] ),
{ bar: 42, baz: true }
)
assertEquals(
omit( obj, [ 'foo', 'bar' ] ),
{ baz: true }
)
} )
8 changes: 8 additions & 0 deletions src/lib/pick.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const pick = <Obj extends Record<string, unknown>>
( obj: Obj, keys: ( keyof Obj )[] ) => {
if ( keys.length === 0 ) return {}
const entries = Object.entries( obj ) as [ keyof Obj, unknown ][]
return Object.fromEntries(
entries.filter( ( [ key ] ) => keys.includes( key ) )
)
}
23 changes: 23 additions & 0 deletions src/lib/pick_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { pick } from './pick.ts'
import { assertEquals } from 'std/testing/asserts.ts'

const obj = {
foo: 'foo',
bar: 42,
baz: true,
}

Deno.test( 'pick', () => {
assertEquals(
pick( obj, [] ),
{}
)
assertEquals(
pick( obj, [ 'foo' ] ),
{ foo: 'foo' }
)
assertEquals(
pick( obj, [ 'foo', 'bar' ] ),
{ foo: 'foo', bar: 42 }
)
} )
10 changes: 6 additions & 4 deletions src/partialSafeParse.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { z } from 'zod'
import { mapValues, omit, pick } from 'lodash'
import { zu } from '../mod.ts'
import { mapValues } from './lib/mapValues.ts'
import { pick } from './lib/pick.ts'
import { omit } from './lib/omit.ts'

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

const validData = schema
.omit( mapValues( fieldErrors, () => true as const ) )
.parse( validInput )
.omit( mapValues( () => true )( fieldErrors ) )
.parse( validInput ) as Partial<z.infer<Schema>>

return {
...result,
Expand Down
41 changes: 23 additions & 18 deletions src/partialSafeParse_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,28 @@ Deno.test( 'partialSafeParse', async t => {
)
} )

await t.step( `Readme Example`, () => {
const userSchema = z.object( { name: z.string(), age: z.number() } )
const result = zu.partialSafeParse( userSchema, { name: null, age: 42 } )
assertObjectMatch(
result,
{
successType: 'partial',
validData: { age: 42 },
invalidData: { name: null },
}
)
assertEquals(
result.error?.flatten().fieldErrors ?? {},
{
name: [ 'Expected string, received null' ],
}
)
} )




// await t.step( `with useURLSearchParams`, () => {
// const params = new URLSearchParams( 'foo=foo&bar=42' )
// const schema = zu.useURLSearchParams(
Expand Down Expand Up @@ -122,23 +144,6 @@ Deno.test( 'partialSafeParse', async t => {
// // )
// } )

await t.step( `Readme Example`, () => {
const userSchema = z.object( { name: z.string(), age: z.number() } )
const result = zu.partialSafeParse( userSchema, { name: null, age: 42 } )
assertObjectMatch(
result,
{
successType: 'partial',
validData: { age: 42 },
invalidData: { name: null },
}
)
assertEquals(
result.error?.flatten().fieldErrors ?? {},
{
name: [ 'Expected string, received null' ],
}
)
} )


} )

0 comments on commit 28fb496

Please sign in to comment.