UNPKG

fastcomments-sdk

Version:

FastComments API Client - A SDK for interacting with the FastComments API

497 lines (376 loc) 13.5 kB
# FastComments Node.js/TypeScript SDK Official Node.js and TypeScript SDK for the FastComments API. Build secure and scalable backend applications that interact with FastComments, or build reactive client applications. ## Installation [![npm](https://img.shields.io/npm/v/fastcomments-sdk?logo=npm&label=npm&color=cb3837)](https://www.npmjs.com/package/fastcomments-sdk) ```bash npm install fastcomments-sdk ``` ## API Documentation Full API reference: [docs/api/README.md](docs/api/README.md) ## Browser vs Server Compatibility This SDK uses **dual entry points** to ensure optimal compatibility and prevent runtime errors: - **`fastcomments-sdk/browser`** - Browser-safe version with native `fetch` - **`fastcomments-sdk/server`** - Full Node.js version with SSO support - **`fastcomments-sdk`** (default) - Types only, safe to import anywhere ## Usage This SDK provides separate entry points for browser and server environments to ensure optimal compatibility and security: ### Browser Usage (Client-Side) For browser/frontend applications, use the browser-safe export that excludes Node.js dependencies: ```typescript // Browser-safe import (no Node.js dependencies) import { createFastCommentsBrowserSDK } from 'fastcomments-sdk/browser'; // Create browser SDK instance const sdk = createFastCommentsBrowserSDK({ basePath: 'https://fastcomments.com' // optional, defaults to https://fastcomments.com }); // Use public APIs (no API key needed - safe for browsers) const comments = await sdk.publicApi.getCommentsPublic({ tenantId: 'your-tenant-id', urlId: 'page-url-id' }); ``` ### Server Usage (Node.js) For server/backend applications, use the full SDK with SSO and authentication features: ```typescript // Server-side import (includes SSO and designed to work with NodeJS) import { createFastCommentsSDK } from 'fastcomments-sdk/server'; // Create server SDK instance const sdk = createFastCommentsSDK({ apiKey: 'your-api-key', // Keep this secret on the server! basePath: 'https://fastcomments.com' // optional, defaults to https://fastcomments.com }); // Use secured APIs with your API key const comments = await sdk.defaultApi.getComments({ tenantId: 'your-tenant-id', urlId: 'page-url-id' }); ``` ### Types Only Import If you only need TypeScript types (no runtime code), use the default import: ```typescript // Types only (no runtime dependencies - safe everywhere) import type { PublicComment, CreateCommentParams, GetCommentsPublic200Response } from 'fastcomments-sdk'; ``` ### Using Individual API Classes #### Browser Environment ```typescript import { PublicApi, Configuration } from 'fastcomments-sdk/browser'; const config = new Configuration({ basePath: 'https://fastcomments.com' }); const publicApi = new PublicApi(config); ``` #### Server Environment ```typescript import { DefaultApi, PublicApi, Configuration } from 'fastcomments-sdk/server'; const config = new Configuration({ apiKey: 'your-api-key', basePath: 'https://fastcomments.com' }); const defaultApi = new DefaultApi(config); const publicApi = new PublicApi(config); ``` ## Public vs Secured APIs The SDK provides these API classes: - **`DefaultApi`** - Secured endpoints that require your API key for authentication. Use these for server-side operations. - **`PublicApi`** - Public endpoints that can be accessed without an API key. These can be called directly from browsers/mobile devices/etc. - **`ModerationApi`** - Moderator dashboard endpoints (comment moderation, bans, badges, trust factor, search). Authenticated by the moderator's session; pass the `sso` query param for SSO-authenticated moderators. - **`HiddenApi`** - Internal/admin endpoints for advanced use cases. ### Example: Using Public API (browser-safe) ```typescript import { PublicApi } from 'fastcomments-sdk/browser'; const publicApi = new PublicApi(); // Get comments for a page (no API key required) const response = await publicApi.getCommentsPublic({ tenantId: 'your-tenant-id', urlId: 'page-url-id' }); ``` ### Example: Using Default API (server-side only) ```typescript import { DefaultApi, Configuration } from 'fastcomments-sdk/server'; const config = new Configuration({ apiKey: 'your-api-key' // Keep this secret! }); const defaultApi = new DefaultApi(config); // Get comments with full admin access const response = await defaultApi.getComments({ tenantId: 'your-tenant-id', urlId: 'page-url-id' }); ``` ### Example: Using Moderation API ```typescript import { createFastCommentsSDK } from 'fastcomments-sdk/server'; const sdk = createFastCommentsSDK({ /* basePath, etc. */ }); // Moderator-authenticated calls (session cookie, or pass `sso` for an SSO moderator). const comments = await sdk.moderationApi.getApiComments({ tenantId: 'your-tenant-id' }); await sdk.moderationApi.postSetCommentSpamStatus({ commentId: 'comment-id', spam: true }); ``` ## SSO (Single Sign-On) Integration FastComments supports SSO to integrate with your existing user authentication system. **SSO functionality is only available in the server export** since it requires Node.js crypto features. ### Simple SSO (Server-Side Only) Simple SSO should be generated server-side and sent to the client: ```typescript // Server-side code (Node.js/backend) import { FastCommentsSSO, PublicApi } from 'fastcomments-sdk/server'; // Create simple SSO using the built-in helper const userData = { username: 'john_doe', email: 'john@example.com', displayName: 'John Doe', avatar: 'https://example.com/avatar.jpg' }; const sso = FastCommentsSSO.createSimple(userData, { loginURL: '/login', logoutURL: '/logout' }); const ssoToken = sso.createToken(); // Send ssoToken to your client-side code // Client-side code can then use this token with the browser SDK ``` ### Secure SSO (Server-Side, Recommended) Secure SSO should be implemented server-side and provides better security: ```typescript // Server-side code (Node.js/backend) import { FastCommentsSSO, PublicApi } from 'fastcomments-sdk/server'; // Create secure SSO using the built-in helper const userData = { id: 'user-123', email: 'john@example.com', username: 'john_doe', displayName: 'John Doe', avatar: 'https://example.com/avatar.jpg', isAdmin: false, isModerator: false }; const sso = FastCommentsSSO.createSecure('your-api-key', userData, { loginURL: '/login', logoutURL: '/logout' }); const ssoConfig = sso.prepareToSend(); // Use with API calls on the server const publicApi = new PublicApi(); const response = await publicApi.getCommentsPublic({ tenantId: 'your-tenant-id', urlId: 'page-url-id', sso: JSON.stringify(ssoConfig) }); // Or send ssoConfig to client for browser usage ``` ### Using SSO from Browser (with Server-Generated Token) ```typescript // Client-side code (browser) import { PublicApi } from 'fastcomments-sdk/browser'; // Get SSO token from your server endpoint const ssoToken = await fetch('/api/sso-token').then(r => r.json()); const publicApi = new PublicApi(); const response = await publicApi.getCommentsPublic({ tenantId: 'your-tenant-id', urlId: 'page-url-id', sso: ssoToken // Use the server-generated SSO token }); ``` ### SSO with Comment Creation ```typescript // Server-side: Create SSO and comment import { FastCommentsSSO, PublicApi } from 'fastcomments-sdk/server'; const sso = FastCommentsSSO.createSecure('your-api-key', userData); const ssoConfig = sso.prepareToSend(); const response = await publicApi.createCommentPublic({ tenantId: 'your-tenant-id', urlId: 'page-url-id', broadcastId: 'unique-broadcast-id', commentData: { comment: 'This is my comment', date: Date.now(), commenterName: 'John Doe', url: 'https://example.com/page', urlId: 'page-url-id' }, sso: JSON.stringify(ssoConfig) }); ``` ## Common Use Cases ### Getting Comments for a Page ```typescript const comments = await sdk.publicApi.getCommentsPublic({ tenantId: 'your-tenant-id', urlId: 'article-123' }); ``` ### Creating a Comment ```typescript const newComment = await sdk.publicApi.createCommentPublic({ createCommentParams: { tenantId: 'your-tenant-id', urlId: 'article-123', comment: 'Great article!', commenterName: 'John Doe', commenterEmail: 'john@example.com' } }); ``` ### Voting on a Comment ```typescript const voteResponse = await sdk.publicApi.voteComment({ voteBodyParams: { commentId: 'comment-id', direction: 1 // 1 for upvote, -1 for downvote } }); ``` ### User Management (Requires API Key) ```typescript // Search for users (requires DefaultApi) const users = await sdk.defaultApi.searchUsers({ tenantId: 'your-tenant-id', urlId: 'page-id', usernameStartsWith: 'john' }); ``` ## Live Events (Real-time Updates) Subscribe to live events to get real-time updates for comments, votes, and other activities. ### Page-Level Events Listen for live events on a specific page (comments, votes, etc.): ```typescript import { subscribeToChanges, LiveEvent, LiveEventType } from 'fastcomments-sdk/browser'; const config = { tenantId: 'your-tenant-id', urlId: 'page-url-id', }; // Subscribe to live events for a page const subscription = subscribeToChanges( config, 'your-tenant-id', // tenantIdWS 'page-url-id', // urlIdWS 'user-session-id', // userIdWS (get this from getComments response) (event: LiveEvent) => { console.log('Live event received:', event); switch (event.type) { case LiveEventType.new_comment: console.log('New comment:', event.comment); // Update your UI with the new comment break; case LiveEventType.new_vote: console.log('New vote:', event.vote); // Update vote counts in your UI break; case LiveEventType.updated_comment: console.log('Comment updated:', event.comment); break; default: console.log('Other event type:', event.type); } return true; // Return true if event was handled }, (isConnected: boolean) => { console.log('Connection status:', isConnected ? 'Connected' : 'Disconnected'); } ); // Close the subscription when done subscription.close(); ``` ### Subscribe to User Events Listen for user-specific events (notifications, mentions, etc.): ```typescript import { subscribeToUserFeed, LiveEvent, LiveEventType } from 'fastcomments-sdk/browser'; const userConfig = { userIdWS: 'user-session-id', // Get this from getComments response }; // Subscribe to user's personal feed const userSubscription = subscribeToUserFeed( userConfig, (event: LiveEvent) => { console.log('User event received:', event); switch (event.type) { case LiveEventType.notification: console.log('New notification:', event.notification); // Show notification in your UI break; case LiveEventType.notification_update: console.log('Notification updated:', event.notification); break; default: console.log('Other user event:', event.type); } return true; }, (isConnected: boolean) => { console.log('User feed connection:', isConnected ? 'Connected' : 'Disconnected'); } ); // Close when done userSubscription.close(); ``` ### Getting userIdWS The `userIdWS` parameter is required for live events and can be obtained from API responses: ```typescript const response = await sdk.publicApi.getCommentsPublic({ tenantId: 'your-tenant-id', urlId: 'page-id' }); // Extract userIdWS from the response const userIdWS = response.data?.userSessionInfo?.userIdWS; if (userIdWS) { // Now you can subscribe to live events const subscription = subscribeToChanges(config, tenantIdWS, urlIdWS, userIdWS, handleEvent); } ``` ## Broadcast IDs You'll see you're supposed to pass a `broadcastId` in some API calls. When you receive events, you'll get this ID back, so you know to ignore the event if you plan to optimistically apply changes on the client (which you'll probably want to do since it offers the best experience). Pass a UUID here. The ID should be unique enough to not occur twice in a browser session. ```typescript import { v4 as uuidv4 } from 'uuid'; const response = await sdk.publicApi.createCommentPublic({ createCommentParams: { tenantId: 'your-tenant-id', urlId: 'page-id', comment: 'My comment', broadcastId: uuidv4() // Unique ID for this operation } }); ``` ## Error Handling ```typescript try { const comments = await sdk.publicApi.getCommentsPublic({ tenantId: 'your-tenant-id', urlId: 'page-id' }); } catch (error) { if (error.response?.status === 404) { console.log('Page not found'); } else { console.error('API Error:', error.message); } } ``` ## TypeScript Support The SDK is written in TypeScript and provides complete type definitions for all API methods and response models: ```typescript // Import types from the default export (safe everywhere) import type { PublicComment, CreateCommentParams, GetCommentsPublic200Response } from 'fastcomments-sdk'; // Use with browser SDK import { createFastCommentsBrowserSDK } from 'fastcomments-sdk/browser'; const sdk = createFastCommentsBrowserSDK(); const response: GetCommentsPublic200Response = await sdk.publicApi.getCommentsPublic({ tenantId: 'your-tenant-id', urlId: 'page-id' }); const comments: PublicComment[] = response.comments || []; ``` ## License MIT