175 lines
3.9 KiB
TypeScript
175 lines
3.9 KiB
TypeScript
import { Env } from './Env';
|
|
|
|
/**
|
|
* Configuration template with placeholder support
|
|
*/
|
|
export class ConfigTemplate {
|
|
public static readonly Empty: ConfigTemplate = new ConfigTemplate();
|
|
|
|
private _contentText: string;
|
|
private _params: string[];
|
|
|
|
constructor(contentText: string = '') {
|
|
this._contentText = contentText;
|
|
this._params = this.extractParams();
|
|
}
|
|
|
|
public get content(): string {
|
|
return this._contentText;
|
|
}
|
|
|
|
/**
|
|
* Backward compatibility getter
|
|
*/
|
|
public get Params(): string[] {
|
|
return this.params;
|
|
}
|
|
|
|
public get params(): string[] {
|
|
return [...this._params];
|
|
}
|
|
|
|
/**
|
|
* Extracts @placeholder@ patterns from template content
|
|
*/
|
|
private extractParams(): string[] {
|
|
const regex = /@(\w+)@/g;
|
|
const paramsSet = new Set<string>();
|
|
let match;
|
|
|
|
while ((match = regex.exec(this._contentText)) !== null) {
|
|
paramsSet.add(match[1]);
|
|
}
|
|
|
|
return Array.from(paramsSet);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Main configuration container
|
|
*/
|
|
export class Config {
|
|
public static readonly ENV_NAME_PARAM = 'env_name';
|
|
|
|
public envs: Env[] = [];
|
|
public template: ConfigTemplate = ConfigTemplate.Empty;
|
|
|
|
/**
|
|
* Sets environments (backward compatibility)
|
|
*/
|
|
public addEnvs(envs: Env[]): void {
|
|
this.envs = envs;
|
|
}
|
|
|
|
/**
|
|
* Sets environments
|
|
*/
|
|
public setEnvs(envs: Env[]): void {
|
|
this.envs = envs;
|
|
}
|
|
|
|
/**
|
|
* 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 {
|
|
return '{}';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates template by adding placeholders for environment params
|
|
*/
|
|
public updateTemplateFromEnv(env: Env): void {
|
|
let templateObj: Record<string, any> = {};
|
|
|
|
// Try to parse existing template
|
|
try {
|
|
if (this.template.content.trim()) {
|
|
templateObj = JSON.parse(this.template.content);
|
|
}
|
|
} catch {
|
|
// Start fresh if invalid JSON
|
|
}
|
|
|
|
// Add placeholders for params that don't exist yet
|
|
for (const param of env.params) {
|
|
if (param.name && param.name.trim()) {
|
|
const placeholder = `@${param.name}@`;
|
|
|
|
if (!this.template.content.includes(placeholder)) {
|
|
templateObj[`!!! ${param.name}`] = placeholder;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.template = new ConfigTemplate(JSON.stringify(templateObj, null, 4));
|
|
}
|
|
|
|
/**
|
|
* Validates that all template placeholders have corresponding params (backward compatibility)
|
|
*/
|
|
public validateParams(): string[] {
|
|
return this.validatePlaceholders();
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* Creates a deep copy of the config
|
|
*/
|
|
public clone(): Config {
|
|
const cloned = new Config();
|
|
cloned.envs = [...this.envs];
|
|
cloned.template = this.template;
|
|
return cloned;
|
|
}
|
|
}
|