@envpilot/cli 1.3.3 → 1.4.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/dist/index.js +393 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ function initSentry() {
|
|
|
9
9
|
Sentry.init({
|
|
10
10
|
dsn,
|
|
11
11
|
environment: "cli",
|
|
12
|
-
release: true ? "1.
|
|
12
|
+
release: true ? "1.4.0" : "0.0.0",
|
|
13
13
|
// Free tier: disable performance monitoring
|
|
14
14
|
tracesSampleRate: 0,
|
|
15
15
|
beforeSend(event) {
|
|
@@ -1384,10 +1384,356 @@ function printPostInit(selectedOrg, selectedProject) {
|
|
|
1384
1384
|
import { Command as Command3 } from "commander";
|
|
1385
1385
|
import chalk5 from "chalk";
|
|
1386
1386
|
import inquirer2 from "inquirer";
|
|
1387
|
+
|
|
1388
|
+
// src/lib/format-converter.ts
|
|
1389
|
+
var ALL_FORMATS = [
|
|
1390
|
+
"env",
|
|
1391
|
+
"json",
|
|
1392
|
+
"yaml",
|
|
1393
|
+
"docker-compose",
|
|
1394
|
+
"aws",
|
|
1395
|
+
"vercel",
|
|
1396
|
+
"netlify"
|
|
1397
|
+
];
|
|
1398
|
+
function serialize(vars, format, meta) {
|
|
1399
|
+
switch (format) {
|
|
1400
|
+
case "env":
|
|
1401
|
+
return serializeEnv(vars, meta);
|
|
1402
|
+
case "json":
|
|
1403
|
+
return serializeJson(vars);
|
|
1404
|
+
case "yaml":
|
|
1405
|
+
return serializeYaml(vars, meta);
|
|
1406
|
+
case "docker-compose":
|
|
1407
|
+
return serializeDockerCompose(vars, meta);
|
|
1408
|
+
case "aws":
|
|
1409
|
+
return serializeAws(vars, meta);
|
|
1410
|
+
case "vercel":
|
|
1411
|
+
return serializeVercel(vars);
|
|
1412
|
+
case "netlify":
|
|
1413
|
+
return serializeNetlify(vars, meta);
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
function parse(content, format, options) {
|
|
1417
|
+
switch (format) {
|
|
1418
|
+
case "env":
|
|
1419
|
+
return parseEnvFile(content);
|
|
1420
|
+
case "json":
|
|
1421
|
+
return parseJson(content);
|
|
1422
|
+
case "yaml":
|
|
1423
|
+
return parseYaml(content);
|
|
1424
|
+
case "docker-compose":
|
|
1425
|
+
return parseDockerCompose(content);
|
|
1426
|
+
case "aws":
|
|
1427
|
+
return parseAws(content, options?.prefix);
|
|
1428
|
+
case "vercel":
|
|
1429
|
+
return parseVercel(content);
|
|
1430
|
+
case "netlify":
|
|
1431
|
+
return parseNetlify(content);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
function getDefaultFilename(format, environment) {
|
|
1435
|
+
const env = environment || "development";
|
|
1436
|
+
switch (format) {
|
|
1437
|
+
case "env":
|
|
1438
|
+
return env === "development" ? ".env.local" : `.env.${env}`;
|
|
1439
|
+
case "json":
|
|
1440
|
+
return `${env}.json`;
|
|
1441
|
+
case "yaml":
|
|
1442
|
+
return `${env}.yaml`;
|
|
1443
|
+
case "docker-compose":
|
|
1444
|
+
return "docker-compose.yml";
|
|
1445
|
+
case "aws":
|
|
1446
|
+
return `${env}.aws.json`;
|
|
1447
|
+
case "vercel":
|
|
1448
|
+
return `${env}.vercel.json`;
|
|
1449
|
+
case "netlify":
|
|
1450
|
+
return "netlify.toml";
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
function serializeEnv(vars, meta) {
|
|
1454
|
+
const lines = [];
|
|
1455
|
+
if (meta?.environment) {
|
|
1456
|
+
lines.push(`# Environment: ${meta.environment}`);
|
|
1457
|
+
}
|
|
1458
|
+
if (meta?.projectName) {
|
|
1459
|
+
lines.push(`# Project: ${meta.projectName}`);
|
|
1460
|
+
}
|
|
1461
|
+
if (lines.length > 0) {
|
|
1462
|
+
lines.push(`# Exported: ${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
1463
|
+
lines.push("");
|
|
1464
|
+
}
|
|
1465
|
+
return lines.join("\n") + stringifyEnv(vars, { sort: true });
|
|
1466
|
+
}
|
|
1467
|
+
function serializeJson(vars) {
|
|
1468
|
+
const sorted = Object.keys(vars).sort().reduce(
|
|
1469
|
+
(obj, key) => {
|
|
1470
|
+
obj[key] = vars[key];
|
|
1471
|
+
return obj;
|
|
1472
|
+
},
|
|
1473
|
+
{}
|
|
1474
|
+
);
|
|
1475
|
+
return JSON.stringify(sorted, null, 2) + "\n";
|
|
1476
|
+
}
|
|
1477
|
+
function parseJson(content) {
|
|
1478
|
+
const data = JSON.parse(content);
|
|
1479
|
+
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
1480
|
+
throw new Error("Expected a JSON object with string key-value pairs");
|
|
1481
|
+
}
|
|
1482
|
+
const result = {};
|
|
1483
|
+
for (const [key, value] of Object.entries(data)) {
|
|
1484
|
+
if (typeof value === "string") {
|
|
1485
|
+
result[key] = value;
|
|
1486
|
+
} else if (value !== null && value !== void 0) {
|
|
1487
|
+
result[key] = String(value);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
return result;
|
|
1491
|
+
}
|
|
1492
|
+
function yamlQuote(value) {
|
|
1493
|
+
if (value === "" || value === "true" || value === "false" || value === "null" || value === "~" || /^[0-9]/.test(value) || /[:#\[\]{}&*!|>'"%@`]/.test(value) || value.includes("\n") || value.startsWith(" ") || value.endsWith(" ")) {
|
|
1494
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
1495
|
+
return `"${escaped}"`;
|
|
1496
|
+
}
|
|
1497
|
+
return value;
|
|
1498
|
+
}
|
|
1499
|
+
function serializeYaml(vars, meta) {
|
|
1500
|
+
const lines = [];
|
|
1501
|
+
if (meta?.environment) {
|
|
1502
|
+
lines.push(`# Environment: ${meta.environment}`);
|
|
1503
|
+
}
|
|
1504
|
+
if (meta?.projectName) {
|
|
1505
|
+
lines.push(`# Project: ${meta.projectName}`);
|
|
1506
|
+
}
|
|
1507
|
+
if (lines.length > 0) {
|
|
1508
|
+
lines.push("");
|
|
1509
|
+
}
|
|
1510
|
+
for (const key of Object.keys(vars).sort()) {
|
|
1511
|
+
lines.push(`${key}: ${yamlQuote(vars[key])}`);
|
|
1512
|
+
}
|
|
1513
|
+
return lines.join("\n") + "\n";
|
|
1514
|
+
}
|
|
1515
|
+
function parseYaml(content) {
|
|
1516
|
+
const result = {};
|
|
1517
|
+
for (const line of content.split("\n")) {
|
|
1518
|
+
const trimmed = line.trim();
|
|
1519
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
1520
|
+
const colonIndex = trimmed.indexOf(": ");
|
|
1521
|
+
if (colonIndex === -1) {
|
|
1522
|
+
if (trimmed.endsWith(":")) {
|
|
1523
|
+
const key2 = trimmed.slice(0, -1).trim();
|
|
1524
|
+
if (key2 && /^[A-Za-z_][A-Za-z0-9_]*$/.test(key2)) {
|
|
1525
|
+
result[key2] = "";
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
continue;
|
|
1529
|
+
}
|
|
1530
|
+
const key = trimmed.substring(0, colonIndex).trim();
|
|
1531
|
+
let value = trimmed.substring(colonIndex + 2).trim();
|
|
1532
|
+
if (line.startsWith(" ") || line.startsWith(" ")) continue;
|
|
1533
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1534
|
+
value = value.slice(1, -1);
|
|
1535
|
+
if (value.includes("\\")) {
|
|
1536
|
+
value = value.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
1540
|
+
result[key] = value;
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
return result;
|
|
1544
|
+
}
|
|
1545
|
+
function serializeDockerCompose(vars, meta) {
|
|
1546
|
+
const lines = [];
|
|
1547
|
+
if (meta?.environment || meta?.projectName) {
|
|
1548
|
+
lines.push("# Docker Compose environment variables");
|
|
1549
|
+
if (meta.projectName) lines.push(`# Project: ${meta.projectName}`);
|
|
1550
|
+
if (meta.environment) lines.push(`# Environment: ${meta.environment}`);
|
|
1551
|
+
lines.push("");
|
|
1552
|
+
}
|
|
1553
|
+
lines.push("services:");
|
|
1554
|
+
lines.push(" app:");
|
|
1555
|
+
lines.push(" environment:");
|
|
1556
|
+
for (const key of Object.keys(vars).sort()) {
|
|
1557
|
+
lines.push(` ${key}: ${yamlQuote(vars[key])}`);
|
|
1558
|
+
}
|
|
1559
|
+
return lines.join("\n") + "\n";
|
|
1560
|
+
}
|
|
1561
|
+
function parseDockerCompose(content) {
|
|
1562
|
+
const result = {};
|
|
1563
|
+
const lines = content.split("\n");
|
|
1564
|
+
let inEnvironment = false;
|
|
1565
|
+
let environmentIndent = -1;
|
|
1566
|
+
for (const line of lines) {
|
|
1567
|
+
const trimmed = line.trim();
|
|
1568
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
1569
|
+
const indent = line.length - line.trimStart().length;
|
|
1570
|
+
if (trimmed === "environment:") {
|
|
1571
|
+
inEnvironment = true;
|
|
1572
|
+
environmentIndent = indent;
|
|
1573
|
+
continue;
|
|
1574
|
+
}
|
|
1575
|
+
if (inEnvironment) {
|
|
1576
|
+
if (indent <= environmentIndent && trimmed !== "") {
|
|
1577
|
+
inEnvironment = false;
|
|
1578
|
+
environmentIndent = -1;
|
|
1579
|
+
continue;
|
|
1580
|
+
}
|
|
1581
|
+
if (trimmed.startsWith("- ")) {
|
|
1582
|
+
const entry = trimmed.slice(2);
|
|
1583
|
+
const eqIdx = entry.indexOf("=");
|
|
1584
|
+
if (eqIdx !== -1) {
|
|
1585
|
+
const key = entry.substring(0, eqIdx).trim();
|
|
1586
|
+
let value = entry.substring(eqIdx + 1).trim();
|
|
1587
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1588
|
+
value = value.slice(1, -1);
|
|
1589
|
+
}
|
|
1590
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
1591
|
+
result[key] = value;
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
continue;
|
|
1595
|
+
}
|
|
1596
|
+
const colonIndex = trimmed.indexOf(": ");
|
|
1597
|
+
if (colonIndex !== -1) {
|
|
1598
|
+
const key = trimmed.substring(0, colonIndex).trim();
|
|
1599
|
+
let value = trimmed.substring(colonIndex + 2).trim();
|
|
1600
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1601
|
+
value = value.slice(1, -1);
|
|
1602
|
+
if (value.includes("\\")) {
|
|
1603
|
+
value = value.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
1607
|
+
result[key] = value;
|
|
1608
|
+
}
|
|
1609
|
+
} else if (trimmed.endsWith(":")) {
|
|
1610
|
+
const key = trimmed.slice(0, -1).trim();
|
|
1611
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
1612
|
+
result[key] = "";
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
return result;
|
|
1618
|
+
}
|
|
1619
|
+
function serializeAws(vars, meta) {
|
|
1620
|
+
const prefix = meta?.prefix || `/${meta?.projectName || "app"}`;
|
|
1621
|
+
const parameters = Object.keys(vars).sort().map((key) => ({
|
|
1622
|
+
name: `${prefix}/${key}`,
|
|
1623
|
+
value: vars[key],
|
|
1624
|
+
type: "SecureString"
|
|
1625
|
+
}));
|
|
1626
|
+
return JSON.stringify({ parameters }, null, 2) + "\n";
|
|
1627
|
+
}
|
|
1628
|
+
function parseAws(content, prefix) {
|
|
1629
|
+
const data = JSON.parse(content);
|
|
1630
|
+
const result = {};
|
|
1631
|
+
const params = data.parameters || data.Parameters || [];
|
|
1632
|
+
if (!Array.isArray(params)) {
|
|
1633
|
+
throw new Error(
|
|
1634
|
+
"Expected AWS Parameter Store format with 'parameters' array"
|
|
1635
|
+
);
|
|
1636
|
+
}
|
|
1637
|
+
for (const param of params) {
|
|
1638
|
+
const name = param.name || param.Name || "";
|
|
1639
|
+
const value = param.value || param.Value || "";
|
|
1640
|
+
let key;
|
|
1641
|
+
if (prefix && name.startsWith(prefix + "/")) {
|
|
1642
|
+
key = name.substring(prefix.length + 1);
|
|
1643
|
+
} else {
|
|
1644
|
+
const lastSlash = name.lastIndexOf("/");
|
|
1645
|
+
key = lastSlash !== -1 ? name.substring(lastSlash + 1) : name;
|
|
1646
|
+
}
|
|
1647
|
+
if (key && /^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
1648
|
+
result[key] = value;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
return result;
|
|
1652
|
+
}
|
|
1653
|
+
function serializeVercel(vars) {
|
|
1654
|
+
const sorted = Object.keys(vars).sort().reduce(
|
|
1655
|
+
(obj, key) => {
|
|
1656
|
+
obj[key] = vars[key];
|
|
1657
|
+
return obj;
|
|
1658
|
+
},
|
|
1659
|
+
{}
|
|
1660
|
+
);
|
|
1661
|
+
return JSON.stringify({ env: sorted }, null, 2) + "\n";
|
|
1662
|
+
}
|
|
1663
|
+
function parseVercel(content) {
|
|
1664
|
+
const data = JSON.parse(content);
|
|
1665
|
+
const result = {};
|
|
1666
|
+
const env = data.env;
|
|
1667
|
+
if (!env || typeof env !== "object" || Array.isArray(env)) {
|
|
1668
|
+
throw new Error("Expected Vercel format with 'env' object");
|
|
1669
|
+
}
|
|
1670
|
+
for (const [key, value] of Object.entries(env)) {
|
|
1671
|
+
if (typeof value === "string") {
|
|
1672
|
+
result[key] = value;
|
|
1673
|
+
} else if (value !== null && value !== void 0) {
|
|
1674
|
+
result[key] = String(value);
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
return result;
|
|
1678
|
+
}
|
|
1679
|
+
function tomlQuote(value) {
|
|
1680
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
1681
|
+
return `"${escaped}"`;
|
|
1682
|
+
}
|
|
1683
|
+
function serializeNetlify(vars, meta) {
|
|
1684
|
+
const lines = [];
|
|
1685
|
+
if (meta?.environment || meta?.projectName) {
|
|
1686
|
+
if (meta.projectName) lines.push(`# Project: ${meta.projectName}`);
|
|
1687
|
+
if (meta.environment) lines.push(`# Environment: ${meta.environment}`);
|
|
1688
|
+
lines.push("");
|
|
1689
|
+
}
|
|
1690
|
+
lines.push("[build.environment]");
|
|
1691
|
+
for (const key of Object.keys(vars).sort()) {
|
|
1692
|
+
lines.push(` ${key} = ${tomlQuote(vars[key])}`);
|
|
1693
|
+
}
|
|
1694
|
+
return lines.join("\n") + "\n";
|
|
1695
|
+
}
|
|
1696
|
+
function parseNetlify(content) {
|
|
1697
|
+
const result = {};
|
|
1698
|
+
const lines = content.split("\n");
|
|
1699
|
+
let inBuildEnv = false;
|
|
1700
|
+
for (const line of lines) {
|
|
1701
|
+
const trimmed = line.trim();
|
|
1702
|
+
if (trimmed.startsWith("[")) {
|
|
1703
|
+
inBuildEnv = trimmed === "[build.environment]" || trimmed === "[build.environment]";
|
|
1704
|
+
continue;
|
|
1705
|
+
}
|
|
1706
|
+
if (!inBuildEnv) continue;
|
|
1707
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
1708
|
+
const eqIndex = trimmed.indexOf("=");
|
|
1709
|
+
if (eqIndex === -1) continue;
|
|
1710
|
+
const key = trimmed.substring(0, eqIndex).trim();
|
|
1711
|
+
let value = trimmed.substring(eqIndex + 1).trim();
|
|
1712
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
1713
|
+
value = value.slice(1, -1);
|
|
1714
|
+
value = value.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
1715
|
+
} else if (value.startsWith("'") && value.endsWith("'")) {
|
|
1716
|
+
value = value.slice(1, -1);
|
|
1717
|
+
}
|
|
1718
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
1719
|
+
result[key] = value;
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
return result;
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
// src/commands/pull.ts
|
|
1387
1726
|
var pullCommand = new Command3("pull").description("Download environment variables to local .env file").option(
|
|
1388
1727
|
"-e, --env <environment>",
|
|
1389
1728
|
"Environment (development, staging, production)"
|
|
1390
|
-
).option("-f, --file <path>", "Output file path (default: .env)").option("--force", "Overwrite without confirmation").option(
|
|
1729
|
+
).option("-f, --file <path>", "Output file path (default: .env)").option("--force", "Overwrite without confirmation").option(
|
|
1730
|
+
"--format <format>",
|
|
1731
|
+
"Output format: env, json, yaml, docker-compose, aws, vercel, netlify",
|
|
1732
|
+
"env"
|
|
1733
|
+
).option(
|
|
1734
|
+
"--prefix <prefix>",
|
|
1735
|
+
"AWS Parameter Store path prefix (default: /project-name)"
|
|
1736
|
+
).option("--dry-run", "Show what would be downloaded without writing").option("--project <name-or-id>", "Pull a specific linked project").option("--all", "Pull all linked projects").action(async (options) => {
|
|
1391
1737
|
try {
|
|
1392
1738
|
if (!isAuthenticated()) {
|
|
1393
1739
|
throw notAuthenticated();
|
|
@@ -1420,7 +1766,12 @@ var pullCommand = new Command3("pull").description("Download environment variabl
|
|
|
1420
1766
|
if (!projectConfig) throw notInitialized();
|
|
1421
1767
|
checkTrackedFiles();
|
|
1422
1768
|
const environment = options.env || projectConfig.environment || "development";
|
|
1423
|
-
const
|
|
1769
|
+
const fmt = options.format || "env";
|
|
1770
|
+
if (!ALL_FORMATS.includes(fmt)) {
|
|
1771
|
+
error(`Unknown format: ${fmt}. Supported: ${ALL_FORMATS.join(", ")}`);
|
|
1772
|
+
process.exit(1);
|
|
1773
|
+
}
|
|
1774
|
+
const outputPath = options.file || (fmt === "env" ? getEnvPathForEnvironment(environment) : getDefaultFilename(fmt, environment));
|
|
1424
1775
|
await pullProject(
|
|
1425
1776
|
{
|
|
1426
1777
|
projectId: projectConfig.projectId,
|
|
@@ -1479,7 +1830,8 @@ async function pullAllProjects(options) {
|
|
|
1479
1830
|
async function pullSingleProject(project, options) {
|
|
1480
1831
|
checkTrackedFiles();
|
|
1481
1832
|
const environment = options.env || project.environment;
|
|
1482
|
-
const
|
|
1833
|
+
const fmt = options.format || "env";
|
|
1834
|
+
const outputPath = options.file || (fmt === "env" ? getEnvPathForEnvironment(environment) : getDefaultFilename(fmt, environment));
|
|
1483
1835
|
await pullProject(
|
|
1484
1836
|
{
|
|
1485
1837
|
projectId: project.projectId,
|
|
@@ -1552,10 +1904,8 @@ async function pullProject(project, outputPath, options) {
|
|
|
1552
1904
|
}
|
|
1553
1905
|
} catch {
|
|
1554
1906
|
}
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
fs.writeFileSync(outputPath, JSON.stringify(remoteVars, null, 2) + "\n");
|
|
1558
|
-
} else {
|
|
1907
|
+
const fmt = options.format || "env";
|
|
1908
|
+
if (fmt === "env") {
|
|
1559
1909
|
const comments = {};
|
|
1560
1910
|
for (const variable of variables) {
|
|
1561
1911
|
if (variable.description) {
|
|
@@ -1563,6 +1913,14 @@ async function pullProject(project, outputPath, options) {
|
|
|
1563
1913
|
}
|
|
1564
1914
|
}
|
|
1565
1915
|
writeEnvFile(outputPath, remoteVars, { sort: true, comments });
|
|
1916
|
+
} else {
|
|
1917
|
+
const fs = await import("fs");
|
|
1918
|
+
const output = serialize(remoteVars, fmt, {
|
|
1919
|
+
projectName: project.projectId,
|
|
1920
|
+
environment: project.environment,
|
|
1921
|
+
prefix: options.prefix
|
|
1922
|
+
});
|
|
1923
|
+
fs.writeFileSync(outputPath, output, "utf-8");
|
|
1566
1924
|
}
|
|
1567
1925
|
const role = getRole();
|
|
1568
1926
|
applyFileProtection(outputPath, role, metaProjectRole);
|
|
@@ -1658,7 +2016,14 @@ function validateEnvVars(vars) {
|
|
|
1658
2016
|
var pushCommand = new Command4("push").description("Upload local .env file to cloud").option(
|
|
1659
2017
|
"-e, --env <environment>",
|
|
1660
2018
|
"Target environment (development, staging, production)"
|
|
1661
|
-
).option("-f, --file <path>", "Input file path (default: .env)").option("--merge", "Merge with existing variables (default)").option("--replace", "Replace all existing variables").option(
|
|
2019
|
+
).option("-f, --file <path>", "Input file path (default: .env)").option("--merge", "Merge with existing variables (default)").option("--replace", "Replace all existing variables").option(
|
|
2020
|
+
"--format <format>",
|
|
2021
|
+
"Input format: env, json, yaml, docker-compose, aws, vercel, netlify",
|
|
2022
|
+
"env"
|
|
2023
|
+
).option(
|
|
2024
|
+
"--prefix <prefix>",
|
|
2025
|
+
"AWS Parameter Store path prefix (default: /project-name)"
|
|
2026
|
+
).option("--dry-run", "Show what would be uploaded without making changes").option("--force", "Skip confirmation").option("--project <name-or-id>", "Push to a specific linked project").action(async (options) => {
|
|
1662
2027
|
try {
|
|
1663
2028
|
if (!isAuthenticated()) {
|
|
1664
2029
|
throw notAuthenticated();
|
|
@@ -1740,9 +2105,25 @@ var pushCommand = new Command4("push").description("Upload local .env file to cl
|
|
|
1740
2105
|
}
|
|
1741
2106
|
}
|
|
1742
2107
|
const environment = options.env || defaultEnvironment || "development";
|
|
1743
|
-
const
|
|
2108
|
+
const fmt = options.format || "env";
|
|
2109
|
+
if (!ALL_FORMATS.includes(fmt)) {
|
|
2110
|
+
error(`Unknown format: ${fmt}. Supported: ${ALL_FORMATS.join(", ")}`);
|
|
2111
|
+
process.exit(1);
|
|
2112
|
+
}
|
|
2113
|
+
const inputPath = options.file || (fmt === "env" ? getEnvPathForEnvironment(environment) : getDefaultFilename(fmt, environment));
|
|
1744
2114
|
const mode = options.replace ? "replace" : "merge";
|
|
1745
|
-
|
|
2115
|
+
let localVars;
|
|
2116
|
+
if (fmt === "env") {
|
|
2117
|
+
localVars = readEnvFile(inputPath);
|
|
2118
|
+
} else {
|
|
2119
|
+
const { readFileSync: readFileSync4, existsSync: existsSync4 } = await import("fs");
|
|
2120
|
+
if (!existsSync4(inputPath)) {
|
|
2121
|
+
localVars = null;
|
|
2122
|
+
} else {
|
|
2123
|
+
const content = readFileSync4(inputPath, "utf-8");
|
|
2124
|
+
localVars = parse(content, fmt, { prefix: options.prefix });
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
1746
2127
|
if (!localVars) {
|
|
1747
2128
|
throw fileNotFound(inputPath);
|
|
1748
2129
|
}
|
|
@@ -3141,7 +3522,7 @@ var usageCommand = new Command11("usage").description("Show plan usage and limit
|
|
|
3141
3522
|
// src/lib/version-check.ts
|
|
3142
3523
|
import chalk13 from "chalk";
|
|
3143
3524
|
import Conf2 from "conf";
|
|
3144
|
-
var CLI_VERSION = "1.
|
|
3525
|
+
var CLI_VERSION = true ? "1.4.0" : "0.0.0";
|
|
3145
3526
|
var CHECK_INTERVAL = 60 * 60 * 1e3;
|
|
3146
3527
|
var _cache = null;
|
|
3147
3528
|
function getCache() {
|