@atproto/lex-json 0.0.10 → 0.0.11
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 +13 -0
- package/dist/blob.d.ts +34 -0
- package/dist/blob.d.ts.map +1 -1
- package/dist/blob.js +34 -0
- package/dist/blob.js.map +1 -1
- package/dist/bytes.d.ts +44 -3
- package/dist/bytes.d.ts.map +1 -1
- package/dist/bytes.js +50 -2
- package/dist/bytes.js.map +1 -1
- package/dist/json.d.ts +43 -0
- package/dist/json.d.ts.map +1 -1
- package/dist/json.js.map +1 -1
- package/dist/lex-json.d.ts +127 -2
- package/dist/lex-json.d.ts.map +1 -1
- package/dist/lex-json.js +114 -0
- package/dist/lex-json.js.map +1 -1
- package/dist/link.d.ts +46 -0
- package/dist/link.d.ts.map +1 -1
- package/dist/link.js +21 -4
- package/dist/link.js.map +1 -1
- package/package.json +3 -3
- package/src/blob.ts +34 -0
- package/src/bytes.test.ts +55 -0
- package/src/bytes.ts +52 -5
- package/src/json.ts +45 -0
- package/src/lex-json.test.ts +30 -15
- package/src/lex-json.ts +127 -2
- package/src/link.ts +50 -4
package/src/lex-json.ts
CHANGED
|
@@ -11,6 +11,29 @@ import { encodeLexBytes, parseLexBytes } from './bytes.js'
|
|
|
11
11
|
import { JsonObject, JsonValue } from './json.js'
|
|
12
12
|
import { encodeLexLink, parseLexLink } from './link.js'
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Serialize a Lex value to a JSON string.
|
|
16
|
+
*
|
|
17
|
+
* This function serializes AT Protocol data model values to JSON, automatically
|
|
18
|
+
* encoding special types:
|
|
19
|
+
* - `Cid` instances are encoded as `{$link: string}`
|
|
20
|
+
* - `Uint8Array` instances are encoded as `{$bytes: string}` (base64)
|
|
21
|
+
*
|
|
22
|
+
* @param input - The Lex value to stringify
|
|
23
|
+
* @returns A JSON string representation of the value
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { lexStringify } from '@atproto/lex'
|
|
28
|
+
*
|
|
29
|
+
* // Stringify with CID and bytes encoding
|
|
30
|
+
* const json = lexStringify({
|
|
31
|
+
* ref: someCid,
|
|
32
|
+
* data: new Uint8Array([72, 101, 108, 108, 111])
|
|
33
|
+
* })
|
|
34
|
+
* // json is '{"ref":{"$link":"bafyrei..."},"data":{"$bytes":"SGVsbG8="}}'
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
14
37
|
export function lexStringify(input: LexValue): string {
|
|
15
38
|
// @NOTE Because of the way the "replacer" works in JSON.stringify, it's
|
|
16
39
|
// simpler to convert Lex to JSON first rather than trying to do it
|
|
@@ -18,14 +41,60 @@ export function lexStringify(input: LexValue): string {
|
|
|
18
41
|
return JSON.stringify(lexToJson(input))
|
|
19
42
|
}
|
|
20
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Options for parsing JSON to Lex values.
|
|
46
|
+
*/
|
|
21
47
|
export type LexParseOptions = {
|
|
22
48
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
49
|
+
* When enabled, forbids the presence of invalid Lex values such as:
|
|
50
|
+
* - Non-integer numbers (only safe integers are valid in the Lex data model)
|
|
51
|
+
* - Malformed `$link` objects
|
|
52
|
+
* - Malformed `$bytes` objects
|
|
53
|
+
* - Objects with invalid or empty `$type` properties
|
|
54
|
+
* - Invalid {@link BlobRef} (`$type: 'blob'`) objects
|
|
55
|
+
*
|
|
56
|
+
* When disabled (default), invalid special objects are left as plain objects.
|
|
57
|
+
*
|
|
58
|
+
* @default false
|
|
25
59
|
*/
|
|
26
60
|
strict?: boolean
|
|
27
61
|
}
|
|
28
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Parses a JSON string into Lex values.
|
|
65
|
+
*
|
|
66
|
+
* This function parses JSON and automatically decodes AT Protocol special types:
|
|
67
|
+
* - `{$link: string}` objects are decoded to `Cid` instances
|
|
68
|
+
* - `{$bytes: string}` objects are decoded to `Uint8Array` instances
|
|
69
|
+
* - `{$type: 'blob'}` objects are validated
|
|
70
|
+
*
|
|
71
|
+
* @typeParam T - Type cast for the resulting Lex value. Use when you want to specify the expected structure of the parsed data.
|
|
72
|
+
* @param input - The JSON string to parse
|
|
73
|
+
* @param options - Parsing options (e.g., strict mode)
|
|
74
|
+
* @returns The parsed Lex value
|
|
75
|
+
* @throws {SyntaxError} If the input is not valid JSON
|
|
76
|
+
* @throws {TypeError} If strict mode is enabled and invalid Lex values are found
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* import { lexParse } from '@atproto/lex'
|
|
81
|
+
*
|
|
82
|
+
* // Parse JSON with $link and $bytes decoding
|
|
83
|
+
* const parsed = lexParse<{
|
|
84
|
+
* ref: Cid
|
|
85
|
+
* data: Uint8Array
|
|
86
|
+
* }>(`{
|
|
87
|
+
* "ref": { "$link": "bafyrei..." },
|
|
88
|
+
* "data": { "$bytes": "SGVsbG8sIHdvcmxkIQ==" }
|
|
89
|
+
* }`)
|
|
90
|
+
*
|
|
91
|
+
* // Parse a single CID
|
|
92
|
+
* const someCid = lexParse<Cid>('{"$link": "bafyrei..."}')
|
|
93
|
+
*
|
|
94
|
+
* // Parse binary data
|
|
95
|
+
* const someBytes = lexParse<Uint8Array>('{"$bytes": "SGVsbG8sIHdvcmxkIQ=="}')
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
29
98
|
export function lexParse<T extends LexValue = LexValue>(
|
|
30
99
|
input: string,
|
|
31
100
|
options: LexParseOptions = { strict: false },
|
|
@@ -48,6 +117,35 @@ export function lexParse<T extends LexValue = LexValue>(
|
|
|
48
117
|
})
|
|
49
118
|
}
|
|
50
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Converts a parsed JSON representation of Lexicon value to a {@link LexValue}.
|
|
122
|
+
*
|
|
123
|
+
* This function transforms already-parsed JSON objects into Lex values by
|
|
124
|
+
* decoding AT Protocol special types:
|
|
125
|
+
* - `{$link: string}` objects are converted to `Cid` instances
|
|
126
|
+
* - `{$bytes: string}` objects are converted to `Uint8Array` instances
|
|
127
|
+
*
|
|
128
|
+
* Use this when you have a JavaScript object (e.g., from `JSON.parse()`) and
|
|
129
|
+
* need to convert it to the Lex data model. For parsing JSON strings directly,
|
|
130
|
+
* use {@link lexParse} instead.
|
|
131
|
+
*
|
|
132
|
+
* @param value - The JSON value to convert
|
|
133
|
+
* @param options - Parsing options (e.g., strict mode)
|
|
134
|
+
* @returns The converted Lex value
|
|
135
|
+
* @throws {TypeError} If strict mode is enabled and invalid Lex values are found
|
|
136
|
+
* @throws {TypeError} If the value contains unsupported types (e.g., undefined at top level)
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* import { jsonToLex } from '@atproto/lex'
|
|
141
|
+
*
|
|
142
|
+
* // Convert parsed JSON to Lex values
|
|
143
|
+
* const lex = jsonToLex({
|
|
144
|
+
* ref: { $link: 'bafyrei...' }, // Converted to Cid
|
|
145
|
+
* data: { $bytes: 'SGVsbG8sIHdvcmxkIQ==' } // Converted to Uint8Array
|
|
146
|
+
* })
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
51
149
|
export function jsonToLex(
|
|
52
150
|
value: JsonValue,
|
|
53
151
|
options: LexParseOptions = { strict: false },
|
|
@@ -120,6 +218,33 @@ function jsonObjectToLexMap(
|
|
|
120
218
|
return copy ?? input
|
|
121
219
|
}
|
|
122
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Converts a Lex value to a JSON-compatible value.
|
|
223
|
+
*
|
|
224
|
+
* This function transforms Lex data model values into plain JavaScript objects
|
|
225
|
+
* suitable for JSON serialization:
|
|
226
|
+
* - `Cid` instances are converted to `{$link: string}` objects
|
|
227
|
+
* - `Uint8Array` instances are converted to `{$bytes: string}` objects (base64)
|
|
228
|
+
*
|
|
229
|
+
* Use this when you need to convert Lex values to plain objects (e.g., for
|
|
230
|
+
* custom serialization or inspection). For direct JSON string output, use
|
|
231
|
+
* {@link lexStringify} instead.
|
|
232
|
+
*
|
|
233
|
+
* @param value - The Lex value to convert
|
|
234
|
+
* @returns The JSON-compatible value
|
|
235
|
+
* @throws {TypeError} If the value contains unsupported types
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* import { lexToJson } from '@atproto/lex'
|
|
240
|
+
*
|
|
241
|
+
* // Convert Lex values to JSON-compatible objects
|
|
242
|
+
* const obj = lexToJson({
|
|
243
|
+
* ref: someCid, // Converted to { $link: string }
|
|
244
|
+
* data: someBytes // Converted to { $bytes: string }
|
|
245
|
+
* })
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
123
248
|
export function lexToJson(value: LexValue): JsonValue {
|
|
124
249
|
switch (typeof value) {
|
|
125
250
|
case 'object':
|
package/src/link.ts
CHANGED
|
@@ -6,6 +6,35 @@ import {
|
|
|
6
6
|
} from '@atproto/lex-data'
|
|
7
7
|
import { JsonValue } from './json.js'
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Parses a `{$link: string}` JSON object into a {@link Cid} instance.
|
|
11
|
+
*
|
|
12
|
+
* In the AT Protocol data model, CID references are represented in JSON as an
|
|
13
|
+
* object with a single `$link` property containing a base32-encoded CID string,
|
|
14
|
+
* prefixed with "b". This function decodes that representation into a `Cid`
|
|
15
|
+
* object.
|
|
16
|
+
*
|
|
17
|
+
* @param input - An object potentially containing a `{$link: string}` property
|
|
18
|
+
* @param options - Optional CID validation options
|
|
19
|
+
* @returns The parsed {@link Cid} if the input is a valid `$link` object,
|
|
20
|
+
* or `undefined` if the input is not a valid `$link` representation
|
|
21
|
+
* @throws {TypeError} If `$link` is present but is not a valid CID string
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // Parse a $link object to Cid
|
|
26
|
+
* const cid = parseLexLink({ $link: 'bafyreib2rxk3rybloqtqwbo' })
|
|
27
|
+
* // cid is a Cid instance
|
|
28
|
+
*
|
|
29
|
+
* // Returns undefined for non-$link objects
|
|
30
|
+
* const result = parseLexLink({ foo: 'bar' })
|
|
31
|
+
* // result is undefined
|
|
32
|
+
*
|
|
33
|
+
* // Returns undefined for objects with extra properties
|
|
34
|
+
* const invalid = parseLexLink({ $link: 'bafyrei...', extra: true })
|
|
35
|
+
* // invalid is undefined
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
9
38
|
export function parseLexLink<TOptions extends CheckCidOptions>(
|
|
10
39
|
input: undefined | Record<string, unknown>,
|
|
11
40
|
options: TOptions,
|
|
@@ -31,25 +60,42 @@ export function parseLexLink(
|
|
|
31
60
|
const { $link } = input
|
|
32
61
|
|
|
33
62
|
if (typeof $link !== 'string') {
|
|
34
|
-
|
|
63
|
+
return undefined
|
|
35
64
|
}
|
|
36
65
|
|
|
37
66
|
if ($link.length === 0) {
|
|
38
|
-
|
|
67
|
+
return undefined
|
|
39
68
|
}
|
|
40
69
|
|
|
41
70
|
// Arbitrary limit to prevent DoS via extremely long CIDs
|
|
42
71
|
if ($link.length > 2048) {
|
|
43
|
-
|
|
72
|
+
return undefined
|
|
44
73
|
}
|
|
45
74
|
|
|
46
75
|
try {
|
|
47
76
|
return parseCid($link, options)
|
|
48
77
|
} catch (cause) {
|
|
49
|
-
|
|
78
|
+
return undefined
|
|
50
79
|
}
|
|
51
80
|
}
|
|
52
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Encodes a {@link Cid} instance into a `{$link: string}` JSON representation.
|
|
84
|
+
*
|
|
85
|
+
* In the AT Protocol data model, CID references are represented in JSON as an
|
|
86
|
+
* object with a single `$link` property containing a base32-encoded CID string,
|
|
87
|
+
* prefixed with "b". This function performs that encoding.
|
|
88
|
+
*
|
|
89
|
+
* @param cid - The CID to encode
|
|
90
|
+
* @returns An object with a `$link` property containing the string representation of the CID
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* const cid = CID.parse('bafyreib2rxk3rybloqtqwbo')
|
|
95
|
+
* const encoded = encodeLexLink(cid)
|
|
96
|
+
* // encoded is { $link: 'bafyreib2rxk3rybloqtqwbo' }
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
53
99
|
export function encodeLexLink(cid: Cid): JsonValue {
|
|
54
100
|
return { $link: cid.toString() }
|
|
55
101
|
}
|