@atproto/lex-schema 0.0.4 → 0.0.5
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 +37 -0
- package/dist/core/$type.d.ts +7 -0
- package/dist/core/$type.d.ts.map +1 -1
- package/dist/core/$type.js.map +1 -1
- package/dist/core/result.d.ts +7 -6
- package/dist/core/result.d.ts.map +1 -1
- package/dist/core/result.js +9 -8
- package/dist/core/result.js.map +1 -1
- package/dist/core/string-format.d.ts +37 -26
- package/dist/core/string-format.d.ts.map +1 -1
- package/dist/core/string-format.js +66 -59
- package/dist/core/string-format.js.map +1 -1
- package/dist/core/types.d.ts +3 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/external.d.ts +7 -6
- package/dist/external.d.ts.map +1 -1
- package/dist/external.js +1 -0
- package/dist/external.js.map +1 -1
- package/dist/helpers.d.ts +36 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +3 -0
- package/dist/helpers.js.map +1 -0
- package/dist/schema/blob.d.ts +1 -0
- package/dist/schema/blob.d.ts.map +1 -1
- package/dist/schema/blob.js +32 -18
- package/dist/schema/blob.js.map +1 -1
- package/dist/schema/custom.js +1 -1
- package/dist/schema/custom.js.map +1 -1
- package/dist/schema/integer.js +1 -1
- package/dist/schema/integer.js.map +1 -1
- package/dist/schema/params.d.ts +0 -1
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/payload.d.ts +17 -15
- package/dist/schema/payload.d.ts.map +1 -1
- package/dist/schema/payload.js +28 -0
- package/dist/schema/payload.js.map +1 -1
- package/dist/schema/procedure.d.ts +3 -6
- package/dist/schema/procedure.d.ts.map +1 -1
- package/dist/schema/procedure.js +1 -0
- package/dist/schema/procedure.js.map +1 -1
- package/dist/schema/query.d.ts +3 -5
- package/dist/schema/query.d.ts.map +1 -1
- package/dist/schema/query.js +1 -0
- package/dist/schema/query.js.map +1 -1
- package/dist/schema/record.d.ts +13 -12
- package/dist/schema/record.d.ts.map +1 -1
- package/dist/schema/record.js.map +1 -1
- package/dist/schema/refine.js +1 -1
- package/dist/schema/refine.js.map +1 -1
- package/dist/schema/subscription.d.ts +4 -7
- package/dist/schema/subscription.d.ts.map +1 -1
- package/dist/schema/subscription.js.map +1 -1
- package/dist/schema/typed-object.d.ts +7 -6
- package/dist/schema/typed-object.d.ts.map +1 -1
- package/dist/schema/typed-object.js.map +1 -1
- package/dist/schema/union.d.ts.map +1 -1
- package/dist/schema/union.js +1 -4
- package/dist/schema/union.js.map +1 -1
- package/dist/util/assertion-util.d.ts +8 -0
- package/dist/util/assertion-util.d.ts.map +1 -0
- package/dist/util/assertion-util.js +31 -0
- package/dist/util/assertion-util.js.map +1 -0
- package/dist/validation/schema.d.ts +21 -2
- package/dist/validation/schema.d.ts.map +1 -1
- package/dist/validation/schema.js +25 -2
- package/dist/validation/schema.js.map +1 -1
- package/dist/validation/validation-error.d.ts.map +1 -1
- package/dist/validation/validation-error.js +3 -3
- package/dist/validation/validation-error.js.map +1 -1
- package/dist/validation/validation-issue.js +10 -2
- package/dist/validation/validation-issue.js.map +1 -1
- package/dist/validation/validator.d.ts +4 -3
- package/dist/validation/validator.d.ts.map +1 -1
- package/dist/validation/validator.js +13 -10
- package/dist/validation/validator.js.map +1 -1
- package/package.json +2 -2
- package/src/core/$type.ts +4 -0
- package/src/core/result.ts +9 -8
- package/src/core/string-format.ts +88 -68
- package/src/core/types.ts +4 -0
- package/src/external.ts +9 -8
- package/src/helpers.test.ts +486 -0
- package/src/helpers.ts +61 -0
- package/src/schema/blob.test.ts +2 -4
- package/src/schema/blob.ts +31 -23
- package/src/schema/custom.test.ts +5 -5
- package/src/schema/custom.ts +1 -1
- package/src/schema/integer.ts +1 -1
- package/src/schema/params.ts +0 -7
- package/src/schema/payload.ts +67 -34
- package/src/schema/permission-set.test.ts +36 -36
- package/src/schema/procedure.test.ts +1 -62
- package/src/schema/procedure.ts +8 -20
- package/src/schema/query.test.ts +22 -69
- package/src/schema/query.ts +7 -14
- package/src/schema/record.ts +8 -4
- package/src/schema/refine.ts +1 -1
- package/src/schema/subscription.test.ts +30 -93
- package/src/schema/subscription.ts +11 -24
- package/src/schema/typed-object.ts +7 -3
- package/src/schema/union.ts +1 -4
- package/src/util/assertion-util.ts +40 -0
- package/src/validation/schema.ts +29 -4
- package/src/validation/validation-error.ts +4 -4
- package/src/validation/validation-issue.ts +12 -2
- package/src/validation/validator.ts +16 -12
- package/tsconfig.tests.json +1 -1
package/src/schema/params.ts
CHANGED
|
@@ -18,13 +18,6 @@ export type ParamsSchemaOutput<Shape extends ParamsSchemaShape> =
|
|
|
18
18
|
[K in keyof Shape]: Infer<Shape[K]>
|
|
19
19
|
}>
|
|
20
20
|
|
|
21
|
-
export type InferParamsSchema<T> =
|
|
22
|
-
T extends ParamsSchema<infer P>
|
|
23
|
-
? NonNullable<unknown> extends ParamsSchemaOutput<P>
|
|
24
|
-
? ParamsSchemaOutput<P> | undefined // Allow undefined if all params are optional
|
|
25
|
-
: ParamsSchemaOutput<P>
|
|
26
|
-
: never
|
|
27
|
-
|
|
28
21
|
export class ParamsSchema<
|
|
29
22
|
const Shape extends ParamsSchemaShape = ParamsSchemaShape,
|
|
30
23
|
> extends Schema<ParamsSchemaOutput<Shape>> {
|
package/src/schema/payload.ts
CHANGED
|
@@ -1,53 +1,86 @@
|
|
|
1
1
|
import { LexValue } from '@atproto/lex-data'
|
|
2
|
-
import { Infer,
|
|
2
|
+
import { Infer, Schema } from '../validation.js'
|
|
3
3
|
|
|
4
|
-
export type
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
export type InferPayload<
|
|
5
|
+
P extends Payload,
|
|
6
|
+
B,
|
|
7
|
+
> = P['encoding'] extends infer E extends string
|
|
8
|
+
? {
|
|
9
|
+
encoding: SchemaEncodingToDataEncoding<E>
|
|
10
|
+
body: InferPayloadBody<P, B>
|
|
11
|
+
}
|
|
12
|
+
: void | undefined
|
|
13
|
+
|
|
14
|
+
export type SchemaEncodingToDataEncoding<E extends string> = E extends '*/*'
|
|
15
|
+
? `${string}/${string}`
|
|
16
|
+
: E extends `${infer T extends string}/*`
|
|
17
|
+
? `${T}/${string}`
|
|
18
|
+
: E
|
|
9
19
|
|
|
10
20
|
export type InferPayloadEncoding<P extends Payload> =
|
|
11
|
-
P extends
|
|
12
|
-
|
|
13
|
-
export type InferPayloadBody<P extends Payload> =
|
|
14
|
-
P extends Payload<any, infer S>
|
|
15
|
-
? S extends Validator
|
|
16
|
-
? Infer<S>
|
|
17
|
-
: P extends Payload<infer E extends string>
|
|
18
|
-
? LexBody<E>
|
|
19
|
-
: undefined
|
|
21
|
+
P['encoding'] extends string
|
|
22
|
+
? SchemaEncodingToDataEncoding<P['encoding']>
|
|
20
23
|
: undefined
|
|
21
24
|
|
|
22
|
-
export type
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
> =
|
|
26
|
-
?
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
: void
|
|
36
|
-
|
|
37
|
-
export type PayloadBody<E extends string | undefined> = E extends undefined
|
|
25
|
+
export type InferPayloadBody<
|
|
26
|
+
P extends Payload,
|
|
27
|
+
B,
|
|
28
|
+
> = P['encoding'] extends undefined
|
|
29
|
+
? undefined // No encoding, no payload
|
|
30
|
+
: P['schema'] extends Schema
|
|
31
|
+
? Infer<P['schema']>
|
|
32
|
+
: P['encoding'] extends `application/json`
|
|
33
|
+
? LexValue
|
|
34
|
+
: B
|
|
35
|
+
|
|
36
|
+
export type PayloadSchema<E extends string | undefined> = E extends undefined
|
|
38
37
|
? undefined
|
|
39
|
-
:
|
|
38
|
+
: Schema | undefined
|
|
40
39
|
|
|
41
40
|
export class Payload<
|
|
42
41
|
const Encoding extends string | undefined = string | undefined,
|
|
43
|
-
const
|
|
42
|
+
const Schema extends PayloadSchema<Encoding> = PayloadSchema<Encoding>,
|
|
44
43
|
> {
|
|
45
44
|
constructor(
|
|
46
45
|
readonly encoding: Encoding,
|
|
47
|
-
readonly schema:
|
|
46
|
+
readonly schema: Schema,
|
|
48
47
|
) {
|
|
49
48
|
if (encoding === undefined && schema !== undefined) {
|
|
50
49
|
throw new TypeError('schema cannot be defined when encoding is undefined')
|
|
51
50
|
}
|
|
52
51
|
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Checks whether the given content-type matches the expected payload schema's
|
|
55
|
+
* encoding.
|
|
56
|
+
*/
|
|
57
|
+
matchesEncoding(contentType: string | undefined): boolean {
|
|
58
|
+
const mime = contentType?.split(';', 1)[0].trim()
|
|
59
|
+
|
|
60
|
+
const { encoding } = this
|
|
61
|
+
|
|
62
|
+
// Handle undefined cases
|
|
63
|
+
if (encoding === undefined) {
|
|
64
|
+
// Expecting no body
|
|
65
|
+
return mime === undefined
|
|
66
|
+
} else if (mime === undefined) {
|
|
67
|
+
// Expecting a body, but got no content-type
|
|
68
|
+
return false
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (encoding === '*/*') {
|
|
72
|
+
return true
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (encoding.endsWith('/*')) {
|
|
76
|
+
return mime.startsWith(encoding.slice(0, -1))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Invalid: Lexicon can only specify "*/*" or "type/*" wildcards
|
|
80
|
+
if (encoding.includes('*')) {
|
|
81
|
+
return false
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return encoding === mime
|
|
85
|
+
}
|
|
53
86
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { asNsidString } from '../core.js'
|
|
2
2
|
import { PermissionSet } from './permission-set.js'
|
|
3
3
|
import { Permission } from './permission.js'
|
|
4
4
|
|
|
5
5
|
describe('PermissionSet', () => {
|
|
6
6
|
describe('constructor', () => {
|
|
7
7
|
it('creates a PermissionSet instance with all parameters', () => {
|
|
8
|
-
const nsid =
|
|
8
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
9
9
|
const permissions = [
|
|
10
10
|
new Permission('app.bsky.feed.post:read', {}),
|
|
11
11
|
new Permission('app.bsky.feed.post:write', {}),
|
|
@@ -24,7 +24,7 @@ describe('PermissionSet', () => {
|
|
|
24
24
|
})
|
|
25
25
|
|
|
26
26
|
it('creates a PermissionSet instance with minimal options', () => {
|
|
27
|
-
const nsid =
|
|
27
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
28
28
|
const permissions = [
|
|
29
29
|
new Permission('app.bsky.feed.post:read', {}),
|
|
30
30
|
] as const
|
|
@@ -39,7 +39,7 @@ describe('PermissionSet', () => {
|
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
it('creates a PermissionSet instance with empty permissions array', () => {
|
|
42
|
-
const nsid =
|
|
42
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
43
43
|
const permissions = [] as const
|
|
44
44
|
const options = {}
|
|
45
45
|
|
|
@@ -50,7 +50,7 @@ describe('PermissionSet', () => {
|
|
|
50
50
|
})
|
|
51
51
|
|
|
52
52
|
it('creates a PermissionSet instance with title only', () => {
|
|
53
|
-
const nsid =
|
|
53
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
54
54
|
const permissions = [
|
|
55
55
|
new Permission('app.bsky.feed.like:read', {}),
|
|
56
56
|
] as const
|
|
@@ -65,7 +65,7 @@ describe('PermissionSet', () => {
|
|
|
65
65
|
})
|
|
66
66
|
|
|
67
67
|
it('creates a PermissionSet instance with detail only', () => {
|
|
68
|
-
const nsid =
|
|
68
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
69
69
|
const permissions = [
|
|
70
70
|
new Permission('app.bsky.feed.like:read', {}),
|
|
71
71
|
] as const
|
|
@@ -80,7 +80,7 @@ describe('PermissionSet', () => {
|
|
|
80
80
|
})
|
|
81
81
|
|
|
82
82
|
it('creates a PermissionSet instance with localized titles', () => {
|
|
83
|
-
const nsid =
|
|
83
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
84
84
|
const permissions = [
|
|
85
85
|
new Permission('app.bsky.feed.post:read', {}),
|
|
86
86
|
] as const
|
|
@@ -102,7 +102,7 @@ describe('PermissionSet', () => {
|
|
|
102
102
|
})
|
|
103
103
|
|
|
104
104
|
it('creates a PermissionSet instance with localized details', () => {
|
|
105
|
-
const nsid =
|
|
105
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
106
106
|
const permissions = [
|
|
107
107
|
new Permission('app.bsky.feed.post:read', {}),
|
|
108
108
|
] as const
|
|
@@ -124,7 +124,7 @@ describe('PermissionSet', () => {
|
|
|
124
124
|
})
|
|
125
125
|
|
|
126
126
|
it('creates a PermissionSet instance with all options including localization', () => {
|
|
127
|
-
const nsid =
|
|
127
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
128
128
|
const permissions = [
|
|
129
129
|
new Permission('app.bsky.feed.post:read', {}),
|
|
130
130
|
new Permission('app.bsky.feed.post:write', {}),
|
|
@@ -165,7 +165,7 @@ describe('PermissionSet', () => {
|
|
|
165
165
|
|
|
166
166
|
describe('property immutability', () => {
|
|
167
167
|
it('options object itself is mutable', () => {
|
|
168
|
-
const nsid =
|
|
168
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
169
169
|
const permissions = [
|
|
170
170
|
new Permission('app.bsky.feed.post:read', {}),
|
|
171
171
|
] as const
|
|
@@ -181,7 +181,7 @@ describe('PermissionSet', () => {
|
|
|
181
181
|
|
|
182
182
|
describe('with multiple permissions', () => {
|
|
183
183
|
it('creates a PermissionSet with multiple read permissions', () => {
|
|
184
|
-
const nsid =
|
|
184
|
+
const nsid = asNsidString('app.bsky.oauth.read')
|
|
185
185
|
const permissions = [
|
|
186
186
|
new Permission('app.bsky.feed.post:read', {}),
|
|
187
187
|
new Permission('app.bsky.feed.like:read', {}),
|
|
@@ -211,7 +211,7 @@ describe('PermissionSet', () => {
|
|
|
211
211
|
})
|
|
212
212
|
|
|
213
213
|
it('creates a PermissionSet with mixed read/write permissions', () => {
|
|
214
|
-
const nsid =
|
|
214
|
+
const nsid = asNsidString('app.bsky.oauth.full')
|
|
215
215
|
const permissions = [
|
|
216
216
|
new Permission('app.bsky.feed.post:read', {}),
|
|
217
217
|
new Permission('app.bsky.feed.post:write', {}),
|
|
@@ -229,7 +229,7 @@ describe('PermissionSet', () => {
|
|
|
229
229
|
})
|
|
230
230
|
|
|
231
231
|
it('creates a PermissionSet with a single permission', () => {
|
|
232
|
-
const nsid =
|
|
232
|
+
const nsid = asNsidString('app.bsky.oauth.limited')
|
|
233
233
|
const permissions = [
|
|
234
234
|
new Permission('app.bsky.actor.profile:read', {}),
|
|
235
235
|
] as const
|
|
@@ -249,7 +249,7 @@ describe('PermissionSet', () => {
|
|
|
249
249
|
|
|
250
250
|
describe('edge cases', () => {
|
|
251
251
|
it('handles very long NSID', () => {
|
|
252
|
-
const nsid =
|
|
252
|
+
const nsid = asNsidString(
|
|
253
253
|
'com.example.very.long.namespace.identifier.oauth.permissions',
|
|
254
254
|
)
|
|
255
255
|
const permissions = [new Permission('resource:action', {})] as const
|
|
@@ -261,7 +261,7 @@ describe('PermissionSet', () => {
|
|
|
261
261
|
})
|
|
262
262
|
|
|
263
263
|
it('handles long title strings', () => {
|
|
264
|
-
const nsid =
|
|
264
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
265
265
|
const permissions = [
|
|
266
266
|
new Permission('app.bsky.feed.post:read', {}),
|
|
267
267
|
] as const
|
|
@@ -277,7 +277,7 @@ describe('PermissionSet', () => {
|
|
|
277
277
|
})
|
|
278
278
|
|
|
279
279
|
it('handles long detail strings', () => {
|
|
280
|
-
const nsid =
|
|
280
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
281
281
|
const permissions = [
|
|
282
282
|
new Permission('app.bsky.feed.post:read', {}),
|
|
283
283
|
] as const
|
|
@@ -293,7 +293,7 @@ describe('PermissionSet', () => {
|
|
|
293
293
|
})
|
|
294
294
|
|
|
295
295
|
it('handles multiple language codes in title:lang', () => {
|
|
296
|
-
const nsid =
|
|
296
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
297
297
|
const permissions = [
|
|
298
298
|
new Permission('app.bsky.feed.post:read', {}),
|
|
299
299
|
] as const
|
|
@@ -319,7 +319,7 @@ describe('PermissionSet', () => {
|
|
|
319
319
|
})
|
|
320
320
|
|
|
321
321
|
it('handles undefined values in title:lang', () => {
|
|
322
|
-
const nsid =
|
|
322
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
323
323
|
const permissions = [
|
|
324
324
|
new Permission('app.bsky.feed.post:read', {}),
|
|
325
325
|
] as const
|
|
@@ -342,7 +342,7 @@ describe('PermissionSet', () => {
|
|
|
342
342
|
})
|
|
343
343
|
|
|
344
344
|
it('handles undefined values in detail:lang', () => {
|
|
345
|
-
const nsid =
|
|
345
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
346
346
|
const permissions = [
|
|
347
347
|
new Permission('app.bsky.feed.post:read', {}),
|
|
348
348
|
] as const
|
|
@@ -363,7 +363,7 @@ describe('PermissionSet', () => {
|
|
|
363
363
|
})
|
|
364
364
|
|
|
365
365
|
it('handles special characters in title', () => {
|
|
366
|
-
const nsid =
|
|
366
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
367
367
|
const permissions = [
|
|
368
368
|
new Permission('app.bsky.feed.post:read', {}),
|
|
369
369
|
] as const
|
|
@@ -379,7 +379,7 @@ describe('PermissionSet', () => {
|
|
|
379
379
|
})
|
|
380
380
|
|
|
381
381
|
it('handles special characters in detail', () => {
|
|
382
|
-
const nsid =
|
|
382
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
383
383
|
const permissions = [
|
|
384
384
|
new Permission('app.bsky.feed.post:read', {}),
|
|
385
385
|
] as const
|
|
@@ -396,7 +396,7 @@ describe('PermissionSet', () => {
|
|
|
396
396
|
})
|
|
397
397
|
|
|
398
398
|
it('handles unicode characters in title', () => {
|
|
399
|
-
const nsid =
|
|
399
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
400
400
|
const permissions = [
|
|
401
401
|
new Permission('app.bsky.feed.post:read', {}),
|
|
402
402
|
] as const
|
|
@@ -410,7 +410,7 @@ describe('PermissionSet', () => {
|
|
|
410
410
|
})
|
|
411
411
|
|
|
412
412
|
it('handles empty strings in title', () => {
|
|
413
|
-
const nsid =
|
|
413
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
414
414
|
const permissions = [
|
|
415
415
|
new Permission('app.bsky.feed.post:read', {}),
|
|
416
416
|
] as const
|
|
@@ -424,7 +424,7 @@ describe('PermissionSet', () => {
|
|
|
424
424
|
})
|
|
425
425
|
|
|
426
426
|
it('handles empty strings in detail', () => {
|
|
427
|
-
const nsid =
|
|
427
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
428
428
|
const permissions = [
|
|
429
429
|
new Permission('app.bsky.feed.post:read', {}),
|
|
430
430
|
] as const
|
|
@@ -438,7 +438,7 @@ describe('PermissionSet', () => {
|
|
|
438
438
|
})
|
|
439
439
|
|
|
440
440
|
it('handles large number of permissions', () => {
|
|
441
|
-
const nsid =
|
|
441
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
442
442
|
const permissions = Array.from(
|
|
443
443
|
{ length: 100 },
|
|
444
444
|
(_, i) => new Permission(`resource${i}:action`, {}),
|
|
@@ -453,7 +453,7 @@ describe('PermissionSet', () => {
|
|
|
453
453
|
|
|
454
454
|
describe('real-world permission set examples', () => {
|
|
455
455
|
it('creates a feed management permission set', () => {
|
|
456
|
-
const nsid =
|
|
456
|
+
const nsid = asNsidString('app.bsky.oauth.feed')
|
|
457
457
|
const permissions = [
|
|
458
458
|
new Permission('app.bsky.feed.post:read', {}),
|
|
459
459
|
new Permission('app.bsky.feed.post:write', {}),
|
|
@@ -483,7 +483,7 @@ describe('PermissionSet', () => {
|
|
|
483
483
|
})
|
|
484
484
|
|
|
485
485
|
it('creates a read-only permission set', () => {
|
|
486
|
-
const nsid =
|
|
486
|
+
const nsid = asNsidString('app.bsky.oauth.readonly')
|
|
487
487
|
const permissions = [
|
|
488
488
|
new Permission('app.bsky.feed.post:read', {}),
|
|
489
489
|
new Permission('app.bsky.feed.like:read', {}),
|
|
@@ -504,7 +504,7 @@ describe('PermissionSet', () => {
|
|
|
504
504
|
})
|
|
505
505
|
|
|
506
506
|
it('creates a profile management permission set', () => {
|
|
507
|
-
const nsid =
|
|
507
|
+
const nsid = asNsidString('app.bsky.oauth.profile')
|
|
508
508
|
const permissions = [
|
|
509
509
|
new Permission('app.bsky.actor.profile:read', {}),
|
|
510
510
|
new Permission('app.bsky.actor.profile:write', {}),
|
|
@@ -531,7 +531,7 @@ describe('PermissionSet', () => {
|
|
|
531
531
|
})
|
|
532
532
|
|
|
533
533
|
it('creates a minimal permission set', () => {
|
|
534
|
-
const nsid =
|
|
534
|
+
const nsid = asNsidString('app.bsky.oauth.minimal')
|
|
535
535
|
const permissions = [
|
|
536
536
|
new Permission('app.bsky.actor.profile:read', {}),
|
|
537
537
|
] as const
|
|
@@ -549,7 +549,7 @@ describe('PermissionSet', () => {
|
|
|
549
549
|
|
|
550
550
|
describe('permission validation', () => {
|
|
551
551
|
it('validates that permissions are Permission instances', () => {
|
|
552
|
-
const nsid =
|
|
552
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
553
553
|
const permission1 = new Permission('app.bsky.feed.post:read', {})
|
|
554
554
|
const permission2 = new Permission('app.bsky.feed.post:write', {})
|
|
555
555
|
const permissions = [permission1, permission2] as const
|
|
@@ -562,7 +562,7 @@ describe('PermissionSet', () => {
|
|
|
562
562
|
})
|
|
563
563
|
|
|
564
564
|
it('preserves permission resource strings', () => {
|
|
565
|
-
const nsid =
|
|
565
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
566
566
|
const permissions = [
|
|
567
567
|
new Permission('app.bsky.feed.post:read', {}),
|
|
568
568
|
new Permission('app.bsky.feed.like:write', {}),
|
|
@@ -584,7 +584,7 @@ describe('PermissionSet', () => {
|
|
|
584
584
|
})
|
|
585
585
|
|
|
586
586
|
it('preserves permission options', () => {
|
|
587
|
-
const nsid =
|
|
587
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
588
588
|
const permissionOptions = { custom: 'value' }
|
|
589
589
|
const permissions = [
|
|
590
590
|
new Permission('app.bsky.feed.post:read', permissionOptions),
|
|
@@ -599,7 +599,7 @@ describe('PermissionSet', () => {
|
|
|
599
599
|
|
|
600
600
|
describe('option variations', () => {
|
|
601
601
|
it('accepts title without detail', () => {
|
|
602
|
-
const nsid =
|
|
602
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
603
603
|
const permissions = [
|
|
604
604
|
new Permission('app.bsky.feed.post:read', {}),
|
|
605
605
|
] as const
|
|
@@ -616,7 +616,7 @@ describe('PermissionSet', () => {
|
|
|
616
616
|
})
|
|
617
617
|
|
|
618
618
|
it('accepts detail without title', () => {
|
|
619
|
-
const nsid =
|
|
619
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
620
620
|
const permissions = [
|
|
621
621
|
new Permission('app.bsky.feed.post:read', {}),
|
|
622
622
|
] as const
|
|
@@ -635,7 +635,7 @@ describe('PermissionSet', () => {
|
|
|
635
635
|
})
|
|
636
636
|
|
|
637
637
|
it('accepts title:lang without title', () => {
|
|
638
|
-
const nsid =
|
|
638
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
639
639
|
const permissions = [
|
|
640
640
|
new Permission('app.bsky.feed.post:read', {}),
|
|
641
641
|
] as const
|
|
@@ -656,7 +656,7 @@ describe('PermissionSet', () => {
|
|
|
656
656
|
})
|
|
657
657
|
|
|
658
658
|
it('accepts detail:lang without detail', () => {
|
|
659
|
-
const nsid =
|
|
659
|
+
const nsid = asNsidString('app.bsky.oauth.permissions')
|
|
660
660
|
const permissions = [
|
|
661
661
|
new Permission('app.bsky.feed.post:read', {}),
|
|
662
662
|
] as const
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { ObjectSchema } from './object.js'
|
|
2
2
|
import { ParamsSchema } from './params.js'
|
|
3
3
|
import { Payload } from './payload.js'
|
|
4
|
-
import {
|
|
5
|
-
InferProcedureInputBody,
|
|
6
|
-
InferProcedureOutputBody,
|
|
7
|
-
InferProcedureParameters,
|
|
8
|
-
Procedure,
|
|
9
|
-
} from './procedure.js'
|
|
4
|
+
import { Procedure } from './procedure.js'
|
|
10
5
|
import { StringSchema } from './string.js'
|
|
11
6
|
|
|
12
7
|
describe('Procedure', () => {
|
|
@@ -288,62 +283,6 @@ describe('Procedure', () => {
|
|
|
288
283
|
})
|
|
289
284
|
})
|
|
290
285
|
|
|
291
|
-
describe('type inference helpers', () => {
|
|
292
|
-
it('infers procedure parameters type', () => {
|
|
293
|
-
const parameters = new ParamsSchema({
|
|
294
|
-
limit: new StringSchema({}),
|
|
295
|
-
})
|
|
296
|
-
const procedure = new Procedure(
|
|
297
|
-
'com.example.list',
|
|
298
|
-
parameters,
|
|
299
|
-
new Payload(undefined, undefined),
|
|
300
|
-
new Payload(undefined, undefined),
|
|
301
|
-
undefined,
|
|
302
|
-
)
|
|
303
|
-
|
|
304
|
-
type Params = InferProcedureParameters<typeof procedure>
|
|
305
|
-
// Type test - this will fail at compile time if inference is wrong
|
|
306
|
-
const params: Params = { limit: 'test' }
|
|
307
|
-
expect(params).toBeDefined()
|
|
308
|
-
})
|
|
309
|
-
|
|
310
|
-
it('infers procedure input body type', () => {
|
|
311
|
-
const inputSchema = new ObjectSchema({
|
|
312
|
-
text: new StringSchema({}),
|
|
313
|
-
})
|
|
314
|
-
const procedure = new Procedure(
|
|
315
|
-
'com.example.create',
|
|
316
|
-
new ParamsSchema({}),
|
|
317
|
-
new Payload('application/json', inputSchema),
|
|
318
|
-
new Payload(undefined, undefined),
|
|
319
|
-
undefined,
|
|
320
|
-
)
|
|
321
|
-
|
|
322
|
-
type InputBody = InferProcedureInputBody<typeof procedure>
|
|
323
|
-
// Type test - this will fail at compile time if inference is wrong
|
|
324
|
-
const input: InputBody = { text: 'hello' }
|
|
325
|
-
expect(input).toBeDefined()
|
|
326
|
-
})
|
|
327
|
-
|
|
328
|
-
it('infers procedure output body type', () => {
|
|
329
|
-
const outputSchema = new ObjectSchema({
|
|
330
|
-
uri: new StringSchema({}),
|
|
331
|
-
})
|
|
332
|
-
const procedure = new Procedure(
|
|
333
|
-
'com.example.get',
|
|
334
|
-
new ParamsSchema({}),
|
|
335
|
-
new Payload(undefined, undefined),
|
|
336
|
-
new Payload('application/json', outputSchema),
|
|
337
|
-
undefined,
|
|
338
|
-
)
|
|
339
|
-
|
|
340
|
-
type OutputBody = InferProcedureOutputBody<typeof procedure>
|
|
341
|
-
// Type test - this will fail at compile time if inference is wrong
|
|
342
|
-
const output: OutputBody = { uri: 'at://did:plc:abc/post/123' }
|
|
343
|
-
expect(output).toBeDefined()
|
|
344
|
-
})
|
|
345
|
-
})
|
|
346
|
-
|
|
347
286
|
describe('property access', () => {
|
|
348
287
|
it('provides access to all properties', () => {
|
|
349
288
|
const nsid = 'com.example.test'
|
package/src/schema/procedure.ts
CHANGED
|
@@ -1,28 +1,16 @@
|
|
|
1
1
|
import { NsidString } from '../core.js'
|
|
2
|
-
import { Infer } from '../validation.js'
|
|
3
2
|
import { ParamsSchema } from './params.js'
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
export type InferProcedureParameters<Q extends Procedure> =
|
|
7
|
-
Q extends Procedure<any, infer P extends ParamsSchema, any> ? Infer<P> : never
|
|
8
|
-
|
|
9
|
-
export type InferProcedureInputBody<Q extends Procedure> =
|
|
10
|
-
Q extends Procedure<any, any, infer I extends Payload, any>
|
|
11
|
-
? InferPayloadBody<I>
|
|
12
|
-
: never
|
|
13
|
-
|
|
14
|
-
export type InferProcedureOutputBody<Q extends Procedure> =
|
|
15
|
-
Q extends Procedure<any, any, any, infer O extends Payload>
|
|
16
|
-
? InferPayloadBody<O>
|
|
17
|
-
: never
|
|
3
|
+
import { Payload } from './payload.js'
|
|
18
4
|
|
|
19
5
|
export class Procedure<
|
|
20
|
-
TNsid extends NsidString =
|
|
21
|
-
TParameters extends ParamsSchema =
|
|
22
|
-
TInputPayload extends Payload =
|
|
23
|
-
TOutputPayload extends Payload =
|
|
24
|
-
TErrors extends undefined | readonly string[] =
|
|
6
|
+
TNsid extends NsidString = NsidString,
|
|
7
|
+
TParameters extends ParamsSchema = ParamsSchema,
|
|
8
|
+
TInputPayload extends Payload = Payload,
|
|
9
|
+
TOutputPayload extends Payload = Payload,
|
|
10
|
+
TErrors extends undefined | readonly string[] = undefined | readonly string[],
|
|
25
11
|
> {
|
|
12
|
+
readonly type = 'procedure' as const
|
|
13
|
+
|
|
26
14
|
constructor(
|
|
27
15
|
readonly nsid: TNsid,
|
|
28
16
|
readonly parameters: TParameters,
|