@http-forge/core 0.2.0 → 0.2.1

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.
Files changed (38) hide show
  1. package/README.md +25 -4
  2. package/dist/auth/oauth2-token-manager.d.ts +1 -1
  3. package/dist/collection/collection-loader-factory.d.ts +1 -1
  4. package/dist/collection/collection-service.d.ts +2 -2
  5. package/dist/collection/collection-store.d.ts +1 -1
  6. package/dist/collection/folder-collection-loader.d.ts +17 -228
  7. package/dist/collection/folder-collection-store.d.ts +8 -1
  8. package/dist/collection/folder-io.d.ts +113 -0
  9. package/dist/container.d.ts +13 -14
  10. package/dist/cookie/cookie-service.d.ts +1 -1
  11. package/dist/cookie/in-memory-cookie-jar.d.ts +1 -1
  12. package/dist/cookie/persistent-cookie-jar.d.ts +1 -1
  13. package/dist/di/core-bootstrap.d.ts +25 -0
  14. package/dist/di/index.d.ts +11 -0
  15. package/dist/di/platform-adapters.d.ts +53 -0
  16. package/dist/di/service-container.d.ts +97 -0
  17. package/dist/di/service-identifiers.d.ts +34 -0
  18. package/dist/environment/environment-config-service.d.ts +6 -3
  19. package/dist/environment/environment-file-loader.d.ts +42 -0
  20. package/dist/environment/forge-env.d.ts +1 -1
  21. package/dist/execution/collection-request-executor.d.ts +3 -3
  22. package/dist/execution/request-executor.d.ts +3 -3
  23. package/dist/execution/request-preparer.d.ts +3 -3
  24. package/dist/history/request-history.d.ts +1 -1
  25. package/dist/http/http-request-service.d.ts +2 -2
  26. package/dist/import-export/import-postman-environment.d.ts +1 -1
  27. package/dist/index.d.ts +25 -19
  28. package/dist/index.js +187 -187
  29. package/dist/index.mjs +187 -187
  30. package/dist/openapi/interfaces.d.ts +2 -2
  31. package/dist/script/interfaces.d.ts +12 -0
  32. package/dist/script/request-script-session.d.ts +3 -0
  33. package/dist/script/script-executor.d.ts +1 -1
  34. package/dist/script/script-factories.d.ts +15 -4
  35. package/dist/script/script-utils.d.ts +2 -1
  36. package/dist/test-suite/result-storage-service.d.ts +1 -1
  37. package/dist/types/types.d.ts +7 -0
  38. package/package.json +2 -2
package/README.md CHANGED
@@ -11,11 +11,14 @@
11
11
 
12
12
  **Core Features:**
13
13
  - 🚀 **Postman Collections** - Load and execute `.postman_collection.json` and `.forge.json` files
14
- - 📝 **JavaScript Scripting** - Pre-request and post-response scripts with `pm.*` API (events, variables, assertions)
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, session, flow-level)
17
- - 🍪 **Cookie Persistence** - Automatic cookie storage and reuse across request sequences
18
- - 📊 **Test Assertions** - BDD-style testing with `pm.test()` and `expect()` chains
16
+ - 🌍 **Environments** - Full variable scoping (globals, collection, environment, session, iterationData)
17
+ - 🍪 **Cookie Persistence** - Automatic cookie storage and reuse, `pm.cookies.jar()` and `.toObject()`
18
+ - 📊 **Test Assertions** - BDD-style testing with `pm.test()` (sync/async) and full Chai `expect()` chains
19
+ - 🔐 **CryptoJS** - Full crypto library: hash, HMAC, AES/DES/TripleDES, PBKDF2, encoding helpers
20
+ - 🎯 **Execution Flow** - `pm.setNextRequest()`, `pm.execution.skipRequest()` for suite runner flow control
21
+ - 📈 **Visualizer** - `pm.visualizer.set(template, data)` for custom Handlebars-based HTML output
19
22
  - 🔌 **Extensible** - Custom interceptors, HTTP clients, and module loaders
20
23
 
21
24
  **Ideal for:**
@@ -634,6 +637,24 @@ MIT © Henry Huang
634
637
 
635
638
  ## 📝 Changelog
636
639
 
640
+ ### 0.2.0 (Postman API Parity)
641
+
642
+ - ✅ **Async `pm.test()` support** - Tests with async callbacks are properly awaited
643
+ - ✅ **Expect chain assertions** - `.a(type)`, `.an(type)`, `.deep.equal()`, `.lengthOf()`, `.exist`, `.members()`, `.keys()`, `.string()`
644
+ - ✅ **`pm.iterationData`** scope - Data-driven testing with iteration variables
645
+ - ✅ **Response status getters** - `response.to.be.ok`, `.error`, `.clientError`, `.serverError` work as getters and functions
646
+ - ✅ **Response headers HeaderList** - `.get()`, `.has()`, `.toObject()`, `.each()` on `pm.response.headers`
647
+ - ✅ **`pm.cookies.toObject()`** - Flat `{name: value}` cookie map
648
+ - ✅ **`replaceIn()` on all scopes** - Available on `pm.variables`, `pm.environment`, `pm.collectionVariables`, `pm.globals`
649
+ - ✅ **Sandbox globals** - `xml2Json()`, `jsonStringify()`, `jsonParse()` available in scripts
650
+ - ✅ **Request headers API** - `.toObject()`, `.each()` on `pm.request.headers`
651
+ - ✅ **`pm.execution.setNextRequest()`** - Runner flow control (jump to named request or stop with `null`)
652
+ - ✅ **`pm.execution.skipRequest()`** - Skip HTTP call from pre-request scripts
653
+ - ✅ **`pm.setNextRequest()`** - Top-level alias for flow control
654
+ - ✅ **`pm.visualizer.set(template, data)`** - Custom HTML visualization with Handlebars templates
655
+ - ✅ **`pm.request.url` as Url object** - Postman SDK-compatible Url with `getHost()`, `getPath()`, `getQueryString()`, `protocol`, `host`, `port`, `path`, `query`, `hash`
656
+ - ✅ **Full CryptoJS** - AES/DES/TripleDES encrypt/decrypt, PBKDF2, all hash algorithms (SHA1/256/384/512/SHA3/MD5/RIPEMD160), HMAC, encoding helpers (Hex/Base64/Utf8/Latin1/Utf16)
657
+
637
658
  ### 0.1.0 (Initial Release)
638
659
 
639
660
  - ✅ **Core request execution** with Postman collection support
@@ -15,9 +15,9 @@
15
15
  */
16
16
  import { IEnvironmentConfigService } from '../environment/interfaces';
17
17
  import { IHttpRequestService } from '../http/interfaces';
18
- import { IOAuth2TokenManager, TokenCacheKey, TokenInfo } from './interfaces';
19
18
  import { IExternalBrowserService, ISecretStore } from '../types/platform';
20
19
  import { OAuth2Config } from '../types/types';
20
+ import { IOAuth2TokenManager, TokenCacheKey, TokenInfo } from './interfaces';
21
21
  export declare class OAuth2TokenManager implements IOAuth2TokenManager {
22
22
  private readonly secretStore;
23
23
  private readonly browserService;
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * Factory Pattern: Creates appropriate loader based on configuration
5
5
  */
6
- import { ICollectionStore } from './collection-store';
7
6
  import { IConfigService } from '../config';
7
+ import { ICollectionStore } from './collection-store';
8
8
  /**
9
9
  * Factory for creating collection loaders
10
10
  */
@@ -8,9 +8,9 @@
8
8
  * - ConfigService for configuration
9
9
  * - CollectionLoader for storage abstraction (supports folder and json formats)
10
10
  */
11
- import { Collection, CollectionItem, CollectionRequestItem, CreateRequestOptions, ICollectionService } from './collection-service-interfaces';
12
- import { IFileWatcherFactory } from '../types/platform';
13
11
  import { IConfigService } from '../config';
12
+ import { IFileWatcherFactory } from '../types/platform';
13
+ import { Collection, CollectionItem, CollectionRequestItem, CreateRequestOptions, ICollectionService } from './collection-service-interfaces';
14
14
  /**
15
15
  * Service for managing HTTP Forge collections
16
16
  */
@@ -6,8 +6,8 @@
6
6
  * - JsonCollectionLoader: Loads from single JSON files
7
7
  * - FolderCollectionStore: Loads from directory structure
8
8
  */
9
- import type { Collection, CollectionItem, RequestScripts } from './collection-service-interfaces';
10
9
  import type { CollectionRequest } from '../types/types';
10
+ import type { Collection, CollectionItem, RequestScripts } from './collection-service-interfaces';
11
11
  /**
12
12
  * Rich interface for loading, saving, and managing collections
13
13
  */
@@ -1,256 +1,45 @@
1
1
  /**
2
2
  * Folder Collection Loader
3
3
  *
4
- * Loads collections from directory structure (folder format)
5
- * Each collection is a folder containing:
6
- * - collection.json (metadata)
7
- * - scripts/ (pre-request.js, post-response.js)
8
- * - {folder-slug}/ (subfolders with folder.json)
9
- * - {request-slug}/ (request folders with request.json)
4
+ * Thin adapter around FolderCollectionStore that converts between the
5
+ * `Collection` / `CollectionItem` types (array-based headers/query with
6
+ * `enabled` flag) and the simpler `UnifiedCollection` / `UnifiedRequest`
7
+ * types (Record-based headers/query) used by ForgeContainer.
10
8
  *
11
- * This is a port of the VS Code extension's FolderCollectionLoader
9
+ * All disk I/O is delegated to FolderCollectionStore this class only
10
+ * performs type conversion on the way in and out.
12
11
  */
13
- import type { CollectionScripts, RequestBody, UnifiedCollection, UnifiedFolder, UnifiedRequest } from '../types/types';
12
+ import type { CollectionScripts, UnifiedCollection, UnifiedFolder, UnifiedRequest } from '../types/types';
13
+ import type { CollectionMetadata } from './collection-store';
14
14
  import type { ICollectionLoader } from './interfaces';
15
- /**
16
- * Collection metadata structure
17
- */
18
- interface CollectionMetadata {
19
- id: string;
20
- name: string;
21
- description?: string;
22
- version?: string;
23
- variables?: Record<string, string>;
24
- auth?: any;
25
- order?: string[];
26
- }
27
- /**
28
- * Scripts structure
29
- */
30
- interface Scripts {
31
- preRequest?: string;
32
- postResponse?: string;
33
- }
34
- /**
35
- * Collection item (folder or request)
36
- */
37
- type CollectionItem = UnifiedFolder | UnifiedRequest;
15
+ export { generateSlug } from './folder-io';
16
+ type UnifiedItem = UnifiedFolder | UnifiedRequest;
38
17
  /**
39
18
  * Folder Collection Loader
40
19
  *
41
- * Loads collections from folder structure:
42
- * collections/
43
- * {collection-slug}/
44
- * collection.json
45
- * scripts/
46
- * pre-request.js
47
- * post-response.js
48
- * {folder-slug}/
49
- * folder.json
50
- * scripts/
51
- * {request-slug}/
52
- * request.json
53
- * scripts/
54
- * {request-slug}/
55
- * request.json
56
- * scripts/
20
+ * Implements `ICollectionLoader` and exposes CRUD using `UnifiedCollection` /
21
+ * `UnifiedRequest` types. All disk I/O is handled by the underlying
22
+ * `FolderCollectionStore`; this class converts types on the boundary.
57
23
  */
58
24
  export declare class FolderCollectionLoader implements ICollectionLoader {
59
- protected collectionsDir: string;
60
- protected cache: Map<string, UnifiedCollection>;
61
- protected slugToIdMap: Map<string, string>;
62
- protected idToSlugMap: Map<string, string>;
25
+ /** The underlying canonical store that handles all disk I/O */
26
+ private readonly store;
63
27
  constructor(collectionsDir: string);
64
- /**
65
- * Ensure collections directory exists
66
- */
67
- protected ensureDirectory(): void;
68
- /**
69
- * Load all collections from disk
70
- */
71
28
  loadAll(): UnifiedCollection[];
72
- /**
73
- * Get collection slug from ID
74
- */
75
29
  getSlugById(id: string): string | undefined;
76
- /**
77
- * Get collection ID from slug
78
- */
79
30
  getIdBySlug(slug: string): string | undefined;
80
- /**
81
- * Load a collection from a folder
82
- */
83
- protected loadCollectionFromFolder(slug: string): UnifiedCollection | undefined;
84
- /**
85
- * Load items from a directory
86
- * @param dirPath - Directory path to load items from
87
- * @param parentId - Parent ID for tracking
88
- * @param order - Optional order array (slugs) to sort items
89
- */
90
- protected loadItemsFromDir(dirPath: string, parentId: string, order?: string[]): CollectionItem[];
91
- /**
92
- * Load a folder from directory
93
- */
94
- protected loadFolderFromDir(folderPath: string, slug: string): UnifiedFolder | undefined;
95
- /**
96
- * Load a request from directory
97
- */
98
- protected loadRequestFromDir(requestPath: string, slug: string): UnifiedRequest | undefined;
99
- /**
100
- * Convert array of { key, value, enabled } to Record<string, string>
101
- * Also handles Record format (pass-through)
102
- * Only includes enabled items (or all if enabled is undefined)
103
- */
104
- protected arrayToRecord(arr?: Array<{
105
- key: string;
106
- value: string;
107
- enabled?: boolean;
108
- }> | Record<string, string>): Record<string, string>;
109
- /**
110
- * Load scripts from a scripts directory
111
- */
112
- protected loadScriptsFromDir(scriptsPath: string): Scripts | undefined;
113
- /**
114
- * Load body from external file if present
115
- * Supports: body.json, body.xml, body.txt, body.html, body.js, body.graphql
116
- */
117
- protected loadBodyFromDir(requestPath: string): RequestBody | undefined;
118
- /**
119
- * Load a JSON schema file if it exists.
120
- * Returns the parsed object or undefined.
121
- */
122
- protected loadSchemaFile(filePath: string): any | undefined;
123
- /**
124
- * Load a single collection by ID.
125
- * Checks the in-memory cache first, then falls back to slug-map → loadAll().
126
- */
127
31
  load(id: string): UnifiedCollection | undefined;
128
- /**
129
- * Create a new empty collection and persist it to disk.
130
- */
131
32
  create(name: string, id?: string): Promise<UnifiedCollection>;
132
- /**
133
- * Save (create or update) an entire collection to disk.
134
- */
135
33
  save(collection: UnifiedCollection): Promise<void>;
136
- /**
137
- * Delete a collection by ID (removes directory from disk).
138
- */
139
34
  delete(id: string): Promise<boolean>;
140
- /**
141
- * Check if a collection exists on disk.
142
- */
143
35
  exists(id: string): boolean;
144
- /**
145
- * Get the filesystem path for a collection.
146
- */
147
36
  getCollectionPath(id: string): string;
148
- /**
149
- * Update collection-level metadata (name, description, variables, etc.)
150
- * without rewriting every item.
151
- */
152
37
  updateCollectionMetadata(collectionId: string, updates: Partial<CollectionMetadata>): Promise<void>;
153
- /**
154
- * Save (create or update) a single item within a collection.
155
- * @param collectionId - The owning collection
156
- * @param item - Folder or request to save
157
- * @param parentId - Optional parent folder (omit for root-level)
158
- */
159
- saveItem(collectionId: string, item: CollectionItem, parentId?: string): Promise<void>;
160
- /**
161
- * Update a single item's metadata in-place.
162
- */
163
- updateItem(collectionId: string, itemId: string, updates: Partial<CollectionItem>): Promise<boolean>;
164
- /**
165
- * Delete a single item (and its directory) from a collection.
166
- */
38
+ saveItem(collectionId: string, item: UnifiedItem, parentId?: string): Promise<void>;
39
+ updateItem(collectionId: string, itemId: string, updates: Partial<UnifiedItem>): Promise<boolean>;
167
40
  deleteItem(collectionId: string, itemId: string): Promise<boolean>;
168
- /**
169
- * Move an item to a different parent within the same collection.
170
- * @param newParentId - Target folder ID, or `undefined` for collection root
171
- */
172
41
  moveItem(collectionId: string, itemId: string, newParentId?: string): Promise<boolean>;
173
- /**
174
- * Reorder items within a parent (folder or collection root).
175
- * Writes an `order` array into the parent's metadata file.
176
- */
177
42
  reorderItems(collectionId: string, parentId: string | undefined, orderedItemIds: string[]): Promise<boolean>;
178
- /**
179
- * Save scripts for a specific item (collection, folder, or request).
180
- */
181
43
  saveScripts(collectionId: string, itemId: string, scripts: CollectionScripts): Promise<void>;
182
- /**
183
- * Load scripts for a specific item by ID.
184
- */
185
44
  loadScripts(collectionId: string, itemId: string): CollectionScripts | undefined;
186
- /**
187
- * Persist a list of items to a parent directory.
188
- */
189
- protected saveItemsToDir(parentPath: string, items: CollectionItem[]): Promise<void>;
190
- /**
191
- * Persist a folder's metadata, scripts, and nested items.
192
- */
193
- protected saveFolderToDir(folderPath: string, folder: UnifiedFolder): Promise<void>;
194
- /**
195
- * Persist a request's metadata, body files, schema files, and scripts.
196
- */
197
- protected saveRequestToDir(requestPath: string, request: UnifiedRequest): Promise<void>;
198
- /**
199
- * Write scripts to a scripts/ directory.
200
- */
201
- protected saveScriptsToDir(scriptsPath: string, scripts: CollectionScripts): Promise<void>;
202
- /**
203
- * Separate body content into metadata-inline vs. external-file parts.
204
- */
205
- protected prepareBodyForSave(body: RequestBody | undefined): {
206
- bodyForMetadata: any;
207
- externalBodyFile?: {
208
- filename: string;
209
- content: string;
210
- };
211
- };
212
- /**
213
- * Remove stale body files that don't match the current format.
214
- */
215
- protected cleanupOldBodyFiles(requestPath: string, currentBodyFile?: string): Promise<void>;
216
- /**
217
- * Save OpenAPI schema files (response.schema.json, body.schema.json).
218
- */
219
- protected saveSchemaFiles(requestPath: string, request: UnifiedRequest): Promise<void>;
220
- /**
221
- * Convert Record<string, string> to the array format used in metadata files.
222
- */
223
- protected recordToArray(record?: Record<string, string>): Array<{
224
- key: string;
225
- value: string;
226
- enabled: boolean;
227
- }> | undefined;
228
- /**
229
- * Resolve a filesystem path for an item within a collection.
230
- */
231
- protected findItemPath(collectionId: string, itemId: string): string | undefined;
232
- /**
233
- * Recursively search for a directory named `targetSlug` under `basePath`.
234
- */
235
- protected searchForItemPath(basePath: string, targetSlug: string): string | undefined;
236
- /**
237
- * Find an item by ID in the in-memory tree (recursive).
238
- */
239
- protected findItemById(items: CollectionItem[], id: string): CollectionItem | undefined;
240
- /**
241
- * Remove an item from the in-memory tree by ID (mutates the array).
242
- */
243
- protected deleteItemFromTree(items: CollectionItem[], id: string): boolean;
244
- /**
245
- * Re-sort items to match an ordered list of IDs.
246
- * Items not in `orderedIds` are appended at the end.
247
- */
248
- protected sortItemsByOrder(items: CollectionItem[], orderedIds: string[]): CollectionItem[];
249
45
  }
250
- /**
251
- * Generate a slug from a name
252
- * Handles HTTP method prefixes, version indicators (T7, 1.5), path parameters,
253
- * and deduplication with counter suffixes.
254
- */
255
- export declare function generateSlug(name: string, existingSlugs?: string[]): string;
256
- export {};
@@ -37,6 +37,14 @@ export declare class FolderCollectionStore implements ICollectionStore {
37
37
  private slugToIdMap;
38
38
  private idToSlugMap;
39
39
  constructor(collectionsDir: string);
40
+ /**
41
+ * Get collection/item slug from ID
42
+ */
43
+ getSlugById(id: string): string | undefined;
44
+ /**
45
+ * Get collection/item ID from slug
46
+ */
47
+ getIdBySlug(slug: string): string | undefined;
40
48
  /**
41
49
  * Ensure collections directory exists
42
50
  */
@@ -162,7 +170,6 @@ export declare class FolderCollectionStore implements ICollectionStore {
162
170
  */
163
171
  private sortItemsByOrder;
164
172
  private findItemPath;
165
- private searchForItemPath;
166
173
  private findItemById;
167
174
  private deleteItemFromTree;
168
175
  }
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Folder Format I/O Primitives
3
+ *
4
+ * Shared file I/O operations for the folder-based collection storage format.
5
+ * Used by both FolderCollectionLoader (read-only, UnifiedCollection types)
6
+ * and FolderCollectionStore (full CRUD, Collection types).
7
+ *
8
+ * Eliminates ~200 lines of duplicated code between the two implementations.
9
+ */
10
+ import type { RequestBody } from '../types/types';
11
+ /** Script file names within a scripts/ directory */
12
+ export declare const SCRIPT_FILES: {
13
+ preRequest: string;
14
+ postResponse: string;
15
+ };
16
+ /** Metadata file names that identify item types */
17
+ export declare const METADATA_FILES: {
18
+ collection: string;
19
+ folder: string;
20
+ request: string;
21
+ };
22
+ /**
23
+ * Body file extensions mapped to body type/format.
24
+ * Files stored externally get syntax highlighting benefits.
25
+ * Other types (form-data, urlencoded, binary, none) stay in request.json.
26
+ */
27
+ export declare const BODY_FILE_MAP: Record<string, {
28
+ type: 'raw' | 'graphql';
29
+ format?: 'json' | 'text' | 'xml' | 'html' | 'javascript';
30
+ }>;
31
+ /** Schema files stored alongside request.json for OpenAPI round-trip support */
32
+ export declare const SCHEMA_FILES: {
33
+ responseSchema: string;
34
+ bodySchema: string;
35
+ };
36
+ /** Scripts directory name */
37
+ export declare const SCRIPTS_DIR = "scripts";
38
+ /**
39
+ * Scripts structure (shared shape between CollectionScripts and RequestScripts)
40
+ */
41
+ export interface ScriptsData {
42
+ preRequest?: string;
43
+ postResponse?: string;
44
+ }
45
+ /**
46
+ * Read scripts from a scripts/ directory.
47
+ * Returns undefined if the directory doesn't exist or has no scripts.
48
+ */
49
+ export declare function readScriptsFromDir(scriptsPath: string): ScriptsData | undefined;
50
+ /**
51
+ * Write scripts to a scripts/ directory.
52
+ */
53
+ export declare function writeScriptsToDir(scriptsPath: string, scripts: ScriptsData): Promise<void>;
54
+ /**
55
+ * Load body from external file if present.
56
+ * Supports: body.json, body.xml, body.txt, body.html, body.js, body.graphql
57
+ */
58
+ export declare function readBodyFromDir(requestPath: string): RequestBody | undefined;
59
+ /**
60
+ * Separate body content into metadata-inline vs. external-file parts.
61
+ */
62
+ export declare function prepareBodyForSave(body: any): {
63
+ bodyForMetadata: any;
64
+ externalBodyFile?: {
65
+ filename: string;
66
+ content: string;
67
+ };
68
+ };
69
+ /**
70
+ * Remove stale body files that don't match the current format.
71
+ */
72
+ export declare function cleanupOldBodyFiles(requestPath: string, currentBodyFile?: string): Promise<void>;
73
+ /**
74
+ * Load a JSON schema file if it exists.
75
+ * Returns the parsed object or undefined.
76
+ */
77
+ export declare function readSchemaFile(filePath: string): any | undefined;
78
+ /**
79
+ * Save OpenAPI schema files (response.schema.json, body.schema.json).
80
+ */
81
+ export declare function writeSchemaFiles(requestPath: string, responseSchema?: any, bodySchema?: any): Promise<void>;
82
+ /** Minimal interface for tree traversal — both UnifiedFolder/UnifiedRequest and CollectionItem satisfy this */
83
+ interface TreeNode {
84
+ id: string;
85
+ type: string;
86
+ items?: TreeNode[];
87
+ }
88
+ /**
89
+ * Find an item by ID in a tree (recursive).
90
+ */
91
+ export declare function findItemById<T extends TreeNode>(items: T[], id: string): T | undefined;
92
+ /**
93
+ * Remove an item from a tree by ID (mutates the array).
94
+ */
95
+ export declare function deleteItemFromTree<T extends TreeNode>(items: T[], id: string): boolean;
96
+ /**
97
+ * Re-sort items to match an ordered list of IDs.
98
+ * Items not in orderedIds are appended at the end.
99
+ */
100
+ export declare function sortItemsByOrder<T extends {
101
+ id: string;
102
+ }>(items: T[], orderedIds: string[]): T[];
103
+ /**
104
+ * Recursively search for a directory named targetSlug under basePath.
105
+ */
106
+ export declare function searchForItemPath(basePath: string, targetSlug: string): string | undefined;
107
+ /**
108
+ * Generate a slug from a name.
109
+ * Handles HTTP method prefixes, version indicators (T7, 1.5), path parameters,
110
+ * and deduplication with counter suffixes.
111
+ */
112
+ export declare function generateSlug(name: string, existingSlugs?: string[]): string;
113
+ export {};
@@ -4,20 +4,20 @@
4
4
  * Single Responsibility: Wire up all components with proper dependencies
5
5
  * Factory Pattern: Creates configured instances of services
6
6
  */
7
+ import { ICollectionLoader } from './collection/interfaces';
8
+ import { ParserRegistry } from './collection/parser-registry';
7
9
  import { ICookieService } from './cookie/interfaces';
8
- import { IDataFileParser } from './platform/data-file-parser';
10
+ import { EnvironmentResolver, EnvironmentStoreConfig } from './environment/environment-resolver';
11
+ import { ForgeEnv } from './environment/forge-env';
12
+ import { IVariableInterpolator } from './environment/interfaces';
13
+ import { RequestExecutor } from './execution/request-executor';
14
+ import { IRequestHistory } from './history/history-interfaces';
9
15
  import { IErrorInterceptor, IInterceptorChain, IRequestInterceptor, IResponseInterceptor } from './http/interceptor-chain';
10
16
  import { IRequestPreprocessor } from './http/request-preprocessor';
11
- import { IFileSystem, IHttpClient } from './types/platform';
12
- import { ICollectionLoader } from './collection/interfaces';
13
- import { IRequestHistory } from './history/history-interfaces';
17
+ import { IDataFileParser } from './platform/data-file-parser';
14
18
  import { IScriptExecutor } from './script/interfaces';
15
- import { IVariableInterpolator } from './environment/interfaces';
19
+ import { IFileSystem, IHttpClient } from './types/platform';
16
20
  import { HttpRequest, HttpResponse, RequestSettings, UnifiedCollection, UnifiedRequest } from './types/types';
17
- import { EnvironmentResolver, EnvironmentStoreConfig } from './environment/environment-resolver';
18
- import { ForgeEnv } from './environment/forge-env';
19
- import { ParserRegistry } from './collection/parser-registry';
20
- import { RequestExecutor } from './execution/request-executor';
21
21
  /**
22
22
  * Container configuration options
23
23
  */
@@ -135,18 +135,17 @@ export declare class ForgeContainer {
135
135
  /**
136
136
  * Create a container by auto-loading environments from forgeRoot
137
137
  *
138
- * Reads `{forgeRoot}/environments/environments.json` and creates
139
- * a container with the environment configuration pre-loaded.
138
+ * Reads the multi-file environment folder format under
139
+ * `{forgeRoot}/environments/` (same format used by the VS Code extension).
140
+ * Falls back to the legacy single-file `environments.json` when the
141
+ * multi-file format is not detected.
140
142
  *
141
143
  * @param forgeRoot - Path to http-forge folder (default: './http-forge')
142
144
  * @param options - Additional container options
143
145
  *
144
146
  * @example
145
147
  * ```typescript
146
- * // Auto-load environments from ./http-forge/environments/environments.json
147
148
  * const forge = ForgeContainer.fromForgeRoot('./http-forge');
148
- *
149
- * // Switch environment
150
149
  * forge.forgeEnv.setActiveEnvironment('sit');
151
150
  * ```
152
151
  */
@@ -5,8 +5,8 @@
5
5
  * Platform-agnostic — uses IKeyValueStore for persistence
6
6
  * instead of VS Code globalState.
7
7
  */
8
- import { Cookie, ICookieParser, ICookieReader } from './interfaces';
9
8
  import { IKeyValueStore } from '../types/platform';
9
+ import { Cookie, ICookieParser, ICookieReader } from './interfaces';
10
10
  /**
11
11
  * Full cookie service interface (async write operations for platform persistence)
12
12
  */
@@ -8,8 +8,8 @@
8
8
  * For persistent cookie handling (across requests in a session), use
9
9
  * PersistentCookieJar which wraps an ICookieService backend.
10
10
  */
11
- import type { Cookie } from './interfaces';
12
11
  import type { ICookieJar } from '../script/interfaces';
12
+ import type { Cookie } from './interfaces';
13
13
  export declare class InMemoryCookieJar implements ICookieJar {
14
14
  private cookies;
15
15
  /**
@@ -9,8 +9,8 @@
9
9
  *
10
10
  * Extracted from extension's request-execution/PersistentCookieJar.ts.
11
11
  */
12
- import { Cookie, IAsyncCookieService, ICookieService } from './interfaces';
13
12
  import { ICookieJar } from '../script/interfaces';
13
+ import { Cookie, IAsyncCookieService, ICookieService } from './interfaces';
14
14
  export declare class PersistentCookieJar implements ICookieJar {
15
15
  private cookieService;
16
16
  /** Local cache that reflects script modifications */
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Core Service Bootstrap
3
+ *
4
+ * Registers all platform-agnostic services in the ServiceContainer.
5
+ * The host environment (VS Code, CLI, etc.) only needs to provide
6
+ * PlatformAdapters — the actual service wiring lives here.
7
+ *
8
+ * This is the single source of truth for service dependencies.
9
+ */
10
+ import type { PlatformAdapters } from './platform-adapters';
11
+ import type { ServiceContainer } from './service-container';
12
+ /**
13
+ * Register all platform-agnostic core services in the container.
14
+ *
15
+ * @param container - The service container to register into
16
+ * @param adapters - Platform-specific adapters provided by the host
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const container = ServiceContainer.instance;
21
+ * container.clear();
22
+ * registerCoreServices(container, adapters);
23
+ * ```
24
+ */
25
+ export declare function registerCoreServices(container: ServiceContainer, adapters: PlatformAdapters): void;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Dependency Injection
3
+ *
4
+ * Provides a generic, platform-agnostic DI container and service bootstrap.
5
+ * Host environments (VS Code, CLI, etc.) only need to supply PlatformAdapters.
6
+ */
7
+ export { registerCoreServices } from './core-bootstrap';
8
+ export type { PlatformAdapters } from './platform-adapters';
9
+ export { getServiceContainer, ServiceContainer } from './service-container';
10
+ export { ServiceIdentifiers } from './service-identifiers';
11
+ export type { ServiceIdentifier } from './service-identifiers';