@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,499 +0,0 @@
|
|
|
1
|
-
import { describe, expect, expectTypeOf, it } from 'vitest'
|
|
2
|
-
import { integer } from './integer.js'
|
|
3
|
-
import { ObjectSchema, object } from './object.js'
|
|
4
|
-
import { optional } from './optional.js'
|
|
5
|
-
import { ParamsSchema, params } from './params.js'
|
|
6
|
-
import { RefSchema, ref } from './ref.js'
|
|
7
|
-
import { string } from './string.js'
|
|
8
|
-
import {
|
|
9
|
-
InferSubscriptionMessage,
|
|
10
|
-
InferSubscriptionParameters,
|
|
11
|
-
Subscription,
|
|
12
|
-
subscription,
|
|
13
|
-
} from './subscription.js'
|
|
14
|
-
|
|
15
|
-
describe('Subscription', () => {
|
|
16
|
-
describe('constructor', () => {
|
|
17
|
-
it('creates a Subscription instance with all parameters', () => {
|
|
18
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
19
|
-
const parameters = params({
|
|
20
|
-
cursor: optional(integer()),
|
|
21
|
-
})
|
|
22
|
-
const message = object({
|
|
23
|
-
seq: integer(),
|
|
24
|
-
data: string(),
|
|
25
|
-
})
|
|
26
|
-
const errors = ['ConsumerTooSlow', 'FutureCursor'] as const
|
|
27
|
-
|
|
28
|
-
const mySub = subscription(nsid, parameters, message, errors)
|
|
29
|
-
|
|
30
|
-
expect(mySub).toBeInstanceOf(Subscription)
|
|
31
|
-
expect(mySub.nsid).toBe(nsid)
|
|
32
|
-
expect(mySub.parameters).toBe(parameters)
|
|
33
|
-
expect(mySub.message).toBe(message)
|
|
34
|
-
expect(mySub.errors).toBe(errors)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it('creates a Subscription instance without errors', () => {
|
|
38
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
39
|
-
const parameters = params({
|
|
40
|
-
cursor: optional(integer()),
|
|
41
|
-
})
|
|
42
|
-
const message = object({
|
|
43
|
-
seq: integer(),
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
47
|
-
|
|
48
|
-
expect(mySub).toBeInstanceOf(Subscription)
|
|
49
|
-
expect(mySub.nsid).toBe(nsid)
|
|
50
|
-
expect(mySub.parameters).toBe(parameters)
|
|
51
|
-
expect(mySub.message).toBe(message)
|
|
52
|
-
expect(mySub.errors).toBeUndefined()
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('creates a Subscription instance with empty parameters', () => {
|
|
56
|
-
const nsid = 'app.bsky.notification.subscribe'
|
|
57
|
-
const parameters = params()
|
|
58
|
-
const message = object({
|
|
59
|
-
type: string(),
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
63
|
-
|
|
64
|
-
expect(mySub).toBeInstanceOf(Subscription)
|
|
65
|
-
expect(mySub.parameters).toBe(parameters)
|
|
66
|
-
})
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
describe('type property', () => {
|
|
70
|
-
it('has type set to "subscription"', () => {
|
|
71
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
72
|
-
const parameters = params()
|
|
73
|
-
const message = object({
|
|
74
|
-
seq: integer(),
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
78
|
-
|
|
79
|
-
expect(mySub.type).toBe('subscription')
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
it('type is a constant value', () => {
|
|
83
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
84
|
-
const parameters = params()
|
|
85
|
-
const message = object({
|
|
86
|
-
seq: integer(),
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
90
|
-
|
|
91
|
-
expect(mySub.type).toBe('subscription')
|
|
92
|
-
// TypeScript enforces readonly at compile time
|
|
93
|
-
expect(typeof mySub.type).toBe('string')
|
|
94
|
-
})
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
describe('properties', () => {
|
|
98
|
-
it('has nsid property', () => {
|
|
99
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
100
|
-
const parameters = params()
|
|
101
|
-
const message = object({
|
|
102
|
-
seq: integer(),
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
106
|
-
|
|
107
|
-
expect(mySub.nsid).toBe(nsid)
|
|
108
|
-
expect(typeof mySub.nsid).toBe('string')
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
it('has parameters property', () => {
|
|
112
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
113
|
-
const parameters = params()
|
|
114
|
-
const message = object({
|
|
115
|
-
seq: integer(),
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
119
|
-
|
|
120
|
-
expect(mySub.parameters).toBe(parameters)
|
|
121
|
-
expect(mySub.parameters).toBeInstanceOf(ParamsSchema)
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
it('has message property', () => {
|
|
125
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
126
|
-
const parameters = params()
|
|
127
|
-
const message = object({
|
|
128
|
-
seq: integer(),
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
132
|
-
|
|
133
|
-
expect(mySub.message).toBe(message)
|
|
134
|
-
expect(mySub.message).toBeInstanceOf(ObjectSchema)
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
it('has errors property', () => {
|
|
138
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
139
|
-
const parameters = params()
|
|
140
|
-
const message = object({
|
|
141
|
-
seq: integer(),
|
|
142
|
-
})
|
|
143
|
-
const errors = ['ConsumerTooSlow'] as const
|
|
144
|
-
|
|
145
|
-
const mySub = subscription(nsid, parameters, message, errors)
|
|
146
|
-
|
|
147
|
-
expect(mySub.errors).toBe(errors)
|
|
148
|
-
expect(Array.isArray(mySub.errors)).toBe(true)
|
|
149
|
-
})
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
describe('with complex parameters', () => {
|
|
153
|
-
it('creates a Subscription with multiple parameter types', () => {
|
|
154
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
155
|
-
const parameters = params({
|
|
156
|
-
cursor: optional(integer({ minimum: 0 })),
|
|
157
|
-
includeDeletes: optional(integer({ minimum: 0, maximum: 1 })),
|
|
158
|
-
})
|
|
159
|
-
const message = object({
|
|
160
|
-
seq: integer(),
|
|
161
|
-
data: string(),
|
|
162
|
-
})
|
|
163
|
-
const errors = ['ConsumerTooSlow', 'FutureCursor'] as const
|
|
164
|
-
|
|
165
|
-
const mySub = subscription(nsid, parameters, message, errors)
|
|
166
|
-
|
|
167
|
-
expect(mySub).toBeInstanceOf(Subscription)
|
|
168
|
-
expect(mySub.parameters).toBe(parameters)
|
|
169
|
-
expect(mySub.errors).toEqual(['ConsumerTooSlow', 'FutureCursor'])
|
|
170
|
-
})
|
|
171
|
-
})
|
|
172
|
-
|
|
173
|
-
describe('with various message types', () => {
|
|
174
|
-
it('creates a Subscription with ObjectSchema message', () => {
|
|
175
|
-
const mySub = subscription(
|
|
176
|
-
'com.atproto.sync.subscribeRepos',
|
|
177
|
-
params(),
|
|
178
|
-
object({
|
|
179
|
-
seq: integer(),
|
|
180
|
-
data: string(),
|
|
181
|
-
}),
|
|
182
|
-
undefined,
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
expect(mySub).toBeInstanceOf(Subscription)
|
|
186
|
-
expect(mySub.message).toBeInstanceOf(ObjectSchema)
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
it('creates a Subscription with RefSchema message', () => {
|
|
190
|
-
const message = string()
|
|
191
|
-
const mySub = subscription(
|
|
192
|
-
'app.bsky.feed.subscribe',
|
|
193
|
-
params(),
|
|
194
|
-
ref(() => message),
|
|
195
|
-
undefined,
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
expect(mySub).toBeInstanceOf(Subscription)
|
|
199
|
-
expect(mySub.message).toBeInstanceOf(RefSchema)
|
|
200
|
-
})
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
describe('with different error configurations', () => {
|
|
204
|
-
it('creates a Subscription with a single error', () => {
|
|
205
|
-
const mySub = subscription(
|
|
206
|
-
'com.atproto.sync.subscribeRepos',
|
|
207
|
-
params(),
|
|
208
|
-
object({}),
|
|
209
|
-
['ConsumerTooSlow'],
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
expect(mySub.errors).toEqual(['ConsumerTooSlow'])
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
it('creates a Subscription with multiple errors', () => {
|
|
216
|
-
const mySub = subscription(
|
|
217
|
-
'com.atproto.sync.subscribeRepos',
|
|
218
|
-
params(),
|
|
219
|
-
object({}),
|
|
220
|
-
['ConsumerTooSlow', 'FutureCursor', 'InvalidCursor'],
|
|
221
|
-
)
|
|
222
|
-
|
|
223
|
-
expectTypeOf<
|
|
224
|
-
readonly ['ConsumerTooSlow', 'FutureCursor', 'InvalidCursor']
|
|
225
|
-
>(mySub.errors)
|
|
226
|
-
|
|
227
|
-
expect(mySub.errors).toEqual([
|
|
228
|
-
'ConsumerTooSlow',
|
|
229
|
-
'FutureCursor',
|
|
230
|
-
'InvalidCursor',
|
|
231
|
-
])
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
it('creates a Subscription with empty errors array', () => {
|
|
235
|
-
const mySub = subscription(
|
|
236
|
-
'com.atproto.sync.subscribeRepos',
|
|
237
|
-
params(),
|
|
238
|
-
object({}),
|
|
239
|
-
[],
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
expect(mySub.errors).toEqual([])
|
|
243
|
-
})
|
|
244
|
-
})
|
|
245
|
-
|
|
246
|
-
describe('type inference', () => {
|
|
247
|
-
it('InferSubscriptionParameters correctly infers parameter types', () => {
|
|
248
|
-
const _mySub = subscription(
|
|
249
|
-
'com.atproto.sync.subscribeRepos',
|
|
250
|
-
params({
|
|
251
|
-
cursor: optional(integer()),
|
|
252
|
-
}),
|
|
253
|
-
object({
|
|
254
|
-
seq: integer(),
|
|
255
|
-
}),
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
type Params = InferSubscriptionParameters<typeof _mySub>
|
|
259
|
-
|
|
260
|
-
expectTypeOf<Params>({
|
|
261
|
-
cursor: 12345,
|
|
262
|
-
})
|
|
263
|
-
})
|
|
264
|
-
|
|
265
|
-
it('InferSubscriptionMessage correctly infers message type', () => {
|
|
266
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
267
|
-
const parameters = params()
|
|
268
|
-
const message = object({
|
|
269
|
-
seq: integer(),
|
|
270
|
-
data: string(),
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
const _mySub = subscription(nsid, parameters, message, undefined)
|
|
274
|
-
|
|
275
|
-
type Message = InferSubscriptionMessage<typeof _mySub>
|
|
276
|
-
|
|
277
|
-
expectTypeOf<Message>({
|
|
278
|
-
seq: 12345,
|
|
279
|
-
data: 'test data',
|
|
280
|
-
})
|
|
281
|
-
})
|
|
282
|
-
})
|
|
283
|
-
|
|
284
|
-
describe('edge cases', () => {
|
|
285
|
-
it('handles very long NSID', () => {
|
|
286
|
-
const nsid =
|
|
287
|
-
'com.example.very.long.namespace.identifier.subscription.name'
|
|
288
|
-
const parameters = params()
|
|
289
|
-
const message = object({})
|
|
290
|
-
|
|
291
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
292
|
-
|
|
293
|
-
expect(mySub.nsid).toBe(nsid)
|
|
294
|
-
})
|
|
295
|
-
|
|
296
|
-
it('handles subscription with all optional parameters', () => {
|
|
297
|
-
const nsid = 'app.bsky.feed.subscribe'
|
|
298
|
-
const parameters = params({
|
|
299
|
-
cursor: optional(integer()),
|
|
300
|
-
includeDeletes: optional(integer()),
|
|
301
|
-
includeEdits: optional(integer()),
|
|
302
|
-
})
|
|
303
|
-
const message = object({})
|
|
304
|
-
|
|
305
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
306
|
-
|
|
307
|
-
expect(mySub.parameters).toBe(parameters)
|
|
308
|
-
})
|
|
309
|
-
|
|
310
|
-
it('handles subscription with complex nested message schema', () => {
|
|
311
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
312
|
-
const parameters = params()
|
|
313
|
-
const message = object({
|
|
314
|
-
seq: integer(),
|
|
315
|
-
blocks: object({
|
|
316
|
-
cid: string({ format: 'cid' }),
|
|
317
|
-
data: object({
|
|
318
|
-
uri: string({ format: 'at-uri' }),
|
|
319
|
-
content: string(),
|
|
320
|
-
}),
|
|
321
|
-
}),
|
|
322
|
-
})
|
|
323
|
-
|
|
324
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
325
|
-
|
|
326
|
-
expect(mySub.message).toBeInstanceOf(ObjectSchema)
|
|
327
|
-
})
|
|
328
|
-
})
|
|
329
|
-
|
|
330
|
-
describe('real-world subscription examples', () => {
|
|
331
|
-
it('creates a subscribeLabels subscription', () => {
|
|
332
|
-
const nsid = 'com.atproto.label.subscribeLabels'
|
|
333
|
-
const parameters = params({
|
|
334
|
-
cursor: optional(integer({ minimum: 0 })),
|
|
335
|
-
})
|
|
336
|
-
const message = object({
|
|
337
|
-
seq: integer(),
|
|
338
|
-
labels: object({
|
|
339
|
-
uri: string({ format: 'uri' }),
|
|
340
|
-
val: string(),
|
|
341
|
-
}),
|
|
342
|
-
})
|
|
343
|
-
|
|
344
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
345
|
-
|
|
346
|
-
expect(mySub.type).toBe('subscription')
|
|
347
|
-
expect(mySub.nsid).toBe('com.atproto.label.subscribeLabels')
|
|
348
|
-
expect(mySub.parameters.matches({ cursor: 10 })).toBe(true)
|
|
349
|
-
expect(mySub.parameters.matches({ cursor: -10 })).toBe(false)
|
|
350
|
-
expect(
|
|
351
|
-
mySub.message.matches({
|
|
352
|
-
seq: 1,
|
|
353
|
-
labels: { uri: 'http://foo.com', val: 'test' },
|
|
354
|
-
}),
|
|
355
|
-
).toBe(true)
|
|
356
|
-
expect(
|
|
357
|
-
mySub.message.matches({
|
|
358
|
-
seq: 1,
|
|
359
|
-
labels: { uri: 'http://foo.com', val: 3 },
|
|
360
|
-
}),
|
|
361
|
-
).toBe(false)
|
|
362
|
-
})
|
|
363
|
-
|
|
364
|
-
it('creates a notification subscription', () => {
|
|
365
|
-
const nsid = 'app.bsky.notification.subscribe'
|
|
366
|
-
const parameters = params({
|
|
367
|
-
cursor: optional(string()),
|
|
368
|
-
})
|
|
369
|
-
const message = object({
|
|
370
|
-
type: string(),
|
|
371
|
-
uri: string({ format: 'at-uri' }),
|
|
372
|
-
cid: string({ format: 'cid' }),
|
|
373
|
-
})
|
|
374
|
-
|
|
375
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
376
|
-
|
|
377
|
-
expect(mySub.type).toBe('subscription')
|
|
378
|
-
expect(mySub.nsid).toBe('app.bsky.notification.subscribe')
|
|
379
|
-
})
|
|
380
|
-
})
|
|
381
|
-
|
|
382
|
-
describe('with mixed parameter and message types', () => {
|
|
383
|
-
it('handles required and optional parameters with complex message', () => {
|
|
384
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
385
|
-
const parameters = params({
|
|
386
|
-
cursor: optional(integer({ minimum: 0 })),
|
|
387
|
-
includeDeletes: optional(integer({ minimum: 0, maximum: 1 })),
|
|
388
|
-
})
|
|
389
|
-
const message = object({
|
|
390
|
-
seq: integer(),
|
|
391
|
-
rebase: optional(integer({ minimum: 0, maximum: 1 })),
|
|
392
|
-
tooBig: optional(integer({ minimum: 0, maximum: 1 })),
|
|
393
|
-
repo: string({ format: 'did' }),
|
|
394
|
-
commit: string({ format: 'cid' }),
|
|
395
|
-
blocks: string(),
|
|
396
|
-
ops: object({}),
|
|
397
|
-
})
|
|
398
|
-
|
|
399
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
400
|
-
|
|
401
|
-
expect(mySub.type).toBe('subscription')
|
|
402
|
-
expect(mySub.parameters).toBe(parameters)
|
|
403
|
-
expect(mySub.message).toBe(message)
|
|
404
|
-
})
|
|
405
|
-
})
|
|
406
|
-
|
|
407
|
-
describe('validation through nested schemas', () => {
|
|
408
|
-
it('parameters can validate input through ParamsSchema', () => {
|
|
409
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
410
|
-
const parameters = params({
|
|
411
|
-
cursor: integer({ minimum: 0 }),
|
|
412
|
-
})
|
|
413
|
-
const message = object({})
|
|
414
|
-
|
|
415
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
416
|
-
|
|
417
|
-
// Test that the parameters schema can validate
|
|
418
|
-
const validResult = mySub.parameters.safeParse({ cursor: 100 })
|
|
419
|
-
expect(validResult.success).toBe(true)
|
|
420
|
-
|
|
421
|
-
const invalidResult = mySub.parameters.safeParse({ cursor: -1 })
|
|
422
|
-
expect(invalidResult.success).toBe(false)
|
|
423
|
-
})
|
|
424
|
-
|
|
425
|
-
it('message can validate input through ObjectSchema', () => {
|
|
426
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
427
|
-
const parameters = params()
|
|
428
|
-
const message = object({
|
|
429
|
-
seq: integer({ minimum: 0 }),
|
|
430
|
-
data: string({ minLength: 1 }),
|
|
431
|
-
})
|
|
432
|
-
|
|
433
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
434
|
-
|
|
435
|
-
// Test that the message schema can validate
|
|
436
|
-
const validResult = mySub.message.safeParse({
|
|
437
|
-
seq: 100,
|
|
438
|
-
data: 'test',
|
|
439
|
-
})
|
|
440
|
-
expect(validResult.success).toBe(true)
|
|
441
|
-
|
|
442
|
-
const invalidResult = mySub.message.safeParse({
|
|
443
|
-
seq: -1,
|
|
444
|
-
data: '',
|
|
445
|
-
})
|
|
446
|
-
expect(invalidResult.success).toBe(false)
|
|
447
|
-
})
|
|
448
|
-
})
|
|
449
|
-
|
|
450
|
-
describe('property access', () => {
|
|
451
|
-
it('can access nsid after construction', () => {
|
|
452
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
453
|
-
const parameters = params()
|
|
454
|
-
const message = object({})
|
|
455
|
-
|
|
456
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
457
|
-
|
|
458
|
-
expect(mySub.nsid).toBe(nsid)
|
|
459
|
-
expect(mySub.nsid).toBe('com.atproto.sync.subscribeRepos')
|
|
460
|
-
})
|
|
461
|
-
|
|
462
|
-
it('can access type after construction', () => {
|
|
463
|
-
const nsid = 'com.atproto.sync.subscribeRepos'
|
|
464
|
-
const parameters = params()
|
|
465
|
-
const message = object({})
|
|
466
|
-
|
|
467
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
468
|
-
|
|
469
|
-
expect(mySub.type).toBe('subscription')
|
|
470
|
-
expect(typeof mySub.type).toBe('string')
|
|
471
|
-
})
|
|
472
|
-
})
|
|
473
|
-
|
|
474
|
-
describe('different message schema types', () => {
|
|
475
|
-
it('constructs with ObjectSchema message', () => {
|
|
476
|
-
const nsid = 'app.bsky.test'
|
|
477
|
-
const parameters = params()
|
|
478
|
-
const message = object({
|
|
479
|
-
field: string(),
|
|
480
|
-
})
|
|
481
|
-
|
|
482
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
483
|
-
|
|
484
|
-
expect(mySub.message).toBeInstanceOf(ObjectSchema)
|
|
485
|
-
expect(mySub.message).toBe(message)
|
|
486
|
-
})
|
|
487
|
-
|
|
488
|
-
it('constructs with RefSchema message', () => {
|
|
489
|
-
const nsid = 'app.bsky.test'
|
|
490
|
-
const parameters = params()
|
|
491
|
-
const message = ref(() => object({}))
|
|
492
|
-
|
|
493
|
-
const mySub = subscription(nsid, parameters, message, undefined)
|
|
494
|
-
|
|
495
|
-
expect(mySub.message).toBeInstanceOf(RefSchema)
|
|
496
|
-
expect(mySub.message).toBe(message)
|
|
497
|
-
})
|
|
498
|
-
})
|
|
499
|
-
})
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { LexValue } from '@atproto/lex-data'
|
|
2
|
-
import { Infer, NsidString, Schema } from '../core.js'
|
|
3
|
-
import { ParamsSchema } from './params.js'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Infers the parameters type from a Subscription definition.
|
|
7
|
-
*
|
|
8
|
-
* @template S - The Subscription type
|
|
9
|
-
*/
|
|
10
|
-
export type InferSubscriptionParameters<S extends Subscription> = Infer<
|
|
11
|
-
S['parameters']
|
|
12
|
-
>
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Infers the message type from a Subscription definition.
|
|
16
|
-
*
|
|
17
|
-
* @template S - The Subscription type
|
|
18
|
-
*/
|
|
19
|
-
export type InferSubscriptionMessage<S extends Subscription> = Infer<
|
|
20
|
-
S['message']
|
|
21
|
-
>
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Represents a Lexicon subscription (WebSocket) endpoint definition.
|
|
25
|
-
*
|
|
26
|
-
* Subscriptions are real-time event streams delivered over WebSocket.
|
|
27
|
-
* They have parameters for initializing the connection and a message
|
|
28
|
-
* schema for validating incoming events.
|
|
29
|
-
*
|
|
30
|
-
* @template TNsid - The NSID identifying this subscription
|
|
31
|
-
* @template TParameters - The connection parameters schema type
|
|
32
|
-
* @template TMessage - The message schema type
|
|
33
|
-
* @template TErrors - Array of error type strings, or undefined
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```ts
|
|
37
|
-
* const firehose = new Subscription(
|
|
38
|
-
* 'com.atproto.sync.subscribeRepos',
|
|
39
|
-
* l.params({ cursor: l.optional(l.integer()) }),
|
|
40
|
-
* repoEventSchema,
|
|
41
|
-
* ['FutureCursor']
|
|
42
|
-
* )
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
export class Subscription<
|
|
46
|
-
const TNsid extends NsidString = NsidString,
|
|
47
|
-
const TParameters extends ParamsSchema = ParamsSchema,
|
|
48
|
-
const TMessage extends Schema<LexValue> = Schema<LexValue>,
|
|
49
|
-
const TErrors extends undefined | readonly string[] =
|
|
50
|
-
| undefined
|
|
51
|
-
| readonly string[],
|
|
52
|
-
> {
|
|
53
|
-
readonly type = 'subscription' as const
|
|
54
|
-
|
|
55
|
-
constructor(
|
|
56
|
-
readonly nsid: TNsid,
|
|
57
|
-
readonly parameters: TParameters,
|
|
58
|
-
readonly message: TMessage,
|
|
59
|
-
readonly errors: TErrors,
|
|
60
|
-
) {}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Creates a subscription definition for a Lexicon WebSocket endpoint.
|
|
65
|
-
*
|
|
66
|
-
* Subscriptions enable real-time event streaming. The connection is
|
|
67
|
-
* initialized with parameters, and the server sends messages matching
|
|
68
|
-
* the message schema.
|
|
69
|
-
*
|
|
70
|
-
* @param nsid - The NSID identifying this subscription endpoint
|
|
71
|
-
* @param parameters - Schema for connection parameters
|
|
72
|
-
* @param message - Schema for validating incoming messages
|
|
73
|
-
* @param errors - Optional array of error type strings
|
|
74
|
-
* @returns A new {@link Subscription} instance
|
|
75
|
-
*
|
|
76
|
-
* @example
|
|
77
|
-
* ```ts
|
|
78
|
-
* // Repository event stream
|
|
79
|
-
* const subscribeRepos = l.subscription(
|
|
80
|
-
* 'com.atproto.sync.subscribeRepos',
|
|
81
|
-
* l.params({
|
|
82
|
-
* cursor: l.optional(l.integer()),
|
|
83
|
-
* }),
|
|
84
|
-
* l.typedUnion([
|
|
85
|
-
* l.typedRef(() => commitEventSchema),
|
|
86
|
-
* l.typedRef(() => handleEventSchema),
|
|
87
|
-
* l.typedRef(() => identityEventSchema),
|
|
88
|
-
* ], false),
|
|
89
|
-
* ['FutureCursor', 'ConsumerTooSlow'],
|
|
90
|
-
* )
|
|
91
|
-
*
|
|
92
|
-
* // Label stream
|
|
93
|
-
* const subscribeLabels = l.subscription(
|
|
94
|
-
* 'com.atproto.label.subscribeLabels',
|
|
95
|
-
* l.params({ cursor: l.optional(l.integer()) }),
|
|
96
|
-
* labelEventSchema,
|
|
97
|
-
* )
|
|
98
|
-
* ```
|
|
99
|
-
*/
|
|
100
|
-
/*@__NO_SIDE_EFFECTS__*/
|
|
101
|
-
export function subscription<
|
|
102
|
-
const N extends NsidString,
|
|
103
|
-
const P extends ParamsSchema,
|
|
104
|
-
const M extends Schema<LexValue>,
|
|
105
|
-
const E extends undefined | readonly string[] = undefined,
|
|
106
|
-
>(nsid: N, parameters: P, message: M, errors: E = undefined as E) {
|
|
107
|
-
return new Subscription<N, P, M, E>(nsid, parameters, message, errors)
|
|
108
|
-
}
|