@atproto/syntax 0.6.3 → 0.6.4

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/at-identifier.d.ts +2 -2
  3. package/dist/at-identifier.d.ts.map +1 -1
  4. package/dist/at-identifier.js.map +1 -1
  5. package/dist/aturi.d.ts +5 -5
  6. package/dist/aturi.d.ts.map +1 -1
  7. package/dist/aturi.js +1 -1
  8. package/dist/aturi.js.map +1 -1
  9. package/dist/aturi_validation.d.ts +3 -3
  10. package/dist/aturi_validation.d.ts.map +1 -1
  11. package/dist/aturi_validation.js.map +1 -1
  12. package/dist/language.js +1 -1
  13. package/dist/language.js.map +1 -1
  14. package/dist/nsid.d.ts +1 -1
  15. package/dist/nsid.d.ts.map +1 -1
  16. package/dist/nsid.js.map +1 -1
  17. package/package.json +15 -14
  18. package/benchmark.cjs +0 -208
  19. package/src/at-identifier.ts +0 -104
  20. package/src/aturi.ts +0 -197
  21. package/src/aturi_validation.ts +0 -321
  22. package/src/datetime.ts +0 -369
  23. package/src/did.ts +0 -71
  24. package/src/handle.ts +0 -128
  25. package/src/index.ts +0 -10
  26. package/src/language.ts +0 -39
  27. package/src/lib/result.ts +0 -11
  28. package/src/nsid.ts +0 -182
  29. package/src/recordkey.ts +0 -51
  30. package/src/tid.ts +0 -22
  31. package/src/uri.ts +0 -5
  32. package/tests/aturi-string.test.ts +0 -223
  33. package/tests/aturi.test.ts +0 -428
  34. package/tests/datetime.test.ts +0 -280
  35. package/tests/did.test.ts +0 -104
  36. package/tests/handle.test.ts +0 -239
  37. package/tests/language.test.ts +0 -88
  38. package/tests/nsid.test.ts +0 -174
  39. package/tests/recordkey.test.ts +0 -43
  40. package/tests/tid.test.ts +0 -43
  41. package/tsconfig.build.json +0 -12
  42. package/tsconfig.build.tsbuildinfo +0 -1
  43. package/tsconfig.json +0 -7
  44. package/tsconfig.tests.json +0 -8
  45. package/vitest.config.ts +0 -5
@@ -1,428 +0,0 @@
1
- import { readFileSync } from 'node:fs'
2
- import { describe, expect, it, test } from 'vitest'
3
- import { AtUri } from '../src/index.js'
4
-
5
- describe(AtUri, () => {
6
- describe('parses valid interop', () => {
7
- test.each(
8
- readLines(
9
- `${__dirname}/../../../interop-test-files/syntax/aturi_syntax_valid.txt`,
10
- ),
11
- )('%s', (value) => {
12
- expect(() => new AtUri(value)).not.toThrow()
13
- })
14
- })
15
-
16
- describe('valid at uris', () => {
17
- type AtUriTest = [
18
- input: string,
19
- host: string,
20
- path: string,
21
- query: string,
22
- hash: string,
23
- ]
24
- const TESTS: AtUriTest[] = [
25
- ['foo.com', 'foo.com', '', '', ''],
26
- ['at://foo.com', 'foo.com', '', '', ''],
27
- ['at://foo.com/', 'foo.com', '/', '', ''],
28
- ['at://foo.com/foo', 'foo.com', '/foo', '', ''],
29
- ['at://foo.com/foo/', 'foo.com', '/foo/', '', ''],
30
- ['at://foo.com/foo/bar', 'foo.com', '/foo/bar', '', ''],
31
- ['at://foo.com?foo=bar', 'foo.com', '', 'foo=bar', ''],
32
- ['at://foo.com?foo=bar&baz=buux', 'foo.com', '', 'foo=bar&baz=buux', ''],
33
- ['at://foo.com/?foo=bar', 'foo.com', '/', 'foo=bar', ''],
34
- ['at://foo.com/foo?foo=bar', 'foo.com', '/foo', 'foo=bar', ''],
35
- ['at://foo.com/foo/?foo=bar', 'foo.com', '/foo/', 'foo=bar', ''],
36
- ['at://foo.com#hash', 'foo.com', '', '', '#hash'],
37
- ['at://foo.com/#hash', 'foo.com', '/', '', '#hash'],
38
- ['at://foo.com/foo#hash', 'foo.com', '/foo', '', '#hash'],
39
- ['at://foo.com/foo/#hash', 'foo.com', '/foo/', '', '#hash'],
40
- ['at://foo.com?foo=bar#hash', 'foo.com', '', 'foo=bar', '#hash'],
41
-
42
- [
43
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
44
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
45
- '',
46
- '',
47
- '',
48
- ],
49
- [
50
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
51
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
52
- '',
53
- '',
54
- '',
55
- ],
56
- [
57
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/',
58
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
59
- '/',
60
- '',
61
- '',
62
- ],
63
- [
64
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo',
65
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
66
- '/foo',
67
- '',
68
- '',
69
- ],
70
- [
71
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo/',
72
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
73
- '/foo/',
74
- '',
75
- '',
76
- ],
77
- [
78
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo/bar',
79
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
80
- '/foo/bar',
81
- '',
82
- '',
83
- ],
84
- [
85
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw?foo=bar',
86
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
87
- '',
88
- 'foo=bar',
89
- '',
90
- ],
91
- [
92
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw?foo=bar&baz=buux',
93
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
94
- '',
95
- 'foo=bar&baz=buux',
96
- '',
97
- ],
98
- [
99
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/?foo=bar',
100
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
101
- '/',
102
- 'foo=bar',
103
- '',
104
- ],
105
- [
106
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo?foo=bar',
107
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
108
- '/foo',
109
- 'foo=bar',
110
- '',
111
- ],
112
- [
113
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo/?foo=bar',
114
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
115
- '/foo/',
116
- 'foo=bar',
117
- '',
118
- ],
119
- [
120
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw#hash',
121
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
122
- '',
123
- '',
124
- '#hash',
125
- ],
126
- [
127
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/#hash',
128
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
129
- '/',
130
- '',
131
- '#hash',
132
- ],
133
- [
134
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo#hash',
135
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
136
- '/foo',
137
- '',
138
- '#hash',
139
- ],
140
- [
141
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo/#hash',
142
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
143
- '/foo/',
144
- '',
145
- '#hash',
146
- ],
147
- [
148
- 'at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw?foo=bar#hash',
149
- 'did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw',
150
- '',
151
- 'foo=bar',
152
- '#hash',
153
- ],
154
-
155
- ['did:web:localhost%3A1234', 'did:web:localhost%3A1234', '', '', ''],
156
- ['at://did:web:localhost%3A1234', 'did:web:localhost%3A1234', '', '', ''],
157
- [
158
- 'at://did:web:localhost%3A1234/',
159
- 'did:web:localhost%3A1234',
160
- '/',
161
- '',
162
- '',
163
- ],
164
- [
165
- 'at://did:web:localhost%3A1234/foo',
166
- 'did:web:localhost%3A1234',
167
- '/foo',
168
- '',
169
- '',
170
- ],
171
- [
172
- 'at://did:web:localhost%3A1234/foo/',
173
- 'did:web:localhost%3A1234',
174
- '/foo/',
175
- '',
176
- '',
177
- ],
178
- [
179
- 'at://did:web:localhost%3A1234/foo/bar',
180
- 'did:web:localhost%3A1234',
181
- '/foo/bar',
182
- '',
183
- '',
184
- ],
185
- [
186
- 'at://did:web:localhost%3A1234?foo=bar',
187
- 'did:web:localhost%3A1234',
188
- '',
189
- 'foo=bar',
190
- '',
191
- ],
192
- [
193
- 'at://did:web:localhost%3A1234?foo=bar&baz=buux',
194
- 'did:web:localhost%3A1234',
195
- '',
196
- 'foo=bar&baz=buux',
197
- '',
198
- ],
199
- [
200
- 'at://did:web:localhost%3A1234/?foo=bar',
201
- 'did:web:localhost%3A1234',
202
- '/',
203
- 'foo=bar',
204
- '',
205
- ],
206
- [
207
- 'at://did:web:localhost%3A1234/foo?foo=bar',
208
- 'did:web:localhost%3A1234',
209
- '/foo',
210
- 'foo=bar',
211
- '',
212
- ],
213
- [
214
- 'at://did:web:localhost%3A1234/foo/?foo=bar',
215
- 'did:web:localhost%3A1234',
216
- '/foo/',
217
- 'foo=bar',
218
- '',
219
- ],
220
- [
221
- 'at://did:web:localhost%3A1234#hash',
222
- 'did:web:localhost%3A1234',
223
- '',
224
- '',
225
- '#hash',
226
- ],
227
- [
228
- 'at://did:web:localhost%3A1234/#hash',
229
- 'did:web:localhost%3A1234',
230
- '/',
231
- '',
232
- '#hash',
233
- ],
234
- [
235
- 'at://did:web:localhost%3A1234/foo#hash',
236
- 'did:web:localhost%3A1234',
237
- '/foo',
238
- '',
239
- '#hash',
240
- ],
241
- [
242
- 'at://did:web:localhost%3A1234/foo/#hash',
243
- 'did:web:localhost%3A1234',
244
- '/foo/',
245
- '',
246
- '#hash',
247
- ],
248
- [
249
- 'at://did:web:localhost%3A1234?foo=bar#hash',
250
- 'did:web:localhost%3A1234',
251
- '',
252
- 'foo=bar',
253
- '#hash',
254
- ],
255
- [
256
- 'at://4513echo.bsky.social/app.bsky.feed.post/3jsrpdyf6ss23',
257
- '4513echo.bsky.social',
258
- '/app.bsky.feed.post/3jsrpdyf6ss23',
259
- '',
260
- '',
261
- ],
262
- ]
263
- test.each(TESTS)('%s', (input, host, path, search, hash) => {
264
- const urip = new AtUri(input)
265
- expect(urip.protocol).toBe('at:')
266
- expect(urip.host).toBe(host)
267
- expect(urip.hostname).toBe(host)
268
- expect(urip.origin).toBe(`at://${host}`)
269
- expect(urip.pathname).toBe(path)
270
- expect(urip.search).toBe(search)
271
- expect(urip.hash).toBe(hash)
272
- })
273
- })
274
-
275
- it('handles ATP-specific parsing', () => {
276
- {
277
- const urip = new AtUri('at://foo.com')
278
- expect(urip.collection).toBe('')
279
- expect(urip.rkey).toBe('')
280
- }
281
- {
282
- const urip = new AtUri('at://foo.com/com.example.foo')
283
- expect(urip.collection).toBe('com.example.foo')
284
- expect(urip.rkey).toBe('')
285
- }
286
- {
287
- const urip = new AtUri('at://foo.com/com.example.foo/123')
288
- expect(urip.collection).toBe('com.example.foo')
289
- expect(urip.rkey).toBe('123')
290
- }
291
- })
292
-
293
- it('supports modifications', () => {
294
- const urip = new AtUri('at://foo.com')
295
- expect(urip.toString()).toBe('at://foo.com')
296
-
297
- urip.host = 'bar.com'
298
- expect(urip.toString()).toBe('at://bar.com')
299
- urip.host = 'did:web:localhost%3A1234'
300
- expect(urip.toString()).toBe('at://did:web:localhost%3A1234')
301
- urip.host = 'foo.com'
302
-
303
- urip.pathname = '/'
304
- expect(urip.toString()).toBe('at://foo.com')
305
- urip.pathname = '/foo'
306
- expect(urip.toString()).toBe('at://foo.com/foo')
307
- urip.pathname = 'foo'
308
- expect(urip.toString()).toBe('at://foo.com/foo')
309
-
310
- urip.collection = 'com.example.foo'
311
- urip.rkey = '123'
312
- expect(urip.toString()).toBe('at://foo.com/com.example.foo/123')
313
- urip.rkey = '124'
314
- expect(urip.toString()).toBe('at://foo.com/com.example.foo/124')
315
- urip.collection = 'com.other.foo'
316
- expect(urip.toString()).toBe('at://foo.com/com.other.foo/124')
317
- urip.pathname = ''
318
- urip.rkey = '123'
319
- expect(urip.toString()).toBe('at://foo.com/undefined/123')
320
- urip.pathname = 'foo'
321
-
322
- urip.search = '?foo=bar'
323
- expect(urip.toString()).toBe('at://foo.com/foo?foo=bar')
324
- urip.searchParams.set('baz', 'buux')
325
- expect(urip.toString()).toBe('at://foo.com/foo?foo=bar&baz=buux')
326
-
327
- urip.hash = '#hash'
328
- expect(urip.toString()).toBe('at://foo.com/foo?foo=bar&baz=buux#hash')
329
- urip.hash = 'hash'
330
- expect(urip.toString()).toBe('at://foo.com/foo?foo=bar&baz=buux#hash')
331
- })
332
-
333
- describe('relative URIs', () => {
334
- type AtUriTest = [input: string, path: string, search: string, hash: string]
335
- const TESTS: AtUriTest[] = [
336
- ['', '', '', ''],
337
- ['/', '/', '', ''],
338
- ['/foo', '/foo', '', ''],
339
- ['/foo/', '/foo/', '', ''],
340
- ['/foo/bar', '/foo/bar', '', ''],
341
- ['?foo=bar', '', 'foo=bar', ''],
342
- ['?foo=bar&baz=buux', '', 'foo=bar&baz=buux', ''],
343
- ['/?foo=bar', '/', 'foo=bar', ''],
344
- ['/foo?foo=bar', '/foo', 'foo=bar', ''],
345
- ['/foo/?foo=bar', '/foo/', 'foo=bar', ''],
346
- ['#hash', '', '', '#hash'],
347
- ['/#hash', '/', '', '#hash'],
348
- ['/foo#hash', '/foo', '', '#hash'],
349
- ['/foo/#hash', '/foo/', '', '#hash'],
350
- ['?foo=bar#hash', '', 'foo=bar', '#hash'],
351
- ]
352
- const BASES: string[] = [
353
- 'did:web:localhost%3A1234',
354
- 'at://did:web:localhost%3A1234',
355
- 'at://did:web:localhost%3A1234/foo/bar?foo=bar&baz=buux#hash',
356
- 'did:web:localhost%3A1234',
357
- 'at://did:web:localhost%3A1234',
358
- 'at://did:web:localhost%3A1234/foo/bar?foo=bar&baz=buux#hash',
359
- ]
360
-
361
- describe.each(BASES)('%s', (base) => {
362
- test.each(TESTS)('%s', (input, path, search, hash) => {
363
- const baseUri = new AtUri(base)
364
- const uri = new AtUri(input, base)
365
- expect(uri.protocol).toBe('at:')
366
- expect(uri.host).toBe(baseUri.host)
367
- expect(uri.hostname).toBe(baseUri.hostname)
368
- expect(uri.origin).toBe(baseUri.origin)
369
- expect(uri.pathname).toBe(path)
370
- expect(uri.search).toBe(search)
371
- expect(uri.hash).toBe(hash)
372
- })
373
- })
374
- })
375
-
376
- it('properly checks that the did property is a valid did', () => {
377
- const urip = new AtUri('at://did:example:123')
378
- expect(urip.did).toBe('did:example:123')
379
- urip.host = 'did:example:456'
380
- expect(urip.did).toBe('did:example:456')
381
- urip.host = 'foo.com'
382
- expect(() => urip.did).toThrow()
383
- })
384
-
385
- it('properly checks that the collection is a valid nsid', () => {
386
- const urip = new AtUri('at://foo.com')
387
- expect(urip.collection).toBe('')
388
- expect(() => urip.collectionSafe).toThrow()
389
-
390
- urip.collection = 'com.example.foo'
391
- expect(urip.collection).toBe('com.example.foo')
392
- expect(urip.collectionSafe).toBe('com.example.foo')
393
-
394
- urip.collection = 'com.other.foo'
395
- expect(urip.collection).toBe('com.other.foo')
396
- expect(urip.collectionSafe).toBe('com.other.foo')
397
-
398
- expect(() => (urip.collection = 'not a valid nsid')).toThrow()
399
- expect(urip.collection).toBe('com.other.foo') // unchanged after failed set
400
-
401
- urip.unsafelySetCollection('not-a-valid-nsid')
402
- expect(urip.collection).toBe('not-a-valid-nsid')
403
- expect(() => urip.collectionSafe).toThrow()
404
- })
405
-
406
- it('properly checks that the rkey is a valid record key', () => {
407
- const urip = new AtUri('at://foo.com')
408
- expect(urip.rkey).toBe('')
409
- expect(() => urip.rkeySafe).toThrow()
410
-
411
- urip.rkey = 'valid_rkey-123'
412
- expect(urip.rkey).toBe('valid_rkey-123')
413
- expect(urip.rkeySafe).toBe('valid_rkey-123')
414
-
415
- expect(() => (urip.rkey = 'not a valid rkey')).toThrow()
416
- expect(urip.rkey).toBe('valid_rkey-123') // unchanged after failed set
417
-
418
- urip.unsafelySetRkey('not a valid rkey')
419
- expect(urip.rkey).toBe('not a valid rkey')
420
- expect(() => urip.rkeySafe).toThrow()
421
- })
422
- })
423
-
424
- function readLines(filePath: string): string[] {
425
- return readFileSync(filePath, 'utf-8')
426
- .split(/\r?\n/)
427
- .filter((line) => !line.startsWith('#') && line.length > 0)
428
- }