@otplib/plugin-base32-scure 13.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gerald Yeo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,229 @@
1
+ # @otplib/plugin-base32-scure
2
+
3
+ Base32 encoding/decoding plugin for otplib using the audited `@scure/base` library.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @otplib/plugin-base32-scure
9
+ pnpm add @otplib/plugin-base32-scure
10
+ yarn add @otplib/plugin-base32-scure
11
+ ```
12
+
13
+ ## Overview
14
+
15
+ This plugin provides Base32 encoding and decoding using `@scure/base`, a cryptographic library from the authors of `noble-ciphers`. It offers excellent performance, extensive auditing, and comprehensive TypeScript support.
16
+
17
+ ## Usage
18
+
19
+ ### Basic Usage
20
+
21
+ ```typescript
22
+ import { generateSecret, generate } from "otplib";
23
+ import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
24
+ import { NodeCryptoPlugin } from "@otplib/plugin-crypto-node";
25
+
26
+ const base32 = new ScureBase32Plugin();
27
+ const crypto = new NodeCryptoPlugin();
28
+
29
+ // Generate a secret
30
+ const secret = generateSecret({ crypto, base32 });
31
+
32
+ // Generate a token
33
+ const token = await generate({
34
+ secret,
35
+ crypto,
36
+ base32,
37
+ });
38
+ ```
39
+
40
+ ### Encoding and Decoding
41
+
42
+ ```typescript
43
+ import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
44
+
45
+ const base32 = new ScureBase32Plugin();
46
+
47
+ // Encode binary data to Base32
48
+ const data = new Uint8Array([1, 2, 3, 4, 5]);
49
+ const encoded = base32.encode(data, { padding: true });
50
+ // Output: "AEBAGBAF"
51
+
52
+ // Decode Base32 string to binary
53
+ const decoded = base32.decode("AEBAGBAF");
54
+ // Output: Uint8Array [1, 2, 3, 4, 5]
55
+ ```
56
+
57
+ ### With Custom Options
58
+
59
+ ```typescript
60
+ import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
61
+
62
+ const base32 = new ScureBase32Plugin();
63
+
64
+ // Encode without padding
65
+ const encoded = base32.encode(data, { padding: false });
66
+ // Output: "AEBAGBAF"
67
+
68
+ // Decode handles both padded and unpadded strings
69
+ const decoded1 = base32.decode("AEBAGBAF===="); // With padding
70
+ const decoded2 = base32.decode("AEBAGBAF"); // Without padding
71
+ ```
72
+
73
+ ## When to Use
74
+
75
+ Use this plugin when:
76
+
77
+ - You want an audited, security-focused implementation
78
+ - Performance is critical
79
+ - You need comprehensive input validation
80
+ - You're building security-critical applications
81
+ - You prefer libraries with active maintenance and security audits
82
+
83
+ ## Platform Support
84
+
85
+ Works in all environments:
86
+
87
+ - Node.js (all versions)
88
+ - Browsers (Chrome, Firefox, Safari, Edge)
89
+ - Edge runtimes (Cloudflare Workers, Vercel Edge)
90
+ - Deno
91
+ - Bun
92
+
93
+ ## Examples
94
+
95
+ ### TOTP with Scure Base32
96
+
97
+ ```typescript
98
+ import { generateSecret, generate } from "otplib";
99
+ import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
100
+ import { NodeCryptoPlugin } from "@otplib/plugin-crypto-node";
101
+
102
+ const base32 = new ScureBase32Plugin();
103
+ const crypto = new NodeCryptoPlugin();
104
+
105
+ const secret = generateSecret({ crypto, base32 });
106
+ console.log(secret); // Base32-encoded secret
107
+
108
+ const token = await generate({ secret, crypto, base32 });
109
+ console.log(token); // 6-digit token
110
+ ```
111
+
112
+ ### Web Environment
113
+
114
+ ```typescript
115
+ import { generateSecret, generate } from "otplib";
116
+ import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
117
+ import { WebCryptoPlugin } from "@otplib/plugin-crypto-web";
118
+
119
+ const base32 = new ScureBase32Plugin();
120
+ const crypto = new WebCryptoPlugin();
121
+
122
+ const secret = await generateSecret({ crypto, base32 });
123
+ const token = await generate({ secret, crypto, base32 });
124
+ ```
125
+
126
+ ### Manual Secret Generation
127
+
128
+ ```typescript
129
+ import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
130
+ import { NodeCryptoPlugin } from "@otplib/plugin-crypto-node";
131
+
132
+ const base32 = new ScureBase32Plugin();
133
+ const crypto = new NodeCryptoPlugin();
134
+
135
+ // Generate random secret
136
+ const secretBytes = crypto.randomBytes(20);
137
+ const secret = base32.encode(secretBytes, { padding: false });
138
+
139
+ console.log(secret); // Base32 secret for TOTP
140
+ ```
141
+
142
+ ### Edge Runtime (Cloudflare Worker)
143
+
144
+ ```typescript
145
+ import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
146
+ import { WebCryptoPlugin } from "@otplib/plugin-crypto-web";
147
+
148
+ export default {
149
+ async fetch(request) {
150
+ const base32 = new ScureBase32Plugin();
151
+ const crypto = new WebCryptoPlugin();
152
+
153
+ // Generate secret
154
+ const secretBytes = await crypto.randomBytes(20);
155
+ const secret = base32.encode(secretBytes, { padding: false });
156
+
157
+ return new Response(JSON.stringify({ secret }));
158
+ },
159
+ };
160
+ ```
161
+
162
+ ## Advanced Usage
163
+
164
+ ### Custom Validation
165
+
166
+ ```typescript
167
+ import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
168
+
169
+ const base32 = new ScureBase32Plugin();
170
+
171
+ function validateAndDecode(input: string): Uint8Array | null {
172
+ try {
173
+ // @scure/base validates:
174
+ // - Character set (A-Z, 2-7)
175
+ // - Length (must be multiple of 8 with padding, or correct without)
176
+ // - Padding (if present, must be correct)
177
+ return base32.decode(input);
178
+ } catch (error) {
179
+ console.error("Invalid Base32:", error.message);
180
+ return null;
181
+ }
182
+ }
183
+
184
+ const valid = validateAndDecode("JBSWY3DPEHPK3PXP");
185
+ const invalid = validateAndDecode("invalid@base32!");
186
+ ```
187
+
188
+ ### Integration with Other Libraries
189
+
190
+ ```typescript
191
+ import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
192
+ import { base32 as scureBase32 } from "@scure/base";
193
+
194
+ const plugin = new ScureBase32Plugin();
195
+
196
+ // Use plugin's convenience methods
197
+ const encoded = plugin.encode(data);
198
+
199
+ // Or use @scure/base directly for advanced options
200
+ const encoded = scureBase32.encode(data, { padding: false });
201
+ ```
202
+
203
+ ## Dependencies
204
+
205
+ ```json
206
+ {
207
+ "dependencies": {
208
+ "@scure/base": "^1.1.0"
209
+ }
210
+ }
211
+ ```
212
+
213
+ ## Related Packages
214
+
215
+ - `@scure/base` - Audited encoding/decoding library
216
+ - `@otplib/core` - Core types and interfaces
217
+ - `@otplib/plugin-crypto-node` - Node.js crypto plugin
218
+ - `@otplib/plugin-crypto-web` - Web Crypto API plugin
219
+
220
+ ## Documentation
221
+
222
+ Full documentation available at [otplib.yeojz.dev](https://otplib.yeojz.dev):
223
+
224
+ - [Getting Started Guide](https://otplib.yeojz.dev/guide/getting-started)
225
+ - [API Reference](https://otplib.yeojz.dev/api/)
226
+
227
+ ## License
228
+
229
+ [MIT](./LICENSE) © 2026 Gerald Yeo
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var a=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var l=(o,e)=>{for(var r in e)a(o,r,{get:e[r],enumerable:!0})},m=(o,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of i(e))!p.call(o,t)&&t!==r&&a(o,t,{get:()=>e[t],enumerable:!(n=d(e,t))||n.enumerable});return o};var g=o=>m(a({},"__esModule",{value:!0}),o);var B={};l(B,{ScureBase32Plugin:()=>s,base32:()=>f,default:()=>u});module.exports=g(B);var c=require("@scure/base"),s=class{name="scure";encode(e,r={}){let{padding:n=!1}=r,t=c.base32.encode(e);return n?t:t.replace(/=+$/,"")}decode(e){try{let r=e.toUpperCase(),n=r.padEnd(Math.ceil(r.length/8)*8,"=");return c.base32.decode(n)}catch(r){throw r instanceof Error?new Error(`Invalid Base32 string: ${r.message}`):new Error("Invalid Base32 string")}}},f=Object.freeze(new s),u=s;0&&(module.exports={ScureBase32Plugin,base32});
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @otplib/plugin-base32-scure\n *\n * Base32 plugin for otplib using @scure/base.\n * Works universally across all JavaScript runtimes.\n */\n\nimport { base32 as scureBase32 } from \"@scure/base\";\n\nimport type { Base32EncodeOptions } from \"@otplib/core\";\nimport type { Base32Plugin } from \"@otplib/core\";\n\n/**\n * Scure Base32 plugin\n *\n * This implementation uses @scure/base for Base32 encoding/decoding.\n * @scure/base is a modern, audited cryptography library with zero dependencies.\n *\n * @example\n * ```ts\n * import { ScureBase32Plugin } from '@otplib/plugin-base32-scure';\n *\n * const plugin = new ScureBase32Plugin();\n * const encoded = plugin.encode(data);\n * const decoded = plugin.decode(encoded);\n * ```\n */\nexport class ScureBase32Plugin implements Base32Plugin {\n readonly name = \"scure\";\n\n /**\n * Encode binary data to Base32 string\n *\n * @param data - Uint8Array to encode\n * @param options - Encoding options\n * @returns Base32 encoded string\n */\n encode(data: Uint8Array, options: Base32EncodeOptions = {}): string {\n const { padding = false } = options;\n\n const encoded = scureBase32.encode(data);\n return padding ? encoded : encoded.replace(/=+$/, \"\");\n }\n\n /**\n * Decode Base32 string to binary data\n *\n * @param str - Base32 string to decode\n * @returns Decoded Uint8Array\n * @throws {Error} If string contains invalid characters\n */\n decode(str: string): Uint8Array {\n try {\n const uppercased = str.toUpperCase();\n const padded = uppercased.padEnd(Math.ceil(uppercased.length / 8) * 8, \"=\");\n return scureBase32.decode(padded);\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Invalid Base32 string: ${error.message}`);\n }\n throw new Error(\"Invalid Base32 string\");\n }\n }\n}\n\n/**\n * Default singleton instance for convenience\n *\n * @example\n * ```ts\n * import { base32 } from '@otplib/plugin-base32-scure';\n *\n * const encoded = base32.encode(data);\n * ```\n */\nexport const base32: Base32Plugin = Object.freeze(new ScureBase32Plugin());\n\nexport default ScureBase32Plugin;\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,EAAA,WAAAC,EAAA,YAAAC,IAAA,eAAAC,EAAAL,GAOA,IAAAM,EAAsC,uBAoBzBJ,EAAN,KAAgD,CAC5C,KAAO,QAShB,OAAOK,EAAkBC,EAA+B,CAAC,EAAW,CAClE,GAAM,CAAE,QAAAC,EAAU,EAAM,EAAID,EAEtBE,EAAU,EAAAC,OAAY,OAAOJ,CAAI,EACvC,OAAOE,EAAUC,EAAUA,EAAQ,QAAQ,MAAO,EAAE,CACtD,CASA,OAAOE,EAAyB,CAC9B,GAAI,CACF,IAAMC,EAAaD,EAAI,YAAY,EAC7BE,EAASD,EAAW,OAAO,KAAK,KAAKA,EAAW,OAAS,CAAC,EAAI,EAAG,GAAG,EAC1E,OAAO,EAAAF,OAAY,OAAOG,CAAM,CAClC,OAASC,EAAO,CACd,MAAIA,aAAiB,MACb,IAAI,MAAM,0BAA0BA,EAAM,OAAO,EAAE,EAErD,IAAI,MAAM,uBAAuB,CACzC,CACF,CACF,EAYaZ,EAAuB,OAAO,OAAO,IAAID,CAAmB,EAElEE,EAAQF","names":["index_exports","__export","ScureBase32Plugin","base32","index_default","__toCommonJS","import_base","data","options","padding","encoded","scureBase32","str","uppercased","padded","error"]}
@@ -0,0 +1,56 @@
1
+ import { Base32Plugin, Base32EncodeOptions } from '@otplib/core';
2
+
3
+ /**
4
+ * @otplib/plugin-base32-scure
5
+ *
6
+ * Base32 plugin for otplib using @scure/base.
7
+ * Works universally across all JavaScript runtimes.
8
+ */
9
+
10
+ /**
11
+ * Scure Base32 plugin
12
+ *
13
+ * This implementation uses @scure/base for Base32 encoding/decoding.
14
+ * @scure/base is a modern, audited cryptography library with zero dependencies.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { ScureBase32Plugin } from '@otplib/plugin-base32-scure';
19
+ *
20
+ * const plugin = new ScureBase32Plugin();
21
+ * const encoded = plugin.encode(data);
22
+ * const decoded = plugin.decode(encoded);
23
+ * ```
24
+ */
25
+ declare class ScureBase32Plugin implements Base32Plugin {
26
+ readonly name = "scure";
27
+ /**
28
+ * Encode binary data to Base32 string
29
+ *
30
+ * @param data - Uint8Array to encode
31
+ * @param options - Encoding options
32
+ * @returns Base32 encoded string
33
+ */
34
+ encode(data: Uint8Array, options?: Base32EncodeOptions): string;
35
+ /**
36
+ * Decode Base32 string to binary data
37
+ *
38
+ * @param str - Base32 string to decode
39
+ * @returns Decoded Uint8Array
40
+ * @throws {Error} If string contains invalid characters
41
+ */
42
+ decode(str: string): Uint8Array;
43
+ }
44
+ /**
45
+ * Default singleton instance for convenience
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * import { base32 } from '@otplib/plugin-base32-scure';
50
+ *
51
+ * const encoded = base32.encode(data);
52
+ * ```
53
+ */
54
+ declare const base32: Base32Plugin;
55
+
56
+ export { ScureBase32Plugin, base32, ScureBase32Plugin as default };
@@ -0,0 +1,56 @@
1
+ import { Base32Plugin, Base32EncodeOptions } from '@otplib/core';
2
+
3
+ /**
4
+ * @otplib/plugin-base32-scure
5
+ *
6
+ * Base32 plugin for otplib using @scure/base.
7
+ * Works universally across all JavaScript runtimes.
8
+ */
9
+
10
+ /**
11
+ * Scure Base32 plugin
12
+ *
13
+ * This implementation uses @scure/base for Base32 encoding/decoding.
14
+ * @scure/base is a modern, audited cryptography library with zero dependencies.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { ScureBase32Plugin } from '@otplib/plugin-base32-scure';
19
+ *
20
+ * const plugin = new ScureBase32Plugin();
21
+ * const encoded = plugin.encode(data);
22
+ * const decoded = plugin.decode(encoded);
23
+ * ```
24
+ */
25
+ declare class ScureBase32Plugin implements Base32Plugin {
26
+ readonly name = "scure";
27
+ /**
28
+ * Encode binary data to Base32 string
29
+ *
30
+ * @param data - Uint8Array to encode
31
+ * @param options - Encoding options
32
+ * @returns Base32 encoded string
33
+ */
34
+ encode(data: Uint8Array, options?: Base32EncodeOptions): string;
35
+ /**
36
+ * Decode Base32 string to binary data
37
+ *
38
+ * @param str - Base32 string to decode
39
+ * @returns Decoded Uint8Array
40
+ * @throws {Error} If string contains invalid characters
41
+ */
42
+ decode(str: string): Uint8Array;
43
+ }
44
+ /**
45
+ * Default singleton instance for convenience
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * import { base32 } from '@otplib/plugin-base32-scure';
50
+ *
51
+ * const encoded = base32.encode(data);
52
+ * ```
53
+ */
54
+ declare const base32: Base32Plugin;
55
+
56
+ export { ScureBase32Plugin, base32, ScureBase32Plugin as default };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import{base32 as s}from"@scure/base";var r=class{name="scure";encode(o,e={}){let{padding:t=!1}=e,n=s.encode(o);return t?n:n.replace(/=+$/,"")}decode(o){try{let e=o.toUpperCase(),t=e.padEnd(Math.ceil(e.length/8)*8,"=");return s.decode(t)}catch(e){throw e instanceof Error?new Error(`Invalid Base32 string: ${e.message}`):new Error("Invalid Base32 string")}}},d=Object.freeze(new r),i=r;export{r as ScureBase32Plugin,d as base32,i as default};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @otplib/plugin-base32-scure\n *\n * Base32 plugin for otplib using @scure/base.\n * Works universally across all JavaScript runtimes.\n */\n\nimport { base32 as scureBase32 } from \"@scure/base\";\n\nimport type { Base32EncodeOptions } from \"@otplib/core\";\nimport type { Base32Plugin } from \"@otplib/core\";\n\n/**\n * Scure Base32 plugin\n *\n * This implementation uses @scure/base for Base32 encoding/decoding.\n * @scure/base is a modern, audited cryptography library with zero dependencies.\n *\n * @example\n * ```ts\n * import { ScureBase32Plugin } from '@otplib/plugin-base32-scure';\n *\n * const plugin = new ScureBase32Plugin();\n * const encoded = plugin.encode(data);\n * const decoded = plugin.decode(encoded);\n * ```\n */\nexport class ScureBase32Plugin implements Base32Plugin {\n readonly name = \"scure\";\n\n /**\n * Encode binary data to Base32 string\n *\n * @param data - Uint8Array to encode\n * @param options - Encoding options\n * @returns Base32 encoded string\n */\n encode(data: Uint8Array, options: Base32EncodeOptions = {}): string {\n const { padding = false } = options;\n\n const encoded = scureBase32.encode(data);\n return padding ? encoded : encoded.replace(/=+$/, \"\");\n }\n\n /**\n * Decode Base32 string to binary data\n *\n * @param str - Base32 string to decode\n * @returns Decoded Uint8Array\n * @throws {Error} If string contains invalid characters\n */\n decode(str: string): Uint8Array {\n try {\n const uppercased = str.toUpperCase();\n const padded = uppercased.padEnd(Math.ceil(uppercased.length / 8) * 8, \"=\");\n return scureBase32.decode(padded);\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Invalid Base32 string: ${error.message}`);\n }\n throw new Error(\"Invalid Base32 string\");\n }\n }\n}\n\n/**\n * Default singleton instance for convenience\n *\n * @example\n * ```ts\n * import { base32 } from '@otplib/plugin-base32-scure';\n *\n * const encoded = base32.encode(data);\n * ```\n */\nexport const base32: Base32Plugin = Object.freeze(new ScureBase32Plugin());\n\nexport default ScureBase32Plugin;\n"],"mappings":"AAOA,OAAS,UAAUA,MAAmB,cAoB/B,IAAMC,EAAN,KAAgD,CAC5C,KAAO,QAShB,OAAOC,EAAkBC,EAA+B,CAAC,EAAW,CAClE,GAAM,CAAE,QAAAC,EAAU,EAAM,EAAID,EAEtBE,EAAUL,EAAY,OAAOE,CAAI,EACvC,OAAOE,EAAUC,EAAUA,EAAQ,QAAQ,MAAO,EAAE,CACtD,CASA,OAAOC,EAAyB,CAC9B,GAAI,CACF,IAAMC,EAAaD,EAAI,YAAY,EAC7BE,EAASD,EAAW,OAAO,KAAK,KAAKA,EAAW,OAAS,CAAC,EAAI,EAAG,GAAG,EAC1E,OAAOP,EAAY,OAAOQ,CAAM,CAClC,OAASC,EAAO,CACd,MAAIA,aAAiB,MACb,IAAI,MAAM,0BAA0BA,EAAM,OAAO,EAAE,EAErD,IAAI,MAAM,uBAAuB,CACzC,CACF,CACF,EAYaC,EAAuB,OAAO,OAAO,IAAIT,CAAmB,EAElEU,EAAQV","names":["scureBase32","ScureBase32Plugin","data","options","padding","encoded","str","uppercased","padded","error","base32","index_default"]}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@otplib/plugin-base32-scure",
3
+ "version": "13.0.0",
4
+ "description": "Base32 plugin for otplib using @scure/base",
5
+ "license": "MIT",
6
+ "author": "Gerald Yeo <support@yeojz.dev>",
7
+ "homepage": "https://otplib.yeojz.dev",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/yeojz/otplib.git",
11
+ "directory": "packages/plugin-base32-scure"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/yeojz/otplib/issues"
15
+ },
16
+ "keywords": [
17
+ "otp",
18
+ "base32",
19
+ "encoding",
20
+ "plugin"
21
+ ],
22
+ "sideEffects": false,
23
+ "type": "module",
24
+ "main": "./dist/index.cjs",
25
+ "module": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "import": {
30
+ "types": "./dist/index.d.ts",
31
+ "default": "./dist/index.js"
32
+ },
33
+ "require": {
34
+ "types": "./dist/index.d.cts",
35
+ "default": "./dist/index.cjs"
36
+ }
37
+ }
38
+ },
39
+ "files": [
40
+ "dist",
41
+ "README.md",
42
+ "LICENSE"
43
+ ],
44
+ "dependencies": {
45
+ "@scure/base": "^1.1.7",
46
+ "@otplib/core": "13.0.0"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^25.0.3",
50
+ "tsup": "^8.5.1",
51
+ "typescript": "^5.9.3",
52
+ "vitest": "^4.0.16"
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "scripts": {
58
+ "build": "tsup",
59
+ "dev": "tsup --watch",
60
+ "test": "vitest",
61
+ "test:ci": "vitest run --coverage",
62
+ "typecheck": "tsc --noEmit",
63
+ "lint": "eslint src/",
64
+ "clean": "rm -rf dist .tsbuildinfo"
65
+ }
66
+ }