@baseplate-dev/sync
Version:
Library for syncing Baseplate descriptions
209 lines • 8.66 kB
JavaScript
import { indexTemplateConfigs } from '../utils/index-template-configs.js';
import { sortExtractorConfigTemplateKeys } from '../utils/sort-extractor-config-keys.js';
/**
* Config lookup service for finding and caching extractor.json and providers.json files
*/
export class TemplateExtractorConfigLookup {
packageMap;
extractorConfigCache = new Map();
providersConfigCache = new Map();
indexedPackages = new Set();
initialized = false;
constructor(packageMap) {
this.packageMap = packageMap;
}
checkInitialized() {
if (!this.initialized) {
throw new Error('TemplateExtractorConfigLookup must be initialized before use');
}
}
/**
* Initialize the lookup service by indexing all packages in the package map
*/
async initialize() {
const { extractorEntries, providerEntries } = await indexTemplateConfigs(this.packageMap);
// Build extractor config cache
for (const entry of extractorEntries) {
this.extractorConfigCache.set(entry.generatorName, {
config: entry.config,
generatorDirectory: entry.generatorDirectory,
packageName: entry.packageName,
packagePath: entry.packagePath,
});
}
// Build provider config cache
for (const entry of providerEntries) {
this.providersConfigCache.set(`${entry.packageName}:${entry.providerName}`, {
config: entry.config,
packagePathSpecifier: entry.packagePathSpecifier,
providerName: entry.providerName,
packageName: entry.packageName,
packagePath: entry.packagePath,
});
}
this.initialized = true;
}
/**
* Get the extractor config for a generator
*/
getExtractorConfig(generatorName) {
this.checkInitialized();
return this.extractorConfigCache.get(generatorName);
}
getExtractorConfigOrThrow(generatorName) {
const config = this.getExtractorConfig(generatorName);
if (!config) {
throw new Error(`Generator ${generatorName} not found`);
}
return config;
}
getTemplateConfig(generatorName, templateName) {
const config = this.getExtractorConfigOrThrow(generatorName);
return config.config.templates[templateName];
}
getTemplateConfigOrThrow(generatorName, templateName) {
const config = this.getTemplateConfig(generatorName, templateName);
if (!config) {
throw new Error(`Template ${templateName} not found in generator ${generatorName}`);
}
return config;
}
getTemplatesForGenerator(generatorName, templateMetadataSchema, templateType) {
const config = this.getExtractorConfigOrThrow(generatorName);
const { templates } = config.config;
return Object.entries(templates)
.filter(([, template]) => template.type === templateType)
.map(([templateName, template]) => ({
name: templateName,
config: templateMetadataSchema.parse(template),
}));
}
getGeneratorConfigsForExtractorType(templateType, templateMetadataSchema, generatorConfigSchema) {
return [...this.extractorConfigCache.entries()].map(([generatorName, config]) => {
const generatorConfig = generatorConfigSchema
? generatorConfigSchema.parse(config.config.extractors?.[templateType])
: undefined;
const templates = Object.fromEntries(Object.entries(config.config.templates)
.filter(([, template]) => template.type === templateType)
.map(([templateName, template]) => {
const metadata = templateMetadataSchema.parse(template);
return [templateName, metadata];
}));
return {
generatorName,
generatorDirectory: config.generatorDirectory,
packageName: config.packageName,
packagePath: config.packagePath,
templates,
config: generatorConfig,
};
});
}
/**
* Get provider configs by type
*/
getProviderConfigsByType(type, providerConfigSchema) {
this.checkInitialized();
return [...this.providersConfigCache.values()]
.filter((cached) => cached.config.type === type)
.map((cached) => {
const parsed = providerConfigSchema.parse(cached.config);
return {
...cached,
config: parsed,
};
});
}
/**
* Write a new extractor config to the cache, reusing existing package info if available
*/
setExtractorConfig(generatorName, config) {
this.checkInitialized();
const existingEntry = this.extractorConfigCache.get(generatorName);
if (!existingEntry) {
throw new Error(`Cannot update extractor config for ${generatorName}: generator not found in cache. Please ensure the generator exists before updating.`);
}
this.extractorConfigCache.set(generatorName, {
config,
generatorDirectory: existingEntry.generatorDirectory,
packageName: existingEntry.packageName,
packagePath: existingEntry.packagePath,
});
}
/**
* Update the template config for a generator
* @param generatorName - The name of the generator
* @param templateName - The name of the template to update
* @param config - The template config to update
*/
updateExtractorTemplateConfig(generatorName, templateName, config) {
this.checkInitialized();
const existingEntry = this.extractorConfigCache.get(generatorName);
if (!existingEntry) {
throw new Error(`Generator ${generatorName} not found`);
}
const { templates } = existingEntry.config;
if (!(templateName in templates)) {
throw new Error(`Template ${templateName} not found in generator ${generatorName}`);
}
templates[templateName] = sortExtractorConfigTemplateKeys(config);
}
/**
* Remove a template from the in-memory config for a generator
* @param generatorName - The name of the generator
* @param templateName - The name of the template to remove
* @returns true if the template was removed, false if it didn't exist
*/
removeExtractorTemplate(generatorName, templateName) {
this.checkInitialized();
const entry = this.extractorConfigCache.get(generatorName);
if (!entry) {
return false;
}
if (!(templateName in entry.config.templates)) {
return false;
}
const { [templateName]: _, ...remainingTemplates } = entry.config.templates;
entry.config.templates = remainingTemplates;
return true;
}
/**
* Get plugin configuration for a specific generator
* @param generatorName - The name of the generator
* @param pluginName - The name of the plugin
* @param schema - Zod schema to validate and parse the plugin configuration
* @returns The parsed plugin configuration or undefined if not found
*/
getPluginConfigForGenerator(generatorName, pluginName, schema) {
this.checkInitialized();
const config = this.getExtractorConfig(generatorName);
if (!config?.config.plugins) {
return undefined;
}
if (!(pluginName in config.config.plugins)) {
return undefined;
}
const pluginConfig = config.config.plugins[pluginName];
return schema.parse(pluginConfig);
}
/**
* Get extractor configuration for a specific generator
* @param generatorName - The name of the generator
* @param extractorType - The type of extractor
* @param schema - Zod schema to validate and parse the extractor configuration
* @returns The parsed extractor configuration or undefined if not found
*/
getExtractorConfigForGenerator(generatorName, extractorType, schema) {
this.checkInitialized();
const config = this.getExtractorConfig(generatorName);
if (!config?.config.extractors) {
return undefined;
}
if (!(extractorType in config.config.extractors)) {
return undefined;
}
const extractorConfig = config.config.extractors[extractorType];
return schema.parse(extractorConfig);
}
}
//# sourceMappingURL=template-extractor-config-lookup.js.map