-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsplitenv.mjs
More file actions
141 lines (125 loc) · 3.86 KB
/
splitenv.mjs
File metadata and controls
141 lines (125 loc) · 3.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import fs from "fs";
import path from "path";
// Usage: node splitenv.js <input-file> <prefix1> [prefix2] [...]
const args = process.argv.slice(2);
if (args.length < 2) {
console.error(
`Usage: node ${path.basename(process.argv[1])} <input-file> <prefix...>`,
);
process.exit(1);
}
const [inputFile, ...prefixes] = args;
const baseDir = path.dirname(inputFile);
// Map each prefix to its suffix (stripping trailing underscores)
const prefixToSuffix = prefixes.reduce((acc, prefix) => {
acc[prefix] = prefix.replace(/_+$/, "");
return acc;
}, {});
// Prepare containers for each output group
const groupEntries = Object.values(prefixToSuffix).reduce((acc, suffix) => {
acc[suffix] = [];
return acc;
}, {});
// Read the input .env file
let content;
try {
content = fs.readFileSync(inputFile, "utf-8");
} catch (err) {
console.error(`Error reading file '${inputFile}':`, err.message);
process.exit(1);
}
// Split into lines
const rawLines = content.split(/\r?\n/);
// Merge multi-line values (quoted values spanning lines)
const mergedLines = [];
let inMultiline = false;
let multilineBuffer = "";
let currentQuote = null;
rawLines.forEach((line) => {
if (!inMultiline) {
const match = line.match(/^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
if (match) {
const rest = match[2];
const trimmed = rest.trim();
const startsWithQuote =
trimmed.startsWith(`"`) || trimmed.startsWith(`'`);
const quoteChar = trimmed.charAt(0);
const endsWithQuote = trimmed.endsWith(quoteChar) && trimmed.length > 1;
if (startsWithQuote && !endsWithQuote) {
inMultiline = true;
currentQuote = quoteChar;
multilineBuffer = line;
} else {
mergedLines.push(line);
}
} else {
// Copy non key=value lines (comments/blanks will be filtered later)
mergedLines.push(line);
}
} else {
multilineBuffer += "\n" + line;
if (line.trim().endsWith(currentQuote)) {
inMultiline = false;
mergedLines.push(multilineBuffer);
multilineBuffer = "";
currentQuote = null;
}
}
});
if (inMultiline) {
// Unterminated multiline: push anyway
mergedLines.push(multilineBuffer);
}
// Process each logical line
mergedLines.forEach((line) => {
const trimmed = line.trim();
// Skip blank lines and comments
if (!trimmed || trimmed.startsWith("#")) return;
const idx = line.indexOf("=");
if (idx === -1) return;
const key = line.slice(0, idx);
const value = line.slice(idx + 1);
// Check if the key matches any prefix
let matched = false;
for (const prefix of prefixes) {
if (key.startsWith(prefix)) {
const suffix = prefixToSuffix[prefix];
const newKey = key.slice(prefix.length);
groupEntries[suffix].push({ key: newKey, value });
matched = true;
break;
}
}
if (!matched) {
// Common variable: copy to all groups
Object.values(prefixToSuffix).forEach((suffix) => {
groupEntries[suffix].push({ key, value });
});
}
});
// Write out each .env in its corresponding folder
Object.entries(groupEntries).forEach(([suffix, entries]) => {
const dirName = suffix.toLowerCase();
const dirPath = path.join(baseDir, dirName);
// Ensure directory exists
if (!fs.existsSync(dirPath) || !fs.statSync(dirPath).isDirectory()) {
console.error(
`Error: Directory '${dirPath}' for prefix '${suffix}' does not exist.`,
);
process.exit(1);
}
const outPath = path.join(dirPath, ".env");
const linesOut = entries.map(({ key, value }) => `${key}=${value}`);
const contentOut =
[
"# file generated by file:///./../splitenv.mjs from the file:///./../.env file\n",
...linesOut,
].join("\n") + "\n";
try {
fs.writeFileSync(outPath, contentOut, "utf-8");
console.log(`Wrote ${outPath}`);
} catch (err) {
console.error(`Error writing file '${outPath}': ${err.message}`);
process.exit(1);
}
});