npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@metaengine/openapi-angular

v0.9.9

Published

Generate TypeScript/Angular services and models from OpenAPI specifications with httpResource (Angular 19.2+) and Signal-based data fetching support

Readme

@metaengine/openapi-angular

Generate TypeScript/Angular services and models from OpenAPI specifications.

Features

  • Angular 14+ - Modern Angular with RxJS observables
  • httpResource (Angular 19.2+) - Signal-based data fetching with automatic request management
  • TypeScript - Fully typed API clients and models
  • Dependency Injection - Injectable services with configurable scope
  • HttpClient Integration - Native Angular HTTP client
  • Error Handling - Smart error handling with interceptors
  • Modern inject() - Support for functional injection
  • Tree-shakeable - Optimized bundle size with separate files

Installation

npm install --save-dev @metaengine/openapi-angular

Or use directly with npx:

npx @metaengine/openapi-angular <input> <output>

Requirements

  • Node.js 14.0 or later
  • .NET 8.0 or later runtime (Download)
  • Angular 14.0 or later (for generated code)

Usage

With npm scripts (Recommended when installed locally)

If you installed the package with npm install, add a script to your package.json:

{
  "scripts": {
    "generate:api": "metaengine-openapi-angular api.yaml ./src/app/api --inject-function --error-handling --documentation"
  }
}

Then run:

npm run generate:api

With npx (One-off usage or without installation)

Use npx for trying out the tool or in CI/CD pipelines:

npx @metaengine/openapi-angular <input> <output> [options]

Quick Examples

# Recommended (follows Angular style guide)
npx @metaengine/openapi-angular api.yaml ./src/app/api \
  --inject-function \
  --error-handling \
  --documentation

# Basic (minimal setup)
npx @metaengine/openapi-angular api.yaml ./src/app/api

# From URL
npx @metaengine/openapi-angular https://api.example.com/openapi.json ./src/app/api \
  --inject-function \
  --documentation

# Filter by tags (only specific endpoints)
npx @metaengine/openapi-angular api.yaml ./src/app/api \
  --include-tags users,auth \
  --inject-function

# Advanced (custom DI scope with strict validation)
npx @metaengine/openapi-angular api.yaml ./src/app/api \
  --inject-function \
  --provided-in any \
  --strict-validation \
  --documentation

Note: When the package is installed locally, npx will use that version instead of downloading a new one.

CLI Options

| Option | Description | Default | |--------|-------------|---------| | --include-tags <tags> | Filter by OpenAPI tags (comma-separated, case-insensitive) | - | | --provided-in <value> | Angular injection scope (root, any, platform) | - | | --base-url-token <name> | Injection token name for base URL | BASE_URL | | --options-threshold <n> | Parameter count for options object | 4 | | --documentation | Generate JSDoc comments | false | | --inject-function | Use inject() instead of constructor injection | false | | --http-resource | Use httpResource with Signals for HTTP calls | false | | --error-handling | Enable smart error handling | false | | --strict-validation | Enable strict OpenAPI validation | false | | --verbose | Enable verbose logging | false | | --help, -h | Show help message | - |

Generated Code Structure

The generator creates a clean, modular structure with separate files for each model and service, optimized for tree-shaking:

output/
  ├── models/                    # One file per model
  │   ├── user.ts               # export interface User { ... }
  │   ├── product.ts            # export interface Product { ... }
  │   ├── order.ts              # export interface Order { ... }
  │   └── ...
  ├── services/                  # One file per service/tag
  │   ├── users.service.ts      # UsersService with all user operations
  │   ├── products.service.ts   # ProductsService with all product operations
  │   ├── orders.service.ts     # OrdersService with all order operations
  │   ├── base-api.service.ts   # Base service with common functionality
  │   └── ...
  ├── alias-types.ts            # Type aliases from OpenAPI spec
  ├── dictionary-types.ts       # Dictionary/map types
  └── union-types.ts            # Union types for complex schemas

Example Generated Code

Model (models/user.ts)

export interface User {
    id: string;
    email: string;
    name: string;
    created_at: string;
    roles?: string[];
}

Service (services/users.service.ts)

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { BaseApiService } from './base-api.service';
import { User } from '../models/user';
import { CreateUserRequest } from '../models/create-user-request';
import { UsersListResponse } from '../models/users-list-response';

@Injectable({ providedIn: 'root' })
export class UsersService extends BaseApiService {

  /**
   * Get list of users
   * @param {number} limit Maximum number of users to return
   * @param {number} offset Offset for pagination
   * @returns {Observable<UsersListResponse>} Observable containing the users list
   */
  listUsers(limit?: number, offset?: number): Observable<UsersListResponse> {
    const params: Record<string, any> = {};
    if (limit !== undefined) params['limit'] = limit;
    if (offset !== undefined) params['offset'] = offset;

    return this.createRequest(() => this.http.get<UsersListResponse>(
      this.buildUrl('/users'),
      { params: this.createParams(params) }
    ), 'listUsers');
  }

  /**
   * Get a user by ID
   * @param {string} userId User ID
   * @returns {Observable<User>} Observable containing the user
   */
  getUser(userId: string): Observable<User> {
    return this.createRequest(() => this.http.get<User>(
      this.buildUrl(`/users/${userId}`)
    ), 'getUser');
  }

  /**
   * Create a new user
   * @param {CreateUserRequest} request User creation request
   * @returns {Observable<User>} Observable containing the created user
   */
  createUser(request: CreateUserRequest): Observable<User> {
    return this.createRequest(() => this.http.post<User>(
      this.buildUrl('/users'),
      request
    ), 'createUser');
  }
}

httpResource Support (Angular 19.2+)

When using --http-resource, the generator creates Signal-based resource methods alongside traditional Observable methods for GET operations:

import { Injectable, Signal } from '@angular/core';
import { Observable } from 'rxjs';
import { httpResource, HttpResourceRef } from '@angular/common/http';
import { BaseApiService } from './base-api.service';
import { User } from '../models/user';

@Injectable({ providedIn: 'root' })
export class UsersService extends BaseApiService {

  // Traditional Observable method (always available)
  getUser(userId: string): Observable<User> {
    return this.createRequest(() => this.http.get<User>(
      this.buildUrl(`/users/${userId}`)
    ), 'getUser');
  }

  // Signal-based httpResource method (with --http-resource flag)
  getUserResource(userId: Signal<string | undefined>): HttpResourceRef<User | undefined> {
    return httpResource<User>(
      () => {
        const userIdValue = userId();
        if (typeof userIdValue === 'undefined') {
          return undefined;
        }
        return {
          url: this.buildUrl(`/users/${userIdValue}`)
        };
      });
  }
}

Benefits of httpResource:

  • Automatic request lifecycle management
  • Reactive updates when Signal inputs change
  • Prevents requests when required parameters are undefined
  • Perfect for create/edit forms with initially undefined inputs
  • Smaller bundle size compared to RxJS for simple GET requests

Usage in components:

export class UserDetailsComponent {
  private userIdSignal = signal<string | undefined>(undefined);

  // Automatically refetches when userIdSignal changes
  userResource = inject(UsersService).getUserResource(this.userIdSignal);

  loadUser(id: string) {
    this.userIdSignal.set(id);  // Triggers automatic refetch
  }
}

License

MIT

Support

For issues and feature requests, please visit: https://github.com/meta-engine/openapi-angular/issues