@prauga/flexdoc-backend 2.1.0

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.
Files changed (53) hide show
  1. package/README.md +227 -0
  2. package/dist/flexdoc.module.d.ts +14 -0
  3. package/dist/flexdoc.module.js +77 -0
  4. package/dist/flexdoc.module.js.map +1 -0
  5. package/dist/flexdoc.module.test.d.ts +1 -0
  6. package/dist/flexdoc.module.test.js +72 -0
  7. package/dist/flexdoc.module.test.js.map +1 -0
  8. package/dist/flexdoc.service.d.ts +5 -0
  9. package/dist/flexdoc.service.js +24 -0
  10. package/dist/flexdoc.service.js.map +1 -0
  11. package/dist/framework-adapters.d.ts +25 -0
  12. package/dist/framework-adapters.js +163 -0
  13. package/dist/framework-adapters.js.map +1 -0
  14. package/dist/framework-adapters.test.d.ts +1 -0
  15. package/dist/framework-adapters.test.js +37 -0
  16. package/dist/framework-adapters.test.js.map +1 -0
  17. package/dist/index.d.ts +6 -0
  18. package/dist/index.js +14 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/interfaces.d.ts +169 -0
  21. package/dist/interfaces.js +3 -0
  22. package/dist/interfaces.js.map +1 -0
  23. package/dist/renderer/flexdoc.standalone.css +1 -0
  24. package/dist/renderer/flexdoc.standalone.js +200 -0
  25. package/dist/renderer-assets.d.ts +5 -0
  26. package/dist/renderer-assets.js +60 -0
  27. package/dist/renderer-assets.js.map +1 -0
  28. package/dist/scripts/generate-auth.d.ts +2 -0
  29. package/dist/scripts/generate-auth.js +107 -0
  30. package/dist/scripts/generate-auth.js.map +1 -0
  31. package/dist/setup.d.ts +6 -0
  32. package/dist/setup.js +220 -0
  33. package/dist/setup.js.map +1 -0
  34. package/dist/setup.test.d.ts +1 -0
  35. package/dist/setup.test.js +89 -0
  36. package/dist/setup.test.js.map +1 -0
  37. package/dist/template.d.ts +15 -0
  38. package/dist/template.js +64 -0
  39. package/dist/template.js.map +1 -0
  40. package/dist/template.test.d.ts +1 -0
  41. package/dist/template.test.js +38 -0
  42. package/dist/template.test.js.map +1 -0
  43. package/dist/templates/code-examples.njk +106 -0
  44. package/dist/templates/content.njk +272 -0
  45. package/dist/templates/footer.njk +38 -0
  46. package/dist/templates/header.njk +57 -0
  47. package/dist/templates/layout.njk +647 -0
  48. package/dist/templates/parameters.njk +64 -0
  49. package/dist/templates/request-body.njk +63 -0
  50. package/dist/templates/responses.njk +78 -0
  51. package/dist/templates/sidebar.njk +117 -0
  52. package/dist/tsconfig.tsbuildinfo +1 -0
  53. package/package.json +34 -0
package/README.md ADDED
@@ -0,0 +1,227 @@
1
+ # FlexDoc Backend
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@prauga/flexdoc-backend.svg)](https://www.npmjs.com/package/@prauga/flexdoc-backend)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ The backend package for FlexDoc, a modern, customizable OpenAPI documentation generator that creates beautiful API documentation.
7
+
8
+ ## Screenshots
9
+
10
+ ### Light Mode
11
+
12
+ ![FlexDoc Light Mode](./images/flexdoc-light.png)
13
+
14
+ ### Dark Mode
15
+
16
+ ![FlexDoc Dark Mode](./images/flexdoc-dark.png)
17
+
18
+ ## Features
19
+
20
+ - **Modern UI**: Clean, responsive interface with dark mode support
21
+ - **Customizable**: Easily customize colors, typography, and layout
22
+ - **Interactive**: Test API endpoints directly from the documentation
23
+ - **Framework Agnostic**: Works with any JavaScript framework
24
+ - **OpenAPI Compatible**: Supports OpenAPI 3.0 specifications
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ npm install @prauga/flexdoc-backend
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ### Basic Usage
35
+
36
+ ```typescript
37
+ import { FlexDoc } from '@prauga/flexdoc-backend';
38
+ import { OpenAPIObject } from '@nestjs/swagger';
39
+
40
+ // Create a new FlexDoc instance with your OpenAPI spec
41
+ const flexdoc = new FlexDoc({
42
+ spec: yourOpenAPISpec as OpenAPIObject,
43
+ title: 'My API Documentation',
44
+ description: 'Documentation for my awesome API',
45
+ });
46
+
47
+ // Generate HTML documentation
48
+ const html = flexdoc.generateHTML();
49
+
50
+ // Serve the documentation
51
+ app.get('/api/docs', (req, res) => {
52
+ res.send(html);
53
+ });
54
+ ```
55
+
56
+ ### Configuration Options
57
+
58
+ FlexDoc is highly customizable through the `FlexDocOptions` interface:
59
+
60
+ ```typescript
61
+ import { FlexDoc, FlexDocOptions } from '@prauga/flexdoc-backend';
62
+
63
+ const options: FlexDocOptions = {
64
+ // Required
65
+ spec: yourOpenAPISpec,
66
+
67
+ // Basic metadata
68
+ title: 'My API Documentation',
69
+ description: 'Documentation for my awesome API',
70
+
71
+ // Theme configuration
72
+ themeConfig: {
73
+ colors: {
74
+ primary: {
75
+ main: '#3b82f6',
76
+ light: '#eff6ff',
77
+ dark: '#2563eb',
78
+ },
79
+ // Additional color options...
80
+ },
81
+ typography: {
82
+ fontFamily: 'Inter, system-ui, sans-serif',
83
+ fontSize: '16px',
84
+ // Additional typography options...
85
+ },
86
+ },
87
+
88
+ // Footer customization
89
+ footer: {
90
+ copyright: '© 2025 My Company',
91
+ links: [
92
+ {
93
+ text: 'Terms',
94
+ url: '/terms',
95
+ icon: 'file-text', // Optional Lucide icon name
96
+ },
97
+ {
98
+ text: 'Privacy',
99
+ url: '/privacy',
100
+ },
101
+ ],
102
+ },
103
+
104
+ // Additional options...
105
+ };
106
+
107
+ const flexdoc = new FlexDoc(options);
108
+ ```
109
+
110
+ ### Framework Integration Examples
111
+
112
+ #### NestJS
113
+
114
+ ```typescript
115
+ import { NestFactory } from '@nestjs/core';
116
+ import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
117
+ import { FlexDoc } from '@prauga/flexdoc-backend';
118
+ import { AppModule } from './app.module';
119
+
120
+ async function bootstrap() {
121
+ const app = await NestFactory.create(AppModule);
122
+
123
+ // Create OpenAPI spec with Swagger
124
+ const config = new DocumentBuilder()
125
+ .setTitle('My API')
126
+ .setDescription('My API description')
127
+ .setVersion('1.0')
128
+ .build();
129
+ const document = SwaggerModule.createDocument(app, config);
130
+
131
+ // Create FlexDoc instance
132
+ const flexdoc = new FlexDoc({
133
+ spec: document,
134
+ title: 'My API Documentation',
135
+ description: 'Documentation for my awesome API',
136
+ footer: {
137
+ copyright: '© 2025 My Company',
138
+ },
139
+ });
140
+
141
+ // Serve FlexDoc at /api/docs
142
+ app.use('/api/docs', (req, res) => {
143
+ res.send(flexdoc.generateHTML());
144
+ });
145
+
146
+ await app.listen(3000);
147
+ }
148
+ bootstrap();
149
+ ```
150
+
151
+ #### Express
152
+
153
+ ```typescript
154
+ import express from 'express';
155
+ import { FlexDoc } from '@prauga/flexdoc-backend';
156
+ import swaggerJsdoc from 'swagger-jsdoc';
157
+
158
+ const app = express();
159
+
160
+ // Generate OpenAPI spec
161
+ const options = {
162
+ definition: {
163
+ openapi: '3.0.0',
164
+ info: {
165
+ title: 'My API',
166
+ version: '1.0.0',
167
+ },
168
+ },
169
+ apis: ['./src/routes/*.js'],
170
+ };
171
+ const openapiSpec = swaggerJsdoc(options);
172
+
173
+ // Create FlexDoc instance
174
+ const flexdoc = new FlexDoc({
175
+ spec: openapiSpec,
176
+ title: 'My API Documentation',
177
+ });
178
+
179
+ // Serve FlexDoc
180
+ app.get('/api/docs', (req, res) => {
181
+ res.send(flexdoc.generateHTML());
182
+ });
183
+
184
+ app.listen(3000);
185
+ ```
186
+
187
+ ## API Reference
188
+
189
+ ### `FlexDoc` Class
190
+
191
+ The main class for generating API documentation.
192
+
193
+ #### Constructor
194
+
195
+ ```typescript
196
+ constructor(options: FlexDocOptions)
197
+ ```
198
+
199
+ #### Methods
200
+
201
+ - `generateHTML()`: Generates the HTML documentation
202
+ - `getOpenAPISpec()`: Returns the processed OpenAPI specification
203
+
204
+ ### `FlexDocOptions` Interface
205
+
206
+ Configuration options for FlexDoc:
207
+
208
+ | Property | Type | Description |
209
+ | -------------- | ------------------------------- | -------------------------------- |
210
+ | `spec` | `OpenAPIObject` | The OpenAPI specification object |
211
+ | `title` | `string` | Documentation title |
212
+ | `description` | `string` | Documentation description |
213
+ | `themeConfig` | `ThemeConfig` | Theme configuration |
214
+ | `footer` | `FooterConfig` | Footer configuration |
215
+ | `favicon` | `string` | URL to favicon |
216
+ | `customCss` | `string` | Custom CSS to inject |
217
+ | `customJs` | `string` | Custom JavaScript to inject |
218
+ | `defaultTheme` | `'light' \| 'dark' \| 'system'` | Default theme mode |
219
+
220
+ ## Contributing
221
+
222
+ Contributions are welcome! Please feel free to submit a Pull Request.
223
+
224
+ ## License
225
+
226
+ This project is licensed under the MIT License - see the LICENSE file for details.
227
+
@@ -0,0 +1,14 @@
1
+ import { DynamicModule, OnModuleInit } from '@nestjs/common';
2
+ import { HttpAdapterHost } from '@nestjs/core';
3
+ import { FlexDocModuleOptions } from './interfaces';
4
+ export declare class FlexDocModule implements OnModuleInit {
5
+ private readonly options;
6
+ private readonly httpAdapterHost?;
7
+ constructor(options: FlexDocModuleOptions, httpAdapterHost?: HttpAdapterHost | undefined);
8
+ onModuleInit(): void;
9
+ static forRoot(options: FlexDocModuleOptions): DynamicModule;
10
+ static forRootAsync(options: {
11
+ useFactory: (...args: any[]) => Promise<FlexDocModuleOptions> | FlexDocModuleOptions;
12
+ inject?: any[];
13
+ }): DynamicModule;
14
+ }
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var FlexDocModule_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.FlexDocModule = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const core_1 = require("@nestjs/core");
19
+ const setup_1 = require("./setup");
20
+ const flexdoc_service_1 = require("./flexdoc.service");
21
+ let FlexDocModule = FlexDocModule_1 = class FlexDocModule {
22
+ constructor(options, httpAdapterHost) {
23
+ this.options = options;
24
+ this.httpAdapterHost = httpAdapterHost;
25
+ }
26
+ onModuleInit() {
27
+ if (!this.httpAdapterHost) {
28
+ console.warn('HttpAdapterHost not available. FlexDoc routes will not be registered.');
29
+ return;
30
+ }
31
+ const httpAdapter = this.httpAdapterHost.httpAdapter;
32
+ if (!httpAdapter) {
33
+ console.warn('HTTP Adapter not available. FlexDoc routes will not be registered.');
34
+ return;
35
+ }
36
+ const app = httpAdapter.getInstance();
37
+ (0, setup_1.setupFlexDoc)(app, this.options.path, {
38
+ spec: this.options.spec,
39
+ specUrl: this.options.specUrl,
40
+ options: this.options.options,
41
+ });
42
+ }
43
+ static forRoot(options) {
44
+ return {
45
+ module: FlexDocModule_1,
46
+ providers: [
47
+ flexdoc_service_1.FlexDocService,
48
+ {
49
+ provide: 'FLEXDOC_OPTIONS',
50
+ useValue: options,
51
+ },
52
+ ],
53
+ exports: [flexdoc_service_1.FlexDocService],
54
+ };
55
+ }
56
+ static forRootAsync(options) {
57
+ return {
58
+ module: FlexDocModule_1,
59
+ providers: [
60
+ flexdoc_service_1.FlexDocService,
61
+ {
62
+ provide: 'FLEXDOC_OPTIONS',
63
+ useFactory: options.useFactory,
64
+ inject: options.inject || [],
65
+ },
66
+ ],
67
+ exports: [flexdoc_service_1.FlexDocService],
68
+ };
69
+ }
70
+ };
71
+ exports.FlexDocModule = FlexDocModule;
72
+ exports.FlexDocModule = FlexDocModule = FlexDocModule_1 = __decorate([
73
+ (0, common_1.Module)({}),
74
+ __param(0, (0, common_1.Inject)('FLEXDOC_OPTIONS')),
75
+ __metadata("design:paramtypes", [Object, core_1.HttpAdapterHost])
76
+ ], FlexDocModule);
77
+ //# sourceMappingURL=flexdoc.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flexdoc.module.js","sourceRoot":"","sources":["../src/flexdoc.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAMwB;AACxB,uCAA+C;AAC/C,mCAAuC;AACvC,uDAAmD;AAI5C,IAAM,aAAa,qBAAnB,MAAM,aAAa;IACxB,YAC8C,OAA6B,EACxD,eAAiC;QADN,YAAO,GAAP,OAAO,CAAsB;QACxD,oBAAe,GAAf,eAAe,CAAkB;IACjD,CAAC;IAEJ,YAAY;QACV,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CACV,uEAAuE,CACxE,CAAC;YACF,OAAO;QACT,CAAC;QAGD,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC;QACrD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CACV,oEAAoE,CACrE,CAAC;YACF,OAAO;QACT,CAAC;QAGD,MAAM,GAAG,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;QAGtC,IAAA,oBAAY,EAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YACnC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;YACvB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YAC7B,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,OAA6B;QAC1C,OAAO;YACL,MAAM,EAAE,eAAa;YACrB,SAAS,EAAE;gBACT,gCAAc;gBACd;oBACE,OAAO,EAAE,iBAAiB;oBAC1B,QAAQ,EAAE,OAAO;iBAClB;aACF;YACD,OAAO,EAAE,CAAC,gCAAc,CAAC;SAC1B,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAKnB;QACC,OAAO;YACL,MAAM,EAAE,eAAa;YACrB,SAAS,EAAE;gBACT,gCAAc;gBACd;oBACE,OAAO,EAAE,iBAAiB;oBAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;iBAC7B;aACF;YACD,OAAO,EAAE,CAAC,gCAAc,CAAC;SAC1B,CAAC;IACJ,CAAC;CACF,CAAA;AAnEY,sCAAa;wBAAb,aAAa;IADzB,IAAA,eAAM,EAAC,EAAE,CAAC;IAGN,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;6CACS,sBAAe;GAHzC,aAAa,CAmEzB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const flexdoc_module_1 = require("./flexdoc.module");
4
+ const setup_1 = require("./setup");
5
+ jest.mock('./setup', () => ({
6
+ setupFlexDoc: jest.fn(),
7
+ }));
8
+ describe('FlexDocModule', () => {
9
+ let app;
10
+ let mockHttpAdapterHost;
11
+ beforeEach(() => {
12
+ app = { use: jest.fn() };
13
+ mockHttpAdapterHost = {
14
+ httpAdapter: {
15
+ getInstance: jest.fn().mockReturnValue(app),
16
+ },
17
+ };
18
+ jest.clearAllMocks();
19
+ });
20
+ describe('forRoot', () => {
21
+ it('registers static options and installs FlexDoc on module init', () => {
22
+ const options = {
23
+ path: '/api-docs',
24
+ spec: { openapi: '3.0.0' },
25
+ };
26
+ const dynamicModule = flexdoc_module_1.FlexDocModule.forRoot(options);
27
+ const optionsProvider = dynamicModule.providers.find((provider) => provider.provide === 'FLEXDOC_OPTIONS');
28
+ expect(optionsProvider.useValue).toBe(options);
29
+ const module = new flexdoc_module_1.FlexDocModule(options, mockHttpAdapterHost);
30
+ module.onModuleInit();
31
+ expect(setup_1.setupFlexDoc).toHaveBeenCalledWith(app, '/api-docs', expect.objectContaining({ spec: { openapi: '3.0.0' } }));
32
+ });
33
+ });
34
+ describe('forRootAsync', () => {
35
+ it('registers an async options factory and installs its result', async () => {
36
+ const options = {
37
+ path: '/api-docs',
38
+ spec: { openapi: '3.0.0' },
39
+ };
40
+ const useFactory = jest.fn().mockResolvedValue(options);
41
+ const dynamicModule = flexdoc_module_1.FlexDocModule.forRootAsync({ useFactory });
42
+ const optionsProvider = dynamicModule.providers.find((provider) => provider.provide === 'FLEXDOC_OPTIONS');
43
+ const resolvedOptions = await optionsProvider.useFactory();
44
+ expect(useFactory).toHaveBeenCalled();
45
+ const module = new flexdoc_module_1.FlexDocModule(resolvedOptions, mockHttpAdapterHost);
46
+ module.onModuleInit();
47
+ expect(setup_1.setupFlexDoc).toHaveBeenCalledWith(app, '/api-docs', expect.objectContaining({ spec: { openapi: '3.0.0' } }));
48
+ });
49
+ it('preserves dependency injection metadata for the options factory', async () => {
50
+ const mockServiceToken = 'MockService';
51
+ const mockService = {
52
+ getSpec: jest.fn().mockReturnValue({ openapi: '3.0.0' }),
53
+ };
54
+ const useFactory = (service) => ({
55
+ path: '/api-docs',
56
+ spec: service.getSpec(),
57
+ });
58
+ const dynamicModule = flexdoc_module_1.FlexDocModule.forRootAsync({
59
+ useFactory,
60
+ inject: [mockServiceToken],
61
+ });
62
+ const optionsProvider = dynamicModule.providers.find((provider) => provider.provide === 'FLEXDOC_OPTIONS');
63
+ expect(optionsProvider.inject).toEqual([mockServiceToken]);
64
+ const resolvedOptions = await optionsProvider.useFactory(mockService);
65
+ const module = new flexdoc_module_1.FlexDocModule(resolvedOptions, mockHttpAdapterHost);
66
+ module.onModuleInit();
67
+ expect(mockService.getSpec).toHaveBeenCalled();
68
+ expect(setup_1.setupFlexDoc).toHaveBeenCalledWith(app, '/api-docs', expect.objectContaining({ spec: { openapi: '3.0.0' } }));
69
+ });
70
+ });
71
+ });
72
+ //# sourceMappingURL=flexdoc.module.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flexdoc.module.test.js","sourceRoot":"","sources":["../src/flexdoc.module.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { FlexDocOptions } from './interfaces';
2
+ export declare class FlexDocService {
3
+ generateHTML(spec: object, options?: FlexDocOptions): string;
4
+ generateHTMLFromUrl(specUrl: string, options?: FlexDocOptions): string;
5
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.FlexDocService = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const template_1 = require("./template");
12
+ let FlexDocService = class FlexDocService {
13
+ generateHTML(spec, options = {}) {
14
+ return (0, template_1.generateFlexDocHTML)(spec, options);
15
+ }
16
+ generateHTMLFromUrl(specUrl, options = {}) {
17
+ return (0, template_1.generateFlexDocHTML)(null, { ...options, specUrl });
18
+ }
19
+ };
20
+ exports.FlexDocService = FlexDocService;
21
+ exports.FlexDocService = FlexDocService = __decorate([
22
+ (0, common_1.Injectable)()
23
+ ], FlexDocService);
24
+ //# sourceMappingURL=flexdoc.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flexdoc.service.js","sourceRoot":"","sources":["../src/flexdoc.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AAE5C,yCAAiD;AAG1C,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAAY,CAAC,IAAY,EAAE,UAA0B,EAAE;QACrD,OAAO,IAAA,8BAAmB,EAAC,IAA+B,EAAE,OAAO,CAAC,CAAC;IACvE,CAAC;IAED,mBAAmB,CAAC,OAAe,EAAE,UAA0B,EAAE;QAC/D,OAAO,IAAA,8BAAmB,EAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAC5D,CAAC;CACF,CAAA;AARY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;GACA,cAAc,CAQ1B"}
@@ -0,0 +1,25 @@
1
+ import { FlexDocModuleOptions } from './interfaces';
2
+ export interface ExpressLikeApplication {
3
+ use(path: string, handler: (req: any, res: any, next?: any) => void | Promise<void>): void;
4
+ }
5
+ export interface FastifyLikeReply {
6
+ code(statusCode: number): FastifyLikeReply;
7
+ type(contentType: string): FastifyLikeReply;
8
+ header(name: string, value: string): FastifyLikeReply;
9
+ send(payload: any): any;
10
+ }
11
+ export interface FastifyLikeRequest {
12
+ headers: Record<string, string | string[] | undefined>;
13
+ }
14
+ export interface FastifyLikeApplication {
15
+ get(path: string, options: Record<string, unknown>, handler: (req: FastifyLikeRequest, reply: FastifyLikeReply) => any | Promise<any>): void;
16
+ }
17
+ export interface NestLikeApplication {
18
+ getHttpAdapter(): {
19
+ getType?: () => string;
20
+ getInstance: () => any;
21
+ };
22
+ }
23
+ export declare function setupExpressFlexDoc(app: ExpressLikeApplication, path: string, options: Omit<FlexDocModuleOptions, 'path'>): void;
24
+ export declare function setupFastifyFlexDoc(app: FastifyLikeApplication, path: string, options: Omit<FlexDocModuleOptions, 'path'>): void;
25
+ export declare function setupNestFlexDoc(app: NestLikeApplication, path: string, swaggerDocumentOptions: Record<string, unknown>, options?: Omit<FlexDocModuleOptions, 'path' | 'spec' | 'specUrl'>): void;
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.setupExpressFlexDoc = setupExpressFlexDoc;
37
+ exports.setupFastifyFlexDoc = setupFastifyFlexDoc;
38
+ exports.setupNestFlexDoc = setupNestFlexDoc;
39
+ const crypto = __importStar(require("crypto"));
40
+ const jwt = __importStar(require("jsonwebtoken"));
41
+ const renderer_assets_1 = require("./renderer-assets");
42
+ const setup_1 = require("./setup");
43
+ const template_1 = require("./template");
44
+ function setupExpressFlexDoc(app, path, options) {
45
+ (0, setup_1.setupFlexDoc)(app, path, options);
46
+ }
47
+ function generatedPassword(username, secret) {
48
+ const hash = crypto.createHmac('sha256', secret).update(username).digest('base64').substring(0, 12);
49
+ let password = hash;
50
+ if (!/[A-Z]/.test(password))
51
+ password += 'A';
52
+ if (!/[a-z]/.test(password))
53
+ password += 'a';
54
+ if (!/[0-9]/.test(password))
55
+ password += '1';
56
+ if (!/[^A-Za-z0-9]/.test(password))
57
+ password += '!';
58
+ return password;
59
+ }
60
+ function authorize(headers, auth) {
61
+ if (!auth)
62
+ return true;
63
+ const raw = headers.authorization;
64
+ const value = Array.isArray(raw) ? raw[0] : raw;
65
+ if (!value)
66
+ return false;
67
+ if (auth.type === 'basic') {
68
+ if (!value.startsWith('Basic '))
69
+ return false;
70
+ const decoded = Buffer.from(value.slice(6), 'base64').toString('utf8');
71
+ const separator = decoded.indexOf(':');
72
+ const username = separator < 0 ? decoded : decoded.slice(0, separator);
73
+ const password = separator < 0 ? '' : decoded.slice(separator + 1);
74
+ return password === generatedPassword(username, auth.secretKey);
75
+ }
76
+ let token;
77
+ if (value.startsWith('Bearer '))
78
+ token = value.slice(7);
79
+ else if (value.startsWith('Basic ')) {
80
+ const decoded = Buffer.from(value.slice(6), 'base64').toString('utf8');
81
+ const separator = decoded.indexOf(':');
82
+ if (separator >= 0)
83
+ token = decoded.slice(separator + 1);
84
+ }
85
+ if (!token)
86
+ return false;
87
+ try {
88
+ jwt.verify(token, auth.secretKey);
89
+ return true;
90
+ }
91
+ catch {
92
+ return false;
93
+ }
94
+ }
95
+ async function loadRemoteSpec(url) {
96
+ const response = await fetch(url, { redirect: 'follow', signal: AbortSignal.timeout(10000) });
97
+ if (!response.ok)
98
+ throw new Error(`Failed to load OpenAPI spec: HTTP ${response.status}`);
99
+ return response.json();
100
+ }
101
+ function setupFastifyFlexDoc(app, path, options) {
102
+ const normalizedPath = path.startsWith('/') ? path : `/${path}`;
103
+ const rendererBasePath = `${normalizedPath}/__flexdoc`;
104
+ const auth = options.options?.auth;
105
+ let remoteSpecPromise = null;
106
+ const routeOptions = auth ? {
107
+ preHandler: async (request, reply) => {
108
+ if (!authorize(request.headers, auth)) {
109
+ reply.header('WWW-Authenticate', auth.type === 'basic' ? 'Basic' : 'Bearer');
110
+ return reply.code(401).send('Authentication required');
111
+ }
112
+ },
113
+ } : {};
114
+ const resolvedSpec = async () => {
115
+ if (options.spec)
116
+ return options.spec;
117
+ if (!options.specUrl)
118
+ return null;
119
+ if (!remoteSpecPromise)
120
+ remoteSpecPromise = loadRemoteSpec(options.specUrl).catch((error) => {
121
+ remoteSpecPromise = null;
122
+ throw error;
123
+ });
124
+ return remoteSpecPromise;
125
+ };
126
+ app.get(`${rendererBasePath}/renderer.js`, routeOptions, async (_request, reply) => {
127
+ const assets = (0, renderer_assets_1.getRendererAssets)();
128
+ return reply.type('application/javascript; charset=utf-8').header('Cache-Control', 'public, max-age=31536000, immutable').send(assets.javascript);
129
+ });
130
+ app.get(`${rendererBasePath}/renderer.css`, routeOptions, async (_request, reply) => {
131
+ const assets = (0, renderer_assets_1.getRendererAssets)();
132
+ return reply.type('text/css; charset=utf-8').header('Cache-Control', 'public, max-age=31536000, immutable').send(assets.css);
133
+ });
134
+ app.get(normalizedPath, routeOptions, async (_request, reply) => {
135
+ try {
136
+ const html = (0, template_1.generateFlexDocHTML)(await resolvedSpec(), { ...(options.options || {}), rendererBasePath });
137
+ return reply.type('text/html; charset=utf-8').send(html);
138
+ }
139
+ catch (error) {
140
+ return reply.code(502).type('text/plain; charset=utf-8').send(`Unable to load OpenAPI specification: ${error instanceof Error ? error.message : 'Unknown error'}`);
141
+ }
142
+ });
143
+ }
144
+ function setupNestFlexDoc(app, path, swaggerDocumentOptions, options = {}) {
145
+ let SwaggerModule;
146
+ try {
147
+ SwaggerModule = require('@nestjs/swagger').SwaggerModule;
148
+ }
149
+ catch {
150
+ throw new Error('setupNestFlexDoc requires @nestjs/swagger to be installed');
151
+ }
152
+ const spec = SwaggerModule.createDocument(app, swaggerDocumentOptions);
153
+ const adapter = app.getHttpAdapter();
154
+ const instance = adapter.getInstance();
155
+ const type = adapter.getType?.();
156
+ if (type === 'fastify' || (!instance.use && typeof instance.get === 'function')) {
157
+ setupFastifyFlexDoc(instance, path, { ...options, spec });
158
+ }
159
+ else {
160
+ setupExpressFlexDoc(instance, path, { ...options, spec });
161
+ }
162
+ }
163
+ //# sourceMappingURL=framework-adapters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-adapters.js","sourceRoot":"","sources":["../src/framework-adapters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};