feat: 초기 프로젝트 설정 및 룰.md 파일 추가

This commit is contained in:
2025-07-28 09:53:31 +09:00
commit 09a4d38512
8165 changed files with 1021855 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Levi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,81 @@
# Tiny CBOR
[![](https://img.shields.io/github/actions/workflow/status/levischuck/tiny-cbor/build.yaml?branch=main&style=flat-square)](https://github.com/LeviSchuck/tiny-cbor/actions)
[![](https://img.shields.io/codecov/c/gh/levischuck/tiny-cbor?style=flat-square)](https://codecov.io/gh/levischuck/tiny-cbor)
[![](https://img.shields.io/github/v/tag/levischuck/tiny-cbor?label=npm&logo=npm&style=flat-square)](https://www.npmjs.com/package/@levischuck/tiny-cbor)
[![](https://img.shields.io/jsr/v/%40levischuck/tiny-cbor?style=flat-square&logo=jsr&label=JSR)](https://jsr.io/@levischuck/tiny-cbor)
[![](https://img.shields.io/github/license/levischuck/tiny-cbor?style=flat-square)](https://github.com/LeviSchuck/tiny-cbor/blob/main/LICENSE.txt)
![](https://img.shields.io/bundlephobia/min/%40levischuck/tiny-cbor?style=flat-square)
This minimal generic library decodes and encodes most useful CBOR structures
into simple JavaScript structures:
- Maps with keys as `string`s or `number`s with `CBORType` values as a `Map`
- Arrays of `CBORType` values
- integers as `number`s
- float32 and float64 as `number`s
- float16 `NaN`, `Infinity`, `-Infinity`
- `string`s
- byte strings as `Uint8Array`
- booleans
- `null` and `undefined`
- tags as `CBORTag(tag, value)`
## Limitations
This implementation does not support:
- indefinite length maps, arrays, text strings, or byte strings.
- half precision floating point numbers
- integers outside the range of `[-9007199254740991, 9007199254740991]`, see
[Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER)
- native output to JSON
- does not support generic objects, only `Map`s
This implementation has the following constraints:
- Map keys may only be strings or numbers
- Tags are not interpreted
## Behavior
Maps that have duplicate keys will throw an error during decoding. Decoding data
that is incomplete will throw an error during decoding.
## Example
```ts
// NPM
// import { decodeCBOR } from "@levischuck/tiny-cbor";
// or JSR
// import { decodeCBOR } from "jsr:@levischuck/tiny-cbor";
import { decodeCBOR } from "./index.ts";
// Get your bytes somehow, directly or with decodeBase64 / decodeHex (available through @levischuck/tiny-encodings)
const HELLO_WORLD_BYTES = new Uint8Array([
107, // String wih length 11
104, // h
101, // e
108, // l
108, // l
111, // o
32, // Space
119, // w
111, // o
114, // r
108, // l
100, // d
]);
const helloWorld = decodeCBOR(HELLO_WORLD_BYTES);
if ("hello world" == helloWorld) {
console.log("Success!");
}
```
## Where to get it
This library is available on
[NPM](https://www.npmjs.com/package/@levischuck/tiny-cbor) and
[JSR](https://jsr.io/@levischuck/tiny-cbor).
This library is no longer automatically published to Deno's Third Party Modules.
Newer versions may appear on deno.land/x, but do not work.

View File

@@ -0,0 +1,101 @@
/**
* A value which is wrapped with a CBOR Tag.
* Several tags are registered with defined meanings like 0 for a date string.
* These meanings are **not interpreted** when decoded or encoded.
*
* This class is an immutable record.
* If the tag number or value needs to change, then construct a new tag
*/
export declare class CBORTag {
private tagId;
private tagValue;
/**
* Wrap a value with a tag number.
* When encoded, this tag will be attached to the value.
*
* @param tag Tag number
* @param value Wrapped value
*/
constructor(tag: number, value: CBORType);
/**
* Read the tag number
*/
get tag(): number;
/**
* Read the value
*/
get value(): CBORType;
}
/**
* Supported types which are encodable and decodable with tiny CBOR.
* Note that plain javascript objects are omitted.
*/
export type CBORType = number | bigint | string | Uint8Array | boolean | null | undefined | CBORType[] | CBORTag | Map<string | number, CBORType>;
/**
* Like {decodeCBOR}, but the length of the data is unknown and there is likely
* more -- possibly unrelated non-CBOR -- data afterwards.
*
* Examples:
*
* ```ts
* import {decodePartialCBOR} from './cbor.ts'
* decodePartialCBOR(new Uint8Array([1, 2, 245, 3, 4]), 2)
* // returns [true, 1]
* // It did not decode the leading [1, 2] or trailing [3, 4]
* ```
*
* @param data a data stream to read data from
* @param index where to start reading in the data stream
* @returns a tuple of the value followed by bytes read.
* @throws {Error}
* When the data stream ends early or the CBOR data is not well formed
*/
export declare function decodePartialCBOR(data: DataView | Uint8Array | ArrayBuffer, index: number): [CBORType, number];
/**
* Decode CBOR data from a binary stream
*
* The entire data stream from [0, length) will be consumed.
* If you require a partial decoding, see {decodePartialCBOR}.
*
* Examples:
*
* ```ts
* import {decodeCBOR, CBORTag, CBORType} from './cbor.ts'
* decodeCBOR(new Uint8Array([162, 99, 107, 101, 121, 101, 118, 97, 108, 117, 101, 1, 109, 97, 110, 111, 116, 104, 101, 114, 32, 118, 97, 108, 117, 101]));
* // returns new Map<string | number, CBORType>([
* // ["key", "value"],
* // [1, "another value"]
* // ]);
*
* const taggedItem = new Uint8Array([217, 4, 210, 101, 104, 101, 108, 108, 111]);
* decodeCBOR(new DataView(taggedItem.buffer))
* // returns new CBORTag(1234, "hello")
* ```
*
* @param data a data stream, multiple types are supported
* @returns
*/
export declare function decodeCBOR(data: DataView | Uint8Array | ArrayBuffer): CBORType;
/**
* Encode a supported structure to a CBOR byte string.
*
* Example:
*
* ```ts
* import {encodeCBOR, CBORType, CBORTag} from './cbor.ts'
* encodeCBOR(new Map<string | number, CBORType>([
* ["key", "value"],
* [1, "another value"]
* ]));
* // returns new Uint8Array([162, 99, 107, 101, 121, 101, 118, 97, 108, 117, 101, 1, 109, 97, 110, 111, 116, 104, 101, 114, 32 118, 97, 108, 117, 101])
*
* encodeCBOR(new CBORTag(1234, "hello"))
* // returns new UInt8Array([217, 4, 210, 101, 104, 101, 108, 108, 111])
* ```
*
* @param data Data to encode
* @returns A byte string as a Uint8Array
* @throws Error
* if unsupported data is found during encoding
*/
export declare function encodeCBOR(data: CBORType): Uint8Array;

View File

@@ -0,0 +1,440 @@
import { decodeLength, encodeLength, MAJOR_TYPE_ARRAY, MAJOR_TYPE_BYTE_STRING, MAJOR_TYPE_MAP, MAJOR_TYPE_NEGATIVE_INTEGER, MAJOR_TYPE_SIMPLE_OR_FLOAT, MAJOR_TYPE_TAG, MAJOR_TYPE_TEXT_STRING, MAJOR_TYPE_UNSIGNED_INTEGER, } from "./cbor_internal.js";
/**
* A value which is wrapped with a CBOR Tag.
* Several tags are registered with defined meanings like 0 for a date string.
* These meanings are **not interpreted** when decoded or encoded.
*
* This class is an immutable record.
* If the tag number or value needs to change, then construct a new tag
*/
export class CBORTag {
/**
* Wrap a value with a tag number.
* When encoded, this tag will be attached to the value.
*
* @param tag Tag number
* @param value Wrapped value
*/
constructor(tag, value) {
Object.defineProperty(this, "tagId", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "tagValue", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.tagId = tag;
this.tagValue = value;
}
/**
* Read the tag number
*/
get tag() {
return this.tagId;
}
/**
* Read the value
*/
get value() {
return this.tagValue;
}
}
function decodeUnsignedInteger(data, argument, index) {
return decodeLength(data, argument, index);
}
function decodeNegativeInteger(data, argument, index) {
const [value, length] = decodeUnsignedInteger(data, argument, index);
return [-value - 1, length];
}
function decodeByteString(data, argument, index) {
const [lengthValue, lengthConsumed] = decodeLength(data, argument, index);
const dataStartIndex = index + lengthConsumed;
return [
new Uint8Array(data.buffer.slice(dataStartIndex, dataStartIndex + lengthValue)),
lengthConsumed + lengthValue,
];
}
const TEXT_DECODER = new TextDecoder();
function decodeString(data, argument, index) {
const [value, length] = decodeByteString(data, argument, index);
return [TEXT_DECODER.decode(value), length];
}
function decodeArray(data, argument, index) {
if (argument === 0) {
return [[], 1];
}
const [length, lengthConsumed] = decodeLength(data, argument, index);
let consumedLength = lengthConsumed;
const value = [];
for (let i = 0; i < length; i++) {
const remainingDataLength = data.byteLength - index - consumedLength;
if (remainingDataLength <= 0) {
throw new Error("array is not supported or well formed");
}
const [decodedValue, consumed] = decodeNext(data, index + consumedLength);
value.push(decodedValue);
consumedLength += consumed;
}
return [value, consumedLength];
}
const MAP_ERROR = "Map is not supported or well formed";
function decodeMap(data, argument, index) {
if (argument === 0) {
return [new Map(), 1];
}
const [length, lengthConsumed] = decodeLength(data, argument, index);
let consumedLength = lengthConsumed;
const result = new Map();
for (let i = 0; i < length; i++) {
let remainingDataLength = data.byteLength - index - consumedLength;
if (remainingDataLength <= 0) {
throw new Error(MAP_ERROR);
}
// Load key
const [key, keyConsumed] = decodeNext(data, index + consumedLength);
consumedLength += keyConsumed;
remainingDataLength -= keyConsumed;
// Check that there's enough to have a value
if (remainingDataLength <= 0) {
throw new Error(MAP_ERROR);
}
// Technically CBOR maps can have any type as the key, and so can JS Maps
// However, JS Maps can only reference such keys as references which would
// require key iteration and pattern matching.
// For simplicity, since such keys are not in use with WebAuthn, this
// capability is not implemented and the types are restricted to strings
// and numbers.
if (typeof key !== "string" && typeof key !== "number") {
throw new Error(MAP_ERROR);
}
// CBOR Maps are not well formed if there are duplicate keys
if (result.has(key)) {
throw new Error(MAP_ERROR);
}
// Load value
const [value, valueConsumed] = decodeNext(data, index + consumedLength);
consumedLength += valueConsumed;
result.set(key, value);
}
return [result, consumedLength];
}
function decodeFloat16(data, index) {
if (index + 3 > data.byteLength) {
throw new Error("CBOR stream ended before end of Float 16");
}
// Skip the first byte
const result = data.getUint16(index + 1, false);
// A minimal selection of supported values
if (result == 0x7c00) {
return [Infinity, 3];
}
else if (result == 0x7e00) {
return [NaN, 3];
}
else if (result == 0xfc00) {
return [-Infinity, 3];
}
throw new Error("Float16 data is unsupported");
}
function decodeFloat32(data, index) {
if (index + 5 > data.byteLength) {
throw new Error("CBOR stream ended before end of Float 32");
}
// Skip the first byte
const result = data.getFloat32(index + 1, false);
// First byte + 4 byte float
return [result, 5];
}
function decodeFloat64(data, index) {
if (index + 9 > data.byteLength) {
throw new Error("CBOR stream ended before end of Float 64");
}
// Skip the first byte
const result = data.getFloat64(index + 1, false);
// First byte + 8 byte float
return [result, 9];
}
function decodeTag(data, argument, index) {
const [tag, tagBytes] = decodeLength(data, argument, index);
const [value, valueBytes] = decodeNext(data, index + tagBytes);
return [new CBORTag(tag, value), tagBytes + valueBytes];
}
function decodeNext(data, index) {
if (index >= data.byteLength) {
throw new Error("CBOR stream ended before tag value");
}
const byte = data.getUint8(index);
const majorType = byte >> 5;
const argument = byte & 0x1f;
switch (majorType) {
case MAJOR_TYPE_UNSIGNED_INTEGER: {
return decodeUnsignedInteger(data, argument, index);
}
case MAJOR_TYPE_NEGATIVE_INTEGER: {
return decodeNegativeInteger(data, argument, index);
}
case MAJOR_TYPE_BYTE_STRING: {
return decodeByteString(data, argument, index);
}
case MAJOR_TYPE_TEXT_STRING: {
return decodeString(data, argument, index);
}
case MAJOR_TYPE_ARRAY: {
return decodeArray(data, argument, index);
}
case MAJOR_TYPE_MAP: {
return decodeMap(data, argument, index);
}
case MAJOR_TYPE_TAG: {
return decodeTag(data, argument, index);
}
case MAJOR_TYPE_SIMPLE_OR_FLOAT: {
switch (argument) {
case 20:
return [false, 1];
case 21:
return [true, 1];
case 22:
return [null, 1];
case 23:
return [undefined, 1];
// 24: Simple value (value 32..255 in following byte)
case 25: // IEEE 754 Half-Precision Float (16 bits follow)
return decodeFloat16(data, index);
case 26: // IEEE 754 Single-Precision Float (32 bits follow)
return decodeFloat32(data, index);
case 27: // IEEE 754 Double-Precision Float (64 bits follow)
return decodeFloat64(data, index);
// 28-30: Reserved, not well-formed in the present document
// 31: "break" stop code for indefinite-length items
}
}
}
throw new Error(`Unsupported or not well formed at ${index}`);
}
function encodeSimple(data) {
if (data === true) {
return 0xf5;
}
else if (data === false) {
return 0xf4;
}
else if (data === null) {
return 0xf6;
}
// Else undefined
return 0xf7;
}
function encodeFloat(data) {
if (Math.fround(data) == data || !Number.isFinite(data) || Number.isNaN(data)) {
// Float32
const output = new Uint8Array(5);
output[0] = 0xfa;
const view = new DataView(output.buffer);
view.setFloat32(1, data, false);
return output;
}
else {
// Float64
const output = new Uint8Array(9);
output[0] = 0xfb;
const view = new DataView(output.buffer);
view.setFloat64(1, data, false);
return output;
}
}
function encodeNumber(data) {
if (typeof data == "number") {
if (Number.isSafeInteger(data)) {
// Encode integer
if (data < 0) {
return encodeLength(MAJOR_TYPE_NEGATIVE_INTEGER, Math.abs(data));
}
else {
return encodeLength(MAJOR_TYPE_UNSIGNED_INTEGER, data);
}
}
return [encodeFloat(data)];
}
else {
if (data < 0n) {
return encodeLength(MAJOR_TYPE_NEGATIVE_INTEGER, data * -1n);
}
else {
return encodeLength(MAJOR_TYPE_UNSIGNED_INTEGER, data);
}
}
}
const ENCODER = new TextEncoder();
function encodeString(data, output) {
output.push(...encodeLength(MAJOR_TYPE_TEXT_STRING, data.length));
output.push(ENCODER.encode(data));
}
function encodeBytes(data, output) {
output.push(...encodeLength(MAJOR_TYPE_BYTE_STRING, data.length));
output.push(data);
}
function encodeArray(data, output) {
output.push(...encodeLength(MAJOR_TYPE_ARRAY, data.length));
for (const element of data) {
encodePartialCBOR(element, output);
}
}
function encodeMap(data, output) {
output.push(new Uint8Array(encodeLength(MAJOR_TYPE_MAP, data.size)));
for (const [key, value] of data.entries()) {
encodePartialCBOR(key, output);
encodePartialCBOR(value, output);
}
}
function encodeTag(tag, output) {
output.push(...encodeLength(MAJOR_TYPE_TAG, tag.tag));
encodePartialCBOR(tag.value, output);
}
function encodePartialCBOR(data, output) {
if (typeof data == "boolean" || data === null || data == undefined) {
output.push(encodeSimple(data));
return;
}
if (typeof data == "number" || typeof data == "bigint") {
output.push(...encodeNumber(data));
return;
}
if (typeof data == "string") {
encodeString(data, output);
return;
}
if (data instanceof Uint8Array) {
encodeBytes(data, output);
return;
}
if (Array.isArray(data)) {
encodeArray(data, output);
return;
}
if (data instanceof Map) {
encodeMap(data, output);
return;
}
if (data instanceof CBORTag) {
encodeTag(data, output);
return;
}
throw new Error("Not implemented");
}
/**
* Like {decodeCBOR}, but the length of the data is unknown and there is likely
* more -- possibly unrelated non-CBOR -- data afterwards.
*
* Examples:
*
* ```ts
* import {decodePartialCBOR} from './cbor.ts'
* decodePartialCBOR(new Uint8Array([1, 2, 245, 3, 4]), 2)
* // returns [true, 1]
* // It did not decode the leading [1, 2] or trailing [3, 4]
* ```
*
* @param data a data stream to read data from
* @param index where to start reading in the data stream
* @returns a tuple of the value followed by bytes read.
* @throws {Error}
* When the data stream ends early or the CBOR data is not well formed
*/
export function decodePartialCBOR(data, index) {
if (data.byteLength === 0 || data.byteLength <= index || index < 0) {
throw new Error("No data");
}
if (data instanceof Uint8Array) {
return decodeNext(new DataView(data.buffer), index);
}
else if (data instanceof ArrayBuffer) {
return decodeNext(new DataView(data), index);
}
// otherwise, it is a data view
return decodeNext(data, index);
}
/**
* Decode CBOR data from a binary stream
*
* The entire data stream from [0, length) will be consumed.
* If you require a partial decoding, see {decodePartialCBOR}.
*
* Examples:
*
* ```ts
* import {decodeCBOR, CBORTag, CBORType} from './cbor.ts'
* decodeCBOR(new Uint8Array([162, 99, 107, 101, 121, 101, 118, 97, 108, 117, 101, 1, 109, 97, 110, 111, 116, 104, 101, 114, 32, 118, 97, 108, 117, 101]));
* // returns new Map<string | number, CBORType>([
* // ["key", "value"],
* // [1, "another value"]
* // ]);
*
* const taggedItem = new Uint8Array([217, 4, 210, 101, 104, 101, 108, 108, 111]);
* decodeCBOR(new DataView(taggedItem.buffer))
* // returns new CBORTag(1234, "hello")
* ```
*
* @param data a data stream, multiple types are supported
* @returns
*/
export function decodeCBOR(data) {
const [value, length] = decodePartialCBOR(data, 0);
if (length !== data.byteLength) {
throw new Error(`Data was decoded, but the whole stream was not processed ${length} != ${data.byteLength}`);
}
return value;
}
/**
* Encode a supported structure to a CBOR byte string.
*
* Example:
*
* ```ts
* import {encodeCBOR, CBORType, CBORTag} from './cbor.ts'
* encodeCBOR(new Map<string | number, CBORType>([
* ["key", "value"],
* [1, "another value"]
* ]));
* // returns new Uint8Array([162, 99, 107, 101, 121, 101, 118, 97, 108, 117, 101, 1, 109, 97, 110, 111, 116, 104, 101, 114, 32 118, 97, 108, 117, 101])
*
* encodeCBOR(new CBORTag(1234, "hello"))
* // returns new UInt8Array([217, 4, 210, 101, 104, 101, 108, 108, 111])
* ```
*
* @param data Data to encode
* @returns A byte string as a Uint8Array
* @throws Error
* if unsupported data is found during encoding
*/
export function encodeCBOR(data) {
const results = [];
encodePartialCBOR(data, results);
let length = 0;
for (const result of results) {
if (typeof result == "number") {
length += 1;
}
else {
length += result.length;
}
}
const output = new Uint8Array(length);
let index = 0;
for (const result of results) {
if (typeof result == "number") {
output[index] = result;
index += 1;
}
else {
output.set(result, index);
index += result.length;
}
}
return output;
}

View File

@@ -0,0 +1,11 @@
export declare function decodeLength(data: DataView, argument: number, index: number): [number, number];
export type MajorType = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
export declare const MAJOR_TYPE_UNSIGNED_INTEGER: MajorType;
export declare const MAJOR_TYPE_NEGATIVE_INTEGER: MajorType;
export declare const MAJOR_TYPE_BYTE_STRING: MajorType;
export declare const MAJOR_TYPE_TEXT_STRING: MajorType;
export declare const MAJOR_TYPE_ARRAY: MajorType;
export declare const MAJOR_TYPE_MAP: MajorType;
export declare const MAJOR_TYPE_TAG: MajorType;
export declare const MAJOR_TYPE_SIMPLE_OR_FLOAT: MajorType;
export declare function encodeLength(major: MajorType, argument: number | bigint): number[];

View File

@@ -0,0 +1,111 @@
export function decodeLength(data, argument, index) {
if (argument < 24) {
return [argument, 1];
}
const remainingDataLength = data.byteLength - index - 1;
const view = new DataView(data.buffer, index + 1);
let output;
let bytes = 0;
switch (argument) {
case 24: {
if (remainingDataLength > 0) {
output = view.getUint8(0);
bytes = 2;
}
break;
}
case 25: {
if (remainingDataLength > 1) {
output = view.getUint16(0, false);
bytes = 3;
}
break;
}
case 26: {
if (remainingDataLength > 3) {
output = view.getUint32(0, false);
bytes = 5;
}
break;
}
case 27: {
if (remainingDataLength > 7) {
const bigOutput = view.getBigUint64(0, false);
// Bound it to [24, MAX_SAFE_INTEGER], where it is safe
// to encode as a javascript number
if (bigOutput >= 24n && bigOutput <= Number.MAX_SAFE_INTEGER) {
return [Number(bigOutput), 9];
}
}
break;
}
}
if (output && output >= 24) {
return [output, bytes];
}
throw new Error("Length not supported or not well formed");
}
export const MAJOR_TYPE_UNSIGNED_INTEGER = 0;
export const MAJOR_TYPE_NEGATIVE_INTEGER = 1;
export const MAJOR_TYPE_BYTE_STRING = 2;
export const MAJOR_TYPE_TEXT_STRING = 3;
export const MAJOR_TYPE_ARRAY = 4;
export const MAJOR_TYPE_MAP = 5;
export const MAJOR_TYPE_TAG = 6;
export const MAJOR_TYPE_SIMPLE_OR_FLOAT = 7;
export function encodeLength(major, argument) {
const majorEncoded = major << 5;
if (argument < 0) {
throw new Error("CBOR Data Item argument must not be negative");
}
// Convert to bigint first.
// Encode integers around and above 32 bits in big endian / network byte order
// is unreliable in javascript.
// https://tc39.es/ecma262/#sec-bitwise-shift-operators
// Bit shifting operations result in 32 bit signed numbers
let bigintArgument;
if (typeof argument == "number") {
if (!Number.isInteger(argument)) {
throw new Error("CBOR Data Item argument must be an integer");
}
bigintArgument = BigInt(argument);
}
else {
bigintArgument = argument;
}
// Negative 0 is not a thing
if (major == MAJOR_TYPE_NEGATIVE_INTEGER) {
if (bigintArgument == 0n) {
throw new Error("CBOR Data Item argument cannot be zero when negative");
}
bigintArgument = bigintArgument - 1n;
}
if (bigintArgument > 18446744073709551615n) {
throw new Error("CBOR number out of range");
}
// Encode into 64 bits and extract the tail
const buffer = new Uint8Array(8);
const view = new DataView(buffer.buffer);
view.setBigUint64(0, bigintArgument, false);
if (bigintArgument <= 23) {
return [majorEncoded | buffer[7]];
}
else if (bigintArgument <= 255) {
return [majorEncoded | 24, buffer[7]];
}
else if (bigintArgument <= 65535) {
return [majorEncoded | 25, ...buffer.slice(6)];
}
else if (bigintArgument <= 4294967295) {
return [
majorEncoded | 26,
...buffer.slice(4),
];
}
else {
return [
majorEncoded | 27,
...buffer,
];
}
}

View File

@@ -0,0 +1,2 @@
export { CBORTag, decodeCBOR, decodePartialCBOR, encodeCBOR, } from "./cbor/cbor.js";
export type { CBORType } from "./cbor/cbor.js";

View File

@@ -0,0 +1 @@
export { CBORTag, decodeCBOR, decodePartialCBOR, encodeCBOR, } from "./cbor/cbor.js";

View File

@@ -0,0 +1,3 @@
{
"type": "module"
}

View File

@@ -0,0 +1,25 @@
{
"name": "@levischuck/tiny-cbor",
"version": "0.2.11",
"description": "Tiny CBOR library",
"repository": {
"type": "git",
"url": "git+https://github.com/levischuck/tiny-cbor.git"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/levischuck/tiny-cbor/issues"
},
"main": "./script/index.js",
"module": "./esm/index.js",
"exports": {
".": {
"import": "./esm/index.js",
"require": "./script/index.js"
}
},
"devDependencies": {
"@types/node": "^20.9.0"
},
"_generatedBy": "dnt@0.40.0"
}

View File

@@ -0,0 +1,101 @@
/**
* A value which is wrapped with a CBOR Tag.
* Several tags are registered with defined meanings like 0 for a date string.
* These meanings are **not interpreted** when decoded or encoded.
*
* This class is an immutable record.
* If the tag number or value needs to change, then construct a new tag
*/
export declare class CBORTag {
private tagId;
private tagValue;
/**
* Wrap a value with a tag number.
* When encoded, this tag will be attached to the value.
*
* @param tag Tag number
* @param value Wrapped value
*/
constructor(tag: number, value: CBORType);
/**
* Read the tag number
*/
get tag(): number;
/**
* Read the value
*/
get value(): CBORType;
}
/**
* Supported types which are encodable and decodable with tiny CBOR.
* Note that plain javascript objects are omitted.
*/
export type CBORType = number | bigint | string | Uint8Array | boolean | null | undefined | CBORType[] | CBORTag | Map<string | number, CBORType>;
/**
* Like {decodeCBOR}, but the length of the data is unknown and there is likely
* more -- possibly unrelated non-CBOR -- data afterwards.
*
* Examples:
*
* ```ts
* import {decodePartialCBOR} from './cbor.ts'
* decodePartialCBOR(new Uint8Array([1, 2, 245, 3, 4]), 2)
* // returns [true, 1]
* // It did not decode the leading [1, 2] or trailing [3, 4]
* ```
*
* @param data a data stream to read data from
* @param index where to start reading in the data stream
* @returns a tuple of the value followed by bytes read.
* @throws {Error}
* When the data stream ends early or the CBOR data is not well formed
*/
export declare function decodePartialCBOR(data: DataView | Uint8Array | ArrayBuffer, index: number): [CBORType, number];
/**
* Decode CBOR data from a binary stream
*
* The entire data stream from [0, length) will be consumed.
* If you require a partial decoding, see {decodePartialCBOR}.
*
* Examples:
*
* ```ts
* import {decodeCBOR, CBORTag, CBORType} from './cbor.ts'
* decodeCBOR(new Uint8Array([162, 99, 107, 101, 121, 101, 118, 97, 108, 117, 101, 1, 109, 97, 110, 111, 116, 104, 101, 114, 32, 118, 97, 108, 117, 101]));
* // returns new Map<string | number, CBORType>([
* // ["key", "value"],
* // [1, "another value"]
* // ]);
*
* const taggedItem = new Uint8Array([217, 4, 210, 101, 104, 101, 108, 108, 111]);
* decodeCBOR(new DataView(taggedItem.buffer))
* // returns new CBORTag(1234, "hello")
* ```
*
* @param data a data stream, multiple types are supported
* @returns
*/
export declare function decodeCBOR(data: DataView | Uint8Array | ArrayBuffer): CBORType;
/**
* Encode a supported structure to a CBOR byte string.
*
* Example:
*
* ```ts
* import {encodeCBOR, CBORType, CBORTag} from './cbor.ts'
* encodeCBOR(new Map<string | number, CBORType>([
* ["key", "value"],
* [1, "another value"]
* ]));
* // returns new Uint8Array([162, 99, 107, 101, 121, 101, 118, 97, 108, 117, 101, 1, 109, 97, 110, 111, 116, 104, 101, 114, 32 118, 97, 108, 117, 101])
*
* encodeCBOR(new CBORTag(1234, "hello"))
* // returns new UInt8Array([217, 4, 210, 101, 104, 101, 108, 108, 111])
* ```
*
* @param data Data to encode
* @returns A byte string as a Uint8Array
* @throws Error
* if unsupported data is found during encoding
*/
export declare function encodeCBOR(data: CBORType): Uint8Array;

View File

@@ -0,0 +1,447 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodeCBOR = exports.decodeCBOR = exports.decodePartialCBOR = exports.CBORTag = void 0;
const cbor_internal_js_1 = require("./cbor_internal.js");
/**
* A value which is wrapped with a CBOR Tag.
* Several tags are registered with defined meanings like 0 for a date string.
* These meanings are **not interpreted** when decoded or encoded.
*
* This class is an immutable record.
* If the tag number or value needs to change, then construct a new tag
*/
class CBORTag {
/**
* Wrap a value with a tag number.
* When encoded, this tag will be attached to the value.
*
* @param tag Tag number
* @param value Wrapped value
*/
constructor(tag, value) {
Object.defineProperty(this, "tagId", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "tagValue", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.tagId = tag;
this.tagValue = value;
}
/**
* Read the tag number
*/
get tag() {
return this.tagId;
}
/**
* Read the value
*/
get value() {
return this.tagValue;
}
}
exports.CBORTag = CBORTag;
function decodeUnsignedInteger(data, argument, index) {
return (0, cbor_internal_js_1.decodeLength)(data, argument, index);
}
function decodeNegativeInteger(data, argument, index) {
const [value, length] = decodeUnsignedInteger(data, argument, index);
return [-value - 1, length];
}
function decodeByteString(data, argument, index) {
const [lengthValue, lengthConsumed] = (0, cbor_internal_js_1.decodeLength)(data, argument, index);
const dataStartIndex = index + lengthConsumed;
return [
new Uint8Array(data.buffer.slice(dataStartIndex, dataStartIndex + lengthValue)),
lengthConsumed + lengthValue,
];
}
const TEXT_DECODER = new TextDecoder();
function decodeString(data, argument, index) {
const [value, length] = decodeByteString(data, argument, index);
return [TEXT_DECODER.decode(value), length];
}
function decodeArray(data, argument, index) {
if (argument === 0) {
return [[], 1];
}
const [length, lengthConsumed] = (0, cbor_internal_js_1.decodeLength)(data, argument, index);
let consumedLength = lengthConsumed;
const value = [];
for (let i = 0; i < length; i++) {
const remainingDataLength = data.byteLength - index - consumedLength;
if (remainingDataLength <= 0) {
throw new Error("array is not supported or well formed");
}
const [decodedValue, consumed] = decodeNext(data, index + consumedLength);
value.push(decodedValue);
consumedLength += consumed;
}
return [value, consumedLength];
}
const MAP_ERROR = "Map is not supported or well formed";
function decodeMap(data, argument, index) {
if (argument === 0) {
return [new Map(), 1];
}
const [length, lengthConsumed] = (0, cbor_internal_js_1.decodeLength)(data, argument, index);
let consumedLength = lengthConsumed;
const result = new Map();
for (let i = 0; i < length; i++) {
let remainingDataLength = data.byteLength - index - consumedLength;
if (remainingDataLength <= 0) {
throw new Error(MAP_ERROR);
}
// Load key
const [key, keyConsumed] = decodeNext(data, index + consumedLength);
consumedLength += keyConsumed;
remainingDataLength -= keyConsumed;
// Check that there's enough to have a value
if (remainingDataLength <= 0) {
throw new Error(MAP_ERROR);
}
// Technically CBOR maps can have any type as the key, and so can JS Maps
// However, JS Maps can only reference such keys as references which would
// require key iteration and pattern matching.
// For simplicity, since such keys are not in use with WebAuthn, this
// capability is not implemented and the types are restricted to strings
// and numbers.
if (typeof key !== "string" && typeof key !== "number") {
throw new Error(MAP_ERROR);
}
// CBOR Maps are not well formed if there are duplicate keys
if (result.has(key)) {
throw new Error(MAP_ERROR);
}
// Load value
const [value, valueConsumed] = decodeNext(data, index + consumedLength);
consumedLength += valueConsumed;
result.set(key, value);
}
return [result, consumedLength];
}
function decodeFloat16(data, index) {
if (index + 3 > data.byteLength) {
throw new Error("CBOR stream ended before end of Float 16");
}
// Skip the first byte
const result = data.getUint16(index + 1, false);
// A minimal selection of supported values
if (result == 0x7c00) {
return [Infinity, 3];
}
else if (result == 0x7e00) {
return [NaN, 3];
}
else if (result == 0xfc00) {
return [-Infinity, 3];
}
throw new Error("Float16 data is unsupported");
}
function decodeFloat32(data, index) {
if (index + 5 > data.byteLength) {
throw new Error("CBOR stream ended before end of Float 32");
}
// Skip the first byte
const result = data.getFloat32(index + 1, false);
// First byte + 4 byte float
return [result, 5];
}
function decodeFloat64(data, index) {
if (index + 9 > data.byteLength) {
throw new Error("CBOR stream ended before end of Float 64");
}
// Skip the first byte
const result = data.getFloat64(index + 1, false);
// First byte + 8 byte float
return [result, 9];
}
function decodeTag(data, argument, index) {
const [tag, tagBytes] = (0, cbor_internal_js_1.decodeLength)(data, argument, index);
const [value, valueBytes] = decodeNext(data, index + tagBytes);
return [new CBORTag(tag, value), tagBytes + valueBytes];
}
function decodeNext(data, index) {
if (index >= data.byteLength) {
throw new Error("CBOR stream ended before tag value");
}
const byte = data.getUint8(index);
const majorType = byte >> 5;
const argument = byte & 0x1f;
switch (majorType) {
case cbor_internal_js_1.MAJOR_TYPE_UNSIGNED_INTEGER: {
return decodeUnsignedInteger(data, argument, index);
}
case cbor_internal_js_1.MAJOR_TYPE_NEGATIVE_INTEGER: {
return decodeNegativeInteger(data, argument, index);
}
case cbor_internal_js_1.MAJOR_TYPE_BYTE_STRING: {
return decodeByteString(data, argument, index);
}
case cbor_internal_js_1.MAJOR_TYPE_TEXT_STRING: {
return decodeString(data, argument, index);
}
case cbor_internal_js_1.MAJOR_TYPE_ARRAY: {
return decodeArray(data, argument, index);
}
case cbor_internal_js_1.MAJOR_TYPE_MAP: {
return decodeMap(data, argument, index);
}
case cbor_internal_js_1.MAJOR_TYPE_TAG: {
return decodeTag(data, argument, index);
}
case cbor_internal_js_1.MAJOR_TYPE_SIMPLE_OR_FLOAT: {
switch (argument) {
case 20:
return [false, 1];
case 21:
return [true, 1];
case 22:
return [null, 1];
case 23:
return [undefined, 1];
// 24: Simple value (value 32..255 in following byte)
case 25: // IEEE 754 Half-Precision Float (16 bits follow)
return decodeFloat16(data, index);
case 26: // IEEE 754 Single-Precision Float (32 bits follow)
return decodeFloat32(data, index);
case 27: // IEEE 754 Double-Precision Float (64 bits follow)
return decodeFloat64(data, index);
// 28-30: Reserved, not well-formed in the present document
// 31: "break" stop code for indefinite-length items
}
}
}
throw new Error(`Unsupported or not well formed at ${index}`);
}
function encodeSimple(data) {
if (data === true) {
return 0xf5;
}
else if (data === false) {
return 0xf4;
}
else if (data === null) {
return 0xf6;
}
// Else undefined
return 0xf7;
}
function encodeFloat(data) {
if (Math.fround(data) == data || !Number.isFinite(data) || Number.isNaN(data)) {
// Float32
const output = new Uint8Array(5);
output[0] = 0xfa;
const view = new DataView(output.buffer);
view.setFloat32(1, data, false);
return output;
}
else {
// Float64
const output = new Uint8Array(9);
output[0] = 0xfb;
const view = new DataView(output.buffer);
view.setFloat64(1, data, false);
return output;
}
}
function encodeNumber(data) {
if (typeof data == "number") {
if (Number.isSafeInteger(data)) {
// Encode integer
if (data < 0) {
return (0, cbor_internal_js_1.encodeLength)(cbor_internal_js_1.MAJOR_TYPE_NEGATIVE_INTEGER, Math.abs(data));
}
else {
return (0, cbor_internal_js_1.encodeLength)(cbor_internal_js_1.MAJOR_TYPE_UNSIGNED_INTEGER, data);
}
}
return [encodeFloat(data)];
}
else {
if (data < 0n) {
return (0, cbor_internal_js_1.encodeLength)(cbor_internal_js_1.MAJOR_TYPE_NEGATIVE_INTEGER, data * -1n);
}
else {
return (0, cbor_internal_js_1.encodeLength)(cbor_internal_js_1.MAJOR_TYPE_UNSIGNED_INTEGER, data);
}
}
}
const ENCODER = new TextEncoder();
function encodeString(data, output) {
output.push(...(0, cbor_internal_js_1.encodeLength)(cbor_internal_js_1.MAJOR_TYPE_TEXT_STRING, data.length));
output.push(ENCODER.encode(data));
}
function encodeBytes(data, output) {
output.push(...(0, cbor_internal_js_1.encodeLength)(cbor_internal_js_1.MAJOR_TYPE_BYTE_STRING, data.length));
output.push(data);
}
function encodeArray(data, output) {
output.push(...(0, cbor_internal_js_1.encodeLength)(cbor_internal_js_1.MAJOR_TYPE_ARRAY, data.length));
for (const element of data) {
encodePartialCBOR(element, output);
}
}
function encodeMap(data, output) {
output.push(new Uint8Array((0, cbor_internal_js_1.encodeLength)(cbor_internal_js_1.MAJOR_TYPE_MAP, data.size)));
for (const [key, value] of data.entries()) {
encodePartialCBOR(key, output);
encodePartialCBOR(value, output);
}
}
function encodeTag(tag, output) {
output.push(...(0, cbor_internal_js_1.encodeLength)(cbor_internal_js_1.MAJOR_TYPE_TAG, tag.tag));
encodePartialCBOR(tag.value, output);
}
function encodePartialCBOR(data, output) {
if (typeof data == "boolean" || data === null || data == undefined) {
output.push(encodeSimple(data));
return;
}
if (typeof data == "number" || typeof data == "bigint") {
output.push(...encodeNumber(data));
return;
}
if (typeof data == "string") {
encodeString(data, output);
return;
}
if (data instanceof Uint8Array) {
encodeBytes(data, output);
return;
}
if (Array.isArray(data)) {
encodeArray(data, output);
return;
}
if (data instanceof Map) {
encodeMap(data, output);
return;
}
if (data instanceof CBORTag) {
encodeTag(data, output);
return;
}
throw new Error("Not implemented");
}
/**
* Like {decodeCBOR}, but the length of the data is unknown and there is likely
* more -- possibly unrelated non-CBOR -- data afterwards.
*
* Examples:
*
* ```ts
* import {decodePartialCBOR} from './cbor.ts'
* decodePartialCBOR(new Uint8Array([1, 2, 245, 3, 4]), 2)
* // returns [true, 1]
* // It did not decode the leading [1, 2] or trailing [3, 4]
* ```
*
* @param data a data stream to read data from
* @param index where to start reading in the data stream
* @returns a tuple of the value followed by bytes read.
* @throws {Error}
* When the data stream ends early or the CBOR data is not well formed
*/
function decodePartialCBOR(data, index) {
if (data.byteLength === 0 || data.byteLength <= index || index < 0) {
throw new Error("No data");
}
if (data instanceof Uint8Array) {
return decodeNext(new DataView(data.buffer), index);
}
else if (data instanceof ArrayBuffer) {
return decodeNext(new DataView(data), index);
}
// otherwise, it is a data view
return decodeNext(data, index);
}
exports.decodePartialCBOR = decodePartialCBOR;
/**
* Decode CBOR data from a binary stream
*
* The entire data stream from [0, length) will be consumed.
* If you require a partial decoding, see {decodePartialCBOR}.
*
* Examples:
*
* ```ts
* import {decodeCBOR, CBORTag, CBORType} from './cbor.ts'
* decodeCBOR(new Uint8Array([162, 99, 107, 101, 121, 101, 118, 97, 108, 117, 101, 1, 109, 97, 110, 111, 116, 104, 101, 114, 32, 118, 97, 108, 117, 101]));
* // returns new Map<string | number, CBORType>([
* // ["key", "value"],
* // [1, "another value"]
* // ]);
*
* const taggedItem = new Uint8Array([217, 4, 210, 101, 104, 101, 108, 108, 111]);
* decodeCBOR(new DataView(taggedItem.buffer))
* // returns new CBORTag(1234, "hello")
* ```
*
* @param data a data stream, multiple types are supported
* @returns
*/
function decodeCBOR(data) {
const [value, length] = decodePartialCBOR(data, 0);
if (length !== data.byteLength) {
throw new Error(`Data was decoded, but the whole stream was not processed ${length} != ${data.byteLength}`);
}
return value;
}
exports.decodeCBOR = decodeCBOR;
/**
* Encode a supported structure to a CBOR byte string.
*
* Example:
*
* ```ts
* import {encodeCBOR, CBORType, CBORTag} from './cbor.ts'
* encodeCBOR(new Map<string | number, CBORType>([
* ["key", "value"],
* [1, "another value"]
* ]));
* // returns new Uint8Array([162, 99, 107, 101, 121, 101, 118, 97, 108, 117, 101, 1, 109, 97, 110, 111, 116, 104, 101, 114, 32 118, 97, 108, 117, 101])
*
* encodeCBOR(new CBORTag(1234, "hello"))
* // returns new UInt8Array([217, 4, 210, 101, 104, 101, 108, 108, 111])
* ```
*
* @param data Data to encode
* @returns A byte string as a Uint8Array
* @throws Error
* if unsupported data is found during encoding
*/
function encodeCBOR(data) {
const results = [];
encodePartialCBOR(data, results);
let length = 0;
for (const result of results) {
if (typeof result == "number") {
length += 1;
}
else {
length += result.length;
}
}
const output = new Uint8Array(length);
let index = 0;
for (const result of results) {
if (typeof result == "number") {
output[index] = result;
index += 1;
}
else {
output.set(result, index);
index += result.length;
}
}
return output;
}
exports.encodeCBOR = encodeCBOR;

View File

@@ -0,0 +1,11 @@
export declare function decodeLength(data: DataView, argument: number, index: number): [number, number];
export type MajorType = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
export declare const MAJOR_TYPE_UNSIGNED_INTEGER: MajorType;
export declare const MAJOR_TYPE_NEGATIVE_INTEGER: MajorType;
export declare const MAJOR_TYPE_BYTE_STRING: MajorType;
export declare const MAJOR_TYPE_TEXT_STRING: MajorType;
export declare const MAJOR_TYPE_ARRAY: MajorType;
export declare const MAJOR_TYPE_MAP: MajorType;
export declare const MAJOR_TYPE_TAG: MajorType;
export declare const MAJOR_TYPE_SIMPLE_OR_FLOAT: MajorType;
export declare function encodeLength(major: MajorType, argument: number | bigint): number[];

View File

@@ -0,0 +1,116 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodeLength = exports.MAJOR_TYPE_SIMPLE_OR_FLOAT = exports.MAJOR_TYPE_TAG = exports.MAJOR_TYPE_MAP = exports.MAJOR_TYPE_ARRAY = exports.MAJOR_TYPE_TEXT_STRING = exports.MAJOR_TYPE_BYTE_STRING = exports.MAJOR_TYPE_NEGATIVE_INTEGER = exports.MAJOR_TYPE_UNSIGNED_INTEGER = exports.decodeLength = void 0;
function decodeLength(data, argument, index) {
if (argument < 24) {
return [argument, 1];
}
const remainingDataLength = data.byteLength - index - 1;
const view = new DataView(data.buffer, index + 1);
let output;
let bytes = 0;
switch (argument) {
case 24: {
if (remainingDataLength > 0) {
output = view.getUint8(0);
bytes = 2;
}
break;
}
case 25: {
if (remainingDataLength > 1) {
output = view.getUint16(0, false);
bytes = 3;
}
break;
}
case 26: {
if (remainingDataLength > 3) {
output = view.getUint32(0, false);
bytes = 5;
}
break;
}
case 27: {
if (remainingDataLength > 7) {
const bigOutput = view.getBigUint64(0, false);
// Bound it to [24, MAX_SAFE_INTEGER], where it is safe
// to encode as a javascript number
if (bigOutput >= 24n && bigOutput <= Number.MAX_SAFE_INTEGER) {
return [Number(bigOutput), 9];
}
}
break;
}
}
if (output && output >= 24) {
return [output, bytes];
}
throw new Error("Length not supported or not well formed");
}
exports.decodeLength = decodeLength;
exports.MAJOR_TYPE_UNSIGNED_INTEGER = 0;
exports.MAJOR_TYPE_NEGATIVE_INTEGER = 1;
exports.MAJOR_TYPE_BYTE_STRING = 2;
exports.MAJOR_TYPE_TEXT_STRING = 3;
exports.MAJOR_TYPE_ARRAY = 4;
exports.MAJOR_TYPE_MAP = 5;
exports.MAJOR_TYPE_TAG = 6;
exports.MAJOR_TYPE_SIMPLE_OR_FLOAT = 7;
function encodeLength(major, argument) {
const majorEncoded = major << 5;
if (argument < 0) {
throw new Error("CBOR Data Item argument must not be negative");
}
// Convert to bigint first.
// Encode integers around and above 32 bits in big endian / network byte order
// is unreliable in javascript.
// https://tc39.es/ecma262/#sec-bitwise-shift-operators
// Bit shifting operations result in 32 bit signed numbers
let bigintArgument;
if (typeof argument == "number") {
if (!Number.isInteger(argument)) {
throw new Error("CBOR Data Item argument must be an integer");
}
bigintArgument = BigInt(argument);
}
else {
bigintArgument = argument;
}
// Negative 0 is not a thing
if (major == exports.MAJOR_TYPE_NEGATIVE_INTEGER) {
if (bigintArgument == 0n) {
throw new Error("CBOR Data Item argument cannot be zero when negative");
}
bigintArgument = bigintArgument - 1n;
}
if (bigintArgument > 18446744073709551615n) {
throw new Error("CBOR number out of range");
}
// Encode into 64 bits and extract the tail
const buffer = new Uint8Array(8);
const view = new DataView(buffer.buffer);
view.setBigUint64(0, bigintArgument, false);
if (bigintArgument <= 23) {
return [majorEncoded | buffer[7]];
}
else if (bigintArgument <= 255) {
return [majorEncoded | 24, buffer[7]];
}
else if (bigintArgument <= 65535) {
return [majorEncoded | 25, ...buffer.slice(6)];
}
else if (bigintArgument <= 4294967295) {
return [
majorEncoded | 26,
...buffer.slice(4),
];
}
else {
return [
majorEncoded | 27,
...buffer,
];
}
}
exports.encodeLength = encodeLength;

View File

@@ -0,0 +1,2 @@
export { CBORTag, decodeCBOR, decodePartialCBOR, encodeCBOR, } from "./cbor/cbor.js";
export type { CBORType } from "./cbor/cbor.js";

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodeCBOR = exports.decodePartialCBOR = exports.decodeCBOR = exports.CBORTag = void 0;
var cbor_js_1 = require("./cbor/cbor.js");
Object.defineProperty(exports, "CBORTag", { enumerable: true, get: function () { return cbor_js_1.CBORTag; } });
Object.defineProperty(exports, "decodeCBOR", { enumerable: true, get: function () { return cbor_js_1.decodeCBOR; } });
Object.defineProperty(exports, "decodePartialCBOR", { enumerable: true, get: function () { return cbor_js_1.decodePartialCBOR; } });
Object.defineProperty(exports, "encodeCBOR", { enumerable: true, get: function () { return cbor_js_1.encodeCBOR; } });

View File

@@ -0,0 +1,3 @@
{
"type": "commonjs"
}