@envmanager-cli/cli 0.1.7 → 0.1.9

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.
@@ -2,6 +2,9 @@
2
2
 
3
3
  // src/bin/envmanager.ts
4
4
  import { Command as Command15 } from "commander";
5
+ import { readFileSync as readFileSync10 } from "fs";
6
+ import { dirname as dirname3, resolve as resolve9 } from "path";
7
+ import { fileURLToPath as fileURLToPath2 } from "url";
5
8
 
6
9
  // src/commands/login.ts
7
10
  import { Command } from "commander";
@@ -88,7 +91,7 @@ function escapeHtml(str) {
88
91
  return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
89
92
  }
90
93
  async function startCallbackServer(expectedState, port = 8976) {
91
- return new Promise((resolve9, reject) => {
94
+ return new Promise((resolve10, reject) => {
92
95
  const timeout = setTimeout(() => {
93
96
  server.close();
94
97
  reject(new Error("Authentication timed out after 5 minutes"));
@@ -161,9 +164,9 @@ async function startCallbackServer(expectedState, port = 8976) {
161
164
  clearTimeout(timeout);
162
165
  server.close();
163
166
  if (apiKey) {
164
- resolve9({ apiKey });
167
+ resolve10({ apiKey });
165
168
  } else {
166
- resolve9({
169
+ resolve10({
167
170
  accessToken,
168
171
  refreshToken,
169
172
  expiresIn: parseInt(expiresIn || "3600", 10)
@@ -1506,17 +1509,23 @@ async function subscribeToVariableChanges(environmentId, onEvent, onStatus) {
1506
1509
  channel.on("broadcast", { event: "variable_change" }, (payload) => {
1507
1510
  onEvent(payload.payload);
1508
1511
  });
1512
+ channel.on("broadcast", { event: "*" }, (payload) => {
1513
+ const data = payload.payload;
1514
+ if (data?.action && data?.key && data?.environment_id) {
1515
+ onEvent(data);
1516
+ }
1517
+ });
1509
1518
  channel.on("system", { event: "*" }, (status) => {
1510
1519
  if (status.event === "connected") {
1511
1520
  reconnectAttempts = 0;
1512
1521
  onStatus?.("connected");
1513
1522
  }
1514
1523
  });
1515
- const subscription = await new Promise((resolve9, reject) => {
1524
+ const subscription = await new Promise((resolve10, reject) => {
1516
1525
  channel.subscribe(async (status, err) => {
1517
1526
  if (status === "SUBSCRIBED") {
1518
1527
  onStatus?.("connected");
1519
- resolve9({
1528
+ resolve10({
1520
1529
  channel,
1521
1530
  environmentId,
1522
1531
  unsubscribe: async () => {
@@ -1747,6 +1756,38 @@ var devCommand = new Command9("dev").description("Start real-time sync daemon -
1747
1756
  spinner.text = "Connecting to realtime...";
1748
1757
  let fileWatcher = null;
1749
1758
  let isPaused = false;
1759
+ let lastRemoteKeys = null;
1760
+ async function syncRemoteToLocal(silent = false) {
1761
+ const updatedVariables = await fetchAllVariables(environmentId, true);
1762
+ const currentLocal = /* @__PURE__ */ new Map();
1763
+ if (existsSync7(outputFile)) {
1764
+ const content = readFileSync6(outputFile, "utf-8");
1765
+ Object.entries(parseDotenv3(content)).forEach(([k, v]) => {
1766
+ currentLocal.set(k, v);
1767
+ });
1768
+ }
1769
+ const newMerged = mergeWithRemote(currentLocal, updatedVariables, strategy);
1770
+ const remoteKeySig = [...newMerged.entries()].sort().map(([k, v]) => `${k}=${v}`).join("\n");
1771
+ if (remoteKeySig === lastRemoteKeys) return false;
1772
+ lastRemoteKeys = remoteKeySig;
1773
+ if (!silent) {
1774
+ const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString();
1775
+ for (const key of currentLocal.keys()) {
1776
+ if (!newMerged.has(key)) {
1777
+ console.log(chalk10.red(`[${timestamp}] - ${key}`));
1778
+ }
1779
+ }
1780
+ for (const [key] of newMerged) {
1781
+ if (!currentLocal.has(key)) {
1782
+ console.log(chalk10.green(`[${timestamp}] + ${key}`));
1783
+ }
1784
+ }
1785
+ }
1786
+ writeFileSync3(outputFile, formatEnvFile(newMerged));
1787
+ return true;
1788
+ }
1789
+ const initialKeys = [...merged.entries()].sort().map(([k, v]) => `${k}=${v}`).join("\n");
1790
+ lastRemoteKeys = initialKeys;
1750
1791
  const subscription = await subscribeToVariableChanges(
1751
1792
  environmentId,
1752
1793
  async (event) => {
@@ -1769,16 +1810,7 @@ var devCommand = new Command9("dev").description("Start real-time sync daemon -
1769
1810
  }
1770
1811
  isPaused = true;
1771
1812
  try {
1772
- const updatedVariables = await fetchAllVariables(environmentId, true);
1773
- const currentLocal = /* @__PURE__ */ new Map();
1774
- if (existsSync7(outputFile)) {
1775
- const content = readFileSync6(outputFile, "utf-8");
1776
- Object.entries(parseDotenv3(content)).forEach(([k, v]) => {
1777
- currentLocal.set(k, v);
1778
- });
1779
- }
1780
- const newMerged = mergeWithRemote(currentLocal, updatedVariables, strategy);
1781
- writeFileSync3(outputFile, formatEnvFile(newMerged));
1813
+ await syncRemoteToLocal(true);
1782
1814
  } finally {
1783
1815
  isPaused = false;
1784
1816
  }
@@ -1825,6 +1857,17 @@ Realtime error: ${message || ""}`));
1825
1857
  console.log(chalk10.gray("Watching for changes. Press Ctrl+C to stop."));
1826
1858
  console.log("");
1827
1859
  let isCleaningUp = false;
1860
+ const POLL_INTERVAL_MS = 5e3;
1861
+ const pollInterval = setInterval(async () => {
1862
+ if (isPaused) return;
1863
+ isPaused = true;
1864
+ try {
1865
+ await syncRemoteToLocal();
1866
+ } catch {
1867
+ } finally {
1868
+ isPaused = false;
1869
+ }
1870
+ }, POLL_INTERVAL_MS);
1828
1871
  const TOKEN_REFRESH_INTERVAL_MS = 30 * 60 * 1e3;
1829
1872
  const refreshInterval = setInterval(async () => {
1830
1873
  try {
@@ -1839,6 +1882,7 @@ Realtime error: ${message || ""}`));
1839
1882
  }
1840
1883
  isCleaningUp = true;
1841
1884
  console.log(chalk10.gray("\nStopping dev mode..."));
1885
+ clearInterval(pollInterval);
1842
1886
  clearInterval(refreshInterval);
1843
1887
  fileWatcher?.stop();
1844
1888
  subscription.unsubscribe().catch(() => {
@@ -2991,9 +3035,9 @@ import { fileURLToPath } from "url";
2991
3035
  import { dirname as dirname2, resolve as resolve8 } from "path";
2992
3036
  function getCliVersion() {
2993
3037
  try {
2994
- const __dirname2 = dirname2(fileURLToPath(import.meta.url));
2995
- const pkg = JSON.parse(readFileSync9(resolve8(__dirname2, "../../package.json"), "utf-8"));
2996
- return pkg.version || "unknown";
3038
+ const __dirname3 = dirname2(fileURLToPath(import.meta.url));
3039
+ const pkg2 = JSON.parse(readFileSync9(resolve8(__dirname3, "../../package.json"), "utf-8"));
3040
+ return pkg2.version || "unknown";
2997
3041
  } catch {
2998
3042
  return "unknown";
2999
3043
  }
@@ -3085,8 +3129,10 @@ var debugCommand = new Command14("debug").description("Collect diagnostic info f
3085
3129
  });
3086
3130
 
3087
3131
  // src/bin/envmanager.ts
3132
+ var __dirname2 = dirname3(fileURLToPath2(import.meta.url));
3133
+ var pkg = JSON.parse(readFileSync10(resolve9(__dirname2, "../../package.json"), "utf-8"));
3088
3134
  var program = new Command15();
3089
- program.name("envmanager").description("CLI for EnvManager - secure environment variable management").version("0.1.0");
3135
+ program.name("envmanager").description("CLI for EnvManager - secure environment variable management").version(pkg.version);
3090
3136
  program.addCommand(loginCommand);
3091
3137
  program.addCommand(logoutCommand);
3092
3138
  program.addCommand(whoamiCommand);