nestjs-openapi 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,35 +1,32 @@
1
- # nestjs-openapi
1
+ <div align="center">
2
+ <img src="docs/public/logo.png" alt="nestjs-openapi" width="120" />
3
+ <h1>nestjs-openapi</h1>
4
+ <p>Static OpenAPI generation for NestJS.<br/>Analyzes TypeScript source directly—no build step, no app bootstrap.</p>
2
5
 
3
- Static OpenAPI generation for NestJS. Analyzes TypeScript source directly—no build step, no app bootstrap.
6
+ [![npm version](https://img.shields.io/npm/v/nestjs-openapi)](https://www.npmjs.com/package/nestjs-openapi)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
4
8
 
5
- [![npm version](https://img.shields.io/npm/v/nestjs-openapi)](https://www.npmjs.com/package/nestjs-openapi)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
9
+ <a href="https://nestjs-openapi.vercel.app">Documentation</a> · <a href="https://nestjs-openapi.vercel.app/docs/quick-start">Quick Start</a> · <a href="https://github.com/Newbie012/nestjs-openapi/issues">Report Bug</a>
10
+ </div>
7
11
 
8
- ## Why static analysis?
12
+ <br/>
9
13
 
10
- | | Runtime (`@nestjs/swagger`) | Static (`nestjs-openapi`) |
11
- |---|---|---|
12
- | Requires runtime execution | Yes | No |
13
- | Requires app bootstrap | Yes | No |
14
- | Preserves generics/unions | No | Yes |
14
+ ## Motivation
15
15
 
16
- ## Who is this for?
16
+ `@nestjs/swagger` relies on `reflect-metadata` at runtime, which only exposes basic type signatures. Unions, generics, and literal types are erased. To work around this, you duplicate type information in decorators:
17
17
 
18
- - Teams who want accurate OpenAPI from TypeScript types without runtime metadata
19
- - CI/CD pipelines that should not boot the app or require infrastructure
20
- - Projects that want OpenAPI as a build artifact or committed output
21
-
22
- ## Compatibility
18
+ ```typescript
19
+ // You already have this type
20
+ status: 'pending' | 'shipped' | 'delivered';
23
21
 
24
- - NestJS 10 or 11 (decorator-based controllers)
25
- - TypeScript 5+
26
- - Node 20+
22
+ // But you also need this decorator to make the spec accurate
23
+ @ApiProperty({ enum: ['pending', 'shipped', 'delivered'] })
24
+ status: 'pending' | 'shipped' | 'delivered';
25
+ ```
27
26
 
28
- ## Limitations
27
+ When they drift apart, your spec lies about your API.
29
28
 
30
- - Dynamic route registration at runtime is not supported
31
- - Response shortcut decorators like `@ApiOkResponse()` are not read
32
- - Controller versioning via `@Controller({ path, version })` is not supported
29
+ **nestjs-openapi** reads your TypeScript source directly using the AST. Your types are your spec—no duplication, no drift.
33
30
 
34
31
  ## Quick start
35
32
 
@@ -59,27 +56,16 @@ Generate:
59
56
  npx nestjs-openapi generate
60
57
  ```
61
58
 
62
- ## Migration from @nestjs/swagger
63
-
64
- 1. Keep your controllers and route decorators as-is.
65
- 2. Move `DocumentBuilder` config into `openapi.config.ts`.
66
- 3. Replace response shortcuts with `@ApiResponse({ status: ... })`.
67
- 4. (Optional) Use `OpenApiModule` to serve the generated spec at runtime.
68
-
69
- See the full guide in the docs.
70
-
71
59
  ## Documentation
72
60
 
73
- Full documentation: **[nestjs-openapi.dev](https://nestjs-openapi.dev)**
61
+ Full documentation at **[nestjs-openapi.vercel.app](https://nestjs-openapi.vercel.app)**
74
62
 
75
- - [Configuration](https://nestjs-openapi.dev/docs/guides/configuration)
76
- - [Security schemes](https://nestjs-openapi.dev/docs/guides/security)
77
- - [Validation extraction](https://nestjs-openapi.dev/docs/guides/validation)
78
- - [Serving specs at runtime](https://nestjs-openapi.dev/docs/guides/serving)
79
- - [Migration guide](https://nestjs-openapi.dev/docs/recipes/migration)
80
- - [CI/CD recipe](https://nestjs-openapi.dev/docs/recipes/ci-cd)
81
- - [FAQ](https://nestjs-openapi.dev/docs/faq)
82
- - [Decorator support](https://nestjs-openapi.dev/docs/guides/decorators)
63
+ - [Configuration](https://nestjs-openapi.vercel.app/docs/guides/configuration)
64
+ - [Security schemes](https://nestjs-openapi.vercel.app/docs/guides/security)
65
+ - [Serving specs at runtime](https://nestjs-openapi.vercel.app/docs/guides/serving)
66
+ - [Migration from @nestjs/swagger](https://nestjs-openapi.vercel.app/docs/recipes/migration)
67
+ - [CI/CD recipe](https://nestjs-openapi.vercel.app/docs/recipes/ci-cd)
68
+ - [FAQ](https://nestjs-openapi.vercel.app/docs/faq)
83
69
 
84
70
  ## Contributing
85
71
 
package/dist/cli.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import 'tsx';
3
- import { g as generate, e as formatValidationResult } from './shared/nestjs-openapi.DlNMM8Zq.mjs';
3
+ import { g as generate, e as formatValidationResult } from './shared/nestjs-openapi.CCvQ3RSW.mjs';
4
4
  import minimist from 'minimist';
5
5
  import { relative } from 'node:path';
6
6
  import { createRequire } from 'node:module';
@@ -9,7 +9,7 @@ import 'node:fs';
9
9
  import 'ts-morph';
10
10
  import 'glob';
11
11
  import 'js-yaml';
12
- import './shared/nestjs-openapi.B1bBy_tG.mjs';
12
+ import './shared/nestjs-openapi.CzNt1duF.mjs';
13
13
  import 'ts-json-schema-generator';
14
14
  import 'node:crypto';
15
15
  import 'node:url';
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- export { c as categorizeBrokenRefs, d as defineConfig, f as findConfigFile, e as formatValidationResult, g as generate, b as loadAndResolveConfig, a as loadConfig, l as loadConfigFromFile, r as resolveConfig, v as validateSpec } from './shared/nestjs-openapi.DlNMM8Zq.mjs';
1
+ export { c as categorizeBrokenRefs, d as defineConfig, f as findConfigFile, e as formatValidationResult, g as generate, b as loadAndResolveConfig, a as loadConfig, l as loadConfigFromFile, r as resolveConfig, v as validateSpec } from './shared/nestjs-openapi.CCvQ3RSW.mjs';
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { resolve } from 'node:path';
4
4
  import { Module } from '@nestjs/common';
5
5
  export { generateAsync, generate as generateEffect } from './internal.mjs';
6
- import { P as ProjectInitError, E as EntryNotFoundError } from './shared/nestjs-openapi.B1bBy_tG.mjs';
7
- export { a as ConfigLoadError, C as ConfigNotFoundError, b as ConfigValidationError, I as InvalidMethodError, c as getAllControllers, q as getArrayInitializer, o as getControllerMethodInfos, e as getControllerName, d as getControllerPrefix, j as getControllerTags, h as getDecoratorName, k as getHttpDecorator, f as getHttpMethods, m as getMethodInfo, w as getModuleDecoratorArg, z as getModuleMetadata, g as getModules, s as getStringLiteralValue, u as getSymbolFromIdentifier, l as isHttpDecorator, i as isHttpMethod, v as isModuleClass, n as normalizePath, y as resolveArrayOfClasses, x as resolveClassFromExpression, r as resolveClassFromSymbol, t as transformMethod, p as transformMethods } from './shared/nestjs-openapi.B1bBy_tG.mjs';
6
+ import { P as ProjectInitError, E as EntryNotFoundError } from './shared/nestjs-openapi.CzNt1duF.mjs';
7
+ export { a as ConfigLoadError, C as ConfigNotFoundError, b as ConfigValidationError, I as InvalidMethodError, c as getAllControllers, q as getArrayInitializer, o as getControllerMethodInfos, e as getControllerName, d as getControllerPrefix, j as getControllerTags, h as getDecoratorName, k as getHttpDecorator, f as getHttpMethods, m as getMethodInfo, w as getModuleDecoratorArg, z as getModuleMetadata, g as getModules, s as getStringLiteralValue, u as getSymbolFromIdentifier, l as isHttpDecorator, i as isHttpMethod, v as isModuleClass, n as normalizePath, y as resolveArrayOfClasses, x as resolveClassFromExpression, r as resolveClassFromSymbol, t as transformMethod, p as transformMethods } from './shared/nestjs-openapi.CzNt1duF.mjs';
8
8
  import { Context, Effect, Layer } from 'effect';
9
9
  import { Project } from 'ts-morph';
10
10
  import 'glob';
package/dist/internal.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Effect } from 'effect';
2
2
  import { Project } from 'ts-morph';
3
- import { E as EntryNotFoundError, g as getModules, o as getControllerMethodInfos, p as transformMethods } from './shared/nestjs-openapi.B1bBy_tG.mjs';
3
+ import { E as EntryNotFoundError, g as getModules, o as getControllerMethodInfos, p as transformMethods } from './shared/nestjs-openapi.CzNt1duF.mjs';
4
4
 
5
5
  const generate = (options) => Effect.gen(function* () {
6
6
  yield* Effect.logInfo("Starting OpenAPI generation").pipe(
@@ -4,7 +4,7 @@ import { join, dirname, resolve } from 'node:path';
4
4
  import { Project } from 'ts-morph';
5
5
  import { globSync, glob } from 'glob';
6
6
  import yaml from 'js-yaml';
7
- import { C as ConfigNotFoundError, a as ConfigLoadError, b as ConfigValidationError, p as transformMethods, A as extractClassConstraints, B as getRequiredProperties, D as mergeValidationConstraints, E as EntryNotFoundError, g as getModules, o as getControllerMethodInfos } from './nestjs-openapi.B1bBy_tG.mjs';
7
+ import { C as ConfigNotFoundError, a as ConfigLoadError, b as ConfigValidationError, p as transformMethods, A as extractClassConstraints, B as getRequiredProperties, D as mergeValidationConstraints, E as EntryNotFoundError, g as getModules, o as getControllerMethodInfos } from './nestjs-openapi.CzNt1duF.mjs';
8
8
  import { createGenerator } from 'ts-json-schema-generator';
9
9
  import { randomUUID } from 'node:crypto';
10
10
  import { pathToFileURL } from 'node:url';
@@ -850,7 +850,7 @@ const isExpandableType = (typeName) => {
850
850
  if (BUILT_IN_TYPES.has(typeName.split("<")[0])) return false;
851
851
  if (typeName.includes(" | ") || typeName.includes(" & ")) return false;
852
852
  if (typeName.endsWith("[]")) return false;
853
- return /^[A-Z][a-zA-Z0-9]*$/.test(typeName);
853
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(typeName);
854
854
  };
855
855
  const tsTypeToString = (typeText) => {
856
856
  const trimmed = typeText.trim();
@@ -1327,6 +1327,7 @@ const tsTypeToOpenApiSchema = (tsType) => {
1327
1327
  return { type: "object" };
1328
1328
  case "unknown":
1329
1329
  case "any":
1330
+ case "object":
1330
1331
  return { type: "object" };
1331
1332
  }
1332
1333
  if (trimmed === "StreamableFile" || trimmed === "Buffer" || trimmed === "Readable" || trimmed === "ReadableStream") {
@@ -1345,7 +1346,7 @@ const tsTypeToOpenApiSchema = (tsType) => {
1345
1346
  type: "object"
1346
1347
  };
1347
1348
  }
1348
- if (trimmed.match(/^[A-Z][a-zA-Z0-9]*(<[^>]+>)?$/)) {
1349
+ if (trimmed.match(/^[a-zA-Z_$][a-zA-Z0-9_$]*(<[^>]+>)?$/)) {
1349
1350
  return { $ref: `#/components/schemas/${trimmed}` };
1350
1351
  }
1351
1352
  return { type: "object" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nestjs-openapi",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Static code analysis tool to generate OpenAPI specifications from NestJS applications",
5
5
  "main": "./dist/index.mjs",
6
6
  "module": "./dist/index.mjs",