Skip to content

Commit 18a86e0

Browse files
authored
Merge branch 'main' into improv/commons/typeutils
2 parents ab890f3 + 133159b commit 18a86e0

File tree

3 files changed

+110
-1
lines changed

3 files changed

+110
-1
lines changed

Diff for: packages/commons/package.json

+9-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444
"import": "./lib/esm/typeUtils.js",
4545
"require": "./lib/cjs/typeUtils.js"
4646
},
47+
"./utils/base64": {
48+
"import": "./lib/esm/fromBase64.js",
49+
"require": "./lib/cjs/fromBase64.js"
50+
},
4751
"./types": {
4852
"import": "./lib/esm/types/index.js",
4953
"require": "./lib/cjs/types/index.js"
@@ -55,6 +59,10 @@
5559
"lib/cjs/typeUtils.d.ts",
5660
"lib/esm/typeUtils.d.ts"
5761
],
62+
"utils/base64": [
63+
"lib/cjs/fromBase64.d.ts",
64+
"lib/esm/fromBase64.d.ts"
65+
],
5866
"types": [
5967
"lib/cjs/types/index.d.ts",
6068
"lib/esm/types/index.d.ts"
@@ -83,4 +91,4 @@
8391
"devDependencies": {
8492
"@aws-lambda-powertools/testing-utils": "file:../testing"
8593
}
86-
}
94+
}

Diff for: packages/commons/src/fromBase64.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const BASE64_REGEX = /^[A-Za-z0-9+/]*={0,2}$/;
2+
3+
/**
4+
* Convert a base64 string to a Uint8Array.
5+
*
6+
* The input string must be a valid base64 string, otherwise an error will be thrown.
7+
*
8+
* The encoding parameter is optional and defaults to 'utf-8'.
9+
*
10+
* @example
11+
* ```ts
12+
* import { fromBase64 } from '@aws-lambda-powertools/commons/utils/base64';
13+
*
14+
* const encodedValue = 'aGVsbG8gd29ybGQ=';
15+
*
16+
* const decoded = fromBase64(encodedValue);
17+
* // new Uint8Array([ 97, 71, 86, 115, 98, 71, 56, 103, 100, 50, 57, 121, 98, 71, 81, 61 ]);
18+
* ```
19+
*
20+
* @param input The base64 string to convert to a Uint8Array
21+
* @param encoding The encoding of the input string (optional)
22+
*/
23+
const fromBase64 = (input: string, encoding?: BufferEncoding): Uint8Array => {
24+
if ((input.length * 3) % 4 !== 0) {
25+
throw new TypeError(`Incorrect padding on base64 string.`);
26+
}
27+
if (!BASE64_REGEX.exec(input)) {
28+
throw new TypeError(`Invalid base64 string.`);
29+
}
30+
const buffer = encoding ? Buffer.from(input, encoding) : Buffer.from(input);
31+
32+
return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
33+
};
34+
35+
export { fromBase64 };

Diff for: packages/commons/tests/unit/fromBase64.test.ts

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* Test fromBase64 function
3+
*
4+
* @group unit/commons/fromBase64
5+
*/
6+
import { fromBase64 } from '../../src/fromBase64.js';
7+
8+
describe('Function: fromBase64', () => {
9+
beforeEach(() => {
10+
jest.clearAllMocks();
11+
jest.resetModules();
12+
});
13+
14+
it('returns the Uint8Array from a base64 string', () => {
15+
// Prepare
16+
const base64 = 'aGVsbG8gd29ybGQ=';
17+
const expected = new Uint8Array([
18+
97, 71, 86, 115, 98, 71, 56, 103, 100, 50, 57, 121, 98, 71, 81, 61,
19+
]);
20+
21+
// Act
22+
const result = fromBase64(base64);
23+
24+
// Assess
25+
expect(result).toStrictEqual(expected);
26+
});
27+
28+
it('throws a TypeError when the base64 string has incorrect padding', () => {
29+
// Prepare
30+
const base64 = 'aGVsbG8gd29ybGQ';
31+
32+
// Act
33+
const result = (): Uint8Array => fromBase64(base64);
34+
35+
// Assess
36+
expect(result).toThrow(TypeError);
37+
expect(result).toThrow(`Incorrect padding on base64 string.`);
38+
});
39+
40+
it('throws a TypeError when the base64 string is invalid', () => {
41+
// Prepare
42+
const base64 = 'a-VsbG8gd29ybGQ=';
43+
44+
// Act
45+
const result = (): Uint8Array => fromBase64(base64);
46+
47+
// Assess
48+
expect(result).toThrow(TypeError);
49+
expect(result).toThrow(`Invalid base64 string.`);
50+
});
51+
52+
it('uses the provided encoding to create the Uint8Array', () => {
53+
// Prepare
54+
const base64 = 'aGVsbG8gd29ybGQ=';
55+
const encoding = 'utf8';
56+
const expected = new Uint8Array([
57+
97, 71, 86, 115, 98, 71, 56, 103, 100, 50, 57, 121, 98, 71, 81, 61,
58+
]);
59+
60+
// Act
61+
const result = fromBase64(base64, encoding);
62+
63+
// Assess
64+
expect(result).toStrictEqual(expected);
65+
});
66+
});

0 commit comments

Comments
 (0)