@dotenc/cli 0.4.4 → 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 +0 -1
  2. package/dist/cli.js +188 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -447,7 +447,6 @@ Alternatively, the `DOTENC_ENV` variable can be used to set the environment, so
447
447
  dotenc run node app.js
448
448
  ```
449
449
 
450
- > **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.
451
450
 
452
451
  ## How dotenc compares
453
452
 
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.4",
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",
@@ -1298,6 +1298,77 @@ var init_create = __esm(() => {
1298
1298
  init_createEnvironment();
1299
1299
  });
1300
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
+
1301
1372
  // src/helpers/createHash.ts
1302
1373
  import crypto9 from "node:crypto";
1303
1374
  var createHash = (input) => {
@@ -1443,6 +1514,117 @@ var init_edit = __esm(() => {
1443
1514
  init_chooseEnvironment();
1444
1515
  });
1445
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
+
1446
1628
  // src/commands/env/list.ts
1447
1629
  var envListCommand = async () => {
1448
1630
  const environments = await getEnvironments();
@@ -2069,7 +2251,9 @@ var init_program = __esm(() => {
2069
2251
  init_config();
2070
2252
  init_dev();
2071
2253
  init_create();
2254
+ init_decrypt();
2072
2255
  init_edit();
2256
+ init_encrypt();
2073
2257
  init_list2();
2074
2258
  init_rotate();
2075
2259
  init_init();
@@ -2085,6 +2269,8 @@ var init_program = __esm(() => {
2085
2269
  env = program.command("env").description("manage environments");
2086
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));
2087
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);
2088
2274
  env.command("rotate").argument("[environment]", "the environment to rotate the data key for").description("rotate the data key for an environment").action(rotateCommand);
2089
2275
  env.command("list").description("list all environments").action(envListCommand);
2090
2276
  auth = program.command("auth").description("manage environment access");
@@ -2097,7 +2283,7 @@ var init_program = __esm(() => {
2097
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);
2098
2284
  key.command("list").description("list all public keys in the project").action(keyListCommand);
2099
2285
  key.command("remove").argument("[name]", "the name of the public key to remove").description("remove a public key from the project").action(keyRemoveCommand);
2100
- 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);
2101
2287
  program.command("whoami").description("show your identity in this project").action(whoamiCommand);
2102
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);
2103
2289
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotenc/cli",
3
- "version": "0.4.4",
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",