@atproto/lex-schema 0.1.5 → 0.1.6
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.
- package/CHANGELOG.md +14 -0
- package/dist/core/$type.d.ts +2 -2
- package/dist/core/$type.d.ts.map +1 -1
- package/dist/core/$type.js.map +1 -1
- package/dist/core/record-key.d.ts +1 -1
- package/dist/core/record-key.d.ts.map +1 -1
- package/dist/core/record-key.js.map +1 -1
- package/dist/core/schema.d.ts +3 -2
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +1 -1
- package/dist/core/schema.js.map +1 -1
- package/dist/core/standard-schema.d.ts +2 -2
- package/dist/core/standard-schema.d.ts.map +1 -1
- package/dist/core/standard-schema.js.map +1 -1
- package/dist/core/string-format.d.ts +2 -2
- package/dist/core/string-format.d.ts.map +1 -1
- package/dist/core/string-format.js.map +1 -1
- package/dist/core/validation-error.d.ts +1 -1
- package/dist/core/validation-error.d.ts.map +1 -1
- package/dist/core/validation-error.js +1 -1
- package/dist/core/validation-error.js.map +1 -1
- package/dist/core/validator.d.ts +1 -1
- package/dist/core/validator.d.ts.map +1 -1
- package/dist/core/validator.js +1 -1
- package/dist/core/validator.js.map +1 -1
- package/dist/helpers.d.ts +2 -2
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +2 -2
- package/dist/helpers.js.map +1 -1
- package/dist/schema/array.d.ts +1 -1
- package/dist/schema/array.d.ts.map +1 -1
- package/dist/schema/array.js +1 -1
- package/dist/schema/array.js.map +1 -1
- package/dist/schema/blob.d.ts +1 -1
- package/dist/schema/blob.d.ts.map +1 -1
- package/dist/schema/blob.js +2 -2
- package/dist/schema/blob.js.map +1 -1
- package/dist/schema/boolean.js +1 -1
- package/dist/schema/boolean.js.map +1 -1
- package/dist/schema/bytes.js +1 -1
- package/dist/schema/bytes.js.map +1 -1
- package/dist/schema/cid.d.ts +1 -1
- package/dist/schema/cid.d.ts.map +1 -1
- package/dist/schema/cid.js +3 -3
- package/dist/schema/cid.js.map +1 -1
- package/dist/schema/custom.js +1 -1
- package/dist/schema/custom.js.map +1 -1
- package/dist/schema/dict.d.ts +1 -1
- package/dist/schema/dict.d.ts.map +1 -1
- package/dist/schema/dict.js +1 -1
- package/dist/schema/dict.js.map +1 -1
- package/dist/schema/discriminated-union.d.ts +1 -1
- package/dist/schema/discriminated-union.d.ts.map +1 -1
- package/dist/schema/discriminated-union.js +2 -1
- package/dist/schema/discriminated-union.js.map +1 -1
- package/dist/schema/enum.js +1 -1
- package/dist/schema/enum.js.map +1 -1
- package/dist/schema/integer.js +1 -1
- package/dist/schema/integer.js.map +1 -1
- package/dist/schema/intersection.d.ts +1 -1
- package/dist/schema/intersection.d.ts.map +1 -1
- package/dist/schema/intersection.js +3 -1
- package/dist/schema/intersection.js.map +1 -1
- package/dist/schema/lex-map.d.ts +1 -1
- package/dist/schema/lex-map.d.ts.map +1 -1
- package/dist/schema/lex-map.js +1 -1
- package/dist/schema/lex-map.js.map +1 -1
- package/dist/schema/lex-value.d.ts +1 -1
- package/dist/schema/lex-value.d.ts.map +1 -1
- package/dist/schema/lex-value.js +1 -1
- package/dist/schema/lex-value.js.map +1 -1
- package/dist/schema/literal.js +1 -1
- package/dist/schema/literal.js.map +1 -1
- package/dist/schema/never.js +1 -1
- package/dist/schema/never.js.map +1 -1
- package/dist/schema/null.js +1 -1
- package/dist/schema/null.js.map +1 -1
- package/dist/schema/nullable.d.ts +1 -1
- package/dist/schema/nullable.d.ts.map +1 -1
- package/dist/schema/nullable.js +1 -1
- package/dist/schema/nullable.js.map +1 -1
- package/dist/schema/object.d.ts +2 -1
- package/dist/schema/object.d.ts.map +1 -1
- package/dist/schema/object.js +1 -1
- package/dist/schema/object.js.map +1 -1
- package/dist/schema/optional.d.ts +2 -1
- package/dist/schema/optional.d.ts.map +1 -1
- package/dist/schema/optional.js +2 -1
- package/dist/schema/optional.js.map +1 -1
- package/dist/schema/params.d.ts +1 -1
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js +1 -1
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/payload.d.ts +3 -2
- package/dist/schema/payload.d.ts.map +1 -1
- package/dist/schema/payload.js +2 -1
- package/dist/schema/payload.js.map +1 -1
- package/dist/schema/permission-set.d.ts +1 -1
- package/dist/schema/permission-set.d.ts.map +1 -1
- package/dist/schema/permission-set.js +1 -0
- package/dist/schema/permission-set.js.map +1 -1
- package/dist/schema/permission.d.ts +1 -1
- package/dist/schema/permission.d.ts.map +1 -1
- package/dist/schema/permission.js.map +1 -1
- package/dist/schema/procedure.d.ts +1 -1
- package/dist/schema/procedure.d.ts.map +1 -1
- package/dist/schema/procedure.js +2 -0
- package/dist/schema/procedure.js.map +1 -1
- package/dist/schema/query.d.ts +1 -1
- package/dist/schema/query.d.ts.map +1 -1
- package/dist/schema/query.js +2 -0
- package/dist/schema/query.js.map +1 -1
- package/dist/schema/record.d.ts +2 -2
- package/dist/schema/record.d.ts.map +1 -1
- package/dist/schema/record.js +1 -1
- package/dist/schema/record.js.map +1 -1
- package/dist/schema/ref.d.ts +1 -1
- package/dist/schema/ref.d.ts.map +1 -1
- package/dist/schema/ref.js +1 -1
- package/dist/schema/ref.js.map +1 -1
- package/dist/schema/refine.d.ts +2 -2
- package/dist/schema/refine.d.ts.map +1 -1
- package/dist/schema/refine.js +1 -1
- package/dist/schema/refine.js.map +1 -1
- package/dist/schema/regexp.js +1 -1
- package/dist/schema/regexp.js.map +1 -1
- package/dist/schema/string.d.ts +2 -2
- package/dist/schema/string.d.ts.map +1 -1
- package/dist/schema/string.js +1 -1
- package/dist/schema/string.js.map +1 -1
- package/dist/schema/subscription.d.ts +3 -2
- package/dist/schema/subscription.d.ts.map +1 -1
- package/dist/schema/subscription.js +2 -0
- package/dist/schema/subscription.js.map +1 -1
- package/dist/schema/token.d.ts +1 -1
- package/dist/schema/token.d.ts.map +1 -1
- package/dist/schema/token.js +1 -1
- package/dist/schema/token.js.map +1 -1
- package/dist/schema/typed-object.d.ts +2 -2
- package/dist/schema/typed-object.d.ts.map +1 -1
- package/dist/schema/typed-object.js +1 -1
- package/dist/schema/typed-object.js.map +1 -1
- package/dist/schema/typed-ref.d.ts +1 -1
- package/dist/schema/typed-ref.d.ts.map +1 -1
- package/dist/schema/typed-ref.js +1 -1
- package/dist/schema/typed-ref.js.map +1 -1
- package/dist/schema/typed-union.d.ts +1 -1
- package/dist/schema/typed-union.d.ts.map +1 -1
- package/dist/schema/typed-union.js +3 -1
- package/dist/schema/typed-union.js.map +1 -1
- package/dist/schema/union.d.ts +1 -1
- package/dist/schema/union.d.ts.map +1 -1
- package/dist/schema/union.js +1 -1
- package/dist/schema/union.js.map +1 -1
- package/dist/schema/unknown.js +1 -1
- package/dist/schema/unknown.js.map +1 -1
- package/dist/schema/with-default.d.ts +1 -1
- package/dist/schema/with-default.d.ts.map +1 -1
- package/dist/schema/with-default.js +1 -1
- package/dist/schema/with-default.js.map +1 -1
- package/package.json +6 -10
- package/src/core/$type.test.ts +0 -24
- package/src/core/$type.ts +0 -199
- package/src/core/record-key.ts +0 -85
- package/src/core/result.ts +0 -15
- package/src/core/schema.ts +0 -412
- package/src/core/standard-schema.test.ts +0 -124
- package/src/core/standard-schema.ts +0 -31
- package/src/core/string-format.ts +0 -411
- package/src/core/types.ts +0 -120
- package/src/core/validation-error.ts +0 -134
- package/src/core/validation-issue.ts +0 -340
- package/src/core/validator.ts +0 -636
- package/src/core.ts +0 -9
- package/src/external.ts +0 -3
- package/src/helpers.test.ts +0 -694
- package/src/helpers.ts +0 -222
- package/src/index.ts +0 -3
- package/src/schema/array.test.ts +0 -251
- package/src/schema/array.ts +0 -126
- package/src/schema/blob.test.ts +0 -733
- package/src/schema/blob.ts +0 -150
- package/src/schema/boolean.test.ts +0 -118
- package/src/schema/boolean.ts +0 -46
- package/src/schema/bytes.test.ts +0 -227
- package/src/schema/bytes.ts +0 -81
- package/src/schema/cid.test.ts +0 -125
- package/src/schema/cid.ts +0 -69
- package/src/schema/custom.test.ts +0 -414
- package/src/schema/custom.ts +0 -106
- package/src/schema/dict.test.ts +0 -181
- package/src/schema/dict.ts +0 -122
- package/src/schema/discriminated-union.test.ts +0 -676
- package/src/schema/discriminated-union.ts +0 -196
- package/src/schema/enum.test.ts +0 -398
- package/src/schema/enum.ts +0 -77
- package/src/schema/integer.test.ts +0 -314
- package/src/schema/integer.ts +0 -86
- package/src/schema/intersection.test.ts +0 -33
- package/src/schema/intersection.ts +0 -113
- package/src/schema/lex-map.test.ts +0 -593
- package/src/schema/lex-map.ts +0 -63
- package/src/schema/lex-value.test.ts +0 -81
- package/src/schema/lex-value.ts +0 -86
- package/src/schema/literal.test.ts +0 -533
- package/src/schema/literal.ts +0 -70
- package/src/schema/never.test.ts +0 -175
- package/src/schema/never.ts +0 -56
- package/src/schema/null.test.ts +0 -80
- package/src/schema/null.ts +0 -49
- package/src/schema/nullable.test.ts +0 -470
- package/src/schema/nullable.ts +0 -74
- package/src/schema/object.test.ts +0 -69
- package/src/schema/object.ts +0 -136
- package/src/schema/optional.test.ts +0 -479
- package/src/schema/optional.ts +0 -92
- package/src/schema/params.test.ts +0 -1118
- package/src/schema/params.ts +0 -371
- package/src/schema/payload.test.ts +0 -340
- package/src/schema/payload.ts +0 -204
- package/src/schema/permission-set.test.ts +0 -613
- package/src/schema/permission-set.ts +0 -86
- package/src/schema/permission.test.ts +0 -537
- package/src/schema/permission.ts +0 -63
- package/src/schema/procedure.test.ts +0 -324
- package/src/schema/procedure.ts +0 -98
- package/src/schema/query.test.ts +0 -348
- package/src/schema/query.ts +0 -86
- package/src/schema/record.test.ts +0 -812
- package/src/schema/record.ts +0 -217
- package/src/schema/ref.test.ts +0 -349
- package/src/schema/ref.ts +0 -103
- package/src/schema/refine.test.ts +0 -579
- package/src/schema/refine.ts +0 -153
- package/src/schema/regexp.test.ts +0 -577
- package/src/schema/regexp.ts +0 -82
- package/src/schema/string.test.ts +0 -773
- package/src/schema/string.ts +0 -229
- package/src/schema/subscription.test.ts +0 -499
- package/src/schema/subscription.ts +0 -108
- package/src/schema/token.test.ts +0 -152
- package/src/schema/token.ts +0 -103
- package/src/schema/typed-object.test.ts +0 -745
- package/src/schema/typed-object.ts +0 -181
- package/src/schema/typed-ref.test.ts +0 -796
- package/src/schema/typed-ref.ts +0 -126
- package/src/schema/typed-union.test.ts +0 -355
- package/src/schema/typed-union.ts +0 -130
- package/src/schema/union.test.ts +0 -191
- package/src/schema/union.ts +0 -89
- package/src/schema/unknown.test.ts +0 -313
- package/src/schema/unknown.ts +0 -47
- package/src/schema/with-default.ts +0 -81
- package/src/schema.ts +0 -43
- package/src/util/array-agg.test.ts +0 -42
- package/src/util/array-agg.ts +0 -44
- package/src/util/assertion-util.ts +0 -1
- package/src/util/if-any.ts +0 -3
- package/src/util/lazy-property.ts +0 -14
- package/src/util/memoize.ts +0 -37
- package/tsconfig.build.json +0 -12
- package/tsconfig.json +0 -7
- package/tsconfig.tests.json +0 -8
|
@@ -1,577 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { regexp } from './regexp.js'
|
|
3
|
-
|
|
4
|
-
describe('RegexpSchema', () => {
|
|
5
|
-
describe('basic validation', () => {
|
|
6
|
-
const schema = regexp(/^[a-z]+$/)
|
|
7
|
-
|
|
8
|
-
it('validates strings matching the pattern', () => {
|
|
9
|
-
const result = schema.safeParse('hello')
|
|
10
|
-
expect(result.success).toBe(true)
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
it('validates strings with different matching values', () => {
|
|
14
|
-
const result = schema.safeParse('world')
|
|
15
|
-
expect(result.success).toBe(true)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
it('rejects strings not matching the pattern', () => {
|
|
19
|
-
const result = schema.safeParse('Hello')
|
|
20
|
-
expect(result.success).toBe(false)
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('rejects strings with numbers when pattern requires letters', () => {
|
|
24
|
-
const result = schema.safeParse('hello123')
|
|
25
|
-
expect(result.success).toBe(false)
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
it('rejects non-strings', () => {
|
|
29
|
-
const result = schema.safeParse(123)
|
|
30
|
-
expect(result.success).toBe(false)
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('rejects null', () => {
|
|
34
|
-
const result = schema.safeParse(null)
|
|
35
|
-
expect(result.success).toBe(false)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('rejects undefined', () => {
|
|
39
|
-
const result = schema.safeParse(undefined)
|
|
40
|
-
expect(result.success).toBe(false)
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('rejects booleans', () => {
|
|
44
|
-
const result = schema.safeParse(true)
|
|
45
|
-
expect(result.success).toBe(false)
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('rejects arrays', () => {
|
|
49
|
-
const result = schema.safeParse(['hello'])
|
|
50
|
-
expect(result.success).toBe(false)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it('rejects plain objects', () => {
|
|
54
|
-
const result = schema.safeParse({ value: 'hello' })
|
|
55
|
-
expect(result.success).toBe(false)
|
|
56
|
-
})
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
describe('numeric patterns', () => {
|
|
60
|
-
const schema = regexp(/^\d+$/)
|
|
61
|
-
|
|
62
|
-
it('validates numeric strings', () => {
|
|
63
|
-
const result = schema.safeParse('12345')
|
|
64
|
-
expect(result.success).toBe(true)
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
it('validates single digit strings', () => {
|
|
68
|
-
const result = schema.safeParse('0')
|
|
69
|
-
expect(result.success).toBe(true)
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('rejects strings with letters', () => {
|
|
73
|
-
const result = schema.safeParse('123abc')
|
|
74
|
-
expect(result.success).toBe(false)
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
it('rejects empty strings', () => {
|
|
78
|
-
const result = schema.safeParse('')
|
|
79
|
-
expect(result.success).toBe(false)
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
describe('email pattern', () => {
|
|
84
|
-
const schema = regexp(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/)
|
|
85
|
-
|
|
86
|
-
it('validates simple email addresses', () => {
|
|
87
|
-
const result = schema.safeParse('user@example.com')
|
|
88
|
-
expect(result.success).toBe(true)
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
it('validates email with subdomain', () => {
|
|
92
|
-
const result = schema.safeParse('user@mail.example.com')
|
|
93
|
-
expect(result.success).toBe(true)
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
it('validates email with numbers and special characters', () => {
|
|
97
|
-
const result = schema.safeParse('user.name+tag@example.com')
|
|
98
|
-
expect(result.success).toBe(true)
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
it('rejects email without @', () => {
|
|
102
|
-
const result = schema.safeParse('userexample.com')
|
|
103
|
-
expect(result.success).toBe(false)
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
it('rejects email without domain', () => {
|
|
107
|
-
const result = schema.safeParse('user@')
|
|
108
|
-
expect(result.success).toBe(false)
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
it('rejects email without TLD', () => {
|
|
112
|
-
const result = schema.safeParse('user@example')
|
|
113
|
-
expect(result.success).toBe(false)
|
|
114
|
-
})
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
describe('URL pattern', () => {
|
|
118
|
-
const schema = regexp(/^https?:\/\/[^\s/$.?#].[^\s]*$/)
|
|
119
|
-
|
|
120
|
-
it('validates HTTP URLs', () => {
|
|
121
|
-
const result = schema.safeParse('http://example.com')
|
|
122
|
-
expect(result.success).toBe(true)
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
it('validates HTTPS URLs', () => {
|
|
126
|
-
const result = schema.safeParse('https://example.com')
|
|
127
|
-
expect(result.success).toBe(true)
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
it('validates URLs with paths', () => {
|
|
131
|
-
const result = schema.safeParse('https://example.com/path/to/resource')
|
|
132
|
-
expect(result.success).toBe(true)
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
it('validates URLs with query parameters', () => {
|
|
136
|
-
const result = schema.safeParse('https://example.com?param=value')
|
|
137
|
-
expect(result.success).toBe(true)
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
it('rejects URLs without protocol', () => {
|
|
141
|
-
const result = schema.safeParse('example.com')
|
|
142
|
-
expect(result.success).toBe(false)
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
it('rejects URLs with spaces', () => {
|
|
146
|
-
const result = schema.safeParse('https://example.com/path with spaces')
|
|
147
|
-
expect(result.success).toBe(false)
|
|
148
|
-
})
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
describe('phone number pattern', () => {
|
|
152
|
-
const schema = regexp(/^\+?[1-9]\d{1,14}$/)
|
|
153
|
-
|
|
154
|
-
it('validates simple phone numbers', () => {
|
|
155
|
-
const result = schema.safeParse('1234567890')
|
|
156
|
-
expect(result.success).toBe(true)
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
it('validates phone numbers with plus prefix', () => {
|
|
160
|
-
const result = schema.safeParse('+1234567890')
|
|
161
|
-
expect(result.success).toBe(true)
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
it('validates international phone numbers', () => {
|
|
165
|
-
const result = schema.safeParse('+441234567890')
|
|
166
|
-
expect(result.success).toBe(true)
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
it('rejects phone numbers starting with zero', () => {
|
|
170
|
-
const result = schema.safeParse('0123456789')
|
|
171
|
-
expect(result.success).toBe(false)
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
it('rejects phone numbers with letters', () => {
|
|
175
|
-
const result = schema.safeParse('123-456-ABCD')
|
|
176
|
-
expect(result.success).toBe(false)
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
it('rejects phone numbers with special characters', () => {
|
|
180
|
-
const result = schema.safeParse('123-456-7890')
|
|
181
|
-
expect(result.success).toBe(false)
|
|
182
|
-
})
|
|
183
|
-
})
|
|
184
|
-
|
|
185
|
-
describe('hex color pattern', () => {
|
|
186
|
-
const schema = regexp(/^#[0-9A-Fa-f]{6}$/)
|
|
187
|
-
|
|
188
|
-
it('validates 6-digit hex colors', () => {
|
|
189
|
-
const result = schema.safeParse('#FF5733')
|
|
190
|
-
expect(result.success).toBe(true)
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
it('validates lowercase hex colors', () => {
|
|
194
|
-
const result = schema.safeParse('#ff5733')
|
|
195
|
-
expect(result.success).toBe(true)
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
it('validates mixed case hex colors', () => {
|
|
199
|
-
const result = schema.safeParse('#Ff5733')
|
|
200
|
-
expect(result.success).toBe(true)
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
it('rejects hex colors without hash', () => {
|
|
204
|
-
const result = schema.safeParse('FF5733')
|
|
205
|
-
expect(result.success).toBe(false)
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
it('rejects 3-digit hex colors', () => {
|
|
209
|
-
const result = schema.safeParse('#FFF')
|
|
210
|
-
expect(result.success).toBe(false)
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
it('rejects hex colors with invalid characters', () => {
|
|
214
|
-
const result = schema.safeParse('#GG5733')
|
|
215
|
-
expect(result.success).toBe(false)
|
|
216
|
-
})
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
describe('alphanumeric pattern', () => {
|
|
220
|
-
const schema = regexp(/^[a-zA-Z0-9]+$/)
|
|
221
|
-
|
|
222
|
-
it('validates alphanumeric strings', () => {
|
|
223
|
-
const result = schema.safeParse('abc123')
|
|
224
|
-
expect(result.success).toBe(true)
|
|
225
|
-
})
|
|
226
|
-
|
|
227
|
-
it('validates only letters', () => {
|
|
228
|
-
const result = schema.safeParse('abcdef')
|
|
229
|
-
expect(result.success).toBe(true)
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
it('validates only numbers', () => {
|
|
233
|
-
const result = schema.safeParse('123456')
|
|
234
|
-
expect(result.success).toBe(true)
|
|
235
|
-
})
|
|
236
|
-
|
|
237
|
-
it('rejects strings with spaces', () => {
|
|
238
|
-
const result = schema.safeParse('abc 123')
|
|
239
|
-
expect(result.success).toBe(false)
|
|
240
|
-
})
|
|
241
|
-
|
|
242
|
-
it('rejects strings with special characters', () => {
|
|
243
|
-
const result = schema.safeParse('abc_123')
|
|
244
|
-
expect(result.success).toBe(false)
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
it('rejects empty strings', () => {
|
|
248
|
-
const result = schema.safeParse('')
|
|
249
|
-
expect(result.success).toBe(false)
|
|
250
|
-
})
|
|
251
|
-
})
|
|
252
|
-
|
|
253
|
-
describe('case-insensitive pattern', () => {
|
|
254
|
-
const schema = regexp(/^hello$/i)
|
|
255
|
-
|
|
256
|
-
it('validates lowercase match', () => {
|
|
257
|
-
const result = schema.safeParse('hello')
|
|
258
|
-
expect(result.success).toBe(true)
|
|
259
|
-
})
|
|
260
|
-
|
|
261
|
-
it('validates uppercase match', () => {
|
|
262
|
-
const result = schema.safeParse('HELLO')
|
|
263
|
-
expect(result.success).toBe(true)
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
it('validates mixed case match', () => {
|
|
267
|
-
const result = schema.safeParse('HeLLo')
|
|
268
|
-
expect(result.success).toBe(true)
|
|
269
|
-
})
|
|
270
|
-
|
|
271
|
-
it('rejects non-matching strings', () => {
|
|
272
|
-
const result = schema.safeParse('world')
|
|
273
|
-
expect(result.success).toBe(false)
|
|
274
|
-
})
|
|
275
|
-
})
|
|
276
|
-
|
|
277
|
-
describe('multiline pattern', () => {
|
|
278
|
-
const schema = regexp(/^line\d+$/m)
|
|
279
|
-
|
|
280
|
-
it('validates single line matching pattern', () => {
|
|
281
|
-
const result = schema.safeParse('line1')
|
|
282
|
-
expect(result.success).toBe(true)
|
|
283
|
-
})
|
|
284
|
-
|
|
285
|
-
it('validates multiline string with matching line', () => {
|
|
286
|
-
const result = schema.safeParse('line1\nline2')
|
|
287
|
-
expect(result.success).toBe(true)
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
it('rejects strings without matching lines', () => {
|
|
291
|
-
const result = schema.safeParse('hello\nworld')
|
|
292
|
-
expect(result.success).toBe(false)
|
|
293
|
-
})
|
|
294
|
-
})
|
|
295
|
-
|
|
296
|
-
describe('optional character pattern', () => {
|
|
297
|
-
const schema = regexp(/^colou?r$/)
|
|
298
|
-
|
|
299
|
-
it('validates with optional character present', () => {
|
|
300
|
-
const result = schema.safeParse('colour')
|
|
301
|
-
expect(result.success).toBe(true)
|
|
302
|
-
})
|
|
303
|
-
|
|
304
|
-
it('validates with optional character absent', () => {
|
|
305
|
-
const result = schema.safeParse('color')
|
|
306
|
-
expect(result.success).toBe(true)
|
|
307
|
-
})
|
|
308
|
-
|
|
309
|
-
it('rejects strings not matching pattern', () => {
|
|
310
|
-
const result = schema.safeParse('colouur')
|
|
311
|
-
expect(result.success).toBe(false)
|
|
312
|
-
})
|
|
313
|
-
})
|
|
314
|
-
|
|
315
|
-
describe('character range pattern', () => {
|
|
316
|
-
const schema = regexp(/^[0-5]+$/)
|
|
317
|
-
|
|
318
|
-
it('validates strings within range', () => {
|
|
319
|
-
const result = schema.safeParse('012345')
|
|
320
|
-
expect(result.success).toBe(true)
|
|
321
|
-
})
|
|
322
|
-
|
|
323
|
-
it('validates single character in range', () => {
|
|
324
|
-
const result = schema.safeParse('3')
|
|
325
|
-
expect(result.success).toBe(true)
|
|
326
|
-
})
|
|
327
|
-
|
|
328
|
-
it('rejects strings with characters outside range', () => {
|
|
329
|
-
const result = schema.safeParse('0123456')
|
|
330
|
-
expect(result.success).toBe(false)
|
|
331
|
-
})
|
|
332
|
-
})
|
|
333
|
-
|
|
334
|
-
describe('quantifier pattern', () => {
|
|
335
|
-
const schema = regexp(/^a{3}$/)
|
|
336
|
-
|
|
337
|
-
it('validates exact repetition count', () => {
|
|
338
|
-
const result = schema.safeParse('aaa')
|
|
339
|
-
expect(result.success).toBe(true)
|
|
340
|
-
})
|
|
341
|
-
|
|
342
|
-
it('rejects fewer repetitions', () => {
|
|
343
|
-
const result = schema.safeParse('aa')
|
|
344
|
-
expect(result.success).toBe(false)
|
|
345
|
-
})
|
|
346
|
-
|
|
347
|
-
it('rejects more repetitions', () => {
|
|
348
|
-
const result = schema.safeParse('aaaa')
|
|
349
|
-
expect(result.success).toBe(false)
|
|
350
|
-
})
|
|
351
|
-
})
|
|
352
|
-
|
|
353
|
-
describe('range quantifier pattern', () => {
|
|
354
|
-
const schema = regexp(/^a{2,4}$/)
|
|
355
|
-
|
|
356
|
-
it('validates minimum repetition count', () => {
|
|
357
|
-
const result = schema.safeParse('aa')
|
|
358
|
-
expect(result.success).toBe(true)
|
|
359
|
-
})
|
|
360
|
-
|
|
361
|
-
it('validates middle repetition count', () => {
|
|
362
|
-
const result = schema.safeParse('aaa')
|
|
363
|
-
expect(result.success).toBe(true)
|
|
364
|
-
})
|
|
365
|
-
|
|
366
|
-
it('validates maximum repetition count', () => {
|
|
367
|
-
const result = schema.safeParse('aaaa')
|
|
368
|
-
expect(result.success).toBe(true)
|
|
369
|
-
})
|
|
370
|
-
|
|
371
|
-
it('rejects fewer than minimum repetitions', () => {
|
|
372
|
-
const result = schema.safeParse('a')
|
|
373
|
-
expect(result.success).toBe(false)
|
|
374
|
-
})
|
|
375
|
-
|
|
376
|
-
it('rejects more than maximum repetitions', () => {
|
|
377
|
-
const result = schema.safeParse('aaaaa')
|
|
378
|
-
expect(result.success).toBe(false)
|
|
379
|
-
})
|
|
380
|
-
})
|
|
381
|
-
|
|
382
|
-
describe('alternation pattern', () => {
|
|
383
|
-
const schema = regexp(/^(cat|dog|bird)$/)
|
|
384
|
-
|
|
385
|
-
it('validates first alternative', () => {
|
|
386
|
-
const result = schema.safeParse('cat')
|
|
387
|
-
expect(result.success).toBe(true)
|
|
388
|
-
})
|
|
389
|
-
|
|
390
|
-
it('validates second alternative', () => {
|
|
391
|
-
const result = schema.safeParse('dog')
|
|
392
|
-
expect(result.success).toBe(true)
|
|
393
|
-
})
|
|
394
|
-
|
|
395
|
-
it('validates third alternative', () => {
|
|
396
|
-
const result = schema.safeParse('bird')
|
|
397
|
-
expect(result.success).toBe(true)
|
|
398
|
-
})
|
|
399
|
-
|
|
400
|
-
it('rejects strings not matching any alternative', () => {
|
|
401
|
-
const result = schema.safeParse('fish')
|
|
402
|
-
expect(result.success).toBe(false)
|
|
403
|
-
})
|
|
404
|
-
})
|
|
405
|
-
|
|
406
|
-
describe('word boundary pattern', () => {
|
|
407
|
-
const schema = regexp(/\bword\b/)
|
|
408
|
-
|
|
409
|
-
it('validates word with boundaries', () => {
|
|
410
|
-
const result = schema.safeParse('word')
|
|
411
|
-
expect(result.success).toBe(true)
|
|
412
|
-
})
|
|
413
|
-
|
|
414
|
-
it('validates word within sentence', () => {
|
|
415
|
-
const result = schema.safeParse('this is a word')
|
|
416
|
-
expect(result.success).toBe(true)
|
|
417
|
-
})
|
|
418
|
-
|
|
419
|
-
it('rejects word as part of larger word', () => {
|
|
420
|
-
const result = schema.safeParse('wording')
|
|
421
|
-
expect(result.success).toBe(false)
|
|
422
|
-
})
|
|
423
|
-
})
|
|
424
|
-
|
|
425
|
-
describe('lookahead pattern', () => {
|
|
426
|
-
const schema = regexp(/^(?=.*[A-Z])(?=.*[0-9]).{8,}$/)
|
|
427
|
-
|
|
428
|
-
it('validates string meeting all lookahead conditions', () => {
|
|
429
|
-
const result = schema.safeParse('Password1')
|
|
430
|
-
expect(result.success).toBe(true)
|
|
431
|
-
})
|
|
432
|
-
|
|
433
|
-
it('validates string with multiple uppercase and numbers', () => {
|
|
434
|
-
const result = schema.safeParse('ABC12345')
|
|
435
|
-
expect(result.success).toBe(true)
|
|
436
|
-
})
|
|
437
|
-
|
|
438
|
-
it('rejects string without uppercase', () => {
|
|
439
|
-
const result = schema.safeParse('password1')
|
|
440
|
-
expect(result.success).toBe(false)
|
|
441
|
-
})
|
|
442
|
-
|
|
443
|
-
it('rejects string without number', () => {
|
|
444
|
-
const result = schema.safeParse('Password')
|
|
445
|
-
expect(result.success).toBe(false)
|
|
446
|
-
})
|
|
447
|
-
|
|
448
|
-
it('rejects string too short', () => {
|
|
449
|
-
const result = schema.safeParse('Pass1')
|
|
450
|
-
expect(result.success).toBe(false)
|
|
451
|
-
})
|
|
452
|
-
})
|
|
453
|
-
|
|
454
|
-
describe('unicode pattern', () => {
|
|
455
|
-
const schema = regexp(/^[\u4e00-\u9fa5]+$/)
|
|
456
|
-
|
|
457
|
-
it('validates Chinese characters', () => {
|
|
458
|
-
const result = schema.safeParse('你好')
|
|
459
|
-
expect(result.success).toBe(true)
|
|
460
|
-
})
|
|
461
|
-
|
|
462
|
-
it('validates multiple Chinese characters', () => {
|
|
463
|
-
const result = schema.safeParse('世界')
|
|
464
|
-
expect(result.success).toBe(true)
|
|
465
|
-
})
|
|
466
|
-
|
|
467
|
-
it('rejects non-Chinese characters', () => {
|
|
468
|
-
const result = schema.safeParse('hello')
|
|
469
|
-
expect(result.success).toBe(false)
|
|
470
|
-
})
|
|
471
|
-
|
|
472
|
-
it('rejects mixed Chinese and English', () => {
|
|
473
|
-
const result = schema.safeParse('你好hello')
|
|
474
|
-
expect(result.success).toBe(false)
|
|
475
|
-
})
|
|
476
|
-
})
|
|
477
|
-
|
|
478
|
-
describe('empty string pattern', () => {
|
|
479
|
-
const schema = regexp(/^$/)
|
|
480
|
-
|
|
481
|
-
it('validates empty strings', () => {
|
|
482
|
-
const result = schema.safeParse('')
|
|
483
|
-
expect(result.success).toBe(true)
|
|
484
|
-
})
|
|
485
|
-
|
|
486
|
-
it('rejects non-empty strings', () => {
|
|
487
|
-
const result = schema.safeParse('hello')
|
|
488
|
-
expect(result.success).toBe(false)
|
|
489
|
-
})
|
|
490
|
-
|
|
491
|
-
it('rejects whitespace strings', () => {
|
|
492
|
-
const result = schema.safeParse(' ')
|
|
493
|
-
expect(result.success).toBe(false)
|
|
494
|
-
})
|
|
495
|
-
})
|
|
496
|
-
|
|
497
|
-
describe('wildcard pattern', () => {
|
|
498
|
-
const schema = regexp(/^.*$/)
|
|
499
|
-
|
|
500
|
-
it('validates empty strings', () => {
|
|
501
|
-
const result = schema.safeParse('')
|
|
502
|
-
expect(result.success).toBe(true)
|
|
503
|
-
})
|
|
504
|
-
|
|
505
|
-
it('validates any string', () => {
|
|
506
|
-
const result = schema.safeParse('anything goes here 123 !@#')
|
|
507
|
-
expect(result.success).toBe(true)
|
|
508
|
-
})
|
|
509
|
-
|
|
510
|
-
it('validates strings with special characters', () => {
|
|
511
|
-
const result = schema.safeParse('!@#$%^&*()')
|
|
512
|
-
expect(result.success).toBe(true)
|
|
513
|
-
})
|
|
514
|
-
|
|
515
|
-
it('validates strings with unicode', () => {
|
|
516
|
-
const result = schema.safeParse('Hello 世界 🌍')
|
|
517
|
-
expect(result.success).toBe(true)
|
|
518
|
-
})
|
|
519
|
-
})
|
|
520
|
-
|
|
521
|
-
describe('edge cases', () => {
|
|
522
|
-
it('handles pattern with escape sequences', () => {
|
|
523
|
-
const schema = regexp(/^\d{3}\.\d{3}\.\d{3}\.\d{3}$/)
|
|
524
|
-
const result = schema.safeParse('192.168.001.001')
|
|
525
|
-
expect(result.success).toBe(true)
|
|
526
|
-
})
|
|
527
|
-
|
|
528
|
-
it('handles pattern with special regex characters', () => {
|
|
529
|
-
const schema = regexp(/^\$\d+\.\d{2}$/)
|
|
530
|
-
const result = schema.safeParse('$99.99')
|
|
531
|
-
expect(result.success).toBe(true)
|
|
532
|
-
})
|
|
533
|
-
|
|
534
|
-
it('handles very long strings', () => {
|
|
535
|
-
const schema = regexp(/^[a-z]+$/)
|
|
536
|
-
const longString = 'a'.repeat(10000)
|
|
537
|
-
const result = schema.safeParse(longString)
|
|
538
|
-
expect(result.success).toBe(true)
|
|
539
|
-
})
|
|
540
|
-
|
|
541
|
-
it('handles strings with newlines', () => {
|
|
542
|
-
const schema = regexp(/^hello\nworld$/)
|
|
543
|
-
const result = schema.safeParse('hello\nworld')
|
|
544
|
-
expect(result.success).toBe(true)
|
|
545
|
-
})
|
|
546
|
-
|
|
547
|
-
it('handles strings with tabs', () => {
|
|
548
|
-
const schema = regexp(/^hello\tworld$/)
|
|
549
|
-
const result = schema.safeParse('hello\tworld')
|
|
550
|
-
expect(result.success).toBe(true)
|
|
551
|
-
})
|
|
552
|
-
|
|
553
|
-
it('handles emoji patterns', () => {
|
|
554
|
-
const schema = regexp(/^[\u{1F600}-\u{1F64F}]+$/u)
|
|
555
|
-
const result = schema.safeParse('😀😃😄')
|
|
556
|
-
expect(result.success).toBe(true)
|
|
557
|
-
})
|
|
558
|
-
|
|
559
|
-
it('handles global flag in pattern', () => {
|
|
560
|
-
const schema = regexp(/test/g)
|
|
561
|
-
const result = schema.safeParse('test')
|
|
562
|
-
expect(result.success).toBe(true)
|
|
563
|
-
})
|
|
564
|
-
|
|
565
|
-
it('handles pattern matching anywhere in string', () => {
|
|
566
|
-
const schema = regexp(/test/)
|
|
567
|
-
const result = schema.safeParse('this is a test string')
|
|
568
|
-
expect(result.success).toBe(true)
|
|
569
|
-
})
|
|
570
|
-
|
|
571
|
-
it('handles complex nested groups', () => {
|
|
572
|
-
const schema = regexp(/^((https?|ftp):\/\/)?([a-z0-9]+\.)+[a-z]{2,}$/)
|
|
573
|
-
const result = schema.safeParse('https://example.com')
|
|
574
|
-
expect(result.success).toBe(true)
|
|
575
|
-
})
|
|
576
|
-
})
|
|
577
|
-
})
|
package/src/schema/regexp.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { Schema, ValidationContext } from '../core.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Schema for validating strings against a regular expression pattern.
|
|
5
|
-
*
|
|
6
|
-
* Validates that the input is a string and matches the provided pattern.
|
|
7
|
-
* The pattern is tested using RegExp.test().
|
|
8
|
-
*
|
|
9
|
-
* @template TValue - The string type (can be narrowed with branded types)
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* const schema = new RegexpSchema(/^[a-z]+$/)
|
|
14
|
-
* schema.validate('hello') // success
|
|
15
|
-
* schema.validate('Hello') // fails - uppercase not allowed
|
|
16
|
-
* ```
|
|
17
|
-
*/
|
|
18
|
-
export class RegexpSchema<
|
|
19
|
-
TValue extends string = string,
|
|
20
|
-
> extends Schema<TValue> {
|
|
21
|
-
readonly type = 'regexp' as const
|
|
22
|
-
|
|
23
|
-
constructor(
|
|
24
|
-
public readonly pattern: RegExp,
|
|
25
|
-
public readonly message?: string,
|
|
26
|
-
) {
|
|
27
|
-
super()
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
validateInContext(input: unknown, ctx: ValidationContext) {
|
|
31
|
-
if (typeof input !== 'string') {
|
|
32
|
-
return ctx.issueUnexpectedType(input, 'string')
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (!this.pattern.test(input)) {
|
|
36
|
-
return ctx.issueInvalidFormat(
|
|
37
|
-
input,
|
|
38
|
-
this.pattern.toString(),
|
|
39
|
-
this.message,
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return ctx.success(input as TValue)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Creates a regexp schema that validates strings against a pattern.
|
|
49
|
-
*
|
|
50
|
-
* Useful for custom string formats not covered by the built-in format
|
|
51
|
-
* validators.
|
|
52
|
-
*
|
|
53
|
-
* @param pattern - Regular expression pattern to match against
|
|
54
|
-
* @returns A new {@link RegexpSchema} instance
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```ts
|
|
58
|
-
* // Simple pattern
|
|
59
|
-
* const slugSchema = l.regexp(/^[a-z0-9-]+$/)
|
|
60
|
-
*
|
|
61
|
-
* // With anchors for exact match
|
|
62
|
-
* const uuidSchema = l.regexp(
|
|
63
|
-
* /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
|
|
64
|
-
* )
|
|
65
|
-
*
|
|
66
|
-
* // Semantic versioning
|
|
67
|
-
* const semverSchema = l.regexp(/^\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/)
|
|
68
|
-
*
|
|
69
|
-
* // Use in object
|
|
70
|
-
* const configSchema = l.object({
|
|
71
|
-
* name: l.regexp(/^[a-z][a-z0-9-]*$/), // kebab-case identifier
|
|
72
|
-
* version: semverSchema,
|
|
73
|
-
* })
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
|
-
/*@__NO_SIDE_EFFECTS__*/
|
|
77
|
-
export function regexp<TInput extends string = string>(
|
|
78
|
-
pattern: RegExp,
|
|
79
|
-
message?: string,
|
|
80
|
-
): RegexpSchema<TInput> {
|
|
81
|
-
return new RegexpSchema<TInput>(pattern, message)
|
|
82
|
-
}
|