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.
- package/dist/index.js +141 -33
- 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
|
|
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
|
|
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
|
-
|
|
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
|
|
13659
|
-
|
|
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(`
|
|
13744
|
+
consola.warn(` Nothing to push for ${app.name}${reason}. Skipping.`);
|
|
13662
13745
|
continue;
|
|
13663
13746
|
}
|
|
13664
13747
|
if (args["dry-run"]) {
|
|
13665
|
-
|
|
13666
|
-
|
|
13667
|
-
const
|
|
13668
|
-
|
|
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
|
|
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
|
-
|
|
13680
|
-
|
|
13681
|
-
|
|
13682
|
-
|
|
13683
|
-
|
|
13684
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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(
|
|
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(
|
|
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 =
|
|
14256
|
-
const appDir =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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"]')) {
|