@atproto/lex-schema 0.0.9 → 0.0.10
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 +34 -0
- package/LICENSE.txt +1 -1
- package/dist/core/$type.d.ts +11 -0
- package/dist/core/$type.d.ts.map +1 -1
- package/dist/core/$type.js +4 -0
- package/dist/core/$type.js.map +1 -1
- package/dist/core/schema.d.ts +31 -24
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +38 -8
- package/dist/core/schema.js.map +1 -1
- package/dist/core/string-format.d.ts +35 -35
- package/dist/core/string-format.d.ts.map +1 -1
- package/dist/core/string-format.js +49 -91
- package/dist/core/string-format.js.map +1 -1
- package/dist/core/validation-issue.js +1 -1
- package/dist/core/validation-issue.js.map +1 -1
- package/dist/core/validator.d.ts +53 -32
- package/dist/core/validator.d.ts.map +1 -1
- package/dist/core/validator.js +18 -22
- package/dist/core/validator.js.map +1 -1
- package/dist/external.d.ts +0 -85
- package/dist/external.d.ts.map +1 -1
- package/dist/external.js +0 -164
- package/dist/external.js.map +1 -1
- package/dist/helpers.d.ts +10 -5
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +3 -3
- package/dist/helpers.js.map +1 -1
- package/dist/schema/array.d.ts +9 -5
- package/dist/schema/array.d.ts.map +1 -1
- package/dist/schema/array.js +14 -5
- package/dist/schema/array.js.map +1 -1
- package/dist/schema/blob.d.ts +9 -7
- package/dist/schema/blob.d.ts.map +1 -1
- package/dist/schema/blob.js +9 -5
- package/dist/schema/blob.js.map +1 -1
- package/dist/schema/boolean.d.ts +3 -7
- package/dist/schema/boolean.d.ts.map +1 -1
- package/dist/schema/boolean.js +6 -7
- package/dist/schema/boolean.js.map +1 -1
- package/dist/schema/bytes.d.ts +3 -2
- package/dist/schema/bytes.d.ts.map +1 -1
- package/dist/schema/bytes.js +7 -3
- package/dist/schema/bytes.js.map +1 -1
- package/dist/schema/cid.d.ts +7 -7
- package/dist/schema/cid.d.ts.map +1 -1
- package/dist/schema/cid.js +5 -1
- package/dist/schema/cid.js.map +1 -1
- package/dist/schema/custom.d.ts +6 -5
- package/dist/schema/custom.d.ts.map +1 -1
- package/dist/schema/custom.js +10 -4
- package/dist/schema/custom.js.map +1 -1
- package/dist/schema/dict.d.ts +8 -8
- package/dist/schema/dict.d.ts.map +1 -1
- package/dist/schema/dict.js +11 -2
- package/dist/schema/dict.js.map +1 -1
- package/dist/schema/discriminated-union.d.ts +21 -14
- package/dist/schema/discriminated-union.d.ts.map +1 -1
- package/dist/schema/discriminated-union.js +7 -0
- package/dist/schema/discriminated-union.js.map +1 -1
- package/dist/schema/enum.d.ts +7 -9
- package/dist/schema/enum.d.ts.map +1 -1
- package/dist/schema/enum.js +8 -4
- package/dist/schema/enum.js.map +1 -1
- package/dist/schema/integer.d.ts +5 -5
- package/dist/schema/integer.d.ts.map +1 -1
- package/dist/schema/integer.js +9 -5
- package/dist/schema/integer.js.map +1 -1
- package/dist/schema/intersection.d.ts +4 -4
- package/dist/schema/intersection.d.ts.map +1 -1
- package/dist/schema/intersection.js +5 -0
- package/dist/schema/intersection.js.map +1 -1
- package/dist/schema/literal.d.ts +6 -9
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js +7 -4
- package/dist/schema/literal.js.map +1 -1
- package/dist/schema/never.d.ts +3 -2
- package/dist/schema/never.d.ts.map +1 -1
- package/dist/schema/never.js +5 -1
- package/dist/schema/never.js.map +1 -1
- package/dist/schema/null.d.ts +4 -3
- package/dist/schema/null.d.ts.map +1 -1
- package/dist/schema/null.js +6 -4
- package/dist/schema/null.js.map +1 -1
- package/dist/schema/nullable.d.ts +6 -5
- package/dist/schema/nullable.d.ts.map +1 -1
- package/dist/schema/nullable.js +9 -5
- package/dist/schema/nullable.js.map +1 -1
- package/dist/schema/object.d.ts +10 -8
- package/dist/schema/object.d.ts.map +1 -1
- package/dist/schema/object.js +11 -3
- package/dist/schema/object.js.map +1 -1
- package/dist/schema/optional.d.ts +7 -5
- package/dist/schema/optional.d.ts.map +1 -1
- package/dist/schema/optional.js +14 -6
- package/dist/schema/optional.js.map +1 -1
- package/dist/schema/params.d.ts +24 -13
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js +47 -25
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/payload.d.ts +12 -9
- package/dist/schema/payload.d.ts.map +1 -1
- package/dist/schema/payload.js +11 -0
- package/dist/schema/payload.js.map +1 -1
- package/dist/schema/permission-set.d.ts +1 -0
- package/dist/schema/permission-set.d.ts.map +1 -1
- package/dist/schema/permission-set.js +5 -0
- package/dist/schema/permission-set.js.map +1 -1
- package/dist/schema/permission.d.ts +6 -5
- package/dist/schema/permission.d.ts.map +1 -1
- package/dist/schema/permission.js +5 -0
- package/dist/schema/permission.js.map +1 -1
- package/dist/schema/procedure.d.ts +2 -1
- package/dist/schema/procedure.d.ts.map +1 -1
- package/dist/schema/procedure.js +5 -0
- package/dist/schema/procedure.js.map +1 -1
- package/dist/schema/query.d.ts +2 -1
- package/dist/schema/query.d.ts.map +1 -1
- package/dist/schema/query.js +5 -0
- package/dist/schema/query.js.map +1 -1
- package/dist/schema/record.d.ts +48 -30
- package/dist/schema/record.d.ts.map +1 -1
- package/dist/schema/record.js +12 -9
- package/dist/schema/record.js.map +1 -1
- package/dist/schema/ref.d.ts +9 -6
- package/dist/schema/ref.d.ts.map +1 -1
- package/dist/schema/ref.js +9 -16
- package/dist/schema/ref.js.map +1 -1
- package/dist/schema/refine.d.ts +4 -4
- package/dist/schema/refine.d.ts.map +1 -1
- package/dist/schema/refine.js.map +1 -1
- package/dist/schema/regexp.d.ts +4 -3
- package/dist/schema/regexp.d.ts.map +1 -1
- package/dist/schema/regexp.js +5 -0
- package/dist/schema/regexp.js.map +1 -1
- package/dist/schema/string.d.ts +7 -8
- package/dist/schema/string.d.ts.map +1 -1
- package/dist/schema/string.js +13 -19
- package/dist/schema/string.js.map +1 -1
- package/dist/schema/subscription.d.ts +2 -1
- package/dist/schema/subscription.d.ts.map +1 -1
- package/dist/schema/subscription.js +5 -0
- package/dist/schema/subscription.js.map +1 -1
- package/dist/schema/token.d.ts +6 -5
- package/dist/schema/token.d.ts.map +1 -1
- package/dist/schema/token.js +5 -0
- package/dist/schema/token.js.map +1 -1
- package/dist/schema/typed-object.d.ts +43 -26
- package/dist/schema/typed-object.d.ts.map +1 -1
- package/dist/schema/typed-object.js +6 -3
- package/dist/schema/typed-object.js.map +1 -1
- package/dist/schema/typed-ref.d.ts +16 -25
- package/dist/schema/typed-ref.d.ts.map +1 -1
- package/dist/schema/typed-ref.js +7 -17
- package/dist/schema/typed-ref.js.map +1 -1
- package/dist/schema/typed-union.d.ts +9 -21
- package/dist/schema/typed-union.d.ts.map +1 -1
- package/dist/schema/typed-union.js +15 -11
- package/dist/schema/typed-union.js.map +1 -1
- package/dist/schema/union.d.ts +6 -6
- package/dist/schema/union.d.ts.map +1 -1
- package/dist/schema/union.js +7 -5
- package/dist/schema/union.js.map +1 -1
- package/dist/schema/unknown-object.d.ts +5 -4
- package/dist/schema/unknown-object.d.ts.map +1 -1
- package/dist/schema/unknown-object.js +5 -1
- package/dist/schema/unknown-object.js.map +1 -1
- package/dist/schema/unknown.d.ts +3 -2
- package/dist/schema/unknown.d.ts.map +1 -1
- package/dist/schema/unknown.js +5 -1
- package/dist/schema/unknown.js.map +1 -1
- package/dist/schema/with-default.d.ts +9 -0
- package/dist/schema/with-default.d.ts.map +1 -0
- package/dist/schema/with-default.js +27 -0
- package/dist/schema/with-default.js.map +1 -0
- package/dist/schema.d.ts +2 -2
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +2 -4
- package/dist/schema.js.map +1 -1
- package/dist/util/assertion-util.d.ts +0 -6
- package/dist/util/assertion-util.d.ts.map +1 -1
- package/dist/util/assertion-util.js +0 -28
- package/dist/util/assertion-util.js.map +1 -1
- package/dist/util/memoize.d.ts +2 -2
- package/dist/util/memoize.d.ts.map +1 -1
- package/dist/util/memoize.js +23 -39
- package/dist/util/memoize.js.map +1 -1
- package/package.json +3 -3
- package/src/core/$type.test.ts +20 -0
- package/src/core/$type.ts +30 -0
- package/src/core/schema.ts +86 -38
- package/src/core/string-format.ts +119 -158
- package/src/core/validation-issue.ts +1 -1
- package/src/core/validator.ts +93 -53
- package/src/external.ts +0 -404
- package/src/helpers.test.ts +22 -21
- package/src/helpers.ts +14 -14
- package/src/schema/array.test.ts +38 -40
- package/src/schema/array.ts +35 -13
- package/src/schema/blob.test.ts +21 -21
- package/src/schema/blob.ts +19 -17
- package/src/schema/boolean.test.ts +9 -8
- package/src/schema/boolean.ts +7 -13
- package/src/schema/bytes.test.ts +13 -13
- package/src/schema/bytes.ts +13 -8
- package/src/schema/cid.test.ts +3 -3
- package/src/schema/cid.ts +13 -12
- package/src/schema/custom.test.ts +26 -26
- package/src/schema/custom.ts +20 -13
- package/src/schema/dict.test.ts +21 -39
- package/src/schema/dict.ts +28 -19
- package/src/schema/discriminated-union.test.ts +128 -128
- package/src/schema/discriminated-union.ts +45 -26
- package/src/schema/enum.test.ts +17 -16
- package/src/schema/enum.ts +16 -16
- package/src/schema/integer.test.ts +22 -21
- package/src/schema/integer.ts +12 -9
- package/src/schema/intersection.test.ts +10 -10
- package/src/schema/intersection.ts +17 -14
- package/src/schema/literal.test.ts +35 -34
- package/src/schema/literal.ts +12 -15
- package/src/schema/never.test.ts +5 -5
- package/src/schema/never.ts +7 -2
- package/src/schema/null.test.ts +3 -3
- package/src/schema/null.ts +9 -9
- package/src/schema/nullable.test.ts +31 -42
- package/src/schema/nullable.ts +17 -9
- package/src/schema/object.test.ts +10 -12
- package/src/schema/object.ts +27 -18
- package/src/schema/optional.test.ts +21 -28
- package/src/schema/optional.ts +27 -10
- package/src/schema/params.test.ts +471 -47
- package/src/schema/params.ts +72 -38
- package/src/schema/payload.test.ts +150 -156
- package/src/schema/payload.ts +35 -19
- package/src/schema/permission-set.test.ts +206 -273
- package/src/schema/permission-set.ts +8 -0
- package/src/schema/permission.test.ts +177 -177
- package/src/schema/permission.ts +13 -5
- package/src/schema/procedure.test.ts +183 -242
- package/src/schema/procedure.ts +18 -5
- package/src/schema/query.test.ts +186 -200
- package/src/schema/query.ts +16 -4
- package/src/schema/record.test.ts +121 -101
- package/src/schema/record.ts +74 -40
- package/src/schema/ref.test.ts +101 -118
- package/src/schema/ref.ts +33 -28
- package/src/schema/refine.test.ts +28 -28
- package/src/schema/refine.ts +23 -20
- package/src/schema/regexp.test.ts +29 -33
- package/src/schema/regexp.ts +11 -7
- package/src/schema/string.test.ts +35 -35
- package/src/schema/string.ts +24 -33
- package/src/schema/subscription.test.ts +259 -387
- package/src/schema/subscription.ts +16 -4
- package/src/schema/token.test.ts +47 -324
- package/src/schema/token.ts +14 -7
- package/src/schema/typed-object.test.ts +98 -81
- package/src/schema/typed-object.ts +68 -33
- package/src/schema/typed-ref.test.ts +206 -234
- package/src/schema/typed-ref.ts +40 -42
- package/src/schema/typed-union.test.ts +40 -64
- package/src/schema/typed-union.ts +36 -58
- package/src/schema/union.test.ts +17 -27
- package/src/schema/union.ts +20 -16
- package/src/schema/unknown-object.test.ts +8 -8
- package/src/schema/unknown-object.ts +9 -7
- package/src/schema/unknown.test.ts +4 -4
- package/src/schema/unknown.ts +7 -5
- package/src/schema/with-default.ts +35 -0
- package/src/schema.ts +2 -6
- package/src/util/assertion-util.ts +0 -39
- package/src/util/memoize.ts +26 -46
- package/dist/schema/_parameters.d.ts +0 -17
- package/dist/schema/_parameters.d.ts.map +0 -1
- package/dist/schema/_parameters.js +0 -20
- package/dist/schema/_parameters.js.map +0 -1
- package/src/schema/_parameters.test.ts +0 -417
- package/src/schema/_parameters.ts +0 -26
|
@@ -1,346 +1,340 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { integer } from './integer.js'
|
|
3
|
+
import { object } from './object.js'
|
|
4
|
+
import { payload } from './payload.js'
|
|
5
|
+
import { string } from './string.js'
|
|
6
|
+
import { unknown } from './unknown.js'
|
|
7
7
|
|
|
8
8
|
describe('Payload', () => {
|
|
9
9
|
describe('basic construction', () => {
|
|
10
10
|
it('creates payload with encoding and no schema', () => {
|
|
11
|
-
const
|
|
12
|
-
expect(
|
|
13
|
-
expect(
|
|
11
|
+
const def = payload('application/json', undefined)
|
|
12
|
+
expect(def.encoding).toBe('application/json')
|
|
13
|
+
expect(def.schema).toBeUndefined()
|
|
14
14
|
})
|
|
15
15
|
|
|
16
16
|
it('creates payload with encoding and schema', () => {
|
|
17
|
-
const schema =
|
|
18
|
-
name:
|
|
17
|
+
const schema = object({
|
|
18
|
+
name: string(),
|
|
19
19
|
})
|
|
20
|
-
const
|
|
21
|
-
expect(
|
|
22
|
-
expect(
|
|
20
|
+
const def = payload('application/json', schema)
|
|
21
|
+
expect(def.encoding).toBe('application/json')
|
|
22
|
+
expect(def.schema).toBe(schema)
|
|
23
23
|
})
|
|
24
24
|
|
|
25
25
|
it('creates payload with undefined encoding and undefined schema', () => {
|
|
26
|
-
const
|
|
27
|
-
expect(
|
|
28
|
-
expect(
|
|
26
|
+
const def = payload(undefined, undefined)
|
|
27
|
+
expect(def.encoding).toBeUndefined()
|
|
28
|
+
expect(def.schema).toBeUndefined()
|
|
29
29
|
})
|
|
30
30
|
|
|
31
31
|
it('creates payload with text encoding', () => {
|
|
32
|
-
const
|
|
33
|
-
expect(
|
|
34
|
-
expect(
|
|
32
|
+
const def = payload('text/plain', undefined)
|
|
33
|
+
expect(def.encoding).toBe('text/plain')
|
|
34
|
+
expect(def.schema).toBeUndefined()
|
|
35
35
|
})
|
|
36
36
|
|
|
37
37
|
it('creates payload with text/html encoding', () => {
|
|
38
|
-
const
|
|
39
|
-
expect(
|
|
40
|
-
expect(
|
|
38
|
+
const def = payload('text/html', undefined)
|
|
39
|
+
expect(def.encoding).toBe('text/html')
|
|
40
|
+
expect(def.schema).toBeUndefined()
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
it('creates payload with application/octet-stream encoding', () => {
|
|
44
|
-
const
|
|
45
|
-
expect(
|
|
46
|
-
expect(
|
|
44
|
+
const def = payload('application/octet-stream', undefined)
|
|
45
|
+
expect(def.encoding).toBe('application/octet-stream')
|
|
46
|
+
expect(def.schema).toBeUndefined()
|
|
47
47
|
})
|
|
48
48
|
|
|
49
49
|
it('creates payload with image encoding', () => {
|
|
50
|
-
const
|
|
51
|
-
expect(
|
|
52
|
-
expect(
|
|
50
|
+
const def = payload('image/png', undefined)
|
|
51
|
+
expect(def.encoding).toBe('image/png')
|
|
52
|
+
expect(def.schema).toBeUndefined()
|
|
53
53
|
})
|
|
54
54
|
})
|
|
55
55
|
|
|
56
56
|
describe('encoding types', () => {
|
|
57
57
|
it('handles application/json encoding', () => {
|
|
58
|
-
const
|
|
59
|
-
expect(
|
|
58
|
+
const def = payload('application/json', undefined)
|
|
59
|
+
expect(def.encoding).toBe('application/json')
|
|
60
60
|
})
|
|
61
61
|
|
|
62
62
|
it('handles text/* encodings', () => {
|
|
63
|
-
const textPlain =
|
|
63
|
+
const textPlain = payload('text/plain', undefined)
|
|
64
64
|
expect(textPlain.encoding).toBe('text/plain')
|
|
65
65
|
|
|
66
|
-
const textHtml =
|
|
66
|
+
const textHtml = payload('text/html', undefined)
|
|
67
67
|
expect(textHtml.encoding).toBe('text/html')
|
|
68
68
|
|
|
69
|
-
const textCss =
|
|
69
|
+
const textCss = payload('text/css', undefined)
|
|
70
70
|
expect(textCss.encoding).toBe('text/css')
|
|
71
71
|
})
|
|
72
72
|
|
|
73
73
|
it('handles binary encodings', () => {
|
|
74
|
-
const octetStream =
|
|
74
|
+
const octetStream = payload('application/octet-stream', undefined)
|
|
75
75
|
expect(octetStream.encoding).toBe('application/octet-stream')
|
|
76
76
|
|
|
77
|
-
const imagePng =
|
|
77
|
+
const imagePng = payload('image/png', undefined)
|
|
78
78
|
expect(imagePng.encoding).toBe('image/png')
|
|
79
79
|
|
|
80
|
-
const imageJpeg =
|
|
80
|
+
const imageJpeg = payload('image/jpeg', undefined)
|
|
81
81
|
expect(imageJpeg.encoding).toBe('image/jpeg')
|
|
82
82
|
})
|
|
83
83
|
|
|
84
84
|
it('handles custom mime types', () => {
|
|
85
|
-
const
|
|
86
|
-
expect(
|
|
85
|
+
const def = payload('application/vnd.custom+json', undefined)
|
|
86
|
+
expect(def.encoding).toBe('application/vnd.custom+json')
|
|
87
87
|
})
|
|
88
88
|
})
|
|
89
89
|
|
|
90
90
|
describe('with schemas', () => {
|
|
91
91
|
it('creates payload with object schema', () => {
|
|
92
|
-
const schema =
|
|
93
|
-
id:
|
|
94
|
-
name:
|
|
92
|
+
const schema = object({
|
|
93
|
+
id: integer(),
|
|
94
|
+
name: string(),
|
|
95
95
|
})
|
|
96
|
-
const
|
|
97
|
-
expect(
|
|
98
|
-
expect(
|
|
96
|
+
const def = payload('application/json', schema)
|
|
97
|
+
expect(def.encoding).toBe('application/json')
|
|
98
|
+
expect(def.schema).toBe(schema)
|
|
99
99
|
})
|
|
100
100
|
|
|
101
101
|
it('creates payload with string schema', () => {
|
|
102
|
-
const schema =
|
|
103
|
-
const
|
|
104
|
-
expect(
|
|
105
|
-
expect(
|
|
102
|
+
const schema = string()
|
|
103
|
+
const def = payload('application/json', schema)
|
|
104
|
+
expect(def.encoding).toBe('application/json')
|
|
105
|
+
expect(def.schema).toBe(schema)
|
|
106
106
|
})
|
|
107
107
|
|
|
108
108
|
it('creates payload with integer schema', () => {
|
|
109
|
-
const schema =
|
|
110
|
-
const
|
|
111
|
-
expect(
|
|
112
|
-
expect(
|
|
109
|
+
const schema = integer()
|
|
110
|
+
const def = payload('application/json', schema)
|
|
111
|
+
expect(def.encoding).toBe('application/json')
|
|
112
|
+
expect(def.schema).toBe(schema)
|
|
113
113
|
})
|
|
114
114
|
|
|
115
115
|
it('creates payload with unknown schema', () => {
|
|
116
|
-
const schema =
|
|
117
|
-
const
|
|
118
|
-
expect(
|
|
119
|
-
expect(
|
|
116
|
+
const schema = unknown()
|
|
117
|
+
const def = payload('application/json', schema)
|
|
118
|
+
expect(def.encoding).toBe('application/json')
|
|
119
|
+
expect(def.schema).toBe(schema)
|
|
120
120
|
})
|
|
121
121
|
|
|
122
122
|
it('creates payload with complex nested schema', () => {
|
|
123
|
-
const schema =
|
|
124
|
-
user:
|
|
125
|
-
id:
|
|
126
|
-
name:
|
|
127
|
-
email:
|
|
123
|
+
const schema = object({
|
|
124
|
+
user: object({
|
|
125
|
+
id: integer(),
|
|
126
|
+
name: string(),
|
|
127
|
+
email: string({ format: 'uri' }),
|
|
128
128
|
}),
|
|
129
|
-
metadata:
|
|
130
|
-
createdAt:
|
|
131
|
-
updatedAt:
|
|
129
|
+
metadata: object({
|
|
130
|
+
createdAt: string({ format: 'datetime' }),
|
|
131
|
+
updatedAt: string({ format: 'datetime' }),
|
|
132
132
|
}),
|
|
133
133
|
})
|
|
134
|
-
const
|
|
135
|
-
expect(
|
|
136
|
-
expect(
|
|
134
|
+
const def = payload('application/json', schema)
|
|
135
|
+
expect(def.encoding).toBe('application/json')
|
|
136
|
+
expect(def.schema).toBe(schema)
|
|
137
137
|
})
|
|
138
138
|
})
|
|
139
139
|
|
|
140
140
|
describe('validation constraints', () => {
|
|
141
141
|
it('throws error when schema is defined but encoding is undefined', () => {
|
|
142
|
-
const schema =
|
|
142
|
+
const schema = string()
|
|
143
143
|
expect(() => {
|
|
144
144
|
// @ts-expect-error
|
|
145
|
-
|
|
145
|
+
payload(undefined, schema)
|
|
146
146
|
}).toThrow(TypeError)
|
|
147
147
|
expect(() => {
|
|
148
148
|
// @ts-expect-error
|
|
149
|
-
|
|
149
|
+
payload(undefined, schema)
|
|
150
150
|
}).toThrow('schema cannot be defined when encoding is undefined')
|
|
151
151
|
})
|
|
152
152
|
|
|
153
153
|
it('throws error when object schema is defined but encoding is undefined', () => {
|
|
154
|
-
const schema =
|
|
155
|
-
name:
|
|
154
|
+
const schema = object({
|
|
155
|
+
name: string(),
|
|
156
156
|
})
|
|
157
157
|
expect(() => {
|
|
158
158
|
// @ts-expect-error
|
|
159
|
-
|
|
159
|
+
payload(undefined, schema)
|
|
160
160
|
}).toThrow(TypeError)
|
|
161
161
|
expect(() => {
|
|
162
162
|
// @ts-expect-error
|
|
163
|
-
|
|
163
|
+
payload(undefined, schema)
|
|
164
164
|
}).toThrow('schema cannot be defined when encoding is undefined')
|
|
165
165
|
})
|
|
166
166
|
|
|
167
167
|
it('throws error when integer schema is defined but encoding is undefined', () => {
|
|
168
|
-
const schema =
|
|
168
|
+
const schema = integer()
|
|
169
169
|
expect(() => {
|
|
170
170
|
// @ts-expect-error
|
|
171
|
-
|
|
171
|
+
payload(undefined, schema)
|
|
172
172
|
}).toThrow(TypeError)
|
|
173
173
|
})
|
|
174
174
|
|
|
175
175
|
it('allows undefined encoding with undefined schema', () => {
|
|
176
176
|
expect(() => {
|
|
177
|
-
|
|
177
|
+
payload(undefined, undefined)
|
|
178
178
|
}).not.toThrow()
|
|
179
179
|
})
|
|
180
180
|
|
|
181
181
|
it('allows defined encoding with undefined schema', () => {
|
|
182
182
|
expect(() => {
|
|
183
|
-
|
|
183
|
+
payload('application/json', undefined)
|
|
184
184
|
}).not.toThrow()
|
|
185
185
|
})
|
|
186
186
|
|
|
187
187
|
it('allows defined encoding with defined schema', () => {
|
|
188
|
-
const schema =
|
|
188
|
+
const schema = string()
|
|
189
189
|
expect(() => {
|
|
190
|
-
|
|
190
|
+
payload('application/json', schema)
|
|
191
191
|
}).not.toThrow()
|
|
192
192
|
})
|
|
193
193
|
})
|
|
194
194
|
|
|
195
195
|
describe('property access', () => {
|
|
196
196
|
it('has accessible encoding property', () => {
|
|
197
|
-
const
|
|
198
|
-
expect(
|
|
197
|
+
const def = payload('application/json', undefined)
|
|
198
|
+
expect(def.encoding).toBe('application/json')
|
|
199
199
|
})
|
|
200
200
|
|
|
201
201
|
it('has accessible schema property', () => {
|
|
202
|
-
const schema =
|
|
203
|
-
const
|
|
204
|
-
expect(
|
|
202
|
+
const schema = string()
|
|
203
|
+
const def = payload('application/json', schema)
|
|
204
|
+
expect(def.schema).toBe(schema)
|
|
205
205
|
})
|
|
206
206
|
|
|
207
207
|
it('encoding property is immutable in TypeScript', () => {
|
|
208
|
-
const
|
|
208
|
+
const def = payload('application/json', undefined)
|
|
209
209
|
// TypeScript enforces readonly at compile time
|
|
210
|
-
expect(
|
|
210
|
+
expect(def.encoding).toBe('application/json')
|
|
211
211
|
})
|
|
212
212
|
|
|
213
213
|
it('schema property is immutable in TypeScript', () => {
|
|
214
|
-
const schema =
|
|
215
|
-
const
|
|
214
|
+
const schema = string()
|
|
215
|
+
const def = payload('application/json', schema)
|
|
216
216
|
// TypeScript enforces readonly at compile time
|
|
217
|
-
expect(
|
|
217
|
+
expect(def.schema).toBe(schema)
|
|
218
218
|
})
|
|
219
219
|
})
|
|
220
220
|
|
|
221
221
|
describe('usage scenarios', () => {
|
|
222
222
|
it('creates payload for JSON API response', () => {
|
|
223
|
-
const
|
|
223
|
+
const def = payload(
|
|
224
224
|
'application/json',
|
|
225
|
-
|
|
226
|
-
success:
|
|
227
|
-
data:
|
|
225
|
+
object({
|
|
226
|
+
success: string(),
|
|
227
|
+
data: unknown(),
|
|
228
228
|
}),
|
|
229
229
|
)
|
|
230
|
-
expect(
|
|
231
|
-
expect(
|
|
230
|
+
expect(def.encoding).toBe('application/json')
|
|
231
|
+
expect(def.schema).toBeDefined()
|
|
232
232
|
})
|
|
233
233
|
|
|
234
234
|
it('creates payload for plain text response', () => {
|
|
235
|
-
const
|
|
236
|
-
expect(
|
|
237
|
-
expect(
|
|
235
|
+
const def = payload('text/plain', undefined)
|
|
236
|
+
expect(def.encoding).toBe('text/plain')
|
|
237
|
+
expect(def.schema).toBeUndefined()
|
|
238
238
|
})
|
|
239
239
|
|
|
240
240
|
it('creates payload for binary data', () => {
|
|
241
|
-
const
|
|
242
|
-
expect(
|
|
243
|
-
expect(
|
|
241
|
+
const def = payload('application/octet-stream', undefined)
|
|
242
|
+
expect(def.encoding).toBe('application/octet-stream')
|
|
243
|
+
expect(def.schema).toBeUndefined()
|
|
244
244
|
})
|
|
245
245
|
|
|
246
246
|
it('creates payload for image upload', () => {
|
|
247
|
-
const
|
|
248
|
-
expect(
|
|
249
|
-
expect(
|
|
247
|
+
const def = payload('image/jpeg', undefined)
|
|
248
|
+
expect(def.encoding).toBe('image/jpeg')
|
|
249
|
+
expect(def.schema).toBeUndefined()
|
|
250
250
|
})
|
|
251
251
|
|
|
252
252
|
it('creates payload for multipart form data', () => {
|
|
253
|
-
const
|
|
254
|
-
expect(
|
|
255
|
-
expect(
|
|
253
|
+
const def = payload('multipart/form-data', undefined)
|
|
254
|
+
expect(def.encoding).toBe('multipart/form-data')
|
|
255
|
+
expect(def.schema).toBeUndefined()
|
|
256
256
|
})
|
|
257
257
|
|
|
258
258
|
it('creates payload for URL encoded form', () => {
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
)
|
|
263
|
-
expect(payload.encoding).toBe('application/x-www-form-urlencoded')
|
|
264
|
-
expect(payload.schema).toBeUndefined()
|
|
259
|
+
const def = payload('application/x-www-form-urlencoded', undefined)
|
|
260
|
+
expect(def.encoding).toBe('application/x-www-form-urlencoded')
|
|
261
|
+
expect(def.schema).toBeUndefined()
|
|
265
262
|
})
|
|
266
263
|
|
|
267
264
|
it('creates empty payload (no encoding, no schema)', () => {
|
|
268
|
-
const
|
|
269
|
-
expect(
|
|
270
|
-
expect(
|
|
265
|
+
const def = payload(undefined, undefined)
|
|
266
|
+
expect(def.encoding).toBeUndefined()
|
|
267
|
+
expect(def.schema).toBeUndefined()
|
|
271
268
|
})
|
|
272
269
|
})
|
|
273
270
|
|
|
274
271
|
describe('edge cases', () => {
|
|
275
272
|
it('handles encoding with charset parameter', () => {
|
|
276
|
-
const
|
|
277
|
-
expect(
|
|
273
|
+
const def = payload('application/json; charset=utf-8', undefined)
|
|
274
|
+
expect(def.encoding).toBe('application/json; charset=utf-8')
|
|
278
275
|
})
|
|
279
276
|
|
|
280
277
|
it('handles encoding with multiple parameters', () => {
|
|
281
|
-
const payload =
|
|
282
|
-
|
|
283
|
-
undefined,
|
|
284
|
-
)
|
|
285
|
-
expect(payload.encoding).toBe('multipart/form-data; boundary=something')
|
|
278
|
+
const def = payload('multipart/form-data; boundary=something', undefined)
|
|
279
|
+
expect(def.encoding).toBe('multipart/form-data; boundary=something')
|
|
286
280
|
})
|
|
287
281
|
|
|
288
282
|
it('handles empty string encoding', () => {
|
|
289
|
-
const
|
|
290
|
-
expect(
|
|
283
|
+
const def = payload('', undefined)
|
|
284
|
+
expect(def.encoding).toBe('')
|
|
291
285
|
})
|
|
292
286
|
|
|
293
287
|
it('creates multiple payloads with same schema reference', () => {
|
|
294
|
-
const sharedSchema =
|
|
295
|
-
id:
|
|
288
|
+
const sharedSchema = object({
|
|
289
|
+
id: integer(),
|
|
296
290
|
})
|
|
297
|
-
const
|
|
298
|
-
const
|
|
291
|
+
const def1 = payload('application/json', sharedSchema)
|
|
292
|
+
const def2 = payload('application/json', sharedSchema)
|
|
299
293
|
|
|
300
|
-
expect(
|
|
301
|
-
expect(
|
|
294
|
+
expect(def1.schema).toBe(def2.schema)
|
|
295
|
+
expect(def1.schema).toBe(sharedSchema)
|
|
302
296
|
})
|
|
303
297
|
|
|
304
298
|
it('creates multiple payloads with different schemas', () => {
|
|
305
|
-
const schema1 =
|
|
306
|
-
const schema2 =
|
|
307
|
-
const
|
|
308
|
-
const
|
|
299
|
+
const schema1 = string()
|
|
300
|
+
const schema2 = integer()
|
|
301
|
+
const def1 = payload('application/json', schema1)
|
|
302
|
+
const def2 = payload('application/json', schema2)
|
|
309
303
|
|
|
310
|
-
expect(
|
|
311
|
-
expect(
|
|
312
|
-
expect(
|
|
304
|
+
expect(def1.schema).not.toBe(def2.schema)
|
|
305
|
+
expect(def1.schema).toBe(schema1)
|
|
306
|
+
expect(def2.schema).toBe(schema2)
|
|
313
307
|
})
|
|
314
308
|
})
|
|
315
309
|
|
|
316
310
|
describe('type inference scenarios', () => {
|
|
317
311
|
it('works with application/json and object schema', () => {
|
|
318
|
-
const schema =
|
|
319
|
-
message:
|
|
312
|
+
const schema = object({
|
|
313
|
+
message: string(),
|
|
320
314
|
})
|
|
321
|
-
const
|
|
322
|
-
expect(
|
|
323
|
-
expect(
|
|
315
|
+
const def = payload('application/json', schema)
|
|
316
|
+
expect(def.encoding).toBe('application/json')
|
|
317
|
+
expect(def.schema).toBe(schema)
|
|
324
318
|
})
|
|
325
319
|
|
|
326
320
|
it('works with text/* encodings expecting string bodies', () => {
|
|
327
|
-
const
|
|
328
|
-
const
|
|
329
|
-
const
|
|
321
|
+
const def1 = payload('text/plain', undefined)
|
|
322
|
+
const def2 = payload('text/html', undefined)
|
|
323
|
+
const def3 = payload('text/csv', undefined)
|
|
330
324
|
|
|
331
|
-
expect(
|
|
332
|
-
expect(
|
|
333
|
-
expect(
|
|
325
|
+
expect(def1.encoding).toBe('text/plain')
|
|
326
|
+
expect(def2.encoding).toBe('text/html')
|
|
327
|
+
expect(def3.encoding).toBe('text/csv')
|
|
334
328
|
})
|
|
335
329
|
|
|
336
330
|
it('works with binary encodings expecting Uint8Array bodies', () => {
|
|
337
|
-
const
|
|
338
|
-
const
|
|
339
|
-
const
|
|
331
|
+
const def1 = payload('image/png', undefined)
|
|
332
|
+
const def2 = payload('application/octet-stream', undefined)
|
|
333
|
+
const def3 = payload('video/mp4', undefined)
|
|
340
334
|
|
|
341
|
-
expect(
|
|
342
|
-
expect(
|
|
343
|
-
expect(
|
|
335
|
+
expect(def1.encoding).toBe('image/png')
|
|
336
|
+
expect(def2.encoding).toBe('application/octet-stream')
|
|
337
|
+
expect(def3.encoding).toBe('video/mp4')
|
|
344
338
|
})
|
|
345
339
|
})
|
|
346
340
|
})
|
package/src/schema/payload.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { LexValue } from '@atproto/lex-data'
|
|
2
2
|
import { Infer, Schema } from '../core.js'
|
|
3
|
+
import { ObjectSchema, ObjectSchemaShape, object } from './object.js'
|
|
3
4
|
|
|
4
5
|
export type InferPayload<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
> =
|
|
6
|
+
TPayload extends Payload,
|
|
7
|
+
TBody,
|
|
8
|
+
> = TPayload['encoding'] extends infer E extends string
|
|
8
9
|
? {
|
|
9
10
|
encoding: SchemaEncodingToDataEncoding<E>
|
|
10
|
-
body: InferPayloadBody<
|
|
11
|
+
body: InferPayloadBody<TPayload, TBody>
|
|
11
12
|
}
|
|
12
13
|
: void | undefined
|
|
13
14
|
|
|
@@ -17,33 +18,33 @@ export type SchemaEncodingToDataEncoding<E extends string> = E extends '*/*'
|
|
|
17
18
|
? `${T}/${string}`
|
|
18
19
|
: E
|
|
19
20
|
|
|
20
|
-
export type InferPayloadEncoding<
|
|
21
|
-
|
|
22
|
-
? SchemaEncodingToDataEncoding<
|
|
21
|
+
export type InferPayloadEncoding<TPayload extends Payload> =
|
|
22
|
+
TPayload['encoding'] extends string
|
|
23
|
+
? SchemaEncodingToDataEncoding<TPayload['encoding']>
|
|
23
24
|
: undefined
|
|
24
25
|
|
|
25
26
|
export type InferPayloadBody<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
> =
|
|
27
|
+
TPayload extends Payload,
|
|
28
|
+
TBody,
|
|
29
|
+
> = TPayload['encoding'] extends undefined
|
|
29
30
|
? undefined // No encoding, no payload
|
|
30
|
-
:
|
|
31
|
-
? Infer<
|
|
32
|
-
:
|
|
31
|
+
: TPayload['schema'] extends Schema
|
|
32
|
+
? Infer<TPayload['schema']>
|
|
33
|
+
: TPayload['encoding'] extends `application/json`
|
|
33
34
|
? LexValue
|
|
34
|
-
:
|
|
35
|
+
: TBody
|
|
35
36
|
|
|
36
|
-
export type
|
|
37
|
+
export type PayloadShape<E extends string | undefined> = E extends undefined
|
|
37
38
|
? undefined
|
|
38
39
|
: Schema | undefined
|
|
39
40
|
|
|
40
41
|
export class Payload<
|
|
41
|
-
const
|
|
42
|
-
const
|
|
42
|
+
const TEncoding extends string | undefined = string | undefined,
|
|
43
|
+
const TPayload extends PayloadShape<TEncoding> = PayloadShape<TEncoding>,
|
|
43
44
|
> {
|
|
44
45
|
constructor(
|
|
45
|
-
readonly encoding:
|
|
46
|
-
readonly schema:
|
|
46
|
+
readonly encoding: TEncoding,
|
|
47
|
+
readonly schema: TPayload,
|
|
47
48
|
) {
|
|
48
49
|
if (encoding === undefined && schema !== undefined) {
|
|
49
50
|
throw new TypeError('schema cannot be defined when encoding is undefined')
|
|
@@ -84,3 +85,18 @@ export class Payload<
|
|
|
84
85
|
return encoding === mime
|
|
85
86
|
}
|
|
86
87
|
}
|
|
88
|
+
|
|
89
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
90
|
+
export function payload<
|
|
91
|
+
const E extends string | undefined = undefined,
|
|
92
|
+
const S extends PayloadShape<E> = undefined,
|
|
93
|
+
>(encoding: E = undefined as E, validator: S = undefined as S) {
|
|
94
|
+
return new Payload<E, S>(encoding, validator)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
98
|
+
export function jsonPayload<const P extends ObjectSchemaShape>(
|
|
99
|
+
properties: P,
|
|
100
|
+
): Payload<'application/json', ObjectSchema<P>> {
|
|
101
|
+
return payload('application/json', object(properties))
|
|
102
|
+
}
|