UNPKG

@konemono/nostr-content-parser

Version:
277 lines (204 loc) 6.92 kB
# Nostr Content Parser Parse Nostr content into structured tokens. ## Installation ```bash npm install @konemono/nostr-content-parser ``` ## Usage ```javascript import { parseContent, parseContentAsync, TokenType, NIP19SubType, } from "@konemono/nostr-content-parser"; const content = "Hello npub1xyz... Check :custom_emoji: #nostr"; const tags = [["emoji", "custom_emoji", "https://example.com/emoji.png"]]; // Synchronous parsing (recommended for most cases) const tokens = parseContent(content, tags); console.log(tokens); // Asynchronous parsing with URL type detection const tokensWithUrlTypes = await parseContentAsync(content, tags); console.log(tokensWithUrlTypes); ``` ## Token Types ### Main Types - `TokenType.TEXT` - Plain text - `TokenType.NIP19` - NIP-19 entities (npub, nprofile, note, nevent, naddr, nsec) - `TokenType.URL` - URLs - `TokenType.CUSTOM_EMOJI` - Custom emojis - `TokenType.HASHTAG` - Hashtags - `TokenType.LN_ADDRESS` - Lightning addresses - `TokenType.LN_URL` - Lightning URLs - `TokenType.LNBC` - Lightning invoices - `TokenType.EMAIL` - Email addresses - `TokenType.BITCOIN_ADDRESS` - Bitcoin addresses - `TokenType.CASHU_TOKEN` - Cashu tokens - `TokenType.NIP_IDENTIFIER` - NIP identifiers ### NIP19 Sub Types - `NIP19SubType.NPUB` - Public key - `NIP19SubType.NPROFILE` - Profile - `NIP19SubType.NOTE` - Note - `NIP19SubType.NEVENT` - Event - `NIP19SubType.NADDR` - Address - `NIP19SubType.NSEC` - Secret key ## API ### Core Functions #### `parseContent(content, tags, options?)` **Synchronous parsing** - Recommended for most use cases. **Parameters:** - `content: string`Input content to parse. - `tags: string[][]`Optional tag array (used for custom emoji, etc). - `options: object`Optional settings: - `includeNostrPrefixOnly?: boolean` If `true` (default), only tokens starting with `nostr:` will be included for NIP-19. If `false`, plain NIP-19 tokens (without prefix) will also be parsed. - `hashtagsFromTagsOnly?: boolean` If `true` (default), only hashtags that match a `t` tag will be parsed as hashtags. If `false`, all `#`-prefixed words are treated as hashtags. **Returns:** `Token[]` URL type detection is performed based on file extensions only (fast and lightweight). #### `parseContentAsync(content, tags, options?)` **Asynchronous parsing** - Use when you need comprehensive URL type detection. **Parameters:** - `content: string`Input content to parse. - `tags: string[][]`Optional tag array (used for custom emoji, etc). - `options: object`Optional settings: - `includeNostrPrefixOnly?: boolean` (same as sync version) - `hashtagsFromTagsOnly?: boolean` (same as sync version) **Returns:** `Promise<Token[]>` URL type detection includes HTTP HEAD requests to determine content type when file extension is not available. ### Filter Functions - `filterTokens(tokens, types)` - Filter tokens by type - `filterTokensBy(tokens, predicate)` - Filter tokens by custom predicate ### NIP19 Functions - `getNip19Entities(tokens)` - Get all NIP-19 entities - `filterNip19BySubType(tokens, subType)` - Filter NIP-19 by sub type - `getNpubs(tokens)` - Get npub tokens - `getNprofiles(tokens)` - Get nprofile tokens - `getNotes(tokens)` - Get note tokens - `getNevents(tokens)` - Get nevent tokens - `getNaddrs(tokens)` - Get naddr tokens - `getNsecs(tokens)` - Get nsec tokens ### Other Entity Functions - `getUrls(tokens)` - Get URLs - `getCustomEmojis(tokens)` - Get custom emojis - `getHashtags(tokens)` - Get hashtags - `getLightningAddresses(tokens)` - Get Lightning addresses - `getLightningUrls(tokens)` - Get Lightning URLs - `getLightningInvoices(tokens)` - Get Lightning invoices - `getBitcoinAddresses(tokens)` - Get Bitcoin addresses - `getCashuTokens(tokens)` - Get Cashu tokens - `getEmails(tokens)` - Get email addresses - `getNipIdentifiers(tokens)` - Get NIP identifiers ### Utility Functions - `resetPatterns()` - Reset regex patterns (call if needed) ## Examples ### Basic Parsing (Synchronous) ```javascript // Fast, synchronous parsing const tokens = parseContent("Check out npub1xyz... and #nostr!"); // Returns tokens with NIP19 and HASHTAG types ``` ### URL Type Detection (Asynchronous) ```javascript // Comprehensive URL type detection const content = "Check this image: https://example.com/photo and https://example.com/video.mp4"; const tokens = await parseContentAsync(content); const urls = getUrls(tokens); urls.forEach((url) => { console.log(`URL: ${url.content}`); console.log(`Scheme: ${url.metadata.scheme}`); // "https", "http" console.log(`Type: ${url.metadata.type}`); // "image", "video", "audio" (if detected) }); ``` ### Working with NIP19 Tokens ```javascript const tokens = parseContent("Check nostr:npub1xyz... and note1abc...", [], { includeNostrPrefixOnly: false, // Include plain NIP19 tokens }); const nip19Tokens = getNip19Entities(tokens); nip19Tokens.forEach((token) => { console.log(`Type: ${token.metadata.subType}`); // "npub", "note", etc. console.log(`Has nostr: prefix: ${token.metadata.hasNostrPrefix}`); console.log(`Plain NIP19: ${token.metadata.plainNip19}`); }); // Filter specific NIP19 types const npubs = getNpubs(tokens); const notes = filterNip19BySubType(tokens, NIP19SubType.NOTE); ``` ### Hashtag Filtering ```javascript const content = "#nostr #dev"; const tags = [["t", "nostr"]]; const tokens = parseContent(content, tags, { hashtagsFromTagsOnly: true, }); // Only "#nostr" will be returned as a HASHTAG token ``` ### Custom Emoji Handling ```javascript const content = "Hello :custom_emoji:!"; const tags = [["emoji", "custom_emoji", "https://example.com/emoji.png"]]; const tokens = parseContent(content, tags); const emojis = getCustomEmojis(tokens); emojis.forEach((emoji) => { console.log(`Name: ${emoji.metadata.name}`); console.log(`URL: ${emoji.metadata.url}`); }); ``` ### Performance Comparison ```javascript // Fast: Extension-based URL type detection only const fastTokens = parseContent(content); // Comprehensive: Includes HTTP requests for unknown URLs const detailedTokens = await parseContentAsync(content); ``` ## Token Structure Each token has the following structure: ```typescript interface Token { type: TokenType; content: string; start: number; end: number; metadata: Record<string, unknown>; } ``` ### Metadata Examples **NIP19 Token:** ```javascript { subType: "npub", hasNostrPrefix: true, plainNip19: "npub1xyz..." } ``` **Custom Emoji Token:** ```javascript { name: "custom_emoji", url: "https://example.com/emoji.png" } ``` **URL Token:** ```javascript { scheme: "https", type: "image" // Only present if detected } ``` ## Commands ```bash # Run tests npm test # Run tests once npm run test:run # Build npm run build # Pre-publish check npm run prepublishOnly # Publish to npm npm publish ```