Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions lib/build.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import chalk from 'chalk';
import fs from 'fs';
import { globSync } from 'glob';
import jsonschema from 'jsonschema';
import { Validator } from 'jsonschema';
import path from 'path';
import shell from 'shelljs';
import YAML from 'js-yaml';
Expand All @@ -21,6 +21,8 @@ const discardedSchema = require('../schemas/discarded.json');

let _currBuild = null;

const jsonschema = new Validator();

function validateData(options) {
const START = '🔬 ' + chalk.yellow('Validating schema...');
const END = '👍 ' + chalk.green('schema okay');
Expand Down Expand Up @@ -203,6 +205,9 @@ function read(f) {


function validateSchema(file, instance, schema) {
// add this schema to the cache, so $ref can be resolved faster
jsonschema.addSchema(schema);

let validationErrors = jsonschema.validate(instance, schema).errors;

if (validationErrors.length) {
Expand Down Expand Up @@ -362,6 +367,15 @@ function generatePresets(dataDir, tstrings, searchableFieldIDs, listReusedIcons)
if (!icons[icon]) icons[icon] = [];
icons[icon].push(id);
}

if (preset.relation) {
tstrings.presets[id].relation_roles = {};
for (const member of preset.relation.members) {
for (const role in member.roles) {
tstrings.presets[id].relation_roles[role] = member.roles[role];
}
}
}
});

if (listReusedIcons) {
Expand Down Expand Up @@ -454,8 +468,10 @@ function generateTranslations(fields, presets, tstrings, searchableFieldIDs) {
let tags = preset.tags || {};
let keys = Object.keys(tags);

const tagsString = keys.map(k => `${k}=${tags[k]}`).join(' + ');

if (keys.length) {
yamlPreset['#name'] = keys.map(k => `${k}=${tags[k]}`).join(' + ');
yamlPreset['#name'] = tagsString;
if (yamlPreset.aliases) {
yamlPreset['#name'] += ' | ' + yamlPreset.aliases.split('\n').join(', ');
}
Expand All @@ -466,6 +482,12 @@ function generateTranslations(fields, presets, tstrings, searchableFieldIDs) {
yamlPreset['#name'] += ` | Local preset for countries ${preset.locationSet.include.map(country => `"${country.toUpperCase()}"`).join(', ')}`;
}

if (yamlPreset.relation_roles) {
for (const role in yamlPreset.relation_roles) {
yamlPreset.relation_roles[`#${role}`] = `Relation role “${role}” when used with ${tagsString}`;
}
}

if (preset.searchable !== false) {
if (yamlPreset.terms) {
yamlPreset['#terms'] = 'terms: ' + yamlPreset.terms;
Expand Down
11 changes: 8 additions & 3 deletions schemas/field.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"enum": ["point", "vertex", "line", "area", "relation"]
"$ref": "#/$defs/Geometry"
}
},
"default": {
Expand Down Expand Up @@ -294,5 +293,11 @@
{ "required": ["keys"] }
]}
]}
]
],
"$defs": {
"Geometry": {
"type": "string",
"enum": ["point", "vertex", "line", "area", "relation"]
}
}
}
80 changes: 79 additions & 1 deletion schemas/preset.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,86 @@
}
},
"additionalProperties": false
},
"relation": {
"$ref": "#/$defs/RelationSchema"
},
"relationCrossReference": {
"description": "A preset can reference the relation schema from another preset",
"type": "string",
"pattern": "^\\{.+\\}$"
}
},
"additionalProperties": false,
"required": ["name", "geometry", "tags"]
"required": ["name", "geometry", "tags"],
"$defs": {
"RelationSchema": {
"type": "object",
"properties": {
"optionalTags": {
"type": "object",
"description": "Only useful for specifying placeholders which are referenced in members.*.matchTags",
"examples": [{ "route": "$1" }],
"additionalProperties": {
"type": "string"
}
},
"id": {
"type": "string",
"description": "The “permanent relation type ID”, this should match the value of https://osm.wiki/Property:P41 in the OSM wiki’s wikibase system."
},
"allowDuplicateMembers": {
"type": "boolean",
"default": true
},
"members": {
"type": "array",
"items": {
"type": "object",
"properties": {
"roles": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Map of roles to their label in the default language. An empty string is allowed as key."
},
"geometry": {
"type": "array",
"items": {
"$ref": "field.json#/$defs/Geometry"
},
"description": "If not specified, any geometry is allowed"
},
"matchTags": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"examples": [
[{ "a": 1, "b": 2 }],
[{ "a": 1 }, { "b": 2 }]
],
"description": "`*` can be used as a tag value. If multiple array items are specified, only 1 needs to match."
},
"min": {
"type": "integer",
"description": "If unspecified, there is no minimum"
},
"max": {
"type": "integer",
"description": "If unspecified, there is no maximum"
}
},
"additionalProperties": false
}
}
},
"required": ["id", "allowDuplicateMembers", "members"],
"additionalProperties": false
}
}
}