@marvalt/digivalt-core 0.1.1 โ 0.1.3
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/bin/init.cjs +2 -1
- package/package.json +1 -1
- package/template/scripts/deploy-secrets.js +93 -0
package/bin/init.cjs
CHANGED
|
@@ -34,7 +34,8 @@ try {
|
|
|
34
34
|
console.log('\n๐ DigiVAlt Cloudflare proxy routes installed successfully!');
|
|
35
35
|
console.log('๐ Next Steps:');
|
|
36
36
|
console.log('1. Copy .dev.vars.example to .dev.vars and add your API keys.');
|
|
37
|
-
console.log("2.
|
|
37
|
+
console.log("2. Sync your production credentials to Cloudflare by running:");
|
|
38
|
+
console.log(" ๐ node scripts/deploy-secrets.js");
|
|
38
39
|
console.log("3. Run `npx wrangler pages dev` to test your proxy functions locally.");
|
|
39
40
|
} catch (error) {
|
|
40
41
|
console.error('โ Failed to construct templates:', error);
|
package/package.json
CHANGED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ๐ DigiVAlt Cloudflare Secrets Deployer
|
|
7
|
+
*
|
|
8
|
+
* Automates the synchronization of local .env.local variables
|
|
9
|
+
* securely straight into your Cloudflare Pages environment
|
|
10
|
+
* using Wrangler bulk secret injection.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const envPath = path.resolve(process.cwd(), '.env.local');
|
|
14
|
+
|
|
15
|
+
if (!fs.existsSync(envPath)) {
|
|
16
|
+
console.error("โ No .env.local file found in the root directory!");
|
|
17
|
+
console.log("๐ Please create a .env.local file with your production secrets.");
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log("๐ Parsing .env.local secrets...");
|
|
22
|
+
const rawEnv = fs.readFileSync(envPath, 'utf8');
|
|
23
|
+
const secrets = {};
|
|
24
|
+
|
|
25
|
+
rawEnv.split('\n').forEach(line => {
|
|
26
|
+
const trimmed = line.trim();
|
|
27
|
+
// Ignore comments and empty lines
|
|
28
|
+
if (!trimmed || trimmed.startsWith('#')) return;
|
|
29
|
+
|
|
30
|
+
const match = trimmed.match(/^([^=]+)=(.*)$/);
|
|
31
|
+
if (match) {
|
|
32
|
+
const key = match[1].trim();
|
|
33
|
+
let value = match[2].trim();
|
|
34
|
+
|
|
35
|
+
// Strip surrounding quotes if present
|
|
36
|
+
if (value.startsWith('"') && value.endsWith('"')) value = value.slice(1, -1);
|
|
37
|
+
if (value.startsWith("'") && value.endsWith("'")) value = value.slice(1, -1);
|
|
38
|
+
|
|
39
|
+
secrets[key] = value;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const secretCount = Object.keys(secrets).length;
|
|
44
|
+
if (secretCount === 0) {
|
|
45
|
+
console.log("โ ๏ธ No valid SECRETS found in .env.local. Exiting.");
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const tmpJsonPath = path.resolve(process.cwd(), '.tmp-cloudflare-secrets.json');
|
|
50
|
+
fs.writeFileSync(tmpJsonPath, JSON.stringify(secrets, null, 2));
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
console.log(`๐ Uploading ${secretCount} secrets to Cloudflare Pages...`);
|
|
54
|
+
|
|
55
|
+
// Try to read the Cloudflare project name and account ID from wrangler.toml
|
|
56
|
+
const tomlPath = path.resolve(process.cwd(), 'wrangler.toml');
|
|
57
|
+
let projectName = '';
|
|
58
|
+
let accountId = '';
|
|
59
|
+
|
|
60
|
+
if (fs.existsSync(tomlPath)) {
|
|
61
|
+
const tomlContent = fs.readFileSync(tomlPath, 'utf8');
|
|
62
|
+
|
|
63
|
+
// Parse Project Name
|
|
64
|
+
const nameMatch = tomlContent.match(/^name\s*=\s*"([^"]+)"/m);
|
|
65
|
+
if (nameMatch) projectName = nameMatch[1];
|
|
66
|
+
|
|
67
|
+
// Parse Account ID
|
|
68
|
+
const accountMatch = tomlContent.match(/^account_id\s*=\s*"([^"]+)"/m);
|
|
69
|
+
if (accountMatch) accountId = accountMatch[1];
|
|
70
|
+
|
|
71
|
+
if (projectName) console.log(`๐ฆ Targeted Cloudflare Project: ${projectName}`);
|
|
72
|
+
if (accountId) console.log(`๐ข Targeted Cloudflare Account: ${accountId}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Construct the command string tightly bound to the exact workspace
|
|
76
|
+
let cmd = `npx wrangler pages secret bulk .tmp-cloudflare-secrets.json`;
|
|
77
|
+
if (projectName) cmd += ` --project-name ${projectName}`;
|
|
78
|
+
if (accountId) cmd += ` --account-id ${accountId}`;
|
|
79
|
+
|
|
80
|
+
// Execute Wrangler natively
|
|
81
|
+
execSync(cmd, { stdio: 'inherit' });
|
|
82
|
+
console.log("โ
All secrets deployed successfully to Cloudflare!");
|
|
83
|
+
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error("โ Failed to push secrets to Cloudflare.");
|
|
86
|
+
console.error("Ensure you are logged into Wrangler (`npx wrangler login`) and the project exists.");
|
|
87
|
+
} finally {
|
|
88
|
+
// Always rigorously clean up the temporary plaintext JSON file for security
|
|
89
|
+
if (fs.existsSync(tmpJsonPath)) {
|
|
90
|
+
fs.unlinkSync(tmpJsonPath);
|
|
91
|
+
console.log("๐งน Cleaned up temporary credentials payload.");
|
|
92
|
+
}
|
|
93
|
+
}
|