Skip to content

Commit

Permalink
feat: add Base64 type support (#8)
Browse files Browse the repository at this point in the history
Co-authored-by: Pooya Parsa <[email protected]>
  • Loading branch information
itpropro and pi0 committed Apr 29, 2024
1 parent 915efa2 commit d06d6e5
Show file tree
Hide file tree
Showing 17 changed files with 442 additions and 12 deletions.
80 changes: 80 additions & 0 deletions README.md
Expand Up @@ -22,6 +22,7 @@
## 👍 Supported Types

- [ArrayBuffer][ArrayBuffer]
- [Base64][Base64]
- [Blob][Blob]
- [DataView][DataView]
- [Number Array][Number Array]
Expand Down Expand Up @@ -132,6 +133,10 @@ assertArrayBuffer(value); // Throws an error if value is not ArrayBuffer

## Array Buffer

### `arrayBufferToBase64(arrayBuffer, base64Options)`

Convert from [ArrayBuffer][ArrayBuffer] to [Base64][Base64]

### `arrayBufferToBlob(arrayBuffer, options?)`

Convert from [ArrayBuffer][ArrayBuffer] to [Blob][Blob]
Expand Down Expand Up @@ -172,6 +177,52 @@ Test if input is an instance of [ArrayBuffer][ArrayBuffer] and return `true` or

Convert from any value to [ArrayBuffer][ArrayBuffer]

## Base64

### `assertBase64(input, opts?)`

Assert that input is an instance of [String][String] and matches the [Base64][Base64] pattern or throw a `TypeError`.

### `base64ToArrayBuffer(string, base64Options?)`

Convert from [Base64][Base64] to [ArrayBuffer][ArrayBuffer]

### `base64ToBlob(string, opts?)`

Convert from [Base64][Base64] to [Blob][Blob]

### `base64ToDataView(string, base64Options?)`

Convert from [Base64][Base64] to [DataView][DataView]

### `base64ToNumberArray(string, base64Options?)`

Convert from [Base64][Base64] to [Number Array][Number Array]

### `base64ToReadableStream(string, base64Options?)`

Convert from [Base64][Base64] to [ReadableStream][ReadableStream]

### `base64ToResponse(string)`

Convert from [Base64][Base64] to [Response][Response]

### `base64ToString(string, opts?)`

Convert from [Base64][Base64] to [String][String]

### `base64ToUint8Array(string, base64Options?)`

Convert from [Base64][Base64] to [Uint8Array][Uint8Array]

### `isBase64(input, base64Options?)`

Test if input is string and matches the [Base64][Base64] pattern and return `true` or `false`.

### `toBase64(input)`

Convert from any value to [Base64][Base64]

## Blob

### `assertBlob(input)`
Expand All @@ -182,6 +233,10 @@ Assert that input is an instance of [Blob][Blob] or throw a `TypeError`.

Convert from [Blob][Blob] to [ArrayBuffer][ArrayBuffer]

### `blobToBase64(blob, base64Options)`

Convert from [Blob][Blob] to [Base64][Base64]

### `blobToDataView(blob)`

Convert from [Blob][Blob] to [DataView][DataView]
Expand Down Expand Up @@ -224,6 +279,10 @@ Assert that input is an instance of [DataView][DataView] or throw a `TypeError`.

Convert from [DataView][DataView] to [ArrayBuffer][ArrayBuffer]

### `dataViewToBase64(dataView, base64Options?)`

Convert from [DataView][DataView] to [Base64][Base64]

### `dataViewToBlob(dataView, options?)`

Convert from [DataView][DataView] to [Blob][Blob]
Expand Down Expand Up @@ -270,6 +329,10 @@ Test if input is an instance of [Number Array][Number Array] and return `true` o

Convert from [Number Array][Number Array] to [ArrayBuffer][ArrayBuffer]

### `numberArrayToBase64(numberArray, base64Options?)`

Convert from [Number Array][Number Array] to [Base64][Base64]

### `numberArrayToBlob(numberArray, options?)`

Convert from [Number Array][Number Array] to [Blob][Blob]
Expand Down Expand Up @@ -308,6 +371,10 @@ Test if input is an instance of [ReadableStream][ReadableStream] and return `tru

Convert from [ReadableStream][ReadableStream] to [ArrayBuffer][ArrayBuffer]

### `readableStreamToBase64(readableStream, base64Options?)`

Convert from [ReadableStream][ReadableStream] to [Base64][Base64]

### `readableStreamToBlob(readableStream, options?)`

Convert from [ReadableStream][ReadableStream] to [Blob][Blob]
Expand Down Expand Up @@ -350,6 +417,10 @@ Test if input is an instance of [Response][Response] and return `true` or `false

Convert from [Response][Response] to [ArrayBuffer][ArrayBuffer]

### `responseToBase64(response, base64Options?)`

Convert from [Response][Response] to [Base64][Base64]

### `responseToBlob(response)`

Convert from [Response][Response] to [Blob][Blob]
Expand Down Expand Up @@ -388,6 +459,10 @@ Test if input is an instance of [String][String] and return `true` or `false`.

Convert from [string][string] to [ArrayBuffer][ArrayBuffer]

### `stringToBase64(string, opts?)`

Convert from [string][string] to [Base64][Base64]

### `stringToBlob(string, options?)`

Convert from [string][string] to [Blob][Blob]
Expand Down Expand Up @@ -426,6 +501,10 @@ Convert from any value to [Uint8Array][Uint8Array]

Convert from [Uint8Array][Uint8Array] to [ArrayBuffer][ArrayBuffer]

### `uint8ArrayToBase64(uint8Array, base64Options?)`

Convert from [Uint8Array][Uint8Array] to [Base64][Base64]

### `uint8ArrayToBlob(uint8Array, options?)`

Convert from [Uint8Array][Uint8Array] to [Blob][Blob]
Expand Down Expand Up @@ -506,6 +585,7 @@ _🤖 auto updated with [automd](https://automd.unjs.io)_
<!-- /automd -->

[ArrayBuffer]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
[Base64]: https://developer.mozilla.org/en-US/docs/Glossary/Base64
[Blob]: https://developer.mozilla.org/en-US/docs/Web/API/Blob
[DataView]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView
[Number Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
Expand Down
1 change: 1 addition & 0 deletions scripts/gen-maps.ts
Expand Up @@ -2,6 +2,7 @@ import { writeFileSync } from "node:fs";

const types = [
"arrayBuffer",
"base64",
"blob",
"dataView",
"numberArray",
Expand Down
38 changes: 38 additions & 0 deletions src/convert-maps.ts
@@ -1,15 +1,26 @@
// Auto generated using gen-maps script
import {
assertArrayBuffer,
base64ToArrayBuffer,
blobToArrayBuffer,
dataViewToArrayBuffer,
numberArrayToArrayBuffer,
readableStreamToArrayBuffer,
responseToArrayBuffer,
stringToArrayBuffer,
uint8ArrayToArrayBuffer,
assertBase64,
arrayBufferToBase64,
blobToBase64,
dataViewToBase64,
numberArrayToBase64,
readableStreamToBase64,
responseToBase64,
stringToBase64,
uint8ArrayToBase64,
assertBlob,
arrayBufferToBlob,
base64ToBlob,
dataViewToBlob,
numberArrayToBlob,
readableStreamToBlob,
Expand All @@ -18,6 +29,7 @@ import {
uint8ArrayToBlob,
assertDataView,
arrayBufferToDataView,
base64ToDataView,
blobToDataView,
numberArrayToDataView,
readableStreamToDataView,
Expand All @@ -26,6 +38,7 @@ import {
uint8ArrayToDataView,
assertNumberArray,
arrayBufferToNumberArray,
base64ToNumberArray,
blobToNumberArray,
dataViewToNumberArray,
readableStreamToNumberArray,
Expand All @@ -34,6 +47,7 @@ import {
uint8ArrayToNumberArray,
assertReadableStream,
arrayBufferToReadableStream,
base64ToReadableStream,
blobToReadableStream,
dataViewToReadableStream,
numberArrayToReadableStream,
Expand All @@ -42,6 +56,7 @@ import {
uint8ArrayToReadableStream,
assertResponse,
arrayBufferToResponse,
base64ToResponse,
blobToResponse,
dataViewToResponse,
numberArrayToResponse,
Expand All @@ -50,6 +65,7 @@ import {
uint8ArrayToResponse,
assertString,
arrayBufferToString,
base64ToString,
blobToString,
dataViewToString,
numberArrayToString,
Expand All @@ -58,6 +74,7 @@ import {
uint8ArrayToString,
assertUint8Array,
arrayBufferToUint8Array,
base64ToUint8Array,
blobToUint8Array,
dataViewToUint8Array,
numberArrayToUint8Array,
Expand All @@ -68,6 +85,7 @@ import {

export const _toArrayBuffer = {
ArrayBuffer: (input: unknown) => (assertArrayBuffer(input), input),
Base64: base64ToArrayBuffer,
Blob: blobToArrayBuffer,
DataView: dataViewToArrayBuffer,
NumberArray: numberArrayToArrayBuffer,
Expand All @@ -77,8 +95,21 @@ export const _toArrayBuffer = {
Uint8Array: uint8ArrayToArrayBuffer,
} as const;

export const _toBase64 = {
ArrayBuffer: arrayBufferToBase64,
Base64: (input: unknown) => (assertBase64(input), input),
Blob: blobToBase64,
DataView: dataViewToBase64,
NumberArray: numberArrayToBase64,
ReadableStream: readableStreamToBase64,
Response: responseToBase64,
String: stringToBase64,
Uint8Array: uint8ArrayToBase64,
} as const;

export const _toBlob = {
ArrayBuffer: arrayBufferToBlob,
Base64: base64ToBlob,
Blob: (input: unknown) => (assertBlob(input), input),
DataView: dataViewToBlob,
NumberArray: numberArrayToBlob,
Expand All @@ -90,6 +121,7 @@ export const _toBlob = {

export const _toDataView = {
ArrayBuffer: arrayBufferToDataView,
Base64: base64ToDataView,
Blob: blobToDataView,
DataView: (input: unknown) => (assertDataView(input), input),
NumberArray: numberArrayToDataView,
Expand All @@ -101,6 +133,7 @@ export const _toDataView = {

export const _toNumberArray = {
ArrayBuffer: arrayBufferToNumberArray,
Base64: base64ToNumberArray,
Blob: blobToNumberArray,
DataView: dataViewToNumberArray,
NumberArray: (input: unknown) => (assertNumberArray(input), input),
Expand All @@ -112,6 +145,7 @@ export const _toNumberArray = {

export const _toReadableStream = {
ArrayBuffer: arrayBufferToReadableStream,
Base64: base64ToReadableStream,
Blob: blobToReadableStream,
DataView: dataViewToReadableStream,
NumberArray: numberArrayToReadableStream,
Expand All @@ -123,6 +157,7 @@ export const _toReadableStream = {

export const _toResponse = {
ArrayBuffer: arrayBufferToResponse,
Base64: base64ToResponse,
Blob: blobToResponse,
DataView: dataViewToResponse,
NumberArray: numberArrayToResponse,
Expand All @@ -134,6 +169,7 @@ export const _toResponse = {

export const _toString = {
ArrayBuffer: arrayBufferToString,
Base64: base64ToString,
Blob: blobToString,
DataView: dataViewToString,
NumberArray: numberArrayToString,
Expand All @@ -145,6 +181,7 @@ export const _toString = {

export const _toUint8Array = {
ArrayBuffer: arrayBufferToUint8Array,
Base64: base64ToUint8Array,
Blob: blobToUint8Array,
DataView: dataViewToUint8Array,
NumberArray: numberArrayToUint8Array,
Expand All @@ -156,6 +193,7 @@ export const _toUint8Array = {

export const _to = {
ArrayBuffer: _toArrayBuffer,
Base64: _toBase64,
Blob: _toBlob,
DataView: _toDataView,
NumberArray: _toNumberArray,
Expand Down
13 changes: 12 additions & 1 deletion src/convert.ts
@@ -1,7 +1,8 @@
import { DataType, DataTypeName } from "./types";
import type { Base64, DataType, DataTypeName } from "./types";
import { detectType } from "./detect";
import {
_toArrayBuffer,
_toBase64,
_toBlob,
_toDataView,
_toNumberArray,
Expand All @@ -14,6 +15,9 @@ import {

/**
* Convert from any value to any supported data type
* @param toType - The target data type
* @param input - The input value
* @param fromType - The source data type (optional)
*/
export function convertTo<T extends DataTypeName>(
toType: T,
Expand Down Expand Up @@ -82,6 +86,13 @@ export const toString = (input: DataType) =>
export const toUint8Array = (input: DataType) =>
_convertTo<string>(input, _toUint8Array);

/**
* Convert from any value to [Base64][Base64]
* @group Base64
*/
export const toBase64 = (input: DataType) =>
_convertTo<Base64>(input, _toBase64);

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function _convertTo<T extends DataType>(
input: DataType,
Expand Down
18 changes: 18 additions & 0 deletions src/data-types/_utils.ts
@@ -1,3 +1,5 @@
import type { Base64, Base64Options } from "../types";

type TestFn<T> = (input: unknown) => input is T;

export function assertType<T>(
Expand All @@ -9,3 +11,19 @@ export function assertType<T>(
throw new TypeError(`Expected ${name} type but got ${typeof test}.`);
}
}

export function _base64Encode(
data: Uint8Array | string,
base64Options?: Base64Options,
): Base64 {
let encoded = btoa(
typeof data === "string" ? data : String.fromCodePoint(...data),
);
if (base64Options?.urlSafe) {
encoded = encoded
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, "");
}
return encoded;
}

0 comments on commit d06d6e5

Please sign in to comment.