Add extra validation on custom downloaded themes

This commit is contained in:
Pieter Vander Vennet 2022-09-11 01:49:07 +02:00
parent 818cd62abc
commit 6f9199f1ad
3 changed files with 45 additions and 23 deletions

View file

@ -1,23 +1,24 @@
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"
import { QueryParameters } from "./Web/QueryParameters"
import { AllKnownLayouts } from "../Customizations/AllKnownLayouts"
import { FixedUiElement } from "../UI/Base/FixedUiElement"
import { Utils } from "../Utils"
import {QueryParameters} from "./Web/QueryParameters"
import {AllKnownLayouts} from "../Customizations/AllKnownLayouts"
import {FixedUiElement} from "../UI/Base/FixedUiElement"
import {Utils} from "../Utils"
import Combine from "../UI/Base/Combine"
import { SubtleButton } from "../UI/Base/SubtleButton"
import {SubtleButton} from "../UI/Base/SubtleButton"
import BaseUIElement from "../UI/BaseUIElement"
import { UIEventSource } from "./UIEventSource"
import { LocalStorageSource } from "./Web/LocalStorageSource"
import {UIEventSource} from "./UIEventSource"
import {LocalStorageSource} from "./Web/LocalStorageSource"
import LZString from "lz-string"
import { FixLegacyTheme } from "../Models/ThemeConfig/Conversion/LegacyJsonConvert"
import { LayerConfigJson } from "../Models/ThemeConfig/Json/LayerConfigJson"
import {FixLegacyTheme} from "../Models/ThemeConfig/Conversion/LegacyJsonConvert"
import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson"
import SharedTagRenderings from "../Customizations/SharedTagRenderings"
import * as known_layers from "../assets/generated/known_layers.json"
import { PrepareTheme } from "../Models/ThemeConfig/Conversion/PrepareTheme"
import {PrepareTheme} from "../Models/ThemeConfig/Conversion/PrepareTheme"
import * as licenses from "../assets/generated/license_info.json"
import TagRenderingConfig from "../Models/ThemeConfig/TagRenderingConfig"
import { FixImages } from "../Models/ThemeConfig/Conversion/FixImages"
import {FixImages} from "../Models/ThemeConfig/Conversion/FixImages"
import Svg from "../Svg"
import {DoesImageExist, PrevalidateTheme, ValidateThemeAndLayers} from "../Models/ThemeConfig/Conversion/Validation";
export default class DetermineLayout {
private static readonly _knownImages = new Set(Array.from(licenses).map((l) => l.path))
@ -129,11 +130,11 @@ export default class DetermineLayout {
}),
json !== undefined
? new SubtleButton(Svg.download_svg(), "Download the JSON file").onClick(() => {
Utils.offerContentsAsDownloadableFile(
JSON.stringify(json, null, " "),
"theme_definition.json"
)
})
Utils.offerContentsAsDownloadableFile(
JSON.stringify(json, null, " "),
"theme_definition.json"
)
})
: undefined,
])
.SetClass("flex flex-col clickable")
@ -179,6 +180,23 @@ export default class DetermineLayout {
json.id = forceId ?? json.id
{
let {errors} = new PrevalidateTheme().convert(json, "validation")
if (errors.length > 0) {
throw "Detected errors: " + errors.join("\n")
}
}
{
let {errors} = new ValidateThemeAndLayers(
new DoesImageExist(new Set<string>(), _ => true),
"",
false,
SharedTagRenderings.SharedTagRendering
).convert(json, "validation")
if (errors.length > 0) {
throw "Detected errors: " + errors.join("\n")
}
}
return new LayoutConfig(json, false, {
definitionRaw: JSON.stringify(raw, null, " "),
definedAtUrl: sourceUrl,

View file

@ -147,7 +147,7 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
const warnings = []
const information = []
const theme = new LayoutConfig(json, true)
const theme = new LayoutConfig(json, this._isBuiltin)
{
// Legacy format checks
@ -168,7 +168,7 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
}
}
}
{
if(this._isBuiltin) {
// Check images: are they local, are the licenses there, is the theme icon square, ...
const images = new ExtractImages(
this._isBuiltin,
@ -224,6 +224,8 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
}
try {
if(this._isBuiltin){
if (theme.id !== theme.id.toLowerCase()) {
errors.push("Theme ids should be in lowercase, but it is " + theme.id)
}
@ -250,6 +252,7 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
warnings,
information
)
}
const dups = Utils.Dupiclates(json.layers.map((layer) => layer["id"]))
if (dups.length > 0) {
errors.push(
@ -298,7 +301,7 @@ export class ValidateThemeAndLayers extends Fuse<LayoutConfigJson> {
super(
"Validates a theme and the contained layers",
new ValidateTheme(doesImageExist, path, isBuiltin, sharedTagRenderings),
new On("layers", new Each(new ValidateLayer(undefined, false, doesImageExist)))
new On("layers", new Each(new ValidateLayer(undefined, isBuiltin, doesImageExist)))
)
}
}
@ -506,7 +509,7 @@ export class DetectShadowedMappings extends DesugaringStep<QuestionableTagRender
{}
)} is fully matched by a previous mapping (namely ${j}), which matches:
${parsedConditions[j].asHumanString(false, false, {})}.
To fix this problem, you can try to:
- Move the shadowed mapping up
- Do you want to use a different text in 'question mode'? Add 'hideInAnswer=true' to the first mapping
@ -700,7 +703,7 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> {
}
try {
{
if(this._isBuiltin) {
// Some checks for legacy elements
if (json["overpassTags"] !== undefined) {
@ -747,7 +750,7 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> {
warnings.push(context + " has a tagRendering as `isShown`")
}
}
{
if(this._isBuiltin) {
// Check location of layer file
const expected: string = `assets/layers/${json.id}/${json.id}.json`
if (this._path != undefined && this._path.indexOf(expected) < 0) {
@ -795,6 +798,7 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> {
}
}
}
if (json.tagRenderings !== undefined) {
const r = new On(
"tagRenderings",

View file

@ -122,7 +122,7 @@ export default class ScriptUtils {
return root.svg
}
public static async ReadSvgSync(path: string, callback: (svg: any) => void): Promise<any> {
public static ReadSvgSync(path: string, callback: (svg: any) => void): any {
xml2js.parseString(readFileSync(path, "UTF8"), { async: false }, (err, root) => {
if (err) {
throw err