@solidactions/cli 0.7.0 → 0.7.3
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/deploy.js +16 -27
- package/dist/commands/env-delete.js +6 -22
- package/dist/commands/env-list.js +4 -14
- package/dist/commands/env-map.js +4 -15
- package/dist/commands/env-pull.js +4 -14
- package/dist/commands/env-push.js +4 -15
- package/dist/commands/env-set.js +6 -25
- package/dist/commands/init.js +18 -2
- package/dist/commands/logs-build.js +3 -10
- package/dist/commands/logs.js +6 -22
- package/dist/commands/pull.js +3 -10
- package/dist/commands/run.js +4 -15
- package/dist/commands/runs.js +3 -10
- package/dist/commands/schedule-delete.js +4 -14
- package/dist/commands/schedule-list.js +3 -10
- package/dist/commands/schedule-set.js +3 -11
- package/dist/commands/steps.js +5 -18
- package/dist/commands/webhooks.js +3 -10
- package/dist/commands/workspaces.js +89 -0
- package/dist/index.js +18 -0
- package/dist/utils/api.js +129 -0
- package/package.json +1 -1
package/dist/commands/deploy.js
CHANGED
|
@@ -11,8 +11,8 @@ const axios_1 = __importDefault(require("axios"));
|
|
|
11
11
|
const form_data_1 = __importDefault(require("form-data"));
|
|
12
12
|
const chalk_1 = __importDefault(require("chalk"));
|
|
13
13
|
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
14
|
-
const init_1 = require("./init");
|
|
15
14
|
const env_1 = require("../utils/env");
|
|
15
|
+
const api_1 = require("../utils/api");
|
|
16
16
|
/**
|
|
17
17
|
* Validate project structure before deployment.
|
|
18
18
|
* Checks for required files and SDK dependency.
|
|
@@ -89,7 +89,7 @@ function validateProject(sourceDir) {
|
|
|
89
89
|
* Push YAML env declarations to the project.
|
|
90
90
|
* This registers all YAML-declared vars and their mappings.
|
|
91
91
|
*/
|
|
92
|
-
async function pushYamlDeclarations(
|
|
92
|
+
async function pushYamlDeclarations(config, projectSlug, yamlConfig) {
|
|
93
93
|
const parsedVars = (0, env_1.parseYamlEnvVars)(yamlConfig);
|
|
94
94
|
if (parsedVars.length === 0) {
|
|
95
95
|
return;
|
|
@@ -102,12 +102,8 @@ async function pushYamlDeclarations(host, apiKey, projectSlug, yamlConfig) {
|
|
|
102
102
|
source: 'yaml',
|
|
103
103
|
}));
|
|
104
104
|
try {
|
|
105
|
-
await axios_1.default.post(`${host}/api/v1/projects/${projectSlug}/variable-mappings/sync-yaml`, { declarations }, {
|
|
106
|
-
headers:
|
|
107
|
-
'Authorization': `Bearer ${apiKey}`,
|
|
108
|
-
'Accept': 'application/json',
|
|
109
|
-
'Content-Type': 'application/json',
|
|
110
|
-
},
|
|
105
|
+
await axios_1.default.post(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings/sync-yaml`, { declarations }, {
|
|
106
|
+
headers: (0, api_1.getApiHeaders)(config, 'application/json'),
|
|
111
107
|
});
|
|
112
108
|
console.log(chalk_1.default.gray(`Synced ${declarations.length} YAML env declarations`));
|
|
113
109
|
}
|
|
@@ -116,11 +112,7 @@ async function pushYamlDeclarations(host, apiKey, projectSlug, yamlConfig) {
|
|
|
116
112
|
}
|
|
117
113
|
}
|
|
118
114
|
async function deploy(projectName, sourcePath, options = {}) {
|
|
119
|
-
const config = (0,
|
|
120
|
-
if (!config?.apiKey) {
|
|
121
|
-
console.error(chalk_1.default.red('Not initialized. Run `solidactions init <api-key>` first.'));
|
|
122
|
-
process.exit(1);
|
|
123
|
-
}
|
|
115
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
124
116
|
const sourceDir = sourcePath ? path_1.default.resolve(sourcePath) : process.cwd();
|
|
125
117
|
const environment = options.env || 'dev';
|
|
126
118
|
if (!fs_1.default.existsSync(sourceDir)) {
|
|
@@ -165,10 +157,7 @@ async function deploy(projectName, sourcePath, options = {}) {
|
|
|
165
157
|
? projectName
|
|
166
158
|
: `${projectName}-${environment}`;
|
|
167
159
|
const checkResponse = await axios_1.default.get(`${config.host}/api/v1/projects/${lookupSlug}`, {
|
|
168
|
-
headers:
|
|
169
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
170
|
-
'Accept': 'application/json',
|
|
171
|
-
},
|
|
160
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
172
161
|
});
|
|
173
162
|
projectSlug = checkResponse.data.slug || checkResponse.data.name;
|
|
174
163
|
}
|
|
@@ -187,11 +176,7 @@ async function deploy(projectName, sourcePath, options = {}) {
|
|
|
187
176
|
slug: projectName.toLowerCase().replace(/[^a-z0-9-]/g, '-') + (environment !== 'production' ? `-${environment}` : ''),
|
|
188
177
|
environment: environment,
|
|
189
178
|
}, {
|
|
190
|
-
headers:
|
|
191
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
192
|
-
'Accept': 'application/json',
|
|
193
|
-
'Content-Type': 'application/json',
|
|
194
|
-
},
|
|
179
|
+
headers: (0, api_1.getApiHeaders)(config, 'application/json'),
|
|
195
180
|
});
|
|
196
181
|
projectSlug = createResponse.data.slug || createResponse.data.name;
|
|
197
182
|
console.log(chalk_1.default.green(`Project "${projectName}"${envLabel} created.`));
|
|
@@ -218,8 +203,7 @@ async function deploy(projectName, sourcePath, options = {}) {
|
|
|
218
203
|
await axios_1.default.post(`${config.host}/api/v1/projects/${projectSlug}/deploy`, form, {
|
|
219
204
|
headers: {
|
|
220
205
|
...form.getHeaders(),
|
|
221
|
-
|
|
222
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
206
|
+
...(0, api_1.getApiHeaders)(config),
|
|
223
207
|
},
|
|
224
208
|
maxContentLength: Infinity,
|
|
225
209
|
maxBodyLength: Infinity
|
|
@@ -228,13 +212,13 @@ async function deploy(projectName, sourcePath, options = {}) {
|
|
|
228
212
|
console.log(chalk_1.default.yellow('Waiting for build to complete...\n'));
|
|
229
213
|
// Poll for completion
|
|
230
214
|
let attempts = 0;
|
|
231
|
-
const maxAttempts =
|
|
215
|
+
const maxAttempts = 600; // 10 minutes of inactivity timeout
|
|
232
216
|
let lastLogLength = 0;
|
|
233
217
|
const poll = setInterval(async () => {
|
|
234
218
|
try {
|
|
235
219
|
attempts++;
|
|
236
220
|
const statusRes = await axios_1.default.get(`${config.host}/api/v1/projects/${projectSlug}`, {
|
|
237
|
-
headers:
|
|
221
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
238
222
|
});
|
|
239
223
|
const { status, build_log } = statusRes.data;
|
|
240
224
|
// Stream new log content
|
|
@@ -245,13 +229,18 @@ async function deploy(projectName, sourcePath, options = {}) {
|
|
|
245
229
|
process.stdout.write('\n');
|
|
246
230
|
}
|
|
247
231
|
lastLogLength = build_log.length;
|
|
232
|
+
attempts = 0; // Reset timeout — build is still progressing
|
|
233
|
+
}
|
|
234
|
+
// Periodic waiting indicator when no logs yet
|
|
235
|
+
if (attempts > 0 && attempts % 15 === 0 && lastLogLength === 0) {
|
|
236
|
+
console.log(chalk_1.default.gray('Still waiting for build to start...'));
|
|
248
237
|
}
|
|
249
238
|
if (status === 'deployed') {
|
|
250
239
|
clearInterval(poll);
|
|
251
240
|
console.log(chalk_1.default.green(`\n✓ Deployed to ${projectSlug}${envLabel}!`));
|
|
252
241
|
// Always sync YAML declarations (registers env vars and their mappings)
|
|
253
242
|
if (yamlConfig) {
|
|
254
|
-
await pushYamlDeclarations(config
|
|
243
|
+
await pushYamlDeclarations(config, projectSlug, yamlConfig);
|
|
255
244
|
}
|
|
256
245
|
fs_1.default.unlinkSync(archivePath);
|
|
257
246
|
process.exit(0);
|
|
@@ -7,13 +7,9 @@ exports.envDelete = envDelete;
|
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const prompts_1 = __importDefault(require("prompts"));
|
|
10
|
-
const
|
|
10
|
+
const api_1 = require("../utils/api");
|
|
11
11
|
async function envDelete(keyOrProject, keyIfProject, options = {}) {
|
|
12
|
-
const config = (0,
|
|
13
|
-
if (!config?.apiKey) {
|
|
14
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
15
|
-
process.exit(1);
|
|
16
|
-
}
|
|
12
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
17
13
|
// Determine mode: if keyIfProject is provided, it's project mapping delete
|
|
18
14
|
const isProjectMode = keyIfProject !== undefined;
|
|
19
15
|
const projectName = isProjectMode ? keyOrProject : undefined;
|
|
@@ -24,10 +20,7 @@ async function envDelete(keyOrProject, keyIfProject, options = {}) {
|
|
|
24
20
|
console.log(chalk_1.default.blue(`Deleting variable mapping "${key}" from project "${projectName}"...`));
|
|
25
21
|
// First, get the mapping to find its ID
|
|
26
22
|
const listResponse = await axios_1.default.get(`${config.host}/api/v1/projects/${projectName}/variable-mappings`, {
|
|
27
|
-
headers:
|
|
28
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
29
|
-
'Accept': 'application/json',
|
|
30
|
-
},
|
|
23
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
31
24
|
});
|
|
32
25
|
const mappings = listResponse.data || [];
|
|
33
26
|
const mapping = mappings.find((m) => m.env_name === key);
|
|
@@ -52,10 +45,7 @@ async function envDelete(keyOrProject, keyIfProject, options = {}) {
|
|
|
52
45
|
}
|
|
53
46
|
// Delete the mapping
|
|
54
47
|
await axios_1.default.delete(`${config.host}/api/v1/projects/${projectName}/variable-mappings/${mapping.id}`, {
|
|
55
|
-
headers:
|
|
56
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
57
|
-
'Accept': 'application/json',
|
|
58
|
-
},
|
|
48
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
59
49
|
});
|
|
60
50
|
if (mapping.is_yaml_declared) {
|
|
61
51
|
console.log(chalk_1.default.green(`Variable mapping "${key}" cleared successfully.`));
|
|
@@ -69,10 +59,7 @@ async function envDelete(keyOrProject, keyIfProject, options = {}) {
|
|
|
69
59
|
console.log(chalk_1.default.blue(`Deleting global variable "${key}"...`));
|
|
70
60
|
// First, get the variable to find its ID
|
|
71
61
|
const listResponse = await axios_1.default.get(`${config.host}/api/v1/variables`, {
|
|
72
|
-
headers:
|
|
73
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
74
|
-
'Accept': 'application/json',
|
|
75
|
-
},
|
|
62
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
76
63
|
});
|
|
77
64
|
const variables = listResponse.data?.data || [];
|
|
78
65
|
const variable = variables.find((v) => v.key === key);
|
|
@@ -95,10 +82,7 @@ async function envDelete(keyOrProject, keyIfProject, options = {}) {
|
|
|
95
82
|
}
|
|
96
83
|
// Delete the variable
|
|
97
84
|
await axios_1.default.delete(`${config.host}/api/v1/variables/${variable.id}`, {
|
|
98
|
-
headers:
|
|
99
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
100
|
-
'Accept': 'application/json',
|
|
101
|
-
},
|
|
85
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
102
86
|
});
|
|
103
87
|
console.log(chalk_1.default.green(`Global variable "${key}" deleted successfully.`));
|
|
104
88
|
}
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.envList = envList;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const
|
|
9
|
+
const api_1 = require("../utils/api");
|
|
10
10
|
/**
|
|
11
11
|
* Format a value for display, with inherited badge if applicable.
|
|
12
12
|
*/
|
|
@@ -27,11 +27,7 @@ function formatEnvValue(value, source, isSecret) {
|
|
|
27
27
|
return displayValue;
|
|
28
28
|
}
|
|
29
29
|
async function envList(projectName, options = {}) {
|
|
30
|
-
const config = (0,
|
|
31
|
-
if (!config?.apiKey) {
|
|
32
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
33
|
-
process.exit(1);
|
|
34
|
-
}
|
|
30
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
35
31
|
try {
|
|
36
32
|
if (projectName) {
|
|
37
33
|
// List project variable mappings
|
|
@@ -41,10 +37,7 @@ async function envList(projectName, options = {}) {
|
|
|
41
37
|
: `${projectName}-${environment}`;
|
|
42
38
|
console.log(chalk_1.default.blue(`Environment variables for project "${projectName}" (${environment}):`));
|
|
43
39
|
const response = await axios_1.default.get(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings`, {
|
|
44
|
-
headers:
|
|
45
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
46
|
-
'Accept': 'application/json',
|
|
47
|
-
},
|
|
40
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
48
41
|
});
|
|
49
42
|
const mappings = response.data || [];
|
|
50
43
|
if (mappings.length === 0) {
|
|
@@ -99,10 +92,7 @@ async function envList(projectName, options = {}) {
|
|
|
99
92
|
// List global variables with per-environment values
|
|
100
93
|
console.log(chalk_1.default.blue('Global environment variables:'));
|
|
101
94
|
const response = await axios_1.default.get(`${config.host}/api/v1/variables`, {
|
|
102
|
-
headers:
|
|
103
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
104
|
-
'Accept': 'application/json',
|
|
105
|
-
},
|
|
95
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
106
96
|
});
|
|
107
97
|
const variables = response.data?.data || [];
|
|
108
98
|
if (variables.length === 0) {
|
package/dist/commands/env-map.js
CHANGED
|
@@ -6,21 +6,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.envMap = envMap;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const
|
|
9
|
+
const api_1 = require("../utils/api");
|
|
10
10
|
async function envMap(projectName, projectKey, globalKey) {
|
|
11
|
-
const config = (0,
|
|
12
|
-
if (!config?.apiKey) {
|
|
13
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
11
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
16
12
|
console.log(chalk_1.default.blue(`Mapping global variable "${globalKey}" to project key "${projectKey}" in "${projectName}"...`));
|
|
17
13
|
try {
|
|
18
14
|
// First, get the global variable ID by key
|
|
19
15
|
const varsResponse = await axios_1.default.get(`${config.host}/api/v1/variables`, {
|
|
20
|
-
headers:
|
|
21
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
22
|
-
'Accept': 'application/json',
|
|
23
|
-
},
|
|
16
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
24
17
|
});
|
|
25
18
|
const variables = varsResponse.data.data || varsResponse.data;
|
|
26
19
|
const globalVar = variables.find((v) => v.key === globalKey);
|
|
@@ -34,11 +27,7 @@ async function envMap(projectName, projectKey, globalKey) {
|
|
|
34
27
|
project_key: projectKey,
|
|
35
28
|
global_variable_id: globalVar.id,
|
|
36
29
|
}, {
|
|
37
|
-
headers:
|
|
38
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
39
|
-
'Accept': 'application/json',
|
|
40
|
-
'Content-Type': 'application/json',
|
|
41
|
-
},
|
|
30
|
+
headers: (0, api_1.getApiHeaders)(config, 'application/json'),
|
|
42
31
|
});
|
|
43
32
|
console.log(chalk_1.default.green(`Variable mapping created!`));
|
|
44
33
|
console.log(chalk_1.default.gray(` ${globalKey} -> ${projectKey} (in ${projectName})`));
|
|
@@ -9,7 +9,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const axios_1 = __importDefault(require("axios"));
|
|
10
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
11
|
const readline_1 = __importDefault(require("readline"));
|
|
12
|
-
const
|
|
12
|
+
const api_1 = require("../utils/api");
|
|
13
13
|
/**
|
|
14
14
|
* Prompt the user for confirmation (unless --yes flag is set).
|
|
15
15
|
*/
|
|
@@ -26,11 +26,7 @@ async function confirm(message) {
|
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
async function envPull(projectName, options = {}) {
|
|
29
|
-
const config = (0,
|
|
30
|
-
if (!config?.apiKey) {
|
|
31
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
29
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
34
30
|
const environment = options.env || 'dev';
|
|
35
31
|
// Build the project slug for lookup
|
|
36
32
|
const projectSlug = environment === 'production'
|
|
@@ -43,10 +39,7 @@ async function envPull(projectName, options = {}) {
|
|
|
43
39
|
try {
|
|
44
40
|
// First, check if there are any secrets
|
|
45
41
|
const checkResponse = await axios_1.default.get(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings?resolve_oauth=true`, {
|
|
46
|
-
headers:
|
|
47
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
48
|
-
'Accept': 'application/json',
|
|
49
|
-
},
|
|
42
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
50
43
|
});
|
|
51
44
|
const mappings = checkResponse.data || [];
|
|
52
45
|
if (mappings.length === 0) {
|
|
@@ -65,10 +58,7 @@ async function envPull(projectName, options = {}) {
|
|
|
65
58
|
}
|
|
66
59
|
// Now fetch with reveal=true to get actual values
|
|
67
60
|
const response = await axios_1.default.get(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings?reveal=true&resolve_oauth=true`, {
|
|
68
|
-
headers:
|
|
69
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
70
|
-
'Accept': 'application/json',
|
|
71
|
-
},
|
|
61
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
72
62
|
});
|
|
73
63
|
const variables = response.data || [];
|
|
74
64
|
// --update-oauth: Only pull OAuth tokens and merge into existing .env
|
|
@@ -9,14 +9,10 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const axios_1 = __importDefault(require("axios"));
|
|
10
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
11
|
const prompts_1 = __importDefault(require("prompts"));
|
|
12
|
-
const
|
|
12
|
+
const api_1 = require("../utils/api");
|
|
13
13
|
const env_1 = require("../utils/env");
|
|
14
14
|
async function envPush(projectName, sourcePath, options = {}) {
|
|
15
|
-
const config = (0,
|
|
16
|
-
if (!config?.apiKey) {
|
|
17
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
18
|
-
process.exit(1);
|
|
19
|
-
}
|
|
15
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
20
16
|
const sourceDir = path_1.default.resolve(sourcePath);
|
|
21
17
|
const environment = options.env || 'dev';
|
|
22
18
|
// Read solidactions.yaml
|
|
@@ -85,10 +81,7 @@ async function envPush(projectName, sourcePath, options = {}) {
|
|
|
85
81
|
let serverMappings = [];
|
|
86
82
|
try {
|
|
87
83
|
const response = await axios_1.default.get(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings`, {
|
|
88
|
-
headers:
|
|
89
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
90
|
-
'Accept': 'application/json',
|
|
91
|
-
},
|
|
84
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
92
85
|
});
|
|
93
86
|
serverMappings = response.data || [];
|
|
94
87
|
}
|
|
@@ -191,11 +184,7 @@ async function envPush(projectName, sourcePath, options = {}) {
|
|
|
191
184
|
}));
|
|
192
185
|
try {
|
|
193
186
|
const response = await axios_1.default.post(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings/bulk`, { variables }, {
|
|
194
|
-
headers:
|
|
195
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
196
|
-
'Accept': 'application/json',
|
|
197
|
-
'Content-Type': 'application/json',
|
|
198
|
-
},
|
|
187
|
+
headers: (0, api_1.getApiHeaders)(config, 'application/json'),
|
|
199
188
|
});
|
|
200
189
|
const { created, updated } = response.data;
|
|
201
190
|
console.log(chalk_1.default.green(`\n✓ Pushed ${toPush.length} variable(s) to ${projectSlug}`));
|
package/dist/commands/env-set.js
CHANGED
|
@@ -6,13 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.envSet = envSet;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const
|
|
9
|
+
const api_1 = require("../utils/api");
|
|
10
10
|
async function envSet(keyOrProject, valueOrKey, valueIfProject, options = {}) {
|
|
11
|
-
const config = (0,
|
|
12
|
-
if (!config?.apiKey) {
|
|
13
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
11
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
16
12
|
// Detect mode based on arguments
|
|
17
13
|
const isProjectMode = valueIfProject !== undefined;
|
|
18
14
|
if (isProjectMode) {
|
|
@@ -36,11 +32,7 @@ async function envSet(keyOrProject, valueOrKey, valueIfProject, options = {}) {
|
|
|
36
32
|
is_secret: isSecret,
|
|
37
33
|
}]
|
|
38
34
|
}, {
|
|
39
|
-
headers:
|
|
40
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
41
|
-
'Accept': 'application/json',
|
|
42
|
-
'Content-Type': 'application/json',
|
|
43
|
-
},
|
|
35
|
+
headers: (0, api_1.getApiHeaders)(config, 'application/json'),
|
|
44
36
|
});
|
|
45
37
|
const { created, updated } = response.data;
|
|
46
38
|
const action = created > 0 ? 'created' : 'updated';
|
|
@@ -100,31 +92,20 @@ async function envSet(keyOrProject, valueOrKey, valueIfProject, options = {}) {
|
|
|
100
92
|
try {
|
|
101
93
|
// Check if variable already exists
|
|
102
94
|
const getResponse = await axios_1.default.get(`${config.host}/api/v1/variables`, {
|
|
103
|
-
headers:
|
|
104
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
105
|
-
'Accept': 'application/json',
|
|
106
|
-
},
|
|
95
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
107
96
|
});
|
|
108
97
|
const variables = getResponse.data?.data || [];
|
|
109
98
|
const existing = variables.find((v) => v.key === key);
|
|
110
99
|
let action;
|
|
111
100
|
if (existing) {
|
|
112
101
|
await axios_1.default.put(`${config.host}/api/v1/variables/${existing.id}`, body, {
|
|
113
|
-
headers:
|
|
114
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
115
|
-
'Accept': 'application/json',
|
|
116
|
-
'Content-Type': 'application/json',
|
|
117
|
-
},
|
|
102
|
+
headers: (0, api_1.getApiHeaders)(config, 'application/json'),
|
|
118
103
|
});
|
|
119
104
|
action = 'updated';
|
|
120
105
|
}
|
|
121
106
|
else {
|
|
122
107
|
await axios_1.default.post(`${config.host}/api/v1/variables`, body, {
|
|
123
|
-
headers:
|
|
124
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
125
|
-
'Accept': 'application/json',
|
|
126
|
-
'Content-Type': 'application/json',
|
|
127
|
-
},
|
|
108
|
+
headers: (0, api_1.getApiHeaders)(config, 'application/json'),
|
|
128
109
|
});
|
|
129
110
|
action = 'created';
|
|
130
111
|
}
|
package/dist/commands/init.js
CHANGED
|
@@ -13,6 +13,8 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
13
13
|
const path_1 = __importDefault(require("path"));
|
|
14
14
|
const os_1 = __importDefault(require("os"));
|
|
15
15
|
const chalk_1 = __importDefault(require("chalk"));
|
|
16
|
+
const api_1 = require("../utils/api");
|
|
17
|
+
const workspaces_1 = require("./workspaces");
|
|
16
18
|
const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.solidactions');
|
|
17
19
|
const CONFIG_FILE = path_1.default.join(CONFIG_DIR, 'config.json');
|
|
18
20
|
function getConfig() {
|
|
@@ -63,13 +65,27 @@ async function init(apiKey, options) {
|
|
|
63
65
|
console.log(chalk_1.default.blue(`Initializing SolidActions CLI...`));
|
|
64
66
|
console.log(chalk_1.default.gray(`Host: ${host}`));
|
|
65
67
|
// Save the configuration
|
|
66
|
-
|
|
68
|
+
const config = {
|
|
67
69
|
host,
|
|
68
70
|
apiKey: apiKey.trim(),
|
|
69
|
-
}
|
|
71
|
+
};
|
|
72
|
+
saveConfig(config);
|
|
70
73
|
console.log(chalk_1.default.green('CLI initialized successfully!'));
|
|
71
74
|
console.log(chalk_1.default.gray(`Configuration saved to ${CONFIG_FILE}`));
|
|
72
75
|
console.log('');
|
|
76
|
+
// Set workspace — explicit flag or interactive prompt
|
|
77
|
+
try {
|
|
78
|
+
if (options.workspace) {
|
|
79
|
+
await (0, workspaces_1.workspaceSet)(options.workspace);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
await (0, api_1.ensureWorkspaceSelected)(config);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
console.log(chalk_1.default.yellow('Could not set workspace. Run `solidactions workspace:set` later.'));
|
|
87
|
+
}
|
|
88
|
+
console.log('');
|
|
73
89
|
console.log(chalk_1.default.blue('Quick start:'));
|
|
74
90
|
console.log(chalk_1.default.gray(' solidactions deploy <project-name> Deploy current directory'));
|
|
75
91
|
console.log(chalk_1.default.gray(' solidactions run <project> <workflow> Run a workflow'));
|
|
@@ -6,20 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.logsBuild = logsBuild;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const
|
|
9
|
+
const api_1 = require("../utils/api");
|
|
10
10
|
async function logsBuild(projectName) {
|
|
11
|
-
const config = (0,
|
|
12
|
-
if (!config?.apiKey) {
|
|
13
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
11
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
16
12
|
console.log(chalk_1.default.blue(`Fetching build logs for project "${projectName}"...`));
|
|
17
13
|
try {
|
|
18
14
|
const response = await axios_1.default.get(`${config.host}/api/v1/projects/${projectName}/build-log`, {
|
|
19
|
-
headers:
|
|
20
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
21
|
-
'Accept': 'application/json',
|
|
22
|
-
},
|
|
15
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
23
16
|
});
|
|
24
17
|
const buildLog = response.data.build_log || response.data;
|
|
25
18
|
if (!buildLog || buildLog.length === 0) {
|
package/dist/commands/logs.js
CHANGED
|
@@ -6,31 +6,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.logs = logs;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const
|
|
9
|
+
const api_1 = require("../utils/api");
|
|
10
10
|
async function logs(runId, options) {
|
|
11
|
-
const config = (0,
|
|
12
|
-
if (!config?.apiKey) {
|
|
13
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
11
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
16
12
|
console.log(chalk_1.default.blue(`Fetching logs for run: ${runId}...`));
|
|
17
13
|
try {
|
|
18
14
|
// Get the run status first
|
|
19
15
|
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
|
-
},
|
|
16
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
24
17
|
});
|
|
25
18
|
const runData = runResponse.data;
|
|
26
19
|
console.log(chalk_1.default.gray(`Status: ${runData.status}`));
|
|
27
20
|
console.log(chalk_1.default.gray('---'));
|
|
28
21
|
// Get the logs for this run
|
|
29
22
|
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
|
-
},
|
|
23
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
34
24
|
});
|
|
35
25
|
const errors = logsResponse.data.errors || [];
|
|
36
26
|
if (errors.length > 0) {
|
|
@@ -46,10 +36,7 @@ async function logs(runId, options) {
|
|
|
46
36
|
const pollInterval = setInterval(async () => {
|
|
47
37
|
try {
|
|
48
38
|
const refreshResponse = await axios_1.default.get(`${config.host}/api/v1/runs/${runId}/logs`, {
|
|
49
|
-
headers:
|
|
50
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
51
|
-
'Accept': 'application/json',
|
|
52
|
-
},
|
|
39
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
53
40
|
});
|
|
54
41
|
const newLogData = refreshResponse.data.logs || '';
|
|
55
42
|
if (newLogData.length > printed) {
|
|
@@ -58,10 +45,7 @@ async function logs(runId, options) {
|
|
|
58
45
|
}
|
|
59
46
|
// Check if run is complete
|
|
60
47
|
const runStatus = await axios_1.default.get(`${config.host}/api/v1/runs/${runId}`, {
|
|
61
|
-
headers:
|
|
62
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
63
|
-
'Accept': 'application/json',
|
|
64
|
-
},
|
|
48
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
65
49
|
});
|
|
66
50
|
if (['completed', 'failed', 'acknowledged'].includes(runStatus.data.status)) {
|
|
67
51
|
clearInterval(pollInterval);
|
package/dist/commands/pull.js
CHANGED
|
@@ -9,21 +9,14 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const axios_1 = __importDefault(require("axios"));
|
|
10
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
11
|
const adm_zip_1 = __importDefault(require("adm-zip"));
|
|
12
|
-
const
|
|
12
|
+
const api_1 = require("../utils/api");
|
|
13
13
|
async function pull(projectName, destPath) {
|
|
14
|
-
const config = (0,
|
|
15
|
-
if (!config?.apiKey) {
|
|
16
|
-
console.error(chalk_1.default.red('Not initialized. Run `solidactions init <api-key>` first.'));
|
|
17
|
-
process.exit(1);
|
|
18
|
-
}
|
|
14
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
19
15
|
const destination = destPath ? path_1.default.resolve(destPath) : process.cwd();
|
|
20
16
|
console.log(chalk_1.default.blue(`Pulling project "${projectName}"...`));
|
|
21
17
|
try {
|
|
22
18
|
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
|
-
},
|
|
19
|
+
headers: { ...(0, api_1.getApiHeaders)(config), 'Accept': 'application/octet-stream' },
|
|
27
20
|
responseType: 'arraybuffer',
|
|
28
21
|
});
|
|
29
22
|
const zipBuffer = Buffer.from(response.data);
|
package/dist/commands/run.js
CHANGED
|
@@ -6,13 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.run = run;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const
|
|
9
|
+
const api_1 = require("../utils/api");
|
|
10
10
|
async function run(projectName, workflowName, options) {
|
|
11
|
-
const config = (0,
|
|
12
|
-
if (!config?.apiKey) {
|
|
13
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
11
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
16
12
|
const environment = options.env || 'dev';
|
|
17
13
|
const projectSlug = environment === 'production'
|
|
18
14
|
? projectName
|
|
@@ -30,11 +26,7 @@ async function run(projectName, workflowName, options) {
|
|
|
30
26
|
}
|
|
31
27
|
try {
|
|
32
28
|
const response = await axios_1.default.post(`${config.host}/api/v1/projects/${projectSlug}/workflows/${workflowName}/trigger`, { input: inputData }, {
|
|
33
|
-
headers:
|
|
34
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
35
|
-
'Accept': 'application/json',
|
|
36
|
-
'Content-Type': 'application/json',
|
|
37
|
-
},
|
|
29
|
+
headers: (0, api_1.getApiHeaders)(config, 'application/json'),
|
|
38
30
|
});
|
|
39
31
|
const runData = response.data.run || response.data;
|
|
40
32
|
console.log(chalk_1.default.green(`Workflow triggered! Run ID: ${runData.id}`));
|
|
@@ -46,10 +38,7 @@ async function run(projectName, workflowName, options) {
|
|
|
46
38
|
try {
|
|
47
39
|
attempts++;
|
|
48
40
|
const statusResponse = await axios_1.default.get(`${config.host}/api/v1/runs/${runData.id}`, {
|
|
49
|
-
headers:
|
|
50
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
51
|
-
'Accept': 'application/json',
|
|
52
|
-
},
|
|
41
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
53
42
|
});
|
|
54
43
|
const status = statusResponse.data.status;
|
|
55
44
|
if (status === 'completed') {
|
package/dist/commands/runs.js
CHANGED
|
@@ -6,13 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.runs = runs;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const
|
|
9
|
+
const api_1 = require("../utils/api");
|
|
10
10
|
async function runs(projectName, options = {}) {
|
|
11
|
-
const config = (0,
|
|
12
|
-
if (!config?.apiKey) {
|
|
13
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
11
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
16
12
|
const limit = options.limit || 20;
|
|
17
13
|
console.log(chalk_1.default.blue(projectName ? `Recent runs for "${projectName}":` : 'Recent runs:'));
|
|
18
14
|
try {
|
|
@@ -21,10 +17,7 @@ async function runs(projectName, options = {}) {
|
|
|
21
17
|
params.project = projectName;
|
|
22
18
|
}
|
|
23
19
|
const response = await axios_1.default.get(`${config.host}/api/v1/runs`, {
|
|
24
|
-
headers:
|
|
25
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
26
|
-
'Accept': 'application/json',
|
|
27
|
-
},
|
|
20
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
28
21
|
params,
|
|
29
22
|
});
|
|
30
23
|
const runsList = response.data.data || response.data;
|
|
@@ -7,21 +7,14 @@ exports.scheduleDelete = scheduleDelete;
|
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const prompts_1 = __importDefault(require("prompts"));
|
|
10
|
-
const
|
|
10
|
+
const api_1 = require("../utils/api");
|
|
11
11
|
async function scheduleDelete(projectName, scheduleId, options = {}) {
|
|
12
|
-
const config = (0,
|
|
13
|
-
if (!config?.apiKey) {
|
|
14
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
15
|
-
process.exit(1);
|
|
16
|
-
}
|
|
12
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
17
13
|
console.log(chalk_1.default.blue(`Deleting schedule ${scheduleId} from project "${projectName}"...`));
|
|
18
14
|
try {
|
|
19
15
|
// First, get the schedule details for confirmation
|
|
20
16
|
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
|
-
},
|
|
17
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
25
18
|
});
|
|
26
19
|
const schedules = listResponse.data || [];
|
|
27
20
|
const schedule = schedules.find((s) => s.id?.toString() === scheduleId);
|
|
@@ -44,10 +37,7 @@ async function scheduleDelete(projectName, scheduleId, options = {}) {
|
|
|
44
37
|
}
|
|
45
38
|
// Delete the schedule
|
|
46
39
|
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
|
-
},
|
|
40
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
51
41
|
});
|
|
52
42
|
console.log(chalk_1.default.green(`Schedule ${scheduleId} deleted successfully.`));
|
|
53
43
|
console.log(chalk_1.default.gray(` Workflow: ${schedule.workflow_name || schedule.workflow_slug}`));
|
|
@@ -6,20 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.scheduleList = scheduleList;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const
|
|
9
|
+
const api_1 = require("../utils/api");
|
|
10
10
|
async function scheduleList(projectName) {
|
|
11
|
-
const config = (0,
|
|
12
|
-
if (!config?.apiKey) {
|
|
13
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
11
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
16
12
|
console.log(chalk_1.default.blue(`Schedules for project "${projectName}":`));
|
|
17
13
|
try {
|
|
18
14
|
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
|
-
},
|
|
15
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
23
16
|
});
|
|
24
17
|
const schedules = response.data || [];
|
|
25
18
|
if (schedules.length === 0) {
|
|
@@ -6,13 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.scheduleSet = scheduleSet;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const
|
|
9
|
+
const api_1 = require("../utils/api");
|
|
10
10
|
async function scheduleSet(projectName, cron, options) {
|
|
11
|
-
const config = (0,
|
|
12
|
-
if (!config?.apiKey) {
|
|
13
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
11
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
16
12
|
console.log(chalk_1.default.blue(`Setting schedule for project "${projectName}"...`));
|
|
17
13
|
// Parse input JSON if provided
|
|
18
14
|
let inputData;
|
|
@@ -36,11 +32,7 @@ async function scheduleSet(projectName, cron, options) {
|
|
|
36
32
|
payload.input = inputData;
|
|
37
33
|
}
|
|
38
34
|
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
|
-
},
|
|
35
|
+
headers: (0, api_1.getApiHeaders)(config, 'application/json'),
|
|
44
36
|
});
|
|
45
37
|
console.log(chalk_1.default.green(`Schedule set successfully!`));
|
|
46
38
|
console.log(chalk_1.default.gray(` Cron: ${cron}`));
|
package/dist/commands/steps.js
CHANGED
|
@@ -6,13 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.steps = steps;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const
|
|
9
|
+
const api_1 = require("../utils/api");
|
|
10
10
|
async function steps(runId, options) {
|
|
11
|
-
const config = (0,
|
|
12
|
-
if (!config?.apiKey) {
|
|
13
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
11
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
16
12
|
// Flag validation: --follow and --step are incompatible
|
|
17
13
|
if (options.follow && options.step) {
|
|
18
14
|
console.error(chalk_1.default.red('Cannot use --follow with --step.'));
|
|
@@ -20,10 +16,7 @@ async function steps(runId, options) {
|
|
|
20
16
|
}
|
|
21
17
|
try {
|
|
22
18
|
const response = await axios_1.default.get(`${config.host}/api/v1/runs/${runId}/steps`, {
|
|
23
|
-
headers:
|
|
24
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
25
|
-
'Accept': 'application/json',
|
|
26
|
-
},
|
|
19
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
27
20
|
});
|
|
28
21
|
const data = response.data;
|
|
29
22
|
// --json mode: output raw JSON and exit
|
|
@@ -68,16 +61,10 @@ async function steps(runId, options) {
|
|
|
68
61
|
const pollInterval = setInterval(async () => {
|
|
69
62
|
try {
|
|
70
63
|
const refreshResponse = await axios_1.default.get(`${config.host}/api/v1/runs/${runId}/steps`, {
|
|
71
|
-
headers:
|
|
72
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
73
|
-
'Accept': 'application/json',
|
|
74
|
-
},
|
|
64
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
75
65
|
});
|
|
76
66
|
const runStatus = await axios_1.default.get(`${config.host}/api/v1/runs/${runId}`, {
|
|
77
|
-
headers:
|
|
78
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
79
|
-
'Accept': 'application/json',
|
|
80
|
-
},
|
|
67
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
81
68
|
});
|
|
82
69
|
console.clear();
|
|
83
70
|
displayAllSteps(runId, refreshResponse.data);
|
|
@@ -6,13 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.webhookList = webhookList;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const
|
|
9
|
+
const api_1 = require("../utils/api");
|
|
10
10
|
async function webhookList(projectName, options = {}) {
|
|
11
|
-
const config = (0,
|
|
12
|
-
if (!config?.apiKey) {
|
|
13
|
-
console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
11
|
+
const config = await (0, api_1.requireConfigWithWorkspace)();
|
|
16
12
|
const environment = options.env || 'dev';
|
|
17
13
|
const projectSlug = environment === 'production' ? projectName : `${projectName}-${environment}`;
|
|
18
14
|
console.log(chalk_1.default.blue(`Webhooks for project "${projectName}"${environment !== 'production' ? ` (${environment})` : ''}:`));
|
|
@@ -22,10 +18,7 @@ async function webhookList(projectName, options = {}) {
|
|
|
22
18
|
params.show_secrets = 'true';
|
|
23
19
|
}
|
|
24
20
|
const response = await axios_1.default.get(`${config.host}/api/v1/projects/${projectSlug}/webhooks`, {
|
|
25
|
-
headers:
|
|
26
|
-
'Authorization': `Bearer ${config.apiKey}`,
|
|
27
|
-
'Accept': 'application/json',
|
|
28
|
-
},
|
|
21
|
+
headers: (0, api_1.getApiHeaders)(config),
|
|
29
22
|
params,
|
|
30
23
|
});
|
|
31
24
|
const webhooks = response.data || [];
|
|
@@ -0,0 +1,89 @@
|
|
|
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.workspacesList = workspacesList;
|
|
7
|
+
exports.workspaceSet = workspaceSet;
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const api_1 = require("../utils/api");
|
|
11
|
+
const init_1 = require("./init");
|
|
12
|
+
async function workspacesList() {
|
|
13
|
+
const config = (0, api_1.requireConfig)();
|
|
14
|
+
try {
|
|
15
|
+
const response = await axios_1.default.get(`${config.host}/api/v1/workspaces`, {
|
|
16
|
+
headers: {
|
|
17
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
18
|
+
'Accept': 'application/json',
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
// API returns { workspaces: { "Org Name": [{ id, name, role, tenant_name, ... }] } }
|
|
22
|
+
const grouped = response.data.workspaces || response.data.data || response.data;
|
|
23
|
+
let hasWorkspaces = false;
|
|
24
|
+
console.log(chalk_1.default.blue(`\nYour workspaces:\n`));
|
|
25
|
+
if (typeof grouped === 'object' && !Array.isArray(grouped)) {
|
|
26
|
+
for (const orgName of Object.keys(grouped)) {
|
|
27
|
+
console.log(` ${chalk_1.default.white(orgName)}`);
|
|
28
|
+
for (const ws of grouped[orgName]) {
|
|
29
|
+
hasWorkspaces = true;
|
|
30
|
+
const current = config.workspaceId === ws.id ? chalk_1.default.green(' ← current') : '';
|
|
31
|
+
console.log(` ${chalk_1.default.white(ws.name)} ${chalk_1.default.gray(`(${ws.role})`)}${current}`);
|
|
32
|
+
console.log(chalk_1.default.gray(` ID: ${ws.id}`));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else if (Array.isArray(grouped)) {
|
|
37
|
+
for (const ws of grouped) {
|
|
38
|
+
hasWorkspaces = true;
|
|
39
|
+
const current = config.workspaceId === ws.id ? chalk_1.default.green(' ← current') : '';
|
|
40
|
+
console.log(` ${chalk_1.default.white(ws.name)} ${chalk_1.default.gray(`(${ws.org_name || ''}, ${ws.role})`)}${current}`);
|
|
41
|
+
console.log(chalk_1.default.gray(` ID: ${ws.id}`));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (!hasWorkspaces) {
|
|
45
|
+
console.log(chalk_1.default.yellow('No workspaces found.'));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
console.log('');
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error(chalk_1.default.red('Failed to list workspaces:'), error.response?.data?.message || error.message);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function workspaceSet(workspaceId) {
|
|
56
|
+
const config = (0, api_1.requireConfig)();
|
|
57
|
+
// Validate the workspace exists and user has access
|
|
58
|
+
try {
|
|
59
|
+
const response = await axios_1.default.get(`${config.host}/api/v1/workspaces`, {
|
|
60
|
+
headers: {
|
|
61
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
62
|
+
'Accept': 'application/json',
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
// Flatten grouped response
|
|
66
|
+
const grouped = response.data.workspaces || response.data.data || response.data;
|
|
67
|
+
let allWorkspaces = [];
|
|
68
|
+
if (typeof grouped === 'object' && !Array.isArray(grouped)) {
|
|
69
|
+
for (const orgWorkspaces of Object.values(grouped)) {
|
|
70
|
+
allWorkspaces.push(...orgWorkspaces);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else if (Array.isArray(grouped)) {
|
|
74
|
+
allWorkspaces = grouped;
|
|
75
|
+
}
|
|
76
|
+
const workspace = allWorkspaces.find((w) => w.id === workspaceId || w.slug === workspaceId || w.name === workspaceId);
|
|
77
|
+
if (!workspace) {
|
|
78
|
+
console.error(chalk_1.default.red(`Workspace "${workspaceId}" not found. Run \`solidactions workspaces\` to list available workspaces.`));
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
config.workspaceId = workspace.id;
|
|
82
|
+
(0, init_1.saveConfig)(config);
|
|
83
|
+
console.log(chalk_1.default.green(`Workspace set to: ${workspace.name} (${workspace.id})`));
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error(chalk_1.default.red('Failed to set workspace:'), error.response?.data?.message || error.message);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ const webhooks_1 = require("./commands/webhooks");
|
|
|
23
23
|
const dev_1 = require("./commands/dev");
|
|
24
24
|
const ai_init_1 = require("./commands/ai-init");
|
|
25
25
|
const ai_examples_1 = require("./commands/ai-examples");
|
|
26
|
+
const workspaces_1 = require("./commands/workspaces");
|
|
26
27
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
27
28
|
const pkg = require('../package.json');
|
|
28
29
|
const program = new commander_1.Command();
|
|
@@ -39,6 +40,7 @@ program
|
|
|
39
40
|
.argument('<api-key>', 'Your SolidActions API key')
|
|
40
41
|
.option('--dev', 'Use local development server (http://localhost:8000)')
|
|
41
42
|
.option('--host <url>', 'Custom API host URL')
|
|
43
|
+
.option('--workspace <name-or-id>', 'Set workspace by name, slug, or ID (skips interactive prompt)')
|
|
42
44
|
.action((apiKey, options) => {
|
|
43
45
|
(0, init_1.init)(apiKey, options);
|
|
44
46
|
});
|
|
@@ -243,6 +245,22 @@ program
|
|
|
243
245
|
(0, webhooks_1.webhookList)(project, options);
|
|
244
246
|
});
|
|
245
247
|
// =============================================================================
|
|
248
|
+
// Workspaces
|
|
249
|
+
// =============================================================================
|
|
250
|
+
program
|
|
251
|
+
.command('workspaces')
|
|
252
|
+
.description('List your workspaces across all organizations')
|
|
253
|
+
.action(() => {
|
|
254
|
+
(0, workspaces_1.workspacesList)();
|
|
255
|
+
});
|
|
256
|
+
program
|
|
257
|
+
.command('workspace:set')
|
|
258
|
+
.description('Set the active workspace for CLI operations')
|
|
259
|
+
.argument('<workspace-id>', 'Workspace ID, slug, or name')
|
|
260
|
+
.action((workspaceId) => {
|
|
261
|
+
(0, workspaces_1.workspaceSet)(workspaceId);
|
|
262
|
+
});
|
|
263
|
+
// =============================================================================
|
|
246
264
|
// AI Helper
|
|
247
265
|
// =============================================================================
|
|
248
266
|
program
|
|
@@ -0,0 +1,129 @@
|
|
|
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.getApiHeaders = getApiHeaders;
|
|
7
|
+
exports.ensureWorkspaceSelected = ensureWorkspaceSelected;
|
|
8
|
+
exports.requireConfig = requireConfig;
|
|
9
|
+
exports.requireConfigWithWorkspace = requireConfigWithWorkspace;
|
|
10
|
+
const axios_1 = __importDefault(require("axios"));
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
const readline_1 = __importDefault(require("readline"));
|
|
13
|
+
const init_1 = require("../commands/init");
|
|
14
|
+
/**
|
|
15
|
+
* Get standard API headers including X-Workspace-Id if configured.
|
|
16
|
+
*/
|
|
17
|
+
function getApiHeaders(config, contentType) {
|
|
18
|
+
const headers = {
|
|
19
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
20
|
+
'Accept': 'application/json',
|
|
21
|
+
};
|
|
22
|
+
if (contentType) {
|
|
23
|
+
headers['Content-Type'] = contentType;
|
|
24
|
+
}
|
|
25
|
+
if (config.workspaceId) {
|
|
26
|
+
headers['X-Workspace-Id'] = config.workspaceId;
|
|
27
|
+
}
|
|
28
|
+
return headers;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Ensure a workspace is selected. If not configured, fetches workspaces and auto-selects
|
|
32
|
+
* (if only one) or prompts the user to choose.
|
|
33
|
+
*
|
|
34
|
+
* Returns the config with workspaceId set, or exits if no workspaces available.
|
|
35
|
+
*/
|
|
36
|
+
async function ensureWorkspaceSelected(config) {
|
|
37
|
+
if (config.workspaceId) {
|
|
38
|
+
return config;
|
|
39
|
+
}
|
|
40
|
+
// Fetch workspaces from API (this endpoint doesn't require X-Workspace-Id)
|
|
41
|
+
let workspaces;
|
|
42
|
+
try {
|
|
43
|
+
const response = await axios_1.default.get(`${config.host}/api/v1/workspaces`, {
|
|
44
|
+
headers: {
|
|
45
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
46
|
+
'Accept': 'application/json',
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
// API returns { workspaces: { "Org Name": [{ id, name, role, tenant_name, ... }] } }
|
|
50
|
+
// Flatten the grouped structure into a flat array
|
|
51
|
+
const grouped = response.data.workspaces || response.data.teams || response.data.data || response.data;
|
|
52
|
+
if (typeof grouped === 'object' && !Array.isArray(grouped)) {
|
|
53
|
+
workspaces = [];
|
|
54
|
+
for (const orgName of Object.keys(grouped)) {
|
|
55
|
+
for (const ws of grouped[orgName]) {
|
|
56
|
+
workspaces.push({
|
|
57
|
+
id: ws.id,
|
|
58
|
+
name: ws.name,
|
|
59
|
+
org_name: ws.tenant_name || orgName,
|
|
60
|
+
role: ws.role,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
workspaces = Array.isArray(grouped) ? grouped : [];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (error.response?.status === 401) {
|
|
71
|
+
console.error(chalk_1.default.red('Authentication failed. Run `solidactions init <api-key>` to reconfigure.'));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.error(chalk_1.default.red('Failed to fetch workspaces:'), error.response?.data?.message || error.message);
|
|
75
|
+
}
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
if (workspaces.length === 0) {
|
|
79
|
+
console.error(chalk_1.default.red('No workspaces found. Create a workspace at your SolidActions dashboard first.'));
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
let selected;
|
|
83
|
+
if (workspaces.length === 1) {
|
|
84
|
+
selected = workspaces[0];
|
|
85
|
+
console.log(chalk_1.default.gray(`Auto-selected workspace: ${selected.name}`));
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Prompt user to select
|
|
89
|
+
console.log(chalk_1.default.blue('\nSelect a workspace:\n'));
|
|
90
|
+
workspaces.forEach((ws, i) => {
|
|
91
|
+
console.log(` ${chalk_1.default.white(`${i + 1}.`)} ${ws.name} ${chalk_1.default.gray(`(${ws.org_name}, ${ws.role})`)}`);
|
|
92
|
+
});
|
|
93
|
+
console.log('');
|
|
94
|
+
const rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout });
|
|
95
|
+
const answer = await new Promise((resolve) => {
|
|
96
|
+
rl.question(chalk_1.default.blue('Enter number: '), resolve);
|
|
97
|
+
});
|
|
98
|
+
rl.close();
|
|
99
|
+
const index = parseInt(answer, 10) - 1;
|
|
100
|
+
if (isNaN(index) || index < 0 || index >= workspaces.length) {
|
|
101
|
+
console.error(chalk_1.default.red('Invalid selection.'));
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
selected = workspaces[index];
|
|
105
|
+
}
|
|
106
|
+
// Save workspace selection to config
|
|
107
|
+
config.workspaceId = selected.id;
|
|
108
|
+
(0, init_1.saveConfig)(config);
|
|
109
|
+
console.log(chalk_1.default.green(`Workspace set: ${selected.name}`));
|
|
110
|
+
return config;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get config and ensure it's initialized. Exits if not.
|
|
114
|
+
*/
|
|
115
|
+
function requireConfig() {
|
|
116
|
+
const config = (0, init_1.getConfig)();
|
|
117
|
+
if (!config?.apiKey) {
|
|
118
|
+
console.error(chalk_1.default.red('Not initialized. Run `solidactions init <api-key>` first.'));
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
return config;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get config with workspace selected. Use this for any command that needs workspace context.
|
|
125
|
+
*/
|
|
126
|
+
async function requireConfigWithWorkspace() {
|
|
127
|
+
const config = requireConfig();
|
|
128
|
+
return ensureWorkspaceSelected(config);
|
|
129
|
+
}
|