qa360 2.0.5 → 2.0.7
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/dist/commands/history.js
CHANGED
|
@@ -188,19 +188,27 @@ export class QA360History {
|
|
|
188
188
|
*/
|
|
189
189
|
async diff(runIdA, runIdB, options) {
|
|
190
190
|
const vault = await this.getVault();
|
|
191
|
+
// Support short IDs (prefix match) like history get does
|
|
192
|
+
const getRunWithPrefix = async (runId) => {
|
|
193
|
+
let run = await vault.getRun(runId);
|
|
194
|
+
if (!run && runId.length < 36) {
|
|
195
|
+
run = await vault.getRunByPrefix(runId);
|
|
196
|
+
}
|
|
197
|
+
return run;
|
|
198
|
+
};
|
|
191
199
|
const [runA, runB] = await Promise.all([
|
|
192
|
-
|
|
193
|
-
|
|
200
|
+
getRunWithPrefix(runIdA),
|
|
201
|
+
getRunWithPrefix(runIdB)
|
|
194
202
|
]);
|
|
195
203
|
if (!runA)
|
|
196
204
|
throw new Error(`Run A not found: ${runIdA}`);
|
|
197
205
|
if (!runB)
|
|
198
206
|
throw new Error(`Run B not found: ${runIdB}`);
|
|
199
207
|
const [gatesA, gatesB, findingsA, findingsB] = await Promise.all([
|
|
200
|
-
vault.getGates(
|
|
201
|
-
vault.getGates(
|
|
202
|
-
vault.getFindings(
|
|
203
|
-
vault.getFindings(
|
|
208
|
+
vault.getGates(runA.id),
|
|
209
|
+
vault.getGates(runB.id),
|
|
210
|
+
vault.getFindings(runA.id),
|
|
211
|
+
vault.getFindings(runB.id)
|
|
204
212
|
]);
|
|
205
213
|
const diff = {
|
|
206
214
|
runs: {
|
|
@@ -500,7 +508,20 @@ export class QA360History {
|
|
|
500
508
|
*/
|
|
501
509
|
async pin(runId, unpin = false) {
|
|
502
510
|
const vault = await this.getVault();
|
|
503
|
-
|
|
511
|
+
// Resolve short ID to full ID if needed
|
|
512
|
+
let fullId = runId;
|
|
513
|
+
const run = await vault.getRun(runId);
|
|
514
|
+
if (!run && runId.length < 36) {
|
|
515
|
+
// Try prefix match for short IDs
|
|
516
|
+
const prefixMatch = await vault.getRunByPrefix(runId);
|
|
517
|
+
if (prefixMatch) {
|
|
518
|
+
fullId = prefixMatch.id;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
else if (run) {
|
|
522
|
+
fullId = run.id;
|
|
523
|
+
}
|
|
524
|
+
await vault.pinRun(fullId, !unpin);
|
|
504
525
|
const action = unpin ? 'unpinned' : 'pinned';
|
|
505
526
|
console.log(chalk.green(`✅ Run ${runId} ${action} successfully!`));
|
|
506
527
|
}
|
|
@@ -50,6 +50,20 @@ export class PackLoaderV2 {
|
|
|
50
50
|
let changes = [];
|
|
51
51
|
let migrationWarnings = [];
|
|
52
52
|
if (detectedVersion === 1) {
|
|
53
|
+
// Check for legacy format before migrating
|
|
54
|
+
if (migrator.isLegacyFormat(parsed)) {
|
|
55
|
+
return {
|
|
56
|
+
success: false,
|
|
57
|
+
error: new Error(`Legacy pack format detected (version ${parsed.version || '0.9.x'}). ` +
|
|
58
|
+
`This format is no longer supported.\n\n` +
|
|
59
|
+
`To fix this:\n` +
|
|
60
|
+
` 1. Delete the old pack file: ${resolvedPath}\n` +
|
|
61
|
+
` 2. Create a new pack: qa360 init\n` +
|
|
62
|
+
` 3. Or copy an example: qa360 examples copy api-basic`),
|
|
63
|
+
sourcePath: resolvedPath,
|
|
64
|
+
format: 'legacy'
|
|
65
|
+
};
|
|
66
|
+
}
|
|
53
67
|
// Migrate v1 to v2
|
|
54
68
|
const migrationResult = migrator.migrate(parsed);
|
|
55
69
|
if (!migrationResult.success) {
|
|
@@ -69,6 +83,20 @@ export class PackLoaderV2 {
|
|
|
69
83
|
pack = parsed;
|
|
70
84
|
}
|
|
71
85
|
else {
|
|
86
|
+
// Check for legacy format and provide helpful error
|
|
87
|
+
if (migrator.isLegacyFormat(parsed)) {
|
|
88
|
+
return {
|
|
89
|
+
success: false,
|
|
90
|
+
error: new Error(`Legacy pack format detected (version ${parsed.version || '0.9.x'}). ` +
|
|
91
|
+
`This format is no longer supported.\n\n` +
|
|
92
|
+
`To fix this:\n` +
|
|
93
|
+
` 1. Delete the old pack file: ${resolvedPath}\n` +
|
|
94
|
+
` 2. Create a new pack: qa360 init\n` +
|
|
95
|
+
` 3. Or copy an example: qa360 examples copy api-basic`),
|
|
96
|
+
sourcePath: resolvedPath,
|
|
97
|
+
format: 'legacy'
|
|
98
|
+
};
|
|
99
|
+
}
|
|
72
100
|
return {
|
|
73
101
|
success: false,
|
|
74
102
|
error: new Error(`Unknown pack format. Version: ${parsed.version}`),
|
|
@@ -51,6 +51,11 @@ export declare class PackMigrator {
|
|
|
51
51
|
private sanitizeGateName;
|
|
52
52
|
/**
|
|
53
53
|
* Detect pack version
|
|
54
|
+
* Handles both integer versions (1, 2) and semver strings (1.0.0, 2.0.0)
|
|
54
55
|
*/
|
|
55
56
|
detectVersion(pack: any): 1 | 2 | 'unknown';
|
|
57
|
+
/**
|
|
58
|
+
* Check if pack is in legacy format (v0.9.x or earlier)
|
|
59
|
+
*/
|
|
60
|
+
isLegacyFormat(pack: any): boolean;
|
|
56
61
|
}
|
|
@@ -435,12 +435,26 @@ export class PackMigrator {
|
|
|
435
435
|
}
|
|
436
436
|
/**
|
|
437
437
|
* Detect pack version
|
|
438
|
+
* Handles both integer versions (1, 2) and semver strings (1.0.0, 2.0.0)
|
|
438
439
|
*/
|
|
439
440
|
detectVersion(pack) {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
441
|
+
// Handle semver format (e.g., "1.0.0", "2.0.0")
|
|
442
|
+
if (pack.version) {
|
|
443
|
+
if (typeof pack.version === 'number') {
|
|
444
|
+
if (pack.version === 2)
|
|
445
|
+
return 2;
|
|
446
|
+
if (pack.version === 1)
|
|
447
|
+
return 1;
|
|
448
|
+
}
|
|
449
|
+
else if (typeof pack.version === 'string') {
|
|
450
|
+
// Extract major version from semver string
|
|
451
|
+
const majorVersion = parseInt(pack.version.split('.')[0], 10);
|
|
452
|
+
if (majorVersion === 2)
|
|
453
|
+
return 2;
|
|
454
|
+
if (majorVersion === 1)
|
|
455
|
+
return 1;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
444
458
|
// Heuristic detection
|
|
445
459
|
if (pack.gates && Array.isArray(pack.gates))
|
|
446
460
|
return 1;
|
|
@@ -450,6 +464,17 @@ export class PackMigrator {
|
|
|
450
464
|
if (firstGate?.test_files || firstGate?.adapter)
|
|
451
465
|
return 2;
|
|
452
466
|
}
|
|
467
|
+
// Check for legacy format (v0.9.x) with adapters/tests
|
|
468
|
+
if (pack.adapters || pack.tests) {
|
|
469
|
+
// Legacy format detected - treat as unknown to trigger helpful error
|
|
470
|
+
return 'unknown';
|
|
471
|
+
}
|
|
453
472
|
return 'unknown';
|
|
454
473
|
}
|
|
474
|
+
/**
|
|
475
|
+
* Check if pack is in legacy format (v0.9.x or earlier)
|
|
476
|
+
*/
|
|
477
|
+
isLegacyFormat(pack) {
|
|
478
|
+
return !!(pack.adapters || (pack.tests && Array.isArray(pack.tests)));
|
|
479
|
+
}
|
|
455
480
|
}
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Config loader utilities for CLI commands
|
|
3
3
|
*/
|
|
4
|
-
import { PackConfigV1, type PackConfigV2 } from '
|
|
4
|
+
import { PackConfigV1, type PackConfigV2 } from '../core/index.js';
|
|
5
5
|
export declare function loadPackConfig(packPath: string): Promise<PackConfigV1 | PackConfigV2>;
|