@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,154 +1,154 @@
1
- import type { PluginPackageJson } from '@apiquest/types';
2
- import { Logger } from './Logger.js';
3
-
4
- export interface ResolvedPlugin {
5
- name: string;
6
- version: string;
7
- type: 'protocol' | 'auth' | 'value';
8
- path: string;
9
- entryPoint: string;
10
- protocols?: string[];
11
- authTypes?: string[];
12
- provider?: string;
13
- }
14
-
15
- export class PluginResolver {
16
- private resolved: Map<string, ResolvedPlugin> = new Map();
17
- private logger: Logger;
18
-
19
- constructor(baseLogger?: Logger) {
20
- this.logger = baseLogger?.createLogger('PluginResolver') ?? new Logger('PluginResolver');
21
- }
22
-
23
- /**
24
- * Scan multiple directories and resolve all available plugins
25
- * This is fast - just file I/O, no module loading
26
- */
27
- async scanDirectories(dirs: string[]): Promise<ResolvedPlugin[]> {
28
- const scanPromises = dirs.map(dir =>
29
- this.scanDirectory(dir).catch(err => {
30
- this.logger.error('Plugin scanning failed:', err);
31
- })
32
- );
33
-
34
- await Promise.all(scanPromises);
35
-
36
- return Array.from(this.resolved.values());
37
- }
38
-
39
- /**
40
- * Scan single directory for plugins
41
- */
42
- private async scanDirectory(pluginsDir: string): Promise<void> {
43
- const { readdir, readFile, access } = await import('fs/promises');
44
- const path = await import('path');
45
-
46
- this.logger.debug(`Scanning plugins: ${pluginsDir}`);
47
-
48
- // Check if directory exists
49
- try {
50
- await access(pluginsDir);
51
- } catch {
52
- this.logger.debug(`Plugins directory does not exist: ${pluginsDir}`);
53
- return;
54
- }
55
-
56
- const entries = await readdir(pluginsDir, { withFileTypes: true });
57
-
58
- for (const entry of entries) {
59
- // Only process plugin-* directories
60
- if (!entry.isDirectory() || !entry.name.startsWith('plugin-')) {
61
- continue;
62
- }
63
-
64
- const pluginPath = path.join(pluginsDir, entry.name);
65
- await this.resolvePlugin(pluginPath);
66
- }
67
- }
68
-
69
- /**
70
- * Resolve a single plugin - read metadata but don't load module
71
- */
72
- private async resolvePlugin(pluginPath: string): Promise<void> {
73
- const { readFile } = await import('fs/promises');
74
- const path = await import('path');
75
-
76
- const packageJsonPath = path.join(pluginPath, 'package.json');
77
-
78
- try {
79
- // Read package.json
80
- const pkgContent = await readFile(packageJsonPath, 'utf-8');
81
- const pkg = JSON.parse(pkgContent) as PluginPackageJson;
82
-
83
- // Check if plugin is for fracture runtime
84
- const runtime = pkg.apiquest?.runtime;
85
- const runtimeArray = Array.isArray(runtime) ? runtime : [runtime];
86
- if (pkg.apiquest === null || pkg.apiquest === undefined || !runtimeArray.includes('fracture')) {
87
- this.logger.debug(`Skipping ${pkg.name} (runtime: ${runtime ?? 'undefined'})`);
88
- return;
89
- }
90
-
91
- // Extract metadata from package.json
92
- const type = pkg.apiquest.type;
93
- if (!['protocol', 'auth', 'value'].includes(type)) {
94
- this.logger.warn(`Unknown plugin type: ${type} (${pkg.name})`);
95
- return;
96
- }
97
-
98
- // Resolve entry point
99
- const entryPoint = pkg.main ?? 'dist/index.js';
100
- const fullEntryPath = path.join(pluginPath, entryPoint);
101
-
102
- // Extract capabilities from apiquest.capabilities.provides
103
- const provides = pkg.apiquest.capabilities?.provides ?? {};
104
-
105
- // Create resolved plugin info
106
- const resolved: ResolvedPlugin = {
107
- name: pkg.name,
108
- version: pkg.version,
109
- type: type as 'protocol' | 'auth' | 'value',
110
- path: pluginPath,
111
- entryPoint: fullEntryPath,
112
- protocols: provides.protocols,
113
- authTypes: provides.authTypes,
114
- provider: provides.provider,
115
- };
116
-
117
- // Check for version conflicts
118
- const existing = this.resolved.get(pkg.name);
119
- if (existing !== null && existing !== undefined) {
120
- if (this.compareVersions(pkg.version, existing.version) > 0) {
121
- this.logger.debug(`Upgrading ${pkg.name} from v${existing.version} to v${pkg.version}`);
122
- this.resolved.set(pkg.name, resolved);
123
- } else {
124
- this.logger.debug(`Skipping ${pkg.name} v${pkg.version} (v${existing.version} already resolved)`);
125
- }
126
- } else {
127
- this.logger.debug(`Resolved ${pkg.name} v${pkg.version} (${type})`);
128
- this.resolved.set(pkg.name, resolved);
129
- }
130
- } catch (error: unknown) {
131
- const errorMsg = error instanceof Error ? error.message : String(error);
132
- this.logger.error(`Failed to resolve plugin at ${pluginPath}:`, errorMsg);
133
- }
134
- }
135
-
136
- /**
137
- * Compare semantic versions
138
- * Returns: 1 if a > b, -1 if a < b, 0 if equal
139
- */
140
- private compareVersions(a: string, b: string): number {
141
- const aParts = a.split('.').map(Number);
142
- const bParts = b.split('.').map(Number);
143
-
144
- for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
145
- const aNum = aParts[i] ?? 0;
146
- const bNum = bParts[i] ?? 0;
147
-
148
- if (aNum > bNum) return 1;
149
- if (aNum < bNum) return -1;
150
- }
151
-
152
- return 0;
153
- }
154
- }
1
+ import type { PluginPackageJson } from '@apiquest/types';
2
+ import { Logger } from './Logger.js';
3
+
4
+ export interface ResolvedPlugin {
5
+ name: string;
6
+ version: string;
7
+ type: 'protocol' | 'auth' | 'value';
8
+ path: string;
9
+ entryPoint: string;
10
+ protocols?: string[];
11
+ authTypes?: string[];
12
+ provider?: string;
13
+ }
14
+
15
+ export class PluginResolver {
16
+ private resolved: Map<string, ResolvedPlugin> = new Map();
17
+ private logger: Logger;
18
+
19
+ constructor(baseLogger?: Logger) {
20
+ this.logger = baseLogger?.createLogger('PluginResolver') ?? new Logger('PluginResolver');
21
+ }
22
+
23
+ /**
24
+ * Scan multiple directories and resolve all available plugins
25
+ * This is fast - just file I/O, no module loading
26
+ */
27
+ async scanDirectories(dirs: string[]): Promise<ResolvedPlugin[]> {
28
+ const scanPromises = dirs.map(dir =>
29
+ this.scanDirectory(dir).catch(err => {
30
+ this.logger.error('Plugin scanning failed:', err);
31
+ })
32
+ );
33
+
34
+ await Promise.all(scanPromises);
35
+
36
+ return Array.from(this.resolved.values());
37
+ }
38
+
39
+ /**
40
+ * Scan single directory for plugins
41
+ */
42
+ private async scanDirectory(pluginsDir: string): Promise<void> {
43
+ const { readdir, readFile, access } = await import('fs/promises');
44
+ const path = await import('path');
45
+
46
+ this.logger.debug(`Scanning plugins: ${pluginsDir}`);
47
+
48
+ // Check if directory exists
49
+ try {
50
+ await access(pluginsDir);
51
+ } catch {
52
+ this.logger.debug(`Plugins directory does not exist: ${pluginsDir}`);
53
+ return;
54
+ }
55
+
56
+ const entries = await readdir(pluginsDir, { withFileTypes: true });
57
+
58
+ for (const entry of entries) {
59
+ // Only process plugin-* directories
60
+ if (!entry.isDirectory() || !entry.name.startsWith('plugin-')) {
61
+ continue;
62
+ }
63
+
64
+ const pluginPath = path.join(pluginsDir, entry.name);
65
+ await this.resolvePlugin(pluginPath);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Resolve a single plugin - read metadata but don't load module
71
+ */
72
+ private async resolvePlugin(pluginPath: string): Promise<void> {
73
+ const { readFile } = await import('fs/promises');
74
+ const path = await import('path');
75
+
76
+ const packageJsonPath = path.join(pluginPath, 'package.json');
77
+
78
+ try {
79
+ // Read package.json
80
+ const pkgContent = await readFile(packageJsonPath, 'utf-8');
81
+ const pkg = JSON.parse(pkgContent) as PluginPackageJson;
82
+
83
+ // Check if plugin is for fracture runtime
84
+ const runtime = pkg.apiquest?.runtime;
85
+ const runtimeArray = Array.isArray(runtime) ? runtime : [runtime];
86
+ if (pkg.apiquest === null || pkg.apiquest === undefined || !runtimeArray.includes('fracture')) {
87
+ this.logger.debug(`Skipping ${pkg.name} (runtime: ${runtime ?? 'undefined'})`);
88
+ return;
89
+ }
90
+
91
+ // Extract metadata from package.json
92
+ const type = pkg.apiquest.type;
93
+ if (!['protocol', 'auth', 'value'].includes(type)) {
94
+ this.logger.warn(`Unknown plugin type: ${type} (${pkg.name})`);
95
+ return;
96
+ }
97
+
98
+ // Resolve entry point
99
+ const entryPoint = pkg.main ?? 'dist/index.js';
100
+ const fullEntryPath = path.join(pluginPath, entryPoint);
101
+
102
+ // Extract capabilities from apiquest.capabilities.provides
103
+ const provides = pkg.apiquest.capabilities?.provides ?? {};
104
+
105
+ // Create resolved plugin info
106
+ const resolved: ResolvedPlugin = {
107
+ name: pkg.name,
108
+ version: pkg.version,
109
+ type: type as 'protocol' | 'auth' | 'value',
110
+ path: pluginPath,
111
+ entryPoint: fullEntryPath,
112
+ protocols: provides.protocols,
113
+ authTypes: provides.authTypes,
114
+ provider: provides.provider,
115
+ };
116
+
117
+ // Check for version conflicts
118
+ const existing = this.resolved.get(pkg.name);
119
+ if (existing !== null && existing !== undefined) {
120
+ if (this.compareVersions(pkg.version, existing.version) > 0) {
121
+ this.logger.debug(`Upgrading ${pkg.name} from v${existing.version} to v${pkg.version}`);
122
+ this.resolved.set(pkg.name, resolved);
123
+ } else {
124
+ this.logger.debug(`Skipping ${pkg.name} v${pkg.version} (v${existing.version} already resolved)`);
125
+ }
126
+ } else {
127
+ this.logger.debug(`Resolved ${pkg.name} v${pkg.version} (${type})`);
128
+ this.resolved.set(pkg.name, resolved);
129
+ }
130
+ } catch (error: unknown) {
131
+ const errorMsg = error instanceof Error ? error.message : String(error);
132
+ this.logger.error(`Failed to resolve plugin at ${pluginPath}:`, errorMsg);
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Compare semantic versions
138
+ * Returns: 1 if a > b, -1 if a < b, 0 if equal
139
+ */
140
+ private compareVersions(a: string, b: string): number {
141
+ const aParts = a.split('.').map(Number);
142
+ const bParts = b.split('.').map(Number);
143
+
144
+ for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
145
+ const aNum = aParts[i] ?? 0;
146
+ const bNum = bParts[i] ?? 0;
147
+
148
+ if (aNum > bNum) return 1;
149
+ if (aNum < bNum) return -1;
150
+ }
151
+
152
+ return 0;
153
+ }
154
+ }