@atcute/cbor 2.1.1 → 2.1.2
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/README.md +16 -0
- package/dist/decode.js +128 -69
- package/dist/decode.js.map +1 -1
- package/lib/decode.ts +155 -75
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -3,7 +3,23 @@
|
|
|
3
3
|
lightweight [DASL dCBOR42 (deterministic CBOR with tag 42)][dasl-dcbor42] codec library for AT
|
|
4
4
|
Protocol.
|
|
5
5
|
|
|
6
|
+
the specific profile being implemented is [IPLD DAG-CBOR][ipld-dag-cbor], with some additional notes
|
|
7
|
+
to keep in mind:
|
|
8
|
+
|
|
9
|
+
- `undefined` types are still forbidden, except for when they are in a `map` type, where fields will
|
|
10
|
+
be omitted instead, which makes it easier to construct objects to then pass to the encoder.
|
|
11
|
+
- `byte` and `link` types are represented by atproto's [lex-json][atproto-data-model] interfaces,
|
|
12
|
+
but because these involve string codec and parsing, they are done lazily by `BytesWrapper` and
|
|
13
|
+
`CidLinkWrapper` instances.
|
|
14
|
+
- use `fromBytes` and `fromCidLink` to convert them to Uint8Array or CID interface respectively,
|
|
15
|
+
without hitting the string conversion path.
|
|
16
|
+
- use `toBytes` and `toCidLink` for the other direction.
|
|
17
|
+
- integers can't exceed JavaScript's safe integer range, no bigint conversions will occur as they
|
|
18
|
+
will be thrown instead if encountered.
|
|
19
|
+
|
|
20
|
+
[atproto-data-model]: https://atproto.com/specs/data-model
|
|
6
21
|
[dasl-dcbor42]: https://dasl.ing/dcbor42.html
|
|
22
|
+
[ipld-dag-cbor]: https://ipld.io/specs/codecs/dag-cbor/spec
|
|
7
23
|
|
|
8
24
|
```ts
|
|
9
25
|
import { encode } from '@atcute/cbor';
|
package/dist/decode.js
CHANGED
|
@@ -22,7 +22,8 @@ const readArgument = (state, info) => {
|
|
|
22
22
|
throw new Error(`invalid argument encoding; got ${info}`);
|
|
23
23
|
};
|
|
24
24
|
const readFloat64 = (state) => {
|
|
25
|
-
const
|
|
25
|
+
const view = (state.v ??= new DataView(state.b.buffer, state.b.byteOffset, state.b.byteLength));
|
|
26
|
+
const value = view.getFloat64(state.p);
|
|
26
27
|
state.p += 8;
|
|
27
28
|
return value;
|
|
28
29
|
};
|
|
@@ -73,85 +74,143 @@ const readCid = (state, length) => {
|
|
|
73
74
|
const slice = state.b.subarray(state.p + 1, (state.p += length));
|
|
74
75
|
return new CidLinkWrapper(slice);
|
|
75
76
|
};
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
77
|
+
var ContainerType;
|
|
78
|
+
(function (ContainerType) {
|
|
79
|
+
ContainerType[ContainerType["MAP"] = 0] = "MAP";
|
|
80
|
+
ContainerType[ContainerType["ARRAY"] = 1] = "ARRAY";
|
|
81
|
+
})(ContainerType || (ContainerType = {}));
|
|
82
|
+
export const decodeFirst = (buf) => {
|
|
83
|
+
const len = buf.length;
|
|
84
|
+
const state = {
|
|
85
|
+
b: buf,
|
|
86
|
+
v: null,
|
|
87
|
+
p: 0,
|
|
88
|
+
};
|
|
89
|
+
let stack = null;
|
|
90
|
+
let result;
|
|
91
|
+
jump: while (state.p < len) {
|
|
92
|
+
const prelude = readUint8(state);
|
|
93
|
+
const type = prelude >> 5;
|
|
94
|
+
const info = prelude & 0x1f;
|
|
95
|
+
const arg = type < 7 ? readArgument(state, info) : 0;
|
|
96
|
+
let value;
|
|
97
|
+
switch (type) {
|
|
98
|
+
case 0: {
|
|
99
|
+
value = arg;
|
|
100
|
+
break;
|
|
98
101
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
102
|
+
case 1: {
|
|
103
|
+
value = -1 - arg;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
case 2: {
|
|
107
|
+
value = readBytes(state, arg);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case 3: {
|
|
111
|
+
value = readString(state, arg);
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
case 4: {
|
|
115
|
+
const arr = new Array(arg);
|
|
116
|
+
value = arr;
|
|
117
|
+
if (arg > 0) {
|
|
118
|
+
stack = { t: ContainerType.ARRAY, c: arr, k: null, r: arg, n: stack };
|
|
119
|
+
continue jump;
|
|
107
120
|
}
|
|
108
|
-
|
|
109
|
-
const key = readString(state, len);
|
|
110
|
-
if (key === '__proto__')
|
|
111
|
-
// Guard against prototype pollution. CWE-1321
|
|
112
|
-
Object.defineProperty(object, key, { enumerable: true, configurable: true, writable: true });
|
|
113
|
-
object[key] = readValue(state);
|
|
121
|
+
break;
|
|
114
122
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
123
|
+
case 5: {
|
|
124
|
+
const obj = {};
|
|
125
|
+
value = obj;
|
|
126
|
+
if (arg > 0) {
|
|
127
|
+
// `arg * 2` because we're reading both keys and values
|
|
128
|
+
stack = { t: ContainerType.MAP, c: obj, k: null, r: arg * 2, n: stack };
|
|
129
|
+
continue jump;
|
|
122
130
|
}
|
|
123
|
-
|
|
124
|
-
return readCid(state, len);
|
|
131
|
+
break;
|
|
125
132
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
+
case 6: {
|
|
134
|
+
switch (arg) {
|
|
135
|
+
case 42: {
|
|
136
|
+
const [type, info] = readTypeInfo(state);
|
|
137
|
+
if (type !== 2) {
|
|
138
|
+
throw new TypeError(`expected cid-link to be type 2 (bytes); got type ${type}`);
|
|
139
|
+
}
|
|
140
|
+
const len = readArgument(state, info);
|
|
141
|
+
value = readCid(state, len);
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
default: {
|
|
145
|
+
throw new TypeError(`unsupported tag; got ${arg}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
case 7: {
|
|
151
|
+
switch (info) {
|
|
152
|
+
case 20:
|
|
153
|
+
case 21: {
|
|
154
|
+
value = info === 21;
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
case 22: {
|
|
158
|
+
value = null;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
case 27: {
|
|
162
|
+
value = readFloat64(state);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
default: {
|
|
166
|
+
throw new Error(`invalid simple value; got ${info}`);
|
|
167
|
+
}
|
|
133
168
|
}
|
|
134
|
-
|
|
135
|
-
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
default: {
|
|
172
|
+
throw new TypeError(`invalid type; got ${type}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
while (stack !== null) {
|
|
176
|
+
const node = stack;
|
|
177
|
+
switch (node.t) {
|
|
178
|
+
case ContainerType.ARRAY: {
|
|
179
|
+
const index = node.c.length - node.r;
|
|
180
|
+
node.c[index] = value;
|
|
181
|
+
break;
|
|
136
182
|
}
|
|
137
|
-
case
|
|
138
|
-
|
|
183
|
+
case ContainerType.MAP: {
|
|
184
|
+
if (node.k === null) {
|
|
185
|
+
if (typeof value !== 'string') {
|
|
186
|
+
throw new TypeError(`expected map to only have string keys; got ${type}`);
|
|
187
|
+
}
|
|
188
|
+
node.k = value;
|
|
189
|
+
}
|
|
190
|
+
else if (node.k !== '__proto__') {
|
|
191
|
+
node.c[node.k] = value;
|
|
192
|
+
node.k = null;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
// Guard against prototype pollution. CWE-1321
|
|
196
|
+
Object.defineProperty(node.c, node.k, { enumerable: true, configurable: true, writable: true });
|
|
197
|
+
node.k = null;
|
|
198
|
+
}
|
|
199
|
+
break;
|
|
139
200
|
}
|
|
140
201
|
}
|
|
141
|
-
|
|
202
|
+
if (--node.r !== 0) {
|
|
203
|
+
// We still have more values to decode, continue
|
|
204
|
+
continue jump;
|
|
205
|
+
}
|
|
206
|
+
// Unwrap the stack
|
|
207
|
+
value = node.c;
|
|
208
|
+
stack = node.n;
|
|
142
209
|
}
|
|
210
|
+
result = value;
|
|
211
|
+
break;
|
|
143
212
|
}
|
|
144
|
-
|
|
145
|
-
};
|
|
146
|
-
export const decodeFirst = (buf) => {
|
|
147
|
-
const state = {
|
|
148
|
-
b: buf,
|
|
149
|
-
v: new DataView(buf.buffer, buf.byteOffset, buf.byteLength),
|
|
150
|
-
p: 0,
|
|
151
|
-
};
|
|
152
|
-
const value = readValue(state);
|
|
153
|
-
const remainder = buf.subarray(state.p);
|
|
154
|
-
return [value, remainder];
|
|
213
|
+
return [result, buf.subarray(state.p)];
|
|
155
214
|
};
|
|
156
215
|
export const decode = (buf) => {
|
|
157
216
|
const [value, remainder] = decodeFirst(buf);
|
package/dist/decode.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decode.js","sourceRoot":"","sources":["../lib/decode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAgB,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,OAAO,EAAc,MAAM,YAAY,CAAC;AAQjD,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,IAAY,EAAU,EAAE;IAC3D,IAAI,IAAI,GAAG,EAAE,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACb,CAAC;IAED,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,EAAE,CAAC,CAAC,CAAC;YACT,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;QACD,KAAK,EAAE,CAAC,CAAC,CAAC;YACT,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QACD,KAAK,EAAE,CAAC,CAAC,CAAC;YACT,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QACD,KAAK,EAAE,CAAC,CAAC,CAAC;YACT,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;IACF,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,KAAY,EAAU,EAAE;IAC5C,MAAM,
|
|
1
|
+
{"version":3,"file":"decode.js","sourceRoot":"","sources":["../lib/decode.ts"],"names":[],"mappings":"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"}
|
package/lib/decode.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { toBytes, type Bytes } from './bytes.js';
|
|
|
5
5
|
|
|
6
6
|
interface State {
|
|
7
7
|
b: Uint8Array;
|
|
8
|
-
v: DataView;
|
|
8
|
+
v: DataView | null;
|
|
9
9
|
p: number;
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -33,7 +33,8 @@ const readArgument = (state: State, info: number): number => {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
const readFloat64 = (state: State): number => {
|
|
36
|
-
const
|
|
36
|
+
const view = (state.v ??= new DataView(state.b.buffer, state.b.byteOffset, state.b.byteLength));
|
|
37
|
+
const value = view.getFloat64(state.p);
|
|
37
38
|
|
|
38
39
|
state.p += 8;
|
|
39
40
|
return value;
|
|
@@ -106,101 +107,180 @@ const readCid = (state: State, length: number): CidLink => {
|
|
|
106
107
|
return new CidLinkWrapper(slice);
|
|
107
108
|
};
|
|
108
109
|
|
|
109
|
-
const
|
|
110
|
-
|
|
110
|
+
const enum ContainerType {
|
|
111
|
+
MAP,
|
|
112
|
+
ARRAY,
|
|
113
|
+
}
|
|
111
114
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
+
type Container =
|
|
116
|
+
| {
|
|
117
|
+
t: ContainerType.MAP;
|
|
118
|
+
c: Record<string, unknown>;
|
|
119
|
+
k: string | null;
|
|
120
|
+
r: number;
|
|
121
|
+
n: Container | null;
|
|
122
|
+
}
|
|
123
|
+
| {
|
|
124
|
+
t: ContainerType.ARRAY;
|
|
125
|
+
c: any[];
|
|
126
|
+
k: null;
|
|
127
|
+
r: number;
|
|
128
|
+
n: Container | null;
|
|
129
|
+
};
|
|
115
130
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return arg;
|
|
119
|
-
}
|
|
120
|
-
case 1: {
|
|
121
|
-
return -1 - arg;
|
|
122
|
-
}
|
|
123
|
-
case 2: {
|
|
124
|
-
return readBytes(state, arg);
|
|
125
|
-
}
|
|
126
|
-
case 3: {
|
|
127
|
-
return readString(state, arg);
|
|
128
|
-
}
|
|
129
|
-
case 4: {
|
|
130
|
-
const array = new Array(arg);
|
|
131
|
+
export const decodeFirst = (buf: Uint8Array): [value: any, remainder: Uint8Array] => {
|
|
132
|
+
const len = buf.length;
|
|
131
133
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
const state: State = {
|
|
135
|
+
b: buf,
|
|
136
|
+
v: null,
|
|
137
|
+
p: 0,
|
|
138
|
+
};
|
|
135
139
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
case 5: {
|
|
139
|
-
const object: Record<string, unknown> = {};
|
|
140
|
+
let stack: Container | null = null;
|
|
141
|
+
let result: any;
|
|
140
142
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (type !== 3) {
|
|
144
|
-
throw new TypeError(`expected map to only have string keys; got type ${type}`);
|
|
145
|
-
}
|
|
143
|
+
jump: while (state.p < len) {
|
|
144
|
+
const prelude = readUint8(state);
|
|
146
145
|
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
const type = prelude >> 5;
|
|
147
|
+
const info = prelude & 0x1f;
|
|
148
|
+
const arg = type < 7 ? readArgument(state, info) : 0;
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
// Guard against prototype pollution. CWE-1321
|
|
152
|
-
Object.defineProperty(object, key, { enumerable: true, configurable: true, writable: true });
|
|
150
|
+
let value: any;
|
|
153
151
|
|
|
154
|
-
|
|
152
|
+
switch (type) {
|
|
153
|
+
case 0: {
|
|
154
|
+
value = arg;
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
case 1: {
|
|
158
|
+
value = -1 - arg;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
case 2: {
|
|
162
|
+
value = readBytes(state, arg);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
case 3: {
|
|
166
|
+
value = readString(state, arg);
|
|
167
|
+
break;
|
|
155
168
|
}
|
|
169
|
+
case 4: {
|
|
170
|
+
const arr = new Array(arg);
|
|
171
|
+
value = arr;
|
|
156
172
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
if (arg === 42) {
|
|
161
|
-
const [type, info] = readTypeInfo(state);
|
|
162
|
-
if (type !== 2) {
|
|
163
|
-
throw new TypeError(`expected cid-link to be type 2 (bytes); got type ${type}`);
|
|
173
|
+
if (arg > 0) {
|
|
174
|
+
stack = { t: ContainerType.ARRAY, c: arr, k: null, r: arg, n: stack };
|
|
175
|
+
continue jump;
|
|
164
176
|
}
|
|
165
177
|
|
|
166
|
-
|
|
167
|
-
return readCid(state, len);
|
|
178
|
+
break;
|
|
168
179
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
180
|
+
case 5: {
|
|
181
|
+
const obj: Record<string, unknown> = {};
|
|
182
|
+
value = obj;
|
|
183
|
+
|
|
184
|
+
if (arg > 0) {
|
|
185
|
+
// `arg * 2` because we're reading both keys and values
|
|
186
|
+
stack = { t: ContainerType.MAP, c: obj, k: null, r: arg * 2, n: stack };
|
|
187
|
+
continue jump;
|
|
177
188
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
189
|
+
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
case 6: {
|
|
193
|
+
switch (arg) {
|
|
194
|
+
case 42: {
|
|
195
|
+
const [type, info] = readTypeInfo(state);
|
|
196
|
+
if (type !== 2) {
|
|
197
|
+
throw new TypeError(`expected cid-link to be type 2 (bytes); got type ${type}`);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const len = readArgument(state, info);
|
|
201
|
+
value = readCid(state, len);
|
|
202
|
+
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
default: {
|
|
206
|
+
throw new TypeError(`unsupported tag; got ${arg}`);
|
|
207
|
+
}
|
|
183
208
|
}
|
|
209
|
+
|
|
210
|
+
break;
|
|
184
211
|
}
|
|
212
|
+
case 7: {
|
|
213
|
+
switch (info) {
|
|
214
|
+
case 20:
|
|
215
|
+
case 21: {
|
|
216
|
+
value = info === 21;
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
case 22: {
|
|
220
|
+
value = null;
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
case 27: {
|
|
224
|
+
value = readFloat64(state);
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
default: {
|
|
228
|
+
throw new Error(`invalid simple value; got ${info}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
185
231
|
|
|
186
|
-
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
default: {
|
|
235
|
+
throw new TypeError(`invalid type; got ${type}`);
|
|
236
|
+
}
|
|
187
237
|
}
|
|
188
|
-
}
|
|
189
238
|
|
|
190
|
-
|
|
191
|
-
|
|
239
|
+
while (stack !== null) {
|
|
240
|
+
const node = stack;
|
|
192
241
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
242
|
+
switch (node.t) {
|
|
243
|
+
case ContainerType.ARRAY: {
|
|
244
|
+
const index = node.c.length - node.r;
|
|
245
|
+
node.c[index] = value;
|
|
246
|
+
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
case ContainerType.MAP: {
|
|
250
|
+
if (node.k === null) {
|
|
251
|
+
if (typeof value !== 'string') {
|
|
252
|
+
throw new TypeError(`expected map to only have string keys; got ${type}`);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
node.k = value;
|
|
256
|
+
} else if (node.k !== '__proto__') {
|
|
257
|
+
node.c[node.k] = value;
|
|
258
|
+
node.k = null;
|
|
259
|
+
} else {
|
|
260
|
+
// Guard against prototype pollution. CWE-1321
|
|
261
|
+
Object.defineProperty(node.c, node.k, { enumerable: true, configurable: true, writable: true });
|
|
262
|
+
node.k = null;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
199
268
|
|
|
200
|
-
|
|
201
|
-
|
|
269
|
+
if (--node.r !== 0) {
|
|
270
|
+
// We still have more values to decode, continue
|
|
271
|
+
continue jump;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Unwrap the stack
|
|
275
|
+
value = node.c;
|
|
276
|
+
stack = node.n;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
result = value;
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
202
282
|
|
|
203
|
-
return [
|
|
283
|
+
return [result, buf.subarray(state.p)];
|
|
204
284
|
};
|
|
205
285
|
|
|
206
286
|
export const decode = (buf: Uint8Array): any => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@atcute/cbor",
|
|
4
|
-
"version": "2.1.
|
|
4
|
+
"version": "2.1.2",
|
|
5
5
|
"description": "lightweight DASL dCBOR42 codec library for AT Protocol",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"atproto",
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
"sideEffects": false,
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@ipld/dag-cbor": "^9.2.2",
|
|
28
|
-
"@types/bun": "^1.1
|
|
28
|
+
"@types/bun": "^1.2.1",
|
|
29
29
|
"cbor-x": "^1.6.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@atcute/cid": "^2.1.0",
|
|
33
|
-
"@atcute/
|
|
34
|
-
"@atcute/
|
|
33
|
+
"@atcute/multibase": "^1.1.2",
|
|
34
|
+
"@atcute/uint8array": "^1.0.1"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "rm -rf dist; tsc --project tsconfig.build.json",
|