@atproto/lex-data 0.0.9 → 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 +14 -0
- package/dist/blob.d.ts +143 -6
- package/dist/blob.d.ts.map +1 -1
- package/dist/blob.js +23 -0
- package/dist/blob.js.map +1 -1
- package/dist/cid.d.ts +211 -27
- package/dist/cid.d.ts.map +1 -1
- package/dist/cid.js +115 -19
- package/dist/cid.js.map +1 -1
- package/dist/lex-equals.d.ts +38 -0
- package/dist/lex-equals.d.ts.map +1 -1
- package/dist/lex-equals.js +38 -0
- package/dist/lex-equals.js.map +1 -1
- package/dist/lex-error.d.ts +83 -3
- package/dist/lex-error.d.ts.map +1 -1
- package/dist/lex-error.js +52 -3
- package/dist/lex-error.js.map +1 -1
- package/dist/lex.d.ts +184 -2
- package/dist/lex.d.ts.map +1 -1
- package/dist/lex.js +99 -0
- package/dist/lex.js.map +1 -1
- package/dist/object.d.ts +54 -4
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +54 -4
- package/dist/object.js.map +1 -1
- package/dist/uint8array.d.ts +96 -4
- package/dist/uint8array.d.ts.map +1 -1
- package/dist/uint8array.js +96 -4
- package/dist/uint8array.js.map +1 -1
- package/dist/utf8.d.ts +77 -0
- package/dist/utf8.d.ts.map +1 -1
- package/dist/utf8.js +77 -0
- package/dist/utf8.js.map +1 -1
- package/package.json +2 -2
- package/src/blob.ts +143 -6
- package/src/cid-implementation.test.ts +7 -15
- package/src/cid.test.ts +14 -16
- package/src/cid.ts +228 -52
- package/src/lex-equals.ts +38 -0
- package/src/lex-error.ts +83 -4
- package/src/lex.ts +187 -1
- package/src/object.ts +54 -4
- package/src/uint8array.ts +96 -4
- package/src/utf8.ts +77 -0
package/dist/lex.d.ts
CHANGED
|
@@ -1,18 +1,200 @@
|
|
|
1
1
|
import { Cid } from './cid.js';
|
|
2
|
+
/**
|
|
3
|
+
* Primitive values in the Lexicon data model.
|
|
4
|
+
*
|
|
5
|
+
* Represents the basic scalar types that can appear in AT Protocol data:
|
|
6
|
+
* - `number` - Integer values only (no floats)
|
|
7
|
+
* - `string` - UTF-8 text
|
|
8
|
+
* - `boolean` - true or false
|
|
9
|
+
* - `null` - Explicit null value
|
|
10
|
+
* - `Cid` - Content Identifier (link by hash)
|
|
11
|
+
* - `Uint8Array` - Binary data (bytes)
|
|
12
|
+
*
|
|
13
|
+
* @see {@link LexValue} for the complete recursive value type
|
|
14
|
+
*/
|
|
2
15
|
export type LexScalar = number | string | boolean | null | Cid | Uint8Array;
|
|
16
|
+
/**
|
|
17
|
+
* Any valid Lexicon value (recursive type).
|
|
18
|
+
*
|
|
19
|
+
* This is the union of all types that can appear in AT Protocol Lexicon data:
|
|
20
|
+
* - {@link LexScalar} - Primitive values (number, string, boolean, null, Cid, Uint8Array)
|
|
21
|
+
* - `LexValue[]` - Arrays of LexValues
|
|
22
|
+
* - `{ [key: string]?: LexValue }` - Objects with string keys and LexValue values
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import type { LexValue } from '@atproto/lex'
|
|
27
|
+
*
|
|
28
|
+
* const scalar: LexValue = 'hello'
|
|
29
|
+
* const array: LexValue = [1, 2, 3]
|
|
30
|
+
* const object: LexValue = { name: 'Alice', age: 30 }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @see {@link LexScalar} for primitive value types
|
|
34
|
+
* @see {@link LexMap} for object types
|
|
35
|
+
* @see {@link LexArray} for array types
|
|
36
|
+
*/
|
|
3
37
|
export type LexValue = LexScalar | LexValue[] | {
|
|
4
38
|
[_ in string]?: LexValue;
|
|
5
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Object with string keys and LexValue values.
|
|
42
|
+
*
|
|
43
|
+
* Represents a plain object in the Lexicon data model where all values
|
|
44
|
+
* must be valid {@link LexValue} types.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import type { LexMap } from '@atproto/lex'
|
|
49
|
+
*
|
|
50
|
+
* const user: LexMap = {
|
|
51
|
+
* name: 'Alice',
|
|
52
|
+
* age: 30,
|
|
53
|
+
* tags: ['admin', 'user']
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @see {@link TypedLexMap} for objects with a required `$type` property
|
|
58
|
+
*/
|
|
6
59
|
export type LexMap = {
|
|
7
60
|
[_ in string]?: LexValue;
|
|
8
61
|
};
|
|
62
|
+
/**
|
|
63
|
+
* Array of {@link LexValue} elements.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* import type { LexArray } from '@atproto/lex'
|
|
68
|
+
*
|
|
69
|
+
* const items: LexArray = [1, 'two', { three: 3 }]
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
9
72
|
export type LexArray = LexValue[];
|
|
73
|
+
/**
|
|
74
|
+
* Type guard to check if a value is a valid {@link LexMap}.
|
|
75
|
+
*
|
|
76
|
+
* Returns true if the value is a plain object where all values are valid
|
|
77
|
+
* {@link LexValue} types.
|
|
78
|
+
*
|
|
79
|
+
* @param value - The value to check
|
|
80
|
+
* @returns `true` if the value is a valid LexMap
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* import { isLexMap } from '@atproto/lex'
|
|
85
|
+
*
|
|
86
|
+
* if (isLexMap(data)) {
|
|
87
|
+
* // data is narrowed to LexMap
|
|
88
|
+
* console.log(Object.keys(data))
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
10
92
|
export declare function isLexMap(value: unknown): value is LexMap;
|
|
93
|
+
/**
|
|
94
|
+
* Type guard to check if a value is a valid {@link LexArray}.
|
|
95
|
+
*
|
|
96
|
+
* Returns true if the value is an array where all elements are valid
|
|
97
|
+
* {@link LexValue} types.
|
|
98
|
+
*
|
|
99
|
+
* @param value - The value to check
|
|
100
|
+
* @returns `true` if the value is a valid LexArray
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* import { isLexArray } from '@atproto/lex'
|
|
105
|
+
*
|
|
106
|
+
* if (isLexArray(data)) {
|
|
107
|
+
* // data is narrowed to LexArray
|
|
108
|
+
* data.forEach(item => console.log(item))
|
|
109
|
+
* }
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
11
112
|
export declare function isLexArray(value: unknown): value is LexArray;
|
|
113
|
+
/**
|
|
114
|
+
* Type guard to check if a value is a valid {@link LexScalar}.
|
|
115
|
+
*
|
|
116
|
+
* Returns true if the value is one of the primitive Lexicon types:
|
|
117
|
+
* number (integer only), string, boolean, null, Cid, or Uint8Array.
|
|
118
|
+
*
|
|
119
|
+
* @param value - The value to check
|
|
120
|
+
* @returns `true` if the value is a valid LexScalar
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* import { isLexScalar } from '@atproto/lex'
|
|
125
|
+
*
|
|
126
|
+
* isLexScalar('hello') // true
|
|
127
|
+
* isLexScalar(42) // true
|
|
128
|
+
* isLexScalar(3.14) // false (floats not allowed)
|
|
129
|
+
* isLexScalar([1, 2]) // false (arrays are not scalars)
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
12
132
|
export declare function isLexScalar(value: unknown): value is LexScalar;
|
|
133
|
+
/**
|
|
134
|
+
* Type guard to check if a value is a valid {@link LexValue}.
|
|
135
|
+
*
|
|
136
|
+
* Performs a deep check to validate that the value (and all nested values)
|
|
137
|
+
* conform to the Lexicon data model. This includes checking for:
|
|
138
|
+
* - Valid scalar types (number, string, boolean, null, Cid, Uint8Array)
|
|
139
|
+
* - Arrays containing only valid LexValues
|
|
140
|
+
* - Plain objects with string keys and valid LexValue values
|
|
141
|
+
* - No cyclic references (which cannot be serialized to JSON or CBOR)
|
|
142
|
+
*
|
|
143
|
+
* @param value - The value to check
|
|
144
|
+
* @returns `true` if the value is a valid LexValue
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* import { isLexValue } from '@atproto/lex'
|
|
149
|
+
*
|
|
150
|
+
* isLexValue({ name: 'Alice', tags: ['admin'] }) // true
|
|
151
|
+
* isLexValue(new Date()) // false (not a plain object)
|
|
152
|
+
* isLexValue({ fn: () => {} }) // false (functions not allowed)
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
13
155
|
export declare function isLexValue(value: unknown): value is LexValue;
|
|
14
|
-
|
|
15
|
-
|
|
156
|
+
/**
|
|
157
|
+
* A {@link LexMap} with a required `$type` property.
|
|
158
|
+
*
|
|
159
|
+
* Used to represent typed objects in the Lexicon data model, where the
|
|
160
|
+
* `$type` property identifies the Lexicon schema that defines the object's
|
|
161
|
+
* structure.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* import type { TypedLexMap } from '@atproto/lex'
|
|
166
|
+
*
|
|
167
|
+
* const post: TypedLexMap = {
|
|
168
|
+
* $type: 'app.bsky.feed.post',
|
|
169
|
+
* text: 'Hello world!',
|
|
170
|
+
* createdAt: '2024-01-01T00:00:00Z'
|
|
171
|
+
* }
|
|
172
|
+
* ```
|
|
173
|
+
*
|
|
174
|
+
* @see {@link isTypedLexMap} to check if a value is a TypedLexMap
|
|
175
|
+
*/
|
|
176
|
+
export type TypedLexMap<T extends string = string> = LexMap & {
|
|
177
|
+
$type: T;
|
|
16
178
|
};
|
|
179
|
+
/**
|
|
180
|
+
* Type guard to check if a value is a {@link TypedLexMap}.
|
|
181
|
+
*
|
|
182
|
+
* Returns true if the value is a valid {@link LexMap} with a non-empty
|
|
183
|
+
* `$type` string property.
|
|
184
|
+
*
|
|
185
|
+
* @param value - The LexValue to check
|
|
186
|
+
* @returns `true` if the value is a TypedLexMap
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```typescript
|
|
190
|
+
* import { isTypedLexMap } from '@atproto/lex'
|
|
191
|
+
*
|
|
192
|
+
* const data = { $type: 'app.bsky.feed.post', text: 'Hello' }
|
|
193
|
+
*
|
|
194
|
+
* if (isTypedLexMap(data)) {
|
|
195
|
+
* console.log(data.$type) // 'app.bsky.feed.post'
|
|
196
|
+
* }
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
17
199
|
export declare function isTypedLexMap(value: LexValue): value is TypedLexMap;
|
|
18
200
|
//# sourceMappingURL=lex.d.ts.map
|
package/dist/lex.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lex.d.ts","sourceRoot":"","sources":["../src/lex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAS,MAAM,UAAU,CAAA;AAGrC,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,GAAG,GAAG,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"lex.d.ts","sourceRoot":"","sources":["../src/lex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAS,MAAM,UAAU,CAAA;AAGrC;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,GAAG,GAAG,UAAU,CAAA;AAE3E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,EAAE,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,QAAQ;CAAE,CAAA;AAE5E;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,MAAM,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,QAAQ;CAAE,CAAA;AAEjD;;;;;;;;;GASG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAAA;AAEjC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAExD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAa9D;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CA8C5D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,MAAM,GAAG;IAAE,KAAK,EAAE,CAAC,CAAA;CAAE,CAAA;AAE1E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,GAAG,KAAK,IAAI,WAAW,CAInE"}
|
package/dist/lex.js
CHANGED
|
@@ -7,12 +7,69 @@ exports.isLexValue = isLexValue;
|
|
|
7
7
|
exports.isTypedLexMap = isTypedLexMap;
|
|
8
8
|
const cid_js_1 = require("./cid.js");
|
|
9
9
|
const object_js_1 = require("./object.js");
|
|
10
|
+
/**
|
|
11
|
+
* Type guard to check if a value is a valid {@link LexMap}.
|
|
12
|
+
*
|
|
13
|
+
* Returns true if the value is a plain object where all values are valid
|
|
14
|
+
* {@link LexValue} types.
|
|
15
|
+
*
|
|
16
|
+
* @param value - The value to check
|
|
17
|
+
* @returns `true` if the value is a valid LexMap
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { isLexMap } from '@atproto/lex'
|
|
22
|
+
*
|
|
23
|
+
* if (isLexMap(data)) {
|
|
24
|
+
* // data is narrowed to LexMap
|
|
25
|
+
* console.log(Object.keys(data))
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
10
29
|
function isLexMap(value) {
|
|
11
30
|
return (0, object_js_1.isPlainObject)(value) && Object.values(value).every(isLexValue);
|
|
12
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Type guard to check if a value is a valid {@link LexArray}.
|
|
34
|
+
*
|
|
35
|
+
* Returns true if the value is an array where all elements are valid
|
|
36
|
+
* {@link LexValue} types.
|
|
37
|
+
*
|
|
38
|
+
* @param value - The value to check
|
|
39
|
+
* @returns `true` if the value is a valid LexArray
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* import { isLexArray } from '@atproto/lex'
|
|
44
|
+
*
|
|
45
|
+
* if (isLexArray(data)) {
|
|
46
|
+
* // data is narrowed to LexArray
|
|
47
|
+
* data.forEach(item => console.log(item))
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
13
51
|
function isLexArray(value) {
|
|
14
52
|
return Array.isArray(value) && value.every(isLexValue);
|
|
15
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Type guard to check if a value is a valid {@link LexScalar}.
|
|
56
|
+
*
|
|
57
|
+
* Returns true if the value is one of the primitive Lexicon types:
|
|
58
|
+
* number (integer only), string, boolean, null, Cid, or Uint8Array.
|
|
59
|
+
*
|
|
60
|
+
* @param value - The value to check
|
|
61
|
+
* @returns `true` if the value is a valid LexScalar
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* import { isLexScalar } from '@atproto/lex'
|
|
66
|
+
*
|
|
67
|
+
* isLexScalar('hello') // true
|
|
68
|
+
* isLexScalar(42) // true
|
|
69
|
+
* isLexScalar(3.14) // false (floats not allowed)
|
|
70
|
+
* isLexScalar([1, 2]) // false (arrays are not scalars)
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
16
73
|
function isLexScalar(value) {
|
|
17
74
|
switch (typeof value) {
|
|
18
75
|
case 'object':
|
|
@@ -28,6 +85,28 @@ function isLexScalar(value) {
|
|
|
28
85
|
return false;
|
|
29
86
|
}
|
|
30
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Type guard to check if a value is a valid {@link LexValue}.
|
|
90
|
+
*
|
|
91
|
+
* Performs a deep check to validate that the value (and all nested values)
|
|
92
|
+
* conform to the Lexicon data model. This includes checking for:
|
|
93
|
+
* - Valid scalar types (number, string, boolean, null, Cid, Uint8Array)
|
|
94
|
+
* - Arrays containing only valid LexValues
|
|
95
|
+
* - Plain objects with string keys and valid LexValue values
|
|
96
|
+
* - No cyclic references (which cannot be serialized to JSON or CBOR)
|
|
97
|
+
*
|
|
98
|
+
* @param value - The value to check
|
|
99
|
+
* @returns `true` if the value is a valid LexValue
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* import { isLexValue } from '@atproto/lex'
|
|
104
|
+
*
|
|
105
|
+
* isLexValue({ name: 'Alice', tags: ['admin'] }) // true
|
|
106
|
+
* isLexValue(new Date()) // false (not a plain object)
|
|
107
|
+
* isLexValue({ fn: () => {} }) // false (functions not allowed)
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
31
110
|
function isLexValue(value) {
|
|
32
111
|
// Using a stack to avoid recursion depth issues.
|
|
33
112
|
const stack = [value];
|
|
@@ -78,6 +157,26 @@ function isLexValue(value) {
|
|
|
78
157
|
visited.clear();
|
|
79
158
|
return true;
|
|
80
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Type guard to check if a value is a {@link TypedLexMap}.
|
|
162
|
+
*
|
|
163
|
+
* Returns true if the value is a valid {@link LexMap} with a non-empty
|
|
164
|
+
* `$type` string property.
|
|
165
|
+
*
|
|
166
|
+
* @param value - The LexValue to check
|
|
167
|
+
* @returns `true` if the value is a TypedLexMap
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```typescript
|
|
171
|
+
* import { isTypedLexMap } from '@atproto/lex'
|
|
172
|
+
*
|
|
173
|
+
* const data = { $type: 'app.bsky.feed.post', text: 'Hello' }
|
|
174
|
+
*
|
|
175
|
+
* if (isTypedLexMap(data)) {
|
|
176
|
+
* console.log(data.$type) // 'app.bsky.feed.post'
|
|
177
|
+
* }
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
81
180
|
function isTypedLexMap(value) {
|
|
82
181
|
return (isLexMap(value) && typeof value.$type === 'string' && value.$type.length > 0);
|
|
83
182
|
}
|
package/dist/lex.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lex.js","sourceRoot":"","sources":["../src/lex.ts"],"names":[],"mappings":"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","sourcesContent":["import { Cid, isCid } from './cid.js'\nimport { isPlainObject, isPlainProto } from './object.js'\n\nexport type LexScalar = number | string | boolean | null | Cid | Uint8Array\nexport type LexValue = LexScalar | LexValue[] | { [_ in string]?: LexValue }\nexport type LexMap = { [_ in string]?: LexValue }\nexport type LexArray = LexValue[]\n\nexport function isLexMap(value: unknown): value is LexMap {\n return isPlainObject(value) && Object.values(value).every(isLexValue)\n}\n\nexport function isLexArray(value: unknown): value is LexArray {\n return Array.isArray(value) && value.every(isLexValue)\n}\n\nexport function isLexScalar(value: unknown): value is LexScalar {\n switch (typeof value) {\n case 'object':\n return value === null || value instanceof Uint8Array || isCid(value)\n case 'string':\n case 'boolean':\n return true\n case 'number':\n if (Number.isInteger(value)) return true\n // fallthrough\n default:\n return false\n }\n}\n\nexport function isLexValue(value: unknown): value is LexValue {\n // Using a stack to avoid recursion depth issues.\n const stack: unknown[] = [value]\n // Cyclic structures are not valid LexValues as they cannot be serialized to\n // JSON or CBOR. This also allows us to avoid infinite loops when traversing\n // the structure.\n const visited = new Set<object>()\n\n do {\n const value = stack.pop()!\n\n // Optimization: we are not using `isLexScalar` here to avoid extra function\n // calls, and to avoid computing `typeof value` multiple times.\n switch (typeof value) {\n case 'object':\n if (value === null) {\n // LexScalar\n } else if (isPlainProto(value)) {\n if (visited.has(value)) return false\n visited.add(value)\n stack.push(...Object.values(value))\n } else if (Array.isArray(value)) {\n if (visited.has(value)) return false\n visited.add(value)\n stack.push(...value)\n } else if (value instanceof Uint8Array || isCid(value)) {\n // LexScalar\n } else {\n return false\n }\n break\n case 'string':\n case 'boolean':\n break\n case 'number':\n if (Number.isInteger(value)) break\n // fallthrough\n default:\n return false\n }\n } while (stack.length > 0)\n\n // Optimization: ease GC's work\n visited.clear()\n\n return true\n}\n\nexport type TypedLexMap = LexMap & { $type: string }\nexport function isTypedLexMap(value: LexValue): value is TypedLexMap {\n return (\n isLexMap(value) && typeof value.$type === 'string' && value.$type.length > 0\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"lex.js","sourceRoot":"","sources":["../src/lex.ts"],"names":[],"mappings":"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","sourcesContent":["import { Cid, isCid } from './cid.js'\nimport { isPlainObject, isPlainProto } from './object.js'\n\n/**\n * Primitive values in the Lexicon data model.\n *\n * Represents the basic scalar types that can appear in AT Protocol data:\n * - `number` - Integer values only (no floats)\n * - `string` - UTF-8 text\n * - `boolean` - true or false\n * - `null` - Explicit null value\n * - `Cid` - Content Identifier (link by hash)\n * - `Uint8Array` - Binary data (bytes)\n *\n * @see {@link LexValue} for the complete recursive value type\n */\nexport type LexScalar = number | string | boolean | null | Cid | Uint8Array\n\n/**\n * Any valid Lexicon value (recursive type).\n *\n * This is the union of all types that can appear in AT Protocol Lexicon data:\n * - {@link LexScalar} - Primitive values (number, string, boolean, null, Cid, Uint8Array)\n * - `LexValue[]` - Arrays of LexValues\n * - `{ [key: string]?: LexValue }` - Objects with string keys and LexValue values\n *\n * @example\n * ```typescript\n * import type { LexValue } from '@atproto/lex'\n *\n * const scalar: LexValue = 'hello'\n * const array: LexValue = [1, 2, 3]\n * const object: LexValue = { name: 'Alice', age: 30 }\n * ```\n *\n * @see {@link LexScalar} for primitive value types\n * @see {@link LexMap} for object types\n * @see {@link LexArray} for array types\n */\nexport type LexValue = LexScalar | LexValue[] | { [_ in string]?: LexValue }\n\n/**\n * Object with string keys and LexValue values.\n *\n * Represents a plain object in the Lexicon data model where all values\n * must be valid {@link LexValue} types.\n *\n * @example\n * ```typescript\n * import type { LexMap } from '@atproto/lex'\n *\n * const user: LexMap = {\n * name: 'Alice',\n * age: 30,\n * tags: ['admin', 'user']\n * }\n * ```\n *\n * @see {@link TypedLexMap} for objects with a required `$type` property\n */\nexport type LexMap = { [_ in string]?: LexValue }\n\n/**\n * Array of {@link LexValue} elements.\n *\n * @example\n * ```typescript\n * import type { LexArray } from '@atproto/lex'\n *\n * const items: LexArray = [1, 'two', { three: 3 }]\n * ```\n */\nexport type LexArray = LexValue[]\n\n/**\n * Type guard to check if a value is a valid {@link LexMap}.\n *\n * Returns true if the value is a plain object where all values are valid\n * {@link LexValue} types.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid LexMap\n *\n * @example\n * ```typescript\n * import { isLexMap } from '@atproto/lex'\n *\n * if (isLexMap(data)) {\n * // data is narrowed to LexMap\n * console.log(Object.keys(data))\n * }\n * ```\n */\nexport function isLexMap(value: unknown): value is LexMap {\n return isPlainObject(value) && Object.values(value).every(isLexValue)\n}\n\n/**\n * Type guard to check if a value is a valid {@link LexArray}.\n *\n * Returns true if the value is an array where all elements are valid\n * {@link LexValue} types.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid LexArray\n *\n * @example\n * ```typescript\n * import { isLexArray } from '@atproto/lex'\n *\n * if (isLexArray(data)) {\n * // data is narrowed to LexArray\n * data.forEach(item => console.log(item))\n * }\n * ```\n */\nexport function isLexArray(value: unknown): value is LexArray {\n return Array.isArray(value) && value.every(isLexValue)\n}\n\n/**\n * Type guard to check if a value is a valid {@link LexScalar}.\n *\n * Returns true if the value is one of the primitive Lexicon types:\n * number (integer only), string, boolean, null, Cid, or Uint8Array.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid LexScalar\n *\n * @example\n * ```typescript\n * import { isLexScalar } from '@atproto/lex'\n *\n * isLexScalar('hello') // true\n * isLexScalar(42) // true\n * isLexScalar(3.14) // false (floats not allowed)\n * isLexScalar([1, 2]) // false (arrays are not scalars)\n * ```\n */\nexport function isLexScalar(value: unknown): value is LexScalar {\n switch (typeof value) {\n case 'object':\n return value === null || value instanceof Uint8Array || isCid(value)\n case 'string':\n case 'boolean':\n return true\n case 'number':\n if (Number.isInteger(value)) return true\n // fallthrough\n default:\n return false\n }\n}\n\n/**\n * Type guard to check if a value is a valid {@link LexValue}.\n *\n * Performs a deep check to validate that the value (and all nested values)\n * conform to the Lexicon data model. This includes checking for:\n * - Valid scalar types (number, string, boolean, null, Cid, Uint8Array)\n * - Arrays containing only valid LexValues\n * - Plain objects with string keys and valid LexValue values\n * - No cyclic references (which cannot be serialized to JSON or CBOR)\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid LexValue\n *\n * @example\n * ```typescript\n * import { isLexValue } from '@atproto/lex'\n *\n * isLexValue({ name: 'Alice', tags: ['admin'] }) // true\n * isLexValue(new Date()) // false (not a plain object)\n * isLexValue({ fn: () => {} }) // false (functions not allowed)\n * ```\n */\nexport function isLexValue(value: unknown): value is LexValue {\n // Using a stack to avoid recursion depth issues.\n const stack: unknown[] = [value]\n // Cyclic structures are not valid LexValues as they cannot be serialized to\n // JSON or CBOR. This also allows us to avoid infinite loops when traversing\n // the structure.\n const visited = new Set<object>()\n\n do {\n const value = stack.pop()!\n\n // Optimization: we are not using `isLexScalar` here to avoid extra function\n // calls, and to avoid computing `typeof value` multiple times.\n switch (typeof value) {\n case 'object':\n if (value === null) {\n // LexScalar\n } else if (isPlainProto(value)) {\n if (visited.has(value)) return false\n visited.add(value)\n stack.push(...Object.values(value))\n } else if (Array.isArray(value)) {\n if (visited.has(value)) return false\n visited.add(value)\n stack.push(...value)\n } else if (value instanceof Uint8Array || isCid(value)) {\n // LexScalar\n } else {\n return false\n }\n break\n case 'string':\n case 'boolean':\n break\n case 'number':\n if (Number.isInteger(value)) break\n // fallthrough\n default:\n return false\n }\n } while (stack.length > 0)\n\n // Optimization: ease GC's work\n visited.clear()\n\n return true\n}\n\n/**\n * A {@link LexMap} with a required `$type` property.\n *\n * Used to represent typed objects in the Lexicon data model, where the\n * `$type` property identifies the Lexicon schema that defines the object's\n * structure.\n *\n * @example\n * ```typescript\n * import type { TypedLexMap } from '@atproto/lex'\n *\n * const post: TypedLexMap = {\n * $type: 'app.bsky.feed.post',\n * text: 'Hello world!',\n * createdAt: '2024-01-01T00:00:00Z'\n * }\n * ```\n *\n * @see {@link isTypedLexMap} to check if a value is a TypedLexMap\n */\nexport type TypedLexMap<T extends string = string> = LexMap & { $type: T }\n\n/**\n * Type guard to check if a value is a {@link TypedLexMap}.\n *\n * Returns true if the value is a valid {@link LexMap} with a non-empty\n * `$type` string property.\n *\n * @param value - The LexValue to check\n * @returns `true` if the value is a TypedLexMap\n *\n * @example\n * ```typescript\n * import { isTypedLexMap } from '@atproto/lex'\n *\n * const data = { $type: 'app.bsky.feed.post', text: 'Hello' }\n *\n * if (isTypedLexMap(data)) {\n * console.log(data.$type) // 'app.bsky.feed.post'\n * }\n * ```\n */\nexport function isTypedLexMap(value: LexValue): value is TypedLexMap {\n return (\n isLexMap(value) && typeof value.$type === 'string' && value.$type.length > 0\n )\n}\n"]}
|
package/dist/object.d.ts
CHANGED
|
@@ -1,15 +1,65 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Checks whether the input is an object (not null).
|
|
3
|
+
*
|
|
4
|
+
* Returns true for any non-null value with typeof 'object', including
|
|
5
|
+
* arrays, plain objects, class instances, etc.
|
|
6
|
+
*
|
|
7
|
+
* @param input - The value to check
|
|
8
|
+
* @returns `true` if the input is an object (not null)
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { isObject } from '@atproto/lex-data'
|
|
13
|
+
*
|
|
14
|
+
* isObject({}) // true
|
|
15
|
+
* isObject([1, 2, 3]) // true
|
|
16
|
+
* isObject(new Date()) // true
|
|
17
|
+
* isObject(null) // false
|
|
18
|
+
* isObject('string') // false
|
|
19
|
+
* ```
|
|
3
20
|
*/
|
|
4
21
|
export declare function isObject(input: unknown): input is object;
|
|
5
22
|
/**
|
|
6
|
-
* Checks whether the input is
|
|
7
|
-
*
|
|
23
|
+
* Checks whether the input is a plain object.
|
|
24
|
+
*
|
|
25
|
+
* A plain object is an object (not null) whose prototype is either null
|
|
26
|
+
* or `Object.prototype`. This excludes arrays, class instances, and other
|
|
27
|
+
* special objects.
|
|
28
|
+
*
|
|
29
|
+
* @param input - The value to check
|
|
30
|
+
* @returns `true` if the input is a plain object
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* import { isPlainObject } from '@atproto/lex-data'
|
|
35
|
+
*
|
|
36
|
+
* isPlainObject({}) // true
|
|
37
|
+
* isPlainObject({ a: 1 }) // true
|
|
38
|
+
* isPlainObject(Object.create(null)) // true
|
|
39
|
+
* isPlainObject([1, 2, 3]) // false
|
|
40
|
+
* isPlainObject(new Date()) // false
|
|
41
|
+
* isPlainObject(null) // false
|
|
42
|
+
* ```
|
|
8
43
|
*/
|
|
9
44
|
export declare function isPlainObject(input: unknown): input is Record<string, unknown>;
|
|
10
45
|
/**
|
|
11
|
-
* Checks whether the prototype of
|
|
12
|
-
*
|
|
46
|
+
* Checks whether the prototype of an object is plain (null or Object.prototype).
|
|
47
|
+
*
|
|
48
|
+
* This is useful for checking if an object is a plain object without
|
|
49
|
+
* checking that it's non-null first (the null check is already done).
|
|
50
|
+
*
|
|
51
|
+
* @param input - The object to check (must be non-null)
|
|
52
|
+
* @returns `true` if the object's prototype is plain
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* import { isPlainProto } from '@atproto/lex-data'
|
|
57
|
+
*
|
|
58
|
+
* isPlainProto({}) // true
|
|
59
|
+
* isPlainProto(Object.create(null)) // true
|
|
60
|
+
* isPlainProto([1, 2, 3]) // false (Array.prototype)
|
|
61
|
+
* isPlainProto(new Date()) // false (Date.prototype)
|
|
62
|
+
* ```
|
|
13
63
|
*/
|
|
14
64
|
export declare function isPlainProto(input: object): input is Record<string, unknown>;
|
|
15
65
|
//# sourceMappingURL=object.d.ts.map
|
package/dist/object.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAExD;AAKD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,oCAE3C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAU5E"}
|
package/dist/object.js
CHANGED
|
@@ -5,6 +5,23 @@ exports.isPlainObject = isPlainObject;
|
|
|
5
5
|
exports.isPlainProto = isPlainProto;
|
|
6
6
|
/**
|
|
7
7
|
* Checks whether the input is an object (not null).
|
|
8
|
+
*
|
|
9
|
+
* Returns true for any non-null value with typeof 'object', including
|
|
10
|
+
* arrays, plain objects, class instances, etc.
|
|
11
|
+
*
|
|
12
|
+
* @param input - The value to check
|
|
13
|
+
* @returns `true` if the input is an object (not null)
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { isObject } from '@atproto/lex-data'
|
|
18
|
+
*
|
|
19
|
+
* isObject({}) // true
|
|
20
|
+
* isObject([1, 2, 3]) // true
|
|
21
|
+
* isObject(new Date()) // true
|
|
22
|
+
* isObject(null) // false
|
|
23
|
+
* isObject('string') // false
|
|
24
|
+
* ```
|
|
8
25
|
*/
|
|
9
26
|
function isObject(input) {
|
|
10
27
|
return input != null && typeof input === 'object';
|
|
@@ -12,15 +29,48 @@ function isObject(input) {
|
|
|
12
29
|
const ObjectProto = Object.prototype;
|
|
13
30
|
const ObjectToString = Object.prototype.toString;
|
|
14
31
|
/**
|
|
15
|
-
* Checks whether the input is
|
|
16
|
-
*
|
|
32
|
+
* Checks whether the input is a plain object.
|
|
33
|
+
*
|
|
34
|
+
* A plain object is an object (not null) whose prototype is either null
|
|
35
|
+
* or `Object.prototype`. This excludes arrays, class instances, and other
|
|
36
|
+
* special objects.
|
|
37
|
+
*
|
|
38
|
+
* @param input - The value to check
|
|
39
|
+
* @returns `true` if the input is a plain object
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* import { isPlainObject } from '@atproto/lex-data'
|
|
44
|
+
*
|
|
45
|
+
* isPlainObject({}) // true
|
|
46
|
+
* isPlainObject({ a: 1 }) // true
|
|
47
|
+
* isPlainObject(Object.create(null)) // true
|
|
48
|
+
* isPlainObject([1, 2, 3]) // false
|
|
49
|
+
* isPlainObject(new Date()) // false
|
|
50
|
+
* isPlainObject(null) // false
|
|
51
|
+
* ```
|
|
17
52
|
*/
|
|
18
53
|
function isPlainObject(input) {
|
|
19
54
|
return isObject(input) && isPlainProto(input);
|
|
20
55
|
}
|
|
21
56
|
/**
|
|
22
|
-
* Checks whether the prototype of
|
|
23
|
-
*
|
|
57
|
+
* Checks whether the prototype of an object is plain (null or Object.prototype).
|
|
58
|
+
*
|
|
59
|
+
* This is useful for checking if an object is a plain object without
|
|
60
|
+
* checking that it's non-null first (the null check is already done).
|
|
61
|
+
*
|
|
62
|
+
* @param input - The object to check (must be non-null)
|
|
63
|
+
* @returns `true` if the object's prototype is plain
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* import { isPlainProto } from '@atproto/lex-data'
|
|
68
|
+
*
|
|
69
|
+
* isPlainProto({}) // true
|
|
70
|
+
* isPlainProto(Object.create(null)) // true
|
|
71
|
+
* isPlainProto([1, 2, 3]) // false (Array.prototype)
|
|
72
|
+
* isPlainProto(new Date()) // false (Date.prototype)
|
|
73
|
+
* ```
|
|
24
74
|
*/
|
|
25
75
|
function isPlainProto(input) {
|
|
26
76
|
const proto = Object.getPrototypeOf(input);
|
package/dist/object.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object.js","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"object.js","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":";;AAoBA,4BAEC;AA2BD,sCAEC;AAqBD,oCAUC;AAlFD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAgB,QAAQ,CAAC,KAAc;IACrC,OAAO,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAA;AACnD,CAAC;AAED,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,CAAA;AACpC,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAA;AAEhD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,aAAa,CAAC,KAAc;IAC1C,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,CAAA;AAC/C,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,YAAY,CAAC,KAAa;IACxC,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;IAC1C,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAC/B,OAAO,CACL,CAAC,KAAK,KAAK,WAAW;QACpB,sEAAsE;QACtE,6BAA6B;QAC7B,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;QACxC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,iBAAiB,CACjD,CAAA;AACH,CAAC","sourcesContent":["/**\n * Checks whether the input is an object (not null).\n *\n * Returns true for any non-null value with typeof 'object', including\n * arrays, plain objects, class instances, etc.\n *\n * @param input - The value to check\n * @returns `true` if the input is an object (not null)\n *\n * @example\n * ```typescript\n * import { isObject } from '@atproto/lex-data'\n *\n * isObject({}) // true\n * isObject([1, 2, 3]) // true\n * isObject(new Date()) // true\n * isObject(null) // false\n * isObject('string') // false\n * ```\n */\nexport function isObject(input: unknown): input is object {\n return input != null && typeof input === 'object'\n}\n\nconst ObjectProto = Object.prototype\nconst ObjectToString = Object.prototype.toString\n\n/**\n * Checks whether the input is a plain object.\n *\n * A plain object is an object (not null) whose prototype is either null\n * or `Object.prototype`. This excludes arrays, class instances, and other\n * special objects.\n *\n * @param input - The value to check\n * @returns `true` if the input is a plain object\n *\n * @example\n * ```typescript\n * import { isPlainObject } from '@atproto/lex-data'\n *\n * isPlainObject({}) // true\n * isPlainObject({ a: 1 }) // true\n * isPlainObject(Object.create(null)) // true\n * isPlainObject([1, 2, 3]) // false\n * isPlainObject(new Date()) // false\n * isPlainObject(null) // false\n * ```\n */\nexport function isPlainObject(input: unknown) {\n return isObject(input) && isPlainProto(input)\n}\n\n/**\n * Checks whether the prototype of an object is plain (null or Object.prototype).\n *\n * This is useful for checking if an object is a plain object without\n * checking that it's non-null first (the null check is already done).\n *\n * @param input - The object to check (must be non-null)\n * @returns `true` if the object's prototype is plain\n *\n * @example\n * ```typescript\n * import { isPlainProto } from '@atproto/lex-data'\n *\n * isPlainProto({}) // true\n * isPlainProto(Object.create(null)) // true\n * isPlainProto([1, 2, 3]) // false (Array.prototype)\n * isPlainProto(new Date()) // false (Date.prototype)\n * ```\n */\nexport function isPlainProto(input: object): input is Record<string, unknown> {\n const proto = Object.getPrototypeOf(input)\n if (proto === null) return true\n return (\n (proto === ObjectProto ||\n // Needed to support NodeJS's `runInNewContext` which produces objects\n // with a different prototype\n Object.getPrototypeOf(proto) === null) &&\n ObjectToString.call(input) === '[object Object]'\n )\n}\n"]}
|
package/dist/uint8array.d.ts
CHANGED
|
@@ -3,24 +3,116 @@ export type { Base64Alphabet };
|
|
|
3
3
|
/**
|
|
4
4
|
* Encodes a Uint8Array into a base64 string.
|
|
5
5
|
*
|
|
6
|
+
* Uses native Uint8Array.prototype.toBase64 when available (Node.js 24+, modern browsers),
|
|
7
|
+
* falling back to Node.js Buffer or a ponyfill implementation.
|
|
8
|
+
*
|
|
9
|
+
* @param bytes - The binary data to encode
|
|
10
|
+
* @param alphabet - The base64 alphabet to use ('base64' or 'base64url'), defaults to 'base64'
|
|
6
11
|
* @returns The base64 encoded string
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { toBase64 } from '@atproto/lex-data'
|
|
16
|
+
*
|
|
17
|
+
* const bytes = new Uint8Array([72, 101, 108, 108, 111])
|
|
18
|
+
* toBase64(bytes) // 'SGVsbG8='
|
|
19
|
+
* toBase64(bytes, 'base64url') // 'SGVsbG8' (URL-safe, no padding)
|
|
20
|
+
* ```
|
|
7
21
|
*/
|
|
8
22
|
export declare const toBase64: (bytes: Uint8Array, alphabet?: Base64Alphabet) => string;
|
|
9
23
|
/**
|
|
10
|
-
* Decodes a base64 string into a Uint8Array.
|
|
11
|
-
*
|
|
24
|
+
* Decodes a base64 string into a Uint8Array.
|
|
25
|
+
*
|
|
26
|
+
* Supports both padded and unpadded base64 strings. Uses native
|
|
27
|
+
* Uint8Array.fromBase64 when available, falling back to Node.js Buffer
|
|
28
|
+
* or a ponyfill implementation.
|
|
12
29
|
*
|
|
13
|
-
* @
|
|
30
|
+
* @param b64 - The base64 string to decode
|
|
31
|
+
* @param alphabet - The base64 alphabet to use ('base64' or 'base64url'), defaults to 'base64'
|
|
32
|
+
* @returns The decoded binary data
|
|
14
33
|
* @throws If the input is not a valid base64 string
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* import { fromBase64 } from '@atproto/lex-data'
|
|
38
|
+
*
|
|
39
|
+
* fromBase64('SGVsbG8=') // Uint8Array([72, 101, 108, 108, 111])
|
|
40
|
+
* fromBase64('SGVsbG8', 'base64url') // Same, URL-safe alphabet
|
|
41
|
+
* ```
|
|
15
42
|
*/
|
|
16
43
|
export declare const fromBase64: (b64: string, alphabet?: Base64Alphabet) => Uint8Array;
|
|
44
|
+
/**
|
|
45
|
+
* Returns the input if it is a Uint8Array, otherwise returns undefined.
|
|
46
|
+
*
|
|
47
|
+
* @param input - The value to check
|
|
48
|
+
* @returns The input if it's a Uint8Array, otherwise undefined
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* import { ifUint8Array } from '@atproto/lex-data'
|
|
53
|
+
*
|
|
54
|
+
* ifUint8Array(new Uint8Array([1, 2])) // Uint8Array([1, 2])
|
|
55
|
+
* ifUint8Array('not binary') // undefined
|
|
56
|
+
* ifUint8Array(new ArrayBuffer(4)) // undefined
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
17
59
|
export declare function ifUint8Array(input: unknown): Uint8Array | undefined;
|
|
18
60
|
/**
|
|
19
61
|
* Coerces various binary data representations into a Uint8Array.
|
|
20
62
|
*
|
|
21
|
-
*
|
|
63
|
+
* Handles the following input types:
|
|
64
|
+
* - `Uint8Array` - Returned as-is
|
|
65
|
+
* - `ArrayBufferView` (e.g., DataView, other TypedArrays) - Converted to Uint8Array
|
|
66
|
+
* - `ArrayBuffer` - Wrapped in a Uint8Array
|
|
67
|
+
*
|
|
68
|
+
* @param input - The value to convert
|
|
69
|
+
* @returns A Uint8Array, or `undefined` if the input could not be converted
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* import { asUint8Array } from '@atproto/lex-data'
|
|
74
|
+
*
|
|
75
|
+
* asUint8Array(new Uint8Array([1, 2])) // Uint8Array([1, 2])
|
|
76
|
+
* asUint8Array(new ArrayBuffer(4)) // Uint8Array of length 4
|
|
77
|
+
* asUint8Array(new Int16Array([1, 2])) // Uint8Array view of the buffer
|
|
78
|
+
* asUint8Array('string') // undefined
|
|
79
|
+
* ```
|
|
22
80
|
*/
|
|
23
81
|
export declare function asUint8Array(input: unknown): Uint8Array | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* Compares two Uint8Arrays for byte-by-byte equality.
|
|
84
|
+
*
|
|
85
|
+
* @param a - First Uint8Array to compare
|
|
86
|
+
* @param b - Second Uint8Array to compare
|
|
87
|
+
* @returns `true` if both arrays have the same length and identical bytes
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* import { ui8Equals } from '@atproto/lex-data'
|
|
92
|
+
*
|
|
93
|
+
* ui8Equals(new Uint8Array([1, 2]), new Uint8Array([1, 2])) // true
|
|
94
|
+
* ui8Equals(new Uint8Array([1, 2]), new Uint8Array([1, 3])) // false
|
|
95
|
+
* ui8Equals(new Uint8Array([1]), new Uint8Array([1, 2])) // false
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
24
98
|
export declare function ui8Equals(a: Uint8Array, b: Uint8Array): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Concatenates multiple Uint8Arrays into a single Uint8Array.
|
|
101
|
+
*
|
|
102
|
+
* Uses Node.js Buffer.concat when available for performance,
|
|
103
|
+
* falling back to a ponyfill implementation.
|
|
104
|
+
*
|
|
105
|
+
* @param arrays - The Uint8Arrays to concatenate
|
|
106
|
+
* @returns A new Uint8Array containing all input bytes in order
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* import { ui8Concat } from '@atproto/lex-data'
|
|
111
|
+
*
|
|
112
|
+
* const a = new Uint8Array([1, 2])
|
|
113
|
+
* const b = new Uint8Array([3, 4])
|
|
114
|
+
* ui8Concat([a, b]) // Uint8Array([1, 2, 3, 4])
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
25
117
|
export declare const ui8Concat: (array: readonly Uint8Array[]) => Uint8Array;
|
|
26
118
|
//# sourceMappingURL=uint8array.d.ts.map
|
package/dist/uint8array.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uint8array.d.ts","sourceRoot":"","sources":["../src/uint8array.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAavD,YAAY,EAAE,cAAc,EAAE,CAAA;AAO9B
|
|
1
|
+
{"version":3,"file":"uint8array.d.ts","sourceRoot":"","sources":["../src/uint8array.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAavD,YAAY,EAAE,cAAc,EAAE,CAAA;AAO9B;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,QAAQ,EAAE,CACrB,KAAK,EAAE,UAAU,EACjB,QAAQ,CAAC,EAAE,cAAc,KACtB,MAGa,CAAA;AAElB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,UAAU,EAAE,CACvB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,cAAc,KACtB,UAGe,CAAA;AAUpB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAMnE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAkBnE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAY/D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,SAAS,8CACgD,CAAA"}
|