nest-scramble 3.0.3 β 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +482 -1103
- package/UI_FEATURES.md +21 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +236 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov.info +2930 -0
- package/dist/cli.js +10 -1
- package/dist/cli.js.map +1 -1
- package/dist/generators/TypedClientGenerator.d.ts +23 -0
- package/dist/generators/TypedClientGenerator.d.ts.map +1 -0
- package/dist/generators/TypedClientGenerator.js +215 -0
- package/dist/generators/TypedClientGenerator.js.map +1 -0
- package/dist/index.d.ts +9 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -8
- package/dist/index.js.map +1 -1
- package/package.json +13 -12
package/README.md
CHANGED
|
@@ -1,1103 +1,482 @@
|
|
|
1
|
-
# Nest-Scramble
|
|
2
|
-
|
|
3
|
-
> Zero-config API Documentation
|
|
4
|
-
|
|
5
|
-
[](https://badge.fury.io/js/nest-scramble)
|
|
6
|
-
[](https://opensource.org/licenses/MIT)
|
|
7
|
-
[](https://github.com/Eng-MMustafa/nest-scramble)
|
|
8
|
-
[](https://github.com/Eng-MMustafa)
|
|
9
|
-
[](https://docs.nestjs.com)
|
|
10
|
-
[](https://nodejs.org)
|
|
11
|
-
[](https://www.typescriptlang.org)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
### Option B
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
//
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
|
266
|
-
|
|
267
|
-
|
|
|
268
|
-
|
|
|
269
|
-
|
|
|
270
|
-
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
GET /
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
//
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
**Development Mode:**
|
|
485
|
-
```typescript
|
|
486
|
-
import { WatchModeService } from 'nest-scramble';
|
|
487
|
-
|
|
488
|
-
const watchMode = new WatchModeService({
|
|
489
|
-
sourcePath: 'src',
|
|
490
|
-
outputPath: 'openapi.json',
|
|
491
|
-
baseUrl: 'http://localhost:3000',
|
|
492
|
-
useCache: true, // Enable smart caching
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
await watchMode.start();
|
|
496
|
-
// β
Auto-regenerates docs on file changes
|
|
497
|
-
// β
Only re-scans affected files
|
|
498
|
-
// β
Tracks DTO inheritance chains
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
**Programmatic API with Caching:**
|
|
502
|
-
```typescript
|
|
503
|
-
import { IncrementalScannerService } from 'nest-scramble';
|
|
504
|
-
|
|
505
|
-
const scanner = new IncrementalScannerService({
|
|
506
|
-
useCache: true,
|
|
507
|
-
cacheFilePath: '.scramble-cache.json',
|
|
508
|
-
// Optional: Use SHA-256 for large projects (>1000 files)
|
|
509
|
-
// hashAlgorithm: 'sha256',
|
|
510
|
-
});
|
|
511
|
-
|
|
512
|
-
// Initialize and perform full scan
|
|
513
|
-
scanner.initialize('src');
|
|
514
|
-
const controllers = scanner.scanControllers('src');
|
|
515
|
-
|
|
516
|
-
// Process file changes incrementally
|
|
517
|
-
const changes = [
|
|
518
|
-
{ type: 'change', filePath: 'src/users.controller.ts', hash: '...' }
|
|
519
|
-
];
|
|
520
|
-
const results = scanner.processFileChanges(changes);
|
|
521
|
-
|
|
522
|
-
// Cleanup when done
|
|
523
|
-
scanner.cleanup();
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
### π Transitive Dependency Tracking
|
|
527
|
-
|
|
528
|
-
The system automatically tracks **inheritance chains** and **indirect dependencies**:
|
|
529
|
-
|
|
530
|
-
**Example Scenario:**
|
|
531
|
-
```typescript
|
|
532
|
-
// base.dto.ts
|
|
533
|
-
export class BaseDto {
|
|
534
|
-
id: number;
|
|
535
|
-
createdAt: Date;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
// update-user.dto.ts
|
|
539
|
-
export class UpdateUserDto extends BaseDto {
|
|
540
|
-
name: string;
|
|
541
|
-
email: string;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
// users.controller.ts
|
|
545
|
-
@Controller('users')
|
|
546
|
-
export class UsersController {
|
|
547
|
-
@Put(':id')
|
|
548
|
-
update(@Body() dto: UpdateUserDto) { }
|
|
549
|
-
}
|
|
550
|
-
```
|
|
551
|
-
|
|
552
|
-
**What happens when `BaseDto` changes:**
|
|
553
|
-
1. β
System detects `UpdateUserDto` inherits from `BaseDto`
|
|
554
|
-
2. β
System finds `UsersController` depends on `UpdateUserDto`
|
|
555
|
-
3. β
All three files are marked for re-scanning
|
|
556
|
-
4. β
**No stale data** - even with deep inheritance chains!
|
|
557
|
-
|
|
558
|
-
### π Hash Collision Prevention
|
|
559
|
-
|
|
560
|
-
Multi-layer verification system ensures **zero stale data**:
|
|
561
|
-
|
|
562
|
-
**Layer 1: Hash Comparison**
|
|
563
|
-
- MD5 (default) - Fast, suitable for most projects
|
|
564
|
-
- SHA-256 (optional) - More secure for large monorepos
|
|
565
|
-
|
|
566
|
-
**Layer 2: File Size Verification**
|
|
567
|
-
- Catches hash collisions automatically
|
|
568
|
-
- Triggers re-scan if size differs
|
|
569
|
-
|
|
570
|
-
**Layer 3: Collision Tracking**
|
|
571
|
-
- Monitors and logs collision events
|
|
572
|
-
- Auto-alerts after 3+ collisions
|
|
573
|
-
- Recommends switching to SHA-256
|
|
574
|
-
|
|
575
|
-
**Configuration:**
|
|
576
|
-
```typescript
|
|
577
|
-
const scanner = new IncrementalScannerService({
|
|
578
|
-
useCache: true,
|
|
579
|
-
hashAlgorithm: 'sha256', // Use SHA-256 for large projects
|
|
580
|
-
});
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
### π¦ Cache Invalidation Strategy
|
|
584
|
-
|
|
585
|
-
The cache automatically invalidates when:
|
|
586
|
-
- β
Cache version mismatch (after library upgrade)
|
|
587
|
-
- β
TTL expiration (default: 24 hours, configurable)
|
|
588
|
-
- β
`tsconfig.json` changes
|
|
589
|
-
- β
File content hash changes
|
|
590
|
-
- β
File size differs (collision detection)
|
|
591
|
-
- β
File deletion
|
|
592
|
-
- β
DTO dependency changes
|
|
593
|
-
- β
Manual invalidation
|
|
594
|
-
|
|
595
|
-
**Custom TTL:**
|
|
596
|
-
```typescript
|
|
597
|
-
const cacheManager = new CacheManager({
|
|
598
|
-
ttl: 12 * 60 * 60 * 1000, // 12 hours
|
|
599
|
-
});
|
|
600
|
-
```
|
|
601
|
-
|
|
602
|
-
### π― Best Practices
|
|
603
|
-
|
|
604
|
-
**1. Add Cache to .gitignore:**
|
|
605
|
-
```gitignore
|
|
606
|
-
# Nest-Scramble cache
|
|
607
|
-
scramble-cache.json
|
|
608
|
-
.scramble-cache.json
|
|
609
|
-
```
|
|
610
|
-
|
|
611
|
-
**2. Use Watch Mode in Development:**
|
|
612
|
-
```bash
|
|
613
|
-
# Terminal 1: Run your NestJS app
|
|
614
|
-
npm run start:dev
|
|
615
|
-
|
|
616
|
-
# Terminal 2: Run Nest-Scramble watch mode
|
|
617
|
-
npx nest-scramble watch src -o openapi.json
|
|
618
|
-
```
|
|
619
|
-
|
|
620
|
-
**3. Choose Hash Algorithm Based on Project Size:**
|
|
621
|
-
- **Small/Medium (<1000 files):** Use MD5 (default, fastest)
|
|
622
|
-
- **Large (>1000 files):** Use SHA-256 (more secure)
|
|
623
|
-
- **Monorepos (10k+ files):** Use SHA-256 + monitor collisions
|
|
624
|
-
|
|
625
|
-
**4. Monitor Cache Performance:**
|
|
626
|
-
```typescript
|
|
627
|
-
const stats = scanner.getCacheManager().getStats();
|
|
628
|
-
console.log(`Cache: ${stats.controllerCount} controllers`);
|
|
629
|
-
console.log(`Hash algorithm: ${stats.hashAlgorithm}`);
|
|
630
|
-
console.log(`Collisions: ${stats.hashCollisions}`);
|
|
631
|
-
console.log(`Size: ${(stats.cacheSize / 1024).toFixed(2)} KB`);
|
|
632
|
-
```
|
|
633
|
-
|
|
634
|
-
### π§ͺ Advanced Examples
|
|
635
|
-
|
|
636
|
-
**Example 1: Dependency Analysis**
|
|
637
|
-
```typescript
|
|
638
|
-
import { DependencyTracker } from 'nest-scramble';
|
|
639
|
-
|
|
640
|
-
const tracker = scanner.getDependencyTracker();
|
|
641
|
-
const info = tracker.getDependencyInfo('src/users.controller.ts');
|
|
642
|
-
|
|
643
|
-
console.log('Dependencies:', info.dependencies);
|
|
644
|
-
console.log('Dependents:', info.dependents);
|
|
645
|
-
console.log('Inheritance chain:', info.inheritanceChain);
|
|
646
|
-
console.log('Transitive affected:', info.transitiveAffected);
|
|
647
|
-
```
|
|
648
|
-
|
|
649
|
-
**Example 2: Cache Performance Test**
|
|
650
|
-
```typescript
|
|
651
|
-
// See: src/examples/cache-performance-test.ts
|
|
652
|
-
import { runPerformanceTest } from 'nest-scramble/examples';
|
|
653
|
-
|
|
654
|
-
await runPerformanceTest();
|
|
655
|
-
// Compares traditional vs incremental scanning
|
|
656
|
-
// Shows real performance metrics
|
|
657
|
-
```
|
|
658
|
-
|
|
659
|
-
**Example 3: Hash Collision Detection**
|
|
660
|
-
```typescript
|
|
661
|
-
// See: src/examples/hash-collision-demo.ts
|
|
662
|
-
import { demonstrateHashCollisionDetection } from 'nest-scramble/examples';
|
|
663
|
-
|
|
664
|
-
await demonstrateHashCollisionDetection();
|
|
665
|
-
// Shows multi-layer verification in action
|
|
666
|
-
// Compares MD5 vs SHA-256 performance
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
### π Additional Resources
|
|
670
|
-
|
|
671
|
-
- **[Advanced Dependency Tracking Example](./src/examples/advanced-dependency-tracking.ts)** - Transitive dependencies demo
|
|
672
|
-
- **[Hash Collision Demo](./src/examples/hash-collision-demo.ts)** - Multi-layer verification
|
|
673
|
-
- **[Cache Performance Test](./src/examples/cache-performance-test.ts)** - Benchmark comparisons
|
|
674
|
-
- **[Complete Integration Example](./src/examples/complete-integration-example.ts)** - Production-ready setup
|
|
675
|
-
|
|
676
|
-
## π¨ Documentation UI - Professional API Dashboard
|
|
677
|
-
|
|
678
|
-
### β¨ Elite Dashboard Design (NEW!)
|
|
679
|
-
|
|
680
|
-
Nest-Scramble features a **professional, high-end API dashboard** inspired by Stripe and Postman, with refined typography and a polished dark palette for long reading sessions.
|
|
681
|
-
|
|
682
|
-
**π Key Features:**
|
|
683
|
-
- **Sidebar-Only Navigation** - Fixed 320px sidebar with controller grouping
|
|
684
|
-
- **Single-Request Per Page** - Each endpoint gets its own dedicated view
|
|
685
|
-
- **Three-Column Elite Layout** - Information | Request Editor | Test Panel
|
|
686
|
-
- **Soft Dark Background** - Refined deep blues for a premium, eye-friendly dark mode
|
|
687
|
-
- **Cyber-Cyan Accents** - `#00f2ff` for active states and primary actions
|
|
688
|
-
- **Vibrant HTTP Method Badges** - Color-coded with glow effects:
|
|
689
|
-
- GET = Royal Blue (`#3B82F6`)
|
|
690
|
-
- POST = Emerald Green (`#10B981`)
|
|
691
|
-
- PUT = Amber Orange (`#F59E0B`)
|
|
692
|
-
- PATCH = Violet Purple (`#8B5CF6`)
|
|
693
|
-
- DELETE = Vibrant Red (`#EF4444`)
|
|
694
|
-
- **Glassmorphism Effects** - Backdrop blur on request/response panels
|
|
695
|
-
- **40px Spacious Padding** - Premium whitespace throughout
|
|
696
|
-
- **Terminal-Style Response** - Black box with green text for API responses
|
|
697
|
-
- **High-Contrast Labels** - Required, Type, and Default badges
|
|
698
|
-
- **Custom Scrollbars** - Gradient cyan-to-purple styling
|
|
699
|
-
- **Plus Jakarta Sans Typography** - Modern, professional font family with optimized sizing
|
|
700
|
-
- **Clear Sidebar Text** - Slightly larger nav fonts for effortless scanning
|
|
701
|
-
- **Powered by Badge** - Animated branding with pulse effect
|
|
702
|
-
|
|
703
|
-
### π Three-Column Elite Interface
|
|
704
|
-
|
|
705
|
-
The dashboard uses a professional three-column layout for each endpoint:
|
|
706
|
-
|
|
707
|
-
**Column 1 (Left) - Information Panel:**
|
|
708
|
-
- Endpoint title with large, bold typography
|
|
709
|
-
- HTTP method badge with vibrant colors and glow
|
|
710
|
-
- Endpoint description and documentation
|
|
711
|
-
- Clean parameters table with high-contrast labels
|
|
712
|
-
- Type information and required field indicators
|
|
713
|
-
|
|
714
|
-
**Column 2 (Middle) - Request Body Editor:**
|
|
715
|
-
- Glassmorphism design with backdrop blur
|
|
716
|
-
- Auto-filled mock data examples
|
|
717
|
-
- JSON editor with syntax highlighting
|
|
718
|
-
- Copy-to-clipboard functionality
|
|
719
|
-
- Real-time validation
|
|
720
|
-
|
|
721
|
-
**Column 3 (Right) - Test Request Panel:**
|
|
722
|
-
- Enhanced glassmorphism with cyan border glow
|
|
723
|
-
- Large "Send Request" button with gradient animation
|
|
724
|
-
- Terminal-style response viewer (black background, green text)
|
|
725
|
-
- Status code indicators
|
|
726
|
-
- Response headers display
|
|
727
|
-
|
|
728
|
-
### π¨ Theme Customization
|
|
729
|
-
|
|
730
|
-
**Futuristic Theme (Default):**
|
|
731
|
-
```typescript
|
|
732
|
-
NestScrambleModule.forRoot({
|
|
733
|
-
theme: 'futuristic', // Professional dark dashboard
|
|
734
|
-
primaryColor: '#00f2ff', // Cyber-Cyan (default)
|
|
735
|
-
customDomainIcon: '/logo.png', // Your brand favicon
|
|
736
|
-
apiTitle: 'My Awesome API',
|
|
737
|
-
})
|
|
738
|
-
```
|
|
739
|
-
|
|
740
|
-
**Classic Theme:**
|
|
741
|
-
```typescript
|
|
742
|
-
NestScrambleModule.forRoot({
|
|
743
|
-
theme: 'classic', // Clean, light, professional
|
|
744
|
-
primaryColor: '#0066cc', // Corporate blue
|
|
745
|
-
apiTitle: 'Enterprise API',
|
|
746
|
-
})
|
|
747
|
-
```
|
|
748
|
-
|
|
749
|
-
**Custom Color Branding:**
|
|
750
|
-
```typescript
|
|
751
|
-
// One line changes the entire UI color scheme!
|
|
752
|
-
NestScrambleModule.forRoot({
|
|
753
|
-
primaryColor: '#a855f7', // Electric Purple
|
|
754
|
-
// or '#10b981' for Emerald Green
|
|
755
|
-
// or '#f59e0b' for Amber Orange
|
|
756
|
-
// or any hex color you want!
|
|
757
|
-
})
|
|
758
|
-
```
|
|
759
|
-
|
|
760
|
-
### π UI Configuration Options
|
|
761
|
-
|
|
762
|
-
| Option | Type | Default | Description |
|
|
763
|
-
|--------|------|---------|-------------|
|
|
764
|
-
| `theme` | `'classic' \| 'futuristic'` | `'futuristic'` | UI theme selection |
|
|
765
|
-
| `primaryColor` | `string` | `'#00f2ff'` | Primary accent color (hex) |
|
|
766
|
-
| `customDomainIcon` | `string` | `''` | Custom favicon URL |
|
|
767
|
-
| `apiTitle` | `string` | Auto-detected | API documentation title |
|
|
768
|
-
| `apiVersion` | `string` | Auto-detected | API version number |
|
|
769
|
-
|
|
770
|
-
### π Interactive Features
|
|
771
|
-
|
|
772
|
-
When you visit `http://localhost:3000/docs`, you'll experience:
|
|
773
|
-
|
|
774
|
-
- π― **Single-Request Navigation** - Each endpoint on its own dedicated page
|
|
775
|
-
- π **Controller Grouping** - Organized sidebar with uppercase section headers
|
|
776
|
-
- π¨ **Active State Glow** - Cyber-cyan highlight for selected endpoints
|
|
777
|
-
- π **Auto-generated Examples** - Pre-filled mock data in request editor
|
|
778
|
-
- π§ͺ **Live Testing** - Send requests directly from the three-column interface
|
|
779
|
-
- π» **Terminal Response** - Black box with green text for authentic feel
|
|
780
|
-
- π **Quick Search** - Press 'K' to search endpoints instantly
|
|
781
|
-
- π± **Responsive Design** - Adapts to mobile, tablet, and desktop
|
|
782
|
-
- β¨ **Animated Branding** - Pulsing "Powered by Nest-Scramble" badge
|
|
783
|
-
- π **Developer Easter Eggs** - Check your browser console for surprises!
|
|
784
|
-
|
|
785
|
-
### π₯οΈ Terminal Dashboard
|
|
786
|
-
|
|
787
|
-
The startup dashboard now features **gradient styling** with ANSI colors:
|
|
788
|
-
|
|
789
|
-
```
|
|
790
|
-
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
791
|
-
β β¨ NEST-SCRAMBLE by Mohamed Mustafa β
|
|
792
|
-
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
|
|
793
|
-
β β
|
|
794
|
-
β β Documentation β
|
|
795
|
-
β β http://localhost:3000/docs β
|
|
796
|
-
β β
|
|
797
|
-
β β OpenAPI Spec β
|
|
798
|
-
β β http://localhost:3000/docs-json β
|
|
799
|
-
β β
|
|
800
|
-
β β Mock Server β
|
|
801
|
-
β β http://localhost:3000/scramble-mock β
|
|
802
|
-
β β
|
|
803
|
-
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
|
|
804
|
-
β π¦ Source Path: src β
|
|
805
|
-
β π― Controllers: 5 β
|
|
806
|
-
β π¨ Theme: Futuristic β
|
|
807
|
-
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
808
|
-
```
|
|
809
|
-
|
|
810
|
-
### π More UI Documentation
|
|
811
|
-
|
|
812
|
-
For complete UI customization guide, see:
|
|
813
|
-
- **[UI_FEATURES.md](./UI_FEATURES.md)** - Comprehensive feature documentation
|
|
814
|
-
- **[examples/futuristic-ui-example.ts](./examples/futuristic-ui-example.ts)** - Usage examples
|
|
815
|
-
|
|
816
|
-
### Available Endpoints
|
|
817
|
-
|
|
818
|
-
| Endpoint | Description |
|
|
819
|
-
|----------|-------------|
|
|
820
|
-
| `GET /docs` | Interactive Scalar UI documentation |
|
|
821
|
-
| `GET /docs-json` | OpenAPI 3.0 JSON specification |
|
|
822
|
-
| `GET /docs/json` | Legacy endpoint (same as above) |
|
|
823
|
-
| `GET /docs/spec` | OpenAPI spec as JSON response |
|
|
824
|
-
|
|
825
|
-
### Accessing the OpenAPI Spec
|
|
826
|
-
|
|
827
|
-
You can use the OpenAPI JSON with other tools:
|
|
828
|
-
|
|
829
|
-
```bash
|
|
830
|
-
# Download the spec
|
|
831
|
-
curl http://localhost:3000/docs-json > openapi.json
|
|
832
|
-
|
|
833
|
-
# Use with Swagger UI
|
|
834
|
-
docker run -p 8080:8080 -e SWAGGER_JSON=/openapi.json -v $(pwd):/usr/share/nginx/html/openapi.json swaggerapi/swagger-ui
|
|
835
|
-
|
|
836
|
-
# Import into Postman
|
|
837
|
-
# File > Import > Link > http://localhost:3000/docs-json
|
|
838
|
-
```
|
|
839
|
-
|
|
840
|
-
## β
Supported Features
|
|
841
|
-
|
|
842
|
-
### Type Analysis
|
|
843
|
-
- β
Primitive types (string, number, boolean)
|
|
844
|
-
- β
Arrays and nested objects
|
|
845
|
-
- β
Union types
|
|
846
|
-
- β
Enums
|
|
847
|
-
- β
Optional properties
|
|
848
|
-
- β
Circular references (auto-detected)
|
|
849
|
-
|
|
850
|
-
### HTTP Methods
|
|
851
|
-
- β
GET, POST, PUT, DELETE, PATCH
|
|
852
|
-
- β
Path parameters (@Param)
|
|
853
|
-
- β
Query parameters (@Query)
|
|
854
|
-
- β
Request bodies (@Body)
|
|
855
|
-
|
|
856
|
-
### Code Generation
|
|
857
|
-
- β
Curl commands
|
|
858
|
-
- β
JavaScript Fetch
|
|
859
|
-
- β
TypeScript with types
|
|
860
|
-
|
|
861
|
-
## π§ͺ Testing with Demo Controller
|
|
862
|
-
|
|
863
|
-
The library includes a `DemoController` with complex DTOs:
|
|
864
|
-
|
|
865
|
-
```typescript
|
|
866
|
-
// Complex DTOs with circular references
|
|
867
|
-
export class UserDto {
|
|
868
|
-
id: number;
|
|
869
|
-
name: string;
|
|
870
|
-
email: string;
|
|
871
|
-
role: UserRole; // Enum
|
|
872
|
-
address: AddressDto; // Nested
|
|
873
|
-
posts: PostDto[]; // Circular reference
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
export class PostDto {
|
|
877
|
-
id: number;
|
|
878
|
-
title: string;
|
|
879
|
-
content: string;
|
|
880
|
-
author: UserDto; // Circular reference
|
|
881
|
-
}
|
|
882
|
-
```
|
|
883
|
-
|
|
884
|
-
Run the demo to verify everything works perfectly.
|
|
885
|
-
|
|
886
|
-
## πΊοΈ Roadmap
|
|
887
|
-
|
|
888
|
-
- [ ] GraphQL support
|
|
889
|
-
- [ ] Custom mock data providers
|
|
890
|
-
- [ ] Authentication integration
|
|
891
|
-
- [ ] API versioning
|
|
892
|
-
- [ ] Performance optimizations
|
|
893
|
-
- [ ] Plugin system for custom analyzers
|
|
894
|
-
|
|
895
|
-
## π§ Troubleshooting
|
|
896
|
-
|
|
897
|
-
### Common Issues
|
|
898
|
-
|
|
899
|
-
#### 1. **"No controllers found" Warning**
|
|
900
|
-
|
|
901
|
-
If you see this warning on startup:
|
|
902
|
-
```
|
|
903
|
-
[Nest-Scramble] No controllers found in /src. Please check your sourcePath config.
|
|
904
|
-
```
|
|
905
|
-
|
|
906
|
-
**Solution:**
|
|
907
|
-
- Ensure your `sourcePath` option points to the correct directory containing your controllers
|
|
908
|
-
- Check that your controllers use the `@Controller()` decorator from `@nestjs/common`
|
|
909
|
-
- Verify your project structure matches the configured path
|
|
910
|
-
|
|
911
|
-
```typescript
|
|
912
|
-
NestScrambleModule.forRoot({
|
|
913
|
-
sourcePath: 'src', // Make sure this matches your project structure
|
|
914
|
-
})
|
|
915
|
-
```
|
|
916
|
-
|
|
917
|
-
#### 2. **UI Not Loading / Blank Page at /docs**
|
|
918
|
-
|
|
919
|
-
**Solution:**
|
|
920
|
-
- Clear your browser cache and hard refresh (Ctrl+Shift+R / Cmd+Shift+R)
|
|
921
|
-
- Check browser console for errors
|
|
922
|
-
- Verify the `/docs-json` endpoint returns valid JSON
|
|
923
|
-
- Ensure you're using version 3.0.0 or higher: `npm list nest-scramble`
|
|
924
|
-
- Verify NestJS version compatibility (v10.x or v11.x required)
|
|
925
|
-
- Check Node.js version: `node --version` (must be >=18.10.0)
|
|
926
|
-
- Check TypeScript version: `npx tsc --version` (must be >=5.0.0)
|
|
927
|
-
|
|
928
|
-
#### 3. **TypeScript Compilation Errors**
|
|
929
|
-
|
|
930
|
-
If you get errors like `Cannot find module 'nest-scramble'`:
|
|
931
|
-
|
|
932
|
-
**Solution:**
|
|
933
|
-
```bash
|
|
934
|
-
# Clear node_modules and reinstall
|
|
935
|
-
rm -rf node_modules package-lock.json
|
|
936
|
-
npm install
|
|
937
|
-
|
|
938
|
-
# Rebuild your project
|
|
939
|
-
npm run build
|
|
940
|
-
```
|
|
941
|
-
|
|
942
|
-
#### 4. **"Unauthorized" (401) Error on /docs Endpoint**
|
|
943
|
-
|
|
944
|
-
If you have a Global AuthGuard and get 401 Unauthorized when accessing `/docs` or `/docs-json`:
|
|
945
|
-
|
|
946
|
-
**Solution:**
|
|
947
|
-
|
|
948
|
-
Nest-Scramble automatically marks its documentation endpoints as public using `@SetMetadata('isPublic', true)`. However, your AuthGuard needs to respect this metadata.
|
|
949
|
-
|
|
950
|
-
Update your AuthGuard to check for the `isPublic` metadata:
|
|
951
|
-
|
|
952
|
-
```typescript
|
|
953
|
-
import { Injectable, ExecutionContext } from '@nestjs/common';
|
|
954
|
-
import { Reflector } from '@nestjs/core';
|
|
955
|
-
import { AuthGuard } from '@nestjs/passport';
|
|
956
|
-
|
|
957
|
-
@Injectable()
|
|
958
|
-
export class JwtAuthGuard extends AuthGuard('jwt') {
|
|
959
|
-
constructor(private reflector: Reflector) {
|
|
960
|
-
super();
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
canActivate(context: ExecutionContext) {
|
|
964
|
-
// Check if route is marked as public
|
|
965
|
-
const isPublic = this.reflector.getAllAndOverride<boolean>('isPublic', [
|
|
966
|
-
context.getHandler(),
|
|
967
|
-
context.getClass(),
|
|
968
|
-
]);
|
|
969
|
-
|
|
970
|
-
if (isPublic) {
|
|
971
|
-
return true; // Allow access to public routes
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
return super.canActivate(context);
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
```
|
|
978
|
-
|
|
979
|
-
**Alternative Solution - Exclude /docs path:**
|
|
980
|
-
|
|
981
|
-
```typescript
|
|
982
|
-
import { Module } from '@nestjs/common';
|
|
983
|
-
import { APP_GUARD } from '@nestjs/core';
|
|
984
|
-
|
|
985
|
-
@Module({
|
|
986
|
-
providers: [
|
|
987
|
-
{
|
|
988
|
-
provide: APP_GUARD,
|
|
989
|
-
useClass: JwtAuthGuard,
|
|
990
|
-
},
|
|
991
|
-
],
|
|
992
|
-
})
|
|
993
|
-
export class AppModule {}
|
|
994
|
-
|
|
995
|
-
// In your AuthGuard:
|
|
996
|
-
canActivate(context: ExecutionContext) {
|
|
997
|
-
const request = context.switchToHttp().getRequest();
|
|
998
|
-
|
|
999
|
-
// Skip authentication for documentation endpoints
|
|
1000
|
-
if (request.url.startsWith('/docs')) {
|
|
1001
|
-
return true;
|
|
1002
|
-
}
|
|
1003
|
-
|
|
1004
|
-
return super.canActivate(context);
|
|
1005
|
-
}
|
|
1006
|
-
```
|
|
1007
|
-
|
|
1008
|
-
#### 5. **pnpm Dependency Conflicts**
|
|
1009
|
-
|
|
1010
|
-
If using pnpm and getting peer dependency warnings:
|
|
1011
|
-
|
|
1012
|
-
**Solution:**
|
|
1013
|
-
Nest-Scramble v1.1.0+ properly declares peer dependencies. Update to the latest version:
|
|
1014
|
-
```bash
|
|
1015
|
-
pnpm update nest-scramble
|
|
1016
|
-
```
|
|
1017
|
-
|
|
1018
|
-
#### 6. **Controllers Not Being Scanned**
|
|
1019
|
-
|
|
1020
|
-
The scanner looks in your **host project's** `src` folder, not the library's folder.
|
|
1021
|
-
|
|
1022
|
-
**Diagnostic Steps:**
|
|
1023
|
-
1. Check the startup logs - they show exactly where the scanner is looking:
|
|
1024
|
-
```
|
|
1025
|
-
[Nest-Scramble] Scanning directory: /path/to/your/project/src
|
|
1026
|
-
[Nest-Scramble] Found X controller(s)
|
|
1027
|
-
```
|
|
1028
|
-
|
|
1029
|
-
2. Ensure your controllers are in TypeScript files (`.ts`) not JavaScript (`.js`)
|
|
1030
|
-
|
|
1031
|
-
3. Verify your `tsconfig.json` exists in the project root
|
|
1032
|
-
|
|
1033
|
-
#### 7. **Mock Endpoints Not Working**
|
|
1034
|
-
|
|
1035
|
-
If `/scramble-mock/*` returns 404:
|
|
1036
|
-
|
|
1037
|
-
**Solution:**
|
|
1038
|
-
- Ensure `enableMock: true` in your configuration
|
|
1039
|
-
- The middleware applies to all routes matching `/scramble-mock/*`
|
|
1040
|
-
- Example: `http://localhost:3000/scramble-mock/users/123`
|
|
1041
|
-
|
|
1042
|
-
#### 8. **OpenAPI Spec is Empty or Incomplete**
|
|
1043
|
-
|
|
1044
|
-
**Solution:**
|
|
1045
|
-
- Ensure your DTOs are TypeScript classes or interfaces (not plain objects)
|
|
1046
|
-
- Check that your controller methods have proper return type annotations
|
|
1047
|
-
- Verify decorators are imported from `@nestjs/common`
|
|
1048
|
-
|
|
1049
|
-
```typescript
|
|
1050
|
-
// β
Good - Explicit return type
|
|
1051
|
-
@Get(':id')
|
|
1052
|
-
getUser(@Param('id') id: string): UserDto {
|
|
1053
|
-
return this.userService.findOne(id);
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
// β Bad - No return type
|
|
1057
|
-
@Get(':id')
|
|
1058
|
-
getUser(@Param('id') id: string) {
|
|
1059
|
-
return this.userService.findOne(id);
|
|
1060
|
-
}
|
|
1061
|
-
```
|
|
1062
|
-
|
|
1063
|
-
### Getting Help
|
|
1064
|
-
|
|
1065
|
-
If you're still experiencing issues:
|
|
1066
|
-
|
|
1067
|
-
1. **Check the logs** - Nest-Scramble provides detailed diagnostic output on startup
|
|
1068
|
-
2. **Verify your version** - Run `npm list nest-scramble` (should be 3.0.0+)
|
|
1069
|
-
3. **Check NestJS compatibility** - Verify you're using NestJS v10.x or v11.x (v9 is no longer supported)
|
|
1070
|
-
4. **Check Node.js version** - Run `node --version` (must be >=18.10.0)
|
|
1071
|
-
5. **Check TypeScript version** - Run `npx tsc --version` (must be >=5.0.0)
|
|
1072
|
-
6. **Open an issue** - [GitHub Issues](https://github.com/Eng-MMustafa/nest-scramble/issues)
|
|
1073
|
-
|
|
1074
|
-
When reporting issues, please include:
|
|
1075
|
-
- Nest-Scramble version (3.0.0+)
|
|
1076
|
-
- NestJS version (v10.x or v11.x)
|
|
1077
|
-
- Node.js version (>=18.10.0)
|
|
1078
|
-
- TypeScript version (>=5.0.0)
|
|
1079
|
-
- Package manager (npm/yarn/pnpm)
|
|
1080
|
-
- Startup logs
|
|
1081
|
-
- Sample controller code
|
|
1082
|
-
|
|
1083
|
-
## π€ Contributing
|
|
1084
|
-
|
|
1085
|
-
We welcome contributions! Please:
|
|
1086
|
-
|
|
1087
|
-
1. Fork the repository
|
|
1088
|
-
2. Create a feature branch
|
|
1089
|
-
3. Add tests for new features
|
|
1090
|
-
4. Submit a pull request
|
|
1091
|
-
|
|
1092
|
-
## π License
|
|
1093
|
-
|
|
1094
|
-
MIT License - see [LICENSE](LICENSE) file.
|
|
1095
|
-
|
|
1096
|
-
## βπ» About the Author
|
|
1097
|
-
|
|
1098
|
-

|
|
1099
|
-
|
|
1100
|
-
Mohamed Mustafa is a passionate full-stack developer with a deep love for TypeScript and modern web frameworks. His mission is to build tools that enhance developer experience and eliminate repetitive tasks. When he's not crafting open-source libraries, you'll find him exploring new technologies, contributing to the developer community, or sharing insights through technical writing.
|
|
1101
|
-
|
|
1102
|
-
- [GitHub](https://github.com/Eng-MMustafa)
|
|
1103
|
-
- [LinkedIn](https://www.linkedin.com/in/engmohammedmustafa/)
|
|
1
|
+
# Nest-Scramble
|
|
2
|
+
|
|
3
|
+
> Zero-config API Documentation, Postman Generator & Typed Client SDK for NestJS β powered by static TypeScript analysis
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/js/nest-scramble)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://github.com/Eng-MMustafa/nest-scramble)
|
|
8
|
+
[](https://github.com/Eng-MMustafa)
|
|
9
|
+
[](https://docs.nestjs.com)
|
|
10
|
+
[](https://nodejs.org)
|
|
11
|
+
[](https://www.typescriptlang.org)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## What's New in v3.0.4
|
|
16
|
+
|
|
17
|
+
### Typed HTTP Client SDK Generation β¨
|
|
18
|
+
|
|
19
|
+
The biggest quality-of-life addition yet. Nest-Scramble can now **generate a fully-typed TypeScript API client** directly from your NestJS controllers β no OpenAPI tooling required, no extra decorators, zero dependencies in the output.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx nest-scramble generate src --format client --output ./api-client.ts
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Generated output (`api-client.ts`):**
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
// Auto-generated by nest-scramble v3.0.4 β do not edit manually
|
|
29
|
+
// Re-generate: npx nest-scramble generate src --format client
|
|
30
|
+
|
|
31
|
+
export class UsersApiClient {
|
|
32
|
+
constructor(private readonly baseUrl: string) {}
|
|
33
|
+
|
|
34
|
+
async getUsers(page?: number, limit?: number): Promise<UserListDto[]> {
|
|
35
|
+
const url = new URL(`${this.baseUrl}/users`);
|
|
36
|
+
if (page !== undefined) url.searchParams.set('page', String(page));
|
|
37
|
+
if (limit !== undefined) url.searchParams.set('limit', String(limit));
|
|
38
|
+
const res = await fetch(url.toString());
|
|
39
|
+
return res.json();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async createUser(body: CreateUserDto): Promise<UserDto> {
|
|
43
|
+
const res = await fetch(`${this.baseUrl}/users`, {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
headers: { 'Content-Type': 'application/json' },
|
|
46
|
+
body: JSON.stringify(body),
|
|
47
|
+
});
|
|
48
|
+
return res.json();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async deleteUser(id: string): Promise<void> {
|
|
52
|
+
await fetch(`${this.baseUrl}/users/${id}`, { method: 'DELETE' });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Use it anywhere β frontend, E2E tests, microservices:**
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { UsersApiClient } from './api-client';
|
|
61
|
+
|
|
62
|
+
const client = new UsersApiClient('http://localhost:3000');
|
|
63
|
+
const users = await client.getUsers(1, 10); // fully typed β
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
No extra runtime packages. Uses native `fetch`. Stays in sync with your controllers by re-running the command.
|
|
67
|
+
|
|
68
|
+
### Other v3.0.4 changes
|
|
69
|
+
|
|
70
|
+
- Controller-based sidebar grouping is now the default (no config needed)
|
|
71
|
+
- Route param normalisation `:id` β `{id}` for full OpenAPI compliance
|
|
72
|
+
- Scalar standalone HTML integration for more reliable docs rendering
|
|
73
|
+
- `baseUrl` is now respected exactly as configured in the dashboard
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Why Nest-Scramble
|
|
78
|
+
|
|
79
|
+
No `@ApiProperty` decorators. No runtime overhead. Nest-Scramble reads your TypeScript source using AST analysis and automatically produces:
|
|
80
|
+
|
|
81
|
+
| | Nest-Scramble | @nestjs/swagger |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| Analysis | Static AST (compile-time) | Runtime reflection |
|
|
84
|
+
| Decorators required | None | `@ApiProperty` everywhere |
|
|
85
|
+
| Circular references | Auto-detected | Manual workarounds |
|
|
86
|
+
| Performance overhead | Zero | Decorator cost on every request |
|
|
87
|
+
| Postman collection | Built-in | Third-party export |
|
|
88
|
+
| Typed client SDK | β
v3.0.4 | β |
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Quick Start
|
|
93
|
+
|
|
94
|
+
### Option A β Auto-inject (30 seconds)
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npm install nest-scramble
|
|
98
|
+
npx nest-scramble init
|
|
99
|
+
npm run start:dev
|
|
100
|
+
# Visit http://localhost:3000/docs
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The `init` command patches your `app.module.ts` automatically.
|
|
104
|
+
|
|
105
|
+
### Option B β Manual
|
|
106
|
+
|
|
107
|
+
**1. Install**
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm install nest-scramble
|
|
111
|
+
# yarn add nest-scramble
|
|
112
|
+
# pnpm add nest-scramble
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**2. Register the module**
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { Module } from '@nestjs/common';
|
|
119
|
+
import { NestScrambleModule } from 'nest-scramble';
|
|
120
|
+
|
|
121
|
+
@Module({
|
|
122
|
+
imports: [NestScrambleModule.forRoot()], // zero-config
|
|
123
|
+
})
|
|
124
|
+
export class AppModule {}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**3. Start your app**
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npm run start:dev
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Terminal output:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
137
|
+
β β¨ NEST-SCRAMBLE by Mohamed Mustafa β
|
|
138
|
+
β β
|
|
139
|
+
β β Docs β http://localhost:3000/docs β
|
|
140
|
+
β β OpenAPI β http://localhost:3000/docs-json β
|
|
141
|
+
β β Mock β http://localhost:3000/scramble-mock β
|
|
142
|
+
β β
|
|
143
|
+
β π¦ Source: src π― Controllers: 5 β
|
|
144
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Configuration
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
NestScrambleModule.forRoot({
|
|
153
|
+
sourcePath: 'src', // default: 'src'
|
|
154
|
+
baseUrl: 'http://localhost:3000', // default: auto-detected from PORT/HOST
|
|
155
|
+
path: '/docs', // default: '/docs'
|
|
156
|
+
enableMock: true, // default: true
|
|
157
|
+
autoExportPostman: false, // default: false
|
|
158
|
+
postmanOutputPath: 'collection.json', // default: 'collection.json'
|
|
159
|
+
theme: 'futuristic', // 'classic' | 'futuristic'
|
|
160
|
+
primaryColor: '#00f2ff', // any hex colour
|
|
161
|
+
customDomainIcon: '', // favicon URL
|
|
162
|
+
apiTitle: 'My API', // default: from package.json
|
|
163
|
+
apiVersion: '1.0.0', // default: from package.json
|
|
164
|
+
useIncrementalScanning: false, // faster startup via caching
|
|
165
|
+
enableWatchMode: false, // auto-regenerate on file changes
|
|
166
|
+
cacheTtl: 86400000, // cache TTL in ms (default: 24h)
|
|
167
|
+
})
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
| Option | Type | Default | Description |
|
|
171
|
+
|--------|------|---------|-------------|
|
|
172
|
+
| `sourcePath` | `string` | `'src'` | Directory containing your controllers |
|
|
173
|
+
| `baseUrl` | `string` | auto | Base URL shown in docs and mock server |
|
|
174
|
+
| `path` | `string` | `'/docs'` | Documentation UI endpoint |
|
|
175
|
+
| `enableMock` | `boolean` | `true` | Enable `/scramble-mock/*` proxy endpoints |
|
|
176
|
+
| `autoExportPostman` | `boolean` | `false` | Write Postman collection on startup |
|
|
177
|
+
| `theme` | `'classic' \| 'futuristic'` | `'futuristic'` | UI theme |
|
|
178
|
+
| `primaryColor` | `string` | `'#00f2ff'` | Accent colour (hex) |
|
|
179
|
+
| `useIncrementalScanning` | `boolean` | `false` | Cache AST results between restarts |
|
|
180
|
+
| `enableWatchMode` | `boolean` | `false` | Re-scan on file save |
|
|
181
|
+
| `cacheTtl` | `number` | `86400000` | Cache lifetime in milliseconds |
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## CLI Reference
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Generate OpenAPI JSON
|
|
189
|
+
npx nest-scramble generate src -o openapi.json
|
|
190
|
+
|
|
191
|
+
# Generate Postman collection
|
|
192
|
+
npx nest-scramble generate src --format postman -o collection.json
|
|
193
|
+
|
|
194
|
+
# Generate typed TypeScript client (NEW in v3.0.4)
|
|
195
|
+
npx nest-scramble generate src --format client -o api-client.ts
|
|
196
|
+
|
|
197
|
+
# Custom options
|
|
198
|
+
npx nest-scramble generate src \
|
|
199
|
+
-o my-api.json \
|
|
200
|
+
-t "My API" \
|
|
201
|
+
-v "2.0.0" \
|
|
202
|
+
-b "https://api.example.com"
|
|
203
|
+
|
|
204
|
+
# Check version
|
|
205
|
+
npx nest-scramble --version
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**All `generate` options:**
|
|
209
|
+
|
|
210
|
+
| Flag | Description | Default |
|
|
211
|
+
|------|-------------|---------|
|
|
212
|
+
| `-o, --output <file>` | Output file path | `openapi.json` |
|
|
213
|
+
| `-f, --format <type>` | `openapi` \| `postman` \| `client` | `openapi` |
|
|
214
|
+
| `-b, --baseUrl <url>` | API base URL | `http://localhost:3000` |
|
|
215
|
+
| `-t, --title <title>` | API title | `NestJS API` |
|
|
216
|
+
| `-v, --apiVersion <ver>` | API version | `1.0.0` |
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Programmatic API
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
import { ScannerService, OpenApiTransformer, PostmanCollectionGenerator } from 'nest-scramble';
|
|
224
|
+
import * as fs from 'fs';
|
|
225
|
+
|
|
226
|
+
const scanner = new ScannerService();
|
|
227
|
+
const controllers = scanner.scanControllers('src');
|
|
228
|
+
|
|
229
|
+
// OpenAPI spec
|
|
230
|
+
const transformer = new OpenApiTransformer('http://localhost:3000');
|
|
231
|
+
const spec = transformer.transform(controllers, 'My API', '1.0.0', 'http://localhost:3000');
|
|
232
|
+
fs.writeFileSync('openapi.json', JSON.stringify(spec, null, 2));
|
|
233
|
+
|
|
234
|
+
// Postman collection
|
|
235
|
+
const postman = new PostmanCollectionGenerator('http://localhost:3000');
|
|
236
|
+
const collection = postman.generateCollection(controllers);
|
|
237
|
+
fs.writeFileSync('collection.json', JSON.stringify(collection, null, 2));
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Advanced: Incremental Scanning & Watch Mode
|
|
243
|
+
|
|
244
|
+
Enable for **10β100Γ faster restarts** on large projects.
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
NestScrambleModule.forRoot({
|
|
248
|
+
useIncrementalScanning: true, // cache AST results to scramble-cache.json
|
|
249
|
+
enableWatchMode: true, // recompute only changed files
|
|
250
|
+
cacheTtl: 86400000, // invalidate after 24h
|
|
251
|
+
})
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Cache is invalidated automatically when file content, file size, `tsconfig.json`, or the library version changes.
|
|
255
|
+
|
|
256
|
+
**Add to `.gitignore`:**
|
|
257
|
+
|
|
258
|
+
```gitignore
|
|
259
|
+
scramble-cache.json
|
|
260
|
+
.scramble-cache.json
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**Benchmark (typical project):**
|
|
264
|
+
|
|
265
|
+
| Scenario | Time |
|
|
266
|
+
|---|---|
|
|
267
|
+
| Cold start (no cache) | ~2100 ms |
|
|
268
|
+
| Warm cache (full) | ~50 ms |
|
|
269
|
+
| Single file changed | ~20 ms |
|
|
270
|
+
| DTO changed (5 dependents) | ~100 ms |
|
|
271
|
+
|
|
272
|
+
**Programmatic incremental scanner:**
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
import { IncrementalScannerService } from 'nest-scramble';
|
|
276
|
+
|
|
277
|
+
const scanner = new IncrementalScannerService({ useCache: true });
|
|
278
|
+
scanner.initialize('src');
|
|
279
|
+
const controllers = scanner.scanControllers('src');
|
|
280
|
+
scanner.cleanup();
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Live Mocking
|
|
286
|
+
|
|
287
|
+
With `enableMock: true` (default), all routes are available under `/scramble-mock/*` with realistic auto-generated data β no database, no environment setup needed.
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
GET /scramble-mock/users/1
|
|
291
|
+
# β { "id": 1, "name": "Jane Smith", "email": "jane@example.com", "createdAt": "..." }
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Mock values are field-name-aware:
|
|
295
|
+
- `email` β `faker.internet.email()`
|
|
296
|
+
- `name` / `fullName` β `faker.person.fullName()`
|
|
297
|
+
- `createdAt` / `updatedAt` β `faker.date.recent()`
|
|
298
|
+
- `id` β incremental integer
|
|
299
|
+
- Arrays β 2β5 auto-generated items
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Documentation UI
|
|
304
|
+
|
|
305
|
+
Visit `/docs` for the interactive dashboard:
|
|
306
|
+
|
|
307
|
+
- **Sidebar navigation** β endpoints grouped by controller, collapsible
|
|
308
|
+
- **Three-column layout** β Info | Request Editor | Test Panel
|
|
309
|
+
- **Live request sender** β test endpoints directly in the browser
|
|
310
|
+
- **Pre-filled mock data** β request bodies auto-populated
|
|
311
|
+
- **Theme options** β `futuristic` (dark, cyan accents) or `classic` (light)
|
|
312
|
+
- **Search** β press `K` to filter endpoints instantly
|
|
313
|
+
|
|
314
|
+
**Custom branding:**
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
NestScrambleModule.forRoot({
|
|
318
|
+
theme: 'futuristic',
|
|
319
|
+
primaryColor: '#a855f7', // electric purple
|
|
320
|
+
customDomainIcon: '/logo.png',
|
|
321
|
+
apiTitle: 'My Platform API',
|
|
322
|
+
})
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Available endpoints:**
|
|
326
|
+
|
|
327
|
+
| Endpoint | Description |
|
|
328
|
+
|----------|-------------|
|
|
329
|
+
| `GET /docs` | Interactive Scalar UI |
|
|
330
|
+
| `GET /docs-json` | OpenAPI 3.0 JSON spec |
|
|
331
|
+
| `GET /docs/spec` | OpenAPI spec as JSON response |
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## CI/CD Integration
|
|
336
|
+
|
|
337
|
+
```yaml
|
|
338
|
+
# .github/workflows/docs.yml
|
|
339
|
+
name: Generate API Docs
|
|
340
|
+
on:
|
|
341
|
+
push:
|
|
342
|
+
branches: [main]
|
|
343
|
+
|
|
344
|
+
jobs:
|
|
345
|
+
generate:
|
|
346
|
+
runs-on: ubuntu-latest
|
|
347
|
+
steps:
|
|
348
|
+
- uses: actions/checkout@v3
|
|
349
|
+
- uses: actions/setup-node@v3
|
|
350
|
+
with: { node-version: '20' }
|
|
351
|
+
- run: npm install
|
|
352
|
+
- run: npx nest-scramble generate src -o openapi.json
|
|
353
|
+
- uses: actions/upload-artifact@v3
|
|
354
|
+
with:
|
|
355
|
+
name: openapi-spec
|
|
356
|
+
path: openapi.json
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Supported Types & Decorators
|
|
362
|
+
|
|
363
|
+
**TypeScript types:**
|
|
364
|
+
- Primitives: `string`, `number`, `boolean`
|
|
365
|
+
- Arrays, nested objects, union types
|
|
366
|
+
- Enums, optional properties
|
|
367
|
+
- Circular references (auto-detected and resolved)
|
|
368
|
+
|
|
369
|
+
**NestJS decorators:**
|
|
370
|
+
- HTTP methods: `@Get`, `@Post`, `@Put`, `@Patch`, `@Delete`
|
|
371
|
+
- Parameters: `@Param`, `@Query`, `@Body`
|
|
372
|
+
- Controllers: `@Controller` (path & group name)
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## Troubleshooting
|
|
377
|
+
|
|
378
|
+
**No controllers found**
|
|
379
|
+
|
|
380
|
+
Verify `sourcePath` points to the directory containing your `@Controller()` classes. On startup, Nest-Scramble logs the exact path it is scanning.
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
NestScrambleModule.forRoot({ sourcePath: 'src' })
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
**`/docs` returns 401 Unauthorized**
|
|
387
|
+
|
|
388
|
+
Your global `AuthGuard` is blocking the docs route. Add an `isPublic` bypass:
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
@Injectable()
|
|
392
|
+
export class JwtAuthGuard extends AuthGuard('jwt') {
|
|
393
|
+
constructor(private reflector: Reflector) { super(); }
|
|
394
|
+
|
|
395
|
+
canActivate(context: ExecutionContext) {
|
|
396
|
+
const isPublic = this.reflector.getAllAndOverride<boolean>('isPublic', [
|
|
397
|
+
context.getHandler(),
|
|
398
|
+
context.getClass(),
|
|
399
|
+
]);
|
|
400
|
+
return isPublic ? true : super.canActivate(context);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Nest-Scramble marks its own endpoints with `@SetMetadata('isPublic', true)` automatically.
|
|
406
|
+
|
|
407
|
+
**OpenAPI spec is empty or incomplete**
|
|
408
|
+
|
|
409
|
+
Ensure your controller methods declare an explicit return type:
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
// β
Good
|
|
413
|
+
@Get(':id')
|
|
414
|
+
getUser(@Param('id') id: string): UserDto { ... }
|
|
415
|
+
|
|
416
|
+
// β Missing return type β DTO cannot be inferred
|
|
417
|
+
@Get(':id')
|
|
418
|
+
getUser(@Param('id') id: string) { ... }
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
**TypeScript compilation errors after install**
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
rm -rf node_modules package-lock.json
|
|
425
|
+
npm install
|
|
426
|
+
npm run build
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
**When reporting an issue, include:** Nest-Scramble version, NestJS version, Node.js version, TypeScript version, startup log output.
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## Requirements
|
|
434
|
+
|
|
435
|
+
| Requirement | Minimum Version |
|
|
436
|
+
|---|---|
|
|
437
|
+
| Node.js | 18.10.0 |
|
|
438
|
+
| TypeScript | 5.0.0 |
|
|
439
|
+
| NestJS | 10.x or 11.x |
|
|
440
|
+
| reflect-metadata | 0.1.13 (optional) |
|
|
441
|
+
|
|
442
|
+
### Upgrading from v2.x
|
|
443
|
+
|
|
444
|
+
```bash
|
|
445
|
+
npm install @nestjs/common@^10 @nestjs/core@^10
|
|
446
|
+
npm install nest-scramble@latest
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## Roadmap
|
|
452
|
+
|
|
453
|
+
- [x] OpenAPI 3.0 generation (static AST)
|
|
454
|
+
- [x] Interactive Scalar UI with controller grouping
|
|
455
|
+
- [x] Postman collection export
|
|
456
|
+
- [x] Live mock server
|
|
457
|
+
- [x] Incremental scanning & watch mode
|
|
458
|
+
- [x] Transitive dependency tracking
|
|
459
|
+
- [x] Typed TypeScript client SDK (v3.0.4)
|
|
460
|
+
- [ ] Insomnia / Bruno collection export
|
|
461
|
+
- [ ] `@ScrambleDoc()` lightweight metadata decorator
|
|
462
|
+
- [ ] GraphQL schema support
|
|
463
|
+
- [ ] Plugin API for custom analyzers
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## Contributing
|
|
468
|
+
|
|
469
|
+
1. Fork the repository
|
|
470
|
+
2. Create a feature branch
|
|
471
|
+
3. Add tests for new behaviour
|
|
472
|
+
4. Submit a pull request
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
## License
|
|
477
|
+
|
|
478
|
+
MIT β see [LICENSE](LICENSE).
|
|
479
|
+
|
|
480
|
+
## Author
|
|
481
|
+
|
|
482
|
+
**Mohamed Mustafa** β [GitHub](https://github.com/Eng-MMustafa) Β· [LinkedIn](https://www.linkedin.com/in/engmohammedmustafa/)
|