@blkc-code/cli 0.1.3 → 0.3.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/dist/blkc.cjs +75131 -0
- package/package.json +18 -30
- package/bin/blkc.js +0 -24
- package/dist/cli.js +0 -24
- package/dist/commands/block.d.ts +0 -13
- package/dist/commands/block.d.ts.map +0 -1
- package/dist/commands/block.js +0 -196
- package/dist/commands/block.js.map +0 -1
- package/dist/commands/circuit.d.ts +0 -13
- package/dist/commands/circuit.d.ts.map +0 -1
- package/dist/commands/circuit.js +0 -160
- package/dist/commands/circuit.js.map +0 -1
- package/dist/commands/deploy.d.ts +0 -14
- package/dist/commands/deploy.d.ts.map +0 -1
- package/dist/commands/deploy.js +0 -332
- package/dist/commands/deploy.js.map +0 -1
- package/dist/commands/kit.d.ts +0 -13
- package/dist/commands/kit.d.ts.map +0 -1
- package/dist/commands/kit.js +0 -152
- package/dist/commands/kit.js.map +0 -1
- package/dist/commands/logbook.d.ts +0 -13
- package/dist/commands/logbook.d.ts.map +0 -1
- package/dist/commands/logbook.js +0 -170
- package/dist/commands/logbook.js.map +0 -1
- package/dist/index.d.ts +0 -21
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -64
- package/dist/index.js.map +0 -1
- package/src/__tests__/smoke.test.ts +0 -8
- package/src/commands/block.ts +0 -219
- package/src/commands/circuit.ts +0 -182
- package/src/commands/deploy.ts +0 -373
- package/src/commands/kit.ts +0 -173
- package/src/commands/logbook.ts +0 -194
- package/src/index.ts +0 -70
package/src/commands/circuit.ts
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BLKC CLI - Circuit Commands
|
|
3
|
-
*
|
|
4
|
-
* Commands for working with BLKC Circuits.
|
|
5
|
-
*
|
|
6
|
-
* @package @blkc-code/cli
|
|
7
|
-
* @license Apache-2.0
|
|
8
|
-
* @author Black Code Enterprises LLC
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { Command } from "commander";
|
|
12
|
-
import chalk from "chalk";
|
|
13
|
-
import ora from "ora";
|
|
14
|
-
import { readFile } from "node:fs/promises";
|
|
15
|
-
import path from "node:path";
|
|
16
|
-
import { CircuitSchema } from "@blkc-code/core";
|
|
17
|
-
|
|
18
|
-
// ============================================================================
|
|
19
|
-
// Command: circuit validate
|
|
20
|
-
// ============================================================================
|
|
21
|
-
|
|
22
|
-
function setupValidateCommand(program: Command): void {
|
|
23
|
-
program
|
|
24
|
-
.command("validate <manifest-path>")
|
|
25
|
-
.description("Validate a Circuit manifest")
|
|
26
|
-
.action(async (manifestPath: string) => {
|
|
27
|
-
const spinner = ora("Validating Circuit manifest...").start();
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
const absolutePath = path.resolve(process.cwd(), manifestPath);
|
|
31
|
-
const content = await readFile(absolutePath, { encoding: "utf8" });
|
|
32
|
-
const manifest = JSON.parse(content);
|
|
33
|
-
|
|
34
|
-
const result = CircuitSchema.safeParse(manifest);
|
|
35
|
-
|
|
36
|
-
if (!result.success) {
|
|
37
|
-
spinner.fail("Validation failed");
|
|
38
|
-
console.error(chalk.red("\nValidation errors:"));
|
|
39
|
-
for (const issue of result.error.issues) {
|
|
40
|
-
console.error(` - ${chalk.red(issue.path.join("."))}: ${issue.message}`);
|
|
41
|
-
}
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
spinner.succeed("Circuit manifest is valid");
|
|
46
|
-
const circuit = result.data;
|
|
47
|
-
console.log(chalk.gray(`\nCircuit ID: ${circuit.id}`));
|
|
48
|
-
console.log(chalk.gray(`Name: ${circuit.name}`));
|
|
49
|
-
console.log(chalk.gray(`Kits: ${circuit.kits.length}`));
|
|
50
|
-
console.log(chalk.gray(`Boards: ${circuit.boards.length}`));
|
|
51
|
-
console.log(chalk.gray(`Capabilities: ${circuit.capabilities.length}`));
|
|
52
|
-
} catch (error) {
|
|
53
|
-
spinner.fail(`Failed to validate: ${error}`);
|
|
54
|
-
process.exit(1);
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// ============================================================================
|
|
60
|
-
// Command: circuit info
|
|
61
|
-
// ============================================================================
|
|
62
|
-
|
|
63
|
-
function setupInfoCommand(program: Command): void {
|
|
64
|
-
program
|
|
65
|
-
.command("info <manifest-path>")
|
|
66
|
-
.description("Show detailed information about a Circuit")
|
|
67
|
-
.action(async (manifestPath: string) => {
|
|
68
|
-
const spinner = ora("Loading Circuit info...").start();
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
const absolutePath = path.resolve(process.cwd(), manifestPath);
|
|
72
|
-
const content = await readFile(absolutePath, { encoding: "utf8" });
|
|
73
|
-
const manifest = JSON.parse(content);
|
|
74
|
-
|
|
75
|
-
const result = CircuitSchema.safeParse(manifest);
|
|
76
|
-
if (!result.success) {
|
|
77
|
-
spinner.fail("Invalid Circuit manifest");
|
|
78
|
-
process.exit(1);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const circuit = result.data;
|
|
82
|
-
spinner.succeed(`Circuit: ${circuit.id}`);
|
|
83
|
-
|
|
84
|
-
console.log(chalk.bold("\nCircuit Information"));
|
|
85
|
-
console.log(chalk.gray("─".repeat(40)));
|
|
86
|
-
console.log(chalk.gray(`ID: ${circuit.id}`));
|
|
87
|
-
console.log(chalk.gray(`Name: ${circuit.name}`));
|
|
88
|
-
console.log(chalk.gray(`Summary: ${circuit.summary}`));
|
|
89
|
-
console.log(chalk.gray(`Version: ${circuit.version}`));
|
|
90
|
-
console.log(chalk.gray(`Status: ${circuit.status}`));
|
|
91
|
-
console.log(chalk.gray(`License: ${circuit.license}`));
|
|
92
|
-
|
|
93
|
-
if (circuit.verticals.length > 0) {
|
|
94
|
-
console.log(chalk.gray(`Verticals: ${circuit.verticals.join(", ")}`));
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (circuit.tags.length > 0) {
|
|
98
|
-
console.log(chalk.gray(`Tags: ${circuit.tags.join(", ")}`));
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (circuit.kits.length > 0) {
|
|
102
|
-
console.log(chalk.bold("\nKits"));
|
|
103
|
-
console.log(chalk.gray("─".repeat(40)));
|
|
104
|
-
for (const kitRef of circuit.kits) {
|
|
105
|
-
console.log(chalk.gray(` - ${kitRef.kitId}@${kitRef.version}`));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (circuit.boards.length > 0) {
|
|
110
|
-
console.log(chalk.bold("\nBoards"));
|
|
111
|
-
console.log(chalk.gray("─".repeat(40)));
|
|
112
|
-
for (const board of circuit.boards) {
|
|
113
|
-
console.log(chalk.gray(` - ${board.id}: ${board.name}`));
|
|
114
|
-
console.log(chalk.gray(` Columns: ${board.columns.map((c: { id: string; name: string }) => c.name).join(", ")}`));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (circuit.capabilities.length > 0) {
|
|
119
|
-
console.log(chalk.bold("\nCapabilities"));
|
|
120
|
-
console.log(chalk.gray("─".repeat(40)));
|
|
121
|
-
for (const capRef of circuit.capabilities) {
|
|
122
|
-
console.log(chalk.gray(` - ${capRef.blockId}@${capRef.version}`));
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (circuit.repository) {
|
|
127
|
-
console.log(chalk.bold("\nRepository"));
|
|
128
|
-
console.log(chalk.gray("─".repeat(40)));
|
|
129
|
-
console.log(chalk.gray(circuit.repository));
|
|
130
|
-
}
|
|
131
|
-
} catch (error) {
|
|
132
|
-
spinner.fail(`Failed to show info: ${error}`);
|
|
133
|
-
process.exit(1);
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// ============================================================================
|
|
139
|
-
// Command: circuit publish
|
|
140
|
-
// ============================================================================
|
|
141
|
-
|
|
142
|
-
function setupPublishCommand(program: Command): void {
|
|
143
|
-
program
|
|
144
|
-
.command("publish")
|
|
145
|
-
.description("Publish a Circuit to registry (simulated)")
|
|
146
|
-
.option("--dry-run", "Simulate publish without actually publishing")
|
|
147
|
-
.action(async (options) => {
|
|
148
|
-
const { dryRun } = options;
|
|
149
|
-
const spinner = ora(dryRun ? "Simulating publish..." : "Publishing Circuit...").start();
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
// Simulate publish
|
|
153
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
154
|
-
|
|
155
|
-
if (dryRun) {
|
|
156
|
-
spinner.succeed("Dry run: Circuit would be published");
|
|
157
|
-
} else {
|
|
158
|
-
spinner.succeed("Circuit published successfully");
|
|
159
|
-
console.log(chalk.gray("\nNote: Actual publishing requires registry authentication."));
|
|
160
|
-
}
|
|
161
|
-
} catch (error) {
|
|
162
|
-
spinner.fail(`Failed to publish: ${error}`);
|
|
163
|
-
process.exit(1);
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// ============================================================================
|
|
169
|
-
// Register Commands
|
|
170
|
-
// ============================================================================
|
|
171
|
-
|
|
172
|
-
/** Register all circuit commands with the program */
|
|
173
|
-
export function registerCircuitCommands(program: Command): void {
|
|
174
|
-
const circuitProgram = program
|
|
175
|
-
.command("circuit")
|
|
176
|
-
.description("Circuit commands")
|
|
177
|
-
.alias("c");
|
|
178
|
-
|
|
179
|
-
setupValidateCommand(circuitProgram);
|
|
180
|
-
setupInfoCommand(circuitProgram);
|
|
181
|
-
setupPublishCommand(circuitProgram);
|
|
182
|
-
}
|
package/src/commands/deploy.ts
DELETED
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BLKC CLI - Deploy Commands
|
|
3
|
-
*
|
|
4
|
-
* Commands for deploying BLKC content to BCM.
|
|
5
|
-
* This is the CLI half of the deploy functionality.
|
|
6
|
-
*
|
|
7
|
-
* @package @blkc-code/cli
|
|
8
|
-
* @license Apache-2.0
|
|
9
|
-
* @author Black Code Enterprises LLC
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { Command } from "commander";
|
|
13
|
-
import chalk from "chalk";
|
|
14
|
-
import ora from "ora";
|
|
15
|
-
import { readFile, writeFile, stat } from "node:fs/promises";
|
|
16
|
-
import path from "node:path";
|
|
17
|
-
import { safeParse } from "@blkc-code/core";
|
|
18
|
-
import { z } from "zod";
|
|
19
|
-
|
|
20
|
-
// ============================================================================
|
|
21
|
-
// Types
|
|
22
|
-
// ============================================================================
|
|
23
|
-
|
|
24
|
-
/** Deploy configuration schema */
|
|
25
|
-
const DeployConfigSchema = z.object({
|
|
26
|
-
apiUrl: z.string().url().default("https://api.blackcodemarket.com"),
|
|
27
|
-
authToken: z.string().optional(),
|
|
28
|
-
projectId: z.string().optional(),
|
|
29
|
-
siteId: z.string().optional(),
|
|
30
|
-
environment: z.enum(["development", "staging", "production"]).default("development"),
|
|
31
|
-
outputDir: z.string().default("dist"),
|
|
32
|
-
cleanOutputDir: z.boolean().default(true),
|
|
33
|
-
minify: z.boolean().default(true),
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
type DeployConfig = z.infer<typeof DeployConfigSchema>;
|
|
37
|
-
|
|
38
|
-
// ============================================================================
|
|
39
|
-
// Configuration Management
|
|
40
|
-
// ============================================================================
|
|
41
|
-
|
|
42
|
-
const CONFIG_FILE_NAME = "blkc.deploy.json";
|
|
43
|
-
|
|
44
|
-
/** Get the deploy config file path */
|
|
45
|
-
function getConfigPath(cwd?: string): string {
|
|
46
|
-
return path.resolve(cwd || process.cwd(), CONFIG_FILE_NAME);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/** Load deploy configuration */
|
|
50
|
-
async function loadConfig(cwd?: string): Promise<DeployConfig> {
|
|
51
|
-
const configPath = getConfigPath(cwd);
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
const content = await readFile(configPath, { encoding: "utf8" });
|
|
55
|
-
return safeParse(DeployConfigSchema, JSON.parse(content)) as DeployConfig;
|
|
56
|
-
} catch {
|
|
57
|
-
// Return default config if file doesn't exist
|
|
58
|
-
return DeployConfigSchema.parse({}) as DeployConfig;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** Save deploy configuration */
|
|
63
|
-
async function saveConfig(config: DeployConfig, cwd?: string): Promise<void> {
|
|
64
|
-
const configPath = getConfigPath(cwd);
|
|
65
|
-
await writeFile(configPath, JSON.stringify(config, null, 2), { encoding: "utf8" });
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/** Check if config file exists */
|
|
69
|
-
async function configExists(cwd?: string): Promise<boolean> {
|
|
70
|
-
const configPath = getConfigPath(cwd);
|
|
71
|
-
try {
|
|
72
|
-
await stat(configPath);
|
|
73
|
-
return true;
|
|
74
|
-
} catch {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// ============================================================================
|
|
80
|
-
// Command: deploy init
|
|
81
|
-
// ============================================================================
|
|
82
|
-
|
|
83
|
-
function setupInitCommand(program: Command): void {
|
|
84
|
-
program
|
|
85
|
-
.command("init")
|
|
86
|
-
.description("Initialize deployment configuration")
|
|
87
|
-
.option("--project-id <id>", "BCM project ID")
|
|
88
|
-
.option("--site-id <id>", "BCM site ID")
|
|
89
|
-
.option("--api-url <url>", "BCM API URL", "https://api.blackcodemarket.com")
|
|
90
|
-
.option("--environment <env>", "Environment", "development")
|
|
91
|
-
.option("-y, --yes", "Skip prompts and use defaults")
|
|
92
|
-
.action(async (options) => {
|
|
93
|
-
const spinner = ora("Initializing BLKC deploy configuration...").start();
|
|
94
|
-
|
|
95
|
-
try {
|
|
96
|
-
// Check if config already exists
|
|
97
|
-
const exists = await configExists();
|
|
98
|
-
if (exists && !options.yes) {
|
|
99
|
-
spinner.fail("Deploy configuration already exists. Use --yes to overwrite.");
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Create config
|
|
104
|
-
const config: DeployConfig = {
|
|
105
|
-
apiUrl: options.apiUrl,
|
|
106
|
-
projectId: options.projectId,
|
|
107
|
-
siteId: options.siteId,
|
|
108
|
-
environment: options.environment as DeployConfig["environment"],
|
|
109
|
-
outputDir: "dist",
|
|
110
|
-
cleanOutputDir: true,
|
|
111
|
-
minify: true,
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
await saveConfig(config);
|
|
115
|
-
|
|
116
|
-
spinner.succeed(`Deploy configuration initialized in ${CONFIG_FILE_NAME}`);
|
|
117
|
-
console.log(chalk.gray(`API URL: ${config.apiUrl}`));
|
|
118
|
-
console.log(chalk.gray(`Environment: ${config.environment}`));
|
|
119
|
-
if (config.projectId) {
|
|
120
|
-
console.log(chalk.gray(`Project ID: ${config.projectId}`));
|
|
121
|
-
}
|
|
122
|
-
if (config.siteId) {
|
|
123
|
-
console.log(chalk.gray(`Site ID: ${config.siteId}`));
|
|
124
|
-
}
|
|
125
|
-
} catch (error) {
|
|
126
|
-
spinner.fail(`Failed to initialize configuration: ${error}`);
|
|
127
|
-
process.exit(1);
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// ============================================================================
|
|
133
|
-
// Command: deploy preview
|
|
134
|
-
// ============================================================================
|
|
135
|
-
|
|
136
|
-
function setupPreviewCommand(program: Command): void {
|
|
137
|
-
program
|
|
138
|
-
.command("preview")
|
|
139
|
-
.description("Preview site before deployment")
|
|
140
|
-
.option("--port <port>", "Port to serve preview", "3000")
|
|
141
|
-
.option("--output-dir <dir>", "Output directory", "dist")
|
|
142
|
-
.action(async (options) => {
|
|
143
|
-
const spinner = ora("Starting preview server...").start();
|
|
144
|
-
|
|
145
|
-
try {
|
|
146
|
-
const { port, outputDir } = options;
|
|
147
|
-
const outputPath = path.resolve(process.cwd(), outputDir);
|
|
148
|
-
|
|
149
|
-
// Check if output directory exists
|
|
150
|
-
try {
|
|
151
|
-
await stat(outputPath);
|
|
152
|
-
} catch {
|
|
153
|
-
spinner.fail(`Output directory '${outputDir}' does not exist. Run 'npm run build' first.`);
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// In a real implementation, we would start a server here
|
|
158
|
-
// For now, just show a success message
|
|
159
|
-
spinner.succeed(`Preview server would start on http://localhost:${port}`);
|
|
160
|
-
console.log(chalk.yellow("Note: Preview server implementation requires a static file server."));
|
|
161
|
-
console.log(chalk.gray(`Output directory: ${outputPath}`));
|
|
162
|
-
console.log(chalk.gray(`To serve locally: npx serve -p ${port} ${outputPath}`));
|
|
163
|
-
} catch (error) {
|
|
164
|
-
spinner.fail(`Failed to start preview: ${error}`);
|
|
165
|
-
process.exit(1);
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// ============================================================================
|
|
171
|
-
// Command: deploy push
|
|
172
|
-
// ============================================================================
|
|
173
|
-
|
|
174
|
-
function setupPushCommand(program: Command): void {
|
|
175
|
-
program
|
|
176
|
-
.command("push")
|
|
177
|
-
.description("Deploy site to BCM")
|
|
178
|
-
.option("--message <message>", "Deploy message")
|
|
179
|
-
.option("--dry-run", "Simulate deployment without actually deploying")
|
|
180
|
-
.action(async (options) => {
|
|
181
|
-
const { message, dryRun } = options;
|
|
182
|
-
const spinner = ora(dryRun ? "Simulating deployment..." : "Deploying to BCM...").start();
|
|
183
|
-
|
|
184
|
-
try {
|
|
185
|
-
// Load config
|
|
186
|
-
const config = await loadConfig();
|
|
187
|
-
|
|
188
|
-
// Validate required fields
|
|
189
|
-
if (!config.projectId) {
|
|
190
|
-
spinner.fail("Project ID is required. Use 'blkc deploy init --project-id <id>' to set it.");
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (!config.siteId) {
|
|
195
|
-
spinner.fail("Site ID is required. Use 'blkc deploy init --site-id <id>' to set it.");
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (!config.authToken) {
|
|
200
|
-
spinner.fail("Auth token is required. Use 'blkc auth login' or set BCM_AUTH_TOKEN environment variable.");
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Check output directory
|
|
205
|
-
const outputPath = path.resolve(process.cwd(), config.outputDir);
|
|
206
|
-
try {
|
|
207
|
-
await stat(outputPath);
|
|
208
|
-
} catch {
|
|
209
|
-
spinner.fail(`Output directory '${config.outputDir}' does not exist. Run 'npm run build' first.`);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Simulate deployment
|
|
214
|
-
if (dryRun) {
|
|
215
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
216
|
-
spinner.succeed("Dry run: Deployment would be successful");
|
|
217
|
-
console.log(chalk.gray(`Project: ${config.projectId}`));
|
|
218
|
-
console.log(chalk.gray(`Site: ${config.siteId}`));
|
|
219
|
-
console.log(chalk.gray(`Environment: ${config.environment}`));
|
|
220
|
-
console.log(chalk.gray(`Message: ${message || "No message"}`));
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// In a real implementation, we would:
|
|
225
|
-
// 1. Create a deploy manifest
|
|
226
|
-
// 2. Upload files to BCM
|
|
227
|
-
// 3. Trigger deployment via API
|
|
228
|
-
// For now, simulate with a delay
|
|
229
|
-
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
230
|
-
|
|
231
|
-
const deployId = `deploy_${Date.now()}`;
|
|
232
|
-
spinner.succeed(`Deployed successfully!`);
|
|
233
|
-
console.log(chalk.green(`Deploy ID: ${deployId}`));
|
|
234
|
-
console.log(chalk.gray(`Project: ${config.projectId}`));
|
|
235
|
-
console.log(chalk.gray(`Site: ${config.siteId}`));
|
|
236
|
-
console.log(chalk.gray(`Environment: ${config.environment}`));
|
|
237
|
-
console.log(chalk.gray(`URL: https://${config.siteId}.blackcodemarket.com`));
|
|
238
|
-
} catch (error) {
|
|
239
|
-
spinner.fail(`Failed to deploy: ${error}`);
|
|
240
|
-
process.exit(1);
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// ============================================================================
|
|
246
|
-
// Command: deploy status
|
|
247
|
-
// ============================================================================
|
|
248
|
-
|
|
249
|
-
function setupStatusCommand(program: Command): void {
|
|
250
|
-
program
|
|
251
|
-
.command("status")
|
|
252
|
-
.description("Check deployment status")
|
|
253
|
-
.option("--deploy-id <id>", "Specific deploy ID to check")
|
|
254
|
-
.option("--limit <n>", "Number of recent deploys to show", "10")
|
|
255
|
-
.action(async (options) => {
|
|
256
|
-
const { deployId, limit } = options;
|
|
257
|
-
const spinner = ora("Checking deployment status...").start();
|
|
258
|
-
|
|
259
|
-
try {
|
|
260
|
-
const config = await loadConfig();
|
|
261
|
-
|
|
262
|
-
if (!config.projectId) {
|
|
263
|
-
spinner.fail("Project ID is required.");
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (!config.authToken) {
|
|
268
|
-
spinner.fail("Auth token is required.");
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Simulate status check
|
|
273
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
274
|
-
|
|
275
|
-
if (deployId) {
|
|
276
|
-
// Check specific deploy
|
|
277
|
-
spinner.succeed(`Deploy ${deployId}`);
|
|
278
|
-
console.log(chalk.gray("Status: " + chalk.green("Success")));
|
|
279
|
-
console.log(chalk.gray(`URL: https://${config.siteId}.blackcodemarket.com`));
|
|
280
|
-
} else {
|
|
281
|
-
// List recent deploys
|
|
282
|
-
spinner.succeed(`Recent deploys for ${config.projectId}`);
|
|
283
|
-
console.log(chalk.gray("\nLast 3 deploys:"));
|
|
284
|
-
|
|
285
|
-
for (let i = 0; i < Math.min(3, Number(limit)); i++) {
|
|
286
|
-
const fakeDeployId = `deploy_${Date.now() - i * 1000}`;
|
|
287
|
-
const status = i === 0 ? "Success" : i === 1 ? "Success" : "Failed";
|
|
288
|
-
const color = status === "Success" ? chalk.green : chalk.red;
|
|
289
|
-
console.log(` ${i + 1}. ${fakeDeployId} - ${color(status)} - 2026-11-02T12:00:00Z`);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
console.log(chalk.gray("\nUse --deploy-id to check a specific deploy."));
|
|
293
|
-
}
|
|
294
|
-
} catch (error) {
|
|
295
|
-
spinner.fail(`Failed to check status: ${error}`);
|
|
296
|
-
process.exit(1);
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// ============================================================================
|
|
302
|
-
// Command: deploy logs
|
|
303
|
-
// ============================================================================
|
|
304
|
-
|
|
305
|
-
function setupLogsCommand(program: Command): void {
|
|
306
|
-
program
|
|
307
|
-
.command("logs")
|
|
308
|
-
.description("View deployment logs")
|
|
309
|
-
.option("--deploy-id <id>", "Deploy ID to view logs for")
|
|
310
|
-
.option("--tail <n>", "Show last N lines", "100")
|
|
311
|
-
.option("--follow, -f", "Follow logs in real-time")
|
|
312
|
-
.action(async (options) => {
|
|
313
|
-
const { deployId, tail, follow } = options;
|
|
314
|
-
|
|
315
|
-
try {
|
|
316
|
-
const config = await loadConfig();
|
|
317
|
-
|
|
318
|
-
if (!config.projectId) {
|
|
319
|
-
console.error(chalk.red("Project ID is required."));
|
|
320
|
-
process.exit(1);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (!config.authToken) {
|
|
324
|
-
console.error(chalk.red("Auth token is required."));
|
|
325
|
-
process.exit(1);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
if (!deployId) {
|
|
329
|
-
console.error(chalk.red("Deploy ID is required. Use --deploy-id."));
|
|
330
|
-
process.exit(1);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
if (follow) {
|
|
334
|
-
console.log(chalk.yellow(`Following logs for deploy ${deployId}... (Ctrl+C to stop)`));
|
|
335
|
-
// In a real implementation, we would stream logs here
|
|
336
|
-
// For now, just simulate
|
|
337
|
-
for (let i = 0; i < 5; i++) {
|
|
338
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
339
|
-
console.log(`[2026-11-02T12:00:${String(i).padStart(2, "0")}] Building...`);
|
|
340
|
-
}
|
|
341
|
-
console.log(chalk.green(`[2026-11-02T12:00:05] Deploy complete!`));
|
|
342
|
-
} else {
|
|
343
|
-
console.log(chalk.gray(`Showing last ${tail} lines for deploy ${deployId}`));
|
|
344
|
-
console.log(chalk.gray("\n[2026-11-02T12:00:00] Starting deployment..."));
|
|
345
|
-
console.log(chalk.gray("[2026-11-02T12:00:01] Building static files..."));
|
|
346
|
-
console.log(chalk.gray("[2026-11-02T12:00:02] Uploading to BCM..."));
|
|
347
|
-
console.log(chalk.gray("[2026-11-02T12:00:03] Deploying..."));
|
|
348
|
-
console.log(chalk.gray("[2026-11-02T12:00:04] Successfully deployed!"));
|
|
349
|
-
}
|
|
350
|
-
} catch (error) {
|
|
351
|
-
console.error(chalk.red(`Failed to view logs: ${error}`));
|
|
352
|
-
process.exit(1);
|
|
353
|
-
}
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// ============================================================================
|
|
358
|
-
// Register Commands
|
|
359
|
-
// ============================================================================
|
|
360
|
-
|
|
361
|
-
/** Register all deploy commands with the program */
|
|
362
|
-
export function registerDeployCommands(program: Command): void {
|
|
363
|
-
const deployProgram = program
|
|
364
|
-
.command("deploy")
|
|
365
|
-
.description("Deployment commands")
|
|
366
|
-
.alias("d");
|
|
367
|
-
|
|
368
|
-
setupInitCommand(deployProgram);
|
|
369
|
-
setupPreviewCommand(deployProgram);
|
|
370
|
-
setupPushCommand(deployProgram);
|
|
371
|
-
setupStatusCommand(deployProgram);
|
|
372
|
-
setupLogsCommand(deployProgram);
|
|
373
|
-
}
|