nest-scramble 1.1.0 → 1.2.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.
- package/README.md +410 -73
- package/dist/NestScrambleModule.d.ts +8 -2
- package/dist/NestScrambleModule.d.ts.map +1 -1
- package/dist/NestScrambleModule.js +54 -22
- package/dist/NestScrambleModule.js.map +1 -1
- package/dist/cli.js +123 -14
- package/dist/cli.js.map +1 -1
- package/dist/controllers/DocsController.d.ts +2 -0
- package/dist/controllers/DocsController.d.ts.map +1 -1
- package/dist/controllers/DocsController.js +5 -1
- package/dist/controllers/DocsController.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/AutoDetector.d.ts +47 -0
- package/dist/utils/AutoDetector.d.ts.map +1 -0
- package/dist/utils/AutoDetector.js +194 -0
- package/dist/utils/AutoDetector.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
As a NestJS developer, I was tired of drowning in `@ApiProperty` decorators just to get basic API documentation. I longed for a zero-config solution where docs just worked without polluting my code. **Nest-Scramble changes that** by using static TypeScript analysis to automatically generate:
|
|
13
13
|
|
|
14
14
|
- ✅ **OpenAPI 3.0 specifications** from your DTOs
|
|
15
|
+
- ✅ **Interactive Scalar UI documentation** with zero configuration
|
|
15
16
|
- ✅ **Postman collections** with smart mock data
|
|
16
|
-
- ✅ **Interactive documentation** with code samples
|
|
17
17
|
- ✅ **Live mocking** for rapid prototyping
|
|
18
18
|
|
|
19
19
|
**Zero configuration. Zero decorators. Just pure TypeScript.**
|
|
@@ -55,61 +55,142 @@ Nest-Scramble is engineered using cutting-edge static analysis techniques that t
|
|
|
55
55
|
|
|
56
56
|
This approach delivers what runtime reflection simply cannot: perfect accuracy, zero overhead, and future-proof compatibility with TypeScript's evolving type system.
|
|
57
57
|
|
|
58
|
-
## ⚡ Quick Start (
|
|
58
|
+
## ⚡ Quick Start - Zero Config (2 Steps!)
|
|
59
|
+
|
|
60
|
+
### Option A: Auto-Injection (Recommended - 30 seconds!)
|
|
59
61
|
|
|
60
|
-
### 1. Install
|
|
61
62
|
```bash
|
|
63
|
+
# 1. Install
|
|
64
|
+
npm install nest-scramble
|
|
65
|
+
|
|
66
|
+
# 2. Auto-inject into your project
|
|
67
|
+
npx nest-scramble init
|
|
68
|
+
|
|
69
|
+
# 3. Start your app
|
|
70
|
+
npm run start:dev
|
|
71
|
+
|
|
72
|
+
# 🎉 Done! Visit http://localhost:3000/docs
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The `init` command automatically:
|
|
76
|
+
- ✅ Adds the import statement to your `app.module.ts`
|
|
77
|
+
- ✅ Injects `NestScrambleModule.forRoot()` into your imports
|
|
78
|
+
- ✅ Uses smart defaults with zero configuration needed
|
|
79
|
+
|
|
80
|
+
### Option B: Manual Installation (3 Steps)
|
|
81
|
+
|
|
82
|
+
#### 1. Install the Package
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Using npm
|
|
86
|
+
npm install nest-scramble
|
|
87
|
+
|
|
88
|
+
# Using yarn
|
|
89
|
+
yarn add nest-scramble
|
|
90
|
+
|
|
91
|
+
# Using pnpm
|
|
62
92
|
pnpm add nest-scramble
|
|
63
93
|
```
|
|
64
94
|
|
|
65
|
-
|
|
95
|
+
#### 2. Import Module in Your NestJS App
|
|
96
|
+
|
|
97
|
+
**Zero-Config (Recommended):**
|
|
98
|
+
```typescript
|
|
99
|
+
import { Module } from '@nestjs/common';
|
|
100
|
+
import { NestScrambleModule } from 'nest-scramble';
|
|
101
|
+
|
|
102
|
+
@Module({
|
|
103
|
+
imports: [
|
|
104
|
+
NestScrambleModule.forRoot(), // 🎯 That's it! Zero config needed
|
|
105
|
+
],
|
|
106
|
+
})
|
|
107
|
+
export class AppModule {}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**With Custom Options:**
|
|
66
111
|
```typescript
|
|
67
|
-
|
|
112
|
+
import { Module } from '@nestjs/common';
|
|
68
113
|
import { NestScrambleModule } from 'nest-scramble';
|
|
69
114
|
|
|
70
115
|
@Module({
|
|
71
116
|
imports: [
|
|
72
117
|
NestScrambleModule.forRoot({
|
|
73
|
-
|
|
74
|
-
|
|
118
|
+
sourcePath: 'src', // Auto-detected by default
|
|
119
|
+
baseUrl: 'http://localhost:3000', // Auto-detected from PORT env
|
|
120
|
+
enableMock: true, // Enabled by default
|
|
121
|
+
autoExportPostman: false, // Disabled by default
|
|
122
|
+
apiTitle: 'My API', // Auto-detected from package.json
|
|
123
|
+
apiVersion: '1.0.0', // Auto-detected from package.json
|
|
75
124
|
}),
|
|
76
125
|
],
|
|
77
126
|
})
|
|
78
127
|
export class AppModule {}
|
|
79
128
|
```
|
|
80
129
|
|
|
81
|
-
|
|
82
|
-
- **📖 API Docs**: http://localhost:3000/docs
|
|
83
|
-
- **🎭 Live Mocking**: http://localhost:3000/scramble-mock/users
|
|
84
|
-
- **📤 Postman Collection**: Auto-generated at `collection.json`
|
|
130
|
+
#### 3. Start Your App and Visit Documentation
|
|
85
131
|
|
|
86
|
-
|
|
132
|
+
```bash
|
|
133
|
+
npm run start:dev
|
|
134
|
+
```
|
|
87
135
|
|
|
88
|
-
|
|
136
|
+
You'll see a beautiful dashboard in your terminal:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
┌──────────────────────────────────────────────────────────┐
|
|
140
|
+
│ 🚀 Nest-Scramble by Mohamed Mustafa is Active! │
|
|
141
|
+
├──────────────────────────────────────────────────────────┤
|
|
142
|
+
│ 📖 Docs: http://localhost:3000/docs │
|
|
143
|
+
│ 📄 JSON: http://localhost:3000/docs-json │
|
|
144
|
+
│ 🎭 Mock: http://localhost:3000/scramble-mock │
|
|
145
|
+
│ ✨ Scanning: src │
|
|
146
|
+
│ 🎯 Controllers: 5 │
|
|
147
|
+
└──────────────────────────────────────────────────────────┘
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Then open your browser:
|
|
151
|
+
|
|
152
|
+
- **📖 Interactive API Docs (Scalar UI)**: http://localhost:3000/docs
|
|
153
|
+
- **📄 OpenAPI JSON Spec**: http://localhost:3000/docs-json
|
|
154
|
+
- **🎭 Mock Endpoints**: http://localhost:3000/scramble-mock/*
|
|
155
|
+
|
|
156
|
+
**That's it!** Nest-Scramble automatically:
|
|
157
|
+
- 🔍 Detects your project structure
|
|
158
|
+
- 📂 Finds your controllers
|
|
159
|
+
- 📝 Generates OpenAPI spec
|
|
160
|
+
- 🎨 Serves beautiful documentation
|
|
161
|
+
- 🎭 Provides mock endpoints
|
|
162
|
+
|
|
163
|
+
## ⚙️ Configuration Options
|
|
89
164
|
|
|
90
165
|
```typescript
|
|
91
166
|
NestScrambleModule.forRoot({
|
|
92
|
-
//
|
|
93
|
-
|
|
167
|
+
// Source directory to scan for controllers
|
|
168
|
+
sourcePath: 'src', // default: 'src'
|
|
94
169
|
|
|
95
|
-
//
|
|
96
|
-
|
|
170
|
+
// API base URL for OpenAPI spec
|
|
171
|
+
baseUrl: 'http://localhost:3000', // default: 'http://localhost:3000'
|
|
97
172
|
|
|
98
|
-
//
|
|
99
|
-
|
|
173
|
+
// Enable live mocking middleware
|
|
174
|
+
enableMock: true, // default: true
|
|
100
175
|
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
openApiOutputPath: 'openapi.json',
|
|
176
|
+
// Auto-export Postman collection on startup
|
|
177
|
+
autoExportPostman: false, // default: false
|
|
104
178
|
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
// Source directory to scan
|
|
109
|
-
sourcePath: 'src', // default: 'src'
|
|
179
|
+
// Postman collection output path
|
|
180
|
+
postmanOutputPath: 'collection.json', // default: 'collection.json'
|
|
110
181
|
})
|
|
111
182
|
```
|
|
112
183
|
|
|
184
|
+
### Configuration Details
|
|
185
|
+
|
|
186
|
+
| Option | Type | Default | Description |
|
|
187
|
+
|--------|------|---------|-------------|
|
|
188
|
+
| `sourcePath` | `string` | `'src'` | Directory where your NestJS controllers are located |
|
|
189
|
+
| `baseUrl` | `string` | `'http://localhost:3000'` | Base URL for your API (used in OpenAPI spec) |
|
|
190
|
+
| `enableMock` | `boolean` | `true` | Enable `/scramble-mock/*` endpoints for testing |
|
|
191
|
+
| `autoExportPostman` | `boolean` | `false` | Automatically generate Postman collection file |
|
|
192
|
+
| `postmanOutputPath` | `string` | `'collection.json'` | Output path for Postman collection |
|
|
193
|
+
|
|
113
194
|
## 🎭 Live Mocking Guide
|
|
114
195
|
|
|
115
196
|
Nest-Scramble provides **instant API mocking** without writing controllers:
|
|
@@ -149,57 +230,157 @@ GET /scramble-mock/users/123
|
|
|
149
230
|
## 🔧 Advanced Usage
|
|
150
231
|
|
|
151
232
|
### CLI Generation
|
|
233
|
+
|
|
234
|
+
The Nest-Scramble CLI allows you to generate API documentation without running your NestJS application.
|
|
235
|
+
|
|
236
|
+
#### Generate OpenAPI Specification
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
# Using npx
|
|
240
|
+
npx nest-scramble generate src
|
|
241
|
+
|
|
242
|
+
# Using pnpm dlx
|
|
243
|
+
pnpm dlx nest-scramble generate src
|
|
244
|
+
|
|
245
|
+
# Using yarn dlx
|
|
246
|
+
yarn dlx nest-scramble generate src
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
#### CLI Options
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
nest-scramble generate <sourcePath> [options]
|
|
253
|
+
|
|
254
|
+
Options:
|
|
255
|
+
-o, --output <file> Output file path (default: "openapi.json")
|
|
256
|
+
-f, --format <type> Output format: openapi or postman (default: "openapi")
|
|
257
|
+
-b, --baseUrl <url> Base URL for the API (default: "http://localhost:3000")
|
|
258
|
+
-t, --title <title> API title (default: "NestJS API")
|
|
259
|
+
-v, --apiVersion <version> API version (default: "1.0.0")
|
|
260
|
+
-h, --help Display help for command
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### Examples
|
|
264
|
+
|
|
265
|
+
**Generate OpenAPI JSON:**
|
|
266
|
+
```bash
|
|
267
|
+
pnpm dlx nest-scramble generate src --output openapi.json
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Generate Postman Collection:**
|
|
152
271
|
```bash
|
|
153
|
-
pnpm dlx nest-scramble generate src --output
|
|
272
|
+
pnpm dlx nest-scramble generate src --format postman --output collection.json
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**Custom API Details:**
|
|
276
|
+
```bash
|
|
277
|
+
pnpm dlx nest-scramble generate src \
|
|
278
|
+
--output my-api.json \
|
|
279
|
+
--title "My Awesome API" \
|
|
280
|
+
--apiVersion "2.0.0" \
|
|
281
|
+
--baseUrl "https://api.example.com"
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**Check Version:**
|
|
285
|
+
```bash
|
|
286
|
+
pnpm dlx nest-scramble --version
|
|
154
287
|
```
|
|
155
288
|
|
|
156
289
|
### Programmatic API
|
|
290
|
+
|
|
291
|
+
Use Nest-Scramble programmatically in your Node.js scripts:
|
|
292
|
+
|
|
157
293
|
```typescript
|
|
158
|
-
import { ScannerService, OpenApiTransformer } from 'nest-scramble';
|
|
294
|
+
import { ScannerService, OpenApiTransformer, PostmanCollectionGenerator } from 'nest-scramble';
|
|
295
|
+
import * as fs from 'fs';
|
|
159
296
|
|
|
297
|
+
// Scan controllers
|
|
160
298
|
const scanner = new ScannerService();
|
|
161
299
|
const controllers = scanner.scanControllers('src');
|
|
162
300
|
|
|
163
|
-
|
|
164
|
-
const
|
|
301
|
+
// Generate OpenAPI spec
|
|
302
|
+
const transformer = new OpenApiTransformer('http://localhost:3000');
|
|
303
|
+
const openApiSpec = transformer.transform(
|
|
304
|
+
controllers,
|
|
305
|
+
'My API',
|
|
306
|
+
'1.0.0',
|
|
307
|
+
'http://localhost:3000'
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
// Save to file
|
|
311
|
+
fs.writeFileSync('openapi.json', JSON.stringify(openApiSpec, null, 2));
|
|
312
|
+
|
|
313
|
+
// Or generate Postman collection
|
|
314
|
+
const postmanGen = new PostmanCollectionGenerator('http://localhost:3000');
|
|
315
|
+
const collection = postmanGen.generateCollection(controllers);
|
|
316
|
+
fs.writeFileSync('collection.json', JSON.stringify(collection, null, 2));
|
|
165
317
|
```
|
|
166
318
|
|
|
167
|
-
###
|
|
168
|
-
|
|
169
|
-
|
|
319
|
+
### CI/CD Integration
|
|
320
|
+
|
|
321
|
+
Add to your CI/CD pipeline to auto-generate documentation:
|
|
322
|
+
|
|
323
|
+
```yaml
|
|
324
|
+
# .github/workflows/docs.yml
|
|
325
|
+
name: Generate API Docs
|
|
326
|
+
|
|
327
|
+
on:
|
|
328
|
+
push:
|
|
329
|
+
branches: [main]
|
|
330
|
+
|
|
331
|
+
jobs:
|
|
332
|
+
generate-docs:
|
|
333
|
+
runs-on: ubuntu-latest
|
|
334
|
+
steps:
|
|
335
|
+
- uses: actions/checkout@v3
|
|
336
|
+
- uses: actions/setup-node@v3
|
|
337
|
+
with:
|
|
338
|
+
node-version: '18'
|
|
339
|
+
- run: npm install
|
|
340
|
+
- run: npx nest-scramble generate src --output openapi.json
|
|
341
|
+
- uses: actions/upload-artifact@v3
|
|
342
|
+
with:
|
|
343
|
+
name: api-docs
|
|
344
|
+
path: openapi.json
|
|
170
345
|
```
|
|
171
|
-
Automatically regenerates docs on file changes.
|
|
172
346
|
|
|
173
|
-
## 🎨 UI
|
|
347
|
+
## 🎨 Documentation UI
|
|
174
348
|
|
|
175
|
-
###
|
|
176
|
-
For the modern Scalar documentation UI:
|
|
349
|
+
### Built-in Scalar UI
|
|
177
350
|
|
|
178
|
-
|
|
179
|
-
import { ApiReference } from '@scalar/nestjs';
|
|
351
|
+
Nest-Scramble comes with **Scalar UI** built-in via CDN. No additional packages needed!
|
|
180
352
|
|
|
181
|
-
|
|
182
|
-
imports: [
|
|
183
|
-
NestScrambleModule.forRoot(),
|
|
184
|
-
ApiReference({
|
|
185
|
-
path: '/docs',
|
|
186
|
-
spec: {
|
|
187
|
-
content: () => {
|
|
188
|
-
const scanner = new ScannerService();
|
|
189
|
-
const controllers = scanner.scanControllers('src');
|
|
190
|
-
const transformer = new OpenApiTransformer();
|
|
191
|
-
return transformer.transform(controllers);
|
|
192
|
-
},
|
|
193
|
-
},
|
|
194
|
-
}),
|
|
195
|
-
],
|
|
196
|
-
})
|
|
197
|
-
export class AppModule {}
|
|
198
|
-
```
|
|
353
|
+
When you visit `http://localhost:3000/docs`, you'll see a beautiful, interactive API documentation interface with:
|
|
199
354
|
|
|
200
|
-
|
|
355
|
+
- 🎯 **Interactive API Explorer** - Test endpoints directly from the browser
|
|
356
|
+
- 📝 **Auto-generated Examples** - Request/response samples for all endpoints
|
|
357
|
+
- 🔍 **Search Functionality** - Quickly find endpoints
|
|
358
|
+
- 🌙 **Dark Mode Support** - Easy on the eyes
|
|
359
|
+
- 📱 **Mobile Responsive** - Works on all devices
|
|
201
360
|
|
|
202
|
-
|
|
361
|
+
### Available Endpoints
|
|
362
|
+
|
|
363
|
+
| Endpoint | Description |
|
|
364
|
+
|----------|-------------|
|
|
365
|
+
| `GET /docs` | Interactive Scalar UI documentation |
|
|
366
|
+
| `GET /docs-json` | OpenAPI 3.0 JSON specification |
|
|
367
|
+
| `GET /docs/json` | Legacy endpoint (same as above) |
|
|
368
|
+
| `GET /docs/spec` | OpenAPI spec as JSON response |
|
|
369
|
+
|
|
370
|
+
### Accessing the OpenAPI Spec
|
|
371
|
+
|
|
372
|
+
You can use the OpenAPI JSON with other tools:
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
# Download the spec
|
|
376
|
+
curl http://localhost:3000/docs-json > openapi.json
|
|
377
|
+
|
|
378
|
+
# Use with Swagger UI
|
|
379
|
+
docker run -p 8080:8080 -e SWAGGER_JSON=/openapi.json -v $(pwd):/usr/share/nginx/html/openapi.json swaggerapi/swagger-ui
|
|
380
|
+
|
|
381
|
+
# Import into Postman
|
|
382
|
+
# File > Import > Link > http://localhost:3000/docs-json
|
|
383
|
+
```
|
|
203
384
|
|
|
204
385
|
## ✅ Supported Features
|
|
205
386
|
|
|
@@ -260,26 +441,182 @@ Run the demo to verify everything works perfectly.
|
|
|
260
441
|
|
|
261
442
|
### Common Issues
|
|
262
443
|
|
|
263
|
-
**
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
444
|
+
#### 1. **"No controllers found" Warning**
|
|
445
|
+
|
|
446
|
+
If you see this warning on startup:
|
|
447
|
+
```
|
|
448
|
+
[Nest-Scramble] No controllers found in /src. Please check your sourcePath config.
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
**Solution:**
|
|
452
|
+
- Ensure your `sourcePath` option points to the correct directory containing your controllers
|
|
453
|
+
- Check that your controllers use the `@Controller()` decorator from `@nestjs/common`
|
|
454
|
+
- Verify your project structure matches the configured path
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
NestScrambleModule.forRoot({
|
|
458
|
+
sourcePath: 'src', // Make sure this matches your project structure
|
|
459
|
+
})
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
#### 2. **UI Not Loading / Blank Page at /docs**
|
|
463
|
+
|
|
464
|
+
**Solution:**
|
|
465
|
+
- Clear your browser cache and hard refresh (Ctrl+Shift+R / Cmd+Shift+R)
|
|
466
|
+
- Check browser console for errors
|
|
467
|
+
- Verify the `/docs-json` endpoint returns valid JSON
|
|
468
|
+
- Ensure you're using version 1.1.0 or higher: `npm list nest-scramble`
|
|
469
|
+
|
|
470
|
+
#### 3. **TypeScript Compilation Errors**
|
|
471
|
+
|
|
472
|
+
If you get errors like `Cannot find module 'nest-scramble'`:
|
|
473
|
+
|
|
474
|
+
**Solution:**
|
|
475
|
+
```bash
|
|
476
|
+
# Clear node_modules and reinstall
|
|
477
|
+
rm -rf node_modules package-lock.json
|
|
478
|
+
npm install
|
|
479
|
+
|
|
480
|
+
# Rebuild your project
|
|
481
|
+
npm run build
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
#### 4. **"Unauthorized" (401) Error on /docs Endpoint**
|
|
485
|
+
|
|
486
|
+
If you have a Global AuthGuard and get 401 Unauthorized when accessing `/docs` or `/docs-json`:
|
|
487
|
+
|
|
488
|
+
**Solution:**
|
|
489
|
+
|
|
490
|
+
Nest-Scramble automatically marks its documentation endpoints as public using `@SetMetadata('isPublic', true)`. However, your AuthGuard needs to respect this metadata.
|
|
491
|
+
|
|
492
|
+
Update your AuthGuard to check for the `isPublic` metadata:
|
|
493
|
+
|
|
494
|
+
```typescript
|
|
495
|
+
import { Injectable, ExecutionContext } from '@nestjs/common';
|
|
496
|
+
import { Reflector } from '@nestjs/core';
|
|
497
|
+
import { AuthGuard } from '@nestjs/passport';
|
|
498
|
+
|
|
499
|
+
@Injectable()
|
|
500
|
+
export class JwtAuthGuard extends AuthGuard('jwt') {
|
|
501
|
+
constructor(private reflector: Reflector) {
|
|
502
|
+
super();
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
canActivate(context: ExecutionContext) {
|
|
506
|
+
// Check if route is marked as public
|
|
507
|
+
const isPublic = this.reflector.getAllAndOverride<boolean>('isPublic', [
|
|
508
|
+
context.getHandler(),
|
|
509
|
+
context.getClass(),
|
|
510
|
+
]);
|
|
511
|
+
|
|
512
|
+
if (isPublic) {
|
|
513
|
+
return true; // Allow access to public routes
|
|
271
514
|
}
|
|
515
|
+
|
|
516
|
+
return super.canActivate(context);
|
|
272
517
|
}
|
|
273
518
|
}
|
|
274
519
|
```
|
|
275
520
|
|
|
276
|
-
**
|
|
277
|
-
|
|
521
|
+
**Alternative Solution - Exclude /docs path:**
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
import { Module } from '@nestjs/common';
|
|
525
|
+
import { APP_GUARD } from '@nestjs/core';
|
|
526
|
+
|
|
527
|
+
@Module({
|
|
528
|
+
providers: [
|
|
529
|
+
{
|
|
530
|
+
provide: APP_GUARD,
|
|
531
|
+
useClass: JwtAuthGuard,
|
|
532
|
+
},
|
|
533
|
+
],
|
|
534
|
+
})
|
|
535
|
+
export class AppModule {}
|
|
536
|
+
|
|
537
|
+
// In your AuthGuard:
|
|
538
|
+
canActivate(context: ExecutionContext) {
|
|
539
|
+
const request = context.switchToHttp().getRequest();
|
|
540
|
+
|
|
541
|
+
// Skip authentication for documentation endpoints
|
|
542
|
+
if (request.url.startsWith('/docs')) {
|
|
543
|
+
return true;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return super.canActivate(context);
|
|
547
|
+
}
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
#### 5. **pnpm Dependency Conflicts**
|
|
551
|
+
|
|
552
|
+
If using pnpm and getting peer dependency warnings:
|
|
553
|
+
|
|
554
|
+
**Solution:**
|
|
555
|
+
Nest-Scramble v1.1.0+ properly declares peer dependencies. Update to the latest version:
|
|
556
|
+
```bash
|
|
557
|
+
pnpm update nest-scramble
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
#### 6. **Controllers Not Being Scanned**
|
|
561
|
+
|
|
562
|
+
The scanner looks in your **host project's** `src` folder, not the library's folder.
|
|
563
|
+
|
|
564
|
+
**Diagnostic Steps:**
|
|
565
|
+
1. Check the startup logs - they show exactly where the scanner is looking:
|
|
566
|
+
```
|
|
567
|
+
[Nest-Scramble] Scanning directory: /path/to/your/project/src
|
|
568
|
+
[Nest-Scramble] Found X controller(s)
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
2. Ensure your controllers are in TypeScript files (`.ts`) not JavaScript (`.js`)
|
|
572
|
+
|
|
573
|
+
3. Verify your `tsconfig.json` exists in the project root
|
|
574
|
+
|
|
575
|
+
#### 7. **Mock Endpoints Not Working**
|
|
576
|
+
|
|
577
|
+
If `/scramble-mock/*` returns 404:
|
|
578
|
+
|
|
579
|
+
**Solution:**
|
|
580
|
+
- Ensure `enableMock: true` in your configuration
|
|
581
|
+
- The middleware applies to all routes matching `/scramble-mock/*`
|
|
582
|
+
- Example: `http://localhost:3000/scramble-mock/users/123`
|
|
583
|
+
|
|
584
|
+
#### 8. **OpenAPI Spec is Empty or Incomplete**
|
|
585
|
+
|
|
586
|
+
**Solution:**
|
|
587
|
+
- Ensure your DTOs are TypeScript classes or interfaces (not plain objects)
|
|
588
|
+
- Check that your controller methods have proper return type annotations
|
|
589
|
+
- Verify decorators are imported from `@nestjs/common`
|
|
590
|
+
|
|
591
|
+
```typescript
|
|
592
|
+
// ✅ Good - Explicit return type
|
|
593
|
+
@Get(':id')
|
|
594
|
+
getUser(@Param('id') id: string): UserDto {
|
|
595
|
+
return this.userService.findOne(id);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// ❌ Bad - No return type
|
|
599
|
+
@Get(':id')
|
|
600
|
+
getUser(@Param('id') id: string) {
|
|
601
|
+
return this.userService.findOne(id);
|
|
602
|
+
}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
### Getting Help
|
|
606
|
+
|
|
607
|
+
If you're still experiencing issues:
|
|
278
608
|
|
|
279
|
-
**
|
|
280
|
-
|
|
609
|
+
1. **Check the logs** - Nest-Scramble provides detailed diagnostic output on startup
|
|
610
|
+
2. **Verify your version** - Run `npm list nest-scramble` (should be 1.1.0+)
|
|
611
|
+
3. **Open an issue** - [GitHub Issues](https://github.com/Eng-MMustafa/nest-scramble/issues)
|
|
612
|
+
4. **Join discussions** - [GitHub Discussions](https://github.com/Eng-MMustafa/nest-scramble/discussions)
|
|
281
613
|
|
|
282
|
-
|
|
614
|
+
When reporting issues, please include:
|
|
615
|
+
- Nest-Scramble version
|
|
616
|
+
- NestJS version
|
|
617
|
+
- Package manager (npm/yarn/pnpm)
|
|
618
|
+
- Startup logs
|
|
619
|
+
- Sample controller code
|
|
283
620
|
|
|
284
621
|
## 🤝 Contributing
|
|
285
622
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Nest-Scramble | Developed by Mohamed Mustafa | MIT License **/
|
|
2
|
-
import { DynamicModule, MiddlewareConsumer } from '@nestjs/common';
|
|
2
|
+
import { DynamicModule, MiddlewareConsumer, OnModuleInit } from '@nestjs/common';
|
|
3
3
|
export interface NestScrambleOptions {
|
|
4
4
|
path?: string;
|
|
5
5
|
enableMock?: boolean;
|
|
@@ -7,8 +7,14 @@ export interface NestScrambleOptions {
|
|
|
7
7
|
postmanOutputPath?: string;
|
|
8
8
|
baseUrl?: string;
|
|
9
9
|
sourcePath?: string;
|
|
10
|
+
apiTitle?: string;
|
|
11
|
+
apiVersion?: string;
|
|
10
12
|
}
|
|
11
|
-
export declare class NestScrambleModule {
|
|
13
|
+
export declare class NestScrambleModule implements OnModuleInit {
|
|
14
|
+
private static moduleOptions;
|
|
15
|
+
private static detectedPort;
|
|
16
|
+
onModuleInit(): void;
|
|
17
|
+
private displayDashboard;
|
|
12
18
|
static forRoot(options?: NestScrambleOptions): DynamicModule;
|
|
13
19
|
static forRootAsync(options?: NestScrambleOptions): DynamicModule;
|
|
14
20
|
configure(consumer: MiddlewareConsumer): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NestScrambleModule.d.ts","sourceRoot":"","sources":["../src/NestScrambleModule.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,OAAO,EAAE,aAAa,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"NestScrambleModule.d.ts","sourceRoot":"","sources":["../src/NestScrambleModule.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAU,YAAY,EAAiB,MAAM,gBAAgB,CAAC;AASxG,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBACa,kBAAmB,YAAW,YAAY;IACrD,OAAO,CAAC,MAAM,CAAC,aAAa,CAA2B;IACvD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAgB;IAE3C,YAAY;IAIZ,OAAO,CAAC,gBAAgB;IAkBxB,MAAM,CAAC,OAAO,CAAC,OAAO,GAAE,mBAAwB,GAAG,aAAa;IA4EhE,MAAM,CAAC,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,aAAa;IAKrE,SAAS,CAAC,QAAQ,EAAE,kBAAkB;CAMvC"}
|
|
@@ -16,35 +16,65 @@ const ScannerService_1 = require("./scanner/ScannerService");
|
|
|
16
16
|
const MockGenerator_1 = require("./utils/MockGenerator");
|
|
17
17
|
const OpenApiTransformer_1 = require("./utils/OpenApiTransformer");
|
|
18
18
|
const DocsController_1 = require("./controllers/DocsController");
|
|
19
|
+
const AutoDetector_1 = require("./utils/AutoDetector");
|
|
19
20
|
let NestScrambleModule = NestScrambleModule_1 = class NestScrambleModule {
|
|
21
|
+
onModuleInit() {
|
|
22
|
+
this.displayDashboard();
|
|
23
|
+
}
|
|
24
|
+
displayDashboard() {
|
|
25
|
+
const port = NestScrambleModule_1.detectedPort;
|
|
26
|
+
const options = NestScrambleModule_1.moduleOptions;
|
|
27
|
+
const projectStructure = AutoDetector_1.AutoDetector.detectProjectStructure();
|
|
28
|
+
console.log('\n┌──────────────────────────────────────────────────────────┐');
|
|
29
|
+
console.log('│ 🚀 Nest-Scramble by Mohamed Mustafa is Active! │');
|
|
30
|
+
console.log('├──────────────────────────────────────────────────────────┤');
|
|
31
|
+
console.log(`│ 📖 Docs: http://localhost:${port}/docs${' '.repeat(Math.max(0, 26 - port.toString().length))}│`);
|
|
32
|
+
console.log(`│ 📄 JSON: http://localhost:${port}/docs-json${' '.repeat(Math.max(0, 21 - port.toString().length))}│`);
|
|
33
|
+
if (options.enableMock !== false) {
|
|
34
|
+
console.log(`│ 🎭 Mock: http://localhost:${port}/scramble-mock${' '.repeat(Math.max(0, 16 - port.toString().length))}│`);
|
|
35
|
+
}
|
|
36
|
+
console.log(`│ ✨ Scanning: ${projectStructure.sourcePath}${' '.repeat(Math.max(0, 43 - projectStructure.sourcePath.length))}│`);
|
|
37
|
+
console.log(`│ 🎯 Controllers: ${projectStructure.controllerPaths.length}${' '.repeat(Math.max(0, 40 - projectStructure.controllerPaths.length.toString().length))}│`);
|
|
38
|
+
console.log('└──────────────────────────────────────────────────────────┘\n');
|
|
39
|
+
}
|
|
20
40
|
static forRoot(options = {}) {
|
|
21
|
-
|
|
41
|
+
// Auto-detect project structure
|
|
42
|
+
const projectStructure = AutoDetector_1.AutoDetector.detectProjectStructure();
|
|
43
|
+
// Smart defaults with auto-detection
|
|
44
|
+
const config = {
|
|
45
|
+
path: options.path || '/docs',
|
|
46
|
+
enableMock: options.enableMock !== undefined ? options.enableMock : true,
|
|
47
|
+
autoExportPostman: options.autoExportPostman || false,
|
|
48
|
+
postmanOutputPath: options.postmanOutputPath || 'collection.json',
|
|
49
|
+
baseUrl: options.baseUrl || AutoDetector_1.AutoDetector.detectBaseUrl(),
|
|
50
|
+
sourcePath: options.sourcePath || projectStructure.sourcePath,
|
|
51
|
+
apiTitle: options.apiTitle || AutoDetector_1.AutoDetector.getAppName(),
|
|
52
|
+
apiVersion: options.apiVersion || AutoDetector_1.AutoDetector.getAppVersion(),
|
|
53
|
+
};
|
|
54
|
+
// Store for dashboard display
|
|
55
|
+
NestScrambleModule_1.moduleOptions = config;
|
|
56
|
+
NestScrambleModule_1.detectedPort = AutoDetector_1.AutoDetector.detectPort();
|
|
22
57
|
console.log(`\n${'='.repeat(60)}`);
|
|
23
|
-
console.log(`🚀 [Nest-Scramble]
|
|
58
|
+
console.log(`🚀 [Nest-Scramble] Zero-Config Auto-Detection Engine`);
|
|
24
59
|
console.log(` Developed by Mohamed Mustafa | MIT License`);
|
|
25
60
|
console.log(`${'='.repeat(60)}`);
|
|
61
|
+
console.log(`\n[Nest-Scramble] 🔍 Auto-detected project structure:`);
|
|
62
|
+
console.log(` Root: ${projectStructure.rootPath}`);
|
|
63
|
+
console.log(` Source: ${config.sourcePath}`);
|
|
64
|
+
console.log(` Config: ${projectStructure.tsConfigPath}`);
|
|
26
65
|
const scanner = new ScannerService_1.ScannerService();
|
|
27
|
-
const controllers = scanner.scanControllers(sourcePath);
|
|
28
|
-
console.log(`\n[Nest-Scramble] Generating OpenAPI specification...`);
|
|
29
|
-
const transformer = new OpenApiTransformer_1.OpenApiTransformer(baseUrl);
|
|
30
|
-
const openApiSpec = transformer.transform(controllers,
|
|
31
|
-
console.log(`[Nest-Scramble] OpenAPI spec generated successfully`);
|
|
32
|
-
if (autoExportPostman) {
|
|
33
|
-
console.log(`[Nest-Scramble] Exporting Postman collection...`);
|
|
34
|
-
const generator = new PostmanCollectionGenerator_1.PostmanCollectionGenerator(baseUrl);
|
|
66
|
+
const controllers = scanner.scanControllers(config.sourcePath);
|
|
67
|
+
console.log(`\n[Nest-Scramble] 📦 Generating OpenAPI specification...`);
|
|
68
|
+
const transformer = new OpenApiTransformer_1.OpenApiTransformer(config.baseUrl);
|
|
69
|
+
const openApiSpec = transformer.transform(controllers, config.apiTitle, config.apiVersion, config.baseUrl);
|
|
70
|
+
console.log(`[Nest-Scramble] ✅ OpenAPI spec generated successfully`);
|
|
71
|
+
if (config.autoExportPostman) {
|
|
72
|
+
console.log(`[Nest-Scramble] 📤 Exporting Postman collection...`);
|
|
73
|
+
const generator = new PostmanCollectionGenerator_1.PostmanCollectionGenerator(config.baseUrl);
|
|
35
74
|
const collection = generator.generateCollection(controllers);
|
|
36
|
-
require('fs').writeFileSync(postmanOutputPath, JSON.stringify(collection, null, 2));
|
|
37
|
-
console.log(`[Nest-Scramble] ✓ Postman collection exported to ${postmanOutputPath}`);
|
|
38
|
-
}
|
|
39
|
-
const port = baseUrl.split(':').pop() || '3000';
|
|
40
|
-
console.log(`\n${'='.repeat(60)}`);
|
|
41
|
-
console.log(`✅ [Nest-Scramble] Ready!`);
|
|
42
|
-
console.log(`📚 API Docs available at: http://localhost:${port}/docs`);
|
|
43
|
-
console.log(`📄 OpenAPI JSON at: http://localhost:${port}/docs-json`);
|
|
44
|
-
if (enableMock) {
|
|
45
|
-
console.log(`🎭 Mock endpoints at: http://localhost:${port}/scramble-mock/*`);
|
|
75
|
+
require('fs').writeFileSync(config.postmanOutputPath, JSON.stringify(collection, null, 2));
|
|
76
|
+
console.log(`[Nest-Scramble] ✓ Postman collection exported to ${config.postmanOutputPath}`);
|
|
46
77
|
}
|
|
47
|
-
console.log(`${'='.repeat(60)}\n`);
|
|
48
78
|
return {
|
|
49
79
|
module: NestScrambleModule_1,
|
|
50
80
|
providers: [
|
|
@@ -62,7 +92,7 @@ let NestScrambleModule = NestScrambleModule_1 = class NestScrambleModule {
|
|
|
62
92
|
},
|
|
63
93
|
{
|
|
64
94
|
provide: 'NEST_SCRAMBLE_OPTIONS',
|
|
65
|
-
useValue:
|
|
95
|
+
useValue: config,
|
|
66
96
|
},
|
|
67
97
|
],
|
|
68
98
|
exports: [ScannerService_1.ScannerService, PostmanCollectionGenerator_1.PostmanCollectionGenerator, OpenApiTransformer_1.OpenApiTransformer],
|
|
@@ -82,6 +112,8 @@ let NestScrambleModule = NestScrambleModule_1 = class NestScrambleModule {
|
|
|
82
112
|
}
|
|
83
113
|
};
|
|
84
114
|
exports.NestScrambleModule = NestScrambleModule;
|
|
115
|
+
NestScrambleModule.moduleOptions = {};
|
|
116
|
+
NestScrambleModule.detectedPort = 3000;
|
|
85
117
|
exports.NestScrambleModule = NestScrambleModule = NestScrambleModule_1 = __decorate([
|
|
86
118
|
(0, common_1.Module)({})
|
|
87
119
|
], NestScrambleModule);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NestScrambleModule.js","sourceRoot":"","sources":["../src/NestScrambleModule.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,kEAAkE;AAClE,
|
|
1
|
+
{"version":3,"file":"NestScrambleModule.js","sourceRoot":"","sources":["../src/NestScrambleModule.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -40,36 +40,145 @@ const fs = __importStar(require("fs"));
|
|
|
40
40
|
const path = __importStar(require("path"));
|
|
41
41
|
const PostmanCollectionGenerator_1 = require("./generators/PostmanCollectionGenerator");
|
|
42
42
|
const ScannerService_1 = require("./scanner/ScannerService");
|
|
43
|
+
const OpenApiTransformer_1 = require("./utils/OpenApiTransformer");
|
|
44
|
+
const packageJson = require('../package.json');
|
|
43
45
|
const program = new commander_1.Command();
|
|
44
46
|
program
|
|
45
47
|
.name('nest-scramble')
|
|
46
48
|
.description('Zero-config API Documentation & Postman Generator for NestJS')
|
|
47
|
-
.version(
|
|
49
|
+
.version(packageJson.version);
|
|
48
50
|
program
|
|
49
51
|
.command('generate')
|
|
50
|
-
.description('Generate
|
|
52
|
+
.description('Generate API documentation from NestJS project')
|
|
51
53
|
.argument('<sourcePath>', 'Path to the source directory (e.g., src)')
|
|
52
|
-
.option('-o, --output <file>', 'Output file path', '
|
|
53
|
-
.option('-
|
|
54
|
+
.option('-o, --output <file>', 'Output file path', 'openapi.json')
|
|
55
|
+
.option('-f, --format <type>', 'Output format: openapi or postman', 'openapi')
|
|
56
|
+
.option('-b, --baseUrl <url>', 'Base URL for the API', 'http://localhost:3000')
|
|
57
|
+
.option('-t, --title <title>', 'API title', 'NestJS API')
|
|
58
|
+
.option('-v, --apiVersion <version>', 'API version', '1.0.0')
|
|
54
59
|
.action(async (sourcePath, options) => {
|
|
55
60
|
try {
|
|
56
|
-
console.log('
|
|
61
|
+
console.log('\n' + '='.repeat(60));
|
|
62
|
+
console.log('🚀 Nest-Scramble CLI');
|
|
63
|
+
console.log(' Developed by Mohamed Mustafa | MIT License');
|
|
64
|
+
console.log('='.repeat(60) + '\n');
|
|
65
|
+
console.log(`📂 Scanning controllers in: ${sourcePath}`);
|
|
57
66
|
const scanner = new ScannerService_1.ScannerService();
|
|
58
67
|
const controllers = scanner.scanControllers(sourcePath);
|
|
59
68
|
if (controllers.length === 0) {
|
|
60
|
-
console.log('No controllers found.');
|
|
61
|
-
|
|
69
|
+
console.log('❌ No controllers found.');
|
|
70
|
+
console.log('💡 Make sure your controllers use @Controller() decorator');
|
|
71
|
+
process.exit(1);
|
|
62
72
|
}
|
|
63
|
-
|
|
64
|
-
console.log(
|
|
65
|
-
const generator = new PostmanCollectionGenerator_1.PostmanCollectionGenerator(options.baseUrl);
|
|
66
|
-
const collection = generator.generateCollection(controllers);
|
|
73
|
+
const methodCount = controllers.reduce((sum, c) => sum + c.methods.length, 0);
|
|
74
|
+
console.log(`✅ Found ${controllers.length} controller(s) with ${methodCount} endpoint(s)\n`);
|
|
67
75
|
const outputPath = path.resolve(options.output);
|
|
68
|
-
|
|
69
|
-
|
|
76
|
+
if (options.format === 'postman') {
|
|
77
|
+
console.log('📦 Generating Postman collection...');
|
|
78
|
+
const generator = new PostmanCollectionGenerator_1.PostmanCollectionGenerator(options.baseUrl);
|
|
79
|
+
const collection = generator.generateCollection(controllers);
|
|
80
|
+
fs.writeFileSync(outputPath, JSON.stringify(collection, null, 2));
|
|
81
|
+
console.log(`✅ Postman collection saved to: ${outputPath}`);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
console.log('📄 Generating OpenAPI specification...');
|
|
85
|
+
const transformer = new OpenApiTransformer_1.OpenApiTransformer(options.baseUrl);
|
|
86
|
+
const spec = transformer.transform(controllers, options.title, options.apiVersion, options.baseUrl);
|
|
87
|
+
fs.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
|
|
88
|
+
console.log(`✅ OpenAPI spec saved to: ${outputPath}`);
|
|
89
|
+
}
|
|
90
|
+
console.log('\n' + '='.repeat(60));
|
|
91
|
+
console.log('🎉 Generation complete!');
|
|
92
|
+
console.log('='.repeat(60) + '\n');
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.error('\n❌ Error:', error instanceof Error ? error.message : error);
|
|
96
|
+
console.error('\n💡 Troubleshooting:');
|
|
97
|
+
console.error(' - Ensure the source path is correct');
|
|
98
|
+
console.error(' - Check that tsconfig.json exists in your project root');
|
|
99
|
+
console.error(' - Verify your controllers use @Controller() decorator\n');
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
program
|
|
104
|
+
.command('init')
|
|
105
|
+
.description('Auto-inject Nest-Scramble into your NestJS project')
|
|
106
|
+
.option('-m, --module <path>', 'Path to your app module', 'src/app.module.ts')
|
|
107
|
+
.action(async (options) => {
|
|
108
|
+
try {
|
|
109
|
+
console.log('\n' + '='.repeat(60));
|
|
110
|
+
console.log('🚀 Nest-Scramble Auto-Injector');
|
|
111
|
+
console.log(' Developed by Mohamed Mustafa | MIT License');
|
|
112
|
+
console.log('='.repeat(60) + '\n');
|
|
113
|
+
const { Project } = require('ts-morph');
|
|
114
|
+
const fs = require('fs');
|
|
115
|
+
const path = require('path');
|
|
116
|
+
const modulePath = path.resolve(options.module);
|
|
117
|
+
if (!fs.existsSync(modulePath)) {
|
|
118
|
+
console.error(`❌ Module file not found: ${modulePath}`);
|
|
119
|
+
console.error('💡 Try: nest-scramble init --module src/app.module.ts');
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
console.log(`📂 Found module: ${modulePath}`);
|
|
123
|
+
const project = new Project();
|
|
124
|
+
const sourceFile = project.addSourceFileAtPath(modulePath);
|
|
125
|
+
// Check if already imported
|
|
126
|
+
const existingImport = sourceFile.getImportDeclaration((imp) => imp.getModuleSpecifierValue() === 'nest-scramble');
|
|
127
|
+
if (existingImport) {
|
|
128
|
+
console.log('⚠️ Nest-Scramble is already imported in this module');
|
|
129
|
+
console.log('✅ No changes needed!');
|
|
130
|
+
process.exit(0);
|
|
131
|
+
}
|
|
132
|
+
// Add import statement
|
|
133
|
+
console.log('📝 Adding import statement...');
|
|
134
|
+
sourceFile.addImportDeclaration({
|
|
135
|
+
moduleSpecifier: 'nest-scramble',
|
|
136
|
+
namedImports: ['NestScrambleModule'],
|
|
137
|
+
});
|
|
138
|
+
// Find the @Module decorator
|
|
139
|
+
const classes = sourceFile.getClasses();
|
|
140
|
+
const moduleClass = classes.find((cls) => cls.getDecorator('Module') !== undefined);
|
|
141
|
+
if (!moduleClass) {
|
|
142
|
+
console.error('❌ Could not find @Module decorator');
|
|
143
|
+
console.error('💡 Please add NestScrambleModule.forRoot() manually');
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
const moduleDecorator = moduleClass.getDecorator('Module');
|
|
147
|
+
const decoratorArgs = moduleDecorator?.getArguments();
|
|
148
|
+
if (!decoratorArgs || decoratorArgs.length === 0) {
|
|
149
|
+
console.error('❌ Module decorator has no arguments');
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
const configObject = decoratorArgs[0];
|
|
153
|
+
const configText = configObject.getText();
|
|
154
|
+
// Add NestScrambleModule to imports array
|
|
155
|
+
let newConfigText = configText;
|
|
156
|
+
if (configText.includes('imports:')) {
|
|
157
|
+
// Add to existing imports array
|
|
158
|
+
newConfigText = configText.replace(/imports:\s*\[/, 'imports: [\n NestScrambleModule.forRoot(),');
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
// Create imports array
|
|
162
|
+
newConfigText = configText.replace(/\{/, '{\n imports: [NestScrambleModule.forRoot()],');
|
|
163
|
+
}
|
|
164
|
+
configObject.replaceWithText(newConfigText);
|
|
165
|
+
// Save the file
|
|
166
|
+
console.log('💾 Saving changes...');
|
|
167
|
+
await sourceFile.save();
|
|
168
|
+
console.log('\n' + '='.repeat(60));
|
|
169
|
+
console.log('✅ Nest-Scramble successfully injected!');
|
|
170
|
+
console.log('='.repeat(60));
|
|
171
|
+
console.log('\n📋 Next steps:');
|
|
172
|
+
console.log(' 1. Run: npm run start:dev');
|
|
173
|
+
console.log(' 2. Visit: http://localhost:3000/docs');
|
|
174
|
+
console.log(' 3. Enjoy zero-config API documentation! 🎉\n');
|
|
70
175
|
}
|
|
71
176
|
catch (error) {
|
|
72
|
-
console.error('Error:', error);
|
|
177
|
+
console.error('\n❌ Error:', error instanceof Error ? error.message : error);
|
|
178
|
+
console.error('\n💡 Manual installation:');
|
|
179
|
+
console.error(' 1. Import: import { NestScrambleModule } from "nest-scramble";');
|
|
180
|
+
console.error(' 2. Add to imports: NestScrambleModule.forRoot()');
|
|
181
|
+
console.error(' 3. Done! 🚀\n');
|
|
73
182
|
process.exit(1);
|
|
74
183
|
}
|
|
75
184
|
});
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AACA,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAElE,yCAAoC;AACpC,uCAAyB;AACzB,2CAA6B;AAC7B,wFAAqF;AACrF,6DAA0D;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AACA,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAElE,yCAAoC;AACpC,uCAAyB;AACzB,2CAA6B;AAC7B,wFAAqF;AACrF,6DAA0D;AAC1D,mEAAgE;AAEhE,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE/C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,eAAe,CAAC;KACrB,WAAW,CAAC,8DAA8D,CAAC;KAC3E,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAEhC,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,gDAAgD,CAAC;KAC7D,QAAQ,CAAC,cAAc,EAAE,0CAA0C,CAAC;KACpE,MAAM,CAAC,qBAAqB,EAAE,kBAAkB,EAAE,cAAc,CAAC;KACjE,MAAM,CAAC,qBAAqB,EAAE,mCAAmC,EAAE,SAAS,CAAC;KAC7E,MAAM,CAAC,qBAAqB,EAAE,sBAAsB,EAAE,uBAAuB,CAAC;KAC9E,MAAM,CAAC,qBAAqB,EAAE,WAAW,EAAE,YAAY,CAAC;KACxD,MAAM,CAAC,4BAA4B,EAAE,aAAa,EAAE,OAAO,CAAC;KAC5D,MAAM,CAAC,KAAK,EAAE,UAAkB,EAAE,OAMlC,EAAE,EAAE;IACH,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QAEnC,OAAO,CAAC,GAAG,CAAC,+BAA+B,UAAU,EAAE,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,IAAI,+BAAc,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QAExD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;YACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,WAAW,WAAW,CAAC,MAAM,uBAAuB,WAAW,gBAAgB,CAAC,CAAC;QAE7F,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEhD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;YACnD,MAAM,SAAS,GAAG,IAAI,uDAA0B,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAClE,MAAM,UAAU,GAAG,SAAS,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;YAC7D,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,kCAAkC,UAAU,EAAE,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;YACtD,MAAM,WAAW,GAAG,IAAI,uCAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC5D,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YACpG,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC5D,OAAO,CAAC,GAAG,CAAC,4BAA4B,UAAU,EAAE,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC5E,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACvC,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;QACxD,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC3E,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,oDAAoD,CAAC;KACjE,MAAM,CAAC,qBAAqB,EAAE,yBAAyB,EAAE,mBAAmB,CAAC;KAC7E,MAAM,CAAC,KAAK,EAAE,OAA2B,EAAE,EAAE;IAC5C,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QAEnC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAE7B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEhD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,4BAA4B,UAAU,EAAE,CAAC,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;YACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,oBAAoB,UAAU,EAAE,CAAC,CAAC;QAE9C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAE3D,4BAA4B;QAC5B,MAAM,cAAc,GAAG,UAAU,CAAC,oBAAoB,CACpD,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,uBAAuB,EAAE,KAAK,eAAe,CAChE,CAAC;QAEF,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;YACpE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,uBAAuB;QACvB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,UAAU,CAAC,oBAAoB,CAAC;YAC9B,eAAe,EAAE,eAAe;YAChC,YAAY,EAAE,CAAC,oBAAoB,CAAC;SACrC,CAAC,CAAC;QAEH,6BAA6B;QAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,UAAU,EAAE,CAAC;QACxC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAQ,EAAE,EAAE,CAC5C,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,SAAS,CACzC,CAAC;QAEF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACpD,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,eAAe,GAAG,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC3D,MAAM,aAAa,GAAG,eAAe,EAAE,YAAY,EAAE,CAAC;QAEtD,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjD,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC;QAE1C,0CAA0C;QAC1C,IAAI,aAAa,GAAG,UAAU,CAAC;QAE/B,IAAI,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACpC,gCAAgC;YAChC,aAAa,GAAG,UAAU,CAAC,OAAO,CAChC,eAAe,EACf,+CAA+C,CAChD,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,uBAAuB;YACvB,aAAa,GAAG,UAAU,CAAC,OAAO,CAChC,IAAI,EACJ,+CAA+C,CAChD,CAAC;QACJ,CAAC;QAED,YAAY,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;QAE5C,gBAAgB;QAChB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACpC,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;QAExB,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IAEjE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC5E,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC3C,OAAO,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACnF,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACpE,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocsController.d.ts","sourceRoot":"","sources":["../../src/controllers/DocsController.ts"],"names":[],"mappings":"AAGA,
|
|
1
|
+
{"version":3,"file":"DocsController.d.ts","sourceRoot":"","sources":["../../src/controllers/DocsController.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,aAAa,aAAa,CAAC;AACxC,eAAO,MAAM,MAAM,wDAAyC,CAAC;AAE7D,qBAEa,cAAc;IAEU,OAAO,CAAC,WAAW;gBAAX,WAAW,EAAE,GAAG;IAI3D,OAAO,CAAQ,GAAG,EAAE,GAAG;IA0BvB,cAAc,CAAQ,GAAG,EAAE,GAAG;IAa9B,oBAAoB,CAAQ,GAAG,EAAE,GAAG;IAKpC,cAAc;CAGf"}
|
|
@@ -12,9 +12,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
12
12
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.DocsController = void 0;
|
|
15
|
+
exports.DocsController = exports.Public = exports.IS_PUBLIC_KEY = void 0;
|
|
16
16
|
/** Nest-Scramble | Developed by Mohamed Mustafa | MIT License **/
|
|
17
17
|
const common_1 = require("@nestjs/common");
|
|
18
|
+
exports.IS_PUBLIC_KEY = 'isPublic';
|
|
19
|
+
const Public = () => (0, common_1.SetMetadata)(exports.IS_PUBLIC_KEY, true);
|
|
20
|
+
exports.Public = Public;
|
|
18
21
|
let DocsController = class DocsController {
|
|
19
22
|
constructor(openApiSpec) {
|
|
20
23
|
this.openApiSpec = openApiSpec;
|
|
@@ -91,6 +94,7 @@ __decorate([
|
|
|
91
94
|
], DocsController.prototype, "getOpenApiSpec", null);
|
|
92
95
|
exports.DocsController = DocsController = __decorate([
|
|
93
96
|
(0, common_1.Controller)(),
|
|
97
|
+
(0, exports.Public)(),
|
|
94
98
|
__param(0, (0, common_1.Inject)('NEST_SCRAMBLE_OPENAPI')),
|
|
95
99
|
__metadata("design:paramtypes", [Object])
|
|
96
100
|
], DocsController);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocsController.js","sourceRoot":"","sources":["../../src/controllers/DocsController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,kEAAkE;AAClE,
|
|
1
|
+
{"version":3,"file":"DocsController.js","sourceRoot":"","sources":["../../src/controllers/DocsController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,kEAAkE;AAClE,2CAA2E;AAE9D,QAAA,aAAa,GAAG,UAAU,CAAC;AACjC,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,IAAA,oBAAW,EAAC,qBAAa,EAAE,IAAI,CAAC,CAAC;AAAhD,QAAA,MAAM,UAA0C;AAItD,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAC2C,WAAgB;QAAhB,gBAAW,GAAX,WAAW,CAAK;IACxD,CAAC;IAGJ,OAAO,CAAQ,GAAQ;QACrB,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;QAkBT,CAAC;QAEL,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;QAC1D,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IAGD,cAAc,CAAQ,GAAQ;QAC5B,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC7D,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;YACjE,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;YAClD,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,iDAAiD,EAAE,KAAK,CAAC,CAAC;YACxE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,0CAA0C,EAAE,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAGD,oBAAoB,CAAQ,GAAQ;QAClC,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAGD,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF,CAAA;AArDY,wCAAc;AAMzB;IADC,IAAA,YAAG,EAAC,MAAM,CAAC;IACH,WAAA,IAAA,YAAG,GAAE,CAAA;;;;6CAuBb;AAGD;IADC,IAAA,YAAG,EAAC,WAAW,CAAC;IACD,WAAA,IAAA,YAAG,GAAE,CAAA;;;;oDAUpB;AAGD;IADC,IAAA,YAAG,EAAC,WAAW,CAAC;IACK,WAAA,IAAA,YAAG,GAAE,CAAA;;;;0DAE1B;AAGD;IADC,IAAA,YAAG,EAAC,WAAW,CAAC;;;;oDAGhB;yBApDU,cAAc;IAF1B,IAAA,mBAAU,GAAE;IACZ,IAAA,cAAM,GAAE;IAGJ,WAAA,IAAA,eAAM,EAAC,uBAAuB,CAAC,CAAA;;GAFvB,cAAc,CAqD1B"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from './scanner/ScannerService';
|
|
|
5
5
|
export * from './utils/DtoAnalyzer';
|
|
6
6
|
export * from './utils/MockGenerator';
|
|
7
7
|
export * from './utils/OpenApiTransformer';
|
|
8
|
+
export * from './utils/AutoDetector';
|
|
8
9
|
export * from './middleware/MockMiddleware';
|
|
9
10
|
export * from './controllers/DocsController';
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,cAAc,yCAAyC,CAAC;AACxD,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,cAAc,yCAAyC,CAAC;AACxD,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ __exportStar(require("./scanner/ScannerService"), exports);
|
|
|
21
21
|
__exportStar(require("./utils/DtoAnalyzer"), exports);
|
|
22
22
|
__exportStar(require("./utils/MockGenerator"), exports);
|
|
23
23
|
__exportStar(require("./utils/OpenApiTransformer"), exports);
|
|
24
|
+
__exportStar(require("./utils/AutoDetector"), exports);
|
|
24
25
|
__exportStar(require("./middleware/MockMiddleware"), exports);
|
|
25
26
|
__exportStar(require("./controllers/DocsController"), exports);
|
|
26
27
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kEAAkE;AAClE,0EAAwD;AACxD,uDAAqC;AACrC,2DAAyC;AACzC,sDAAoC;AACpC,wDAAsC;AACtC,6DAA2C;AAC3C,8DAA4C;AAC5C,+DAA6C"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kEAAkE;AAClE,0EAAwD;AACxD,uDAAqC;AACrC,2DAAyC;AACzC,sDAAoC;AACpC,wDAAsC;AACtC,6DAA2C;AAC3C,uDAAqC;AACrC,8DAA4C;AAC5C,+DAA6C"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export interface ProjectStructure {
|
|
2
|
+
rootPath: string;
|
|
3
|
+
sourcePath: string;
|
|
4
|
+
packageJson: any;
|
|
5
|
+
tsConfigPath: string;
|
|
6
|
+
hasControllers: boolean;
|
|
7
|
+
controllerPaths: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare class AutoDetector {
|
|
10
|
+
/**
|
|
11
|
+
* Auto-detect the project structure and configuration
|
|
12
|
+
*/
|
|
13
|
+
static detectProjectStructure(): ProjectStructure;
|
|
14
|
+
/**
|
|
15
|
+
* Auto-detect the source directory
|
|
16
|
+
*/
|
|
17
|
+
private static detectSourcePath;
|
|
18
|
+
/**
|
|
19
|
+
* Detect tsconfig.json location
|
|
20
|
+
*/
|
|
21
|
+
private static detectTsConfig;
|
|
22
|
+
/**
|
|
23
|
+
* Check if directory has TypeScript files
|
|
24
|
+
*/
|
|
25
|
+
private static hasTypeScriptFiles;
|
|
26
|
+
/**
|
|
27
|
+
* Find all controller files recursively
|
|
28
|
+
*/
|
|
29
|
+
private static findControllers;
|
|
30
|
+
/**
|
|
31
|
+
* Detect the port from environment or default
|
|
32
|
+
*/
|
|
33
|
+
static detectPort(): number;
|
|
34
|
+
/**
|
|
35
|
+
* Detect base URL
|
|
36
|
+
*/
|
|
37
|
+
static detectBaseUrl(): string;
|
|
38
|
+
/**
|
|
39
|
+
* Get app name from package.json or default
|
|
40
|
+
*/
|
|
41
|
+
static getAppName(): string;
|
|
42
|
+
/**
|
|
43
|
+
* Get app version from package.json or default
|
|
44
|
+
*/
|
|
45
|
+
static getAppVersion(): string;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=AutoDetector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AutoDetector.d.ts","sourceRoot":"","sources":["../../src/utils/AutoDetector.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,GAAG,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,qBAAa,YAAY;IACvB;;OAEG;IACH,MAAM,CAAC,sBAAsB,IAAI,gBAAgB;IAkCjD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAkB/B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAiB7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IASjC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IA2B9B;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM;IAI3B;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,MAAM;IAM9B;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM;IAa3B;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,MAAM;CAY/B"}
|
|
@@ -0,0 +1,194 @@
|
|
|
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.AutoDetector = void 0;
|
|
37
|
+
/** Nest-Scramble | Developed by Mohamed Mustafa | MIT License **/
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
class AutoDetector {
|
|
41
|
+
/**
|
|
42
|
+
* Auto-detect the project structure and configuration
|
|
43
|
+
*/
|
|
44
|
+
static detectProjectStructure() {
|
|
45
|
+
const rootPath = process.cwd();
|
|
46
|
+
// Try to find package.json
|
|
47
|
+
const packageJsonPath = path.join(rootPath, 'package.json');
|
|
48
|
+
let packageJson = {};
|
|
49
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
50
|
+
try {
|
|
51
|
+
packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.warn('[Nest-Scramble] Could not parse package.json');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Auto-detect source path
|
|
58
|
+
const sourcePath = this.detectSourcePath(rootPath);
|
|
59
|
+
// Find tsconfig.json
|
|
60
|
+
const tsConfigPath = this.detectTsConfig(rootPath);
|
|
61
|
+
// Find controllers
|
|
62
|
+
const controllerPaths = this.findControllers(path.join(rootPath, sourcePath));
|
|
63
|
+
return {
|
|
64
|
+
rootPath,
|
|
65
|
+
sourcePath,
|
|
66
|
+
packageJson,
|
|
67
|
+
tsConfigPath,
|
|
68
|
+
hasControllers: controllerPaths.length > 0,
|
|
69
|
+
controllerPaths,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Auto-detect the source directory
|
|
74
|
+
*/
|
|
75
|
+
static detectSourcePath(rootPath) {
|
|
76
|
+
const possiblePaths = ['src', 'lib', 'app', 'source'];
|
|
77
|
+
for (const possiblePath of possiblePaths) {
|
|
78
|
+
const fullPath = path.join(rootPath, possiblePath);
|
|
79
|
+
if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {
|
|
80
|
+
// Check if it contains TypeScript files
|
|
81
|
+
const hasTs = this.hasTypeScriptFiles(fullPath);
|
|
82
|
+
if (hasTs) {
|
|
83
|
+
return possiblePath;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Default to 'src'
|
|
88
|
+
return 'src';
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Detect tsconfig.json location
|
|
92
|
+
*/
|
|
93
|
+
static detectTsConfig(rootPath) {
|
|
94
|
+
const possiblePaths = [
|
|
95
|
+
'tsconfig.json',
|
|
96
|
+
'tsconfig.app.json',
|
|
97
|
+
'tsconfig.build.json',
|
|
98
|
+
];
|
|
99
|
+
for (const possiblePath of possiblePaths) {
|
|
100
|
+
const fullPath = path.join(rootPath, possiblePath);
|
|
101
|
+
if (fs.existsSync(fullPath)) {
|
|
102
|
+
return fullPath;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return path.join(rootPath, 'tsconfig.json');
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Check if directory has TypeScript files
|
|
109
|
+
*/
|
|
110
|
+
static hasTypeScriptFiles(dirPath) {
|
|
111
|
+
try {
|
|
112
|
+
const files = fs.readdirSync(dirPath);
|
|
113
|
+
return files.some(file => file.endsWith('.ts'));
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Find all controller files recursively
|
|
121
|
+
*/
|
|
122
|
+
static findControllers(dirPath, controllers = []) {
|
|
123
|
+
if (!fs.existsSync(dirPath)) {
|
|
124
|
+
return controllers;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
128
|
+
for (const entry of entries) {
|
|
129
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
130
|
+
if (entry.isDirectory()) {
|
|
131
|
+
// Skip node_modules and dist
|
|
132
|
+
if (entry.name !== 'node_modules' && entry.name !== 'dist' && entry.name !== '.git') {
|
|
133
|
+
this.findControllers(fullPath, controllers);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else if (entry.isFile() && entry.name.endsWith('.controller.ts')) {
|
|
137
|
+
controllers.push(fullPath);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
// Silently skip directories we can't read
|
|
143
|
+
}
|
|
144
|
+
return controllers;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Detect the port from environment or default
|
|
148
|
+
*/
|
|
149
|
+
static detectPort() {
|
|
150
|
+
return parseInt(process.env.PORT || '3000', 10);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Detect base URL
|
|
154
|
+
*/
|
|
155
|
+
static detectBaseUrl() {
|
|
156
|
+
const port = this.detectPort();
|
|
157
|
+
const host = process.env.HOST || 'localhost';
|
|
158
|
+
return `http://${host}:${port}`;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get app name from package.json or default
|
|
162
|
+
*/
|
|
163
|
+
static getAppName() {
|
|
164
|
+
try {
|
|
165
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
166
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
167
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
168
|
+
return packageJson.name || 'NestJS API';
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// Ignore
|
|
173
|
+
}
|
|
174
|
+
return 'NestJS API';
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Get app version from package.json or default
|
|
178
|
+
*/
|
|
179
|
+
static getAppVersion() {
|
|
180
|
+
try {
|
|
181
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
182
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
183
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
184
|
+
return packageJson.version || '1.0.0';
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// Ignore
|
|
189
|
+
}
|
|
190
|
+
return '1.0.0';
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
exports.AutoDetector = AutoDetector;
|
|
194
|
+
//# sourceMappingURL=AutoDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AutoDetector.js","sourceRoot":"","sources":["../../src/utils/AutoDetector.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nest-scramble",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "A next-generation, decorator-free API documentation engine and intelligent mock server for NestJS, engineered by Mohamed Mustafa",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|