cmssy-cli 0.7.0 → 0.9.0
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 +382 -36
- package/dist/cli.js +29 -10
- package/dist/cli.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +147 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +20 -16
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/package.d.ts +7 -0
- package/dist/commands/package.d.ts.map +1 -0
- package/dist/commands/package.js +161 -0
- package/dist/commands/package.js.map +1 -0
- package/dist/commands/publish.d.ts +12 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +395 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/push.d.ts +9 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +199 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/upload.d.ts +7 -0
- package/dist/commands/upload.d.ts.map +1 -0
- package/dist/commands/upload.js +126 -0
- package/dist/commands/upload.js.map +1 -0
- package/dist/dev-ui/app.js +163 -2
- package/dist/dev-ui/index.html +396 -2
- package/dist/utils/cmssy-config.d.ts +0 -3
- package/dist/utils/cmssy-config.d.ts.map +1 -1
- package/dist/utils/cmssy-config.js.map +1 -1
- package/dist/utils/config.d.ts +1 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +1 -0
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/graphql.d.ts +1 -0
- package/dist/utils/graphql.d.ts.map +1 -1
- package/dist/utils/graphql.js +28 -0
- package/dist/utils/graphql.js.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import fs from "fs-extra";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
import FormData from "form-data";
|
|
6
|
+
import fetch from "node-fetch";
|
|
7
|
+
import { loadConfig } from "../utils/config.js";
|
|
8
|
+
export async function uploadCommand(packageFiles = [], options) {
|
|
9
|
+
const cwd = process.cwd();
|
|
10
|
+
const packagesDir = path.join(cwd, "packages");
|
|
11
|
+
// Load API config
|
|
12
|
+
const config = loadConfig();
|
|
13
|
+
if (!config.apiToken) {
|
|
14
|
+
console.error(chalk.red("✖ API token not configured. Run:") +
|
|
15
|
+
chalk.white("\n cmssy configure"));
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
// Determine workspace ID
|
|
19
|
+
let workspaceId = options.workspace || config.workspaceId;
|
|
20
|
+
if (!workspaceId) {
|
|
21
|
+
console.error(chalk.red("✖ Workspace ID required. Specify with --workspace or set CMSSY_WORKSPACE_ID in .env"));
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
// Check if packages directory exists
|
|
25
|
+
if (!(await fs.pathExists(packagesDir))) {
|
|
26
|
+
console.error(chalk.red("✖ No packages directory found. Run:") +
|
|
27
|
+
chalk.white("\n cmssy package --all"));
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
// Determine which packages to upload
|
|
31
|
+
let toUpload = [];
|
|
32
|
+
if (options.all) {
|
|
33
|
+
// Get all ZIP files from packages directory
|
|
34
|
+
const files = await fs.readdir(packagesDir);
|
|
35
|
+
toUpload = files
|
|
36
|
+
.filter((f) => f.endsWith(".zip"))
|
|
37
|
+
.map((f) => path.join(packagesDir, f));
|
|
38
|
+
}
|
|
39
|
+
else if (packageFiles.length > 0) {
|
|
40
|
+
// Specific files
|
|
41
|
+
for (const file of packageFiles) {
|
|
42
|
+
const filePath = path.isAbsolute(file) ? file : path.join(packagesDir, file);
|
|
43
|
+
// Add .zip extension if missing
|
|
44
|
+
const zipPath = filePath.endsWith(".zip") ? filePath : `${filePath}.zip`;
|
|
45
|
+
if (!(await fs.pathExists(zipPath))) {
|
|
46
|
+
console.error(chalk.red(`✖ Package not found: ${zipPath}`));
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
toUpload.push(zipPath);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
console.error(chalk.red("✖ Specify packages to upload or use --all:\n") +
|
|
54
|
+
chalk.white(" cmssy upload hero-1.0.0.zip\n") +
|
|
55
|
+
chalk.white(" cmssy upload hero-1.0.0 pricing-2.1.0\n") +
|
|
56
|
+
chalk.white(" cmssy upload --all"));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
if (toUpload.length === 0) {
|
|
60
|
+
console.log(chalk.yellow("⚠ No packages found to upload"));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
console.log(chalk.blue(`\n📤 Uploading ${toUpload.length} package(s)...\n`));
|
|
64
|
+
// Upload each package
|
|
65
|
+
let successCount = 0;
|
|
66
|
+
let failCount = 0;
|
|
67
|
+
for (const filePath of toUpload) {
|
|
68
|
+
const fileName = path.basename(filePath);
|
|
69
|
+
const result = await uploadPackage(filePath, workspaceId, config.apiUrl, config.apiToken);
|
|
70
|
+
if (result.success) {
|
|
71
|
+
successCount++;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
failCount++;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
console.log();
|
|
78
|
+
if (successCount > 0) {
|
|
79
|
+
console.log(chalk.green(`✓ Successfully uploaded ${successCount} package(s)`));
|
|
80
|
+
}
|
|
81
|
+
if (failCount > 0) {
|
|
82
|
+
console.log(chalk.red(`✖ Failed to upload ${failCount} package(s)`));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function uploadPackage(filePath, workspaceId, apiUrl, apiToken) {
|
|
86
|
+
const fileName = path.basename(filePath);
|
|
87
|
+
const spinner = ora(`Uploading ${chalk.cyan(fileName)}`).start();
|
|
88
|
+
try {
|
|
89
|
+
// Create form data
|
|
90
|
+
const form = new FormData();
|
|
91
|
+
form.append("file", fs.createReadStream(filePath), {
|
|
92
|
+
filename: fileName,
|
|
93
|
+
contentType: "application/zip",
|
|
94
|
+
});
|
|
95
|
+
form.append("workspaceId", workspaceId);
|
|
96
|
+
// Determine upload endpoint
|
|
97
|
+
const uploadUrl = apiUrl.replace("/graphql", "/api/upload-package");
|
|
98
|
+
// Upload file
|
|
99
|
+
const response = await fetch(uploadUrl, {
|
|
100
|
+
method: "POST",
|
|
101
|
+
headers: {
|
|
102
|
+
Authorization: `Bearer ${apiToken}`,
|
|
103
|
+
...form.getHeaders(),
|
|
104
|
+
},
|
|
105
|
+
body: form,
|
|
106
|
+
});
|
|
107
|
+
if (!response.ok) {
|
|
108
|
+
const errorText = await response.text();
|
|
109
|
+
throw new Error(`HTTP ${response.status}: ${errorText || response.statusText}`);
|
|
110
|
+
}
|
|
111
|
+
const result = await response.json();
|
|
112
|
+
if (result.success || result.url) {
|
|
113
|
+
const fileSize = (fs.statSync(filePath).size / 1024).toFixed(2);
|
|
114
|
+
spinner.succeed(`Uploaded ${chalk.cyan(fileName)} (${fileSize} KB)${result.url ? chalk.gray(` → ${result.url}`) : ""}`);
|
|
115
|
+
return { success: true };
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
throw new Error(result.error || "Upload failed");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
spinner.fail(`Failed to upload ${chalk.cyan(fileName)}: ${error.message}`);
|
|
123
|
+
return { success: false, error: error.message };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"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"}
|
package/dist/dev-ui/app.js
CHANGED
|
@@ -45,8 +45,14 @@ function renderBlocksList() {
|
|
|
45
45
|
data-block="${block.name}"
|
|
46
46
|
onclick="selectBlock('${block.name}')"
|
|
47
47
|
>
|
|
48
|
-
<div class="block-item-
|
|
49
|
-
|
|
48
|
+
<div class="block-item-header">
|
|
49
|
+
<div class="block-item-name">${block.displayName || block.name}</div>
|
|
50
|
+
<span class="version-badge">v${block.version || '1.0.0'}</span>
|
|
51
|
+
</div>
|
|
52
|
+
<div class="block-item-footer">
|
|
53
|
+
<span class="block-item-type">${block.type}</span>
|
|
54
|
+
<span class="status-badge status-local">Local</span>
|
|
55
|
+
</div>
|
|
50
56
|
</div>
|
|
51
57
|
`).join('');
|
|
52
58
|
}
|
|
@@ -72,6 +78,12 @@ async function selectBlock(blockName) {
|
|
|
72
78
|
document.getElementById('preview-title').textContent = block.displayName || block.name;
|
|
73
79
|
document.getElementById('editor-subtitle').textContent = block.name;
|
|
74
80
|
|
|
81
|
+
// Show publish button
|
|
82
|
+
const publishBtn = document.getElementById('publish-btn');
|
|
83
|
+
if (publishBtn) {
|
|
84
|
+
publishBtn.style.display = 'block';
|
|
85
|
+
}
|
|
86
|
+
|
|
75
87
|
// Render preview
|
|
76
88
|
renderPreview();
|
|
77
89
|
|
|
@@ -492,5 +504,154 @@ function escapeHtml(text) {
|
|
|
492
504
|
return div.innerHTML;
|
|
493
505
|
}
|
|
494
506
|
|
|
507
|
+
// Publish functionality
|
|
508
|
+
let publishTaskId = null;
|
|
509
|
+
let publishEventSource = null;
|
|
510
|
+
|
|
511
|
+
window.openPublishModal = function() {
|
|
512
|
+
if (!currentBlock) return;
|
|
513
|
+
|
|
514
|
+
const modal = document.getElementById('publish-modal');
|
|
515
|
+
const blockName = document.getElementById('publish-block-name');
|
|
516
|
+
const version = document.getElementById('publish-version');
|
|
517
|
+
|
|
518
|
+
blockName.textContent = currentBlock.displayName || currentBlock.name;
|
|
519
|
+
version.textContent = `v${currentBlock.version || '1.0.0'}`;
|
|
520
|
+
|
|
521
|
+
// Reset form
|
|
522
|
+
document.getElementById('publish-target-marketplace').checked = true;
|
|
523
|
+
document.getElementById('publish-workspace-id').value = '';
|
|
524
|
+
document.getElementById('publish-version-bump').value = '';
|
|
525
|
+
|
|
526
|
+
// Show/hide workspace input
|
|
527
|
+
toggleWorkspaceInput();
|
|
528
|
+
|
|
529
|
+
modal.classList.add('active');
|
|
530
|
+
};
|
|
531
|
+
|
|
532
|
+
window.closePublishModal = function() {
|
|
533
|
+
const modal = document.getElementById('publish-modal');
|
|
534
|
+
modal.classList.remove('active');
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
window.toggleWorkspaceInput = function() {
|
|
538
|
+
const target = document.querySelector('input[name="publish-target"]:checked').value;
|
|
539
|
+
const workspaceGroup = document.getElementById('workspace-id-group');
|
|
540
|
+
|
|
541
|
+
if (target === 'workspace') {
|
|
542
|
+
workspaceGroup.style.display = 'block';
|
|
543
|
+
} else {
|
|
544
|
+
workspaceGroup.style.display = 'none';
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
window.startPublish = async function() {
|
|
549
|
+
if (!currentBlock) return;
|
|
550
|
+
|
|
551
|
+
const target = document.querySelector('input[name="publish-target"]:checked').value;
|
|
552
|
+
const workspaceId = document.getElementById('publish-workspace-id').value;
|
|
553
|
+
const versionBump = document.getElementById('publish-version-bump').value;
|
|
554
|
+
|
|
555
|
+
// Validate workspace ID if needed
|
|
556
|
+
if (target === 'workspace' && !workspaceId) {
|
|
557
|
+
alert('Workspace ID is required for workspace publish');
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// Show progress UI, hide form
|
|
562
|
+
document.getElementById('publish-form').style.display = 'none';
|
|
563
|
+
document.getElementById('publish-progress').style.display = 'block';
|
|
564
|
+
|
|
565
|
+
try {
|
|
566
|
+
// Start publish
|
|
567
|
+
const response = await fetch(`/api/blocks/${currentBlock.name}/publish`, {
|
|
568
|
+
method: 'POST',
|
|
569
|
+
headers: { 'Content-Type': 'application/json' },
|
|
570
|
+
body: JSON.stringify({ target, workspaceId, versionBump })
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
if (!response.ok) {
|
|
574
|
+
const error = await response.json();
|
|
575
|
+
throw new Error(error.error || 'Failed to start publish');
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
const { taskId } = await response.json();
|
|
579
|
+
publishTaskId = taskId;
|
|
580
|
+
|
|
581
|
+
// Stream progress
|
|
582
|
+
streamPublishProgress(taskId);
|
|
583
|
+
|
|
584
|
+
} catch (error) {
|
|
585
|
+
console.error('Publish failed:', error);
|
|
586
|
+
showPublishError(error.message);
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
function streamPublishProgress(taskId) {
|
|
591
|
+
// Close existing connection
|
|
592
|
+
if (publishEventSource) {
|
|
593
|
+
publishEventSource.close();
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
publishEventSource = new EventSource(`/api/publish/progress/${taskId}`);
|
|
597
|
+
|
|
598
|
+
publishEventSource.onmessage = (event) => {
|
|
599
|
+
const task = JSON.parse(event.data);
|
|
600
|
+
updatePublishProgress(task);
|
|
601
|
+
|
|
602
|
+
// Close connection when done
|
|
603
|
+
if (task.status === 'completed' || task.status === 'failed') {
|
|
604
|
+
publishEventSource.close();
|
|
605
|
+
publishEventSource = null;
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
publishEventSource.onerror = () => {
|
|
610
|
+
console.error('SSE connection lost');
|
|
611
|
+
publishEventSource.close();
|
|
612
|
+
publishEventSource = null;
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
function updatePublishProgress(task) {
|
|
617
|
+
const progressBar = document.getElementById('publish-progress-bar');
|
|
618
|
+
const progressText = document.getElementById('publish-progress-text');
|
|
619
|
+
const stepsContainer = document.getElementById('publish-steps');
|
|
620
|
+
|
|
621
|
+
// Update progress bar
|
|
622
|
+
progressBar.style.width = `${task.progress}%`;
|
|
623
|
+
progressText.textContent = `${task.progress}%`;
|
|
624
|
+
|
|
625
|
+
// Update steps
|
|
626
|
+
stepsContainer.innerHTML = task.steps.map(step => `
|
|
627
|
+
<div class="progress-step ${step.status}">
|
|
628
|
+
<span class="step-icon">
|
|
629
|
+
${step.status === 'completed' ? '✓' : step.status === 'failed' ? '✗' : '⏳'}
|
|
630
|
+
</span>
|
|
631
|
+
<span class="step-message">${step.message}</span>
|
|
632
|
+
</div>
|
|
633
|
+
`).join('');
|
|
634
|
+
|
|
635
|
+
// Handle completion
|
|
636
|
+
if (task.status === 'completed') {
|
|
637
|
+
document.getElementById('publish-close-btn').style.display = 'block';
|
|
638
|
+
document.getElementById('publish-close-btn').textContent = 'Done';
|
|
639
|
+
} else if (task.status === 'failed') {
|
|
640
|
+
document.getElementById('publish-close-btn').style.display = 'block';
|
|
641
|
+
document.getElementById('publish-close-btn').textContent = 'Close';
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
function showPublishError(message) {
|
|
646
|
+
const progressDiv = document.getElementById('publish-progress');
|
|
647
|
+
progressDiv.innerHTML = `
|
|
648
|
+
<div class="publish-error">
|
|
649
|
+
<div class="error-icon">✗</div>
|
|
650
|
+
<div class="error-message">${escapeHtml(message)}</div>
|
|
651
|
+
<button class="btn btn-secondary" onclick="closePublishModal()">Close</button>
|
|
652
|
+
</div>
|
|
653
|
+
`;
|
|
654
|
+
}
|
|
655
|
+
|
|
495
656
|
// Start the app
|
|
496
657
|
init();
|