@buoy-design/cli 0.1.9 → 0.1.11
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/cloud/client.d.ts +261 -0
- package/dist/cloud/client.d.ts.map +1 -0
- package/dist/cloud/client.js +140 -0
- package/dist/cloud/client.js.map +1 -0
- package/dist/cloud/config.d.ts +51 -0
- package/dist/cloud/config.d.ts.map +1 -0
- package/dist/cloud/config.js +98 -0
- package/dist/cloud/config.js.map +1 -0
- package/dist/cloud/index.d.ts +5 -0
- package/dist/cloud/index.d.ts.map +1 -0
- package/dist/cloud/index.js +5 -0
- package/dist/cloud/index.js.map +1 -0
- package/dist/cloud/queue.d.ts +52 -0
- package/dist/cloud/queue.d.ts.map +1 -0
- package/dist/cloud/queue.js +108 -0
- package/dist/cloud/queue.js.map +1 -0
- package/dist/cloud/sync.d.ts +75 -0
- package/dist/cloud/sync.d.ts.map +1 -0
- package/dist/cloud/sync.js +116 -0
- package/dist/cloud/sync.js.map +1 -0
- package/dist/commands/begin.d.ts +8 -0
- package/dist/commands/begin.d.ts.map +1 -0
- package/dist/commands/begin.js +380 -0
- package/dist/commands/begin.js.map +1 -0
- package/dist/commands/billing.d.ts +11 -0
- package/dist/commands/billing.d.ts.map +1 -0
- package/dist/commands/billing.js +295 -0
- package/dist/commands/billing.js.map +1 -0
- package/dist/commands/ci.d.ts.map +1 -1
- package/dist/commands/ci.js +18 -0
- package/dist/commands/ci.js.map +1 -1
- package/dist/commands/dock.d.ts +3 -0
- package/dist/commands/dock.d.ts.map +1 -0
- package/dist/commands/dock.js +881 -0
- package/dist/commands/dock.js.map +1 -0
- package/dist/commands/drift.d.ts.map +1 -1
- package/dist/commands/drift.js +36 -2
- package/dist/commands/drift.js.map +1 -1
- package/dist/commands/explain.d.ts.map +1 -1
- package/dist/commands/explain.js +15 -3
- package/dist/commands/explain.js.map +1 -1
- package/dist/commands/github.d.ts +10 -0
- package/dist/commands/github.d.ts.map +1 -0
- package/dist/commands/github.js +223 -0
- package/dist/commands/github.js.map +1 -0
- package/dist/commands/history.d.ts +3 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +320 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/index.d.ts +11 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +12 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/link.d.ts +8 -0
- package/dist/commands/link.d.ts.map +1 -0
- package/dist/commands/link.js +279 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/login.d.ts +8 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +143 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +8 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +31 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/scan.d.ts.map +1 -1
- package/dist/commands/scan.js +178 -31
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +135 -20
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/sync.d.ts +8 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +126 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/tokens.js +1 -1
- package/dist/commands/unlink.d.ts +8 -0
- package/dist/commands/unlink.d.ts.map +1 -0
- package/dist/commands/unlink.js +80 -0
- package/dist/commands/unlink.js.map +1 -0
- package/dist/commands/whoami.d.ts +8 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +86 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/config/auto-detect.d.ts.map +1 -1
- package/dist/config/auto-detect.js +9 -2
- package/dist/config/auto-detect.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +6 -6
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +70 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +8 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/hooks/index.js +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/insights/index.d.ts +3 -0
- package/dist/insights/index.d.ts.map +1 -0
- package/dist/insights/index.js +3 -0
- package/dist/insights/index.js.map +1 -0
- package/dist/insights/interactive.d.ts +11 -0
- package/dist/insights/interactive.d.ts.map +1 -0
- package/dist/insights/interactive.js +36 -0
- package/dist/insights/interactive.js.map +1 -0
- package/dist/insights/project-insights.d.ts +39 -0
- package/dist/insights/project-insights.d.ts.map +1 -0
- package/dist/insights/project-insights.js +198 -0
- package/dist/insights/project-insights.js.map +1 -0
- package/dist/integrations/github-formatter.js +4 -4
- package/dist/integrations/github-formatter.js.map +1 -1
- package/dist/output/formatters.d.ts +6 -0
- package/dist/output/formatters.d.ts.map +1 -1
- package/dist/output/formatters.js +236 -1
- package/dist/output/formatters.js.map +1 -1
- package/dist/scan/orchestrator.d.ts +14 -1
- package/dist/scan/orchestrator.d.ts.map +1 -1
- package/dist/scan/orchestrator.js +64 -4
- package/dist/scan/orchestrator.js.map +1 -1
- package/dist/services/architect.js +1 -1
- package/dist/services/architect.js.map +1 -1
- package/dist/services/drift-analysis.d.ts +3 -0
- package/dist/services/drift-analysis.d.ts.map +1 -1
- package/dist/services/drift-analysis.js +18 -2
- package/dist/services/drift-analysis.js.map +1 -1
- package/dist/store/cloud-store.d.ts +34 -0
- package/dist/store/cloud-store.d.ts.map +1 -0
- package/dist/store/cloud-store.js +100 -0
- package/dist/store/cloud-store.js.map +1 -0
- package/dist/store/index.d.ts +57 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +93 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/local-store.d.ts +31 -0
- package/dist/store/local-store.d.ts.map +1 -0
- package/dist/store/local-store.js +384 -0
- package/dist/store/local-store.js.map +1 -0
- package/dist/store/types.d.ts +147 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +6 -0
- package/dist/store/types.js.map +1 -0
- package/dist/wizard/ci-generator.d.ts +15 -0
- package/dist/wizard/ci-generator.d.ts.map +1 -0
- package/dist/wizard/ci-generator.js +129 -0
- package/dist/wizard/ci-generator.js.map +1 -0
- package/dist/wizard/index.d.ts +7 -0
- package/dist/wizard/index.d.ts.map +1 -0
- package/dist/wizard/index.js +7 -0
- package/dist/wizard/index.js.map +1 -0
- package/dist/wizard/issue-reviewer.d.ts +16 -0
- package/dist/wizard/issue-reviewer.d.ts.map +1 -0
- package/dist/wizard/issue-reviewer.js +183 -0
- package/dist/wizard/issue-reviewer.js.map +1 -0
- package/dist/wizard/menu.d.ts +46 -0
- package/dist/wizard/menu.d.ts.map +1 -0
- package/dist/wizard/menu.js +88 -0
- package/dist/wizard/menu.js.map +1 -0
- package/package.json +19 -15
- package/LICENSE +0 -21
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Offline Queue for Failed Uploads
|
|
3
|
+
*
|
|
4
|
+
* When scan uploads fail (network issues, API errors), they're queued
|
|
5
|
+
* for retry. The queue is stored in .buoy/sync-queue.json in the project.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
const QUEUE_DIR = '.buoy';
|
|
10
|
+
const QUEUE_FILE = 'sync-queue.json';
|
|
11
|
+
/**
|
|
12
|
+
* Get the queue file path for a project
|
|
13
|
+
*/
|
|
14
|
+
function getQueuePath(projectRoot) {
|
|
15
|
+
return join(projectRoot, QUEUE_DIR, QUEUE_FILE);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Ensure the .buoy directory exists
|
|
19
|
+
*/
|
|
20
|
+
function ensureQueueDir(projectRoot) {
|
|
21
|
+
const dir = join(projectRoot, QUEUE_DIR);
|
|
22
|
+
if (!existsSync(dir)) {
|
|
23
|
+
mkdirSync(dir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Read the sync queue
|
|
28
|
+
*/
|
|
29
|
+
export function readQueue(projectRoot) {
|
|
30
|
+
const queuePath = getQueuePath(projectRoot);
|
|
31
|
+
try {
|
|
32
|
+
if (!existsSync(queuePath)) {
|
|
33
|
+
return { scans: [] };
|
|
34
|
+
}
|
|
35
|
+
const content = readFileSync(queuePath, 'utf-8');
|
|
36
|
+
return JSON.parse(content);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return { scans: [] };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Write the sync queue
|
|
44
|
+
*/
|
|
45
|
+
export function writeQueue(projectRoot, queue) {
|
|
46
|
+
ensureQueueDir(projectRoot);
|
|
47
|
+
const queuePath = getQueuePath(projectRoot);
|
|
48
|
+
writeFileSync(queuePath, JSON.stringify(queue, null, 2));
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Add a failed scan to the queue
|
|
52
|
+
*/
|
|
53
|
+
export function queueScan(projectRoot, projectId, data, error) {
|
|
54
|
+
const queue = readQueue(projectRoot);
|
|
55
|
+
const now = new Date().toISOString();
|
|
56
|
+
const queuedScan = {
|
|
57
|
+
id: `q_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`,
|
|
58
|
+
projectId,
|
|
59
|
+
data,
|
|
60
|
+
attempts: 1,
|
|
61
|
+
lastAttempt: now,
|
|
62
|
+
error,
|
|
63
|
+
createdAt: now,
|
|
64
|
+
};
|
|
65
|
+
queue.scans.push(queuedScan);
|
|
66
|
+
writeQueue(projectRoot, queue);
|
|
67
|
+
return queuedScan;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Update a queued scan after a retry attempt
|
|
71
|
+
*/
|
|
72
|
+
export function updateQueuedScan(projectRoot, scanId, updates) {
|
|
73
|
+
const queue = readQueue(projectRoot);
|
|
74
|
+
const scan = queue.scans.find((s) => s.id === scanId);
|
|
75
|
+
if (scan) {
|
|
76
|
+
Object.assign(scan, updates);
|
|
77
|
+
writeQueue(projectRoot, queue);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Remove a scan from the queue (after successful upload)
|
|
82
|
+
*/
|
|
83
|
+
export function removeFromQueue(projectRoot, scanId) {
|
|
84
|
+
const queue = readQueue(projectRoot);
|
|
85
|
+
queue.scans = queue.scans.filter((s) => s.id !== scanId);
|
|
86
|
+
writeQueue(projectRoot, queue);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get pending scans that should be retried
|
|
90
|
+
*/
|
|
91
|
+
export function getPendingScans(projectRoot, maxAttempts = 5) {
|
|
92
|
+
const queue = readQueue(projectRoot);
|
|
93
|
+
return queue.scans.filter((s) => s.attempts < maxAttempts);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get count of queued scans
|
|
97
|
+
*/
|
|
98
|
+
export function getQueueCount(projectRoot) {
|
|
99
|
+
const queue = readQueue(projectRoot);
|
|
100
|
+
return queue.scans.length;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Clear all queued scans
|
|
104
|
+
*/
|
|
105
|
+
export function clearQueue(projectRoot) {
|
|
106
|
+
writeQueue(projectRoot, { scans: [] });
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/cloud/queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud Sync Utilities
|
|
3
|
+
*
|
|
4
|
+
* Handles uploading scans to Buoy Cloud with offline support.
|
|
5
|
+
*/
|
|
6
|
+
import { type UploadScanRequest } from './client.js';
|
|
7
|
+
import { getQueueCount } from './queue.js';
|
|
8
|
+
export interface SyncResult {
|
|
9
|
+
success: boolean;
|
|
10
|
+
scanId?: string;
|
|
11
|
+
queued?: boolean;
|
|
12
|
+
error?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get git metadata for current commit
|
|
16
|
+
*/
|
|
17
|
+
export declare function getGitMetadata(cwd: string): {
|
|
18
|
+
commitSha?: string;
|
|
19
|
+
branch?: string;
|
|
20
|
+
author?: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Convert CLI scan results to API format
|
|
24
|
+
*/
|
|
25
|
+
export declare function formatScanForUpload(components: Array<{
|
|
26
|
+
name: string;
|
|
27
|
+
path: string;
|
|
28
|
+
framework?: string;
|
|
29
|
+
props?: Array<{
|
|
30
|
+
name: string;
|
|
31
|
+
type?: string;
|
|
32
|
+
required?: boolean;
|
|
33
|
+
defaultValue?: unknown;
|
|
34
|
+
}>;
|
|
35
|
+
imports?: string[];
|
|
36
|
+
loc?: number;
|
|
37
|
+
}>, tokens: Array<{
|
|
38
|
+
name: string;
|
|
39
|
+
value: string;
|
|
40
|
+
type: string;
|
|
41
|
+
path?: string;
|
|
42
|
+
source?: string;
|
|
43
|
+
}>, drift: Array<{
|
|
44
|
+
type: string;
|
|
45
|
+
severity: 'error' | 'warning' | 'info';
|
|
46
|
+
message: string;
|
|
47
|
+
file?: string;
|
|
48
|
+
line?: number;
|
|
49
|
+
component?: string;
|
|
50
|
+
token?: string;
|
|
51
|
+
suggestion?: string;
|
|
52
|
+
}>, gitMetadata?: {
|
|
53
|
+
commitSha?: string;
|
|
54
|
+
branch?: string;
|
|
55
|
+
author?: string;
|
|
56
|
+
}): UploadScanRequest;
|
|
57
|
+
/**
|
|
58
|
+
* Upload scan results to Buoy Cloud
|
|
59
|
+
* Returns immediately if not logged in or no cloud project linked.
|
|
60
|
+
*/
|
|
61
|
+
export declare function syncScan(projectRoot: string, cloudProjectId: string, scanData: UploadScanRequest): Promise<SyncResult>;
|
|
62
|
+
/**
|
|
63
|
+
* Retry uploading queued scans
|
|
64
|
+
*/
|
|
65
|
+
export declare function syncQueue(projectRoot: string): Promise<{
|
|
66
|
+
synced: number;
|
|
67
|
+
failed: number;
|
|
68
|
+
remaining: number;
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* Check if there are queued scans
|
|
72
|
+
*/
|
|
73
|
+
export declare function hasQueuedScans(projectRoot: string): boolean;
|
|
74
|
+
export { getQueueCount };
|
|
75
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/cloud/sync.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAEL,KAAK,iBAAiB,EAIvB,MAAM,aAAa,CAAC;AACrB,OAAO,EAKL,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CASA;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,KAAK,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC3F,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC,EACF,MAAM,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,EACF,KAAK,EAAE,KAAK,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,EACF,WAAW,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACrE,iBAAiB,CAUnB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAiCrB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAgChE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud Sync Utilities
|
|
3
|
+
*
|
|
4
|
+
* Handles uploading scans to Buoy Cloud with offline support.
|
|
5
|
+
*/
|
|
6
|
+
import { execSync } from 'child_process';
|
|
7
|
+
import { isLoggedIn } from './config.js';
|
|
8
|
+
import { uploadScan, } from './client.js';
|
|
9
|
+
import { queueScan, getPendingScans, removeFromQueue, updateQueuedScan, getQueueCount, } from './queue.js';
|
|
10
|
+
/**
|
|
11
|
+
* Get git metadata for current commit
|
|
12
|
+
*/
|
|
13
|
+
export function getGitMetadata(cwd) {
|
|
14
|
+
try {
|
|
15
|
+
const commitSha = execSync('git rev-parse HEAD', { cwd, encoding: 'utf-8' }).trim();
|
|
16
|
+
const branch = execSync('git rev-parse --abbrev-ref HEAD', { cwd, encoding: 'utf-8' }).trim();
|
|
17
|
+
const author = execSync('git log -1 --format="%an <%ae>"', { cwd, encoding: 'utf-8' }).trim();
|
|
18
|
+
return { commitSha, branch, author };
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Convert CLI scan results to API format
|
|
26
|
+
*/
|
|
27
|
+
export function formatScanForUpload(components, tokens, drift, gitMetadata) {
|
|
28
|
+
return {
|
|
29
|
+
commitSha: gitMetadata?.commitSha,
|
|
30
|
+
branch: gitMetadata?.branch,
|
|
31
|
+
author: gitMetadata?.author,
|
|
32
|
+
timestamp: new Date().toISOString(),
|
|
33
|
+
components: components,
|
|
34
|
+
tokens: tokens,
|
|
35
|
+
drift: drift,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Upload scan results to Buoy Cloud
|
|
40
|
+
* Returns immediately if not logged in or no cloud project linked.
|
|
41
|
+
*/
|
|
42
|
+
export async function syncScan(projectRoot, cloudProjectId, scanData) {
|
|
43
|
+
// Check if logged in
|
|
44
|
+
if (!isLoggedIn()) {
|
|
45
|
+
return { success: false, error: 'Not logged in' };
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const result = await uploadScan(cloudProjectId, scanData);
|
|
49
|
+
if (result.ok && result.data) {
|
|
50
|
+
return {
|
|
51
|
+
success: true,
|
|
52
|
+
scanId: result.data.id,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// Upload failed - queue for retry
|
|
56
|
+
queueScan(projectRoot, cloudProjectId, scanData, result.error);
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
queued: true,
|
|
60
|
+
error: result.error,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
// Network or other error - queue for retry
|
|
65
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
66
|
+
queueScan(projectRoot, cloudProjectId, scanData, errorMessage);
|
|
67
|
+
return {
|
|
68
|
+
success: false,
|
|
69
|
+
queued: true,
|
|
70
|
+
error: errorMessage,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Retry uploading queued scans
|
|
76
|
+
*/
|
|
77
|
+
export async function syncQueue(projectRoot) {
|
|
78
|
+
const pending = getPendingScans(projectRoot);
|
|
79
|
+
let synced = 0;
|
|
80
|
+
let failed = 0;
|
|
81
|
+
for (const scan of pending) {
|
|
82
|
+
try {
|
|
83
|
+
const result = await uploadScan(scan.projectId, scan.data);
|
|
84
|
+
if (result.ok) {
|
|
85
|
+
removeFromQueue(projectRoot, scan.id);
|
|
86
|
+
synced++;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
updateQueuedScan(projectRoot, scan.id, {
|
|
90
|
+
attempts: scan.attempts + 1,
|
|
91
|
+
lastAttempt: new Date().toISOString(),
|
|
92
|
+
error: result.error,
|
|
93
|
+
});
|
|
94
|
+
failed++;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
updateQueuedScan(projectRoot, scan.id, {
|
|
99
|
+
attempts: scan.attempts + 1,
|
|
100
|
+
lastAttempt: new Date().toISOString(),
|
|
101
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
102
|
+
});
|
|
103
|
+
failed++;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const remaining = getQueueCount(projectRoot);
|
|
107
|
+
return { synced, failed, remaining };
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check if there are queued scans
|
|
111
|
+
*/
|
|
112
|
+
export function hasQueuedScans(projectRoot) {
|
|
113
|
+
return getQueueCount(projectRoot) > 0;
|
|
114
|
+
}
|
|
115
|
+
export { getQueueCount };
|
|
116
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/cloud/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"begin.d.ts","sourceRoot":"","sources":["../../src/commands/begin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCpC,wBAAgB,kBAAkB,IAAI,OAAO,CAkG5C"}
|