@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.
- package/README.md +119 -0
- package/bin/cli.js +2 -2
- package/dist/CollectionRunner.js +3 -3
- package/dist/ScriptEngine.js +4 -4
- package/dist/cli/plugin-commands.d.ts.map +1 -1
- package/dist/cli/plugin-commands.js +2 -1
- package/dist/cli/plugin-commands.js.map +1 -1
- package/package.json +55 -50
- package/src/CollectionAnalyzer.ts +102 -102
- package/src/CollectionRunner.ts +1423 -1423
- package/src/CollectionRunner.types.ts +9 -9
- package/src/CollectionValidator.ts +289 -289
- package/src/ConsoleReporter.ts +143 -143
- package/src/CookieJar.ts +258 -258
- package/src/DagScheduler.ts +439 -439
- package/src/Logger.ts +85 -85
- package/src/PluginLoader.ts +126 -126
- package/src/PluginManager.ts +208 -208
- package/src/PluginResolver.ts +154 -154
- package/src/QuestAPI.ts +764 -764
- package/src/QuestAPI.types.ts +33 -33
- package/src/QuestTestAPI.ts +164 -164
- package/src/RequestFilter.ts +224 -224
- package/src/ScriptEngine.ts +219 -219
- package/src/ScriptValidator.ts +428 -428
- package/src/TaskGraph.ts +598 -598
- package/src/TestCounter.ts +109 -109
- package/src/VariableResolver.ts +114 -114
- package/src/cli/index.ts +480 -480
- package/src/cli/plugin-commands.ts +342 -341
- package/src/cli/plugin-discovery.ts +44 -44
- package/src/index.ts +24 -24
- package/src/utils.ts +52 -52
- package/tsconfig.json +20 -20
- package/tsconfig.test.json +5 -5
- package/vitest.config.ts +22 -22
- package/dist/ExecutionTree.d.ts +0 -77
- package/dist/ExecutionTree.d.ts.map +0 -1
- package/dist/ExecutionTree.js +0 -265
- package/dist/ExecutionTree.js.map +0 -1
- package/dist/fracture/src/CollectionAnalyzer.d.ts +0 -17
- package/dist/fracture/src/CollectionAnalyzer.d.ts.map +0 -1
- package/dist/fracture/src/CollectionAnalyzer.js +0 -70
- package/dist/fracture/src/CollectionAnalyzer.js.map +0 -1
- package/dist/fracture/src/CollectionRunner.d.ts +0 -39
- package/dist/fracture/src/CollectionRunner.d.ts.map +0 -1
- package/dist/fracture/src/CollectionRunner.js +0 -802
- package/dist/fracture/src/CollectionRunner.js.map +0 -1
- package/dist/fracture/src/CollectionRunner.types.d.ts +0 -8
- package/dist/fracture/src/CollectionRunner.types.d.ts.map +0 -1
- package/dist/fracture/src/CollectionRunner.types.js +0 -2
- package/dist/fracture/src/CollectionRunner.types.js.map +0 -1
- package/dist/fracture/src/CollectionValidator.d.ts +0 -14
- package/dist/fracture/src/CollectionValidator.d.ts.map +0 -1
- package/dist/fracture/src/CollectionValidator.js +0 -145
- package/dist/fracture/src/CollectionValidator.js.map +0 -1
- package/dist/fracture/src/ConsoleReporter.d.ts +0 -24
- package/dist/fracture/src/ConsoleReporter.d.ts.map +0 -1
- package/dist/fracture/src/ConsoleReporter.js +0 -123
- package/dist/fracture/src/ConsoleReporter.js.map +0 -1
- package/dist/fracture/src/CookieJar.d.ts +0 -70
- package/dist/fracture/src/CookieJar.d.ts.map +0 -1
- package/dist/fracture/src/CookieJar.js +0 -233
- package/dist/fracture/src/CookieJar.js.map +0 -1
- package/dist/fracture/src/ExecutionTree.d.ts +0 -77
- package/dist/fracture/src/ExecutionTree.d.ts.map +0 -1
- package/dist/fracture/src/ExecutionTree.js +0 -258
- package/dist/fracture/src/ExecutionTree.js.map +0 -1
- package/dist/fracture/src/Logger.d.ts +0 -25
- package/dist/fracture/src/Logger.d.ts.map +0 -1
- package/dist/fracture/src/Logger.js +0 -78
- package/dist/fracture/src/Logger.js.map +0 -1
- package/dist/fracture/src/PluginLoader.d.ts +0 -23
- package/dist/fracture/src/PluginLoader.d.ts.map +0 -1
- package/dist/fracture/src/PluginLoader.js +0 -102
- package/dist/fracture/src/PluginLoader.js.map +0 -1
- package/dist/fracture/src/PluginManager.d.ts +0 -64
- package/dist/fracture/src/PluginManager.d.ts.map +0 -1
- package/dist/fracture/src/PluginManager.js +0 -162
- package/dist/fracture/src/PluginManager.js.map +0 -1
- package/dist/fracture/src/PluginResolver.d.ts +0 -35
- package/dist/fracture/src/PluginResolver.d.ts.map +0 -1
- package/dist/fracture/src/PluginResolver.js +0 -128
- package/dist/fracture/src/PluginResolver.js.map +0 -1
- package/dist/fracture/src/QuestAPI.d.ts +0 -9
- package/dist/fracture/src/QuestAPI.d.ts.map +0 -1
- package/dist/fracture/src/QuestAPI.js +0 -679
- package/dist/fracture/src/QuestAPI.js.map +0 -1
- package/dist/fracture/src/QuestAPI.types.d.ts +0 -35
- package/dist/fracture/src/QuestAPI.types.d.ts.map +0 -1
- package/dist/fracture/src/QuestAPI.types.js +0 -3
- package/dist/fracture/src/QuestAPI.types.js.map +0 -1
- package/dist/fracture/src/QuestTestAPI.d.ts +0 -12
- package/dist/fracture/src/QuestTestAPI.d.ts.map +0 -1
- package/dist/fracture/src/QuestTestAPI.js +0 -133
- package/dist/fracture/src/QuestTestAPI.js.map +0 -1
- package/dist/fracture/src/ScriptEngine.d.ts +0 -21
- package/dist/fracture/src/ScriptEngine.d.ts.map +0 -1
- package/dist/fracture/src/ScriptEngine.js +0 -183
- package/dist/fracture/src/ScriptEngine.js.map +0 -1
- package/dist/fracture/src/ScriptValidator.d.ts +0 -68
- package/dist/fracture/src/ScriptValidator.d.ts.map +0 -1
- package/dist/fracture/src/ScriptValidator.js +0 -351
- package/dist/fracture/src/ScriptValidator.js.map +0 -1
- package/dist/fracture/src/TestCounter.d.ts +0 -18
- package/dist/fracture/src/TestCounter.d.ts.map +0 -1
- package/dist/fracture/src/TestCounter.js +0 -82
- package/dist/fracture/src/TestCounter.js.map +0 -1
- package/dist/fracture/src/VariableResolver.d.ts +0 -20
- package/dist/fracture/src/VariableResolver.d.ts.map +0 -1
- package/dist/fracture/src/VariableResolver.js +0 -100
- package/dist/fracture/src/VariableResolver.js.map +0 -1
- package/dist/fracture/src/cli/index.d.ts +0 -3
- package/dist/fracture/src/cli/index.d.ts.map +0 -1
- package/dist/fracture/src/cli/index.js +0 -347
- package/dist/fracture/src/cli/index.js.map +0 -1
- package/dist/fracture/src/cli/plugin-commands.d.ts +0 -6
- package/dist/fracture/src/cli/plugin-commands.d.ts.map +0 -1
- package/dist/fracture/src/cli/plugin-commands.js +0 -263
- package/dist/fracture/src/cli/plugin-commands.js.map +0 -1
- package/dist/fracture/src/cli/plugin-discovery.d.ts +0 -11
- package/dist/fracture/src/cli/plugin-discovery.d.ts.map +0 -1
- package/dist/fracture/src/cli/plugin-discovery.js +0 -64
- package/dist/fracture/src/cli/plugin-discovery.js.map +0 -1
- package/dist/fracture/src/index.d.ts +0 -13
- package/dist/fracture/src/index.d.ts.map +0 -1
- package/dist/fracture/src/index.js +0 -17
- package/dist/fracture/src/index.js.map +0 -1
- package/dist/fracture/src/utils.d.ts +0 -28
- package/dist/fracture/src/utils.d.ts.map +0 -1
- package/dist/fracture/src/utils.js +0 -48
- package/dist/fracture/src/utils.js.map +0 -1
- package/dist/plugin-auth/src/apikey-auth.d.ts +0 -3
- package/dist/plugin-auth/src/apikey-auth.d.ts.map +0 -1
- package/dist/plugin-auth/src/apikey-auth.js +0 -73
- package/dist/plugin-auth/src/apikey-auth.js.map +0 -1
- package/dist/plugin-auth/src/basic-auth.d.ts +0 -3
- package/dist/plugin-auth/src/basic-auth.d.ts.map +0 -1
- package/dist/plugin-auth/src/basic-auth.js +0 -61
- package/dist/plugin-auth/src/basic-auth.js.map +0 -1
- package/dist/plugin-auth/src/bearer-auth.d.ts +0 -3
- package/dist/plugin-auth/src/bearer-auth.d.ts.map +0 -1
- package/dist/plugin-auth/src/bearer-auth.js +0 -49
- package/dist/plugin-auth/src/bearer-auth.js.map +0 -1
- package/dist/plugin-auth/src/helpers.d.ts +0 -3
- package/dist/plugin-auth/src/helpers.d.ts.map +0 -1
- package/dist/plugin-auth/src/helpers.js +0 -8
- package/dist/plugin-auth/src/helpers.js.map +0 -1
- package/dist/plugin-auth/src/index.d.ts +0 -10
- package/dist/plugin-auth/src/index.d.ts.map +0 -1
- package/dist/plugin-auth/src/index.js +0 -25
- package/dist/plugin-auth/src/index.js.map +0 -1
- package/dist/plugin-auth/src/oauth2-auth.d.ts +0 -35
- package/dist/plugin-auth/src/oauth2-auth.d.ts.map +0 -1
- package/dist/plugin-auth/src/oauth2-auth.js +0 -266
- package/dist/plugin-auth/src/oauth2-auth.js.map +0 -1
- package/dist/plugin-http/src/index.d.ts +0 -4
- package/dist/plugin-http/src/index.d.ts.map +0 -1
- package/dist/plugin-http/src/index.js +0 -266
- package/dist/plugin-http/src/index.js.map +0 -1
- package/dist/plugin-vault-file/src/index.d.ts +0 -67
- package/dist/plugin-vault-file/src/index.d.ts.map +0 -1
- package/dist/plugin-vault-file/src/index.js +0 -171
- package/dist/plugin-vault-file/src/index.js.map +0 -1
- package/dist/types.d.ts +0 -374
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -13
- package/dist/types.js.map +0 -1
|
@@ -1,341 +1,342 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { exec } from 'child_process';
|
|
3
|
-
import { promisify } from 'util';
|
|
4
|
-
import { readdir, readFile, access } from 'fs/promises';
|
|
5
|
-
import path from 'path';
|
|
6
|
-
import { execSync } from 'child_process';
|
|
7
|
-
|
|
8
|
-
const execAsync = promisify(exec);
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Add plugin management commands to the CLI program
|
|
12
|
-
*/
|
|
13
|
-
export function addPluginCommands(program: Command): void {
|
|
14
|
-
const pluginCommand = program
|
|
15
|
-
.command('plugin')
|
|
16
|
-
.description('Manage ApiQuest plugins');
|
|
17
|
-
|
|
18
|
-
// quest plugin install <name>
|
|
19
|
-
pluginCommand
|
|
20
|
-
.command('install')
|
|
21
|
-
.description('Install a plugin')
|
|
22
|
-
.argument('<names...>', 'Plugin name(s) to install')
|
|
23
|
-
.action(async (names: string[]) => {
|
|
24
|
-
for (const name of names) {
|
|
25
|
-
const packageName = name.startsWith('@') ? name : `@apiquest/plugin-${name}`;
|
|
26
|
-
|
|
27
|
-
console.log(`Installing ${packageName}...`);
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
// Use npm to install globally
|
|
31
|
-
await execAsync(`npm install -g ${packageName}`);
|
|
32
|
-
console.log(`✓ ${packageName} installed`);
|
|
33
|
-
} catch (error) {
|
|
34
|
-
const err = error as { message?: string };
|
|
35
|
-
console.error(`✗ Failed to install ${packageName}:`, err.message ?? String(error));
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
// quest plugin list
|
|
41
|
-
pluginCommand
|
|
42
|
-
.command('list')
|
|
43
|
-
.description('List installed plugins')
|
|
44
|
-
.action(async () => {
|
|
45
|
-
console.log('Installed plugins:\n');
|
|
46
|
-
|
|
47
|
-
// Check global npm packages
|
|
48
|
-
try {
|
|
49
|
-
const globalPath = execSync('npm root -g', { encoding: 'utf-8' }).trim();
|
|
50
|
-
const apiquestPath = path.join(globalPath, '@apiquest');
|
|
51
|
-
await listPluginsFromDir(apiquestPath, 'Global (npm)');
|
|
52
|
-
} catch (error) {
|
|
53
|
-
console.log(' [Global (npm)] Could not access global npm packages\n');
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// quest plugin available
|
|
58
|
-
pluginCommand
|
|
59
|
-
.command('available')
|
|
60
|
-
.description('List available plugins from npm registry (fracture runtime)')
|
|
61
|
-
.action(async () => {
|
|
62
|
-
console.log('Available plugins (npm registry):\n');
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
const plugins = await fetchAvailablePlugins();
|
|
66
|
-
if (plugins.length === 0) {
|
|
67
|
-
console.log(' No plugins found for fracture runtime.');
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
for (const plugin of plugins) {
|
|
72
|
-
console.log(` - ${plugin.name}@${plugin.version}`);
|
|
73
|
-
if (plugin.type !== undefined) {
|
|
74
|
-
console.log(` Type: ${plugin.type}`);
|
|
75
|
-
}
|
|
76
|
-
if (plugin.runtime.length > 0) {
|
|
77
|
-
console.log(` Runtime: ${plugin.runtime.join(', ')}`);
|
|
78
|
-
}
|
|
79
|
-
if (plugin.description !== undefined) {
|
|
80
|
-
console.log(` Description: ${plugin.description}`);
|
|
81
|
-
}
|
|
82
|
-
printCapabilities(plugin.provides, ' ');
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
.
|
|
96
|
-
.
|
|
97
|
-
.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
.
|
|
117
|
-
.
|
|
118
|
-
.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
console.log(`
|
|
184
|
-
console.log(`
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
searchUrl.
|
|
253
|
-
searchUrl.searchParams.set('
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
.
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
.filter(plugin => plugin
|
|
281
|
-
.
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
const
|
|
297
|
-
const
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
}
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { exec } from 'child_process';
|
|
3
|
+
import { promisify } from 'util';
|
|
4
|
+
import { readdir, readFile, access } from 'fs/promises';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { execSync } from 'child_process';
|
|
7
|
+
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Add plugin management commands to the CLI program
|
|
12
|
+
*/
|
|
13
|
+
export function addPluginCommands(program: Command): void {
|
|
14
|
+
const pluginCommand = program
|
|
15
|
+
.command('plugin')
|
|
16
|
+
.description('Manage ApiQuest plugins');
|
|
17
|
+
|
|
18
|
+
// quest plugin install <name>
|
|
19
|
+
pluginCommand
|
|
20
|
+
.command('install')
|
|
21
|
+
.description('Install a plugin')
|
|
22
|
+
.argument('<names...>', 'Plugin name(s) to install')
|
|
23
|
+
.action(async (names: string[]) => {
|
|
24
|
+
for (const name of names) {
|
|
25
|
+
const packageName = name.startsWith('@') ? name : `@apiquest/plugin-${name}`;
|
|
26
|
+
|
|
27
|
+
console.log(`Installing ${packageName}...`);
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
// Use npm to install globally
|
|
31
|
+
await execAsync(`npm install -g ${packageName}`);
|
|
32
|
+
console.log(`✓ ${packageName} installed`);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
const err = error as { message?: string };
|
|
35
|
+
console.error(`✗ Failed to install ${packageName}:`, err.message ?? String(error));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// quest plugin list
|
|
41
|
+
pluginCommand
|
|
42
|
+
.command('list')
|
|
43
|
+
.description('List installed plugins')
|
|
44
|
+
.action(async () => {
|
|
45
|
+
console.log('Installed plugins:\n');
|
|
46
|
+
|
|
47
|
+
// Check global npm packages
|
|
48
|
+
try {
|
|
49
|
+
const globalPath = execSync('npm root -g', { encoding: 'utf-8' }).trim();
|
|
50
|
+
const apiquestPath = path.join(globalPath, '@apiquest');
|
|
51
|
+
await listPluginsFromDir(apiquestPath, 'Global (npm)');
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.log(' [Global (npm)] Could not access global npm packages\n');
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// quest plugin available
|
|
58
|
+
pluginCommand
|
|
59
|
+
.command('available')
|
|
60
|
+
.description('List available plugins from npm registry (fracture runtime)')
|
|
61
|
+
.action(async () => {
|
|
62
|
+
console.log('Available plugins (npm registry):\n');
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const plugins = await fetchAvailablePlugins();
|
|
66
|
+
if (plugins.length === 0) {
|
|
67
|
+
console.log(' No plugins found for fracture runtime.');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
for (const plugin of plugins) {
|
|
72
|
+
console.log(` - ${plugin.name}@${plugin.version}`);
|
|
73
|
+
if (plugin.type !== undefined) {
|
|
74
|
+
console.log(` Type: ${plugin.type}`);
|
|
75
|
+
}
|
|
76
|
+
if (plugin.runtime.length > 0) {
|
|
77
|
+
console.log(` Runtime: ${plugin.runtime.join(', ')}`);
|
|
78
|
+
}
|
|
79
|
+
if (plugin.description !== undefined) {
|
|
80
|
+
console.log(` Description: ${plugin.description}`);
|
|
81
|
+
}
|
|
82
|
+
printCapabilities(plugin.provides, ' ');
|
|
83
|
+
console.log('');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
console.log('');
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error('Failed to query npm registry:', error instanceof Error ? error.message : String(error));
|
|
89
|
+
process.exit(4);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// quest plugin remove <name>
|
|
94
|
+
pluginCommand
|
|
95
|
+
.command('remove')
|
|
96
|
+
.description('Remove a plugin')
|
|
97
|
+
.argument('<names...>', 'Plugin name(s) to remove')
|
|
98
|
+
.action(async (names: string[]) => {
|
|
99
|
+
for (const name of names) {
|
|
100
|
+
const packageName = name.startsWith('@') ? name : `@apiquest/plugin-${name}`;
|
|
101
|
+
|
|
102
|
+
console.log(`Removing ${packageName}...`);
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
await execAsync(`npm uninstall -g ${packageName}`);
|
|
106
|
+
console.log(`✓ ${packageName} removed`);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
const err = error as { message?: string };
|
|
109
|
+
console.error(`✗ Failed to remove ${packageName}:`, err.message ?? String(error));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// quest plugin update <name>
|
|
115
|
+
pluginCommand
|
|
116
|
+
.command('update')
|
|
117
|
+
.description('Update plugin(s)')
|
|
118
|
+
.argument('[names...]', 'Plugin name(s) to update (all if not specified)')
|
|
119
|
+
.action(async (names: string[]) => {
|
|
120
|
+
if (names.length === 0) {
|
|
121
|
+
// Update all @apiquest plugins
|
|
122
|
+
console.log('Updating all @apiquest plugins...');
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
await execAsync('npm update -g @apiquest/*');
|
|
126
|
+
console.log('✓ All plugins updated');
|
|
127
|
+
} catch (error) {
|
|
128
|
+
const err = error as { message?: string };
|
|
129
|
+
console.error('✗ Failed to update plugins:', err.message ?? String(error));
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
for (const name of names) {
|
|
133
|
+
const packageName = name.startsWith('@') ? name : `@apiquest/plugin-${name}`;
|
|
134
|
+
|
|
135
|
+
console.log(`Updating ${packageName}...`);
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
await execAsync(`npm update -g ${packageName}`);
|
|
139
|
+
console.log(`✓ ${packageName} updated`);
|
|
140
|
+
} catch (error) {
|
|
141
|
+
const err = error as { message?: string };
|
|
142
|
+
console.error(`✗ Failed to update ${packageName}:`, err.message ?? String(error));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* List plugins from a specific directory
|
|
151
|
+
*/
|
|
152
|
+
async function listPluginsFromDir(dir: string, label: string): Promise<void> {
|
|
153
|
+
try {
|
|
154
|
+
await access(dir);
|
|
155
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
156
|
+
const plugins = entries.filter(e => e.isDirectory() && e.name.startsWith('plugin-'));
|
|
157
|
+
|
|
158
|
+
let foundAny = false;
|
|
159
|
+
console.log(` [${label}]`);
|
|
160
|
+
|
|
161
|
+
for (const plugin of plugins) {
|
|
162
|
+
const pluginPath = path.join(dir, plugin.name);
|
|
163
|
+
const packageJsonPath = path.join(pluginPath, 'package.json');
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
const pkgContent = await readFile(packageJsonPath, 'utf-8');
|
|
167
|
+
const pkg: {
|
|
168
|
+
name?: string;
|
|
169
|
+
version?: string;
|
|
170
|
+
apiquest?: ApiquestMetadata;
|
|
171
|
+
} = JSON.parse(pkgContent) as { name?: string; version?: string; apiquest?: ApiquestMetadata };
|
|
172
|
+
|
|
173
|
+
// Only list fracture runtime plugins
|
|
174
|
+
if (pkg.apiquest?.runtime?.includes('fracture') !== true) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
foundAny = true;
|
|
179
|
+
const version = pkg.version ?? 'unknown';
|
|
180
|
+
const type = pkg.apiquest?.type ?? 'unknown';
|
|
181
|
+
const runtime = pkg.apiquest?.runtime?.join(', ') ?? 'unknown';
|
|
182
|
+
|
|
183
|
+
console.log(` - ${pkg.name ?? 'unknown'}@${version}`);
|
|
184
|
+
console.log(` Type: ${type}`);
|
|
185
|
+
console.log(` Runtime: ${runtime}`);
|
|
186
|
+
|
|
187
|
+
printCapabilities(pkg.apiquest?.capabilities?.provides, ' ');
|
|
188
|
+
|
|
189
|
+
} catch {
|
|
190
|
+
// Skip invalid package.json
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (!foundAny) {
|
|
195
|
+
console.log(` No fracture plugins found`);
|
|
196
|
+
}
|
|
197
|
+
console.log('');
|
|
198
|
+
} catch {
|
|
199
|
+
console.log(` [${label}] Directory not found or not accessible\n`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
interface PluginProvides {
|
|
204
|
+
protocols?: string[];
|
|
205
|
+
authTypes?: string[];
|
|
206
|
+
reportTypes?: string[];
|
|
207
|
+
importFormats?: string[];
|
|
208
|
+
exportFormats?: string[];
|
|
209
|
+
visualizations?: string[];
|
|
210
|
+
provider?: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
interface ApiquestMetadata {
|
|
214
|
+
type?: string;
|
|
215
|
+
runtime?: string[];
|
|
216
|
+
capabilities?: {
|
|
217
|
+
provides?: PluginProvides;
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
interface RegistrySearchResponse {
|
|
222
|
+
objects: Array<{
|
|
223
|
+
package?: {
|
|
224
|
+
name?: string;
|
|
225
|
+
};
|
|
226
|
+
}>;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
interface RegistryPackageResponse {
|
|
230
|
+
name: string;
|
|
231
|
+
version?: string;
|
|
232
|
+
description?: string;
|
|
233
|
+
'dist-tags'?: {
|
|
234
|
+
latest?: string;
|
|
235
|
+
};
|
|
236
|
+
versions?: Record<string, {
|
|
237
|
+
description?: string;
|
|
238
|
+
apiquest?: ApiquestMetadata;
|
|
239
|
+
}>;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
interface AvailablePlugin {
|
|
243
|
+
name: string;
|
|
244
|
+
version: string;
|
|
245
|
+
description?: string;
|
|
246
|
+
type?: string;
|
|
247
|
+
runtime: string[];
|
|
248
|
+
provides?: PluginProvides;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async function fetchAvailablePlugins(): Promise<AvailablePlugin[]> {
|
|
252
|
+
const searchUrl = new URL('https://registry.npmjs.org/-/v1/search');
|
|
253
|
+
searchUrl.searchParams.set('text', '@apiquest/plugin');
|
|
254
|
+
searchUrl.searchParams.set('size', '250');
|
|
255
|
+
|
|
256
|
+
const response = await fetch(searchUrl.toString(), {
|
|
257
|
+
headers: {
|
|
258
|
+
'Accept': 'application/json'
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
if (!response.ok) {
|
|
263
|
+
throw new Error(`Registry search failed: ${response.status} ${response.statusText}`);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const data = await response.json() as RegistrySearchResponse;
|
|
267
|
+
const names = data.objects
|
|
268
|
+
.map(obj => obj.package?.name)
|
|
269
|
+
.filter((name): name is string => typeof name === 'string' && name.startsWith('@apiquest/plugin-'));
|
|
270
|
+
|
|
271
|
+
const pluginResults = await Promise.all(names.map(async (name) => {
|
|
272
|
+
try {
|
|
273
|
+
return await fetchRegistryPluginInfo(name);
|
|
274
|
+
} catch {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
}));
|
|
278
|
+
|
|
279
|
+
return pluginResults
|
|
280
|
+
.filter((plugin): plugin is AvailablePlugin => plugin !== null)
|
|
281
|
+
.filter(plugin => plugin.runtime.includes('fracture'))
|
|
282
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async function fetchRegistryPluginInfo(name: string): Promise<AvailablePlugin | null> {
|
|
286
|
+
const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(name)}`, {
|
|
287
|
+
headers: {
|
|
288
|
+
'Accept': 'application/json'
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
if (!response.ok) {
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const data = await response.json() as RegistryPackageResponse;
|
|
297
|
+
const latest = data['dist-tags']?.latest;
|
|
298
|
+
const versionData = latest !== undefined && data.versions !== undefined ? data.versions[latest] : undefined;
|
|
299
|
+
const metadata = versionData?.apiquest;
|
|
300
|
+
|
|
301
|
+
if (latest === undefined || metadata === undefined) {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const runtime = Array.isArray(metadata.runtime) ? metadata.runtime : [];
|
|
306
|
+
return {
|
|
307
|
+
name: data.name,
|
|
308
|
+
version: latest,
|
|
309
|
+
description: versionData?.description,
|
|
310
|
+
type: metadata.type,
|
|
311
|
+
runtime,
|
|
312
|
+
provides: metadata.capabilities?.provides
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function printCapabilities(provides?: PluginProvides, indent = ' '): void {
|
|
317
|
+
if (provides === undefined) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (provides.protocols !== undefined && provides.protocols.length > 0) {
|
|
322
|
+
console.log(`${indent}Protocols: ${provides.protocols.join(', ')}`);
|
|
323
|
+
}
|
|
324
|
+
if (provides.authTypes !== undefined && provides.authTypes.length > 0) {
|
|
325
|
+
console.log(`${indent}Auth Types: ${provides.authTypes.join(', ')}`);
|
|
326
|
+
}
|
|
327
|
+
if (provides.reportTypes !== undefined && provides.reportTypes.length > 0) {
|
|
328
|
+
console.log(`${indent}Report Types: ${provides.reportTypes.join(', ')}`);
|
|
329
|
+
}
|
|
330
|
+
if (provides.importFormats !== undefined && provides.importFormats.length > 0) {
|
|
331
|
+
console.log(`${indent}Import Formats: ${provides.importFormats.join(', ')}`);
|
|
332
|
+
}
|
|
333
|
+
if (provides.exportFormats !== undefined && provides.exportFormats.length > 0) {
|
|
334
|
+
console.log(`${indent}Export Formats: ${provides.exportFormats.join(', ')}`);
|
|
335
|
+
}
|
|
336
|
+
if (provides.visualizations !== undefined && provides.visualizations.length > 0) {
|
|
337
|
+
console.log(`${indent}Visualizations: ${provides.visualizations.join(', ')}`);
|
|
338
|
+
}
|
|
339
|
+
if (provides.provider !== undefined) {
|
|
340
|
+
console.log(`${indent}Provider: ${provides.provider}`);
|
|
341
|
+
}
|
|
342
|
+
}
|