@http-forge/core 0.2.9 → 0.2.11
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 +24 -117
- package/dist/index.js +166 -166
- package/dist/index.mjs +166 -166
- package/dist/infrastructure/script/script-executor.d.ts +8 -0
- package/dist/infrastructure/test-suite/interfaces.d.ts +5 -1
- package/dist/infrastructure/test-suite/test-suite-service.d.ts +8 -0
- package/dist/infrastructure/test-suite/test-suite-store.d.ts +64 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,15 +13,14 @@
|
|
|
13
13
|
- 🚀 **Postman Collections** - Load and execute `.postman_collection.json` and `.forge.json` files
|
|
14
14
|
- 📝 **JavaScript Scripting** - Pre-request and post-response scripts with full `pm.*` API (variables, assertions, execution flow, visualizer)
|
|
15
15
|
- 🔄 **Dynamic Variables** - Built-in generators: `{{$randomInt}}`, `{{$timestamp}}`, `{{$uuid}}`, `{{$guid}}`, etc.
|
|
16
|
-
- 🌍 **Environments** - Full variable scoping (globals, collection, environment, iterationData)
|
|
16
|
+
- 🌍 **Environments** - Full variable scoping (globals, collection, environment, session, iterationData)
|
|
17
17
|
- 👁️ **File Watching** - Automatic reload on collection/environment file changes with notification callbacks
|
|
18
18
|
- 🍪 **Cookie Persistence** - Automatic cookie storage and reuse, `pm.cookies.jar()` and `.toObject()`
|
|
19
19
|
- 📊 **Test Assertions** - BDD-style testing with `pm.test()` (sync/async) and full Chai `expect()` chains
|
|
20
20
|
- 🔐 **CryptoJS** - Full crypto library: hash, HMAC, AES/DES/TripleDES, PBKDF2, encoding helpers
|
|
21
21
|
- 🎯 **Execution Flow** - `pm.setNextRequest()`, `pm.execution.skipRequest()` for suite runner flow control
|
|
22
22
|
- 📈 **Visualizer** - `pm.visualizer.set(template, data)` for custom Handlebars-based HTML output
|
|
23
|
-
-
|
|
24
|
-
- �🔌 **Extensible** - Custom interceptors, HTTP clients, and module loaders
|
|
23
|
+
- 🔌 **Extensible** - Custom interceptors, HTTP clients, and module loaders
|
|
25
24
|
|
|
26
25
|
**Ideal for:**
|
|
27
26
|
- CI/CD pipeline integration (GitHub Actions, GitLab CI, Jenkins)
|
|
@@ -79,25 +78,6 @@ forge.setEnvironment({
|
|
|
79
78
|
const result = await forge.execute(request, collection);
|
|
80
79
|
```
|
|
81
80
|
|
|
82
|
-
### URL Path Parameters
|
|
83
|
-
|
|
84
|
-
If your request URL uses Express-style route parameters, provide values using the request `params` field.
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
const request = {
|
|
88
|
-
name: 'Redirect Test',
|
|
89
|
-
method: 'GET',
|
|
90
|
-
url: '{{baseUrl}}/redirect/:redirectNumber',
|
|
91
|
-
params: {
|
|
92
|
-
redirectNumber: '3'
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
const result = await forge.execute(request, collection);
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
The engine will substitute `:redirectNumber` before execution, while still resolving environment variables and dynamic template expressions.
|
|
100
|
-
|
|
101
81
|
### With Custom Configuration
|
|
102
82
|
|
|
103
83
|
```typescript
|
|
@@ -237,6 +217,14 @@ const data = pm.response.json();
|
|
|
237
217
|
pm.environment.set('userId', data.id);
|
|
238
218
|
pm.environment.set('authToken', data.token);
|
|
239
219
|
|
|
220
|
+
// Store non-string values (auto-serialized)
|
|
221
|
+
pm.environment.set('userList', data.users); // Array → JSON string
|
|
222
|
+
pm.environment.set('config', { retries: 3 }); // Object → JSON string
|
|
223
|
+
|
|
224
|
+
// get() auto-deserializes back
|
|
225
|
+
const users = pm.environment.get('userList'); // → Array
|
|
226
|
+
const config = pm.environment.get('config'); // → Object
|
|
227
|
+
|
|
240
228
|
// Store cookies from response
|
|
241
229
|
if (pm.response.headers.has('Set-Cookie')) {
|
|
242
230
|
pm.cookies.set('authCookie', data.authCookie);
|
|
@@ -380,47 +368,6 @@ const entries = history.getAll(); // All requests
|
|
|
380
368
|
const byId = history.getByRequestId(id); // Specific request history
|
|
381
369
|
```
|
|
382
370
|
|
|
383
|
-
### 🛡️ Sensitive Data Redaction
|
|
384
|
-
|
|
385
|
-
History and result files automatically redact sensitive data before writing to disk. This prevents tokens, passwords, and credentials from being persisted in plaintext.
|
|
386
|
-
|
|
387
|
-
```typescript
|
|
388
|
-
import {
|
|
389
|
-
redactHeaders, redactUrl, redactBody,
|
|
390
|
-
redactHistoryEntry, redactFullResponse, redactFullResultDetails
|
|
391
|
-
} from '@http-forge/core';
|
|
392
|
-
|
|
393
|
-
// Redact sensitive headers
|
|
394
|
-
redactHeaders({ 'Authorization': 'Bearer eyJ...', 'Content-Type': 'application/json' });
|
|
395
|
-
// → { 'Authorization': '***', 'Content-Type': 'application/json' }
|
|
396
|
-
|
|
397
|
-
// Any header containing 'token', 'cookie', 'secret' is redacted
|
|
398
|
-
redactHeaders({ 'avs-token': 'abc123', 'telus-access-token-cookie': 'xyz' });
|
|
399
|
-
// → { 'avs-token': '***', 'telus-access-token-cookie': '***' }
|
|
400
|
-
|
|
401
|
-
// Redact sensitive URL query params
|
|
402
|
-
redactUrl('https://api.example.com/auth?client_secret=abc&scope=read');
|
|
403
|
-
// → 'https://api.example.com/auth?client_secret=***&scope=read'
|
|
404
|
-
|
|
405
|
-
// Redact sensitive JSON body fields (recursive)
|
|
406
|
-
redactBody({ user: 'admin', password: 'hunter2', data: { api_token: 'xyz' } });
|
|
407
|
-
// → { user: 'admin', password: '***', data: { api_token: '***' } }
|
|
408
|
-
|
|
409
|
-
// Redact URL-encoded form bodies
|
|
410
|
-
redactBody('username=admin&password=secret&grant_type=password');
|
|
411
|
-
// → 'username=admin&password=***&grant_type=***'
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
**Auto-detected patterns:**
|
|
415
|
-
- **Headers**: `authorization`, `proxy-authorization`, `www-authenticate`, and any header containing `token`, `cookie`, `secret`, `credential`, `api-key`, `bearer`, `session-id`
|
|
416
|
-
- **Fields/Params**: Any name containing `password`, `passwd`, `pwd`, `token`, `cookie`, `secret`, `credential`, `api_key`, `access_token`, `refresh_token`, `client_secret`, `private_key`, `auth_code`, `bearer`, `session_id`, `jwt`
|
|
417
|
-
|
|
418
|
-
**Integration points:**
|
|
419
|
-
- `RequestHistoryService.addEntry()` — redacts `sentRequest` (headers, body, URL) before saving
|
|
420
|
-
- `RequestHistoryService.saveFullResponse()` — redacts response headers and cookies
|
|
421
|
-
- `ResultStorageService.saveResult()` — redacts request/response headers and body in suite results
|
|
422
|
-
- `originalConfig` (unresolved `{{variable}}` templates) is never redacted — only resolved values
|
|
423
|
-
|
|
424
371
|
## 📖 API Reference
|
|
425
372
|
|
|
426
373
|
### ForgeContainer
|
|
@@ -528,23 +475,14 @@ interface KeyValueEntry {
|
|
|
528
475
|
format?: string; // Semantic hint (e.g. "uuid", "date-time")
|
|
529
476
|
enum?: string[]; // Allowed values
|
|
530
477
|
deprecated?: boolean;
|
|
531
|
-
// Extended constraint fields for full OpenAPI
|
|
532
|
-
// String constraints
|
|
478
|
+
// Extended constraint fields for full OpenAPI round-trip
|
|
533
479
|
pattern?: string; // Regex validation pattern
|
|
534
|
-
minLength?: number;
|
|
535
|
-
maxLength?: number;
|
|
536
|
-
// Numeric constraints (integer / number)
|
|
537
480
|
minimum?: number;
|
|
538
481
|
maximum?: number;
|
|
539
|
-
exclusiveMinimum?:
|
|
540
|
-
exclusiveMaximum?:
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
minItems?: number;
|
|
544
|
-
maxItems?: number;
|
|
545
|
-
uniqueItems?: boolean;
|
|
546
|
-
// Common
|
|
547
|
-
nullable?: boolean;
|
|
482
|
+
exclusiveMinimum?: number;
|
|
483
|
+
exclusiveMaximum?: number;
|
|
484
|
+
minLength?: number;
|
|
485
|
+
maxLength?: number;
|
|
548
486
|
oneOf?: Array<Record<string, any>>; // Merged constraint variants
|
|
549
487
|
}
|
|
550
488
|
```
|
|
@@ -561,22 +499,13 @@ interface PathParamEntry {
|
|
|
561
499
|
format?: string;
|
|
562
500
|
enum?: string[];
|
|
563
501
|
deprecated?: boolean;
|
|
564
|
-
// String constraints
|
|
565
502
|
pattern?: string;
|
|
566
|
-
minLength?: number;
|
|
567
|
-
maxLength?: number;
|
|
568
|
-
// Numeric constraints
|
|
569
503
|
minimum?: number;
|
|
570
504
|
maximum?: number;
|
|
571
|
-
exclusiveMinimum?:
|
|
572
|
-
exclusiveMaximum?:
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
minItems?: number;
|
|
576
|
-
maxItems?: number;
|
|
577
|
-
uniqueItems?: boolean;
|
|
578
|
-
// Common
|
|
579
|
-
nullable?: boolean;
|
|
505
|
+
exclusiveMinimum?: number;
|
|
506
|
+
exclusiveMaximum?: number;
|
|
507
|
+
minLength?: number;
|
|
508
|
+
maxLength?: number;
|
|
580
509
|
oneOf?: Array<Record<string, any>>;
|
|
581
510
|
}
|
|
582
511
|
```
|
|
@@ -587,20 +516,15 @@ The core library includes full OpenAPI 3.0.3 import and export with constraint p
|
|
|
587
516
|
|
|
588
517
|
**Import** (`OpenApiImporter`):
|
|
589
518
|
- Parses OpenAPI 3.0 YAML/JSON specs into `UnifiedCollection`
|
|
590
|
-
- Extracts all parameter schema constraints
|
|
519
|
+
- Extracts all parameter schema constraints (`pattern`, `minimum`, `maximum`, `exclusiveMinimum`, `exclusiveMaximum`, `minLength`, `maxLength`, `enum`, `format`)
|
|
591
520
|
- Preserves `oneOf` schemas from merged parameters, deriving combined enum hints for UI display
|
|
592
|
-
- Sets `hasMetadata` flag when any constraint or description field is present
|
|
593
521
|
|
|
594
522
|
**Export** (`OpenApiExporter`):
|
|
595
523
|
- Generates OpenAPI 3.0.3 specs from collections
|
|
596
|
-
-
|
|
597
|
-
- **Collision-aware merging** via `mergeParameterSchema()`: When multiple requests normalize to the same path + HTTP method, they are merged into a single operation:
|
|
524
|
+
- **Collision-aware merging**: When multiple requests normalize to the same path + HTTP method, they are merged into a single operation:
|
|
598
525
|
- Descriptions are appended, tags are unioned
|
|
599
|
-
- **
|
|
600
|
-
-
|
|
601
|
-
- **Both simple, same constraint kind** (both enum, both pattern, etc.) → merged in-place (union enum values, widen numeric ranges, alternation-join patterns)
|
|
602
|
-
- **Both simple, different constraint kinds** → wrapped in `oneOf` — each variant keeps its self-consistent schema
|
|
603
|
-
- `stripConstraints()` called after **all** merge branches to prevent stale fields (e.g. `enum`) leaking alongside `oneOf`
|
|
526
|
+
- Parameters with the **same constraint kind** (both enum, both pattern, etc.) are merged in-place (union enum values, widen numeric ranges, alternation-join patterns)
|
|
527
|
+
- Parameters with **different constraint kinds** are wrapped in `oneOf` — each variant keeps its self-consistent schema
|
|
604
528
|
- All constraint fields round-trip without data loss
|
|
605
529
|
|
|
606
530
|
## 🛠️ Use Cases
|
|
@@ -795,23 +719,6 @@ MIT © Henry Huang
|
|
|
795
719
|
|
|
796
720
|
## 📝 Changelog
|
|
797
721
|
|
|
798
|
-
### 0.2.7 (Session Scope Removal & Postman Parity)
|
|
799
|
-
|
|
800
|
-
- ✅ **Session scope removed** — The separate "session" variable scope has been removed. `pm.environment.set()` now persists to workspace state (matching Postman's behavior). Variable resolution uses a Postman-compatible 5-scope cascade: `variables > iterationData > environmentVariables > collectionVariables > globals`.
|
|
801
|
-
- ✅ **Request preparer extraVariables fix** — All request resolutions (params, query, headers, bearer auth, basic auth, API key) now use `extraVariables`. Previously only body and URL used them.
|
|
802
|
-
- ✅ **Exported `ResolvedEnvironment` type** — Now part of the public API for downstream consumers.
|
|
803
|
-
|
|
804
|
-
### 0.2.6 (Sensitive Data Redaction & Variable Propagation Fix)
|
|
805
|
-
|
|
806
|
-
- ✅ **Sensitive data redaction** — History files, shared history, suite test results, and full response files automatically redact sensitive data before persisting to disk:
|
|
807
|
-
- Headers matching `authorization`, `proxy-authorization`, or containing `token`, `cookie`, `secret`, `credential`, `api-key`, `bearer`, `session-id`
|
|
808
|
-
- URL query params and JSON/form body fields matching `password`, `token`, `secret`, `api_key`, `client_secret`, `private_key`, `auth_code`, `jwt`, etc.
|
|
809
|
-
- Response `Set-Cookie` headers and cookies with sensitive names
|
|
810
|
-
- Unresolved `{{variable}}` templates in `originalConfig` are preserved — only resolved values redacted
|
|
811
|
-
- Exported functions: `redactHeaders()`, `redactUrl()`, `redactBody()`, `redactHistoryEntry()`, `redactFullResponse()`, `redactFullResultDetails()`
|
|
812
|
-
- ✅ **Fixed `pm.environment.set()` propagation** — Post-response script `pm.environment.set()` now correctly propagates to `{{variable}}` resolution in subsequent collection runner requests. The session now uses live scope references instead of a disconnected snapshot.
|
|
813
|
-
- ✅ **Cookie jar flush in collection runner** — `flush()` is now called in the `finally` block ensuring script-set cookies persist to the shared session store after a run completes.
|
|
814
|
-
|
|
815
722
|
### 0.2.5 (OpenAPI Constraint Round-Trip & Collision Merging)
|
|
816
723
|
|
|
817
724
|
- ✅ **Full parameter constraint round-trip** — OpenAPI import/export now preserves all schema constraint fields: `pattern`, `minimum`, `maximum`, `exclusiveMinimum`, `exclusiveMaximum`, `minLength`, `maxLength`, and `oneOf` on both `KeyValueEntry` and `PathParamEntry`
|
|
@@ -850,7 +757,7 @@ MIT © Henry Huang
|
|
|
850
757
|
- ✅ **Core request execution** with Postman collection support
|
|
851
758
|
- ✅ **Dynamic variables** - 7 generators for on-the-fly value generation
|
|
852
759
|
- ✅ **Postman-compatible scripting** - `pm.*` API with full feature parity
|
|
853
|
-
- ✅ **Variable scoping** - globals, collection, environment,
|
|
760
|
+
- ✅ **Variable scoping** - globals, collection, environment, session, flow-level
|
|
854
761
|
- ✅ **Cookie persistence** - automatic storage and reuse across request chains
|
|
855
762
|
- ✅ **Pre-request & post-response scripts** with shared VM context
|
|
856
763
|
- ✅ **Test assertions** with BDD-style `pm.test()` and expect chains
|