Skip to content

Commit d06d6e5

Browse files
itpropropi0
andauthored
feat: add Base64 type support (#8)
Co-authored-by: Pooya Parsa <[email protected]>
1 parent 915efa2 commit d06d6e5

17 files changed

+442
-12
lines changed

README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
## 👍 Supported Types
2323

2424
- [ArrayBuffer][ArrayBuffer]
25+
- [Base64][Base64]
2526
- [Blob][Blob]
2627
- [DataView][DataView]
2728
- [Number Array][Number Array]
@@ -132,6 +133,10 @@ assertArrayBuffer(value); // Throws an error if value is not ArrayBuffer
132133

133134
## Array Buffer
134135

136+
### `arrayBufferToBase64(arrayBuffer, base64Options)`
137+
138+
Convert from [ArrayBuffer][ArrayBuffer] to [Base64][Base64]
139+
135140
### `arrayBufferToBlob(arrayBuffer, options?)`
136141

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

173178
Convert from any value to [ArrayBuffer][ArrayBuffer]
174179

180+
## Base64
181+
182+
### `assertBase64(input, opts?)`
183+
184+
Assert that input is an instance of [String][String] and matches the [Base64][Base64] pattern or throw a `TypeError`.
185+
186+
### `base64ToArrayBuffer(string, base64Options?)`
187+
188+
Convert from [Base64][Base64] to [ArrayBuffer][ArrayBuffer]
189+
190+
### `base64ToBlob(string, opts?)`
191+
192+
Convert from [Base64][Base64] to [Blob][Blob]
193+
194+
### `base64ToDataView(string, base64Options?)`
195+
196+
Convert from [Base64][Base64] to [DataView][DataView]
197+
198+
### `base64ToNumberArray(string, base64Options?)`
199+
200+
Convert from [Base64][Base64] to [Number Array][Number Array]
201+
202+
### `base64ToReadableStream(string, base64Options?)`
203+
204+
Convert from [Base64][Base64] to [ReadableStream][ReadableStream]
205+
206+
### `base64ToResponse(string)`
207+
208+
Convert from [Base64][Base64] to [Response][Response]
209+
210+
### `base64ToString(string, opts?)`
211+
212+
Convert from [Base64][Base64] to [String][String]
213+
214+
### `base64ToUint8Array(string, base64Options?)`
215+
216+
Convert from [Base64][Base64] to [Uint8Array][Uint8Array]
217+
218+
### `isBase64(input, base64Options?)`
219+
220+
Test if input is string and matches the [Base64][Base64] pattern and return `true` or `false`.
221+
222+
### `toBase64(input)`
223+
224+
Convert from any value to [Base64][Base64]
225+
175226
## Blob
176227

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

183234
Convert from [Blob][Blob] to [ArrayBuffer][ArrayBuffer]
184235

236+
### `blobToBase64(blob, base64Options)`
237+
238+
Convert from [Blob][Blob] to [Base64][Base64]
239+
185240
### `blobToDataView(blob)`
186241

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

225280
Convert from [DataView][DataView] to [ArrayBuffer][ArrayBuffer]
226281

282+
### `dataViewToBase64(dataView, base64Options?)`
283+
284+
Convert from [DataView][DataView] to [Base64][Base64]
285+
227286
### `dataViewToBlob(dataView, options?)`
228287

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

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

332+
### `numberArrayToBase64(numberArray, base64Options?)`
333+
334+
Convert from [Number Array][Number Array] to [Base64][Base64]
335+
273336
### `numberArrayToBlob(numberArray, options?)`
274337

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

309372
Convert from [ReadableStream][ReadableStream] to [ArrayBuffer][ArrayBuffer]
310373

374+
### `readableStreamToBase64(readableStream, base64Options?)`
375+
376+
Convert from [ReadableStream][ReadableStream] to [Base64][Base64]
377+
311378
### `readableStreamToBlob(readableStream, options?)`
312379

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

351418
Convert from [Response][Response] to [ArrayBuffer][ArrayBuffer]
352419

420+
### `responseToBase64(response, base64Options?)`
421+
422+
Convert from [Response][Response] to [Base64][Base64]
423+
353424
### `responseToBlob(response)`
354425

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

389460
Convert from [string][string] to [ArrayBuffer][ArrayBuffer]
390461

462+
### `stringToBase64(string, opts?)`
463+
464+
Convert from [string][string] to [Base64][Base64]
465+
391466
### `stringToBlob(string, options?)`
392467

393468
Convert from [string][string] to [Blob][Blob]
@@ -426,6 +501,10 @@ Convert from any value to [Uint8Array][Uint8Array]
426501

427502
Convert from [Uint8Array][Uint8Array] to [ArrayBuffer][ArrayBuffer]
428503

504+
### `uint8ArrayToBase64(uint8Array, base64Options?)`
505+
506+
Convert from [Uint8Array][Uint8Array] to [Base64][Base64]
507+
429508
### `uint8ArrayToBlob(uint8Array, options?)`
430509

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

508587
[ArrayBuffer]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
588+
[Base64]: https://developer.mozilla.org/en-US/docs/Glossary/Base64
509589
[Blob]: https://developer.mozilla.org/en-US/docs/Web/API/Blob
510590
[DataView]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView
511591
[Number Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

scripts/gen-maps.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { writeFileSync } from "node:fs";
22

33
const types = [
44
"arrayBuffer",
5+
"base64",
56
"blob",
67
"dataView",
78
"numberArray",

src/convert-maps.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
// Auto generated using gen-maps script
22
import {
33
assertArrayBuffer,
4+
base64ToArrayBuffer,
45
blobToArrayBuffer,
56
dataViewToArrayBuffer,
67
numberArrayToArrayBuffer,
78
readableStreamToArrayBuffer,
89
responseToArrayBuffer,
910
stringToArrayBuffer,
1011
uint8ArrayToArrayBuffer,
12+
assertBase64,
13+
arrayBufferToBase64,
14+
blobToBase64,
15+
dataViewToBase64,
16+
numberArrayToBase64,
17+
readableStreamToBase64,
18+
responseToBase64,
19+
stringToBase64,
20+
uint8ArrayToBase64,
1121
assertBlob,
1222
arrayBufferToBlob,
23+
base64ToBlob,
1324
dataViewToBlob,
1425
numberArrayToBlob,
1526
readableStreamToBlob,
@@ -18,6 +29,7 @@ import {
1829
uint8ArrayToBlob,
1930
assertDataView,
2031
arrayBufferToDataView,
32+
base64ToDataView,
2133
blobToDataView,
2234
numberArrayToDataView,
2335
readableStreamToDataView,
@@ -26,6 +38,7 @@ import {
2638
uint8ArrayToDataView,
2739
assertNumberArray,
2840
arrayBufferToNumberArray,
41+
base64ToNumberArray,
2942
blobToNumberArray,
3043
dataViewToNumberArray,
3144
readableStreamToNumberArray,
@@ -34,6 +47,7 @@ import {
3447
uint8ArrayToNumberArray,
3548
assertReadableStream,
3649
arrayBufferToReadableStream,
50+
base64ToReadableStream,
3751
blobToReadableStream,
3852
dataViewToReadableStream,
3953
numberArrayToReadableStream,
@@ -42,6 +56,7 @@ import {
4256
uint8ArrayToReadableStream,
4357
assertResponse,
4458
arrayBufferToResponse,
59+
base64ToResponse,
4560
blobToResponse,
4661
dataViewToResponse,
4762
numberArrayToResponse,
@@ -50,6 +65,7 @@ import {
5065
uint8ArrayToResponse,
5166
assertString,
5267
arrayBufferToString,
68+
base64ToString,
5369
blobToString,
5470
dataViewToString,
5571
numberArrayToString,
@@ -58,6 +74,7 @@ import {
5874
uint8ArrayToString,
5975
assertUint8Array,
6076
arrayBufferToUint8Array,
77+
base64ToUint8Array,
6178
blobToUint8Array,
6279
dataViewToUint8Array,
6380
numberArrayToUint8Array,
@@ -68,6 +85,7 @@ import {
6885

6986
export const _toArrayBuffer = {
7087
ArrayBuffer: (input: unknown) => (assertArrayBuffer(input), input),
88+
Base64: base64ToArrayBuffer,
7189
Blob: blobToArrayBuffer,
7290
DataView: dataViewToArrayBuffer,
7391
NumberArray: numberArrayToArrayBuffer,
@@ -77,8 +95,21 @@ export const _toArrayBuffer = {
7795
Uint8Array: uint8ArrayToArrayBuffer,
7896
} as const;
7997

98+
export const _toBase64 = {
99+
ArrayBuffer: arrayBufferToBase64,
100+
Base64: (input: unknown) => (assertBase64(input), input),
101+
Blob: blobToBase64,
102+
DataView: dataViewToBase64,
103+
NumberArray: numberArrayToBase64,
104+
ReadableStream: readableStreamToBase64,
105+
Response: responseToBase64,
106+
String: stringToBase64,
107+
Uint8Array: uint8ArrayToBase64,
108+
} as const;
109+
80110
export const _toBlob = {
81111
ArrayBuffer: arrayBufferToBlob,
112+
Base64: base64ToBlob,
82113
Blob: (input: unknown) => (assertBlob(input), input),
83114
DataView: dataViewToBlob,
84115
NumberArray: numberArrayToBlob,
@@ -90,6 +121,7 @@ export const _toBlob = {
90121

91122
export const _toDataView = {
92123
ArrayBuffer: arrayBufferToDataView,
124+
Base64: base64ToDataView,
93125
Blob: blobToDataView,
94126
DataView: (input: unknown) => (assertDataView(input), input),
95127
NumberArray: numberArrayToDataView,
@@ -101,6 +133,7 @@ export const _toDataView = {
101133

102134
export const _toNumberArray = {
103135
ArrayBuffer: arrayBufferToNumberArray,
136+
Base64: base64ToNumberArray,
104137
Blob: blobToNumberArray,
105138
DataView: dataViewToNumberArray,
106139
NumberArray: (input: unknown) => (assertNumberArray(input), input),
@@ -112,6 +145,7 @@ export const _toNumberArray = {
112145

113146
export const _toReadableStream = {
114147
ArrayBuffer: arrayBufferToReadableStream,
148+
Base64: base64ToReadableStream,
115149
Blob: blobToReadableStream,
116150
DataView: dataViewToReadableStream,
117151
NumberArray: numberArrayToReadableStream,
@@ -123,6 +157,7 @@ export const _toReadableStream = {
123157

124158
export const _toResponse = {
125159
ArrayBuffer: arrayBufferToResponse,
160+
Base64: base64ToResponse,
126161
Blob: blobToResponse,
127162
DataView: dataViewToResponse,
128163
NumberArray: numberArrayToResponse,
@@ -134,6 +169,7 @@ export const _toResponse = {
134169

135170
export const _toString = {
136171
ArrayBuffer: arrayBufferToString,
172+
Base64: base64ToString,
137173
Blob: blobToString,
138174
DataView: dataViewToString,
139175
NumberArray: numberArrayToString,
@@ -145,6 +181,7 @@ export const _toString = {
145181

146182
export const _toUint8Array = {
147183
ArrayBuffer: arrayBufferToUint8Array,
184+
Base64: base64ToUint8Array,
148185
Blob: blobToUint8Array,
149186
DataView: dataViewToUint8Array,
150187
NumberArray: numberArrayToUint8Array,
@@ -156,6 +193,7 @@ export const _toUint8Array = {
156193

157194
export const _to = {
158195
ArrayBuffer: _toArrayBuffer,
196+
Base64: _toBase64,
159197
Blob: _toBlob,
160198
DataView: _toDataView,
161199
NumberArray: _toNumberArray,

src/convert.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { DataType, DataTypeName } from "./types";
1+
import type { Base64, DataType, DataTypeName } from "./types";
22
import { detectType } from "./detect";
33
import {
44
_toArrayBuffer,
5+
_toBase64,
56
_toBlob,
67
_toDataView,
78
_toNumberArray,
@@ -14,6 +15,9 @@ import {
1415

1516
/**
1617
* Convert from any value to any supported data type
18+
* @param toType - The target data type
19+
* @param input - The input value
20+
* @param fromType - The source data type (optional)
1721
*/
1822
export function convertTo<T extends DataTypeName>(
1923
toType: T,
@@ -82,6 +86,13 @@ export const toString = (input: DataType) =>
8286
export const toUint8Array = (input: DataType) =>
8387
_convertTo<string>(input, _toUint8Array);
8488

89+
/**
90+
* Convert from any value to [Base64][Base64]
91+
* @group Base64
92+
*/
93+
export const toBase64 = (input: DataType) =>
94+
_convertTo<Base64>(input, _toBase64);
95+
8596
// eslint-disable-next-line @typescript-eslint/no-unused-vars
8697
function _convertTo<T extends DataType>(
8798
input: DataType,

src/data-types/_utils.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { Base64, Base64Options } from "../types";
2+
13
type TestFn<T> = (input: unknown) => input is T;
24

35
export function assertType<T>(
@@ -9,3 +11,19 @@ export function assertType<T>(
911
throw new TypeError(`Expected ${name} type but got ${typeof test}.`);
1012
}
1113
}
14+
15+
export function _base64Encode(
16+
data: Uint8Array | string,
17+
base64Options?: Base64Options,
18+
): Base64 {
19+
let encoded = btoa(
20+
typeof data === "string" ? data : String.fromCodePoint(...data),
21+
);
22+
if (base64Options?.urlSafe) {
23+
encoded = encoded
24+
.replace(/\+/g, "-")
25+
.replace(/\//g, "_")
26+
.replace(/=+$/, "");
27+
}
28+
return encoded;
29+
}

0 commit comments

Comments
 (0)