@atproto/lex-cbor 0.0.16 → 0.1.0-next.0

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 CHANGED
@@ -1,5 +1,24 @@
1
1
  # @atproto/lex-cbor
2
2
 
3
+ ## 0.1.0-next.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#4929](https://github.com/bluesky-social/atproto/pull/4929) [`bb7491c`](https://github.com/bluesky-social/atproto/commit/bb7491c29e06181e1d2f8cf6eb454f9bb8ab961b) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Drop support for Node.js 18 and 20. Node.js 22 is now the minimum supported version. Docker images now use Node.js 24.
8
+
9
+ - [#4943](https://github.com/bluesky-social/atproto/pull/4943) [`07ae5d4`](https://github.com/bluesky-social/atproto/commit/07ae5d4452df51e045e0239da7a04cf0bc154028) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Convert to pure ESM. All packages now ship `"type": "module"` with ES module output and Node16 module resolution.
10
+
11
+ Node.js 22's `require()` compatibility layer can still load these packages in CommonJS code.
12
+
13
+ - [#4930](https://github.com/bluesky-social/atproto/pull/4930) [`042df15`](https://github.com/bluesky-social/atproto/commit/042df15087c0e62cd1e715fcbf58852fab875af9) Thanks [@devinivy](https://github.com/devinivy)! - Build with TypeScript 6.0. Emitted `.d.ts` files now use TypeScript 6's stricter `Uint8Array<ArrayBuffer>` typing in places where Web/Node APIs require buffer-backed (not shared-memory) byte arrays. Consumers compiling against these types on older TypeScript should see no runtime impact, but may need to widen or cast in spots that previously relied on `Uint8Array` defaulting to `<ArrayBufferLike>`.
14
+
15
+ Internal: tsconfig `moduleResolution: "node"` is silenced via `ignoreDeprecations: "6.0"` for now; the proper migration to `node16`/`bundler` resolution is deferred.
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [[`bb7491c`](https://github.com/bluesky-social/atproto/commit/bb7491c29e06181e1d2f8cf6eb454f9bb8ab961b), [`07ae5d4`](https://github.com/bluesky-social/atproto/commit/07ae5d4452df51e045e0239da7a04cf0bc154028), [`042df15`](https://github.com/bluesky-social/atproto/commit/042df15087c0e62cd1e715fcbf58852fab875af9)]:
20
+ - @atproto/lex-data@0.1.0-next.0
21
+
3
22
  ## 0.0.16
4
23
 
5
24
  ### Patch Changes
@@ -9,12 +9,12 @@ import { LexValue } from '@atproto/lex-data';
9
9
  * - `undefined` values are not permitted (undefined object properties will be stripped)
10
10
  * - Only safe integer numbers are allowed (no floats or non-integer values)
11
11
  */
12
- export declare const encodeOptions: Readonly<import("cborg/interface").EncodeOptions>;
12
+ export declare const encodeOptions: any;
13
13
  /**
14
14
  * Configuration options for CBOR decoding that enforces AT Protocol data model
15
15
  * constraints.
16
16
  */
17
- export declare const decodeOptions: Readonly<import("cborg/interface").DecodeOptions>;
17
+ export declare const decodeOptions: any;
18
18
  /**
19
19
  * Encodes a LexValue to CBOR bytes using the AT Protocol data model (DRISL format).
20
20
  *
@@ -1 +1 @@
1
- {"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../src/encoding.ts"],"names":[],"mappings":"AAWA,OAAO,EAAO,QAAQ,EAAoB,MAAM,mBAAmB,CAAA;AASnE;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,mDAsCxB,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,mDAoBxB,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,UAAU,CAEzE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,EAAE,KAAK,EAAE,UAAU,GAAG,CAAC,CAE1E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAiB,SAAS,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,EACtD,IAAI,EAAE,UAAU,GACf,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAM7B"}
1
+ {"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../src/encoding.ts"],"names":[],"mappings":"AAWA,OAAO,EAAO,QAAQ,EAAoB,MAAM,mBAAmB,CAAA;AASnE;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,KAsCxB,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,KAoBxB,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,UAAU,CAEzE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,EAAE,KAAK,EAAE,UAAU,GAAG,CAAC,CAE1E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAiB,SAAS,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,EACtD,IAAI,EAAE,UAAU,GACf,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAM7B"}
@@ -0,0 +1,167 @@
1
+ import { Token, Type, decode as cborgDecode, decodeFirst as cborgDecodeFirst, encode as cborgEncode, } from 'cborg';
2
+ import { decodeCid, ifCid } from '@atproto/lex-data';
3
+ // @NOTE "cborg" version 4 is required to support multi-decoding via the
4
+ // "decodeFirst" function. However, that version only exposes ES modules.
5
+ // Because this package is using "commonjs", "cborg" will be bundled instead of
6
+ // depending on it directly.
7
+ const CID_CBOR_TAG = 42;
8
+ /**
9
+ * Configuration options for CBOR encoding that enforces AT Protocol data model
10
+ * constraints.
11
+ *
12
+ * This configuration ensures:
13
+ * - CIDs are encoded using CBOR tag 42 with a leading 0x00 byte prefix
14
+ * - Map keys must be strings (no numeric or other key types allowed)
15
+ * - `undefined` values are not permitted (undefined object properties will be stripped)
16
+ * - Only safe integer numbers are allowed (no floats or non-integer values)
17
+ */
18
+ export const encodeOptions = Object.freeze({
19
+ float64: true,
20
+ ignoreUndefinedProperties: true,
21
+ typeEncoders: Object.freeze({
22
+ Map: (map) => {
23
+ for (const key of map.keys()) {
24
+ if (typeof key !== 'string') {
25
+ throw new Error('Only string keys are allowed in CBOR "map" by the AT Data Model');
26
+ }
27
+ }
28
+ // @NOTE Maps will be encoded as CBOR "map", which will be decoded as object.
29
+ return null;
30
+ },
31
+ Object: (obj) => {
32
+ const cid = ifCid(obj);
33
+ if (cid) {
34
+ const bytes = new Uint8Array(cid.bytes.byteLength + 1);
35
+ bytes.set(cid.bytes, 1); // prefix is 0x00, for historical reasons
36
+ return [new Token(Type.tag, CID_CBOR_TAG), new Token(Type.bytes, bytes)];
37
+ }
38
+ // Fallback to default object encoder
39
+ return null;
40
+ },
41
+ undefined: () => {
42
+ throw new Error('`undefined` is not supported by the AT Data Model');
43
+ },
44
+ number: (num) => {
45
+ if (Number.isSafeInteger(num))
46
+ return null;
47
+ throw new Error(`Non-integer numbers (${num}) are not supported by the AT Data Model`);
48
+ },
49
+ }),
50
+ });
51
+ /**
52
+ * Configuration options for CBOR decoding that enforces AT Protocol data model
53
+ * constraints.
54
+ */
55
+ export const decodeOptions = /*#__PURE__*/ Object.freeze({
56
+ allowIndefinite: false,
57
+ coerceUndefinedToNull: true,
58
+ allowNaN: false,
59
+ allowInfinity: false,
60
+ allowBigInt: true,
61
+ strict: true,
62
+ useMaps: false,
63
+ rejectDuplicateMapKeys: true,
64
+ tags: /*#__PURE__*/ Object.freeze(
65
+ /*#__PURE__*/ Object.assign([], {
66
+ [CID_CBOR_TAG]: (bytes) => {
67
+ if (bytes[0] !== 0) {
68
+ throw new Error('Invalid CID for CBOR tag 42; expected leading 0x00');
69
+ }
70
+ const cibBytes = bytes.subarray(1); // ignore leading 0x00
71
+ return decodeCid(cibBytes);
72
+ },
73
+ })),
74
+ });
75
+ /**
76
+ * Encodes a LexValue to CBOR bytes using the AT Protocol data model (DRISL format).
77
+ *
78
+ * @param data - The LexValue to encode
79
+ * @returns The CBOR-encoded bytes
80
+ * @throws {Error} If the data contains non-string map keys, undefined values, or non-integer numbers
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * import { encode } from '@atproto/lex-cbor'
85
+ *
86
+ * // Encode a simple object
87
+ * const bytes = encode({ text: 'Hello', count: 42 })
88
+ *
89
+ * // Encode an AT Protocol record
90
+ * const recordBytes = encode({
91
+ * $type: 'app.bsky.feed.post',
92
+ * text: 'Hello from AT Protocol!',
93
+ * createdAt: new Date().toISOString(),
94
+ * })
95
+ * ```
96
+ */
97
+ export function encode(data) {
98
+ return cborgEncode(data, encodeOptions);
99
+ }
100
+ /**
101
+ * Decodes CBOR bytes to a LexValue using the AT Protocol data model (DRISL format).
102
+ *
103
+ * @typeParam T - Allows casting the decoded values to a specific LexValue subtype
104
+ * @param bytes - The CBOR bytes to decode
105
+ * @returns The decoded LexValue
106
+ * @throws {Error} If the bytes are not valid CBOR or violate AT Protocol constraints
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * import { encode, decode } from '@atproto/lex-cbor'
111
+ * import type { LexValue } from '@atproto/lex'
112
+ *
113
+ * // Round-trip encoding and decoding
114
+ * const original = { text: 'Hello', count: 42 }
115
+ * const bytes = encode(original)
116
+ * const decoded: LexValue = decode(bytes)
117
+ *
118
+ * // Decode with a specific type
119
+ * interface Post {
120
+ * $type: string
121
+ * text: string
122
+ * createdAt: string
123
+ * }
124
+ * const post = decode<Post>(recordBytes)
125
+ * ```
126
+ */
127
+ export function decode(bytes) {
128
+ return cborgDecode(bytes, decodeOptions);
129
+ }
130
+ /**
131
+ * Generator that yields multiple decoded LexValues from a buffer containing
132
+ * concatenated CBOR-encoded values.
133
+ *
134
+ * This is useful for processing streams or files containing multiple
135
+ * CBOR-encoded records back-to-back (e.g., CAR file blocks or event streams).
136
+ *
137
+ * @typeParam T - Allows casting the decoded values to a specific LexValue subtype
138
+ * @param data - The buffer containing one or more CBOR-encoded values
139
+ * @yields Decoded LexValues one at a time
140
+ * @throws {Error} If any value in the buffer is not valid CBOR or violates AT Protocol constraints
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * import { encode, decodeAll } from '@atproto/lex-cbor'
145
+ *
146
+ * // Concatenate multiple encoded values
147
+ * const bytes1 = encode({ id: 1, text: 'First' })
148
+ * const bytes2 = encode({ id: 2, text: 'Second' })
149
+ * const combined = new Uint8Array([...bytes1, ...bytes2])
150
+ *
151
+ * // Decode all values from the combined buffer
152
+ * for (const value of decodeAll(combined)) {
153
+ * console.log(value)
154
+ * }
155
+ * // Output:
156
+ * // { id: 1, text: 'First' }
157
+ * // { id: 2, text: 'Second' }
158
+ * ```
159
+ */
160
+ export function* decodeAll(data) {
161
+ do {
162
+ const [result, remainingBytes] = cborgDecodeFirst(data, decodeOptions);
163
+ yield result;
164
+ data = remainingBytes;
165
+ } while (data.byteLength > 0);
166
+ }
167
+ //# sourceMappingURL=encoding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoding.js","sourceRoot":"","sources":["../src/encoding.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DecodeOptions,\n EncodeOptions,\n TagDecoder,\n Token,\n Type,\n decode as cborgDecode,\n decodeFirst as cborgDecodeFirst,\n encode as cborgEncode,\n} from 'cborg'\nimport { OptionalTypeEncoder } from 'cborg/interface'\nimport { Cid, LexValue, decodeCid, ifCid } from '@atproto/lex-data'\n\n// @NOTE \"cborg\" version 4 is required to support multi-decoding via the\n// \"decodeFirst\" function. However, that version only exposes ES modules.\n// Because this package is using \"commonjs\", \"cborg\" will be bundled instead of\n// depending on it directly.\n\nconst CID_CBOR_TAG = 42\n\n/**\n * Configuration options for CBOR encoding that enforces AT Protocol data model\n * constraints.\n *\n * This configuration ensures:\n * - CIDs are encoded using CBOR tag 42 with a leading 0x00 byte prefix\n * - Map keys must be strings (no numeric or other key types allowed)\n * - `undefined` values are not permitted (undefined object properties will be stripped)\n * - Only safe integer numbers are allowed (no floats or non-integer values)\n */\nexport const encodeOptions = Object.freeze<EncodeOptions>({\n float64: true,\n ignoreUndefinedProperties: true,\n typeEncoders: Object.freeze<{ [typeName: string]: OptionalTypeEncoder }>({\n Map: (map: Map<unknown, unknown>): null => {\n for (const key of map.keys()) {\n if (typeof key !== 'string') {\n throw new Error(\n 'Only string keys are allowed in CBOR \"map\" by the AT Data Model',\n )\n }\n }\n\n // @NOTE Maps will be encoded as CBOR \"map\", which will be decoded as object.\n return null\n },\n Object: (obj: object): Token[] | null => {\n const cid = ifCid(obj)\n if (cid) {\n const bytes = new Uint8Array(cid.bytes.byteLength + 1)\n bytes.set(cid.bytes, 1) // prefix is 0x00, for historical reasons\n return [new Token(Type.tag, CID_CBOR_TAG), new Token(Type.bytes, bytes)]\n }\n\n // Fallback to default object encoder\n return null\n },\n undefined: (): null => {\n throw new Error('`undefined` is not supported by the AT Data Model')\n },\n number: (num: number): null => {\n if (Number.isSafeInteger(num)) return null\n\n throw new Error(\n `Non-integer numbers (${num}) are not supported by the AT Data Model`,\n )\n },\n }),\n})\n\n/**\n * Configuration options for CBOR decoding that enforces AT Protocol data model\n * constraints.\n */\nexport const decodeOptions = /*#__PURE__*/ Object.freeze<DecodeOptions>({\n allowIndefinite: false,\n coerceUndefinedToNull: true,\n allowNaN: false,\n allowInfinity: false,\n allowBigInt: true,\n strict: true,\n useMaps: false,\n rejectDuplicateMapKeys: true,\n tags: /*#__PURE__*/ Object.freeze<TagDecoder[]>(\n /*#__PURE__*/ Object.assign([], {\n [CID_CBOR_TAG]: (bytes: Uint8Array): Cid => {\n if (bytes[0] !== 0) {\n throw new Error('Invalid CID for CBOR tag 42; expected leading 0x00')\n }\n const cibBytes = bytes.subarray(1) // ignore leading 0x00\n return decodeCid(cibBytes)\n },\n }),\n ) as TagDecoder[],\n})\n\n/**\n * Encodes a LexValue to CBOR bytes using the AT Protocol data model (DRISL format).\n *\n * @param data - The LexValue to encode\n * @returns The CBOR-encoded bytes\n * @throws {Error} If the data contains non-string map keys, undefined values, or non-integer numbers\n *\n * @example\n * ```typescript\n * import { encode } from '@atproto/lex-cbor'\n *\n * // Encode a simple object\n * const bytes = encode({ text: 'Hello', count: 42 })\n *\n * // Encode an AT Protocol record\n * const recordBytes = encode({\n * $type: 'app.bsky.feed.post',\n * text: 'Hello from AT Protocol!',\n * createdAt: new Date().toISOString(),\n * })\n * ```\n */\nexport function encode<T extends LexValue = LexValue>(data: T): Uint8Array {\n return cborgEncode(data, encodeOptions)\n}\n\n/**\n * Decodes CBOR bytes to a LexValue using the AT Protocol data model (DRISL format).\n *\n * @typeParam T - Allows casting the decoded values to a specific LexValue subtype\n * @param bytes - The CBOR bytes to decode\n * @returns The decoded LexValue\n * @throws {Error} If the bytes are not valid CBOR or violate AT Protocol constraints\n *\n * @example\n * ```typescript\n * import { encode, decode } from '@atproto/lex-cbor'\n * import type { LexValue } from '@atproto/lex'\n *\n * // Round-trip encoding and decoding\n * const original = { text: 'Hello', count: 42 }\n * const bytes = encode(original)\n * const decoded: LexValue = decode(bytes)\n *\n * // Decode with a specific type\n * interface Post {\n * $type: string\n * text: string\n * createdAt: string\n * }\n * const post = decode<Post>(recordBytes)\n * ```\n */\nexport function decode<T extends LexValue = LexValue>(bytes: Uint8Array): T {\n return cborgDecode(bytes, decodeOptions)\n}\n\n/**\n * Generator that yields multiple decoded LexValues from a buffer containing\n * concatenated CBOR-encoded values.\n *\n * This is useful for processing streams or files containing multiple\n * CBOR-encoded records back-to-back (e.g., CAR file blocks or event streams).\n *\n * @typeParam T - Allows casting the decoded values to a specific LexValue subtype\n * @param data - The buffer containing one or more CBOR-encoded values\n * @yields Decoded LexValues one at a time\n * @throws {Error} If any value in the buffer is not valid CBOR or violates AT Protocol constraints\n *\n * @example\n * ```typescript\n * import { encode, decodeAll } from '@atproto/lex-cbor'\n *\n * // Concatenate multiple encoded values\n * const bytes1 = encode({ id: 1, text: 'First' })\n * const bytes2 = encode({ id: 2, text: 'Second' })\n * const combined = new Uint8Array([...bytes1, ...bytes2])\n *\n * // Decode all values from the combined buffer\n * for (const value of decodeAll(combined)) {\n * console.log(value)\n * }\n * // Output:\n * // { id: 1, text: 'First' }\n * // { id: 2, text: 'Second' }\n * ```\n */\nexport function* decodeAll<T extends LexValue = LexValue>(\n data: Uint8Array,\n): Generator<T, void, unknown> {\n do {\n const [result, remainingBytes] = cborgDecodeFirst(data, decodeOptions)\n yield result\n data = remainingBytes\n } while (data.byteLength > 0)\n}\n"]}
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ import { cidForCbor } from '@atproto/lex-data';
2
+ import { encode } from './encoding.js';
3
+ export { decode, decodeAll, encode } from './encoding.js';
4
+ export { decode as cborDecode, decodeAll as cborDecodeAll, decodeOptions, encode as cborEncode, encodeOptions, } from './encoding.js';
5
+ /**
6
+ * Computes a CID (Content Identifier) for a given LexValue.
7
+ *
8
+ * This function first encodes the value to CBOR bytes using the AT Protocol
9
+ * data model constraints, then computes the CID hash of those bytes. The
10
+ * resulting CID can be used to uniquely identify and reference the content.
11
+ *
12
+ * @param value - The LexValue to compute a CID for
13
+ * @returns A promise that resolves to the CID for the CBOR-encoded value
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { cidForLex } from '@atproto/lex-cbor'
18
+ *
19
+ * const record = {
20
+ * $type: 'app.bsky.feed.post',
21
+ * text: 'Hello, AT Protocol!',
22
+ * createdAt: new Date().toISOString(),
23
+ * }
24
+ *
25
+ * const cid = await cidForLex(record)
26
+ * console.log(cid.toString()) // e.g., 'bafyreih...'
27
+ * ```
28
+ */
29
+ export async function cidForLex(value) {
30
+ return cidForCbor(encode(value));
31
+ }
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAKtC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAEzD,OAAO,EACL,MAAM,IAAI,UAAU,EACpB,SAAS,IAAI,aAAa,EAC1B,aAAa,EACb,MAAM,IAAI,UAAU,EACpB,aAAa,GACd,MAAM,eAAe,CAAA;AAEtB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAe;IAC7C,OAAO,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;AAClC,CAAC","sourcesContent":["import { CborCid, LexValue, cidForCbor } from '@atproto/lex-data'\nimport { encode } from './encoding.js'\n\nexport type { Cid } from '@atproto/lex-data'\nexport type { CborCid, LexValue }\n\nexport { decode, decodeAll, encode } from './encoding.js'\n\nexport {\n decode as cborDecode,\n decodeAll as cborDecodeAll,\n decodeOptions,\n encode as cborEncode,\n encodeOptions,\n} from './encoding.js'\n\n/**\n * Computes a CID (Content Identifier) for a given LexValue.\n *\n * This function first encodes the value to CBOR bytes using the AT Protocol\n * data model constraints, then computes the CID hash of those bytes. The\n * resulting CID can be used to uniquely identify and reference the content.\n *\n * @param value - The LexValue to compute a CID for\n * @returns A promise that resolves to the CID for the CBOR-encoded value\n *\n * @example\n * ```typescript\n * import { cidForLex } from '@atproto/lex-cbor'\n *\n * const record = {\n * $type: 'app.bsky.feed.post',\n * text: 'Hello, AT Protocol!',\n * createdAt: new Date().toISOString(),\n * }\n *\n * const cid = await cidForLex(record)\n * console.log(cid.toString()) // e.g., 'bafyreih...'\n * ```\n */\nexport async function cidForLex(value: LexValue): Promise<CborCid> {\n return cidForCbor(encode(value))\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "name": "@atproto/lex-cbor",
3
- "version": "0.0.16",
3
+ "version": "0.1.0-next.0",
4
+ "engines": {
5
+ "node": ">=22"
6
+ },
4
7
  "license": "MIT",
5
8
  "description": "Lexicon encoding utilities for AT Lexicon data in CBOR format",
6
9
  "keywords": [
@@ -26,31 +29,23 @@
26
29
  "./CHANGELOG.md"
27
30
  ],
28
31
  "sideEffects": false,
29
- "type": "commonjs",
30
- "main": "./dist/index.cjs",
31
- "module": "./dist/index.mjs",
32
- "types": "./dist/index.d.ts",
32
+ "type": "module",
33
33
  "exports": {
34
34
  ".": {
35
35
  "types": "./dist/index.d.ts",
36
- "browser": "./dist/index.mjs",
37
- "import": "./dist/index.mjs",
38
- "default": "./dist/index.cjs"
36
+ "default": "./dist/index.js"
39
37
  }
40
38
  },
41
39
  "dependencies": {
40
+ "cborg": "^4.5.8",
42
41
  "tslib": "^2.8.1",
43
- "@atproto/lex-data": "^0.0.15"
42
+ "@atproto/lex-data": "^0.1.0-next.0"
44
43
  },
45
44
  "devDependencies": {
46
- "cborg": "^4.5.8",
47
- "vite": "^6.2.0",
48
45
  "vitest": "^4.0.16",
49
- "@atproto/lex-json": "^0.0.15"
46
+ "@atproto/lex-json": "^0.1.0-next.0"
50
47
  },
51
48
  "scripts": {
52
- "dev": "vite build --watch",
53
- "prebuild": "vite build --emptyOutDir",
54
49
  "build": "tsc --build tsconfig.build.json",
55
50
  "test": "vitest run"
56
51
  }
package/src/encoding.ts CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  decodeFirst as cborgDecodeFirst,
9
9
  encode as cborgEncode,
10
10
  } from 'cborg'
11
- import { OptionalTypeEncoder } from 'cborg/lib/encode'
11
+ import { OptionalTypeEncoder } from 'cborg/interface'
12
12
  import { Cid, LexValue, decodeCid, ifCid } from '@atproto/lex-data'
13
13
 
14
14
  // @NOTE "cborg" version 4 is required to support multi-decoding via the
@@ -5,7 +5,6 @@
5
5
  "compilerOptions": {
6
6
  "noImplicitAny": true,
7
7
  "importHelpers": true,
8
- "emitDeclarationOnly": true,
9
8
  "rootDir": "./src",
10
9
  "outDir": "./dist"
11
10
  }