mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-21 09:03:02 +00:00
77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
import {GeneratorOptions} from './index.js';
|
|
import {JSONSchema7} from 'json-schema';
|
|
import {ElasticsearchOptionsDSL} from '../dsl/schema.js';
|
|
import {
|
|
IndicesPutTemplateRequest,
|
|
MappingProperty,
|
|
MappingTypeMapping,
|
|
SearchRequest,
|
|
} from '@elastic/elasticsearch/lib/api/types.js';
|
|
import {Context} from './context.js';
|
|
import deepmerge from 'deepmerge';
|
|
import {renderTemplate} from '../template.js';
|
|
|
|
/**
|
|
* Sanitize a type name
|
|
*/
|
|
export function sanitizeTypeName(typeName: string): string {
|
|
return typeName.replaceAll(' ', '_');
|
|
}
|
|
|
|
export class MappingGenerator {
|
|
readonly presets: Map<string, ElasticsearchOptionsDSL>;
|
|
|
|
readonly cache: Map<string, {mapping: MappingProperty; dependencies: Map<string, Set<string>>}>;
|
|
|
|
readonly searchMods: {mods: Partial<SearchRequest>} = {mods: {}};
|
|
|
|
readonly template: Partial<IndicesPutTemplateRequest>;
|
|
|
|
constructor(readonly project: JSONSchema7, options: GeneratorOptions) {
|
|
this.template = options.template ?? {};
|
|
this.presets = new Map(Object.entries(options.presets));
|
|
this.cache = new Map(
|
|
Object.entries(options.overrides).map(([name, mapping]) => [
|
|
name,
|
|
{
|
|
mapping,
|
|
dependencies: new Map(),
|
|
},
|
|
]),
|
|
);
|
|
}
|
|
|
|
buildTemplate(name: string): IndicesPutTemplateRequest {
|
|
const thingType = ((this.project.definitions![name] as JSONSchema7).properties!.type as JSONSchema7)
|
|
.const;
|
|
if (typeof thingType !== 'string') {
|
|
throw new TypeError(`${name} needs a valid thing type`);
|
|
}
|
|
const mappingContext = new Context(this, thingType, [name], [], new Map());
|
|
const mappings = mappingContext.resolveReference(name);
|
|
|
|
const request: IndicesPutTemplateRequest = deepmerge(
|
|
{mappings: mappings as MappingTypeMapping},
|
|
renderTemplate(this.template, [
|
|
['{name}', name],
|
|
['{type}', thingType],
|
|
['{_type}', sanitizeTypeName(thingType)],
|
|
]),
|
|
);
|
|
|
|
if (mappingContext.dependencies.size > 0) {
|
|
request.mappings!.dynamic_templates = [];
|
|
for (const [name, paths] of mappingContext.dependencies) {
|
|
request.mappings!.dynamic_templates.push({
|
|
[name]: {
|
|
path_match: paths.size > 1 ? [...paths] : paths.values().next().value,
|
|
mapping: mappingContext.resolveReference(name),
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
return request;
|
|
}
|
|
}
|