@umeshindu222/apisnap 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,6 @@
1
- # 📸 APISnap
1
+
2
+ <img width="4368" height="2112" alt="Group 1" src="https://github.com/user-attachments/assets/c162b436-1c64-470e-9f41-e5ceb09a31d4" />
3
+
2
4
 
3
5
  ## Quick start
4
6
 
@@ -25,6 +27,7 @@ apisnap.init(app); // ← must be AFTER your routes
25
27
 
26
28
  [![npm version](https://img.shields.io/npm/v/@umeshindu222/apisnap.svg)](https://www.npmjs.com/package/@umeshindu222/apisnap)
27
29
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
30
+ [![Socket Badge](https://badge.socket.dev/npm/package/@umeshindu222/apisnap/1.2.3)](https://socket.dev/npm/package/%40umeshindu222%2Fapisnap)
28
31
 
29
32
  ---
30
33
 
@@ -46,10 +49,16 @@ One command. Every route. Instant results.
46
49
  - **Auth Hints** - tells you exactly how to fix 401/403 errors
47
50
  - **Slow Route Detection** - flags endpoints that are too slow
48
51
  - **Retry Logic** - auto-retries failed requests
52
+ - **Rate-limit Backoff** - honors `429 Retry-After` and retries automatically
49
53
  - **HTML Reports** - beautiful visual reports you can share
50
54
  - **JSON Export** - structured output for CI/CD pipelines
51
55
  - **Config File** - save your settings so you don't retype every time
52
56
  - **Method Filter** - test only GET, POST, DELETE etc.
57
+ - **Path Filter + Dry Run** - target a route subset and preview without requests
58
+ - **OpenAPI Discovery** - load routes from an OpenAPI JSON spec
59
+ - **Baseline Diffing** - compare against saved runs and fail on regressions
60
+ - **Latency Percentiles** - p50 / p95 / p99 in terminal and reports
61
+ - **Doctor Command** - quick setup diagnostics
53
62
  - **Smart Path Params** - auto-replaces `:id`, `:slug`, `:uuid` with safe defaults
54
63
  - **Express v4 & v5** - works with both versions
55
64
 
@@ -315,15 +324,45 @@ APISnap reads the config file automatically.
315
324
 
316
325
  > ⚠️ **Add `.apisnaprc.json` to your `.gitignore`** so your token is never committed to GitHub.
317
326
 
327
+ ### Config Schema + Secrets
328
+
329
+ Use the bundled schema for autocomplete and validation:
330
+
331
+ ```json
332
+ {
333
+ "$schema": "./apisnaprc.schema.json"
334
+ }
335
+ ```
336
+
337
+ You can reference environment variables anywhere in config values:
338
+
339
+ ```json
340
+ {
341
+ "headers": [
342
+ "Authorization: Bearer $API_TOKEN"
343
+ ],
344
+ "authFlow": {
345
+ "url": "/auth/login",
346
+ "body": {
347
+ "username": "$API_USER",
348
+ "password": "$API_PASSWORD"
349
+ },
350
+ "tokenPath": "token"
351
+ }
352
+ }
353
+ ```
354
+
318
355
  ### Full Config File Options
319
356
 
320
357
  ```json
321
358
  {
359
+ "$schema": "./apisnaprc.schema.json",
322
360
  "port": "3000",
323
361
  "slow": "300",
324
362
  "timeout": "5000",
325
363
  "retry": "1",
326
364
  "concurrency": 5,
365
+ "openapi": "./openapi.json",
327
366
  "body": {
328
367
  "name": "test",
329
368
  "email": "test@example.com"
@@ -342,13 +381,19 @@ APISnap reads the config file automatically.
342
381
  "routes": [
343
382
  {
344
383
  "path": "/api/users",
345
- "body": { "name": "John", "email": "john@example.com" }
384
+ "body": { "name": "John", "email": "john@example.com" },
385
+ "timeout": 10000
346
386
  },
347
387
  {
348
388
  "path": "/api/products",
349
389
  "body": { "title": "Widget", "price": 9.99 }
350
390
  }
351
- ]
391
+ ],
392
+ "envs": {
393
+ "staging": {
394
+ "baseUrl": "https://staging.example.com"
395
+ }
396
+ }
352
397
  }
353
398
  ```
354
399
 
@@ -358,6 +403,7 @@ APISnap reads the config file automatically.
358
403
 
359
404
  ```bash
360
405
  npx @umeshindu222/apisnap [options]
406
+ npx @umeshindu222/apisnap doctor [options]
361
407
  ```
362
408
 
363
409
  | Option | Description | Default |
@@ -371,11 +417,28 @@ npx @umeshindu222/apisnap [options]
371
417
  | `-e, --export <file>` | Save JSON report to file | — |
372
418
  | `--html <file>` | Save HTML report to file | — |
373
419
  | `--only <methods>` | Only test these methods e.g. `GET,POST` | — |
420
+ | `--filter <pattern>` | Path substring/glob filter e.g. `/api/users*` | — |
374
421
  | `--base-url <url>` | Test a different server e.g. staging | `localhost` |
375
422
  | `--params <json>` | Override path params as JSON | — |
423
+ | `--dry-run` | Print resolved endpoint plan and exit | `false` |
376
424
  | `--fail-on-slow` | Exit code 1 if slow routes found | `false` |
377
425
  | `--concurrency <n>` | Concurrent requests to run | `1` |
378
426
  | `--body <json>` | Default JSON body for POST/PUT/PATCH | — |
427
+ | `--auth-flow` | Execute configured authFlow login before tests | `false` |
428
+ | `--session` | Capture/replay cookies from responses | `false` |
429
+ | `--save-baseline <file>` | Save run as baseline JSON | — |
430
+ | `--diff <file>` | Compare against baseline and show regressions | — |
431
+ | `--openapi <file>` | Discover routes from OpenAPI JSON | — |
432
+ | `--ci` | CI-friendly JSON output and strict exit logic | `false` |
433
+ | `--env <name>` | Load environment profile from config | — |
434
+
435
+ Doctor options:
436
+
437
+ | Option | Description | Default |
438
+ |--------|-------------|---------|
439
+ | `doctor` | Diagnose config, server reachability, and middleware wiring | — |
440
+ | `doctor -p, --port <n>` | Port to diagnose | config/`3000` |
441
+ | `doctor --env <name>` | Diagnose a specific config environment | — |
379
442
 
380
443
  ---
381
444
 
@@ -436,6 +499,31 @@ npx @umeshindu222/apisnap --export report
436
499
  npx @umeshindu222/apisnap --retry 3
437
500
  ```
438
501
 
502
+ ### Preview routes only (no HTTP calls)
503
+ ```bash
504
+ npx @umeshindu222/apisnap --dry-run --filter "/api/users*"
505
+ ```
506
+
507
+ ### Diff against baseline and fail on regressions
508
+ ```bash
509
+ npx @umeshindu222/apisnap --diff baseline.json
510
+ ```
511
+
512
+ ### Save a baseline for future comparisons
513
+ ```bash
514
+ npx @umeshindu222/apisnap --save-baseline baseline.json
515
+ ```
516
+
517
+ ### Discover from OpenAPI instead of live discovery
518
+ ```bash
519
+ npx @umeshindu222/apisnap --openapi ./openapi.json
520
+ ```
521
+
522
+ ### Run setup diagnostics
523
+ ```bash
524
+ npx @umeshindu222/apisnap doctor -p 3000
525
+ ```
526
+
439
527
  ### CI/CD — fail the pipeline if any endpoint is broken
440
528
  ```bash
441
529
  npx @umeshindu222/apisnap --export ci-report
@@ -460,7 +548,7 @@ npx @umeshindu222/apisnap \
460
548
  ## Sample Output
461
549
 
462
550
  ```
463
- 📸 APISnap v1.1.4
551
+ 📸 APISnap v1.2.3
464
552
  Target: http://localhost:3000
465
553
  Slow: >200ms
466
554
  Timeout: 5000ms
@@ -481,6 +569,9 @@ npx @umeshindu222/apisnap \
481
569
  ❌ Failed: 1
482
570
  ⚠️ Slow: 1 (>200ms)
483
571
  ⏱ Avg: 95ms
572
+ 📈 p50: 12ms
573
+ 📈 p95: 543ms
574
+ 📈 p99: 543ms
484
575
  🕐 Total: 573ms
485
576
 
486
577
  ⚠️ Some endpoints are unhealthy!
@@ -493,7 +584,7 @@ npx @umeshindu222/apisnap \
493
584
  ```json
494
585
  {
495
586
  "tool": "APISnap",
496
- "version": "1.1.4",
587
+ "version": "1.2.3",
497
588
  "generatedAt": "2026-03-08T10:00:00.000Z",
498
589
  "config": {
499
590
  "port": "3000",
@@ -506,6 +597,9 @@ npx @umeshindu222/apisnap \
506
597
  "failed": 1,
507
598
  "slow": 1,
508
599
  "avgDuration": 95,
600
+ "p50Duration": 12,
601
+ "p95Duration": 543,
602
+ "p99Duration": 543,
509
603
  "totalDuration": 573
510
604
  },
511
605
  "results": [
@@ -0,0 +1,128 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://umeshindu222.github.io/apisnap/apisnaprc.schema.json",
4
+ "title": "APISnap Configuration",
5
+ "type": "object",
6
+ "additionalProperties": true,
7
+ "properties": {
8
+ "port": {
9
+ "type": ["string", "number"],
10
+ "default": 3000
11
+ },
12
+ "slow": {
13
+ "type": ["string", "number"],
14
+ "default": 200
15
+ },
16
+ "timeout": {
17
+ "type": ["string", "number"],
18
+ "default": 5000
19
+ },
20
+ "retry": {
21
+ "type": ["string", "number"],
22
+ "default": 0
23
+ },
24
+ "concurrency": {
25
+ "type": ["string", "number"],
26
+ "default": 1
27
+ },
28
+ "baseUrl": {
29
+ "type": "string"
30
+ },
31
+ "openapi": {
32
+ "type": ["string", "boolean"],
33
+ "description": "Path to OpenAPI JSON file used for discovery"
34
+ },
35
+ "cookie": {
36
+ "type": "string"
37
+ },
38
+ "headers": {
39
+ "type": "array",
40
+ "items": {
41
+ "type": "string"
42
+ }
43
+ },
44
+ "params": {
45
+ "type": "object",
46
+ "additionalProperties": {
47
+ "type": ["string", "number", "boolean"]
48
+ }
49
+ },
50
+ "body": {
51
+ "type": "object",
52
+ "additionalProperties": true
53
+ },
54
+ "skip": {
55
+ "type": "array",
56
+ "items": {
57
+ "type": "string"
58
+ }
59
+ },
60
+ "authFlow": {
61
+ "$ref": "#/definitions/AuthFlow"
62
+ },
63
+ "routes": {
64
+ "type": "array",
65
+ "items": {
66
+ "$ref": "#/definitions/RouteConfig"
67
+ }
68
+ },
69
+ "envs": {
70
+ "type": "object",
71
+ "additionalProperties": {
72
+ "type": "object"
73
+ }
74
+ }
75
+ },
76
+ "definitions": {
77
+ "AuthFlow": {
78
+ "type": "object",
79
+ "required": ["url", "body", "tokenPath"],
80
+ "properties": {
81
+ "url": {
82
+ "type": "string"
83
+ },
84
+ "body": {
85
+ "type": "object",
86
+ "additionalProperties": true
87
+ },
88
+ "tokenPath": {
89
+ "type": "string"
90
+ },
91
+ "headerName": {
92
+ "type": "string"
93
+ },
94
+ "prefix": {
95
+ "type": "string"
96
+ }
97
+ }
98
+ },
99
+ "RouteConfig": {
100
+ "type": "object",
101
+ "required": ["path"],
102
+ "properties": {
103
+ "path": {
104
+ "type": "string"
105
+ },
106
+ "body": {
107
+ "type": "object",
108
+ "additionalProperties": true
109
+ },
110
+ "headers": {
111
+ "type": "array",
112
+ "items": {
113
+ "type": "string"
114
+ }
115
+ },
116
+ "auth": {
117
+ "type": "string",
118
+ "enum": ["none"]
119
+ },
120
+ "timeout": {
121
+ "type": "number",
122
+ "minimum": 1
123
+ }
124
+ },
125
+ "additionalProperties": true
126
+ }
127
+ }
128
+ }