-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
index.ts
53 lines (47 loc) · 1.48 KB
/
index.ts
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
/** We don't normalize anything, so it is just strings and strings. */
export type Data = Record<string, string>
/** We typecast the value as a string so that it is compatible with envfiles. */
export type Input = Record<string, any>
// perhaps in the future we can use @bevry/json's toJSON and parseJSON and JSON.stringify to support more advanced types
/** Parse an envfile string. */
export function parse(src: string): Data {
const result: Data = {}
const lines = splitInLines(src)
for (const line of lines) {
const match = line.match(/^([^=:#]+?)[=:]((.|\n)*)/)
if (match) {
const key = match[1].trim()
const value = match[2].trim().replace(/['"]+/g, '')
result[key] = value
}
}
return result
}
/** Turn an object into an envfile string. */
export function stringify(obj: Input): string {
let result = ''
for (const [key, value] of Object.entries(obj)) {
if (key) {
const line = `${key}=${jsonValueToEnv(value)}`
result += line + '\n'
}
}
return result
}
function splitInLines(src: string): string[] {
return src
.replace(/("[\s\S]*?")/g, (_m, cg) => {
return cg.replace(/\n/g, '%%LINE-BREAK%%')
})
.split('\n')
.filter((i) => Boolean(i.trim()))
.map((i) => i.replace(/%%LINE-BREAK%%/g, '\n'))
}
function jsonValueToEnv(value: any): string {
let processedValue = String(value)
processedValue = processedValue.replace(/\n/g, '\\n')
processedValue = processedValue.includes('\\n')
? `"${processedValue}"`
: processedValue
return processedValue
}