forked from MapComplete/MapComplete
		
	Themes: add extra check so that in a mapping cannot override the , fix two such instances
This commit is contained in:
		
							parent
							
								
									393d4e75d8
								
							
						
					
					
						commit
						56ea1163bb
					
				
					 3 changed files with 145 additions and 92 deletions
				
			
		| 
						 | 
					@ -135,7 +135,6 @@
 | 
				
			||||||
            "de": "Kletterschuhe können hier ausgeliehen werden"
 | 
					            "de": "Kletterschuhe können hier ausgeliehen werden"
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          "addExtraTags": [
 | 
					          "addExtraTags": [
 | 
				
			||||||
            "service:climbing_shoes:rental:fee=",
 | 
					 | 
				
			||||||
            "service:climbing_shoes:rental:charge="
 | 
					            "service:climbing_shoes:rental:charge="
 | 
				
			||||||
          ]
 | 
					          ]
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -231,12 +231,7 @@
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              "if": {
 | 
					              "if": "fee=no",
 | 
				
			||||||
                "and": [
 | 
					 | 
				
			||||||
                  "fee=no",
 | 
					 | 
				
			||||||
                  "charge="
 | 
					 | 
				
			||||||
                ]
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
              "then": {
 | 
					              "then": {
 | 
				
			||||||
                "en": "Can be used for free",
 | 
					                "en": "Can be used for free",
 | 
				
			||||||
                "id": "Boleh digunakan tanpa bayaran",
 | 
					                "id": "Boleh digunakan tanpa bayaran",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@ import FilterConfigJson from "../Json/FilterConfigJson"
 | 
				
			||||||
import DeleteConfig from "../DeleteConfig"
 | 
					import DeleteConfig from "../DeleteConfig"
 | 
				
			||||||
import {QuestionableTagRenderingConfigJson} from "../Json/QuestionableTagRenderingConfigJson"
 | 
					import {QuestionableTagRenderingConfigJson} from "../Json/QuestionableTagRenderingConfigJson"
 | 
				
			||||||
import Validators from "../../../UI/InputElement/Validators"
 | 
					import Validators from "../../../UI/InputElement/Validators"
 | 
				
			||||||
 | 
					import TagRenderingConfig from "../TagRenderingConfig";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ValidateLanguageCompleteness extends DesugaringStep<any> {
 | 
					class ValidateLanguageCompleteness extends DesugaringStep<any> {
 | 
				
			||||||
    private readonly _languages: string[]
 | 
					    private readonly _languages: string[]
 | 
				
			||||||
| 
						 | 
					@ -383,6 +384,51 @@ export class PrevalidateTheme extends Fuse<LayoutConfigJson> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class DetectConflictingAddExtraTags extends DesugaringStep<TagRenderingConfigJson> {
 | 
				
			||||||
 | 
					    constructor() {
 | 
				
			||||||
 | 
					        super("The `if`-part in a mapping might set some keys. Those key are not allowed to be set in the `addExtraTags`, as this might result in conflicting values", [], "DetectConflictingAddExtraTags");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    convert(json: TagRenderingConfigJson, context: string): {
 | 
				
			||||||
 | 
					        result: TagRenderingConfigJson;
 | 
				
			||||||
 | 
					        errors?: string[];
 | 
				
			||||||
 | 
					        warnings?: string[];
 | 
				
			||||||
 | 
					        information?: string[]
 | 
				
			||||||
 | 
					    } {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!(json.mappings?.length > 0)) {
 | 
				
			||||||
 | 
					            return {result: json}
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const tagRendering = new TagRenderingConfig(json)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const errors = []
 | 
				
			||||||
 | 
					        for (let i = 0; i < tagRendering.mappings.length; i++) {
 | 
				
			||||||
 | 
					            const mapping = tagRendering.mappings[i];
 | 
				
			||||||
 | 
					            if (!mapping.addExtraTags) {
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            const keysInMapping = new Set(mapping.if.usedKeys())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const keysInAddExtraTags = mapping.addExtraTags.map(t => t.key)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const duplicateKeys = keysInAddExtraTags.filter(k => keysInMapping.has(k))
 | 
				
			||||||
 | 
					            if (duplicateKeys.length > 0) {
 | 
				
			||||||
 | 
					                errors.push(
 | 
				
			||||||
 | 
					                    "At " + context + ".mappings[" + i + "]: AddExtraTags overrides a key that is set in the `if`-clause of this mapping. Selecting this answer might thus first set one value (needed to match as answer) and then override it with a different value, resulting in an unsaveable question. The offending `addExtraTags` is " + duplicateKeys.join(", ")
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            result: json,
 | 
				
			||||||
 | 
					            errors
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJson> {
 | 
					export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJson> {
 | 
				
			||||||
    private readonly _calculatedTagNames: string[]
 | 
					    private readonly _calculatedTagNames: string[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -669,6 +715,7 @@ export class ValidateTagRenderings extends Fuse<TagRenderingConfigJson> {
 | 
				
			||||||
        super(
 | 
					        super(
 | 
				
			||||||
            "Various validation on tagRenderingConfigs",
 | 
					            "Various validation on tagRenderingConfigs",
 | 
				
			||||||
            new DetectShadowedMappings(layerConfig),
 | 
					            new DetectShadowedMappings(layerConfig),
 | 
				
			||||||
 | 
					            new DetectConflictingAddExtraTags(),
 | 
				
			||||||
            new DetectMappingsWithImages(doesImageExist),
 | 
					            new DetectMappingsWithImages(doesImageExist),
 | 
				
			||||||
            new MiscTagRenderingChecks(options)
 | 
					            new MiscTagRenderingChecks(options)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -865,6 +912,13 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (json.filter) {
 | 
				
			||||||
 | 
					                const r = new On("filter", new Each( new ValidateFilter())).convert(json, context)
 | 
				
			||||||
 | 
					                warnings.push(...(r.warnings ?? []))
 | 
				
			||||||
 | 
					                errors.push(...(r.errors ?? []))
 | 
				
			||||||
 | 
					                information.push(...(r.information ?? []))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (json.tagRenderings !== undefined) {
 | 
					            if (json.tagRenderings !== undefined) {
 | 
				
			||||||
                const r = new On(
 | 
					                const r = new On(
 | 
				
			||||||
                    "tagRenderings",
 | 
					                    "tagRenderings",
 | 
				
			||||||
| 
						 | 
					@ -949,9 +1003,14 @@ export class ValidateFilter extends DesugaringStep<FilterConfigJson> {
 | 
				
			||||||
        warnings?: string[]
 | 
					        warnings?: string[]
 | 
				
			||||||
        information?: string[]
 | 
					        information?: string[]
 | 
				
			||||||
    } {
 | 
					    } {
 | 
				
			||||||
 | 
					        if (typeof filter === "string") {
 | 
				
			||||||
 | 
					            // Calling another filter, we skip
 | 
				
			||||||
 | 
					            return {result: filter}
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        const errors = []
 | 
					        const errors = []
 | 
				
			||||||
        for (const option of filter.options) {
 | 
					        for (const option of filter.options) {
 | 
				
			||||||
            for (let i = 0; i < option.fields.length; i++) {
 | 
					
 | 
				
			||||||
 | 
					            for (let i = 0; i < option.fields?.length ?? 0; i++) {
 | 
				
			||||||
                const field = option.fields[i]
 | 
					                const field = option.fields[i]
 | 
				
			||||||
                const type = field.type ?? "string"
 | 
					                const type = field.type ?? "string"
 | 
				
			||||||
                if (Validators.availableTypes.find((t) => t === type) === undefined) {
 | 
					                if (Validators.availableTypes.find((t) => t === type) === undefined) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue