nestjs-openapi-parser 0.0.4 → 0.0.6
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/dist/config/types.d.ts +27 -0
- package/dist/config/types.js.map +1 -1
- package/dist/lib.d.ts +2 -2
- package/dist/lib.js.map +1 -1
- package/dist/parser/index.js +53 -0
- package/dist/parser/index.js.map +1 -1
- package/dist/types/openapi.d.ts +10 -0
- package/docs/configuration.md +21 -0
- package/package.json +1 -1
package/dist/config/types.d.ts
CHANGED
|
@@ -111,11 +111,38 @@ export interface ConventionsConfig {
|
|
|
111
111
|
* constructor. Looked up against the project's AST index by `klass.name`.
|
|
112
112
|
*/
|
|
113
113
|
export type ModelConstructor = abstract new (...args: any[]) => unknown;
|
|
114
|
+
export interface PagesConfig {
|
|
115
|
+
/**
|
|
116
|
+
* Markdown files rendered as standalone pages. Each path is relative to the
|
|
117
|
+
* project root or absolute. The page title is the file's first `# heading`
|
|
118
|
+
* line (else the file name); the whole file body is the page content.
|
|
119
|
+
*/
|
|
120
|
+
files: string[];
|
|
121
|
+
/**
|
|
122
|
+
* Sidebar heading for the Markdown pages section. Setting this (or `apiGroup`)
|
|
123
|
+
* switches on `x-tagGroups` grouped navigation; defaults to `Documentation`
|
|
124
|
+
* for the missing one. When BOTH are omitted no `x-tagGroups` is emitted — the
|
|
125
|
+
* pages simply lead the flat tag list (still rendered first, no group headers).
|
|
126
|
+
*/
|
|
127
|
+
group?: string;
|
|
128
|
+
/**
|
|
129
|
+
* Sidebar heading that groups the API's operation tags — needed once grouping
|
|
130
|
+
* is on, because `x-tagGroups` hides any ungrouped tag. Setting this (or
|
|
131
|
+
* `group`) switches on grouping; defaults to `API` for the missing one.
|
|
132
|
+
*/
|
|
133
|
+
apiGroup?: string;
|
|
134
|
+
}
|
|
114
135
|
export interface NestParserConfig {
|
|
115
136
|
openapi: OpenApiConfig;
|
|
116
137
|
project?: ProjectConfig;
|
|
117
138
|
conventions?: ConventionsConfig;
|
|
118
139
|
hooks?: NestParserHooks;
|
|
140
|
+
/**
|
|
141
|
+
* Standalone Markdown pages emitted ahead of the API reference via
|
|
142
|
+
* `x-tagGroups` (rendered by Scalar/Redoc). Omit to emit no pages and no
|
|
143
|
+
* `x-tagGroups` at all.
|
|
144
|
+
*/
|
|
145
|
+
pages?: PagesConfig;
|
|
119
146
|
/**
|
|
120
147
|
* Class references to force-include in `components.schemas`, even when no
|
|
121
148
|
* endpoint reaches them. Pass the class itself (not its name) — we resolve
|
package/dist/config/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":";;AA0LA,oCAEC;AAHD,yEAAyE;AACzE,SAAgB,YAAY,CAAC,MAAwB;IACnD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/lib.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ export { parseNestProject } from './parser';
|
|
|
2
2
|
export type { ParseNestProjectOptions } from './parser';
|
|
3
3
|
export { AstIndex, PathBuilder, SchemaBuilder } from './parser';
|
|
4
4
|
export { defineConfig } from './config/types';
|
|
5
|
-
export type { NestParserConfig, NestParserHooks, OpenApiConfig, ProjectConfig, ConventionsConfig, ResponseSchemaContext, SecurityContext, EndpointSummaryContext, ModelConstructor, } from './config/types';
|
|
5
|
+
export type { NestParserConfig, NestParserHooks, OpenApiConfig, ProjectConfig, ConventionsConfig, PagesConfig, ResponseSchemaContext, SecurityContext, EndpointSummaryContext, ModelConstructor, } from './config/types';
|
|
6
6
|
export { loadConfig } from './config/loader';
|
|
7
7
|
export type { LoadConfigOptions, LoadedConfig } from './config/loader';
|
|
8
8
|
export { validateDocument } from './validate';
|
|
9
9
|
export type { ValidationResult } from './validate';
|
|
10
10
|
export { filterScopedComments, getScopes, getTags, isVisible, parseScopeList } from './parser/tags';
|
|
11
11
|
export type { TagBag } from './parser/tags';
|
|
12
|
-
export type { OpenApiDocument, OpenApiInfo, OpenApiServer, OpenApiSchema, OpenApiSecurityScheme, OpenApiSecurityRequirement, } from './types/openapi';
|
|
12
|
+
export type { OpenApiDocument, OpenApiInfo, OpenApiServer, OpenApiSchema, OpenApiSecurityScheme, OpenApiSecurityRequirement, OpenApiTagGroup, } from './types/openapi';
|
package/dist/lib.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":";;;AAAA,mCAA4C;AAAnC,0GAAA,gBAAgB,OAAA;AAEzB,mCAAgE;AAAvD,kGAAA,QAAQ,OAAA;AAAE,qGAAA,WAAW,OAAA;AAAE,uGAAA,aAAa,OAAA;AAE7C,wCAA8C;AAArC,qGAAA,YAAY,OAAA;
|
|
1
|
+
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":";;;AAAA,mCAA4C;AAAnC,0GAAA,gBAAgB,OAAA;AAEzB,mCAAgE;AAAvD,kGAAA,QAAQ,OAAA;AAAE,qGAAA,WAAW,OAAA;AAAE,uGAAA,aAAa,OAAA;AAE7C,wCAA8C;AAArC,qGAAA,YAAY,OAAA;AAcrB,0CAA6C;AAApC,oGAAA,UAAU,OAAA;AAGnB,uCAA8C;AAArC,4GAAA,gBAAgB,OAAA;AAGzB,sCAAoG;AAA3F,4GAAA,oBAAoB,OAAA;AAAE,iGAAA,SAAS,OAAA;AAAE,+FAAA,OAAO,OAAA;AAAE,iGAAA,SAAS,OAAA;AAAE,sGAAA,cAAc,OAAA"}
|
package/dist/parser/index.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.SchemaBuilder = exports.PathBuilder = exports.AstIndex = void 0;
|
|
4
7
|
exports.parseNestProject = parseNestProject;
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
5
10
|
const validate_1 = require("../validate");
|
|
6
11
|
const ast_index_1 = require("./ast-index");
|
|
7
12
|
Object.defineProperty(exports, "AstIndex", { enumerable: true, get: function () { return ast_index_1.AstIndex; } });
|
|
@@ -81,6 +86,7 @@ async function parseNestProject(options) {
|
|
|
81
86
|
if (tags.length > 0) {
|
|
82
87
|
document.tags = tags;
|
|
83
88
|
}
|
|
89
|
+
applyPages(document, projectRoot, config.pages, tags);
|
|
84
90
|
const { valid, errors } = await (0, validate_1.validateDocument)(document);
|
|
85
91
|
if (!valid) {
|
|
86
92
|
throw new Error(`Generated OpenAPI document failed schema validation:\n${errors
|
|
@@ -92,4 +98,51 @@ async function parseNestProject(options) {
|
|
|
92
98
|
function formatScopes(scopes) {
|
|
93
99
|
return scopes.size === 0 ? '{}' : `{${[...scopes].join(', ')}}`;
|
|
94
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Emit the configured Markdown pages as standalone, operation-less tags and wrap
|
|
103
|
+
* the whole document in `x-tagGroups` so Scalar/Redoc renders the pages first
|
|
104
|
+
* (right under the Introduction). Because `x-tagGroups` hides any ungrouped tag,
|
|
105
|
+
* the API's own operation tags are gathered into a second group.
|
|
106
|
+
*/
|
|
107
|
+
function applyPages(document, projectRoot, pages, operationTags) {
|
|
108
|
+
if (!pages || pages.files.length === 0)
|
|
109
|
+
return;
|
|
110
|
+
const pageTags = pages.files.map((file) => {
|
|
111
|
+
const { title, content } = readPage(node_path_1.default.resolve(projectRoot, file));
|
|
112
|
+
return { name: title, description: content };
|
|
113
|
+
});
|
|
114
|
+
// Pages render first; the existing operation tags keep their order after them.
|
|
115
|
+
document.tags = [...pageTags, ...(document.tags ?? [])];
|
|
116
|
+
// `x-tagGroups` is opt-in: only when a section name is given. Without one the
|
|
117
|
+
// pages just lead the flat tag list — no "Documentation"/"API" headers, and no
|
|
118
|
+
// need to corral the API's own tags (x-tagGroups would otherwise hide any
|
|
119
|
+
// ungrouped tag). A missing counterpart name falls back to its default.
|
|
120
|
+
if (pages.group === undefined && pages.apiGroup === undefined)
|
|
121
|
+
return;
|
|
122
|
+
const tagGroups = [
|
|
123
|
+
{ name: pages.group ?? 'Documentation', tags: pageTags.map((t) => t.name) },
|
|
124
|
+
];
|
|
125
|
+
if (operationTags.length > 0) {
|
|
126
|
+
tagGroups.push({ name: pages.apiGroup ?? 'API', tags: operationTags.map((t) => t.name) });
|
|
127
|
+
}
|
|
128
|
+
document['x-tagGroups'] = tagGroups;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Read a Markdown page: the title is the first line when it's an ATX heading
|
|
132
|
+
* (`# Title`), otherwise the file's base name without extension. The content is
|
|
133
|
+
* the whole file, verbatim.
|
|
134
|
+
*/
|
|
135
|
+
function readPage(filePath) {
|
|
136
|
+
let content;
|
|
137
|
+
try {
|
|
138
|
+
content = node_fs_1.default.readFileSync(filePath, 'utf-8');
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
throw new Error(`pages: Markdown file not found or unreadable: ${filePath}`);
|
|
142
|
+
}
|
|
143
|
+
const firstLine = content.split('\n', 1)[0]?.trim() ?? '';
|
|
144
|
+
const heading = /^#{1,6}\s+(.+?)\s*$/.exec(firstLine);
|
|
145
|
+
const title = heading ? heading[1].trim() : node_path_1.default.basename(filePath).replace(/\.[^.]+$/, '');
|
|
146
|
+
return { title, content };
|
|
147
|
+
}
|
|
95
148
|
//# sourceMappingURL=index.js.map
|
package/dist/parser/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"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"}
|
package/dist/types/openapi.d.ts
CHANGED
|
@@ -25,6 +25,11 @@ export interface OpenApiInfo {
|
|
|
25
25
|
}
|
|
26
26
|
export type OpenApiSecurityScheme = Record<string, unknown>;
|
|
27
27
|
export type OpenApiSecurityRequirement = Record<string, string[]>;
|
|
28
|
+
/** A Redoc/Scalar tag group — top-level navigation grouping a set of tag names. */
|
|
29
|
+
export interface OpenApiTagGroup {
|
|
30
|
+
name: string;
|
|
31
|
+
tags: string[];
|
|
32
|
+
}
|
|
28
33
|
export interface OpenApiDocument {
|
|
29
34
|
openapi: string;
|
|
30
35
|
info: OpenApiInfo;
|
|
@@ -39,4 +44,9 @@ export interface OpenApiDocument {
|
|
|
39
44
|
name: string;
|
|
40
45
|
description?: string;
|
|
41
46
|
}[];
|
|
47
|
+
/**
|
|
48
|
+
* Redoc/Scalar navigation groups. When present, tags not listed in any group
|
|
49
|
+
* are hidden — so the API's own tags must be grouped too, not just doc pages.
|
|
50
|
+
*/
|
|
51
|
+
'x-tagGroups'?: OpenApiTagGroup[];
|
|
42
52
|
}
|
package/docs/configuration.md
CHANGED
|
@@ -34,6 +34,7 @@ export default defineConfig({
|
|
|
34
34
|
|
|
35
35
|
scopes: [], // see "Documentation variants" below
|
|
36
36
|
additionalModels: [], // force-include unreachable models — see docs/parser.md
|
|
37
|
+
pages: { files: ['./docs/getting-started.md'] }, // see "Markdown pages" below
|
|
37
38
|
|
|
38
39
|
hooks: {
|
|
39
40
|
// see "Hooks"
|
|
@@ -41,6 +42,26 @@ export default defineConfig({
|
|
|
41
42
|
});
|
|
42
43
|
```
|
|
43
44
|
|
|
45
|
+
## Markdown pages — `pages`
|
|
46
|
+
|
|
47
|
+
Render standalone Markdown files as documentation pages ahead of the API reference (via `x-tagGroups`, which Scalar and Redoc display in the sidebar, right under the Introduction):
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
defineConfig({
|
|
51
|
+
// ...
|
|
52
|
+
pages: {
|
|
53
|
+
files: ['./docs/getting-started.md', './docs/authentication.md'],
|
|
54
|
+
group: 'Documentation', // sidebar heading for the pages (default)
|
|
55
|
+
apiGroup: 'API', // sidebar heading for the endpoints (default)
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- Each path is resolved relative to the project root (or absolute). A missing file fails the build.
|
|
61
|
+
- The page **title** is the file's first line when it's a `#` heading, otherwise the file name (without extension). The **whole file body** becomes the page content.
|
|
62
|
+
- Pages are emitted first, so they appear at the top of the sidebar.
|
|
63
|
+
- **Grouping is opt-in.** `group` / `apiGroup` switch on `x-tagGroups` navigation (a missing one falls back to its default). Omit **both** and no `x-tagGroups` is emitted — the pages simply lead the flat tag list (still first, just without section headers). When grouping is on, the API's own operation tags are gathered into the `apiGroup` section, because `x-tagGroups` hides any ungrouped tag.
|
|
64
|
+
|
|
44
65
|
## Documentation variants — `@Scope`
|
|
45
66
|
|
|
46
67
|
Tag controllers, methods, models or fields with `@Scope` to make them appear in the spec only when the build is configured for a matching scope. Untagged items are always emitted.
|