@edifice.io/edifice-nestjs-core 1.0.0-develop-pedago.20251210153355 → 1.0.0-develop-pedago.20251211085539

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
@@ -988,6 +988,7 @@ Each tool is available as a binary when you install `@edifice.io/edifice-nestjs-
988
988
  - **edifice-generate-entities**: Generate MikroORM entities from database schema
989
989
  - **edifice-generate-metadata**: Generate application metadata file
990
990
  - **edifice-k6-sync-dto**: Synchronize DTOs for K6 Testing
991
+ - **generate-swagger-pdf**: Generate a PDF from your NestJS API Swagger documentation
991
992
 
992
993
  ---
993
994
 
@@ -1073,6 +1074,40 @@ pnpm edifice-k6-sync-dto
1073
1074
 
1074
1075
  ---
1075
1076
 
1077
+ #### generate-swagger-pdf
1078
+
1079
+ **Purpose:**
1080
+ Generate a PDF from the Swagger (OpenAPI) documentation exposed by your NestJS server.
1081
+
1082
+ **Usage:**
1083
+
1084
+ ```bash
1085
+ npx generate-swagger-pdf --host <host> --port <port>
1086
+ ```
1087
+
1088
+ **Options:**
1089
+
1090
+ - `--host`, `-h`: Swagger server host (default: `127.0.0.1`)
1091
+ - `--port`, `-p`: Swagger server port (default: `3002`)
1092
+
1093
+ The PDF will be generated in the `documentation/api-docs.pdf` folder of your project.
1094
+
1095
+ **Example:**
1096
+
1097
+ ```bash
1098
+ npx generate-swagger-pdf --host 127.0.0.1 --port 4000
1099
+ ```
1100
+
1101
+ This package provides several CLI tools to help you automate common backend tasks.
1102
+ Each tool is available as a binary when you install `@edifice.io/edifice-nestjs-core`.
1103
+
1104
+ - **edifice-generate-entities**: Generate MikroORM entities from database schema
1105
+ - **edifice-generate-metadata**: Generate application metadata file
1106
+ - **edifice-k6-sync-dto**: Synchronize DTOs for K6 Testing
1107
+ - **generate-swagger-pdf**: Generate a PDF from your NestJS API Swagger documentation
1108
+
1109
+ ---
1110
+
1076
1111
  **Note:**
1077
1112
  All CLI tools are available after installing the package.
1078
1113
  You can run them with `pnpm` or `npx` from your project root.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const child_process_1 = require("child_process");
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const wait_on_1 = __importDefault(require("wait-on"));
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const yargs_1 = __importDefault(require("yargs"));
12
+ async function isServerRunning() {
13
+ try {
14
+ const response = await axios_1.default.get(`http://${host}:${port}/openapi-json`, {
15
+ timeout: 3000,
16
+ validateStatus: () => true,
17
+ });
18
+ return response.status >= 200 && response.status < 300;
19
+ }
20
+ catch (error) {
21
+ console.error('Connection error:', error.message);
22
+ return false;
23
+ }
24
+ }
25
+ async function generateSwaggerPdf() {
26
+ const apiUrl = `http://${host}:${port}`;
27
+ const swaggerJsonUrl = `${apiUrl}/openapi-json`;
28
+ const outputDir = path_1.default.resolve(process.cwd(), 'documentation');
29
+ const outputPath = path_1.default.join(outputDir, 'api-docs.pdf');
30
+ const tempJsonPath = path_1.default.join(outputDir, 'swagger-spec.json');
31
+ const htmlPath = path_1.default.join(outputDir, 'api-docs.html');
32
+ try {
33
+ console.log(`Fetching OpenAPI specification from ${swaggerJsonUrl}...`);
34
+ await fs_extra_1.default.ensureDir(outputDir);
35
+ const response = await axios_1.default.get(swaggerJsonUrl, { timeout: 5000 });
36
+ console.log('OpenAPI specification successfully retrieved.');
37
+ await fs_extra_1.default.writeJson(tempJsonPath, response.data, { spaces: 2 });
38
+ console.log(`Specification saved to ${tempJsonPath}`);
39
+ console.log('Generating documentation...');
40
+ let success = false;
41
+ if (!success) {
42
+ try {
43
+ console.log('Generating HTML with @redocly/cli...');
44
+ (0, child_process_1.execSync)(`npx @redocly/cli build-docs ${tempJsonPath} --output=${htmlPath}`, { stdio: 'inherit' });
45
+ success = true;
46
+ console.log('HTML documentation generated successfully with @redocly/cli.');
47
+ if (success && fs_extra_1.default.existsSync(htmlPath)) {
48
+ try {
49
+ console.log('Converting HTML to PDF with electron-pdf...');
50
+ (0, child_process_1.execSync)(`npx electron-pdf "${htmlPath}" "${outputPath}" --landscape=false --marginsType=1`, {
51
+ stdio: 'inherit',
52
+ });
53
+ console.log('PDF documentation generated successfully with electron-pdf.');
54
+ return outputPath;
55
+ }
56
+ catch (_) {
57
+ console.log('electron-pdf conversion failed, trying next method...');
58
+ }
59
+ }
60
+ }
61
+ catch (_) {
62
+ console.log('@redocly/cli failed, trying next method...');
63
+ }
64
+ }
65
+ if (!success) {
66
+ try {
67
+ console.log('Generating PDF with swagger-to-pdf...');
68
+ (0, child_process_1.execSync)(`npx swagger-to-pdf ${tempJsonPath} ${outputPath}`, {
69
+ stdio: 'inherit',
70
+ });
71
+ success = true;
72
+ console.log('PDF documentation generated successfully with swagger-to-pdf.');
73
+ return outputPath;
74
+ }
75
+ catch (_) {
76
+ console.log('swagger-to-pdf failed, trying next method...');
77
+ }
78
+ }
79
+ if (!success) {
80
+ throw new Error('All documentation generation methods failed.');
81
+ }
82
+ return outputPath;
83
+ }
84
+ catch (error) {
85
+ console.error('Error generating documentation:', error.message);
86
+ throw error;
87
+ }
88
+ }
89
+ async function run() {
90
+ console.log('Checking if server is already running...');
91
+ const serverAlreadyRunning = await isServerRunning();
92
+ let serverProcess = null;
93
+ try {
94
+ if (!serverAlreadyRunning) {
95
+ console.log('Starting server...');
96
+ serverProcess = (0, child_process_1.spawn)('pnpm', ['start'], {
97
+ shell: true,
98
+ stdio: 'pipe',
99
+ detached: true,
100
+ env: { ...process.env, PORT: port, HOST: host },
101
+ });
102
+ serverProcess.stdout.on('data', (data) => {
103
+ console.log(`[Server]: ${data.toString().trim()}`);
104
+ });
105
+ serverProcess.stderr.on('data', (data) => {
106
+ console.error(`[Server Error]: ${data.toString().trim()}`);
107
+ });
108
+ console.log('Waiting for server to be ready...');
109
+ await (0, wait_on_1.default)({
110
+ resources: [`http-get://${host}:${port}/openapi-json`],
111
+ delay: 1000,
112
+ interval: 1000,
113
+ timeout: 60000,
114
+ verbose: true,
115
+ });
116
+ console.log('Server is ready!');
117
+ }
118
+ else {
119
+ console.log('Server is already running.');
120
+ }
121
+ console.log('Generating API documentation...');
122
+ const docPath = await generateSwaggerPdf();
123
+ if (fs_extra_1.default.existsSync(docPath)) {
124
+ console.log(`Documentation generated: ${docPath}`);
125
+ if (docPath.endsWith('.pdf')) {
126
+ console.log('PDF documentation was successfully generated.');
127
+ }
128
+ else {
129
+ console.log('HTML documentation was generated. Use browser print function to create PDF if needed.');
130
+ }
131
+ }
132
+ }
133
+ catch (error) {
134
+ console.error('Error in run process:', error.message);
135
+ process.exit(1);
136
+ }
137
+ finally {
138
+ if (serverProcess && !serverAlreadyRunning) {
139
+ console.log('Shutting down server...');
140
+ try {
141
+ if (process.platform === 'win32') {
142
+ (0, child_process_1.execSync)(`taskkill /pid ${serverProcess.pid} /T /F`);
143
+ }
144
+ else {
145
+ process.kill(-serverProcess.pid, 'SIGINT');
146
+ }
147
+ }
148
+ catch (error) {
149
+ console.error('Error shutting down server:', error.message);
150
+ }
151
+ }
152
+ }
153
+ }
154
+ const argv = (0, yargs_1.default)(process.argv.slice(2))
155
+ .option('host', {
156
+ alias: 'h',
157
+ type: 'string',
158
+ description: 'Host of the API server',
159
+ default: '127.0.0.1',
160
+ })
161
+ .option('port', {
162
+ alias: 'p',
163
+ type: 'number',
164
+ description: 'Port of the API server',
165
+ default: 3002,
166
+ })
167
+ .help()
168
+ .parse();
169
+ const host = argv.host;
170
+ const port = argv.port;
171
+ run();
172
+ //# sourceMappingURL=generate-swagger-pdf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-swagger-pdf.js","sourceRoot":"","sources":["../../src/bin/generate-swagger-pdf.ts"],"names":[],"mappings":"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"}