diff --git a/Logic/DetermineLayout.ts b/Logic/DetermineLayout.ts index 85da45e2bb..206c8e4c1c 100644 --- a/Logic/DetermineLayout.ts +++ b/Logic/DetermineLayout.ts @@ -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(), _ => 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, diff --git a/Models/ThemeConfig/Conversion/Validation.ts b/Models/ThemeConfig/Conversion/Validation.ts index d7d2acd098..0a996e10ae 100644 --- a/Models/ThemeConfig/Conversion/Validation.ts +++ b/Models/ThemeConfig/Conversion/Validation.ts @@ -147,7 +147,7 @@ class ValidateTheme extends DesugaringStep { 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 { } } } - { + 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 { } 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 { 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 { 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 { } try { - { + if(this._isBuiltin) { // Some checks for legacy elements if (json["overpassTags"] !== undefined) { @@ -747,7 +750,7 @@ export class ValidateLayer extends DesugaringStep { 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 { } } } + if (json.tagRenderings !== undefined) { const r = new On( "tagRenderings", diff --git a/scripts/ScriptUtils.ts b/scripts/ScriptUtils.ts index 21d7079aeb..6dc454c55b 100644 --- a/scripts/ScriptUtils.ts +++ b/scripts/ScriptUtils.ts @@ -122,7 +122,7 @@ export default class ScriptUtils { return root.svg } - public static async ReadSvgSync(path: string, callback: (svg: any) => void): Promise { + public static ReadSvgSync(path: string, callback: (svg: any) => void): any { xml2js.parseString(readFileSync(path, "UTF8"), { async: false }, (err, root) => { if (err) { throw err