1
|
|
|
import type { PathLike } from "fs" |
2
|
|
|
import { sync } from "globby" |
3
|
|
|
import { appenderSync, arr2line, createLineReader, templateLine } from "../utils" |
4
|
|
|
|
5
|
|
|
export { |
6
|
|
|
readMd |
7
|
|
|
} |
8
|
|
|
|
9
|
|
|
if (!module.parent) |
10
|
|
|
main() |
11
|
|
|
|
12
|
|
|
async function main() { |
13
|
|
|
const templatesDir = `${__dirname}/template/` |
14
|
|
|
, files = sync(`**/*`, { |
15
|
|
|
"gitignore": true, |
16
|
|
|
"cwd": templatesDir |
17
|
|
|
}) |
18
|
|
|
, vars = await readMd(`${__dirname}/input.md`) |
19
|
|
|
|
20
|
|
|
await appenderSync(`${__dirname}/output/input.env`)(...vars[""]) |
21
|
|
|
|
22
|
|
|
for (const file of files) { |
23
|
|
|
const outputFile = `${__dirname}/output/${file}` |
24
|
|
|
, reader = createLineReader(`${templatesDir}${file}`) |
25
|
|
|
, append = appenderSync(outputFile) |
26
|
|
|
|
27
|
|
|
for await (const line of reader) { |
28
|
|
|
const templ = templateLine<"type"|"prefix">(line) |
29
|
|
|
|
30
|
|
|
if (!templ) { |
31
|
|
|
await append(line, "\n") |
32
|
|
|
continue |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
const { |
36
|
|
|
indentation, |
37
|
|
|
type = "", |
38
|
|
|
prefix = "" |
39
|
|
|
} = templ |
40
|
|
|
|
41
|
|
|
if (!(type in vars)) |
42
|
|
|
throw Error(`Unknown type: "${type}"`) |
43
|
|
|
|
44
|
|
|
const vars4type = vars[type] |
45
|
|
|
|
46
|
|
|
await append( |
47
|
|
|
...Object.keys(vars4type) |
48
|
|
|
.map(e => { |
49
|
|
|
const status = vars4type[e] |
50
|
|
|
|
51
|
|
|
return arr2line( |
52
|
|
|
indentation, |
53
|
|
|
status && status !== "-" ? "" : "#", |
54
|
|
|
prefix, |
55
|
|
|
e |
56
|
|
|
) |
57
|
|
|
}) |
58
|
|
|
) |
59
|
|
|
} |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
return files |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
async function readMd(path: PathLike) { |
66
|
|
|
const reader = createLineReader(path) |
67
|
|
|
//@ts-expect-error |
68
|
|
|
, $return: { |
69
|
|
|
//@ts-expect-error |
70
|
|
|
"": string[] |
71
|
|
|
[x: string]: Record<string, string> //string[] | boolean |
72
|
|
|
} = {"": [] as string[]} |
73
|
|
|
|
74
|
|
|
let headers: undefined|string[] |
75
|
|
|
|
76
|
|
|
for await (const line of reader) { |
77
|
|
|
if (!line.match(/^\|([^|]*\|)+$/)) { |
78
|
|
|
headers = undefined |
79
|
|
|
continue |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
if (headers === undefined) { |
83
|
|
|
headers = line.split(/\s*\|\s*/) |
84
|
|
|
headers.shift() |
85
|
|
|
headers.length-- |
86
|
|
|
|
87
|
|
|
const {length} = headers |
88
|
|
|
for (let i = 0; i < length; i++) { |
89
|
|
|
const header = headers[i] |
90
|
|
|
|
91
|
|
|
if (!header) |
92
|
|
|
continue |
93
|
|
|
|
94
|
|
|
$return[header] = {} |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
continue |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
if (line.match(/^\|(\s*\-+\s*\|)+$/)) |
101
|
|
|
continue |
102
|
|
|
|
103
|
|
|
const cellParser = /[^\|]+/g |
104
|
|
|
|
105
|
|
|
let i = -1 |
106
|
|
|
, key: string |
107
|
|
|
, cell: string|undefined |
108
|
|
|
|
109
|
|
|
while (cell = cellParser.exec(line)?.[0]) { |
110
|
|
|
i++ |
111
|
|
|
|
112
|
|
|
const trimmed = cell |
113
|
|
|
.replace(/(^ +| +$)/g, '') |
114
|
|
|
.replace(" ", " ") |
115
|
|
|
.replace(" ", "\t") |
116
|
|
|
|
117
|
|
|
if (i === 0) { |
118
|
|
|
if (!trimmed) |
119
|
|
|
break |
120
|
|
|
|
121
|
|
|
key = trimmed |
122
|
|
|
$return[""].push(trimmed) |
123
|
|
|
continue |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
if (!trimmed) |
127
|
|
|
continue |
128
|
|
|
|
129
|
|
|
$return[headers[i]][key!] = trimmed |
130
|
|
|
} |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
return $return |
134
|
|
|
} |
135
|
|
|
|