From b2067241b21837e1fff03e227c925dd97d31d1fc Mon Sep 17 00:00:00 2001 From: vveerrgg Date: Sun, 29 Dec 2024 20:02:08 -0800 Subject: [PATCH] docs: improve documentation across codebase - Add comprehensive JSDoc comments to NIP-19 functions - Update README with documentation section - Generate updated TypeDoc documentation - Fix function implementations and error handling - Maintain consistent documentation style --- README.md | 370 ++- docs/.nojekyll | 1 - docs/README.md | 317 +-- docs/_media/CONTRIBUTING.md | 69 + docs/_media/LICENSE | 21 + docs/functions/configureHMAC.md | 26 + docs/functions/createEvent.md | 63 + docs/functions/fromHex.md | 42 + docs/functions/generateKeyPairWithSeed.md | 30 + docs/functions/generateSeedPhrase.md | 28 + docs/functions/getEntropyFromSeedPhrase.md | 40 + docs/functions/getPublicKey.md | 36 + docs/functions/hexToNpub.md | 40 + docs/functions/hexToNsec.md | 40 + docs/functions/npubToHex.md | 40 + docs/functions/nsecToHex.md | 40 + docs/functions/nsecToPrivateKey.md | 40 + docs/functions/privateKeyToNpub.md | 40 + docs/functions/privateKeyToNsec.md | 40 + docs/functions/seedPhraseToKeyPair.md | 43 + docs/functions/seedPhraseToPrivateKey.md | 40 + docs/functions/signEvent.md | 51 + docs/functions/signMessage.md | 46 + docs/functions/validateSeedPhrase.md | 36 + docs/functions/verifyEvent.md | 36 + docs/functions/verifySignature.md | 48 + docs/globals.md | 39 + docs/interfaces/KeyPair.md | 44 +- docs/interfaces/NostrEvent.md | 60 +- docs/interfaces/UnsignedEvent.md | 44 +- docs/modules.md | 570 ---- docs/namespaces/nip19/README.md | 21 + docs/namespaces/nip19/functions/decode.md | 37 + docs/namespaces/nip19/functions/noteDecode.md | 29 + docs/namespaces/nip19/functions/noteEncode.md | 29 + docs/namespaces/nip19/functions/npubDecode.md | 29 + docs/namespaces/nip19/functions/npubEncode.md | 29 + docs/namespaces/nip19/functions/nsecDecode.md | 29 + docs/namespaces/nip19/functions/nsecEncode.md | 29 + package-lock.json | 2353 ++++------------- package.json | 21 +- src/bips/bip39.ts | 64 + src/bips/index.ts | 6 + src/constants.ts | 83 + src/core/crypto.ts | 250 ++ src/core/events.ts | 159 ++ src/core/index.ts | 3 + src/core/keys.ts | 159 ++ src/crypto/events.ts | 192 ++ src/crypto/index.ts | 7 + src/crypto/keys.ts | 217 ++ src/index.ts | 260 +- src/nips/index.ts | 9 + src/nips/nip-19.ts | 162 ++ src/nips/nip-26.ts | 162 ++ src/types/events.ts | 84 + src/types/index.ts | 2 + src/types/keys.ts | 63 + src/utils/conversion.ts | 64 + src/utils/index.ts | 3 + src/utils/logger.ts | 45 + src/utils/validation.ts | 64 + typedoc.json | 18 +- 63 files changed, 4101 insertions(+), 2961 deletions(-) delete mode 100644 docs/.nojekyll create mode 100644 docs/_media/CONTRIBUTING.md create mode 100644 docs/_media/LICENSE create mode 100644 docs/functions/configureHMAC.md create mode 100644 docs/functions/createEvent.md create mode 100644 docs/functions/fromHex.md create mode 100644 docs/functions/generateKeyPairWithSeed.md create mode 100644 docs/functions/generateSeedPhrase.md create mode 100644 docs/functions/getEntropyFromSeedPhrase.md create mode 100644 docs/functions/getPublicKey.md create mode 100644 docs/functions/hexToNpub.md create mode 100644 docs/functions/hexToNsec.md create mode 100644 docs/functions/npubToHex.md create mode 100644 docs/functions/nsecToHex.md create mode 100644 docs/functions/nsecToPrivateKey.md create mode 100644 docs/functions/privateKeyToNpub.md create mode 100644 docs/functions/privateKeyToNsec.md create mode 100644 docs/functions/seedPhraseToKeyPair.md create mode 100644 docs/functions/seedPhraseToPrivateKey.md create mode 100644 docs/functions/signEvent.md create mode 100644 docs/functions/signMessage.md create mode 100644 docs/functions/validateSeedPhrase.md create mode 100644 docs/functions/verifyEvent.md create mode 100644 docs/functions/verifySignature.md create mode 100644 docs/globals.md delete mode 100644 docs/modules.md create mode 100644 docs/namespaces/nip19/README.md create mode 100644 docs/namespaces/nip19/functions/decode.md create mode 100644 docs/namespaces/nip19/functions/noteDecode.md create mode 100644 docs/namespaces/nip19/functions/noteEncode.md create mode 100644 docs/namespaces/nip19/functions/npubDecode.md create mode 100644 docs/namespaces/nip19/functions/npubEncode.md create mode 100644 docs/namespaces/nip19/functions/nsecDecode.md create mode 100644 docs/namespaces/nip19/functions/nsecEncode.md create mode 100644 src/bips/bip39.ts create mode 100644 src/bips/index.ts create mode 100644 src/constants.ts create mode 100644 src/core/crypto.ts create mode 100644 src/core/events.ts create mode 100644 src/core/index.ts create mode 100644 src/core/keys.ts create mode 100644 src/crypto/events.ts create mode 100644 src/crypto/index.ts create mode 100644 src/crypto/keys.ts create mode 100644 src/nips/index.ts create mode 100644 src/nips/nip-19.ts create mode 100644 src/nips/nip-26.ts create mode 100644 src/types/events.ts create mode 100644 src/types/index.ts create mode 100644 src/types/keys.ts create mode 100644 src/utils/conversion.ts create mode 100644 src/utils/index.ts create mode 100644 src/utils/logger.ts create mode 100644 src/utils/validation.ts diff --git a/README.md b/README.md index 55c6fbd..d746c3a 100644 --- a/README.md +++ b/README.md @@ -11,18 +11,34 @@ -A comprehensive TypeScript library for managing Nostr keys with seed phrases, including event signing, verification, and WebSocket utilities. - -## Features - -- 🔑 Generate and manage seed phrases for Nostr keys -- 🔄 Convert between different key formats (hex, nsec, npub) -- ✍️ Sign and verify messages -- 📝 Create and verify Nostr events -- 🌐 WebSocket utilities for Nostr applications -- 📦 TypeScript support with full type definitions -- ✅ Comprehensive test coverage -- 🔒 Secure key management practices +A focused TypeScript library for Nostr key management and seedphrase functionality, with seamless integration with nostr-crypto-utils. This package specializes in converting between nsec keys and seed phrases, managing delegations, and handling various key formats. + +## Core Features + +- 🌱 **Seedphrase Management** + - Generate and validate BIP39 seed phrases + - Convert between seed phrases and Nostr keys + - Secure entropy generation + - Multiple language support + +- 🔑 **Key Operations** + - Convert between formats (hex, nsec, npub) + - Validate key pairs + - Generate new key pairs + - Public key derivation + +- 📝 **Delegation Support (NIP-26)** + - Create delegation tokens + - Time-based conditions + - Event kind filtering + - Token validation and verification + - Expiry management + +- 🔄 **Format Conversions** + - Hex ↔ nsec + - Hex ↔ npub + - Seed phrase ↔ key pair + - Comprehensive validation ## NIPs Support Status @@ -31,50 +47,9 @@ A comprehensive TypeScript library for managing Nostr keys with seed phrases, in | NIP | Status | Description | |-----|--------|-------------| | 01 | 🟢 | Basic protocol flow & event signing | -| 06 | 🟢 | Basic key derivation and event signing | -| 13 | 🟢 | Proof of Work support | +| 06 | 🟢 | Basic key derivation from seed phrase | | 19 | 🟢 | bech32-encoded entities | -| 49 | 🟢 | Private Key Generation from Seed Phrases | - -### NIP-49 Implementation Details - -This package fully implements NIP-49, which specifies the use of BIP-39-style mnemonic seed phrases for generating private keys in the Nostr protocol. Our implementation ensures full compatibility with the NIP-49 specification while providing robust tooling for developers. - -#### Key Features & Compliance - -1. **Mnemonic Generation & Handling**: - - Full BIP-39 compliance for seed phrase generation - - Support for multiple languages and word lists - - Secure entropy generation for new seed phrases - -2. **Standardized Key Derivation**: - - Implements the standard derivation path (m/44'/1237'/0'/0/0) - - Ensures compatibility with other NIP-49 compliant tools and wallets - - Supports custom derivation paths for advanced use cases - -3. **Key Format & Encoding**: - - Outputs Nostr-compatible `nsec` and `npub` keys - - Supports conversion between different key formats - - Maintains compatibility with existing Nostr infrastructure - -4. **Security & Best Practices**: - - Implements secure key generation and storage practices - - Provides validation utilities for seed phrases - - Follows cryptographic best practices for key management - -#### Interoperability - -This implementation ensures compatibility with: -- Nostr wallets implementing NIP-49 -- Key management tools using BIP-39 mnemonics -- Other Nostr clients and libraries following the specification - -#### Validation & Testing - -To verify compatibility, the package includes: -- Comprehensive test suites against NIP-49 specifications -- Validation against known test vectors -- Integration tests with common Nostr tools and libraries +| 26 | 🟢 | Delegated event signing | ## Installation @@ -82,212 +57,179 @@ To verify compatibility, the package includes: npm install nostr-nsec-seedphrase ``` -## Getting Started - -This library provides a comprehensive set of tools for managing Nostr keys with seed phrases. Here's how to get started: - -### Prerequisites +## Quick Start -- Node.js 16.0.0 or later -- npm or yarn package manager - -### Basic Usage - -#### Key Generation and Management +### Generate a New Key Pair with Seed Phrase ```typescript -import { generateKeyPairWithSeed, seedPhraseToKeyPair } from 'nostr-nsec-seedphrase'; +import { generateKeyPairWithSeed } from 'nostr-nsec-seedphrase'; -// Generate a new key pair with seed phrase const keyPair = generateKeyPairWithSeed(); -console.log(keyPair); -// { -// privateKey: '...', -// publicKey: '...', -// nsec: '...', -// npub: '...', -// seedPhrase: '...' -// } - -// Convert existing seed phrase to key pair -const existingKeyPair = seedPhraseToKeyPair('your twelve word seed phrase here'); +console.log({ + seedPhrase: keyPair.seedPhrase, + nsec: keyPair.nsec, + npub: keyPair.npub +}); ``` -### Message Signing and Verification +### Convert Seed Phrase to Key Pair ```typescript -import { signMessage, verifySignature } from 'nostr-nsec-seedphrase'; - -// Sign a message -const signature = await signMessage('Hello Nostr!', keyPair.privateKey); - -// Verify a signature -const isValid = await verifySignature('Hello Nostr!', signature, keyPair.publicKey); +import { seedPhraseToKeyPair } from 'nostr-nsec-seedphrase'; + +const keyPair = await seedPhraseToKeyPair('your twelve word seed phrase here'); +console.log({ + privateKey: keyPair.privateKey, // hex format + publicKey: keyPair.publicKey, // hex format + nsec: keyPair.nsec, // bech32 format + npub: keyPair.npub // bech32 format +}); ``` -### Event Creation and Verification +### Create and Verify Delegations ```typescript -import { createEvent, verifyEvent } from 'nostr-nsec-seedphrase'; - -// Create a new event -const event = await createEvent( - 'Hello Nostr!', // content - 1, // kind (1 = text note) - keyPair.privateKey, - [] // tags (optional) +import { createDelegation, verifyDelegation } from 'nostr-nsec-seedphrase'; + +// Create a delegation token +const delegation = await createDelegation( + delegateePublicKey, + { + kinds: [1, 2], // allowed event kinds + since: Math.floor(Date.now() / 1000), + until: Math.floor(Date.now() / 1000) + 86400 // 24 hours + }, + delegatorPrivateKey ); -// Verify an event -const isValidEvent = await verifyEvent(event); +// Verify a delegation +const isValid = await verifyDelegation( + delegation, + Math.floor(Date.now() / 1000), // current timestamp + 1 // event kind to verify +); ``` -## Key Management Functions +## Key Features in Detail -### Public Key Generation -```typescript -import { getPublicKey } from 'nostr-nsec-seedphrase'; +### 1. Seedphrase Management -// Generate public key from private key -const pubkey = getPublicKey(privateKeyHex); -``` +The library provides comprehensive seedphrase functionality: -### NIP-19 Encoding/Decoding ```typescript -import { nip19 } from 'nostr-nsec-seedphrase'; +import { + generateSeedPhrase, + validateSeedPhrase, + seedPhraseToKeyPair +} from 'nostr-nsec-seedphrase'; -// Encode/decode public keys (npub) -const npub = nip19.npubEncode(pubkeyHex); -const pubkey = nip19.npubDecode(npub); +// Generate a new seed phrase +const seedPhrase = generateSeedPhrase(); -// Encode/decode private keys (nsec) -const nsec = nip19.nsecEncode(privkeyHex); -const privkey = nip19.nsecDecode(nsec); +// Validate an existing seed phrase +const isValid = validateSeedPhrase(seedPhrase); -// Encode/decode event IDs (note) -const note = nip19.noteEncode(eventIdHex); -const eventId = nip19.noteDecode(note); +// Convert seed phrase to key pair +const keyPair = await seedPhraseToKeyPair(seedPhrase); ``` -## API Reference - -### Key Management -- `generateKeyPairWithSeed()`: Generate a new key pair with seed phrase -- `seedPhraseToKeyPair(seedPhrase: string)`: Convert seed phrase to key pair -- `fromHex(privateKeyHex: string)`: Create key pair from hex private key -- `validateSeedPhrase(seedPhrase: string)`: Validate a seed phrase +### 2. Key Format Conversions -### Format Conversion -- `nsecToHex(nsec: string)`: Convert nsec to hex format -- `npubToHex(npub: string)`: Convert npub to hex format -- `hexToNsec(privateKeyHex: string)`: Convert hex to nsec format -- `hexToNpub(publicKeyHex: string)`: Convert hex to npub format +Easy conversion between different key formats: -### Signing and Verification -- `signMessage(message: string, privateKey: string)`: Sign a message -- `verifySignature(message: string, signature: string, publicKey: string)`: Verify a signature -- `createEvent(content: string, kind: number, privateKey: string, tags?: string[][])`: Create a Nostr event -- `verifyEvent(event: NostrEvent)`: Verify a Nostr event +```typescript +import { + hexToNsec, + hexToNpub, + nsecToHex, + npubToHex +} from 'nostr-nsec-seedphrase'; + +// Convert hex to bech32 formats +const nsec = hexToNsec(privateKeyHex); +const npub = hexToNpub(publicKeyHex); + +// Convert bech32 to hex formats +const privateKeyHex = nsecToHex(nsec); +const publicKeyHex = npubToHex(npub); +``` -## Development +### 3. Delegation Management -### Setting Up Development Environment +Comprehensive NIP-26 delegation support: -1. Clone the repository -```bash -git clone https://github.com/humanjavaenterprises/nostr-nsec-seedphrase.git -cd nostr-nsec-seedphrase +```typescript +import { + createDelegation, + verifyDelegation, + isDelegationValid, + getDelegationExpiry +} from 'nostr-nsec-seedphrase'; + +// Create a delegation with conditions +const delegation = await createDelegation(delegatee, { + kinds: [1], // only text notes + since: Math.floor(Date.now() / 1000), + until: Math.floor(Date.now() / 1000) + 86400 +}, delegatorPrivateKey); + +// Check delegation validity +const isValid = await isDelegationValid(delegation); + +// Get delegation expiry +const expiry = getDelegationExpiry(delegation); ``` -2. Install dependencies -```bash -npm install -``` +## Documentation -3. Build the project -```bash -npm run build -``` +The library includes comprehensive TypeScript types and JSDoc documentation. You can: -### Running Tests +1. View the documentation in your IDE through TypeScript and JSDoc annotations +2. Generate HTML documentation using: + ```bash + npm run docs + ``` +3. Access the generated documentation in the `docs` directory -```bash -# Run all tests -npm test +### Key Format Utilities -# Run tests with coverage -npm run test:coverage -``` +```typescript +import { nip19 } from 'nostr-nsec-seedphrase'; -### Code Style +// Encode/decode public keys +const npub = nip19.npubEncode(hexPublicKey); +const hexPubkey = nip19.npubDecode(npub); -This project uses Prettier for code formatting. Format your code before committing: +// Encode/decode private keys +const nsec = nip19.nsecEncode(hexPrivateKey); +const hexPrivkey = nip19.nsecDecode(nsec); -```bash -npm run format +// Encode/decode event IDs +const note = nip19.noteEncode(eventId); +const hexEventId = nip19.noteDecode(note); ``` -## Security Considerations - -- Always keep your seed phrases and private keys secure -- Never share your private keys or seed phrases -- Be cautious when using this library in a browser environment -- Consider using a hardware wallet for additional security -- Validate all inputs and handle errors appropriately - -## Recent Updates - -### v0.5.0 -- 🔧 Fixed Bech32 mocking in test suite -- 🔄 Improved signature verification consistency -- 🎯 Enhanced key pair generation and validation -- 🛠️ Updated test infrastructure for better reliability -- 📦 Streamlined dependency mocking system - -### v0.4.0 -- 📚 Added comprehensive documentation and examples -- 📝 Added Code of Conduct -- 🔍 Enhanced development setup instructions -- 🛡️ Added security considerations section - -### v0.3.0 -- 🔧 Enhanced module resolution for better compatibility -- ✨ Improved testing infrastructure and mocks -- 📝 Enhanced TypeScript support and configurations -- 🔒 Enhanced cryptographic functionality -- 🎯 Updated ESLint and TypeScript configurations - -### v0.2.0 -- 🔧 Fixed HMAC configuration for secp256k1 -- ✅ Added comprehensive test coverage -- 🎯 Improved TypeScript types -- 📚 Enhanced documentation +## Integration with nostr-crypto-utils -## Contributing +This package is designed to work seamlessly with nostr-crypto-utils: -We welcome contributions! Please follow these steps: +- Uses compatible key formats and types +- Leverages nostr-crypto-utils for cryptographic operations +- Maintains consistent error handling and validation -1. Fork the repository -2. Create your feature branch (`git checkout -b feature/amazing-feature`) -3. Commit your changes (`git commit -m 'feat: add amazing feature'`) -4. Push to the branch (`git push origin feature/amazing-feature`) -5. Open a Pull Request +## Security Considerations -Before contributing: -- Read our [Code of Conduct](CODE_OF_CONDUCT.md) -- Check our [Contributing Guidelines](.github/CONTRIBUTING.md) -- Review our [Security Policy](SECURITY.md) -- Search [existing issues](https://github.com/humanjavaenterprises/nostr-nsec-seedphrase/issues) before creating a new one +- Never share or expose private keys or seed phrases +- Always validate input seed phrases and keys +- Use secure entropy sources for key generation +- Implement proper key storage practices +- Regularly rotate delegation tokens +- Set appropriate expiry times for delegations -## License - -[MIT](LICENSE) +## Contributing -## Author +We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. -[Vergel Evans](https://github.com/vergelevans) +## License ---- -
-Made with ❤️ by Humanjava Enterprises -
+MIT License - see the [LICENSE](LICENSE) file for details. diff --git a/docs/.nojekyll b/docs/.nojekyll deleted file mode 100644 index e2ac661..0000000 --- a/docs/.nojekyll +++ /dev/null @@ -1 +0,0 @@ -TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 12241fb..d914c93 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,6 @@ -nostr-nsec-seedphrase / [Exports](modules.md) +**nostr-nsec-seedphrase v0.6.0** + +*** # nostr-nsec-seedphrase @@ -13,18 +15,34 @@ nostr-nsec-seedphrase / [Exports](modules.md) -A comprehensive TypeScript library for managing Nostr keys with seed phrases, including event signing, verification, and WebSocket utilities. +A focused TypeScript library for Nostr key management and seedphrase functionality, with seamless integration with nostr-crypto-utils. This package specializes in converting between nsec keys and seed phrases, managing delegations, and handling various key formats. + +## Core Features + +- 🌱 **Seedphrase Management** + - Generate and validate BIP39 seed phrases + - Convert between seed phrases and Nostr keys + - Secure entropy generation + - Multiple language support -## Features +- 🔑 **Key Operations** + - Convert between formats (hex, nsec, npub) + - Validate key pairs + - Generate new key pairs + - Public key derivation -- 🔑 Generate and manage seed phrases for Nostr keys -- 🔄 Convert between different key formats (hex, nsec, npub) -- ✍️ Sign and verify messages -- 📝 Create and verify Nostr events -- 🌐 WebSocket utilities for Nostr applications -- 📦 TypeScript support with full type definitions -- ✅ Comprehensive test coverage -- 🔒 Secure key management practices +- 📝 **Delegation Support (NIP-26)** + - Create delegation tokens + - Time-based conditions + - Event kind filtering + - Token validation and verification + - Expiry management + +- 🔄 **Format Conversions** + - Hex ↔ nsec + - Hex ↔ npub + - Seed phrase ↔ key pair + - Comprehensive validation ## NIPs Support Status @@ -33,50 +51,9 @@ A comprehensive TypeScript library for managing Nostr keys with seed phrases, in | NIP | Status | Description | |-----|--------|-------------| | 01 | 🟢 | Basic protocol flow & event signing | -| 06 | 🟢 | Basic key derivation and event signing | -| 13 | 🟢 | Proof of Work support | +| 06 | 🟢 | Basic key derivation from seed phrase | | 19 | 🟢 | bech32-encoded entities | -| 49 | 🟢 | Private Key Generation from Seed Phrases | - -### NIP-49 Implementation Details - -This package fully implements NIP-49, which specifies the use of BIP-39-style mnemonic seed phrases for generating private keys in the Nostr protocol. Our implementation ensures full compatibility with the NIP-49 specification while providing robust tooling for developers. - -#### Key Features & Compliance - -1. **Mnemonic Generation & Handling**: - - Full BIP-39 compliance for seed phrase generation - - Support for multiple languages and word lists - - Secure entropy generation for new seed phrases - -2. **Standardized Key Derivation**: - - Implements the standard derivation path (m/44'/1237'/0'/0/0) - - Ensures compatibility with other NIP-49 compliant tools and wallets - - Supports custom derivation paths for advanced use cases - -3. **Key Format & Encoding**: - - Outputs Nostr-compatible `nsec` and `npub` keys - - Supports conversion between different key formats - - Maintains compatibility with existing Nostr infrastructure - -4. **Security & Best Practices**: - - Implements secure key generation and storage practices - - Provides validation utilities for seed phrases - - Follows cryptographic best practices for key management - -#### Interoperability - -This implementation ensures compatibility with: -- Nostr wallets implementing NIP-49 -- Key management tools using BIP-39 mnemonics -- Other Nostr clients and libraries following the specification - -#### Validation & Testing - -To verify compatibility, the package includes: -- Comprehensive test suites against NIP-49 specifications -- Validation against known test vectors -- Integration tests with common Nostr tools and libraries +| 26 | 🟢 | Delegated event signing | ## Installation @@ -84,174 +61,150 @@ To verify compatibility, the package includes: npm install nostr-nsec-seedphrase ``` -## Getting Started +## Quick Start -This library provides a comprehensive set of tools for managing Nostr keys with seed phrases. Here's how to get started: - -### Prerequisites - -- Node.js 16.0.0 or later -- npm or yarn package manager - -### Basic Usage - -#### Key Generation and Management +### Generate a New Key Pair with Seed Phrase ```typescript -import { generateKeyPairWithSeed, seedPhraseToKeyPair } from 'nostr-nsec-seedphrase'; +import { generateKeyPairWithSeed } from 'nostr-nsec-seedphrase'; -// Generate a new key pair with seed phrase const keyPair = generateKeyPairWithSeed(); -console.log(keyPair); -// { -// privateKey: '...', -// publicKey: '...', -// nsec: '...', -// npub: '...', -// seedPhrase: '...' -// } - -// Convert existing seed phrase to key pair -const existingKeyPair = seedPhraseToKeyPair('your twelve word seed phrase here'); +console.log({ + seedPhrase: keyPair.seedPhrase, + nsec: keyPair.nsec, + npub: keyPair.npub +}); ``` -### Message Signing and Verification +### Convert Seed Phrase to Key Pair ```typescript -import { signMessage, verifySignature } from 'nostr-nsec-seedphrase'; - -// Sign a message -const signature = await signMessage('Hello Nostr!', keyPair.privateKey); - -// Verify a signature -const isValid = await verifySignature('Hello Nostr!', signature, keyPair.publicKey); +import { seedPhraseToKeyPair } from 'nostr-nsec-seedphrase'; + +const keyPair = await seedPhraseToKeyPair('your twelve word seed phrase here'); +console.log({ + privateKey: keyPair.privateKey, // hex format + publicKey: keyPair.publicKey, // hex format + nsec: keyPair.nsec, // bech32 format + npub: keyPair.npub // bech32 format +}); ``` -### Event Creation and Verification +### Create and Verify Delegations ```typescript -import { createEvent, verifyEvent } from 'nostr-nsec-seedphrase'; - -// Create a new event -const event = await createEvent( - 'Hello Nostr!', // content - 1, // kind (1 = text note) - keyPair.privateKey, - [] // tags (optional) +import { createDelegation, verifyDelegation } from 'nostr-nsec-seedphrase'; + +// Create a delegation token +const delegation = await createDelegation( + delegateePublicKey, + { + kinds: [1, 2], // allowed event kinds + since: Math.floor(Date.now() / 1000), + until: Math.floor(Date.now() / 1000) + 86400 // 24 hours + }, + delegatorPrivateKey ); -// Verify an event -const isValidEvent = await verifyEvent(event); +// Verify a delegation +const isValid = await verifyDelegation( + delegation, + Math.floor(Date.now() / 1000), // current timestamp + 1 // event kind to verify +); ``` -## API Reference +## Key Features in Detail -### Key Management -- `generateKeyPairWithSeed()`: Generate a new key pair with seed phrase -- `seedPhraseToKeyPair(seedPhrase: string)`: Convert seed phrase to key pair -- `fromHex(privateKeyHex: string)`: Create key pair from hex private key -- `validateSeedPhrase(seedPhrase: string)`: Validate a seed phrase +### 1. Seedphrase Management -### Format Conversion -- `nsecToHex(nsec: string)`: Convert nsec to hex format -- `npubToHex(npub: string)`: Convert npub to hex format -- `hexToNsec(privateKeyHex: string)`: Convert hex to nsec format -- `hexToNpub(publicKeyHex: string)`: Convert hex to npub format +The library provides comprehensive seedphrase functionality: -### Signing and Verification -- `signMessage(message: string, privateKey: string)`: Sign a message -- `verifySignature(message: string, signature: string, publicKey: string)`: Verify a signature -- `createEvent(content: string, kind: number, privateKey: string, tags?: string[][])`: Create a Nostr event -- `verifyEvent(event: NostrEvent)`: Verify a Nostr event +```typescript +import { + generateSeedPhrase, + validateSeedPhrase, + seedPhraseToKeyPair +} from 'nostr-nsec-seedphrase'; -## Development +// Generate a new seed phrase +const seedPhrase = generateSeedPhrase(); -### Setting Up Development Environment +// Validate an existing seed phrase +const isValid = validateSeedPhrase(seedPhrase); -1. Clone the repository -```bash -git clone https://github.com/humanjavaenterprises/nostr-nsec-seedphrase.git -cd nostr-nsec-seedphrase +// Convert seed phrase to key pair +const keyPair = await seedPhraseToKeyPair(seedPhrase); ``` -2. Install dependencies -```bash -npm install -``` +### 2. Key Format Conversions -3. Build the project -```bash -npm run build +Easy conversion between different key formats: + +```typescript +import { + hexToNsec, + hexToNpub, + nsecToHex, + npubToHex +} from 'nostr-nsec-seedphrase'; + +// Convert hex to bech32 formats +const nsec = hexToNsec(privateKeyHex); +const npub = hexToNpub(publicKeyHex); + +// Convert bech32 to hex formats +const privateKeyHex = nsecToHex(nsec); +const publicKeyHex = npubToHex(npub); ``` -### Running Tests +### 3. Delegation Management -```bash -# Run all tests -npm test +Comprehensive NIP-26 delegation support: -# Run tests with coverage -npm run test:coverage +```typescript +import { + createDelegation, + verifyDelegation, + isDelegationValid, + getDelegationExpiry +} from 'nostr-nsec-seedphrase'; + +// Create a delegation with conditions +const delegation = await createDelegation(delegatee, { + kinds: [1], // only text notes + since: Math.floor(Date.now() / 1000), + until: Math.floor(Date.now() / 1000) + 86400 +}, delegatorPrivateKey); + +// Check delegation validity +const isValid = await isDelegationValid(delegation); + +// Get delegation expiry +const expiry = getDelegationExpiry(delegation); ``` -### Code Style +## Integration with nostr-crypto-utils -This project uses Prettier for code formatting. Format your code before committing: +This package is designed to work seamlessly with nostr-crypto-utils: -```bash -npm run format -``` +- Uses compatible key formats and types +- Leverages nostr-crypto-utils for cryptographic operations +- Maintains consistent error handling and validation ## Security Considerations -- Always keep your seed phrases and private keys secure -- Never share your private keys or seed phrases -- Be cautious when using this library in a browser environment -- Consider using a hardware wallet for additional security -- Validate all inputs and handle errors appropriately - -## Recent Updates - -### v0.4.0 -- 📚 Added comprehensive documentation and examples -- 📝 Added Code of Conduct -- 🔍 Enhanced development setup instructions -- 🛡️ Added security considerations section - -### v0.3.0 -- 🔧 Enhanced module resolution for better compatibility -- ✨ Improved testing infrastructure and mocks -- 📝 Enhanced TypeScript support and configurations -- 🔒 Enhanced cryptographic functionality -- 🎯 Updated ESLint and TypeScript configurations - -### v0.2.0 -- 🔧 Fixed HMAC configuration for secp256k1 -- ✅ Added comprehensive test coverage -- 🎯 Improved TypeScript types -- 📚 Enhanced documentation +- Never share or expose private keys or seed phrases +- Always validate input seed phrases and keys +- Use secure entropy sources for key generation +- Implement proper key storage practices +- Regularly rotate delegation tokens +- Set appropriate expiry times for delegations ## Contributing -We welcome contributions! Please follow these steps: - -1. Fork the repository -2. Create your feature branch (`git checkout -b feature/amazing-feature`) -3. Commit your changes (`git commit -m 'feat: add amazing feature'`) -4. Push to the branch (`git push origin feature/amazing-feature`) -5. Open a Pull Request - -Please read our [Code of Conduct](CODE_OF_CONDUCT.md) before contributing. +We welcome contributions! Please see our [Contributing Guide](_media/CONTRIBUTING.md) for details. ## License -[MIT](LICENSE) - -## Author - -[Vergel Evans](https://github.com/vergelevans) - ---- -
-Made with ❤️ by Humanjava Enterprises -
+MIT License - see the [LICENSE](_media/LICENSE) file for details. diff --git a/docs/_media/CONTRIBUTING.md b/docs/_media/CONTRIBUTING.md new file mode 100644 index 0000000..7d079b0 --- /dev/null +++ b/docs/_media/CONTRIBUTING.md @@ -0,0 +1,69 @@ +# Contributing to Nostr Nsec Seedphrase Library + +First off, thank you for considering contributing to the Nostr Nsec Seedphrase Library! It's people like you that make this library better for everyone. + +## Code of Conduct + +This project and everyone participating in it is governed by our Code of Conduct. By participating, you are expected to uphold this code. + +## How Can I Contribute? + +### Reporting Bugs + +Before creating bug reports, please check the issue list as you might find out that you don't need to create one. When you are creating a bug report, please include as many details as possible: + +* Use a clear and descriptive title +* Describe the exact steps which reproduce the problem +* Provide specific examples to demonstrate the steps +* Describe the behavior you observed after following the steps +* Explain which behavior you expected to see instead and why +* Include any error messages or logs + +### Suggesting Enhancements + +If you have a suggestion for the library, we'd love to hear about it. Before creating enhancement suggestions, please check the issue list as you might find out that you don't need to create one. + +When you are creating an enhancement suggestion, please include as many details as possible: + +* Use a clear and descriptive title +* Provide a step-by-step description of the suggested enhancement +* Provide specific examples to demonstrate the steps +* Describe the current behavior and explain which behavior you expected to see instead + +### Pull Requests + +* Fill in the required template +* Do not include issue numbers in the PR title +* Follow the TypeScript styleguide +* Include thoughtfully-worded, well-structured tests +* Document new code +* End all files with a newline + +## Development Process + +1. Fork the repository +2. Create a new branch for your feature or bug fix +3. Write your code +4. Write or update tests as needed +5. Run the test suite +6. Push your changes +7. Submit a pull request + +## Testing + +We use Jest for testing. Please ensure all tests pass before submitting a pull request: + +```bash +npm test +``` + +## Style Guide + +* Use TypeScript +* Follow the existing code style +* Write descriptive commit messages +* Document your code with JSDoc comments + +## License + +By contributing, you agree that your contributions will be licensed under the MIT License. diff --git a/docs/_media/LICENSE b/docs/_media/LICENSE new file mode 100644 index 0000000..60ffadc --- /dev/null +++ b/docs/_media/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 MaiQR Platform + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/docs/functions/configureHMAC.md b/docs/functions/configureHMAC.md new file mode 100644 index 0000000..b201e5b --- /dev/null +++ b/docs/functions/configureHMAC.md @@ -0,0 +1,26 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / configureHMAC + +# Function: configureHMAC() + +> **configureHMAC**(): `void` + +Configures secp256k1 with HMAC for WebSocket utilities +This is required for some WebSocket implementations + +## Returns + +`void` + +## Example + +```ts +configureHMAC(); +``` + +## Defined in + +[index.ts:403](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L403) diff --git a/docs/functions/createEvent.md b/docs/functions/createEvent.md new file mode 100644 index 0000000..93fee60 --- /dev/null +++ b/docs/functions/createEvent.md @@ -0,0 +1,63 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / createEvent + +# Function: createEvent() + +> **createEvent**(`content`, `kind`, `privateKey`, `tags`?): `Promise`\<[`NostrEvent`](../interfaces/NostrEvent.md)\> + +Creates a new signed Nostr event + +## Parameters + +### content + +`string` + +The event content + +### kind + +`number` + +The event kind (1 for text note, etc.) + +### privateKey + +`string` + +The hex-encoded private key to sign with + +### tags? + +`string`[][] = `[]` + +Optional event tags + +## Returns + +`Promise`\<[`NostrEvent`](../interfaces/NostrEvent.md)\> + +The signed event + +## Throws + +If event creation or signing fails + +## Example + +```ts +const event = await createEvent( + "Hello Nostr!", + 1, + privateKey, + [["t", "nostr"]] +); +console.log(event); // complete signed event +``` + +## Defined in + +[index.ts:453](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L453) diff --git a/docs/functions/fromHex.md b/docs/functions/fromHex.md new file mode 100644 index 0000000..1188d6a --- /dev/null +++ b/docs/functions/fromHex.md @@ -0,0 +1,42 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / fromHex + +# Function: fromHex() + +> **fromHex**(`privateKeyHex`): [`KeyPair`](../interfaces/KeyPair.md) + +Creates a key pair from a hex private key + +## Parameters + +### privateKeyHex + +`string` + +The hex-encoded private key + +## Returns + +[`KeyPair`](../interfaces/KeyPair.md) + +A key pair containing private and public keys in various formats + +## Throws + +If the private key is invalid + +## Example + +```ts +const keyPair = fromHex("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"); +console.log(keyPair.publicKey); // corresponding public key +console.log(keyPair.nsec); // bech32 nsec private key +console.log(keyPair.npub); // bech32 npub public key +``` + +## Defined in + +[index.ts:175](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L175) diff --git a/docs/functions/generateKeyPairWithSeed.md b/docs/functions/generateKeyPairWithSeed.md new file mode 100644 index 0000000..ca6fff5 --- /dev/null +++ b/docs/functions/generateKeyPairWithSeed.md @@ -0,0 +1,30 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / generateKeyPairWithSeed + +# Function: generateKeyPairWithSeed() + +> **generateKeyPairWithSeed**(): [`KeyPair`](../interfaces/KeyPair.md) + +Generates a new key pair with a random seed phrase + +## Returns + +[`KeyPair`](../interfaces/KeyPair.md) + +A new key pair containing private and public keys in various formats + +## Example + +```ts +const keyPair = generateKeyPairWithSeed(); +console.log(keyPair.seedPhrase); // random seed phrase +console.log(keyPair.privateKey); // hex private key +console.log(keyPair.publicKey); // hex public key +``` + +## Defined in + +[index.ts:159](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L159) diff --git a/docs/functions/generateSeedPhrase.md b/docs/functions/generateSeedPhrase.md new file mode 100644 index 0000000..674d394 --- /dev/null +++ b/docs/functions/generateSeedPhrase.md @@ -0,0 +1,28 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / generateSeedPhrase + +# Function: generateSeedPhrase() + +> **generateSeedPhrase**(): `string` + +Generates a new BIP39 seed phrase + +## Returns + +`string` + +A random 12-word BIP39 mnemonic seed phrase + +## Example + +```ts +const seedPhrase = generateSeedPhrase(); +console.log(seedPhrase); // "witch collapse practice feed shame open despair creek road again ice least" +``` + +## Defined in + +[index.ts:72](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L72) diff --git a/docs/functions/getEntropyFromSeedPhrase.md b/docs/functions/getEntropyFromSeedPhrase.md new file mode 100644 index 0000000..ca152f7 --- /dev/null +++ b/docs/functions/getEntropyFromSeedPhrase.md @@ -0,0 +1,40 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / getEntropyFromSeedPhrase + +# Function: getEntropyFromSeedPhrase() + +> **getEntropyFromSeedPhrase**(`seedPhrase`): `Uint8Array` + +Converts a BIP39 seed phrase to its entropy value + +## Parameters + +### seedPhrase + +`string` + +The BIP39 seed phrase to convert + +## Returns + +`Uint8Array` + +The entropy value + +## Throws + +If the seed phrase is invalid + +## Example + +```ts +const entropy = getEntropyFromSeedPhrase("witch collapse practice feed shame open despair creek road again ice least"); +console.log(entropy); // Uint8Array +``` + +## Defined in + +[index.ts:85](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L85) diff --git a/docs/functions/getPublicKey.md b/docs/functions/getPublicKey.md new file mode 100644 index 0000000..ef9bf7b --- /dev/null +++ b/docs/functions/getPublicKey.md @@ -0,0 +1,36 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / getPublicKey + +# Function: getPublicKey() + +> **getPublicKey**(`privateKey`): `string` + +Derives a public key from a private key + +## Parameters + +### privateKey + +`string` + +The hex-encoded private key + +## Returns + +`string` + +The hex-encoded public key + +## Example + +```ts +const pubkey = getPublicKey("1234567890abcdef..."); +console.log(pubkey); // hex public key +``` + +## Defined in + +[index.ts:212](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L212) diff --git a/docs/functions/hexToNpub.md b/docs/functions/hexToNpub.md new file mode 100644 index 0000000..ccfa05f --- /dev/null +++ b/docs/functions/hexToNpub.md @@ -0,0 +1,40 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / hexToNpub + +# Function: hexToNpub() + +> **hexToNpub**(`publicKeyHex`): `string` + +Converts a hex public key to bech32 npub format + +## Parameters + +### publicKeyHex + +`string` + +The hex-encoded public key + +## Returns + +`string` + +The bech32-encoded npub public key + +## Throws + +If the public key is invalid + +## Example + +```ts +const npub = hexToNpub("1234567890abcdef..."); +console.log(npub); // "npub1..." +``` + +## Defined in + +[index.ts:573](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L573) diff --git a/docs/functions/hexToNsec.md b/docs/functions/hexToNsec.md new file mode 100644 index 0000000..ad8accc --- /dev/null +++ b/docs/functions/hexToNsec.md @@ -0,0 +1,40 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / hexToNsec + +# Function: hexToNsec() + +> **hexToNsec**(`privateKeyHex`): `string` + +Converts a hex private key to bech32 nsec format + +## Parameters + +### privateKeyHex + +`string` + +The hex-encoded private key + +## Returns + +`string` + +The bech32-encoded nsec private key + +## Throws + +If the private key is invalid + +## Example + +```ts +const nsec = hexToNsec("1234567890abcdef..."); +console.log(nsec); // "nsec1..." +``` + +## Defined in + +[index.ts:592](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L592) diff --git a/docs/functions/npubToHex.md b/docs/functions/npubToHex.md new file mode 100644 index 0000000..7c8aee4 --- /dev/null +++ b/docs/functions/npubToHex.md @@ -0,0 +1,40 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / npubToHex + +# Function: npubToHex() + +> **npubToHex**(`npub`): `string` + +Converts a bech32 npub public key to hex format + +## Parameters + +### npub + +`string` + +The bech32-encoded npub public key + +## Returns + +`string` + +The hex-encoded public key + +## Throws + +If the npub key is invalid + +## Example + +```ts +const hex = npubToHex("npub1..."); +console.log(hex); // "1234567890abcdef..." +``` + +## Defined in + +[index.ts:550](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L550) diff --git a/docs/functions/nsecToHex.md b/docs/functions/nsecToHex.md new file mode 100644 index 0000000..4e07b62 --- /dev/null +++ b/docs/functions/nsecToHex.md @@ -0,0 +1,40 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / nsecToHex + +# Function: nsecToHex() + +> **nsecToHex**(`nsec`): `string` + +Converts a bech32 nsec private key to hex format + +## Parameters + +### nsec + +`string` + +The bech32-encoded nsec private key + +## Returns + +`string` + +The hex-encoded private key + +## Throws + +If the nsec key is invalid + +## Example + +```ts +const hex = nsecToHex("nsec1..."); +console.log(hex); // "1234567890abcdef..." +``` + +## Defined in + +[index.ts:530](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L530) diff --git a/docs/functions/nsecToPrivateKey.md b/docs/functions/nsecToPrivateKey.md new file mode 100644 index 0000000..3f3c3c0 --- /dev/null +++ b/docs/functions/nsecToPrivateKey.md @@ -0,0 +1,40 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / nsecToPrivateKey + +# Function: nsecToPrivateKey() + +> **nsecToPrivateKey**(`nsec`): `string` + +Converts a bech32 nsec private key to hex format + +## Parameters + +### nsec + +`string` + +The bech32-encoded nsec private key + +## Returns + +`string` + +The hex-encoded private key + +## Throws + +If the nsec key is invalid + +## Example + +```ts +const hex = nsecToPrivateKey("nsec1..."); +console.log(hex); // "1234567890abcdef..." +``` + +## Defined in + +[index.ts:667](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L667) diff --git a/docs/functions/privateKeyToNpub.md b/docs/functions/privateKeyToNpub.md new file mode 100644 index 0000000..5358f65 --- /dev/null +++ b/docs/functions/privateKeyToNpub.md @@ -0,0 +1,40 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / privateKeyToNpub + +# Function: privateKeyToNpub() + +> **privateKeyToNpub**(`privateKey`): `string` + +Converts a private key to bech32 npub format + +## Parameters + +### privateKey + +`string` + +The hex-encoded private key + +## Returns + +`string` + +The bech32-encoded npub public key + +## Throws + +If the private key is invalid + +## Example + +```ts +const npub = privateKeyToNpub("1234567890abcdef..."); +console.log(npub); // "npub1..." +``` + +## Defined in + +[index.ts:515](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L515) diff --git a/docs/functions/privateKeyToNsec.md b/docs/functions/privateKeyToNsec.md new file mode 100644 index 0000000..5603d44 --- /dev/null +++ b/docs/functions/privateKeyToNsec.md @@ -0,0 +1,40 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / privateKeyToNsec + +# Function: privateKeyToNsec() + +> **privateKeyToNsec**(`privateKey`): `string` + +Converts a private key to bech32 nsec format + +## Parameters + +### privateKey + +`string` + +The hex-encoded private key + +## Returns + +`string` + +The bech32-encoded nsec private key + +## Throws + +If the private key is invalid + +## Example + +```ts +const nsec = privateKeyToNsec("1234567890abcdef..."); +console.log(nsec); // "nsec1..." +``` + +## Defined in + +[index.ts:502](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L502) diff --git a/docs/functions/seedPhraseToKeyPair.md b/docs/functions/seedPhraseToKeyPair.md new file mode 100644 index 0000000..659ef19 --- /dev/null +++ b/docs/functions/seedPhraseToKeyPair.md @@ -0,0 +1,43 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / seedPhraseToKeyPair + +# Function: seedPhraseToKeyPair() + +> **seedPhraseToKeyPair**(`seedPhrase`): [`KeyPair`](../interfaces/KeyPair.md) + +Converts a BIP39 seed phrase to a Nostr key pair + +## Parameters + +### seedPhrase + +`string` + +The BIP39 seed phrase to convert + +## Returns + +[`KeyPair`](../interfaces/KeyPair.md) + +A key pair containing private and public keys in various formats + +## Throws + +If the seed phrase is invalid or key generation fails + +## Example + +```ts +const keyPair = seedPhraseToKeyPair("witch collapse practice feed shame open despair creek road again ice least"); +console.log(keyPair.privateKey); // hex private key +console.log(keyPair.publicKey); // hex public key +console.log(keyPair.nsec); // bech32 nsec private key +console.log(keyPair.npub); // bech32 npub public key +``` + +## Defined in + +[index.ts:122](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L122) diff --git a/docs/functions/seedPhraseToPrivateKey.md b/docs/functions/seedPhraseToPrivateKey.md new file mode 100644 index 0000000..4655ca2 --- /dev/null +++ b/docs/functions/seedPhraseToPrivateKey.md @@ -0,0 +1,40 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / seedPhraseToPrivateKey + +# Function: seedPhraseToPrivateKey() + +> **seedPhraseToPrivateKey**(`seedPhrase`): `string` + +Converts a BIP39 seed phrase to a private key + +## Parameters + +### seedPhrase + +`string` + +The BIP39 seed phrase to convert + +## Returns + +`string` + +The hex-encoded private key + +## Throws + +If the seed phrase is invalid + +## Example + +```ts +const privateKey = seedPhraseToPrivateKey("witch collapse practice feed shame open despair creek road again ice least"); +console.log(privateKey); // hex private key +``` + +## Defined in + +[index.ts:489](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L489) diff --git a/docs/functions/signEvent.md b/docs/functions/signEvent.md new file mode 100644 index 0000000..f86ff52 --- /dev/null +++ b/docs/functions/signEvent.md @@ -0,0 +1,51 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / signEvent + +# Function: signEvent() + +> **signEvent**(`event`, `privateKey`): `Promise`\<`string`\> + +Signs a Nostr event + +## Parameters + +### event + +[`UnsignedEvent`](../interfaces/UnsignedEvent.md) + +The event to sign + +### privateKey + +`string` + +The hex-encoded private key to sign with + +## Returns + +`Promise`\<`string`\> + +The hex-encoded signature + +## Throws + +If signing fails + +## Example + +```ts +const signature = await signEvent({ + pubkey: "...", + created_at: Math.floor(Date.now() / 1000), + kind: 1, + tags: [], + content: "Hello Nostr!" +}, privateKey); +``` + +## Defined in + +[index.ts:346](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L346) diff --git a/docs/functions/signMessage.md b/docs/functions/signMessage.md new file mode 100644 index 0000000..6def547 --- /dev/null +++ b/docs/functions/signMessage.md @@ -0,0 +1,46 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / signMessage + +# Function: signMessage() + +> **signMessage**(`message`, `privateKey`): `Promise`\<`string`\> + +Signs a message with a private key + +## Parameters + +### message + +`string` + +The message to sign + +### privateKey + +`string` + +The hex-encoded private key to sign with + +## Returns + +`Promise`\<`string`\> + +The hex-encoded signature + +## Throws + +If signing fails + +## Example + +```ts +const signature = await signMessage("Hello Nostr!", privateKey); +console.log(signature); // hex-encoded signature +``` + +## Defined in + +[index.ts:612](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L612) diff --git a/docs/functions/validateSeedPhrase.md b/docs/functions/validateSeedPhrase.md new file mode 100644 index 0000000..f59a7d7 --- /dev/null +++ b/docs/functions/validateSeedPhrase.md @@ -0,0 +1,36 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / validateSeedPhrase + +# Function: validateSeedPhrase() + +> **validateSeedPhrase**(`seedPhrase`): `boolean` + +Validates a BIP39 seed phrase + +## Parameters + +### seedPhrase + +`string` + +The seed phrase to validate + +## Returns + +`boolean` + +True if the seed phrase is valid, false otherwise + +## Example + +```ts +const isValid = validateSeedPhrase("witch collapse practice feed shame open despair creek road again ice least"); +console.log(isValid); // true +``` + +## Defined in + +[index.ts:102](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L102) diff --git a/docs/functions/verifyEvent.md b/docs/functions/verifyEvent.md new file mode 100644 index 0000000..ac26e49 --- /dev/null +++ b/docs/functions/verifyEvent.md @@ -0,0 +1,36 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / verifyEvent + +# Function: verifyEvent() + +> **verifyEvent**(`event`): `Promise`\<`boolean`\> + +Verifies a Nostr event signature + +## Parameters + +### event + +[`NostrEvent`](../interfaces/NostrEvent.md) + +The event to verify + +## Returns + +`Promise`\<`boolean`\> + +True if the signature is valid, false otherwise + +## Example + +```ts +const isValid = await verifyEvent(event); +console.log(isValid); // true or false +``` + +## Defined in + +[index.ts:372](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L372) diff --git a/docs/functions/verifySignature.md b/docs/functions/verifySignature.md new file mode 100644 index 0000000..e8f9076 --- /dev/null +++ b/docs/functions/verifySignature.md @@ -0,0 +1,48 @@ +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / verifySignature + +# Function: verifySignature() + +> **verifySignature**(`message`, `signature`, `publicKey`): `Promise`\<`boolean`\> + +Verifies a message signature + +## Parameters + +### message + +`string` + +The original message + +### signature + +`string` + +The hex-encoded signature to verify + +### publicKey + +`string` + +The hex-encoded public key to verify against + +## Returns + +`Promise`\<`boolean`\> + +True if the signature is valid, false otherwise + +## Example + +```ts +const isValid = await verifySignature("Hello Nostr!", signature, publicKey); +console.log(isValid); // true or false +``` + +## Defined in + +[index.ts:638](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L638) diff --git a/docs/globals.md b/docs/globals.md new file mode 100644 index 0000000..5df34a2 --- /dev/null +++ b/docs/globals.md @@ -0,0 +1,39 @@ +[**nostr-nsec-seedphrase v0.6.0**](README.md) + +*** + +# nostr-nsec-seedphrase v0.6.0 + +## Namespaces + +- [nip19](namespaces/nip19/README.md) + +## Interfaces + +- [KeyPair](interfaces/KeyPair.md) +- [NostrEvent](interfaces/NostrEvent.md) +- [UnsignedEvent](interfaces/UnsignedEvent.md) + +## Functions + +- [configureHMAC](functions/configureHMAC.md) +- [createEvent](functions/createEvent.md) +- [fromHex](functions/fromHex.md) +- [generateKeyPairWithSeed](functions/generateKeyPairWithSeed.md) +- [generateSeedPhrase](functions/generateSeedPhrase.md) +- [getEntropyFromSeedPhrase](functions/getEntropyFromSeedPhrase.md) +- [getPublicKey](functions/getPublicKey.md) +- [hexToNpub](functions/hexToNpub.md) +- [hexToNsec](functions/hexToNsec.md) +- [npubToHex](functions/npubToHex.md) +- [nsecToHex](functions/nsecToHex.md) +- [nsecToPrivateKey](functions/nsecToPrivateKey.md) +- [privateKeyToNpub](functions/privateKeyToNpub.md) +- [privateKeyToNsec](functions/privateKeyToNsec.md) +- [seedPhraseToKeyPair](functions/seedPhraseToKeyPair.md) +- [seedPhraseToPrivateKey](functions/seedPhraseToPrivateKey.md) +- [signEvent](functions/signEvent.md) +- [signMessage](functions/signMessage.md) +- [validateSeedPhrase](functions/validateSeedPhrase.md) +- [verifyEvent](functions/verifyEvent.md) +- [verifySignature](functions/verifySignature.md) diff --git a/docs/interfaces/KeyPair.md b/docs/interfaces/KeyPair.md index 01384be..f17cee6 100644 --- a/docs/interfaces/KeyPair.md +++ b/docs/interfaces/KeyPair.md @@ -1,75 +1,69 @@ -[nostr-nsec-seedphrase - v0.4.2](../README.md) / [Exports](../modules.md) / KeyPair +[**nostr-nsec-seedphrase v0.6.0**](../README.md) -# Interface: KeyPair - -Represents a Nostr key pair with associated formats +*** -## Table of contents +[nostr-nsec-seedphrase](../globals.md) / KeyPair -### Properties +# Interface: KeyPair -- [npub](KeyPair.md#npub) -- [nsec](KeyPair.md#nsec) -- [privateKey](KeyPair.md#privatekey) -- [publicKey](KeyPair.md#publickey) -- [seedPhrase](KeyPair.md#seedphrase) +Represents a Nostr key pair with associated formats ## Properties ### npub -• **npub**: `string` +> **npub**: `string` Public key in bech32 npub format #### Defined in -[index.ts:32](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L32) +[index.ts:21](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L21) -___ +*** ### nsec -• **nsec**: `string` +> **nsec**: `string` Private key in bech32 nsec format #### Defined in -[index.ts:30](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L30) +[index.ts:19](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L19) -___ +*** ### privateKey -• **privateKey**: `string` +> **privateKey**: `string` Private key in hex format #### Defined in -[index.ts:26](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L26) +[index.ts:15](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L15) -___ +*** ### publicKey -• **publicKey**: `string` +> **publicKey**: `string` Public key in hex format #### Defined in -[index.ts:28](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L28) +[index.ts:17](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L17) -___ +*** ### seedPhrase -• **seedPhrase**: `string` +> **seedPhrase**: `string` BIP39 seed phrase used to generate this key pair #### Defined in -[index.ts:34](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L34) +[index.ts:23](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L23) diff --git a/docs/interfaces/NostrEvent.md b/docs/interfaces/NostrEvent.md index 41428fb..b35e564 100644 --- a/docs/interfaces/NostrEvent.md +++ b/docs/interfaces/NostrEvent.md @@ -1,105 +1,97 @@ -[nostr-nsec-seedphrase - v0.4.2](../README.md) / [Exports](../modules.md) / NostrEvent +[**nostr-nsec-seedphrase v0.6.0**](../README.md) + +*** + +[nostr-nsec-seedphrase](../globals.md) / NostrEvent # Interface: NostrEvent Represents a signed Nostr event -**`See`** +## See https://github.com/nostr-protocol/nips/blob/master/01.md -## Table of contents - -### Properties - -- [content](NostrEvent.md#content) -- [created\_at](NostrEvent.md#created_at) -- [id](NostrEvent.md#id) -- [kind](NostrEvent.md#kind) -- [pubkey](NostrEvent.md#pubkey) -- [sig](NostrEvent.md#sig) -- [tags](NostrEvent.md#tags) - ## Properties ### content -• **content**: `string` +> **content**: `string` Event content (arbitrary string) #### Defined in -[index.ts:54](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L54) +[index.ts:43](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L43) -___ +*** ### created\_at -• **created\_at**: `number` +> **created\_at**: `number` Unix timestamp in seconds #### Defined in -[index.ts:48](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L48) +[index.ts:37](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L37) -___ +*** ### id -• **id**: `string` +> **id**: `string` Event ID (32-bytes lowercase hex of the sha256 of the serialized event data) #### Defined in -[index.ts:44](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L44) +[index.ts:33](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L33) -___ +*** ### kind -• **kind**: `number` +> **kind**: `number` Event kind (integer) #### Defined in -[index.ts:50](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L50) +[index.ts:39](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L39) -___ +*** ### pubkey -• **pubkey**: `string` +> **pubkey**: `string` Event creator's public key (32-bytes lowercase hex) #### Defined in -[index.ts:46](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L46) +[index.ts:35](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L35) -___ +*** ### sig -• **sig**: `string` +> **sig**: `string` Event signature (64-bytes hex of the schnorr signature of the sha256 hash of the serialized event data) #### Defined in -[index.ts:56](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L56) +[index.ts:45](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L45) -___ +*** ### tags -• **tags**: `string`[][] +> **tags**: `string`[][] Array of arrays of strings (event tags) #### Defined in -[index.ts:52](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L52) +[index.ts:41](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L41) diff --git a/docs/interfaces/UnsignedEvent.md b/docs/interfaces/UnsignedEvent.md index e46390a..73f5ea8 100644 --- a/docs/interfaces/UnsignedEvent.md +++ b/docs/interfaces/UnsignedEvent.md @@ -1,75 +1,69 @@ -[nostr-nsec-seedphrase - v0.4.2](../README.md) / [Exports](../modules.md) / UnsignedEvent +[**nostr-nsec-seedphrase v0.6.0**](../README.md) -# Interface: UnsignedEvent - -Represents an unsigned Nostr event before signing +*** -## Table of contents +[nostr-nsec-seedphrase](../globals.md) / UnsignedEvent -### Properties +# Interface: UnsignedEvent -- [content](UnsignedEvent.md#content) -- [created\_at](UnsignedEvent.md#created_at) -- [kind](UnsignedEvent.md#kind) -- [pubkey](UnsignedEvent.md#pubkey) -- [tags](UnsignedEvent.md#tags) +Represents an unsigned Nostr event before signing ## Properties ### content -• **content**: `string` +> **content**: `string` Event content (arbitrary string) #### Defined in -[index.ts:73](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L73) +[index.ts:62](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L62) -___ +*** ### created\_at -• **created\_at**: `number` +> **created\_at**: `number` Unix timestamp in seconds #### Defined in -[index.ts:67](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L67) +[index.ts:56](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L56) -___ +*** ### kind -• **kind**: `number` +> **kind**: `number` Event kind (integer) #### Defined in -[index.ts:69](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L69) +[index.ts:58](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L58) -___ +*** ### pubkey -• **pubkey**: `string` +> **pubkey**: `string` Event creator's public key (32-bytes lowercase hex) #### Defined in -[index.ts:65](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L65) +[index.ts:54](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L54) -___ +*** ### tags -• **tags**: `string`[][] +> **tags**: `string`[][] Array of arrays of strings (event tags) #### Defined in -[index.ts:71](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L71) +[index.ts:60](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L60) diff --git a/docs/modules.md b/docs/modules.md deleted file mode 100644 index 4c946cc..0000000 --- a/docs/modules.md +++ /dev/null @@ -1,570 +0,0 @@ -[nostr-nsec-seedphrase - v0.4.2](README.md) / Exports - -# nostr-nsec-seedphrase - v0.4.2 - -## Table of contents - -### Interfaces - -- [KeyPair](interfaces/KeyPair.md) -- [NostrEvent](interfaces/NostrEvent.md) -- [UnsignedEvent](interfaces/UnsignedEvent.md) - -### Functions - -- [configureHMAC](modules.md#configurehmac) -- [createEvent](modules.md#createevent) -- [fromHex](modules.md#fromhex) -- [generateKeyPairWithSeed](modules.md#generatekeypairwithseed) -- [generateSeedPhrase](modules.md#generateseedphrase) -- [getEntropyFromSeedPhrase](modules.md#getentropyfromseedphrase) -- [hexToNpub](modules.md#hextonpub) -- [hexToNsec](modules.md#hextonsec) -- [npubToHex](modules.md#npubtohex) -- [nsecToHex](modules.md#nsectohex) -- [seedPhraseToKeyPair](modules.md#seedphrasetokeypair) -- [signEvent](modules.md#signevent) -- [signMessage](modules.md#signmessage) -- [validateSeedPhrase](modules.md#validateseedphrase) -- [verifyEvent](modules.md#verifyevent) -- [verifySignature](modules.md#verifysignature) - -## Functions - -### configureHMAC - -▸ **configureHMAC**(): `void` - -Configures secp256k1 with HMAC for WebSocket utilities -This is required for some WebSocket implementations - -#### Returns - -`void` - -**`Example`** - -```ts -configureHMAC(); -``` - -#### Defined in - -[index.ts:429](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L429) - -___ - -### createEvent - -▸ **createEvent**(`content`, `kind`, `privateKey`, `tags?`): `Promise`\<[`NostrEvent`](interfaces/NostrEvent.md)\> - -Creates a new signed Nostr event - -#### Parameters - -| Name | Type | Default value | Description | -| :------ | :------ | :------ | :------ | -| `content` | `string` | `undefined` | The event content | -| `kind` | `number` | `undefined` | The event kind (1 for text note, etc.) | -| `privateKey` | `string` | `undefined` | The hex-encoded private key to sign with | -| `tags?` | `string`[][] | `[]` | Optional event tags | - -#### Returns - -`Promise`\<[`NostrEvent`](interfaces/NostrEvent.md)\> - -The signed event - -**`Throws`** - -If event creation or signing fails - -**`Example`** - -```ts -const event = await createEvent( - "Hello Nostr!", - 1, - privateKey, - [["t", "nostr"]] -); -console.log(event); // complete signed event -``` - -#### Defined in - -[index.ts:479](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L479) - -___ - -### fromHex - -▸ **fromHex**(`privateKeyHex`): [`KeyPair`](interfaces/KeyPair.md) - -Creates a key pair from a hex private key - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `privateKeyHex` | `string` | The hex-encoded private key | - -#### Returns - -[`KeyPair`](interfaces/KeyPair.md) - -A key pair containing private and public keys in various formats - -**`Throws`** - -If the private key is invalid - -**`Example`** - -```ts -const keyPair = fromHex("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"); -console.log(keyPair.publicKey); // corresponding public key -console.log(keyPair.nsec); // bech32 nsec private key -console.log(keyPair.npub); // bech32 npub public key -``` - -#### Defined in - -[index.ts:190](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L190) - -___ - -### generateKeyPairWithSeed - -▸ **generateKeyPairWithSeed**(): [`KeyPair`](interfaces/KeyPair.md) - -Generates a new key pair with a random seed phrase - -#### Returns - -[`KeyPair`](interfaces/KeyPair.md) - -A new key pair containing private and public keys in various formats - -**`Example`** - -```ts -const keyPair = generateKeyPairWithSeed(); -console.log(keyPair.seedPhrase); // random seed phrase -console.log(keyPair.privateKey); // hex private key -console.log(keyPair.publicKey); // hex public key -``` - -#### Defined in - -[index.ts:168](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L168) - -___ - -### generateSeedPhrase - -▸ **generateSeedPhrase**(): `string` - -Generates a new BIP39 seed phrase - -#### Returns - -`string` - -A random 12-word BIP39 mnemonic seed phrase - -**`Example`** - -```ts -const seedPhrase = generateSeedPhrase(); -console.log(seedPhrase); // "witch collapse practice feed shame open despair creek road again ice least" -``` - -#### Defined in - -[index.ts:83](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L83) - -___ - -### getEntropyFromSeedPhrase - -▸ **getEntropyFromSeedPhrase**(`seedPhrase`): `string` - -Converts a BIP39 seed phrase to its entropy value - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `seedPhrase` | `string` | The BIP39 seed phrase to convert | - -#### Returns - -`string` - -The hex-encoded entropy value - -**`Throws`** - -If the seed phrase is invalid - -**`Example`** - -```ts -const entropy = getEntropyFromSeedPhrase("witch collapse practice feed shame open despair creek road again ice least"); -console.log(entropy); // "0123456789abcdef0123456789abcdef" -``` - -#### Defined in - -[index.ts:96](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L96) - -___ - -### hexToNpub - -▸ **hexToNpub**(`publicKeyHex`): `string` - -Converts a hex public key to bech32 npub format - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `publicKeyHex` | `string` | The hex-encoded public key | - -#### Returns - -`string` - -The bech32-encoded npub public key - -**`Throws`** - -If the public key is invalid - -**`Example`** - -```ts -const npub = hexToNpub("1234567890abcdef..."); -console.log(npub); // "npub1..." -``` - -#### Defined in - -[index.ts:272](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L272) - -___ - -### hexToNsec - -▸ **hexToNsec**(`privateKeyHex`): `string` - -Converts a hex private key to bech32 nsec format - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `privateKeyHex` | `string` | The hex-encoded private key | - -#### Returns - -`string` - -The bech32-encoded nsec private key - -**`Throws`** - -If the private key is invalid - -**`Example`** - -```ts -const nsec = hexToNsec("1234567890abcdef..."); -console.log(nsec); // "nsec1..." -``` - -#### Defined in - -[index.ts:291](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L291) - -___ - -### npubToHex - -▸ **npubToHex**(`npub`): `string` - -Converts a bech32 npub public key to hex format - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `npub` | `string` | The bech32-encoded npub public key | - -#### Returns - -`string` - -The hex-encoded public key - -**`Throws`** - -If the npub key is invalid - -**`Example`** - -```ts -const hex = npubToHex("npub1..."); -console.log(hex); // "1234567890abcdef..." -``` - -#### Defined in - -[index.ts:249](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L249) - -___ - -### nsecToHex - -▸ **nsecToHex**(`nsec`): `string` - -Converts a bech32 nsec private key to hex format - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `nsec` | `string` | The bech32-encoded nsec private key | - -#### Returns - -`string` - -The hex-encoded private key - -**`Throws`** - -If the nsec key is invalid - -**`Example`** - -```ts -const hex = nsecToHex("nsec1..."); -console.log(hex); // "1234567890abcdef..." -``` - -#### Defined in - -[index.ts:226](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L226) - -___ - -### seedPhraseToKeyPair - -▸ **seedPhraseToKeyPair**(`seedPhrase`): [`KeyPair`](interfaces/KeyPair.md) - -Converts a BIP39 seed phrase to a Nostr key pair - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `seedPhrase` | `string` | The BIP39 seed phrase to convert | - -#### Returns - -[`KeyPair`](interfaces/KeyPair.md) - -A key pair containing private and public keys in various formats - -**`Throws`** - -If the seed phrase is invalid or key generation fails - -**`Example`** - -```ts -const keyPair = seedPhraseToKeyPair("witch collapse practice feed shame open despair creek road again ice least"); -console.log(keyPair.privateKey); // hex private key -console.log(keyPair.publicKey); // hex public key -console.log(keyPair.nsec); // bech32 nsec private key -console.log(keyPair.npub); // bech32 npub public key -``` - -#### Defined in - -[index.ts:135](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L135) - -___ - -### signEvent - -▸ **signEvent**(`event`, `privateKey`): `Promise`\<`string`\> - -Signs a Nostr event - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `event` | [`UnsignedEvent`](interfaces/UnsignedEvent.md) | The event to sign | -| `privateKey` | `string` | The hex-encoded private key to sign with | - -#### Returns - -`Promise`\<`string`\> - -The hex-encoded signature - -**`Throws`** - -If signing fails - -**`Example`** - -```ts -const signature = await signEvent({ - pubkey: "...", - created_at: Math.floor(Date.now() / 1000), - kind: 1, - tags: [], - content: "Hello Nostr!" -}, privateKey); -``` - -#### Defined in - -[index.ts:372](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L372) - -___ - -### signMessage - -▸ **signMessage**(`message`, `privateKey`): `Promise`\<`string`\> - -Signs a message with a private key - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `message` | `string` | The message to sign | -| `privateKey` | `string` | The hex-encoded private key to sign with | - -#### Returns - -`Promise`\<`string`\> - -The hex-encoded signature - -**`Throws`** - -If signing fails - -**`Example`** - -```ts -const signature = await signMessage("Hello Nostr!", privateKey); -console.log(signature); // hex-encoded signature -``` - -#### Defined in - -[index.ts:311](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L311) - -___ - -### validateSeedPhrase - -▸ **validateSeedPhrase**(`seedPhrase`): `boolean` - -Validates a BIP39 seed phrase - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `seedPhrase` | `string` | The seed phrase to validate | - -#### Returns - -`boolean` - -True if the seed phrase is valid, false otherwise - -**`Example`** - -```ts -const isValid = validateSeedPhrase("witch collapse practice feed shame open despair creek road again ice least"); -console.log(isValid); // true -``` - -#### Defined in - -[index.ts:112](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L112) - -___ - -### verifyEvent - -▸ **verifyEvent**(`event`): `Promise`\<`boolean`\> - -Verifies a Nostr event signature - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `event` | [`NostrEvent`](interfaces/NostrEvent.md) | The event to verify | - -#### Returns - -`Promise`\<`boolean`\> - -True if the signature is valid, false otherwise - -**`Example`** - -```ts -const isValid = await verifyEvent(event); -console.log(isValid); // true or false -``` - -#### Defined in - -[index.ts:398](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L398) - -___ - -### verifySignature - -▸ **verifySignature**(`message`, `signature`, `publicKey`): `Promise`\<`boolean`\> - -Verifies a message signature - -#### Parameters - -| Name | Type | Description | -| :------ | :------ | :------ | -| `message` | `string` | The original message | -| `signature` | `string` | The hex-encoded signature to verify | -| `publicKey` | `string` | The hex-encoded public key to verify against | - -#### Returns - -`Promise`\<`boolean`\> - -True if the signature is valid, false otherwise - -**`Example`** - -```ts -const isValid = await verifySignature("Hello Nostr!", signature, publicKey); -console.log(isValid); // true or false -``` - -#### Defined in - -[index.ts:337](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/82dc31d49db09b8dba7ff55e6136b06bb1b16a3e/src/index.ts#L337) diff --git a/docs/namespaces/nip19/README.md b/docs/namespaces/nip19/README.md new file mode 100644 index 0000000..dfead14 --- /dev/null +++ b/docs/namespaces/nip19/README.md @@ -0,0 +1,21 @@ +[**nostr-nsec-seedphrase v0.6.0**](../../README.md) + +*** + +[nostr-nsec-seedphrase](../../globals.md) / nip19 + +# nip19 + +NIP-19 encoding and decoding functions + +## Index + +### Functions + +- [decode](functions/decode.md) +- [noteDecode](functions/noteDecode.md) +- [noteEncode](functions/noteEncode.md) +- [npubDecode](functions/npubDecode.md) +- [npubEncode](functions/npubEncode.md) +- [nsecDecode](functions/nsecDecode.md) +- [nsecEncode](functions/nsecEncode.md) diff --git a/docs/namespaces/nip19/functions/decode.md b/docs/namespaces/nip19/functions/decode.md new file mode 100644 index 0000000..5c54fe1 --- /dev/null +++ b/docs/namespaces/nip19/functions/decode.md @@ -0,0 +1,37 @@ +[**nostr-nsec-seedphrase v0.6.0**](../../../README.md) + +*** + +[nostr-nsec-seedphrase](../../../globals.md) / [nip19](../README.md) / decode + +# Function: decode() + +> **decode**(`bech32str`): `object` + +Decodes any bech32-encoded Nostr entity + +## Parameters + +### bech32str + +`string` + +The bech32-encoded string + +## Returns + +`object` + +Object containing the decoded type and data + +### data + +> **data**: `Uint8Array` + +### type + +> **type**: `string` + +## Defined in + +[index.ts:304](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L304) diff --git a/docs/namespaces/nip19/functions/noteDecode.md b/docs/namespaces/nip19/functions/noteDecode.md new file mode 100644 index 0000000..95fd683 --- /dev/null +++ b/docs/namespaces/nip19/functions/noteDecode.md @@ -0,0 +1,29 @@ +[**nostr-nsec-seedphrase v0.6.0**](../../../README.md) + +*** + +[nostr-nsec-seedphrase](../../../globals.md) / [nip19](../README.md) / noteDecode + +# Function: noteDecode() + +> **noteDecode**(`note`): `string` + +Decodes a note string to hex format + +## Parameters + +### note + +`string` + +The bech32-encoded note string + +## Returns + +`string` + +The hex-encoded event ID + +## Defined in + +[index.ts:290](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L290) diff --git a/docs/namespaces/nip19/functions/noteEncode.md b/docs/namespaces/nip19/functions/noteEncode.md new file mode 100644 index 0000000..7395bae --- /dev/null +++ b/docs/namespaces/nip19/functions/noteEncode.md @@ -0,0 +1,29 @@ +[**nostr-nsec-seedphrase v0.6.0**](../../../README.md) + +*** + +[nostr-nsec-seedphrase](../../../globals.md) / [nip19](../README.md) / noteEncode + +# Function: noteEncode() + +> **noteEncode**(`eventId`): `string` + +Encodes an event ID into note format + +## Parameters + +### eventId + +`string` + +The hex-encoded event ID + +## Returns + +`string` + +The bech32-encoded note string + +## Defined in + +[index.ts:279](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L279) diff --git a/docs/namespaces/nip19/functions/npubDecode.md b/docs/namespaces/nip19/functions/npubDecode.md new file mode 100644 index 0000000..e62ceac --- /dev/null +++ b/docs/namespaces/nip19/functions/npubDecode.md @@ -0,0 +1,29 @@ +[**nostr-nsec-seedphrase v0.6.0**](../../../README.md) + +*** + +[nostr-nsec-seedphrase](../../../globals.md) / [nip19](../README.md) / npubDecode + +# Function: npubDecode() + +> **npubDecode**(`npub`): `string` + +Decodes an npub string to hex format + +## Parameters + +### npub + +`string` + +The bech32-encoded npub string + +## Returns + +`string` + +The hex-encoded public key + +## Defined in + +[index.ts:244](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L244) diff --git a/docs/namespaces/nip19/functions/npubEncode.md b/docs/namespaces/nip19/functions/npubEncode.md new file mode 100644 index 0000000..e5ceb7c --- /dev/null +++ b/docs/namespaces/nip19/functions/npubEncode.md @@ -0,0 +1,29 @@ +[**nostr-nsec-seedphrase v0.6.0**](../../../README.md) + +*** + +[nostr-nsec-seedphrase](../../../globals.md) / [nip19](../README.md) / npubEncode + +# Function: npubEncode() + +> **npubEncode**(`pubkey`): `string` + +Encodes a public key into npub format + +## Parameters + +### pubkey + +`string` + +The hex-encoded public key + +## Returns + +`string` + +The bech32-encoded npub string + +## Defined in + +[index.ts:233](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L233) diff --git a/docs/namespaces/nip19/functions/nsecDecode.md b/docs/namespaces/nip19/functions/nsecDecode.md new file mode 100644 index 0000000..e4734b8 --- /dev/null +++ b/docs/namespaces/nip19/functions/nsecDecode.md @@ -0,0 +1,29 @@ +[**nostr-nsec-seedphrase v0.6.0**](../../../README.md) + +*** + +[nostr-nsec-seedphrase](../../../globals.md) / [nip19](../README.md) / nsecDecode + +# Function: nsecDecode() + +> **nsecDecode**(`nsec`): `string` + +Decodes an nsec string to hex format + +## Parameters + +### nsec + +`string` + +The bech32-encoded nsec string + +## Returns + +`string` + +The hex-encoded private key + +## Defined in + +[index.ts:267](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L267) diff --git a/docs/namespaces/nip19/functions/nsecEncode.md b/docs/namespaces/nip19/functions/nsecEncode.md new file mode 100644 index 0000000..2b7cae0 --- /dev/null +++ b/docs/namespaces/nip19/functions/nsecEncode.md @@ -0,0 +1,29 @@ +[**nostr-nsec-seedphrase v0.6.0**](../../../README.md) + +*** + +[nostr-nsec-seedphrase](../../../globals.md) / [nip19](../README.md) / nsecEncode + +# Function: nsecEncode() + +> **nsecEncode**(`privkey`): `string` + +Encodes a private key into nsec format + +## Parameters + +### privkey + +`string` + +The hex-encoded private key + +## Returns + +`string` + +The bech32-encoded nsec string + +## Defined in + +[index.ts:256](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase/blob/885e04e5180059d4aa901af59d633038a53240cb/src/index.ts#L256) diff --git a/package-lock.json b/package-lock.json index 9c7b4b7..e6a5117 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,106 +1,34 @@ { "name": "nostr-nsec-seedphrase", - "version": "0.5.0", + "version": "0.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "nostr-nsec-seedphrase", - "version": "0.5.0", + "version": "0.6.0", "license": "MIT", "dependencies": { "@noble/hashes": "^1.3.3", "@noble/secp256k1": "^2.1.0", - "@types/bech32": "^1.1.8", + "@scure/base": "^1.2.1", "bech32": "^2.0.0", "bip39": "^3.1.0", - "nostr-tools": "^2.1.4", + "nostr-crypto-utils": "^0.4.2", "pino": "^8.17.2" }, "devDependencies": { - "@types/bip39": "^3.0.0", - "@types/node": "^20.17.10", + "@types/node": "^20.10.5", "@typescript-eslint/eslint-plugin": "^6.15.0", "@typescript-eslint/parser": "^6.15.0", - "@vitest/coverage-v8": "^1.6.0", "eslint": "^8.56.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.1.1", - "pino-pretty": "^10.3.0", "prettier": "^3.1.1", - "serve": "^14.2.1", - "typedoc": "^0.25.4", - "typedoc-plugin-markdown": "^3.17.1", + "typedoc": "^0.27.6", + "typedoc-plugin-markdown": "^4.3.3", "typescript": "^5.3.3", - "vite": "^5.0.10", "vitest": "^1.6.0" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", - "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.26.3" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/types": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", - "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -497,6 +425,7 @@ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" }, @@ -515,6 +444,7 @@ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -524,6 +454,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -547,6 +478,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -557,6 +489,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -569,16 +502,30 @@ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@gerrit0/mini-shiki": { + "version": "1.24.4", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-1.24.4.tgz", + "integrity": "sha512-YEHW1QeAg6UmxEmswiQbOVEg1CW22b1XUD/lNTliOsu0LD0wqoyleFMnmbTp697QE0pcadQiR5cVtbbAPncvpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/engine-oniguruma": "^1.24.2", + "@shikijs/types": "^1.24.2", + "@shikijs/vscode-textmate": "^9.3.1" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", @@ -593,6 +540,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -603,6 +551,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -615,6 +564,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -628,22 +578,15 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "engines": { - "node": ">=8" - } + "license": "BSD-3-Clause" }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, + "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -651,58 +594,36 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT" + }, + "node_modules/@noble/curves": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.7.0.tgz", + "integrity": "sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==", + "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@noble/hashes": "1.6.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@noble/ciphers": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.5.3.tgz", - "integrity": "sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w==", + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.0.tgz", + "integrity": "sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, "funding": { "url": "https://paulmillr.com/funding/" } @@ -711,6 +632,7 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.1.tgz", "integrity": "sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==", + "license": "MIT", "engines": { "node": "^14.21.3 || >=16" }, @@ -722,6 +644,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-2.1.0.tgz", "integrity": "sha512-XLEQQNdablO0XZOIniFQimiXsZDNwaYgL96dZwC54Q30imSbAOFf3NKtepc+cXyuZf5Q1HCgbqgZ2UFFuHVcEw==", + "license": "MIT", "funding": { "url": "https://paulmillr.com/funding/" } @@ -731,6 +654,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -744,6 +668,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -753,6 +678,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -761,23 +687,10 @@ "node": ">= 8" } }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz", - "integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz", + "integrity": "sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==", "cpu": [ "arm" ], @@ -789,9 +702,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz", - "integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz", + "integrity": "sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==", "cpu": [ "arm64" ], @@ -803,9 +716,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz", - "integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz", + "integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==", "cpu": [ "arm64" ], @@ -817,9 +730,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz", - "integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz", + "integrity": "sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==", "cpu": [ "x64" ], @@ -831,9 +744,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz", - "integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz", + "integrity": "sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==", "cpu": [ "arm64" ], @@ -845,9 +758,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz", - "integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz", + "integrity": "sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==", "cpu": [ "x64" ], @@ -859,9 +772,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz", - "integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz", + "integrity": "sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==", "cpu": [ "arm" ], @@ -873,9 +786,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz", - "integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz", + "integrity": "sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==", "cpu": [ "arm" ], @@ -887,9 +800,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz", - "integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz", + "integrity": "sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==", "cpu": [ "arm64" ], @@ -901,9 +814,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz", - "integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz", + "integrity": "sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==", "cpu": [ "arm64" ], @@ -915,9 +828,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz", - "integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz", + "integrity": "sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==", "cpu": [ "loong64" ], @@ -929,9 +842,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz", - "integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz", + "integrity": "sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==", "cpu": [ "ppc64" ], @@ -943,9 +856,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz", - "integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz", + "integrity": "sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==", "cpu": [ "riscv64" ], @@ -957,9 +870,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz", - "integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz", + "integrity": "sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==", "cpu": [ "s390x" ], @@ -971,9 +884,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz", - "integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz", + "integrity": "sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==", "cpu": [ "x64" ], @@ -985,9 +898,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz", - "integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz", + "integrity": "sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==", "cpu": [ "x64" ], @@ -999,9 +912,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz", - "integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz", + "integrity": "sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==", "cpu": [ "arm64" ], @@ -1013,9 +926,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz", - "integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz", + "integrity": "sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==", "cpu": [ "ia32" ], @@ -1027,9 +940,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz", - "integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz", + "integrity": "sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==", "cpu": [ "x64" ], @@ -1041,110 +954,49 @@ ] }, "node_modules/@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@scure/bip32": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", - "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", - "dependencies": { - "@noble/curves": "~1.1.0", - "@noble/hashes": "~1.3.1", - "@scure/base": "~1.1.0" - }, + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.1.tgz", + "integrity": "sha512-DGmGtC8Tt63J5GfHgfl5CuAXh96VF/LD8K9Hr/Gv0J2lAoRGlPOMpqMpMbCTOoOJMZCk2Xt+DskdDyn6dEFdzQ==", + "license": "MIT", "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/@scure/bip32/node_modules/@noble/curves": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", - "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "node_modules/@shikijs/engine-oniguruma": { + "version": "1.24.4", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.24.4.tgz", + "integrity": "sha512-Do2ry6flp2HWdvpj2XOwwa0ljZBRy15HKZITzPcNIBOGSeprnA8gOooA/bLsSPuy8aJBa+Q/r34dMmC3KNL/zw==", + "dev": true, + "license": "MIT", "dependencies": { - "@noble/hashes": "1.3.1" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32/node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", - "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32/node_modules/@noble/hashes": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", - "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "@shikijs/types": "1.24.4", + "@shikijs/vscode-textmate": "^9.3.1" } }, - "node_modules/@scure/bip39": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", - "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "node_modules/@shikijs/types": { + "version": "1.24.4", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.24.4.tgz", + "integrity": "sha512-0r0XU7Eaow0PuDxuWC1bVqmWCgm3XqizIaT7SM42K03vc69LGooT0U8ccSR44xP/hGlNx4FKhtYpV+BU6aaKAA==", + "dev": true, + "license": "MIT", "dependencies": { - "@noble/hashes": "~1.3.0", - "@scure/base": "~1.1.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "@shikijs/vscode-textmate": "^9.3.1", + "@types/hast": "^3.0.4" } }, - "node_modules/@scure/bip39/node_modules/@noble/hashes": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", - "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } + "node_modules/@shikijs/vscode-textmate": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.1.tgz", + "integrity": "sha512-79QfK1393x9Ho60QFyLti+QfdJzRQCVLFb97kOIV7Eo9vQU/roINgk7m24uv0a7AUvN//RDH36FLjjK48v0s9g==", + "dev": true, + "license": "MIT" }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@types/bech32": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@types/bech32/-/bech32-1.1.8.tgz", - "integrity": "sha512-shvkfjHrDoGPhNHQvLjTESgDOzdcGQuyWgkbc2PQZSUdhwArt+gjfn9ehPyVPKQ1Vnams1deetvZxe0s98bl4g==", - "deprecated": "This is a stub types definition. bech32 provides its own type definitions, so you do not need this installed.", - "dependencies": { - "bech32": "*" - } - }, - "node_modules/@types/bip39": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/bip39/-/bip39-3.0.4.tgz", - "integrity": "sha512-kgmgxd14vTUMqcKu/gRi7adMchm7teKnOzdkeP0oQ5QovXpbUJISU0KUtBt84DdxCws/YuNlSCIoZqgXexe6KQ==", - "deprecated": "This is a stub types definition. bip39 provides its own type definitions, so you do not need this installed.", "dev": true, - "license": "MIT", - "dependencies": { - "bip39": "*" - } + "license": "MIT" }, "node_modules/@types/estree": { "version": "1.0.6", @@ -1153,11 +1005,22 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "20.17.10", @@ -1173,13 +1036,22 @@ "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.21.0", @@ -1215,6 +1087,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -1243,6 +1116,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0" @@ -1260,6 +1134,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "6.21.0", "@typescript-eslint/utils": "6.21.0", @@ -1287,6 +1162,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, + "license": "MIT", "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -1300,6 +1176,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", @@ -1328,6 +1205,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", @@ -1353,6 +1231,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" @@ -1366,53 +1245,11 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/@vitest/coverage-v8": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.6.0.tgz", - "integrity": "sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.1", - "@bcoe/v8-coverage": "^0.2.3", - "debug": "^4.3.4", - "istanbul-lib-coverage": "^3.2.2", - "istanbul-lib-report": "^3.0.1", - "istanbul-lib-source-maps": "^5.0.4", - "istanbul-reports": "^3.1.6", - "magic-string": "^0.30.5", - "magicast": "^0.3.3", - "picocolors": "^1.0.0", - "std-env": "^3.5.0", - "strip-literal": "^2.0.0", - "test-exclude": "^6.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "vitest": "1.6.0" - } - }, - "node_modules/@vitest/coverage-v8/node_modules/istanbul-lib-source-maps": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", - "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.23", - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0" - }, - "engines": { - "node": ">=10" - } + "license": "ISC" }, "node_modules/@vitest/expect": { "version": "1.6.0", @@ -1517,12 +1354,6 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/@zeit/schemas": { - "version": "2.36.0", - "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.36.0.tgz", - "integrity": "sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==", - "dev": true - }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -1535,24 +1366,12 @@ "node": ">=6.5" } }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/acorn": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1565,6 +1384,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -1587,6 +1407,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1598,55 +1419,22 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/ansi-sequence-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", - "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", - "dev": true - }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -1657,43 +1445,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1721,7 +1485,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", @@ -1746,67 +1511,24 @@ "node_modules/bech32": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==", + "license": "MIT" }, "node_modules/bip39": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", + "license": "ISC", "dependencies": { "@noble/hashes": "^1.2.0" } }, - "node_modules/boxen": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.0.tgz", - "integrity": "sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==", - "dev": true, - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.0", - "chalk": "^5.0.1", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/boxen/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -1816,6 +1538,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -1847,15 +1570,6 @@ "ieee754": "^1.2.1" } }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -1871,22 +1585,11 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/chai": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", @@ -1906,21 +1609,12 @@ "node": ">=4" } }, - "node_modules/chai/node_modules/type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -1932,21 +1626,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chalk-template": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", - "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/chalk-template?sponsor=1" - } - }, "node_modules/check-error": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", @@ -1960,40 +1639,12 @@ "node": "*" } }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clipboardy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz", - "integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==", - "dev": true, - "dependencies": { - "arch": "^2.2.0", - "execa": "^5.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2005,71 +1656,15 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true, "license": "MIT" }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/confbox": { "version": "0.1.8", @@ -2078,20 +1673,12 @@ "dev": true, "license": "MIT" }, - "node_modules/content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2101,21 +1688,18 @@ "node": ">= 8" } }, - "node_modules/dateformat": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "license": "MIT" }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -2141,26 +1725,19 @@ "node": ">=6" } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -2170,6 +1747,7 @@ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -2182,6 +1760,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -2189,26 +1768,17 @@ "node": ">=6.0.0" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/esbuild": { @@ -2255,6 +1825,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2268,6 +1839,7 @@ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -2318,55 +1890,12 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", - "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.9.1" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": "*", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -2383,6 +1912,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -2395,6 +1925,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2405,6 +1936,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2417,6 +1949,7 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -2434,6 +1967,7 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -2446,6 +1980,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -2458,6 +1993,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2477,6 +2013,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -2500,53 +2037,42 @@ } }, "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=16.17" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/fast-copy": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", - "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==", - "dev": true, - "license": "MIT" - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true, - "license": "Apache-2.0" + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2563,6 +2089,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -2574,13 +2101,15 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-redact": { "version": "3.5.0", @@ -2591,18 +2120,12 @@ "node": ">=6" } }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true, - "license": "MIT" - }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -2612,6 +2135,7 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -2624,6 +2148,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2636,6 +2161,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -2652,6 +2178,7 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -2665,13 +2192,15 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", @@ -2679,6 +2208,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -2698,12 +2228,13 @@ } }, "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2715,6 +2246,7 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2735,6 +2267,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -2747,6 +2280,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2757,6 +2291,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2769,6 +2304,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -2784,6 +2320,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -2803,58 +2340,27 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } + "license": "MIT" }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/help-me": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", - "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", - "dev": true, - "license": "MIT" - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=10.17.0" + "node": ">=16.17.0" } }, "node_modules/ieee754": { @@ -2882,6 +2388,7 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -2891,6 +2398,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -2907,6 +2415,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -2917,6 +2426,7 @@ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -2926,52 +2436,25 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "dev": true, + "license": "ISC" }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -2984,6 +2467,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -2993,103 +2477,44 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/is-port-reachable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-4.0.0.tgz", - "integrity": "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } + "license": "ISC" }, - "node_modules/joycon": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", - "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -3101,31 +2526,29 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -3135,6 +2558,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -3143,6 +2567,16 @@ "node": ">= 0.8.0" } }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/local-pkg": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", @@ -3165,6 +2599,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -3179,7 +2614,8 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loupe": { "version": "2.3.7", @@ -3195,68 +2631,57 @@ "version": "2.3.9", "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/magic-string": { - "version": "0.30.15", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.15.tgz", - "integrity": "sha512-zXeaYRgZ6ldS1RJJUrMrYgNJ4fdwnyI6tVqoiIhyCyv5IVTK9BU8Ic2l253GGETQHxI4HNUwhJ3fjDhKqEoaAw==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, - "node_modules/magicast": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", - "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.25.4", - "@babel/types": "^7.25.4", - "source-map-js": "^1.2.0" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "bin": { + "markdown-it": "bin/markdown-it.mjs" } }, - "node_modules/marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "dev": true, - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 12" - } + "license": "MIT" }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -3266,6 +2691,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -3274,43 +2700,17 @@ "node": ">=8.6" } }, - "node_modules/mime-db": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", - "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/minimatch": { @@ -3318,6 +2718,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -3328,16 +2729,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/mlly": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.3.tgz", @@ -3355,7 +2746,8 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.8", @@ -3380,96 +2772,54 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "license": "MIT" }, - "node_modules/nostr-tools": { - "version": "2.10.4", - "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.10.4.tgz", - "integrity": "sha512-biU7sk+jxHgVASfobg2T5ttxOGGSt69wEVBC51sHHOEaKAAdzHBLV/I2l9Rf61UzClhliZwNouYhqIso4a3HYg==", + "node_modules/nostr-crypto-utils": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/nostr-crypto-utils/-/nostr-crypto-utils-0.4.2.tgz", + "integrity": "sha512-9jVtKw3m8+iEZQRMARREDKyy5Bkyz1sYFJwWicyclkjByw8j4N6cFTxkUAeJqUDkg/8j1DmeIWqEjJFXm/rYTw==", + "license": "MIT", "dependencies": { - "@noble/ciphers": "^0.5.1", - "@noble/curves": "1.2.0", - "@noble/hashes": "1.3.1", - "@scure/base": "1.1.1", - "@scure/bip32": "1.3.1", - "@scure/bip39": "1.2.1" - }, - "optionalDependencies": { - "nostr-wasm": "0.1.0" - }, - "peerDependencies": { - "typescript": ">=5.0.0" + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", + "@noble/secp256k1": "^2.0.0", + "bech32": "^2.0.0", + "buffer": "^6.0.3", + "crypto-js": "^4.2.0", + "pino": "^8.17.1" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": ">=16.0.0" } }, - "node_modules/nostr-tools/node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@noble/hashes": "1.3.2" + "path-key": "^4.0.0" }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/nostr-tools/node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", "engines": { - "node": ">= 16" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/nostr-tools/node_modules/@noble/hashes": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", - "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 16" + "node": ">=12" }, "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/nostr-wasm": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/nostr-wasm/-/nostr-wasm-0.1.0.tgz", - "integrity": "sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA==", - "optional": true - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/on-exit-leak-free": { @@ -3481,34 +2831,27 @@ "node": ">=14.0.0" } }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "license": "MIT", "dependencies": { - "mimic-fn": "^2.1.0" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3519,6 +2862,7 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -3536,6 +2880,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -3551,6 +2896,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -3566,6 +2912,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -3578,6 +2925,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3587,36 +2935,27 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/path-to-regexp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", - "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", - "dev": true - }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3642,13 +2981,15 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -3688,32 +3029,6 @@ "split2": "^4.0.0" } }, - "node_modules/pino-pretty": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.3.1.tgz", - "integrity": "sha512-az8JbIYeN/1iLj2t0jR9DV48/LQ3RC6hZPpapKPkb84Q+yTidMCpgWxIT3N0flnBDilyBQ1luWNpOeJptjdp/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "colorette": "^2.0.7", - "dateformat": "^4.6.3", - "fast-copy": "^3.0.0", - "fast-safe-stringify": "^2.1.1", - "help-me": "^5.0.0", - "joycon": "^3.1.1", - "minimist": "^1.2.6", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^1.0.0", - "pump": "^3.0.0", - "readable-stream": "^4.0.0", - "secure-json-parse": "^2.4.0", - "sonic-boom": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "bin": { - "pino-pretty": "bin.js" - } - }, "node_modules/pino-std-serializers": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", @@ -3721,14 +3036,14 @@ "license": "MIT" }, "node_modules/pkg-types": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", - "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.0.tgz", + "integrity": "sha512-kS7yWjVFCkIw9hqdJBoMxDdzEngmkr5FXeWZZfQ6GoYacjVnsW6l2CcYW/0ThD0vF4LPJgVYnrg4d0uuhwYQbg==", "dev": true, "license": "MIT", "dependencies": { "confbox": "^0.1.8", - "mlly": "^1.7.2", + "mlly": "^1.7.3", "pathe": "^1.1.2" } }, @@ -3766,6 +3081,7 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -3775,6 +3091,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -3785,28 +3102,16 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "license": "MIT", "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -3817,6 +3122,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3839,22 +3145,22 @@ "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", "license": "MIT" }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "engines": { + "node": ">=6" } }, - "node_modules/punycode": { + "node_modules/punycode.js": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3877,7 +3183,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/quick-format-unescaped": { "version": "4.0.4", @@ -3885,49 +3192,17 @@ "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", "license": "MIT" }, - "node_modules/range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.6.0.tgz", + "integrity": "sha512-cbAdYt0VcnpN2Bekq7PU+k363ZRsPwJoEEJOEtSJQlJXzwaxt3FIo/uL+KeDSGIjJqtkwyge4KQgD2S2kd+CQw==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -3949,42 +3224,12 @@ "node": ">= 12.13.0" } }, - "node_modules/registry-auth-token": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", - "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", - "dev": true, - "dependencies": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", - "dev": true, - "dependencies": { - "rc": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -3994,6 +3239,7 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -4005,6 +3251,7 @@ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -4016,9 +3263,9 @@ } }, "node_modules/rollup": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.1.tgz", - "integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.1.tgz", + "integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==", "dev": true, "license": "MIT", "dependencies": { @@ -4032,25 +3279,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.28.1", - "@rollup/rollup-android-arm64": "4.28.1", - "@rollup/rollup-darwin-arm64": "4.28.1", - "@rollup/rollup-darwin-x64": "4.28.1", - "@rollup/rollup-freebsd-arm64": "4.28.1", - "@rollup/rollup-freebsd-x64": "4.28.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.28.1", - "@rollup/rollup-linux-arm-musleabihf": "4.28.1", - "@rollup/rollup-linux-arm64-gnu": "4.28.1", - "@rollup/rollup-linux-arm64-musl": "4.28.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.28.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.28.1", - "@rollup/rollup-linux-riscv64-gnu": "4.28.1", - "@rollup/rollup-linux-s390x-gnu": "4.28.1", - "@rollup/rollup-linux-x64-gnu": "4.28.1", - "@rollup/rollup-linux-x64-musl": "4.28.1", - "@rollup/rollup-win32-arm64-msvc": "4.28.1", - "@rollup/rollup-win32-ia32-msvc": "4.28.1", - "@rollup/rollup-win32-x64-msvc": "4.28.1", + "@rollup/rollup-android-arm-eabi": "4.29.1", + "@rollup/rollup-android-arm64": "4.29.1", + "@rollup/rollup-darwin-arm64": "4.29.1", + "@rollup/rollup-darwin-x64": "4.29.1", + "@rollup/rollup-freebsd-arm64": "4.29.1", + "@rollup/rollup-freebsd-x64": "4.29.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.29.1", + "@rollup/rollup-linux-arm-musleabihf": "4.29.1", + "@rollup/rollup-linux-arm64-gnu": "4.29.1", + "@rollup/rollup-linux-arm64-musl": "4.29.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.29.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.29.1", + "@rollup/rollup-linux-riscv64-gnu": "4.29.1", + "@rollup/rollup-linux-s390x-gnu": "4.29.1", + "@rollup/rollup-linux-x64-gnu": "4.29.1", + "@rollup/rollup-linux-x64-musl": "4.29.1", + "@rollup/rollup-win32-arm64-msvc": "4.29.1", + "@rollup/rollup-win32-ia32-msvc": "4.29.1", + "@rollup/rollup-win32-x64-msvc": "4.29.1", "fsevents": "~2.3.2" } }, @@ -4073,6 +3320,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -4106,18 +3354,12 @@ "node": ">=10" } }, - "node_modules/secure-json-parse": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", - "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4125,128 +3367,12 @@ "node": ">=10" } }, - "node_modules/serve": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/serve/-/serve-14.2.4.tgz", - "integrity": "sha512-qy1S34PJ/fcY8gjVGszDB3EXiPSk5FKhUa7tQe0UPRddxRidc2V6cNHPNewbE1D7MAkgLuWEt3Vw56vYy73tzQ==", - "dev": true, - "dependencies": { - "@zeit/schemas": "2.36.0", - "ajv": "8.12.0", - "arg": "5.0.2", - "boxen": "7.0.0", - "chalk": "5.0.1", - "chalk-template": "0.4.0", - "clipboardy": "3.0.0", - "compression": "1.7.4", - "is-port-reachable": "4.0.0", - "serve-handler": "6.1.6", - "update-check": "1.5.4" - }, - "bin": { - "serve": "build/main.js" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/serve-handler": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", - "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", - "dev": true, - "dependencies": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "mime-types": "2.1.18", - "minimatch": "3.1.2", - "path-is-inside": "1.0.2", - "path-to-regexp": "3.3.0", - "range-parser": "1.2.0" - } - }, - "node_modules/serve-handler/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/serve-handler/node_modules/mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-handler/node_modules/mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "dependencies": { - "mime-db": "~1.33.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-handler/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/serve/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/serve/node_modules/chalk": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", - "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/serve/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -4259,22 +3385,11 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/shiki": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", - "integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==", - "dev": true, - "dependencies": { - "ansi-sequence-parser": "^1.1.0", - "jsonc-parser": "^3.2.0", - "vscode-oniguruma": "^1.7.0", - "vscode-textmate": "^8.0.0" - } - }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -4283,16 +3398,24 @@ "license": "ISC" }, "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4306,15 +3429,6 @@ "atomic-sleep": "^1.0.0" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -4357,55 +3471,12 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4414,12 +3485,16 @@ } }, "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strip-json-comments": { @@ -4427,6 +3502,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -4447,83 +3523,25 @@ "url": "https://github.com/sponsors/antfu" } }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true, - "license": "MIT" - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/synckit": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", - "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", - "dev": true, "license": "MIT", "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/thread-stream": { "version": "2.7.0", @@ -4566,6 +3584,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -4578,6 +3597,7 @@ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -4585,18 +3605,12 @@ "typescript": ">=4.2.0" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "license": "0BSD" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -4605,10 +3619,11 @@ } }, "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -4618,6 +3633,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -4626,43 +3642,63 @@ } }, "node_modules/typedoc": { - "version": "0.25.13", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.13.tgz", - "integrity": "sha512-pQqiwiJ+Z4pigfOnnysObszLiU3mVLWAExSPf+Mu06G/qsc3wzbuM56SZQvONhHLncLUhYzOVkjFFpFfL5AzhQ==", + "version": "0.27.6", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.27.6.tgz", + "integrity": "sha512-oBFRoh2Px6jFx366db0lLlihcalq/JzyCVp7Vaq1yphL/tbgx2e+bkpkCgJPunaPvPwoTOXSwasfklWHm7GfAw==", "dev": true, + "license": "Apache-2.0", "dependencies": { + "@gerrit0/mini-shiki": "^1.24.0", "lunr": "^2.3.9", - "marked": "^4.3.0", - "minimatch": "^9.0.3", - "shiki": "^0.14.7" + "markdown-it": "^14.1.0", + "minimatch": "^9.0.5", + "yaml": "^2.6.1" }, "bin": { "typedoc": "bin/typedoc" }, "engines": { - "node": ">= 16" + "node": ">= 18" }, "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x" + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x" } }, "node_modules/typedoc-plugin-markdown": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.17.1.tgz", - "integrity": "sha512-QzdU3fj0Kzw2XSdoL15ExLASt2WPqD7FbLeaqwT70+XjKyTshBnUlQA5nNREO1C2P8Uen0CDjsBLMsCQ+zd0lw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-4.3.3.tgz", + "integrity": "sha512-kESCcNRzOcFJATLML2FoCfaTF9c0ujmbZ+UXsJvmNlFLS3v8tDKfDifreJXvXWa9d8gUcetZqOqFcZ/7+Ba34Q==", "dev": true, - "dependencies": { - "handlebars": "^4.7.7" + "license": "MIT", + "engines": { + "node": ">= 18" }, "peerDependencies": { - "typedoc": ">=0.24.0" + "typedoc": "0.27.x" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "devOptional": true, + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -4671,6 +3707,13 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, "node_modules/ufo": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", @@ -4678,53 +3721,23 @@ "dev": true, "license": "MIT" }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true - }, - "node_modules/update-check": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz", - "integrity": "sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==", "dev": true, - "dependencies": { - "registry-auth-token": "3.3.2", - "registry-url": "3.1.0" - } + "license": "MIT" }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/vite": { "version": "5.4.11", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", @@ -4874,167 +3887,12 @@ } } }, - "node_modules/vitest/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/vitest/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/vitest/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/vitest/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vscode-oniguruma": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", - "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", - "dev": true - }, - "node_modules/vscode-textmate": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", - "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", - "dev": true - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -5062,103 +3920,42 @@ "node": ">=8" } }, - "node_modules/widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "dev": true, - "dependencies": { - "string-width": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } + "license": "ISC" }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "node_modules/yaml": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" + "license": "ISC", + "bin": { + "yaml": "bin.mjs" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">= 14" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index 84af176..a56111d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nostr-nsec-seedphrase", - "version": "0.5.0", + "version": "0.6.0", "description": "A TypeScript library for managing Nostr keys with seed phrases, including event signing, verification, and WebSocket utilities", "type": "module", "main": "./dist/index.js", @@ -16,7 +16,7 @@ "test": "vitest run", "test:watch": "vitest", "test:coverage": "vitest run --coverage", - "lint": "eslint src/**/*.ts", + "lint": "eslint src --ext .ts", "format": "prettier --write \"src/**/*.ts\"", "prepare": "npm run build", "prepublishOnly": "npm test && npm run lint", @@ -49,28 +49,21 @@ "dependencies": { "@noble/hashes": "^1.3.3", "@noble/secp256k1": "^2.1.0", - "@types/bech32": "^1.1.8", + "@scure/base": "^1.2.1", "bech32": "^2.0.0", "bip39": "^3.1.0", - "nostr-tools": "^2.1.4", + "nostr-crypto-utils": "^0.4.2", "pino": "^8.17.2" }, "devDependencies": { - "@types/bip39": "^3.0.0", - "@types/node": "^20.17.10", + "@types/node": "^20.10.5", "@typescript-eslint/eslint-plugin": "^6.15.0", "@typescript-eslint/parser": "^6.15.0", - "@vitest/coverage-v8": "^1.6.0", "eslint": "^8.56.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.1.1", - "pino-pretty": "^10.3.0", "prettier": "^3.1.1", - "serve": "^14.2.1", - "typedoc": "^0.25.4", - "typedoc-plugin-markdown": "^3.17.1", + "typedoc": "^0.27.6", + "typedoc-plugin-markdown": "^4.3.3", "typescript": "^5.3.3", - "vite": "^5.0.10", "vitest": "^1.6.0" }, "publishConfig": { diff --git a/src/bips/bip39.ts b/src/bips/bip39.ts new file mode 100644 index 0000000..2b9fb86 --- /dev/null +++ b/src/bips/bip39.ts @@ -0,0 +1,64 @@ +import { generateMnemonic, validateMnemonic, mnemonicToEntropy } from 'bip39'; +import { sha256 } from '@noble/hashes/sha256'; +import { logger } from '../utils/logger.js'; + +/** + * Generates a new BIP39 seed phrase + * @returns {string} The generated seed phrase + * @example + * const seedPhrase = generateSeedPhrase(); + * console.log(seedPhrase); // "witch collapse practice feed shame open despair creek road again ice least" + */ +export function generateSeedPhrase(): string { + try { + return generateMnemonic(); + } catch (error) { + logger.error('Failed to generate seed phrase:', error); + throw new Error('Failed to generate seed phrase'); + } +} + +/** + * Validates a BIP39 seed phrase + * @param {string} seedPhrase - The seed phrase to validate + * @returns {boolean} True if the seed phrase is valid + * @example + * const isValid = validateSeedPhrase("witch collapse practice feed shame open despair creek road again ice least"); + * console.log(isValid); // true + */ +export function validateSeedPhrase(seedPhrase: string): boolean { + try { + return validateMnemonic(seedPhrase); + } catch (error) { + logger.error('Failed to validate seed phrase:', error); + return false; + } +} + +/** + * Converts a BIP39 seed phrase to its entropy value + * @param {string} seedPhrase - The BIP39 seed phrase to convert + * @returns {Uint8Array} The entropy value + * @throws {Error} If the seed phrase is invalid + * @example + * const entropy = getEntropyFromSeedPhrase("witch collapse practice feed shame open despair creek road again ice least"); + * console.log(entropy); // Uint8Array + */ +export function getEntropyFromSeedPhrase(seedPhrase: string): Uint8Array { + try { + if (!validateSeedPhrase(seedPhrase)) { + throw new Error('Invalid seed phrase'); + } + // Convert the seed phrase to entropy bytes + const entropyHex = mnemonicToEntropy(seedPhrase); + // Convert hex string to Uint8Array + const entropyBytes = new Uint8Array(entropyHex.length / 2); + for (let i = 0; i < entropyHex.length; i += 2) { + entropyBytes[i / 2] = parseInt(entropyHex.slice(i, i + 2), 16); + } + return entropyBytes; + } catch (error) { + logger.error('Failed to get entropy from seed phrase:', error); + throw new Error('Failed to get entropy from seed phrase'); + } +} diff --git a/src/bips/index.ts b/src/bips/index.ts new file mode 100644 index 0000000..73e71ea --- /dev/null +++ b/src/bips/index.ts @@ -0,0 +1,6 @@ +/** + * @module bips + * @description Bitcoin Improvement Proposals (BIPs) implementations + */ + +export * from './bip39.js'; diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..86a4b38 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,83 @@ +/** + * @module constants + * @description Constants used throughout the library + */ + +/** + * Standard Nostr message types as defined in NIP-01 + * @see https://github.com/nostr-protocol/nips/blob/master/01.md + */ +export const NOSTR_MESSAGE_TYPE = { + EVENT: 'EVENT', + REQ: 'REQ', + CLOSE: 'CLOSE', + NOTICE: 'NOTICE', + EOSE: 'EOSE', + OK: 'OK', + AUTH: 'AUTH', + ERROR: 'ERROR' +} as const; + +/** + * Standard Nostr event kinds as defined in various NIPs + * @see https://github.com/nostr-protocol/nips + */ +export const NOSTR_EVENT_KIND = { + SET_METADATA: 0, + TEXT_NOTE: 1, + RECOMMEND_SERVER: 2, + CONTACT_LIST: 3, + ENCRYPTED_DIRECT_MESSAGE: 4, + DELETE: 5, + REPOST: 6, + REACTION: 7, + BADGE_AWARD: 8, + CHANNEL_CREATE: 40, + CHANNEL_METADATA: 41, + CHANNEL_MESSAGE: 42, + CHANNEL_HIDE_MESSAGE: 43, + CHANNEL_MUTE_USER: 44, + CHANNEL_RESERVED_FIRST: 40, + CHANNEL_RESERVED_LAST: 49, + REPLACEABLE_FIRST: 10000, + REPLACEABLE_LAST: 19999, + EPHEMERAL_FIRST: 20000, + EPHEMERAL_LAST: 29999, + PARAMETERIZED_REPLACEABLE_FIRST: 30000, + PARAMETERIZED_REPLACEABLE_LAST: 39999 +} as const; + +/** + * Standard Nostr tag types + */ +export const NOSTR_TAG = { + EVENT: 'e', + PUBKEY: 'p', + REFERENCE: 'a', + DELEGATION: 'delegation', + DEDUPLICATION: 'd', + EXPIRATION: 'expiration', + KIND: 'k', + RELAY: 'relay' +} as const; + +/** + * Protocol-related constants + */ +export const Protocol = { + DEFAULT_RELAY_URL: 'wss://relay.nostr.info', + RECONNECT_DELAY: 1000, + MAX_RECONNECT_DELAY: 30000, + PING_INTERVAL: 30000, + SUBSCRIPTION_TIMEOUT: 10000, +} as const; + +/** + * Default values + */ +export const Defaults = { + KIND: NOSTR_EVENT_KIND.TEXT_NOTE, + CREATED_AT: () => Math.floor(Date.now() / 1000), + TAGS: [] as string[][], + CONTENT: '', +} as const; diff --git a/src/core/crypto.ts b/src/core/crypto.ts new file mode 100644 index 0000000..f3576bf --- /dev/null +++ b/src/core/crypto.ts @@ -0,0 +1,250 @@ +import { schnorr } from '@noble/curves/secp256k1'; +import { sha256 } from '@noble/hashes/sha256'; +import { hmac } from '@noble/hashes/hmac'; +import { bytesToHex, hexToBytes } from '@noble/hashes/utils'; +import logger from '../utils/logger.js'; +import type { ValidationResult } from '../types/keys.js'; +import type { NostrEvent, UnsignedEvent } from '../types/events.js'; + +/** + * Signs a message with a private key + * @param {string} message - Message to sign + * @param {string} privateKey - Private key in hex format + * @returns {Promise} Signature in hex format + */ +export async function sign(message: string, privateKey: string): Promise { + try { + const messageBytes = new TextEncoder().encode(message); + const messageHash = sha256(messageBytes); + const signature = await schnorr.sign(messageHash, privateKey); + return bytesToHex(signature); + } catch (error) { + logger.error('Failed to sign message:', error); + throw new Error('Failed to sign message'); + } +} + +/** + * Verifies a signature + * @param {string} signature - Signature in hex format + * @param {string} message - Original message that was signed + * @param {string} publicKey - Public key in hex format + * @returns {Promise} True if signature is valid + */ +export async function verify( + signature: string, + message: string, + publicKey: string +): Promise { + try { + const messageBytes = new TextEncoder().encode(message); + const messageHash = sha256(messageBytes); + const isValid = await schnorr.verify( + hexToBytes(signature), + messageHash, + publicKey + ); + return isValid; + } catch (error) { + logger.error('Failed to verify signature:', error); + return false; + } +} + +/** + * Verifies a signature and returns a detailed result + * @param {string} signature - Signature in hex format + * @param {string} message - Original message that was signed + * @param {string} publicKey - Public key in hex format + * @returns {Promise} Validation result with details + */ +export async function verifyWithResult( + signature: string, + message: string, + publicKey: string +): Promise { + try { + const isValid = await verify(signature, message, publicKey); + return { + isValid, + error: isValid ? undefined : 'Invalid signature', + }; + } catch (error) { + logger.error('Failed to verify signature:', error); + return { + isValid: false, + error: error instanceof Error ? error.message : 'Unknown error', + }; + } +} + +/** + * Derives a shared secret using ECDH + * @param {string} privateKey - Private key in hex format + * @param {string} publicKey - Public key in hex format + * @returns {Promise} Shared secret bytes + */ +export async function getSharedSecret( + privateKey: string, + publicKey: string +): Promise { + try { + const privKeyBytes = hexToBytes(privateKey); + const pubKeyBytes = hexToBytes(publicKey); + const sharedPoint = schnorr.getPublicKey(privKeyBytes); + return sha256(sharedPoint); + } catch (error) { + logger.error('Failed to derive shared secret:', error); + throw new Error('Failed to derive shared secret'); + } +} + +/** + * Synchronously computes HMAC-SHA256 + * @param {Uint8Array} key - Key bytes + * @param {Uint8Array} message - Message bytes + * @returns {Uint8Array} HMAC bytes + */ +export function hmacSha256Sync(key: Uint8Array, message: Uint8Array): Uint8Array { + return hmac.create(sha256, key).update(message).digest(); +} + +/** + * Asynchronously computes HMAC-SHA256 + * @param {Uint8Array} key - Key bytes + * @param {Uint8Array} message - Message bytes + * @returns {Promise} HMAC bytes + */ +export async function hmacSha256Async( + key: Uint8Array, + message: Uint8Array +): Promise { + return hmacSha256Sync(key, message); +} + +/** + * Calculates the event hash/ID according to the Nostr protocol + * @param {UnsignedEvent} event - The unsigned event to hash + * @returns {string} The event hash in hex format + */ +export function getEventHash(event: UnsignedEvent): string { + try { + const serialized = JSON.stringify([ + 0, + event.pubkey, + event.created_at, + event.kind, + event.tags, + event.content, + ]); + const hash = sha256(new TextEncoder().encode(serialized)); + return bytesToHex(hash); + } catch (error) { + logger.error('Failed to get event hash:', error); + throw new Error('Failed to get event hash'); + } +} + +/** + * Signs an event with a private key + * @param {UnsignedEvent} event - The unsigned event to sign + * @param {string} privateKey - Private key in hex format + * @returns {Promise} The signature in hex format + */ +export async function signEvent( + event: UnsignedEvent, + privateKey: string +): Promise { + try { + const eventHash = getEventHash(event); + const sig = await schnorr.sign(hexToBytes(eventHash), privateKey); + return bytesToHex(sig); + } catch (error) { + logger.error('Failed to sign event:', error); + throw new Error('Failed to sign event'); + } +} + +/** + * Verifies an event signature + * @param {NostrEvent} event - The signed event to verify + * @returns {Promise} True if the signature is valid + */ +export async function verifyEvent(event: NostrEvent): Promise { + try { + const hash = getEventHash({ + pubkey: event.pubkey, + created_at: event.created_at, + kind: event.kind, + tags: event.tags, + content: event.content, + }); + + return schnorr.verify( + hexToBytes(event.sig), + hexToBytes(hash), + event.pubkey + ); + } catch (error) { + logger.error('Failed to verify event:', error); + return false; + } +} + +/** + * Signs a message with a private key + * @param {string} message - Message to sign + * @param {string} privateKey - Private key in hex format + * @returns {Promise} The signature in hex format + */ +export async function signMessage( + message: string, + privateKey: string +): Promise { + try { + const messageHash = sha256(new TextEncoder().encode(message)); + const sig = await schnorr.sign(messageHash, privateKey); + return bytesToHex(sig); + } catch (error) { + logger.error('Failed to sign message:', error); + throw new Error('Failed to sign message'); + } +} + +/** + * Verifies a message signature + * @param {string} signature - Signature in hex format + * @param {string} message - Original message that was signed + * @param {string} publicKey - Public key in hex format + * @returns {Promise} True if the signature is valid + */ +export async function verifyMessage( + signature: string, + message: string, + publicKey: string +): Promise { + try { + const messageHash = sha256(new TextEncoder().encode(message)); + return await schnorr.verify( + hexToBytes(signature), + messageHash, + publicKey + ); + } catch (error) { + logger.error('Failed to verify message:', error); + return false; + } +} + +/** + * Configures the HMAC functions for schnorr + */ +export function configureHMAC(): void { + try { + (schnorr.utils as any).hmacSha256Sync = hmacSha256Sync; + (schnorr.utils as any).hmacSha256Async = hmacSha256Async; + } catch (error) { + logger.error('Failed to configure HMAC:', error); + throw new Error('Failed to configure HMAC'); + } +} diff --git a/src/core/events.ts b/src/core/events.ts new file mode 100644 index 0000000..8de574e --- /dev/null +++ b/src/core/events.ts @@ -0,0 +1,159 @@ +import { pino } from 'pino'; +import { NostrEvent, UnsignedEvent } from '../types/events.js'; +import { signEvent, getEventHash } from './crypto.js'; +import { getPublicKey } from './keys.js'; + +const logger = pino({ + level: process.env.LOG_LEVEL || "info", + transport: { + target: "pino-pretty", + options: { + colorize: true, + }, + }, +}); + +/** + * Creates a new signed Nostr event + * @param {string} content - The event content + * @param {number} kind - The event kind (1 for text note, etc.) + * @param {string} privateKey - The hex-encoded private key to sign with + * @param {string[][]} [tags=[]] - Optional event tags + * @returns {Promise} The signed event + * @throws {Error} If event creation or signing fails + * @example + * const event = await createEvent( + * "Hello Nostr!", + * 1, + * privateKey, + * [["t", "nostr"]] + * ); + * console.log(event); // complete signed event + */ +export async function createEvent( + content: string, + kind: number, + privateKey: string, + tags: string[][] = [], +): Promise { + try { + // Create unsigned event + const unsignedEvent: UnsignedEvent = { + pubkey: getPublicKey(privateKey), + created_at: Math.floor(Date.now() / 1000), + kind, + tags, + content, + }; + + // Get event hash and signature + const id = getEventHash(unsignedEvent); + const sig = await signEvent(unsignedEvent, privateKey); + + // Return complete signed event + return { + ...unsignedEvent, + id, + sig, + }; + } catch (error) { + logger.error('Failed to create event:', error); + throw new Error('Failed to create event'); + } +} + +/** + * Validates a Nostr event's structure and data types + * @param {NostrEvent} event - The event to validate + * @returns {boolean} True if the event is valid, false otherwise + */ +export function validateEventStructure(event: NostrEvent): boolean { + try { + // Check required fields exist + if (!event.id || !event.pubkey || !event.sig) { + return false; + } + + // Validate field types + if ( + typeof event.id !== 'string' || + typeof event.pubkey !== 'string' || + typeof event.created_at !== 'number' || + typeof event.kind !== 'number' || + !Array.isArray(event.tags) || + typeof event.content !== 'string' || + typeof event.sig !== 'string' + ) { + return false; + } + + // Validate field formats + if ( + !/^[0-9a-f]{64}$/.test(event.id) || + !/^[0-9a-f]{64}$/.test(event.pubkey) || + !/^[0-9a-f]{128}$/.test(event.sig) + ) { + return false; + } + + // Validate tags structure + if (!event.tags.every(tag => Array.isArray(tag) && tag.every(item => typeof item === 'string'))) { + return false; + } + + return true; + } catch (error) { + logger.error('Failed to validate event structure:', error); + return false; + } +} + +/** + * Serializes an event for hashing or transmission + * @param {UnsignedEvent} event - The event to serialize + * @returns {string} JSON string of the event in the Nostr format + */ +export function serializeEvent(event: UnsignedEvent): string { + try { + return JSON.stringify([ + 0, + event.pubkey, + event.created_at, + event.kind, + event.tags, + event.content, + ]); + } catch (error) { + logger.error('Failed to serialize event:', error); + throw new Error('Failed to serialize event'); + } +} + +/** + * Gets the creation date of an event as a Date object + * @param {NostrEvent} event - The event to get the date from + * @returns {Date} The creation date + */ +export function getEventDate(event: NostrEvent): Date { + return new Date(event.created_at * 1000); +} + +/** + * Extracts tags of a specific type from an event + * @param {NostrEvent} event - The event to extract tags from + * @param {string} tagName - The tag identifier to look for + * @returns {string[][]} Array of matching tags + */ +export function getEventTags(event: NostrEvent, tagName: string): string[][] { + return event.tags.filter(tag => tag[0] === tagName); +} + +/** + * Checks if an event has a specific tag + * @param {NostrEvent} event - The event to check + * @param {string} tagName - The tag identifier to look for + * @returns {boolean} True if the event has the tag + */ +export function hasEventTag(event: NostrEvent, tagName: string): boolean { + return event.tags.some(tag => tag[0] === tagName); +} diff --git a/src/core/index.ts b/src/core/index.ts new file mode 100644 index 0000000..8094da7 --- /dev/null +++ b/src/core/index.ts @@ -0,0 +1,3 @@ +export * from './keys.js'; +export * from './crypto.js'; +export * from './events.js'; diff --git a/src/core/keys.ts b/src/core/keys.ts new file mode 100644 index 0000000..291ab63 --- /dev/null +++ b/src/core/keys.ts @@ -0,0 +1,159 @@ +import * as secp256k1 from "@noble/secp256k1"; +import { bytesToHex, hexToBytes } from "@noble/hashes/utils"; +import { pino } from "pino"; +import { KeyPair } from "../types/keys.js"; +import { generateSeedPhrase, validateSeedPhrase, getEntropyFromSeedPhrase } from "../bips/bip39.js"; +import { hexToNpub, hexToNsec } from "../nips/nip-19.js"; + +const logger = pino({ + level: process.env.LOG_LEVEL || "info", + transport: { + target: "pino-pretty", + options: { + colorize: true, + }, + }, +}); + +/** + * Derives a public key from a private key + * @param {string} privateKey - The hex-encoded private key + * @returns {string} The hex-encoded public key + * @example + * const pubkey = getPublicKey("1234567890abcdef..."); + * console.log(pubkey); // hex public key + */ +export function getPublicKey(privateKey: string): string { + try { + const pubkey = bytesToHex(secp256k1.getPublicKey(privateKey, true)); + return pubkey; + } catch (error) { + logger.error('Failed to derive public key:', error); + throw new Error('Failed to derive public key'); + } +} + +/** + * Creates a key pair from a hex private key + * @param {string} privateKeyHex - The hex-encoded private key + * @returns {KeyPair} A key pair containing private and public keys in various formats + * @throws {Error} If the private key is invalid + * @example + * const keyPair = fromHex("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"); + * console.log(keyPair.publicKey); // corresponding public key + * console.log(keyPair.nsec); // bech32 nsec private key + * console.log(keyPair.npub); // bech32 npub public key + */ +export function fromHex(privateKeyHex: string): KeyPair { + try { + if (!privateKeyHex || privateKeyHex.length !== 64) { + throw new Error('Invalid private key format'); + } + + const pubkeyHex = getPublicKey(privateKeyHex); + const pubkeyBytes = hexToBytes(pubkeyHex); + const publicKey = { + hex: pubkeyHex, + compressed: pubkeyBytes, + schnorr: pubkeyBytes.slice(1), + npub: hexToNpub(pubkeyHex) + }; + const nsec = hexToNsec(privateKeyHex); + + return { + privateKey: privateKeyHex, + publicKey, + nsec, + seedPhrase: '', // No seed phrase for hex-derived keys + }; + } catch (error) { + logger.error('Failed to create key pair from hex:', error); + throw new Error('Failed to create key pair from hex'); + } +} + +/** + * Generates a new key pair with a random seed phrase + * @returns {KeyPair} A new key pair containing private and public keys in various formats + * @example + * const keyPair = generateKeyPairWithSeed(); + * console.log(keyPair.seedPhrase); // random seed phrase + * console.log(keyPair.privateKey); // hex private key + * console.log(keyPair.publicKey); // hex public key + */ +export function generateKeyPairWithSeed(): KeyPair { + try { + const seedPhrase = generateSeedPhrase(); + if (!validateSeedPhrase(seedPhrase)) { + throw new Error('Generated invalid seed phrase'); + } + return seedPhraseToKeyPair(seedPhrase); + } catch (error) { + logger.error('Failed to generate key pair with seed:', error); + throw new Error('Failed to generate key pair with seed'); + } +} + +/** + * Converts a BIP39 seed phrase to a Nostr key pair + * @param {string} seedPhrase - The BIP39 seed phrase to convert + * @returns {KeyPair} A key pair containing private and public keys in various formats + * @throws {Error} If the seed phrase is invalid or key generation fails + * @example + * const keyPair = seedPhraseToKeyPair("witch collapse practice feed shame open despair creek road again ice least"); + * console.log(keyPair.privateKey); // hex private key + * console.log(keyPair.publicKey); // hex public key + * console.log(keyPair.nsec); // bech32 nsec private key + * console.log(keyPair.npub); // bech32 npub public key + */ +export function seedPhraseToKeyPair(seedPhrase: string): KeyPair { + try { + if (!validateSeedPhrase(seedPhrase)) { + throw new Error('Invalid seed phrase'); + } + + const privateKey = seedPhraseToPrivateKey(seedPhrase); + const pubkeyHex = getPublicKey(privateKey); + const pubkeyBytes = hexToBytes(pubkeyHex); + const publicKey = { + hex: pubkeyHex, + compressed: pubkeyBytes, + schnorr: pubkeyBytes.slice(1), + npub: hexToNpub(pubkeyHex) + }; + const nsec = hexToNsec(privateKey); + + return { + privateKey, + publicKey, + nsec, + seedPhrase, + }; + } catch (error) { + logger.error('Failed to convert seed phrase to key pair:', error); + throw new Error('Failed to convert seed phrase to key pair'); + } +} + +/** + * Converts a BIP39 seed phrase to a private key + * @param {string} seedPhrase - The BIP39 seed phrase to convert + * @returns {string} The hex-encoded private key + * @throws {Error} If the seed phrase is invalid + * @example + * const privateKey = seedPhraseToPrivateKey("witch collapse practice feed shame open despair creek road again ice least"); + * console.log(privateKey); // hex private key + */ +export function seedPhraseToPrivateKey(seedPhrase: string): string { + try { + if (!validateSeedPhrase(seedPhrase)) { + throw new Error('Invalid seed phrase'); + } + + const entropy = getEntropyFromSeedPhrase(seedPhrase); + return bytesToHex(entropy); + } catch (error) { + logger.error('Failed to convert seed phrase to private key:', error); + throw new Error('Failed to convert seed phrase to private key'); + } +} diff --git a/src/crypto/events.ts b/src/crypto/events.ts new file mode 100644 index 0000000..3d91cb9 --- /dev/null +++ b/src/crypto/events.ts @@ -0,0 +1,192 @@ +/** + * @module crypto/events + * @description Event signing and verification functions for Nostr + */ + +import { schnorr } from '@noble/curves/secp256k1'; +import { sha256 } from '@noble/hashes/sha256'; +import { bytesToHex, hexToBytes } from '@noble/hashes/utils'; +import { logger } from '../utils/logger.js'; +import type { NostrEvent, UnsignedEvent } from '../types/events.js'; +import { ValidationResult } from '../types/keys.js'; +import { Defaults } from '../constants.js'; + +/** + * Calculates the event hash/ID according to the Nostr protocol + * @param event - The event to hash + * @returns The hex-encoded event hash + */ +export function getEventHash(event: UnsignedEvent): string { + try { + const serialized = JSON.stringify([ + 0, + event.pubkey, + event.created_at, + event.kind, + event.tags, + event.content, + ]); + return bytesToHex(sha256(new TextEncoder().encode(serialized))); + } catch (error) { + logger.error('Failed to calculate event hash:', error); + throw error; + } +} + +/** + * Creates an unsigned event + * @param pubkey - The public key of the event creator + * @param content - The event content + * @param kind - The event kind (defaults to TEXT_NOTE) + * @param tags - The event tags (defaults to empty array) + * @returns An unsigned event + */ +export function createUnsignedEvent( + pubkey: string, + content: string, + kind: number = Defaults.KIND, + tags: string[][] = Defaults.TAGS, +): UnsignedEvent { + return { + pubkey, + created_at: Defaults.CREATED_AT(), + kind, + tags, + content, + }; +} + +/** + * Signs a Nostr event using Schnorr signatures + * @param event - The event to sign + * @param privateKey - The hex-encoded private key to sign with + * @returns The signed event + * @throws {Error} If signing fails + */ +export async function signEvent( + event: UnsignedEvent, + privateKey: string, +): Promise { + try { + const id = getEventHash(event); + const sig = bytesToHex( + await schnorr.sign( + hexToBytes(id), + hexToBytes(privateKey) + ) + ); + + logger.log('Event signed successfully'); + return { + ...event, + id, + sig, + }; + } catch (error) { + logger.error('Failed to sign event:', error); + throw error; + } +} + +/** + * Verifies a Nostr event signature + * @param event - The event to verify + * @returns Validation result + */ +export async function verifyEvent(event: NostrEvent): Promise { + try { + if (!event.id || !event.pubkey || !event.sig) { + return { + isValid: false, + error: 'Missing required fields', + }; + } + + const hash = getEventHash(event); + if (hash !== event.id) { + return { + isValid: false, + error: 'Event hash mismatch', + }; + } + + logger.log('Verifying event signature'); + const isValid = await schnorr.verify( + hexToBytes(event.sig), + hexToBytes(hash), + hexToBytes(event.pubkey) + ); + + return { + isValid, + error: isValid ? undefined : 'Invalid signature', + }; + } catch (error) { + logger.error('Failed to verify event:', error); + return { + isValid: false, + error: error instanceof Error ? error.message : 'Unknown error', + }; + } +} + +/** + * Signs a message with a private key using Schnorr signatures + * @param message - The message to sign + * @param privateKey - The hex-encoded private key to sign with + * @returns The hex-encoded signature + * @throws {Error} If signing fails + */ +export async function signMessage( + message: string, + privateKey: string, +): Promise { + try { + const messageBytes = new TextEncoder().encode(message); + const messageHash = sha256(messageBytes); + const signature = await schnorr.sign( + messageHash, + hexToBytes(privateKey) + ); + logger.log('Message signed successfully'); + return bytesToHex(signature); + } catch (error) { + logger.error('Failed to sign message:', error); + throw error; + } +} + +/** + * Verifies a message signature using Schnorr verification + * @param message - The original message + * @param signature - The hex-encoded signature to verify + * @param publicKey - The hex-encoded public key to verify against + * @returns Validation result + */ +export async function verifySignature( + message: string, + signature: string, + publicKey: string, +): Promise { + try { + const messageBytes = new TextEncoder().encode(message); + const messageHash = sha256(messageBytes); + logger.log('Verifying message signature'); + const isValid = await schnorr.verify( + hexToBytes(signature), + messageHash, + hexToBytes(publicKey) + ); + + return { + isValid, + error: isValid ? undefined : 'Invalid signature', + }; + } catch (error) { + logger.error('Failed to verify signature:', error); + return { + isValid: false, + error: error instanceof Error ? error.message : 'Unknown error', + }; + } +} diff --git a/src/crypto/index.ts b/src/crypto/index.ts new file mode 100644 index 0000000..7c083c7 --- /dev/null +++ b/src/crypto/index.ts @@ -0,0 +1,7 @@ +/** + * @module crypto + * @description Cryptographic operations for Nostr + */ + +export * from './keys.js'; +export * from './events.js'; diff --git a/src/crypto/keys.ts b/src/crypto/keys.ts new file mode 100644 index 0000000..8656cc1 --- /dev/null +++ b/src/crypto/keys.ts @@ -0,0 +1,217 @@ +/** + * @module crypto/keys + * @description Key management functions for Nostr + */ + +import { generateMnemonic, validateMnemonic, mnemonicToEntropy } from 'bip39'; +import { secp256k1, schnorr } from '@noble/curves/secp256k1'; +import { bytesToHex, hexToBytes } from '@noble/hashes/utils'; +import { sha256 } from '@noble/hashes/sha256'; +import { logger } from '../utils/logger.js'; +import { KeyPair, PublicKeyDetails, ValidationResult, PublicKey } from '../types/keys.js'; +import { hexToNpub, hexToNsec } from '../nips/nip-19.js'; + +/** + * Gets the compressed public key (33 bytes with prefix) + */ +function getCompressedPublicKey(privateKeyBytes: Uint8Array): Uint8Array { + return secp256k1.getPublicKey(privateKeyBytes, true); +} + +/** + * Gets the schnorr public key (32 bytes x-coordinate) as per BIP340 + */ +function getSchnorrPublicKey(privateKeyBytes: Uint8Array): Uint8Array { + return schnorr.getPublicKey(privateKeyBytes); +} + +/** + * Creates a PublicKeyDetails object from a hex string + */ +export function createPublicKey(hex: string): PublicKeyDetails { + const bytes = hexToBytes(hex); + // For schnorr, we need to remove the first byte (compression prefix) + const schnorrBytes = bytes.length === 33 ? bytes.slice(1) : bytes; + + return { + hex, + compressed: bytes.length === 33 ? bytes : getCompressedPublicKey(bytes), + schnorr: schnorrBytes, + npub: hexToNpub(hex), + }; +} + +/** + * Generates a new BIP39 seed phrase + * @returns A random 12-word BIP39 mnemonic seed phrase + */ +export function generateSeedPhrase(): string { + logger.log('Generating new seed phrase'); + return generateMnemonic(128); // 12 words +} + +/** + * Converts a BIP39 seed phrase to its entropy value + * @param seedPhrase - The BIP39 seed phrase to convert + * @returns The entropy value + * @throws {Error} If the seed phrase is invalid + */ +export function getEntropyFromSeedPhrase(seedPhrase: string): Uint8Array { + try { + if (!validateMnemonic(seedPhrase)) { + throw new Error('Invalid seed phrase'); + } + return hexToBytes(mnemonicToEntropy(seedPhrase)); + } catch (error) { + logger.error('Failed to get entropy from seed phrase:', error); + throw error; + } +} + +/** + * Validates a BIP39 seed phrase + * @param seedPhrase - The seed phrase to validate + * @returns True if the seed phrase is valid, false otherwise + */ +export function validateSeedPhrase(seedPhrase: string): boolean { + logger.log({ seedPhrase }, 'Validating seed phrase'); + const isValid = validateMnemonic(seedPhrase); + logger.log({ isValid }, 'Validated seed phrase'); + return Boolean(isValid); +} + +/** + * Converts a BIP39 seed phrase to a Nostr key pair + * @param seedPhrase - The BIP39 seed phrase to convert + * @returns A key pair containing private and public keys in various formats + * @throws {Error} If the seed phrase is invalid or key generation fails + */ +export async function seedPhraseToKeyPair(seedPhrase: string): Promise { + try { + if (!validateSeedPhrase(seedPhrase)) { + throw new Error('Invalid seed phrase'); + } + + const entropy = getEntropyFromSeedPhrase(seedPhrase); + const privateKey = derivePrivateKey(entropy); + const publicKey = createPublicKey(bytesToHex(getCompressedPublicKey(hexToBytes(privateKey)))); + + return { + privateKey, + publicKey, + nsec: hexToNsec(privateKey), + seedPhrase, + }; + } catch (error) { + logger.error('Failed to create key pair from seed phrase:', error); + throw error; + } +} + +/** + * Derives a private key from entropy + * @param {Uint8Array} entropy - The entropy to derive from + * @returns {string} The hex-encoded private key + */ +export function derivePrivateKey(entropy: Uint8Array): string { + try { + let privateKeyBytes = entropy; + // Hash the entropy to get a valid private key + privateKeyBytes = sha256(privateKeyBytes); + return bytesToHex(privateKeyBytes); + } catch (error) { + logger.error('Failed to derive private key:', error); + throw new Error('Failed to derive private key'); + } +} + +/** + * Generates a new key pair with a random seed phrase + * @returns A new key pair containing private and public keys in various formats + */ +export async function generateKeyPairWithSeed(): Promise { + const seedPhrase = generateSeedPhrase(); + return seedPhraseToKeyPair(seedPhrase); +} + +/** + * Creates a key pair from a hex private key + * @param privateKeyHex - The hex-encoded private key + * @returns A key pair containing private and public keys in various formats + * @throws {Error} If the private key is invalid + */ +export async function fromHex(privateKeyHex: string): Promise { + try { + const privateKeyBytes = hexToBytes(privateKeyHex); + if (!secp256k1.utils.isValidPrivateKey(privateKeyBytes)) { + throw new Error('Invalid private key'); + } + const publicKey = createPublicKey(bytesToHex(getCompressedPublicKey(privateKeyBytes))); + + return { + privateKey: privateKeyHex, + publicKey, + nsec: hexToNsec(privateKeyHex), + seedPhrase: '', // No seed phrase for hex-imported keys + }; + } catch (error) { + logger.error('Failed to create key pair from hex:', error); + throw error; + } +} + +/** + * Validates a key pair + * @param publicKey - The public key to validate + * @param privateKey - The private key to validate + * @returns Validation result + */ +export async function validateKeyPair( + publicKey: PublicKey, + privateKey: string, +): Promise { + try { + const privateKeyBytes = hexToBytes(privateKey); + if (!secp256k1.utils.isValidPrivateKey(privateKeyBytes)) { + return { + isValid: false, + error: 'Invalid private key', + }; + } + + const pubKeyHex = typeof publicKey === 'string' ? publicKey : publicKey.hex; + const derivedPublicKey = bytesToHex(getCompressedPublicKey(privateKeyBytes)); + + if (pubKeyHex !== derivedPublicKey) { + return { + isValid: false, + error: 'Public key does not match private key', + }; + } + + return { + isValid: true, + }; + } catch (error) { + logger.error('Failed to validate key pair:', error); + return { + isValid: false, + error: error instanceof Error ? error.message : 'Unknown error', + }; + } +} + +/** + * Validates a Nostr public key + * @param publicKey - The public key to validate + * @returns True if valid, false otherwise + */ +export function validatePublicKey(publicKey: string): boolean { + try { + const bytes = hexToBytes(publicKey); + return bytes.length === 32 || bytes.length === 33; + } catch (error) { + logger.error('Failed to validate public key:', error); + return false; + } +} diff --git a/src/index.ts b/src/index.ts index 2e5ee1a..6659aef 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,18 +3,8 @@ import * as secp256k1 from "@noble/secp256k1"; import { bytesToHex, hexToBytes } from "@noble/hashes/utils"; import { sha256 } from "@noble/hashes/sha256"; import { hmac } from "@noble/hashes/hmac"; -import { pino } from "pino"; import { bech32 } from "bech32"; - -const logger = pino({ - level: process.env.LOG_LEVEL || "info", - transport: { - target: "pino-pretty", - options: { - colorize: true, - }, - }, -}); +import { logger } from "./utils/logger.js"; /** * Represents a Nostr key pair with associated formats @@ -110,10 +100,10 @@ export function getEntropyFromSeedPhrase(seedPhrase: string): Uint8Array { * console.log(isValid); // true */ export function validateSeedPhrase(seedPhrase: string): boolean { - console.log({ seedPhrase }, "Validating seed phrase"); - console.log({ seedPhrase }, "Input being validated"); + logger.log({ seedPhrase }, "Validating seed phrase"); + logger.log({ seedPhrase }, "Input being validated"); const isValid = validateMnemonic(seedPhrase); - console.log({ isValid }, "Validated seed phrase"); + logger.log({ isValid }, "Validated seed phrase"); return Boolean(isValid); } @@ -152,7 +142,7 @@ export function seedPhraseToKeyPair(seedPhrase: string): KeyPair { seedPhrase, }; } catch (error) { - console.error("Failed to create key pair from seed phrase:", error); + logger.error("Failed to create key pair from seed phrase:", error); throw error; } } @@ -206,7 +196,7 @@ export function fromHex(privateKeyHex: string): KeyPair { seedPhrase: "", // No seed phrase for hex-imported keys }; } catch (error) { - console.error("Failed to create key pair from hex:", error); + logger.error("Failed to create key pair from hex:", error); throw error; } } @@ -225,21 +215,32 @@ export function getPublicKey(privateKey: string): string { const publicKeyBytes = secp256k1.getPublicKey(privateKeyBytes, true); // Force compressed format return bytesToHex(publicKeyBytes); } catch (error) { - console.error("Failed to derive public key from private key:", privateKey); + logger.error("Failed to derive public key from private key:", privateKey); throw error; } } /** * NIP-19 encoding and decoding functions + * @namespace */ export const nip19 = { + /** + * Encodes a public key into npub format + * @param {string} pubkey - The hex-encoded public key + * @returns {string} The bech32-encoded npub string + */ npubEncode(pubkey: string): string { const data = hexToBytes(pubkey); const words = bech32.toWords(Uint8Array.from(data)); return bech32.encode("npub", words, 1000); }, + /** + * Decodes an npub string to hex format + * @param {string} npub - The bech32-encoded npub string + * @returns {string} The hex-encoded public key + */ npubDecode(npub: string): string { const { prefix, words } = bech32.decode(npub, 1000); if (prefix !== "npub") throw new Error("Invalid npub: wrong prefix"); @@ -247,12 +248,22 @@ export const nip19 = { return bytesToHex(data instanceof Uint8Array ? data : Uint8Array.from(data)); }, + /** + * Encodes a private key into nsec format + * @param {string} privkey - The hex-encoded private key + * @returns {string} The bech32-encoded nsec string + */ nsecEncode(privkey: string): string { const data = hexToBytes(privkey); const words = bech32.toWords(Uint8Array.from(data)); return bech32.encode("nsec", words, 1000); }, + /** + * Decodes an nsec string to hex format + * @param {string} nsec - The bech32-encoded nsec string + * @returns {string} The hex-encoded private key + */ nsecDecode(nsec: string): string { const { prefix, words } = bech32.decode(nsec, 1000); if (prefix !== "nsec") throw new Error("Invalid nsec: wrong prefix"); @@ -260,12 +271,22 @@ export const nip19 = { return bytesToHex(data instanceof Uint8Array ? data : Uint8Array.from(data)); }, + /** + * Encodes an event ID into note format + * @param {string} eventId - The hex-encoded event ID + * @returns {string} The bech32-encoded note string + */ noteEncode(eventId: string): string { const data = hexToBytes(eventId); const words = bech32.toWords(Uint8Array.from(data)); return bech32.encode("note", words, 1000); }, + /** + * Decodes a note string to hex format + * @param {string} note - The bech32-encoded note string + * @returns {string} The hex-encoded event ID + */ noteDecode(note: string): string { const { prefix, words } = bech32.decode(note, 1000); if (prefix !== "note") throw new Error("Invalid note: wrong prefix"); @@ -273,6 +294,13 @@ export const nip19 = { return bytesToHex(data instanceof Uint8Array ? data : Uint8Array.from(data)); }, + /** + * Decodes any bech32-encoded Nostr entity + * @param {string} bech32str - The bech32-encoded string + * @returns {{ type: string; data: Uint8Array }} Object containing the decoded type and data + * @property {string} type - The type of the decoded entity (npub, nsec, or note) + * @property {Uint8Array} data - The raw decoded data + */ decode(bech32str: string): { type: string; data: Uint8Array } { const { prefix, words } = bech32.decode(bech32str, 1000); const data = bech32.fromWords(words); @@ -283,87 +311,6 @@ export const nip19 = { } }; -/** - * Converts a bech32 nsec private key to hex format - * @param {string} nsec - The bech32-encoded nsec private key - * @returns {string} The hex-encoded private key - * @throws {Error} If the nsec key is invalid - * @example - * const hex = nsecToHex("nsec1..."); - * console.log(hex); // "1234567890abcdef..." - */ -export function nsecToHex(nsec: string): string { - try { - const hexPrivateKey = nip19.nsecDecode(nsec); - console.log("Converted nsec to hex"); - return hexPrivateKey; - } catch (error) { - console.error("Failed to convert nsec to hex:", error); - throw error; - } -} - -/** - * Converts a bech32 npub public key to hex format - * @param {string} npub - The bech32-encoded npub public key - * @returns {string} The hex-encoded public key - * @throws {Error} If the npub key is invalid - * @example - * const hex = npubToHex("npub1..."); - * console.log(hex); // "1234567890abcdef..." - */ -export function npubToHex(npub: string): string { - try { - const { type, data } = nip19.decode(npub); - if (type !== "npub") { - throw new Error("Invalid npub format"); - } - console.log("Converted npub to hex"); - return bytesToHex(data); - } catch (error) { - console.error("Failed to convert npub to hex:", error); - throw error; - } -} - -/** - * Converts a hex public key to bech32 npub format - * @param {string} publicKeyHex - The hex-encoded public key - * @returns {string} The bech32-encoded npub public key - * @throws {Error} If the public key is invalid - * @example - * const npub = hexToNpub("1234567890abcdef..."); - * console.log(npub); // "npub1..." - */ -export function hexToNpub(publicKeyHex: string): string { - try { - console.log("Converting hex to npub"); - return nip19.npubEncode(publicKeyHex); - } catch (error) { - console.error("Failed to convert hex to npub:", error); - throw error; - } -} - -/** - * Converts a hex private key to bech32 nsec format - * @param {string} privateKeyHex - The hex-encoded private key - * @returns {string} The bech32-encoded nsec private key - * @throws {Error} If the private key is invalid - * @example - * const nsec = hexToNsec("1234567890abcdef..."); - * console.log(nsec); // "nsec1..." - */ -export function hexToNsec(privateKeyHex: string): string { - try { - console.log("Converting hex to nsec"); - return nip19.nsecEncode(privateKeyHex); - } catch (error) { - console.error("Failed to convert hex to nsec:", error); - throw error; - } -} - /** * Calculates the event hash/ID according to the Nostr protocol * @param {UnsignedEvent} event - The event to hash @@ -406,10 +353,10 @@ export async function signEvent( hexToBytes(eventHash), hexToBytes(privateKey), ); - console.log("Event signed successfully"); + logger.log("Event signed successfully"); return bytesToHex(signature.toCompactRawBytes()); } catch (error) { - console.error("Failed to sign event:", error); + logger.error("Failed to sign event:", error); throw error; } } @@ -425,24 +372,24 @@ export async function signEvent( export async function verifyEvent(event: NostrEvent): Promise { try { if (!event.id || !event.pubkey || !event.sig) { - console.log("Invalid event: missing required fields"); + logger.log("Invalid event: missing required fields"); return false; } const hash = getEventHash(event); if (hash !== event.id) { - console.log("Event hash mismatch"); + logger.log("Event hash mismatch"); return false; } - console.log("Verifying event signature"); + logger.log("Verifying event signature"); return await secp256k1.verify( hexToBytes(event.sig), hexToBytes(hash), hexToBytes(event.pubkey), ); } catch (error) { - console.error("Failed to verify event:", error); + logger.error("Failed to verify event:", error); throw error; } } @@ -479,8 +426,8 @@ export function configureHMAC(): void { hmacSha256Sync: hmacSyncFunction, }; - console.log("Configured HMAC for secp256k1"); - console.log( + logger.log("Configured HMAC for secp256k1"); + logger.log( "secp256k1.utils after configuration:", (secp256k1 as any).utils, ); @@ -522,7 +469,7 @@ export async function createEvent( const id = getEventHash(event); const sig = await signEvent(event, privateKey); - console.log("Created new Nostr event"); + logger.log("Created new Nostr event"); return { ...event, id, @@ -553,7 +500,7 @@ export function seedPhraseToPrivateKey(seedPhrase: string): string { * console.log(nsec); // "nsec1..." */ export function privateKeyToNsec(privateKey: string): string { - return hexToNsec(privateKey); + return nip19.nsecEncode(privateKey); } /** @@ -568,7 +515,7 @@ export function privateKeyToNsec(privateKey: string): string { export function privateKeyToNpub(privateKey: string): string { const privateKeyBytes = hexToBytes(privateKey); const publicKey = secp256k1.getPublicKey(privateKeyBytes, true); - return hexToNpub(bytesToHex(publicKey)); + return nip19.npubEncode(bytesToHex(publicKey)); } /** @@ -577,11 +524,79 @@ export function privateKeyToNpub(privateKey: string): string { * @returns {string} The hex-encoded private key * @throws {Error} If the nsec key is invalid * @example - * const hex = nsecToPrivateKey("nsec1..."); + * const hex = nsecToHex("nsec1..."); * console.log(hex); // "1234567890abcdef..." */ -export function nsecToPrivateKey(nsec: string): string { - return nsecToHex(nsec); +export function nsecToHex(nsec: string): string { + try { + const hexPrivateKey = nip19.nsecDecode(nsec); + logger.log("Converted nsec to hex"); + return hexPrivateKey; + } catch (error) { + logger.error("Failed to convert nsec to hex:", error); + throw error; + } +} + +/** + * Converts a bech32 npub public key to hex format + * @param {string} npub - The bech32-encoded npub public key + * @returns {string} The hex-encoded public key + * @throws {Error} If the npub key is invalid + * @example + * const hex = npubToHex("npub1..."); + * console.log(hex); // "1234567890abcdef..." + */ +export function npubToHex(npub: string): string { + try { + const { type, data } = nip19.decode(npub); + if (type !== "npub") { + throw new Error("Invalid npub format"); + } + logger.log("Converted npub to hex"); + return bytesToHex(data); + } catch (error) { + logger.error("Failed to convert npub to hex:", error); + throw error; + } +} + +/** + * Converts a hex public key to bech32 npub format + * @param {string} publicKeyHex - The hex-encoded public key + * @returns {string} The bech32-encoded npub public key + * @throws {Error} If the public key is invalid + * @example + * const npub = hexToNpub("1234567890abcdef..."); + * console.log(npub); // "npub1..." + */ +export function hexToNpub(publicKeyHex: string): string { + try { + logger.log("Converting hex to npub"); + return nip19.npubEncode(publicKeyHex); + } catch (error) { + logger.error("Failed to convert hex to npub:", error); + throw error; + } +} + +/** + * Converts a hex private key to bech32 nsec format + * @param {string} privateKeyHex - The hex-encoded private key + * @returns {string} The bech32-encoded nsec private key + * @throws {Error} If the private key is invalid + * @example + * const nsec = hexToNsec("1234567890abcdef..."); + * console.log(nsec); // "nsec1..." + */ +export function hexToNsec(privateKeyHex: string): string { + try { + logger.log("Converting hex to nsec"); + return nip19.nsecEncode(privateKeyHex); + } catch (error) { + logger.error("Failed to convert hex to nsec:", error); + throw error; + } } /** @@ -602,10 +617,10 @@ export async function signMessage( const messageBytes = new TextEncoder().encode(message); const messageHash = sha256(messageBytes); const signature = await secp256k1.sign(messageHash, hexToBytes(privateKey)); - console.log("Message signed successfully"); + logger.log("Message signed successfully"); return bytesToHex(signature.toCompactRawBytes()); } catch (error) { - console.error("Failed to sign message:", error); + logger.error("Failed to sign message:", error); throw error; } } @@ -628,14 +643,27 @@ export async function verifySignature( try { const messageBytes = new TextEncoder().encode(message); const messageHash = sha256(messageBytes); - console.log("Verifying message signature"); + logger.log("Verifying message signature"); return await secp256k1.verify( hexToBytes(signature), messageHash, hexToBytes(publicKey), ); } catch (error) { - console.error("Failed to verify signature:", error); + logger.error("Failed to verify signature:", error); throw error; } } + +/** + * Converts a bech32 nsec private key to hex format + * @param {string} nsec - The bech32-encoded nsec private key + * @returns {string} The hex-encoded private key + * @throws {Error} If the nsec key is invalid + * @example + * const hex = nsecToPrivateKey("nsec1..."); + * console.log(hex); // "1234567890abcdef..." + */ +export function nsecToPrivateKey(nsec: string): string { + return nip19.nsecDecode(nsec); +} diff --git a/src/nips/index.ts b/src/nips/index.ts new file mode 100644 index 0000000..cf0a21a --- /dev/null +++ b/src/nips/index.ts @@ -0,0 +1,9 @@ +/** + * @module nips + * @description Nostr Implementation Possibilities (NIPs) + */ + +export * as nip19 from './nip-19.js'; +export * as nip26 from './nip-26.js'; +// We'll add these as we implement them +// export * from './nip-06.js'; diff --git a/src/nips/nip-19.ts b/src/nips/nip-19.ts new file mode 100644 index 0000000..49893bb --- /dev/null +++ b/src/nips/nip-19.ts @@ -0,0 +1,162 @@ +/** + * NIP-19: bech32-encoded entities + * @module nip19 + * @description Implements NIP-19 specification for bech32-encoded entities in Nostr. + * Provides encoding and decoding functions for npub (public keys), nsec (private keys), + * and note (event IDs) formats. + * @see https://github.com/nostr-protocol/nips/blob/master/19.md + */ + +import { bech32 } from '@scure/base'; +import { bytesToHex, hexToBytes } from '@noble/hashes/utils'; +import { sha256 } from '@noble/hashes/sha256'; +import { logger } from '../utils/logger.js'; +import type { Bech32Result } from '../types/index.js'; + +/** + * Valid bech32 prefix types for Nostr entities + * @typedef {('npub1' | 'nsec1' | 'note1')} Bech32Prefix + */ +type Bech32Prefix = 'npub1' | 'nsec1' | 'note1'; + +/** + * Ensures the input string has a valid bech32 format by adding '1' if missing + * @param {string} str - Input string to format + * @returns {string} Properly formatted bech32 string + * @example + * ensureBech32Format('npub') // returns 'npub1' + * ensureBech32Format('npub1abc') // returns 'npub1abc' + */ +function ensureBech32Format(str: string): `${string}1${string}` { + return str.includes('1') ? str as `${string}1${string}` : `${str}1`; +} + +/** + * Encodes a public key into npub format + * @param {string} hex - The hex-encoded public key + * @returns {string} The bech32-encoded npub string + * @throws {Error} If encoding fails + * @example + * const npub = hexToNpub('3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d'); + * // returns 'npub1...' + */ +export function hexToNpub(hex: string): string { + try { + const bytes = hexToBytes(hex); + const words = bech32.toWords(bytes); + const encoded = bech32.encode('npub1' as Bech32Prefix, words); + return encoded; + } catch (error) { + logger.error('Failed to encode npub:', error); + throw new Error('Failed to encode npub'); + } +} + +/** + * Encodes a private key into nsec format + * @param {string} hex - The hex-encoded private key + * @returns {string} The bech32-encoded nsec string + * @throws {Error} If encoding fails + * @security This function handles sensitive private key data + * @example + * const nsec = hexToNsec('3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d'); + * // returns 'nsec1...' + */ +export function hexToNsec(hex: string): string { + try { + const bytes = hexToBytes(hex); + const words = bech32.toWords(bytes); + const encoded = bech32.encode('nsec1' as Bech32Prefix, words); + return encoded; + } catch (error) { + logger.error('Failed to encode nsec:', error); + throw new Error('Failed to encode nsec'); + } +} + +/** + * Encodes an event ID into note format + * @param {string} hex - The hex-encoded event ID + * @returns {string} The bech32-encoded note string + * @throws {Error} If encoding fails + * @example + * const note = hexToNote('3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d'); + * // returns 'note1...' + */ +export function hexToNote(hex: string): string { + try { + const bytes = hexToBytes(hex); + const words = bech32.toWords(bytes); + const encoded = bech32.encode('note1' as Bech32Prefix, words); + return encoded; + } catch (error) { + logger.error('Failed to encode note:', error); + throw new Error('Failed to encode note'); + } +} + +/** + * Decodes a bech32-encoded Nostr entity + * @param {string} str - The bech32-encoded string (npub1, nsec1, or note1) + * @returns {Bech32Result} Object containing the decoded type and data + * @throws {Error} If decoding fails + * @example + * const result = decode('npub1...'); + * // returns { type: 'npub', data: Uint8Array } + */ +export function decode(str: string): Bech32Result { + try { + const formattedStr = ensureBech32Format(str); + const { prefix, words } = bech32.decode(formattedStr); + const data = new Uint8Array(bech32.fromWords(words)); + return { type: prefix.replace(/1$/, ''), data }; + } catch (error) { + logger.error('Failed to decode bech32:', error); + throw new Error('Failed to decode bech32'); + } +} + +/** + * Converts a bech32 nsec private key to hex format + * @param {string} nsec - The bech32-encoded nsec private key + * @returns {string} The hex-encoded private key + * @throws {Error} If conversion fails or input is invalid + * @security This function handles sensitive private key data + * @example + * const hex = nsecToHex('nsec1...'); + * // returns '3bf0c63f...' + */ +export function nsecToHex(nsec: string): string { + try { + const { type, data } = decode(nsec); + if (type !== 'nsec') { + throw new Error('Invalid nsec format'); + } + return bytesToHex(data); + } catch (error) { + logger.error('Failed to convert nsec to hex:', error); + throw new Error('Failed to convert nsec to hex'); + } +} + +/** + * Converts a bech32 npub public key to hex format + * @param {string} npub - The bech32-encoded npub public key + * @returns {string} The hex-encoded public key + * @throws {Error} If conversion fails or input is invalid + * @example + * const hex = npubToHex('npub1...'); + * // returns '3bf0c63f...' + */ +export function npubToHex(npub: string): string { + try { + const { type, data } = decode(npub); + if (type !== 'npub') { + throw new Error('Invalid npub format'); + } + return bytesToHex(data); + } catch (error) { + logger.error('Failed to convert npub to hex:', error); + throw new Error('Failed to convert npub to hex'); + } +} diff --git a/src/nips/nip-26.ts b/src/nips/nip-26.ts new file mode 100644 index 0000000..26085be --- /dev/null +++ b/src/nips/nip-26.ts @@ -0,0 +1,162 @@ +/** + * @module nips/nip-26 + * @description NIP-26 Delegated Event Signing implementation + * @see https://github.com/nostr-protocol/nips/blob/master/26.md + */ + +import { schnorr } from '@noble/curves/secp256k1'; +import { sha256 } from '@noble/hashes/sha256'; +import { bytesToHex, hexToBytes } from '@noble/hashes/utils'; +import { logger } from '../utils/logger.js'; +import { ValidationResult } from '../types/index.js'; + +export interface DelegationConditions { + /** Unix timestamp after which delegation is valid */ + since?: number; + /** Unix timestamp until which delegation is valid */ + until?: number; + /** Event kinds that can be signed */ + kinds?: number[]; +} + +export interface DelegationToken { + /** Public key of the delegator */ + delegator: string; + /** Public key of the delegatee */ + delegatee: string; + /** Conditions of the delegation */ + conditions: DelegationConditions; + /** Token signature */ + signature: string; +} + +/** + * Creates a delegation token string + * @param conditions - Delegation conditions + * @returns Delegation token string + */ +function createDelegationString( + delegator: string, + delegatee: string, + conditions: DelegationConditions +): string { + const parts = ['nostr', 'delegation', delegator, delegatee]; + + if (conditions.kinds) { + parts.push(`kinds=${conditions.kinds.join(',')}`); + } + if (conditions.since) { + parts.push(`created_at>${conditions.since}`); + } + if (conditions.until) { + parts.push(`created_at<${conditions.until}`); + } + + return parts.join(':'); +} + +/** + * Creates a delegation token + * @param delegatee - Public key of the delegatee + * @param conditions - Delegation conditions + * @param delegatorPrivateKey - Private key of the delegator + * @returns Delegation token + */ +export async function createDelegation( + delegatee: string, + conditions: DelegationConditions, + delegatorPrivateKey: string +): Promise { + try { + // Get delegator's public key + const delegator = bytesToHex(schnorr.getPublicKey(delegatorPrivateKey)); + + // Create delegation string + const tokenString = createDelegationString(delegator, delegatee, conditions); + + // Sign the token + const messageHash = sha256(new TextEncoder().encode(tokenString)); + const signature = await schnorr.sign(messageHash, delegatorPrivateKey); + + logger.log('Created delegation token'); + return { + delegator, + delegatee, + conditions, + signature: bytesToHex(signature), + }; + } catch (error) { + logger.error('Failed to create delegation token:', error); + throw error; + } +} + +/** + * Verifies a delegation token + * @param token - The delegation token to verify + * @param now - Current Unix timestamp in seconds (optional, defaults to current time) + * @returns Result of the validation + */ +async function verifyDelegation(token: string, now?: number): Promise { + try { + const tokenObject: DelegationToken = JSON.parse(token); + // Check conditions + if (now) { + if (tokenObject.conditions.since && now < tokenObject.conditions.since) { + return { + isValid: false, + error: 'Event timestamp before delegation validity period', + }; + } + if (tokenObject.conditions.until && now > tokenObject.conditions.until) { + return { + isValid: false, + error: 'Event timestamp after delegation validity period', + }; + } + } + + // Verify signature + const tokenString = createDelegationString( + tokenObject.delegator, + tokenObject.delegatee, + tokenObject.conditions + ); + const messageHash = sha256(new TextEncoder().encode(tokenString)); + + const isValid = await schnorr.verify( + tokenObject.signature, + messageHash, + tokenObject.delegator + ); + + return { + isValid, + error: isValid ? undefined : 'Invalid delegation signature', + }; + } catch (error) { + logger.error('Failed to verify delegation:', error); + return { isValid: false, error: error instanceof Error ? error.message : 'Unknown error' }; + } +} + +/** + * Checks if a delegation token is currently valid + * @param token - The delegation token to check + * @param now - Current Unix timestamp in seconds (optional, defaults to current time) + * @returns True if the delegation is valid + */ +export async function isValidDelegation(token: string, now?: number): Promise { + const result = await verifyDelegation(token, now); + return result.isValid; +} + +/** + * Gets the expiration time of a delegation token + * @param token - Delegation token + * @returns Expiration timestamp or undefined if no expiration + */ +export function getDelegationExpiry(token: string): number | undefined { + const tokenObject: DelegationToken = JSON.parse(token); + return tokenObject.conditions.until; +} diff --git a/src/types/events.ts b/src/types/events.ts new file mode 100644 index 0000000..a0e5b98 --- /dev/null +++ b/src/types/events.ts @@ -0,0 +1,84 @@ +/** + * Represents a signed Nostr event + * @interface + * @see https://github.com/nostr-protocol/nips/blob/master/01.md + */ +export interface NostrEvent { + /** Event ID (32-bytes lowercase hex of the sha256 of the serialized event data) */ + id: string; + /** Event creator's public key (32-bytes lowercase hex) */ + pubkey: string; + /** Unix timestamp in seconds */ + created_at: number; + /** Event kind (integer) */ + kind: number; + /** Array of arrays of strings (event tags) */ + tags: string[][]; + /** Event content (arbitrary string) */ + content: string; + /** Schnorr signature of the event ID (64-bytes hex) */ + sig: string; +} + +/** + * Represents an unsigned Nostr event before signing + * @interface + */ +export interface UnsignedEvent { + /** Event creator's public key (32-bytes lowercase hex) */ + pubkey: string; + /** Unix timestamp in seconds */ + created_at: number; + /** Event kind (integer) */ + kind: number; + /** Array of arrays of strings (event tags) */ + tags: string[][]; + /** Event content (arbitrary string) */ + content: string; +} + +/** + * @module types/events + * @description Event-related type definitions + */ + +/** + * Result of event validation + */ +export interface ValidationResult { + /** Whether the validation passed */ + isValid: boolean; + /** Error message if validation failed */ + error?: string; +} + +/** + * Tag type for Nostr events + */ +export type Tag = string[]; + +/** + * Unsigned Nostr event + */ +export interface UnsignedEvent { + /** Public key of the event creator */ + pubkey: string; + /** Unix timestamp in seconds */ + created_at: number; + /** Event kind (1 for text note, etc.) */ + kind: number; + /** Array of tags */ + tags: Tag[]; + /** Content of the event */ + content: string; +} + +/** + * Complete Nostr event with signature + */ +export interface NostrEvent extends UnsignedEvent { + /** Event ID (32-byte SHA256 hash of the serialized event data) */ + id: string; + /** Schnorr signature of the event ID */ + sig: string; +} diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..8f1efc6 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,2 @@ +export * from './keys.js'; +export type { Tag, UnsignedEvent, NostrEvent } from './events.js'; diff --git a/src/types/keys.ts b/src/types/keys.ts new file mode 100644 index 0000000..bf0f44f --- /dev/null +++ b/src/types/keys.ts @@ -0,0 +1,63 @@ +/** + * @module types/keys + * @description Key-related type definitions + */ + +/** + * Public key can be either a hex string or a detailed object + */ +export type PublicKey = string | PublicKeyDetails; + +/** + * Public key in hex format + */ +export type PublicKeyHex = string; + +/** + * Detailed public key information + */ +export interface PublicKeyDetails { + /** Hex-encoded public key */ + hex: string; + /** Compressed public key (33 bytes with prefix) */ + compressed: Uint8Array; + /** Schnorr public key (32 bytes x-coordinate) as per BIP340 */ + schnorr: Uint8Array; + /** Bech32-encoded npub format */ + npub: string; +} + +/** + * Key pair used for signing and encryption + * @see https://github.com/nostr-protocol/nips/blob/master/01.md + */ +export interface KeyPair { + /** Private key in hex format */ + privateKey: string; + /** Public key details */ + publicKey: PublicKeyDetails; + /** Private key in bech32 nsec format */ + nsec: string; + /** BIP39 seed phrase used to generate this key pair (if available) */ + seedPhrase?: string; +} + +/** + * Result of decoding a bech32 string + */ +export interface Bech32Result { + /** Type of the decoded data (e.g., 'npub', 'nsec', 'note') */ + type: string; + /** The decoded data */ + data: Uint8Array; +} + +/** + * Result of key pair validation + */ +export interface ValidationResult { + /** Whether the validation passed */ + isValid: boolean; + /** Error message if validation failed */ + error?: string; +} diff --git a/src/utils/conversion.ts b/src/utils/conversion.ts new file mode 100644 index 0000000..15ee60a --- /dev/null +++ b/src/utils/conversion.ts @@ -0,0 +1,64 @@ +import { bytesToHex, hexToBytes } from "@noble/hashes/utils"; +import { logger } from './logger.js'; + +/** + * Converts a string to Uint8Array using UTF-8 encoding + * @param {string} str - The string to convert + * @returns {Uint8Array} The resulting bytes + */ +export function stringToBytes(str: string): Uint8Array { + try { + return new TextEncoder().encode(str); + } catch (error) { + logger.error('Failed to convert string to bytes:', error); + throw new Error('Failed to convert string to bytes'); + } +} + +/** + * Converts a Uint8Array to string using UTF-8 encoding + * @param {Uint8Array} bytes - The bytes to convert + * @returns {string} The resulting string + */ +export function bytesToString(bytes: Uint8Array): string { + try { + return new TextDecoder().decode(bytes); + } catch (error) { + logger.error('Failed to convert bytes to string:', error); + throw new Error('Failed to convert bytes to string'); + } +} + +/** + * Converts a hex string to base64 + * @param {string} hex - The hex string to convert + * @returns {string} The base64 string + */ +export function hexToBase64(hex: string): string { + try { + const bytes = hexToBytes(hex); + return btoa(String.fromCharCode(...bytes)); + } catch (error) { + logger.error('Failed to convert hex to base64:', error); + throw new Error('Failed to convert hex to base64'); + } +} + +/** + * Converts a base64 string to hex + * @param {string} base64 - The base64 string to convert + * @returns {string} The hex string + */ +export function base64ToHex(base64: string): string { + try { + const binary = atob(base64); + const bytes = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + return bytesToHex(bytes); + } catch (error) { + logger.error('Failed to convert base64 to hex:', error); + throw new Error('Failed to convert base64 to hex'); + } +} diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..7b63f18 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,3 @@ +export * from './logger.js'; +export * from './validation.js'; +export * from './conversion.js'; diff --git a/src/utils/logger.ts b/src/utils/logger.ts new file mode 100644 index 0000000..be4cd74 --- /dev/null +++ b/src/utils/logger.ts @@ -0,0 +1,45 @@ +/** + * @module Logger + * @category Utils + * @description Enhanced logging utility with support for both ESM and CJS. + * Provides consistent logging across the application with proper type safety. + */ + +import pino, { Logger } from 'pino'; + +/** + * Configuration options for the logger + */ +const options = { + level: process.env.LOG_LEVEL || 'info' +}; + +/** + * Custom logger type that extends pino's Logger with additional functionality + */ +type CustomLogger = Logger & { + /** + * Enhanced log method that handles both string and object-based logging + * @param {string | Record} obj - The message or object to log + * @param {string} [msg] - Optional message when logging an object + */ + log: (obj: string | Record, msg?: string) => void; +}; + +// Create the logger instance with proper ESM/CJS compatibility +const baseLogger = (pino.default || pino)(options) as Logger; + +// Create the custom logger instance +const logger = baseLogger as CustomLogger; + +// Add log method as an alias for info with enhanced type safety +logger.log = (obj: string | Record, msg?: string) => { + if (typeof obj === 'string') { + logger.info(obj); + } else { + logger.info(obj, msg); + } +}; + +export { logger }; +export default logger; diff --git a/src/utils/validation.ts b/src/utils/validation.ts new file mode 100644 index 0000000..9b29b4b --- /dev/null +++ b/src/utils/validation.ts @@ -0,0 +1,64 @@ +import { logger } from './logger.js'; + +/** + * Validates a hex string + * @param {string} hex - The hex string to validate + * @param {number} [expectedLength] - Optional expected length of the hex string + * @returns {boolean} True if valid hex string, false otherwise + */ +export function isValidHex(hex: string, expectedLength?: number): boolean { + try { + if (!hex) return false; + if (!/^[0-9a-f]*$/i.test(hex)) return false; + if (expectedLength && hex.length !== expectedLength) return false; + return true; + } catch (error) { + logger.error('Hex validation failed:', error); + return false; + } +} + +/** + * Validates a timestamp is within a reasonable range + * @param {number} timestamp - Unix timestamp in seconds + * @param {number} [maxAgeDays=30] - Maximum age in days + * @returns {boolean} True if timestamp is valid, false otherwise + */ +export function isValidTimestamp(timestamp: number, maxAgeDays = 30): boolean { + try { + const now = Math.floor(Date.now() / 1000); + const maxAge = maxAgeDays * 24 * 60 * 60; + return timestamp > (now - maxAge) && timestamp <= now; + } catch (error) { + logger.error('Timestamp validation failed:', error); + return false; + } +} + +/** + * Checks if a string is base64 encoded + * @param {string} str - The string to check + * @returns {boolean} True if valid base64, false otherwise + */ +export function isBase64(str: string): boolean { + try { + return /^[A-Za-z0-9+/]*={0,2}$/.test(str); + } catch (error) { + logger.error('Base64 validation failed:', error); + return false; + } +} + +/** + * Validates an array contains only strings + * @param {unknown[]} arr - The array to validate + * @returns {boolean} True if array contains only strings, false otherwise + */ +export function isStringArray(arr: unknown[]): arr is string[] { + try { + return Array.isArray(arr) && arr.every(item => typeof item === 'string'); + } catch (error) { + logger.error('String array validation failed:', error); + return false; + } +} diff --git a/typedoc.json b/typedoc.json index 269aca4..bd86b84 100644 --- a/typedoc.json +++ b/typedoc.json @@ -12,11 +12,25 @@ "readme": "README.md", "categorizeByGroup": true, "categoryOrder": [ + "Core", + "BIPs", + "NIPs", "Key Management", "Seed Phrase", "Event Operations", - "Message Handling", + "Cryptography", "Types", + "Utils", "*" - ] + ], + "navigationLinks": { + "GitHub": "https://github.com/humanjavaenterprises/nostr-nsec-seedphrase" + }, + "sidebarLinks": { + "API": "modules.md" + }, + "validation": { + "invalidLink": true, + "notDocumented": true + } }