From 4766f8bbdec6a4f94a640484dbf8dba66028789d Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sat, 10 Apr 2021 03:50:44 +0200 Subject: [PATCH] More validation and fixes --- Customizations/AllKnownLayers.ts | 83 +++------------- Customizations/AllKnownLayouts.ts | 109 ++++++--------------- Customizations/JSON/LayerConfig.ts | 2 +- Customizations/JSON/TagRenderingConfig.ts | 3 + UI/BigComponents/AttributionPanel.ts | 1 - UI/BigComponents/MoreScreen.ts | 8 +- UI/i18n/Translation.ts | 20 ++-- assets/themes/fruit_trees/fruit_trees.json | 10 +- index.ts | 8 +- package-lock.json | 74 ++++++++++++++ package.json | 9 +- preferences.ts | 10 +- scripts/generateLayerOverview.ts | 62 ++++++------ 13 files changed, 192 insertions(+), 207 deletions(-) diff --git a/Customizations/AllKnownLayers.ts b/Customizations/AllKnownLayers.ts index ba5795d..ae059e5 100644 --- a/Customizations/AllKnownLayers.ts +++ b/Customizations/AllKnownLayers.ts @@ -1,90 +1,35 @@ -import * as drinkingWater from "../assets/layers/drinking_water/drinking_water.json"; -import * as ghostbikes from "../assets/layers/ghost_bike/ghost_bike.json" -import * as viewpoint from "../assets/layers/viewpoint/viewpoint.json" -import * as bike_parking from "../assets/layers/bike_parking/bike_parking.json" -import * as bike_repair_station from "../assets/layers/bike_repair_station/bike_repair_station.json" -import * as birdhides from "../assets/layers/bird_hide/birdhides.json" -import * as nature_reserve from "../assets/layers/nature_reserve/nature_reserve.json" -import * as bike_cafes from "../assets/layers/bike_cafe/bike_cafes.json" -import * as bike_monitoring_station from "../assets/layers/bike_monitoring_station/bike_monitoring_station.json" -import * as cycling_themed_objects from "../assets/layers/cycling_themed_object/cycling_themed_objects.json" -import * as bike_shops from "../assets/layers/bike_shop/bike_shop.json" -import * as bike_cleaning from "../assets/layers/bike_cleaning/bike_cleaning.json" -import * as bicycle_library from "../assets/layers/bicycle_library/bicycle_library.json" -import * as bicycle_tube_vending_machine from "../assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json" -import * as maps from "../assets/layers/maps/maps.json" -import * as information_boards from "../assets/layers/information_board/information_board.json" -import * as direction from "../assets/layers/direction/direction.json" -import * as surveillance_camera from "../assets/layers/surveillance_cameras/surveillance_cameras.json" -import * as toilets from "../assets/layers/toilets/toilets.json" -import * as bookcases from "../assets/layers/public_bookcases/public_bookcases.json" -import * as tree_nodes from "../assets/layers/trees/tree_nodes.json" -import * as benches from "../assets/layers/benches/benches.json" -import * as benches_at_pt from "../assets/layers/benches/benches_at_pt.json" -import * as picnic_tables from "../assets/layers/benches/picnic_tables.json" -import * as play_forest from "../assets/layers/play_forest/play_forest.json" -import * as playground from "../assets/layers/playground/playground.json" -import * as sport_pitch from "../assets/layers/sport_pitch/sport_pitch.json" -import * as slow_roads from "../assets/layers/slow_roads/slow_roads.json" import LayerConfig from "./JSON/LayerConfig"; import {LayerConfigJson} from "./JSON/LayerConfigJson"; -import * as grass_in_parks from "../assets/layers/village_green/grass_in_parks.json" -import * as village_green from "../assets/layers/village_green/village_green.json" +import * as known_layers from "../assets/generated/known_layers_and_themes.json" +import {Utils} from "../Utils"; export default class AllKnownLayers { - private static sharedLayersListRaw : LayerConfigJson[] = [ - drinkingWater, - ghostbikes, - viewpoint, - bike_parking, - bike_repair_station, - bike_monitoring_station, - birdhides, - nature_reserve, - bike_cafes, - bicycle_library, - cycling_themed_objects, - bike_shops, - bike_cleaning, - bicycle_tube_vending_machine, - maps, - direction, - information_boards, - toilets, - bookcases, - surveillance_camera, - tree_nodes, - benches, - benches_at_pt, - picnic_tables, - play_forest, - playground, - sport_pitch, - slow_roads, - grass_in_parks, - village_green - ]; - // Must be below the list... public static sharedLayers: Map = AllKnownLayers.getSharedLayers(); public static sharedLayersJson: Map = AllKnownLayers.getSharedLayersJson(); - + private static sharedLayersListRaw: LayerConfigJson[] = known_layers.layers; private static getSharedLayers(): Map { const sharedLayers = new Map(); - for (const layer of AllKnownLayers.sharedLayersListRaw) { - const parsed = new LayerConfig(layer, "shared_layers") - sharedLayers.set(layer.id, parsed); - sharedLayers[layer.id] = parsed; + for (const layer of known_layers.layers) { + try { + const parsed = new LayerConfig(layer, "shared_layers") + sharedLayers.set(layer.id, parsed); + sharedLayers[layer.id] = parsed; + } catch (e) { + if (!Utils.runningFromConsole) { + console.error("CRITICAL: Could not parse a layer configuration!", layer.id, " due to", e) + } + } } return sharedLayers; } private static getSharedLayersJson(): Map { const sharedLayers = new Map(); - for (const layer of AllKnownLayers.sharedLayersListRaw) { + for (const layer of known_layers.layers) { sharedLayers.set(layer.id, layer); sharedLayers[layer.id] = layer; } diff --git a/Customizations/AllKnownLayouts.ts b/Customizations/AllKnownLayouts.ts index 488c21c..8acc177 100644 --- a/Customizations/AllKnownLayouts.ts +++ b/Customizations/AllKnownLayouts.ts @@ -1,74 +1,29 @@ -import * as bookcases from "../assets/themes/bookcases/Bookcases.json"; -import * as aed from "../assets/themes/aed/aed.json"; -import * as toilets from "../assets/themes/toilets/toilets.json"; -import * as artworks from "../assets/themes/artwork/artwork.json"; -import * as cyclestreets from "../assets/themes/cyclestreets/cyclestreets.json"; -import * as ghostbikes from "../assets/themes/ghostbikes/ghostbikes.json" -import * as cyclofix from "../assets/themes/cyclofix/cyclofix.json" -import * as buurtnatuur from "../assets/themes/buurtnatuur/buurtnatuur.json" -import * as nature from "../assets/themes/nature/nature.json" -import * as maps from "../assets/themes/maps/maps.json" -import * as shops from "../assets/themes/shops/shops.json" -import * as bike_monitoring_stations from "../assets/themes/bike_monitoring_station/bike_monitoring_stations.json" -import * as fritures from "../assets/themes/fritures/fritures.json" -import * as benches from "../assets/themes/benches/benches.json"; -import * as charging_stations from "../assets/themes/charging_stations/charging_stations.json" -import * as widths from "../assets/themes/widths/width.json" -import * as drinking_water from "../assets/themes/drinking_water/drinking_water.json" -import * as climbing from "../assets/themes/climbing/climbing.json" -import * as surveillance_cameras from "../assets/themes/surveillance_cameras/surveillance_cameras.json" -import * as trees from "../assets/themes/trees/trees.json" -import * as personal from "../assets/themes/personalLayout/personalLayout.json" -import * as playgrounds from "../assets/themes/playgrounds/playgrounds.json" -import * as bicycle_lib from "../assets/themes/bicycle_library/bicycle_library.json" -import * as campersites from "../assets/themes/campersites/campersites.json" -import * as play_forests from "../assets/themes/play_forests/play_forests.json" -import * as speelplekken from "../assets/themes/speelplekken/speelplekken.json" -import * as sport_pitches from "../assets/themes/sport_pitches/sport_pitches.json" -import * as grb from "../assets/themes/grb.json" -import * as facadegardens from "../assets/themes/facadegardens/facadegardens.json" -import LayerConfig from "./JSON/LayerConfig"; import LayoutConfig from "./JSON/LayoutConfig"; import AllKnownLayers from "./AllKnownLayers"; +import * as known_themes from "../assets/generated/known_layers_and_themes.json" +import {LayoutConfigJson} from "./JSON/LayoutConfigJson"; export class AllKnownLayouts { - public static allLayers: Map = undefined; - public static layoutsList: LayoutConfig[] = [ - new LayoutConfig(personal), - AllKnownLayouts.GenerateCycloFix(), - new LayoutConfig(aed), - new LayoutConfig(bookcases), - new LayoutConfig(toilets), - new LayoutConfig(artworks), - new LayoutConfig(ghostbikes), - new LayoutConfig(shops), - new LayoutConfig(drinking_water), - new LayoutConfig(nature), - new LayoutConfig(cyclestreets), - new LayoutConfig(bicycle_lib), - new LayoutConfig(maps), - new LayoutConfig(fritures), - new LayoutConfig(benches), - new LayoutConfig(charging_stations), - new LayoutConfig(widths), - new LayoutConfig(buurtnatuur), - new LayoutConfig(bike_monitoring_stations), - new LayoutConfig(surveillance_cameras), - new LayoutConfig(climbing), - new LayoutConfig(playgrounds), - new LayoutConfig(trees), - new LayoutConfig(campersites), - new LayoutConfig(play_forests), - new LayoutConfig(speelplekken), - new LayoutConfig(sport_pitches), - new LayoutConfig(grb), - new LayoutConfig(facadegardens) - ]; - public static allSets: Map = AllKnownLayouts.AllLayouts(); - private static GenerateCycloFix(): LayoutConfig { - const layout = new LayoutConfig(cyclofix) + public static allKnownLayouts: Map = AllKnownLayouts.AllLayouts(); + public static layoutsList: LayoutConfig[] = AllKnownLayouts.GenerateOrderedList(AllKnownLayouts.allKnownLayouts); + + private static GenerateOrderedList(allKnownLayouts: Map): LayoutConfig[] { + const keys = ["personal", "cyclofix", "bookcases", "toilets", "aed"] + const list = [] + for (const key of keys) { + list.push(allKnownLayouts.get(key)) + } + allKnownLayouts.forEach((layout, key) => { + if (keys.indexOf(key) < 0) { + list.push(layout) + } + }) + return list; + } + + private static AddGhostBikes(layout: LayoutConfig): LayoutConfig { const now = new Date(); const m = now.getMonth() + 1; const day = new Date().getDate() + 1; @@ -86,8 +41,15 @@ export class AllKnownLayouts { } private static AllLayouts(): Map { - this.allLayers = new Map(); - for (const layout of this.layoutsList) { + const dict: Map = new Map(); + for (const layoutConfigJson of known_themes.themes) { + const layout = new LayoutConfig(layoutConfigJson, true) + + if (layout.id === "cyclofix") { + AllKnownLayouts.AddGhostBikes(layout) + } + dict.set(layout.id, layout) + for (let i = 0; i < layout.layers.length; i++) { let layer = layout.layers[i]; if (typeof (layer) === "string") { @@ -98,20 +60,9 @@ export class AllKnownLayouts { } } - if (this.allLayers[layer.id] !== undefined) { - continue; - } - this.allLayers[layer.id] = layer; - this.allLayers[layer.id.toLowerCase()] = layer; } } - - const allSets: Map = new Map(); - for (const layout of this.layoutsList) { - allSets[layout.id] = layout; - allSets[layout.id.toLowerCase()] = layout; - } - return allSets; + return dict; } } diff --git a/Customizations/JSON/LayerConfig.ts b/Customizations/JSON/LayerConfig.ts index d304448..0577c6d 100644 --- a/Customizations/JSON/LayerConfig.ts +++ b/Customizations/JSON/LayerConfig.ts @@ -7,6 +7,7 @@ import {TagRenderingConfigJson} from "./TagRenderingConfigJson"; import {Translation} from "../../UI/i18n/Translation"; import Img from "../../UI/Base/Img"; import Svg from "../../Svg"; + import {Utils} from "../../Utils"; import Combine from "../../UI/Base/Combine"; import {VariableUiElement} from "../../UI/Base/VariableUIElement"; @@ -18,7 +19,6 @@ import SourceConfig from "./SourceConfig"; import {TagsFilter} from "../../Logic/Tags/TagsFilter"; import {Tag} from "../../Logic/Tags/Tag"; import SubstitutingTag from "../../Logic/Tags/SubstitutingTag"; - export default class LayerConfig { diff --git a/Customizations/JSON/TagRenderingConfig.ts b/Customizations/JSON/TagRenderingConfig.ts index 9dc92f7..05661b7 100644 --- a/Customizations/JSON/TagRenderingConfig.ts +++ b/Customizations/JSON/TagRenderingConfig.ts @@ -90,6 +90,9 @@ export default class TagRenderingConfig { this.multiAnswer = json.multiAnswer ?? false if (json.mappings) { + if(!Array.isArray(json.mappings)){ + throw "Tagrendering has a 'mappings'-object, but expected a list ("+context+")" + } this.mappings = json.mappings.map((mapping, i) => { diff --git a/UI/BigComponents/AttributionPanel.ts b/UI/BigComponents/AttributionPanel.ts index 9767e35..30b2fd4 100644 --- a/UI/BigComponents/AttributionPanel.ts +++ b/UI/BigComponents/AttributionPanel.ts @@ -34,7 +34,6 @@ export default class AttributionPanel extends Combine { } private static IconAttribution(iconPath: string) { - console.log("Attribution panel for ", iconPath) if (iconPath.startsWith("http")) { iconPath = "." + new URL(iconPath).pathname; } diff --git a/UI/BigComponents/MoreScreen.ts b/UI/BigComponents/MoreScreen.ts index 6fe0524..e5b0361 100644 --- a/UI/BigComponents/MoreScreen.ts +++ b/UI/BigComponents/MoreScreen.ts @@ -85,16 +85,12 @@ export default class MoreScreen extends UIElement { const linkButton: UIElement[] = [] - for (const k in AllKnownLayouts.allSets) { - const layout: LayoutConfig = AllKnownLayouts.allSets[k]; - if (k === personal.id) { + for (const layout of AllKnownLayouts.layoutsList) { + if (layout.id === personal.id) { if (State.state.osmConnection.userDetails.data.csCount < Constants.userJourney.personalLayoutUnlock) { continue; } } - if (layout.id !== k) { - continue; // This layout was added multiple time due to an uppercase - } linkButton.push(this.createLinkButton(layout)); } diff --git a/UI/i18n/Translation.ts b/UI/i18n/Translation.ts index cf0ca8f..279b0a9 100644 --- a/UI/i18n/Translation.ts +++ b/UI/i18n/Translation.ts @@ -19,6 +19,9 @@ export class Translation extends UIElement { let count = 0; for (const translationsKey in translations) { count++; + if(typeof(translations[translationsKey]) != "string"){ + throw "Error in an object depicting a translation: a non-string object was found. ("+context+")\n You probably put some other section accidentally in the translation" + } } this.translations = translations; if (count === 0) { @@ -134,12 +137,17 @@ export class Translation extends UIElement { } else { // We are running this in ts-node (~= nodejs), and can not access document // So, we fallback to simple regex - const matches = render.match(/]+>/g) - if (matches != null) { - const sources = matches.map(img => img.match(/src=("[^"]+"|'[^']+'|[^/ ]+)/)) - .filter(match => match != null) - .map(match => match[1].trim().replace(/^['"]/, '').replace(/['"]$/, '')); - allIcons.push(...sources) + try { + const matches = render.match(/]+>/g) + if (matches != null) { + const sources = matches.map(img => img.match(/src=("[^"]+"|'[^']+'|[^/ ]+)/)) + .filter(match => match != null) + .map(match => match[1].trim().replace(/^['"]/, '').replace(/['"]$/, '')); + allIcons.push(...sources) + } + }catch(e){ + console.error("Could not search for images: ", render, this.txt) + throw e } } } diff --git a/assets/themes/fruit_trees/fruit_trees.json b/assets/themes/fruit_trees/fruit_trees.json index 5bf1401..d6a2e6b 100644 --- a/assets/themes/fruit_trees/fruit_trees.json +++ b/assets/themes/fruit_trees/fruit_trees.json @@ -28,11 +28,12 @@ "nl": "Boomgaarden" }, "minzoom": 12, - "overpassTags": { + "source":{ + "osmTags": { "and": [ "landuse=orchard" ] - }, + } }, "title": { "render": { "nl": "Boomgaard" @@ -73,11 +74,12 @@ "nl": "Boom" }, "minzoom": 12, - "overpassTags": { + "source":{ + "osmTags": { "and": [ "natural=tree" ] - }, + }}, "title": { "render": { "nl": "Boom" diff --git a/index.ts b/index.ts index 111f92a..d145cd1 100644 --- a/index.ts +++ b/index.ts @@ -52,7 +52,7 @@ if (location.hostname === "localhost" || location.hostname === "127.0.0.1") { } -// ----------------- SELECT THE RIGHT QUESTSET ----------------- +// ----------------- SELECT THE RIGHT Theme ----------------- const path = window.location.pathname.split("/").slice(-1)[0]; @@ -64,7 +64,7 @@ if (path !== "index.html" && path !== "") { console.log("Using layout", defaultLayout); } defaultLayout = QueryParameters.GetQueryParameter("layout", defaultLayout, "The layout to load into MapComplete").data; -let layoutToUse: LayoutConfig = AllKnownLayouts.allSets[defaultLayout.toLowerCase()]; +let layoutToUse: LayoutConfig = AllKnownLayouts.allKnownLayouts.get(defaultLayout.toLowerCase()); const userLayoutParam = QueryParameters.GetQueryParameter("userlayout", "false"); @@ -81,7 +81,7 @@ if (layoutFromBase64.startsWith("http")) { $.ajax({ url: link, - success: function (data) { + success: (data) => { try { const parsed = JSON.parse(data); @@ -121,6 +121,6 @@ if (layoutFromBase64.startsWith("http")) { .SetStyle("pointer-events: all;") .AttachTo("topleft-tools"); } -window.addEventListener('contextmenu', function (e) { // Not compatible with IE < 9 +window.addEventListener('contextmenu', (e) => { // Not compatible with IE < 9 e.preventDefault(); }, false); diff --git a/package-lock.json b/package-lock.json index 95c2c2e..304c00f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4731,6 +4731,11 @@ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -11611,6 +11616,75 @@ } } }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "tslint-no-circular-imports": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/tslint-no-circular-imports/-/tslint-no-circular-imports-0.7.0.tgz", + "integrity": "sha512-k3wxpeMC4ef40UbpfBVHEHIzKfNZq5/SCtAO1YjGsaNTklo+K53/TWLrym+poA65RJFDiYgYNWvkeIIkJNA0Vw==", + "dev": true + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "requires": { + "tslib": "^1.8.1" + } + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", diff --git a/package.json b/package.json index 2904b96..6052e73 100644 --- a/package.json +++ b/package.json @@ -8,20 +8,23 @@ "main": "index.js", "scripts": { "increase-memory": "export NODE_OPTIONS=--max_old_space_size=4096", - "start": "npm run increase-memory && parcel *.html UI/** Logic/** assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*", + "start": "ts-node scripts/generateLayerOverview.ts && npm run increase-memory && parcel *.html UI/** Logic/** assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*", "test": "ts-node test/Tag.spec.ts && ts-node test/TagQuestion.spec.ts && ts-node test/ImageSearcher.spec.ts && ts-node test/ImageAttribution.spec.ts", "generate:editor-layer-index": "cd assets/ && wget https://osmlab.github.io/editor-layer-index/imagery.geojson --output-document=editor-layer-index.json", "generate:images": "ts-node scripts/generateIncludedImages.ts", "generate:translations": "ts-node scripts/generateTranslations.ts", "generate:layouts": "ts-node scripts/generateLayouts.ts", "generate:docs": "ts-node scripts/generateDocs.ts", + "generate:layeroverview": "ts-node scripts/generateLayerOverview.ts", + "generate:licenses": "ts-node scripts/generateLicenseInfo.ts", "optimize-images": "cd assets/generated/ && find -name '*.png' -exec optipng '{}' \\; && echo 'PNGs are optimized'", "generate": "npm run generate:images && npm run generate:translations", "build": "rm -rf dist/ && npm run generate && parcel build --public-url ./ *.html assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*", - "prepare-deploy": "npm run test && npm run generate:editor-layer-index && npm run generate:layouts && npm run generate && npm run build && rm -rf .cache && npm run generate:docs", + "prepare-deploy": "npm run test && npm run generate:editor-layer-index && npm run generate:layouts && npm run generate:layeroverview && npm run generate && npm run build && rm -rf .cache && npm run generate:docs", "deploy:staging": "npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/Staging/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/Staging/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", "deploy:pietervdvn": "npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/MapComplete/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/MapComplete/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", "deploy:production": "rm -rf ./assets/generated && npm run prepare-deploy && npm run optimize-images && rm -rf /home/pietervdvn/git/mapcomplete.github.io/* && cp -r dist/* /home/pietervdvn/git/mapcomplete.github.io/ && cd /home/pietervdvn/git/mapcomplete.github.io/ && echo \"mapcomplete.osm.be\" > CNAME && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", + "lint": "tslint --project . -c tslint.json '**.ts' ", "clean": "rm -rf .cache/ && (find *.html | grep -v \"\\(index\\|land\\|test\\|preferences\\|customGenerator\\).html\" | xargs rm) && rm *.webmanifest" }, "keywords": [ @@ -64,6 +67,7 @@ "sharp": "^0.27.0", "slick-carousel": "^1.8.1", "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.2", + "tslint": "^6.1.3", "turf": "^3.0.14" }, "devDependencies": { @@ -76,6 +80,7 @@ "read-file": "^0.2.0", "ts-node": "^9.0.0", "ts-node-dev": "^1.0.0-pre.63", + "tslint-no-circular-imports": "^0.7.0", "turndown": "^7.0.0", "typescript": "^3.9.7", "write-file": "^1.0.0" diff --git a/preferences.ts b/preferences.ts index b297432..5343444 100644 --- a/preferences.ts +++ b/preferences.ts @@ -17,9 +17,7 @@ function createTable(preferences: any) { } rendered = true; const prefs = []; - console.log(preferences); for (const key in preferences) { - console.log(key) const pref = connection.GetPreference(key, ""); let value: UIElement = new FixedUiElement(pref.data); @@ -36,19 +34,17 @@ function createTable(preferences: any) { "", new Button("delete", () => pref.setData("")), "", - value, + value, "" ]; prefs.push(...c); } - const el = new Combine( + new Combine( ["", ...prefs, "
"] - ); // .AttachTo("maindiv"); - console.log(el.InnerRender()) - el.AttachTo("maindiv"); + ).AttachTo("maindiv"); } connection.preferencesHandler.preferences.addCallback((prefs) => createTable(prefs)) diff --git a/scripts/generateLayerOverview.ts b/scripts/generateLayerOverview.ts index 66dc6ef..f9de21c 100644 --- a/scripts/generateLayerOverview.ts +++ b/scripts/generateLayerOverview.ts @@ -8,6 +8,7 @@ import {error} from "util"; import * as licenses from "../assets/generated/license_info.json" import SmallLicense from "../Models/smallLicense"; import LayoutConfig from "../Customizations/JSON/LayoutConfig"; +import {LayerConfigJson} from "../Customizations/JSON/LayerConfigJson"; // This scripts scans 'assets/layers/*.json' for layer definition files and 'assets/themes/*.json' for theme definition files. // It spits out an overview of those to be used to load them @@ -28,7 +29,7 @@ const layerFiles = ScriptUtils.readDirRecSync("./assets/layers") console.error("Could not parse file ", path, "due to ", e) } }) -const themeFiles : any[] = ScriptUtils.readDirRecSync("./assets/themes") +const themeFiles: any[] = ScriptUtils.readDirRecSync("./assets/themes") .filter(path => path.indexOf(".json") > 0) .filter(path => path.indexOf("license_info.json") < 0) .map(path => { @@ -49,57 +50,62 @@ for (const i in licenses) { } const knownPaths = new Set(licensePaths) -function validateLayer(layer: LayerConfig, context?:string) : number{ +function validateLayer(layerJson: LayerConfigJson, context?: string): number { let errorCount = 0; - const images = Array.from(layer.ExtractImages()) - const remoteImages = images.filter(img => img.indexOf("http") == 0) - for (const remoteImage of remoteImages) { - console.error("Found a remote image:", remoteImage, "in layer", layer.id) + if (layerJson["overpassTags"] !== undefined) { errorCount++ + console.error("CRIT! Layer ", layerJson.id, "still uses the old 'overpassTags'-format. Please use 'source: {osmTags: }' instead") } - for (const image of images) { - if (!knownPaths.has(image)) { - console.error("Image with path", image, "not found or not attributed; it is used in", layer.id, context === undefined ? "" : ` in a layer defined in the theme ${context}`) + try { + const layer = new LayerConfig(layerJson, "test", true) + const images = Array.from(layer.ExtractImages()) + const remoteImages = images.filter(img => img.indexOf("http") == 0) + for (const remoteImage of remoteImages) { + console.error("Found a remote image:", remoteImage, "in layer", layer.id) errorCount++ } + for (const image of images) { + if (!knownPaths.has(image)) { + console.error("Image with path", image, "not found or not attributed; it is used in", layer.id, context === undefined ? "" : ` in a layer defined in the theme ${context}`) + errorCount++ + } + } + + } catch (e) { + console.error("Layer ", layerJson.id ?? JSON.stringify(layerJson).substring(0, 50), " is invalid: ", e) + return 1 } return errorCount } + let layerErrorCount = 0 const knownLayerIds = new Set(); for (const layerFile of layerFiles) { knownLayerIds.add(layerFile.id) - try { - const layer = new LayerConfig(layerFile, "test", true) - layerErrorCount += validateLayer(layer) - } catch (e) { - console.error("Layer ", layerFile.id, " is invalid: ", e) - layerErrorCount++ - } - if (layerFile.overpassTags !== undefined) { - layerErrorCount++ - console.warn("Layer ", layerFile.id, "still uses the old 'overpassTags'-format. Please use 'source: {osmTags: }' instead") - } + layerErrorCount += validateLayer(layerFile) } let themeErrorCount = 0 for (const themeFile of themeFiles) { for (const layer of themeFile.layers) { - if(typeof layer === "string"){ - if(!knownLayerIds.has(layer)){ + if (typeof layer === "string") { + if (!knownLayerIds.has(layer)) { console.error("Unknown layer id: ", layer) themeErrorCount++ } + }else if(layer.builtin === undefined){ + // layer.builtin contains layer overrides - we can skip those + layerErrorCount += validateLayer(layer, themeFile.id) } } - + themeFile.layers = themeFile.layers.filter(l => typeof l != "string") - + try { - const layout = new LayoutConfig(themeFile, true, "test") - for (const layer of layout.layers) { - layerErrorCount += validateLayer(layer, layout.id) + const theme = new LayoutConfig(themeFile, true, "test") + if(theme.id !== theme.id.toLowerCase()){ + console.error("Theme ids should be in lowercase, but it is ", theme.id) } } catch (e) { console.error("Could not parse theme", themeFile["id"], "due to", e) @@ -107,4 +113,4 @@ for (const themeFile of themeFiles) { } } -console.log("Found ", layerErrorCount, "errors in the layers; "+themeErrorCount+" errors in the themes") \ No newline at end of file +console.log("Found ", layerErrorCount, "errors in the layers; " + themeErrorCount + " errors in the themes") \ No newline at end of file