Star 历史趋势
数据来源: GitHub API · 生成自 Stargazers.cn
README.md
Massimo Logo

Massimo

npm version License

Massimo is an API SDK client and CLI tool for creating fully-typed clients for remote OpenAPI or GraphQL APIs. Generate TypeScript/JavaScript clients with automatic type inference, authentication support, and seamless integration with popular frontend frameworks.

Why "Massimo"? The name is inspired by Massimo Troisi, the beloved Italian actor from the film "Il Postino" (The Postman). Just as the postman in the movie delivered messages and connected people, Massimo delivers API connections and bridges the gap between services, making communication between applications as effortless and poetic as Troisi's unforgettable performance.

🚀 Features

  • OpenAPI Client Generation: Create fully-typed clients from OpenAPI 3.x specifications
  • GraphQL Client Generation: Generate clients from GraphQL schemas with type support
  • TypeScript First: Full TypeScript support with automatic type generation
  • Framework Agnostic: Works with any Node.js application or frontend framework
  • Authentication Support: Built-in support for headers, tokens, and custom authentication
  • Fastify Plugin: Ready-to-use Fastify plugin for seamless integration

📦 Installation

CLI Tool

npm install -g massimo-cli

Library

npm install massimo

🛠️ Quick Start

Generate an OpenAPI Client

massimo http://api.example.com/openapi.json --name myclient

Generate a GraphQL Client

massimo http://api.example.com/graphql --name myclient --type graphql

Use the Generated Client

JavaScript/TypeScript (Node.js, Undici-based):

The undici-based client is preferred for Node.js environments when you need:

  • Maximum performance - Undici is the fastest HTTP/1.1 client for Node.js
  • Advanced connection management with pooling, keep-alive, and pipelining
  • HTTP/2 support with full capabilities
  • Node.js optimized runtime (bundled with Node.js 18+)
  • Advanced features like interceptors, custom dispatchers, and WebSocket support
  • Efficient streaming with pipeline and stream methods for large payloads
  • Comprehensive error types and network-level error handling
// Generate Node.js client // massimo http://api.example.com/openapi.json --name myclient import myClient from "./myclient/myclient.mjs"; const client = await myClient({ url: "https://api.example.com", }); // OpenAPI const users = await client.getUsers(); const newUser = await client.createUser({ name: "John Doe" }); // GraphQL const result = await client.graphql({ query: "query { users { id name } }", });

Frontend Client (Browser, Fetch-based):

The fetch-based client is preferred for browser environments and when you need:

  • Browser compatibility with native Fetch API (Undici is Node.js-only)
  • Zero dependencies for minimal bundle size
  • Isomorphic code that runs in browsers and Node.js
  • Maximum compatibility across all JavaScript runtimes
  • Simple HTTP requests without advanced configuration
  • Publishing to npm with broadest runtime support
  • Independence from specific undici version features
// Generate frontend client // massimo http://api.example.com/openapi.json --frontend --name myclient // Option 1: Named operations import { setBaseUrl, getUsers, createUser } from "./myclient/api.mjs"; setBaseUrl("https://api.example.com"); // Make type-safe API calls const users = await getUsers({}); const newUser = await createUser({ name: "Jane Doe", email: "jane@example.com", }); // Option 2: Factory method import buildClient from "./myclient/api.mjs"; const client = buildClient("https://api.example.com"); // Set default headers for authentication client.setDefaultHeaders({ Authorization: "Bearer token", }); const users = await client.getUsers({}); const user = await client.getUserById({ id: "123" });

Fastify Plugin:

import fastify from "fastify"; import pltClient from "massimo/fastify-plugin.js"; const server = fastify(); server.register(pltClient, { url: "http://example.com", type: "openapi", // or "graphql" }); // OpenAPI server.post("/", async (request, reply) => { const res = await request.movies.createMovie({ title: "foo" }); return res; }); server.listen({ port: 3000 });

Note that you would need to install massimo as a dependency.

TypeScript with Fastify Plugin:

Massimo generates full TypeScript support for Fastify. To add types information to your plugin, you can either extend the FastifyRequest interface globally or locally.

import { type MoviesClient } from "./movies/movies.ts"; import fastify, { type FastifyRequest } from "fastify"; import pltClient from "massimo/fastify-plugin.js"; const server = fastify(); server.register(pltClient, { url: "http://example.com", type: "openapi", // or "graphql" }); // Method A: extend the interface globally declare module "fastify" { interface FastifyRequest { movies: MoviesClient; } } server.get("/movies", async (request: FastifyRequest, reply: FastifyReply) => { return request.movies.getMovies(); }); // Method B: use a local request extension interface MoviesRequest extends FastifyRequest { movies: MoviesClient; } server.get("/movies", async (request: MoviesRequest, reply: FastifyReply) => { return request.movies.getMovies(); });

📚 Documentation

CLI Commands

# Generate client from URL massimo <url> --name <client-name> # Generate from local file massimo ./openapi.json --name myclient # Generate only TypeScript types massimo <url> --name myclient --types-only # Specify client type (auto-detected by default) massimo <url> --name myclient --type openapi massimo <url> --name myclient --type graphql # Custom output folder massimo <url> --name myclient --folder ./clients # Specify module format (valid values: esm, cjs) massimo <url> --name myclient --module esm massimo <url> --name myclient --module cjs # Force TypeScript declaration file extensions (.d.mts/.d.cts) massimo <url> --name myclient --type-extension

Module Format Detection

Massimo automatically detects and generates the appropriate module format (ESM or CommonJS) for your clients:

Auto-Detection (Default Behavior)

When no --module flag is specified, Massimo:

  1. Searches for the nearest package.json starting from the output directory and walking up the directory tree
  2. If package.json is found, checks the type field:
    • If "type": "module" → Generates ESM files (.mjs, .d.mts)
    • If "type" is missing or any other value → Generates CommonJS files (.cjs, .d.ts)
  3. If no package.json is found → Defaults to ESM files (.mjs, .d.mts)
  4. Generated files:
    • ESM: client.mjs + client.d.mts + package.json with "type": "module"
    • CommonJS: client.cjs + client.d.ts + package.json without "type" field

Explicit Module Format

When using the --module flag:

# Force ESM generation massimo <url> --name myclient --module esm # Force CommonJS generation massimo <url> --name myclient --module cjs

This overrides any auto-detection and generates files in the specified format.

Generated File Extensions

Module FormatImplementationTypesPackage.json
ESM.mjs.d.mts"type": "module"
CommonJS.cjs.d.ctsNo "type" field

TypeScript Declaration File Extensions

Massimo uses intelligent logic to determine the appropriate TypeScript declaration file extension (.d.ts, .d.mts, or .d.cts):

Type Extension Determination Rules

  1. When --type-extension is specified:

    • Always generates module-specific extensions
    • ESM format → .d.mts
    • CommonJS format → .d.cts
  2. When --type-extension is NOT specified:

    • If --module flag is provided:
      • Compares the specified module format with the parent package.json type
      • If they match → generates .d.ts (universal compatibility)
      • If they differ → generates module-specific extension (.d.mts or .d.cts)
    • If no --module flag is provided:
      • Always generates .d.ts for maximum compatibility
  3. Parent Package.json Detection:

    • Searches up the directory tree from the output location
    • Stops at the first package.json found
    • ESM parent: "type": "module"
    • CommonJS parent: no type field or "type": "commonjs"

Examples

# Always use module-specific extensions massimo <url> --name myclient --type-extension # Generate .d.ts when module format matches parent package.json massimo <url> --name myclient --module esm # In ESM project → .d.ts massimo <url> --name myclient --module cjs # In CommonJS project → .d.ts # Generate module-specific when formats differ massimo <url> --name myclient --module esm # In CommonJS project → .d.mts massimo <url> --name myclient --module cjs # In ESM project → .d.cts # Auto-detect everything (no module flag) → always .d.ts massimo <url> --name myclient # → .d.ts (maximum compatibility) # Explicit module generates module-specific when no parent package.json massimo <url> --name myclient --module esm # No parent pkg → .d.mts massimo <url> --name myclient --module cjs # No parent pkg → .d.cts

Client Options

interface ClientOptions { url: string; // Base URL for the API headers?: Record<string, string>; // Default headers timeout?: number; // Request timeout in ms throwOnError?: boolean; // Throw on HTTP errors } const client = await generateMyClient({ url: "https://api.example.com", headers: { Authorization: "Bearer token", }, timeout: 5000, throwOnError: true, });

Authentication

Configure authentication headers dynamically:

// In a Fastify plugin app.configureMyClient({ async getHeaders(req, reply) { return { Authorization: `Bearer ${req.user.token}`, "X-User-ID": req.user.id, }; }, });

TypeScript Support

Massimo generates full TypeScript definitions:

// Generated types for OpenAPI interface GetUsersResponse { id: string; name: string; email: string; } interface CreateUserRequest { name: string; email: string; } interface Client { getUsers(): Promise<GetUsersResponse[]>; createUser(req: CreateUserRequest): Promise<GetUsersResponse>; } // Generated types for GraphQL interface User { id?: string; name?: string; email?: string; } interface GraphQLClient { graphql<T>(options: { query: string; variables?: Record<string, unknown>; headers?: Record<string, string>; }): Promise<T>; }

🏗️ Architecture

Massimo consists of two main packages:

  • massimo: Core client library for generating and using API clients
  • massimo-cli: Command-line tool for generating client code

Supported APIs

  • OpenAPI 3.x: Full support for OpenAPI specifications with automatic client generation
  • GraphQL: Support for GraphQL schemas with type generation
  • Any HTTP API: As long as it exposes OpenAPI or GraphQL schemas

Generated Client Features

  • Type Safety: Full TypeScript support with request/response typing
  • Error Handling: Built-in error handling and validation
  • Request/Response Interceptors: Middleware support for modifying requests/responses
  • Retry Logic: Configurable retry mechanisms
  • Telemetry: Automatic telemetry and tracing propagation

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

git clone https://github.com/platformatic/massimo.git cd massimo pnpm install pnpm test

Running Tests

# Run all tests pnpm test # Run tests for specific package cd packages/massimo npm test

📄 License

Licensed under Apache 2.0.

🔗 Links


Made with ❤️ by the Platformatic team.

关于 About

Massimo is an API SDK client and CLI tool for creating clients for remote OpenAPI or GraphQL APIs

语言 Languages

JavaScript96.2%
TypeScript3.2%
CSS0.4%
HTML0.1%
Shell0.1%

提交活跃度 Commit Activity

代码提交热力图
过去 52 周的开发活跃度
161
Total Commits
峰值: 40次/周
Less
More

核心贡献者 Contributors