159 lines
4.6 KiB
TypeScript
159 lines
4.6 KiB
TypeScript
import { Env } from "./Env";
|
|
|
|
|
|
export class ConfigTemplate {
|
|
public static Empty: ConfigTemplate = new ConfigTemplate();
|
|
|
|
constructor(text: string = "") {
|
|
this._contentText = text;
|
|
this.extractParams();
|
|
}
|
|
|
|
private _contentText: string = "";
|
|
private _params: string[] = [];
|
|
|
|
public get content(): string {
|
|
return this._contentText;
|
|
}
|
|
|
|
public get Params(): string[] {
|
|
return [...this._params];
|
|
}
|
|
|
|
private extractParams() {
|
|
let regex = /@(\w+)@/g;
|
|
let matches;
|
|
let paramsSet = new Set<string>();
|
|
|
|
while ((matches = regex.exec(this._contentText)) !== null) {
|
|
if (matches.length > 1) {
|
|
paramsSet.add(matches[1]);
|
|
}
|
|
}
|
|
|
|
this._params = Array.from(paramsSet);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
export class Config {
|
|
public static get ENV_NAME_PARAM(): string { return "env_name" };
|
|
|
|
public envs: Env[] = [];
|
|
public template: ConfigTemplate = ConfigTemplate.Empty;
|
|
|
|
addEnvs(envs: Env[]) {
|
|
this.envs = envs;
|
|
}
|
|
|
|
addTemplate(text: string) {
|
|
this.template = new ConfigTemplate(text);
|
|
}
|
|
|
|
getTemplateAsJson(): string {
|
|
try {
|
|
return this.template.content ;
|
|
} catch (error) {
|
|
console.error("Error converting template content to JSON:", error);
|
|
return "{}";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates the template JSON by adding/updating params from the given environment.
|
|
* Params are added as "!!! paramName": "@paramName@" placeholder pairs.
|
|
* If a param's @placeholder@ already exists in template, it won't be added.
|
|
* Existing template content is preserved.
|
|
*/
|
|
updateTemplateFromEnv(env: Env) {
|
|
let templateObj: Record<string, any> = {};
|
|
|
|
// Try to parse existing template as JSON
|
|
try {
|
|
if (this.template.content.trim()) {
|
|
templateObj = JSON.parse(this.template.content);
|
|
}
|
|
} catch (e) {
|
|
// If parsing fails, start with empty object
|
|
console.warn("Template is not valid JSON, starting fresh");
|
|
}
|
|
|
|
// Add/update params from the environment as placeholders
|
|
for (const param of env.params) {
|
|
if (param.name && param.name.trim() !== "") {
|
|
const placeholderValue = `@${param.name}@`;
|
|
|
|
// Check if this placeholder already exists anywhere in the template
|
|
const placeholderAlreadyExists = this.template.content.includes(placeholderValue);
|
|
|
|
if (!placeholderAlreadyExists) {
|
|
const placeholderKey = `!!! ${param.name}`;
|
|
templateObj[placeholderKey] = placeholderValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Convert back to formatted JSON string
|
|
const newTemplateContent = JSON.stringify(templateObj, null, 4);
|
|
this.template = new ConfigTemplate(newTemplateContent);
|
|
}
|
|
|
|
validateParams(): string[] {
|
|
const envKeys = this.envs.map(env => env.params.map(param => param.name)).flat();
|
|
const missingParams = this.template.Params.filter(param => param != Config.ENV_NAME_PARAM && !envKeys.includes(param));
|
|
|
|
if (missingParams.length > 0) {
|
|
console.error("Template: missing parameters in environments:", missingParams);
|
|
}
|
|
|
|
return missingParams;
|
|
}
|
|
|
|
/**
|
|
* Validates that all @placeholders@ in template have corresponding params.
|
|
* Checks DEFAULT env first, then all custom envs.
|
|
* Returns array of placeholder names that are not defined.
|
|
*/
|
|
validatePlaceholders(): string[] {
|
|
const defaultEnv = this.envs.find(e => e.name === "DEFAULT");
|
|
const customEnvs = this.envs.filter(e => e.name !== "DEFAULT");
|
|
|
|
// Collect all param names from DEFAULT
|
|
const defaultParamNames = new Set(
|
|
defaultEnv?.params.map(p => p.name).filter(n => n && n.trim() !== "") || []
|
|
);
|
|
|
|
// Collect all param names from all custom envs
|
|
const customParamNames = new Set(
|
|
customEnvs.flatMap(e => e.params.map(p => p.name).filter(n => n && n.trim() !== ""))
|
|
);
|
|
|
|
// Extract all @placeholders@ from template
|
|
const placeholderRegex = /@(\w+)@/g;
|
|
const placeholdersInTemplate = new Set<string>();
|
|
let match;
|
|
while ((match = placeholderRegex.exec(this.template.content)) !== null) {
|
|
placeholdersInTemplate.add(match[1]);
|
|
}
|
|
|
|
// Find placeholders that don't have matching params
|
|
const missingParams: string[] = [];
|
|
for (const placeholder of placeholdersInTemplate) {
|
|
if (placeholder === Config.ENV_NAME_PARAM) continue; // Skip built-in
|
|
|
|
// Check if exists in DEFAULT or in ANY custom env
|
|
const inDefault = defaultParamNames.has(placeholder);
|
|
const inCustom = customParamNames.has(placeholder);
|
|
|
|
// Valid if: in DEFAULT, or in at least one custom env
|
|
if (!inDefault && !inCustom) {
|
|
missingParams.push(placeholder);
|
|
}
|
|
}
|
|
|
|
return missingParams;
|
|
}
|
|
}
|
|
|