Skip to content

Commit 84ebe71

Browse files
committed
test: keep every arbitrary in one file
The arbitraries were split across four files only because a module may import ten others, which is a rule about keeping a utility focused and says nothing useful about a test helper whose job is to assemble valid documents out of the check-digit internals. They are one file again, and the cap is off for the test helpers.
1 parent f94463d commit 84ebe71

35 files changed

Lines changed: 661 additions & 492 deletions

‎CONTRIBUTING.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ example `formatSomething`):
151151
block of [fast-check](https://fast-check.dev) properties that hold by specification (a
152152
generated value is valid, format/parse round-trip, masks never change the verdict, arbitrary
153153
input never throws); a property that needs a valid document draws it with `fc.gen()` from the
154-
arbitraries in `src/_internals/test/` (`const cpf = g(cpfs)`, from `document-arbitraries.ts` and
155-
its siblings), never by calling a `generate*` utility inside the property: those use
154+
arbitraries of `src/_internals/test/arbitraries.ts` (`const cpf = g(cpfs)`), never by calling a
155+
`generate*` utility inside the property: those use
156156
`Math.random()`, which the seed fast-check reports does not control, so a failure could be
157157
neither replayed nor shrunk. Then a `describe("<name> types")` block that pins the public signature with
158158
`expectTypeOf` (parameters, options and return type; `vp check` fails on a wrong assertion). A

‎docs/_sidebar.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
* [Document field](guides/document-field.md)
55
* [Address from a CEP](guides/address-form.md)
66
* [State and city](guides/state-city.md)
7+
* [A schema for a document](guides/schema.md)
78
* [Migration v1 to v2](migration-v1-to-v2.md)

‎docs/guides/document-field.md‎

Lines changed: 3 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@ description: "A field that masks and validates a CPF, CNPJ, CEP or phone number
44
keywords: ["CPF input mask", "CNPJ mask", "CEP mask", "phone mask", "React CPF", "Angular CPF", "Vue CPF", "validate CPF"]
55
---
66

7-
A field that formats as you type, inside a form that validates. Pick the document and the framework: each example is only about that document, and runs the code below it, which you can copy as is.
8-
9-
The field only masks. It hands the form the value without its mask, with `parse*`, so the form holds `52998224725` and a submit sends that, and it shows the value back formatted. Validation belongs to the form, where the rest of the form's rules live, which also leaves one error message per field instead of two.
10-
11-
The `mask` function is the same in all of them, and it is all a mask needs. A formatter takes whatever has been typed so far, so it can run on every keystroke; replacing a field's value moves the caret to the end, so `mask` puts the caret back next to the character being edited. Formatting what comes before the caret is what says where it goes. A deleted separator becomes a deleted character, which the formatter would otherwise put straight back.
7+
A field that formats as you type, inside a form that validates. Pick the document and the framework: each example runs the code below it, which you can copy as is.
128

9+
The field only masks, and hands the form the value without its mask, with `parse*`, so a form holds `52998224725` and a submit sends that. Validation belongs to the form, which also leaves one error message per field instead of two. The mask is the same everywhere: a formatter takes whatever has been typed so far, and formatting what comes before the caret says where the caret goes, so editing in the middle works.
1310

1411
<div class="example" data-name="React">
1512

@@ -411,122 +408,4 @@ No build step: save it as an `.html` file and open it. It imports the package fr
411408

412409
</div>
413410

414-
<div class="example" data-name="Schema">
415-
416-
No demo here: a schema is the same code everywhere. Any of these plugs into the form libraries of the other tabs through [Standard Schema](https://standardschema.dev), which all of them speak, and `toStandardSchema` gives one field the same interface with no schema library at all:
417-
418-
<div class="variant" data-variant="CPF">
419-
420-
<div class="file" data-file="cpf-zod.ts">
421-
422-
[cpf-zod.ts](../snippets/document-field/generated/cpf/schema/cpf-zod.ts ':include :type=code ts')
423-
424-
</div>
425-
426-
<div class="file" data-file="cpf-valibot.ts">
427-
428-
[cpf-valibot.ts](../snippets/document-field/generated/cpf/schema/cpf-valibot.ts ':include :type=code ts')
429-
430-
</div>
431-
432-
<div class="file" data-file="cpf-arktype.ts">
433-
434-
[cpf-arktype.ts](../snippets/document-field/generated/cpf/schema/cpf-arktype.ts ':include :type=code ts')
435-
436-
</div>
437-
438-
<div class="file" data-file="cpf-standard.ts">
439-
440-
[cpf-standard.ts](../snippets/document-field/generated/cpf/schema/cpf-standard.ts ':include :type=code ts')
441-
442-
</div>
443-
444-
</div>
445-
446-
<div class="variant" data-variant="CNPJ">
447-
448-
<div class="file" data-file="cnpj-zod.ts">
449-
450-
[cnpj-zod.ts](../snippets/document-field/generated/cnpj/schema/cnpj-zod.ts ':include :type=code ts')
451-
452-
</div>
453-
454-
<div class="file" data-file="cnpj-valibot.ts">
455-
456-
[cnpj-valibot.ts](../snippets/document-field/generated/cnpj/schema/cnpj-valibot.ts ':include :type=code ts')
457-
458-
</div>
459-
460-
<div class="file" data-file="cnpj-arktype.ts">
461-
462-
[cnpj-arktype.ts](../snippets/document-field/generated/cnpj/schema/cnpj-arktype.ts ':include :type=code ts')
463-
464-
</div>
465-
466-
<div class="file" data-file="cnpj-standard.ts">
467-
468-
[cnpj-standard.ts](../snippets/document-field/generated/cnpj/schema/cnpj-standard.ts ':include :type=code ts')
469-
470-
</div>
471-
472-
</div>
473-
474-
<div class="variant" data-variant="CEP">
475-
476-
<div class="file" data-file="cep-zod.ts">
477-
478-
[cep-zod.ts](../snippets/document-field/generated/cep/schema/cep-zod.ts ':include :type=code ts')
479-
480-
</div>
481-
482-
<div class="file" data-file="cep-valibot.ts">
483-
484-
[cep-valibot.ts](../snippets/document-field/generated/cep/schema/cep-valibot.ts ':include :type=code ts')
485-
486-
</div>
487-
488-
<div class="file" data-file="cep-arktype.ts">
489-
490-
[cep-arktype.ts](../snippets/document-field/generated/cep/schema/cep-arktype.ts ':include :type=code ts')
491-
492-
</div>
493-
494-
<div class="file" data-file="cep-standard.ts">
495-
496-
[cep-standard.ts](../snippets/document-field/generated/cep/schema/cep-standard.ts ':include :type=code ts')
497-
498-
</div>
499-
500-
</div>
501-
502-
<div class="variant" data-variant="Phone">
503-
504-
<div class="file" data-file="phone-zod.ts">
505-
506-
[phone-zod.ts](../snippets/document-field/generated/phone/schema/phone-zod.ts ':include :type=code ts')
507-
508-
</div>
509-
510-
<div class="file" data-file="phone-valibot.ts">
511-
512-
[phone-valibot.ts](../snippets/document-field/generated/phone/schema/phone-valibot.ts ':include :type=code ts')
513-
514-
</div>
515-
516-
<div class="file" data-file="phone-arktype.ts">
517-
518-
[phone-arktype.ts](../snippets/document-field/generated/phone/schema/phone-arktype.ts ':include :type=code ts')
519-
520-
</div>
521-
522-
<div class="file" data-file="phone-standard.ts">
523-
524-
[phone-standard.ts](../snippets/document-field/generated/phone/schema/phone-standard.ts ':include :type=code ts')
525-
526-
</div>
527-
528-
</div>
529-
530-
</div>
531-
532-
The [utilities reference](utilities.md) lists every function.
411+
The [utilities reference](../utilities.md) lists every function.

‎docs/guides/schema.md‎

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
---
2+
title: "A schema for a document"
3+
description: "The validators of Brazilian Utils inside a Zod, Valibot or ArkType schema, or as a Standard Schema of their own."
4+
keywords: ["zod CPF", "valibot CPF", "arktype CPF", "Standard Schema", "toStandardSchema", "validate CNPJ schema"]
5+
---
6+
7+
A validator goes straight into a schema: pick the document and the schema library. Nothing runs here, a schema is the same code everywhere.
8+
9+
Each of these builds the document on its own first, so it can be reused wherever a schema needs it, and composes it into a form afterwards. They all speak [Standard Schema](https://standardschema.dev), which is how a schema reaches a form library, and `toStandardSchema` gives one validator that same interface with no schema library at all.
10+
11+
12+
<div class="example" data-name="Zod">
13+
14+
`refine` takes the validator as it is:
15+
16+
<div class="variant" data-variant="CPF">
17+
18+
<div class="file" data-file="cpf-zod.ts">
19+
20+
[cpf-zod.ts](../snippets/document-field/generated/cpf/schema/cpf-zod.ts ':include :type=code ts')
21+
22+
</div>
23+
24+
</div>
25+
26+
<div class="variant" data-variant="CNPJ">
27+
28+
<div class="file" data-file="cnpj-zod.ts">
29+
30+
[cnpj-zod.ts](../snippets/document-field/generated/cnpj/schema/cnpj-zod.ts ':include :type=code ts')
31+
32+
</div>
33+
34+
</div>
35+
36+
<div class="variant" data-variant="CEP">
37+
38+
<div class="file" data-file="cep-zod.ts">
39+
40+
[cep-zod.ts](../snippets/document-field/generated/cep/schema/cep-zod.ts ':include :type=code ts')
41+
42+
</div>
43+
44+
</div>
45+
46+
<div class="variant" data-variant="Phone">
47+
48+
<div class="file" data-file="phone-zod.ts">
49+
50+
[phone-zod.ts](../snippets/document-field/generated/phone/schema/phone-zod.ts ':include :type=code ts')
51+
52+
</div>
53+
54+
</div>
55+
56+
</div>
57+
58+
<div class="example" data-name="Valibot">
59+
60+
`check` takes the validator inside a pipe:
61+
62+
<div class="variant" data-variant="CPF">
63+
64+
<div class="file" data-file="cpf-valibot.ts">
65+
66+
[cpf-valibot.ts](../snippets/document-field/generated/cpf/schema/cpf-valibot.ts ':include :type=code ts')
67+
68+
</div>
69+
70+
</div>
71+
72+
<div class="variant" data-variant="CNPJ">
73+
74+
<div class="file" data-file="cnpj-valibot.ts">
75+
76+
[cnpj-valibot.ts](../snippets/document-field/generated/cnpj/schema/cnpj-valibot.ts ':include :type=code ts')
77+
78+
</div>
79+
80+
</div>
81+
82+
<div class="variant" data-variant="CEP">
83+
84+
<div class="file" data-file="cep-valibot.ts">
85+
86+
[cep-valibot.ts](../snippets/document-field/generated/cep/schema/cep-valibot.ts ':include :type=code ts')
87+
88+
</div>
89+
90+
</div>
91+
92+
<div class="variant" data-variant="Phone">
93+
94+
<div class="file" data-file="phone-valibot.ts">
95+
96+
[phone-valibot.ts](../snippets/document-field/generated/phone/schema/phone-valibot.ts ':include :type=code ts')
97+
98+
</div>
99+
100+
</div>
101+
102+
</div>
103+
104+
<div class="example" data-name="ArkType">
105+
106+
`narrow` takes it, and says what the value must be when it says no:
107+
108+
<div class="variant" data-variant="CPF">
109+
110+
<div class="file" data-file="cpf-arktype.ts">
111+
112+
[cpf-arktype.ts](../snippets/document-field/generated/cpf/schema/cpf-arktype.ts ':include :type=code ts')
113+
114+
</div>
115+
116+
</div>
117+
118+
<div class="variant" data-variant="CNPJ">
119+
120+
<div class="file" data-file="cnpj-arktype.ts">
121+
122+
[cnpj-arktype.ts](../snippets/document-field/generated/cnpj/schema/cnpj-arktype.ts ':include :type=code ts')
123+
124+
</div>
125+
126+
</div>
127+
128+
<div class="variant" data-variant="CEP">
129+
130+
<div class="file" data-file="cep-arktype.ts">
131+
132+
[cep-arktype.ts](../snippets/document-field/generated/cep/schema/cep-arktype.ts ':include :type=code ts')
133+
134+
</div>
135+
136+
</div>
137+
138+
<div class="variant" data-variant="Phone">
139+
140+
<div class="file" data-file="phone-arktype.ts">
141+
142+
[phone-arktype.ts](../snippets/document-field/generated/phone/schema/phone-arktype.ts ':include :type=code ts')
143+
144+
</div>
145+
146+
</div>
147+
148+
</div>
149+
150+
<div class="example" data-name="Standard Schema">
151+
152+
No schema library at all: `toStandardSchema` gives the validator the interface every form library speaks.
153+
154+
<div class="variant" data-variant="CPF">
155+
156+
<div class="file" data-file="cpf-standard.ts">
157+
158+
[cpf-standard.ts](../snippets/document-field/generated/cpf/schema/cpf-standard.ts ':include :type=code ts')
159+
160+
</div>
161+
162+
</div>
163+
164+
<div class="variant" data-variant="CNPJ">
165+
166+
<div class="file" data-file="cnpj-standard.ts">
167+
168+
[cnpj-standard.ts](../snippets/document-field/generated/cnpj/schema/cnpj-standard.ts ':include :type=code ts')
169+
170+
</div>
171+
172+
</div>
173+
174+
<div class="variant" data-variant="CEP">
175+
176+
<div class="file" data-file="cep-standard.ts">
177+
178+
[cep-standard.ts](../snippets/document-field/generated/cep/schema/cep-standard.ts ':include :type=code ts')
179+
180+
</div>
181+
182+
</div>
183+
184+
<div class="variant" data-variant="Phone">
185+
186+
<div class="file" data-file="phone-standard.ts">
187+
188+
[phone-standard.ts](../snippets/document-field/generated/phone/schema/phone-standard.ts ':include :type=code ts')
189+
190+
</div>
191+
192+
</div>
193+
194+
</div>
195+
196+
The [utilities reference](../utilities.md#tostandardschema) documents `toStandardSchema` and the types of the specification.

‎docs/pt-br/_sidebar.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
* [Campo de documento](pt-br/guides/document-field.md)
55
* [Endereço pelo CEP](pt-br/guides/address-form.md)
66
* [Estado e cidade](pt-br/guides/state-city.md)
7+
* [Um schema para um documento](pt-br/guides/schema.md)
78
* [Migração v1 para v2](pt-br/migration-v1-to-v2.md)

0 commit comments

Comments
 (0)