Rename to 'ngx'
parent
9200d10ad8
commit
1b718dae86
|
@ -0,0 +1,129 @@
|
|||
// #region Implementation
|
||||
type ConfigNode = ConfigStatement | ConfigBlock | ConfigBreak | ConfigFile;
|
||||
|
||||
class ConfigBuildable {
|
||||
build(): string {
|
||||
throw new Error("build(..) not implemented!");
|
||||
}
|
||||
|
||||
write(path: string) {
|
||||
const contents = this.build();
|
||||
Deno.writeTextFileSync(path, contents);
|
||||
}
|
||||
}
|
||||
|
||||
class ConfigBlock extends ConfigBuildable {
|
||||
value: string;
|
||||
children: ConfigNode[];
|
||||
|
||||
constructor(value: string, children: ConfigNode[]) {
|
||||
super();
|
||||
|
||||
this.value = value;
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
build(): string {
|
||||
let output = this.value;
|
||||
output += " {\n ";
|
||||
output += this.children
|
||||
.map((child) => child.build().split("\n").join("\n "))
|
||||
.join("\n ");
|
||||
output += "\n}";
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
class ConfigStatement extends ConfigBuildable {
|
||||
value: string;
|
||||
constructor(value: string) {
|
||||
super();
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
build(): string {
|
||||
return this.value + ";";
|
||||
}
|
||||
}
|
||||
|
||||
class ConfigBreak extends ConfigBuildable {
|
||||
build(): string {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
class ConfigFile extends ConfigBuildable {
|
||||
nodes: ConfigNode[];
|
||||
constructor(nodes: ConfigNode[]) {
|
||||
super();
|
||||
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
build(): string {
|
||||
return this.nodes.map((n) => n.build()).join("\n");
|
||||
}
|
||||
}
|
||||
|
||||
type LooseConfigNode = ConfigNode | string | LooseConfigNode[];
|
||||
|
||||
function conform(looseNode: LooseConfigNode): ConfigNode[] {
|
||||
if (typeof looseNode === "string") {
|
||||
return [new ConfigStatement(looseNode)];
|
||||
}
|
||||
if (typeof looseNode === "object" && looseNode instanceof Array) {
|
||||
if (looseNode.length === 0) {
|
||||
return [new ConfigBreak()];
|
||||
} else if (looseNode.length === 1) {
|
||||
return conform(looseNode[0]);
|
||||
} else {
|
||||
return looseNode
|
||||
.map((n) => conform(n))
|
||||
.reduceRight((b, a) =>
|
||||
a.length === 1 ? [...a, ...b] : [...a, new ConfigBreak(), ...b]
|
||||
);
|
||||
}
|
||||
}
|
||||
return [looseNode];
|
||||
}
|
||||
// #endregion
|
||||
|
||||
export function ngx(value?: string, children?: LooseConfigNode[]): ConfigNode {
|
||||
const hasValue = value !== undefined && value !== "";
|
||||
const hasChildren = children !== undefined;
|
||||
|
||||
if (!hasValue && !hasChildren) {
|
||||
return new ConfigBreak();
|
||||
} else if (hasValue && !hasChildren) {
|
||||
return new ConfigStatement(value);
|
||||
} else if (hasValue && hasChildren) {
|
||||
return new ConfigBlock(value, conform(children));
|
||||
} else if (!hasValue && hasChildren) {
|
||||
return new ConfigFile(conform(children));
|
||||
}
|
||||
|
||||
throw new Error("unreachable");
|
||||
}
|
||||
|
||||
export const br = new ConfigBreak();
|
||||
|
||||
export const listen = (...extras: string[]) =>
|
||||
conform([
|
||||
`listen 443 ${["ssl", "http2", ...extras].join(" ")}`,
|
||||
`listen [::]:443 ${["ssl", "http2", ...extras].join(" ")}`,
|
||||
]);
|
||||
|
||||
export const letsEncrypt = (
|
||||
domain: string,
|
||||
liveDir = "/etc/letsencrypt/live"
|
||||
) =>
|
||||
conform([
|
||||
`ssl_certificate ${liveDir}/${domain}/fullchain.pem`,
|
||||
`ssl_certificate_key ${liveDir}/${domain}/privkey.pem`,
|
||||
]);
|
||||
|
||||
export default Object.assign(
|
||||
(value?: string, children?: LooseConfigNode[]) => ngx(value, children),
|
||||
{ br, listen, letsEncrypt }
|
||||
);
|
Loading…
Reference in New Issue