npm package: @interpriz/nextjs-service-generator
Description: Generate type-safe Next.js service layer from OpenAPI specifications
Author: interpriz
Latest version: 0.2.11

# Next.js Service Generator

Generate type-safe Next.js service layer from OpenAPI specifications with automatic Zod validation, TypeScript types, and Next.js cache revalidation tags.

## Features

✨ **Type-Safe** - Generate TypeScript interfaces and Zod schemas from OpenAPI specs  
🚀 **Next.js Optimized** - Built-in support for Next.js cache tags and revalidation  
🔄 **Automatic Updates** - Regenerate services when your API changes  
🔐 **Encrypted Templates** - AES-256-GCM protection for your code patterns  
🛠️ **Smart** - Respects `// ignore-generate` comments to preserve manual edits  
🎯 **Clean** - Auto-formats with ESLint and Prettier  
🤖 **AI-Powered** - MCP server integration for Claude Desktop and other AI assistants  
📦 **Flexible** - List services, schemas, and analyze your OpenAPI spec

## Table of Contents

- [Installation](#installation)
- [Setup](#setup-required-for-team-use)
- [Quick Start](#quick-start)
  - [CLI Usage](#cli-usage)
  - [MCP Server (AI Assistant)](#mcp-server-ai-assistant)
  - [Programmatic Usage](#programmatic-usage)
- [Configuration](#configuration)
- [CLI Features](#cli-features)
- [Generated Files](#generated-files)
- [Documentation](#documentation)
- [License](#license)

## Installation

```bash
npm install @interpriz/nextjs-service-generator
# or
yarn add @interpriz/nextjs-service-generator
# or
pnpm add @interpriz/nextjs-service-generator
```

## Setup (Required for Team Use)

This package uses AES-256-GCM encryption to protect sensitive code patterns. You need to set the encryption key:

### Option 1: Environment Variable (Recommended)

```bash
# Set in your .env file
GEN_SECRET="your-encryption-key-here"

# Or export in shell
export GEN_SECRET="your-encryption-key-here"

# Or execute inline
GEN_SECRET="your-encryption-key-here" npx nextjs-service-gen // args... when you don\'t have config file
```

### Option 2: CI/CD Secrets

```yaml
# GitHub Actions
env:
  GEN_SECRET: ${{ secrets.GEN_SECRET }}

# GitLab CI
variables:
  GEN_SECRET: $CI_GEN_SECRET
```

### Getting the Encryption Key

**For team members**: Get the `GEN_SECRET` from:
- Your team's password manager (1Password, LastPass, etc.)
- Team documentation (private wiki)
- CI/CD secrets manager
- Ask your team lead

**Important**: Never commit the encryption key to Git!

## Quick Start

### CLI Usage

```bash
# Basic usage
npx nextjs-service-gen --url http://localhost:3000/api/v1/openapi.json

# List available services
npx nextjs-service-gen --url http://localhost:3000/openapi.json --list-services

# List available schemas
npx nextjs-service-gen --url http://localhost:3000/openapi.json --list-schemas

# List schemas for specific services
npx nextjs-service-gen --url http://localhost:3000/openapi.json --list-schemas --services users,movies

# Generate only specific services
npx nextjs-service-gen --url http://localhost:3000/openapi.json --services users,movies

# With prefix filter
npx nextjs-service-gen --url http://localhost:3000/openapi.json --prefix /api/v1/client

# Interactive mode
npx nextjs-service-gen --url http://localhost:3000/openapi.json -i
```

### MCP Server (AI Assistant)

Use with Claude Desktop or other AI assistants that support the Model Context Protocol.

**⚠️ Requires GEN_SECRET:** Get encryption key from your team lead!

**See full documentation:** [MCP-INTEGRATION.md](./MCP-INTEGRATION.md)

Quick setup for Claude Desktop:

```json
{
  "mcpServers": {
    "nextjs-service-generator": {
      "command": "npx",
      "args": ["-y", "@interpriz/nextjs-service-generator-mcp"],
      "env": {
        "GEN_SECRET": "your-encryption-key-here",
        "OPENAPI_URL": "http://localhost:8000/api/v1/openapi.json",
        "ENDPOINT_PREFIX": "/api/v1/client"
      }
    }
  }
}
```

Then ask Claude:
```
Generate services from my OpenAPI spec
What schemas are used by the users service?
List all available services
```

### Programmatic Usage

```typescript
import { generateServices } from '@interpriz/nextjs-service-generator';

await generateServices({
  openApiUrl: 'http://localhost:3000/api/v1/openapi.json',
  outputDir: './src/services',
  runLinter: true,
  runFormatter: true,
});
```

## Configuration

### Config File

Create `nextjs-service-gen.config.json` in your project root:

```json
{
  "openApiUrl": "http://localhost:3000/api/v1/openapi.json",
  "outputDir": "./src/services",
  "endpointPrefix": "/api/v1/client",
  "skipFiles": ["auth", "admin"],
  "runLinter": true,
  "runFormatter": true
}
```

### CLI Options

```bash
Options:
  --url <url>          OpenAPI specification URL (required)
  --output <dir>       Output directory (default: ./src/services)
  --prefix <prefix>    Endpoint prefix to filter (e.g., /api/v1/client)
  --services <list>    Generate only specific services (comma-separated)
  --skip <files>       Skip files (services or base: types,fetch-client,actions)
  --list-services      List available services without generating
  --list-schemas       List available schemas without generating
  --interactive, -i    Interactive mode to choose endpoint prefix
  --no-lint            Skip ESLint formatting
  --no-format          Skip Prettier formatting
  --help, -h           Show help
```

## CLI Features

### List Available Services

See what services are available in your OpenAPI spec:

```bash
nextjs-service-gen --url http://localhost:3000/openapi.json --list-services

# Output:
# 📋 Available Services:
#   1. users
#   2. movies
#   3. auth
# Total: 3 services
```

### List Available Schemas

See what schemas are defined in your OpenAPI spec:

```bash
# List all schemas
nextjs-service-gen --url http://localhost:3000/openapi.json --list-schemas

# List schemas for specific services
nextjs-service-gen --url http://localhost:3000/openapi.json --list-schemas --services users,movies

# List schemas filtered by endpoint prefix
nextjs-service-gen --url http://localhost:3000/openapi.json --list-schemas --prefix /api/v1/client
```

### Generate Specific Services

Generate only the services you need:

```bash
# Generate only users and movies services
nextjs-service-gen --url http://localhost:3000/openapi.json --services users,movies

# Combine with prefix filter
nextjs-service-gen --url http://localhost:3000/openapi.json --prefix /api/v1/client --services users
```

### Skip Files

Skip specific services or base files:

```bash
# Skip auth and admin services
nextjs-service-gen --url http://localhost:3000/openapi.json --skip auth,admin

# Skip base API files (use your own implementation)
nextjs-service-gen --url http://localhost:3000/openapi.json --skip types,fetch-client,actions
```

### Endpoint Prefix Selection

The generator supports filtering endpoints by prefix. This is useful when your OpenAPI spec contains multiple API versions or sections (e.g., `/api/v1/client`, `/api/v1/admin`, `/api/v2/public`).

**Auto-detection (default)**:

```bash
nextjs-service-gen --url http://localhost:3000/api/openapi.json
# ✨ Auto-detected prefix: /api/v1/client
```

**Interactive mode**:

```bash
nextjs-service-gen --url http://localhost:3000/api/openapi.json -i
# 📋 Available endpoint prefixes:
#   1. /api/v1/client (10 endpoints)
#   2. /api/v1/admin (5 endpoints)
#   3. No prefix (use all endpoints)
# Select a prefix (enter number):
```

**Manual prefix**:

```bash
nextjs-service-gen --url http://localhost:3000/api/openapi.json --prefix /api/v1/client
```

**Config file**:

```json
{
  "openApiUrl": "http://localhost:3000/api/v1/openapi.json",
  "endpointPrefix": "/api/v1/client"
}
```

## Generated Files

The generator creates:

### `schema.ts` - Zod Schemas and Types

```typescript
import { z } from 'zod';

export const movieSchema = z.object({
  id: z.string().uuid(),
  title: z.string(),
  year: z.number().int(),
  is_premium: z.boolean().optional(),
});

export type MovieType = z.infer<typeof movieSchema>;
```

### `rvk.ts` - Revalidation Keys

```typescript
export const RVK_MOVIES = 'movies' as const;
export const RVK_USERS = 'users' as const;
```

### `{service}.ts` - Service Functions

```typescript
'use server';

import * as actions from './api/actions';
import { RVK_MOVIES } from './rvk';
import { MovieType } from './schema';

export type GetMoviesSearchParams = {
  page?: number;
  page_size?: number;
  title?: string;
};

export async function getMovies(searchParams?: GetMoviesSearchParams) {
  const res = await actions.get<MovieType>(`/movies`, {
    searchParams,
    next: { tags: [RVK_MOVIES] },
  });

  const { body: response, error } = res;
  if (error) throw new Error(error);

  return response;
}
```

## Project Structure

You'll need to provide the `api/actions.ts` module that implements the HTTP methods:

```typescript
// src/services/api/actions.ts
'use server';

import { FetchClient } from 'your-fetch-client';

export async function get<T>(url: string, options?: any) {
  // Your implementation
}

export async function post<T>(url: string, body: any, options?: any) {
  // Your implementation
}

export async function put<T>(url: string, body: any, options?: any) {
  // Your implementation
}

export async function patch<T>(url: string, body: any, options?: any) {
  // Your implementation
}

export async function destroy<T>(url: string, options?: any) {
  // Your implementation (DELETE)
}
```

## OpenAPI Requirements

Your OpenAPI spec should:

- Define schemas in `components.schemas`
- Include request/response types
- Use standard OpenAPI 3.0+ format
- (Optional) Group endpoints by prefix for better organization

Example OpenAPI structure:

```json
{
  "paths": {
    "/api/v1/client/movies": {
      "get": {
        "summary": "Get Movies",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MovieList" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "MovieList": {
        "type": "object",
        "properties": {
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/Movie" } }
        }
      }
    }
  }
}
```

## Preserving Manual Edits

Add `// ignore-generate` at the top of any service file to prevent regeneration:

```typescript
'use server';
// ignore-generate

// This file won't be overwritten during regeneration
export async function customFunction() {
  // Your custom logic
}
```

## Integration with Next.js

### Cache Revalidation

```typescript
import { revalidateTag } from 'next/cache';
import { RVK_MOVIES } from '@/services/rvk';

// Revalidate all movie endpoints
await revalidateTag(RVK_MOVIES);

// Revalidate specific movie
await revalidateTag(`${RVK_MOVIES}_movie_id_${movieId}`);
```

### Server Actions

```typescript
'use client';

import { getMovies } from '@/services/movies';

export default function MoviesPage() {
  const [movies, setMovies] = useState([]);

  useEffect(() => {
    getMovies({ page: 1, page_size: 20 }).then(setMovies);
  }, []);

  return <div>{/* Render movies */}</div>;
}
```

### Troubleshooting

**Error: "GEN_SECRET not found"**

Solution: Set the encryption key in your environment:
```bash
export GEN_SECRET="your-key-here"
```

Contact your team lead if you don't have the key.

## Examples

### Basic Generation

```bash
nextjs-service-gen --url http://localhost:3000/api/v1/openapi.json
```

### With Prefix Filter

```bash
nextjs-service-gen --url http://localhost:3000/openapi.json --prefix /api/v1/client
```

### Custom Output Directory

```bash
nextjs-service-gen --url http://api.example.com/openapi.json --output ./lib/api
```

### Skip Specific Services

```bash
nextjs-service-gen --url http://localhost:3000/openapi.json --skip auth,admin
```

### Without Formatting

```bash
nextjs-service-gen --url http://localhost:3000/openapi.json --no-lint --no-format
```

## Workflow

1. **Develop your API** with OpenAPI documentation
2. **Set encryption key** in your environment
3. **Run generator** to create/update services
4. **Use type-safe services** in your Next.js app
5. **Regenerate** when API changes

## TypeScript Support

Full TypeScript support with generated types:

```typescript
import type { GetMoviesSearchParams, MovieType } from '@/services/movies';

const params: GetMoviesSearchParams = {
  page: 1,
  title: 'Inception',
};

const movies: MovieType[] = await getMovies(params);
```

## Requirements

- Node.js 18+
- Next.js 13+ (with App Router)
- OpenAPI 3.0+ specification
- Zod for schema validation

## Team Setup Checklist

- [ ] Install package: `npm install @interpriz/nextjs-service-generator`
- [ ] Get encryption key from team lead
- [ ] Set `GEN_SECRET` in `.env` (add to `.gitignore`)
- [ ] Add key to CI/CD secrets
- [ ] Run generator: `npx nextjs-service-gen --url <your-api-url>`
- [ ] Verify generated services work
- [ ] Share setup with new team members

## FAQ

### Q: Why do I need an encryption key?

**A:** The encryption key protects proprietary code patterns and templates used in generation.

### Q: Can I use this with Claude Desktop?

**A:** Yes! See [MCP-INTEGRATION.md](./MCP-INTEGRATION.md) for full MCP server setup and usage.

### Q: How do I list schemas for specific services?

**A:** Use the `--list-schemas --services` flags:
```bash
nextjs-service-gen --url $URL --list-schemas --services users,movies
```

### Q: Does this work with OpenAPI 2.0 (Swagger)?

**A:** This tool is designed for OpenAPI 3.0+. For Swagger 2.0, convert your spec first.

## Documentation

- **[MCP-INTEGRATION.md](./MCP-INTEGRATION.md)** - Complete MCP server guide for AI assistants
- **[CHANGELOG-SCHEMAS-CONFIG.md](./CHANGELOG-SCHEMAS-CONFIG.md)** - Schema listing & configuration features
- **[BUGFIX-SCHEMA-IMPORTS.md](./BUGFIX-SCHEMA-IMPORTS.md)** - Bug fix for endpointPrefix filtering
- **[FEATURE-SCHEMAS-BY-SERVICE.md](./FEATURE-SCHEMAS-BY-SERVICE.md)** - Schema filtering by service names
- **[AES_ENCRYPTION_GUIDE.md](./AES_ENCRYPTION_GUIDE.md)** - Encryption setup guide
- **[DATA-FLOW.md](./DATA-FLOW.md)** - Architecture and data flow

## Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

## License

MIT

## Related Projects

- [Next.js](https://nextjs.org)
- [Zod](https://zod.dev)
- [OpenAPI](https://www.openapis.org)
- [Plop](https://plopjs.com)