cf-envsync 0.3.9 → 0.3.10
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 +133 -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,31 @@ 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, 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
|
+
config.vars = { ...config.vars || {}, ...vars };
|
|
13593
|
+
await writeFile(configPath, JSON.stringify(config, null, 2) + `
|
|
13594
|
+
`);
|
|
13595
|
+
return { success: true, filePath: configPath, updatedCount: Object.keys(vars).length };
|
|
13596
|
+
}
|
|
13534
13597
|
var init_wrangler = __esm(() => {
|
|
13535
13598
|
init_dist2();
|
|
13536
13599
|
init_process();
|
|
13600
|
+
init_fs();
|
|
13537
13601
|
});
|
|
13538
13602
|
|
|
13539
13603
|
// src/commands/push.ts
|
|
@@ -13555,7 +13619,7 @@ var init_push = __esm(() => {
|
|
|
13555
13619
|
push_default = defineCommand({
|
|
13556
13620
|
meta: {
|
|
13557
13621
|
name: "push",
|
|
13558
|
-
description: "Push
|
|
13622
|
+
description: "Push secrets (wrangler) and vars (wrangler.jsonc) to Cloudflare Workers"
|
|
13559
13623
|
},
|
|
13560
13624
|
args: {
|
|
13561
13625
|
env: {
|
|
@@ -13636,52 +13700,88 @@ var init_push = __esm(() => {
|
|
|
13636
13700
|
consola.warn(`${progress}No worker defined for ${app.name} in ${environment}. Skipping.`);
|
|
13637
13701
|
continue;
|
|
13638
13702
|
}
|
|
13639
|
-
consola.start(`${progress}Pushing
|
|
13703
|
+
consola.start(`${progress}Pushing ${app.name} → ${workerName} (${environment})...`);
|
|
13640
13704
|
const resolved = await resolveAppEnv(config, app, environment);
|
|
13641
13705
|
let secretsToPush;
|
|
13706
|
+
let varsToPush;
|
|
13707
|
+
const secretKeySet = new Set(app.secrets ?? []);
|
|
13708
|
+
const varsKeySet = new Set(app.vars ?? []);
|
|
13642
13709
|
if (args.shared) {
|
|
13643
13710
|
secretsToPush = {};
|
|
13711
|
+
varsToPush = {};
|
|
13644
13712
|
for (const [key, value] of Object.entries(resolved.map)) {
|
|
13645
13713
|
if (sharedKeys.has(key)) {
|
|
13646
|
-
|
|
13714
|
+
if (secretKeySet.has(key)) {
|
|
13715
|
+
secretsToPush[key] = value;
|
|
13716
|
+
} else if (varsKeySet.has(key)) {
|
|
13717
|
+
varsToPush[key] = value;
|
|
13718
|
+
}
|
|
13647
13719
|
}
|
|
13648
13720
|
}
|
|
13649
13721
|
} else {
|
|
13650
|
-
const secretKeySet = new Set(app.secrets ?? []);
|
|
13651
13722
|
secretsToPush = {};
|
|
13723
|
+
varsToPush = {};
|
|
13652
13724
|
for (const [key, value] of Object.entries(resolved.map)) {
|
|
13653
13725
|
if (secretKeySet.has(key)) {
|
|
13654
13726
|
secretsToPush[key] = value;
|
|
13727
|
+
} else if (varsKeySet.has(key)) {
|
|
13728
|
+
varsToPush[key] = value;
|
|
13655
13729
|
}
|
|
13656
13730
|
}
|
|
13657
13731
|
}
|
|
13658
|
-
const
|
|
13659
|
-
|
|
13732
|
+
const secretCount = Object.keys(secretsToPush).length;
|
|
13733
|
+
const varsCount = Object.keys(varsToPush).length;
|
|
13734
|
+
if (secretCount === 0 && varsCount === 0) {
|
|
13660
13735
|
const reason = args.shared ? " (no shared keys for this app)" : "";
|
|
13661
|
-
consola.warn(`
|
|
13736
|
+
consola.warn(` Nothing to push for ${app.name}${reason}. Skipping.`);
|
|
13662
13737
|
continue;
|
|
13663
13738
|
}
|
|
13664
13739
|
if (args["dry-run"]) {
|
|
13665
|
-
|
|
13666
|
-
|
|
13667
|
-
const
|
|
13668
|
-
|
|
13740
|
+
if (secretCount > 0) {
|
|
13741
|
+
consola.info(` Would push ${secretCount} secrets to worker "${workerName}"`);
|
|
13742
|
+
for (const key of Object.keys(secretsToPush)) {
|
|
13743
|
+
const isShared = sharedKeys.has(key) ? " (shared)" : "";
|
|
13744
|
+
consola.log(` ${key}${isShared}`);
|
|
13745
|
+
}
|
|
13746
|
+
}
|
|
13747
|
+
if (varsCount > 0) {
|
|
13748
|
+
consola.info(` Would write ${varsCount} vars to wrangler config`);
|
|
13749
|
+
for (const key of Object.keys(varsToPush)) {
|
|
13750
|
+
const isShared = sharedKeys.has(key) ? " (shared)" : "";
|
|
13751
|
+
consola.log(` ${key}${isShared}`);
|
|
13752
|
+
}
|
|
13669
13753
|
}
|
|
13670
13754
|
continue;
|
|
13671
13755
|
}
|
|
13672
13756
|
if (!args.force) {
|
|
13673
|
-
const
|
|
13757
|
+
const parts = [];
|
|
13758
|
+
if (secretCount > 0)
|
|
13759
|
+
parts.push(`${secretCount} secrets`);
|
|
13760
|
+
if (varsCount > 0)
|
|
13761
|
+
parts.push(`${varsCount} vars`);
|
|
13762
|
+
const confirmed = await consola.prompt(` Push ${parts.join(" + ")} to "${workerName}" (${environment})?`, { type: "confirm" });
|
|
13674
13763
|
if (!confirmed) {
|
|
13675
13764
|
consola.info(` Skipped ${app.name}.`);
|
|
13676
13765
|
continue;
|
|
13677
13766
|
}
|
|
13678
13767
|
}
|
|
13679
|
-
|
|
13680
|
-
|
|
13681
|
-
|
|
13682
|
-
|
|
13683
|
-
|
|
13684
|
-
|
|
13768
|
+
if (secretCount > 0) {
|
|
13769
|
+
const result = await pushSecrets(workerName, secretsToPush, environment, app.absolutePath);
|
|
13770
|
+
if (result.success) {
|
|
13771
|
+
consola.success(` Pushed ${secretCount} secrets to ${workerName}`);
|
|
13772
|
+
} else {
|
|
13773
|
+
consola.error(` Failed to push secrets to ${workerName}`);
|
|
13774
|
+
hasFailure = true;
|
|
13775
|
+
}
|
|
13776
|
+
}
|
|
13777
|
+
if (varsCount > 0) {
|
|
13778
|
+
const varsResult = await updateWranglerVars(app.absolutePath, varsToPush);
|
|
13779
|
+
if (varsResult.success) {
|
|
13780
|
+
consola.success(` Wrote ${varsCount} vars to ${varsResult.filePath}`);
|
|
13781
|
+
} else {
|
|
13782
|
+
consola.error(` No wrangler.jsonc found in ${app.absolutePath}. Cannot write vars.`);
|
|
13783
|
+
hasFailure = true;
|
|
13784
|
+
}
|
|
13685
13785
|
}
|
|
13686
13786
|
}
|
|
13687
13787
|
if (hasFailure) {
|
|
@@ -13785,7 +13885,7 @@ var exports_validate = {};
|
|
|
13785
13885
|
__export(exports_validate, {
|
|
13786
13886
|
default: () => validate_default
|
|
13787
13887
|
});
|
|
13788
|
-
import { join as
|
|
13888
|
+
import { join as join7 } from "node:path";
|
|
13789
13889
|
function parseAppNames4(args, skip = 1) {
|
|
13790
13890
|
const rest = args._?.slice(skip);
|
|
13791
13891
|
return rest?.length ? rest : undefined;
|
|
@@ -13840,7 +13940,7 @@ var init_validate = __esm(() => {
|
|
|
13840
13940
|
appNames = undefined;
|
|
13841
13941
|
}
|
|
13842
13942
|
const apps = resolveApps(config, appNames);
|
|
13843
|
-
const examplePath =
|
|
13943
|
+
const examplePath = join7(config.projectRoot, ".env.example");
|
|
13844
13944
|
if (!fileExists(examplePath)) {
|
|
13845
13945
|
consola.error("No .env.example found at project root.");
|
|
13846
13946
|
process.exit(1);
|
|
@@ -14128,7 +14228,7 @@ var exports_init = {};
|
|
|
14128
14228
|
__export(exports_init, {
|
|
14129
14229
|
default: () => init_default
|
|
14130
14230
|
});
|
|
14131
|
-
import { join as
|
|
14231
|
+
import { join as join8, relative as relative3, basename } from "node:path";
|
|
14132
14232
|
function generateConfigTS(config) {
|
|
14133
14233
|
const lines = [
|
|
14134
14234
|
`import { defineConfig } from "cf-envsync";`,
|
|
@@ -14209,10 +14309,10 @@ var init_init = __esm(() => {
|
|
|
14209
14309
|
},
|
|
14210
14310
|
async run({ args }) {
|
|
14211
14311
|
const cwd = process.cwd();
|
|
14212
|
-
const existingConfig = CONFIG_FILES.find((f3) => fileExists(
|
|
14312
|
+
const existingConfig = CONFIG_FILES.find((f3) => fileExists(join8(cwd, f3)));
|
|
14213
14313
|
if (existingConfig) {
|
|
14214
14314
|
consola.warn(`${existingConfig} already exists.`);
|
|
14215
|
-
const existingContent = await readFile(
|
|
14315
|
+
const existingContent = await readFile(join8(cwd, existingConfig));
|
|
14216
14316
|
const lines = existingContent.split(`
|
|
14217
14317
|
`);
|
|
14218
14318
|
const preview = lines.length > 20 ? [...lines.slice(0, 20), ` ... (${lines.length - 20} more lines)`].join(`
|
|
@@ -14252,8 +14352,8 @@ ${preview}
|
|
|
14252
14352
|
` + " Falling back to manual configuration.");
|
|
14253
14353
|
}
|
|
14254
14354
|
for (const wranglerFile of wranglerFiles.sort()) {
|
|
14255
|
-
const fullPath =
|
|
14256
|
-
const appDir =
|
|
14355
|
+
const fullPath = join8(cwd, wranglerFile);
|
|
14356
|
+
const appDir = join8(cwd, wranglerFile, "..");
|
|
14257
14357
|
const appPath = relative3(cwd, appDir);
|
|
14258
14358
|
const appName = basename(appDir);
|
|
14259
14359
|
consola.info(` Found ${wranglerFile}`);
|
|
@@ -14354,10 +14454,10 @@ ${preview}
|
|
|
14354
14454
|
apps,
|
|
14355
14455
|
...shared.length > 0 ? { shared } : {}
|
|
14356
14456
|
};
|
|
14357
|
-
const configPath =
|
|
14457
|
+
const configPath = join8(cwd, "envsync.config.ts");
|
|
14358
14458
|
const tsContent = generateConfigTS(config);
|
|
14359
14459
|
if (existingConfig && existingConfig !== "envsync.config.ts") {
|
|
14360
|
-
const oldPath =
|
|
14460
|
+
const oldPath = join8(cwd, existingConfig);
|
|
14361
14461
|
if (fileExists(oldPath)) {
|
|
14362
14462
|
const { unlink } = await import("node:fs/promises");
|
|
14363
14463
|
await unlink(oldPath);
|
|
@@ -14365,7 +14465,7 @@ ${preview}
|
|
|
14365
14465
|
}
|
|
14366
14466
|
await writeFile(configPath, tsContent);
|
|
14367
14467
|
consola.success("Created envsync.config.ts");
|
|
14368
|
-
const examplePath =
|
|
14468
|
+
const examplePath = join8(cwd, ".env.example");
|
|
14369
14469
|
if (!fileExists(examplePath)) {
|
|
14370
14470
|
const allKeys = new Set;
|
|
14371
14471
|
for (const app of Object.values(apps)) {
|
|
@@ -14388,20 +14488,20 @@ ${preview}
|
|
|
14388
14488
|
for (const env2 of environments) {
|
|
14389
14489
|
if (env2 === "local")
|
|
14390
14490
|
continue;
|
|
14391
|
-
const envFile =
|
|
14491
|
+
const envFile = join8(cwd, `.env.${env2}`);
|
|
14392
14492
|
if (!fileExists(envFile)) {
|
|
14393
14493
|
await writeFile(envFile, `# ${env2} environment variables
|
|
14394
14494
|
`);
|
|
14395
14495
|
consola.success(`Created .env.${env2}`);
|
|
14396
14496
|
}
|
|
14397
14497
|
}
|
|
14398
|
-
const rootEnv =
|
|
14498
|
+
const rootEnv = join8(cwd, ".env");
|
|
14399
14499
|
if (!fileExists(rootEnv)) {
|
|
14400
14500
|
await writeFile(rootEnv, `# Local environment variables
|
|
14401
14501
|
`);
|
|
14402
14502
|
consola.success("Created .env");
|
|
14403
14503
|
}
|
|
14404
|
-
const gitignorePath =
|
|
14504
|
+
const gitignorePath = join8(cwd, ".gitignore");
|
|
14405
14505
|
const gitignoreEntries = [".env.local", ".env.keys", ".env.password", "**/.dev.vars"];
|
|
14406
14506
|
if (fileExists(gitignorePath)) {
|
|
14407
14507
|
const existing = await readFile(gitignorePath);
|
|
@@ -14422,7 +14522,7 @@ ${preview}
|
|
|
14422
14522
|
`);
|
|
14423
14523
|
consola.success(`Created .gitignore`);
|
|
14424
14524
|
}
|
|
14425
|
-
const gitattrsPath =
|
|
14525
|
+
const gitattrsPath = join8(cwd, ".gitattributes");
|
|
14426
14526
|
const mergeDriverLines = `.env merge=envsync
|
|
14427
14527
|
.env.* merge=envsync
|
|
14428
14528
|
`;
|
|
@@ -14438,7 +14538,7 @@ ${preview}
|
|
|
14438
14538
|
await writeFile(gitattrsPath, mergeDriverLines);
|
|
14439
14539
|
consola.success("Created .gitattributes with merge driver");
|
|
14440
14540
|
}
|
|
14441
|
-
const gitConfigPath =
|
|
14541
|
+
const gitConfigPath = join8(cwd, ".git", "config");
|
|
14442
14542
|
if (fileExists(gitConfigPath)) {
|
|
14443
14543
|
const gitConfig = await readFile(gitConfigPath);
|
|
14444
14544
|
if (!gitConfig.includes('[merge "envsync"]')) {
|