@apiquest/fracture 1.0.2 → 1.0.4

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 (168) hide show
  1. package/README.md +119 -0
  2. package/bin/cli.js +2 -2
  3. package/dist/CollectionRunner.js +3 -3
  4. package/dist/ScriptEngine.js +4 -4
  5. package/dist/cli/plugin-commands.d.ts.map +1 -1
  6. package/dist/cli/plugin-commands.js +2 -1
  7. package/dist/cli/plugin-commands.js.map +1 -1
  8. package/package.json +55 -50
  9. package/src/CollectionAnalyzer.ts +102 -102
  10. package/src/CollectionRunner.ts +1423 -1423
  11. package/src/CollectionRunner.types.ts +9 -9
  12. package/src/CollectionValidator.ts +289 -289
  13. package/src/ConsoleReporter.ts +143 -143
  14. package/src/CookieJar.ts +258 -258
  15. package/src/DagScheduler.ts +439 -439
  16. package/src/Logger.ts +85 -85
  17. package/src/PluginLoader.ts +126 -126
  18. package/src/PluginManager.ts +208 -208
  19. package/src/PluginResolver.ts +154 -154
  20. package/src/QuestAPI.ts +764 -764
  21. package/src/QuestAPI.types.ts +33 -33
  22. package/src/QuestTestAPI.ts +164 -164
  23. package/src/RequestFilter.ts +224 -224
  24. package/src/ScriptEngine.ts +219 -219
  25. package/src/ScriptValidator.ts +428 -428
  26. package/src/TaskGraph.ts +598 -598
  27. package/src/TestCounter.ts +109 -109
  28. package/src/VariableResolver.ts +114 -114
  29. package/src/cli/index.ts +480 -480
  30. package/src/cli/plugin-commands.ts +342 -341
  31. package/src/cli/plugin-discovery.ts +44 -44
  32. package/src/index.ts +24 -24
  33. package/src/utils.ts +52 -52
  34. package/tsconfig.json +20 -20
  35. package/tsconfig.test.json +5 -5
  36. package/vitest.config.ts +22 -22
  37. package/dist/ExecutionTree.d.ts +0 -77
  38. package/dist/ExecutionTree.d.ts.map +0 -1
  39. package/dist/ExecutionTree.js +0 -265
  40. package/dist/ExecutionTree.js.map +0 -1
  41. package/dist/fracture/src/CollectionAnalyzer.d.ts +0 -17
  42. package/dist/fracture/src/CollectionAnalyzer.d.ts.map +0 -1
  43. package/dist/fracture/src/CollectionAnalyzer.js +0 -70
  44. package/dist/fracture/src/CollectionAnalyzer.js.map +0 -1
  45. package/dist/fracture/src/CollectionRunner.d.ts +0 -39
  46. package/dist/fracture/src/CollectionRunner.d.ts.map +0 -1
  47. package/dist/fracture/src/CollectionRunner.js +0 -802
  48. package/dist/fracture/src/CollectionRunner.js.map +0 -1
  49. package/dist/fracture/src/CollectionRunner.types.d.ts +0 -8
  50. package/dist/fracture/src/CollectionRunner.types.d.ts.map +0 -1
  51. package/dist/fracture/src/CollectionRunner.types.js +0 -2
  52. package/dist/fracture/src/CollectionRunner.types.js.map +0 -1
  53. package/dist/fracture/src/CollectionValidator.d.ts +0 -14
  54. package/dist/fracture/src/CollectionValidator.d.ts.map +0 -1
  55. package/dist/fracture/src/CollectionValidator.js +0 -145
  56. package/dist/fracture/src/CollectionValidator.js.map +0 -1
  57. package/dist/fracture/src/ConsoleReporter.d.ts +0 -24
  58. package/dist/fracture/src/ConsoleReporter.d.ts.map +0 -1
  59. package/dist/fracture/src/ConsoleReporter.js +0 -123
  60. package/dist/fracture/src/ConsoleReporter.js.map +0 -1
  61. package/dist/fracture/src/CookieJar.d.ts +0 -70
  62. package/dist/fracture/src/CookieJar.d.ts.map +0 -1
  63. package/dist/fracture/src/CookieJar.js +0 -233
  64. package/dist/fracture/src/CookieJar.js.map +0 -1
  65. package/dist/fracture/src/ExecutionTree.d.ts +0 -77
  66. package/dist/fracture/src/ExecutionTree.d.ts.map +0 -1
  67. package/dist/fracture/src/ExecutionTree.js +0 -258
  68. package/dist/fracture/src/ExecutionTree.js.map +0 -1
  69. package/dist/fracture/src/Logger.d.ts +0 -25
  70. package/dist/fracture/src/Logger.d.ts.map +0 -1
  71. package/dist/fracture/src/Logger.js +0 -78
  72. package/dist/fracture/src/Logger.js.map +0 -1
  73. package/dist/fracture/src/PluginLoader.d.ts +0 -23
  74. package/dist/fracture/src/PluginLoader.d.ts.map +0 -1
  75. package/dist/fracture/src/PluginLoader.js +0 -102
  76. package/dist/fracture/src/PluginLoader.js.map +0 -1
  77. package/dist/fracture/src/PluginManager.d.ts +0 -64
  78. package/dist/fracture/src/PluginManager.d.ts.map +0 -1
  79. package/dist/fracture/src/PluginManager.js +0 -162
  80. package/dist/fracture/src/PluginManager.js.map +0 -1
  81. package/dist/fracture/src/PluginResolver.d.ts +0 -35
  82. package/dist/fracture/src/PluginResolver.d.ts.map +0 -1
  83. package/dist/fracture/src/PluginResolver.js +0 -128
  84. package/dist/fracture/src/PluginResolver.js.map +0 -1
  85. package/dist/fracture/src/QuestAPI.d.ts +0 -9
  86. package/dist/fracture/src/QuestAPI.d.ts.map +0 -1
  87. package/dist/fracture/src/QuestAPI.js +0 -679
  88. package/dist/fracture/src/QuestAPI.js.map +0 -1
  89. package/dist/fracture/src/QuestAPI.types.d.ts +0 -35
  90. package/dist/fracture/src/QuestAPI.types.d.ts.map +0 -1
  91. package/dist/fracture/src/QuestAPI.types.js +0 -3
  92. package/dist/fracture/src/QuestAPI.types.js.map +0 -1
  93. package/dist/fracture/src/QuestTestAPI.d.ts +0 -12
  94. package/dist/fracture/src/QuestTestAPI.d.ts.map +0 -1
  95. package/dist/fracture/src/QuestTestAPI.js +0 -133
  96. package/dist/fracture/src/QuestTestAPI.js.map +0 -1
  97. package/dist/fracture/src/ScriptEngine.d.ts +0 -21
  98. package/dist/fracture/src/ScriptEngine.d.ts.map +0 -1
  99. package/dist/fracture/src/ScriptEngine.js +0 -183
  100. package/dist/fracture/src/ScriptEngine.js.map +0 -1
  101. package/dist/fracture/src/ScriptValidator.d.ts +0 -68
  102. package/dist/fracture/src/ScriptValidator.d.ts.map +0 -1
  103. package/dist/fracture/src/ScriptValidator.js +0 -351
  104. package/dist/fracture/src/ScriptValidator.js.map +0 -1
  105. package/dist/fracture/src/TestCounter.d.ts +0 -18
  106. package/dist/fracture/src/TestCounter.d.ts.map +0 -1
  107. package/dist/fracture/src/TestCounter.js +0 -82
  108. package/dist/fracture/src/TestCounter.js.map +0 -1
  109. package/dist/fracture/src/VariableResolver.d.ts +0 -20
  110. package/dist/fracture/src/VariableResolver.d.ts.map +0 -1
  111. package/dist/fracture/src/VariableResolver.js +0 -100
  112. package/dist/fracture/src/VariableResolver.js.map +0 -1
  113. package/dist/fracture/src/cli/index.d.ts +0 -3
  114. package/dist/fracture/src/cli/index.d.ts.map +0 -1
  115. package/dist/fracture/src/cli/index.js +0 -347
  116. package/dist/fracture/src/cli/index.js.map +0 -1
  117. package/dist/fracture/src/cli/plugin-commands.d.ts +0 -6
  118. package/dist/fracture/src/cli/plugin-commands.d.ts.map +0 -1
  119. package/dist/fracture/src/cli/plugin-commands.js +0 -263
  120. package/dist/fracture/src/cli/plugin-commands.js.map +0 -1
  121. package/dist/fracture/src/cli/plugin-discovery.d.ts +0 -11
  122. package/dist/fracture/src/cli/plugin-discovery.d.ts.map +0 -1
  123. package/dist/fracture/src/cli/plugin-discovery.js +0 -64
  124. package/dist/fracture/src/cli/plugin-discovery.js.map +0 -1
  125. package/dist/fracture/src/index.d.ts +0 -13
  126. package/dist/fracture/src/index.d.ts.map +0 -1
  127. package/dist/fracture/src/index.js +0 -17
  128. package/dist/fracture/src/index.js.map +0 -1
  129. package/dist/fracture/src/utils.d.ts +0 -28
  130. package/dist/fracture/src/utils.d.ts.map +0 -1
  131. package/dist/fracture/src/utils.js +0 -48
  132. package/dist/fracture/src/utils.js.map +0 -1
  133. package/dist/plugin-auth/src/apikey-auth.d.ts +0 -3
  134. package/dist/plugin-auth/src/apikey-auth.d.ts.map +0 -1
  135. package/dist/plugin-auth/src/apikey-auth.js +0 -73
  136. package/dist/plugin-auth/src/apikey-auth.js.map +0 -1
  137. package/dist/plugin-auth/src/basic-auth.d.ts +0 -3
  138. package/dist/plugin-auth/src/basic-auth.d.ts.map +0 -1
  139. package/dist/plugin-auth/src/basic-auth.js +0 -61
  140. package/dist/plugin-auth/src/basic-auth.js.map +0 -1
  141. package/dist/plugin-auth/src/bearer-auth.d.ts +0 -3
  142. package/dist/plugin-auth/src/bearer-auth.d.ts.map +0 -1
  143. package/dist/plugin-auth/src/bearer-auth.js +0 -49
  144. package/dist/plugin-auth/src/bearer-auth.js.map +0 -1
  145. package/dist/plugin-auth/src/helpers.d.ts +0 -3
  146. package/dist/plugin-auth/src/helpers.d.ts.map +0 -1
  147. package/dist/plugin-auth/src/helpers.js +0 -8
  148. package/dist/plugin-auth/src/helpers.js.map +0 -1
  149. package/dist/plugin-auth/src/index.d.ts +0 -10
  150. package/dist/plugin-auth/src/index.d.ts.map +0 -1
  151. package/dist/plugin-auth/src/index.js +0 -25
  152. package/dist/plugin-auth/src/index.js.map +0 -1
  153. package/dist/plugin-auth/src/oauth2-auth.d.ts +0 -35
  154. package/dist/plugin-auth/src/oauth2-auth.d.ts.map +0 -1
  155. package/dist/plugin-auth/src/oauth2-auth.js +0 -266
  156. package/dist/plugin-auth/src/oauth2-auth.js.map +0 -1
  157. package/dist/plugin-http/src/index.d.ts +0 -4
  158. package/dist/plugin-http/src/index.d.ts.map +0 -1
  159. package/dist/plugin-http/src/index.js +0 -266
  160. package/dist/plugin-http/src/index.js.map +0 -1
  161. package/dist/plugin-vault-file/src/index.d.ts +0 -67
  162. package/dist/plugin-vault-file/src/index.d.ts.map +0 -1
  163. package/dist/plugin-vault-file/src/index.js +0 -171
  164. package/dist/plugin-vault-file/src/index.js.map +0 -1
  165. package/dist/types.d.ts +0 -374
  166. package/dist/types.d.ts.map +0 -1
  167. package/dist/types.js +0 -13
  168. package/dist/types.js.map +0 -1
@@ -1,208 +1,208 @@
1
- import type { IProtocolPlugin, IAuthPlugin, IValueProviderPlugin, Request, ExecutionContext, ProtocolResponse, RuntimeOptions, Auth } from '@apiquest/types';
2
- import { Logger } from './Logger.js';
3
-
4
- export class PluginManager {
5
- private plugins: Map<string, IProtocolPlugin> = new Map();
6
- private authPlugins: Map<string, IAuthPlugin> = new Map();
7
- private variableProviders: Map<string, IValueProviderPlugin> = new Map();
8
- private logger: Logger;
9
-
10
- constructor(baseLogger?: Logger) {
11
- this.logger = baseLogger?.createLogger('PluginManager') ?? new Logger('PluginManager');
12
- }
13
-
14
- /**
15
- * Register a protocol plugin
16
- */
17
- registerPlugin(plugin: IProtocolPlugin): void {
18
- // Register plugin for each protocol it provides
19
- for (const protocol of plugin.protocols) {
20
- this.plugins.set(protocol, plugin);
21
- this.logger.debug(`Registered protocol plugin: ${plugin.name} for protocol '${protocol}'`);
22
- }
23
- }
24
-
25
- /**
26
- * Register an auth plugin
27
- */
28
- registerAuthPlugin(plugin: IAuthPlugin): void {
29
- // Register plugin for each auth type it provides
30
- for (const authType of plugin.authTypes) {
31
- this.authPlugins.set(authType, plugin);
32
- this.logger.debug(`Registered auth plugin: ${plugin.name} for type '${authType}'`);
33
- }
34
- }
35
-
36
- /**
37
- * Register a variable provider plugin
38
- */
39
- registerVariableProvider(plugin: IValueProviderPlugin): void {
40
- this.variableProviders.set(plugin.provider, plugin);
41
- this.logger.debug(`Registered vault provider: ${plugin.name} (${plugin.provider})`);
42
- }
43
-
44
- /**
45
- * Get plugin for a protocol
46
- */
47
- getPlugin(protocol: string): IProtocolPlugin | undefined {
48
- return this.plugins.get(protocol);
49
- }
50
-
51
- /**
52
- * Get auth plugin for a type
53
- */
54
- getAuthPlugin(type: string): IAuthPlugin | undefined {
55
- return this.authPlugins.get(type);
56
- }
57
-
58
- /**
59
- * Apply auth to request if auth is configured
60
- */
61
- private async applyAuth(request: Request, auth: Auth, options: RuntimeOptions): Promise<Request> {
62
- if (auth.type === 'none' || auth.type === 'inherit') {
63
- return request;
64
- }
65
-
66
- const authPlugin = this.authPlugins.get(auth.type);
67
- if (authPlugin === null || authPlugin === undefined) {
68
- this.logger.error(`No auth plugin registered for type: ${auth.type}`);
69
- throw new Error(`No auth plugin registered for type: ${auth.type}`);
70
- }
71
-
72
- this.logger.debug(`Applying auth: ${auth.type} (plugin: ${authPlugin.name})`);
73
-
74
- try {
75
- const pluginLogger = this.logger.createLogger(`Auth:${authPlugin.name}`);
76
- return await authPlugin.apply(request, auth, options, pluginLogger);
77
- } catch (error: unknown) {
78
- const errorMsg = (error as { message?: string }).message ?? 'Unknown error';
79
- this.logger.error(`Auth plugin error (${auth.type}): ${errorMsg}`);
80
- throw new Error(`Auth plugin error (${auth.type}): ${errorMsg}`);
81
- }
82
- }
83
-
84
- /**
85
- * Execute request using appropriate plugin
86
- * @param protocol - Protocol name from collection.protocol
87
- * @param emitEvent - Optional callback for plugin events (e.g., WebSocket onMessage)
88
- */
89
- async execute(
90
- protocol: string,
91
- request: Request,
92
- context: ExecutionContext,
93
- options: RuntimeOptions,
94
- emitEvent?: (eventName: string, eventData: unknown) => Promise<void>
95
- ): Promise<ProtocolResponse> {
96
- // Check abort signal before execution
97
- if ((context.abortSignal as AbortSignal | undefined)?.aborted === true) {
98
- this.logger.debug('Plugin execution aborted before start');
99
- return {
100
- status: 0,
101
- statusText: 'Aborted',
102
- body: '',
103
- headers: {},
104
- duration: 0,
105
- error: 'Request aborted'
106
- };
107
- }
108
-
109
- const plugin = this.plugins.get(protocol);
110
-
111
- if (plugin === null || plugin === undefined) {
112
- this.logger.error(`No plugin registered for protocol: ${protocol}`);
113
- throw new Error(`No plugin registered for protocol: ${protocol}`);
114
- }
115
-
116
- this.logger.debug(`Executing request using ${protocol} plugin: ${plugin.name}`);
117
-
118
- // Validate auth compatibility with protocol
119
- if (request.auth !== null && request.auth !== undefined && request.auth.type !== 'none' && request.auth.type !== 'inherit') {
120
- if (!plugin.supportedAuthTypes.includes(request.auth.type)) {
121
- this.logger.error(`Protocol '${protocol}' does not support auth type '${request.auth.type}'`);
122
- throw new Error(
123
- `Protocol '${protocol}' does not support auth type '${request.auth.type}'. ` +
124
- `Supported types: ${plugin.supportedAuthTypes.join(', ')}`
125
- );
126
- }
127
- }
128
-
129
- // Apply auth if configured (should already be resolved)
130
- let modifiedRequest = request;
131
- if (request.auth !== null && request.auth !== undefined) {
132
- modifiedRequest = await this.applyAuth(modifiedRequest, request.auth, options);
133
-
134
- // Update context.currentRequest to reflect auth modifications
135
- context.currentRequest = modifiedRequest;
136
- }
137
-
138
- // Validate request
139
- this.logger.trace('Validating request with plugin');
140
- const validation = plugin.validate(modifiedRequest, options);
141
- if (validation.valid === false) {
142
- const errorMessages = validation.errors?.map(e => e.message).join(', ') ?? 'Unknown error';
143
- this.logger.error(`Request validation failed: ${errorMessages}`);
144
- throw new Error(`Request validation failed: ${errorMessages}`);
145
- }
146
-
147
- // Execute plugin with merged runtime options, event emitter, and logger
148
- const pluginLogger = this.logger.createLogger(`Protocol:${plugin.name}`);
149
- const response = await plugin.execute(modifiedRequest, context, options, emitEvent, pluginLogger);
150
-
151
- this.logger.debug(`Plugin execution completed in ${response.duration}ms (status: ${response.status})`);
152
-
153
- return response;
154
- }
155
-
156
- /**
157
- * Get all registered plugins
158
- */
159
- getAllPlugins(): IProtocolPlugin[] {
160
- return Array.from(this.plugins.values());
161
- }
162
-
163
- /**
164
- * Get all registered auth plugins
165
- */
166
- getAllAuthPlugins(): IAuthPlugin[] {
167
- return Array.from(this.authPlugins.values());
168
- }
169
-
170
- /**
171
- * Get variable provider plugin
172
- */
173
- getVariableProvider(provider: string): IValueProviderPlugin | undefined {
174
- return this.variableProviders.get(provider);
175
- }
176
-
177
- /**
178
- * Get all registered variable providers
179
- */
180
- getAllVariableProviders(): IValueProviderPlugin[] {
181
- return Array.from(this.variableProviders.values());
182
- }
183
-
184
- /**
185
- * Resolve variable value using provider plugin
186
- * Called when a variable has a provider specified
187
- */
188
- async resolveVariableProvider(
189
- provider: string,
190
- key: string,
191
- config?: Record<string, unknown>,
192
- context?: ExecutionContext
193
- ): Promise<string | null> {
194
- const providerPlugin = this.variableProviders.get(provider);
195
-
196
- if (providerPlugin === null || providerPlugin === undefined) {
197
- throw new Error(`No variable provider plugin registered for: ${provider}`);
198
- }
199
-
200
- try {
201
- const providerLogger = this.logger.createLogger(`Vault:${providerPlugin.name}`);
202
- return await providerPlugin.getValue(key, config, context, providerLogger);
203
- } catch (error: unknown) {
204
- const errorMsg = (error as { message?: string }).message ?? 'Unknown error';
205
- throw new Error(`Variable provider error (${provider}): ${errorMsg}`);
206
- }
207
- }
208
- }
1
+ import type { IProtocolPlugin, IAuthPlugin, IValueProviderPlugin, Request, ExecutionContext, ProtocolResponse, RuntimeOptions, Auth } from '@apiquest/types';
2
+ import { Logger } from './Logger.js';
3
+
4
+ export class PluginManager {
5
+ private plugins: Map<string, IProtocolPlugin> = new Map();
6
+ private authPlugins: Map<string, IAuthPlugin> = new Map();
7
+ private variableProviders: Map<string, IValueProviderPlugin> = new Map();
8
+ private logger: Logger;
9
+
10
+ constructor(baseLogger?: Logger) {
11
+ this.logger = baseLogger?.createLogger('PluginManager') ?? new Logger('PluginManager');
12
+ }
13
+
14
+ /**
15
+ * Register a protocol plugin
16
+ */
17
+ registerPlugin(plugin: IProtocolPlugin): void {
18
+ // Register plugin for each protocol it provides
19
+ for (const protocol of plugin.protocols) {
20
+ this.plugins.set(protocol, plugin);
21
+ this.logger.debug(`Registered protocol plugin: ${plugin.name} for protocol '${protocol}'`);
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Register an auth plugin
27
+ */
28
+ registerAuthPlugin(plugin: IAuthPlugin): void {
29
+ // Register plugin for each auth type it provides
30
+ for (const authType of plugin.authTypes) {
31
+ this.authPlugins.set(authType, plugin);
32
+ this.logger.debug(`Registered auth plugin: ${plugin.name} for type '${authType}'`);
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Register a variable provider plugin
38
+ */
39
+ registerVariableProvider(plugin: IValueProviderPlugin): void {
40
+ this.variableProviders.set(plugin.provider, plugin);
41
+ this.logger.debug(`Registered vault provider: ${plugin.name} (${plugin.provider})`);
42
+ }
43
+
44
+ /**
45
+ * Get plugin for a protocol
46
+ */
47
+ getPlugin(protocol: string): IProtocolPlugin | undefined {
48
+ return this.plugins.get(protocol);
49
+ }
50
+
51
+ /**
52
+ * Get auth plugin for a type
53
+ */
54
+ getAuthPlugin(type: string): IAuthPlugin | undefined {
55
+ return this.authPlugins.get(type);
56
+ }
57
+
58
+ /**
59
+ * Apply auth to request if auth is configured
60
+ */
61
+ private async applyAuth(request: Request, auth: Auth, options: RuntimeOptions): Promise<Request> {
62
+ if (auth.type === 'none' || auth.type === 'inherit') {
63
+ return request;
64
+ }
65
+
66
+ const authPlugin = this.authPlugins.get(auth.type);
67
+ if (authPlugin === null || authPlugin === undefined) {
68
+ this.logger.error(`No auth plugin registered for type: ${auth.type}`);
69
+ throw new Error(`No auth plugin registered for type: ${auth.type}`);
70
+ }
71
+
72
+ this.logger.debug(`Applying auth: ${auth.type} (plugin: ${authPlugin.name})`);
73
+
74
+ try {
75
+ const pluginLogger = this.logger.createLogger(`Auth:${authPlugin.name}`);
76
+ return await authPlugin.apply(request, auth, options, pluginLogger);
77
+ } catch (error: unknown) {
78
+ const errorMsg = (error as { message?: string }).message ?? 'Unknown error';
79
+ this.logger.error(`Auth plugin error (${auth.type}): ${errorMsg}`);
80
+ throw new Error(`Auth plugin error (${auth.type}): ${errorMsg}`);
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Execute request using appropriate plugin
86
+ * @param protocol - Protocol name from collection.protocol
87
+ * @param emitEvent - Optional callback for plugin events (e.g., WebSocket onMessage)
88
+ */
89
+ async execute(
90
+ protocol: string,
91
+ request: Request,
92
+ context: ExecutionContext,
93
+ options: RuntimeOptions,
94
+ emitEvent?: (eventName: string, eventData: unknown) => Promise<void>
95
+ ): Promise<ProtocolResponse> {
96
+ // Check abort signal before execution
97
+ if ((context.abortSignal as AbortSignal | undefined)?.aborted === true) {
98
+ this.logger.debug('Plugin execution aborted before start');
99
+ return {
100
+ status: 0,
101
+ statusText: 'Aborted',
102
+ body: '',
103
+ headers: {},
104
+ duration: 0,
105
+ error: 'Request aborted'
106
+ };
107
+ }
108
+
109
+ const plugin = this.plugins.get(protocol);
110
+
111
+ if (plugin === null || plugin === undefined) {
112
+ this.logger.error(`No plugin registered for protocol: ${protocol}`);
113
+ throw new Error(`No plugin registered for protocol: ${protocol}`);
114
+ }
115
+
116
+ this.logger.debug(`Executing request using ${protocol} plugin: ${plugin.name}`);
117
+
118
+ // Validate auth compatibility with protocol
119
+ if (request.auth !== null && request.auth !== undefined && request.auth.type !== 'none' && request.auth.type !== 'inherit') {
120
+ if (!plugin.supportedAuthTypes.includes(request.auth.type)) {
121
+ this.logger.error(`Protocol '${protocol}' does not support auth type '${request.auth.type}'`);
122
+ throw new Error(
123
+ `Protocol '${protocol}' does not support auth type '${request.auth.type}'. ` +
124
+ `Supported types: ${plugin.supportedAuthTypes.join(', ')}`
125
+ );
126
+ }
127
+ }
128
+
129
+ // Apply auth if configured (should already be resolved)
130
+ let modifiedRequest = request;
131
+ if (request.auth !== null && request.auth !== undefined) {
132
+ modifiedRequest = await this.applyAuth(modifiedRequest, request.auth, options);
133
+
134
+ // Update context.currentRequest to reflect auth modifications
135
+ context.currentRequest = modifiedRequest;
136
+ }
137
+
138
+ // Validate request
139
+ this.logger.trace('Validating request with plugin');
140
+ const validation = plugin.validate(modifiedRequest, options);
141
+ if (validation.valid === false) {
142
+ const errorMessages = validation.errors?.map(e => e.message).join(', ') ?? 'Unknown error';
143
+ this.logger.error(`Request validation failed: ${errorMessages}`);
144
+ throw new Error(`Request validation failed: ${errorMessages}`);
145
+ }
146
+
147
+ // Execute plugin with merged runtime options, event emitter, and logger
148
+ const pluginLogger = this.logger.createLogger(`Protocol:${plugin.name}`);
149
+ const response = await plugin.execute(modifiedRequest, context, options, emitEvent, pluginLogger);
150
+
151
+ this.logger.debug(`Plugin execution completed in ${response.duration}ms (status: ${response.status})`);
152
+
153
+ return response;
154
+ }
155
+
156
+ /**
157
+ * Get all registered plugins
158
+ */
159
+ getAllPlugins(): IProtocolPlugin[] {
160
+ return Array.from(this.plugins.values());
161
+ }
162
+
163
+ /**
164
+ * Get all registered auth plugins
165
+ */
166
+ getAllAuthPlugins(): IAuthPlugin[] {
167
+ return Array.from(this.authPlugins.values());
168
+ }
169
+
170
+ /**
171
+ * Get variable provider plugin
172
+ */
173
+ getVariableProvider(provider: string): IValueProviderPlugin | undefined {
174
+ return this.variableProviders.get(provider);
175
+ }
176
+
177
+ /**
178
+ * Get all registered variable providers
179
+ */
180
+ getAllVariableProviders(): IValueProviderPlugin[] {
181
+ return Array.from(this.variableProviders.values());
182
+ }
183
+
184
+ /**
185
+ * Resolve variable value using provider plugin
186
+ * Called when a variable has a provider specified
187
+ */
188
+ async resolveVariableProvider(
189
+ provider: string,
190
+ key: string,
191
+ config?: Record<string, unknown>,
192
+ context?: ExecutionContext
193
+ ): Promise<string | null> {
194
+ const providerPlugin = this.variableProviders.get(provider);
195
+
196
+ if (providerPlugin === null || providerPlugin === undefined) {
197
+ throw new Error(`No variable provider plugin registered for: ${provider}`);
198
+ }
199
+
200
+ try {
201
+ const providerLogger = this.logger.createLogger(`Vault:${providerPlugin.name}`);
202
+ return await providerPlugin.getValue(key, config, context, providerLogger);
203
+ } catch (error: unknown) {
204
+ const errorMsg = (error as { message?: string }).message ?? 'Unknown error';
205
+ throw new Error(`Variable provider error (${provider}): ${errorMsg}`);
206
+ }
207
+ }
208
+ }