|
|
|
|
@@ -59,7 +59,6 @@ let inheritTagsMap: {[path: string]: CommentTag[]} = {};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets all interfaces that have an @indexable tag
|
|
|
|
|
*
|
|
|
|
|
* @param projectReflection the project reflection from which to extract the indexable interfaces
|
|
|
|
|
*/
|
|
|
|
|
export function getAllIndexableInterfaces(projectReflection: ProjectReflection): DeclarationReflection[] {
|
|
|
|
|
@@ -78,18 +77,13 @@ export function getAllIndexableInterfaces(projectReflection: ProjectReflection):
|
|
|
|
|
|
|
|
|
|
// filter all declaration reflections with an @indexable tag
|
|
|
|
|
indexableInterfaces = indexableInterfaces.filter(declarationReflection => {
|
|
|
|
|
if (
|
|
|
|
|
typeof declarationReflection.comment === 'undefined' ||
|
|
|
|
|
typeof declarationReflection.comment.tags === 'undefined'
|
|
|
|
|
) {
|
|
|
|
|
if (declarationReflection.comment === undefined || declarationReflection.comment.tags === undefined) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
typeof declarationReflection.comment.tags.find(commentTag => {
|
|
|
|
|
return commentTag.tagName === indexableTag;
|
|
|
|
|
}) !== 'undefined'
|
|
|
|
|
);
|
|
|
|
|
return declarationReflection.comment.tags.some(commentTag => {
|
|
|
|
|
return commentTag.tagName === indexableTag;
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return indexableInterfaces;
|
|
|
|
|
@@ -97,7 +91,6 @@ export function getAllIndexableInterfaces(projectReflection: ProjectReflection):
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Composes error messages, that are readable and contain a certain minimum of information
|
|
|
|
|
*
|
|
|
|
|
* @param path the path where the error took place
|
|
|
|
|
* @param topTypeName the name of the SCThingType
|
|
|
|
|
* @param typeName the name of the object, with which something went wrong
|
|
|
|
|
@@ -124,7 +117,6 @@ function composeErrorMessage(
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Trims a string to a readable size and appends "..."
|
|
|
|
|
*
|
|
|
|
|
* @param value the string to trim
|
|
|
|
|
* @param maxLength the maximum allowed length before it is clamped
|
|
|
|
|
*/
|
|
|
|
|
@@ -137,7 +129,6 @@ function trimString(value: string, maxLength: number): string {
|
|
|
|
|
*
|
|
|
|
|
* Warning to future maintainers: The code for generics doesn't account for depth. when there is a new generic, it will
|
|
|
|
|
* override the previous one, if there isn't, it will just continue passing it down.
|
|
|
|
|
*
|
|
|
|
|
* @param type the ReferenceType of a DeclarationReflection
|
|
|
|
|
* @param out the previous reflection, it then overrides all parameters or keeps old ones
|
|
|
|
|
* @param topTypeName the name of the object, with which something went wrong
|
|
|
|
|
@@ -152,9 +143,9 @@ function getReflectionGeneric(
|
|
|
|
|
tags: CommentTag[],
|
|
|
|
|
): Map<string, MappingProperty> {
|
|
|
|
|
if (
|
|
|
|
|
typeof type.typeArguments !== 'undefined' &&
|
|
|
|
|
type.typeArguments !== undefined &&
|
|
|
|
|
type.reflection instanceof DeclarationReflection &&
|
|
|
|
|
typeof type.reflection.typeParameters !== 'undefined'
|
|
|
|
|
type.reflection.typeParameters !== undefined
|
|
|
|
|
) {
|
|
|
|
|
for (let i = 0; i < type.reflection.typeParameters.length; i++) {
|
|
|
|
|
if (i < type.typeArguments.length) {
|
|
|
|
|
@@ -185,7 +176,6 @@ function getReflectionGeneric(
|
|
|
|
|
* Handles a ReferenceType that has no value
|
|
|
|
|
*
|
|
|
|
|
* Most of the times that is an external type.
|
|
|
|
|
*
|
|
|
|
|
* @param ref the ReferenceType
|
|
|
|
|
* @param generics the generics from levels above, so we can use them without having access to the parent
|
|
|
|
|
* @param path the current path to the object we are in
|
|
|
|
|
@@ -207,7 +197,7 @@ function handleExternalType(
|
|
|
|
|
|
|
|
|
|
if (ref.name === 'Array') {
|
|
|
|
|
// basically an external type, but Array is quite common, especially with generics
|
|
|
|
|
if (typeof ref.typeArguments === 'undefined' || typeof ref.typeArguments[0] === 'undefined') {
|
|
|
|
|
if (ref.typeArguments === undefined || ref.typeArguments[0] === undefined) {
|
|
|
|
|
composeErrorMessage(path, topTypeName, 'Array with generics', 'array', 'Failed to parse');
|
|
|
|
|
|
|
|
|
|
return {type: PARSE_ERROR};
|
|
|
|
|
@@ -241,7 +231,6 @@ function handleExternalType(
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handles an object
|
|
|
|
|
*
|
|
|
|
|
* @param decl the DeclarationReflection of the object
|
|
|
|
|
* @param generics the generics from levels above, so we can use them without having access to the parent
|
|
|
|
|
* @param path the current path to the object we are in
|
|
|
|
|
@@ -270,10 +259,10 @@ function handleDeclarationReflection(
|
|
|
|
|
|
|
|
|
|
let empty = true;
|
|
|
|
|
// first check if there are any index signatures, so for example `[name: string]: Foo`
|
|
|
|
|
if (typeof decl.indexSignature !== 'undefined') {
|
|
|
|
|
if (decl.indexSignature !== undefined) {
|
|
|
|
|
out.dynamic = true;
|
|
|
|
|
|
|
|
|
|
if (typeof decl.indexSignature.type !== 'undefined') {
|
|
|
|
|
if (decl.indexSignature.type !== undefined) {
|
|
|
|
|
empty = false;
|
|
|
|
|
const template: Record<string, MappingDynamicTemplate> = {};
|
|
|
|
|
template[decl.name] = {
|
|
|
|
|
@@ -297,7 +286,7 @@ function handleDeclarationReflection(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// check all the children, so in this case we are dealing with an OBJECT
|
|
|
|
|
if (typeof decl.children !== 'undefined' && decl.children.length > 0) {
|
|
|
|
|
if (decl.children !== undefined && decl.children.length > 0) {
|
|
|
|
|
for (const child of decl.children) {
|
|
|
|
|
empty = false;
|
|
|
|
|
out.properties![child.name] = handleDeclarationReflection(
|
|
|
|
|
@@ -312,7 +301,7 @@ function handleDeclarationReflection(
|
|
|
|
|
// get inherited tags
|
|
|
|
|
const tags =
|
|
|
|
|
(inheritedTags ?? []).length > 0
|
|
|
|
|
? typeof inheritedTags!.find(it => isTagType(it.tagName)) !== 'undefined'
|
|
|
|
|
? inheritedTags!.some(it => isTagType(it.tagName))
|
|
|
|
|
? inheritedTags!
|
|
|
|
|
: [...(inheritedTags ?? []), ...getCommentTags(decl, path, topTypeName)]
|
|
|
|
|
: getCommentTags(decl, path, topTypeName);
|
|
|
|
|
@@ -336,7 +325,6 @@ function handleDeclarationReflection(
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reads all comment tags, including inherited ones
|
|
|
|
|
*
|
|
|
|
|
* @param decl the DeclarationReflection to read the tags from
|
|
|
|
|
* @param path the path on which the comments lie
|
|
|
|
|
* @param topTypeName the name of the SCThingType
|
|
|
|
|
@@ -357,7 +345,7 @@ function getCommentTags(
|
|
|
|
|
|
|
|
|
|
let out: CommentTag[] =
|
|
|
|
|
decl.comment instanceof Comment
|
|
|
|
|
? typeof decl.comment.tags !== 'undefined'
|
|
|
|
|
? decl.comment.tags !== undefined
|
|
|
|
|
? decl.comment.tags
|
|
|
|
|
: inheritedTags
|
|
|
|
|
: inheritedTags;
|
|
|
|
|
@@ -382,7 +370,7 @@ function getCommentTags(
|
|
|
|
|
|
|
|
|
|
saveCommentTags(out, path, topTypeName);
|
|
|
|
|
const inheritTag = out.find(value => value.tagName === inheritTagsName);
|
|
|
|
|
if (typeof inheritTag !== 'undefined') {
|
|
|
|
|
if (inheritTag !== undefined) {
|
|
|
|
|
out = arrayPriorityJoin(out, retrieveCommentTags(inheritTag.text.trim(), path, topTypeName));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -391,7 +379,6 @@ function getCommentTags(
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Saves all comment tags to the map
|
|
|
|
|
*
|
|
|
|
|
* @param tags all tags to be saved (@see and @[inheritTags] will be stripped)
|
|
|
|
|
* @param path the path of field
|
|
|
|
|
* @param topTypeName the name of the SCThingType
|
|
|
|
|
@@ -404,7 +391,6 @@ function saveCommentTags(tags: CommentTag[], path: string, topTypeName: string)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Retrieves any saved tags
|
|
|
|
|
*
|
|
|
|
|
* @param path the path to the original field
|
|
|
|
|
* @param currentPath the current path to the object we are in
|
|
|
|
|
* @param topTypeName the name of the SCThingType
|
|
|
|
|
@@ -421,7 +407,6 @@ function retrieveCommentTags(path: string, currentPath: string, topTypeName: str
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Joins two arrays of CommentTags, but overrides all original CommentTags with the same tagName
|
|
|
|
|
*
|
|
|
|
|
* @param originals the original array
|
|
|
|
|
* @param overrider the array that should be appended and provide the override values
|
|
|
|
|
*/
|
|
|
|
|
@@ -445,7 +430,6 @@ function arrayPriorityJoin(originals: CommentTag[], overrider: CommentTag[]): Co
|
|
|
|
|
*
|
|
|
|
|
* Put into a separate function as it is a little bit more complex
|
|
|
|
|
* Works fairly reliable, although there are issues with primitive union types, which don't work at all (And never will)
|
|
|
|
|
*
|
|
|
|
|
* @param type the type object
|
|
|
|
|
* @param generics the generics from levels above, so we can use them without having access to the parent
|
|
|
|
|
* @param path the current path to the object we are in
|
|
|
|
|
@@ -491,7 +475,6 @@ function handleUnionType(
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Serves as a kind of distributor for the different types, should not contain any specific code
|
|
|
|
|
*
|
|
|
|
|
* @param type the type object
|
|
|
|
|
* @param generics the generics from levels above, so we can use them without having access to the parent
|
|
|
|
|
* @param path the current path to the object we are in
|
|
|
|
|
@@ -533,7 +516,7 @@ function handleType(
|
|
|
|
|
return handleUnionType(type, new Map(generics), path, topTypeName, tags);
|
|
|
|
|
}
|
|
|
|
|
if (type instanceof ReferenceType) {
|
|
|
|
|
if (typeof premaps[type.name] === 'undefined' && typeof type.reflection !== 'undefined') {
|
|
|
|
|
if (premaps[type.name] === undefined && type.reflection !== undefined) {
|
|
|
|
|
// there is really no way to make this typesafe, every element in DeclarationReflection is optional.
|
|
|
|
|
return handleDeclarationReflection(
|
|
|
|
|
type.reflection as DeclarationReflection,
|
|
|
|
|
@@ -571,7 +554,6 @@ function handleType(
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Adds an aggregatable to the aggregations list
|
|
|
|
|
*
|
|
|
|
|
* @param path the current path
|
|
|
|
|
* @param topTypeName the name of the top type
|
|
|
|
|
* @param global whether the topTypeName will be used
|
|
|
|
|
@@ -602,7 +584,6 @@ function addAggregatable(path: string, topTypeName: string, global: boolean) {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reads all tags related to Elasticsearch fields from the fieldMap
|
|
|
|
|
*
|
|
|
|
|
* @param previous the previous ElasticsearchValue, for example and object
|
|
|
|
|
* @param path the current path to the object we are in
|
|
|
|
|
* @param topTypeName the name of the SCThingType
|
|
|
|
|
@@ -622,15 +603,15 @@ function readFieldTags(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ignoredTagsList.includes(tag.tagName)) {
|
|
|
|
|
if (typeof fieldmap[tag.tagName] !== 'undefined') {
|
|
|
|
|
if (typeof previous.fields === 'undefined') {
|
|
|
|
|
if (fieldmap[tag.tagName] !== undefined) {
|
|
|
|
|
if (previous.fields === undefined) {
|
|
|
|
|
// create in case it doesn't exist
|
|
|
|
|
previous.fields = {};
|
|
|
|
|
}
|
|
|
|
|
if (tag.text.trim() === '') {
|
|
|
|
|
// merge fields
|
|
|
|
|
previous.fields = {...previous.fields, ...fieldmap[tag.tagName].default};
|
|
|
|
|
} else if (typeof fieldmap[tag.tagName][tag.text.trim()] !== 'undefined') {
|
|
|
|
|
} else if (fieldmap[tag.tagName][tag.text.trim()] !== undefined) {
|
|
|
|
|
// merge fields
|
|
|
|
|
previous.fields = {...previous.fields, ...fieldmap[tag.tagName][tag.text.trim()]};
|
|
|
|
|
} else if (!fieldmap[tag.tagName].ignore.includes(tag.text.trim())) {
|
|
|
|
|
@@ -644,12 +625,12 @@ function readFieldTags(
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} else if (tag.tagName === filterableTagName) {
|
|
|
|
|
if (typeof previous.fields === 'undefined') {
|
|
|
|
|
if (previous.fields === undefined) {
|
|
|
|
|
previous.fields = {};
|
|
|
|
|
}
|
|
|
|
|
if ('type' in previous) {
|
|
|
|
|
const type = filterableMap[previous.type!];
|
|
|
|
|
if (typeof type !== 'undefined') {
|
|
|
|
|
if (type !== undefined) {
|
|
|
|
|
// merge fields
|
|
|
|
|
previous.fields = {...previous.fields, raw: {type: type}};
|
|
|
|
|
} else {
|
|
|
|
|
@@ -664,7 +645,7 @@ function readFieldTags(
|
|
|
|
|
} else {
|
|
|
|
|
composeErrorMessage(path, topTypeName, 'tag', tag.tagName, 'Not applicable for object types');
|
|
|
|
|
}
|
|
|
|
|
} else if (typeof dataType === 'undefined' || typeof typemap[dataType][tag.tagName] === 'undefined') {
|
|
|
|
|
} else if (dataType === undefined || typemap[dataType][tag.tagName] === undefined) {
|
|
|
|
|
composeErrorMessage(path, topTypeName, 'tag', tag.tagName, `Not implemented tag`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -675,7 +656,6 @@ function readFieldTags(
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reads all types related to Elasticsearch fields from the fieldMap
|
|
|
|
|
*
|
|
|
|
|
* @param type the type of the value
|
|
|
|
|
* @param path the current path to the object we are in
|
|
|
|
|
* @param topTypeName the name of the SCThingType
|
|
|
|
|
@@ -684,13 +664,10 @@ function readFieldTags(
|
|
|
|
|
function readTypeTags(type: string, path: string, topTypeName: string, tags: CommentTag[]): MappingProperty {
|
|
|
|
|
let out: MappingProperty = {type: PARSE_ERROR};
|
|
|
|
|
|
|
|
|
|
if (typeof typemap[type] !== 'undefined') {
|
|
|
|
|
if (typemap[type] !== undefined) {
|
|
|
|
|
// first look if the value has a definition in the typemap
|
|
|
|
|
for (let i = tags.length - 1; i >= 0; i--) {
|
|
|
|
|
if (
|
|
|
|
|
!ignoredTagsList.includes(tags[i].tagName) &&
|
|
|
|
|
typeof typemap[type][tags[i].tagName] !== 'undefined'
|
|
|
|
|
) {
|
|
|
|
|
if (!ignoredTagsList.includes(tags[i].tagName) && typemap[type][tags[i].tagName] !== undefined) {
|
|
|
|
|
// if we have a tag that indicates a type
|
|
|
|
|
if (out.type !== PARSE_ERROR) {
|
|
|
|
|
composeErrorMessage(
|
|
|
|
|
@@ -735,7 +712,6 @@ function readTypeTags(type: string, path: string, topTypeName: string, tags: Com
|
|
|
|
|
*
|
|
|
|
|
* This is kind of a suboptimal solution and should be changed in the future.
|
|
|
|
|
* https://gitlab.com/openstapps/core-tools/-/issues/49
|
|
|
|
|
*
|
|
|
|
|
* @param resetInheritTags whether inherited tags should be reset as well
|
|
|
|
|
*/
|
|
|
|
|
function reset(resetInheritTags = true) {
|
|
|
|
|
@@ -761,7 +737,6 @@ function reset(resetInheritTags = true) {
|
|
|
|
|
* Serves as the entry point for getting the mapping, so if you just want to get the mapping files for Elasticsearch,
|
|
|
|
|
* you can do so by calling this function, `RETURNED_VALUE.template` contains the mapping in a fashion that is directly
|
|
|
|
|
* readable by Elasticsearch.
|
|
|
|
|
*
|
|
|
|
|
* @param projectReflection a reflection of the project you want to get the ES Mappings from
|
|
|
|
|
* @param ignoredTags the tag names for which the error output should be suppressed
|
|
|
|
|
* @param showErrorOutput whether to print all errors in the command line or not
|
|
|
|
|
@@ -795,7 +770,7 @@ export function generateTemplate(
|
|
|
|
|
return declarationReflection.name === 'type';
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (typeof typeObject === 'undefined' || typeof typeObject.type === 'undefined') {
|
|
|
|
|
if (typeObject === undefined || typeObject.type === undefined) {
|
|
|
|
|
throw new TypeError('Interface needs a type to be indexable');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -845,7 +820,7 @@ export function generateTemplate(
|
|
|
|
|
return declarationReflection.name === 'type';
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (typeof typeObject === 'undefined' || typeof typeObject.type === 'undefined') {
|
|
|
|
|
if (typeObject === undefined || typeObject.type === undefined) {
|
|
|
|
|
throw new TypeError('Interface needs a type to be indexable');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -873,7 +848,7 @@ export function generateTemplate(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// filter out
|
|
|
|
|
if (interfaceFilter.length > 0 && typeof interfaceFilter.find(it => it === typeName) === 'undefined') {
|
|
|
|
|
if (interfaceFilter.length > 0 && !interfaceFilter.includes(typeName)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|