@nowarajs/totp 1.1.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/CHANGELOG.md +75 -0
- package/LICENSE +21 -0
- package/README.md +216 -0
- package/dist/chunk-4qsch0ea.js +10 -0
- package/dist/chunk-hhdy89hc.js +26 -0
- package/dist/enums/index.d.ts +1 -0
- package/dist/enums/index.js +7 -0
- package/dist/enums/totpErrorKeys.d.ts +7 -0
- package/dist/hotp.d.ts +11 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +108 -0
- package/dist/otpAuthUri.d.ts +21 -0
- package/dist/totp.d.ts +23 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.js +1 -0
- package/dist/types/otpAuthUri.d.ts +35 -0
- package/dist/types/totpOptions.d.ts +23 -0
- package/dist/types/verifyOptions.d.ts +18 -0
- package/dist/utils/base32.d.ts +19 -0
- package/dist/utils/createCounterBuffer.d.ts +8 -0
- package/dist/utils/dynamicTruncation.d.ts +9 -0
- package/dist/utils/generateHmac.d.ts +9 -0
- package/dist/utils/generateSecretBytes.d.ts +10 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +80 -0
- package/dist/utils/timeRemaining.d.ts +9 -0
- package/package.json +94 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
|
|
2
|
+
## v1.1.2
|
|
3
|
+
|
|
4
|
+
[compare changes](https://github.com/NowaraJS/totp/compare/v1.1.1...v1.1.2)
|
|
5
|
+
|
|
6
|
+
### ๐ฆ Chore
|
|
7
|
+
|
|
8
|
+
- **๐ฆ:** [Update package.json with correct name and description] ([e007586](https://github.com/NowaraJS/totp/commit/e007586))
|
|
9
|
+
|
|
10
|
+
### โค๏ธ Contributors
|
|
11
|
+
|
|
12
|
+
- Komiroko <komiriko@pm.me>
|
|
13
|
+
|
|
14
|
+
## v1.1.1
|
|
15
|
+
|
|
16
|
+
[compare changes](https://github.com/NowaraJS/totp/compare/v1.1.0...v1.1.1)
|
|
17
|
+
|
|
18
|
+
### ๐ Documentation
|
|
19
|
+
|
|
20
|
+
- **๐:** [Update README with comprehensive TOTP features and usage] ([e8f8369](https://github.com/NowaraJS/totp/commit/e8f8369))
|
|
21
|
+
|
|
22
|
+
### โค๏ธ Contributors
|
|
23
|
+
|
|
24
|
+
- Komiroko <komiriko@pm.me>
|
|
25
|
+
|
|
26
|
+
## v1.1.0
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### ๐ Enhancements
|
|
30
|
+
|
|
31
|
+
- **๐:** [Add Base32 encoding and decoding utilities] ([580be95](https://github.com/NowaraJS/totp/commit/580be95))
|
|
32
|
+
- **๐:** [Add TOTP error keys enumeration] ([cd31d9d](https://github.com/NowaraJS/totp/commit/cd31d9d))
|
|
33
|
+
- **๐:** [Add createCounterBuffer utility for big-endian conversion] ([6effcbf](https://github.com/NowaraJS/totp/commit/6effcbf))
|
|
34
|
+
- **๐:** [Add dynamic truncation utility for HMAC results] ([8b9d226](https://github.com/NowaraJS/totp/commit/8b9d226))
|
|
35
|
+
- **๐:** [Add generateHmac utility for HMAC generation] ## Features - Introduced a new utility function `generateHmac` for generating HMACs. ([86a62ee](https://github.com/NowaraJS/totp/commit/86a62ee))
|
|
36
|
+
- **๐:** [Add generateSecretBytes utility for TOTP secret generation] ([f0fa3b4](https://github.com/NowaraJS/totp/commit/f0fa3b4))
|
|
37
|
+
- **๐:** [Add timeRemaining utility for TOTP code calculation] ([38c2591](https://github.com/NowaraJS/totp/commit/38c2591))
|
|
38
|
+
- **๐:** [Implement HMAC-based One-Time Password (HOTP) functionality] ([57cc8db](https://github.com/NowaraJS/totp/commit/57cc8db))
|
|
39
|
+
- **๐:** [Add OTPAuth URI building and parsing functionality] ([3c3108c](https://github.com/NowaraJS/totp/commit/3c3108c))
|
|
40
|
+
- **๐:** [Add TOTP implementation and verification functionality] ([e9ca7da](https://github.com/NowaraJS/totp/commit/e9ca7da))
|
|
41
|
+
|
|
42
|
+
### ๐ Documentation
|
|
43
|
+
|
|
44
|
+
- **๐:** [Update copilot instructions for clarity and structure] ([57ca1ea](https://github.com/NowaraJS/totp/commit/57ca1ea))
|
|
45
|
+
|
|
46
|
+
### ๐ฆ Build
|
|
47
|
+
|
|
48
|
+
- **๐ฆ:** [Update devDependencies and exports in package.json] ([2e32770](https://github.com/NowaraJS/totp/commit/2e32770))
|
|
49
|
+
- **๐ฆ:** [Refactor entrypoints in builder.ts for clarity] ([7e241b4](https://github.com/NowaraJS/totp/commit/7e241b4))
|
|
50
|
+
- **๐ฆ:** [Clean and add entrypoints] ([6a82236](https://github.com/NowaraJS/totp/commit/6a82236))
|
|
51
|
+
|
|
52
|
+
### ๐ฆ Chore
|
|
53
|
+
|
|
54
|
+
- **๐ฆ:** [Remove unused utility files and related tests] ## Chores - Deleted `exampleKeyError.ts`, `foo.ts`, and their corresponding test files. ## Description This commit removes unused utility files and their associated tests to clean up the codebase and reduce clutter. These files are no longer needed and their removal helps maintain a more manageable project structure. ([62c6231](https://github.com/NowaraJS/totp/commit/62c6231))
|
|
55
|
+
|
|
56
|
+
### ๐งช Tests
|
|
57
|
+
|
|
58
|
+
- **๐งช:** [Add unit tests for Base32 encoding and decoding] ([7292a8d](https://github.com/NowaraJS/totp/commit/7292a8d))
|
|
59
|
+
- **๐งช:** [Add unit tests for createCounterBuffer utility] ([b13eea0](https://github.com/NowaraJS/totp/commit/b13eea0))
|
|
60
|
+
- **๐งช:** [Add unit tests for dynamic truncation utility] ([9dfb41c](https://github.com/NowaraJS/totp/commit/9dfb41c))
|
|
61
|
+
- **๐งช:** [Add unit tests for generateHmac utility] ([67aa60b](https://github.com/NowaraJS/totp/commit/67aa60b))
|
|
62
|
+
- **๐งช:** [Add unit tests for generateSecretBytes utility] ([52f2ec6](https://github.com/NowaraJS/totp/commit/52f2ec6))
|
|
63
|
+
- **๐งช:** [Add unit tests for timeRemaining utility] ## Tests - Introduced unit tests for the timeRemaining utility function. ## Description This commit adds a test suite for the timeRemaining function, ensuring that it correctly calculates the remaining time until the next TOTP code based on a specified period. The test checks that the remaining time is less than the period, validating the function's expected behavior. ([ae820e8](https://github.com/NowaraJS/totp/commit/ae820e8))
|
|
64
|
+
- **๐งช:** [Add unit tests for HOTP code generation] ([932fb33](https://github.com/NowaraJS/totp/commit/932fb33))
|
|
65
|
+
- **๐งช:** [Add unit tests for OTP Auth URI building and parsing] ## Tests - Implemented unit tests for `buildOtpAuthUri` to ensure it constructs a valid OTP Auth URI. - Added tests for `parseOtpAuthUri` to validate parsing of a valid OTP Auth URI and error handling for invalid cases. ([6160cbd](https://github.com/NowaraJS/totp/commit/6160cbd))
|
|
66
|
+
- **๐งช:** [Add unit tests for TOTP generation and verification] ## Tests - Added tests for TOTP code generation to ensure it produces a valid 6-digit code. - Implemented tests for TOTP code verification, including both valid and invalid scenarios. ## Description This commit introduces unit tests for the TOTP functionality, validating both the generation of TOTP codes and their verification. The tests check that generated codes are of the correct length and format, and that the verification function correctly identifies valid and invalid codes. ([445a954](https://github.com/NowaraJS/totp/commit/445a954))
|
|
67
|
+
|
|
68
|
+
### ๐ค CI
|
|
69
|
+
|
|
70
|
+
- **๐ค:** [Enhance CI workflows with additional MSSQL secrets] ([b96813c](https://github.com/NowaraJS/totp/commit/b96813c))
|
|
71
|
+
|
|
72
|
+
### โค๏ธ Contributors
|
|
73
|
+
|
|
74
|
+
- Komiroko <komiriko@pm.me>
|
|
75
|
+
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 [Project Name]
|
|
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,216 @@
|
|
|
1
|
+
# ๐ NowaraJS - TOTP
|
|
2
|
+
|
|
3
|
+
## ๐ Table of Contents
|
|
4
|
+
|
|
5
|
+
- [๐ NowaraJS - TOTP](#-nowarajs---totp)
|
|
6
|
+
- [๐ Table of Contents](#-table-of-contents)
|
|
7
|
+
- [๐ Description](#-description)
|
|
8
|
+
- [โจ Features](#-features)
|
|
9
|
+
- [๐ง Installation](#-installation)
|
|
10
|
+
- [โ๏ธ Usage](#-usage)
|
|
11
|
+
- [Basic TOTP Generation](#basic-totp-generation)
|
|
12
|
+
- [TOTP Verification](#totp-verification)
|
|
13
|
+
- [HOTP Support](#hotp-support)
|
|
14
|
+
- [OTPAuth URI Generation](#otpauth-uri-generation)
|
|
15
|
+
- [Secret Generation](#secret-generation)
|
|
16
|
+
- [๐ Advanced Configuration](#-advanced-configuration)
|
|
17
|
+
- [๐ ๏ธ Utilities](#-utilities)
|
|
18
|
+
- [๐ API Reference](#-api-reference)
|
|
19
|
+
- [โ๏ธ License](#-license)
|
|
20
|
+
- [๐ง Contact](#-contact)
|
|
21
|
+
|
|
22
|
+
## ๐ Description
|
|
23
|
+
|
|
24
|
+
> A comprehensive Time-based One-Time Password (TOTP) and HMAC-based One-Time Password (HOTP) implementation for TypeScript/JavaScript.
|
|
25
|
+
|
|
26
|
+
**NowaraJS TOTP** provides a secure and RFC-compliant implementation of TOTP and HOTP algorithms with full support for QR code generation, secret management, and various authentication configurations. Perfect for implementing two-factor authentication (2FA) in your applications.
|
|
27
|
+
|
|
28
|
+
## โจ Features
|
|
29
|
+
|
|
30
|
+
- ๐ **RFC 6238 TOTP**: Full RFC-compliant Time-based One-Time Password implementation
|
|
31
|
+
- ๐ **RFC 4226 HOTP**: Complete HMAC-based One-Time Password support
|
|
32
|
+
- ๐ฑ **QR Code Support**: Generate OTPAuth URIs for easy mobile app integration
|
|
33
|
+
- ๐ **Crypto Secure**: Uses Web Crypto API for secure random number generation
|
|
34
|
+
- โก **High Performance**: Optimized for speed with minimal dependencies
|
|
35
|
+
- ๐ ๏ธ **Configurable**: Support for different algorithms (SHA-1, SHA-256, SHA-512)
|
|
36
|
+
- ๐ **Flexible Digits**: Support for 6-8 digit codes
|
|
37
|
+
- โฐ **Time Window**: Configurable time periods and verification windows
|
|
38
|
+
- ๐ฏ **Base32 Encoding**: Built-in Base32 encoding/decoding utilities
|
|
39
|
+
- ๐งช **Type Safe**: Full TypeScript support with comprehensive type definitions
|
|
40
|
+
|
|
41
|
+
## ๐ง Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
bun add @nowarajs/totp @nowarajs/error
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## โ๏ธ Usage
|
|
48
|
+
|
|
49
|
+
### Basic TOTP Generation
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { totp, generateSecretBytes, base32Encode } from '@nowarajs/totp';
|
|
53
|
+
|
|
54
|
+
// Generate a secret
|
|
55
|
+
const secret = generateSecretBytes(20); // 20 bytes = 160 bits
|
|
56
|
+
const secretBase32 = base32Encode(secret);
|
|
57
|
+
|
|
58
|
+
// Generate TOTP code
|
|
59
|
+
const code = await totp(secret, {
|
|
60
|
+
algorithm: 'SHA-1',
|
|
61
|
+
digits: 6,
|
|
62
|
+
period: 30
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
console.log('TOTP Code:', code); // e.g., "123456"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### TOTP Verification
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import { verifyTotp } from '@nowarajs/totp';
|
|
72
|
+
|
|
73
|
+
// Verify a TOTP code
|
|
74
|
+
const isValid = await verifyTotp(secret, userInputCode, {
|
|
75
|
+
algorithm: 'SHA-1',
|
|
76
|
+
digits: 6,
|
|
77
|
+
period: 30,
|
|
78
|
+
window: 1 // Allow 1 time step before/after current time
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
if (isValid) {
|
|
82
|
+
console.log('โ
Code is valid!');
|
|
83
|
+
} else {
|
|
84
|
+
console.log('โ Invalid code');
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### HOTP Support
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { hotp } from '@nowarajs/totp';
|
|
92
|
+
|
|
93
|
+
// Generate HOTP code with counter
|
|
94
|
+
const counter = 123;
|
|
95
|
+
const hotpCode = await hotp(secret, counter, {
|
|
96
|
+
algorithm: 'SHA-1',
|
|
97
|
+
digits: 6
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
console.log('HOTP Code:', hotpCode);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### OTPAuth URI Generation
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { buildOtpAuthUri, base32Encode } from '@nowarajs/totp';
|
|
107
|
+
|
|
108
|
+
const secret = generateSecretBytes(20);
|
|
109
|
+
const secretBase32 = base32Encode(secret);
|
|
110
|
+
|
|
111
|
+
// Create URI for QR code
|
|
112
|
+
const uri = buildOtpAuthUri({
|
|
113
|
+
secretBase32,
|
|
114
|
+
label: 'user@example.com',
|
|
115
|
+
issuer: 'MyApp',
|
|
116
|
+
algorithm: 'SHA-1',
|
|
117
|
+
digits: 6,
|
|
118
|
+
period: 30
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
console.log('QR Code URI:', uri);
|
|
122
|
+
// otpauth://totp/user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Secret Generation
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { generateSecretBytes, base32Encode, base32Decode } from '@nowarajs/totp/utils';
|
|
129
|
+
|
|
130
|
+
// Generate cryptographically secure secret
|
|
131
|
+
const secret = generateSecretBytes(32); // 256 bits for extra security
|
|
132
|
+
|
|
133
|
+
// Encode for storage/transmission
|
|
134
|
+
const encoded = base32Encode(secret);
|
|
135
|
+
console.log('Base32 Secret:', encoded);
|
|
136
|
+
|
|
137
|
+
// Decode when needed
|
|
138
|
+
const decoded = base32Decode(encoded);
|
|
139
|
+
console.log('Original bytes match:', secret.every((byte, i) => byte === decoded[i]));
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## ๐ Advanced Configuration
|
|
143
|
+
|
|
144
|
+
### Custom Algorithm and Settings
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
// Use SHA-256 with 8 digits and 60-second period
|
|
148
|
+
const advancedCode = await totp(secret, {
|
|
149
|
+
algorithm: 'SHA-256',
|
|
150
|
+
digits: 8,
|
|
151
|
+
period: 60
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// Verify with larger time window for clock drift tolerance
|
|
155
|
+
const isValid = await verifyTotp(secret, userCode, {
|
|
156
|
+
algorithm: 'SHA-256',
|
|
157
|
+
digits: 8,
|
|
158
|
+
period: 60,
|
|
159
|
+
window: 2 // Allow ยฑ2 time steps (ยฑ2 minutes)
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Parse Existing OTPAuth URIs
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
import { parseOtpAuthUri } from '@nowarajs/totp';
|
|
167
|
+
|
|
168
|
+
const uri = 'otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example';
|
|
169
|
+
const parsed = parseOtpAuthUri(uri);
|
|
170
|
+
|
|
171
|
+
console.log(parsed);
|
|
172
|
+
// {
|
|
173
|
+
// type: 'totp',
|
|
174
|
+
// label: 'Example:alice@google.com',
|
|
175
|
+
// secret: 'JBSWY3DPEHPK3PXP',
|
|
176
|
+
// issuer: 'Example',
|
|
177
|
+
// algorithm: 'SHA-1',
|
|
178
|
+
// digits: 6,
|
|
179
|
+
// period: 30
|
|
180
|
+
// }
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## ๐ ๏ธ Utilities
|
|
184
|
+
|
|
185
|
+
The package includes several utility functions available through subpath imports:
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
// Base32 encoding/decoding
|
|
189
|
+
import { base32Encode, base32Decode } from '@nowarajs/totp/utils';
|
|
190
|
+
|
|
191
|
+
// Secret generation
|
|
192
|
+
import { generateSecretBytes } from '@nowarajs/totp/utils';
|
|
193
|
+
|
|
194
|
+
// Time utilities
|
|
195
|
+
import { timeRemaining } from '@nowarajs/totp/utils';
|
|
196
|
+
|
|
197
|
+
// Get seconds until next TOTP generation
|
|
198
|
+
const remaining = timeRemaining(30); // for 30-second period
|
|
199
|
+
console.log(`Next code in ${remaining} seconds`);
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## ๐ API Reference
|
|
203
|
+
|
|
204
|
+
You can find the complete API reference documentation for `NowaraJS TOTP` at:
|
|
205
|
+
|
|
206
|
+
- [Reference Documentation](https://nowarajs.github.io/totp/)
|
|
207
|
+
|
|
208
|
+
## โ๏ธ License
|
|
209
|
+
|
|
210
|
+
Distributed under the MIT License. See [LICENSE](./LICENSE) for more information.
|
|
211
|
+
|
|
212
|
+
## ๐ง Contact
|
|
213
|
+
|
|
214
|
+
- GitHub: [NowaraJS](https://github.com/NowaraJS)
|
|
215
|
+
- Package: [@nowarajs/totp](https://www.npmjs.com/package/@nowarajs/totp)
|
|
216
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// source/enums/totpErrorKeys.ts
|
|
2
|
+
var TOTP_ERROR_KEYS = {
|
|
3
|
+
INVALID_BASE32_CHARACTER: "totp.error.invalid_base32_character",
|
|
4
|
+
INVALID_SECRET_LENGTH: "totp.error.invalid_secret_length",
|
|
5
|
+
INVALID_ALGORITHM: "totp.error.invalid_algorithm",
|
|
6
|
+
INVALID_OTP_AUTH_URI: "totp.error.invalid_otp_auth_uri",
|
|
7
|
+
MISSING_SECRET: "totp.error.missing_secret"
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export { TOTP_ERROR_KEYS };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// source/utils/createCounterBuffer.ts
|
|
2
|
+
var createCounterBuffer = (counter) => {
|
|
3
|
+
const counterBuffer = new ArrayBuffer(8);
|
|
4
|
+
const counterView = new DataView(counterBuffer);
|
|
5
|
+
if (typeof counter === "bigint")
|
|
6
|
+
counterView.setBigUint64(0, counter, false);
|
|
7
|
+
else
|
|
8
|
+
counterView.setUint32(4, counter, false);
|
|
9
|
+
return counterBuffer;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// source/utils/dynamicTruncation.ts
|
|
13
|
+
var dynamicTruncation = (hmacArray, digits) => {
|
|
14
|
+
const offset = hmacArray[hmacArray.length - 1] & 15;
|
|
15
|
+
const code = ((hmacArray[offset] & 127) << 24 | (hmacArray[offset + 1] & 255) << 16 | (hmacArray[offset + 2] & 255) << 8 | hmacArray[offset + 3] & 255) % 10 ** digits;
|
|
16
|
+
return code.toString().padStart(digits, "0");
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// source/utils/generateHmac.ts
|
|
20
|
+
import { webcrypto } from "crypto";
|
|
21
|
+
var generateHmac = async (key, data) => {
|
|
22
|
+
const hmac = await webcrypto.subtle.sign("HMAC", key, data);
|
|
23
|
+
return new Uint8Array(hmac);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { createCounterBuffer, dynamicTruncation, generateHmac };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TOTP_ERROR_KEYS } from './totpErrorKeys';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const TOTP_ERROR_KEYS: {
|
|
2
|
+
readonly INVALID_BASE32_CHARACTER: "totp.error.invalid_base32_character";
|
|
3
|
+
readonly INVALID_SECRET_LENGTH: "totp.error.invalid_secret_length";
|
|
4
|
+
readonly INVALID_ALGORITHM: "totp.error.invalid_algorithm";
|
|
5
|
+
readonly INVALID_OTP_AUTH_URI: "totp.error.invalid_otp_auth_uri";
|
|
6
|
+
readonly MISSING_SECRET: "totp.error.missing_secret";
|
|
7
|
+
};
|
package/dist/hotp.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TotpOptions } from './types/totpOptions';
|
|
2
|
+
/**
|
|
3
|
+
* HMAC-based One-Time Password (HOTP) implementation
|
|
4
|
+
*
|
|
5
|
+
* @param secret - Secret key as bytes
|
|
6
|
+
* @param counter - Counter value
|
|
7
|
+
* @param opts - HOTP options
|
|
8
|
+
*
|
|
9
|
+
* @returns Promise resolving to the HOTP code
|
|
10
|
+
*/
|
|
11
|
+
export declare const hotp: (secret: Uint8Array, counter: number | bigint, { algorithm, digits }?: TotpOptions) => Promise<string>;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
createCounterBuffer,
|
|
4
|
+
dynamicTruncation,
|
|
5
|
+
generateHmac
|
|
6
|
+
} from "./chunk-hhdy89hc.js";
|
|
7
|
+
import {
|
|
8
|
+
TOTP_ERROR_KEYS
|
|
9
|
+
} from "./chunk-4qsch0ea.js";
|
|
10
|
+
|
|
11
|
+
// source/hotp.ts
|
|
12
|
+
import { webcrypto } from "crypto";
|
|
13
|
+
var hotp = async (secret, counter, {
|
|
14
|
+
algorithm = "SHA-1",
|
|
15
|
+
digits = 6
|
|
16
|
+
} = {}) => {
|
|
17
|
+
const counterBuffer = createCounterBuffer(counter);
|
|
18
|
+
const key = await webcrypto.subtle.importKey("raw", secret, { name: "HMAC", hash: algorithm }, false, ["sign"]);
|
|
19
|
+
const hmacArray = await generateHmac(key, counterBuffer);
|
|
20
|
+
return dynamicTruncation(hmacArray, digits);
|
|
21
|
+
};
|
|
22
|
+
// source/otpAuthUri.ts
|
|
23
|
+
import { BaseError } from "@nowarajs/error";
|
|
24
|
+
var buildOtpAuthUri = ({
|
|
25
|
+
secretBase32,
|
|
26
|
+
label,
|
|
27
|
+
issuer,
|
|
28
|
+
algorithm = "SHA-1",
|
|
29
|
+
digits = 6,
|
|
30
|
+
period = 30
|
|
31
|
+
}) => {
|
|
32
|
+
const encodedLabel = encodeURIComponent(label);
|
|
33
|
+
const encodedIssuer = issuer ? encodeURIComponent(issuer) : undefined;
|
|
34
|
+
let uri = `otpauth://totp/${encodedLabel}?secret=${secretBase32}`;
|
|
35
|
+
if (encodedIssuer)
|
|
36
|
+
uri += `&issuer=${encodedIssuer}`;
|
|
37
|
+
if (algorithm !== "SHA-1")
|
|
38
|
+
uri += `&algorithm=${algorithm}`;
|
|
39
|
+
if (digits !== 6)
|
|
40
|
+
uri += `&digits=${digits}`;
|
|
41
|
+
if (period !== 30)
|
|
42
|
+
uri += `&period=${period}`;
|
|
43
|
+
return uri;
|
|
44
|
+
};
|
|
45
|
+
var parseOtpAuthUri = (uri) => {
|
|
46
|
+
const url = new URL(uri);
|
|
47
|
+
if (url.protocol !== "otpauth:")
|
|
48
|
+
throw new BaseError({
|
|
49
|
+
message: TOTP_ERROR_KEYS.INVALID_OTP_AUTH_URI
|
|
50
|
+
});
|
|
51
|
+
if (url.hostname !== "totp")
|
|
52
|
+
throw new BaseError({
|
|
53
|
+
message: TOTP_ERROR_KEYS.INVALID_OTP_AUTH_URI
|
|
54
|
+
});
|
|
55
|
+
const label = decodeURIComponent(url.pathname.slice(1));
|
|
56
|
+
const secretBase32 = url.searchParams.get("secret");
|
|
57
|
+
if (!secretBase32)
|
|
58
|
+
throw new BaseError({
|
|
59
|
+
message: TOTP_ERROR_KEYS.MISSING_SECRET
|
|
60
|
+
});
|
|
61
|
+
const issuerParam = url.searchParams.get("issuer");
|
|
62
|
+
const issuer = issuerParam ? decodeURIComponent(issuerParam) : undefined;
|
|
63
|
+
const algorithm = url.searchParams.get("algorithm") || "SHA-1";
|
|
64
|
+
const digits = parseInt(url.searchParams.get("digits") || "6", 10);
|
|
65
|
+
const period = parseInt(url.searchParams.get("period") || "30", 10);
|
|
66
|
+
const result = {
|
|
67
|
+
secretBase32,
|
|
68
|
+
label,
|
|
69
|
+
algorithm,
|
|
70
|
+
digits,
|
|
71
|
+
period,
|
|
72
|
+
...issuer && { issuer }
|
|
73
|
+
};
|
|
74
|
+
return result;
|
|
75
|
+
};
|
|
76
|
+
// source/totp.ts
|
|
77
|
+
var totp = async (secret, {
|
|
78
|
+
algorithm = "SHA-1",
|
|
79
|
+
digits = 6,
|
|
80
|
+
period = 30,
|
|
81
|
+
now = Date.now()
|
|
82
|
+
} = {}) => {
|
|
83
|
+
const timeStep = Math.floor(now / 1000 / period);
|
|
84
|
+
return hotp(secret, timeStep, { algorithm, digits });
|
|
85
|
+
};
|
|
86
|
+
var verifyTotp = async (secret, code, {
|
|
87
|
+
algorithm = "SHA-1",
|
|
88
|
+
digits = 6,
|
|
89
|
+
period = 30,
|
|
90
|
+
window = 0,
|
|
91
|
+
now = Date.now()
|
|
92
|
+
} = {}) => {
|
|
93
|
+
const currentTimeStep = Math.floor(now / 1000 / period);
|
|
94
|
+
for (let i = -window;i <= window; ++i) {
|
|
95
|
+
const timeStep = currentTimeStep + i;
|
|
96
|
+
const expectedCode = await hotp(secret, timeStep, { algorithm, digits });
|
|
97
|
+
if (expectedCode === code)
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
};
|
|
102
|
+
export {
|
|
103
|
+
verifyTotp,
|
|
104
|
+
totp,
|
|
105
|
+
parseOtpAuthUri,
|
|
106
|
+
hotp,
|
|
107
|
+
buildOtpAuthUri
|
|
108
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { OtpAuthUri } from './types/otpAuthUri';
|
|
2
|
+
/**
|
|
3
|
+
* Build an OTPAuth URI for QR code generation
|
|
4
|
+
*
|
|
5
|
+
* @param params - URI parameters
|
|
6
|
+
*
|
|
7
|
+
* @returns OTPAuth URI string
|
|
8
|
+
*/
|
|
9
|
+
export declare const buildOtpAuthUri: ({ secretBase32, label, issuer, algorithm, digits, period }: OtpAuthUri) => string;
|
|
10
|
+
/**
|
|
11
|
+
* Parse an OTPAuth URI
|
|
12
|
+
*
|
|
13
|
+
* @param uri - OTPAuth URI to parse
|
|
14
|
+
*
|
|
15
|
+
* @throws ({@link BaseError}) - if the URI is invalid or missing required parameters
|
|
16
|
+
*
|
|
17
|
+
* @returns Parsed URI parameters
|
|
18
|
+
*/
|
|
19
|
+
export declare const parseOtpAuthUri: (uri: string) => Required<Omit<OtpAuthUri, "issuer">> & {
|
|
20
|
+
issuer?: string;
|
|
21
|
+
};
|
package/dist/totp.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { TotpOptions } from './types/totpOptions';
|
|
2
|
+
import type { VerifyOptions } from './types/verifyOptions';
|
|
3
|
+
/**
|
|
4
|
+
* Time-based One-Time Password (TOTP) implementation
|
|
5
|
+
*
|
|
6
|
+
* @param secret - Secret key as bytes
|
|
7
|
+
* @param opts - TOTP options including current time
|
|
8
|
+
*
|
|
9
|
+
* @returns Promise resolving to the TOTP code
|
|
10
|
+
*/
|
|
11
|
+
export declare const totp: (secret: Uint8Array, { algorithm, digits, period, now }?: TotpOptions & {
|
|
12
|
+
now?: number;
|
|
13
|
+
}) => Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Verify a TOTP code against a secret
|
|
16
|
+
*
|
|
17
|
+
* @param secret - Secret key as bytes
|
|
18
|
+
* @param code - Code to verify
|
|
19
|
+
* @param opts - Verification options
|
|
20
|
+
*
|
|
21
|
+
* @returns Promise resolving to true if code is valid
|
|
22
|
+
*/
|
|
23
|
+
export declare const verifyTotp: (secret: Uint8Array, code: string, { algorithm, digits, period, window, now }?: VerifyOptions) => Promise<boolean>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// @bun
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Complete OTPAuth URI data structure
|
|
3
|
+
*/
|
|
4
|
+
export interface OtpAuthUri {
|
|
5
|
+
/**
|
|
6
|
+
* Base32 encoded secret
|
|
7
|
+
*/
|
|
8
|
+
secretBase32: string;
|
|
9
|
+
/**
|
|
10
|
+
* Label for the account (usually email or username)
|
|
11
|
+
*/
|
|
12
|
+
label: string;
|
|
13
|
+
/**
|
|
14
|
+
* Issuer name (app/service name)
|
|
15
|
+
*/
|
|
16
|
+
issuer: string;
|
|
17
|
+
/**
|
|
18
|
+
* Hash algorithm
|
|
19
|
+
*
|
|
20
|
+
* @defaultValue 'SHA-1'
|
|
21
|
+
*/
|
|
22
|
+
algorithm?: 'SHA-1' | 'SHA-256' | 'SHA-512';
|
|
23
|
+
/**
|
|
24
|
+
* Number of digits
|
|
25
|
+
*
|
|
26
|
+
* @defaultValue 6
|
|
27
|
+
*/
|
|
28
|
+
digits?: 6 | 8;
|
|
29
|
+
/**
|
|
30
|
+
* Time period in seconds
|
|
31
|
+
*
|
|
32
|
+
* @defaultValue 30
|
|
33
|
+
*/
|
|
34
|
+
period?: number;
|
|
35
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for TOTP/HOTP generation
|
|
3
|
+
*/
|
|
4
|
+
export interface TotpOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Hash algorithm to use
|
|
7
|
+
*
|
|
8
|
+
* @defaultValue SHA-1
|
|
9
|
+
*/
|
|
10
|
+
algorithm?: 'SHA-1' | 'SHA-256' | 'SHA-512';
|
|
11
|
+
/**
|
|
12
|
+
* Number of digits in the code
|
|
13
|
+
*
|
|
14
|
+
* @defaultValue 6
|
|
15
|
+
*/
|
|
16
|
+
digits?: 6 | 8;
|
|
17
|
+
/**
|
|
18
|
+
* Time step in seconds for TOTP
|
|
19
|
+
*
|
|
20
|
+
* @defaultValue 30
|
|
21
|
+
*/
|
|
22
|
+
period?: number;
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TotpOptions } from './totpOptions';
|
|
2
|
+
/**
|
|
3
|
+
* Options for TOTP verification
|
|
4
|
+
*/
|
|
5
|
+
export interface VerifyOptions extends TotpOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Time window for verification (ยฑwindow periods)
|
|
8
|
+
*
|
|
9
|
+
* @defaultValue 1
|
|
10
|
+
*/
|
|
11
|
+
window?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Current timestamp in milliseconds
|
|
14
|
+
*
|
|
15
|
+
* @defaultValue Date.now()
|
|
16
|
+
*/
|
|
17
|
+
now?: number;
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encode bytes to Base32 string
|
|
3
|
+
*
|
|
4
|
+
* @param input - Bytes or string to encode
|
|
5
|
+
* @param withPadding - Whether to include padding (default: true)
|
|
6
|
+
*
|
|
7
|
+
* @returns Base32 encoded string
|
|
8
|
+
*/
|
|
9
|
+
export declare const base32Encode: (input: string | Uint8Array, withPadding?: boolean) => string;
|
|
10
|
+
/**
|
|
11
|
+
* Decode Base32 string to bytes
|
|
12
|
+
*
|
|
13
|
+
* @param base32 - Base32 string to decode
|
|
14
|
+
*
|
|
15
|
+
* @throws ({@link BaseError}) - if invalid Base32 character is found
|
|
16
|
+
*
|
|
17
|
+
* @returns Decoded bytes
|
|
18
|
+
*/
|
|
19
|
+
export declare const base32Decode: (base32: string) => Uint8Array;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a counter value to an 8-byte big-endian buffer
|
|
3
|
+
*
|
|
4
|
+
* @param counter - Counter value as number or bigint
|
|
5
|
+
*
|
|
6
|
+
* @returns ArrayBuffer containing the counter in big-endian format
|
|
7
|
+
*/
|
|
8
|
+
export declare const createCounterBuffer: (counter: number | bigint) => ArrayBuffer;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Perform dynamic truncation on HMAC result according to RFC 4226
|
|
3
|
+
*
|
|
4
|
+
* @param hmacArray - HMAC result as byte array
|
|
5
|
+
* @param digits - Number of digits in the final code
|
|
6
|
+
*
|
|
7
|
+
* @returns Truncated code as string with leading zeros
|
|
8
|
+
*/
|
|
9
|
+
export declare const dynamicTruncation: (hmacArray: Uint8Array, digits: number) => string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate HMAC for given data using a crypto key
|
|
3
|
+
*
|
|
4
|
+
* @param key - Crypto key for HMAC
|
|
5
|
+
* @param data - Data to sign
|
|
6
|
+
*
|
|
7
|
+
* @returns Promise resolving to HMAC as Uint8Array
|
|
8
|
+
*/
|
|
9
|
+
export declare const generateHmac: (key: CryptoKey, data: ArrayBuffer) => Promise<Uint8Array>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate cryptographically secure random bytes for TOTP secret
|
|
3
|
+
*
|
|
4
|
+
* @param length - Number of bytes to generate (default: 20)
|
|
5
|
+
*
|
|
6
|
+
* @throws ({@link BaseError}) if length is not positive
|
|
7
|
+
*
|
|
8
|
+
* @returns Uint8Array containing the random bytes
|
|
9
|
+
*/
|
|
10
|
+
export declare const generateSecretBytes: (length?: number) => Uint8Array;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { base32Decode, base32Encode } from './base32';
|
|
2
|
+
export { createCounterBuffer } from './createCounterBuffer';
|
|
3
|
+
export { dynamicTruncation } from './dynamicTruncation';
|
|
4
|
+
export { generateHmac } from './generateHmac';
|
|
5
|
+
export { generateSecretBytes } from './generateSecretBytes';
|
|
6
|
+
export { timeRemaining } from './timeRemaining';
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
createCounterBuffer,
|
|
4
|
+
dynamicTruncation,
|
|
5
|
+
generateHmac
|
|
6
|
+
} from "../chunk-hhdy89hc.js";
|
|
7
|
+
import {
|
|
8
|
+
TOTP_ERROR_KEYS
|
|
9
|
+
} from "../chunk-4qsch0ea.js";
|
|
10
|
+
|
|
11
|
+
// source/utils/base32.ts
|
|
12
|
+
import { BaseError } from "@nowarajs/error";
|
|
13
|
+
var BASE32_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
|
14
|
+
var base32Encode = (input, withPadding = true) => {
|
|
15
|
+
let result = "";
|
|
16
|
+
let bits = 0;
|
|
17
|
+
let value = 0;
|
|
18
|
+
const bytes = input instanceof Uint8Array ? input : new TextEncoder().encode(input);
|
|
19
|
+
for (const byte of bytes) {
|
|
20
|
+
value = value << 8 | byte;
|
|
21
|
+
bits += 8;
|
|
22
|
+
while (bits >= 5) {
|
|
23
|
+
result += BASE32_ALPHABET[value >>> bits - 5 & 31];
|
|
24
|
+
bits -= 5;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (bits > 0)
|
|
28
|
+
result += BASE32_ALPHABET[value << 5 - bits & 31];
|
|
29
|
+
if (withPadding)
|
|
30
|
+
while (result.length % 8 !== 0)
|
|
31
|
+
result += "=";
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
var base32Decode = (base32) => {
|
|
35
|
+
const cleanBase32 = base32.replace(/=+$/, "");
|
|
36
|
+
if (cleanBase32.length === 0)
|
|
37
|
+
return new Uint8Array(0);
|
|
38
|
+
const result = [];
|
|
39
|
+
let bits = 0;
|
|
40
|
+
let value = 0;
|
|
41
|
+
for (const char of cleanBase32) {
|
|
42
|
+
const charValue = BASE32_ALPHABET.indexOf(char);
|
|
43
|
+
if (charValue === -1)
|
|
44
|
+
throw new BaseError({
|
|
45
|
+
message: TOTP_ERROR_KEYS.INVALID_BASE32_CHARACTER,
|
|
46
|
+
cause: `Invalid Base32 character: ${char}`
|
|
47
|
+
});
|
|
48
|
+
value = value << 5 | charValue;
|
|
49
|
+
bits += 5;
|
|
50
|
+
if (bits >= 8) {
|
|
51
|
+
result.push(value >>> bits - 8 & 255);
|
|
52
|
+
bits -= 8;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return new Uint8Array(result);
|
|
56
|
+
};
|
|
57
|
+
// source/utils/generateSecretBytes.ts
|
|
58
|
+
import { BaseError as BaseError2 } from "@nowarajs/error";
|
|
59
|
+
import { getRandomValues } from "crypto";
|
|
60
|
+
var generateSecretBytes = (length = 20) => {
|
|
61
|
+
if (length <= 0)
|
|
62
|
+
throw new BaseError2({
|
|
63
|
+
message: TOTP_ERROR_KEYS.INVALID_SECRET_LENGTH
|
|
64
|
+
});
|
|
65
|
+
return getRandomValues(new Uint8Array(length));
|
|
66
|
+
};
|
|
67
|
+
// source/utils/timeRemaining.ts
|
|
68
|
+
var timeRemaining = (period = 30, now = Date.now()) => {
|
|
69
|
+
const elapsed = Math.floor(now / 1000) % period;
|
|
70
|
+
return period - elapsed;
|
|
71
|
+
};
|
|
72
|
+
export {
|
|
73
|
+
timeRemaining,
|
|
74
|
+
generateSecretBytes,
|
|
75
|
+
generateHmac,
|
|
76
|
+
dynamicTruncation,
|
|
77
|
+
createCounterBuffer,
|
|
78
|
+
base32Encode,
|
|
79
|
+
base32Decode
|
|
80
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculate remaining time until next TOTP code
|
|
3
|
+
*
|
|
4
|
+
* @param period - Time period in seconds (default: 30)
|
|
5
|
+
* @param now - Current timestamp in milliseconds (default: Date.now())
|
|
6
|
+
*
|
|
7
|
+
* @returns Seconds remaining until next code
|
|
8
|
+
*/
|
|
9
|
+
export declare const timeRemaining: (period?: number, now?: number) => number;
|
package/package.json
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nowarajs/totp",
|
|
3
|
+
"version": "1.1.2",
|
|
4
|
+
"author": "Komiriko",
|
|
5
|
+
"description": "A comprehensive Time-based One-Time Password (TOTP) and HMAC-based One-Time Password (HOTP)",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"bun",
|
|
10
|
+
"nowarajs",
|
|
11
|
+
"totp",
|
|
12
|
+
"hotp"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "bun builder.ts",
|
|
16
|
+
"dev": "bun --watch sandbox/index.ts",
|
|
17
|
+
"docs": "bunx typedoc --tsconfig tsconfig.build.json",
|
|
18
|
+
"fix-lint": "eslint --fix ./source",
|
|
19
|
+
"lint": "eslint ./source",
|
|
20
|
+
"test:integration": "bun test $(find test/integration -name '*.spec.ts')",
|
|
21
|
+
"test:unit": "bun test --coverage $(find test/unit -name '*.spec.ts')",
|
|
22
|
+
"test": "bun test --coverage"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@eslint/js": "^9.33.0",
|
|
26
|
+
"@stylistic/eslint-plugin": "^5.2.3",
|
|
27
|
+
"@types/bun": "^1.2.20",
|
|
28
|
+
"eslint": "^9.33.0",
|
|
29
|
+
"globals": "^16.3.0",
|
|
30
|
+
"typescript-eslint": "^8.39.1",
|
|
31
|
+
"typescript": "^5.9.2"
|
|
32
|
+
},
|
|
33
|
+
"exports": {
|
|
34
|
+
"./enums": "./dist/enums/index.js",
|
|
35
|
+
"./types": "./dist/types/index.js",
|
|
36
|
+
"./utils": "./dist/utils/index.js",
|
|
37
|
+
".": "./dist/index.js"
|
|
38
|
+
},
|
|
39
|
+
"changelog": {
|
|
40
|
+
"types": {
|
|
41
|
+
"feat": {
|
|
42
|
+
"title": "๐ Enhancements",
|
|
43
|
+
"semver": "minor"
|
|
44
|
+
},
|
|
45
|
+
"perf": {
|
|
46
|
+
"title": "โก Performance",
|
|
47
|
+
"semver": "patch"
|
|
48
|
+
},
|
|
49
|
+
"fix": {
|
|
50
|
+
"title": "๐ง Fixes",
|
|
51
|
+
"semver": "patch"
|
|
52
|
+
},
|
|
53
|
+
"refactor": {
|
|
54
|
+
"title": "๐งน Refactors",
|
|
55
|
+
"semver": "patch"
|
|
56
|
+
},
|
|
57
|
+
"docs": {
|
|
58
|
+
"title": "๐ Documentation",
|
|
59
|
+
"semver": "patch"
|
|
60
|
+
},
|
|
61
|
+
"build": {
|
|
62
|
+
"title": "๐ฆ Build",
|
|
63
|
+
"semver": "patch"
|
|
64
|
+
},
|
|
65
|
+
"types": {
|
|
66
|
+
"title": "๐ Types",
|
|
67
|
+
"semver": "patch"
|
|
68
|
+
},
|
|
69
|
+
"chore": {
|
|
70
|
+
"title": "๐ฆ Chore"
|
|
71
|
+
},
|
|
72
|
+
"examples": {
|
|
73
|
+
"title": "๐ Examples"
|
|
74
|
+
},
|
|
75
|
+
"test": {
|
|
76
|
+
"title": "๐งช Tests"
|
|
77
|
+
},
|
|
78
|
+
"style": {
|
|
79
|
+
"title": "๐จ Styles"
|
|
80
|
+
},
|
|
81
|
+
"ci": {
|
|
82
|
+
"title": "๐ค CI"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"templates": {
|
|
86
|
+
"commitMessage": "chore(๐ฆ): v{{newVersion}}",
|
|
87
|
+
"tagMessage": "v{{newVersion}}",
|
|
88
|
+
"tagBody": "v{{newVersion}}"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"peerDependencies": {
|
|
92
|
+
"@nowarajs/error": "^1.1.6"
|
|
93
|
+
}
|
|
94
|
+
}
|