@http-forge/core 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/README.md +194 -41
  2. package/dist/auth/interfaces.d.ts +63 -0
  3. package/dist/auth/oauth2-token-manager.d.ts +103 -0
  4. package/dist/collection/collection-loader-factory.d.ts +20 -0
  5. package/dist/{services → collection}/collection-loader.d.ts +3 -3
  6. package/dist/collection/collection-service-interfaces.d.ts +119 -0
  7. package/dist/collection/collection-service.d.ts +75 -0
  8. package/dist/collection/collection-store.d.ts +109 -0
  9. package/dist/collection/folder-collection-loader.d.ts +256 -0
  10. package/dist/collection/folder-collection-store.d.ts +168 -0
  11. package/dist/collection/interfaces.d.ts +32 -0
  12. package/dist/collection/json-collection-loader.d.ts +95 -0
  13. package/dist/{services → collection}/parser-registry.d.ts +1 -2
  14. package/dist/config/config-service.d.ts +79 -0
  15. package/dist/config/config.interface.d.ts +140 -0
  16. package/dist/config/default-config.d.ts +29 -0
  17. package/dist/config/index.d.ts +6 -0
  18. package/dist/container.d.ts +22 -14
  19. package/dist/{implementations → cookie}/cookie-jar.d.ts +2 -3
  20. package/dist/cookie/cookie-service.d.ts +98 -0
  21. package/dist/{implementations → cookie}/cookie-utils.d.ts +1 -2
  22. package/dist/cookie/in-memory-cookie-jar.d.ts +44 -0
  23. package/dist/{interfaces/cookie.d.ts → cookie/interfaces.d.ts} +22 -3
  24. package/dist/cookie/persistent-cookie-jar.d.ts +35 -0
  25. package/dist/environment/environment-config-service.d.ts +95 -0
  26. package/dist/{services → environment}/environment-resolver.d.ts +6 -5
  27. package/dist/{services → environment}/forge-env.d.ts +1 -2
  28. package/dist/environment/interfaces.d.ts +139 -0
  29. package/dist/environment/variable-interpolator.d.ts +100 -0
  30. package/dist/execution/collection-request-executor-interfaces.d.ts +36 -0
  31. package/dist/execution/collection-request-executor.d.ts +78 -0
  32. package/dist/{services → execution}/request-executor.d.ts +23 -11
  33. package/dist/execution/request-preparer-interfaces.d.ts +36 -0
  34. package/dist/execution/request-preparer.d.ts +35 -0
  35. package/dist/graphql/graphql-completion-provider.d.ts +39 -0
  36. package/dist/graphql/graphql-schema-service.d.ts +89 -0
  37. package/dist/{interfaces/history.d.ts → history/history-interfaces.d.ts} +29 -6
  38. package/dist/history/request-history-service-interfaces.d.ts +43 -0
  39. package/dist/history/request-history-service.d.ts +133 -0
  40. package/dist/{implementations → history}/request-history.d.ts +2 -3
  41. package/dist/{implementations → http}/fetch-http-client.d.ts +4 -5
  42. package/dist/http/http-request-service.d.ts +36 -0
  43. package/dist/{implementations → http}/interceptor-chain.d.ts +1 -2
  44. package/dist/http/interfaces.d.ts +25 -0
  45. package/dist/http/merge-request-settings.d.ts +12 -0
  46. package/dist/{implementations → http}/native-http-client.d.ts +6 -15
  47. package/dist/{implementations → http}/request-preprocessor.d.ts +1 -2
  48. package/dist/{services → http}/url-builder.d.ts +7 -10
  49. package/dist/import-export/import-postman-environment.d.ts +21 -0
  50. package/dist/import-export/rest-client-export.d.ts +35 -0
  51. package/dist/index.d.ts +88 -6
  52. package/dist/index.js +262 -35
  53. package/dist/index.mjs +262 -35
  54. package/dist/openapi/example-generator.d.ts +26 -0
  55. package/dist/openapi/history-analyzer.d.ts +29 -0
  56. package/dist/openapi/index.d.ts +16 -0
  57. package/dist/openapi/interfaces.d.ts +42 -0
  58. package/dist/openapi/openapi-exporter.d.ts +73 -0
  59. package/dist/openapi/openapi-importer.d.ts +72 -0
  60. package/dist/openapi/ref-resolver.d.ts +28 -0
  61. package/dist/openapi/schema-inference-service.d.ts +40 -0
  62. package/dist/openapi/schema-inferrer.d.ts +26 -0
  63. package/dist/openapi/script-analyzer.d.ts +41 -0
  64. package/dist/parsers/http-forge-parser.d.ts +2 -3
  65. package/dist/parsers/index.d.ts +0 -1
  66. package/dist/{implementations → platform}/data-file-parser.d.ts +0 -1
  67. package/dist/{implementations → platform}/node-file-system.d.ts +1 -2
  68. package/dist/script/interfaces.d.ts +149 -0
  69. package/dist/script/module-loader.d.ts +115 -0
  70. package/dist/script/request-script-session.d.ts +70 -0
  71. package/dist/script/script-executor.d.ts +60 -0
  72. package/dist/script/script-factories.d.ts +83 -0
  73. package/dist/script/script-utils.d.ts +41 -0
  74. package/dist/test-suite/index.d.ts +10 -0
  75. package/dist/test-suite/interfaces.d.ts +164 -0
  76. package/dist/test-suite/result-storage-service.d.ts +70 -0
  77. package/dist/test-suite/result-storage.d.ts +296 -0
  78. package/dist/test-suite/statistics-service.d.ts +51 -0
  79. package/dist/test-suite/test-suite-service.d.ts +97 -0
  80. package/dist/test-suite/test-suite-store.d.ts +155 -0
  81. package/dist/types/console-service.d.ts +40 -0
  82. package/dist/types/platform.d.ts +206 -0
  83. package/dist/{interfaces → types}/types.d.ts +282 -12
  84. package/dist/utils/dynamic-variables.d.ts +38 -0
  85. package/dist/utils/expression-evaluator.d.ts +34 -0
  86. package/dist/utils/filter-engine.d.ts +47 -0
  87. package/dist/utils/helpers.d.ts +47 -0
  88. package/package.json +11 -3
  89. package/dist/container.d.ts.map +0 -1
  90. package/dist/implementations/cookie-jar.d.ts.map +0 -1
  91. package/dist/implementations/cookie-utils.d.ts.map +0 -1
  92. package/dist/implementations/data-file-parser.d.ts.map +0 -1
  93. package/dist/implementations/fetch-http-client.d.ts.map +0 -1
  94. package/dist/implementations/index.d.ts +0 -22
  95. package/dist/implementations/index.d.ts.map +0 -1
  96. package/dist/implementations/interceptor-chain.d.ts.map +0 -1
  97. package/dist/implementations/module-loader.d.ts +0 -74
  98. package/dist/implementations/module-loader.d.ts.map +0 -1
  99. package/dist/implementations/native-http-client.d.ts.map +0 -1
  100. package/dist/implementations/node-file-system.d.ts.map +0 -1
  101. package/dist/implementations/request-history.d.ts.map +0 -1
  102. package/dist/implementations/request-preprocessor.d.ts.map +0 -1
  103. package/dist/implementations/variable-interpolator.d.ts +0 -55
  104. package/dist/implementations/variable-interpolator.d.ts.map +0 -1
  105. package/dist/implementations/vm2-script-runner.d.ts +0 -76
  106. package/dist/implementations/vm2-script-runner.d.ts.map +0 -1
  107. package/dist/index.d.ts.map +0 -1
  108. package/dist/interfaces/cookie.d.ts.map +0 -1
  109. package/dist/interfaces/history.d.ts.map +0 -1
  110. package/dist/interfaces/index.d.ts +0 -170
  111. package/dist/interfaces/index.d.ts.map +0 -1
  112. package/dist/interfaces/types.d.ts.map +0 -1
  113. package/dist/parsers/http-forge-parser.d.ts.map +0 -1
  114. package/dist/parsers/index.d.ts.map +0 -1
  115. package/dist/services/collection-loader.d.ts.map +0 -1
  116. package/dist/services/environment-resolver.d.ts.map +0 -1
  117. package/dist/services/folder-collection-loader.d.ts +0 -91
  118. package/dist/services/folder-collection-loader.d.ts.map +0 -1
  119. package/dist/services/forge-env.d.ts.map +0 -1
  120. package/dist/services/index.d.ts +0 -20
  121. package/dist/services/index.d.ts.map +0 -1
  122. package/dist/services/parser-registry.d.ts.map +0 -1
  123. package/dist/services/request-executor.d.ts.map +0 -1
  124. package/dist/services/script-pipeline.d.ts +0 -43
  125. package/dist/services/script-pipeline.d.ts.map +0 -1
  126. package/dist/services/script-session.d.ts +0 -66
  127. package/dist/services/script-session.d.ts.map +0 -1
  128. package/dist/services/url-builder.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,26 +1,29 @@
1
1
  # @http-forge/core
2
2
 
3
- **Lightweight, VS Code-independent HTTP API testing engine** - The execution core of HTTP Forge.
3
+ **Standalone HTTP testing engine with Postman collection support and JavaScript-based automation.**
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@http-forge/core.svg)](https://www.npmjs.com/package/@http-forge/core)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
 
8
8
  ## 📦 What is @http-forge/core?
9
9
 
10
- `@http-forge/core` is a standalone, dependency-injection-based HTTP execution engine that powers HTTP Forge. It provides a clean API for:
10
+ `@http-forge/core` is a headless, framework-agnostic HTTP execution engine with **full Postman collection compatibility**. Execute complex API workflows, test suites, and automated flows without the overhead of a UI.
11
11
 
12
- - 🚀 Executing HTTP requests with full HTTP Forge collection support
13
- - 🔄 Running pre-request and post-response scripts
14
- - 🌍 Managing environments and variables
15
- - 🍪 Automatic cookie handling
16
- - 📊 Test assertions and validations
17
- - 🔌 Extensible via interceptors and custom implementations
12
+ **Core Features:**
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)
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
19
+ - 🔌 **Extensible** - Custom interceptors, HTTP clients, and module loaders
18
20
 
19
- **Perfect for:**
20
- - Building custom API testing tools
21
- - Integrating HTTP Forge into CI/CD pipelines
22
- - Creating CLI tools for API testing
23
- - Headless API testing automation
21
+ **Ideal for:**
22
+ - CI/CD pipeline integration (GitHub Actions, GitLab CI, Jenkins)
23
+ - Headless API testing and contract validation
24
+ - Building custom API testing CLIs
25
+ - Load testing and performance monitoring
26
+ - Automated integration test suites
24
27
 
25
28
  ## 🎯 Installation
26
29
 
@@ -141,29 +144,79 @@ console.log(result.preRequestResult); // Pre-request script output
141
144
  console.log(result.postResponseResult); // Test results
142
145
  ```
143
146
 
147
+ ### Dynamic Variables
148
+
149
+ Automatic variable generation within request templates:
150
+
151
+ ```javascript
152
+ // URL with dynamic timestamp
153
+ https://api.example.com/events?timestamp={{$timestamp}}
154
+
155
+ // Headers with unique ID
156
+ X-Request-ID: {{$uuid}}
157
+
158
+ // Query parameters with random value
159
+ ?page=1&seed={{$randomInt:1:100}}
160
+ ```
161
+
162
+ **Supported dynamic variables:**
163
+ - `{{$randomInt}}` - Random integer (0-2147483647)
164
+ - `{{$randomInt:min:max}}` - Random integer in range
165
+ - `{{$timestamp}}` - Current Unix timestamp (seconds)
166
+ - `{{$uuid}}` - UUID v4
167
+ - `{{$guid}}` - GUID (alias for uuid)
168
+ - `{{$randomString}}` - 10-char alphanumeric string
169
+ - `{{$randomHexadecimal}}` - Random hex string
170
+ - `{{$isoTimestamp}}` - ISO 8601 timestamp
171
+
144
172
  ### Script Execution
145
173
 
146
- Run pre-request and post-response scripts:
174
+ Run pre-request and post-response scripts with full Postman API compatibility:
147
175
 
148
- **Pre-request script:**
176
+ **Pre-request script - Set variables & modify request:**
149
177
  ```javascript
150
- // Set variables before request
151
- forge.env.set('timestamp', Date.now());
152
- forge.env.set('requestId', forge.uuid());
178
+ // Set variables across scopes
179
+ pm.variables.set('requestId', pm.variables.randomUUID());
180
+ pm.environment.set('token', 'abc-123');
181
+ pm.collectionVariables.set('counter', '1');
182
+
183
+ // Modify request headers
184
+ pm.request.headers.add({
185
+ name: 'X-Request-ID',
186
+ value: pm.variables.get('requestId')
187
+ });
188
+ pm.request.headers.update({
189
+ name: 'Authorization',
190
+ value: 'Bearer ' + pm.environment.get('token')
191
+ });
192
+
193
+ // Modify URL and body
194
+ pm.request.url = 'https://api.example.com' + pm.request.url;
195
+ pm.request.body.raw = JSON.stringify({ timestamp: Date.now() });
153
196
 
154
- // Modify request
155
- forge.request.headers['X-Request-ID'] = forge.env.get('requestId');
197
+ // Set cookies for next request
198
+ pm.cookies.set('sessionId', 'sess_abc123');
156
199
  ```
157
200
 
158
- **Post-response script:**
201
+ **Post-response script - Test & extract data:**
159
202
  ```javascript
160
- // Run tests
161
- forge.expect(forge.response.status).toBe(200);
162
- forge.expect(forge.response.body.success).toBeTruthy();
203
+ // Run assertions
204
+ pm.test('Status is 200', () => {
205
+ pm.expect(pm.response.code).to.equal(200);
206
+ });
207
+ pm.test('Response time under 1s', () => {
208
+ pm.expect(pm.response.responseTime).to.be.below(1000);
209
+ });
210
+
211
+ // Extract data for next request
212
+ const data = pm.response.json();
213
+ pm.environment.set('userId', data.id);
214
+ pm.environment.set('authToken', data.token);
163
215
 
164
- // Extract data from response
165
- const token = forge.response.body.token;
166
- forge.env.set('authToken', token);
216
+ // Store cookies from response
217
+ if (pm.response.headers.has('Set-Cookie')) {
218
+ pm.cookies.set('authCookie', data.authCookie);
219
+ }
167
220
  ```
168
221
 
169
222
  ### Environment Management
@@ -240,21 +293,49 @@ const forge = new ForgeContainer({
240
293
  });
241
294
  ```
242
295
 
243
- ### Cookie Management
296
+ ### Cookie Management & Persistence
244
297
 
245
- Automatic cookie handling across requests:
298
+ Automatic cookie storage and reuse across multi-request flows:
246
299
 
247
300
  ```typescript
248
301
  const forge = new ForgeContainer({
249
- enableCookies: true
302
+ enableCookies: true // Cookies persist across requests in session
250
303
  });
251
304
 
252
- // Cookies are automatically stored and sent
305
+ // Login - response sets Session-ID cookie
253
306
  const loginResult = await forge.execute(loginRequest, collection);
254
- // Session cookie from login is automatically included in next request
307
+
308
+ // Subsequent requests automatically include Session-ID
309
+ // No need to manually extract and re-add cookies
255
310
  const dataResult = await forge.execute(dataRequest, collection);
311
+ const updateResult = await forge.execute(updateRequest, collection);
256
312
  ```
257
313
 
314
+ **Access cookies in scripts:**
315
+ ```javascript
316
+ // Pre-request script - read stored cookies
317
+ if (pm.cookies.has('sessionId')) {
318
+ const sid = pm.cookies.get('sessionId');
319
+ pm.request.headers.add({
320
+ name: 'Cookie',
321
+ value: 'sessionId=' + sid
322
+ });
323
+ }
324
+
325
+ // Post-response script - store new cookies
326
+ pm.response.cookies.forEach(cookie => {
327
+ pm.cookies.set(cookie.name, cookie.value);
328
+ });
329
+
330
+ // List all active cookies
331
+ const allCookies = pm.cookies.list(); // [{name, value}, ...]
332
+
333
+ // Clear cookies
334
+ pm.cookies.clear(); // When switching users/sessions
335
+ ```
336
+
337
+ Cookies are automatically extracted from `Set-Cookie` response headers and reused in subsequent `Cookie` request headers.
338
+
258
339
  ### Request History
259
340
 
260
341
  Track all executed requests:
@@ -450,6 +531,72 @@ class ApiTestRunner {
450
531
  }
451
532
  ```
452
533
 
534
+ ### Multi-Request Workflows
535
+
536
+ Execute dependent request chains with automatic cookie and variable management:
537
+
538
+ ```typescript
539
+ import { ForgeContainer } from '@http-forge/core';
540
+
541
+ async function apiAuthWorkflow() {
542
+ const forge = new ForgeContainer({
543
+ enableCookies: true, // Cookies persist across requests
544
+ enableHistory: true
545
+ });
546
+
547
+ // Request 1: Login (sets session cookie)
548
+ const loginReq = {
549
+ name: 'Login',
550
+ method: 'POST',
551
+ url: 'https://api.example.com/auth/login',
552
+ body: { type: 'raw', content: JSON.stringify({
553
+ username: '{{email}}',
554
+ password: '{{password}}'
555
+ })},
556
+ scripts: {
557
+ postResponse: `
558
+ const { token, userId } = pm.response.json();
559
+ pm.environment.set('authToken', token);
560
+ pm.environment.set('userId', userId);
561
+ `
562
+ }
563
+ };
564
+
565
+ const loginResult = await forge.execute(loginReq, collection);
566
+ console.log('✓ Logged in, token:', forge.getResolvedEnvironment()['authToken']);
567
+
568
+ // Request 2: Fetch user profile (uses session cookie automatically)
569
+ const profileReq = {
570
+ name: 'Get Profile',
571
+ method: 'GET',
572
+ url: 'https://api.example.com/users/{{userId}}',
573
+ headers: {
574
+ 'Authorization': 'Bearer {{authToken}}' // Uses token from login
575
+ }
576
+ };
577
+
578
+ const profileResult = await forge.execute(profileReq, collection);
579
+ console.log('✓ Profile:', profileResult.response.body);
580
+
581
+ // Request 3: Update profile (session cookie still active)
582
+ const updateReq = {
583
+ name: 'Update Profile',
584
+ method: 'PATCH',
585
+ url: 'https://api.example.com/users/{{userId}}',
586
+ headers: {
587
+ 'Authorization': 'Bearer {{authToken}}'
588
+ },
589
+ body: { type: 'raw', content: JSON.stringify({ status: 'active' })}
590
+ };
591
+
592
+ const updateResult = await forge.execute(updateReq, collection);
593
+ console.log('✓ Updated profile');
594
+
595
+ // Session automatically logged out - cookies cleared
596
+ forge.getRequestHistory().clear();
597
+ }
598
+ ```
599
+
453
600
  ## 📦 Storage Formats
454
601
 
455
602
  ### File Format (Single JSON)
@@ -489,12 +636,18 @@ MIT © Henry Huang
489
636
 
490
637
  ### 0.1.0 (Initial Release)
491
638
 
492
- - ✅ Core request execution engine
493
- - ✅ Environment and variable management
494
- - ✅ Pre-request and post-response scripts
495
- - ✅ Cookie jar support
496
- - ✅ Request/response interceptors
497
- - ✅ Request history tracking
498
- - ✅ File and folder collection formats
499
- - ✅ Full TypeScript support
500
- - ✅ Comprehensive test coverage
639
+ - ✅ **Core request execution** with Postman collection support
640
+ - ✅ **Dynamic variables** - 7 generators for on-the-fly value generation
641
+ - ✅ **Postman-compatible scripting** - `pm.*` API with full feature parity
642
+ - ✅ **Variable scoping** - globals, collection, environment, session, flow-level
643
+ - ✅ **Cookie persistence** - automatic storage and reuse across request chains
644
+ - ✅ **Pre-request & post-response scripts** with shared VM context
645
+ - ✅ **Test assertions** with BDD-style `pm.test()` and expect chains
646
+ - ✅ **Environment management** with variable substitution
647
+ - ✅ **Cookie jar** with domain-aware matching
648
+ - ✅ **Request/response interceptors** for customization
649
+ - ✅ **Request history** tracking
650
+ - ✅ **File and folder collection formats** (Postman-compatible)
651
+ - ✅ **Full TypeScript support** with comprehensive types
652
+ - ✅ **Dependency injection** for extensibility
653
+ - ✅ **Comprehensive test coverage**
@@ -0,0 +1,63 @@
1
+ /**
2
+ * OAuth2 Token Manager Interface
3
+ *
4
+ * Platform-independent interface for OAuth2 token management.
5
+ * Handles all grant types: client_credentials, password, authorization_code, implicit.
6
+ *
7
+ * VS Code impl: uses vscode.env.openExternal, vscode.SecretStorage
8
+ * CLI/Standalone impl: uses system browser + local HTTP callback server
9
+ * Browser impl: uses window.open() + postMessage
10
+ */
11
+ import { OAuth2Config } from '../types/types';
12
+ export interface TokenInfo {
13
+ accessToken: string;
14
+ /** e.g. "Bearer" */
15
+ tokenType: string;
16
+ /** Unix timestamp (ms) */
17
+ expiresAt?: number;
18
+ refreshToken?: string;
19
+ scope?: string;
20
+ /** Original token response */
21
+ raw: Record<string, unknown>;
22
+ }
23
+ export interface TokenCacheKey {
24
+ tokenUrl: string;
25
+ clientId: string;
26
+ scope?: string;
27
+ grantType: string;
28
+ }
29
+ export interface IOAuth2TokenManager {
30
+ /**
31
+ * Get a valid access token for the given OAuth2 configuration.
32
+ * May return a cached token, refresh an expired token, or initiate a new flow.
33
+ */
34
+ getToken(config: OAuth2Config, environment: string): Promise<TokenInfo>;
35
+ /**
36
+ * Refresh an expired token using the refresh token.
37
+ */
38
+ refreshToken(config: OAuth2Config, currentRefreshToken: string, environment: string): Promise<TokenInfo>;
39
+ /**
40
+ * Initiate the authorization code flow (opens browser, waits for callback).
41
+ */
42
+ authorizationCodeFlow(config: OAuth2Config, environment: string): Promise<TokenInfo>;
43
+ /**
44
+ * Initiate the implicit flow (opens browser, waits for callback).
45
+ */
46
+ implicitFlow(config: OAuth2Config, environment: string): Promise<TokenInfo>;
47
+ /**
48
+ * Clear a cached token.
49
+ */
50
+ clearToken(cacheKey: TokenCacheKey): void;
51
+ /**
52
+ * Clear all cached tokens.
53
+ */
54
+ clearAllTokens(): void;
55
+ /**
56
+ * Handle authorization code callback (from browser redirect).
57
+ */
58
+ handleAuthorizationCallback(code: string | undefined, state: string | undefined, error?: string): void;
59
+ /**
60
+ * Handle implicit flow callback (from browser redirect with token in fragment).
61
+ */
62
+ handleImplicitCallback(accessToken: string, tokenType: string | undefined, expiresIn: number | undefined, state: string | undefined): void;
63
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * OAuth2 Token Manager
3
+ *
4
+ * Platform-independent implementation of OAuth2 token lifecycle management:
5
+ * - Token caching with expiration
6
+ * - PKCE (S256 / plain) challenge generation
7
+ * - Authorization Code flow via system browser + URI handler callback
8
+ * - Implicit flow via system browser
9
+ * - Client Credentials and Password grant token fetching
10
+ * - Token refresh with automatic retry
11
+ * - Secure storage for refresh tokens via ISecretStore
12
+ *
13
+ * Platform-specific behaviour (browser opening, secret storage, callback URIs)
14
+ * is injected via IExternalBrowserService and ISecretStore interfaces.
15
+ */
16
+ import { IEnvironmentConfigService } from '../environment/interfaces';
17
+ import { IHttpRequestService } from '../http/interfaces';
18
+ import { IOAuth2TokenManager, TokenCacheKey, TokenInfo } from './interfaces';
19
+ import { IExternalBrowserService, ISecretStore } from '../types/platform';
20
+ import { OAuth2Config } from '../types/types';
21
+ export declare class OAuth2TokenManager implements IOAuth2TokenManager {
22
+ private readonly secretStore;
23
+ private readonly browserService;
24
+ private readonly envConfigService;
25
+ private readonly httpService;
26
+ private readonly callbackPath;
27
+ private tokenCache;
28
+ /**
29
+ * Pending authorization-code resolve/reject.
30
+ * Set when we launch the browser; resolved when the URI handler fires.
31
+ */
32
+ private pendingAuthCallback;
33
+ /**
34
+ * Pending implicit-flow resolve/reject.
35
+ */
36
+ private pendingImplicitCallback;
37
+ /**
38
+ * @param secretStore Secure storage for refresh tokens (wraps vscode.SecretStorage, keytar, etc.)
39
+ * @param browserService External browser interaction (wraps vscode.env.openExternal, etc.)
40
+ * @param envConfigService Environment variable resolution
41
+ * @param httpService HTTP client for token endpoint calls
42
+ * @param callbackPath Platform-specific callback path (e.g. "henry-huang.http-forge/oauth2/callback")
43
+ */
44
+ constructor(secretStore: ISecretStore, browserService: IExternalBrowserService, envConfigService: IEnvironmentConfigService, httpService: IHttpRequestService, callbackPath?: string);
45
+ /**
46
+ * Get a valid token — uses cache, refresh, or full re-auth as needed.
47
+ */
48
+ getToken(config: OAuth2Config, environment: string): Promise<TokenInfo>;
49
+ /**
50
+ * Refresh an existing token.
51
+ */
52
+ refreshToken(config: OAuth2Config, currentRefreshToken: string, environment: string): Promise<TokenInfo>;
53
+ /**
54
+ * Authorization Code + PKCE flow.
55
+ *
56
+ * 1. Generate code_verifier & code_challenge (S256)
57
+ * 2. Open system browser with authorize URL
58
+ * 3. Wait for URI handler callback with ?code=xxx&state=yyy
59
+ * 4. Exchange code + code_verifier for token
60
+ */
61
+ authorizationCodeFlow(config: OAuth2Config, environment: string): Promise<TokenInfo>;
62
+ /**
63
+ * Implicit flow — opens browser, waits for hash fragment with access_token.
64
+ * Since the URI handler receives query params (not fragments), a small
65
+ * redirect page is needed to convert fragment → query. We handle both cases.
66
+ */
67
+ implicitFlow(config: OAuth2Config, environment: string): Promise<TokenInfo>;
68
+ /**
69
+ * Called by the URI handler when browser redirects back.
70
+ * Handles both authorization_code (?code=) and implicit (?access_token=) callbacks.
71
+ */
72
+ handleAuthorizationCallback(code: string | undefined, state: string | undefined, error?: string): void;
73
+ /**
74
+ * Handle implicit callback with access_token directly.
75
+ */
76
+ handleImplicitCallback(accessToken: string, tokenType: string | undefined, expiresIn: number | undefined, state: string | undefined): void;
77
+ clearToken(cacheKey: TokenCacheKey): void;
78
+ clearAllTokens(): void;
79
+ /**
80
+ * Fetch token using client_credentials or password grant.
81
+ */
82
+ private fetchToken;
83
+ /**
84
+ * Apply client authentication to the request (body or Basic Auth header).
85
+ */
86
+ private applyClientAuth;
87
+ /**
88
+ * Parse token endpoint response body into TokenInfo.
89
+ */
90
+ private parseTokenResponse;
91
+ private isExpired;
92
+ private buildCacheKeyString;
93
+ /**
94
+ * Get the callback URI for OAuth2 redirects.
95
+ * Uses the browser service to create a valid, externally accessible callback URI.
96
+ */
97
+ private getCallbackUri;
98
+ /** Resolve environment variables in a string */
99
+ private resolve;
100
+ private generateCodeVerifier;
101
+ private generateCodeChallengeS256;
102
+ private storeRefreshToken;
103
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Collection Loader Factory
3
+ *
4
+ * Factory Pattern: Creates appropriate loader based on configuration
5
+ */
6
+ import { ICollectionStore } from './collection-store';
7
+ import { IConfigService } from '../config';
8
+ /**
9
+ * Factory for creating collection loaders
10
+ */
11
+ export declare class CollectionLoaderFactory {
12
+ /**
13
+ * Create a collection loader based on configuration
14
+ */
15
+ static create(configService: IConfigService): ICollectionStore;
16
+ /**
17
+ * Create a loader for a specific format
18
+ */
19
+ static createForFormat(format: 'folder' | 'json', collectionsPath: string): ICollectionStore;
20
+ }
@@ -4,8 +4,9 @@
4
4
  * Single Responsibility: Load collections from file system
5
5
  * Dependency Inversion: Uses IFileSystem and ParserRegistry abstractions
6
6
  */
7
- import { ICollectionLoader, IFileSystem } from '../interfaces';
8
- import { UnifiedCollection } from '../interfaces/types';
7
+ import { IFileSystem } from '../types/platform';
8
+ import { UnifiedCollection } from '../types/types';
9
+ import { ICollectionLoader } from './interfaces';
9
10
  import { ParserRegistry } from './parser-registry';
10
11
  /**
11
12
  * Options for loading a collection
@@ -49,4 +50,3 @@ export declare class CollectionLoader implements ICollectionLoader {
49
50
  */
50
51
  getSupportedFormats(): string[];
51
52
  }
52
- //# sourceMappingURL=collection-loader.d.ts.map
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Collection Service Interface
3
+ *
4
+ * Interface Segregation: Separated into focused sub-interfaces
5
+ * Dependency Inversion: Consumers depend on this abstraction
6
+ */
7
+ import { CollectionRequest, KeyValueEntry, RequestAuth, RequestScripts, RequestSettings } from '../types/types';
8
+ export type { CollectionRequest, KeyValueEntry, RequestAuth, RequestScripts, RequestSettings };
9
+ /**
10
+ * Request item in a collection - CollectionRequest with type discriminator
11
+ */
12
+ export type CollectionRequestItem = CollectionRequest & {
13
+ type: 'request';
14
+ };
15
+ /**
16
+ * Folder item in a collection
17
+ */
18
+ export interface CollectionFolderItem {
19
+ type: 'folder';
20
+ id: string;
21
+ name: string;
22
+ description?: string;
23
+ auth?: RequestAuth;
24
+ scripts?: RequestScripts;
25
+ items?: CollectionItem[];
26
+ }
27
+ /**
28
+ * Collection item - discriminated union of request or folder
29
+ */
30
+ export type CollectionItem = CollectionRequestItem | CollectionFolderItem;
31
+ /**
32
+ * Collection definition
33
+ */
34
+ export interface Collection {
35
+ id: string;
36
+ name: string;
37
+ description?: string;
38
+ version?: string;
39
+ variables?: Record<string, string>;
40
+ auth?: RequestAuth;
41
+ scripts?: RequestScripts;
42
+ items: CollectionItem[];
43
+ }
44
+ /**
45
+ * Options for creating a request in a collection
46
+ */
47
+ export type CreateRequestOptions = Omit<CollectionRequest, 'id'> & {
48
+ collectionId: string;
49
+ parentId?: string;
50
+ id?: string;
51
+ };
52
+ /**
53
+ * Options for creating a folder
54
+ */
55
+ export interface CreateFolderOptions {
56
+ name: string;
57
+ collectionId: string;
58
+ parentId?: string;
59
+ }
60
+ /**
61
+ * Read-only collection operations
62
+ */
63
+ export interface ICollectionReader {
64
+ getAllCollections(): Collection[];
65
+ getCollection(id: string): Collection | undefined;
66
+ getCollectionById(id: string): Collection | undefined;
67
+ getCollectionByName(name: string): Collection | undefined;
68
+ findRequest(collectionId: string, requestId: string): CollectionRequestItem | undefined;
69
+ getCollectionVariables(collectionId: string): Record<string, string>;
70
+ }
71
+ /**
72
+ * Collection modification operations
73
+ */
74
+ export interface ICollectionWriter {
75
+ createCollection(name: string): Promise<Collection>;
76
+ saveCollection(collection: Collection): Promise<void>;
77
+ deleteCollection(id: string): Promise<boolean>;
78
+ renameCollection(id: string, newName: string): Promise<boolean>;
79
+ }
80
+ /**
81
+ * Request management operations
82
+ */
83
+ export interface IRequestManager {
84
+ createRequest(options: CreateRequestOptions): Promise<CollectionItem>;
85
+ updateRequest(collectionId: string, requestId: string, updates: Partial<CollectionItem>): Promise<boolean>;
86
+ deleteRequest(collectionId: string, requestId: string): Promise<boolean>;
87
+ renameRequest(collectionId: string, requestId: string, newName: string): Promise<boolean>;
88
+ }
89
+ /**
90
+ * Folder management operations
91
+ */
92
+ export interface IFolderManager {
93
+ createFolder(options: CreateFolderOptions): Promise<CollectionItem>;
94
+ deleteFolder(collectionId: string, folderId: string): Promise<boolean>;
95
+ renameFolder(collectionId: string, folderId: string, newName: string): Promise<boolean>;
96
+ }
97
+ /**
98
+ * Collection variable management
99
+ */
100
+ export interface ICollectionVariableManager {
101
+ setCollectionVariable(collectionId: string, key: string, value: unknown): void;
102
+ deleteCollectionVariable(collectionId: string, key: string): void;
103
+ clearCollectionVariables(collectionId: string): void;
104
+ getCollectionVariableLocals(collectionId: string): Record<string, string>;
105
+ }
106
+ /**
107
+ * Collection import/export operations
108
+ */
109
+ export interface ICollectionImportExport {
110
+ importCollection(filePath: string): Promise<Collection>;
111
+ exportCollection(id: string, filePath: string): Promise<void>;
112
+ exportCollectionAsRestClientFolder(id: string, outDir: string): Promise<void>;
113
+ }
114
+ /**
115
+ * Full collection service interface
116
+ */
117
+ export interface ICollectionService extends ICollectionReader, ICollectionWriter, IRequestManager, IFolderManager, ICollectionVariableManager, ICollectionImportExport {
118
+ dispose(): void;
119
+ }