@solidactions/cli 0.1.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 +56 -0
- package/dist/commands/deploy.js +454 -0
- package/dist/commands/env-create.js +87 -0
- package/dist/commands/env-delete.js +123 -0
- package/dist/commands/env-list.js +178 -0
- package/dist/commands/env-map.js +66 -0
- package/dist/commands/env-pull.js +134 -0
- package/dist/commands/init.js +97 -0
- package/dist/commands/logs-build.js +50 -0
- package/dist/commands/logs.js +103 -0
- package/dist/commands/pull.js +59 -0
- package/dist/commands/run.js +96 -0
- package/dist/commands/runs.js +97 -0
- package/dist/commands/schedule-delete.js +73 -0
- package/dist/commands/schedule-list.js +88 -0
- package/dist/commands/schedule-set.js +74 -0
- package/dist/index.js +191 -0
- package/package.json +58 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.logs = logs;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const init_1 = require("./init");
|
|
10
|
+
async function logs(runId, options) {
|
|
11
|
+
const config = (0, init_1.getConfig)();
|
|
12
|
+
if (!config?.apiKey) {
|
|
13
|
+
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
console.log(chalk_1.default.blue(`Fetching logs for run: ${runId}...`));
|
|
17
|
+
try {
|
|
18
|
+
// Get the run status first
|
|
19
|
+
const runResponse = await axios_1.default.get(`${config.host}/api/v1/runs/${runId}`, {
|
|
20
|
+
headers: {
|
|
21
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
22
|
+
'Accept': 'application/json',
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
const runData = runResponse.data;
|
|
26
|
+
console.log(chalk_1.default.gray(`Status: ${runData.status}`));
|
|
27
|
+
console.log(chalk_1.default.gray('---'));
|
|
28
|
+
// Get the logs for this run
|
|
29
|
+
const logsResponse = await axios_1.default.get(`${config.host}/api/v1/runs/${runId}/logs`, {
|
|
30
|
+
headers: {
|
|
31
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
32
|
+
'Accept': 'application/json',
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
let logEntries = logsResponse.data.logs || [];
|
|
36
|
+
displayLogs(logEntries);
|
|
37
|
+
if (options.follow && runData.status === 'running') {
|
|
38
|
+
console.log(chalk_1.default.gray('\n--- Following logs (Ctrl+C to stop) ---\n'));
|
|
39
|
+
const pollInterval = setInterval(async () => {
|
|
40
|
+
try {
|
|
41
|
+
const refreshResponse = await axios_1.default.get(`${config.host}/api/v1/runs/${runId}/logs`, {
|
|
42
|
+
headers: {
|
|
43
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
44
|
+
'Accept': 'application/json',
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
const newLogs = refreshResponse.data.logs || [];
|
|
48
|
+
const newEntries = newLogs.slice(logEntries.length);
|
|
49
|
+
displayLogs(newEntries);
|
|
50
|
+
logEntries = newLogs;
|
|
51
|
+
// Check if run is complete
|
|
52
|
+
const runStatus = await axios_1.default.get(`${config.host}/api/v1/runs/${runId}`, {
|
|
53
|
+
headers: {
|
|
54
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
55
|
+
'Accept': 'application/json',
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
if (['completed', 'failed', 'acknowledged'].includes(runStatus.data.status)) {
|
|
59
|
+
clearInterval(pollInterval);
|
|
60
|
+
console.log(chalk_1.default.gray(`\n--- Run ${runStatus.data.status} ---`));
|
|
61
|
+
process.exit(runStatus.data.status === 'completed' ? 0 : 1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Ignore transient errors during follow
|
|
66
|
+
}
|
|
67
|
+
}, 2000);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (error.response) {
|
|
72
|
+
if (error.response.status === 401) {
|
|
73
|
+
console.error(chalk_1.default.red('Authentication failed. Run "solidactions init <api-key>" to re-configure.'));
|
|
74
|
+
}
|
|
75
|
+
else if (error.response.status === 404) {
|
|
76
|
+
console.error(chalk_1.default.red('Run not found.'));
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
console.error(chalk_1.default.red(`Failed: ${error.response.status}`), error.response.data);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
console.error(chalk_1.default.red('Connection failed:'), error.message);
|
|
84
|
+
}
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function displayLogs(entries) {
|
|
89
|
+
for (const entry of entries) {
|
|
90
|
+
const timestamp = entry.timestamp ? new Date(entry.timestamp).toLocaleTimeString() : '??:??:??';
|
|
91
|
+
const stream = entry.stream || 'stdout';
|
|
92
|
+
const message = entry.message || entry.content || '';
|
|
93
|
+
let coloredMessage;
|
|
94
|
+
if (stream === 'stderr') {
|
|
95
|
+
coloredMessage = chalk_1.default.red(message);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
coloredMessage = chalk_1.default.white(message);
|
|
99
|
+
}
|
|
100
|
+
const streamIndicator = stream === 'stderr' ? chalk_1.default.red('[err]') : chalk_1.default.gray('[out]');
|
|
101
|
+
console.log(`${chalk_1.default.gray(`[${timestamp}]`)} ${streamIndicator} ${coloredMessage}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.pull = pull;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const axios_1 = __importDefault(require("axios"));
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
+
const adm_zip_1 = __importDefault(require("adm-zip"));
|
|
12
|
+
const init_1 = require("./init");
|
|
13
|
+
async function pull(projectName, destPath) {
|
|
14
|
+
const config = (0, init_1.getConfig)();
|
|
15
|
+
if (!config?.apiKey) {
|
|
16
|
+
console.error(chalk_1.default.red('Not initialized. Run `solidactions init <api-key>` first.'));
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const destination = destPath ? path_1.default.resolve(destPath) : process.cwd();
|
|
20
|
+
console.log(chalk_1.default.blue(`Pulling project "${projectName}"...`));
|
|
21
|
+
try {
|
|
22
|
+
const response = await axios_1.default.get(`${config.host}/api/v1/projects/${projectName}/source`, {
|
|
23
|
+
headers: {
|
|
24
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
25
|
+
'Accept': 'application/octet-stream',
|
|
26
|
+
},
|
|
27
|
+
responseType: 'arraybuffer',
|
|
28
|
+
});
|
|
29
|
+
const zipBuffer = Buffer.from(response.data);
|
|
30
|
+
const tempZipPath = path_1.default.join(destination, '.steps-pull-temp.zip');
|
|
31
|
+
// Write the zip to a temp file
|
|
32
|
+
fs_1.default.writeFileSync(tempZipPath, zipBuffer);
|
|
33
|
+
console.log(chalk_1.default.gray(`Downloaded ${zipBuffer.length} bytes`));
|
|
34
|
+
console.log(chalk_1.default.yellow(`Extracting to ${destination}...`));
|
|
35
|
+
// Extract the zip
|
|
36
|
+
const zip = new adm_zip_1.default(tempZipPath);
|
|
37
|
+
zip.extractAllTo(destination, true);
|
|
38
|
+
// Clean up temp file
|
|
39
|
+
fs_1.default.unlinkSync(tempZipPath);
|
|
40
|
+
console.log(chalk_1.default.green(`Project "${projectName}" pulled successfully!`));
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error.response) {
|
|
44
|
+
if (error.response.status === 404) {
|
|
45
|
+
console.error(chalk_1.default.red(`Project "${projectName}" not found.`));
|
|
46
|
+
}
|
|
47
|
+
else if (error.response.status === 401) {
|
|
48
|
+
console.error(chalk_1.default.red('Authentication failed. Run "solidactions init <api-key>" to re-configure.'));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
console.error(chalk_1.default.red(`Failed: ${error.response.status}`));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
console.error(chalk_1.default.red('Connection failed:'), error.message);
|
|
56
|
+
}
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.run = run;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const init_1 = require("./init");
|
|
10
|
+
async function run(projectName, workflowName, options) {
|
|
11
|
+
const config = (0, init_1.getConfig)();
|
|
12
|
+
if (!config?.apiKey) {
|
|
13
|
+
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
console.log(chalk_1.default.blue(`Running workflow "${workflowName}" in project "${projectName}"...`));
|
|
17
|
+
let inputData = {};
|
|
18
|
+
if (options.input) {
|
|
19
|
+
try {
|
|
20
|
+
inputData = JSON.parse(options.input);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
console.error(chalk_1.default.red('Invalid JSON input.'));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const response = await axios_1.default.post(`${config.host}/api/v1/projects/${projectName}/workflows/${workflowName}/trigger`, { input: inputData }, {
|
|
29
|
+
headers: {
|
|
30
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
31
|
+
'Accept': 'application/json',
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
const runData = response.data.run || response.data;
|
|
36
|
+
console.log(chalk_1.default.green(`Workflow triggered! Run ID: ${runData.id}`));
|
|
37
|
+
if (options.wait) {
|
|
38
|
+
console.log(chalk_1.default.gray('Waiting for completion...'));
|
|
39
|
+
let attempts = 0;
|
|
40
|
+
const maxAttempts = 300; // 5 minutes max
|
|
41
|
+
const poll = setInterval(async () => {
|
|
42
|
+
try {
|
|
43
|
+
attempts++;
|
|
44
|
+
const statusResponse = await axios_1.default.get(`${config.host}/api/v1/runs/${runData.id}`, {
|
|
45
|
+
headers: {
|
|
46
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
47
|
+
'Accept': 'application/json',
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
const status = statusResponse.data.status;
|
|
51
|
+
if (status === 'completed') {
|
|
52
|
+
clearInterval(poll);
|
|
53
|
+
console.log(chalk_1.default.green('\nWorkflow completed successfully!'));
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
else if (status === 'failed') {
|
|
57
|
+
clearInterval(poll);
|
|
58
|
+
console.error(chalk_1.default.red('\nWorkflow failed!'));
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
else if (attempts >= maxAttempts) {
|
|
62
|
+
clearInterval(poll);
|
|
63
|
+
console.error(chalk_1.default.yellow('\nTimeout waiting for workflow. It may still be running.'));
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
process.stdout.write('.');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Ignore transient errors
|
|
72
|
+
}
|
|
73
|
+
}, 1000);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (error.response) {
|
|
78
|
+
if (error.response.status === 401) {
|
|
79
|
+
console.error(chalk_1.default.red('Authentication failed. Run "solidactions init <api-key>" to re-configure.'));
|
|
80
|
+
}
|
|
81
|
+
else if (error.response.status === 404) {
|
|
82
|
+
console.error(chalk_1.default.red('Project or workflow not found.'));
|
|
83
|
+
}
|
|
84
|
+
else if (error.response.status === 422) {
|
|
85
|
+
console.error(chalk_1.default.red('Validation error:'), error.response.data.message);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
console.error(chalk_1.default.red(`Failed: ${error.response.status}`), error.response.data);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
console.error(chalk_1.default.red('Connection failed:'), error.message);
|
|
93
|
+
}
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runs = runs;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const init_1 = require("./init");
|
|
10
|
+
async function runs(projectName, options = {}) {
|
|
11
|
+
const config = (0, init_1.getConfig)();
|
|
12
|
+
if (!config?.apiKey) {
|
|
13
|
+
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
const limit = options.limit || 20;
|
|
17
|
+
console.log(chalk_1.default.blue(projectName ? `Recent runs for "${projectName}":` : 'Recent runs:'));
|
|
18
|
+
try {
|
|
19
|
+
const params = { limit };
|
|
20
|
+
if (projectName) {
|
|
21
|
+
params.project = projectName;
|
|
22
|
+
}
|
|
23
|
+
const response = await axios_1.default.get(`${config.host}/api/v1/runs`, {
|
|
24
|
+
headers: {
|
|
25
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
26
|
+
'Accept': 'application/json',
|
|
27
|
+
},
|
|
28
|
+
params,
|
|
29
|
+
});
|
|
30
|
+
const runsList = response.data.data || response.data;
|
|
31
|
+
if (!runsList || runsList.length === 0) {
|
|
32
|
+
console.log(chalk_1.default.gray('No runs found.'));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
console.log('');
|
|
36
|
+
console.log(chalk_1.default.gray('ID'.padEnd(38) + 'WORKFLOW'.padEnd(25) + 'STATUS'.padEnd(12) + 'STARTED'.padEnd(22) + 'DURATION'));
|
|
37
|
+
console.log(chalk_1.default.gray('-'.repeat(110)));
|
|
38
|
+
for (const run of runsList) {
|
|
39
|
+
const id = run.id || '?';
|
|
40
|
+
const workflow = run.workflow?.name || run.workflow_name || '?';
|
|
41
|
+
const status = run.status || '?';
|
|
42
|
+
const startedAt = run.started_at ? new Date(run.started_at).toLocaleString() : '-';
|
|
43
|
+
const duration = calculateDuration(run.started_at, run.completed_at);
|
|
44
|
+
const statusColor = getStatusColor(status);
|
|
45
|
+
console.log(chalk_1.default.gray(id.toString().padEnd(38)) +
|
|
46
|
+
workflow.padEnd(25) +
|
|
47
|
+
statusColor(status.padEnd(12)) +
|
|
48
|
+
chalk_1.default.gray(startedAt.padEnd(22)) +
|
|
49
|
+
chalk_1.default.gray(duration));
|
|
50
|
+
}
|
|
51
|
+
console.log('');
|
|
52
|
+
console.log(chalk_1.default.gray(`Showing ${runsList.length} run(s)`));
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (error.response) {
|
|
56
|
+
if (error.response.status === 401) {
|
|
57
|
+
console.error(chalk_1.default.red('Authentication failed. Run "solidactions init <api-key>" to re-configure.'));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.error(chalk_1.default.red(`Failed: ${error.response.status}`), error.response.data);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.error(chalk_1.default.red('Connection failed:'), error.message);
|
|
65
|
+
}
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function calculateDuration(startedAt, completedAt) {
|
|
70
|
+
if (!startedAt)
|
|
71
|
+
return '-';
|
|
72
|
+
const start = new Date(startedAt).getTime();
|
|
73
|
+
const end = completedAt ? new Date(completedAt).getTime() : Date.now();
|
|
74
|
+
const durationMs = end - start;
|
|
75
|
+
if (durationMs < 1000)
|
|
76
|
+
return `${durationMs}ms`;
|
|
77
|
+
if (durationMs < 60000)
|
|
78
|
+
return `${Math.round(durationMs / 1000)}s`;
|
|
79
|
+
if (durationMs < 3600000)
|
|
80
|
+
return `${Math.round(durationMs / 60000)}m`;
|
|
81
|
+
return `${Math.round(durationMs / 3600000)}h`;
|
|
82
|
+
}
|
|
83
|
+
function getStatusColor(status) {
|
|
84
|
+
switch (status.toLowerCase()) {
|
|
85
|
+
case 'completed':
|
|
86
|
+
return chalk_1.default.green;
|
|
87
|
+
case 'running':
|
|
88
|
+
return chalk_1.default.blue;
|
|
89
|
+
case 'pending':
|
|
90
|
+
case 'queued':
|
|
91
|
+
return chalk_1.default.yellow;
|
|
92
|
+
case 'failed':
|
|
93
|
+
return chalk_1.default.red;
|
|
94
|
+
default:
|
|
95
|
+
return chalk_1.default.gray;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.scheduleDelete = scheduleDelete;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
10
|
+
const init_1 = require("./init");
|
|
11
|
+
async function scheduleDelete(projectName, scheduleId, options = {}) {
|
|
12
|
+
const config = (0, init_1.getConfig)();
|
|
13
|
+
if (!config?.apiKey) {
|
|
14
|
+
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
console.log(chalk_1.default.blue(`Deleting schedule ${scheduleId} from project "${projectName}"...`));
|
|
18
|
+
try {
|
|
19
|
+
// First, get the schedule details for confirmation
|
|
20
|
+
const listResponse = await axios_1.default.get(`${config.host}/api/v1/projects/${projectName}/schedules`, {
|
|
21
|
+
headers: {
|
|
22
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
23
|
+
'Accept': 'application/json',
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
const schedules = listResponse.data || [];
|
|
27
|
+
const schedule = schedules.find((s) => s.id?.toString() === scheduleId);
|
|
28
|
+
if (!schedule) {
|
|
29
|
+
console.error(chalk_1.default.red(`Schedule ${scheduleId} not found in project "${projectName}".`));
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
// Confirm deletion unless --yes flag is provided
|
|
33
|
+
if (!options.yes) {
|
|
34
|
+
const response = await (0, prompts_1.default)({
|
|
35
|
+
type: 'confirm',
|
|
36
|
+
name: 'confirm',
|
|
37
|
+
message: `Delete schedule for workflow "${schedule.workflow_name || schedule.workflow_slug}" (${schedule.cron_expression})?`,
|
|
38
|
+
initial: false,
|
|
39
|
+
});
|
|
40
|
+
if (!response.confirm) {
|
|
41
|
+
console.log(chalk_1.default.gray('Cancelled.'));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Delete the schedule
|
|
46
|
+
await axios_1.default.delete(`${config.host}/api/v1/projects/${projectName}/schedules/${scheduleId}`, {
|
|
47
|
+
headers: {
|
|
48
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
49
|
+
'Accept': 'application/json',
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
console.log(chalk_1.default.green(`Schedule ${scheduleId} deleted successfully.`));
|
|
53
|
+
console.log(chalk_1.default.gray(` Workflow: ${schedule.workflow_name || schedule.workflow_slug}`));
|
|
54
|
+
console.log(chalk_1.default.gray(` Cron: ${schedule.cron_expression}`));
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (error.response) {
|
|
58
|
+
if (error.response.status === 401) {
|
|
59
|
+
console.error(chalk_1.default.red('Authentication failed. Run "solidactions init <api-key>" to re-configure.'));
|
|
60
|
+
}
|
|
61
|
+
else if (error.response.status === 404) {
|
|
62
|
+
console.error(chalk_1.default.red(`Project "${projectName}" or schedule ${scheduleId} not found.`));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
console.error(chalk_1.default.red(`Failed: ${error.response.status}`), error.response.data);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.error(chalk_1.default.red('Connection failed:'), error.message);
|
|
70
|
+
}
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.scheduleList = scheduleList;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const init_1 = require("./init");
|
|
10
|
+
async function scheduleList(projectName) {
|
|
11
|
+
const config = (0, init_1.getConfig)();
|
|
12
|
+
if (!config?.apiKey) {
|
|
13
|
+
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
console.log(chalk_1.default.blue(`Schedules for project "${projectName}":`));
|
|
17
|
+
try {
|
|
18
|
+
const response = await axios_1.default.get(`${config.host}/api/v1/projects/${projectName}/schedules`, {
|
|
19
|
+
headers: {
|
|
20
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
21
|
+
'Accept': 'application/json',
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
const schedules = response.data || [];
|
|
25
|
+
if (schedules.length === 0) {
|
|
26
|
+
console.log(chalk_1.default.gray('No schedules found.'));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
console.log('');
|
|
30
|
+
console.log(chalk_1.default.gray('ID'.padEnd(8) + 'WORKFLOW'.padEnd(25) + 'CRON'.padEnd(18) + 'ENABLED'.padEnd(10) + 'NEXT RUN'));
|
|
31
|
+
console.log(chalk_1.default.gray('-'.repeat(95)));
|
|
32
|
+
for (const schedule of schedules) {
|
|
33
|
+
const id = schedule.id?.toString() || '?';
|
|
34
|
+
const workflow = schedule.workflow_name || schedule.workflow_slug || '?';
|
|
35
|
+
const cron = schedule.cron_expression || '?';
|
|
36
|
+
const enabled = schedule.enabled;
|
|
37
|
+
const nextRun = schedule.next_run_at ? formatRelativeTime(schedule.next_run_at) : '-';
|
|
38
|
+
const enabledColor = enabled ? chalk_1.default.green : chalk_1.default.red;
|
|
39
|
+
console.log(chalk_1.default.gray(id.padEnd(8)) +
|
|
40
|
+
workflow.padEnd(25) +
|
|
41
|
+
chalk_1.default.cyan(cron.padEnd(18)) +
|
|
42
|
+
enabledColor((enabled ? 'yes' : 'no').padEnd(10)) +
|
|
43
|
+
chalk_1.default.gray(nextRun));
|
|
44
|
+
}
|
|
45
|
+
console.log('');
|
|
46
|
+
console.log(chalk_1.default.gray(`${schedules.length} schedule(s)`));
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (error.response) {
|
|
50
|
+
if (error.response.status === 401) {
|
|
51
|
+
console.error(chalk_1.default.red('Authentication failed. Run "solidactions init <api-key>" to re-configure.'));
|
|
52
|
+
}
|
|
53
|
+
else if (error.response.status === 404) {
|
|
54
|
+
console.error(chalk_1.default.red(`Project "${projectName}" not found.`));
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
console.error(chalk_1.default.red(`Failed: ${error.response.status}`), error.response.data);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
console.error(chalk_1.default.red('Connection failed:'), error.message);
|
|
62
|
+
}
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function formatRelativeTime(isoDate) {
|
|
67
|
+
const date = new Date(isoDate);
|
|
68
|
+
const now = new Date();
|
|
69
|
+
const diffMs = date.getTime() - now.getTime();
|
|
70
|
+
if (diffMs < 0) {
|
|
71
|
+
return 'overdue';
|
|
72
|
+
}
|
|
73
|
+
const diffMinutes = Math.floor(diffMs / (1000 * 60));
|
|
74
|
+
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
|
75
|
+
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
76
|
+
if (diffMinutes < 60) {
|
|
77
|
+
return `in ${diffMinutes}m`;
|
|
78
|
+
}
|
|
79
|
+
else if (diffHours < 24) {
|
|
80
|
+
return `in ${diffHours}h`;
|
|
81
|
+
}
|
|
82
|
+
else if (diffDays < 7) {
|
|
83
|
+
return `in ${diffDays}d`;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
return date.toLocaleDateString();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.scheduleSet = scheduleSet;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const init_1 = require("./init");
|
|
10
|
+
async function scheduleSet(projectName, cron, options) {
|
|
11
|
+
const config = (0, init_1.getConfig)();
|
|
12
|
+
if (!config?.apiKey) {
|
|
13
|
+
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
console.log(chalk_1.default.blue(`Setting schedule for project "${projectName}"...`));
|
|
17
|
+
// Parse input JSON if provided
|
|
18
|
+
let inputData;
|
|
19
|
+
if (options.input) {
|
|
20
|
+
try {
|
|
21
|
+
inputData = JSON.parse(options.input);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
console.error(chalk_1.default.red('Invalid JSON input.'));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const payload = {
|
|
30
|
+
cron,
|
|
31
|
+
};
|
|
32
|
+
if (options.workflow) {
|
|
33
|
+
payload.workflow = options.workflow;
|
|
34
|
+
}
|
|
35
|
+
if (inputData) {
|
|
36
|
+
payload.input = inputData;
|
|
37
|
+
}
|
|
38
|
+
await axios_1.default.post(`${config.host}/api/v1/projects/${projectName}/schedules`, payload, {
|
|
39
|
+
headers: {
|
|
40
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
41
|
+
'Accept': 'application/json',
|
|
42
|
+
'Content-Type': 'application/json',
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
console.log(chalk_1.default.green(`Schedule set successfully!`));
|
|
46
|
+
console.log(chalk_1.default.gray(` Cron: ${cron}`));
|
|
47
|
+
if (options.workflow) {
|
|
48
|
+
console.log(chalk_1.default.gray(` Workflow: ${options.workflow}`));
|
|
49
|
+
}
|
|
50
|
+
if (inputData) {
|
|
51
|
+
console.log(chalk_1.default.gray(` Input: ${JSON.stringify(inputData)}`));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (error.response) {
|
|
56
|
+
if (error.response.status === 401) {
|
|
57
|
+
console.error(chalk_1.default.red('Authentication failed. Run "solidactions init <api-key>" to re-configure.'));
|
|
58
|
+
}
|
|
59
|
+
else if (error.response.status === 404) {
|
|
60
|
+
console.error(chalk_1.default.red(`Project "${projectName}" not found.`));
|
|
61
|
+
}
|
|
62
|
+
else if (error.response.status === 422) {
|
|
63
|
+
console.error(chalk_1.default.red('Validation error:'), error.response.data.message || error.response.data.errors);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.error(chalk_1.default.red(`Failed: ${error.response.status}`), error.response.data);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
console.error(chalk_1.default.red('Connection failed:'), error.message);
|
|
71
|
+
}
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
}
|