nestjs-openapi-parser 0.0.4 → 0.0.5

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.
@@ -111,11 +111,36 @@ 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, placed first (right under
123
+ * the Introduction). Defaults to `Documentation`.
124
+ */
125
+ group?: string;
126
+ /**
127
+ * Sidebar heading that groups the API's operation tags. Required because
128
+ * `x-tagGroups` hides any ungrouped tag, so the API tags must be grouped too.
129
+ * Defaults to `API`.
130
+ */
131
+ apiGroup?: string;
132
+ }
114
133
  export interface NestParserConfig {
115
134
  openapi: OpenApiConfig;
116
135
  project?: ProjectConfig;
117
136
  conventions?: ConventionsConfig;
118
137
  hooks?: NestParserHooks;
138
+ /**
139
+ * Standalone Markdown pages emitted ahead of the API reference via
140
+ * `x-tagGroups` (rendered by Scalar/Redoc). Omit to emit no pages and no
141
+ * `x-tagGroups` at all.
142
+ */
143
+ pages?: PagesConfig;
119
144
  /**
120
145
  * Class references to force-include in `components.schemas`, even when no
121
146
  * endpoint reaches them. Pass the class itself (not its name) — we resolve
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":";;AA8JA,oCAEC;AAHD,yEAAyE;AACzE,SAAgB,YAAY,CAAC,MAAwB;IACnD,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":";;AAwLA,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;AAarB,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"}
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"}
@@ -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,45 @@ 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
+ const tagGroups = [
117
+ { name: pages.group ?? 'Documentation', tags: pageTags.map((t) => t.name) },
118
+ ];
119
+ if (operationTags.length > 0) {
120
+ tagGroups.push({ name: pages.apiGroup ?? 'API', tags: operationTags.map((t) => t.name) });
121
+ }
122
+ document['x-tagGroups'] = tagGroups;
123
+ }
124
+ /**
125
+ * Read a Markdown page: the title is the first line when it's an ATX heading
126
+ * (`# Title`), otherwise the file's base name without extension. The content is
127
+ * the whole file, verbatim.
128
+ */
129
+ function readPage(filePath) {
130
+ let content;
131
+ try {
132
+ content = node_fs_1.default.readFileSync(filePath, 'utf-8');
133
+ }
134
+ catch {
135
+ throw new Error(`pages: Markdown file not found or unreadable: ${filePath}`);
136
+ }
137
+ const firstLine = content.split('\n', 1)[0]?.trim() ?? '';
138
+ const heading = /^#{1,6}\s+(.+?)\s*$/.exec(firstLine);
139
+ const title = heading ? heading[1].trim() : node_path_1.default.basename(filePath).replace(/\.[^.]+$/, '');
140
+ return { title, content };
141
+ }
95
142
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"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"}
@@ -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
  }
@@ -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
+ - Because `x-tagGroups` hides any tag not in a group, the API's own operation tags are automatically gathered into the `apiGroup` section — so endpoints stay visible.
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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nestjs-openapi-parser",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "CLI that parses a NestJS project with ts-morph and generates an OpenAPI document.",
5
5
  "author": "MobilyFlow",
6
6
  "license": "MIT",