refactor: complete application rewrite with modern UI
This commit is contained in:
@@ -1,158 +1,174 @@
|
||||
import { Env } from "./Env";
|
||||
|
||||
import { Env } from './Env';
|
||||
|
||||
/**
|
||||
* Configuration template with placeholder support
|
||||
*/
|
||||
export class ConfigTemplate {
|
||||
public static Empty: ConfigTemplate = new ConfigTemplate();
|
||||
public static readonly Empty: ConfigTemplate = new ConfigTemplate();
|
||||
|
||||
constructor(text: string = "") {
|
||||
this._contentText = text;
|
||||
this.extractParams();
|
||||
private _contentText: string;
|
||||
private _params: string[];
|
||||
|
||||
constructor(contentText: string = '') {
|
||||
this._contentText = contentText;
|
||||
this._params = this.extractParams();
|
||||
}
|
||||
|
||||
private _contentText: string = "";
|
||||
private _params: string[] = [];
|
||||
|
||||
public get content(): string {
|
||||
return this._contentText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backward compatibility getter
|
||||
*/
|
||||
public get Params(): string[] {
|
||||
return this.params;
|
||||
}
|
||||
|
||||
public get params(): string[] {
|
||||
return [...this._params];
|
||||
}
|
||||
|
||||
private extractParams() {
|
||||
let regex = /@(\w+)@/g;
|
||||
let matches;
|
||||
let paramsSet = new Set<string>();
|
||||
/**
|
||||
* Extracts @placeholder@ patterns from template content
|
||||
*/
|
||||
private extractParams(): string[] {
|
||||
const regex = /@(\w+)@/g;
|
||||
const paramsSet = new Set<string>();
|
||||
let match;
|
||||
|
||||
while ((matches = regex.exec(this._contentText)) !== null) {
|
||||
if (matches.length > 1) {
|
||||
paramsSet.add(matches[1]);
|
||||
}
|
||||
while ((match = regex.exec(this._contentText)) !== null) {
|
||||
paramsSet.add(match[1]);
|
||||
}
|
||||
|
||||
this._params = Array.from(paramsSet);
|
||||
return Array.from(paramsSet);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main configuration container
|
||||
*/
|
||||
export class Config {
|
||||
public static get ENV_NAME_PARAM(): string { return "env_name" };
|
||||
public static readonly ENV_NAME_PARAM = 'env_name';
|
||||
|
||||
public envs: Env[] = [];
|
||||
public template: ConfigTemplate = ConfigTemplate.Empty;
|
||||
|
||||
addEnvs(envs: Env[]) {
|
||||
/**
|
||||
* Sets environments (backward compatibility)
|
||||
*/
|
||||
public addEnvs(envs: Env[]): void {
|
||||
this.envs = envs;
|
||||
}
|
||||
|
||||
addTemplate(text: string) {
|
||||
this.template = new ConfigTemplate(text);
|
||||
/**
|
||||
* Sets environments
|
||||
*/
|
||||
public setEnvs(envs: Env[]): void {
|
||||
this.envs = envs;
|
||||
}
|
||||
|
||||
getTemplateAsJson(): string {
|
||||
/**
|
||||
* Sets template content (backward compatibility)
|
||||
*/
|
||||
public addTemplate(content: string): void {
|
||||
this.setTemplate(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets template content
|
||||
*/
|
||||
public setTemplate(content: string): void {
|
||||
this.template = new ConfigTemplate(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets template as JSON string
|
||||
*/
|
||||
public getTemplateAsJson(): string {
|
||||
try {
|
||||
return this.template.content ;
|
||||
} catch (error) {
|
||||
console.error("Error converting template content to JSON:", error);
|
||||
return "{}";
|
||||
return this.template.content;
|
||||
} catch {
|
||||
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.
|
||||
* Updates template by adding placeholders for environment params
|
||||
*/
|
||||
updateTemplateFromEnv(env: Env) {
|
||||
public updateTemplateFromEnv(env: Env): void {
|
||||
let templateObj: Record<string, any> = {};
|
||||
|
||||
// Try to parse existing template as JSON
|
||||
// Try to parse existing template
|
||||
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");
|
||||
} catch {
|
||||
// Start fresh if invalid JSON
|
||||
}
|
||||
|
||||
// Add/update params from the environment as placeholders
|
||||
// Add placeholders for params that don't exist yet
|
||||
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;
|
||||
if (param.name && param.name.trim()) {
|
||||
const placeholder = `@${param.name}@`;
|
||||
|
||||
if (!this.template.content.includes(placeholder)) {
|
||||
templateObj[`!!! ${param.name}`] = placeholder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert back to formatted JSON string
|
||||
const newTemplateContent = JSON.stringify(templateObj, null, 4);
|
||||
this.template = new ConfigTemplate(newTemplateContent);
|
||||
this.template = new ConfigTemplate(JSON.stringify(templateObj, null, 4));
|
||||
}
|
||||
|
||||
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));
|
||||
/**
|
||||
* Validates that all template placeholders have corresponding params (backward compatibility)
|
||||
*/
|
||||
public validateParams(): string[] {
|
||||
return this.validatePlaceholders();
|
||||
}
|
||||
|
||||
if (missingParams.length > 0) {
|
||||
console.error("Template: missing parameters in environments:", missingParams);
|
||||
/**
|
||||
* Validates that all template placeholders have corresponding params
|
||||
*/
|
||||
public validatePlaceholders(): string[] {
|
||||
const defaultEnv = this.envs.find(e => e.name === 'DEFAULT');
|
||||
const customEnvs = this.envs.filter(e => e.name !== 'DEFAULT');
|
||||
|
||||
// Collect param names from DEFAULT
|
||||
const defaultParamNames = new Set(
|
||||
defaultEnv?.getParamNames() || []
|
||||
);
|
||||
|
||||
// Collect param names from all custom envs
|
||||
const customParamNames = new Set(
|
||||
customEnvs.flatMap(e => e.getParamNames())
|
||||
);
|
||||
|
||||
// Find missing placeholders
|
||||
const missingParams: string[] = [];
|
||||
for (const placeholder of this.template.params) {
|
||||
if (placeholder === Config.ENV_NAME_PARAM) continue;
|
||||
|
||||
const inDefault = defaultParamNames.has(placeholder);
|
||||
const inCustom = customParamNames.has(placeholder);
|
||||
|
||||
if (!inDefault && !inCustom) {
|
||||
missingParams.push(placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
* Creates a deep copy of the config
|
||||
*/
|
||||
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;
|
||||
public clone(): Config {
|
||||
const cloned = new Config();
|
||||
cloned.envs = [...this.envs];
|
||||
cloned.template = this.template;
|
||||
return cloned;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user