diff --git a/README.md b/README.md index b2e24bd..c32c4ca 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,37 @@ # Nx Plugin OpenAPI -A powerful Nx plugin ecosystem for generating API client code from OpenAPI specifications. This monorepo provides a flexible, plugin-based architecture that supports multiple code generators. +Generate API clients from OpenAPI specs in your Nx workspace. Pluggable architecture -- choose the generator that fits your stack. ## Packages -| Package | Description | npm | -|---------|-------------|-----| -| [`@nx-plugin-openapi/core`](./packages/core/README.md) | Core plugin system with executor and generators | [![npm](https://img.shields.io/npm/v/@nx-plugin-openapi/core.svg)](https://www.npmjs.com/package/@nx-plugin-openapi/core) | -| [`@nx-plugin-openapi/plugin-openapi`](./packages/plugin-openapi/README.md) | Plugin for [OpenAPI Generator](https://openapi-generator.tech) | [![npm](https://img.shields.io/npm/v/@nx-plugin-openapi/plugin-openapi.svg)](https://www.npmjs.com/package/@nx-plugin-openapi/plugin-openapi) | -| [`@nx-plugin-openapi/plugin-hey-api`](./packages/plugin-hey-api/README.md) | Plugin for [hey-api/openapi-ts](https://github.com/hey-api/openapi-ts) | [![npm](https://img.shields.io/npm/v/@nx-plugin-openapi/plugin-hey-api.svg)](https://www.npmjs.com/package/@nx-plugin-openapi/plugin-hey-api) | -| [`@lambda-solutions/nx-plugin-openapi`](./packages/nx-plugin-openapi/README.md) | Legacy package (OpenAPI Generator only) | [![npm](https://img.shields.io/npm/v/@lambda-solutions/nx-plugin-openapi.svg)](https://www.npmjs.com/package/@lambda-solutions/nx-plugin-openapi) | - -## Architecture - -``` -┌─────────────────────────────────────────────────────────────┐ -│ @nx-plugin-openapi/core │ -│ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐ │ -│ │ generate-api │ │ Plugin Loader │ │ Auto Install │ │ -│ │ executor │ │ │ │ │ │ -│ └─────────────────┘ └─────────────────┘ └──────────────┘ │ -└─────────────────────────────────────────────────────────────┘ - │ - ┌───────────────────┴───────────────────┐ - ▼ ▼ -┌────────────────────────┐ ┌────────────────────────┐ -│ @nx-plugin-openapi/ │ │ @nx-plugin-openapi/ │ -│ plugin-openapi │ │ plugin-hey-api │ -│ │ │ │ -│ Uses @openapitools/ │ │ Uses @hey-api/ │ -│ openapi-generator-cli │ │ openapi-ts │ -└────────────────────────┘ └────────────────────────┘ -``` +| Package | Description | +|---------|-------------| +| [`@nx-plugin-openapi/core`](./packages/core/README.md) | Core executor and plugin system | +| [`@nx-plugin-openapi/plugin-openapi`](./packages/plugin-openapi/README.md) | [OpenAPI Generator](https://openapi-generator.tech) -- 50+ languages, Angular services | +| [`@nx-plugin-openapi/plugin-hey-api`](./packages/plugin-hey-api/README.md) | [hey-api](https://heyapi.dev/) -- modern TypeScript, fetch/axios, tree-shakeable | ## Quick Start -### Installation +**1. Install core + a generator plugin** ```bash -# Install the core package nx add @nx-plugin-openapi/core -# Install a generator plugin (choose one or both) -npm install --save-dev @nx-plugin-openapi/plugin-openapi # For OpenAPI Generator -npm install --save-dev @nx-plugin-openapi/plugin-hey-api # For hey-api +# Pick one (or both): +npm install -D @nx-plugin-openapi/plugin-openapi @openapitools/openapi-generator-cli +npm install -D @nx-plugin-openapi/plugin-hey-api @hey-api/openapi-ts ``` -### Basic Usage - -Execute the following command: +**2. Add a target** (interactive) ```bash nx g @nx-plugin-openapi/core:add-generate-api-target ``` -This will add a `generate-api` target to your `project.json`: +Or add it manually to `project.json`: -```json +```jsonc +// OpenAPI Generator { "targets": { "generate-api": { @@ -71,9 +46,8 @@ This will add a `generate-api` target to your `project.json`: } ``` -Or use the `hey-api` generator: - -```json +```jsonc +// hey-api { "targets": { "generate-api": { @@ -88,48 +62,26 @@ Or use the `hey-api` generator: } ``` -### Run the generator +**3. Generate** ```bash nx run my-app:generate-api ``` -## Documentation - -For comprehensive documentation, visit our [documentation site](https://nx-plugin-openapi.lambda-solutions.io/). +## Why this plugin? -- [Getting Started](https://berger-engineering-io.github.io/nx-plugin-openapi/getting-started/overview/) -- [Installation Guide](https://berger-engineering-io.github.io/nx-plugin-openapi/getting-started/installation/) -- [Plugins Overview](https://berger-engineering-io.github.io/nx-plugin-openapi/plugins/overview/) -- [Configuration Reference](https://berger-engineering-io.github.io/nx-plugin-openapi/usage/configuration/) -- [Creating Custom Plugins](https://berger-engineering-io.github.io/nx-plugin-openapi/guides/creating-plugins/) -- [Examples](https://berger-engineering-io.github.io/nx-plugin-openapi/usage/examples/) +- **Nx-native** -- caching, affected commands, dependency graph, Nx Cloud +- **Pluggable** -- swap generators without changing your workflow +- **Multiple specs** -- generate from several OpenAPI files in one target +- **Auto-install** -- missing plugins are installed on first run -## Features - -- **Plugin Architecture**: Choose between multiple code generators -- **Auto-Installation**: Plugins are automatically installed when needed -- **Nx Integration**: Full support for Nx caching, affected commands, and dependency graph -- **Multiple Specs**: Generate code from multiple OpenAPI specifications in a single target -- **Flexible Configuration**: Pass generator-specific options via `generatorOptions` - -## Available Generators - -### `openapi-tools` (via `@nx-plugin-openapi/plugin-openapi`) - -Uses the battle-tested [OpenAPI Generator](https://openapi-generator.tech) to generate TypeScript Angular clients and more. - -**Peer dependency**: `@openapitools/openapi-generator-cli` - -### `hey-api` (via `@nx-plugin-openapi/plugin-hey-api`) - -Uses [hey-api/openapi-ts](https://github.com/hey-api/openapi-ts) for modern TypeScript client generation with excellent type safety. +## Documentation -**Peer dependency**: `@hey-api/openapi-ts` +Full docs: [berger-engineering-io.github.io/nx-plugin-openapi](https://berger-engineering-io.github.io/nx-plugin-openapi/) -## Contributing +## Legacy package -Contributions are welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines. +The original `@lambda-solutions/nx-plugin-openapi` is still maintained for backward compatibility. See [migration guide](./packages/nx-plugin-openapi/README.md). ## License diff --git a/apps/docs/astro.config.mjs b/apps/docs/astro.config.mjs index 92f8fd5..839643f 100644 --- a/apps/docs/astro.config.mjs +++ b/apps/docs/astro.config.mjs @@ -9,7 +9,7 @@ export default defineConfig({ starlight({ title: 'Nx Plugin OpenAPI', description: - 'Nx Plugin for seamless integration of OpenAPI Generator Angular client', + 'Generate type-safe API clients from OpenAPI specs in your Nx workspace', social: [ { icon: 'github', @@ -18,44 +18,31 @@ export default defineConfig({ }, ], sidebar: [ - { - label: 'Getting Started', - items: [ - { label: 'Overview', slug: 'getting-started/overview' }, - { label: 'Installation', slug: 'getting-started/installation' }, - { label: 'Quick Start', slug: 'getting-started/quick-start' }, - ], - }, + { label: 'Getting Started', slug: 'getting-started' }, { label: 'Plugins', items: [ - { label: 'Overview', slug: 'plugins/overview' }, { label: 'OpenAPI Generator', slug: 'plugins/plugin-openapi' }, { label: 'hey-api', slug: 'plugins/plugin-hey-api' }, ], }, { - label: 'Usage', - items: [ - { label: 'Configuration', slug: 'usage/configuration' }, - { label: 'Examples', slug: 'usage/examples' }, - { label: 'Nx Integration', slug: 'usage/nx-integration' }, - ], - }, - { - label: 'API Reference', + label: 'Reference', items: [ - { label: 'generate-api executor', slug: 'reference/generate-api' }, + { label: 'Configuration', slug: 'reference/configuration' }, ], }, { label: 'Guides', items: [ - { label: 'Creating Custom Plugins', slug: 'guides/creating-plugins' }, + { + label: 'Creating Custom Plugins', + slug: 'guides/creating-plugins', + }, ], }, { - label: 'Legacy Nx Plugin', + label: 'Legacy Plugin', items: [ { label: 'Overview', slug: 'legacy-nx-plugin/overview' }, ], diff --git a/apps/docs/src/content/docs/getting-started.md b/apps/docs/src/content/docs/getting-started.md new file mode 100644 index 0000000..0d137e9 --- /dev/null +++ b/apps/docs/src/content/docs/getting-started.md @@ -0,0 +1,116 @@ +--- +title: Getting Started +description: Install and generate your first API client in under 5 minutes +--- + +## Install + +Requires an Nx workspace (v19+) and Node.js. + +```bash +# Core package +nx add @nx-plugin-openapi/core +``` + +Then pick a generator plugin: + +```bash +# Option A: OpenAPI Generator -- 50+ languages, Angular injectable services, Java required +npm install -D @nx-plugin-openapi/plugin-openapi @openapitools/openapi-generator-cli + +# Option B: hey-api -- modern TypeScript, fetch/axios, tree-shakeable, no Java +npm install -D @nx-plugin-openapi/plugin-hey-api @hey-api/openapi-ts +``` + +:::tip[Auto-install] +If you skip installing a plugin, the core package will attempt to install it automatically on first use. +::: + +## Add a generate-api target + +The quickest way: + +```bash +nx g @nx-plugin-openapi/core:add-generate-api-target +``` + +This walks you through the options and adds a `generate-api` target to your `project.json`. + +### Manual setup + +Add the target yourself: + +```json title="project.json" +{ + "targets": { + "generate-api": { + "executor": "@nx-plugin-openapi/core:generate-api", + "options": { + "generator": "hey-api", + "inputSpec": "apps/my-app/openapi.yaml", + "outputPath": "libs/api-client/src" + }, + "outputs": ["{options.outputPath}"] + } + } +} +``` + +Set `"generator"` to `"openapi-tools"` for OpenAPI Generator or `"hey-api"` for hey-api. + +## Generate + +```bash +nx run my-app:generate-api +``` + +The executor cleans the output directory, runs the chosen generator, and produces the client code. + +## Recommended Nx setup + +Add these defaults to `nx.json` so caching and build dependencies work automatically: + +```json title="nx.json" +{ + "targetDefaults": { + "generate-api": { + "cache": true, + "inputs": [ + "{projectRoot}/swagger.json", + "{projectRoot}/openapi.yaml", + "{projectRoot}/openapi-config.json" + ], + "outputs": ["{options.outputPath}"] + }, + "build": { + "dependsOn": ["generate-api"] + } + } +} +``` + +## Multiple specs + +For microservice architectures, pass an object instead of a string: + +```json +{ + "options": { + "generator": "hey-api", + "inputSpec": { + "users-api": "apis/users.yaml", + "products-api": "apis/products.yaml" + }, + "outputPath": "libs/api-clients/src" + } +} +``` + +Each key becomes a subdirectory under `outputPath`. + +## Next steps + +- [OpenAPI Generator plugin](/plugins/plugin-openapi/) -- all options for `openapi-tools` +- [hey-api plugin](/plugins/plugin-hey-api/) -- all options for `hey-api` +- [Configuration reference](/reference/configuration/) -- executor options +- [Creating custom plugins](/guides/creating-plugins/) -- build your own generator diff --git a/apps/docs/src/content/docs/getting-started/installation.md b/apps/docs/src/content/docs/getting-started/installation.md deleted file mode 100644 index d3d672a..0000000 --- a/apps/docs/src/content/docs/getting-started/installation.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: Installation -description: Learn how to install and set up the Nx Plugin OpenAPI in your workspace ---- - -# Installation - -This guide will walk you through installing the Nx Plugin OpenAPI in your Nx workspace. - -## Prerequisites - -Before installing the plugin, make sure you have: - -- An existing Nx workspace (version 19+) -- Node.js and npm installed - -## Core Package Installation - -The recommended approach is to use the new modular package structure with the core package and your choice of generator plugin. - -### Step 1: Install the Core Package - -```bash -nx add @nx-plugin-openapi/core -``` - -or -```bash -npm install --save-dev @nx-plugin-openapi/core -``` - -### Step 2: Install a Generator Plugin - -Choose and install one or more generator plugins based on your needs: - -#### Option A: OpenAPI Generator (openapi-tools) - -For projects using [OpenAPI Generator](https://openapi-generator.tech): - -```bash -npm install --save-dev @nx-plugin-openapi/plugin-openapi @openapitools/openapi-generator-cli -``` - -#### Option B: hey-api - -For projects using [hey-api/openapi-ts](https://github.com/hey-api/openapi-ts): - -```bash -npm install --save-dev @nx-plugin-openapi/plugin-hey-api @hey-api/openapi-ts -``` - -:::tip[Auto-Installation] -Generator plugins and their peer dependencies are auto-installed when first used. If you specify `"generator": "openapi-tools"` or `"generator": "hey-api"` and the plugin isn't installed, the core package will attempt to install it automatically. -::: - -## Package Overview - -| Package | Purpose | Peer Dependencies | -|---------|---------|-------------------| -| `@nx-plugin-openapi/core` | Core executor and plugin system | `@nx/devkit` | -| `@nx-plugin-openapi/plugin-openapi` | OpenAPI Generator plugin | `@openapitools/openapi-generator-cli` | -| `@nx-plugin-openapi/plugin-hey-api` | hey-api plugin | `@hey-api/openapi-ts` | - -## Legacy Package Installation - -For backward compatibility, the original package is still available: - -```bash -# Legacy package (OpenAPI Generator only) -npm install --save-dev @lambda-solutions/nx-plugin-openapi @openapitools/openapi-generator-cli -``` - -:::note[Migration] -If you're using the legacy `@lambda-solutions/nx-plugin-openapi` package, consider migrating to the new modular structure for better flexibility and support for multiple generators. -::: - -## Verification - -After installation, verify the packages are installed correctly: - -```bash -# Check core package -nx list @nx-plugin-openapi/core -``` - -You should see output similar to: - -``` -@nx-plugin-openapi/core - -Executors: -- generate-api : Generate API code using a selected generator plugin - -Generators: -- add-generate-api-target : Add a generate-api target using the core executor -- init : Initialize core plugin defaults -``` - -## Using the Generator - -You can quickly add a `generate-api` target to an existing project: - -```bash -nx generate @nx-plugin-openapi/core:add-generate-api-target --project=my-app -``` - -This interactive generator will guide you through the configuration options. - -## Next Steps - -Now that the plugin is installed, you can: - -1. [Configure your first project](/getting-started/quick-start/) to use the `generate-api` executor -2. Learn about [advanced configuration options](/usage/configuration/) -3. Explore [examples](/usage/examples/) for common use cases - -If you encounter issues, please [file an issue on GitHub](https://github.com/berger-engineering-io/nx-plugin-openapi/issues). diff --git a/apps/docs/src/content/docs/getting-started/overview.md b/apps/docs/src/content/docs/getting-started/overview.md deleted file mode 100644 index c1091f6..0000000 --- a/apps/docs/src/content/docs/getting-started/overview.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Overview -description: Learn about the Nx Plugin OpenAPI and what it can do for your project ---- - -# Overview - -The Nx Plugin OpenAPI brings first-class support for generating API client code from OpenAPI specifications within your Nx workspace, leveraging all the powerful features of the Nx task pipeline. - -## Plugin Architecture - -The project is structured as a modular plugin system, allowing you to choose the code generator that best fits your needs: - -``` -┌─────────────────────────────────────────────────────────────┐ -│ @nx-plugin-openapi/core │ -│ Executor, Plugin Loader, Auto-Installation │ -└─────────────────────────────────────────────────────────────┘ - │ - ┌───────────────────┴───────────────────┐ - ▼ ▼ -┌────────────────────────┐ ┌────────────────────────┐ -│ plugin-openapi │ │ plugin-hey-api │ -│ (OpenAPI Generator) │ │ (hey-api/openapi-ts) │ -└────────────────────────┘ └────────────────────────┘ -``` - -### Available Generators - -| Generator | Plugin | Description | -|-----------|--------|-------------| -| `openapi-tools` | `@nx-plugin-openapi/plugin-openapi` | Uses [OpenAPI Generator](https://openapi-generator.tech) - supports 50+ languages including TypeScript Angular | -| `hey-api` | `@nx-plugin-openapi/plugin-hey-api` | Uses [hey-api/openapi-ts](https://github.com/hey-api/openapi-ts) - modern TypeScript-first client generation | - -## Key Benefits - -### 🚀 **Nx Native Integration** -- Uses standard Nx executors and configuration -- Integrates with Nx's dependency graph -- Supports Nx's powerful caching system -- Works with Nx Cloud for distributed caching - -### ⚡ **Smart Caching** -- Only regenerates when OpenAPI specs change -- Supports both local and remote OpenAPI specifications -- Caches based on file content, not timestamps -- Dramatically speeds up builds in large monorepos - -### 🔧 **Flexible Plugin System** -- Choose the generator that fits your project needs -- Plugins are auto-installed when first used -- Pass generator-specific options via `generatorOptions` -- Support for multiple OpenAPI specifications in a single target -- [Create custom plugins](/guides/creating-plugins/) for any OpenAPI generator - -### 📦 **Production Ready** -- Battle-tested generators used in thousands of production applications -- Comprehensive configuration options for customization -- TypeScript-safe configuration through JSON schema - -## Choosing a Generator - -### OpenAPI Generator (`openapi-tools`) - -Best for: -- Angular applications needing injectable services -- Projects requiring specific OpenAPI Generator templates -- Teams familiar with OpenAPI Generator ecosystem -- Supporting multiple languages/frameworks - -### hey-api (`hey-api`) - -Best for: -- Modern TypeScript/JavaScript projects -- Projects prioritizing type safety -- Fetch-based HTTP clients -- Simpler, more lightweight generated code - -## Extensibility - -Need to integrate a different OpenAPI generator? The plugin architecture makes it easy to create custom plugins for any code generator. See our [Creating Custom Plugins](/guides/creating-plugins/) guide for a complete walkthrough. - -## Next Steps - -Ready to get started? Let's [install the plugin](/getting-started/installation/) in your Nx workspace. diff --git a/apps/docs/src/content/docs/getting-started/quick-start.md b/apps/docs/src/content/docs/getting-started/quick-start.md deleted file mode 100644 index 8707c1f..0000000 --- a/apps/docs/src/content/docs/getting-started/quick-start.md +++ /dev/null @@ -1,248 +0,0 @@ ---- -title: Quick Start -description: Get up and running with your first API client generation ---- - -# Quick Start - -This guide will help you generate your first API client using the Nx Plugin OpenAPI. - -## Step 1: Prepare Your OpenAPI Specification - -You'll need an OpenAPI specification file. This can be: -- A local JSON or YAML file -- A remote URL endpoint - -For this example, we'll use a local file. Create a simple OpenAPI spec: - -```json title="apps/my-app/swagger.json" -{ - "openapi": "3.0.0", - "info": { - "title": "Sample API", - "version": "1.0.0" - }, - "paths": { - "/users": { - "get": { - "summary": "Get all users", - "responses": { - "200": { - "description": "Successful response", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "email": { - "type": "string", - "format": "email" - } - } - } - } - } -} -``` - -## Step 2: Configure the Executor - -Add the `generate-api` executor to your project's `project.json`. - -### Using the Generator (Recommended) - -The easiest way is to use the interactive generator: - -```bash -nx generate @nx-plugin-openapi/core:add-generate-api-target --project=my-app -``` - -The generator will walk you through the configuration options. - -### Manual Configuration - -You can also manually add the executor configuration to your `project.json` file: - -#### Using OpenAPI Generator (openapi-tools) - -```json title="apps/my-app/project.json" -{ - "name": "my-app", - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "openapi-tools", - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "apps/my-app/src/app/api" - }, - "outputs": ["{options.outputPath}"] - }, - "build": { - "dependsOn": ["generate-api"] - } - } -} -``` - -#### Using hey-api - -```json title="apps/my-app/project.json" -{ - "name": "my-app", - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "hey-api", - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "apps/my-app/src/app/api" - }, - "outputs": ["{options.outputPath}"] - }, - "build": { - "dependsOn": ["generate-api"] - } - } -} -``` - -:::tip[Generator Selection] -- **`openapi-tools`**: Best for Angular projects needing injectable services, or when using OpenAPI Generator's extensive template ecosystem. -- **`hey-api`**: Best for modern TypeScript projects wanting simpler, more type-safe generated code. -::: - - - -## Step 3: Generate the API Client - -Run the executor to generate your API client: - -```bash -nx run my-app:generate-api -``` - -You should see output similar to: - -``` -✔ Starting to generate API from provided OpenAPI spec... -✔ Cleaning outputPath libs/api-client/src first -✔ API generation completed successfully. -``` - -## Step 4: Examine the Generated Code - -The generated code structure varies based on the generator you chose: - -### OpenAPI Generator (openapi-tools) Output - -``` -libs/api-client/src/ -├── api/ -│ ├── api.ts -│ ├── default.service.ts -│ └── ... -├── model/ -│ ├── models.ts -│ ├── user.ts -│ └── ... -├── configuration.ts -├── index.ts -└── variables.ts -``` - -### hey-api Output - -``` -libs/api-client/src/ -├── client/ -│ └── client.ts -├── schemas/ -│ └── ... -├── services/ -│ └── ... -├── types/ -│ └── ... -└── index.ts -``` - -## Step 5: Set Up Nx Integration (Optional) - -For better integration with Nx's build system, configure target defaults in your `nx.json`: - -```json title="nx.json" -{ - "targetDefaults": { - "generate-api": { - "cache": true, - "inputs": [ - "{projectRoot}/swagger.json", - "{projectRoot}/openapi.yaml", - "{projectRoot}/openapi-config.json" - ] - }, - "build": { - "dependsOn": ["^build", "^generate-api", "generate-api"] - } - } -} -``` - -This configuration: -- Enables caching for the `generate-api` executor -- Makes builds depend on API generation -- Includes relevant input files for cache invalidation - -## Step 6: Use the Generated Client - -The usage of the generated client depends on which generator you chose: - -- **OpenAPI Generator**: See the [official documentation](https://openapi-generator.tech/docs/generators/typescript-angular#using-the-generated-client) for Angular integration. -- **hey-api**: See the [hey-api documentation](https://heyapi.dev/) for usage examples. - -## Next Steps - -Congratulations! You've successfully generated your first API client. Here's what you can do next: - -- **[Explore Configuration Options](/usage/configuration/)** - Learn about advanced configuration options -- **[View Examples](/usage/examples/)** - See more complex usage patterns -- **[API Reference](/reference/generate-api/)** - Complete reference for all available options - -## Common Issues - -### Plugin Not Found - -If you see an error about a plugin not being found, ensure the plugin package is installed: - -```bash -# For openapi-tools -npm install --save-dev @nx-plugin-openapi/plugin-openapi @openapitools/openapi-generator-cli - -# For hey-api -npm install --save-dev @nx-plugin-openapi/plugin-hey-api @hey-api/openapi-ts -``` - -### Output Directory Conflicts - -The plugin automatically cleans the output directory before generation. Make sure the `outputPath` doesn't contain important files that shouldn't be deleted. diff --git a/apps/docs/src/content/docs/guides/creating-plugins.md b/apps/docs/src/content/docs/guides/creating-plugins.md index f9cd27c..b435be2 100644 --- a/apps/docs/src/content/docs/guides/creating-plugins.md +++ b/apps/docs/src/content/docs/guides/creating-plugins.md @@ -1,805 +1,139 @@ --- -title: Creating Custom Generator Plugins -description: Learn how to create a custom plugin to integrate any OpenAPI code generator with the Nx plugin +title: Creating Custom Plugins +description: Build a custom generator plugin for @nx-plugin-openapi/core --- -# Creating Custom Generator Plugins +Each plugin implements the `GeneratorPlugin` interface and handles the actual code generation. The core package handles plugin discovery, Nx integration, and caching. -This guide walks you through creating a custom plugin to integrate any OpenAPI code generator with `@nx-plugin-openapi/core`. Whether you want to use a different TypeScript generator, a language-specific generator, or your own custom generator, this guide covers everything you need to know. - -## Overview - -The plugin architecture is designed to be extensible. Each plugin implements the `GeneratorPlugin` interface and handles the actual code generation. The core package handles: - -- Plugin discovery and loading -- Configuration validation -- Nx executor integration -- Caching and task orchestration - -``` -┌─────────────────────────────────────────────────────────────┐ -│ @nx-plugin-openapi/core │ -│ Executor, Plugin Loader, Auto-Installation │ -└─────────────────────────────────────────────────────────────┘ - │ - ┌───────────────────┼───────────────────┐ - ▼ ▼ ▼ -┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ -│ plugin-openapi │ │ plugin-hey-api │ │ Your Plugin! │ -└──────────────────┘ └──────────────────┘ └──────────────────┘ -``` - -## Quick Start - -Here's a minimal plugin implementation: +## Minimal plugin ```typescript import { BaseGenerator, - GeneratorContext, GeneratorPlugin, GenerateOptionsBase, + GeneratorContext, } from '@nx-plugin-openapi/core'; -export class MyGenerator - extends BaseGenerator - implements GeneratorPlugin -{ +export class MyGenerator extends BaseGenerator implements GeneratorPlugin { readonly name = 'my-generator'; - async generate( - options: GenerateOptionsBase, - ctx: GeneratorContext - ): Promise { + async generate(options: GenerateOptionsBase, ctx: GeneratorContext): Promise { const { inputSpec, outputPath } = options; - // Clean the output directory - this.cleanOutput(ctx, outputPath); - - // Call your generator here - await this.runMyGenerator(inputSpec, outputPath, ctx); + if (typeof inputSpec === 'string') { + this.cleanOutput(ctx, outputPath); + await this.run(inputSpec, outputPath, options.generatorOptions || {}, ctx); + } else { + for (const [name, specPath] of Object.entries(inputSpec)) { + const out = `${outputPath}/${name}`; + this.cleanOutput(ctx, out); + await this.run(specPath, out, options.generatorOptions || {}, ctx); + } + } } - private async runMyGenerator( - inputSpec: string, - outputPath: string, - ctx: GeneratorContext - ): Promise { - // Your generation logic here + private async run(spec: string, out: string, opts: Record, ctx: GeneratorContext) { + const { join } = await import('node:path'); + const generator = await import('my-openapi-generator'); + await generator.generate({ input: spec, output: join(ctx.root, out), ...opts }); } } -// Export a singleton instance export default new MyGenerator(); ``` -## Core Concepts - -### The GeneratorPlugin Interface - -Every plugin must implement the `GeneratorPlugin` interface: +## Plugin interface ```typescript interface GeneratorPlugin> { - // Unique identifier for the plugin readonly name: string; - - // Optional: Validate options before generation validate?(options: TOptions & GenerateOptionsBase): void | Promise; - - // Required: Perform the actual code generation - generate( - options: TOptions & GenerateOptionsBase, - ctx: GeneratorContext - ): Promise; - - // Optional: Return JSON schema for configuration validation + generate(options: TOptions & GenerateOptionsBase, ctx: GeneratorContext): Promise; getSchema?(): unknown; } -``` -### GenerateOptionsBase - -These are the core options available to all plugins: - -```typescript interface GenerateOptionsBase { - // Single spec path/URL or object mapping names to paths inputSpec: string | Record; - - // Output directory (relative to workspace root) outputPath: string; - - // Plugin-specific options generatorOptions?: Record; } -``` - -### GeneratorContext -Context provided by the executor: - -```typescript interface GeneratorContext { - // Absolute path to workspace root root: string; - - // Optional project name workspaceName?: string; } ``` -### BaseGenerator Class - -The `BaseGenerator` class provides utility methods: - -```typescript -abstract class BaseGenerator { - // Safely cleans the output directory - protected cleanOutput(ctx: GeneratorContext, relOutputPath: string): void; -} -``` - -## Step-by-Step Guide - -### Step 1: Create the Package Structure - -Create a new package in your workspace or as a standalone npm package: - -``` -packages/plugin-my-generator/ -├── src/ -│ ├── lib/ -│ │ ├── my-generator.ts -│ │ ├── my-generator.spec.ts -│ │ └── options.ts -│ └── index.ts -├── package.json -├── tsconfig.json -├── tsconfig.lib.json -└── README.md -``` - -### Step 2: Define Your Options Interface +`BaseGenerator` provides `cleanOutput(ctx, relPath)` to safely remove the output directory before generation. -Create a TypeScript interface for your generator's specific options: +## Package setup -```typescript -// src/lib/options.ts - -export interface MyGeneratorOptions { - // Language-specific options - language?: string; - - // Framework options - framework?: string; - - // Output format options - outputFormat?: 'single-file' | 'multiple-files'; - - // Custom template path - templatePath?: string; - - // Any other options your generator supports - [key: string]: unknown; -} ``` - -### Step 3: Implement the Generator Class - -```typescript -// src/lib/my-generator.ts - -import { join } from 'node:path'; -import { spawn } from 'node:child_process'; -import { logger } from '@nx/devkit'; -import { - BaseGenerator, - GeneratorContext, - GeneratorPlugin, - GenerateOptionsBase, - ExecutionError, -} from '@nx-plugin-openapi/core'; -import { MyGeneratorOptions } from './options'; - -export class MyGenerator - extends BaseGenerator - implements GeneratorPlugin -{ - // Unique name used in configuration - readonly name = 'my-generator'; - - // Optional: Validate options before generation - async validate( - options: MyGeneratorOptions & GenerateOptionsBase - ): Promise { - if (options.language && !['typescript', 'javascript'].includes(options.language)) { - throw new Error(`Unsupported language: ${options.language}`); - } - } - - // Required: Main generation method - async generate( - options: MyGeneratorOptions & GenerateOptionsBase, - ctx: GeneratorContext - ): Promise { - const { inputSpec, outputPath } = options; - const generatorOptions = (options.generatorOptions || {}) as Partial; - - logger.info(`Starting my-generator code generation`); - - // Handle single specification - if (typeof inputSpec === 'string') { - await this.generateForSpec(inputSpec, outputPath, generatorOptions, ctx); - } - // Handle multiple specifications - else { - const entries = Object.entries(inputSpec); - logger.info(`Generating code for ${entries.length} services`); - - for (const [serviceName, specPath] of entries) { - logger.info(`Generating service: ${serviceName}`); - const serviceOutputPath = join(outputPath, serviceName); - await this.generateForSpec(specPath, serviceOutputPath, generatorOptions, ctx); - } - } - - logger.info(`my-generator code generation completed successfully`); - } - - private async generateForSpec( - specPath: string, - outputPath: string, - options: Partial, - ctx: GeneratorContext - ): Promise { - // Clean the output directory before generation - this.cleanOutput(ctx, outputPath); - - // Build the full output path - const fullOutputPath = join(ctx.root, outputPath); - - // Call your generator - await this.invokeGenerator(specPath, fullOutputPath, options, ctx); - } - - private async invokeGenerator( - specPath: string, - outputPath: string, - options: Partial, - ctx: GeneratorContext - ): Promise { - // Option 1: Call a JavaScript/TypeScript API - await this.invokeViaApi(specPath, outputPath, options); - - // Option 2: Spawn a CLI process - // await this.invokeViaCli(specPath, outputPath, options, ctx); - } - - // Example: Calling a generator's JavaScript API - private async invokeViaApi( - specPath: string, - outputPath: string, - options: Partial - ): Promise { - let generator: any; - try { - // Dynamic import of the generator package - generator = await import('my-openapi-generator'); - } catch (e) { - const msg = e instanceof Error ? e.message : String(e); - throw new Error( - `my-openapi-generator is required but not installed. ` + - `Install it with: npm install -D my-openapi-generator. ` + - `Original error: ${msg}` - ); - } - - // Call the generator's API - await generator.generate({ - input: specPath, - output: outputPath, - ...options, - }); - } - - // Example: Spawning a CLI process - private async invokeViaCli( - specPath: string, - outputPath: string, - options: Partial, - ctx: GeneratorContext - ): Promise { - return new Promise((resolve, reject) => { - const args = this.buildCliArgs(specPath, outputPath, options); - - logger.debug(`Executing: npx my-generator ${args.join(' ')}`); - - const childProcess = spawn('npx', ['my-generator', ...args], { - cwd: ctx.root, - stdio: 'inherit', - }); - - childProcess.on('close', (code) => { - if (code === 0) { - resolve(); - } else { - reject(new ExecutionError( - `Generator exited with code ${code}`, - `npx my-generator ${args.join(' ')}`, - code ?? undefined - )); - } - }); - - childProcess.on('error', (error) => { - reject(new ExecutionError( - `Failed to spawn process: ${error.message}`, - `npx my-generator`, - undefined, - error - )); - }); - }); - } - - private buildCliArgs( - specPath: string, - outputPath: string, - options: Partial - ): string[] { - const args: string[] = [ - '--input', specPath, - '--output', outputPath, - ]; - - if (options.language) { - args.push('--language', options.language); - } - - if (options.framework) { - args.push('--framework', options.framework); - } - - return args; - } -} - -// Export a singleton instance - this is required! -export default new MyGenerator(); +my-plugin/ + src/ + lib/my-generator.ts + index.ts + package.json ``` -### Step 4: Create the Package Entry Point - -```typescript -// src/index.ts - -// Named exports for consumers who want to extend or test +```typescript title="src/index.ts" export { MyGenerator } from './lib/my-generator'; -export { MyGeneratorOptions } from './lib/options'; - -// Default export of the singleton instance -// This is what the plugin loader uses export { default } from './lib/my-generator'; - -// Alternative named export (the loader checks multiple patterns) -export { default as MyPlugin } from './lib/my-generator'; ``` -### Step 5: Configure package.json - -```json +```json title="package.json" { "name": "@my-org/plugin-my-generator", - "version": "1.0.0", - "description": "My custom OpenAPI generator plugin for nx-plugin-openapi", "type": "commonjs", "main": "./src/index.js", - "typings": "./src/index.d.ts", - "dependencies": { - "tslib": "^2.3.0" - }, "peerDependencies": { "@nx-plugin-openapi/core": ">=0.0.1", - "@nx/devkit": ">=19.0.0", "my-openapi-generator": "^1.0.0" - }, - "peerDependenciesMeta": { - "my-openapi-generator": { - "optional": false - } } } ``` -**Important notes:** - -- Use `"type": "commonjs"` for compatibility with the plugin loader -- The underlying generator should be a **peer dependency**, not a direct dependency -- This allows users to control the version of the generator they use - -### Step 6: Write Tests - -```typescript -// src/lib/my-generator.spec.ts - -import { MyGenerator } from './my-generator'; -import { GeneratorContext } from '@nx-plugin-openapi/core'; - -// Mock the generator -jest.mock('my-openapi-generator', () => ({ - generate: jest.fn().mockResolvedValue(undefined), -})); - -describe('MyGenerator', () => { - let generator: MyGenerator; - let mockContext: GeneratorContext; - - beforeEach(() => { - generator = new MyGenerator(); - mockContext = { - root: '/workspace', - workspaceName: 'test-project', - }; - jest.clearAllMocks(); - }); - - it('should have the correct name', () => { - expect(generator.name).toBe('my-generator'); - }); - - it('should generate code for a single spec', async () => { - const options = { - inputSpec: 'api/openapi.yaml', - outputPath: 'libs/api-client/src', - generatorOptions: { - language: 'typescript', - }, - }; - - await generator.generate(options, mockContext); - - const mockGenerator = await import('my-openapi-generator'); - expect(mockGenerator.generate).toHaveBeenCalledWith( - expect.objectContaining({ - input: 'api/openapi.yaml', - output: '/workspace/libs/api-client/src', - language: 'typescript', - }) - ); - }); - - it('should generate code for multiple specs', async () => { - const options = { - inputSpec: { - 'users': 'api/users.yaml', - 'products': 'api/products.yaml', - }, - outputPath: 'libs/api-clients/src', - }; - - await generator.generate(options, mockContext); - - const mockGenerator = await import('my-openapi-generator'); - expect(mockGenerator.generate).toHaveBeenCalledTimes(2); - }); -}); -``` - -## Using Your Plugin +Key points: +- Use `"type": "commonjs"` for plugin loader compatibility +- The underlying generator should be a **peer dependency** +- Export a **default singleton** instance -Once your plugin is published or linked locally, use it in your Nx workspace: +## Using your plugin ```json title="project.json" { - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "@my-org/plugin-my-generator", - "inputSpec": "apps/my-app/openapi.yaml", - "outputPath": "libs/api-client/src", - "generatorOptions": { - "language": "typescript", - "framework": "fetch" - } - } - } - } -} -``` - -The plugin loader will: - -1. Check if the plugin is registered in the `GeneratorRegistry` -2. Look in the in-memory cache -3. Try to import from `node_modules` -4. Auto-install the plugin if not found (in non-CI environments) - -## Advanced Topics - -### Plugin Discovery - -The plugin loader looks for exports in this order: - -1. `module.default` - Default export (recommended) -2. `module.createPlugin()` - Factory function -3. `module.plugin` - Named export -4. `module.Plugin` - Named export (capitalized) - -### Built-in Plugin Aliases - -For convenience, the core package includes aliases for built-in plugins: - -| Alias | Package | -|-------|---------| -| `openapi-tools` | `@nx-plugin-openapi/plugin-openapi` | -| `hey-api` | `@nx-plugin-openapi/plugin-hey-api` | - -### Registering Plugins Programmatically - -For advanced use cases, you can pre-register plugins: - -```typescript -import { GeneratorRegistry } from '@nx-plugin-openapi/core'; -import myPlugin from '@my-org/plugin-my-generator'; - -const registry = GeneratorRegistry.instance(); -registry.register(myPlugin); -``` - -### Error Handling - -Use the error classes from `@nx-plugin-openapi/core` for consistent error handling: - -```typescript -import { - ExecutionError, - ValidationError, - ConfigurationError, -} from '@nx-plugin-openapi/core'; - -// For command execution failures -throw new ExecutionError( - 'Generator failed', - 'npx my-generator --input spec.yaml', - 1, // exit code - originalError // optional cause -); - -// For validation failures -throw new ValidationError('Invalid language option'); - -// For configuration issues -throw new ConfigurationError('Missing required option: framework'); -``` - -### Implementing Retry Logic - -For CLI-based generators that may have transient failures: - -```typescript -private async executeWithRetry( - fn: () => Promise, - maxAttempts: number = 3 -): Promise { - let lastError: Error | undefined; - - for (let attempt = 1; attempt <= maxAttempts; attempt++) { - try { - await fn(); - return; - } catch (error) { - lastError = error as Error; - logger.warn(`Attempt ${attempt} failed: ${lastError.message}`); - - if (attempt < maxAttempts) { - const delay = 1000 * Math.pow(2, attempt - 1); - await new Promise(resolve => setTimeout(resolve, delay)); - } - } - } - - throw lastError; -} -``` - -### Supporting Custom Templates - -If your generator supports custom templates: - -```typescript -interface MyGeneratorOptions { - templatePath?: string; - templateVariables?: Record; -} - -private async invokeGenerator( - specPath: string, - outputPath: string, - options: Partial, - ctx: GeneratorContext -): Promise { - const templatePath = options.templatePath - ? join(ctx.root, options.templatePath) - : undefined; - - await generator.generate({ - input: specPath, - output: outputPath, - templates: templatePath, - variables: options.templateVariables, - }); -} -``` - -## Real-World Examples - -### Example 1: Integrating `openapi-typescript` - -```typescript -import { join } from 'node:path'; -import { writeFileSync } from 'node:fs'; -import { - BaseGenerator, - GeneratorPlugin, - GenerateOptionsBase, - GeneratorContext, -} from '@nx-plugin-openapi/core'; - -export class OpenApiTypescriptGenerator - extends BaseGenerator - implements GeneratorPlugin -{ - readonly name = 'openapi-typescript'; - - async generate( - options: GenerateOptionsBase, - ctx: GeneratorContext - ): Promise { - const { inputSpec, outputPath } = options; - - // Dynamic import - const openApiTs = await import('openapi-typescript'); - - if (typeof inputSpec === 'string') { - this.cleanOutput(ctx, outputPath); - const types = await openApiTs.default(inputSpec); - const outFile = join(ctx.root, outputPath, 'types.ts'); - writeFileSync(outFile, types); - } else { - for (const [name, specPath] of Object.entries(inputSpec)) { - const serviceOutputPath = join(outputPath, name); - this.cleanOutput(ctx, serviceOutputPath); - const types = await openApiTs.default(specPath); - const outFile = join(ctx.root, serviceOutputPath, 'types.ts'); - writeFileSync(outFile, types); - } - } + "options": { + "generator": "@my-org/plugin-my-generator", + "inputSpec": "apps/my-app/openapi.yaml", + "outputPath": "libs/api-client/src", + "generatorOptions": { "language": "typescript" } } } - -export default new OpenApiTypescriptGenerator(); ``` -### Example 2: Integrating `swagger-typescript-api` - -```typescript -import { join } from 'node:path'; -import { - BaseGenerator, - GeneratorPlugin, - GenerateOptionsBase, - GeneratorContext, -} from '@nx-plugin-openapi/core'; - -interface SwaggerTypescriptApiOptions { - httpClientType?: 'axios' | 'fetch'; - generateClient?: boolean; - generateRouteTypes?: boolean; - moduleNameIndex?: number; -} - -export class SwaggerTypescriptApiGenerator - extends BaseGenerator - implements GeneratorPlugin -{ - readonly name = 'swagger-typescript-api'; - - async generate( - options: SwaggerTypescriptApiOptions & GenerateOptionsBase, - ctx: GeneratorContext - ): Promise { - const { inputSpec, outputPath, generatorOptions = {} } = options; - - const { generateApi } = await import('swagger-typescript-api'); - - const config = { - httpClientType: generatorOptions.httpClientType || 'fetch', - generateClient: generatorOptions.generateClient ?? true, - generateRouteTypes: generatorOptions.generateRouteTypes ?? true, - moduleNameIndex: generatorOptions.moduleNameIndex ?? 0, - }; - - if (typeof inputSpec === 'string') { - this.cleanOutput(ctx, outputPath); - await generateApi({ - input: join(ctx.root, inputSpec), - output: join(ctx.root, outputPath), - ...config, - }); - } else { - for (const [name, specPath] of Object.entries(inputSpec)) { - const serviceOutputPath = join(outputPath, name); - this.cleanOutput(ctx, serviceOutputPath); - await generateApi({ - input: join(ctx.root, specPath), - output: join(ctx.root, serviceOutputPath), - name, - ...config, - }); - } - } - } -} - -export default new SwaggerTypescriptApiGenerator(); -``` - -## Best Practices - -1. **Use peer dependencies** for the underlying generator to give users version control -2. **Support both single and multiple specs** for microservice architectures -3. **Always clean the output directory** before generation to avoid stale files -4. **Use the `@nx/devkit` logger** for consistent output formatting -5. **Provide helpful error messages** when dependencies are missing -6. **Test with both local files and remote URLs** as input specs -7. **Document all available options** in your plugin's README -8. **Export a singleton instance** as the default export - -## Troubleshooting - -### Plugin Not Found - -If your plugin isn't being loaded: - -1. Ensure the package is installed: `npm ls @my-org/plugin-my-generator` -2. Check the export pattern matches what the loader expects -3. Verify `"type": "commonjs"` in package.json -4. Check for TypeScript compilation errors - -### Generator Dependency Missing - -If the underlying generator isn't installed: - -1. Add clear instructions to install peer dependencies -2. Consider adding a helpful error message in your plugin: - -```typescript -try { - await import('my-openapi-generator'); -} catch { - throw new Error( - 'my-openapi-generator is required but not installed.\n' + - 'Install it with: npm install -D my-openapi-generator' - ); -} -``` +The plugin loader tries these export patterns in order: +1. `module.default` (recommended) +2. `module.createPlugin()` +3. `module.plugin` +4. `module.Plugin` -### Path Resolution Issues +## Error handling -Always use `join(ctx.root, relativePath)` for absolute paths: +Use the built-in error classes for consistent reporting: ```typescript -// ✅ Correct -const fullPath = join(ctx.root, outputPath); +import { ExecutionError, ValidationError, ConfigurationError } from '@nx-plugin-openapi/core'; -// ❌ Wrong - may resolve incorrectly -const fullPath = outputPath; +throw new ExecutionError('Generator failed', 'npx my-gen --input spec.yaml', 1); +throw new ValidationError('Invalid language'); +throw new ConfigurationError('Missing option: framework'); ``` -## Next Steps +## Best practices -- [Configuration Guide](/usage/configuration/) - Learn about all configuration options -- [Nx Integration](/usage/nx-integration/) - Set up caching and task dependencies -- [Examples](/usage/examples/) - See real-world configuration examples +1. Support both single and multiple specs (`string | Record`) +2. Always clean output before generation +3. Use `@nx/devkit` logger for output +4. Provide clear error messages when peer dependencies are missing +5. Test with both local files and remote URLs diff --git a/apps/docs/src/content/docs/index.mdx b/apps/docs/src/content/docs/index.mdx index f148802..58750de 100644 --- a/apps/docs/src/content/docs/index.mdx +++ b/apps/docs/src/content/docs/index.mdx @@ -1,13 +1,13 @@ --- title: Nx Plugin OpenAPI -description: Nx Plugin for seamless integration of OpenAPI Generator Angular client +description: Generate API clients from OpenAPI specs in your Nx workspace template: splash hero: - tagline: Seamless Nx integration of OpenAPI generator. Generate Angular API clients from OpenAPI specifications with ease! + tagline: Generate type-safe API clients from OpenAPI specs -- pluggable, cacheable, Nx-native. actions: - text: Get Started - link: /getting-started/overview/ + link: /getting-started/ icon: right-arrow - text: View on GitHub link: https://github.com/berger-engineering-io/nx-plugin-openapi @@ -15,40 +15,37 @@ hero: variant: minimal --- - - - - - - - - import { Card, CardGrid } from '@astrojs/starlight/components'; ## Why Nx Plugin OpenAPI? - - Seamlessly integrates with your Nx workspace using familiar executors and configurations. + + Choose between OpenAPI Generator (50+ languages) or hey-api (modern TypeScript) -- or build your own. - - Leverages Nx's intelligent caching to avoid regenerating unchanged API clients. + + Uses standard Nx executors. Full support for caching, affected commands, dependency graph, and Nx Cloud. - - Choose from multiple code generators or create your own custom plugins. + + Generate clients from several OpenAPI files in a single target -- great for microservice architectures. - - Generates Angular-compatible TypeScript clients out of the box using the well established OpenAPI Generator for Angular. + + Run `nx g @nx-plugin-openapi/core:add-generate-api-target` and you're generating code. Plugins auto-install on first use. -## Features +## Quick start + +```bash +# 1. Install +nx add @nx-plugin-openapi/core +npm install -D @nx-plugin-openapi/plugin-hey-api @hey-api/openapi-ts -- **🎯 Executor-based**: Use `nx run my-app:generate-api` to generate API clients -- **🔌 Plugin Architecture**: Choose between [OpenAPI Generator](/plugins/plugin-openapi/) or [hey-api](/plugins/plugin-hey-api/), or [create your own](/guides/creating-plugins/) -- **📁 File & URL Support**: Work with local OpenAPI specs or remote URLs -- **🔄 Smart Caching**: Only regenerates when OpenAPI specs change +# 2. Add target (interactive) +nx g @nx-plugin-openapi/core:add-generate-api-target -## Quick Example +# 3. Generate +nx run my-app:generate-api +``` -Ready to get started? Check out our [installation guide](/getting-started/installation/) or explore the [examples](/usage/examples/). +Ready to dive in? Head to the [Getting Started](/getting-started/) guide. diff --git a/apps/docs/src/content/docs/legacy-nx-plugin/overview.md b/apps/docs/src/content/docs/legacy-nx-plugin/overview.md index 509187d..efba879 100644 --- a/apps/docs/src/content/docs/legacy-nx-plugin/overview.md +++ b/apps/docs/src/content/docs/legacy-nx-plugin/overview.md @@ -1,54 +1,19 @@ --- -title: "@lambda-solutions/nx-plugin-openapi" -description: Documentation for the original standalone Nx plugin for OpenAPI Generator +title: Legacy Plugin +description: Documentation for the original @lambda-solutions/nx-plugin-openapi package --- -# @lambda-solutions/nx-plugin-openapi - -The original Nx Plugin for seamless integration of [OpenAPI Generator](https://openapi-generator.tech) in your Nx workspace. - -:::note[Legacy Package] -This is the original standalone plugin. For new projects, consider using the modular [`@nx-plugin-openapi/core`](/getting-started/installation/) package which provides more flexibility with multiple generator plugins. +:::caution[Legacy] +For new projects, use [`@nx-plugin-openapi/core`](/getting-started/) with a generator plugin instead. The legacy package only supports OpenAPI Generator and has no plugin architecture. ::: -## Features - -- Executor for generating API clients from OpenAPI specifications -- First-class Nx caching support -- TypeScript Angular client generation -- Works with both local and remote OpenAPI specs - -## Installation - -### Using nx add (Recommended) - -The easiest way to install the plugin: +## Install ```bash nx add @lambda-solutions/nx-plugin-openapi ``` -This command will: -- Install the plugin package -- Install the required peer dependency (`@openapitools/openapi-generator-cli`) - -### Manual Installation - -If you prefer manual installation: - -```bash -# Install the plugin -npm install --save-dev @lambda-solutions/nx-plugin-openapi - -# Install the peer dependency -npm install --save-dev @openapitools/openapi-generator-cli -``` - -## Quick Start - -### 1. Add a generate-api target - -Add a `generate-api` target to your `project.json`: +## Usage ```json title="project.json" { @@ -64,300 +29,32 @@ Add a `generate-api` target to your `project.json`: } ``` -### 2. Run the generator - ```bash nx run my-app:generate-api ``` -## Configuration - -### Required Options - -| Option | Type | Description | -|--------|------|-------------| -| `inputSpec` | string | Path to the OpenAPI specification file (local file or URL) | -| `outputPath` | string | Output directory for the generated client | - -### Core Options - -| Option | Type | Default | Description | -|--------|------|---------|-------------| -| `configFile` | string | - | Path to OpenAPI Generator configuration file | -| `skipValidateSpec` | boolean | `false` | Skip validation of the OpenAPI specification | -| `auth` | string | - | Authentication for remote specs (e.g., `bearer:token`) | - -### Naming Options - -| Option | Type | Description | -|--------|------|-------------| -| `apiNameSuffix` | string | Suffix to append to API class names | -| `apiPackage` | string | Package name for API classes | -| `packageName` | string | Package name for the generated library | -| `modelNamePrefix` | string | Prefix for model class names | -| `modelNameSuffix` | string | Suffix for model class names | -| `modelPackage` | string | Package name for model classes | - -### Project Information - -| Option | Type | Description | -|--------|------|-------------| -| `artifactId` | string | Artifact ID for the generated project | -| `artifactVersion` | string | Artifact version | -| `groupId` | string | Group ID for Maven-style organization | - -### Generation Behavior - -| Option | Type | Default | Description | -|--------|------|---------|-------------| -| `dryRun` | boolean | `false` | Perform dry run without generating files | -| `enablePostProcessFile` | boolean | `false` | Enable post-processing of files | -| `minimalUpdate` | boolean | `false` | Only update changed files | -| `skipOverwrite` | boolean | `false` | Don't overwrite existing files | -| `removeOperationIdPrefix` | boolean | `false` | Remove operation ID prefixes | -| `skipOperationExample` | boolean | `false` | Skip operation examples | -| `strictSpec` | boolean | `false` | Use strict spec validation | - -### Template Customization - -| Option | Type | Description | -|--------|------|-------------| -| `templateDirectory` | string | Custom templates directory | -| `ignoreFileOverride` | string | Custom ignore file path | - -### Global Properties - -| Option | Type | Description | -|--------|------|-------------| -| `globalProperties` | object | Properties passed to OpenAPI Generator | - -### Git Integration - -| Option | Type | Description | -|--------|------|-------------| -| `gitHost` | string | Git host (e.g., `github.com`) | -| `gitUserId` | string | Git user/organization ID | -| `gitRepoId` | string | Git repository ID | - -### Other Options - -| Option | Type | Description | -|--------|------|-------------| -| `httpUserAgent` | string | Custom HTTP user agent | -| `releaseNote` | string | Release notes for generated code | -| `inputSpecRootDirectory` | string | Root directory for specs | -| `invokerPackage` | string | Package for invoker classes | -| `logToStderr` | boolean | Log to stderr instead of stdout | - -## Configuration Examples - -### Basic Configuration - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@lambda-solutions/nx-plugin-openapi:generate-api", - "options": { - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src" - } - } - } -} -``` - -### With Global Properties - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@lambda-solutions/nx-plugin-openapi:generate-api", - "options": { - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src", - "globalProperties": { - "supportsES6": "true", - "npmName": "@my-org/api-client", - "npmVersion": "1.0.0", - "providedInRoot": "true", - "withInterfaces": "true", - "useSingleRequestParameter": "true" - } - } - } - } -} -``` - -### Using a Configuration File +All [OpenAPI Generator CLI options](https://openapi-generator.tech/docs/usage/#generate) are supported (`configFile`, `globalProperties`, `skipValidateSpec`, etc.). -```json title="apps/my-app/openapi-config.json" -{ - "npmName": "@my-org/api-client", - "npmVersion": "1.0.0", - "ngVersion": "17.0.0", - "providedInRoot": true, - "withInterfaces": true, - "useSingleRequestParameter": true, - "supportsES6": true, - "modelPropertyNaming": "camelCase", - "enumPropertyNaming": "UPPERCASE" -} -``` +## Migrate to modular packages -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@lambda-solutions/nx-plugin-openapi:generate-api", - "options": { - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src", - "configFile": "apps/my-app/openapi-config.json" - } - } - } -} -``` - -### Remote OpenAPI Specification - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@lambda-solutions/nx-plugin-openapi:generate-api", - "options": { - "inputSpec": "https://api.example.com/v1/swagger.json", - "outputPath": "libs/api-client/src", - "auth": "bearer:your-api-token" - } - } - } -} -``` - -### Environment-Specific Configurations - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@lambda-solutions/nx-plugin-openapi:generate-api", - "options": { - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src" - }, - "configurations": { - "development": { - "inputSpec": "http://localhost:3000/api/swagger.json", - "skipValidateSpec": true - }, - "production": { - "inputSpec": "https://api.prod.example.com/swagger.json", - "strictSpec": true - } - } - } - } -} -``` - -Run with a specific configuration: - -```bash -nx run my-app:generate-api:development -``` - -## Nx Caching - -The plugin fully supports Nx's caching system. Generated output is cached based on: - -- The OpenAPI specification file content -- All configuration options -- Plugin version - -To enable caching in CI, configure [Nx Cloud](https://nx.app/) or local caching. - -## Verification - -After installation, verify the plugin is working: - -```bash -nx list @lambda-solutions/nx-plugin-openapi -``` - -Expected output: - -``` -@lambda-solutions/nx-plugin-openapi - -Executors: -- generate-api : Generate API client code from OpenAPI specifications -``` - -## Troubleshooting - -### Java Not Found - -OpenAPI Generator requires Java 8+: - -```bash -java -version -``` - -If Java isn't installed, download it from [adoptium.net](https://adoptium.net/). - -### Spec Validation Errors - -Skip validation if needed: - -```json -{ - "skipValidateSpec": true -} -``` - -### Caching Issues - -Clear the Nx cache if you encounter stale output: - -```bash -nx reset -``` - -## Migration to Modular Architecture - -To migrate to the new modular architecture: - -1. Install the new packages: +1. Install: ```bash - npm install --save-dev @nx-plugin-openapi/core @nx-plugin-openapi/plugin-openapi + npm install -D @nx-plugin-openapi/core @nx-plugin-openapi/plugin-openapi ``` -2. Update your executor: +2. Update executor: ```json { "executor": "@nx-plugin-openapi/core:generate-api", "options": { "generator": "openapi-tools", - // ... other options remain the same + "inputSpec": "apps/my-app/swagger.json", + "outputPath": "libs/api-client/src" } } ``` -3. Optionally remove the legacy package: +3. Uninstall legacy: ```bash npm uninstall @lambda-solutions/nx-plugin-openapi ``` - -## Support - -- [GitHub Issues](https://github.com/berger-engineering-io/nx-plugin-openapi/issues) - Report bugs and request features -- [Documentation](https://berger-engineering-io.github.io/nx-plugin-openapi/) - Full documentation site - -## License - -MIT diff --git a/apps/docs/src/content/docs/plugins/overview.md b/apps/docs/src/content/docs/plugins/overview.md deleted file mode 100644 index e547e46..0000000 --- a/apps/docs/src/content/docs/plugins/overview.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: Plugins Overview -description: Learn about the available plugins for Nx Plugin OpenAPI ---- - -# Plugins Overview - -The Nx Plugin OpenAPI ecosystem provides a modular plugin architecture, allowing you to choose the code generator that best fits your project's needs. - -## Available Plugins - -| Plugin | Package | Generator Value | Description | -|--------|---------|-----------------|-------------| -| [OpenAPI Generator](/plugins/plugin-openapi/) | `@nx-plugin-openapi/plugin-openapi` | `openapi-tools` | Uses the battle-tested [OpenAPI Generator](https://openapi-generator.tech) | -| [hey-api](/plugins/plugin-hey-api/) | `@nx-plugin-openapi/plugin-hey-api` | `hey-api` | Uses [hey-api/openapi-ts](https://github.com/hey-api/openapi-ts) for modern TypeScript clients | - -:::note[Legacy Package] -Looking for the original `@lambda-solutions/nx-plugin-openapi` package? See the [Legacy Nx Plugin](/legacy-nx-plugin/overview/) section. -::: - -## Architecture - -The plugin system is built around a core package that provides: - -- The `generate-api` executor -- Plugin loading and auto-installation -- Common configuration handling - -``` -┌─────────────────────────────────────────────────────────────┐ -│ @nx-plugin-openapi/core │ -│ Executor, Plugin Loader, Auto-Installation │ -└─────────────────────────────────────────────────────────────┘ - │ - ┌───────────────────┼───────────────────┐ - ▼ ▼ ▼ -┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ -│ plugin-openapi │ │ plugin-hey-api │ │ Custom Plugins │ -│ (OpenAPI Gen) │ │ (hey-api) │ │ (Your own!) │ -└──────────────────┘ └──────────────────┘ └──────────────────┘ -``` - -## Choosing a Plugin - -### OpenAPI Generator (`openapi-tools`) - -**Best for:** -- Angular applications needing injectable services -- Projects requiring specific OpenAPI Generator templates -- Teams familiar with the OpenAPI Generator ecosystem -- Supporting multiple languages/frameworks from a single spec - -**Features:** -- 50+ language/framework generators -- Extensive customization via templates -- Mature, battle-tested tooling - -### hey-api (`hey-api`) - -**Best for:** -- Modern TypeScript/JavaScript projects -- Projects prioritizing type safety and tree-shaking -- Fetch-based or Axios HTTP clients -- Simpler, more lightweight generated code - -**Features:** -- TypeScript-first approach -- Excellent type inference -- Plugin-based architecture for customization -- Modern ESM output - -## Using Multiple Generators - -You can use different generators for different projects in your monorepo: - -```json title="libs/angular-client/project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "openapi-tools", - "inputSpec": "specs/api.yaml", - "outputPath": "libs/angular-client/src/generated" - } - } - } -} -``` - -```json title="libs/ts-client/project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "hey-api", - "inputSpec": "specs/api.yaml", - "outputPath": "libs/ts-client/src/generated" - } - } - } -} -``` - -## Creating Custom Plugins - -Need to integrate a different OpenAPI generator? The plugin architecture makes it easy to create custom plugins. See our [Creating Custom Plugins](/guides/creating-plugins/) guide for a complete walkthrough. - -## Next Steps - -- [OpenAPI Generator Plugin](/plugins/plugin-openapi/) - Full documentation for the OpenAPI Generator plugin -- [hey-api Plugin](/plugins/plugin-hey-api/) - Full documentation for the hey-api plugin -- [Creating Custom Plugins](/guides/creating-plugins/) - Build your own generator plugin diff --git a/apps/docs/src/content/docs/plugins/plugin-hey-api.md b/apps/docs/src/content/docs/plugins/plugin-hey-api.md index a71382a..c932d44 100644 --- a/apps/docs/src/content/docs/plugins/plugin-hey-api.md +++ b/apps/docs/src/content/docs/plugins/plugin-hey-api.md @@ -1,27 +1,17 @@ --- title: hey-api Plugin -description: Documentation for the @nx-plugin-openapi/plugin-hey-api plugin +description: Use hey-api/openapi-ts with Nx via @nx-plugin-openapi/plugin-hey-api --- -# hey-api Plugin +The `@nx-plugin-openapi/plugin-hey-api` plugin wraps [hey-api/openapi-ts](https://heyapi.dev/) -- modern TypeScript client generation with excellent type safety, tree-shaking, and no Java dependency. -The `@nx-plugin-openapi/plugin-hey-api` plugin integrates [hey-api/openapi-ts](https://github.com/hey-api/openapi-ts) with the Nx Plugin OpenAPI ecosystem. - -## Installation +## Install ```bash -# Install the core package and plugin -npm install --save-dev @nx-plugin-openapi/core @nx-plugin-openapi/plugin-hey-api - -# Install the peer dependency -npm install --save-dev @hey-api/openapi-ts +npm install -D @nx-plugin-openapi/core @nx-plugin-openapi/plugin-hey-api @hey-api/openapi-ts ``` -:::tip[Auto-Installation] -The plugin and its peer dependencies can be auto-installed. If you specify `"generator": "hey-api"` and the plugin isn't installed, the core package will attempt to install it automatically. -::: - -## Basic Usage +## Basic usage ```json title="project.json" { @@ -38,79 +28,56 @@ The plugin and its peer dependencies can be auto-installed. If you specify `"gen } ``` -## Configuration Options +## Options -Pass hey-api specific options via the `generatorOptions` property or directly in `options`. - -### Core Options +Pass hey-api options via `generatorOptions`. See [hey-api docs](https://heyapi.dev/) for all options. | Option | Type | Description | |--------|------|-------------| -| `generator` | string | Must be `"hey-api"` | -| `inputSpec` | string | Path to OpenAPI spec (local or URL) | -| `outputPath` | string | Output directory for generated code | +| `client` | `string` | HTTP client: `"@hey-api/client-fetch"`, `"@hey-api/client-axios"` | +| `plugins` | `array` | hey-api plugins to enable | +| `schemas` | `object` | Schema generation config | +| `services` | `object` | Service generation config | +| `types` | `object` | Type generation config | -### hey-api Options +## Example with plugins -| Option | Type | Description | -|--------|------|-------------| -| `client` | string | HTTP client to use (`"fetch"`, `"axios"`, etc.) | -| `plugins` | array | Array of hey-api plugins to enable | -| `schemas` | object | Schema generation options | -| `services` | object | Service generation options | -| `types` | object | Type generation options | - -## Client Selection - -hey-api supports multiple HTTP clients: - -### Fetch (Default) - -```json +```json title="project.json" { - "generator": "hey-api", - "inputSpec": "openapi.yaml", - "outputPath": "libs/api-client/src", - "generatorOptions": { - "client": "@hey-api/client-fetch" + "options": { + "generator": "hey-api", + "inputSpec": "apps/my-app/openapi.yaml", + "outputPath": "libs/api-client/src", + "generatorOptions": { + "client": "@hey-api/client-fetch", + "plugins": [ + "@hey-api/schemas", + { "name": "@hey-api/services", "asClass": true }, + { "name": "@hey-api/types", "enums": "javascript" } + ] + } } } ``` -### Axios +## TanStack Query ```json { - "generatorOptions": { - "client": "@hey-api/client-axios" - } -} -``` - -## Using Plugins - -hey-api has a plugin system for customizing output: - -```json -{ - "generator": "hey-api", - "inputSpec": "openapi.yaml", - "outputPath": "libs/api-client/src", "generatorOptions": { "client": "@hey-api/client-fetch", "plugins": [ - "@hey-api/schemas", "@hey-api/services", - { - "name": "@hey-api/types", - "enums": "javascript" - } + "@hey-api/types", + "@tanstack/react-query" ] } } ``` -### Available Plugins +Replace with `@tanstack/vue-query` for Vue. + +## Available plugins | Plugin | Description | |--------|-------------| @@ -121,119 +88,23 @@ hey-api has a plugin system for customizing output: | `@tanstack/react-query` | React Query integration | | `@tanstack/vue-query` | Vue Query integration | -## TanStack Query Integration - -hey-api has excellent TanStack Query support: +## Output structure -### React Query - -```json -{ - "generatorOptions": { - "client": "@hey-api/client-fetch", - "plugins": [ - "@hey-api/services", - "@hey-api/types", - "@tanstack/react-query" - ] - } -} ``` - -### Vue Query - -```json -{ - "generatorOptions": { - "client": "@hey-api/client-fetch", - "plugins": [ - "@hey-api/services", - "@hey-api/types", - "@tanstack/vue-query" - ] - } -} -``` - -## Type Generation Options - -Customize how types are generated: - -```json -{ - "generatorOptions": { - "plugins": [ - { - "name": "@hey-api/types", - "enums": "javascript", - "exportInlineEnums": true - } - ] - } -} +libs/api-client/src/ + client/ + schemas/ + services/ + types/ + index.ts ``` -### Enum Options +## When to choose hey-api over OpenAPI Generator -| Value | Description | -|-------|-------------| -| `"javascript"` | Generate JavaScript enums | -| `"typescript"` | Generate TypeScript enums | -| `false` | Use union types instead of enums | - -## Complete Example - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "hey-api", - "inputSpec": "apps/my-app/openapi.yaml", - "outputPath": "libs/api-client/src/generated", - "generatorOptions": { - "client": "@hey-api/client-fetch", - "plugins": [ - "@hey-api/schemas", - { - "name": "@hey-api/services", - "asClass": true - }, - { - "name": "@hey-api/types", - "enums": "javascript" - } - ] - } - } - } - } -} -``` - -## Why hey-api? - -- **TypeScript-first**: Designed from the ground up for TypeScript -- **Tree-shakeable**: Only import what you use -- **Modern output**: ESM modules, no legacy code -- **Type safety**: Excellent type inference -- **Plugin system**: Extensible architecture -- **Active development**: Regular updates and improvements - -## Comparison with OpenAPI Generator - -| Feature | hey-api | OpenAPI Generator | -|---------|---------|-------------------| -| Languages | TypeScript only | 50+ languages | -| Output size | Smaller, tree-shakeable | Larger, more complete | +| | hey-api | OpenAPI Generator | +|---|---------|-------------------| +| Languages | TypeScript only | 50+ | +| Output size | Smaller, tree-shakeable | Larger | | Type safety | Excellent | Good | -| Angular support | Basic | Excellent (injectable services) | -| Customization | Plugins | Templates | +| Angular DI | Basic | Excellent | | Java required | No | Yes | - -## Next Steps - -- [hey-api Documentation](https://heyapi.dev/) - Official hey-api docs -- [Configuration Reference](/usage/configuration/) - Full configuration options -- [Examples](/usage/examples/) - Common use cases diff --git a/apps/docs/src/content/docs/plugins/plugin-openapi.md b/apps/docs/src/content/docs/plugins/plugin-openapi.md index f1952c0..4a63040 100644 --- a/apps/docs/src/content/docs/plugins/plugin-openapi.md +++ b/apps/docs/src/content/docs/plugins/plugin-openapi.md @@ -1,27 +1,19 @@ --- title: OpenAPI Generator Plugin -description: Documentation for the @nx-plugin-openapi/plugin-openapi plugin +description: Use OpenAPI Generator with Nx via @nx-plugin-openapi/plugin-openapi --- -# OpenAPI Generator Plugin +The `@nx-plugin-openapi/plugin-openapi` plugin wraps [OpenAPI Generator](https://openapi-generator.tech) -- supporting 50+ languages and frameworks including TypeScript Angular. -The `@nx-plugin-openapi/plugin-openapi` plugin integrates [OpenAPI Generator](https://openapi-generator.tech) with the Nx Plugin OpenAPI ecosystem. - -## Installation +## Install ```bash -# Install the core package and plugin -npm install --save-dev @nx-plugin-openapi/core @nx-plugin-openapi/plugin-openapi - -# Install the peer dependency -npm install --save-dev @openapitools/openapi-generator-cli +npm install -D @nx-plugin-openapi/core @nx-plugin-openapi/plugin-openapi @openapitools/openapi-generator-cli ``` -:::tip[Auto-Installation] -The plugin and its peer dependencies can be auto-installed. If you specify `"generator": "openapi-tools"` and the plugin isn't installed, the core package will attempt to install it automatically. -::: +Requires **Java 8+** at runtime. -## Basic Usage +## Basic usage ```json title="project.json" { @@ -30,7 +22,7 @@ The plugin and its peer dependencies can be auto-installed. If you specify `"gen "executor": "@nx-plugin-openapi/core:generate-api", "options": { "generator": "openapi-tools", - "inputSpec": "apps/my-app/openapi.yaml", + "inputSpec": "apps/my-app/swagger.json", "outputPath": "libs/api-client/src" } } @@ -38,80 +30,36 @@ The plugin and its peer dependencies can be auto-installed. If you specify `"gen } ``` -## Configuration Options - -All [OpenAPI Generator CLI options](https://openapi-generator.tech/docs/usage/#generate) are supported. Pass them either directly in `options` or via the `generatorOptions` property. - -### Core Options - -| Option | Type | Description | -|--------|------|-------------| -| `generator` | string | Must be `"openapi-tools"` | -| `inputSpec` | string | Path to OpenAPI spec (local or URL) | -| `outputPath` | string | Output directory for generated code | -| `configFile` | string | Path to OpenAPI Generator config file | -| `skipValidateSpec` | boolean | Skip spec validation | - -### Naming Options - -| Option | Type | Description | -|--------|------|-------------| -| `apiNameSuffix` | string | Suffix for API class names | -| `apiPackage` | string | Package name for API classes | -| `modelNamePrefix` | string | Prefix for model class names | -| `modelNameSuffix` | string | Suffix for model class names | -| `modelPackage` | string | Package name for model classes | -| `packageName` | string | Package name for the generated library | - -### Generation Behavior - -| Option | Type | Description | -|--------|------|-------------| -| `dryRun` | boolean | Perform dry run without generating files | -| `minimalUpdate` | boolean | Only update changed files | -| `skipOverwrite` | boolean | Skip overwriting existing files | -| `removeOperationIdPrefix` | boolean | Remove operation ID prefixes | -| `strictSpec` | boolean | Use strict spec validation | +## Options -### Template Customization +All [OpenAPI Generator CLI options](https://openapi-generator.tech/docs/usage/#generate) are supported. Pass them directly in `options` or via `generatorOptions`. | Option | Type | Description | |--------|------|-------------| -| `templateDirectory` | string | Custom templates directory | -| `ignoreFileOverride` | string | Custom ignore file path | +| `configFile` | `string` | Path to an OpenAPI Generator config JSON file | +| `skipValidateSpec` | `boolean` | Skip spec validation | +| `globalProperties` | `object` | Key-value pairs passed to the generator | +| `apiNameSuffix` | `string` | Suffix for API class names | +| `modelNamePrefix` / `modelNameSuffix` | `string` | Prefix/suffix for model names | +| `templateDirectory` | `string` | Custom Mustache templates directory | +| `dryRun` | `boolean` | Preview without generating files | -### Global Properties - -```json -{ - "globalProperties": { - "supportsES6": "true", - "npmName": "@my-org/api-client", - "npmVersion": "1.0.0", - "providedInRoot": "true", - "withInterfaces": "true", - "useSingleRequestParameter": "true" - } -} -``` - -## Angular TypeScript Configuration - -For Angular projects, use these recommended settings: +## Angular example ```json title="project.json" { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "openapi-tools", - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src", - "globalProperties": { - "supportsES6": "true", - "providedInRoot": "true", - "withInterfaces": "true", - "useSingleRequestParameter": "true" + "targets": { + "generate-api": { + "executor": "@nx-plugin-openapi/core:generate-api", + "options": { + "generator": "openapi-tools", + "inputSpec": "apps/my-app/swagger.json", + "outputPath": "libs/api-client/src", + "globalProperties": { + "supportsES6": "true", + "providedInRoot": "true", + "withInterfaces": "true" + } } } } @@ -123,67 +71,35 @@ Or use a separate config file: ```json title="openapi-config.json" { "npmName": "@my-org/api-client", - "npmVersion": "1.0.0", "ngVersion": "17.0.0", "providedInRoot": true, "withInterfaces": true, - "useSingleRequestParameter": true, - "supportsES6": true, - "modelPropertyNaming": "camelCase", - "enumPropertyNaming": "UPPERCASE" + "supportsES6": true } ``` ```json title="project.json" { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "openapi-tools", - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src", - "configFile": "apps/my-app/openapi-config.json" - } + "options": { + "generator": "openapi-tools", + "inputSpec": "apps/my-app/swagger.json", + "outputPath": "libs/api-client/src", + "configFile": "apps/my-app/openapi-config.json" } } ``` -## Supported Generators +## Supported generators -OpenAPI Generator supports 50+ generators. Common ones include: +Default is `typescript-angular`. Other common choices: -- `typescript-angular` (default for this plugin) -- `typescript-fetch` -- `typescript-axios` -- `typescript-node` -- `java` -- `kotlin` -- `python` +- `typescript-fetch`, `typescript-axios`, `typescript-node` +- `java`, `kotlin`, `python`, `go` -See the [OpenAPI Generator documentation](https://openapi-generator.tech/docs/generators/) for the full list. +Full list: [openapi-generator.tech/docs/generators](https://openapi-generator.tech/docs/generators/) ## Troubleshooting -### Java Not Found - -OpenAPI Generator requires Java 8+. Ensure Java is installed and available in your PATH: - -```bash -java -version -``` - -### Spec Validation Errors - -If you're confident your spec is valid, you can skip validation: - -```json -{ - "skipValidateSpec": true -} -``` - -## Next Steps +**Java not found** -- OpenAPI Generator requires Java 8+. Check with `java -version`. -- [Configuration Reference](/usage/configuration/) - Full configuration options -- [Examples](/usage/examples/) - Common use cases -- [Nx Integration](/usage/nx-integration/) - Advanced Nx features +**Spec validation errors** -- Set `"skipValidateSpec": true` if your spec is valid but fails validation. diff --git a/apps/docs/src/content/docs/reference/configuration.md b/apps/docs/src/content/docs/reference/configuration.md new file mode 100644 index 0000000..cf22eb4 --- /dev/null +++ b/apps/docs/src/content/docs/reference/configuration.md @@ -0,0 +1,78 @@ +--- +title: Configuration Reference +description: All executor options for the generate-api executor +--- + +## Core options + +These apply to all generator plugins. + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `generator` | `string` | `"openapi-tools"` | `"openapi-tools"` or `"hey-api"` | +| `inputSpec` | `string \| object` | *required* | Path/URL to spec, or `{ name: path }` for multiple specs | +| `outputPath` | `string` | *required* | Output directory (cleaned before each run) | +| `generatorOptions` | `object` | `{}` | Options forwarded to the selected generator plugin | + +## OpenAPI Generator options (`openapi-tools`) + +Pass these directly in `options` or inside `generatorOptions`. Full reference: [openapi-generator.tech/docs/usage/#generate](https://openapi-generator.tech/docs/usage/#generate) + +| Option | Type | Description | +|--------|------|-------------| +| `configFile` | `string` | Path to config JSON file | +| `skipValidateSpec` | `boolean` | Skip spec validation | +| `globalProperties` | `object` | Key-value pairs passed to the generator | +| `apiNameSuffix` | `string` | Suffix for API class names | +| `modelNamePrefix` | `string` | Prefix for model class names | +| `modelNameSuffix` | `string` | Suffix for model class names | +| `packageName` | `string` | Package name for generated library | +| `templateDirectory` | `string` | Custom Mustache templates directory | +| `dryRun` | `boolean` | Preview without generating | +| `minimalUpdate` | `boolean` | Only update changed files | +| `skipOverwrite` | `boolean` | Don't overwrite existing files | +| `strictSpec` | `boolean` | Strict spec validation | +| `auth` | `string` | Auth for remote specs (e.g. `bearer:token`) | + +## hey-api options (`hey-api`) + +Pass these inside `generatorOptions`. Full reference: [heyapi.dev](https://heyapi.dev/) + +| Option | Type | Description | +|--------|------|-------------| +| `client` | `string` | HTTP client (`"@hey-api/client-fetch"`, `"@hey-api/client-axios"`) | +| `plugins` | `array` | hey-api plugins to enable | +| `schemas` | `object` | Schema generation config | +| `services` | `object` | Service generation config | +| `types` | `object` | Type generation config | + +## Environment-specific config + +Use Nx configurations for different environments: + +```json title="project.json" +{ + "targets": { + "generate-api": { + "executor": "@nx-plugin-openapi/core:generate-api", + "options": { + "generator": "hey-api", + "inputSpec": "apps/my-app/openapi.yaml", + "outputPath": "libs/api-client/src" + }, + "configurations": { + "dev": { + "inputSpec": "http://localhost:3000/api/openapi.json" + }, + "prod": { + "inputSpec": "https://api.example.com/openapi.json" + } + } + } + } +} +``` + +```bash +nx run my-app:generate-api:dev +``` diff --git a/apps/docs/src/content/docs/reference/generate-api.md b/apps/docs/src/content/docs/reference/generate-api.md deleted file mode 100644 index 079c71c..0000000 --- a/apps/docs/src/content/docs/reference/generate-api.md +++ /dev/null @@ -1,773 +0,0 @@ ---- -title: generate-api Executor -description: Complete reference for the generate-api executor ---- - -# generate-api Executor - -The `generate-api` executor generates API client code from OpenAPI specifications using your choice of generator plugin. - -## Usage - -```bash -nx run :generate-api -``` - -## Basic Configuration - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "openapi-tools", - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src" - } - } - } -} -``` - -## Core Options - -These options are available for all generator plugins. - -### `generator` - -- **Type:** `string` -- **Default:** `"openapi-tools"` -- **Required:** No -- **Description:** Specifies which generator plugin to use - -**Available values:** -- `"openapi-tools"` - Uses OpenAPI Generator CLI (`@openapitools/openapi-generator-cli`) -- `"hey-api"` - Uses hey-api (`@hey-api/openapi-ts`) - -**Examples:** -```json -{ - "generator": "openapi-tools" -} -``` - -```json -{ - "generator": "hey-api" -} -``` - -### `inputSpec` - -- **Type:** `string | Record` -- **Required:** Yes -- **Description:** Path to the OpenAPI specification file(s) or URL(s) - -The input specification can be: -- A single string: Path to one OpenAPI specification (backward compatible) -- An object: Multiple specifications mapped by service name (for microservices) - -#### Single Specification (String) - -For projects with a single API: - -```json -{ - "inputSpec": "apps/my-app/swagger.json" -} -``` - -```json -{ - "inputSpec": "https://api.example.com/swagger.json" -} -``` - -#### Multiple Specifications (Object) - -For microservice architectures with multiple APIs: - -```json -{ - "inputSpec": { - "ms-product": "apps/my-app/ms-product.json", - "ms-user": "apps/my-app/ms-user.json", - "ms-inventory": "apps/my-app/ms-inventory.json" - } -} -``` - -When using multiple specifications: -- Each key becomes a subdirectory name under `outputPath` -- Each API is generated in its own subdirectory -- All configured options are applied to each generation - -**Generated structure for multiple specs:** -``` -libs/api/src/ - ms-product/ - // generated API for product service - ms-user/ - // generated API for user service - ms-inventory/ - // generated API for inventory service -``` - -### `outputPath` - -- **Type:** `string` -- **Required:** Yes -- **Description:** Output directory for the generated API client code - -The output directory will be cleaned before generation. Relative paths are resolved from the workspace root. - -**Examples:** -```json -{ - "outputPath": "libs/api-client/src" -} -``` - -```json -{ - "outputPath": "apps/my-app/src/app/generated" -} -``` - -### `generatorOptions` - -- **Type:** `object` -- **Default:** `{}` -- **Required:** No -- **Description:** Plugin-specific options passed to the generator - -This object allows you to pass options specific to the selected generator. The available options depend on which generator you're using. - -**Example for OpenAPI Generator:** -```json -{ - "generatorOptions": { - "configFile": "apps/my-app/openapi-config.json", - "skipValidateSpec": true, - "globalProperties": { - "supportsES6": "true" - } - } -} -``` - -**Example for hey-api:** -```json -{ - "generatorOptions": { - "client": "fetch", - "plugins": ["@hey-api/schemas"] - } -} -``` - ---- - -## OpenAPI Generator Options - -The following options apply when using `generator: "openapi-tools"`. They can be specified directly in `options` or within `generatorOptions`. - -### `configFile` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Path to OpenAPI Generator configuration file - -Allows you to specify detailed generation options in a separate JSON file. - -**Example:** -```json -{ - "configFile": "apps/my-app/openapi-config.json" -} -``` - -### `skipValidateSpec` - -- **Type:** `boolean` -- **Default:** `false` -- **Description:** Skip validation of the OpenAPI specification - -Set to `true` for faster generation when you're confident your specification is valid. - -**Example:** -```json -{ - "skipValidateSpec": true -} -``` - -## Authentication & Security - -### `auth` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Authentication configuration for accessing remote specifications - -**Example:** -```json -{ - "auth": "bearer:your-api-token" -} -``` - -## Naming & Package Configuration - -### `apiNameSuffix` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Suffix to append to generated API class names - -**Example:** -```json -{ - "apiNameSuffix": "Client" -} -``` - -### `apiPackage` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Package name for API classes - -**Example:** -```json -{ - "apiPackage": "com.example.api" -} -``` - -### `packageName` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Package name for the generated client library - -**Example:** -```json -{ - "packageName": "@my-org/api-client" -} -``` - -### `modelNamePrefix` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Prefix for generated model class names - -**Example:** -```json -{ - "modelNamePrefix": "Api" -} -``` - -### `modelNameSuffix` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Suffix for generated model class names - -**Example:** -```json -{ - "modelNameSuffix": "Model" -} -``` - -### `modelPackage` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Package name for model classes - -**Example:** -```json -{ - "modelPackage": "com.example.models" -} -``` - -## Project Metadata - -### `artifactId` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Artifact ID for the generated code - -**Example:** -```json -{ - "artifactId": "my-api-client" -} -``` - -### `artifactVersion` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Version of the generated artifact - -**Example:** -```json -{ - "artifactVersion": "1.0.0" -} -``` - -### `groupId` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Group ID for the generated code - -**Example:** -```json -{ - "groupId": "com.example" -} -``` - -## Generation Behavior - -### `dryRun` - -- **Type:** `boolean` -- **Default:** `false` -- **Description:** Perform a dry run without actually generating files - -Useful for testing configuration without creating files. - -**Example:** -```json -{ - "dryRun": true -} -``` - -### `enablePostProcessFile` - -- **Type:** `boolean` -- **Default:** `false` -- **Description:** Enable post-processing of generated files - -**Example:** -```json -{ - "enablePostProcessFile": true -} -``` - -### `minimalUpdate` - -- **Type:** `boolean` -- **Default:** `false` -- **Description:** Only update files that have actually changed - -**Example:** -```json -{ - "minimalUpdate": true -} -``` - -### `skipOverwrite` - -- **Type:** `boolean` -- **Default:** `false` -- **Description:** Skip overwriting existing files - -**Example:** -```json -{ - "skipOverwrite": true -} -``` - -### `removeOperationIdPrefix` - -- **Type:** `boolean` -- **Default:** `false` -- **Description:** Remove operation ID prefixes from generated method names - -**Example:** -```json -{ - "removeOperationIdPrefix": true -} -``` - -### `skipOperationExample` - -- **Type:** `boolean` -- **Default:** `false` -- **Description:** Skip generating operation examples in the code - -**Example:** -```json -{ - "skipOperationExample": true -} -``` - -### `strictSpec` - -- **Type:** `boolean` -- **Default:** `false` -- **Description:** Use strict specification validation - -**Example:** -```json -{ - "strictSpec": true -} -``` - -## Templates & Customization - -### `templateDirectory` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Directory containing custom templates for code generation - -**Example:** -```json -{ - "templateDirectory": "apps/my-app/templates" -} -``` - -### `ignoreFileOverride` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Path to a custom ignore file - -**Example:** -```json -{ - "ignoreFileOverride": "apps/my-app/.openapi-generator-ignore" -} -``` - -## Advanced Configuration - -### `globalProperties` - -- **Type:** `object` -- **Default:** `undefined` -- **Description:** Global properties for the OpenAPI Generator - -An object where keys are property names and values are property values. - -**Example:** -```json -{ - "globalProperties": { - "supportsES6": "true", - "npmName": "@my-org/api-client", - "npmVersion": "1.0.0", - "providedInRoot": "true", - "withInterfaces": "true" - } -} -``` - -### `httpUserAgent` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Custom HTTP user agent string - -**Example:** -```json -{ - "httpUserAgent": "MyApp/1.0.0" -} -``` - -### `releaseNote` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Release notes for the generated code - -**Example:** -```json -{ - "releaseNote": "Initial release of the API client" -} -``` - -### `inputSpecRootDirectory` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Root directory for input specifications - -**Example:** -```json -{ - "inputSpecRootDirectory": "specs/" -} -``` - -### `invokerPackage` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Package name for invoker classes - -**Example:** -```json -{ - "invokerPackage": "com.example.invoker" -} -``` - -## Git Integration - -### `gitHost` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Git host for the repository - -**Example:** -```json -{ - "gitHost": "github.com" -} -``` - -### `gitUserId` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Git user ID - -**Example:** -```json -{ - "gitUserId": "my-username" -} -``` - -### `gitRepoId` - -- **Type:** `string` -- **Default:** `undefined` -- **Description:** Git repository ID - -**Example:** -```json -{ - "gitRepoId": "my-api-client" -} -``` - -## Logging & Debugging - -### `logToStderr` - -- **Type:** `boolean` -- **Default:** `false` -- **Description:** Log output to stderr instead of stdout - -**Example:** -```json -{ - "logToStderr": true -} -``` - -## Complete Example - -Here's a comprehensive example showing many options: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/demo/swagger.json", - "outputPath": "libs/api-client/src", - "configFile": "apps/demo/openapi-config.json", - "packageName": "@my-org/demo-api-client", - "apiNameSuffix": "Service", - "modelNamePrefix": "Api", - "modelNameSuffix": "Model", - "skipValidateSpec": false, - "strictSpec": true, - "globalProperties": { - "supportsES6": "true", - "npmName": "@my-org/demo-api-client", - "npmVersion": "1.0.0", - "providedInRoot": "true", - "withInterfaces": "true" - } - }, - "outputs": ["{options.outputPath}"] - } - } -} -``` - -### Multiple APIs Example - -For microservice architectures: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": { - "auth-service": "apis/auth-service.yaml", - "product-service": "apis/product-service.yaml", - "order-service": "apis/order-service.yaml", - "payment-service": "apis/payment-service.yaml" - }, - "outputPath": "libs/api-clients/src", - "packageName": "@my-org/api-clients", - "apiNameSuffix": "ApiService", - "modelNamePrefix": "Api", - "globalProperties": { - "supportsES6": "true", - "providedInRoot": "true", - "withInterfaces": "true" - } - }, - "outputs": ["{options.outputPath}"] - } - } -} -``` - -This will generate: -``` -libs/api-clients/src/ - auth-service/ - // Auth API client - product-service/ - // Product API client - order-service/ - // Order API client - payment-service/ - // Payment API client -``` - -## Environment-Specific Configuration - -Use configurations for different environments: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/demo/swagger.json", - "outputPath": "libs/api-client/src" - }, - "configurations": { - "development": { - "inputSpec": "http://localhost:3000/api/swagger.json", - "skipValidateSpec": true - }, - "production": { - "inputSpec": "https://api.prod.example.com/swagger.json", - "strictSpec": true - } - } - } - } -} -``` - -Run with configuration: -```bash -nx run demo:generate-api:development -``` - ---- - -## hey-api Generator Options - -The following options apply when using `generator: "hey-api"`. Pass them via `generatorOptions`. - -### Common hey-api Options - -| Option | Type | Description | -|--------|------|-------------| -| `client` | string | HTTP client to use (`"fetch"`, `"axios"`, etc.) | -| `plugins` | array | Array of plugins to enable | -| `schemas` | object | Schema generation configuration | -| `services` | object | Service generation configuration | -| `types` | object | Type generation configuration | - -For a complete list of options, see the [hey-api documentation](https://heyapi.dev/). - -### hey-api Example - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "hey-api", - "inputSpec": "apps/demo/openapi.yaml", - "outputPath": "libs/api-client/src", - "generatorOptions": { - "client": "fetch", - "plugins": [ - "@hey-api/schemas", - "@hey-api/services", - "@hey-api/types" - ] - } - }, - "outputs": ["{options.outputPath}"] - } - } -} -``` - -### hey-api Multiple Services Example - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "hey-api", - "inputSpec": { - "users": "apis/users-api.yaml", - "products": "apis/products-api.yaml" - }, - "outputPath": "libs/api-clients/src", - "generatorOptions": { - "client": "axios" - } - }, - "outputs": ["{options.outputPath}"] - } - } -} -``` \ No newline at end of file diff --git a/apps/docs/src/content/docs/usage/configuration.md b/apps/docs/src/content/docs/usage/configuration.md deleted file mode 100644 index e58e5d0..0000000 --- a/apps/docs/src/content/docs/usage/configuration.md +++ /dev/null @@ -1,372 +0,0 @@ ---- -title: Configuration -description: Learn how to configure the generate-api executor with all available options ---- - -# Configuration - -The `generate-api` executor offers extensive configuration options to customize the generated API client code. This page covers all available configuration options and how to use them effectively. - -## Basic Configuration - -At minimum, you need to specify the generator, input specification, and output path: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "openapi-tools", - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src" - } - } - } -} -``` - -## Core Options - -These options are available for all generators: - -| Option | Type | Default | Description | -|--------|------|---------|-------------| -| `generator` | string | `"openapi-tools"` | Generator plugin to use (`"openapi-tools"` or `"hey-api"`) | -| `inputSpec` | string \| object | *required* | Path to the OpenAPI specification file (local file or URL), or an object for multiple specs | -| `outputPath` | string | *required* | Output directory for the generated client | -| `generatorOptions` | object | `{}` | Plugin-specific options passed to the generator | - -## Generator Selection - -### `generator` - -Specifies which generator plugin to use: - -```json -{ - "generator": "openapi-tools" -} -``` - -Available values: -- `"openapi-tools"` - Uses OpenAPI Generator CLI (default) -- `"hey-api"` - Uses hey-api/openapi-ts - -## Plugin-Specific Options - -Each generator has its own set of options. Pass them via the `generatorOptions` property or directly in the options object. - -### OpenAPI Generator Options - -See [OpenAPI Generator docs](https://openapi-generator.tech/docs/usage/#generate) for all available options. - -### hey-api Options - -See [hey-api documentation](https://heyapi.dev/) for configuration options. Common options include: -- `client` - HTTP client to use (e.g., `"fetch"`, `"axios"`) -- `plugins` - Array of plugins to enable -- `schemas` - Schema generation options - ---- - -## Detailed Options (OpenAPI Generator) - -The following options apply when using `generator: "openapi-tools"`. They can be specified directly in `options` or within `generatorOptions`. - -### Core Options - -### `configFile` -```json -{ - "configFile": "apps/my-app/openapi-config.json" -} -``` -Path to an OpenAPI Generator configuration file. This allows you to specify detailed generation options in a separate file. - -### `skipValidateSpec` -```json -{ - "skipValidateSpec": true -} -``` -Skip validation of the OpenAPI specification. Useful for faster generation when you're confident your spec is valid. - -## Authentication & Security - -### `auth` -```json -{ - "auth": "bearer:your-token-here" -} -``` -Authentication configuration for accessing remote OpenAPI specifications. - -## Naming & Organization - -### `apiNameSuffix` -```json -{ - "apiNameSuffix": "Client" -} -``` -Suffix to append to generated API class names. - -### `apiPackage` -```json -{ - "apiPackage": "com.example.api" -} -``` -Package name for API classes. - -### `packageName` -```json -{ - "packageName": "@my-org/api-client" -} -``` -Package name for the generated client library. - -### Model Naming - -```json -{ - "modelNamePrefix": "Api", - "modelNameSuffix": "Model", - "modelPackage": "com.example.models" -} -``` - -## Project Information - -### `artifactId` & `artifactVersion` -```json -{ - "artifactId": "my-api-client", - "artifactVersion": "1.0.0" -} -``` - -### `groupId` -```json -{ - "groupId": "com.example" -} -``` - -## Generation Behavior - -### `dryRun` -```json -{ - "dryRun": true -} -``` -Perform a dry run without actually generating files. Useful for testing configuration. - -### `enablePostProcessFile` -```json -{ - "enablePostProcessFile": true -} -``` -Enable post-processing of generated files. - -### `minimalUpdate` -```json -{ - "minimalUpdate": true -} -``` -Only update files that have actually changed. - -### `skipOverwrite` -```json -{ - "skipOverwrite": true -} -``` -Skip overwriting existing files. - -### `removeOperationIdPrefix` -```json -{ - "removeOperationIdPrefix": true -} -``` -Remove operation ID prefixes from generated method names. - -### `skipOperationExample` -```json -{ - "skipOperationExample": true -} -``` -Skip generating operation examples in the code. - -### `strictSpec` -```json -{ - "strictSpec": true -} -``` -Use strict specification validation. - -## Templates & Customization - -### `templateDirectory` -```json -{ - "templateDirectory": "apps/my-app/templates" -} -``` -Directory containing custom templates for code generation. - -### `ignoreFileOverride` -```json -{ - "ignoreFileOverride": "apps/my-app/.openapi-generator-ignore" -} -``` -Path to a custom ignore file. - -## Advanced Options - -### `globalProperties` -```json -{ - "globalProperties": { - "supportsES6": "true", - "npmName": "@my-org/api-client", - "npmVersion": "1.0.0", - "providedInRoot": "true", - "withInterfaces": "true", - "useSingleRequestParameter": "true" - } -} -``` -Global properties passed to the OpenAPI Generator. - -### `httpUserAgent` -```json -{ - "httpUserAgent": "MyApp/1.0.0" -} -``` -Custom HTTP user agent string. - -### `releaseNote` -```json -{ - "releaseNote": "Initial release of the API client" -} -``` -Release notes for the generated code. - -### `inputSpecRootDirectory` -```json -{ - "inputSpecRootDirectory": "specs/" -} -``` -Root directory for input specifications. - -### `invokerPackage` -```json -{ - "invokerPackage": "com.example.invoker" -} -``` -Package name for invoker classes. - -## Git Integration - -### Git Repository Information -```json -{ - "gitHost": "github.com", - "gitUserId": "my-username", - "gitRepoId": "my-api-client" -} -``` - -## Logging & Debugging - -### `logToStderr` -```json -{ - "logToStderr": true -} -``` -Log output to stderr instead of stdout. - -## Configuration File Example - -Instead of specifying all options in `project.json`, you can use a separate configuration file: - -```json title="apps/my-app/openapi-config.json" -{ - "npmName": "@my-org/api-client", - "npmVersion": "1.0.0", - "ngVersion": "17.0.0", - "providedInRoot": true, - "withInterfaces": true, - "useSingleRequestParameter": true, - "supportsES6": true, - "modelPropertyNaming": "camelCase", - "enumPropertyNaming": "UPPERCASE" -} -``` - -Then reference it: - -```json title="project.json" -{ - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src", - "configFile": "apps/my-app/openapi-config.json" - } - } -} -``` - -## Environment-Specific Configuration - -You can use different configurations for different environments: - -```json title="project.json" -{ - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src" - }, - "configurations": { - "development": { - "inputSpec": "http://localhost:3000/api/swagger.json", - "skipValidateSpec": true - }, - "production": { - "inputSpec": "https://api.prod.example.com/swagger.json", - "strictSpec": true - } - } - } -} -``` - -Run with specific configuration: -```bash -nx run my-app:generate-api:development -``` - -## Next Steps - -- [View Examples](/usage/examples/) for common configuration patterns -- [API Reference](/reference/options/) for complete option details -- [Nx Integration](/usage/nx-integration/) for advanced Nx workspace setup diff --git a/apps/docs/src/content/docs/usage/examples.md b/apps/docs/src/content/docs/usage/examples.md deleted file mode 100644 index 382bfdf..0000000 --- a/apps/docs/src/content/docs/usage/examples.md +++ /dev/null @@ -1,454 +0,0 @@ ---- -title: Examples -description: Common usage patterns and examples for the generate-api executor ---- - -# Examples - -This page provides practical examples for common use cases with the `generate-api` executor. Examples are provided for both the OpenAPI Generator (`openapi-tools`) and hey-api (`hey-api`) generators. - -## Basic Examples - -### Local OpenAPI Specification (OpenAPI Generator) - -Generate an API client from a local OpenAPI specification file using OpenAPI Generator: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "openapi-tools", - "inputSpec": "apps/demo/swagger.json", - "outputPath": "apps/demo/src/app/api" - }, - "outputs": ["{options.outputPath}"] - } - } -} -``` - -### Local OpenAPI Specification (hey-api) - -Generate an API client using hey-api: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "hey-api", - "inputSpec": "apps/demo/openapi.yaml", - "outputPath": "apps/demo/src/app/api" - }, - "outputs": ["{options.outputPath}"] - } - } -} -``` - -### Remote OpenAPI Specification - -Generate from a remote URL (works with both generators): - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "openapi-tools", - "inputSpec": "https://api.example.com/swagger.json", - "outputPath": "apps/demo/src/app/api" - } - } - } -} -``` - -:::tip[Caching with Remote URLs] -Nx caching works with remote URLs too! The executor will cache based on the content of the remote specification, so unchanged specs won't trigger regeneration. -::: - -## Configuration Examples - -### With Custom Configuration File - -Use a separate configuration file for detailed OpenAPI Generator options: - -```json title="apps/demo/openapi-config.json" -{ - "npmName": "@my-org/api-client", - "npmVersion": "1.0.0", - "ngVersion": "17.0.0", - "providedInRoot": true, - "withInterfaces": true, - "useSingleRequestParameter": true, - "supportsES6": true, - "modelPropertyNaming": "camelCase", - "enumPropertyNaming": "UPPERCASE" -} -``` - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/demo/openapi.json", - "outputPath": "apps/demo/src/app/api" - "configFile": "apps/demo/openapi-config.json" - } - } - } -} -``` - -## Advanced Examples - -### Custom Package Configuration - -Generate with custom package information and naming: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/demo/swagger.json", - "outputPath": "libs/api-client/src", - "packageName": "@my-org/demo-api-client", - "apiNameSuffix": "Service", - "modelNamePrefix": "Api", - "modelNameSuffix": "Model" - } - } - } -} -``` - -### Global Properties Configuration - -Use global properties for fine-tuned control: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/demo/swagger.json", - "outputPath": "libs/api-client/src", - "globalProperties": { - "supportsES6": "true", - "npmName": "@my-org/api-client", - "npmVersion": "2.0.0", - "providedInRoot": "true", - "withInterfaces": "true", - "useSingleRequestParameter": "true", - "enumPropertyNaming": "UPPERCASE" - } - } - } - } -} -``` - -### Authentication for Remote APIs - -Access protected OpenAPI specifications: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "https://api.example.com/swagger.json", - "outputPath": "libs/api-client/src", - "auth": "bearer:your-api-token-here", - "httpUserAgent": "MyApp/1.0.0" - } - } - } -} -``` - -### Custom Templates - -Use custom templates for code generation: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/demo/swagger.json", - "outputPath": "libs/api-client/src", - "templateDirectory": "apps/demo/templates", - "enablePostProcessFile": true - } - } - } -} -``` - -## Environment-Specific Examples - -### Development vs Production - -Configure different behaviors for different environments: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/demo/swagger.json", - "outputPath": "libs/api-client/src" - }, - "configurations": { - "development": { - "inputSpec": "http://localhost:3000/api/swagger.json", - "skipValidateSpec": true, - "dryRun": false - }, - "production": { - "inputSpec": "https://api.prod.example.com/swagger.json", - "strictSpec": true, - "skipValidateSpec": false - }, - "test": { - "dryRun": true, - "skipValidateSpec": true - } - } - } - } -} -``` - -Usage: -```bash -# Development environment -nx run demo:generate-api:development - -# Production environment -nx run demo:generate-api:production - -# Test run -nx run demo:generate-api:test -``` - -## Multiple API Clients - -### Separate Targets for Different APIs - -Generate multiple API clients from different specifications: - -```json title="project.json" -{ - "targets": { - "generate-user-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/demo/user-api.json", - "outputPath": "libs/user-api-client/src", - "packageName": "@my-org/user-api-client" - } - }, - "generate-product-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/demo/product-api.json", - "outputPath": "libs/product-api-client/src", - "packageName": "@my-org/product-api-client" - } - }, - "generate-all-apis": { - "executor": "nx:run-commands", - "options": { - "commands": [ - "nx run demo:generate-user-api", - "nx run demo:generate-product-api" - ], - "parallel": true - } - } - } -} -``` - -## Monorepo Examples - -### Shared Library Generation - -Generate a shared API client library used across multiple apps: - -```json title="libs/shared-api-client/project.json" -{ - "name": "shared-api-client", - "targets": { - "generate": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "https://api.company.com/swagger.json", - "outputPath": "libs/shared-api-client/src/lib/generated", - "packageName": "@my-org/shared-api-client", - "globalProperties": { - "providedInRoot": "true", - "ngVersion": "17.0.0" - } - } - }, - "build": { - "dependsOn": ["generate"] - } - } -} -``` - -### Workspace-Level Configuration - -Configure API generation at the workspace level in `nx.json`: - -```json title="nx.json" -{ - "targetDefaults": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "cache": true, - "inputs": [ - "{projectRoot}/swagger.json", - "{projectRoot}/openapi.json", - "{projectRoot}/api-spec.yaml", - "{projectRoot}/openapi-config.json" - ] - }, - "build": { - "dependsOn": ["^build", "^generate-api", "generate-api"] - } - } -} -``` - -## hey-api Specific Examples - -### Basic hey-api Configuration - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "hey-api", - "inputSpec": "apps/demo/openapi.yaml", - "outputPath": "libs/api-client/src", - "generatorOptions": { - "client": "fetch" - } - }, - "outputs": ["{options.outputPath}"] - } - } -} -``` - -### hey-api with Custom Plugins - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "hey-api", - "inputSpec": "apps/demo/openapi.yaml", - "outputPath": "libs/api-client/src", - "generatorOptions": { - "client": "axios", - "plugins": ["@hey-api/schemas", "@hey-api/services"] - } - } - } - } -} -``` - -### hey-api with Multiple Services - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "hey-api", - "inputSpec": { - "users-api": "apis/users-openapi.yaml", - "products-api": "apis/products-openapi.yaml" - }, - "outputPath": "libs/api-clients/src" - } - } - } -} -``` - -## Troubleshooting Examples - -### Debug Generation Issues (OpenAPI Generator) - -Use dry run to test configuration without generating files: - -```json title="project.json" -{ - "targets": { - "debug-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "openapi-tools", - "inputSpec": "apps/demo/swagger.json", - "outputPath": "libs/api-client/src", - "dryRun": true, - "logToStderr": true - } - } - } -} -``` - -### Handle Large APIs (OpenAPI Generator) - -For large OpenAPI specifications, optimize generation: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "openapi-tools", - "inputSpec": "apps/demo/large-api.json", - "outputPath": "libs/api-client/src", - "skipValidateSpec": true, - "minimalUpdate": true, - "skipOperationExample": true - } - } - } -} -``` - -## Next Steps - -- [Learn about Nx Integration](/usage/nx-integration/) for advanced workspace setup -- [API Reference](/reference/generate-api/) for complete option details -- [Configuration Guide](/usage/configuration/) for detailed option explanations diff --git a/apps/docs/src/content/docs/usage/nx-integration.md b/apps/docs/src/content/docs/usage/nx-integration.md deleted file mode 100644 index f40a261..0000000 --- a/apps/docs/src/content/docs/usage/nx-integration.md +++ /dev/null @@ -1,456 +0,0 @@ ---- -title: Nx Integration -description: Learn how to integrate the generate-api executor with Nx's build system and caching ---- - -# Nx Integration - -The Nx Plugin OpenAPI is designed to work seamlessly with Nx's build system, caching, and dependency graph. This page explains how to set up advanced integration patterns. - -## Target Dependencies - -### Basic Dependency Setup - -Make your build process depend on API generation: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src" - } - }, - "build": { - "dependsOn": ["generate-api"] - } - } -} -``` - -### Cross-Project Dependencies - -Set up dependencies between projects: - -```json title="apps/frontend/project.json" -{ - "targets": { - "build": { - "dependsOn": ["^generate-api", "generate-api"] - } - } -} -``` - -This ensures that: -- `^generate-api` - All dependencies' `generate-api` targets run first -- `generate-api` - This project's `generate-api` target runs - -## Workspace-Level Configuration - -### Target Defaults - -Configure default behavior for all `generate-api` targets in your workspace: - -```json title="nx.json" -{ - "targetDefaults": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "cache": true, - "inputs": [ - "{projectRoot}/swagger.json", - "{projectRoot}/openapi.json", - "{projectRoot}/api-spec.yaml", - "{projectRoot}/openapi-config.json", - "{projectRoot}/openapitools.json" - ], - "outputs": ["{options.outputPath}"] - }, - "build": { - "dependsOn": ["^build", "^generate-api", "generate-api"] - }, - "test": { - "dependsOn": ["generate-api"] - } - } -} -``` - -## Caching Configuration - -### Input Files for Cache Invalidation - -Specify which files should trigger cache invalidation: - -```json title="nx.json" -{ - "targetDefaults": { - "generate-api": { - "cache": true, - "inputs": [ - "{projectRoot}/swagger.json", - "{projectRoot}/openapi.json", - "{projectRoot}/api-spec.yaml", - "{projectRoot}/openapi-config.json", - "{projectRoot}/openapitools.json", - "{projectRoot}/.openapi-generator-ignore", - "{projectRoot}/templates/**/*" - ] - } - } -} -``` - -### Remote URL Caching - -For remote OpenAPI specifications, the executor automatically handles caching based on content: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "https://api.example.com/swagger.json", - "outputPath": "libs/api-client/src" - } - } - } -} -``` - -The cache key includes the remote URL content, so: -- ✅ Same content = cache hit -- ✅ Changed content = cache miss and regeneration -- ⚠️ Remote fetch happens on every run to check for changes - -### Output Configuration - -Specify outputs for proper caching: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src" - }, - "outputs": [ - "{options.outputPath}", - "libs/api-client/src" - ] - } - } -} -``` - -## Affected Commands - -### Run Generation for Affected Projects - -Generate API clients only for projects affected by changes: - -```bash -# Generate APIs for affected projects -nx affected --target=generate-api - -# Build affected projects (will generate APIs first due to dependencies) -nx affected --target=build -``` - -### Include API Specs in Affected Analysis - -Make sure OpenAPI specification changes trigger affected analysis: - -```json title="nx.json" -{ - "implicitDependencies": { - "shared-api-spec.json": ["user-service", "product-service"], - "common-types.yaml": "*" - } -} -``` - -## Project Graph Integration - -### Visualize Dependencies - -View how API generation fits into your project graph: - -```bash -nx graph -``` - -This will show: -- Which projects depend on generated API clients -- How API generation targets relate to build targets -- The overall dependency flow - -### Implicit Dependencies - -Create implicit dependencies for shared API specifications: - -```json title="nx.json" -{ - "implicitDependencies": { - "shared/api-specs/user-api.json": ["frontend", "mobile-app"], - "shared/api-specs/common.yaml": "*" - } -} -``` - -## Advanced Patterns - -### Multi-Stage Generation - -Set up complex generation pipelines: - -```json title="project.json" -{ - "targets": { - "generate-types": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "shared/specs/types.yaml", - "outputPath": "libs/shared-types/src" - } - }, - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "dependsOn": ["generate-types"], - "options": { - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src" - } - }, - "build": { - "dependsOn": ["generate-api"] - } - } -} -``` - -### Parallel Generation - -Generate multiple API clients in parallel: - -```json title="nx.json" -{ - "targetDefaults": { - "generate-user-api": { - "executor": "@nx-plugin-openapi/core:generate-api" - }, - "generate-product-api": { - "executor": "@nx-plugin-openapi/core:generate-api" - }, - "generate-all-apis": { - "executor": "nx:run-commands", - "options": { - "commands": [ - "nx run my-app:generate-user-api", - "nx run my-app:generate-product-api" - ], - "parallel": true - } - } - } -} -``` - -### Conditional Generation - -Use environment variables for conditional generation: - -```json title="project.json" -{ - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src" - }, - "configurations": { - "development": { - "inputSpec": "http://localhost:3000/api/swagger.json" - }, - "production": { - "inputSpec": "https://api.prod.example.com/swagger.json" - } - } - } - } -} -``` - -## Performance Optimization - -### Cache Strategy - -Optimize caching for large monorepos: - -```json title="nx.json" -{ - "tasksRunnerOptions": { - "default": { - "runner": "nx/tasks-runners/default", - "options": { - "cacheableOperations": ["generate-api", "build", "test"], - "parallel": 3 - } - } - }, - "targetDefaults": { - "generate-api": { - "cache": true, - "inputs": [ - "{projectRoot}/swagger.json", - "{projectRoot}/openapi-config.json" - ], - "outputs": ["{options.outputPath}"] - } - } -} -``` - -### Distributed Caching - -Use Nx Cloud for distributed caching: - -```bash -# Connect to Nx Cloud -nx connect - -# All generate-api tasks will be cached in the cloud -nx run-many --target=generate-api --all -``` - -## CI/CD Integration - -### GitHub Actions - -```yaml title=".github/workflows/ci.yml" -name: CI - -on: [push, pull_request] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 # Needed for Nx affected commands - - - uses: actions/setup-node@v3 - with: - node-version: '18' - cache: 'npm' - - - run: npm ci - - # Set up Nx Cloud (optional) - - run: npx nx-cloud start-ci-run - - # Generate APIs for affected projects - - name: Generate API Clients - run: npx nx affected --target=generate-api --parallel=3 - - # Build affected projects - - name: Build - run: npx nx affected --target=build --parallel=3 - - # Test affected projects - - name: Test - run: npx nx affected --target=test --parallel=3 -``` - -### Jenkins Pipeline - -```groovy title="Jenkinsfile" -pipeline { - agent any - - stages { - stage('Install') { - steps { - sh 'npm ci' - } - } - - stage('Generate APIs') { - steps { - sh 'npx nx affected --target=generate-api --base=origin/main' - } - } - - stage('Build') { - steps { - sh 'npx nx affected --target=build --base=origin/main' - } - } - - stage('Test') { - steps { - sh 'npx nx affected --target=test --base=origin/main' - } - } - } - - post { - always { - publishHTML([ - allowMissing: false, - alwaysLinkToLastBuild: true, - keepAll: true, - reportDir: 'coverage', - reportFiles: 'index.html', - reportName: 'Coverage Report' - ]) - } - } -} -``` - -## Troubleshooting - -### Cache Issues - -If you're experiencing cache issues: - -```bash -# Clear cache -nx reset - -# Run with verbose output -nx run my-app:generate-api --verbose - -# Skip cache for debugging -nx run my-app:generate-api --skip-nx-cache -``` - -### Dependency Issues - -Check project dependencies: - -```bash -# View project graph -nx graph - -# Show project details -nx show project my-app - -# List all tasks -nx run-many --target=generate-api --dry-run -``` - -## Next Steps - -- [View Examples](/usage/examples/) for practical implementation patterns -- [API Reference](/reference/generate-api/) for complete executor documentation -- [Configuration Guide](/usage/configuration/) for detailed option explanations \ No newline at end of file diff --git a/packages/core/README.md b/packages/core/README.md index 4842f75..3a1bde4 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -1,35 +1,32 @@ # @nx-plugin-openapi/core -Core package for the Nx Plugin OpenAPI ecosystem. This package provides the plugin infrastructure, executor, and generators for code generation from OpenAPI specifications. +Core package for generating API clients from OpenAPI specs in Nx. Provides the executor, plugin loader, and generators. -## Installation +## Install ```bash -npm install --save-dev @nx-plugin-openapi/core +nx add @nx-plugin-openapi/core ``` -You'll also need to install a generator plugin: +Then install a generator plugin: ```bash -# For OpenAPI Generator -npm install --save-dev @nx-plugin-openapi/plugin-openapi @openapitools/openapi-generator-cli +# OpenAPI Generator (50+ languages, Angular services) +npm install -D @nx-plugin-openapi/plugin-openapi @openapitools/openapi-generator-cli -# For hey-api -npm install --save-dev @nx-plugin-openapi/plugin-hey-api @hey-api/openapi-ts +# hey-api (modern TypeScript, fetch/axios) +npm install -D @nx-plugin-openapi/plugin-hey-api @hey-api/openapi-ts ``` -## Features +## Usage -- **Plugin Architecture**: Extensible system supporting multiple code generators -- **Auto-Installation**: Plugins are automatically installed when needed -- **Multiple Specs**: Generate code from multiple OpenAPI specifications in a single target -- **Nx Integration**: Full support for caching, affected commands, and dependency graph +Add a target via the interactive generator: -## Executors - -### generate-api +```bash +nx g @nx-plugin-openapi/core:add-generate-api-target +``` -Generate API client code using a selected generator plugin. +Or configure `project.json` directly: ```json { @@ -37,8 +34,8 @@ Generate API client code using a selected generator plugin. "generate-api": { "executor": "@nx-plugin-openapi/core:generate-api", "options": { - "generator": "openapi-tools", - "inputSpec": "apps/my-app/swagger.json", + "generator": "hey-api", + "inputSpec": "apps/my-app/openapi.yaml", "outputPath": "libs/api-client/src" } } @@ -46,59 +43,39 @@ Generate API client code using a selected generator plugin. } ``` -#### Options - -| Option | Type | Default | Description | -|--------|------|---------|-------------| -| `generator` | string | `"openapi-tools"` | Generator plugin to use (`"openapi-tools"` or `"hey-api"`) | -| `inputSpec` | string \| object | *required* | Path to OpenAPI spec(s) | -| `outputPath` | string | *required* | Output directory | -| `generatorOptions` | object | `{}` | Plugin-specific options | - -## Generators - -### add-generate-api-target - -Add a `generate-api` target to an existing project. +Then run: ```bash -nx generate @nx-plugin-openapi/core:add-generate-api-target --project=my-app +nx run my-app:generate-api ``` -### init - -Initialize core plugin defaults in the workspace. +## Executor options -```bash -nx generate @nx-plugin-openapi/core:init -``` - -## Available Generator Plugins - -| Plugin | Package | Generator Name | -|--------|---------|----------------| -| OpenAPI Generator | `@nx-plugin-openapi/plugin-openapi` | `openapi-tools` | -| hey-api | `@nx-plugin-openapi/plugin-hey-api` | `hey-api` | - -## Plugin Development +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `generator` | `string` | `"openapi-tools"` | `"openapi-tools"` or `"hey-api"` | +| `inputSpec` | `string \| object` | *required* | Path/URL to spec, or `{ name: path }` for multiple | +| `outputPath` | `string` | *required* | Output directory | +| `generatorOptions` | `object` | `{}` | Options forwarded to the generator plugin | -The core package exports interfaces for building custom generator plugins: +## Plugin development ```typescript -import { GeneratorPlugin, GenerateOptionsBase, GeneratorContext } from '@nx-plugin-openapi/core'; +import { BaseGenerator, GeneratorPlugin, GenerateOptionsBase, GeneratorContext } from '@nx-plugin-openapi/core'; -export class MyGenerator implements GeneratorPlugin { +export class MyGenerator extends BaseGenerator implements GeneratorPlugin { readonly name = 'my-generator'; async generate(options: GenerateOptionsBase, ctx: GeneratorContext): Promise { - // Implementation + this.cleanOutput(ctx, options.outputPath); + // your generation logic } } -``` -## Documentation +export default new MyGenerator(); +``` -For comprehensive documentation, visit our [documentation site](https://berger-engineering-io.github.io/nx-plugin-openapi/). +See the [Creating Custom Plugins](https://berger-engineering-io.github.io/nx-plugin-openapi/guides/creating-plugins/) guide. ## License diff --git a/packages/nx-plugin-openapi/README.md b/packages/nx-plugin-openapi/README.md index 3a76360..b112b0e 100644 --- a/packages/nx-plugin-openapi/README.md +++ b/packages/nx-plugin-openapi/README.md @@ -1,30 +1,58 @@ -# @lambda-solutions/nx-plugin-openapi -Nx Plugin for seamless Nx integration of [OpenApi Generator](https://openapi-generator.tech) Angular client. +# @lambda-solutions/nx-plugin-openapi (Legacy) -## Features -* Executor for generating Angular API clients from OpenAPI specifications -* First class caching support +Original Nx plugin for [OpenAPI Generator](https://openapi-generator.tech) Angular clients. -![Setup](../../apps/docs/public/nx-plugin-openapi-setup.gif) +> **For new projects, use [`@nx-plugin-openapi/core`](../core/README.md) with a generator plugin instead.** It supports multiple generators and has a more flexible architecture. -## Installation +## Install -To install the Plugin in your Nx workspace, run the following command: ```bash nx add @lambda-solutions/nx-plugin-openapi ``` -Or if you prefer to install it manually, you can add it as a dev dependency: -```bash -npm install --save-dev @lambda-solutions/nx-plugin-openapi +## Usage + +```json +{ + "targets": { + "generate-api": { + "executor": "@lambda-solutions/nx-plugin-openapi:generate-api", + "options": { + "inputSpec": "apps/my-app/swagger.json", + "outputPath": "libs/api-client/src" + } + } + } +} ``` -## Docs -See [Docs](https://nx-plugin-openapi.lambda-solutions.io/) - -## Roadmap -See [official documentaiton](https://nx-plugin-openapi.lambda-solutions.io/roadmap/roadmap/) +```bash +nx run my-app:generate-api +``` +## Migrating to the modular packages + +1. Install: + ```bash + npm install -D @nx-plugin-openapi/core @nx-plugin-openapi/plugin-openapi + ``` + +2. Update executor in `project.json`: + ```json + { + "executor": "@nx-plugin-openapi/core:generate-api", + "options": { + "generator": "openapi-tools", + "inputSpec": "apps/my-app/swagger.json", + "outputPath": "libs/api-client/src" + } + } + ``` + +3. Remove legacy package: + ```bash + npm uninstall @lambda-solutions/nx-plugin-openapi + ``` ## License diff --git a/packages/plugin-hey-api/README.md b/packages/plugin-hey-api/README.md index 306f21f..34f7ded 100644 --- a/packages/plugin-hey-api/README.md +++ b/packages/plugin-hey-api/README.md @@ -1,17 +1,15 @@ # @nx-plugin-openapi/plugin-hey-api -Generator plugin for [hey-api/openapi-ts](https://github.com/hey-api/openapi-ts). This plugin integrates with `@nx-plugin-openapi/core` to provide modern TypeScript client generation from OpenAPI specifications. +[hey-api/openapi-ts](https://heyapi.dev/) plugin for `@nx-plugin-openapi/core`. Modern TypeScript client generation with excellent type safety. -## Installation +## Install ```bash -npm install --save-dev @nx-plugin-openapi/core @nx-plugin-openapi/plugin-hey-api @hey-api/openapi-ts +npm install -D @nx-plugin-openapi/core @nx-plugin-openapi/plugin-hey-api @hey-api/openapi-ts ``` ## Usage -Configure the `generate-api` executor with `generator: "hey-api"`: - ```json { "targets": { @@ -27,68 +25,44 @@ Configure the `generate-api` executor with `generator: "hey-api"`: } ``` -## Features - -- **Modern TypeScript**: Type-safe client generation with excellent TypeScript support -- **Multiple HTTP Clients**: Support for fetch, axios, and other HTTP clients -- **Plugin System**: Extensible via hey-api plugins -- **Lightweight Output**: Cleaner, more maintainable generated code - -## Options - -Pass hey-api options via `generatorOptions`. See the [hey-api documentation](https://heyapi.dev/) for all available options. - -| Option | Type | Description | -|--------|------|-------------| -| `client` | string | HTTP client to use (`"fetch"`, `"axios"`, etc.) | -| `plugins` | array | Array of hey-api plugins to enable | -| `schemas` | object | Schema generation configuration | -| `services` | object | Service generation configuration | -| `types` | object | Type generation configuration | +### With options -### Example with Options +Pass hey-api options via `generatorOptions`. See [hey-api docs](https://heyapi.dev/) for all options. ```json { - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "hey-api", - "inputSpec": "apps/my-app/openapi.yaml", - "outputPath": "libs/api-client/src", - "generatorOptions": { - "client": "fetch", - "plugins": [ - "@hey-api/schemas", - "@hey-api/services", - "@hey-api/types" - ] - } - } + "options": { + "generator": "hey-api", + "inputSpec": "apps/my-app/openapi.yaml", + "outputPath": "libs/api-client/src", + "generatorOptions": { + "client": "@hey-api/client-fetch", + "plugins": [ + "@hey-api/schemas", + "@hey-api/services", + { "name": "@hey-api/types", "enums": "javascript" } + ] } } } ``` -### Using Axios Client +### TanStack Query ```json { - "options": { - "generator": "hey-api", - "inputSpec": "apps/my-app/openapi.yaml", - "outputPath": "libs/api-client/src", - "generatorOptions": { - "client": "axios" - } + "generatorOptions": { + "client": "@hey-api/client-fetch", + "plugins": [ + "@hey-api/services", + "@hey-api/types", + "@tanstack/react-query" + ] } } ``` -## Multiple Specifications - -Generate clients for multiple APIs: +### Multiple specs ```json { @@ -98,47 +72,15 @@ Generate clients for multiple APIs: "users-api": "apis/users.yaml", "products-api": "apis/products.yaml" }, - "outputPath": "libs/api-clients/src", - "generatorOptions": { - "client": "fetch" - } + "outputPath": "libs/api-clients/src" } } ``` -This generates: -``` -libs/api-clients/src/ - users-api/ - // Users API client - products-api/ - // Products API client -``` - -## Generated Output Structure - -``` -libs/api-client/src/ -├── client/ -│ └── client.ts -├── schemas/ -│ └── ... -├── services/ -│ └── ... -├── types/ -│ └── ... -└── index.ts -``` - -## Peer Dependencies +## Peer dependencies - `@hey-api/openapi-ts` (^0.83.1) -## Documentation - -- [hey-api Documentation](https://heyapi.dev/) -- [Nx Plugin OpenAPI Documentation](https://berger-engineering-io.github.io/nx-plugin-openapi/) - ## License MIT diff --git a/packages/plugin-openapi/README.md b/packages/plugin-openapi/README.md index 864cef5..04f14a6 100644 --- a/packages/plugin-openapi/README.md +++ b/packages/plugin-openapi/README.md @@ -1,17 +1,15 @@ # @nx-plugin-openapi/plugin-openapi -Generator plugin for [OpenAPI Generator](https://openapi-generator.tech). This plugin integrates with `@nx-plugin-openapi/core` to provide code generation capabilities using the OpenAPI Generator CLI. +[OpenAPI Generator](https://openapi-generator.tech) plugin for `@nx-plugin-openapi/core`. Supports 50+ languages and frameworks including TypeScript Angular. -## Installation +## Install ```bash -npm install --save-dev @nx-plugin-openapi/core @nx-plugin-openapi/plugin-openapi @openapitools/openapi-generator-cli +npm install -D @nx-plugin-openapi/core @nx-plugin-openapi/plugin-openapi @openapitools/openapi-generator-cli ``` ## Usage -Configure the `generate-api` executor with `generator: "openapi-tools"`: - ```json { "targets": { @@ -27,68 +25,27 @@ Configure the `generate-api` executor with `generator: "openapi-tools"`: } ``` -## Features - -- **TypeScript Angular Generation**: Generate Angular services and models -- **Multiple Languages**: Support for 50+ languages via OpenAPI Generator -- **Custom Templates**: Use custom Mustache templates -- **Configuration Files**: External configuration via JSON files -- **Retry Mechanism**: Automatic retry on transient failures - -## Options +### With options -All [OpenAPI Generator CLI options](https://openapi-generator.tech/docs/usage/#generate) are supported. Common options include: - -| Option | Type | Description | -|--------|------|-------------| -| `configFile` | string | Path to configuration file | -| `skipValidateSpec` | boolean | Skip spec validation | -| `globalProperties` | object | Global generator properties | -| `apiNameSuffix` | string | Suffix for API class names | -| `modelNamePrefix` | string | Prefix for model class names | -| `modelNameSuffix` | string | Suffix for model class names | - -### Example with Options +All [OpenAPI Generator CLI options](https://openapi-generator.tech/docs/usage/#generate) are supported: ```json { - "targets": { - "generate-api": { - "executor": "@nx-plugin-openapi/core:generate-api", - "options": { - "generator": "openapi-tools", - "inputSpec": "apps/my-app/swagger.json", - "outputPath": "libs/api-client/src", - "configFile": "apps/my-app/openapi-config.json", - "globalProperties": { - "supportsES6": "true", - "npmName": "@my-org/api-client", - "providedInRoot": "true", - "withInterfaces": "true" - } - } + "options": { + "generator": "openapi-tools", + "inputSpec": "apps/my-app/swagger.json", + "outputPath": "libs/api-client/src", + "configFile": "apps/my-app/openapi-config.json", + "globalProperties": { + "supportsES6": "true", + "providedInRoot": "true", + "withInterfaces": "true" } } } ``` -### Configuration File Example - -```json title="openapi-config.json" -{ - "npmName": "@my-org/api-client", - "npmVersion": "1.0.0", - "ngVersion": "17.0.0", - "providedInRoot": true, - "withInterfaces": true, - "useSingleRequestParameter": true, - "supportsES6": true -} -``` - -## Multiple Specifications - -Generate clients for multiple APIs: +### Multiple specs ```json { @@ -103,14 +60,10 @@ Generate clients for multiple APIs: } ``` -## Peer Dependencies +## Peer dependencies - `@openapitools/openapi-generator-cli` (^2.20.2) - -## Documentation - -- [OpenAPI Generator Documentation](https://openapi-generator.tech/docs/generators/typescript-angular) -- [Nx Plugin OpenAPI Documentation](https://berger-engineering-io.github.io/nx-plugin-openapi/) +- Java 8+ (required by OpenAPI Generator) ## License