Add some typehints to the models
This commit is contained in:
parent
046902a139
commit
3679814664
6 changed files with 343 additions and 7 deletions
|
@ -141,6 +141,8 @@ export interface LayerConfigJson {
|
||||||
* If not specified, the OsmLink and wikipedia links will be used by default.
|
* If not specified, the OsmLink and wikipedia links will be used by default.
|
||||||
* Use an empty array to hide them.
|
* Use an empty array to hide them.
|
||||||
* Note that "defaults" will insert all the default titleIcons (which are added automatically)
|
* Note that "defaults" will insert all the default titleIcons (which are added automatically)
|
||||||
|
*
|
||||||
|
* Type: icon[]
|
||||||
*/
|
*/
|
||||||
titleIcons?: (string | TagRenderingConfigJson)[] | ["defaults"];
|
titleIcons?: (string | TagRenderingConfigJson)[] | ["defaults"];
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ export interface LayoutConfigJson {
|
||||||
credits?: string;
|
credits?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Who does maintian this preset?
|
* Who does maintain this preset?
|
||||||
*/
|
*/
|
||||||
maintainer: string;
|
maintainer: string;
|
||||||
|
|
||||||
|
@ -74,13 +74,17 @@ export interface LayoutConfigJson {
|
||||||
* The icon representing this theme.
|
* The icon representing this theme.
|
||||||
* Used as logo in the more-screen and (for official themes) as favicon, webmanifest logo, ...
|
* Used as logo in the more-screen and (for official themes) as favicon, webmanifest logo, ...
|
||||||
* Either a URL or a base64 encoded value (which should include 'data:image/svg+xml;base64)
|
* Either a URL or a base64 encoded value (which should include 'data:image/svg+xml;base64)
|
||||||
|
*
|
||||||
|
* Type: icon
|
||||||
*/
|
*/
|
||||||
icon: string;
|
icon: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link to a 'social image' which is included as og:image-tag on official themes.
|
* Link to a 'social image' which is included as og:image-tag on official themes.
|
||||||
* Useful to share the theme on social media.
|
* Useful to share the theme on social media.
|
||||||
* See https://www.h3xed.com/web-and-internet/how-to-use-og-image-meta-tag-facebook-reddit for more information
|
* See https://www.h3xed.com/web-and-internet/how-to-use-og-image-meta-tag-facebook-reddit for more information$
|
||||||
|
*
|
||||||
|
* Type: image
|
||||||
*/
|
*/
|
||||||
socialImage?: string;
|
socialImage?: string;
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@ export default interface PointRenderingConfigJson {
|
||||||
* As a result, on could use a generic pin, then overlay it with a specific icon.
|
* As a result, on could use a generic pin, then overlay it with a specific icon.
|
||||||
* To make things even more practical, one can use all SVG's from the folder "assets/svg" and _substitute the color_ in it.
|
* To make things even more practical, one can use all SVG's from the folder "assets/svg" and _substitute the color_ in it.
|
||||||
* E.g. to draw a red pin, use "pin:#f00", to have a green circle with your icon on top, use `circle:#0f0;<path to my icon.svg>`
|
* E.g. to draw a red pin, use "pin:#f00", to have a green circle with your icon on top, use `circle:#0f0;<path to my icon.svg>`
|
||||||
*
|
|
||||||
|
* Type: icon
|
||||||
*/
|
*/
|
||||||
icon?: string | TagRenderingConfigJson;
|
icon?: string | TagRenderingConfigJson;
|
||||||
|
|
||||||
|
@ -36,7 +37,13 @@ export default interface PointRenderingConfigJson {
|
||||||
*
|
*
|
||||||
* Note: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle
|
* Note: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle
|
||||||
*/
|
*/
|
||||||
iconBadges?: { if: string | AndOrTagConfigJson, then: string | TagRenderingConfigJson }[]
|
iconBadges?: { if: string | AndOrTagConfigJson,
|
||||||
|
/**
|
||||||
|
* Badge to show
|
||||||
|
* Type: icon
|
||||||
|
*/
|
||||||
|
then: string | TagRenderingConfigJson
|
||||||
|
}[]
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -108,6 +108,7 @@ export interface TagRenderingConfigJson {
|
||||||
then: string | any,
|
then: string | any,
|
||||||
/**
|
/**
|
||||||
* An icon supporting this mapping; typically shown pretty small
|
* An icon supporting this mapping; typically shown pretty small
|
||||||
|
* Type: icon
|
||||||
*/
|
*/
|
||||||
icon?: string
|
icon?: string
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,6 +2,105 @@ import ScriptUtils from "./ScriptUtils";
|
||||||
import {readFileSync, writeFileSync} from "fs";
|
import {readFileSync, writeFileSync} from "fs";
|
||||||
|
|
||||||
|
|
||||||
|
interface JsonSchema {
|
||||||
|
description?: string,
|
||||||
|
type?: string,
|
||||||
|
properties?: any,
|
||||||
|
items?: JsonSchema | JsonSchema[],
|
||||||
|
anyOf: JsonSchema[],
|
||||||
|
enum: JsonSchema[],
|
||||||
|
"$ref": string
|
||||||
|
}
|
||||||
|
|
||||||
|
function WalkScheme<T>(
|
||||||
|
onEach: (schemePart: JsonSchema) => T,
|
||||||
|
scheme: JsonSchema,
|
||||||
|
registerSchemePath = false,
|
||||||
|
fullScheme: JsonSchema & { definitions?: any } = undefined,
|
||||||
|
path: string[] = [],
|
||||||
|
isHandlingReference = []
|
||||||
|
): { path: string[], t: T }[] {
|
||||||
|
const results: { path: string[], t: T } [] = []
|
||||||
|
if (scheme === undefined) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
if (scheme["$ref"] !== undefined) {
|
||||||
|
const ref = scheme["$ref"]
|
||||||
|
const prefix = "#/definitions/"
|
||||||
|
if (!ref.startsWith(prefix)) {
|
||||||
|
throw "References is not relative!"
|
||||||
|
}
|
||||||
|
const definitionName = ref.substr(prefix.length)
|
||||||
|
if (isHandlingReference.indexOf(definitionName) >= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const loadedScheme = fullScheme.definitions[definitionName]
|
||||||
|
return WalkScheme(onEach, loadedScheme, registerSchemePath, fullScheme, path, [...isHandlingReference, definitionName]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fullScheme = fullScheme ?? scheme
|
||||||
|
var t = onEach(scheme)
|
||||||
|
|
||||||
|
function walk(v: JsonSchema, pathPart: string) {
|
||||||
|
if (v === undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(registerSchemePath){
|
||||||
|
path.push("" + pathPart)
|
||||||
|
}
|
||||||
|
results.push(...WalkScheme(onEach, v, registerSchemePath, fullScheme, path, isHandlingReference))
|
||||||
|
if(registerSchemePath){
|
||||||
|
path.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function walkEach(scheme: JsonSchema[], pathPart: string) {
|
||||||
|
if (scheme === undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(registerSchemePath){
|
||||||
|
path.push("" + pathPart)
|
||||||
|
}
|
||||||
|
scheme.forEach((v, i) => walk(v, "" + i))
|
||||||
|
if(registerSchemePath){
|
||||||
|
path.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t !== undefined) {
|
||||||
|
results.push({
|
||||||
|
path: [...path],
|
||||||
|
t
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
walkEach(scheme.enum, "enum")
|
||||||
|
walkEach(scheme.anyOf, "anyOf")
|
||||||
|
if (scheme.items !== undefined) {
|
||||||
|
|
||||||
|
if (scheme.items["forEach"] !== undefined) {
|
||||||
|
walkEach(<any>scheme.items, "items")
|
||||||
|
} else {
|
||||||
|
walk(<any>scheme.items, "items")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(registerSchemePath){
|
||||||
|
path.push("properties")
|
||||||
|
}
|
||||||
|
for (const key in scheme.properties) {
|
||||||
|
const prop = scheme.properties[key]
|
||||||
|
path.push(key)
|
||||||
|
results.push(...WalkScheme(onEach, prop, registerSchemePath, fullScheme, path, isHandlingReference))
|
||||||
|
path.pop()
|
||||||
|
}
|
||||||
|
if(registerSchemePath){
|
||||||
|
path.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
|
|
||||||
const allSchemas = ScriptUtils.readDirRecSync("./Docs/Schemas").filter(pth => pth.endsWith("JSC.ts"))
|
const allSchemas = ScriptUtils.readDirRecSync("./Docs/Schemas").filter(pth => pth.endsWith("JSC.ts"))
|
||||||
|
@ -20,9 +119,23 @@ function main() {
|
||||||
def["additionalProperties"] = false
|
def["additionalProperties"] = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFileSync(dir + "/" + name + ".schema.json", JSON.stringify(parsed, null, " "), "UTF8")
|
writeFileSync(dir + "/" + name + ".schema.json", JSON.stringify(parsed, null, " "), "UTF8")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const themeSchema = JSON.parse(readFileSync("./Docs/Schemas/LayoutConfigJson.schema.json", "UTF-8"))
|
||||||
|
const withTypes =WalkScheme((schemePart) => {
|
||||||
|
if (schemePart.description === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const type = schemePart.description.split("\n").filter(line => line.trim().toLocaleLowerCase().startsWith("type: "))[0]
|
||||||
|
if (type === undefined) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return {typeHint: type.substr("type: ".length), type: schemePart.type ?? schemePart.anyOf}
|
||||||
|
}, themeSchema)
|
||||||
|
|
||||||
|
// writeFileSync("./assets/layoutconfigmeta.json",JSON.stringify(withTypes.map(({path, t}) => ({path, ...t})), null, " "))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -4,6 +4,7 @@ import LayoutConfig from "../Models/ThemeConfig/LayoutConfig";
|
||||||
import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson";
|
import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson";
|
||||||
import {TagRenderingConfigJson} from "../Models/ThemeConfig/Json/TagRenderingConfigJson";
|
import {TagRenderingConfigJson} from "../Models/ThemeConfig/Json/TagRenderingConfigJson";
|
||||||
import {AddMiniMap} from "../Models/ThemeConfig/Conversion/PrepareTheme";
|
import {AddMiniMap} from "../Models/ThemeConfig/Conversion/PrepareTheme";
|
||||||
|
import FixRemoteLinks from "../Models/ThemeConfig/Conversion/FixRemoteLinks";
|
||||||
|
|
||||||
export default class LegacyThemeLoaderSpec extends T {
|
export default class LegacyThemeLoaderSpec extends T {
|
||||||
|
|
||||||
|
@ -142,6 +143,215 @@ export default class LegacyThemeLoaderSpec extends T {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly organic_waste_theme = {
|
||||||
|
"id": "recycling-organic",
|
||||||
|
"title": {
|
||||||
|
"nl": "Inzamelpunt organisch alval"
|
||||||
|
},
|
||||||
|
"shortDescription": {
|
||||||
|
"nl": "Inzamelpunt organisch alval"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"nl": "Op deze kaart vindt u inzamelpunten voor organisch afval. Beheer deze naar goeddunken en vermogen."
|
||||||
|
},
|
||||||
|
"language": [
|
||||||
|
"nl"
|
||||||
|
],
|
||||||
|
"maintainer": "",
|
||||||
|
"icon": "https://upload.wikimedia.org/wikipedia/commons/1/15/Compost_…able_waste_-_biodegradable_waste_-_biological_waste_icon.png",
|
||||||
|
"version": "0",
|
||||||
|
"startLat": 0,
|
||||||
|
"startLon": 0,
|
||||||
|
"startZoom": 1,
|
||||||
|
"widenFactor": 0.05,
|
||||||
|
"socialImage": "",
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"id": "recycling-organic",
|
||||||
|
"name": {
|
||||||
|
"nl": "Inzamelpunt organisch alval"
|
||||||
|
},
|
||||||
|
"minzoom": 12,
|
||||||
|
"title": {
|
||||||
|
"render": {
|
||||||
|
"nl": "Inzamelpunt organisch alval"
|
||||||
|
},
|
||||||
|
"mappings": [
|
||||||
|
{
|
||||||
|
"if": {
|
||||||
|
"and": [
|
||||||
|
"name~*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"then": {
|
||||||
|
"nl": "{name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"allowMove": true,
|
||||||
|
"deletion": {},
|
||||||
|
"tagRenderings": [
|
||||||
|
"images",
|
||||||
|
{
|
||||||
|
"freeform": {
|
||||||
|
"key": "opening_hours",
|
||||||
|
"type": "opening_hours",
|
||||||
|
"addExtraTags": []
|
||||||
|
},
|
||||||
|
"question": {
|
||||||
|
"nl": "Wat zijn de openingsuren?"
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"nl": "{opening_hours_table()}"
|
||||||
|
},
|
||||||
|
"mappings": [
|
||||||
|
{
|
||||||
|
"if": {
|
||||||
|
"and": [
|
||||||
|
"opening_hours=\"by appointment\""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"then": {
|
||||||
|
"nl": "Op afspraak"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id": "Composthoekjes-opening_hours"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"question": {
|
||||||
|
"nl": "Wat is de website voor meer informatie?"
|
||||||
|
},
|
||||||
|
"freeform": {
|
||||||
|
"key": "website",
|
||||||
|
"type": "url"
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"nl": "<a href=\"{website}\">{website}</a>"
|
||||||
|
},
|
||||||
|
"id": "Composthoekjes-website"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"question": {
|
||||||
|
"nl": "Wat is het type inzamelpunt?"
|
||||||
|
},
|
||||||
|
"mappings":[
|
||||||
|
{
|
||||||
|
"if":"recycling_type=container",
|
||||||
|
"then":"Container of vat"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if":"recycling_type=centre",
|
||||||
|
"then":"Verwerkingsplaats of containerpark"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if":"recycling_type=dump",
|
||||||
|
"then":"Composthoop"
|
||||||
|
}
|
||||||
|
|
||||||
|
],
|
||||||
|
"id": "Composthoekjes-type"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"question": {
|
||||||
|
"nl": "Wie mag hier organisch afval bezorgen?"
|
||||||
|
},
|
||||||
|
"mappings":[
|
||||||
|
{
|
||||||
|
"if":"access=yes",
|
||||||
|
"then":"Publiek toegankelijk"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if":"access=no",
|
||||||
|
"then":"Privaat"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if":"access=permessive",
|
||||||
|
"then":"Mogelijks toegelaten tot nader order"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if":"access=",
|
||||||
|
"then":"Waarschijnlijk publiek toegankelijk",
|
||||||
|
"hideInAnswer":true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if":"access=residents",
|
||||||
|
"then":"Bewoners van gemeente",
|
||||||
|
"hideInAnswer":"recycling_type!=centre"
|
||||||
|
}
|
||||||
|
|
||||||
|
],
|
||||||
|
"id": "Composthoekjes-voor-wie"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"question": {
|
||||||
|
"nl": "Wat is de naam van dit compost-inzamelpunt?"
|
||||||
|
},
|
||||||
|
"freeform": {
|
||||||
|
"key": "name",
|
||||||
|
"addExtraTags": ["noname="]
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"nl": "De naam van dit compost-inzamelpunt is {name}"
|
||||||
|
},
|
||||||
|
"mappings":[
|
||||||
|
{
|
||||||
|
"if":{"and":["noname=yes","name="]},
|
||||||
|
"then":"Heeft geen naam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if":"name=",
|
||||||
|
"then":"Geen naam bekend",
|
||||||
|
"hideInAnswer":true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id": "Composthoekjes-name"
|
||||||
|
}],
|
||||||
|
"presets": [
|
||||||
|
{
|
||||||
|
"tags": [
|
||||||
|
"amenity=recycling",
|
||||||
|
"recycling:organic=yes"
|
||||||
|
],
|
||||||
|
"title": {
|
||||||
|
"nl": "een inzamelpunt voor organisch afval"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": {
|
||||||
|
"osmTags": {
|
||||||
|
"and": [
|
||||||
|
"recycling:organic~*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapRendering": [
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"render": "circle:white;https://upload.wikimedia.org/wikipedia/commons/1/15/Compost_…able_waste_-_biodegradable_waste_-_biological_waste_icon.png"
|
||||||
|
},
|
||||||
|
"iconSize": {
|
||||||
|
"render": "40,40,center"
|
||||||
|
},
|
||||||
|
"location": [
|
||||||
|
"point"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": {
|
||||||
|
"render": "#00f"
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"render": "8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super([
|
super([
|
||||||
["Walking_node_theme", () => {
|
["Walking_node_theme", () => {
|
||||||
|
@ -201,8 +411,7 @@ export default class LegacyThemeLoaderSpec extends T {
|
||||||
render: "Some random value {minimap}"
|
render: "Some random value {minimap}"
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}]
|
||||||
]
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue