@phantom/base64url 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +59 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# @phantom/base64url
|
|
2
|
+
|
|
3
|
+
Isomorphic base64url encoding/decoding utilities that work in both browser and Node.js environments.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @phantom/base64url
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- 🌐 **Isomorphic** - Works in both browser and Node.js
|
|
14
|
+
- 🚀 **Zero dependencies** - Lightweight and fast
|
|
15
|
+
- 📱 **Modern & Legacy** - Supports both modern APIs and older browsers
|
|
16
|
+
- 🔒 **URL-safe** - Uses base64url format (RFC 4648)
|
|
17
|
+
- 📦 **TypeScript** - Full type support included
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { base64urlEncode, base64urlDecode, stringToBase64url, base64urlDecodeToString } from "@phantom/base64url";
|
|
23
|
+
|
|
24
|
+
// Encode string to base64url
|
|
25
|
+
const encoded = stringToBase64url("Hello World");
|
|
26
|
+
console.log(encoded); // "SGVsbG8gV29ybGQ"
|
|
27
|
+
|
|
28
|
+
// Decode base64url to string
|
|
29
|
+
const decoded = base64urlDecodeToString(encoded);
|
|
30
|
+
console.log(decoded); // "Hello World"
|
|
31
|
+
|
|
32
|
+
// Encode Uint8Array to base64url
|
|
33
|
+
const bytes = new Uint8Array([72, 101, 108, 108, 111]);
|
|
34
|
+
const encodedBytes = base64urlEncode(bytes);
|
|
35
|
+
console.log(encodedBytes); // "SGVsbG8"
|
|
36
|
+
|
|
37
|
+
// Decode base64url to Uint8Array
|
|
38
|
+
const decodedBytes = base64urlDecode(encodedBytes);
|
|
39
|
+
console.log(decodedBytes); // Uint8Array([72, 101, 108, 108, 111])
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## API Reference
|
|
43
|
+
|
|
44
|
+
### `base64urlEncode(data: string | Uint8Array | ArrayLike<number>): string`
|
|
45
|
+
|
|
46
|
+
Encodes data to base64url format.
|
|
47
|
+
|
|
48
|
+
- **data**: String, Uint8Array, or ArrayLike data to encode
|
|
49
|
+
- **Returns**: base64url encoded string (no padding, URL-safe)
|
|
50
|
+
|
|
51
|
+
### `base64urlDecode(str: string): Uint8Array`
|
|
52
|
+
|
|
53
|
+
Decodes base64url string to Uint8Array.
|
|
54
|
+
|
|
55
|
+
- **str**: base64url encoded string
|
|
56
|
+
- **Returns**: decoded Uint8Array
|
|
57
|
+
|
|
58
|
+
### `stringToBase64url(str: string): string`
|
|
59
|
+
|
|
60
|
+
Encodes UTF-8 string to base64url format.
|
|
61
|
+
|
|
62
|
+
- **str**: UTF-8 string to encode
|
|
63
|
+
- **Returns**: base64url encoded string
|
|
64
|
+
|
|
65
|
+
### `base64urlDecodeToString(str: string): string`
|
|
66
|
+
|
|
67
|
+
Decodes base64url string to UTF-8 string.
|
|
68
|
+
|
|
69
|
+
- **str**: base64url encoded string
|
|
70
|
+
- **Returns**: decoded UTF-8 string
|
|
71
|
+
|
|
72
|
+
## Base64url Format
|
|
73
|
+
|
|
74
|
+
Base64url is a URL-safe variant of Base64 encoding defined in RFC 4648:
|
|
75
|
+
|
|
76
|
+
- Uses `-` instead of `+`
|
|
77
|
+
- Uses `_` instead of `/`
|
|
78
|
+
- Removes padding (`=`) characters
|
|
79
|
+
- Safe to use in URLs, filenames, and HTTP headers
|
|
80
|
+
|
|
81
|
+
## Browser Compatibility
|
|
82
|
+
|
|
83
|
+
- **Modern browsers**: Uses native `btoa`/`atob` and `TextEncoder`/`TextDecoder`
|
|
84
|
+
- **Legacy browsers**: Provides fallbacks for older environments
|
|
85
|
+
- **Node.js**: Uses `Buffer` for optimal performance
|
|
86
|
+
|
|
87
|
+
## Examples
|
|
88
|
+
|
|
89
|
+
### JWT Token Handling
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { stringToBase64url, base64urlDecodeToString } from "@phantom/base64url";
|
|
93
|
+
|
|
94
|
+
const payload = JSON.stringify({
|
|
95
|
+
sub: "1234567890",
|
|
96
|
+
name: "John Doe",
|
|
97
|
+
iat: 1516239022,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const encodedPayload = stringToBase64url(payload);
|
|
101
|
+
console.log(`JWT payload: ${encodedPayload}`);
|
|
102
|
+
|
|
103
|
+
const decodedPayload = base64urlDecodeToString(encodedPayload);
|
|
104
|
+
console.log(JSON.parse(decodedPayload));
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Binary Data Encoding
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { base64urlEncode, base64urlDecode } from "@phantom/base64url";
|
|
111
|
+
|
|
112
|
+
// Encode binary data
|
|
113
|
+
const binaryData = new Uint8Array([0xff, 0xfe, 0xfd, 0xfc]);
|
|
114
|
+
const encoded = base64urlEncode(binaryData);
|
|
115
|
+
console.log(encoded); // URL-safe encoded string
|
|
116
|
+
|
|
117
|
+
// Decode back to binary
|
|
118
|
+
const decoded = base64urlDecode(encoded);
|
|
119
|
+
console.log(decoded); // Original Uint8Array
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### API Integration
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { stringToBase64url } from "@phantom/base64url";
|
|
126
|
+
|
|
127
|
+
// Safe for URL parameters
|
|
128
|
+
const userData = JSON.stringify({ userId: 123, action: "login" });
|
|
129
|
+
const safeParam = stringToBase64url(userData);
|
|
130
|
+
|
|
131
|
+
// Use in URL without encoding issues
|
|
132
|
+
const apiUrl = `https://api.example.com/auth?data=${safeParam}`;
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Isomorphic base64url encoding/decoding utilities
|
|
3
|
+
* Works in both browser and Node.js environments
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Encode data to base64url format
|
|
7
|
+
* @param data - String, Uint8Array, or ArrayLike data to encode
|
|
8
|
+
* @returns base64url encoded string
|
|
9
|
+
*/
|
|
10
|
+
declare function base64urlEncode(data: string | Uint8Array | ArrayLike<number>): string;
|
|
11
|
+
/**
|
|
12
|
+
* Decode base64url string to Uint8Array
|
|
13
|
+
* @param str - base64url encoded string
|
|
14
|
+
* @returns decoded Uint8Array
|
|
15
|
+
*/
|
|
16
|
+
declare function base64urlDecode(str: string): Uint8Array;
|
|
17
|
+
/**
|
|
18
|
+
* Decode base64url string to UTF-8 string
|
|
19
|
+
* @param str - base64url encoded string
|
|
20
|
+
* @returns decoded UTF-8 string
|
|
21
|
+
*/
|
|
22
|
+
declare function base64urlDecodeToString(str: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Encode UTF-8 string to base64url format
|
|
25
|
+
* @param str - UTF-8 string to encode
|
|
26
|
+
* @returns base64url encoded string
|
|
27
|
+
*/
|
|
28
|
+
declare function stringToBase64url(str: string): string;
|
|
29
|
+
|
|
30
|
+
export { base64urlDecode, base64urlDecodeToString, base64urlEncode, stringToBase64url };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
base64urlDecode: () => base64urlDecode,
|
|
24
|
+
base64urlDecodeToString: () => base64urlDecodeToString,
|
|
25
|
+
base64urlEncode: () => base64urlEncode,
|
|
26
|
+
stringToBase64url: () => stringToBase64url
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(src_exports);
|
|
29
|
+
var isBrowser = typeof window !== "undefined" && typeof window.btoa !== "undefined";
|
|
30
|
+
function base64urlEncode(data) {
|
|
31
|
+
let base64;
|
|
32
|
+
if (isBrowser) {
|
|
33
|
+
if (typeof data === "string") {
|
|
34
|
+
base64 = btoa(data);
|
|
35
|
+
} else {
|
|
36
|
+
base64 = btoa(String.fromCharCode(...Array.from(data)));
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
if (typeof data === "string") {
|
|
40
|
+
base64 = Buffer.from(data, "utf8").toString("base64");
|
|
41
|
+
} else {
|
|
42
|
+
base64 = Buffer.from(data).toString("base64");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
46
|
+
}
|
|
47
|
+
function base64urlDecode(str) {
|
|
48
|
+
const base64 = str.replace(/-/g, "+").replace(/_/g, "/").padEnd(str.length + (4 - str.length % 4) % 4, "=");
|
|
49
|
+
if (isBrowser) {
|
|
50
|
+
const binaryString = atob(base64);
|
|
51
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
52
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
53
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
54
|
+
}
|
|
55
|
+
return bytes;
|
|
56
|
+
} else {
|
|
57
|
+
return new Uint8Array(Buffer.from(base64, "base64"));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function base64urlDecodeToString(str) {
|
|
61
|
+
const bytes = base64urlDecode(str);
|
|
62
|
+
if (isBrowser && typeof TextDecoder !== "undefined") {
|
|
63
|
+
return new TextDecoder().decode(bytes);
|
|
64
|
+
} else if (!isBrowser) {
|
|
65
|
+
return Buffer.from(bytes).toString("utf8");
|
|
66
|
+
} else {
|
|
67
|
+
return String.fromCharCode(...bytes);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function stringToBase64url(str) {
|
|
71
|
+
if (isBrowser && typeof TextEncoder !== "undefined") {
|
|
72
|
+
const bytes = new TextEncoder().encode(str);
|
|
73
|
+
return base64urlEncode(bytes);
|
|
74
|
+
} else if (!isBrowser) {
|
|
75
|
+
return base64urlEncode(str);
|
|
76
|
+
} else {
|
|
77
|
+
return base64urlEncode(str);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
81
|
+
0 && (module.exports = {
|
|
82
|
+
base64urlDecode,
|
|
83
|
+
base64urlDecodeToString,
|
|
84
|
+
base64urlEncode,
|
|
85
|
+
stringToBase64url
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Isomorphic base64url encoding/decoding utilities\n * Works in both browser and Node.js environments\n */\n\n// Check if we're in a browser environment\nconst isBrowser = typeof window !== \"undefined\" && typeof window.btoa !== \"undefined\";\n\n/**\n * Encode data to base64url format\n * @param data - String, Uint8Array, or ArrayLike data to encode\n * @returns base64url encoded string\n */\nexport function base64urlEncode(data: string | Uint8Array | ArrayLike<number>): string {\n let base64: string;\n\n if (isBrowser) {\n // Browser environment using btoa\n if (typeof data === \"string\") {\n base64 = btoa(data);\n } else {\n // Convert Uint8Array or ArrayLike to string\n base64 = btoa(String.fromCharCode(...Array.from(data)));\n }\n } else {\n // Node.js environment using Buffer\n if (typeof data === \"string\") {\n base64 = Buffer.from(data, \"utf8\").toString(\"base64\");\n } else {\n base64 = Buffer.from(data).toString(\"base64\");\n }\n }\n\n // Convert base64 to base64url\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/**\n * Decode base64url string to Uint8Array\n * @param str - base64url encoded string\n * @returns decoded Uint8Array\n */\nexport function base64urlDecode(str: string): Uint8Array {\n // Convert base64url to base64\n const base64 = str\n .replace(/-/g, \"+\")\n .replace(/_/g, \"/\")\n .padEnd(str.length + ((4 - (str.length % 4)) % 4), \"=\");\n\n if (isBrowser) {\n // Browser environment using atob\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes;\n } else {\n // Node.js environment using Buffer\n return new Uint8Array(Buffer.from(base64, \"base64\"));\n }\n}\n\n/**\n * Decode base64url string to UTF-8 string\n * @param str - base64url encoded string\n * @returns decoded UTF-8 string\n */\nexport function base64urlDecodeToString(str: string): string {\n const bytes = base64urlDecode(str);\n\n if (isBrowser && typeof TextDecoder !== \"undefined\") {\n return new TextDecoder().decode(bytes);\n } else if (!isBrowser) {\n // Node.js environment\n return Buffer.from(bytes).toString(\"utf8\");\n } else {\n // Fallback for older browsers without TextDecoder\n return String.fromCharCode(...bytes);\n }\n}\n\n/**\n * Encode UTF-8 string to base64url format\n * @param str - UTF-8 string to encode\n * @returns base64url encoded string\n */\nexport function stringToBase64url(str: string): string {\n if (isBrowser && typeof TextEncoder !== \"undefined\") {\n const bytes = new TextEncoder().encode(str);\n return base64urlEncode(bytes);\n } else if (!isBrowser) {\n // Node.js environment\n return base64urlEncode(str);\n } else {\n // Fallback for older browsers without TextEncoder\n return base64urlEncode(str);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,IAAM,YAAY,OAAO,WAAW,eAAe,OAAO,OAAO,SAAS;AAOnE,SAAS,gBAAgB,MAAuD;AACrF,MAAI;AAEJ,MAAI,WAAW;AAEb,QAAI,OAAO,SAAS,UAAU;AAC5B,eAAS,KAAK,IAAI;AAAA,IACpB,OAAO;AAEL,eAAS,KAAK,OAAO,aAAa,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC;AAAA,IACxD;AAAA,EACF,OAAO;AAEL,QAAI,OAAO,SAAS,UAAU;AAC5B,eAAS,OAAO,KAAK,MAAM,MAAM,EAAE,SAAS,QAAQ;AAAA,IACtD,OAAO;AACL,eAAS,OAAO,KAAK,IAAI,EAAE,SAAS,QAAQ;AAAA,IAC9C;AAAA,EACF;AAGA,SAAO,OAAO,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AACzE;AAOO,SAAS,gBAAgB,KAAyB;AAEvD,QAAM,SAAS,IACZ,QAAQ,MAAM,GAAG,EACjB,QAAQ,MAAM,GAAG,EACjB,OAAO,IAAI,UAAW,IAAK,IAAI,SAAS,KAAM,GAAI,GAAG;AAExD,MAAI,WAAW;AAEb,UAAM,eAAe,KAAK,MAAM;AAChC,UAAM,QAAQ,IAAI,WAAW,aAAa,MAAM;AAChD,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,YAAM,CAAC,IAAI,aAAa,WAAW,CAAC;AAAA,IACtC;AACA,WAAO;AAAA,EACT,OAAO;AAEL,WAAO,IAAI,WAAW,OAAO,KAAK,QAAQ,QAAQ,CAAC;AAAA,EACrD;AACF;AAOO,SAAS,wBAAwB,KAAqB;AAC3D,QAAM,QAAQ,gBAAgB,GAAG;AAEjC,MAAI,aAAa,OAAO,gBAAgB,aAAa;AACnD,WAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,EACvC,WAAW,CAAC,WAAW;AAErB,WAAO,OAAO,KAAK,KAAK,EAAE,SAAS,MAAM;AAAA,EAC3C,OAAO;AAEL,WAAO,OAAO,aAAa,GAAG,KAAK;AAAA,EACrC;AACF;AAOO,SAAS,kBAAkB,KAAqB;AACrD,MAAI,aAAa,OAAO,gBAAgB,aAAa;AACnD,UAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,GAAG;AAC1C,WAAO,gBAAgB,KAAK;AAAA,EAC9B,WAAW,CAAC,WAAW;AAErB,WAAO,gBAAgB,GAAG;AAAA,EAC5B,OAAO;AAEL,WAAO,gBAAgB,GAAG;AAAA,EAC5B;AACF;","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var isBrowser = typeof window !== "undefined" && typeof window.btoa !== "undefined";
|
|
3
|
+
function base64urlEncode(data) {
|
|
4
|
+
let base64;
|
|
5
|
+
if (isBrowser) {
|
|
6
|
+
if (typeof data === "string") {
|
|
7
|
+
base64 = btoa(data);
|
|
8
|
+
} else {
|
|
9
|
+
base64 = btoa(String.fromCharCode(...Array.from(data)));
|
|
10
|
+
}
|
|
11
|
+
} else {
|
|
12
|
+
if (typeof data === "string") {
|
|
13
|
+
base64 = Buffer.from(data, "utf8").toString("base64");
|
|
14
|
+
} else {
|
|
15
|
+
base64 = Buffer.from(data).toString("base64");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
19
|
+
}
|
|
20
|
+
function base64urlDecode(str) {
|
|
21
|
+
const base64 = str.replace(/-/g, "+").replace(/_/g, "/").padEnd(str.length + (4 - str.length % 4) % 4, "=");
|
|
22
|
+
if (isBrowser) {
|
|
23
|
+
const binaryString = atob(base64);
|
|
24
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
25
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
26
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
27
|
+
}
|
|
28
|
+
return bytes;
|
|
29
|
+
} else {
|
|
30
|
+
return new Uint8Array(Buffer.from(base64, "base64"));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function base64urlDecodeToString(str) {
|
|
34
|
+
const bytes = base64urlDecode(str);
|
|
35
|
+
if (isBrowser && typeof TextDecoder !== "undefined") {
|
|
36
|
+
return new TextDecoder().decode(bytes);
|
|
37
|
+
} else if (!isBrowser) {
|
|
38
|
+
return Buffer.from(bytes).toString("utf8");
|
|
39
|
+
} else {
|
|
40
|
+
return String.fromCharCode(...bytes);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function stringToBase64url(str) {
|
|
44
|
+
if (isBrowser && typeof TextEncoder !== "undefined") {
|
|
45
|
+
const bytes = new TextEncoder().encode(str);
|
|
46
|
+
return base64urlEncode(bytes);
|
|
47
|
+
} else if (!isBrowser) {
|
|
48
|
+
return base64urlEncode(str);
|
|
49
|
+
} else {
|
|
50
|
+
return base64urlEncode(str);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
base64urlDecode,
|
|
55
|
+
base64urlDecodeToString,
|
|
56
|
+
base64urlEncode,
|
|
57
|
+
stringToBase64url
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Isomorphic base64url encoding/decoding utilities\n * Works in both browser and Node.js environments\n */\n\n// Check if we're in a browser environment\nconst isBrowser = typeof window !== \"undefined\" && typeof window.btoa !== \"undefined\";\n\n/**\n * Encode data to base64url format\n * @param data - String, Uint8Array, or ArrayLike data to encode\n * @returns base64url encoded string\n */\nexport function base64urlEncode(data: string | Uint8Array | ArrayLike<number>): string {\n let base64: string;\n\n if (isBrowser) {\n // Browser environment using btoa\n if (typeof data === \"string\") {\n base64 = btoa(data);\n } else {\n // Convert Uint8Array or ArrayLike to string\n base64 = btoa(String.fromCharCode(...Array.from(data)));\n }\n } else {\n // Node.js environment using Buffer\n if (typeof data === \"string\") {\n base64 = Buffer.from(data, \"utf8\").toString(\"base64\");\n } else {\n base64 = Buffer.from(data).toString(\"base64\");\n }\n }\n\n // Convert base64 to base64url\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/**\n * Decode base64url string to Uint8Array\n * @param str - base64url encoded string\n * @returns decoded Uint8Array\n */\nexport function base64urlDecode(str: string): Uint8Array {\n // Convert base64url to base64\n const base64 = str\n .replace(/-/g, \"+\")\n .replace(/_/g, \"/\")\n .padEnd(str.length + ((4 - (str.length % 4)) % 4), \"=\");\n\n if (isBrowser) {\n // Browser environment using atob\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes;\n } else {\n // Node.js environment using Buffer\n return new Uint8Array(Buffer.from(base64, \"base64\"));\n }\n}\n\n/**\n * Decode base64url string to UTF-8 string\n * @param str - base64url encoded string\n * @returns decoded UTF-8 string\n */\nexport function base64urlDecodeToString(str: string): string {\n const bytes = base64urlDecode(str);\n\n if (isBrowser && typeof TextDecoder !== \"undefined\") {\n return new TextDecoder().decode(bytes);\n } else if (!isBrowser) {\n // Node.js environment\n return Buffer.from(bytes).toString(\"utf8\");\n } else {\n // Fallback for older browsers without TextDecoder\n return String.fromCharCode(...bytes);\n }\n}\n\n/**\n * Encode UTF-8 string to base64url format\n * @param str - UTF-8 string to encode\n * @returns base64url encoded string\n */\nexport function stringToBase64url(str: string): string {\n if (isBrowser && typeof TextEncoder !== \"undefined\") {\n const bytes = new TextEncoder().encode(str);\n return base64urlEncode(bytes);\n } else if (!isBrowser) {\n // Node.js environment\n return base64urlEncode(str);\n } else {\n // Fallback for older browsers without TextEncoder\n return base64urlEncode(str);\n }\n}\n"],"mappings":";AAMA,IAAM,YAAY,OAAO,WAAW,eAAe,OAAO,OAAO,SAAS;AAOnE,SAAS,gBAAgB,MAAuD;AACrF,MAAI;AAEJ,MAAI,WAAW;AAEb,QAAI,OAAO,SAAS,UAAU;AAC5B,eAAS,KAAK,IAAI;AAAA,IACpB,OAAO;AAEL,eAAS,KAAK,OAAO,aAAa,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC;AAAA,IACxD;AAAA,EACF,OAAO;AAEL,QAAI,OAAO,SAAS,UAAU;AAC5B,eAAS,OAAO,KAAK,MAAM,MAAM,EAAE,SAAS,QAAQ;AAAA,IACtD,OAAO;AACL,eAAS,OAAO,KAAK,IAAI,EAAE,SAAS,QAAQ;AAAA,IAC9C;AAAA,EACF;AAGA,SAAO,OAAO,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AACzE;AAOO,SAAS,gBAAgB,KAAyB;AAEvD,QAAM,SAAS,IACZ,QAAQ,MAAM,GAAG,EACjB,QAAQ,MAAM,GAAG,EACjB,OAAO,IAAI,UAAW,IAAK,IAAI,SAAS,KAAM,GAAI,GAAG;AAExD,MAAI,WAAW;AAEb,UAAM,eAAe,KAAK,MAAM;AAChC,UAAM,QAAQ,IAAI,WAAW,aAAa,MAAM;AAChD,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,YAAM,CAAC,IAAI,aAAa,WAAW,CAAC;AAAA,IACtC;AACA,WAAO;AAAA,EACT,OAAO;AAEL,WAAO,IAAI,WAAW,OAAO,KAAK,QAAQ,QAAQ,CAAC;AAAA,EACrD;AACF;AAOO,SAAS,wBAAwB,KAAqB;AAC3D,QAAM,QAAQ,gBAAgB,GAAG;AAEjC,MAAI,aAAa,OAAO,gBAAgB,aAAa;AACnD,WAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,EACvC,WAAW,CAAC,WAAW;AAErB,WAAO,OAAO,KAAK,KAAK,EAAE,SAAS,MAAM;AAAA,EAC3C,OAAO;AAEL,WAAO,OAAO,aAAa,GAAG,KAAK;AAAA,EACrC;AACF;AAOO,SAAS,kBAAkB,KAAqB;AACrD,MAAI,aAAa,OAAO,gBAAgB,aAAa;AACnD,UAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,GAAG;AAC1C,WAAO,gBAAgB,KAAK;AAAA,EAC9B,WAAW,CAAC,WAAW;AAErB,WAAO,gBAAgB,GAAG;AAAA,EAC5B,OAAO;AAEL,WAAO,gBAAgB,GAAG;AAAA,EAC5B;AACF;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@phantom/base64url",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Isomorphic base64url encoding/decoding utilities",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.mjs",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "rimraf ./dist && tsup",
|
|
20
|
+
"dev": "rimraf ./dist && tsup --watch",
|
|
21
|
+
"clean": "rm -rf dist",
|
|
22
|
+
"test": "jest",
|
|
23
|
+
"test:watch": "jest --watch",
|
|
24
|
+
"lint": "tsc --noEmit && eslint --cache . --ext .ts",
|
|
25
|
+
"prettier": "prettier --write \"src/**/*.{ts}\""
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/jest": "^29.5.12",
|
|
29
|
+
"@types/node": "^20.11.0",
|
|
30
|
+
"eslint": "8.53.0",
|
|
31
|
+
"jest": "^29.7.0",
|
|
32
|
+
"prettier": "^3.5.2",
|
|
33
|
+
"rimraf": "^6.0.1",
|
|
34
|
+
"ts-jest": "^29.1.2",
|
|
35
|
+
"tsup": "^6.7.0",
|
|
36
|
+
"typescript": "^5.0.4"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"base64url",
|
|
40
|
+
"encoding",
|
|
41
|
+
"decoding",
|
|
42
|
+
"isomorphic",
|
|
43
|
+
"browser",
|
|
44
|
+
"node"
|
|
45
|
+
],
|
|
46
|
+
"license": "MIT"
|
|
47
|
+
}
|