mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-22 17:42:57 +00:00
fix: read type tags correctly after the first time
This commit is contained in:
@@ -93,11 +93,16 @@ commander
|
|||||||
// get project reflection
|
// get project reflection
|
||||||
const projectReflection = getProjectReflection(srcPath);
|
const projectReflection = getProjectReflection(srcPath);
|
||||||
|
|
||||||
const mapping = generateTemplate(projectReflection, ignoredTagsList);
|
const result = generateTemplate(projectReflection, ignoredTagsList, true);
|
||||||
|
if (result.errors.length !== 0) {
|
||||||
|
await Logger.error('Mapping generated with errors!');
|
||||||
|
} else {
|
||||||
|
Logger.ok('Mapping generated without errors!');
|
||||||
|
}
|
||||||
|
|
||||||
// write documentation to file
|
// write documentation to file
|
||||||
// tslint:disable-next-line:no-magic-numbers
|
// tslint:disable-next-line:no-magic-numbers
|
||||||
writeFileSync(mappingPath, JSON.stringify(mapping.template, null, 2));
|
writeFileSync(mappingPath, JSON.stringify(result.template, null, 2));
|
||||||
|
|
||||||
Logger.ok(`Elasticsearch mapping written to ${mappingPath}.`);
|
Logger.ok(`Elasticsearch mapping written to ${mappingPath}.`);
|
||||||
});
|
});
|
||||||
|
|||||||
130
src/mapping.ts
130
src/mapping.ts
@@ -108,8 +108,11 @@ function composeErrorMessage(path: string, typeName: string, object: string, mes
|
|||||||
* @param type the ReferenceType of a DeclarationReflection
|
* @param type the ReferenceType of a DeclarationReflection
|
||||||
* @param out the previous reflection, it then overrides all parameters or keeps old ones
|
* @param out the previous reflection, it then overrides all parameters or keeps old ones
|
||||||
* @param path the current path to the object we are in
|
* @param path the current path to the object we are in
|
||||||
|
* @param tags any tags attached to the type
|
||||||
*/
|
*/
|
||||||
function getReflectionGeneric(type: ReferenceType, out: ReflectionGeneric[], path: string): ReflectionGeneric[] {
|
function getReflectionGeneric(type: ReferenceType,
|
||||||
|
out: ReflectionGeneric[],
|
||||||
|
path: string, tags: CommentTag[]): ReflectionGeneric[] {
|
||||||
if (typeof type.typeArguments !== 'undefined'
|
if (typeof type.typeArguments !== 'undefined'
|
||||||
&& type.reflection instanceof DeclarationReflection
|
&& type.reflection instanceof DeclarationReflection
|
||||||
&& typeof type.reflection.typeParameters !== 'undefined'
|
&& typeof type.reflection.typeParameters !== 'undefined'
|
||||||
@@ -118,14 +121,14 @@ function getReflectionGeneric(type: ReferenceType, out: ReflectionGeneric[], pat
|
|||||||
let replaced = false;
|
let replaced = false;
|
||||||
for (const old of out) {
|
for (const old of out) {
|
||||||
if (old.name === type.reflection.typeParameters[i].name) {
|
if (old.name === type.reflection.typeParameters[i].name) {
|
||||||
old.value = handleType(type.typeArguments[i], out, path);
|
old.value = handleType(type.typeArguments[i], out, path, tags);
|
||||||
replaced = true;
|
replaced = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!replaced) {
|
if (!replaced) {
|
||||||
out.push({
|
out.push({
|
||||||
name: type.reflection.typeParameters[i].name,
|
name: type.reflection.typeParameters[i].name,
|
||||||
value: handleType(type.typeArguments[i], out, path),
|
value: handleType(type.typeArguments[i], out, path, tags),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,7 +146,7 @@ function getReflectionGeneric(type: ReferenceType, out: ReflectionGeneric[], pat
|
|||||||
* @param tags any tags attached to the type
|
* @param tags any tags attached to the type
|
||||||
*/
|
*/
|
||||||
function handleRefWithoutReflection(ref: ReferenceType, generics: ReflectionGeneric[],
|
function handleRefWithoutReflection(ref: ReferenceType, generics: ReflectionGeneric[],
|
||||||
path: string, tags?: CommentTag[]): ElasticsearchValue {
|
path: string, tags: CommentTag[]): ElasticsearchValue {
|
||||||
for (const premap in premaps) {
|
for (const premap in premaps) {
|
||||||
if (premap === ref.name) {
|
if (premap === ref.name) {
|
||||||
return readFieldTags(premaps[premap], path, tags);
|
return readFieldTags(premaps[premap], path, tags);
|
||||||
@@ -157,7 +160,7 @@ function handleRefWithoutReflection(ref: ReferenceType, generics: ReflectionGene
|
|||||||
return {type: ElasticsearchDataType.parse_error};
|
return {type: ElasticsearchDataType.parse_error};
|
||||||
}
|
}
|
||||||
|
|
||||||
return readFieldTags(handleType(ref.typeArguments[0], getReflectionGeneric(ref, generics, path), path),
|
return readFieldTags(handleType(ref.typeArguments[0], getReflectionGeneric(ref, generics, path, tags), path, tags),
|
||||||
path, tags);
|
path, tags);
|
||||||
}
|
}
|
||||||
if (ref.name === '__type') { // empty object
|
if (ref.name === '__type') { // empty object
|
||||||
@@ -179,12 +182,15 @@ function handleRefWithoutReflection(ref: ReferenceType, generics: ReflectionGene
|
|||||||
* @param generics the generics from levels above, so we can use them without having access to the parent
|
* @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
|
* @param path the current path to the object we are in
|
||||||
*/
|
*/
|
||||||
function handleDeclarationReflection(decl: DeclarationReflection, generics: ReflectionGeneric[], path: string):
|
function handleDeclarationReflection(decl: DeclarationReflection,
|
||||||
|
generics: ReflectionGeneric[],
|
||||||
|
path: string):
|
||||||
ElasticsearchValue {
|
ElasticsearchValue {
|
||||||
// check if we have an object referencing a generic
|
// check if we have an object referencing a generic
|
||||||
for (const gRefl of generics) {
|
for (const gRefl of generics) {
|
||||||
if (gRefl.name === decl.name) { // if the object name is the same as the generic name
|
if (gRefl.name === decl.name) { // if the object name is the same as the generic name
|
||||||
return readFieldTags(gRefl.value, path, typeof decl.comment !== 'undefined' ? decl.comment.tags : undefined);
|
return readFieldTags(gRefl.value, path,
|
||||||
|
typeof decl.comment !== 'undefined' ? typeof decl.comment.tags !== 'undefined' ? decl.comment.tags : [] : []);
|
||||||
// use the value defined by the generic
|
// use the value defined by the generic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,17 +225,18 @@ function handleDeclarationReflection(decl: DeclarationReflection, generics: Refl
|
|||||||
}
|
}
|
||||||
} else if (decl.type instanceof Type) { // if the object is a type, so we are dealing with a PROPERTY
|
} else if (decl.type instanceof Type) { // if the object is a type, so we are dealing with a PROPERTY
|
||||||
return handleType(decl.type, generics, path,
|
return handleType(decl.type, generics, path,
|
||||||
typeof decl.comment !== 'undefined' ? decl.comment.tags : undefined);
|
typeof decl.comment !== 'undefined' ? typeof decl.comment.tags !== 'undefined' ? decl.comment.tags : [] : []);
|
||||||
} else if (decl.kindString === 'Enumeration member') {
|
} else if (decl.kindString === 'Enumeration member') {
|
||||||
return readTypeTags(typeof decl.defaultValue, path,
|
return readTypeTags(typeof decl.defaultValue, path,
|
||||||
typeof decl.comment !== 'undefined' ? decl.comment.tags : undefined);
|
typeof decl.comment !== 'undefined' ? typeof decl.comment.tags !== 'undefined' ? decl.comment.tags : [] : []);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty) {
|
if (empty) {
|
||||||
composeErrorMessage(path, 'object', decl.name, 'Empty object');
|
composeErrorMessage(path, 'object', decl.name, 'Empty object');
|
||||||
}
|
}
|
||||||
|
|
||||||
return readFieldTags(out, path, typeof decl.comment !== 'undefined' ? decl.comment.tags : undefined);
|
return readFieldTags(out, path,
|
||||||
|
typeof decl.comment !== 'undefined' ? typeof decl.comment.tags !== 'undefined' ? decl.comment.tags : [] : []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -241,15 +248,19 @@ function handleDeclarationReflection(decl: DeclarationReflection, generics: Refl
|
|||||||
* @param type the type object
|
* @param type the type object
|
||||||
* @param generics the generics from levels above, so we can use them without having access to the parent
|
* @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
|
* @param path the current path to the object we are in
|
||||||
|
* @param tags any tags attached to the type
|
||||||
*/
|
*/
|
||||||
function handleUnionType(type: UnionType, generics: ReflectionGeneric[], path: string): ElasticsearchValue {
|
function handleUnionType(type: UnionType,
|
||||||
|
generics: ReflectionGeneric[],
|
||||||
|
path: string,
|
||||||
|
tags: CommentTag[]): ElasticsearchValue {
|
||||||
const list: ElasticsearchValue[] = [];
|
const list: ElasticsearchValue[] = [];
|
||||||
|
|
||||||
for (const subType of type.types) {
|
for (const subType of type.types) {
|
||||||
if (subType instanceof IntrinsicType && subType.name === 'undefined') {
|
if (subType instanceof IntrinsicType && subType.name === 'undefined') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
list.push(handleType(subType, generics, path));
|
list.push(handleType(subType, generics, path, tags));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list.length > 0) {
|
if (list.length > 0) {
|
||||||
@@ -275,7 +286,7 @@ function handleUnionType(type: UnionType, generics: ReflectionGeneric[], path: s
|
|||||||
* @param path the current path to the object we are in
|
* @param path the current path to the object we are in
|
||||||
* @param tags any tags attached to the type
|
* @param tags any tags attached to the type
|
||||||
*/
|
*/
|
||||||
function handleType(type: Type, generics: ReflectionGeneric[], path: string, tags?: CommentTag[]): ElasticsearchValue {
|
function handleType(type: Type, generics: ReflectionGeneric[], path: string, tags: CommentTag[]): ElasticsearchValue {
|
||||||
// logger.log((type as any).name);
|
// logger.log((type as any).name);
|
||||||
if (type instanceof ArrayType) { // array is irrelevant in Elasticsearch, so just go with the element type
|
if (type instanceof ArrayType) { // array is irrelevant in Elasticsearch, so just go with the element type
|
||||||
return handleType(type.elementType, generics, path, tags);
|
return handleType(type.elementType, generics, path, tags);
|
||||||
@@ -287,13 +298,13 @@ function handleType(type: Type, generics: ReflectionGeneric[], path: string, tag
|
|||||||
return readTypeTags(type.name, path, tags);
|
return readTypeTags(type.name, path, tags);
|
||||||
}
|
}
|
||||||
if (type instanceof UnionType) { // the union type...
|
if (type instanceof UnionType) { // the union type...
|
||||||
return handleUnionType(type, generics, path);
|
return handleUnionType(type, generics, path, tags);
|
||||||
}
|
}
|
||||||
if (type instanceof ReferenceType) {
|
if (type instanceof ReferenceType) {
|
||||||
if (typeof type.reflection !== 'undefined') {
|
if (typeof type.reflection !== 'undefined') {
|
||||||
// there is really no way to make this typesafe, every element in DeclarationReflection is optional.
|
// there is really no way to make this typesafe, every element in DeclarationReflection is optional.
|
||||||
return handleDeclarationReflection(type.reflection as DeclarationReflection,
|
return handleDeclarationReflection(type.reflection as DeclarationReflection,
|
||||||
getReflectionGeneric(type, generics, path), path);
|
getReflectionGeneric(type, generics, path, tags), path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return handleRefWithoutReflection(type, generics, path, tags);
|
return handleRefWithoutReflection(type, generics, path, tags);
|
||||||
@@ -325,40 +336,46 @@ function handleType(type: Type, generics: ReflectionGeneric[], path: string, tag
|
|||||||
* @param prev the previous ElasticsearchValue, for example and object
|
* @param prev the previous ElasticsearchValue, for example and object
|
||||||
* @param path the current path to the object we are in
|
* @param path the current path to the object we are in
|
||||||
* @param tags tags attached to the value
|
* @param tags tags attached to the value
|
||||||
|
* @param dataType the ElasticsearchDataType, for checking if a tag is a type tag
|
||||||
*/
|
*/
|
||||||
function readFieldTags(prev: ElasticsearchValue, path: string, tags?: CommentTag[]): ElasticsearchValue {
|
function readFieldTags(prev: ElasticsearchValue,
|
||||||
if (typeof tags !== 'undefined') {
|
path: string,
|
||||||
for (const tag of tags) {
|
tags: CommentTag[],
|
||||||
if (!ignoredTagsList.includes(tag.tagName)) {
|
dataType?: string): ElasticsearchValue {
|
||||||
if (typeof fieldmap[tag.tagName] !== 'undefined') {
|
for (const tag of tags) {
|
||||||
if (typeof prev.fields === 'undefined') {
|
if (!ignoredTagsList.includes(tag.tagName)) {
|
||||||
prev.fields = {};
|
if (typeof fieldmap[tag.tagName] !== 'undefined') {
|
||||||
}
|
if (typeof prev.fields === 'undefined') {
|
||||||
if (tag.text.trim() === '') {
|
// create in case it doesn't exist
|
||||||
prev.fields = {...prev.fields, ...fieldmap[tag.tagName].default};
|
prev.fields = {};
|
||||||
} else if (typeof fieldmap[tag.tagName][tag.text.trim()] !== 'undefined') {
|
}
|
||||||
// merge the fields
|
if (tag.text.trim() === '') {
|
||||||
prev.fields = {...prev.fields, ...fieldmap[tag.tagName][tag.text.trim()]};
|
// merge fields
|
||||||
} else if (!fieldmap[tag.tagName].ignore.includes(tag.text.trim())) {
|
prev.fields = {...prev.fields, ...fieldmap[tag.tagName].default};
|
||||||
composeErrorMessage(path, 'tag', tag.tagName, `Not implemented tag param "${tag.text.trim()}"`);
|
} else if (typeof fieldmap[tag.tagName][tag.text.trim()] !== 'undefined') {
|
||||||
}
|
// merge fields
|
||||||
} else if (tag.tagName === filterableTagName) {
|
prev.fields = {...prev.fields, ...fieldmap[tag.tagName][tag.text.trim()]};
|
||||||
if (typeof prev.fields === 'undefined') {
|
} else if (!fieldmap[tag.tagName].ignore.includes(tag.text.trim())) {
|
||||||
prev.fields = {};
|
// when there is an unidentified tag
|
||||||
}
|
composeErrorMessage(path, 'tag', tag.tagName, `Not implemented tag param "${tag.text.trim()}"`);
|
||||||
if ('type' in prev) {
|
}
|
||||||
const type = filterableMap[prev.type];
|
} else if (tag.tagName === filterableTagName) {
|
||||||
if (typeof type !== 'undefined') {
|
if (typeof prev.fields === 'undefined') {
|
||||||
prev.fields = {...prev.fields, ...{raw: {type: type}}};
|
prev.fields = {};
|
||||||
} else {
|
}
|
||||||
composeErrorMessage(path, 'tag', tag.tagName, `Not implemented for ${prev.type}`);
|
if ('type' in prev) {
|
||||||
}
|
const type = filterableMap[prev.type];
|
||||||
|
if (typeof type !== 'undefined') {
|
||||||
|
// merge fields
|
||||||
|
prev.fields = {...prev.fields, ...{raw: {type: type}}};
|
||||||
} else {
|
} else {
|
||||||
composeErrorMessage(path, 'tag', tag.tagName, 'Not applicable for object types');
|
composeErrorMessage(path, 'tag', tag.tagName, `Not implemented for ${prev.type}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
composeErrorMessage(path, 'tag', tag.tagName, `Not implemented tag`);
|
composeErrorMessage(path, 'tag', tag.tagName, 'Not applicable for object types');
|
||||||
}
|
}
|
||||||
|
} else if (typeof dataType === 'undefined' || typeof typemap[dataType][tag.tagName] === 'undefined') {
|
||||||
|
composeErrorMessage(path, 'tag', tag.tagName, `Not implemented tag`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,23 +390,20 @@ function readFieldTags(prev: ElasticsearchValue, path: string, tags?: CommentTag
|
|||||||
* @param path the current path to the object we are in
|
* @param path the current path to the object we are in
|
||||||
* @param tags tags attached to the value
|
* @param tags tags attached to the value
|
||||||
*/
|
*/
|
||||||
function readTypeTags(type: string, path: string, tags?: CommentTag[]): ElasticsearchValue {
|
function readTypeTags(type: string, path: string, tags: CommentTag[]): ElasticsearchValue {
|
||||||
let out: ElasticsearchValue = {type: ElasticsearchDataType.parse_error};
|
let out: ElasticsearchValue = {type: ElasticsearchDataType.parse_error};
|
||||||
|
|
||||||
if (typeof typemap[type] !== 'undefined') { // first look if the value has a definition in the typemap
|
if (typeof typemap[type] !== 'undefined') { // first look if the value has a definition in the typemap
|
||||||
if (typeof tags !== 'undefined') { // look if there are any tags
|
for (let i = tags.length - 1; i >= 0; i--) {
|
||||||
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) && typeof typemap[type][tags[i].tagName] !== 'undefined') {
|
// if we have a tag that indicates a type
|
||||||
// if we have a tag that indicates a type
|
if (out.type !== ElasticsearchDataType.parse_error) {
|
||||||
if (out.type !== ElasticsearchDataType.parse_error) {
|
composeErrorMessage(path, 'type', type, `Type conflict; "${typemap[type][tags[i].tagName]}" would` +
|
||||||
composeErrorMessage(path, 'type', type, `Type conflict; "${typemap[type][tags[i].tagName]}" would` +
|
` override "${out.type}"`);
|
||||||
` override "${out.type}"`);
|
out.type = ElasticsearchDataType.type_conflict;
|
||||||
out.type = ElasticsearchDataType.type_conflict;
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
out.type = typemap[type][tags[i].tagName];
|
|
||||||
tags.splice(i, 1); // we need this so readFieldTags can process correctly
|
|
||||||
}
|
}
|
||||||
|
out.type = typemap[type][tags[i].tagName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,7 +411,7 @@ function readTypeTags(type: string, path: string, tags?: CommentTag[]): Elastics
|
|||||||
out.type = typemap[type].default;
|
out.type = typemap[type].default;
|
||||||
}
|
}
|
||||||
|
|
||||||
out = readFieldTags(out, path, tags);
|
out = readFieldTags(out, path, tags, type);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,5 +53,6 @@ export const filterableTagName = 'filterable';
|
|||||||
|
|
||||||
export const filterableMap: ElasticsearchFilterableMap = {
|
export const filterableMap: ElasticsearchFilterableMap = {
|
||||||
date: ElasticsearchDataType.keyword,
|
date: ElasticsearchDataType.keyword,
|
||||||
|
keyword: ElasticsearchDataType.keyword,
|
||||||
text: ElasticsearchDataType.keyword,
|
text: ElasticsearchDataType.keyword,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,7 +44,10 @@ export const premaps: ElasticsearchPremap = {
|
|||||||
dynamic: 'strict',
|
dynamic: 'strict',
|
||||||
properties: {
|
properties: {
|
||||||
bbox: {type: ElasticsearchDataType.float},
|
bbox: {type: ElasticsearchDataType.float},
|
||||||
coordinates: {type: ElasticsearchDataType.geo_point}, // TODO: filterable
|
coordinates: {
|
||||||
|
fields: {raw: {type: ElasticsearchDataType.keyword}},
|
||||||
|
type: ElasticsearchDataType.geo_point,
|
||||||
|
},
|
||||||
crs: {
|
crs: {
|
||||||
dynamic: 'strict',
|
dynamic: 'strict',
|
||||||
properties: {
|
properties: {
|
||||||
@@ -62,7 +65,10 @@ export const premaps: ElasticsearchPremap = {
|
|||||||
dynamic: 'strict',
|
dynamic: 'strict',
|
||||||
properties: {
|
properties: {
|
||||||
bbox: {type: ElasticsearchDataType.float},
|
bbox: {type: ElasticsearchDataType.float},
|
||||||
coordinates: {type: ElasticsearchDataType.geo_point}, // TODO: filterable
|
coordinates: {
|
||||||
|
fields: {raw: {type: ElasticsearchDataType.keyword}},
|
||||||
|
type: ElasticsearchDataType.geo_point,
|
||||||
|
},
|
||||||
crs: {
|
crs: {
|
||||||
dynamic: 'strict',
|
dynamic: 'strict',
|
||||||
properties: {
|
properties: {
|
||||||
|
|||||||
Reference in New Issue
Block a user