Make env-var parsing handle Coolify's full quote-escaping scenarios; try multiple unescaping candidates before failing
This commit is contained in:
parent
4d01664787
commit
0cd6cc68fb
@ -41,27 +41,59 @@ type RouteMap = Record<string, RouteEntry>;
|
|||||||
// ----- Helpers --------------------------------------------------------------
|
// ----- Helpers --------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize a raw env-var value. Some hosting platforms (Coolify included)
|
* Normalize a raw env-var value. Different hosting platforms apply different
|
||||||
* wrap pasted JSON values in extra quotes when the user doesn't quote-escape
|
* (and surprising) transformations when you paste a JSON value into an
|
||||||
* properly, producing strings like:
|
* env-var field. We've observed at least:
|
||||||
* "{\"square\":{...}}"
|
|
||||||
* which JSON.parse cannot read at position 1.
|
|
||||||
*
|
*
|
||||||
* This helper:
|
* 1. Raw JSON pasted in: {"square":{"project":"x"}}
|
||||||
* 1. Trims whitespace
|
* 2. Wrapped in a single layer of quotes: "{"square":{"project":"x"}}"
|
||||||
* 2. Strips a single surrounding layer of `"` or `'`
|
* 3. Wrapped AND every inner quote escaped: "{\"square\":{\"project\":\"x\"}}"
|
||||||
* 3. Unescapes `\"` -> `"`, `\'` -> `'`, and `\\` -> `\`
|
* 4. Inner quotes escaped, no outer wrapping: {\"square\":{\"project\":\"x\"}}
|
||||||
|
*
|
||||||
|
* This helper walks through each plausible unescaping and returns the first
|
||||||
|
* one that produces a syntactically valid JSON string. If none succeed, the
|
||||||
|
* raw value is returned and JSON.parse will throw a clear error.
|
||||||
*/
|
*/
|
||||||
function normalizeEnvValue(raw: string): string {
|
function normalizeEnvValue(raw: string): string {
|
||||||
|
if (!raw) return raw;
|
||||||
|
|
||||||
let value = raw.trim();
|
let value = raw.trim();
|
||||||
if (
|
|
||||||
(value.startsWith('"') && value.endsWith('"')) ||
|
const candidates: string[] = [
|
||||||
(value.startsWith("'") && value.endsWith("'"))
|
value,
|
||||||
) {
|
// Strip a single surrounding layer of `"` or `'`
|
||||||
value = value.slice(1, -1);
|
stripWrappingQuotes(value),
|
||||||
value = value.replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\\\/g, '\\');
|
// Unescape every \" -> " (handles Coolify double-escape)
|
||||||
|
value.replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\\\/g, '\\'),
|
||||||
|
// Combined: strip wrapping quotes AND unescape inner escapes
|
||||||
|
stripWrappingQuotes(value).replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\\\/g, '\\'),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Dedupe and try each
|
||||||
|
const seen = new Set<string>();
|
||||||
|
for (const candidate of candidates) {
|
||||||
|
const trimmed = candidate.trim();
|
||||||
|
if (seen.has(trimmed)) continue;
|
||||||
|
seen.add(trimmed);
|
||||||
|
try {
|
||||||
|
JSON.parse(trimmed);
|
||||||
|
return trimmed;
|
||||||
|
} catch {
|
||||||
|
// try next
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return value.trim();
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stripWrappingQuotes(s: string): string {
|
||||||
|
if (
|
||||||
|
(s.startsWith('"') && s.endsWith('"')) ||
|
||||||
|
(s.startsWith("'") && s.endsWith("'"))
|
||||||
|
) {
|
||||||
|
return s.slice(1, -1);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----- Config ---------------------------------------------------------------
|
// ----- Config ---------------------------------------------------------------
|
||||||
@ -81,7 +113,7 @@ try {
|
|||||||
const raw = (process.env.PROJECT_CREDENTIALS ?? '').slice(0, 300);
|
const raw = (process.env.PROJECT_CREDENTIALS ?? '').slice(0, 300);
|
||||||
console.error('[startup] PROJECT_CREDENTIALS is not valid JSON:', message);
|
console.error('[startup] PROJECT_CREDENTIALS is not valid JSON:', message);
|
||||||
console.error('[startup] Received value (first 300 chars):', raw);
|
console.error('[startup] Received value (first 300 chars):', raw);
|
||||||
console.error('[startup] Hint: in Coolify, paste the JSON without surrounding quotes. If the platform wraps it, set the env var to a single-line value with no leading/trailing whitespace.');
|
console.error('[startup] Tried stripping wrapping quotes and unescaping \\"->". If you still see this, paste the JSON without any escaping.');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user