{"id":50751568,"url":"https://github.com/oharu121/axios-fluent","last_synced_at":"2026-06-11T01:31:34.191Z","repository":{"id":323029780,"uuid":"1091843790","full_name":"oharu121/axios-fluent","owner":"oharu121","description":"A fluent, type-safe HTTP client wrapper around Axios with method chaining","archived":false,"fork":false,"pushed_at":"2026-06-08T18:06:00.000Z","size":357,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-08T20:07:31.554Z","etag":null,"topics":["api","axios","builder","http","rest"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/axios-fluent","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oharu121.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-07T15:50:03.000Z","updated_at":"2026-06-08T18:05:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/oharu121/axios-fluent","commit_stats":null,"previous_names":["oharu121/axios-fluent"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/oharu121/axios-fluent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oharu121%2Faxios-fluent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oharu121%2Faxios-fluent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oharu121%2Faxios-fluent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oharu121%2Faxios-fluent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oharu121","download_url":"https://codeload.github.com/oharu121/axios-fluent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oharu121%2Faxios-fluent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34178819,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","axios","builder","http","rest"],"created_at":"2026-06-11T01:31:33.347Z","updated_at":"2026-06-11T01:31:34.179Z","avatar_url":"https://github.com/oharu121.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# axios-fluent\n\n[![npm version](https://badge.fury.io/js/axios-fluent.svg)](https://badge.fury.io/js/axios-fluent)\n![License](https://img.shields.io/npm/l/axios-fluent)\n![Types](https://img.shields.io/npm/types/axios-fluent)\n![NPM Downloads](https://img.shields.io/npm/dw/axios-fluent)\n![Last Commit](https://img.shields.io/github/last-commit/oharu121/axios-fluent)\n![Coverage](https://codecov.io/gh/oharu121/axios-fluent/branch/main/graph/badge.svg)\n![CI Status](https://github.com/oharu121/axios-fluent/actions/workflows/ci.yml/badge.svg)\n![GitHub Stars](https://img.shields.io/github/stars/oharu121/axios-fluent?style=social)\n\nA fluent, type-safe HTTP client wrapper around Axios with method chaining.\n\n## Features\n\n- Fluent, chainable API for building HTTP requests\n- Full TypeScript support with generic typing\n- Immutable configuration pattern\n- All HTTP methods (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)\n- **Convenient response extraction** - `.data()`, `.status()`, `.headers()`, `.ok()` methods\n- **Enhanced error handling** - Clear, structured error information with `AxonError`\n- Built-in authentication helpers (Bearer, Basic)\n- Content-Type helpers\n- Request/response transformers\n- Secure by default (HTTPS certificate validation enabled)\n\n## Installation\n\n```bash\nnpm install axios-fluent\n```\n\n## Importing\n\n```typescript\n// Default export (recommended)\nimport Axon from \"axios-fluent\";\n\n// Named export (alternative)\nimport { Axon } from \"axios-fluent\";\n\n// With error class\nimport Axon, { AxonError } from \"axios-fluent\";\n```\n\n## Quick Start\n\n```typescript\nimport Axon from \"axios-fluent\";\n\n// Create a client\nconst client = Axon.new();\n\n// Make a simple GET request (backward compatible)\nconst response = await client.get(\"https://api.example.com/users\");\nconsole.log(response.data);\n\n// Or use .data() for cleaner code (new!)\nconst users = await client.get\u003cUser[]\u003e(\"https://api.example.com/users\").data();\n\n// Chain configuration methods\nconst users = await client\n  .baseUrl(\"https://api.example.com\")\n  .bearer(\"your-jwt-token\")\n  .json()\n  .timeout(5000)\n  .get\u003cUser[]\u003e(\"/users\")\n  .data(); // Extract data directly!\n```\n\n## API Reference\n\n### Factory Methods\n\n#### `Axon.new(options?: Options): Axon`\n\nCreates a new Axon instance.\n\n**Options:**\n\n- `allowInsecure?: boolean` - Allow self-signed certificates (default: `false`)\n\n```typescript\n// Secure by default (production)\nconst client = Axon.new();\n\n// Allow self-signed certificates (development only)\nconst devClient = Axon.new({ allowInsecure: true });\n```\n\n#### `Axon.dev(): Axon`\n\nCreates a new Axon instance for development with `allowInsecure: true` enabled by default.\n\n```typescript\n// Quick development setup - allows self-signed certificates\nconst client = Axon.dev();\n\n// Equivalent to:\nconst client = Axon.new({ allowInsecure: true });\n```\n\n**⚠️ Warning:** Only use in development/testing environments. This disables SSL certificate verification.\n\n### HTTP Methods\n\nAll HTTP methods return an `AxonResponse` wrapper that:\n- Is awaitable (backward compatible - returns full `AxiosResponse`)\n- Provides convenient methods: `.data()`, `.status()`, `.headers()`, `.ok()`\n- Supports full TypeScript generic typing\n\n#### `get\u003cT\u003e(url: string): AxonResponse\u003cT\u003e`\n\n```typescript\ninterface User {\n  id: number;\n  name: string;\n}\n\n// Backward compatible - get full response\nconst response = await client.get\u003cUser\u003e(\"/api/user/123\");\nconsole.log(response.data.name); // Type-safe access\n\n// New - get data directly (recommended)\nconst user = await client.get\u003cUser\u003e(\"/api/user/123\").data();\nconsole.log(user.name); // Cleaner code!\n\n// Get just the status code\nconst status = await client.get(\"/api/user/123\").status(); // 200\n\n// Check if request succeeded\nconst isOk = await client.get(\"/api/user/123\").ok(); // true\n```\n\n#### `post\u003cT\u003e(url: string, payload?: any): Promise\u003cAxiosResponse\u003cT\u003e\u003e`\n\n```typescript\nconst newUser = { name: \"John Doe\", email: \"john@example.com\" };\nconst response = await client.post\u003cUser\u003e(\"/api/users\", newUser);\n```\n\n#### `put\u003cT\u003e(url: string, payload?: any): Promise\u003cAxiosResponse\u003cT\u003e\u003e`\n\n```typescript\nconst updates = { name: \"Jane Doe\" };\nawait client.put(\"/api/user/123\", updates);\n```\n\n#### `patch\u003cT\u003e(url: string, payload?: any): Promise\u003cAxiosResponse\u003cT\u003e\u003e`\n\n```typescript\nawait client.patch(\"/api/user/123\", { email: \"new@example.com\" });\n```\n\n#### `delete\u003cT\u003e(url: string, payload?: any): Promise\u003cAxiosResponse\u003cT\u003e\u003e`\n\n```typescript\nawait client.delete(\"/api/user/123\");\n```\n\n#### `head\u003cT\u003e(url: string): Promise\u003cAxiosResponse\u003cT\u003e\u003e`\n\n```typescript\nconst response = await client.head(\"/api/resource\");\nconsole.log(response.headers);\n```\n\n#### `options\u003cT\u003e(url: string): Promise\u003cAxiosResponse\u003cT\u003e\u003e`\n\n```typescript\nconst response = await client.options(\"/api/resource\");\n```\n\n### Response Convenience Methods\n\nAll HTTP methods return an `AxonResponse` wrapper with these convenient methods:\n\n#### `.data(): Promise\u003cT\u003e`\n\nExtracts only the response data, discarding status, headers, etc.\n\n```typescript\n// Instead of:\nconst response = await client.get\u003cUser[]\u003e('/users');\nconst users = response.data;\n\n// You can now do:\nconst users = await client.get\u003cUser[]\u003e('/users').data();\n```\n\n#### `.status(): Promise\u003cnumber\u003e`\n\nExtracts only the HTTP status code.\n\n```typescript\nconst statusCode = await client.get('/users').status();\nconsole.log(statusCode); // 200\n```\n\n#### `.headers(): Promise\u003cany\u003e`\n\nExtracts only the response headers.\n\n```typescript\nconst headers = await client.get('/users').headers();\nconsole.log(headers['content-type']);\n```\n\n#### `.ok(): Promise\u003cboolean\u003e`\n\nChecks if the response status is in the 2xx range (success).\n\n```typescript\nconst isSuccessful = await client.delete('/users/123').ok();\nif (isSuccessful) {\n  console.log('User deleted successfully');\n}\n```\n\n### Enhanced Error Handling\n\nErrors are automatically wrapped in `AxonError` with 5 essential properties for debugging:\n\n```typescript\nimport Axon, { AxonError } from 'axios-fluent';\n\ntry {\n  await client.get('/api/users').data();\n} catch (error) {\n  if (error instanceof AxonError) {\n    // 5 essential properties for error handling\n    console.log('Status:', error.status);           // 404\n    console.log('Status Text:', error.statusText);  // 'Not Found'\n    console.log('URL:', error.url);                 // '/api/users'\n    console.log('Method:', error.method);           // 'GET'\n    console.log('Response:', error.responseData);   // Error body\n\n    // Formatted error message\n    console.log(error.toString());\n    // AxonError: Request failed with status code 404\n    //   Request: GET /api/users\n    //   Status: 404 Not Found\n    //   Response: {\"message\":\"Users not found\"}\n  }\n}\n```\n\n**AxonError Properties:**\n- `status` - HTTP status code (404, 500, etc.)\n- `statusText` - Human-readable status text\n- `url` - Request URL\n- `method` - HTTP method (GET, POST, etc.)\n- `responseData` - Error response body\n\n### Configuration Methods\n\nAll configuration methods return a new Axon instance, making them chainable.\n\n#### `baseUrl(url: string): Axon`\n\nSets the base URL for all requests.\n\n```typescript\nconst client = Axon.new().baseUrl(\"https://api.example.com\");\nawait client.get(\"/users\"); // Requests https://api.example.com/users\n```\n\n#### `timeout(ms: number): Axon`\n\nSets request timeout in milliseconds.\n\n```typescript\nconst client = Axon.new().timeout(5000); // 5 second timeout\n```\n\n### Authentication\n\n#### `bearer(token: string): Axon`\n\nSets Bearer token authentication.\n\n```typescript\nconst client = Axon.new().bearer(\"your-jwt-token\").get(\"/api/protected\");\n```\n\n#### `basic(token: string): Axon`\n\nSets Basic authentication.\n\n```typescript\nconst credentials = btoa(\"username:password\");\nconst client = Axon.new().basic(credentials);\n```\n\n### Headers\n\n#### `setHeader(key: string, value: string): Axon`\n\nSets a custom header.\n\n```typescript\nconst client = Axon.new()\n  .setHeader(\"X-API-Key\", \"secret\")\n  .setHeader(\"X-Custom-Header\", \"value\");\n```\n\n### Content-Type Helpers\n\n#### `json(): Axon`\n\nSets `Content-Type: application/json`.\n\n```typescript\nconst client = Axon.new().json();\n```\n\n#### `multipart(): Axon`\n\nSets `Content-Type: multipart/form-data`.\n\n```typescript\nconst formData = new FormData();\nformData.append(\"file\", fileBlob);\n\nconst client = Axon.new().multipart();\nawait client.post(\"/upload\", formData);\n```\n\n#### `encodeUrl(): Axon`\n\nSets `Content-Type: application/x-www-form-urlencoded`.\n\n```typescript\nconst client = Axon.new().encodeUrl();\n```\n\n#### `octet(): Axon`\n\nSets `Content-Type: application/octet-stream`.\n\n```typescript\nconst client = Axon.new().octet();\n```\n\n### Query Parameters\n\n#### `params(params: object): Axon`\n\nSets query parameters.\n\n```typescript\nconst client = Axon.new().params({ page: 1, limit: 10 });\nawait client.get(\"/api/users\"); // Requests /api/users?page=1\u0026limit=10\n```\n\n### Advanced Configuration\n\n#### `length(contentLength: number): Axon`\n\nSets the `Content-Length` header.\n\n```typescript\nconst client = Axon.new().length(1024);\n```\n\n#### `digest(digest: string): Axon`\n\nSets the `Digest` header for content integrity.\n\n```typescript\nconst client = Axon.new().digest(\"sha256-hash\");\n```\n\n#### `range(offset: number, end: number, fileSize: number): Axon`\n\nSets the `Content-Range` header for partial uploads.\n\n```typescript\nconst client = Axon.new().range(0, 1024, 10240);\n```\n\n#### `transformRequest(transformers: AxiosRequestTransformer | AxiosRequestTransformer[]): Axon`\n\nSets custom request transformers.\n\n```typescript\nconst client = Axon.new().transformRequest((data, headers) =\u003e {\n  // Transform request data\n  return data;\n});\n```\n\n#### `responseType(responseType: ResponseType): Axon`\n\nSets the expected response type.\n\n```typescript\nconst client = Axon.new().responseType(\"blob\");\nconst response = await client.get(\"/download/file.pdf\");\n```\n\n## Examples\n\n### Basic API Client\n\n```typescript\nimport Axon from \"axios-fluent\";\n\nconst api = Axon.new()\n  .baseUrl(\"https://api.example.com\")\n  .bearer(\"your-jwt-token\")\n  .json()\n  .timeout(10000);\n\n// Fetch users - using .data() for cleaner code\nconst users = await api.get\u003cUser[]\u003e(\"/users\").data();\n\n// Create a new user\nconst newUser = await api.post\u003cUser\u003e(\"/users\", {\n  name: \"John Doe\",\n  email: \"john@example.com\",\n}).data();\n\n// Update user\nawait api.put(`/users/${newUser.id}`, {\n  name: \"Jane Doe\",\n});\n\n// Delete user and check if successful\nconst deleted = await api.delete(`/users/${newUser.id}`).ok();\nconsole.log('Deleted:', deleted);\n```\n\n### File Upload\n\n```typescript\nimport Axon from \"axios-fluent\";\nimport FormData from \"form-data\";\n\nconst formData = new FormData();\nformData.append(\"file\", fileBlob);\nformData.append(\"name\", \"document.pdf\");\n\nconst response = await Axon.new()\n  .baseUrl(\"https://api.example.com\")\n  .bearer(\"token\")\n  .multipart()\n  .post(\"/upload\", formData);\n```\n\n### Download File\n\n```typescript\nimport Axon from \"axios-fluent\";\nimport fs from \"fs\";\n\nconst response = await Axon.new()\n  .responseType(\"blob\")\n  .get(\"https://example.com/file.pdf\");\n\nfs.writeFileSync(\"file.pdf\", response.data);\n```\n\n### Error Handling\n\n```typescript\nimport Axon, { AxonError } from \"axios-fluent\";\n\ntry {\n  const users = await Axon.new()\n    .bearer(\"token\")\n    .get(\"https://api.example.com/users\")\n    .data();\n\n  console.log(users);\n} catch (error) {\n  // AxonError provides convenient access to error details\n  if (error instanceof AxonError) {\n    console.error(\"Status:\", error.status);        // 404\n    console.error(\"URL:\", error.url);              // https://api.example.com/users\n    console.error(\"Method:\", error.method);        // GET\n    console.error(\"Response:\", error.responseData);// Error body\n\n    // Formatted error message with all details\n    console.error(error.toString());\n\n    // Handle specific status codes\n    if (error.status === 401) {\n      console.log(\"Unauthorized - refresh token\");\n    } else if (error.status \u003e= 500) {\n      console.log(\"Server error - retry later\");\n    }\n  }\n}\n```\n\n### Pagination\n\n```typescript\nimport Axon from \"axios-fluent\";\n\nasync function fetchAllUsers() {\n  const client = Axon.new().baseUrl(\"https://api.example.com\").bearer(\"token\");\n\n  let page = 1;\n  let allUsers = [];\n\n  while (true) {\n    // Use .data() for cleaner code\n    const response = await client\n      .params({ page, limit: 100 })\n      .get\u003c{ users: User[]; hasMore: boolean }\u003e(\"/users\")\n      .data();\n\n    allUsers.push(...response.users);\n\n    if (!response.hasMore) break;\n    page++;\n  }\n\n  return allUsers;\n}\n```\n\n## Security\n\n### HTTPS Certificate Validation\n\nBy default, Axon validates HTTPS certificates. This is the recommended behavior for production environments.\n\n```typescript\n// Secure by default\nconst client = Axon.new();\n```\n\n### Self-Signed Certificates (Development Only)\n\nFor development or testing environments with self-signed certificates, use the `dev()` factory method:\n\n```typescript\n// Development only - NOT for production\nconst devClient = Axon.dev();\n\n// Or use the explicit option\nconst devClient = Axon.new({ allowInsecure: true });\n```\n\nThis disables SSL certificate verification and makes your application vulnerable to man-in-the-middle attacks.\n\n## TypeScript\n\nAxon is written in TypeScript and provides full type definitions.\n\n```typescript\ninterface ApiResponse\u003cT\u003e {\n  data: T;\n  message: string;\n}\n\ninterface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\nconst response = await Axon.new().get\u003cApiResponse\u003cUser\u003e\u003e(\"/api/user/123\");\n\n// Fully typed response\nconsole.log(response.data.data.name); // TypeScript knows the shape\n```\n\n## License\n\nMIT\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a pull request.\n\n## Support\n\nIf you encounter any issues, please file a bug report on the GitHub repository.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foharu121%2Faxios-fluent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foharu121%2Faxios-fluent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foharu121%2Faxios-fluent/lists"}