UNPKG

@bradsearch/search-sdk

Version:

TypeScript SDK for BradSearch API with JWT authentication, field mapping, and faceted search capabilities

544 lines (425 loc) โ€ข 11.1 kB
# @bradsearch/search-sdk A TypeScript SDK for BradSearch API with JWT authentication, field mapping, and faceted search capabilities. ## ๐Ÿš€ Installation ```bash npm install @bradsearch/search-sdk ``` ## ๐Ÿ“‹ Quick Start ```typescript import { ApiClient } from "@bradsearch/search-sdk"; // Initialize the client const client = new ApiClient({ token: "your-jwt-token", baseUrl: "http://localhost:8080", fields: { name: { type: "text_keyword", filterable: false }, brand: { type: "text_keyword", filterable: true }, categories: { type: "hierarchy", filterable: true }, price: { type: "integer", filterable: true }, variants: { type: "variants", filterable: true, fields: { color: { type: "text_keyword", filterable: true }, size: { type: "keyword", filterable: true }, material: { type: "text_keyword", filterable: true }, }, }, }, mapping: { title: "name", reference: "sku", link: "productUrl", imageUrl: "imageUrl", }, }); // Perform a search const results = await client.query("laptop", { brand: ["Dell", "HP"], categories: ["Electronics > Computers"], }); console.log(results.documents); console.log(results.facets); ``` ## ๐Ÿ”ง Configuration ### ApiClient Constructor ```typescript interface ApiSdkConfig { token: string; // JWT authentication token baseUrl: string; // API base URL (e.g., 'http://localhost:8080') fields: Record<string, FieldConfig>; // Field configurations mapping?: ItemMapping; // Response field mapping (optional) } ``` ### Field Configuration ```typescript interface FieldConfig { type: FieldType; // Field type filterable?: boolean; // Whether field can be used as filter (default: false) fields?: Record<string, FieldConfig>; // For variants type - subfield configurations label?: string; // Human-readable label for the field (optional) } type FieldType = | "text" // Full-text search | "keyword" // Exact match | "text_keyword" // Both full-text and exact match | "hierarchy" // Hierarchical categories (e.g., "Electronics > Computers") | "variants" // Product variants | "object" // Complex objects | "url" // URLs | "image_url" // Image URLs | "integer"; // Numeric values ``` ### Response Mapping Map API response fields to the standard Item interface: ```typescript interface ItemMapping { title?: string; // Maps to item title reference?: string; // Maps to item reference/SKU link?: string; // Maps to item URL imageUrl?: string; // Maps to item image URL } // Standard Item interface interface Item { id: string; title: string; link: string; imageUrl: { small: string; medium: string }; reference: string; _highlights?: Record<string, string>; } ``` ## ๐Ÿ” Search Methods ### Basic Search ```typescript // Simple text search const results = await client.query("laptop"); // Search with options const results = await client.query( "laptop", {}, { limit: 20, offset: 0, sortBy: "name", order: "asc", } ); ``` ### Search with Filters ```typescript // Single filter const results = await client.query("laptop", { brand: "Dell", }); // Multiple filters const results = await client.query("laptop", { brand: ["Dell", "HP"], categories: ["Electronics > Computers > Laptops"], price: ["100-500"], // Range filter }); // Variant filters (using subfield names directly) const results = await client.query("shirt", { color: ["blue", "red"], // Variant attribute filter size: ["M", "L"], // Another variant attribute filter brand: ["Nike"], // Regular field filter }); ``` ### Search All (Browse Mode) ```typescript // Get all items without search query const results = await client.query( "", {}, { searchAll: true, limit: 50, } ); ``` ### Request Cancellation ```typescript const controller = new AbortController(); const results = await client.query( "laptop", {}, { signal: controller.signal, } ); // Cancel the request controller.abort(); ``` ## ๐Ÿ“Š Response Format ```typescript interface SearchResponse<T = Item> { limit: number; // Items per page total: number; // Total items found offset: number; // Current offset facets: Record<string, FacetValue[]>; // Available filters documents: T[]; // Search results } interface FacetValue { value: string; // Filter value count: number; // Number of items with this value } ``` ## ๐Ÿ› ๏ธ Advanced Usage ### Product Variants Configure variant filtering for products with multiple options (color, size, etc.): ```typescript // Configuration const client = new ApiClient({ // ... other config fields: { // ... other fields variants: { type: "variants", filterable: true, fields: { color: { type: "text_keyword", filterable: true }, size: { type: "keyword", filterable: true }, material: { type: "text_keyword", filterable: true }, }, }, }, }); // Filter by variant attributes (use subfield names directly) const results = await client.query("", { color: ["blue", "red", "green"], size: ["S", "M", "L"], }); ``` ### Custom Item Types ```typescript interface CustomProduct { id: string; productName: string; brandName: string; categoryPath: string; price: number; } const results = await client.query<CustomProduct>("laptop"); // results.documents will be CustomProduct[] ``` ### Error Handling ```typescript import { ApiError, AuthenticationError, ValidationError, NetworkError, } from "@bradsearch/search-sdk"; try { const results = await client.query("laptop"); } catch (error) { if (error instanceof AuthenticationError) { console.error("Invalid or expired JWT token"); } else if (error instanceof ValidationError) { console.error("Invalid request parameters"); } else if (error instanceof NetworkError) { console.error("Network connection failed"); } else if (error instanceof ApiError) { console.error("API error:", error.statusCode, error.message); } } ``` ### Utility Methods ```typescript // Get filterable fields const filterableFields = client.getFilterableFields(); // Update configuration client.updateConfig({ fields: { ...client.config.fields, newField: { type: "keyword", filterable: true }, }, }); ``` ## ๐ŸŒ Hierarchy Filters For hierarchical fields (categories), use " > " separator: ```typescript const client = new ApiClient({ // ... other config fields: { categories: { type: "hierarchy", filterable: true }, }, }); // Filter by category hierarchy const results = await client.query("", { categories: [ "Electronics", // Top level "Electronics > Computers", // Second level "Electronics > Computers > Laptops", // Third level ], }); ``` ## ๐Ÿงช Development ### Prerequisites - Node.js >= 16.0.0 - npm or yarn ### Setup ```bash # Clone the repository git clone <repository-url> cd SDK/typescript # Install dependencies npm install # Build the package npm run build # Run tests npm run test # Run linting npm run lint ``` ### Development Scripts ```bash npm run dev # Watch mode for development npm run build # Build for production npm run test # Run tests npm run lint # Run ESLint npm run storybook # Start Storybook demo ``` ### Storybook Demo Interactive demo with real API connections: ```bash npm run storybook ``` Open http://localhost:6006 to see: - Complete search interface - Hierarchy filters with tree structure - Configuration testing - Field mapping examples ## ๐Ÿ“ฆ Publishing ### Preparing for Publication 1. **Update version**: ```bash npm version patch # 1.0.0 -> 1.0.1 npm version minor # 1.0.0 -> 1.1.0 npm version major # 1.0.0 -> 2.0.0 ``` 2. **Build and test**: ```bash npm run build npm run test npm run lint ``` 3. **Preview package contents**: ```bash npm pack --dry-run ``` ### Authentication #### Login to npm ```bash # Login with your npm account npm login # Verify authentication npm whoami ``` #### Switch npm User ```bash # Logout current user npm logout # Login with different account npm login --registry https://registry.npmjs.org/ ``` ### Publishing to npm #### First Time Publication ```bash # Publish as public package (required for scoped packages) npm publish --access public ``` #### Subsequent Releases ```bash # Regular publish (after version bump) npm publish ``` #### Publishing Beta/Alpha Versions ```bash # Tag as beta npm version prerelease --preid=beta npm publish --tag beta # Tag as alpha npm version prerelease --preid=alpha npm publish --tag alpha ``` ### Automated Publishing The package includes a `prepublishOnly` script that automatically builds before publishing: ```json { "scripts": { "prepublishOnly": "npm run build" } } ``` ### Package Configuration Key `package.json` fields for publishing: ```json { "name": "@bradsearch/search-sdk", "version": "1.0.0", "main": "dist/index.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts", "files": [ "dist/**/*.js", "dist/**/*.d.ts", "dist/**/*.js.map", "!dist/stories/**", "!dist/setupTests.*", "README.md" ], "engines": { "node": ">=16.0.0" } } ``` ## ๐Ÿ”’ Security - **JWT Tokens**: Store securely, never commit to version control - **HTTPS**: Always use HTTPS in production - **CORS**: Configure your API server for cross-origin requests: ```javascript // Example CORS headers for your API Access-Control-Allow-Origin: https://your-domain.com Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: Content-Type, Authorization ``` ## ๐Ÿ› Troubleshooting ### CORS Errors If you get CORS errors, ensure your API server handles preflight OPTIONS requests: ```bash # Test preflight request curl -X OPTIONS http://localhost:8080/api/v1/query \ -H "Access-Control-Request-Method: POST" \ -H "Access-Control-Request-Headers: Authorization" ``` ### Authentication Errors - Verify JWT token is valid and not expired - Ensure token contains necessary field configurations - Check API endpoint accessibility ### Build Errors ```bash # Clear dist folder and rebuild rm -rf dist npm run build # Clear node_modules and reinstall rm -rf node_modules package-lock.json npm install ``` ## ๐Ÿค Contributing 1. Fork the repository 2. Create a feature branch: `git checkout -b feature/amazing-feature` 3. Commit changes: `git commit -m 'Add amazing feature'` 4. Push to branch: `git push origin feature/amazing-feature` 5. Open a Pull Request ## ๐Ÿ“„ License MIT License - see [LICENSE](LICENSE) file for details. ## ๐Ÿ”— Links - [npm Package](https://www.npmjs.com/package/@bradsearch/search-sdk) - [GitHub Repository](https://github.com/yourusername/bradsearch) - [Documentation](https://github.com/yourusername/bradsearch#readme) - [Issues](https://github.com/yourusername/bradsearch/issues) ## ๐Ÿ“ž Support For questions and support: - Create an [issue](https://github.com/yourusername/bradsearch/issues) - Email: contact@bradsearch.com