### HTTP Request Examples Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/request.md Illustrates making simple GET requests, POST requests with JSON bodies, and handling potential errors. Also shows how to download files, which return a Buffer. ```javascript import { api } from "sawit-utils"; // Simple GET request const data = await api.request("https://api.example.com/users"); // POST request with body const response = await api.request("https://api.example.com/users", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: "John" }) }); // Download file (returns Buffer) const fileBuffer = await api.request("https://example.com/image.png"); // Error handling try { await api.request("https://invalid.example.com"); } catch (error) { console.error("Request failed:", error.message); } ``` -------------------------------- ### Install Sawit-Utils Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/START-HERE.md Install the sawit-utils library using npm. This command is typically run once at the beginning of a project. ```bash npm install sawit-utils ``` -------------------------------- ### Install sawit-utils with JSR Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/README.md Install the sawit-utils package using JSR. ```bash npx jsr add @indra87g/sawit-utils ``` -------------------------------- ### Accessing and Listing ModuleCache Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/watcher.md Example showing how to retrieve a loaded module from the cache and list all currently loaded modules. ```javascript import { ModuleCache } from "sawit-utils"; // Retrieve a loaded module const pingCommand = ModuleCache.get("./commands/ping.js"); if (pingCommand) { console.log("Command:", pingCommand.command); } // List all loaded modules console.log("Loaded modules:", Array.from(ModuleCache.keys())); ``` -------------------------------- ### Accessing and Listing CommandIndex Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/watcher.md Example demonstrating how to look up a command by its normalized name, list all available commands, and check for the existence of a command. ```javascript import { CommandIndex } from "sawit-utils"; // Look up a command const helpCommand = CommandIndex.get("help"); if (helpCommand) { console.log("Found command:", helpCommand.name); } // List all available commands console.log("Commands:", Array.from(CommandIndex.keys())); // Might output: ['help', 'ping', 'ban', 'kick', ...] // Check if command exists if (CommandIndex.has("admin")) { console.log("Admin command exists"); } ``` -------------------------------- ### Get Content-Type Example Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/request.md Demonstrates fetching the MIME type of a file and the content type of a JSON API endpoint. Returns the Content-Type string or null if not present. ```javascript import { api } from "sawit-utils"; const mimeType = await api.getContentType("https://example.com/image.png"); // "image/png" const jsonType = await api.getContentType("https://api.example.com/data"); // "application/json; charset=utf-8" ``` -------------------------------- ### Project Integration Example for scanDirectory Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/watcher.md Shows how to integrate scanDirectory into your main application startup to load both command and event handler modules. This ensures all modules are loaded and watching for changes before the application proceeds. ```javascript import { scanDirectory } from "sawit-utils"; // In main application startup async function startup() { console.log("Loading command modules..."); await scanDirectory("./src/commands"); console.log("Loading event handlers..."); await scanDirectory("./src/events"); console.log("All modules loaded and watching for changes"); } startup(); ``` -------------------------------- ### Iterating and Checking EventIndex Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/watcher.md Example showing how to iterate through all registered event handlers, check if a specific handler is indexed, and get the total count of event handlers. ```javascript import { EventIndex } from "sawit-utils"; // Iterate all event handlers for (const handler of EventIndex) { if (handler.name) { console.log("Event handler:", handler.name); } } // Check if handler is registered if (EventIndex.has(myEventHandler)) { console.log("Handler is indexed"); } // Get total count console.log("Total event handlers:", EventIndex.size); ``` -------------------------------- ### Example Usage of IgdlSuccessResult Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/types.md Demonstrates how to process a successful result from the igdl function, accessing username and video details. ```javascript const result = await igdl("https://instagram.com/p/ABC123"); if (result.success) { console.log("Username:", result.data.username); console.log("Videos available:", result.data.videos.length); for (const video of result.data.videos) { console.log(`${video.quality}: ${video.url}`); } } ``` -------------------------------- ### Good vitest unit test example Source: https://github.com/indra87g/sawit-utils/blob/main/AGENTS.md An example of a well-written unit test using vitest. It covers actual behavior and includes edge cases for robustness. ```javascript // ✅ GOOD: Tests actual behavior, covers edge cases import { describe, it, expect } from 'vitest' import { formatDate } from '../src/date.js' describe('formatDate', () => { it('formats a valid date correctly', () => { expect(formatDate('2024-01-15')).toBe('15 January 2024') }) it('returns null for invalid input', () => { expect(formatDate(null)).toBeNull() }) it('handles empty string', () => { expect(formatDate('')).toBeNull() }) }) ``` -------------------------------- ### Accessing and Iterating FileCache Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/watcher.md Example demonstrating how to check if a file is cached, retrieve its metadata, and iterate through all cached files. ```javascript import { FileCache } from "sawit-utils"; // Check if a file is cached if (FileCache.has("./commands/ping.js")) { const metadata = FileCache.get("./commands/ping.js"); console.log("File size:", metadata.size); console.log("Last modified:", new Date(metadata.mtimeMs)); } // Iterate all cached files for (const [filePath, metadata] of FileCache) { console.log(`${filePath}: ${metadata.size} bytes`); } ``` -------------------------------- ### Initialize and Use scanDirectory Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/watcher.md Demonstrates how to initialize the scanning process for a commands directory and access the indexed commands and event handlers. This setup enables automatic hot-reloading for module changes. ```javascript import { scanDirectory, CommandIndex, EventIndex } from "sawit-utils"; // Initialize by scanning a commands directory await scanDirectory("./commands"); // After scanning, all modules are indexed console.log("Total commands:", CommandIndex.size); console.log("Total event handlers:", EventIndex.size); // Handles hot-reloading automatically // Edit ./commands/help.js → automatically reloaded and re-indexed ``` -------------------------------- ### Good JSDoc Example Source: https://github.com/indra87g/sawit-utils/blob/main/AGENTS.md An example of a well-formed JSDoc comment for an exported asynchronous function. It includes required tags for parameters, return values, and a usage example. ```javascript /** * Downloads a video from an Instagram Reels URL. * * @param {string} url - The full Instagram Reels URL to download from. * @returns {Promise<{data: {videoUrl: string}} | null>} The video data, or null if the request fails. * @example * const result = await igdl('https://www.instagram.com/reel/...') * console.log(result.data.videoUrl) */ export async function igdl(url) { ``` -------------------------------- ### Example PR Title Formats Source: https://github.com/indra87g/sawit-utils/blob/main/AGENTS.md Provides examples of how to format Pull Request titles for the Forge process, indicating the area of change and a concise description of the work done. ```text 🔨 Forge: tests — add coverage for igdl edge cases ``` ```text 🔨 Forge: types — sync index.d.ts with src exports ``` ```text 🔨 Forge: jsdoc — add full JSDoc to date utilities ``` ```text 🔨 Forge: docs — update codedocs for new functions ``` ```text 🔨 Forge: publish — fix JSR slow types in index.js ``` -------------------------------- ### Indexing Modules with indexModule Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/watcher.md Example demonstrating how to use indexModule to register command modules (with single, multiple, or aliased commands) and event handler modules. ```javascript import { indexModule, CommandIndex, EventIndex } from "sawit-utils"; // Index a command module const helpModule = { command: "help", hidden: "?", handle: (msg) => { /* ... */ } }; indexModule(helpModule); console.log(CommandIndex.get("help")); // helpModule console.log(CommandIndex.get("?")); // helpModule // Index an event handler module const messageHandler = { on: "message", handle: (msg) => { /* ... */ } }; indexModule(messageHandler); console.log(EventIndex.has(messageHandler)); // true // Multiple commands/aliases const multiCommand = { command: ["admin", "mod"], hidden: ["superuser", "op"] }; indexModule(multiCommand); console.log(CommandIndex.get("admin")); // multiCommand console.log(CommandIndex.get("op")); // multiCommand ``` -------------------------------- ### Example Usage of IgdlErrorResult Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/types.md Shows how to handle a failed download operation by checking the success flag and logging the error message. ```javascript const result = await igdl("https://example.com/invalid"); if (!result.success) { console.error("Failed to download:", result.error); } ``` -------------------------------- ### Example of Command Normalization Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/watcher.md Illustrates the output of the normalizeCommand function with different input strings. This shows how various casings and spacings are converted to a standardized format. ```plaintext "Help" → "help" "ADMIN PANEL" → "adminpanel" "cmd-name" → "cmd-name" ``` -------------------------------- ### Making API Requests with Dynamic Endpoints Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/request.md Demonstrates how to use dynamic endpoint methods for making API calls. Includes examples for simple calls, calls with fetch options, and custom registered endpoints. ```javascript import { api } from "sawit-utils"; // Simple endpoint call const result = await api.deline("search", { q: "keyword" }); // With additional fetch options const result = await api.nexray("api/data", {}, { headers: { "Authorization": "Bearer token" } } ); // Path with leading slash (automatically handled) const result = await api.zenzxz("/getUser/123"); // Custom registered endpoint api.register("myapi", "https://custom.example.com/"); const data = await api.myapi("endpoint", { param: "value" }); ``` -------------------------------- ### Bad vitest unit test example Source: https://github.com/indra87g/sawit-utils/blob/main/AGENTS.md An example of a poorly written unit test that only checks the happy path and lacks edge case coverage. ```javascript // ❌ BAD: Only tests the happy path, no edge cases it('works', () => { expect(formatDate('2024-01-15')).toBeTruthy() }) ``` -------------------------------- ### Command Parsing Settings with Prefixes Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/README.md Defines the interface for command parsing settings and shows an example of parsing a command with specified prefix characters. ```typescript interface ParseCommandSettings { prefixes?: string[]; // Valid prefix characters (default: []) noPrefix?: boolean; // Allow commands without prefix (default: false) } const parsed = parseCommand("!help", { prefixes: ["!", "/"] }); ``` -------------------------------- ### Format Uptime Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/format.md Formats a start timestamp into a human-readable uptime string. Use this to display how long a system or process has been running. ```typescript function formatUptime(startTime: number): string ``` ```javascript import { formatUptime } from "sawit-utils"; const startTime = Date.now() - (5 * 24 * 60 * 60 * 1000); formatUptime(startTime); // "5d 0h 0m 0s" (approximately) ``` -------------------------------- ### Register or Override Endpoint Example Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/request.md Shows how to register a new custom endpoint or update the URL for an existing one like 'turu'. This allows for flexible API endpoint management. ```javascript import { api } from "sawit-utils"; // Register a new endpoint api.register("custom", "https://api.custom.com/"); // Override existing endpoint api.register("turu", "https://new-turu-url.com/"); ``` -------------------------------- ### formatUptime Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/format.md Formats an uptime duration in days, hours, minutes, and seconds based on a start timestamp. ```APIDOC ## formatUptime ### Description Formats an uptime duration in days, hours, minutes, and seconds. ### Method ```typescript function formatUptime(startTime: number): string ``` ### Parameters #### Path Parameters - **startTime** (number) - Yes - Start timestamp in milliseconds ### Response #### Success Response - **string** - Formatted uptime string (e.g., "5d 3h 20m 15s") ### Request Example ```javascript import { formatUptime } from "sawit-utils"; const startTime = Date.now() - (5 * 24 * 60 * 60 * 1000); formatUptime(startTime); // "5d 0h 0m 0s" (approximately) ``` ``` -------------------------------- ### Handling API Request Errors Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/QUICK-REFERENCE.md Provides an example of how to use a try-catch block to gracefully handle potential errors during API requests. ```javascript try { await api.request("https://api.example.com"); } catch (error) { console.error("Request failed:", error.message); } ``` -------------------------------- ### Example PR Description Structure Source: https://github.com/indra87g/sawit-utils/blob/main/AGENTS.md A template for the body of a Pull Request description, outlining the changes made, the reasons for them, and verification steps. ```markdown ## What changed [Brief description of the change] ## Why [What problem this solves — missing test, publish blocker, outdated docs, etc.] ## Verification - [ ] `npm test` passes - [ ] `.d.ts` files in sync (if types were touched) - [ ] JSDoc types match `.d.ts` (if JSDoc was touched) - [ ] JSR publish checklist satisfied (if publish-related) ``` -------------------------------- ### isMimeVideo Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/validation.md Checks if a given MIME type represents a video. It returns true if the MIME type string starts with 'video'. ```APIDOC ## isMimeVideo ### Description Checks if a given MIME type represents a video. ### Method ```typescript function isMimeVideo(mime: string): boolean ``` ### Parameters #### Path Parameters - **mime** (string) - Required - The MIME type string ### Returns `boolean` — True if MIME type starts with "video", false otherwise ### Example ```javascript import { isMimeVideo } from "sawit-utils"; isMimeVideo("video/mp4"); // true isMimeVideo("video/webm"); // true isMimeVideo("image/png"); // false ``` ``` -------------------------------- ### Bad JSDoc Examples Source: https://github.com/indra87g/sawit-utils/blob/main/AGENTS.md Illustrates common mistakes in JSDoc comments, such as missing JSDoc entirely or omitting crucial details like types and clear descriptions. ```javascript // ❌ No JSDoc at all export async function igdl(url) { ``` ```javascript // ❌ Missing types, vague description /** * Downloads video * @param url * @returns result */ export async function igdl(url) { ``` -------------------------------- ### isMimeAudio Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/validation.md Checks if a given MIME type represents an audio format. It returns true if the MIME type string starts with 'audio'. ```APIDOC ## isMimeAudio ### Description Checks if a given MIME type represents an audio format. ### Method ```typescript function isMimeAudio(mime: string): boolean ``` ### Parameters #### Path Parameters - **mime** (string) - Required - The MIME type string ### Returns `boolean` — True if MIME type starts with "audio", false otherwise ### Example ```javascript import { isMimeAudio } from "sawit-utils"; isMimeAudio("audio/mp3"); // true isMimeAudio("audio/wav"); // true isMimeAudio("audio/ogg"); // true isMimeAudio("video/mp4"); // false ``` ``` -------------------------------- ### Markdown Documentation Structure Source: https://github.com/indra87g/sawit-utils/blob/main/AGENTS.md A template for structuring markdown documentation files for modules or feature areas. It includes sections for a brief description, functions with parameter and return details, and usage examples. ```markdown # [Module Name] Brief description of what this module does. ## Functions ### functionName(param1, param2) Description of what the function does. **Parameters:** - `param1` {Type} — description - `param2` {Type} — description **Returns:** `{Type}` — description **Example:** ```javascript const result = await functionName(arg1, arg2) ``` ``` -------------------------------- ### Configuring ApiClient Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/QUICK-REFERENCE.md Shows how to instantiate an ApiClient with custom configurations, including setting a timeout and defining a custom registry. ```javascript const client = new ApiClient({ timeout: 5000, // 5 second timeout registry: { custom: "https://api.example.com/" } }); ``` -------------------------------- ### Importing All IGDL Types from Main Entry Point Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/types.md Demonstrates how to import all IGDL-related types directly from the main 'sawit-utils' package. ```javascript import { IgdlVideo, IgdlData, IgdlSuccessResult, IgdlErrorResult, IgdlResult } from "sawit-utils"; ``` -------------------------------- ### Configuring Command Parsing Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/QUICK-REFERENCE.md Demonstrates how to customize command parsing by specifying valid prefixes and whether a prefix is required. ```javascript const parsed = parseCommand("!help search", { prefixes: ["!", "/"], // Valid prefixes noPrefix: false // Require prefix }); ``` -------------------------------- ### Create ApiClient Instances Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/request.md Demonstrates creating ApiClient instances with default settings, a custom timeout, or additional registered endpoints. Use this to configure the client for specific application needs. ```javascript import { ApiClient } from "sawit-utils"; // Default client with built-in endpoints const client = new ApiClient(); // With custom timeout const slowClient = new ApiClient({ timeout: 5000 }); // With additional endpoints const customClient = new ApiClient({ registry: { myapi: "https://api.example.com/v1/" }, timeout: 3000 }); ``` -------------------------------- ### Pre-instantiated ApiClient Usage Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/request.md Shows how to use the pre-instantiated `api` client for immediate use without needing to create a new instance. This client comes with all built-in endpoints already registered. ```javascript import { api } from "sawit-utils"; // Use immediately without creating new instance const data = await api.deline("search", { q: "test" }); const result = await api.request("https://example.com/api"); ``` -------------------------------- ### Scanning Directory for Files Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/QUICK-REFERENCE.md Demonstrates how to use 'scanDirectory' to process files in a specified directory and logs the number of loaded commands. ```javascript import { scanDirectory, CommandIndex } from "sawit-utils"; await scanDirectory("./commands"); console.log("Loaded", CommandIndex.size, "commands"); ``` -------------------------------- ### Importing Utilities Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/QUICK-REFERENCE.md Demonstrates various ways to import functions and types from the 'sawit-utils' library, including single imports, multiple imports, and type-only imports. ```javascript // Single imports import { formatNumber, delay } from "sawit-utils"; // Multiple imports import { toArray, formatTime, parseCommand, api, scanDirectory } from "sawit-utils"; // Type imports import type { IgdlResult, IgdlData } from "sawit-utils"; ``` -------------------------------- ### isMimeImage Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/validation.md Checks if a given MIME type represents an image. It returns true if the MIME type string starts with 'image'. ```APIDOC ## isMimeImage ### Description Checks if a given MIME type represents an image. ### Method ```typescript function isMimeImage(mime: string): boolean ``` ### Parameters #### Path Parameters - **mime** (string) - Required - The MIME type string ### Returns `boolean` — True if MIME type starts with "image", false otherwise ### Example ```javascript import { isMimeImage } from "sawit-utils"; isMimeImage("image/png"); // true isMimeImage("image/jpeg"); // true isMimeImage("image/webp"); // true isMimeImage("video/mp4"); // false isMimeImage("text/plain"); // false ``` ``` -------------------------------- ### Perform HTTP requests with sawit-utils Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/README.md Utilize the pre-instantiated api client or create a custom ApiClient for making HTTP requests and registering custom endpoints. ```javascript import { api, ApiClient } from "sawit-utils"; // Use pre-instantiated client const data = await api.request("https://api.example.com/users"); // Use registered endpoints const result = await api.deline("search", { q: "keyword" }); // Create custom client const client = new ApiClient({ timeout: 5000, registry: { custom: "https://custom.api.com/" } }); const custom = await client.custom("endpoint", { param: "value" }); ``` -------------------------------- ### Formatting and Utility Functions Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/README.md Shows how to use functions for number, size, and time formatting, generating greetings, creating unique IDs, and delaying execution. ```javascript import { formatNumber, formatSize, formatTime, greeting, convertMsToDuration, generateUID, delay } from "sawit-utils"; // Format values console.log(formatNumber(1234567)); // "1,234,567" console.log(formatSize(1048576)); // "1.00 MiB" console.log(greeting()); // "Good afternoon" // Generate stable IDs const id = generateUID("user_123"); // "a1b2c3-d4e5f6" // Delay execution await delay(1000); console.log("Done"); ``` -------------------------------- ### Pre-instantiated Client Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/QUICK-REFERENCE.md An instance of ApiClient named 'api' is exported and ready to be used immediately for making requests. ```APIDOC ## Pre-instantiated Client ### Description An instance of `ApiClient` named `api` is exported and ready to be used immediately. ### Usage ```typescript // Import and use the pre-instantiated api client import { api } from 'sawit-utils'; // Example: Make a GET request to a dynamic endpoint api.deline('/some/path', { query: 'param' }) .then(response => { console.log(response); }) .catch(error => { console.error(error); }); ``` ``` -------------------------------- ### Get Medal Emoji by Index Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/format.md Returns a medal emoji based on a zero-based index. Use this to display rankings or awards visually. ```javascript import { medal } from "sawit-utils"; medal(0); // "🥇" medal(1); // "🥈" medal(2); // "🥉" medal(3); // "🏅" medal(10); // "🏅" ``` -------------------------------- ### Syntax check entry file Source: https://github.com/indra87g/sawit-utils/blob/main/AGENTS.md Performs a syntax check on the main entry point file (src/index.js) using Node.js. This is a prerequisite for publishing. ```bash node --check src/index.js ``` -------------------------------- ### getRandomElement Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/index.md Gets a random element from an array. This function is useful for scenarios where a random selection from a list of items is needed, such as in games or simulations. ```APIDOC ## getRandomElement ### Description Gets a random element from an array. Alias for `randomValue()`. ### Signature ```typescript function getRandomElement(array: T[]): T | null ``` ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Parameters Table | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | array | `T[]` | Yes | — | The array to select from | ### Returns `T | null` — Random element, or null if array is empty ### Example ```javascript import { getRandomElement } from "sawit-utils"; const colors = ["red", "green", "blue"]; getRandomElement(colors); // "green" (or another random color) getRandomElement([1, 2, 3]); // 1, 2, or 3 getRandomElement([]); // null ``` ``` -------------------------------- ### Message Parsing (WhatsApp) Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/README.md Extract text from message objects, get sender numbers, parse commands with arguments, and extract @mentions from messages. ```APIDOC ## Message Parsing (WhatsApp) ### Description Utilities for parsing message content, sender information, commands, and mentions. ### Functions - `extractMessageBody(message)`: Extracts the text content from a message object. - `extractNumber(message)`: Extracts the sender's phone number from a message object. - `parseCommand(messageString)`: Parses a string to extract a command and its arguments. - `parseMentions(messageString)`: Extracts all mentioned user IDs from a message string. ### Request Example ```javascript import { extractMessageBody, extractNumber, parseCommand, parseMentions } from "sawit-utils"; // Extract text from message object const text = extractMessageBody(message); // Get sender number const sender = extractNumber(message); // Parse command with arguments const { command, args } = parseCommand("!ban @user spam"); // Extract @mentions const mentioned = parseMentions("Hi @1234567890 and @9876543210"); ``` ``` -------------------------------- ### Watch directories and load modules with sawit-utils Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/README.md Use scanDirectory to load modules from a directory and automatically watch for changes. Loaded modules are indexed in CommandIndex and EventIndex. ```javascript import { scanDirectory, CommandIndex, EventIndex } from "sawit-utils"; // Scan and load all modules from directory await scanDirectory("./commands"); // All modules now indexed console.log("Loaded commands:", CommandIndex.size); console.log("Loaded handlers:", EventIndex.size); // Automatically watches for changes and reloads ``` -------------------------------- ### Get Random Array Element Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/index.md Selects and returns a random element from a given array. If the array is empty, it returns null. This is an alias for `randomValue()`. ```javascript import { getRandomElement } from "sawit-utils"; const colors = ["red", "green", "blue"]; getRandomElement(colors); // "green" (or another random color) getRandomElement([1, 2, 3]); // 1, 2, or 3 getRandomElement([]); // null ``` -------------------------------- ### String Operations with Sawit-Utils Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/README.md Demonstrates finding similar commands, escaping HTML, and detecting code-like text using functions from 'sawit-utils'. ```javascript import { levenshtein, findTopSuggestions, escapeHTML, looksLikeCode } from "sawit-utils"; // Find similar commands const suggestions = findTopSuggestions("hlp", ["help", "hello", "history"]); // ["help", "hello", "history"] // Escape user input for HTML const safe = escapeHTML(""); // Check if text looks like code if (looksLikeCode(userInput)) { // Treat as code } ``` -------------------------------- ### Check if MIME type is audio Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/validation.md Use this function to determine if a MIME type string represents an audio format. It checks if the string starts with 'audio'. ```javascript import { isMimeAudio } from "sawit-utils"; isMimeAudio("audio/mp3"); // true isMimeAudio("audio/wav"); // true isMimeAudio("audio/ogg"); // true isMimeAudio("video/mp4"); // false ``` -------------------------------- ### Running Tests and Generating Coverage Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/README.md Provides the npm commands to execute all tests and generate a code coverage report for the project. ```bash npm test # Run all tests npm run coverage # Generate coverage report ``` -------------------------------- ### Check if MIME type is a video Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/validation.md Use this function to determine if a MIME type string represents a video format. It checks if the string starts with 'video'. ```javascript import { isMimeVideo } from "sawit-utils"; isMimeVideo("video/mp4"); // true isMimeVideo("video/webm"); // true isMimeVideo("image/png"); // false ``` -------------------------------- ### Check if MIME type is an image Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/validation.md Use this function to determine if a MIME type string represents an image format. It checks if the string starts with 'image'. ```javascript import { isMimeImage } from "sawit-utils"; isMimeImage("image/png"); // true isMimeImage("image/jpeg"); // true isMimeImage("image/webp"); // true isMimeImage("video/mp4"); // false isMimeImage("text/plain"); // false ``` -------------------------------- ### Pre-instantiated api Client Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/request.md A pre-instantiated ApiClient ready for immediate use with all built-in endpoints registered. ```APIDOC ## Pre-instantiated api Client ```typescript export const api: ApiClient ``` A pre-instantiated ApiClient ready for immediate use with all built-in endpoints registered. ### Example: ```javascript import { api } from "sawit-utils"; // Use immediately without creating new instance const data = await api.deline("search", { q: "test" }); const result = await api.request("https://example.com/api"); ``` ``` -------------------------------- ### Good TypeScript type definition Source: https://github.com/indra87g/sawit-utils/blob/main/AGENTS.md An example of a well-defined TypeScript type for an exported function. It includes explicit types, JSDoc, and matches actual JavaScript behavior. ```typescript // ✅ GOOD: Explicit types, matches actual JS behavior, exported properly /** * Downloads Instagram Reels video. * @param {string} url - The Instagram Reels URL * @returns {Promise<{data: {videoUrl: string}}>} */ export declare function igdl(url: string): Promise<{ data: { videoUrl: string } }>; ``` -------------------------------- ### ApiClient Constructor Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/request.md Initializes an ApiClient instance. It can be configured with a custom endpoint registry and a request timeout. ```APIDOC ## ApiClient Constructor ### Description Initializes an ApiClient instance. It can be configured with a custom endpoint registry and a request timeout. ### Constructor Signature ```typescript constructor(config?: { registry?: Record, timeout?: number }) ``` ### Parameters #### Config Object - **config** (`object`) - Optional - Client configuration. - **config.registry** (`Record`) - Optional - Extra endpoints to register, merged with defaults. - **config.timeout** (`number`) - Optional - Request timeout in milliseconds. Defaults to `90000` (90 seconds). ### Example ```javascript import { ApiClient } from "sawit-utils"; // Default client with built-in endpoints const client = new ApiClient(); // With custom timeout const slowClient = new ApiClient({ timeout: 5000 }); // With additional endpoints const customClient = new ApiClient({ registry: { myapi: "https://api.example.com/v1/" }, timeout: 3000 }); ``` ``` -------------------------------- ### Get Content-Type Header Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/request.md Fetches only the Content-Type header from a URL using a HEAD request. This is efficient for checking file types without downloading the entire content. ```typescript async getContentType(url: string): Promise ``` -------------------------------- ### Export all utilities from index.js Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/README.md The main entry point re-exports all public functions from each module, including top-level functions. ```javascript export * from "./array.js"; export * from "./format.js"; export * from "./parsing.js"; export * from "./string.js"; export * from "./validation.js"; export * from "./request.js"; export * from "./watcher.js"; // Plus top-level functions export { generateUID, getRandomElement, delay }; ``` -------------------------------- ### findTopSuggestions Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/string.md Finds the top matching commands based on input string similarity using Levenshtein distance. Results are sorted by similarity, with the most similar first. ```APIDOC ## findTopSuggestions ### Description Finds the top matching commands based on input string similarity using Levenshtein distance. Results are sorted by similarity, with the most similar first. ### Function Signature ```typescript function findTopSuggestions(input: string, commands?: string[], limit?: number): string[] ``` ### Parameters #### Path Parameters (Not applicable for this function) #### Query Parameters (Not applicable for this function) #### Request Body (Not applicable for this function) #### Function Parameters - **input** (string) - Required - User input query - **commands** (string[]) - Optional - List of available commands to match against. Defaults to `[]`. - **limit** (number) - Optional - Maximum number of suggestions to return. Defaults to `3`. ### Returns `string[]` - Array of matching commands sorted by similarity. ### Example ```javascript import { findTopSuggestions } from "sawit-utils"; const commands = ["help", "hello", "history", "delete", "serve"]; findTopSuggestions("helo", commands); // ["help", "hello", "history"] findTopSuggestions("dlte", commands, 2); // ["delete"] findTopSuggestions("", commands); // [] (empty input returns empty) findTopSuggestions("serve", commands, 1); // ["serve"] ``` ``` -------------------------------- ### Initialize ApiClient Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/request.md Instantiate the ApiClient with optional configuration for custom endpoints and request timeouts. If no configuration is provided, default endpoints and a 90-second timeout are used. ```typescript constructor(config?: { registry?: Record, timeout?: number }) ``` -------------------------------- ### Bad TypeScript type definition Source: https://github.com/indra87g/sawit-utils/blob/main/AGENTS.md An example of a poorly defined TypeScript type. It uses loose types like 'any' and lacks descriptive JSDoc, not reflecting the function's actual behavior. ```typescript // ❌ BAD: Too loose, no description, doesn't reflect real behavior export declare function igdl(url: any): any; ``` -------------------------------- ### Pre-instantiated ApiClient Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/QUICK-REFERENCE.md Provides a pre-instantiated ApiClient instance named 'api' for immediate use. ```typescript export const api: ApiClient // Ready to use immediately ``` -------------------------------- ### Watch Files & Load Modules Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/START-HERE.md Scan directories for files and load modules, useful for creating plugin systems or hot-reloading features. ```javascript import { scanDirectory, CommandIndex } from "sawit-utils"; await scanDirectory("./commands"); console.log(`Loaded ${CommandIndex.size} commands`); ``` -------------------------------- ### Run vitest tests Source: https://github.com/indra87g/sawit-utils/blob/main/AGENTS.md Executes all unit tests using the vitest test runner. Ensure this command passes before publishing. ```bash npm test ``` -------------------------------- ### ApiClient Configuration with Custom Registry and Timeout Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/README.md Defines the configuration interface for ApiClient and demonstrates its usage with a custom API registry and a specified timeout. ```typescript interface ApiClientConfig { registry?: Record; // Additional endpoints timeout?: number; // Timeout in milliseconds (default: 90000) } const client = new ApiClient({ timeout: 5000, registry: { myapi: "https://api.example.com/" } }); ``` -------------------------------- ### scanDirectory Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/watcher.md Recursively scans a directory for JavaScript files, loads them as modules, and watches for changes. It caches file metadata, dynamically imports modules, indexes them by commands or events, and sets up file watchers for hot-reloading. ```APIDOC ## scanDirectory ### Description Recursively scans a directory for JavaScript files, loads them as modules, and watches for changes. It caches file metadata, dynamically imports modules, indexes them by commands or events, and sets up file watchers for hot-reloading. ### Method Signature ```typescript async function scanDirectory(directory: string): Promise ``` ### Parameters #### Path Parameters - **directory** (`string`) - Required - Path to the directory to scan ### Behavior Details - Recursively scans for .js files. - Caches file metadata (size, modification time). - Dynamically imports each module. - Indexes modules by commands or events. - Sets up file watchers for hot-reloading. - Logs file additions, updates, and deletions to the console. ### Module Loading Details - Imports with cache-busting query parameter (`?update=timestamp`). - Uses `export.default` if available, otherwise uses full module export. - Catches and logs import errors. ### File Watching Details - Debounces file changes with a 500ms delay. - Compares file stats to detect real changes. - Updates indexes when files change. - Supports adding, updating, and deleting files. ### Console Output Examples ``` ➕ Added : ./commands/newcmd.js 🔔 Updated : ./commands/ping.js 🗑️ Deleted : ./handlers/old.js ❌ Failed to load: ./commands/broken.js ``` ### Example Usage ```javascript import { scanDirectory, CommandIndex, EventIndex } from "sawit-utils"; // Initialize by scanning a commands directory await scanDirectory("./commands"); // After scanning, all modules are indexed console.log("Total commands:", CommandIndex.size); console.log("Total event handlers:", EventIndex.size); // Handles hot-reloading automatically // Edit ./commands/help.js → automatically reloaded and re-indexed ``` ### Project Integration Example ```javascript import { scanDirectory } from "sawit-utils"; // In main application startup async function startup() { console.log("Loading command modules..."); await scanDirectory("./src/commands"); console.log("Loading event handlers..."); await scanDirectory("./src/events"); console.log("All modules loaded and watching for changes"); } startup(); ``` ``` -------------------------------- ### Module Loading Error Handling Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/watcher.md Demonstrates how module loading errors are handled. Failed modules are logged with error details but do not halt the scanning process, allowing for fixes and subsequent re-loading. ```javascript ❌ Failed to load: ./commands/broken.js [Error details printed to console] ``` -------------------------------- ### File Watching & Module Loading Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/README.md Scan directories for modules, index them, and automatically watch for file changes. ```APIDOC ## File Watching & Module Loading ### Description Utilities for scanning directories, indexing modules, and automatically watching for file system changes. ### Functions - `scanDirectory(directoryPath)`: Scans a directory and loads all modules within it. ### Indexes - `CommandIndex`: Stores indexed commands. - `EventIndex`: Stores indexed event handlers. ### Common Use Cases ```javascript import { scanDirectory, CommandIndex, EventIndex } from "sawit-utils"; // Scan and load all modules from directory await scanDirectory("./commands"); // All modules now indexed console.log("Loaded commands:", CommandIndex.size); console.log("Loaded handlers:", EventIndex.size); // Automatically watches for changes and reloads ``` ``` -------------------------------- ### Dynamic Endpoint Methods Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/request.md The ApiClient uses a Proxy to allow dynamic endpoint method calls. All these methods follow the same signature: `async method(path?: string, params?: Record, options?: RequestInit): Promise`. ```APIDOC ## Dynamic Endpoint Methods The ApiClient uses a Proxy to allow dynamic endpoint method calls. All these methods follow the same signature: ```typescript async deline(path?: string, params?: Record, options?: RequestInit): Promise async faa(path?: string, params?: Record, options?: RequestInit): Promise async nexray(path?: string, params?: Record, options?: RequestInit): Promise async zenzxz(path?: string, params?: Record, options?: RequestInit): Promise async lexcode(path?: string, params?: Record, options?: RequestInit): Promise async turu(path?: string, params?: Record, options?: RequestInit): Promise async xemoz(path?: string, params?: Record, options?: RequestInit): Promise ``` ### Parameters #### Path Parameters None explicitly defined for dynamic methods, but the `path` parameter serves this purpose. #### Query Parameters - **params** (`Record`) - Optional - Query parameters to be appended to the URL. #### Request Body Not applicable for these dynamic methods. #### Other Options - **path** (`string`) - Optional - API path (appended to base URL). - **options** (`RequestInit`) - Optional - Additional fetch options. ### Returns - **Promise** — Response parsed based on content-type. ### Error Handling - Throws if endpoint is not registered. ### Example: ```javascript import { api } from "sawit-utils"; // Simple endpoint call const result = await api.deline("search", { q: "keyword" }); // With additional fetch options const result = await api.nexray("api/data", {}, { headers: { "Authorization": "Bearer token" } }); // Path with leading slash (automatically handled) const result = await api.zenzxz("/getUser/123"); // Custom registered endpoint api.register("myapi", "https://custom.example.com/"); const data = await api.myapi("endpoint", { param: "value" }); ``` ``` -------------------------------- ### parseCommand Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/parsing.md Parses a command string into its components: prefix, command name, full text, and arguments. It can handle custom prefixes and commands without a prefix. ```APIDOC ## parseCommand Parses a command string into its components: prefix, command name, full text, and arguments. ### Method ```typescript function parseCommand( body: string, setting?: { prefixes?: string[], noPrefix?: boolean } ): { prefix: string, command: string, text: string, args: string[], isHasPrefix: boolean } ``` ### Parameters #### Path Parameters *None* #### Query Parameters *None* #### Request Body *None* #### Parameters - **body** (`string`) - Required - The raw command string to parse - **setting** (`{ prefixes?: string[], noPrefix?: boolean }`) - Optional - Parsing settings. Defaults to `{ prefixes: [], noPrefix: false }`. - **setting.prefixes** (`string[]`) - Optional - List of valid command prefixes (e.g., ["!", "/"]). Defaults to `[]`. - **setting.noPrefix** (`boolean`) - Optional - If true, parse commands without prefix requirement. Defaults to `false`. ### Request Example ```javascript import { parseCommand } from "sawit-utils"; // Command with prefix parseCommand("!help search", { prefixes: ["!", "/"] }); // { prefix: "!", command: "help", text: "search", args: ["search"], isHasPrefix: true } // Command without prefix parseCommand("hello world", { noPrefix: true }); // { prefix: "", command: "hello", text: "world", args: ["world"], isHasPrefix: false } ``` ### Response #### Success Response (200) - **prefix** (`string`) - The detected prefix of the command, or an empty string if no prefix is found or required. - **command** (`string`) - The name of the command. - **text** (`string`) - The full text following the command name. - **args** (`string[]`) - An array of arguments parsed from the `text`. - **isHasPrefix** (`boolean`) - True if the command had a recognized prefix, false otherwise. #### Response Example ```javascript { "prefix": "!", "command": "help", "text": "search", "args": ["search"], "isHasPrefix": true } ``` **Empty Parse Result:** If input is empty or invalid (contains zero-width characters), returns: ```javascript { prefix: "", command: "", text: "", args: [], isHasPrefix: false } ``` ``` -------------------------------- ### Format for Updating Agent Memory Source: https://github.com/indra87g/sawit-utils/blob/main/AGENTS.md Use this markdown format to record new information in `MEMORY.md`. Include the date, a short title, the context of your work, the discovery made, and its impact on the repository. ```markdown ## YYYY-MM-DD — [Short Title] **Context:** [What you were doing] **Finding:** [What you discovered] **Impact:** [Why it matters for this repo] ``` -------------------------------- ### File System Watcher and Module Indexing Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/INDEX.md Utilities for watching file system changes and indexing modules, including caching mechanisms. ```APIDOC ## File System Watcher and Module Indexing ### Description Utilities for file system watching and module indexing. ### Functions - `scanDirectory()`: Scans a directory for files. - `indexModule()`: Indexes a module. ### Exports - `FileCache`: A map storing file metadata. - `ModuleCache`: A map storing loaded modules. - `CommandIndex`: A map associating commands with modules. - `EventIndex`: A set of event handlers. ``` -------------------------------- ### Scan Directory for Modules and Watch for Changes Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/api-reference/watcher.md Recursively scans a directory for JavaScript files, imports them as modules, and sets up file watchers for hot-reloading. Use this to dynamically load and manage command or event handler modules in your application. ```typescript async function scanDirectory(directory: string): Promise ``` -------------------------------- ### IgdlVideo Interface Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/types.md Represents a single video variant with its direct download URL and quality. ```typescript interface IgdlVideo { url: string; quality: string; } ``` -------------------------------- ### Using Type Guards for IGDL Results Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/QUICK-REFERENCE.md Illustrates how to use type guards to differentiate between successful and error results from the IGDL function, ensuring type safety. ```javascript const result = await igdl("https://instagram.com/..."); if (result.success) { console.log(result.data.username); // IgdlSuccessResult } else { console.error(result.error); // IgdlErrorResult } ``` -------------------------------- ### TypeScript Type Imports for IgdlResult Source: https://github.com/indra87g/sawit-utils/blob/main/_autodocs/README.md Illustrates how to import specific TypeScript types for handling Instagram download results from 'sawit-utils'. ```typescript import { IgdlResult, IgdlSuccessResult, IgdlErrorResult, IgdlData, IgdlVideo } from "sawit-utils"; async function download(url: string): Promise { return igdl(url); } ```