|
1 | 1 | import { Command } from "@cliffy/command"; |
| 2 | +import { parse as dotEnvParse } from "@std/dotenv"; |
2 | 3 | import { getAppFromConfig, readConfig } from "./config.ts"; |
3 | 4 | import { error, withApp } from "./util.ts"; |
4 | 5 | import { createTrpcClient } from "./auth.ts"; |
@@ -103,7 +104,7 @@ export const envListCommand = new Command<EnvCommandContext>() |
103 | 104 | export const envAddCommand = new Command<EnvCommandContext>() |
104 | 105 | .description("Add an environmental variable to the application") |
105 | 106 | .option("--secret", "If the value should be secret", { default: false }) |
106 | | - .arguments("variable:string value:string") |
| 107 | + .arguments("<variable:string> <value:string>") |
107 | 108 | .action(async (options, variable, value) => { |
108 | 109 | const configContent = await readConfig(Deno.cwd()); |
109 | 110 | let { org, app } = getAppFromConfig(configContent); |
@@ -144,7 +145,7 @@ export const envUpdateValueCommand = new Command<EnvCommandContext>() |
144 | 145 | .description( |
145 | 146 | "Update the value of an environmental variable in the application", |
146 | 147 | ) |
147 | | - .arguments("variable:string value:string") |
| 148 | + .arguments("<variable:string> <value:string>") |
148 | 149 | .action(async (options, variable, value) => { |
149 | 150 | const configContent = await readConfig(Deno.cwd()); |
150 | 151 | let { org, app } = getAppFromConfig(configContent); |
@@ -188,7 +189,7 @@ export const envUpdateContextsCommand = new Command<EnvCommandContext>() |
188 | 189 | `Update the contexts of an environmental variable in the application |
189 | 190 | You can define no contexts, which is the equivalent to "All"`, |
190 | 191 | ) |
191 | | - .arguments("variable:string [new-contexts...:string]") |
| 192 | + .arguments("<variable:string> [new-contexts...:string]") |
192 | 193 | .action(async (options, variable, ...newContexts) => { |
193 | 194 | const configContent = await readConfig(Deno.cwd()); |
194 | 195 | let { org, app } = getAppFromConfig(configContent); |
@@ -282,3 +283,46 @@ export const envDeleteCommand = new Command<EnvCommandContext>() |
282 | 283 | `Environmental variable '${variable}' has been successfully deleted`, |
283 | 284 | ); |
284 | 285 | }); |
| 286 | + |
| 287 | +export const envLoadCommand = new Command<EnvCommandContext>() |
| 288 | + .description( |
| 289 | + "Load environmental variables from a .env file into the application", |
| 290 | + ) |
| 291 | + .option( |
| 292 | + "--secrets <keys...:string>", |
| 293 | + "Which keys in the .env file to treat as secrets", |
| 294 | + ) |
| 295 | + .arguments("<file:string>") |
| 296 | + .action(async (options, file) => { |
| 297 | + const configContent = await readConfig(Deno.cwd()); |
| 298 | + let { org, app } = getAppFromConfig(configContent); |
| 299 | + org ??= options.org; |
| 300 | + app ??= options.app; |
| 301 | + |
| 302 | + const orgAndApp = await withApp(options.endpoint, false, org, app); |
| 303 | + const trpcClient = createTrpcClient(options.endpoint); |
| 304 | + |
| 305 | + // deno-lint-ignore no-explicit-any |
| 306 | + const fullApp = await (trpcClient.apps as any).get.query({ |
| 307 | + org: orgAndApp.org, |
| 308 | + app: orgAndApp.app, |
| 309 | + }); |
| 310 | + |
| 311 | + const variables = dotEnvParse(await Deno.readTextFile(file)); |
| 312 | + |
| 313 | + // deno-lint-ignore no-explicit-any |
| 314 | + await (trpcClient.envVarsContexts as any).updateEnvVars.mutate({ |
| 315 | + org: orgAndApp.org, |
| 316 | + add: Object.entries(variables).map(([key, value]) => ({ |
| 317 | + app_id: fullApp.id, |
| 318 | + key, |
| 319 | + value, |
| 320 | + is_secret: options.secrets?.includes(key) ?? false, |
| 321 | + context_ids: null, |
| 322 | + })), |
| 323 | + update: [], |
| 324 | + remove: [], |
| 325 | + }); |
| 326 | + |
| 327 | + console.log(`.env file '${file}' has been successfully loaded.`); |
| 328 | + }); |
0 commit comments