Skip to content

Commit 663cf4f

Browse files
authored
refactor!: move parse and safeParse to top level and rename ~build to build (#15)
1 parent f89b729 commit 663cf4f

28 files changed

Lines changed: 447 additions & 352 deletions

packages/bench/bench/number.bench.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ const invalidNumber = 142
1313
const spurAsyncUnbuild = spurNumberAsync().min(0).max(100)
1414

1515
// Spur async schemas (with constraints)
16-
const spurAsyncBuilt = await (spurNumberAsync().min(0).max(100))['~build']()
16+
const spurAsyncBuilt = await (spurNumberAsync().min(0).max(100)).build()
1717

1818
// Spur sync schemas (with constraints)
19-
const spurSyncBuilt = spurNumberSync().min(0).max(100)['~build']()
19+
const spurSyncBuilt = spurNumberSync().min(0).max(100).build()
2020

2121
// Spur inline schemas (with constraints)
22-
const spurInlineBuilt = await spurNumberInline().min(0).max(100)['~build']()
22+
const spurInlineBuilt = await spurNumberInline().min(0).max(100).build()
2323

2424
// Zod schemas (with constraints)
2525
const zValid = z.number().min(0).max(100)

packages/bench/bench/string.bench.ts

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { safeParse as safeParseAsync, string as spurStringAsync } from 'spur'
2-
import { safeParse as safeParseInlined, string as spurStringInline } from 'spur/inline'
3-
import { safeParse as safeParseSync, string as spurStringSync } from 'spur/sync'
1+
import { string as spurStringAsync } from 'spur'
2+
import { string as spurStringInline } from 'spur/inline'
43

54
import * as v from 'valibot'
65
import { bench, describe } from 'vitest'
@@ -13,13 +12,10 @@ const invalidString = 'a'
1312
const spurAsyncUnbuild = spurStringAsync().minLength(3).maxLength(12)
1413

1514
// Async spur schemas (built once)
16-
const spurAsyncBuilt = await spurStringAsync().minLength(3).maxLength(12)['~build']()
17-
18-
// Sync spur schemas
19-
const spurSyncBuilt = spurStringSync().minLength(3).maxLength(12)['~build']()
15+
const spurAsyncBuilt = await spurStringAsync().minLength(3).maxLength(12).build()
2016

2117
// Inline spur schemas
22-
const spurInlineBuilt = await spurStringInline().minLength(3).maxLength(12)['~build']()
18+
const spurInlineBuilt = await spurStringInline().minLength(3).maxLength(12).build()
2319

2420
// Zod
2521
const zValid = z.string().min(3).max(12)
@@ -29,16 +25,13 @@ const vSchema = v.pipe(v.string(), v.minLength(3), v.maxLength(12))
2925

3026
describe('string: valid parse', () => {
3127
bench('spur unbuild async valid', () => {
32-
safeParseAsync(spurAsyncUnbuild, validString)
28+
spurAsyncUnbuild.safeParse(validString)
3329
})
3430
bench('spur async valid', () => {
35-
safeParseAsync(spurAsyncBuilt, validString)
36-
})
37-
bench('spur sync valid', () => {
38-
safeParseSync(spurSyncBuilt, validString)
31+
spurAsyncBuilt.safeParse(validString)
3932
})
4033
bench('spur inline valid', () => {
41-
safeParseInlined(spurInlineBuilt, validString)
34+
spurInlineBuilt.safeParse(validString)
4235
})
4336
bench('zod valid', () => {
4437
zValid.safeParse(validString)
@@ -50,16 +43,13 @@ describe('string: valid parse', () => {
5043

5144
describe('string: invalid parse', () => {
5245
bench('spur unbuild async invalid', () => {
53-
safeParseAsync(spurAsyncUnbuild, invalidString)
46+
spurAsyncUnbuild.safeParse(validString)
5447
})
5548
bench('spur async invalid', () => {
56-
safeParseAsync(spurAsyncBuilt, invalidString)
57-
})
58-
bench('spur sync invalid', () => {
59-
safeParseSync(spurSyncBuilt, invalidString)
49+
spurAsyncBuilt.safeParse(validString)
6050
})
6151
bench('spur inline invalid', () => {
62-
safeParseInlined(spurInlineBuilt, invalidString)
52+
spurInlineBuilt.safeParse(invalidString)
6353
})
6454
bench('zod invalid', () => {
6555
zValid.safeParse(invalidString)
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { describe, expect, it } from 'vitest'
22

3-
import { parse, safeParse } from '../../index'
43
import { array } from '../../leitplanken/array'
54
import { number } from '../../leitplanken/number'
65
import { string } from '../../leitplanken/string'
@@ -9,35 +8,35 @@ describe('array schema', () => {
98
it('parses arrays when every element matches the child schema', async () => {
109
const schema = array(string().minLength(2))
1110

12-
await expect(parse(schema, ['hi', 'there'])).resolves.toEqual(['hi', 'there'])
11+
await expect(schema.parse(['hi', 'there'])).resolves.toEqual(['hi', 'there'])
1312
})
1413

1514
it('fails when at least one element violates the child schema', async () => {
1615
const schema = array(number().min(0))
1716

18-
const report = await safeParse(schema, [1, -1])
17+
const report = await schema.safeParse([1, -1])
1918

2019
expect(report.passed).toBe(false)
2120
})
2221

2322
it('supports optional modifier on the array schema', async () => {
2423
const schema = array(string()).optional()
2524

26-
const report = await safeParse(schema, undefined)
25+
const report = await schema.safeParse(undefined)
2726
expect(report.passed).toBe(true)
2827
expect(report.value).toBeUndefined()
2928
})
3029

3130
it('enforces array-level minLength constraint', async () => {
3231
const schema = array(string()).minLength(2)
3332

34-
const report = await safeParse(schema, ['only-one'])
33+
const report = await schema.safeParse(['only-one'])
3534
expect(report.passed).toBe(false)
3635
})
3736

3837
it('allows transforming the parsed array result', async () => {
3938
const schema = array(number()).transform(values => values.reduce((total, value) => total + value, 0))
4039

41-
await expect(parse(schema, [1, 2, 3])).resolves.toBe(6)
40+
await expect(schema.parse([1, 2, 3])).resolves.toBe(6)
4241
})
4342
})
Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import { describe, expect, it } from 'vitest'
22

3-
import { boolean, parse, safeParse } from '../../index'
3+
import { boolean } from '../../index'
44

55
describe('boolean schema', () => {
66
it('accepts boolean values', async () => {
77
const schema = boolean()
88

9-
await expect(parse(schema, true)).resolves.toBe(true)
10-
await expect(parse(schema, false)).resolves.toBe(false)
9+
await expect(schema.parse(true)).resolves.toBe(true)
10+
await expect(schema.parse(false)).resolves.toBe(false)
1111
})
1212

1313
it('rejects non-boolean values', async () => {
1414
const schema = boolean()
15-
const report = await safeParse(schema, 'not-boolean')
15+
const report = await schema.safeParse('not-boolean')
1616

1717
expect(report.passed).toBe(false)
1818
expect('value' in report).toBe(false)
@@ -21,22 +21,22 @@ describe('boolean schema', () => {
2121
it('supports optional modifier', async () => {
2222
const schema = boolean().optional()
2323

24-
const hit = await safeParse(schema, true)
24+
const hit = await schema.safeParse(true)
2525
expect(hit.passed).toBe(true)
2626
expect(hit.value).toBe(true)
2727

28-
const optionalReport = await safeParse(schema, undefined)
28+
const optionalReport = await schema.safeParse(undefined)
2929
expect(optionalReport.passed).toBe(true)
3030
expect(optionalReport.value).toBeUndefined()
3131

32-
const nullReport = await safeParse(schema, null)
32+
const nullReport = await schema.safeParse(null)
3333
expect(nullReport.passed).toBe(false)
3434
})
3535

3636
it('supports exactOptional modifier', async () => {
3737
const schema = boolean().exactOptional()
3838

39-
const report = await safeParse(schema, undefined)
39+
const report = await schema.safeParse(undefined)
4040
expect(report.passed).toBe(true)
4141
if (report.passed) {
4242
expect(report.value).toBeUndefined()
@@ -46,68 +46,68 @@ describe('boolean schema', () => {
4646
it('supports undefinable modifier', async () => {
4747
const schema = boolean().undefinable()
4848

49-
const undefReport = await safeParse(schema, undefined)
49+
const undefReport = await schema.safeParse(undefined)
5050
expect(undefReport.passed).toBe(true)
5151
expect(undefReport.value).toBeUndefined()
5252

53-
const nullReport = await safeParse(schema, null)
53+
const nullReport = await schema.safeParse(null)
5454
expect(nullReport.passed).toBe(false)
5555
})
5656

5757
it('supports nullable modifier', async () => {
5858
const schema = boolean().nullable()
5959

60-
const nullReport = await safeParse(schema, null)
60+
const nullReport = await schema.safeParse(null)
6161
expect(nullReport.passed).toBe(true)
6262
expect(nullReport.value).toBeNull()
6363

64-
const undefinedReport = await safeParse(schema, undefined)
64+
const undefinedReport = await schema.safeParse(undefined)
6565
expect(undefinedReport.passed).toBe(false)
6666
})
6767

6868
it('supports nullish modifier', async () => {
6969
const schema = boolean().nullish()
7070

71-
const undefinedReport = await safeParse(schema, undefined)
71+
const undefinedReport = await schema.safeParse(undefined)
7272
expect(undefinedReport.passed).toBe(true)
7373
expect(undefinedReport.value).toBeUndefined()
7474

75-
const nullReport = await safeParse(schema, null)
75+
const nullReport = await schema.safeParse(null)
7676
expect(nullReport.passed).toBe(true)
7777
expect(nullReport.value).toBeNull()
7878
})
7979

8080
it('supports default modifier', async () => {
8181
const schema = boolean().default(true)
8282

83-
await expect(parse(schema, undefined)).resolves.toBe(true)
84-
await expect(parse(schema, null)).resolves.toBe(true)
85-
await expect(parse(schema, false)).resolves.toBe(false)
83+
await expect(schema.parse(undefined)).resolves.toBe(true)
84+
await expect(schema.parse(null)).resolves.toBe(true)
85+
await expect(schema.parse(false)).resolves.toBe(false)
8686
})
8787

8888
it('applies required after optional', async () => {
8989
const schema = boolean().optional().required()
9090

91-
const report = await safeParse(schema, undefined)
91+
const report = await schema.safeParse(undefined)
9292
expect(report.passed).toBe(false)
9393
})
9494

9595
it('uses last optionality modifier wins semantics', async () => {
9696
const optionalThenNullable = boolean().optional().nullable()
9797
const nullableThenOptional = boolean().nullable().optional()
9898

99-
const optionalThenNullableNull = await safeParse(optionalThenNullable, null)
99+
const optionalThenNullableNull = await optionalThenNullable.safeParse(null)
100100
expect(optionalThenNullableNull.passed).toBe(true)
101101
expect(optionalThenNullableNull.value).toBeNull()
102102

103-
const optionalThenNullableUndefined = await safeParse(optionalThenNullable, undefined)
103+
const optionalThenNullableUndefined = await optionalThenNullable.safeParse(undefined)
104104
expect(optionalThenNullableUndefined.passed).toBe(false)
105105

106-
const nullableThenOptionalUndefined = await safeParse(nullableThenOptional, undefined)
106+
const nullableThenOptionalUndefined = await nullableThenOptional.safeParse(undefined)
107107
expect(nullableThenOptionalUndefined.passed).toBe(true)
108108
expect(nullableThenOptionalUndefined.value).toBeUndefined()
109109

110-
const nullableThenOptionalNull = await safeParse(nullableThenOptional, null)
110+
const nullableThenOptionalNull = await nullableThenOptional.safeParse(null)
111111
expect(nullableThenOptionalNull.passed).toBe(false)
112112
})
113113
})

0 commit comments

Comments
 (0)