@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.
- package/README.md +0 -1
- package/dist/cli.js +188 -2
- 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.
|
|
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();
|