Skip to content

Commit 0489081

Browse files
committed
2.0.0
1 parent b6c15c2 commit 0489081

12 files changed

Lines changed: 272 additions & 176 deletions

File tree

.github/workflows/npm-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616

1717
- uses: actions/setup-node@v6
1818
with:
19-
node-version: "26"
19+
node-version: "latest"
2020
check-latest: true
2121

2222
- name: Setup pnpm

.github/workflows/test.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,14 @@ on:
1111

1212
jobs:
1313
test:
14-
strategy:
15-
matrix:
16-
node-version: ["26", "22.0.0"]
1714
runs-on: ubuntu-latest
1815

1916
steps:
2017
- uses: actions/checkout@v6
2118

2219
- uses: actions/setup-node@v6
2320
with:
24-
node-version: ${{ matrix.node-version }}
21+
node-version: "latest"
2522
check-latest: true
2623

2724
- name: Setup pnpm
@@ -30,4 +27,11 @@ jobs:
3027
version: "11"
3128

3229
- run: pnpm i
33-
- run: pnpm test
30+
31+
- run: npm test
32+
33+
- uses: actions/setup-node@v6
34+
with:
35+
node-version: "12.0.0"
36+
37+
- run: npm run test-only-node12

README.md

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,57 +10,75 @@ npm i @bddjr/base64
1010
import base64 from "@bddjr/base64"
1111

1212
// Encode string to base64
13-
var enc = base64.encode("Hello world!")
13+
var enc = base64.encode("👋Hello!")
1414
console.log(enc)
1515

1616
// Decode base64 to string
17-
var dec = base64.decodeToString("SGVsbG8gd29ybGQh")
17+
var dec = base64.decodeToString("8J+Ri0hlbGxvIQ==")
1818
console.log(dec)
1919

2020
// Encode Uint8Array to base64
2121
var enc = base64.encode(new Uint8Array(16))
2222
console.log(enc)
2323

2424
// Decode base64 to Uint8Array
25-
var dec = base64.decode("nszai3rv7QBp+Co0SgB93g==")
25+
var dec = base64.decode("nszai3rv7QBp+/o0SgB93g==")
2626
console.log(dec)
2727

2828

29+
2930
// Encode string to base64url
30-
var enc = base64.encodeurl("Hello world!")
31+
var enc = base64.encodeurl("👋你好")
3132
console.log(enc)
3233

3334
// Decode base64url to string
34-
var dec = base64.decodeurlToString("SGVsbG8gd29ybGQh")
35+
var dec = base64.decodeurlToString("8J-Ri-S9oOWlvQ==")
3536
console.log(dec)
3637

3738
// Encode Uint8Array to base64url
3839
var enc = base64.encodeurl(new Uint8Array(16))
3940
console.log(enc)
4041

4142
// Decode base64url to Uint8Array
42-
var dec = base64.decodeurl("dBZ7uNJ0D6_EbZwZnQcEBA==")
43+
var dec = base64.decodeurl("dBZ7uNJ0D-_EbZwZnQcEBA==")
4344
console.log(dec)
45+
46+
47+
48+
// Encode to base64 omit padding characters (=)
49+
var enc = base64.encode("omit", true)
50+
console.log(enc) // b21pdA
51+
52+
// Encode to base64url omit padding characters (=)
53+
var enc = base64.encodeurl("omit", true)
54+
console.log(enc)
4455
```
4556

4657
You can also use `@bddjr/base64/make` to create an encoder/decoder with a custom alphabet:
4758

48-
```js
59+
```ts
4960
import {
5061
make_bytesToBase64,
51-
make_base64ToBytes,
5262
make_encode,
5363
make_decode,
5464
make_decodeToString,
5565
} from "@bddjr/base64/make"
5666

5767
// base64-no-upper-case
58-
const alphabet = "!#$%&()*,-.:;<>?@[]^_`{|}~abcdefghijklmnopqrstuvwxyz0123456789+/"
59-
60-
const _bytesToBase64 = make_bytesToBase64(alphabet)
61-
const encode = make_encode(_bytesToBase64)
62-
63-
const _base64ToBytes = make_base64ToBytes(alphabet)
64-
const decode = make_decode(_base64ToBytes)
65-
const decodeToString = make_decodeToString(decode)
68+
export const alphabet = "!#$%&()*,-.:;<>?@[]^_`{|}~abcdefghijklmnopqrstuvwxyz0123456789+/"
69+
70+
export const _bytesToBase64 = /*@__PURE__*/ make_bytesToBase64(alphabet)
71+
export const encode = /*@__PURE__*/ make_encode(_bytesToBase64)
72+
73+
export const decode = /*@__PURE__*/ make_decode(alphabet)
74+
export const decodeToString = /*@__PURE__*/ make_decodeToString(decode)
75+
76+
const base64custom = {
77+
alphabet: alphabet as typeof alphabet, // TypeScript
78+
_bytesToBase64,
79+
encode,
80+
decode,
81+
decodeToString,
82+
}
83+
export default base64custom
6684
```

package.json

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@bddjr/base64",
3-
"version": "1.1.0",
3+
"version": "2.0.0",
44
"description": "A high-performance Base64 and Base64url library, featuring automatic native API acceleration, and support for custom alphabets.",
55
"type": "module",
66
"main": "./dist/main.js",
@@ -12,19 +12,20 @@
1212
"./make": {
1313
"types": "./dist/make.d.ts",
1414
"default": "./dist/make.js"
15-
},
16-
"./type": {
17-
"types": "./type.d.ts"
1815
}
1916
},
17+
"engines": {
18+
"node": ">=12.0.0"
19+
},
2020
"scripts": {
2121
"build": "rimraf dist && tsc",
22-
"test": "node --run build && node scripts/test.mjs && node scripts/test-buffer.mjs && node scripts/test-fallback.mjs",
23-
"prepublishOnly": "node --run test"
22+
"test": "npm run build && npm run test-only",
23+
"test-only": "node scripts/test.mjs && node scripts/test-buffer.mjs && node scripts/test-fallback.mjs",
24+
"test-only-node12":"node --experimental-modules scripts/test.mjs && node --experimental-modules scripts/test-fallback.mjs",
25+
"prepublishOnly": "npm test"
2426
},
2527
"files": [
26-
"dist",
27-
"type.d.ts"
28+
"dist"
2829
],
2930
"repository": {
3031
"type": "git",
@@ -51,7 +52,7 @@
5152
},
5253
"devDependencies": {
5354
"@bddjr/rimraf": "^0.1.1",
54-
"@types/node": "^24.12.2",
55+
"@types/node": "^20.0.0",
5556
"typescript": "^6.0.3"
5657
}
57-
}
58+
}

pnpm-lock.yaml

Lines changed: 5 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/test-buffer.mjs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
if (Uint8Array.fromBase64) {
2-
console.log('test-buffer')
3-
delete Uint8Array.fromBase64
4-
delete Uint8Array.prototype.toBase64
5-
await import('./test.mjs')
6-
}
1+
console.log('test-buffer')
2+
if (!Uint8Array.fromBase64) {
3+
console.log('skip')
4+
console.log()
5+
process.exit()
6+
}
7+
delete Uint8Array.fromBase64
8+
delete Uint8Array.prototype.toBase64
9+
import('./test.mjs')

scripts/test-fallback.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ console.log('test-fallback')
22
delete global.Buffer
33
delete Uint8Array.fromBase64
44
delete Uint8Array.prototype.toBase64
5-
await import('./test.mjs')
5+
import('./test.mjs')

scripts/test.mjs

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@ import base64 from '../dist/main.js'
22

33
let allSuccess = true
44

5+
/**
6+
* @param {number} length
7+
*/
8+
function randBytes(length) {
9+
const b = new Uint8Array(length)
10+
for (let i = b.length; i;) {
11+
b[--i] = Math.random() * 256
12+
}
13+
return b
14+
}
15+
516
/**
617
* @param {{
718
* encode: typeof base64.encode
@@ -16,10 +27,15 @@ function test(base64, omitPadding) {
1627
*/
1728
function test2(v) {
1829
console.log('------------------')
30+
console.log('omitPadding:', omitPadding)
1931
console.log(v)
2032
const enc = base64.encode(v, omitPadding)
2133
console.log(enc)
22-
if (omitPadding && enc.endsWith('=')) process.exit(1);
34+
if (omitPadding || v.length % 3 === 0) {
35+
if (enc.endsWith('=')) process.exit(1)
36+
} else if (!enc.endsWith('='.repeat(3 - (v.length % 3)))) {
37+
process.exit(1)
38+
}
2339
var isEqual = false
2440
if (typeof v == 'string') {
2541
const dec = base64.decodeToString(enc)
@@ -36,20 +52,29 @@ function test(base64, omitPadding) {
3652
return true
3753
})()
3854
}
39-
allSuccess &&= isEqual
55+
if (!isEqual) allSuccess = false;
4056
console.log('equal:', isEqual)
4157
isEqual || process.exit(1)
4258
}
4359

4460
test2("Hello world!")
61+
test2("👋Hello!")
62+
test2("👋你好")
63+
test2("")
64+
test2("1")
65+
test2("12")
66+
test2("123")
67+
test2("1234")
68+
test2("12345")
4569
test2("123456")
4670
test2("1234567")
4771
test2("12345678")
48-
test2(crypto.getRandomValues(new Uint8Array(12)))
49-
test2(crypto.getRandomValues(new Uint8Array(13)))
50-
test2(crypto.getRandomValues(new Uint8Array(14)))
51-
test2(crypto.getRandomValues(new Uint8Array(15)))
52-
test2(crypto.getRandomValues(new Uint8Array(16)))
72+
test2("12345678 ")
73+
test2(randBytes(12))
74+
test2(randBytes(13))
75+
test2(randBytes(14))
76+
test2(randBytes(15))
77+
test2(randBytes(16))
5378
}
5479

5580
for (const omitPadding of [false, true]) {
@@ -61,6 +86,21 @@ for (const omitPadding of [false, true]) {
6186
}, omitPadding);
6287
}
6388

89+
console.log('------------------')
90+
console.log(base64.decode('x\t\n\f\r x'))
91+
console.log(base64.decode('xx\t\n\f\r '))
92+
93+
for (const str of ['x', 'x===', '?', 'vvvvX', 'xx==x', 'xx==xx', 'xx=']) {
94+
console.log('------------------')
95+
console.log(`decode invalid base64: ${str}`)
96+
try {
97+
const v = base64.decode(str)
98+
console.log(v)
99+
process.exit(1)
100+
} catch (e) {
101+
console.log(e)
102+
}
103+
}
64104

65105
console.log('------------------')
66106
console.log('allSuccess:', allSuccess)

0 commit comments

Comments
 (0)