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 +27 -41
- package/dist/cli.mjs +2 -2
- package/dist/index.mjs +3 -3
- package/dist/internal.mjs +1 -1
- package/dist/shared/{nestjs-openapi.DlNMM8Zq.mjs → nestjs-openapi.CCvQ3RSW.mjs} +1 -1
- package/dist/shared/{nestjs-openapi.B1bBy_tG.mjs → nestjs-openapi.CzNt1duF.mjs} +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,35 +1,32 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
6
|
+
[](https://www.npmjs.com/package/nestjs-openapi)
|
|
7
|
+
[](LICENSE)
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
|
|
12
|
+
<br/>
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|---|---|---|
|
|
12
|
-
| Requires runtime execution | Yes | No |
|
|
13
|
-
| Requires app bootstrap | Yes | No |
|
|
14
|
-
| Preserves generics/unions | No | Yes |
|
|
14
|
+
## Motivation
|
|
15
15
|
|
|
16
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
## Compatibility
|
|
18
|
+
```typescript
|
|
19
|
+
// You already have this type
|
|
20
|
+
status: 'pending' | 'shipped' | 'delivered';
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
27
|
+
When they drift apart, your spec lies about your API.
|
|
29
28
|
|
|
30
|
-
-
|
|
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
|
|
61
|
+
Full documentation at **[nestjs-openapi.vercel.app](https://nestjs-openapi.vercel.app)**
|
|
74
62
|
|
|
75
|
-
- [Configuration](https://nestjs-openapi.
|
|
76
|
-
- [Security schemes](https://nestjs-openapi.
|
|
77
|
-
- [
|
|
78
|
-
- [
|
|
79
|
-
- [
|
|
80
|
-
- [
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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 /^[
|
|
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(/^[
|
|
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