a textual notation to locate fields within atproto records (draft spec)
microcosm.tngl.io/RecordPath/
1{
2 "description": "RecordPath parsing tests: type classification (scalar vs vector) and validity.",
3 "type_tests": [
4 {
5 "description": "simple key is scalar",
6 "path": "text",
7 "type": "scalar"
8 },
9 {
10 "description": "dotted path is scalar",
11 "path": "subject.uri",
12 "type": "scalar"
13 },
14 {
15 "description": "deeply nested path is scalar",
16 "path": "a.b.c.d.e",
17 "type": "scalar"
18 },
19 {
20 "description": "scalar union is scalar",
21 "path": "embed{app.bsky.embed.record}.record.uri",
22 "type": "scalar"
23 },
24 {
25 "description": "bare array is vector",
26 "path": "tags[]",
27 "type": "vector"
28 },
29 {
30 "description": "array with trailing key is vector",
31 "path": "items[].name",
32 "type": "vector"
33 },
34 {
35 "description": "union array is vector",
36 "path": "features[app.bsky.richtext.facet#link].uri",
37 "type": "vector"
38 },
39 {
40 "description": "nested arrays is vector",
41 "path": "groups[].items[]",
42 "type": "vector"
43 },
44 {
45 "description": "scalar union + array is vector",
46 "path": "embed{app.bsky.embed.images}.images[].alt",
47 "type": "vector"
48 },
49 {
50 "description": "escaped dot does not make it vector",
51 "path": "dot!.key",
52 "type": "scalar"
53 },
54 {
55 "description": "escaped bracket does not make it vector",
56 "path": "a![0!]",
57 "type": "scalar"
58 },
59 {
60 "description": "$type path is scalar",
61 "path": "$type",
62 "type": "scalar"
63 }
64 ],
65 "invalid_tests": [
66 {
67 "description": "empty string",
68 "path": "",
69 "note": "a RecordPath must have at least one segment"
70 },
71 {
72 "description": "unclosed square bracket",
73 "path": "field[",
74 "note": "missing closing ]"
75 },
76 {
77 "description": "unclosed curly brace",
78 "path": "field{nsid",
79 "note": "missing closing }"
80 },
81 {
82 "description": "unopened square bracket",
83 "path": "field]",
84 "note": "missing opening ["
85 },
86 {
87 "description": "unopened curly brace",
88 "path": "field}nsid",
89 "note": "missing opening {"
90 },
91 {
92 "description": "trailing dot",
93 "path": "field.",
94 "note": "empty segment after dot"
95 },
96 {
97 "description": "leading dot",
98 "path": ".field",
99 "note": "empty segment before dot"
100 },
101 {
102 "description": "double dot",
103 "path": "a..b",
104 "note": "empty segment between dots"
105 },
106 {
107 "description": "escape followed by a non-escapable character",
108 "path": "field!s",
109 "note": "escape character with nothing to escape"
110 },
111 {
112 "description": "lone escape at end of input",
113 "path": "field!",
114 "note": "escape character with nothing to escape"
115 }
116 ]
117}