@wtasnorg/node-lib 0.0.8 → 0.0.9

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.
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **createFindDirectories**(`deps`): (`root`, `options`) => `Promise`\<`string`[]\>
10
10
 
11
- Defined in: [find.ts:19](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/find.ts#L19)
11
+ Defined in: [find.ts:19](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/find.ts#L19)
12
12
 
13
13
  Factory that produces an async findDirectories function with
14
14
  injected filesystem dependencies for full testability.
@@ -0,0 +1,49 @@
1
+ [**@wtasnorg/node-lib**](../README.md)
2
+
3
+ ***
4
+
5
+ [@wtasnorg/node-lib](../README.md) / decode
6
+
7
+ # Function: decode()
8
+
9
+ > **decode**(`input`, `charset`): `string`
10
+
11
+ Defined in: base64.ts:119
12
+
13
+ Decode a Base64 string.
14
+
15
+ ## Parameters
16
+
17
+ ### input
18
+
19
+ `string`
20
+
21
+ The Base64 encoded string.
22
+
23
+ ### charset
24
+
25
+ The charset variant to use (default: "standard").
26
+
27
+ `"standard"` | `"urlsafe"` | `"imap"` | `"radix64"`
28
+
29
+ ## Returns
30
+
31
+ `string`
32
+
33
+ The decoded string.
34
+
35
+ ## Example
36
+
37
+ ```typescript
38
+ import { decode } from "./base64.js";
39
+
40
+ decode("SGVsbG8sIFdvcmxkIQ==");
41
+ // => "Hello, World!"
42
+
43
+ decode("SGVsbG8sIFdvcmxkIQ==", "standard");
44
+ // => "Hello, World!"
45
+ ```
46
+
47
+ ## Throws
48
+
49
+ Error if the input contains invalid characters.
@@ -0,0 +1,45 @@
1
+ [**@wtasnorg/node-lib**](../README.md)
2
+
3
+ ***
4
+
5
+ [@wtasnorg/node-lib](../README.md) / encode
6
+
7
+ # Function: encode()
8
+
9
+ > **encode**(`input`, `charset`): `string`
10
+
11
+ Defined in: base64.ts:79
12
+
13
+ Encode a string to Base64.
14
+
15
+ ## Parameters
16
+
17
+ ### input
18
+
19
+ `string`
20
+
21
+ The string to encode.
22
+
23
+ ### charset
24
+
25
+ The charset variant to use (default: "standard").
26
+
27
+ `"standard"` | `"urlsafe"` | `"imap"` | `"radix64"`
28
+
29
+ ## Returns
30
+
31
+ `string`
32
+
33
+ The Base64 encoded string.
34
+
35
+ ## Example
36
+
37
+ ```typescript
38
+ import { encode } from "./base64.js";
39
+
40
+ encode("Hello, World!");
41
+ // => "SGVsbG8sIFdvcmxkIQ=="
42
+
43
+ encode("Hello, World!", "urlsafe");
44
+ // => "SGVsbG8sIFdvcmxkIQ=="
45
+ ```
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **hello**(): `Promise`\<`string`\>
10
10
 
11
- Defined in: [hello.ts:6](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/hello.ts#L6)
11
+ Defined in: [hello.ts:6](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/hello.ts#L6)
12
12
 
13
13
  A sample function that should work to test if lib is installed correctly.
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **parseUserAgent**(`ua`): [`UserAgentInfo`](../interfaces/UserAgentInfo.md)
10
10
 
11
- Defined in: [user-agent.ts:48](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/user-agent.ts#L48)
11
+ Defined in: [user-agent.ts:48](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/user-agent.ts#L48)
12
12
 
13
13
  Parses a user-agent string into a UserAgentInfo object.
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **pojo**\<`T`\>(`instance`): `Record`\<`string`, `unknown`\>
10
10
 
11
- Defined in: [pojo.ts:10](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/pojo.ts#L10)
11
+ Defined in: [pojo.ts:10](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/pojo.ts#L10)
12
12
 
13
13
  Convert a class instance into a plain JavaScript object.
14
14
  Copies only the instance's own enumerable data properties
@@ -6,7 +6,7 @@
6
6
 
7
7
  # Interface: FileSystemDependencies
8
8
 
9
- Defined in: [find.ts:3](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/find.ts#L3)
9
+ Defined in: [find.ts:3](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/find.ts#L3)
10
10
 
11
11
  ## Properties
12
12
 
@@ -14,7 +14,7 @@ Defined in: [find.ts:3](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd
14
14
 
15
15
  > **readdir**: (`_path`, `_opts`) => `Promise`\<`object`[]\>
16
16
 
17
- Defined in: [find.ts:4](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/find.ts#L4)
17
+ Defined in: [find.ts:4](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/find.ts#L4)
18
18
 
19
19
  #### Parameters
20
20
 
@@ -38,7 +38,7 @@ Defined in: [find.ts:4](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd
38
38
 
39
39
  > **stat**: (`_path`) => `Promise`\<\{ `isDirectory`: `boolean`; \}\>
40
40
 
41
- Defined in: [find.ts:5](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/find.ts#L5)
41
+ Defined in: [find.ts:5](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/find.ts#L5)
42
42
 
43
43
  #### Parameters
44
44
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  # Interface: FindDirectoriesOptions
8
8
 
9
- Defined in: [find.ts:8](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/find.ts#L8)
9
+ Defined in: [find.ts:8](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/find.ts#L8)
10
10
 
11
11
  ## Properties
12
12
 
@@ -14,7 +14,7 @@ Defined in: [find.ts:8](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd
14
14
 
15
15
  > `optional` **allowlist**: `string`[] \| (`_absPath`, `_name`) => `boolean`
16
16
 
17
- Defined in: [find.ts:11](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/find.ts#L11)
17
+ Defined in: [find.ts:11](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/find.ts#L11)
18
18
 
19
19
  ***
20
20
 
@@ -22,7 +22,7 @@ Defined in: [find.ts:11](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cf
22
22
 
23
23
  > `optional` **blocklist**: `string`[] \| (`_absPath`, `_name`) => `boolean`
24
24
 
25
- Defined in: [find.ts:12](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/find.ts#L12)
25
+ Defined in: [find.ts:12](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/find.ts#L12)
26
26
 
27
27
  ***
28
28
 
@@ -30,7 +30,7 @@ Defined in: [find.ts:12](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cf
30
30
 
31
31
  > `optional` **followSymlinks**: `boolean`
32
32
 
33
- Defined in: [find.ts:10](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/find.ts#L10)
33
+ Defined in: [find.ts:10](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/find.ts#L10)
34
34
 
35
35
  ***
36
36
 
@@ -38,4 +38,4 @@ Defined in: [find.ts:10](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cf
38
38
 
39
39
  > `optional` **maxDepth**: `number`
40
40
 
41
- Defined in: [find.ts:9](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/find.ts#L9)
41
+ Defined in: [find.ts:9](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/find.ts#L9)
@@ -6,7 +6,7 @@
6
6
 
7
7
  # Interface: UserAgentInfo
8
8
 
9
- Defined in: [user-agent.ts:4](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/user-agent.ts#L4)
9
+ Defined in: [user-agent.ts:4](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/user-agent.ts#L4)
10
10
 
11
11
  Information extracted from a user-agent string.
12
12
 
@@ -16,7 +16,7 @@ Information extracted from a user-agent string.
16
16
 
17
17
  > **browser**: `string`
18
18
 
19
- Defined in: [user-agent.ts:8](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/user-agent.ts#L8)
19
+ Defined in: [user-agent.ts:8](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/user-agent.ts#L8)
20
20
 
21
21
  Browser name (e.g., Chrome, Firefox, Safari, Edge, Opera, Other).
22
22
 
@@ -26,7 +26,7 @@ Browser name (e.g., Chrome, Firefox, Safari, Edge, Opera, Other).
26
26
 
27
27
  > **device**: `string`
28
28
 
29
- Defined in: [user-agent.ts:20](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/user-agent.ts#L20)
29
+ Defined in: [user-agent.ts:20](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/user-agent.ts#L20)
30
30
 
31
31
  Device type (e.g., Mobile, Tablet, Desktop, Other).
32
32
 
@@ -36,7 +36,7 @@ Device type (e.g., Mobile, Tablet, Desktop, Other).
36
36
 
37
37
  > **engine**: `string`
38
38
 
39
- Defined in: [user-agent.ts:24](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/user-agent.ts#L24)
39
+ Defined in: [user-agent.ts:24](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/user-agent.ts#L24)
40
40
 
41
41
  Rendering engine (e.g., Blink, WebKit, Gecko, Presto, Other).
42
42
 
@@ -46,7 +46,7 @@ Rendering engine (e.g., Blink, WebKit, Gecko, Presto, Other).
46
46
 
47
47
  > **os**: `string`
48
48
 
49
- Defined in: [user-agent.ts:16](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/user-agent.ts#L16)
49
+ Defined in: [user-agent.ts:16](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/user-agent.ts#L16)
50
50
 
51
51
  Operating system (e.g., Windows, macOS, Linux, iOS, Android, Other).
52
52
 
@@ -56,6 +56,6 @@ Operating system (e.g., Windows, macOS, Linux, iOS, Android, Other).
56
56
 
57
57
  > **version**: `string`
58
58
 
59
- Defined in: [user-agent.ts:12](https://github.com/wtasg/node-lib/blob/ac07f7b7be8233cfd945908394ac10daf671e6a9/src/user-agent.ts#L12)
59
+ Defined in: [user-agent.ts:12](https://github.com/wtasg/node-lib/blob/b5efd5c345e8fa1bdc2a6d3ea4dd4b2eb5b9cc62/src/user-agent.ts#L12)
60
60
 
61
61
  Browser version (e.g., 120.0.0.0).
@@ -0,0 +1,13 @@
1
+ [**@wtasnorg/node-lib**](../README.md)
2
+
3
+ ***
4
+
5
+ [@wtasnorg/node-lib](../README.md) / Base64CharsetType
6
+
7
+ # Type Alias: Base64CharsetType
8
+
9
+ > **Base64CharsetType** = *typeof* [`Base64Charset`](../variables/Base64Charset.md)\[`number`\]
10
+
11
+ Defined in: base64.ts:18
12
+
13
+ Base64 charset type.
@@ -0,0 +1,17 @@
1
+ [**@wtasnorg/node-lib**](../README.md)
2
+
3
+ ***
4
+
5
+ [@wtasnorg/node-lib](../README.md) / Base64Charset
6
+
7
+ # Variable: Base64Charset
8
+
9
+ > `const` **Base64Charset**: readonly \[`"standard"`, `"urlsafe"`, `"imap"`, `"radix64"`\]
10
+
11
+ Defined in: base64.ts:13
12
+
13
+ Available Base64 charset variants.
14
+ - `standard`: RFC 4648 standard alphabet (A-Z, a-z, 0-9, +, /)
15
+ - `urlsafe`: URL and filename safe (A-Z, a-z, 0-9, -, _)
16
+ - `imap`: Modified Base64 for IMAP mailbox names (A-Z, a-z, 0-9, +, ,)
17
+ - `radix64`: Base64 variant used in OpenPGP (A-Z, a-z, 0-9, +, /)
@@ -0,0 +1,50 @@
1
+ # Base64 Module Refinement Pass
2
+ # Date: 2026-01-19
3
+ # Scope: src/base64.ts
4
+
5
+ ## SRP Analysis
6
+ - encode(): Single responsibility - string to Base64
7
+ - decode(): Single responsibility - Base64 to string
8
+ - buildDecodeTable(): Single responsibility - lookup table creation
9
+ - No business logic mixing, no I/O coupling
10
+
11
+ ## Dependency Direction
12
+ - No external dependencies beyond Node.js built-ins (TextEncoder/TextDecoder)
13
+ - No circular dependencies
14
+ - Pure computation, no framework coupling
15
+
16
+ ## Purity & Side-Effects
17
+ - All functions are pure (no I/O, no global state mutation)
18
+ - Deterministic: same input always produces same output
19
+ - No hidden state mutation
20
+
21
+ ## Naming Review
22
+ - encode/decode: Clear, idiomatic names
23
+ - Base64Charset: Descriptive, matches domain
24
+ - CHARSETS/DECODE_TABLES: Clear internal constants
25
+ - buildDecodeTable: Accurate verb+noun pattern
26
+
27
+ ## Error Handling
28
+ - decode() throws Error with specific character on invalid input
29
+ - Error message includes the offending character
30
+ - No swallowed exceptions
31
+
32
+ ## API Surface
33
+ - Exports: encode, decode, Base64Charset, Base64CharsetType
34
+ - Minimal and focused public API
35
+ - Internal helpers (buildDecodeTable, CHARSETS, PAD) are not exported
36
+
37
+ ## Invariants
38
+ - Charset type is constrained via TypeScript const assertion
39
+ - Invalid charset impossible at compile time
40
+ - Padding handled correctly per Base64 spec
41
+
42
+ ## Test Coverage
43
+ - 74 tests total, base64 tests cover:
44
+ - Encode: empty, single char, padding, all charsets, UTF-8
45
+ - Decode: empty, padding, error handling
46
+ - Round-trip: all charsets with 10 test cases each
47
+ - Tests verify behavior, not implementation
48
+
49
+ ## Summary
50
+ No actionable refinement items. Code is clean, focused, and well-tested.
@@ -0,0 +1,75 @@
1
+ # Base64 Module Security Assessment
2
+ # Date: 2026-01-19
3
+ # Scope: src/base64.ts
4
+
5
+ ## Attack Surface Inventory
6
+ - encode(input: string, charset): accepts user-controlled string
7
+ - decode(input: string, charset): accepts user-controlled Base64 string
8
+ - No network I/O, no file I/O, no exec
9
+
10
+ ## Threat Model
11
+ - Attacker model: untrusted string input
12
+ - Assets: application stability, memory
13
+ - Trust boundary: function input parameters
14
+
15
+ ## OWASP Top 10 Review
16
+
17
+ ### A01 - Broken Access Control
18
+ - N/A: Pure computation, no access control
19
+
20
+ ### A02 - Cryptographic Failures
21
+ - N/A: Not a cryptographic function (encoding != encryption)
22
+ - Note: radix64 is named for OpenPGP but is just Base64 alphabet
23
+
24
+ ### A03 - Injection
25
+ - N/A: No SQL, command, or template execution
26
+ - Output is string manipulation only
27
+
28
+ ### A04 - Insecure Design
29
+ - PASS: Input validation on decode via lookup table
30
+ - PASS: Invalid characters throw explicit error
31
+
32
+ ### A05 - Security Misconfiguration
33
+ - N/A: No configuration, pure library code
34
+
35
+ ### A06 - Vulnerable Components
36
+ - N/A: No external dependencies
37
+
38
+ ### A07 - Identification & Authentication
39
+ - N/A: No auth logic
40
+
41
+ ### A08 - Software & Data Integrity
42
+ - N/A: No deserialization or external data
43
+
44
+ ### A09 - Logging & Monitoring
45
+ - N/A: Library code, no logging (appropriate)
46
+
47
+ ### A10 - SSRF
48
+ - N/A: No URL handling
49
+
50
+ ## Denial of Service Analysis
51
+ - Large input: TextEncoder/TextDecoder handle arbitrary sizes
52
+ - Memory: proportional to input size (expected for encoding)
53
+ - No regex catastrophic backtracking (simple /=+$/ pattern)
54
+ - No infinite loops: bounded by input length
55
+
56
+ ## Input Validation
57
+ - encode(): accepts any valid JS string, converts via TextEncoder
58
+ - decode(): validates each character against charset lookup table
59
+ - Invalid input: throws Error immediately (fail-fast)
60
+
61
+ ## Memory Safety
62
+ - Uses Uint8Array and standard JS arrays
63
+ - No buffer overflows possible in JS/TS
64
+ - No manual memory management
65
+
66
+ ## Findings
67
+ Severity: NONE
68
+
69
+ ## Summary
70
+ No security issues identified. The module is a pure computation library with:
71
+ - No external I/O
72
+ - No dangerous operations
73
+ - Proper input validation
74
+ - Explicit error handling
75
+ - Bounded resource usage
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wtasnorg/node-lib",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "node library",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/readme.txt CHANGED
@@ -11,6 +11,7 @@ A library project for nodejs. #nodejs #typescript #library
11
11
  2. `pojo` for converting class objects to Plain Old Javascript Objects.
12
12
  3. `createFindDirectories` as a factory for finding directories; think `find path -type d`.
13
13
  4. `parseUserAgent` for extracting information from user-agent strings.
14
+ 5. `encode` / `decode` for Base64 encoding/decoding with charset variants (`standard`, `urlsafe`, `imap`, `radix64`).
14
15
 
15
16
  ## Develop
16
17
 
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Base64 encoding/decoding with multiple charset variants.
3
+ * @module base64
4
+ */
5
+ /**
6
+ * Available Base64 charset variants.
7
+ * - `standard`: RFC 4648 standard alphabet (A-Z, a-z, 0-9, +, /)
8
+ * - `urlsafe`: URL and filename safe (A-Z, a-z, 0-9, -, _)
9
+ * - `imap`: Modified Base64 for IMAP mailbox names (A-Z, a-z, 0-9, +, ,)
10
+ * - `radix64`: Base64 variant used in OpenPGP (A-Z, a-z, 0-9, +, /)
11
+ */
12
+ declare const Base64Charset: readonly ["standard", "urlsafe", "imap", "radix64"];
13
+ /**
14
+ * Base64 charset type.
15
+ */
16
+ type Base64CharsetType = (typeof Base64Charset)[number];
17
+ /**
18
+ * Encode a string to Base64.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * import { encode } from "./base64.js";
23
+ *
24
+ * encode("Hello, World!");
25
+ * // => "SGVsbG8sIFdvcmxkIQ=="
26
+ *
27
+ * encode("Hello, World!", "urlsafe");
28
+ * // => "SGVsbG8sIFdvcmxkIQ=="
29
+ * ```
30
+ *
31
+ * @param input - The string to encode.
32
+ * @param charset - The charset variant to use (default: "standard").
33
+ * @returns The Base64 encoded string.
34
+ */
35
+ declare function encode(input: string, charset?: Base64CharsetType): string;
36
+ /**
37
+ * Decode a Base64 string.
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * import { decode } from "./base64.js";
42
+ *
43
+ * decode("SGVsbG8sIFdvcmxkIQ==");
44
+ * // => "Hello, World!"
45
+ *
46
+ * decode("SGVsbG8sIFdvcmxkIQ==", "standard");
47
+ * // => "Hello, World!"
48
+ * ```
49
+ *
50
+ * @param input - The Base64 encoded string.
51
+ * @param charset - The charset variant to use (default: "standard").
52
+ * @returns The decoded string.
53
+ * @throws Error if the input contains invalid characters.
54
+ */
55
+ declare function decode(input: string, charset?: Base64CharsetType): string;
56
+ export { encode, decode, Base64Charset };
57
+ export type { Base64CharsetType };
58
+ //# sourceMappingURL=base64.d.ts.map
package/src/base64.js ADDED
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Base64 encoding/decoding with multiple charset variants.
3
+ * @module base64
4
+ */
5
+ /**
6
+ * Available Base64 charset variants.
7
+ * - `standard`: RFC 4648 standard alphabet (A-Z, a-z, 0-9, +, /)
8
+ * - `urlsafe`: URL and filename safe (A-Z, a-z, 0-9, -, _)
9
+ * - `imap`: Modified Base64 for IMAP mailbox names (A-Z, a-z, 0-9, +, ,)
10
+ * - `radix64`: Base64 variant used in OpenPGP (A-Z, a-z, 0-9, +, /)
11
+ */
12
+ const Base64Charset = ["standard", "urlsafe", "imap", "radix64"];
13
+ /**
14
+ * Charset alphabets for Base64 variants.
15
+ */
16
+ const CHARSETS = {
17
+ standard: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
18
+ urlsafe: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
19
+ imap: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,",
20
+ radix64: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
21
+ };
22
+ /**
23
+ * Padding character for Base64 encoding.
24
+ */
25
+ const PAD = "=";
26
+ /**
27
+ * Build a reverse lookup table for decoding.
28
+ * @param alphabet - The 64-character alphabet string.
29
+ * @returns Map of character to index.
30
+ */
31
+ function buildDecodeTable(alphabet) {
32
+ const table = new Map();
33
+ for (let i = 0; i < alphabet.length; i++) {
34
+ const char = alphabet[i];
35
+ if (char !== undefined) {
36
+ table.set(char, i);
37
+ }
38
+ }
39
+ return table;
40
+ }
41
+ /**
42
+ * Pre-built decode tables for each charset.
43
+ */
44
+ const DECODE_TABLES = {
45
+ standard: buildDecodeTable(CHARSETS.standard),
46
+ urlsafe: buildDecodeTable(CHARSETS.urlsafe),
47
+ imap: buildDecodeTable(CHARSETS.imap),
48
+ radix64: buildDecodeTable(CHARSETS.radix64)
49
+ };
50
+ /**
51
+ * Encode a string to Base64.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * import { encode } from "./base64.js";
56
+ *
57
+ * encode("Hello, World!");
58
+ * // => "SGVsbG8sIFdvcmxkIQ=="
59
+ *
60
+ * encode("Hello, World!", "urlsafe");
61
+ * // => "SGVsbG8sIFdvcmxkIQ=="
62
+ * ```
63
+ *
64
+ * @param input - The string to encode.
65
+ * @param charset - The charset variant to use (default: "standard").
66
+ * @returns The Base64 encoded string.
67
+ */
68
+ function encode(input, charset = "standard") {
69
+ const alphabet = CHARSETS[charset];
70
+ const bytes = new TextEncoder().encode(input);
71
+ let result = "";
72
+ for (let i = 0; i < bytes.length; i += 3) {
73
+ const b0 = bytes[i] ?? 0;
74
+ const b1 = i + 1 < bytes.length ? (bytes[i + 1] ?? 0) : 0;
75
+ const b2 = i + 2 < bytes.length ? (bytes[i + 2] ?? 0) : 0;
76
+ const triple = (b0 << 16) | (b1 << 8) | b2;
77
+ result += alphabet[(triple >> 18) & 0x3f];
78
+ result += alphabet[(triple >> 12) & 0x3f];
79
+ result += i + 1 < bytes.length ? alphabet[(triple >> 6) & 0x3f] : PAD;
80
+ result += i + 2 < bytes.length ? alphabet[triple & 0x3f] : PAD;
81
+ }
82
+ return result;
83
+ }
84
+ /**
85
+ * Decode a Base64 string.
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * import { decode } from "./base64.js";
90
+ *
91
+ * decode("SGVsbG8sIFdvcmxkIQ==");
92
+ * // => "Hello, World!"
93
+ *
94
+ * decode("SGVsbG8sIFdvcmxkIQ==", "standard");
95
+ * // => "Hello, World!"
96
+ * ```
97
+ *
98
+ * @param input - The Base64 encoded string.
99
+ * @param charset - The charset variant to use (default: "standard").
100
+ * @returns The decoded string.
101
+ * @throws Error if the input contains invalid characters.
102
+ */
103
+ function decode(input, charset = "standard") {
104
+ const decodeTable = DECODE_TABLES[charset];
105
+ // Remove padding
106
+ const cleanInput = input.replace(/=+$/, "");
107
+ const bytes = [];
108
+ for (let i = 0; i < cleanInput.length; i += 4) {
109
+ const c0 = cleanInput[i];
110
+ const c1 = cleanInput[i + 1];
111
+ const c2 = cleanInput[i + 2];
112
+ const c3 = cleanInput[i + 3];
113
+ if (c0 === undefined) {
114
+ break;
115
+ }
116
+ const v0 = decodeTable.get(c0);
117
+ const v1 = c1 !== undefined ? decodeTable.get(c1) : 0;
118
+ const v2 = c2 !== undefined ? decodeTable.get(c2) : 0;
119
+ const v3 = c3 !== undefined ? decodeTable.get(c3) : 0;
120
+ if (v0 === undefined) {
121
+ throw new Error(`Invalid Base64 character: ${c0}`);
122
+ }
123
+ if (c1 !== undefined && v1 === undefined) {
124
+ throw new Error(`Invalid Base64 character: ${c1}`);
125
+ }
126
+ const triple = ((v0 ?? 0) << 18) | ((v1 ?? 0) << 12) | ((v2 ?? 0) << 6) | (v3 ?? 0);
127
+ bytes.push((triple >> 16) & 0xff);
128
+ if (c2 !== undefined) {
129
+ bytes.push((triple >> 8) & 0xff);
130
+ }
131
+ if (c3 !== undefined) {
132
+ bytes.push(triple & 0xff);
133
+ }
134
+ }
135
+ return new TextDecoder().decode(new Uint8Array(bytes));
136
+ }
137
+ export { encode, decode, Base64Charset };
138
+ //# sourceMappingURL=base64.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=base64.test.d.ts.map