@dotenc/cli 0.4.3 → 0.4.5

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.
Files changed (3) hide show
  1. package/README.md +5 -3
  2. package/dist/cli.js +253 -47
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  [![NPM Version][npm-image]][npm-url]
4
4
  [![Github License][license-image]](LICENSE)
5
5
  [![NPM Downloads][downloads-image]][npm-url]
6
+ [![Codecov][codecov-image]][codecov-url]
6
7
 
7
8
  🔐 Git-native encrypted environments powered by your SSH keys
8
9
 
@@ -103,7 +104,7 @@ Your SSH private keys never leave `~/.ssh/`. dotenc reads them in place - nothin
103
104
 
104
105
  After setup, your project will look like:
105
106
 
106
- ```
107
+ ```plaintext
107
108
  .
108
109
  ├── .dotenc/
109
110
  │ ├── alice.pub
@@ -332,7 +333,7 @@ Copy the **entire** contents of the private key file and store it as a secret en
332
333
  cat ci_key
333
334
  ```
334
335
 
335
- ```
336
+ ```plaintext
336
337
  -----BEGIN OPENSSH PRIVATE KEY-----
337
338
  b3BlbnNzaC1rZXktdjEAAAAABG5vbm...
338
339
  -----END OPENSSH PRIVATE KEY-----
@@ -446,7 +447,6 @@ Alternatively, the `DOTENC_ENV` variable can be used to set the environment, so
446
447
  dotenc run node app.js
447
448
  ```
448
449
 
449
- > **Note:** `dotenc textconv` is an internal command used by the git diff driver. It is set up automatically during `dotenc init` and allows `git diff` to show decrypted content of `.env.*.enc` files.
450
450
 
451
451
  ## How dotenc compares
452
452
 
@@ -478,3 +478,5 @@ It does not aim to replace centralized secret managers like Vault or Doppler —
478
478
  [license-image]: https://img.shields.io/github/license/ivanfilhoz/dotenc.svg
479
479
  [downloads-image]: https://img.shields.io/npm/dm/@dotenc/cli.svg
480
480
  [npm-url]: https://npmjs.org/package/@dotenc/cli
481
+ [codecov-image]: https://codecov.io/gh/ivanfilhoz/dotenc/graph/badge.svg?token=U2MKXVGBA0
482
+ [codecov-url]: https://codecov.io/gh/ivanfilhoz/dotenc
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ var package_default;
7
7
  var init_package = __esm(() => {
8
8
  package_default = {
9
9
  name: "@dotenc/cli",
10
- version: "0.4.3",
10
+ version: "0.4.5",
11
11
  description: "🔐 Git-native encrypted environments powered by your SSH keys",
12
12
  author: "Ivan Filho <i@ivanfilho.com>",
13
13
  license: "MIT",
@@ -579,8 +579,8 @@ var init_getPrivateKeys = __esm(() => {
579
579
 
580
580
  // src/helpers/decryptEnvironment.ts
581
581
  import chalk2 from "chalk";
582
- var decryptEnvironmentData = async (environment) => {
583
- const { keys: availablePrivateKeys, passphraseProtectedKeys } = await getPrivateKeys();
582
+ var defaultDecryptEnvironmentDataDeps, decryptEnvironmentData = async (environment, deps = defaultDecryptEnvironmentDataDeps) => {
583
+ const { keys: availablePrivateKeys, passphraseProtectedKeys } = await deps.getPrivateKeys();
584
584
  if (!availablePrivateKeys.length) {
585
585
  if (passphraseProtectedKeys.length > 0) {
586
586
  throw new Error(passphraseProtectedKeyError(passphraseProtectedKeys));
@@ -603,20 +603,20 @@ var decryptEnvironmentData = async (environment) => {
603
603
  }
604
604
  let dataKey;
605
605
  try {
606
- dataKey = decryptDataKey(selectedPrivateKey, Buffer.from(grantedKey.encryptedDataKey, "base64"));
606
+ dataKey = deps.decryptDataKey(selectedPrivateKey, Buffer.from(grantedKey.encryptedDataKey, "base64"));
607
607
  } catch (error) {
608
608
  throw new Error("Failed to decrypt the data key.", { cause: error });
609
609
  }
610
- const decryptedContent = await decryptData(dataKey, Buffer.from(environment.encryptedContent, "base64"));
610
+ const decryptedContent = await deps.decryptData(dataKey, Buffer.from(environment.encryptedContent, "base64"));
611
611
  return decryptedContent;
612
- }, decryptEnvironment = async (name) => {
613
- const { keys: availablePrivateKeys } = await getPrivateKeys();
614
- const environmentJson = await getEnvironmentByName(name);
612
+ }, defaultDecryptEnvironmentDeps, decryptEnvironment = async (name, deps = defaultDecryptEnvironmentDeps) => {
613
+ const { keys: availablePrivateKeys } = await deps.getPrivateKeys();
614
+ const environmentJson = await deps.getEnvironmentByName(name);
615
615
  try {
616
- return await decryptEnvironmentData(environmentJson);
616
+ return await decryptEnvironmentData(environmentJson, deps);
617
617
  } catch (error) {
618
618
  if (error instanceof Error && error.message === "Access denied to the environment.") {
619
- console.error(`You do not have access to this environment.
619
+ deps.logError(`You do not have access to this environment.
620
620
 
621
621
  These are your available private keys:
622
622
 
@@ -630,7 +630,7 @@ var decryptEnvironmentData = async (environment) => {
630
630
  `);
631
631
  }
632
632
  if (error instanceof Error && error.message === "Failed to decrypt the data key.") {
633
- console.error(`${chalk2.red("Error:")} failed to decrypt the data key. Please ensure you have the correct private key.`);
633
+ deps.logError(`${chalk2.red("Error:")} failed to decrypt the data key. Please ensure you have the correct private key.`);
634
634
  }
635
635
  throw error;
636
636
  }
@@ -641,6 +641,16 @@ var init_decryptEnvironment = __esm(() => {
641
641
  init_errors();
642
642
  init_getEnvironmentByName();
643
643
  init_getPrivateKeys();
644
+ defaultDecryptEnvironmentDataDeps = {
645
+ getPrivateKeys,
646
+ decryptDataKey,
647
+ decryptData
648
+ };
649
+ defaultDecryptEnvironmentDeps = {
650
+ ...defaultDecryptEnvironmentDataDeps,
651
+ getEnvironmentByName,
652
+ logError: (message) => console.error(message)
653
+ };
644
654
  });
645
655
 
646
656
  // src/helpers/encryptDataKey.ts
@@ -1000,10 +1010,12 @@ import fs7 from "node:fs/promises";
1000
1010
  import os2 from "node:os";
1001
1011
  import path6 from "node:path";
1002
1012
  import { z as z2 } from "zod";
1003
- var homeConfigSchema, configPath, setHomeConfig = async (config) => {
1013
+ var homeConfigSchema, getConfigPath = () => path6.join(os2.homedir(), ".dotenc", "config.json"), setHomeConfig = async (config) => {
1004
1014
  const parsedConfig = homeConfigSchema.parse(config);
1015
+ const configPath = getConfigPath();
1005
1016
  await fs7.writeFile(configPath, JSON.stringify(parsedConfig, null, 2), "utf-8");
1006
1017
  }, getHomeConfig = async () => {
1018
+ const configPath = getConfigPath();
1007
1019
  if (existsSync3(configPath)) {
1008
1020
  const config = JSON.parse(await fs7.readFile(configPath, "utf-8"));
1009
1021
  return homeConfigSchema.parse(config);
@@ -1014,7 +1026,6 @@ var init_homeConfig = __esm(() => {
1014
1026
  homeConfigSchema = z2.object({
1015
1027
  editor: z2.string().nullish()
1016
1028
  });
1017
- configPath = path6.join(os2.homedir(), ".dotenc", "config.json");
1018
1029
  });
1019
1030
 
1020
1031
  // src/commands/config.ts
@@ -1077,66 +1088,69 @@ var init_parseEnv = __esm(() => {
1077
1088
  // src/commands/run.ts
1078
1089
  import { spawn } from "node:child_process";
1079
1090
  import chalk7 from "chalk";
1080
- var runCommand = async (command, args, options) => {
1091
+ var defaultRunCommandDeps, runCommand = async (command, args, options, _command, deps = defaultRunCommandDeps) => {
1081
1092
  const environmentName = options.env || process.env.DOTENC_ENV;
1082
1093
  if (!environmentName) {
1083
- console.error(`No environment provided. Use -e or set DOTENC_ENV to the environment you want to run the command in.
1094
+ deps.logError(`No environment provided. Use -e or set DOTENC_ENV to the environment you want to run the command in.
1084
1095
  To start a new environment, use "dotenc init [environment]".`);
1085
- process.exit(1);
1096
+ deps.exit(1);
1086
1097
  }
1087
1098
  const environments = environmentName.split(",");
1088
1099
  for (const env of environments) {
1089
- const validation = validateEnvironmentName(env);
1100
+ const validation = deps.validateEnvironmentName(env);
1090
1101
  if (!validation.valid) {
1091
- console.error(`${chalk7.red("Error:")} ${validation.reason}`);
1092
- process.exit(1);
1102
+ deps.logError(`${chalk7.red("Error:")} ${validation.reason}`);
1103
+ deps.exit(1);
1093
1104
  }
1094
1105
  }
1095
1106
  let failureCount = 0;
1096
1107
  const decryptedEnvs = await Promise.all(environments.map(async (environment) => {
1097
1108
  let content;
1098
1109
  try {
1099
- content = await decryptEnvironment(environment);
1110
+ content = await deps.decryptEnvironment(environment);
1100
1111
  } catch (error) {
1101
- console.error(error instanceof Error ? error.message : `Unknown error occurred while decrypting the environment ${environment}.`);
1112
+ deps.logError(error instanceof Error ? error.message : `Unknown error occurred while decrypting the environment ${environment}.`);
1102
1113
  failureCount++;
1103
1114
  return {};
1104
1115
  }
1105
- const decryptedEnv2 = parseEnv(content);
1116
+ const decryptedEnv2 = deps.parseEnv(content);
1106
1117
  return decryptedEnv2;
1107
1118
  }));
1108
1119
  if (failureCount === environments.length) {
1109
- console.error(`${chalk7.red("Error:")} All environments failed to load.`);
1110
- process.exit(1);
1120
+ deps.logError(`${chalk7.red("Error:")} All environments failed to load.`);
1121
+ deps.exit(1);
1111
1122
  }
1112
1123
  if (failureCount > 0) {
1113
- console.error(`${chalk7.yellow("Warning:")} ${failureCount} of ${environments.length} environment(s) failed to load.`);
1124
+ deps.logError(`${chalk7.yellow("Warning:")} ${failureCount} of ${environments.length} environment(s) failed to load.`);
1114
1125
  }
1115
1126
  const decryptedEnv = decryptedEnvs.reduce((acc, env) => {
1116
1127
  return { ...acc, ...env };
1117
1128
  }, {});
1118
1129
  const mergedEnv = { ...process.env, ...decryptedEnv };
1119
- const child = spawn(command, args, {
1130
+ const child = deps.spawn(command, args, {
1120
1131
  env: mergedEnv,
1121
1132
  stdio: "inherit"
1122
1133
  });
1123
1134
  child.on("exit", (code) => {
1124
- process.exit(code);
1135
+ deps.exit(code ?? 0);
1125
1136
  });
1126
1137
  };
1127
1138
  var init_run = __esm(() => {
1128
1139
  init_decryptEnvironment();
1129
1140
  init_parseEnv();
1141
+ defaultRunCommandDeps = {
1142
+ decryptEnvironment,
1143
+ parseEnv,
1144
+ validateEnvironmentName,
1145
+ spawn,
1146
+ logError: (message) => console.error(message),
1147
+ exit: (code) => process.exit(code)
1148
+ };
1130
1149
  });
1131
1150
 
1132
1151
  // src/commands/dev.ts
1133
1152
  import chalk8 from "chalk";
1134
- var devCommand = async (command, args, deps = {
1135
- getCurrentKeyName,
1136
- runCommand,
1137
- logError: (message) => console.error(message),
1138
- exit: (code) => process.exit(code)
1139
- }) => {
1153
+ var defaultDevCommandDeps, devCommand = async (command, args, deps = defaultDevCommandDeps) => {
1140
1154
  const keyName = await deps.getCurrentKeyName();
1141
1155
  if (!keyName) {
1142
1156
  deps.logError(`${chalk8.red("Error:")} could not resolve your identity. Run ${chalk8.gray("dotenc init")} first.`);
@@ -1147,6 +1161,12 @@ var devCommand = async (command, args, deps = {
1147
1161
  var init_dev = __esm(() => {
1148
1162
  init_getCurrentKeyName();
1149
1163
  init_run();
1164
+ defaultDevCommandDeps = {
1165
+ getCurrentKeyName,
1166
+ runCommand,
1167
+ logError: console.error,
1168
+ exit: process.exit
1169
+ };
1150
1170
  });
1151
1171
 
1152
1172
  // src/helpers/environmentExists.ts
@@ -1172,9 +1192,9 @@ import { existsSync as existsSync5 } from "node:fs";
1172
1192
  import fs8 from "node:fs/promises";
1173
1193
  import path8 from "node:path";
1174
1194
  import { z as z3 } from "zod";
1175
- var projectConfigSchema, configPath2, getProjectConfig = async () => {
1176
- if (existsSync5(configPath2)) {
1177
- const config = JSON.parse(await fs8.readFile(configPath2, "utf-8"));
1195
+ var projectConfigSchema, configPath, getProjectConfig = async () => {
1196
+ if (existsSync5(configPath)) {
1197
+ const config = JSON.parse(await fs8.readFile(configPath, "utf-8"));
1178
1198
  return projectConfigSchema.parse(config);
1179
1199
  }
1180
1200
  return {};
@@ -1183,7 +1203,7 @@ var init_projectConfig = __esm(() => {
1183
1203
  projectConfigSchema = z3.object({
1184
1204
  projectId: z3.string()
1185
1205
  });
1186
- configPath2 = path8.join(process.cwd(), "dotenc.json");
1206
+ configPath = path8.join(process.cwd(), "dotenc.json");
1187
1207
  });
1188
1208
 
1189
1209
  // src/prompts/createEnvironment.ts
@@ -1278,6 +1298,77 @@ var init_create = __esm(() => {
1278
1298
  init_createEnvironment();
1279
1299
  });
1280
1300
 
1301
+ // src/commands/env/decrypt.ts
1302
+ var defaultDecryptCommandDeps, ansiPattern, stripAnsi = (value) => value.replace(ansiPattern, ""), mapErrorCode = (message) => {
1303
+ if (message.includes("Environment file not found")) {
1304
+ return "ENVIRONMENT_NOT_FOUND";
1305
+ }
1306
+ if (message === "Access denied to the environment.") {
1307
+ return "ACCESS_DENIED";
1308
+ }
1309
+ if (message.includes("No private keys found")) {
1310
+ return "NO_PRIVATE_KEYS";
1311
+ }
1312
+ if (message.toLowerCase().includes("passphrase-protected")) {
1313
+ return "PASSPHRASE_PROTECTED_KEYS";
1314
+ }
1315
+ return "UNKNOWN";
1316
+ }, writeJson = (message, deps) => {
1317
+ deps.writeStdout(`${JSON.stringify(message)}
1318
+ `);
1319
+ }, decryptCommand = async (environmentName, options, _command, deps = defaultDecryptCommandDeps) => {
1320
+ const validation = deps.validateEnvironmentName(environmentName);
1321
+ if (!validation.valid) {
1322
+ if (options.json) {
1323
+ writeJson({
1324
+ ok: false,
1325
+ error: {
1326
+ code: "INVALID_ENVIRONMENT_NAME",
1327
+ message: validation.reason
1328
+ }
1329
+ }, deps);
1330
+ } else {
1331
+ deps.logError(validation.reason);
1332
+ }
1333
+ deps.exit(1);
1334
+ }
1335
+ try {
1336
+ const environment = await deps.getEnvironmentByName(environmentName);
1337
+ const plaintext = await deps.decryptEnvironmentData(environment);
1338
+ if (options.json) {
1339
+ writeJson({ ok: true, content: plaintext }, deps);
1340
+ } else {
1341
+ deps.writeStdout(plaintext);
1342
+ }
1343
+ } catch (error) {
1344
+ const rawMessage = error instanceof Error ? error.message : "Unknown error occurred while decrypting the environment.";
1345
+ const message = stripAnsi(rawMessage);
1346
+ const code = mapErrorCode(message);
1347
+ if (options.json) {
1348
+ writeJson({
1349
+ ok: false,
1350
+ error: { code, message }
1351
+ }, deps);
1352
+ } else {
1353
+ deps.logError(message);
1354
+ }
1355
+ deps.exit(1);
1356
+ }
1357
+ };
1358
+ var init_decrypt = __esm(() => {
1359
+ init_decryptEnvironment();
1360
+ init_getEnvironmentByName();
1361
+ defaultDecryptCommandDeps = {
1362
+ validateEnvironmentName,
1363
+ getEnvironmentByName,
1364
+ decryptEnvironmentData,
1365
+ writeStdout: (message) => process.stdout.write(message),
1366
+ logError: (message) => console.error(message),
1367
+ exit: (code) => process.exit(code)
1368
+ };
1369
+ ansiPattern = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
1370
+ });
1371
+
1281
1372
  // src/helpers/createHash.ts
1282
1373
  import crypto9 from "node:crypto";
1283
1374
  var createHash = (input) => {
@@ -1287,7 +1378,14 @@ var init_createHash = () => {};
1287
1378
 
1288
1379
  // src/helpers/getDefaultEditor.ts
1289
1380
  import { execSync } from "node:child_process";
1290
- var defaultGetDefaultEditorDeps, getDefaultEditor = async (deps = defaultGetDefaultEditorDeps) => {
1381
+ var commandExists = (command) => {
1382
+ try {
1383
+ execSync(`command -v ${command}`, { stdio: "ignore" });
1384
+ return true;
1385
+ } catch {
1386
+ return false;
1387
+ }
1388
+ }, defaultGetDefaultEditorDeps, getDefaultEditor = async (deps = defaultGetDefaultEditorDeps) => {
1291
1389
  const config = await deps.getHomeConfig();
1292
1390
  if (config.editor) {
1293
1391
  return config.editor;
@@ -1314,14 +1412,7 @@ var init_getDefaultEditor = __esm(() => {
1314
1412
  init_homeConfig();
1315
1413
  defaultGetDefaultEditorDeps = {
1316
1414
  getHomeConfig,
1317
- commandExists: (command) => {
1318
- try {
1319
- execSync(`command -v ${command}`, { stdio: "ignore" });
1320
- return true;
1321
- } catch {
1322
- return false;
1323
- }
1324
- },
1415
+ commandExists,
1325
1416
  platform: process.platform
1326
1417
  };
1327
1418
  });
@@ -1423,6 +1514,117 @@ var init_edit = __esm(() => {
1423
1514
  init_chooseEnvironment();
1424
1515
  });
1425
1516
 
1517
+ // src/commands/env/encrypt.ts
1518
+ var defaultEncryptCommandDeps, ansiPattern2, stripAnsi2 = (value) => value.replace(ansiPattern2, ""), mapErrorCode2 = (message) => {
1519
+ if (message.includes("Environment file not found")) {
1520
+ return "ENVIRONMENT_NOT_FOUND";
1521
+ }
1522
+ if (message === "Access denied to the environment.") {
1523
+ return "ACCESS_DENIED";
1524
+ }
1525
+ if (message.includes("No private keys found")) {
1526
+ return "NO_PRIVATE_KEYS";
1527
+ }
1528
+ if (message.includes("No public keys found")) {
1529
+ return "NO_PUBLIC_KEYS";
1530
+ }
1531
+ if (message.toLowerCase().includes("passphrase-protected")) {
1532
+ return "PASSPHRASE_PROTECTED_KEYS";
1533
+ }
1534
+ return "UNKNOWN";
1535
+ }, writeJson2 = (message, deps) => {
1536
+ deps.writeStdout(`${JSON.stringify(message)}
1537
+ `);
1538
+ }, runWithoutConsoleNoise = async (fn) => {
1539
+ const originalLog = console.log;
1540
+ const originalError = console.error;
1541
+ try {
1542
+ console.log = () => {};
1543
+ console.error = () => {};
1544
+ await fn();
1545
+ } finally {
1546
+ console.log = originalLog;
1547
+ console.error = originalError;
1548
+ }
1549
+ }, encryptCommand = async (environmentName, options, _command, deps = defaultEncryptCommandDeps) => {
1550
+ const validation = deps.validateEnvironmentName(environmentName);
1551
+ if (!validation.valid) {
1552
+ if (options.json) {
1553
+ writeJson2({
1554
+ ok: false,
1555
+ error: {
1556
+ code: "INVALID_ENVIRONMENT_NAME",
1557
+ message: validation.reason
1558
+ }
1559
+ }, deps);
1560
+ } else {
1561
+ deps.logError(validation.reason);
1562
+ }
1563
+ deps.exit(1);
1564
+ }
1565
+ if (!options.stdin) {
1566
+ const message = 'No input source provided. Use "--stdin" and pipe the plaintext content.';
1567
+ if (options.json) {
1568
+ writeJson2({
1569
+ ok: false,
1570
+ error: {
1571
+ code: "MISSING_STDIN",
1572
+ message
1573
+ }
1574
+ }, deps);
1575
+ } else {
1576
+ deps.logError(message);
1577
+ }
1578
+ deps.exit(1);
1579
+ }
1580
+ try {
1581
+ const content = await deps.readStdin();
1582
+ if (options.json) {
1583
+ await runWithoutConsoleNoise(async () => {
1584
+ await deps.encryptEnvironment(environmentName, content);
1585
+ });
1586
+ writeJson2({ ok: true }, deps);
1587
+ return;
1588
+ }
1589
+ await deps.encryptEnvironment(environmentName, content);
1590
+ } catch (error) {
1591
+ const rawMessage = error instanceof Error ? error.message : "Unknown error occurred while encrypting the environment.";
1592
+ const message = stripAnsi2(rawMessage);
1593
+ const code = mapErrorCode2(message);
1594
+ if (options.json) {
1595
+ writeJson2({
1596
+ ok: false,
1597
+ error: { code, message }
1598
+ }, deps);
1599
+ } else {
1600
+ deps.logError(message);
1601
+ }
1602
+ deps.exit(1);
1603
+ }
1604
+ };
1605
+ var init_encrypt = __esm(() => {
1606
+ init_encryptEnvironment();
1607
+ defaultEncryptCommandDeps = {
1608
+ validateEnvironmentName,
1609
+ encryptEnvironment,
1610
+ readStdin: () => new Promise((resolve, reject) => {
1611
+ let input = "";
1612
+ process.stdin.setEncoding("utf-8");
1613
+ process.stdin.on("data", (chunk) => {
1614
+ input += chunk;
1615
+ });
1616
+ process.stdin.on("end", () => {
1617
+ resolve(input);
1618
+ });
1619
+ process.stdin.on("error", reject);
1620
+ }),
1621
+ writeStdout: (message) => process.stdout.write(message),
1622
+ logError: (message) => console.error(message),
1623
+ exit: (code) => process.exit(code)
1624
+ };
1625
+ ansiPattern2 = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
1626
+ });
1627
+
1426
1628
  // src/commands/env/list.ts
1427
1629
  var envListCommand = async () => {
1428
1630
  const environments = await getEnvironments();
@@ -2049,7 +2251,9 @@ var init_program = __esm(() => {
2049
2251
  init_config();
2050
2252
  init_dev();
2051
2253
  init_create();
2254
+ init_decrypt();
2052
2255
  init_edit();
2256
+ init_encrypt();
2053
2257
  init_list2();
2054
2258
  init_rotate();
2055
2259
  init_init();
@@ -2065,6 +2269,8 @@ var init_program = __esm(() => {
2065
2269
  env = program.command("env").description("manage environments");
2066
2270
  env.command("create").argument("[environment]", "the name of the new environment").argument("[publicKey]", "the name of the public key to grant access to the environment").description("create a new environment").action((env2, pubKey) => createCommand(env2, pubKey));
2067
2271
  env.command("edit").argument("[environment]", "the environment to edit").description("edit an environment").action(editCommand);
2272
+ env.command("decrypt", { hidden: true }).argument("<environment>", "the environment to decrypt").addOption(new Option("--json", "output machine-readable JSON")).description("decrypt an environment and print plaintext to stdout").action(decryptCommand);
2273
+ env.command("encrypt", { hidden: true }).argument("<environment>", "the environment to encrypt").addOption(new Option("--stdin", "read plaintext content from stdin")).addOption(new Option("--json", "output machine-readable JSON")).description("encrypt plaintext content and write it to an environment file").action(encryptCommand);
2068
2274
  env.command("rotate").argument("[environment]", "the environment to rotate the data key for").description("rotate the data key for an environment").action(rotateCommand);
2069
2275
  env.command("list").description("list all environments").action(envListCommand);
2070
2276
  auth = program.command("auth").description("manage environment access");
@@ -2077,7 +2283,7 @@ var init_program = __esm(() => {
2077
2283
  key.command("add").argument("[name]", "the name of the public key in the project").addOption(new Option("--from-ssh <path>", "add a public key derived from an SSH key file")).addOption(new Option("-f, --from-file <file>", "add the key from a PEM file")).addOption(new Option("-s, --from-string <string>", "add a public key from a string")).description("add a public key to the project").action(keyAddCommand);
2078
2284
  key.command("list").description("list all public keys in the project").action(keyListCommand);
2079
2285
  key.command("remove").argument("[name]", "the name of the public key to remove").description("remove a public key from the project").action(keyRemoveCommand);
2080
- program.command("textconv").argument("<filepath>", "path to the encrypted environment file").description("decrypt an environment file for git diff").action(textconvCommand);
2286
+ program.command("textconv", { hidden: true }).argument("<filepath>", "path to the encrypted environment file").description("decrypt an environment file for git diff").action(textconvCommand);
2081
2287
  program.command("whoami").description("show your identity in this project").action(whoamiCommand);
2082
2288
  program.command("config").argument("<key>", "the key to get or set").argument("[value]", "the value to set the key to").addOption(new Option("-r, --remove", "remove a configuration key")).description("manage global configuration").action(configCommand);
2083
2289
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotenc/cli",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "🔐 Git-native encrypted environments powered by your SSH keys",
5
5
  "author": "Ivan Filho <i@ivanfilho.com>",
6
6
  "license": "MIT",