@solidactions/cli 0.4.0 → 0.5.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 CHANGED
@@ -36,6 +36,7 @@ solidactions deploy <project-name> <path>
36
36
  | `env:delete <key>` | Delete an environment variable |
37
37
  | `env:map <project> <key> <global-key>` | Map a global variable to a project |
38
38
  | `env:pull <project>` | Pull resolved env vars (including OAuth tokens) to a local file |
39
+ | `env:push <project> [path]` | Push .env values to a project |
39
40
  | `schedule:set <project> <cron>` | Set a cron schedule for a workflow |
40
41
  | `schedule:list <project>` | List schedules for a project |
41
42
  | `schedule:delete <project> <id>` | Delete a schedule |
@@ -12,6 +12,7 @@ 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
14
  const init_1 = require("./init");
15
+ const env_1 = require("../utils/env");
15
16
  /**
16
17
  * Validate project structure before deployment.
17
18
  * Checks for required files and SDK dependency.
@@ -84,94 +85,12 @@ function validateProject(sourceDir) {
84
85
  }
85
86
  return { valid: errors.length === 0, errors, warnings };
86
87
  }
87
- /**
88
- * Parse a .env file into a key-value map.
89
- */
90
- function parseEnvFile(filePath) {
91
- const envMap = new Map();
92
- if (!fs_1.default.existsSync(filePath)) {
93
- return envMap;
94
- }
95
- const content = fs_1.default.readFileSync(filePath, 'utf8');
96
- const lines = content.split('\n');
97
- for (const line of lines) {
98
- const trimmed = line.trim();
99
- // Skip empty lines and comments
100
- if (!trimmed || trimmed.startsWith('#')) {
101
- continue;
102
- }
103
- const equalsIndex = trimmed.indexOf('=');
104
- if (equalsIndex === -1) {
105
- continue;
106
- }
107
- const key = trimmed.substring(0, equalsIndex).trim();
108
- let value = trimmed.substring(equalsIndex + 1).trim();
109
- // Remove surrounding quotes if present
110
- if ((value.startsWith('"') && value.endsWith('"')) ||
111
- (value.startsWith("'") && value.endsWith("'"))) {
112
- value = value.slice(1, -1);
113
- }
114
- envMap.set(key, value);
115
- }
116
- return envMap;
117
- }
118
- /**
119
- * Parse YAML env declarations into structured format.
120
- * Handles the new simplified format:
121
- * - VAR_NAME -> { key: "VAR_NAME", mappedTo: null }
122
- * - VAR_NAME: GLOBAL -> { key: "VAR_NAME", mappedTo: "GLOBAL" }
123
- */
124
- function parseYamlEnvVars(config) {
125
- const parsedVars = [];
126
- if (!config.env || !Array.isArray(config.env)) {
127
- return parsedVars;
128
- }
129
- for (const item of config.env) {
130
- if (typeof item === 'string') {
131
- // Simple string: - VAR_NAME (declared only, needs configuration)
132
- parsedVars.push({ key: item, mappedTo: null, oauthName: null });
133
- }
134
- else if (typeof item === 'object' && item !== null) {
135
- // Object: - VAR_NAME: GLOBAL_NAME or - VAR_NAME: { oauth: connection-name }
136
- const keys = Object.keys(item);
137
- if (keys.length === 1) {
138
- const key = keys[0];
139
- const value = item[key];
140
- if (typeof value === 'object' && value !== null && 'oauth' in value) {
141
- if (typeof value.oauth !== 'string' || !value.oauth) {
142
- throw new Error(`Invalid env config for ${key}: 'oauth' must be a non-empty string`);
143
- }
144
- parsedVars.push({ key, mappedTo: null, oauthName: value.oauth });
145
- }
146
- else {
147
- parsedVars.push({ key, mappedTo: value || null, oauthName: null });
148
- }
149
- }
150
- }
151
- }
152
- return parsedVars;
153
- }
154
- /**
155
- * Extract declared variable keys from solidactions.yaml env config.
156
- * Returns a set of env var keys that are declared in YAML.
157
- */
158
- function getYamlDeclaredVars(config) {
159
- const parsedVars = parseYamlEnvVars(config);
160
- return new Set(parsedVars.map(v => v.key));
161
- }
162
- /**
163
- * Check if deployEnv is enabled in the config.
164
- * New format has deployEnv at top level.
165
- */
166
- function isDeployEnvEnabled(config) {
167
- return config.deployEnv === true;
168
- }
169
88
  /**
170
89
  * Push YAML env declarations to the project.
171
90
  * This registers all YAML-declared vars and their mappings.
172
91
  */
173
92
  async function pushYamlDeclarations(host, apiKey, projectSlug, yamlConfig) {
174
- const parsedVars = parseYamlEnvVars(yamlConfig);
93
+ const parsedVars = (0, env_1.parseYamlEnvVars)(yamlConfig);
175
94
  if (parsedVars.length === 0) {
176
95
  return;
177
96
  }
@@ -196,71 +115,6 @@ async function pushYamlDeclarations(host, apiKey, projectSlug, yamlConfig) {
196
115
  console.error(chalk_1.default.yellow('Warning: Failed to sync YAML declarations:'), error.response?.data?.message || error.message);
197
116
  }
198
117
  }
199
- /**
200
- * Push environment variables from .env file to project.
201
- * Only pushes vars that are declared in solidactions.yaml.
202
- */
203
- async function pushEnvVars(host, apiKey, projectSlug, sourceDir, environment, yamlConfig) {
204
- // Get vars declared in YAML
205
- const declaredVars = getYamlDeclaredVars(yamlConfig);
206
- if (declaredVars.size === 0) {
207
- console.log(chalk_1.default.gray('No environment variables declared in solidactions.yaml'));
208
- return;
209
- }
210
- // Read the .env file for this environment
211
- const envFileName = environment === 'production' ? '.env' : `.env.${environment}`;
212
- const envFilePath = path_1.default.join(sourceDir, envFileName);
213
- if (!fs_1.default.existsSync(envFilePath)) {
214
- console.log(chalk_1.default.yellow(`⚠ ${envFileName} not found, skipping env push`));
215
- // Warn about each missing declared var
216
- for (const key of declaredVars) {
217
- console.log(chalk_1.default.yellow(` ⚠ ${key}: no value (not in ${envFileName})`));
218
- }
219
- return;
220
- }
221
- // Parse the .env file
222
- const envValues = parseEnvFile(envFilePath);
223
- // Filter to only YAML-declared vars
224
- const variables = [];
225
- const missing = [];
226
- for (const key of declaredVars) {
227
- const value = envValues.get(key);
228
- if (value !== undefined) {
229
- // Mark vars containing "secret", "key", "token", "password" as secrets
230
- const isSecret = /secret|key|token|password|credential/i.test(key);
231
- variables.push({ key, value, is_secret: isSecret });
232
- }
233
- else {
234
- missing.push(key);
235
- }
236
- }
237
- // Warn about missing vars
238
- for (const key of missing) {
239
- console.log(chalk_1.default.yellow(`⚠ ${key}: not found in ${envFileName}`));
240
- }
241
- if (variables.length === 0) {
242
- console.log(chalk_1.default.yellow('No matching environment variables to push'));
243
- return;
244
- }
245
- // Push to API
246
- try {
247
- const response = await axios_1.default.post(`${host}/api/v1/projects/${projectSlug}/variable-mappings/bulk`, { variables }, {
248
- headers: {
249
- 'Authorization': `Bearer ${apiKey}`,
250
- 'Accept': 'application/json',
251
- 'Content-Type': 'application/json',
252
- },
253
- });
254
- const { created, updated } = response.data;
255
- console.log(chalk_1.default.green(`✓ Pushed ${variables.length} environment variables from ${envFileName}`));
256
- if (created > 0 || updated > 0) {
257
- console.log(chalk_1.default.gray(` (${created} created, ${updated} updated)`));
258
- }
259
- }
260
- catch (error) {
261
- console.error(chalk_1.default.red('Failed to push environment variables:'), error.response?.data?.message || error.message);
262
- }
263
- }
264
118
  async function deploy(projectName, sourcePath, options = {}) {
265
119
  const config = (0, init_1.getConfig)();
266
120
  if (!config?.apiKey) {
@@ -399,11 +253,6 @@ async function deploy(projectName, sourcePath, options = {}) {
399
253
  if (yamlConfig) {
400
254
  await pushYamlDeclarations(config.host, config.apiKey, projectSlug, yamlConfig);
401
255
  }
402
- // Push .env values if deployEnv is enabled
403
- if (yamlConfig && isDeployEnvEnabled(yamlConfig)) {
404
- console.log(chalk_1.default.blue('\nPushing environment variables...'));
405
- await pushEnvVars(config.host, config.apiKey, projectSlug, sourceDir, environment, yamlConfig);
406
- }
407
256
  fs_1.default.unlinkSync(zipPath);
408
257
  process.exit(0);
409
258
  }
@@ -8,6 +8,7 @@ const child_process_1 = require("child_process");
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const fs_1 = __importDefault(require("fs"));
10
10
  const chalk_1 = __importDefault(require("chalk"));
11
+ const dotenv_1 = __importDefault(require("dotenv"));
11
12
  async function dev(file, options) {
12
13
  // Resolve the workflow file path
13
14
  const filePath = path_1.default.resolve(file);
@@ -35,6 +36,12 @@ async function dev(file, options) {
35
36
  console.log(chalk_1.default.gray('Update to the latest SDK version: npm install @solidactions/sdk@latest'));
36
37
  process.exit(1);
37
38
  }
39
+ // Load .env file from project root
40
+ const envPath = path_1.default.join(projectDir, '.env');
41
+ if (fs_1.default.existsSync(envPath)) {
42
+ dotenv_1.default.config({ path: envPath });
43
+ console.log(chalk_1.default.gray(`Loaded .env from ${projectDir}`));
44
+ }
38
45
  // Validate input JSON if provided
39
46
  const input = options.input || '{}';
40
47
  try {
@@ -0,0 +1,208 @@
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.envPush = envPush;
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 prompts_1 = __importDefault(require("prompts"));
12
+ const init_1 = require("./init");
13
+ const env_1 = require("../utils/env");
14
+ async function envPush(projectName, sourcePath, options = {}) {
15
+ const config = (0, init_1.getConfig)();
16
+ if (!config?.apiKey) {
17
+ console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
18
+ process.exit(1);
19
+ }
20
+ const sourceDir = path_1.default.resolve(sourcePath);
21
+ const environment = options.env || 'dev';
22
+ // Read solidactions.yaml
23
+ const yamlPath = path_1.default.join(sourceDir, 'solidactions.yaml');
24
+ if (!fs_1.default.existsSync(yamlPath)) {
25
+ console.error(chalk_1.default.red('solidactions.yaml not found in ' + sourceDir));
26
+ console.log(chalk_1.default.gray('Make sure you\'re in a SolidActions project directory.'));
27
+ process.exit(1);
28
+ }
29
+ let yamlConfig;
30
+ try {
31
+ yamlConfig = (0, env_1.loadSolidActionsConfig)(yamlPath);
32
+ }
33
+ catch (err) {
34
+ console.error(chalk_1.default.red('Failed to parse solidactions.yaml:'), err.message);
35
+ process.exit(1);
36
+ }
37
+ // Get YAML-declared vars
38
+ const declaredVars = (0, env_1.getYamlDeclaredVars)(yamlConfig);
39
+ // Determine env file
40
+ const envFileName = environment === 'production' ? '.env' : `.env.${environment}`;
41
+ const envFilePath = path_1.default.join(sourceDir, envFileName);
42
+ if (!fs_1.default.existsSync(envFilePath)) {
43
+ console.error(chalk_1.default.red(`${envFileName} not found in ${sourceDir}`));
44
+ console.log(chalk_1.default.gray(`Create ${envFileName} with your environment variables, or use a different --env.`));
45
+ process.exit(1);
46
+ }
47
+ // Parse the .env file
48
+ const envValues = (0, env_1.parseEnvFile)(envFilePath);
49
+ if (envValues.size === 0) {
50
+ console.log(chalk_1.default.yellow(`${envFileName} is empty — nothing to push.`));
51
+ process.exit(0);
52
+ }
53
+ // Filter to YAML-declared vars only (unless --include-undeclared)
54
+ let keysToProcess;
55
+ if (options.includeUndeclared) {
56
+ keysToProcess = Array.from(envValues.keys());
57
+ }
58
+ else {
59
+ if (declaredVars.size === 0) {
60
+ console.log(chalk_1.default.yellow('No environment variables declared in solidactions.yaml.'));
61
+ console.log(chalk_1.default.gray('Use --include-undeclared to push all vars from the .env file.'));
62
+ process.exit(0);
63
+ }
64
+ keysToProcess = Array.from(envValues.keys()).filter(k => declaredVars.has(k));
65
+ // Warn about YAML-declared vars missing from .env
66
+ for (const key of declaredVars) {
67
+ if (!envValues.has(key)) {
68
+ console.log(chalk_1.default.yellow(`⚠ ${key}: declared in YAML but not found in ${envFileName}`));
69
+ }
70
+ }
71
+ }
72
+ if (keysToProcess.length === 0) {
73
+ console.log(chalk_1.default.yellow('No matching variables to push.'));
74
+ if (!options.includeUndeclared && envValues.size > 0) {
75
+ console.log(chalk_1.default.gray('Your .env has variables not declared in solidactions.yaml. Use --include-undeclared to push them.'));
76
+ }
77
+ process.exit(0);
78
+ }
79
+ // Build project slug
80
+ const projectSlug = environment === 'production'
81
+ ? projectName
82
+ : `${projectName}-${environment}`;
83
+ console.log(chalk_1.default.blue(`Pushing env vars to "${projectName}" (${environment})...`));
84
+ // Fetch current server state
85
+ let serverMappings = [];
86
+ try {
87
+ 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
+ },
92
+ });
93
+ serverMappings = response.data || [];
94
+ }
95
+ catch (error) {
96
+ if (error.response?.status === 401) {
97
+ console.error(chalk_1.default.red('Authentication failed. Run "solidactions init <api-key>" to re-configure.'));
98
+ process.exit(1);
99
+ }
100
+ else if (error.response?.status === 404) {
101
+ console.error(chalk_1.default.red(`Project "${projectSlug}" not found.`));
102
+ console.log(chalk_1.default.gray(`Deploy first with: solidactions deploy ${projectName} --env ${environment}` + (environment !== 'production' ? ' --create' : '')));
103
+ process.exit(1);
104
+ }
105
+ throw error;
106
+ }
107
+ // Build a lookup of server state by env_name
108
+ const serverState = new Map();
109
+ for (const mapping of serverMappings) {
110
+ serverState.set(mapping.env_name, mapping);
111
+ }
112
+ const entries = [];
113
+ for (const key of keysToProcess) {
114
+ const value = envValues.get(key);
115
+ const isSecret = /secret|key|token|password|credential/i.test(key);
116
+ const existing = serverState.get(key);
117
+ let action;
118
+ if (!existing || existing.status === 'not_configured' || existing.has_value === false) {
119
+ action = 'create';
120
+ }
121
+ else {
122
+ action = 'update';
123
+ }
124
+ // If --new-only, skip updates
125
+ if (options.newOnly && action === 'update') {
126
+ action = 'skip';
127
+ }
128
+ entries.push({ key, value, is_secret: isSecret, action });
129
+ }
130
+ const toCreate = entries.filter(e => e.action === 'create');
131
+ const toUpdate = entries.filter(e => e.action === 'update');
132
+ const toSkip = entries.filter(e => e.action === 'skip');
133
+ const toPush = entries.filter(e => e.action !== 'skip');
134
+ if (toPush.length === 0) {
135
+ console.log(chalk_1.default.yellow('Nothing to push — all variables are already configured.'));
136
+ if (toSkip.length > 0) {
137
+ console.log(chalk_1.default.gray(`${toSkip.length} variable(s) skipped (--new-only).`));
138
+ }
139
+ process.exit(0);
140
+ }
141
+ // Display diff table
142
+ console.log('');
143
+ console.log(chalk_1.default.bold(' KEY'.padEnd(36) + 'ACTION'.padEnd(12) + 'NOTES'));
144
+ console.log(chalk_1.default.gray(' ' + '─'.repeat(56)));
145
+ for (const entry of entries) {
146
+ const keyCol = (' ' + entry.key).padEnd(36);
147
+ let actionCol;
148
+ let notesCol;
149
+ switch (entry.action) {
150
+ case 'create':
151
+ actionCol = chalk_1.default.green('create'.padEnd(12));
152
+ notesCol = chalk_1.default.gray('(new)');
153
+ break;
154
+ case 'update':
155
+ actionCol = chalk_1.default.yellow('update'.padEnd(12));
156
+ notesCol = chalk_1.default.gray('(has existing value)');
157
+ break;
158
+ case 'skip':
159
+ actionCol = chalk_1.default.gray('skip'.padEnd(12));
160
+ notesCol = chalk_1.default.gray('(--new-only)');
161
+ break;
162
+ }
163
+ console.log(keyCol + actionCol + notesCol);
164
+ }
165
+ console.log('');
166
+ // Confirm unless --yes
167
+ if (!options.yes) {
168
+ const summary = [];
169
+ if (toCreate.length > 0)
170
+ summary.push(`${toCreate.length} create`);
171
+ if (toUpdate.length > 0)
172
+ summary.push(`${toUpdate.length} update`);
173
+ if (toSkip.length > 0)
174
+ summary.push(`${toSkip.length} skip`);
175
+ const response = await (0, prompts_1.default)({
176
+ type: 'confirm',
177
+ name: 'confirm',
178
+ message: `Push ${toPush.length} variable(s) to ${projectSlug}? (${summary.join(', ')})`,
179
+ initial: true,
180
+ });
181
+ if (!response.confirm) {
182
+ console.log(chalk_1.default.gray('Cancelled.'));
183
+ return;
184
+ }
185
+ }
186
+ // Push via bulk API
187
+ const variables = toPush.map(e => ({
188
+ key: e.key,
189
+ value: e.value,
190
+ is_secret: e.is_secret,
191
+ }));
192
+ try {
193
+ 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
+ },
199
+ });
200
+ const { created, updated } = response.data;
201
+ console.log(chalk_1.default.green(`\n✓ Pushed ${toPush.length} variable(s) to ${projectSlug}`));
202
+ console.log(chalk_1.default.gray(` ${created} created, ${updated} updated` + (toSkip.length > 0 ? `, ${toSkip.length} skipped` : '')));
203
+ }
204
+ catch (error) {
205
+ console.error(chalk_1.default.red('Failed to push environment variables:'), error.response?.data?.message || error.message);
206
+ process.exit(1);
207
+ }
208
+ }
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ const env_list_1 = require("./commands/env-list");
14
14
  const env_delete_1 = require("./commands/env-delete");
15
15
  const env_map_1 = require("./commands/env-map");
16
16
  const env_pull_1 = require("./commands/env-pull");
17
+ const env_push_1 = require("./commands/env-push");
17
18
  const schedule_set_1 = require("./commands/schedule-set");
18
19
  const schedule_list_1 = require("./commands/schedule-list");
19
20
  const schedule_delete_1 = require("./commands/schedule-delete");
@@ -173,6 +174,18 @@ program
173
174
  .action((project, options) => {
174
175
  (0, env_pull_1.envPull)(project, options);
175
176
  });
177
+ program
178
+ .command('env:push')
179
+ .description('Push environment variables from .env file to a project')
180
+ .argument('<project>', 'Project name')
181
+ .argument('[path]', 'Source directory with solidactions.yaml and .env file', '.')
182
+ .option('-e, --env <environment>', 'Target environment (production/staging/dev)', 'dev')
183
+ .option('--new-only', 'Only push new or empty variables (skip existing)')
184
+ .option('--include-undeclared', 'Also push vars not declared in solidactions.yaml')
185
+ .option('-y, --yes', 'Skip confirmation prompt')
186
+ .action((project, path, options) => {
187
+ (0, env_push_1.envPush)(project, path, options);
188
+ });
176
189
  // =============================================================================
177
190
  // Scheduling
178
191
  // =============================================================================
@@ -0,0 +1,93 @@
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.parseEnvFile = parseEnvFile;
7
+ exports.parseYamlEnvVars = parseYamlEnvVars;
8
+ exports.getYamlDeclaredVars = getYamlDeclaredVars;
9
+ exports.loadSolidActionsConfig = loadSolidActionsConfig;
10
+ const fs_1 = __importDefault(require("fs"));
11
+ const js_yaml_1 = __importDefault(require("js-yaml"));
12
+ /**
13
+ * Parse a .env file into a key-value map.
14
+ */
15
+ function parseEnvFile(filePath) {
16
+ const envMap = new Map();
17
+ if (!fs_1.default.existsSync(filePath)) {
18
+ return envMap;
19
+ }
20
+ const content = fs_1.default.readFileSync(filePath, 'utf8');
21
+ const lines = content.split('\n');
22
+ for (const line of lines) {
23
+ const trimmed = line.trim();
24
+ // Skip empty lines and comments
25
+ if (!trimmed || trimmed.startsWith('#')) {
26
+ continue;
27
+ }
28
+ const equalsIndex = trimmed.indexOf('=');
29
+ if (equalsIndex === -1) {
30
+ continue;
31
+ }
32
+ const key = trimmed.substring(0, equalsIndex).trim();
33
+ let value = trimmed.substring(equalsIndex + 1).trim();
34
+ // Remove surrounding quotes if present
35
+ if ((value.startsWith('"') && value.endsWith('"')) ||
36
+ (value.startsWith("'") && value.endsWith("'"))) {
37
+ value = value.slice(1, -1);
38
+ }
39
+ envMap.set(key, value);
40
+ }
41
+ return envMap;
42
+ }
43
+ /**
44
+ * Parse YAML env declarations into structured format.
45
+ * Handles the new simplified format:
46
+ * - VAR_NAME -> { key: "VAR_NAME", mappedTo: null }
47
+ * - VAR_NAME: GLOBAL -> { key: "VAR_NAME", mappedTo: "GLOBAL" }
48
+ */
49
+ function parseYamlEnvVars(config) {
50
+ const parsedVars = [];
51
+ if (!config.env || !Array.isArray(config.env)) {
52
+ return parsedVars;
53
+ }
54
+ for (const item of config.env) {
55
+ if (typeof item === 'string') {
56
+ // Simple string: - VAR_NAME (declared only, needs configuration)
57
+ parsedVars.push({ key: item, mappedTo: null, oauthName: null });
58
+ }
59
+ else if (typeof item === 'object' && item !== null) {
60
+ // Object: - VAR_NAME: GLOBAL_NAME or - VAR_NAME: { oauth: connection-name }
61
+ const keys = Object.keys(item);
62
+ if (keys.length === 1) {
63
+ const key = keys[0];
64
+ const value = item[key];
65
+ if (typeof value === 'object' && value !== null && 'oauth' in value) {
66
+ if (typeof value.oauth !== 'string' || !value.oauth) {
67
+ throw new Error(`Invalid env config for ${key}: 'oauth' must be a non-empty string`);
68
+ }
69
+ parsedVars.push({ key, mappedTo: null, oauthName: value.oauth });
70
+ }
71
+ else {
72
+ parsedVars.push({ key, mappedTo: value || null, oauthName: null });
73
+ }
74
+ }
75
+ }
76
+ }
77
+ return parsedVars;
78
+ }
79
+ /**
80
+ * Extract declared variable keys from solidactions.yaml env config.
81
+ * Returns a set of env var keys that are declared in YAML.
82
+ */
83
+ function getYamlDeclaredVars(config) {
84
+ const parsedVars = parseYamlEnvVars(config);
85
+ return new Set(parsedVars.map(v => v.key));
86
+ }
87
+ /**
88
+ * Load and parse a solidactions.yaml config file.
89
+ */
90
+ function loadSolidActionsConfig(yamlPath) {
91
+ const content = fs_1.default.readFileSync(yamlPath, 'utf8');
92
+ return js_yaml_1.default.load(content);
93
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidactions/cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "SolidActions CLI - Deploy and manage workflow automation",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -41,6 +41,7 @@
41
41
  "axios": "^1.6.0",
42
42
  "chalk": "^4.1.2",
43
43
  "commander": "^11.0.0",
44
+ "dotenv": "^17.3.1",
44
45
  "form-data": "^4.0.0",
45
46
  "fs-extra": "^11.0.0",
46
47
  "js-yaml": "^4.1.0",