-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add base64ToBlob, base64ToFile, blobToBase64, and fileToBase64
- Loading branch information
1 parent
5d55958
commit 1ca17ec
Showing
12 changed files
with
298 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { base64ToBlob } from './base64-to-blob'; | ||
|
||
describe('base64ToBlob', () => { | ||
it('exports function', () => { | ||
expect(base64ToBlob).toBeInstanceOf(Function); | ||
}); | ||
|
||
it('converts Base64 with no data to Blob', async () => { | ||
const blob = await base64ToBlob('data:application/octet-stream;base64,'); | ||
expect(blob).toBeInstanceOf(Blob); | ||
expect(blob.type).toBe('application/octet-stream'); | ||
}); | ||
|
||
it('converts Base64 without type to Blob', async () => { | ||
const blob = await base64ToBlob('data:;base64,'); | ||
expect(blob).toBeInstanceOf(Blob); | ||
expect(blob.type).toBe('text/plain;charset=us-ascii'); | ||
}); | ||
|
||
it('converts Base64 to Blob', async () => { | ||
const blob = await base64ToBlob('data:text/plain;base64,YQ=='); | ||
expect(blob).toBeInstanceOf(Blob); | ||
expect(blob.type).toBe('text/plain'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/** | ||
* Converts Base64 to Blob. | ||
* | ||
* @param base64 - Base64. | ||
* @returns - Blob. | ||
*/ | ||
export async function base64ToBlob(base64: string): Promise<Blob> { | ||
const response = await fetch(base64); | ||
let blob = await response.blob(); | ||
const mimeType = getMimeType(base64); | ||
if (mimeType) { | ||
// https://stackoverflow.com/a/50875615 | ||
blob = blob.slice(0, blob.size, mimeType); | ||
} | ||
return blob; | ||
} | ||
|
||
const mimeRegex = /^data:(.+);base64,/; | ||
|
||
/** | ||
* Gets MIME type from Base64. | ||
* | ||
* @param base64 - Base64. | ||
* @returns - MIME type. | ||
*/ | ||
function getMimeType(base64: string) { | ||
return base64.match(mimeRegex)?.slice(1, 2).pop(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { base64ToFile } from './base64-to-file'; | ||
|
||
describe('base64ToFile', () => { | ||
it('exports function', () => { | ||
expect(base64ToFile).toBeInstanceOf(Function); | ||
}); | ||
|
||
it('converts Base64 with no data to File', async () => { | ||
const file = await base64ToFile( | ||
'data:application/octet-stream;base64,', | ||
'' | ||
); | ||
expect(file).toBeInstanceOf(File); | ||
}); | ||
|
||
it('converts Base64 without type to File', async () => { | ||
const file = await base64ToFile('data:;base64,', ''); | ||
expect(file).toBeInstanceOf(File); | ||
expect(file.type).toBe(''); | ||
}); | ||
|
||
it('converts Base64 with type to File', async () => { | ||
const file = await base64ToFile('data:text/plain;base64,YQ==', ''); | ||
expect(file).toBeInstanceOf(File); | ||
expect(file.type).toBe('text/plain'); | ||
}); | ||
|
||
it('converts Base64 to File with filename', async () => { | ||
const file = await base64ToFile('data:text/plain;base64,YQ==', 'filename'); | ||
expect(file.name).toBe('filename'); | ||
}); | ||
|
||
it('converts Base64 to File with type', async () => { | ||
const file = await base64ToFile( | ||
'data:application/octet-stream;base64,YQ==', | ||
'', | ||
{ type: 'text/plain ' } | ||
); | ||
expect(file.type).toBe('text/plain'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* istanbul ignore file */ | ||
|
||
/** | ||
* Converts Base64 to File. | ||
* | ||
* @param base64 - Base64. | ||
* @param filename - Filename. | ||
* @param options - Options. | ||
* @returns - File. | ||
*/ | ||
export async function base64ToFile( | ||
base64: string, | ||
filename: string, | ||
options?: FilePropertyBag | ||
): Promise<File> { | ||
const response = await fetch(base64); | ||
const blob = await response.blob(); | ||
return new File([blob], filename, options); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { blobToBase64 } from './blob-to-base64'; | ||
|
||
describe('blobToBase64', () => { | ||
it('exports function', () => { | ||
expect(blobToBase64).toBeInstanceOf(Function); | ||
}); | ||
|
||
it('converts empty Blob without type to Base64', async () => { | ||
const blob = new Blob([]); | ||
expect(await blobToBase64(blob)).toBe( | ||
'data:application/octet-stream;base64,' | ||
); | ||
}); | ||
|
||
it('converts Blob without type to Base64', async () => { | ||
const blob = new Blob(['a']); | ||
expect(await blobToBase64(blob)).toBe( | ||
'data:application/octet-stream;base64,YQ==' | ||
); | ||
}); | ||
|
||
it('converts Blob with type to Base64', async () => { | ||
const blob = new Blob(['a'], { type: 'text/plain' }); | ||
expect(await blobToBase64(blob)).toBe('data:text/plain;base64,YQ=='); | ||
}); | ||
|
||
it.skip('rejects if there is an error', async () => { | ||
const blob = new Blob([]); | ||
const spy = jest | ||
.spyOn(global, 'FileReader') | ||
.mockRejectedValueOnce('error' as never); | ||
expect(blobToBase64(blob)).rejects.toBe('error'); | ||
spy.mockRestore(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/** | ||
* Converts Blob to Base64. | ||
* | ||
* @param blob - Blob. | ||
* @returns - Base64. | ||
*/ | ||
export async function blobToBase64(blob: Blob): Promise<string> { | ||
return typeof FileReader === 'function' | ||
? blobToBase64Browser(blob) | ||
: blobToBase64Node(blob); | ||
} | ||
|
||
enum Event { | ||
error = 'error', | ||
loadend = 'loadend', | ||
} | ||
|
||
/** | ||
* Converts Blob to Base64 in the browser. | ||
* | ||
* @param blob - Blob. | ||
* @returns - Base64. | ||
*/ | ||
async function blobToBase64Browser(blob: Blob): Promise<string> { | ||
return new Promise((resolve, reject) => { | ||
try { | ||
const reader = new FileReader(); | ||
|
||
const handleLoadend = () => { | ||
resolve(reader.result as string); | ||
reader.removeEventListener(Event.loadend, handleLoadend); | ||
}; | ||
|
||
reader.addEventListener(Event.loadend, handleLoadend); | ||
|
||
/* istanbul ignore next */ | ||
const handleError = () => { | ||
reject(reader.error); | ||
reader.removeEventListener(Event.error, handleError); | ||
}; | ||
|
||
reader.addEventListener(Event.error, handleError); | ||
|
||
reader.readAsDataURL(blob); | ||
} catch (error) { | ||
/* istanbul ignore next */ | ||
reject(error); | ||
} | ||
}); | ||
} | ||
|
||
const defaultMimeType = 'application/octet-stream'; | ||
|
||
/** | ||
* Converts Blob to Base64 in Node.js. | ||
* | ||
* @param blob - Blob. | ||
* @returns - Base64. | ||
*/ | ||
async function blobToBase64Node(blob: Blob): Promise<string> { | ||
const buffer = Buffer.from(await blob.text()); | ||
const mimeType = blob.type || defaultMimeType; | ||
return `data:${mimeType};base64,${buffer.toString('base64')}`; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { fileToBase64 } from './file-to-base64'; | ||
|
||
describe('fileToBase64', () => { | ||
it('exports function', () => { | ||
expect(fileToBase64).toBeInstanceOf(Function); | ||
}); | ||
|
||
it('converts empty file without type to Base64', async () => { | ||
const file = new File([], ''); | ||
expect(await fileToBase64(file)).toBe( | ||
'data:application/octet-stream;base64,' | ||
); | ||
}); | ||
|
||
it('converts file without type to Base64', async () => { | ||
const file = new File(['a'], ''); | ||
expect(await fileToBase64(file)).toBe( | ||
'data:application/octet-stream;base64,YQ==' | ||
); | ||
}); | ||
|
||
it('converts file with type to Base64', async () => { | ||
const file = new File(['a'], '', { type: 'text/plain' }); | ||
expect(await fileToBase64(file)).toBe('data:text/plain;base64,YQ=='); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/** | ||
* Converts File to Base64. | ||
* | ||
* @param file - File. | ||
* @returns - Base64. | ||
*/ | ||
export { blobToBase64 as fileToBase64 } from './blob-to-base64'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
import * as index from './index'; | ||
import { base64ToBlob, base64ToFile, blobToBase64, fileToBase64 } from '.'; | ||
|
||
it('exports object', () => { | ||
expect(index).toEqual({}); | ||
}); | ||
it.each([base64ToBlob, base64ToFile, blobToBase64, fileToBase64])( | ||
'exports %p', | ||
(func) => { | ||
expect(func).toBeInstanceOf(Function); | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
export {}; | ||
export * from './base64-to-blob'; | ||
export * from './base64-to-file'; | ||
export * from './blob-to-base64'; | ||
export * from './file-to-base64'; |