{"_id":"@23rdpro/xapi","_rev":"2-89d89eeded9caa9d6a106d49173a8ab7","name":"@23rdpro/xapi","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"@23rdpro/xapi","version":"1.0.0","keywords":[],"author":{"name":"Olumide Bakare"},"license":"ISC","_id":"@23rdpro/xapi@1.0.0","maintainers":[{"name":"23rdpro","email":"mailolumide@gmail.com"}],"homepage":"https://github.com/23rdPro/xapi#readme","bugs":{"url":"https://github.com/23rdPro/xapi/issues"},"bin":{"xapi":"dist/cli.js"},"dist":{"shasum":"9b27b5ff349117257e3731d1f1692d1779628568","tarball":"https://registry.npmjs.org/@23rdpro/xapi/-/xapi-1.0.0.tgz","fileCount":6,"integrity":"sha512-IzFz1HDkwigAhsDLh2XimNndUTo4K2Gpf0sN3Cjg61S8ZtTFdtPvI6ygsZlMR7C7od44dOgthcoMJFmpth1f8A==","signatures":[{"sig":"MEYCIQD5jW+HQGXQDGY1cDpBToXLrE5EBMqe0rycsrrvr3qQuwIhAIxgv2GUguqT+NvjpFIM+p3FaLQ7Q8reQhPTAaOFsbX3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16151308},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","gitHead":"222ce13706e356caf77593988f3c4970c64d01cd","scripts":{"lint":"eslint ./src --ext .ts","test":"vitest run","build":"tsup","format":"prettier --check .","dev:cli":"tsx src/cli.ts","prepare":"husky install","format:fix":"prettier --write .","test:watch":"vitest","xapi:generate":"tsx ./scripts/generate.ts"},"_npmUser":{"name":"23rdpro","email":"mailolumide@gmail.com"},"repository":{"url":"git+https://github.com/23rdPro/xapi.git","type":"git"},"_npmVersion":"10.8.2","description":"Open-source TypeScript SDK for working with the xAPI standard.","directories":{},"lint-staged":{"**/*.{js,ts,tsx}":"eslint --fix"},"_nodeVersion":"20.19.5","dependencies":{"ora":"^9.0.0","axios":"^1.11.0","chalk":"^5.6.2","graphql":"^16.11.0","commander":"^14.0.1","cross-fetch":"^4.1.0","@reduxjs/toolkit":"^2.8.2","@tanstack/react-query":"^5.85.5","@apidevtools/swagger-parser":"^12.0.0"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.14.0","devDependencies":{"tsx":"^4.20.3","zod":"^4.0.17","tsup":"^8.5.0","yaml":"^2.8.1","husky":"^9.1.7","eslint":"^9.32.0","vitest":"^3.2.4","prettier":"^3.6.2","@eslint/js":"^9.32.0","typescript":"^5.9.2","@types/node":"^24.2.0","@types/yaml":"^1.9.7","lint-staged":"^16.1.4","@types/graphql":"^14.5.0","tsconfig-paths":"^4.2.0","typescript-eslint":"^8.39.0","vite-tsconfig-paths":"^5.1.4","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.39.0","json-schema-to-typescript":"^15.0.4","@typescript-eslint/eslint-plugin":"^8.39.0"},"peerDependencies":{"axios":"^1.11.0","@reduxjs/toolkit":"^2.8.2","@tanstack/react-query":"^5.85.5"},"peerDependenciesMeta":{"axios":{"optional":true},"@reduxjs/toolkit":{"optional":true},"@tanstack/react-query":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/xapi_1.0.0_1764246138060_0.6861573113209001","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@23rdpro/xapi","version":"1.0.2","description":"Open-source TypeScript SDK for working with the xAPI standard.","main":"dist/index.js","type":"module","scripts":{"test":"vitest run","test:watch":"vitest","prepare":"husky install","lint":"eslint ./src --ext .ts","format":"prettier --check .","format:fix":"prettier --write .","xapi:generate":"tsx ./scripts/generate.ts","build":"tsup","dev:cli":"tsx src/cli.ts"},"keywords":[],"author":{"name":"Olumide Bakare"},"repository":{"type":"git","url":"git+https://github.com/23rdPro/xapi.git"},"bugs":{"url":"https://github.com/23rdPro/xapi/issues"},"homepage":"https://github.com/23rdPro/xapi#readme","license":"ISC","packageManager":"pnpm@10.14.0","devDependencies":{"@eslint/js":"^9.32.0","@types/graphql":"^14.5.0","@types/node":"^24.2.0","@types/yaml":"^1.9.7","@typescript-eslint/eslint-plugin":"^8.39.0","@typescript-eslint/parser":"^8.39.0","eslint":"^9.32.0","eslint-config-prettier":"^10.1.8","husky":"^9.1.7","json-schema-to-typescript":"^15.0.4","lint-staged":"^16.1.4","prettier":"^3.6.2","tsconfig-paths":"^4.2.0","tsup":"^8.5.0","tsx":"^4.20.3","typescript":"^5.9.2","typescript-eslint":"^8.39.0","vite-tsconfig-paths":"^5.1.4","vitest":"^3.2.4","yaml":"^2.8.1","zod":"^4.0.17"},"lint-staged":{"**/*.{js,ts,tsx}":"eslint --fix"},"dependencies":{"@apidevtools/swagger-parser":"^12.0.0","@reduxjs/toolkit":"^2.8.2","@tanstack/react-query":"^5.85.5","axios":"^1.11.0","chalk":"^5.6.2","commander":"^14.0.1","cross-fetch":"^4.1.0","graphql":"^16.11.0","ora":"^9.0.0"},"types":"dist/index.d.ts","peerDependencies":{"@reduxjs/toolkit":"^2.8.2","@tanstack/react-query":"^5.85.5","axios":"^1.11.0"},"peerDependenciesMeta":{"axios":{"optional":true},"@tanstack/react-query":{"optional":true},"@reduxjs/toolkit":{"optional":true}},"bin":{"xapi":"dist/cli.js"},"_id":"@23rdpro/xapi@1.0.2","gitHead":"76aed202a30882ba78a003a8ae08f676de8d3932","_nodeVersion":"20.19.5","_npmVersion":"10.8.2","dist":{"integrity":"sha512-NOwhBaQFBU/OjQsfgawJt1mOVHwXezEadTmfwua8zC5L5GQOt1TbbFroCazmVwMeLxnGbdbubGC/QwgN8l+b1g==","shasum":"019cdb36577e1b7b08d51f923b0e085dd45f9ba2","tarball":"https://registry.npmjs.org/@23rdpro/xapi/-/xapi-1.0.2.tgz","fileCount":9,"unpackedSize":16170081,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCsBy6NA4fx9f580W9O69hhsEL7QTKF3seJ2a63CsjXIAIgOmfuiSdnb+r0eONnaxIT/MaL7TLndjbxPre4KPUkQrY="}]},"_npmUser":{"name":"23rdpro","email":"mailolumide@gmail.com"},"directories":{},"maintainers":[{"name":"23rdpro","email":"mailolumide@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/xapi_1.0.2_1764247879040_0.8418175434617343"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-27T12:22:17.966Z","modified":"2025-11-27T12:51:19.457Z","1.0.0":"2025-11-27T12:22:18.351Z","1.0.2":"2025-11-27T12:51:19.287Z"},"bugs":{"url":"https://github.com/23rdPro/xapi/issues"},"author":{"name":"Olumide Bakare"},"license":"ISC","homepage":"https://github.com/23rdPro/xapi#readme","keywords":[],"repository":{"type":"git","url":"git+https://github.com/23rdPro/xapi.git"},"description":"Open-source TypeScript SDK for working with the xAPI standard.","maintainers":[{"name":"23rdpro","email":"mailolumide@gmail.com"}],"readme":"# xAPI — Type-Safe API Client Generator\n\n> Generate strongly-typed REST and GraphQL API clients from OpenAPI and GraphQL schemas.\n\n## 📋 Project Overview\n\n**xAPI** is a TypeScript SDK for generating type-safe API clients from OpenAPI and GraphQL schemas. It uses a **plugin-based architecture** that produces strongly-typed clients for:\n\n- **REST APIs** → `fetch`, `axios`, `RTK Query`, `TanStack Query`\n- **GraphQL APIs** → Operations-based clients with subscription support\n\n## 📖 Quick Start\n\n### Installation\n\n```bash\nnpm install @23rdpro/xapi\n# or\npnpm add @23rdpro/xapi\n```\n\n### Basic Usage (CLI)\n\nGenerate a fetch client from an OpenAPI spec:\n\n```bash\nxapi generate ./openapi.yaml fetch --zod --out src/generated\n```\n\nCreate a config file:\n\n```bash\nxapi init\nxapi generate\n```\n\n### Usage Examples\n\n#### Programmatic Examples\n\nSee **[`examples.js`](./examples.js)** for comprehensive examples demonstrating:\n\n- ✅ Generating fetch, axios, RTK, and TanStack clients\n- ✅ Working with GraphQL schemas and subscriptions\n- ✅ Using Zod validators for runtime validation\n- ✅ Programmatic API for integration\n- ✅ Custom naming prefixes\n\n**Run programmatic examples:**\n\n```bash\nnode examples.js\n```\n\nThis generates sample clients from the included Petstore fixtures.\n\n#### CLI Examples\n\nSee **[`cli-examples.js`](./cli-examples.js)** for real-world CLI command examples demonstrating:\n\n- ✅ Installation via npm/pnpm\n- ✅ Generating clients for different HTTP libraries\n- ✅ Configuration file setup\n- ✅ Common workflows and patterns\n- ✅ CI/CD integration\n- ✅ Using generated clients in applications\n\n**Run CLI examples:**\n\n```bash\nnode cli-examples.js\n```\n\nThis will execute actual `xapi generate` commands and show you the workflows.\n\n## 🏗️ Architecture\n\n### Core Flow: Plugin System\n\n```\nCLI / Script\n    ↓\nPlugin Registry\n    ↓\nSchema Detection\n    ↓\nPlugin.run()\n├─ REST Plugin (YAML/JSON)\n└─ GraphQL Plugin (.graphql)\n```\n\n### Key Files\n\n| File | Purpose |\n|------|---------|\n| `src/core/pluginSystem.ts` | Registers plugins, matches schema type by extension |\n| `src/plugins/{rest,graphql,generate}.ts` | Plugin execution logic |\n| `src/cli.ts` | Command parsing (generate, init, doctor) |\n\n### Pipeline for Each Schema Type\n\n#### REST / OpenAPI Path\n\n1. **Load** → `loaders/openapi.ts` — Fetch from file or URL\n2. **Parse** → `parsers/openapi.ts` using `@apidevtools/swagger-parser`\n3. **Normalize** → `normalizers/openapi.ts` → produces uniform `Endpoint[]`\n4. **Generate** → `generators/{typescript,client}.ts`\n\n#### GraphQL Path\n\n1. **Load** → `loaders/graphql.ts` — Support `.graphql` SDL or `.json` introspection\n2. **Parse** → `parsers/graphql.ts` builds GraphQL schema\n3. **Normalize** → `normalizers/graphql.ts` → `GraphQLEndpoint[]`\n4. **Generate** → Same generators as REST (polymorphic)\n\n### HTTP Client Variants\n\nThe generator switches logic based on the CLI/config:\n\n```typescript\n// Supported clients\ntype HttpLibrary = \"fetch\" | \"axios\" | \"rtk\" | \"tanstack\";\n```\n\n- **`fetch`** (default) — Native browser/Node API\n- **`axios`** — Popular HTTP client\n- **`rtk`** — Redux Toolkit Query\n- **`tanstack`** — React Query\n\nSee: `src/generators/client.ts`\n\n## 📦 Critical Data Types\n\n### REST Endpoint\n\n```typescript\ntype Endpoint = {\n  id: string;\n  name: string;\n  method: HttpMethod; // \"get\" | \"post\" | \"put\" | \"patch\" | \"delete\" ...\n  path: string; // e.g., \"/pets/{id}\"\n  params: Param[];\n  requestBody?: Body;\n  responses: Response[];\n};\n```\n\n### GraphQL Endpoint\n\n```typescript\ntype GraphQLEndpoint = {\n  operationType: \"query\" | \"mutation\" | \"subscription\";\n  operationName: string;\n  requestSchema?: any;\n  responseSchema?: any;\n  graphql: { kind, field };\n};\n```\n\n## ⚙️ Configuration & Entry Points\n\n### Optional Config File: `xapi.config.json`\n\n```json\n{\n  \"schema\": \"./openapi.yaml\",\n  \"outDir\": \"src/generated\",\n  \"baseUrl\": \"https://api.example.com\",\n  \"httpLibrary\": \"fetch\",\n  \"zod\": true\n}\n```\n\n### CLI Commands\n\n| Command | Description |\n|---------|-------------|\n| `xapi generate [schema] [client]` | Main codegen (supports `--zod`, `--base-url`, `--out`) |\n| `xapi init` | Create config file interactively |\n| `xapi doctor [schema]` | Validate schema and configuration |\n\n### Development Scripts\n\n```bash\npnpm xapi:generate       # Run code generation\npnpm dev:cli             # Test CLI locally with tsx\npnpm test                # Run tests (Vitest)\npnpm lint                # ESLint check\npnpm build               # Build for distribution\n```\n\n## 🧪 Testing Strategy\n\n### Framework & Setup\n\n- **Test Runner** → `Vitest`\n- **Path Resolution** → `vite-tsconfig-paths` (uses `tsconfig.json` aliases)\n\n### Test Layout\n\n```\ntests/\n├── generators/\n│   ├── client.test.ts       ← REST & GraphQL client generation\n│   └── typescript.test.ts   ← Type & Zod schema generation\n├── parsers/\n│   └── openapi.test.ts      ← Schema dereferencing\n├── normalizers/\n│   └── openapi.test.ts      ← Endpoint normalization\n├── loaders/\n│   └── openapi.test.ts      ← File/URL loading\n├── fixtures/\n│   ├── petstore.yaml        ← Sample OpenAPI spec\n│   ├── petstore.json        ← Sample OpenAPI (JSON)\n│   └── petstore.graphql     ← Sample GraphQL schema\n└── utils/\n    └── file.test.ts         ← Utility functions\n```\n\n### Important Test Files\n\n- **`client.test.ts`** — Verifies fetch, axios, RTK, TanStack variant output\n- **`typescript.test.ts`** — Type & Zod schema generation\n- **`openapi.test.ts`** — Schema dereferencing & validation\n- **`openapi.normalizer.test.ts`** — Endpoint mapping correctness\n\n## 🎯 Common Patterns\n\n### 1. Options Threading\n\nOptions flow through the pipeline via a single `ClientGenOptions` interface:\n\n```typescript\ninterface ClientGenOptions {\n  outputPath?: string;\n  httpLibrary?: \"fetch\" | \"axios\" | \"rtk\" | \"tanstack\";\n  baseUrl?: string;\n  zod?: boolean;\n  wsUrl?: string;           // GraphQL subscriptions\n  prefix?: string;          // Type name prefix\n}\n```\n\n### 2. Naming Conventions\n\n- **Functions** → `camelCase` (e.g., `getPet`, `updateUser`)\n- **Types** → `PascalCase` + suffix (e.g., `GetPetParams`, `GetPetResponse`)\n- **Zod schemas** → `${TypeName}Schema` with inferred type: `${TypeName}Parsed`\n\n### 3. Schema Handling\n\n- Use `stableStringify()` for schema deduplication via content hashing\n- Use `jsonSchemaToTS()` for complex JSON schemas\n- Fall back to `simpleSchemaToTS()` for simple types\n\n### 4. Error Handling\n\n```typescript\n// Missing dependency\nthrow new MissingDependencyError(\"axios\", \"@reduxjs/toolkit\");\n\n// CLI feedback\nconsole.log(chalk.green(\"✅ Success\"));\n\n// Async operations with spinner\nawait withSpinner(\"Generating types...\", async () => {\n  // work here\n});\n```\n\n## 🔧 Development Workflow\n\n1. **Run tests first** to establish baseline\n   ```bash\n   pnpm test\n   ```\n\n2. **Update generator logic** (handle both REST and GraphQL paths if needed)\n   - Edit `src/generators/` or `src/plugins/`\n\n3. **Add test fixtures** if testing new schema patterns\n   - Place in `tests/fixtures/`\n\n4. **Ensure type safety** — use import aliases, not relative paths\n\n5. **Build & test CLI manually**\n   ```bash\n   pnpm build\n   pnpm dev:cli -- ./tests/fixtures/petstore.yaml fetch\n   ```\n\n## 📍 Import Path Aliases\n\n**Always use import aliases**, configured in `tsconfig.json`:\n\n✅ **Correct:**\n```typescript\nimport { normalize } from \"normalizers/openapi\";\nimport { Endpoint } from \"types/endpoint\";\nimport { withSpinner } from \"utils/spinner\";\n```\n\n❌ **Avoid:**\n```typescript\nimport { normalize } from \"../normalizers/openapi\";\nimport { Endpoint } from \"../../types/endpoint\";\n```\n\n## 📦 Key Dependencies\n\n| Package | Purpose |\n|---------|---------|\n| `@apidevtools/swagger-parser` | OpenAPI validation & dereferencing |\n| `graphql` | GraphQL schema parsing & introspection |\n| `zod` | Runtime validation schemas (optional) |\n| `commander` | CLI argument parsing |\n| `chalk` | Terminal colors |\n| `ora` | CLI spinners |\n| `vitest` | Test runner |\n\n---\n\n> **Last Updated:** November 26, 2025  \n> **Maintained by:** xAPI Team\n","readmeFilename":"README.md"}