cf-envsync 0.3.9 → 0.3.11

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 (2) hide show
  1. package/dist/index.js +141 -33
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -13485,6 +13485,48 @@ async function exec(command, options = {}) {
13485
13485
  var init_process = () => {};
13486
13486
 
13487
13487
  // src/core/wrangler.ts
13488
+ import { join as join6 } from "node:path";
13489
+ function stripJsonc(text) {
13490
+ let result = "";
13491
+ let i2 = 0;
13492
+ let inString = false;
13493
+ while (i2 < text.length) {
13494
+ if (inString) {
13495
+ result += text[i2];
13496
+ if (text[i2] === "\\" && i2 + 1 < text.length) {
13497
+ result += text[i2 + 1];
13498
+ i2 += 2;
13499
+ continue;
13500
+ }
13501
+ if (text[i2] === '"')
13502
+ inString = false;
13503
+ i2++;
13504
+ continue;
13505
+ }
13506
+ if (text[i2] === '"') {
13507
+ inString = true;
13508
+ result += text[i2];
13509
+ i2++;
13510
+ continue;
13511
+ }
13512
+ if (text[i2] === "/" && text[i2 + 1] === "/") {
13513
+ while (i2 < text.length && text[i2] !== `
13514
+ `)
13515
+ i2++;
13516
+ continue;
13517
+ }
13518
+ if (text[i2] === "/" && text[i2 + 1] === "*") {
13519
+ i2 += 2;
13520
+ while (i2 < text.length && !(text[i2] === "*" && text[i2 + 1] === "/"))
13521
+ i2++;
13522
+ i2 += 2;
13523
+ continue;
13524
+ }
13525
+ result += text[i2];
13526
+ i2++;
13527
+ }
13528
+ return result.replace(/,(\s*[}\]])/g, "$1");
13529
+ }
13488
13530
  async function checkWrangler() {
13489
13531
  const result = await exec(["npx", "wrangler", "--version"]);
13490
13532
  return result.success;
@@ -13531,9 +13573,39 @@ async function listSecrets(workerName, _environment, cwd) {
13531
13573
  `).map((line) => line.trim()).filter((line) => line.length > 0);
13532
13574
  }
13533
13575
  }
13576
+ function findWranglerConfig(appPath) {
13577
+ for (const name of ["wrangler.jsonc", "wrangler.json"]) {
13578
+ const p = join6(appPath, name);
13579
+ if (fileExists(p))
13580
+ return p;
13581
+ }
13582
+ return;
13583
+ }
13584
+ async function updateWranglerVars(appPath, environment, vars) {
13585
+ const configPath = findWranglerConfig(appPath);
13586
+ if (!configPath) {
13587
+ return { success: false, updatedCount: 0 };
13588
+ }
13589
+ const content = await readFile(configPath);
13590
+ const stripped = stripJsonc(content);
13591
+ const config = JSON.parse(stripped);
13592
+ if (!config.env || typeof config.env !== "object") {
13593
+ config.env = {};
13594
+ }
13595
+ const envSection = config.env;
13596
+ if (!envSection[environment] || typeof envSection[environment] !== "object") {
13597
+ envSection[environment] = {};
13598
+ }
13599
+ const existingVars = envSection[environment].vars || {};
13600
+ envSection[environment].vars = { ...existingVars, ...vars };
13601
+ await writeFile(configPath, JSON.stringify(config, null, 2) + `
13602
+ `);
13603
+ return { success: true, filePath: configPath, updatedCount: Object.keys(vars).length };
13604
+ }
13534
13605
  var init_wrangler = __esm(() => {
13535
13606
  init_dist2();
13536
13607
  init_process();
13608
+ init_fs();
13537
13609
  });
13538
13610
 
13539
13611
  // src/commands/push.ts
@@ -13555,7 +13627,7 @@ var init_push = __esm(() => {
13555
13627
  push_default = defineCommand({
13556
13628
  meta: {
13557
13629
  name: "push",
13558
- description: "Push env vars to Cloudflare Workers secrets"
13630
+ description: "Push secrets (wrangler) and vars (wrangler.jsonc) to Cloudflare Workers"
13559
13631
  },
13560
13632
  args: {
13561
13633
  env: {
@@ -13636,52 +13708,88 @@ var init_push = __esm(() => {
13636
13708
  consola.warn(`${progress}No worker defined for ${app.name} in ${environment}. Skipping.`);
13637
13709
  continue;
13638
13710
  }
13639
- consola.start(`${progress}Pushing secrets for ${app.name} → ${workerName} (${environment})...`);
13711
+ consola.start(`${progress}Pushing ${app.name} → ${workerName} (${environment})...`);
13640
13712
  const resolved = await resolveAppEnv(config, app, environment);
13641
13713
  let secretsToPush;
13714
+ let varsToPush;
13715
+ const secretKeySet = new Set(app.secrets ?? []);
13716
+ const varsKeySet = new Set(app.vars ?? []);
13642
13717
  if (args.shared) {
13643
13718
  secretsToPush = {};
13719
+ varsToPush = {};
13644
13720
  for (const [key, value] of Object.entries(resolved.map)) {
13645
13721
  if (sharedKeys.has(key)) {
13646
- secretsToPush[key] = value;
13722
+ if (secretKeySet.has(key)) {
13723
+ secretsToPush[key] = value;
13724
+ } else if (varsKeySet.has(key)) {
13725
+ varsToPush[key] = value;
13726
+ }
13647
13727
  }
13648
13728
  }
13649
13729
  } else {
13650
- const secretKeySet = new Set(app.secrets ?? []);
13651
13730
  secretsToPush = {};
13731
+ varsToPush = {};
13652
13732
  for (const [key, value] of Object.entries(resolved.map)) {
13653
13733
  if (secretKeySet.has(key)) {
13654
13734
  secretsToPush[key] = value;
13735
+ } else if (varsKeySet.has(key)) {
13736
+ varsToPush[key] = value;
13655
13737
  }
13656
13738
  }
13657
13739
  }
13658
- const keyCount = Object.keys(secretsToPush).length;
13659
- if (keyCount === 0) {
13740
+ const secretCount = Object.keys(secretsToPush).length;
13741
+ const varsCount = Object.keys(varsToPush).length;
13742
+ if (secretCount === 0 && varsCount === 0) {
13660
13743
  const reason = args.shared ? " (no shared keys for this app)" : "";
13661
- consola.warn(` No secrets to push for ${app.name}${reason}. Skipping.`);
13744
+ consola.warn(` Nothing to push for ${app.name}${reason}. Skipping.`);
13662
13745
  continue;
13663
13746
  }
13664
13747
  if (args["dry-run"]) {
13665
- consola.info(` Would push ${keyCount} secrets to worker "${workerName}"`);
13666
- for (const key of Object.keys(secretsToPush)) {
13667
- const isShared = sharedKeys.has(key) ? " (shared)" : "";
13668
- consola.log(` ${key}${isShared}`);
13748
+ if (secretCount > 0) {
13749
+ consola.info(` Would push ${secretCount} secrets to worker "${workerName}"`);
13750
+ for (const key of Object.keys(secretsToPush)) {
13751
+ const isShared = sharedKeys.has(key) ? " (shared)" : "";
13752
+ consola.log(` ${key}${isShared}`);
13753
+ }
13754
+ }
13755
+ if (varsCount > 0) {
13756
+ consola.info(` Would write ${varsCount} vars to wrangler config`);
13757
+ for (const key of Object.keys(varsToPush)) {
13758
+ const isShared = sharedKeys.has(key) ? " (shared)" : "";
13759
+ consola.log(` ${key}${isShared}`);
13760
+ }
13669
13761
  }
13670
13762
  continue;
13671
13763
  }
13672
13764
  if (!args.force) {
13673
- const confirmed = await consola.prompt(` Push ${keyCount} secrets to worker "${workerName}" (${environment})?`, { type: "confirm" });
13765
+ const parts = [];
13766
+ if (secretCount > 0)
13767
+ parts.push(`${secretCount} secrets`);
13768
+ if (varsCount > 0)
13769
+ parts.push(`${varsCount} vars`);
13770
+ const confirmed = await consola.prompt(` Push ${parts.join(" + ")} to "${workerName}" (${environment})?`, { type: "confirm" });
13674
13771
  if (!confirmed) {
13675
13772
  consola.info(` Skipped ${app.name}.`);
13676
13773
  continue;
13677
13774
  }
13678
13775
  }
13679
- const result = await pushSecrets(workerName, secretsToPush, environment, app.absolutePath);
13680
- if (result.success) {
13681
- consola.success(` Pushed ${keyCount} secrets to ${workerName}`);
13682
- } else {
13683
- consola.error(` Failed to push secrets to ${workerName}`);
13684
- hasFailure = true;
13776
+ if (secretCount > 0) {
13777
+ const result = await pushSecrets(workerName, secretsToPush, environment, app.absolutePath);
13778
+ if (result.success) {
13779
+ consola.success(` Pushed ${secretCount} secrets to ${workerName}`);
13780
+ } else {
13781
+ consola.error(` Failed to push secrets to ${workerName}`);
13782
+ hasFailure = true;
13783
+ }
13784
+ }
13785
+ if (varsCount > 0) {
13786
+ const varsResult = await updateWranglerVars(app.absolutePath, environment, varsToPush);
13787
+ if (varsResult.success) {
13788
+ consola.success(` Wrote ${varsCount} vars to ${varsResult.filePath}`);
13789
+ } else {
13790
+ consola.error(` No wrangler.jsonc found in ${app.absolutePath}. Cannot write vars.`);
13791
+ hasFailure = true;
13792
+ }
13685
13793
  }
13686
13794
  }
13687
13795
  if (hasFailure) {
@@ -13785,7 +13893,7 @@ var exports_validate = {};
13785
13893
  __export(exports_validate, {
13786
13894
  default: () => validate_default
13787
13895
  });
13788
- import { join as join6 } from "node:path";
13896
+ import { join as join7 } from "node:path";
13789
13897
  function parseAppNames4(args, skip = 1) {
13790
13898
  const rest = args._?.slice(skip);
13791
13899
  return rest?.length ? rest : undefined;
@@ -13840,7 +13948,7 @@ var init_validate = __esm(() => {
13840
13948
  appNames = undefined;
13841
13949
  }
13842
13950
  const apps = resolveApps(config, appNames);
13843
- const examplePath = join6(config.projectRoot, ".env.example");
13951
+ const examplePath = join7(config.projectRoot, ".env.example");
13844
13952
  if (!fileExists(examplePath)) {
13845
13953
  consola.error("No .env.example found at project root.");
13846
13954
  process.exit(1);
@@ -14128,7 +14236,7 @@ var exports_init = {};
14128
14236
  __export(exports_init, {
14129
14237
  default: () => init_default
14130
14238
  });
14131
- import { join as join7, relative as relative3, basename } from "node:path";
14239
+ import { join as join8, relative as relative3, basename } from "node:path";
14132
14240
  function generateConfigTS(config) {
14133
14241
  const lines = [
14134
14242
  `import { defineConfig } from "cf-envsync";`,
@@ -14209,10 +14317,10 @@ var init_init = __esm(() => {
14209
14317
  },
14210
14318
  async run({ args }) {
14211
14319
  const cwd = process.cwd();
14212
- const existingConfig = CONFIG_FILES.find((f3) => fileExists(join7(cwd, f3)));
14320
+ const existingConfig = CONFIG_FILES.find((f3) => fileExists(join8(cwd, f3)));
14213
14321
  if (existingConfig) {
14214
14322
  consola.warn(`${existingConfig} already exists.`);
14215
- const existingContent = await readFile(join7(cwd, existingConfig));
14323
+ const existingContent = await readFile(join8(cwd, existingConfig));
14216
14324
  const lines = existingContent.split(`
14217
14325
  `);
14218
14326
  const preview = lines.length > 20 ? [...lines.slice(0, 20), ` ... (${lines.length - 20} more lines)`].join(`
@@ -14252,8 +14360,8 @@ ${preview}
14252
14360
  ` + " Falling back to manual configuration.");
14253
14361
  }
14254
14362
  for (const wranglerFile of wranglerFiles.sort()) {
14255
- const fullPath = join7(cwd, wranglerFile);
14256
- const appDir = join7(cwd, wranglerFile, "..");
14363
+ const fullPath = join8(cwd, wranglerFile);
14364
+ const appDir = join8(cwd, wranglerFile, "..");
14257
14365
  const appPath = relative3(cwd, appDir);
14258
14366
  const appName = basename(appDir);
14259
14367
  consola.info(` Found ${wranglerFile}`);
@@ -14354,10 +14462,10 @@ ${preview}
14354
14462
  apps,
14355
14463
  ...shared.length > 0 ? { shared } : {}
14356
14464
  };
14357
- const configPath = join7(cwd, "envsync.config.ts");
14465
+ const configPath = join8(cwd, "envsync.config.ts");
14358
14466
  const tsContent = generateConfigTS(config);
14359
14467
  if (existingConfig && existingConfig !== "envsync.config.ts") {
14360
- const oldPath = join7(cwd, existingConfig);
14468
+ const oldPath = join8(cwd, existingConfig);
14361
14469
  if (fileExists(oldPath)) {
14362
14470
  const { unlink } = await import("node:fs/promises");
14363
14471
  await unlink(oldPath);
@@ -14365,7 +14473,7 @@ ${preview}
14365
14473
  }
14366
14474
  await writeFile(configPath, tsContent);
14367
14475
  consola.success("Created envsync.config.ts");
14368
- const examplePath = join7(cwd, ".env.example");
14476
+ const examplePath = join8(cwd, ".env.example");
14369
14477
  if (!fileExists(examplePath)) {
14370
14478
  const allKeys = new Set;
14371
14479
  for (const app of Object.values(apps)) {
@@ -14388,20 +14496,20 @@ ${preview}
14388
14496
  for (const env2 of environments) {
14389
14497
  if (env2 === "local")
14390
14498
  continue;
14391
- const envFile = join7(cwd, `.env.${env2}`);
14499
+ const envFile = join8(cwd, `.env.${env2}`);
14392
14500
  if (!fileExists(envFile)) {
14393
14501
  await writeFile(envFile, `# ${env2} environment variables
14394
14502
  `);
14395
14503
  consola.success(`Created .env.${env2}`);
14396
14504
  }
14397
14505
  }
14398
- const rootEnv = join7(cwd, ".env");
14506
+ const rootEnv = join8(cwd, ".env");
14399
14507
  if (!fileExists(rootEnv)) {
14400
14508
  await writeFile(rootEnv, `# Local environment variables
14401
14509
  `);
14402
14510
  consola.success("Created .env");
14403
14511
  }
14404
- const gitignorePath = join7(cwd, ".gitignore");
14512
+ const gitignorePath = join8(cwd, ".gitignore");
14405
14513
  const gitignoreEntries = [".env.local", ".env.keys", ".env.password", "**/.dev.vars"];
14406
14514
  if (fileExists(gitignorePath)) {
14407
14515
  const existing = await readFile(gitignorePath);
@@ -14422,7 +14530,7 @@ ${preview}
14422
14530
  `);
14423
14531
  consola.success(`Created .gitignore`);
14424
14532
  }
14425
- const gitattrsPath = join7(cwd, ".gitattributes");
14533
+ const gitattrsPath = join8(cwd, ".gitattributes");
14426
14534
  const mergeDriverLines = `.env merge=envsync
14427
14535
  .env.* merge=envsync
14428
14536
  `;
@@ -14438,7 +14546,7 @@ ${preview}
14438
14546
  await writeFile(gitattrsPath, mergeDriverLines);
14439
14547
  consola.success("Created .gitattributes with merge driver");
14440
14548
  }
14441
- const gitConfigPath = join7(cwd, ".git", "config");
14549
+ const gitConfigPath = join8(cwd, ".git", "config");
14442
14550
  if (fileExists(gitConfigPath)) {
14443
14551
  const gitConfig = await readFile(gitConfigPath);
14444
14552
  if (!gitConfig.includes('[merge "envsync"]')) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cf-envsync",
3
- "version": "0.3.9",
3
+ "version": "0.3.11",
4
4
  "description": "Sync .env files to Cloudflare Workers secrets, .dev.vars, and more",
5
5
  "type": "module",
6
6
  "exports": {