@gluestack-seal/cli
Version:
153 lines (137 loc) • 3.71 kB
text/typescript
import { join } from "path";
import { find } from "lodash";
import {
writeFile,
getPrefix,
getCrossEnvKey,
jsonToEnv,
} from "@gluestack/helpers";
/**
* Env
*
* This class is responsible for generating the .env file
* in your gluestack app
*/
export default class Env {
public keys: any;
public keyCharacter: "%";
public envs: ChildEnv[];
public filepath: string;
constructor(envContent: any, build: "prod" | "dev", routes: any = []) {
this.keys = envContent;
routes.map((route: any) => {
const server = route.domain.split(".")[0] || "";
if (!this.keys[
`ENDPOINT_${server.toUpperCase()}`
]) {
this.keys[
`ENDPOINT_${server.toUpperCase()}`
] = `http://localhost:${route.port}`;
}
});
this.keyCharacter = "%";
this.envs = [];
this.filepath = join(
process.cwd(),
".env",
);
}
// Adds router.js data to the nginx conf data
// if and only if the given path exists
public async addEnv(
serviceName: string,
envContent: any,
path: string,
): Promise<any> {
for await (const key of Object.keys(envContent)) {
this.keys[getCrossEnvKey(serviceName, key)] = envContent[key];
}
const childEnv = new ChildEnv(
getPrefix(serviceName),
serviceName,
envContent,
path,
);
this.envs.push(childEnv);
}
// Generates the .env file
public async generate(): Promise<void> {
try {
for (const key in this.keys) {
const prefix = key.split("_")[0];
const replaceKeys = this.getReplaceKeys(this.keys[key]);
for (const replaceKey of replaceKeys) {
this.keys[key] = this.keys[key].replaceAll(
`${this.keyCharacter}${replaceKey}${this.keyCharacter}`,
this.keys[replaceKey] || "",
);
const childEnv = find(this.envs, { prefix: prefix });
if (childEnv) {
childEnv.updateKey(
key.replace(new RegExp("^" + `${prefix}_`), ""),
this.keys[key],
);
}
}
}
await this.writeEnv();
} catch (err) {
console.log("> .env file creation failed due to following reasons -");
console.log(err);
}
}
public async writeEnv() {
for (const childEnv of this.envs) {
if (childEnv.filepath === this.filepath) {
this.keys = { ...this.keys, ...childEnv.keys };
} else {
await childEnv.writeEnv();
}
}
const env = jsonToEnv(this.keys);
await writeFile(this.filepath, env);
}
private getReplaceKeys(str: string): string[] {
if (!str.includes(this.keyCharacter)) {
return [];
}
const specialChar = "%";
let startIdx = str.indexOf(specialChar);
let endIdx = str.indexOf(specialChar, startIdx + 1);
const result: any = [];
while (startIdx !== -1 && endIdx !== -1) {
const substring = str.substring(startIdx + 1, endIdx);
result.push(substring);
const nextStartIdx = str.indexOf(specialChar, endIdx + 1);
startIdx = endIdx;
endIdx = nextStartIdx;
}
return result;
}
}
class ChildEnv {
public prefix: string;
public serviceName: string;
public keys: any;
public filepath: string;
constructor(
prefix: string,
serviceName: string,
keys: any,
path: string,
) {
this.prefix = prefix;
this.serviceName = serviceName;
this.keys = keys;
this.filepath = join(path, ".env");
}
public updateKey(key: string, value: string) {
this.keys[key] = value;
}
public async writeEnv() {
const env = jsonToEnv(this.keys);
if (env) {
await writeFile(this.filepath, env);
}
}
}