@sopkit/base64 1.0.0

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 ADDED
@@ -0,0 +1,50 @@
1
+ # `@sopkit/base64`
2
+
3
+ Premium, lightweight Base64 encoder and decoder for both Browser and Node.js environments. Part of the SopKit utility ecosystem.
4
+
5
+ ## Online Interactive Tool
6
+ You can use the browser-based interactive version of this tool at [SopKit Base64 Encoder/Decoder](https://sopkit.github.io/base64-encode/).
7
+
8
+ ## Features
9
+ - Full Unicode/UTF-8 support (unlike standard `btoa`/`atob` which fail on emojis and special chars)
10
+ - URL-safe encoding/decoding (`+` ➜ `-`, `/` ➜ `_`, strips `=`)
11
+ - Zero dependencies
12
+ - Fully typed API with strict TypeScript
13
+ - ESM and CommonJS support
14
+
15
+ ## Installation
16
+ ```bash
17
+ npm install @sopkit/base64
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ### ESM
23
+ ```typescript
24
+ import { encode, decode, urlEncode, urlDecode, isValid } from "@sopkit/base64";
25
+
26
+ const text = "Hello World 🚀";
27
+
28
+ // Standard base64
29
+ const encoded = encode(text); // "SGVsbG8gV29ybGQg8J+Zog=="
30
+ const decoded = decode(encoded); // "Hello World 🚀"
31
+
32
+ // URL-safe base64
33
+ const urlSafeEncoded = urlEncode(text); // "SGVsbG8gV29ybGQg8J-Zog"
34
+ const urlSafeDecoded = urlDecode(urlSafeEncoded); // "Hello World 🚀"
35
+
36
+ // Validation
37
+ isValid("SGVsbG8gV29ybGQg8J+Zog=="); // true
38
+ isValid("invalid base64!"); // false
39
+ ```
40
+
41
+ ### CommonJS
42
+ ```javascript
43
+ const { encode, decode } = require("@sopkit/base64");
44
+
45
+ const encoded = encode("Hello World");
46
+ const decoded = decode(encoded);
47
+ ```
48
+
49
+ ## License
50
+ MIT © [SopKit](https://sopkit.github.io/)
package/dist/index.cjs ADDED
@@ -0,0 +1,93 @@
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 index_exports = {};
22
+ __export(index_exports, {
23
+ decode: () => decode,
24
+ encode: () => encode,
25
+ isValid: () => isValid,
26
+ urlDecode: () => urlDecode,
27
+ urlEncode: () => urlEncode
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+ function encode(input) {
31
+ if (typeof input !== "string") {
32
+ throw new TypeError("Input must be a string");
33
+ }
34
+ const bytes = new TextEncoder().encode(input);
35
+ let binary = "";
36
+ for (let i = 0; i < bytes.byteLength; i++) {
37
+ binary += String.fromCharCode(bytes[i]);
38
+ }
39
+ return btoa(binary);
40
+ }
41
+ function decode(input) {
42
+ if (typeof input !== "string") {
43
+ throw new TypeError("Input must be a string");
44
+ }
45
+ try {
46
+ const binary = atob(input);
47
+ const bytes = new Uint8Array(binary.length);
48
+ for (let i = 0; i < binary.length; i++) {
49
+ bytes[i] = binary.charCodeAt(i);
50
+ }
51
+ return new TextDecoder().decode(bytes);
52
+ } catch (e) {
53
+ throw new Error(`Failed to decode Base64: ${e.message}`);
54
+ }
55
+ }
56
+ function urlEncode(input) {
57
+ return encode(input).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
58
+ }
59
+ function urlDecode(input) {
60
+ if (typeof input !== "string") {
61
+ throw new TypeError("Input must be a string");
62
+ }
63
+ let base64 = input.replace(/-/g, "+").replace(/_/g, "/");
64
+ while (base64.length % 4 !== 0) {
65
+ base64 += "=";
66
+ }
67
+ return decode(base64);
68
+ }
69
+ function isValid(input) {
70
+ if (typeof input !== "string" || input.trim() === "") {
71
+ return false;
72
+ }
73
+ const base64Regex = /^[A-Za-z0-9+/_-]*={0,2}$/;
74
+ if (!base64Regex.test(input)) {
75
+ return false;
76
+ }
77
+ try {
78
+ const sanitized = input.replace(/-/g, "+").replace(/_/g, "/");
79
+ atob(sanitized);
80
+ return true;
81
+ } catch {
82
+ return false;
83
+ }
84
+ }
85
+ // Annotate the CommonJS export names for ESM import in node:
86
+ 0 && (module.exports = {
87
+ decode,
88
+ encode,
89
+ isValid,
90
+ urlDecode,
91
+ urlEncode
92
+ });
93
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * SopKit Base64 Utilities\n * Premium, zero-dependency Base64 encoder/decoder supporting Unicode and URL-safe formats.\n * Link: https://sopkit.github.io/base64-encode/\n */\n\n/**\n * Encodes a string into standard Base64 representation.\n * Supports full UTF-8 Unicode characters.\n */\nexport function encode(input: string): string {\n if (typeof input !== \"string\") {\n throw new TypeError(\"Input must be a string\");\n }\n const bytes = new TextEncoder().encode(input);\n let binary = \"\";\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Decodes a standard Base64 string back into its original representation.\n * Supports full UTF-8 Unicode characters.\n */\nexport function decode(input: string): string {\n if (typeof input !== \"string\") {\n throw new TypeError(\"Input must be a string\");\n }\n try {\n const binary = atob(input);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder().decode(bytes);\n } catch (e: any) {\n throw new Error(`Failed to decode Base64: ${e.message}`);\n }\n}\n\n/**\n * Encodes a string into URL-safe Base64 representation.\n * Replaces '+' with '-', '/' with '_', and removes padding '='.\n */\nexport function urlEncode(input: string): string {\n return encode(input)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\n/**\n * Decodes a URL-safe Base64 string back to its original representation.\n */\nexport function urlDecode(input: string): string {\n if (typeof input !== \"string\") {\n throw new TypeError(\"Input must be a string\");\n }\n let base64 = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n while (base64.length % 4 !== 0) {\n base64 += \"=\";\n }\n return decode(base64);\n}\n\n/**\n * Validates whether the given string is a valid Base64 string.\n */\nexport function isValid(input: string): boolean {\n if (typeof input !== \"string\" || input.trim() === \"\") {\n return false;\n }\n const base64Regex = /^[A-Za-z0-9+/_-]*={0,2}$/;\n if (!base64Regex.test(input)) {\n return false;\n }\n try {\n const sanitized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n atob(sanitized);\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUO,SAAS,OAAO,OAAuB;AAC5C,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,UAAU,wBAAwB;AAAA,EAC9C;AACA,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,KAAK;AAC5C,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,MAAM,YAAY,KAAK;AACzC,cAAU,OAAO,aAAa,MAAM,CAAC,CAAC;AAAA,EACxC;AACA,SAAO,KAAK,MAAM;AACpB;AAMO,SAAS,OAAO,OAAuB;AAC5C,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,UAAU,wBAAwB;AAAA,EAC9C;AACA,MAAI;AACF,UAAM,SAAS,KAAK,KAAK;AACzB,UAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,YAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,IAChC;AACA,WAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,EACvC,SAAS,GAAQ;AACf,UAAM,IAAI,MAAM,4BAA4B,EAAE,OAAO,EAAE;AAAA,EACzD;AACF;AAMO,SAAS,UAAU,OAAuB;AAC/C,SAAO,OAAO,KAAK,EAChB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,EAAE;AACtB;AAKO,SAAS,UAAU,OAAuB;AAC/C,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,UAAU,wBAAwB;AAAA,EAC9C;AACA,MAAI,SAAS,MAAM,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AACvD,SAAO,OAAO,SAAS,MAAM,GAAG;AAC9B,cAAU;AAAA,EACZ;AACA,SAAO,OAAO,MAAM;AACtB;AAKO,SAAS,QAAQ,OAAwB;AAC9C,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,WAAO;AAAA,EACT;AACA,QAAM,cAAc;AACpB,MAAI,CAAC,YAAY,KAAK,KAAK,GAAG;AAC5B,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,YAAY,MAAM,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AAC5D,SAAK,SAAS;AACd,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * SopKit Base64 Utilities
3
+ * Premium, zero-dependency Base64 encoder/decoder supporting Unicode and URL-safe formats.
4
+ * Link: https://sopkit.github.io/base64-encode/
5
+ */
6
+ /**
7
+ * Encodes a string into standard Base64 representation.
8
+ * Supports full UTF-8 Unicode characters.
9
+ */
10
+ declare function encode(input: string): string;
11
+ /**
12
+ * Decodes a standard Base64 string back into its original representation.
13
+ * Supports full UTF-8 Unicode characters.
14
+ */
15
+ declare function decode(input: string): string;
16
+ /**
17
+ * Encodes a string into URL-safe Base64 representation.
18
+ * Replaces '+' with '-', '/' with '_', and removes padding '='.
19
+ */
20
+ declare function urlEncode(input: string): string;
21
+ /**
22
+ * Decodes a URL-safe Base64 string back to its original representation.
23
+ */
24
+ declare function urlDecode(input: string): string;
25
+ /**
26
+ * Validates whether the given string is a valid Base64 string.
27
+ */
28
+ declare function isValid(input: string): boolean;
29
+
30
+ export { decode, encode, isValid, urlDecode, urlEncode };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * SopKit Base64 Utilities
3
+ * Premium, zero-dependency Base64 encoder/decoder supporting Unicode and URL-safe formats.
4
+ * Link: https://sopkit.github.io/base64-encode/
5
+ */
6
+ /**
7
+ * Encodes a string into standard Base64 representation.
8
+ * Supports full UTF-8 Unicode characters.
9
+ */
10
+ declare function encode(input: string): string;
11
+ /**
12
+ * Decodes a standard Base64 string back into its original representation.
13
+ * Supports full UTF-8 Unicode characters.
14
+ */
15
+ declare function decode(input: string): string;
16
+ /**
17
+ * Encodes a string into URL-safe Base64 representation.
18
+ * Replaces '+' with '-', '/' with '_', and removes padding '='.
19
+ */
20
+ declare function urlEncode(input: string): string;
21
+ /**
22
+ * Decodes a URL-safe Base64 string back to its original representation.
23
+ */
24
+ declare function urlDecode(input: string): string;
25
+ /**
26
+ * Validates whether the given string is a valid Base64 string.
27
+ */
28
+ declare function isValid(input: string): boolean;
29
+
30
+ export { decode, encode, isValid, urlDecode, urlEncode };
package/dist/index.js ADDED
@@ -0,0 +1,64 @@
1
+ // src/index.ts
2
+ function encode(input) {
3
+ if (typeof input !== "string") {
4
+ throw new TypeError("Input must be a string");
5
+ }
6
+ const bytes = new TextEncoder().encode(input);
7
+ let binary = "";
8
+ for (let i = 0; i < bytes.byteLength; i++) {
9
+ binary += String.fromCharCode(bytes[i]);
10
+ }
11
+ return btoa(binary);
12
+ }
13
+ function decode(input) {
14
+ if (typeof input !== "string") {
15
+ throw new TypeError("Input must be a string");
16
+ }
17
+ try {
18
+ const binary = atob(input);
19
+ const bytes = new Uint8Array(binary.length);
20
+ for (let i = 0; i < binary.length; i++) {
21
+ bytes[i] = binary.charCodeAt(i);
22
+ }
23
+ return new TextDecoder().decode(bytes);
24
+ } catch (e) {
25
+ throw new Error(`Failed to decode Base64: ${e.message}`);
26
+ }
27
+ }
28
+ function urlEncode(input) {
29
+ return encode(input).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
30
+ }
31
+ function urlDecode(input) {
32
+ if (typeof input !== "string") {
33
+ throw new TypeError("Input must be a string");
34
+ }
35
+ let base64 = input.replace(/-/g, "+").replace(/_/g, "/");
36
+ while (base64.length % 4 !== 0) {
37
+ base64 += "=";
38
+ }
39
+ return decode(base64);
40
+ }
41
+ function isValid(input) {
42
+ if (typeof input !== "string" || input.trim() === "") {
43
+ return false;
44
+ }
45
+ const base64Regex = /^[A-Za-z0-9+/_-]*={0,2}$/;
46
+ if (!base64Regex.test(input)) {
47
+ return false;
48
+ }
49
+ try {
50
+ const sanitized = input.replace(/-/g, "+").replace(/_/g, "/");
51
+ atob(sanitized);
52
+ return true;
53
+ } catch {
54
+ return false;
55
+ }
56
+ }
57
+ export {
58
+ decode,
59
+ encode,
60
+ isValid,
61
+ urlDecode,
62
+ urlEncode
63
+ };
64
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * SopKit Base64 Utilities\n * Premium, zero-dependency Base64 encoder/decoder supporting Unicode and URL-safe formats.\n * Link: https://sopkit.github.io/base64-encode/\n */\n\n/**\n * Encodes a string into standard Base64 representation.\n * Supports full UTF-8 Unicode characters.\n */\nexport function encode(input: string): string {\n if (typeof input !== \"string\") {\n throw new TypeError(\"Input must be a string\");\n }\n const bytes = new TextEncoder().encode(input);\n let binary = \"\";\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Decodes a standard Base64 string back into its original representation.\n * Supports full UTF-8 Unicode characters.\n */\nexport function decode(input: string): string {\n if (typeof input !== \"string\") {\n throw new TypeError(\"Input must be a string\");\n }\n try {\n const binary = atob(input);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder().decode(bytes);\n } catch (e: any) {\n throw new Error(`Failed to decode Base64: ${e.message}`);\n }\n}\n\n/**\n * Encodes a string into URL-safe Base64 representation.\n * Replaces '+' with '-', '/' with '_', and removes padding '='.\n */\nexport function urlEncode(input: string): string {\n return encode(input)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\n/**\n * Decodes a URL-safe Base64 string back to its original representation.\n */\nexport function urlDecode(input: string): string {\n if (typeof input !== \"string\") {\n throw new TypeError(\"Input must be a string\");\n }\n let base64 = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n while (base64.length % 4 !== 0) {\n base64 += \"=\";\n }\n return decode(base64);\n}\n\n/**\n * Validates whether the given string is a valid Base64 string.\n */\nexport function isValid(input: string): boolean {\n if (typeof input !== \"string\" || input.trim() === \"\") {\n return false;\n }\n const base64Regex = /^[A-Za-z0-9+/_-]*={0,2}$/;\n if (!base64Regex.test(input)) {\n return false;\n }\n try {\n const sanitized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n atob(sanitized);\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":";AAUO,SAAS,OAAO,OAAuB;AAC5C,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,UAAU,wBAAwB;AAAA,EAC9C;AACA,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,KAAK;AAC5C,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,MAAM,YAAY,KAAK;AACzC,cAAU,OAAO,aAAa,MAAM,CAAC,CAAC;AAAA,EACxC;AACA,SAAO,KAAK,MAAM;AACpB;AAMO,SAAS,OAAO,OAAuB;AAC5C,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,UAAU,wBAAwB;AAAA,EAC9C;AACA,MAAI;AACF,UAAM,SAAS,KAAK,KAAK;AACzB,UAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,YAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,IAChC;AACA,WAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,EACvC,SAAS,GAAQ;AACf,UAAM,IAAI,MAAM,4BAA4B,EAAE,OAAO,EAAE;AAAA,EACzD;AACF;AAMO,SAAS,UAAU,OAAuB;AAC/C,SAAO,OAAO,KAAK,EAChB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,EAAE;AACtB;AAKO,SAAS,UAAU,OAAuB;AAC/C,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,UAAU,wBAAwB;AAAA,EAC9C;AACA,MAAI,SAAS,MAAM,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AACvD,SAAO,OAAO,SAAS,MAAM,GAAG;AAC9B,cAAU;AAAA,EACZ;AACA,SAAO,OAAO,MAAM;AACtB;AAKO,SAAS,QAAQ,OAAwB;AAC9C,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,WAAO;AAAA,EACT;AACA,QAAM,cAAc;AACpB,MAAI,CAAC,YAAY,KAAK,KAAK,GAAG;AAC5B,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,YAAY,MAAM,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AAC5D,SAAK,SAAS;AACd,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@sopkit/base64",
3
+ "version": "1.0.0",
4
+ "description": "Premium, lightweight Base64 utility for browser and Node.js with URL-safe encoding/decoding.",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "type": "module",
9
+ "scripts": {
10
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.cjs"
17
+ }
18
+ },
19
+ "keywords": [
20
+ "sopkit",
21
+ "base64",
22
+ "encode",
23
+ "decode",
24
+ "url-safe",
25
+ "atob",
26
+ "btoa"
27
+ ],
28
+ "author": "SopKit",
29
+ "license": "MIT",
30
+ "homepage": "https://sopkit.github.io/base64-encode/"
31
+ }
package/src/index.ts ADDED
@@ -0,0 +1,86 @@
1
+ /**
2
+ * SopKit Base64 Utilities
3
+ * Premium, zero-dependency Base64 encoder/decoder supporting Unicode and URL-safe formats.
4
+ * Link: https://sopkit.github.io/base64-encode/
5
+ */
6
+
7
+ /**
8
+ * Encodes a string into standard Base64 representation.
9
+ * Supports full UTF-8 Unicode characters.
10
+ */
11
+ export function encode(input: string): string {
12
+ if (typeof input !== "string") {
13
+ throw new TypeError("Input must be a string");
14
+ }
15
+ const bytes = new TextEncoder().encode(input);
16
+ let binary = "";
17
+ for (let i = 0; i < bytes.byteLength; i++) {
18
+ binary += String.fromCharCode(bytes[i]);
19
+ }
20
+ return btoa(binary);
21
+ }
22
+
23
+ /**
24
+ * Decodes a standard Base64 string back into its original representation.
25
+ * Supports full UTF-8 Unicode characters.
26
+ */
27
+ export function decode(input: string): string {
28
+ if (typeof input !== "string") {
29
+ throw new TypeError("Input must be a string");
30
+ }
31
+ try {
32
+ const binary = atob(input);
33
+ const bytes = new Uint8Array(binary.length);
34
+ for (let i = 0; i < binary.length; i++) {
35
+ bytes[i] = binary.charCodeAt(i);
36
+ }
37
+ return new TextDecoder().decode(bytes);
38
+ } catch (e: any) {
39
+ throw new Error(`Failed to decode Base64: ${e.message}`);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Encodes a string into URL-safe Base64 representation.
45
+ * Replaces '+' with '-', '/' with '_', and removes padding '='.
46
+ */
47
+ export function urlEncode(input: string): string {
48
+ return encode(input)
49
+ .replace(/\+/g, "-")
50
+ .replace(/\//g, "_")
51
+ .replace(/=+$/, "");
52
+ }
53
+
54
+ /**
55
+ * Decodes a URL-safe Base64 string back to its original representation.
56
+ */
57
+ export function urlDecode(input: string): string {
58
+ if (typeof input !== "string") {
59
+ throw new TypeError("Input must be a string");
60
+ }
61
+ let base64 = input.replace(/-/g, "+").replace(/_/g, "/");
62
+ while (base64.length % 4 !== 0) {
63
+ base64 += "=";
64
+ }
65
+ return decode(base64);
66
+ }
67
+
68
+ /**
69
+ * Validates whether the given string is a valid Base64 string.
70
+ */
71
+ export function isValid(input: string): boolean {
72
+ if (typeof input !== "string" || input.trim() === "") {
73
+ return false;
74
+ }
75
+ const base64Regex = /^[A-Za-z0-9+/_-]*={0,2}$/;
76
+ if (!base64Regex.test(input)) {
77
+ return false;
78
+ }
79
+ try {
80
+ const sanitized = input.replace(/-/g, "+").replace(/_/g, "/");
81
+ atob(sanitized);
82
+ return true;
83
+ } catch {
84
+ return false;
85
+ }
86
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "declaration": true,
7
+ "outDir": "./dist",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true
12
+ },
13
+ "include": ["src/**/*"]
14
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from "tsup";
2
+
3
+ export default defineConfig({
4
+ entry: ["src/index.ts"],
5
+ format: ["cjs", "esm"],
6
+ dts: true,
7
+ clean: true,
8
+ minify: false,
9
+ sourcemap: true,
10
+ splitting: false,
11
+ });