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
43 changes: 39 additions & 4 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,30 @@
}
}

// Check that no field with a fallbackKey has its fallback field also explicitly listed,
// and that fallbackKey references are valid fields
let allPresetFieldIDs = new Set([
...(preset.fields || []),
...(preset.moreFields || [])
]);
for (let fieldID of allPresetFieldIDs) {
let field = fields[fieldID];
if (!field?.fallbackKey) continue;

let fallbackField = fields[field.fallbackKey];
if (!fallbackField) {
process.stderr.write('Unknown fallback field "' + field.fallbackKey + '" referenced by field "' + fieldID + '" in preset "' + presetID + '" (' + preset.name + ')\n');
process.stdout.write('\n');
process.exit(1);
}

if (allPresetFieldIDs.has(field.fallbackKey)) {
process.stderr.write('The preset "' + presetID + '" includes repeated field "' + field.fallbackKey + '" already implicitly included by field "' + fieldID + '" as a fallback field\n');
process.stdout.write('\n');
process.exit(1);
}
}

if (preset.fields) {
// since `moreFields` is available, check that `fields` doesn't get too cluttered
let fieldCount = preset.fields.length;
Expand All @@ -966,12 +990,23 @@
}
}
}

for (let fieldID in fields) {
let field = fields[fieldID];

if (!usedFieldIDs.has(fieldID) &&
fields[fieldID].universal !== true &&
(fields[fieldID].usage || 'preset') === 'preset') {
process.stdout.write('Field "' + fields[fieldID].label + '" (' + fieldID + ') isn\'t used by any presets.\n');
field.universal !== true &&
(field.usage || 'preset') === 'preset') {
process.stdout.write('Field "' + field.label + '" (' + fieldID + ') isn\'t used by any presets.\n');
}

if (field.fallbackKey) {
let fallbackField = fields[field.fallbackKey];
if (fallbackField?.fallbackKey) {
process.stderr.write('Field "' + field.fallbackKey + '" is used as a fallback by field "' + fieldID + '" but itself has a fallbackKey "' + fallbackField.fallbackKey + '". Recursive fallback fields are not allowed.\n');
process.stdout.write('\n');
process.exit(1);
}
}
}
}
Expand All @@ -980,7 +1015,7 @@
if (!terms) return;

const expectedTerms = terms.map(term => term.toLowerCase().trim()).sort();
if (terms.every((term, index) => expectedTerms[index] === term)) return;

Check warning on line 1018 in lib/build.js

View workflow job for this annotation

GitHub Actions / build (22)

Trailing spaces not allowed

Check warning on line 1018 in lib/build.js

View workflow job for this annotation

GitHub Actions / build (24)

Trailing spaces not allowed

process.stderr.write(`Expected terms in ${where} to be lowercase and sorted alphabetically.`);
process.stdout.write('\n');
Expand Down
9 changes: 7 additions & 2 deletions schemas/field.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"roadheight",
"roadspeed",
"schedule",
"segregatedCombo",
"semiCombo",
"structureRadio",
"tel",
Expand Down Expand Up @@ -210,6 +211,10 @@
"minimum": 1,
"type": "integer"
},
"fallbackKey": {
"description": "The field that is shown instead when this field's visibility requirements are not met",
"type": "string"
},
"prerequisiteTag": {
"description": "Tagging constraint for showing this field in the editor",
"oneOf": [
Expand Down Expand Up @@ -379,9 +384,9 @@
{ "not": { "required": ["keys"] }}
]},
{ "$id": "field-type-with-key-optional-keys", "properties": { "type": { "enum": ["email", "url", "tel", "text", "number"] } }, "required": ["key"] },
{ "$id": "field-type-with-key-and-keys", "properties": { "type": { "enum": ["address", "wikipedia", "wikidata", "directionalCombo"] } }, "required": ["key", "keys"] },
{ "$id": "field-type-with-key-and-keys", "properties": { "type": { "enum": ["address", "wikipedia", "wikidata", "directionalCombo", "segregatedCombo"] } }, "required": ["key", "keys"] },
{ "$id": "field-type-with-key-or-keys", "allOf": [
{ "not": { "properties": { "type": { "enum": ["restriction", "email", "url", "tel", "text", "number", "address", "wikipedia", "wikidata", "directionalCombo"] } } } },
{ "not": { "properties": { "type": { "enum": ["restriction", "email", "url", "tel", "text", "number", "address", "wikipedia", "wikidata", "directionalCombo", "segregatedCombo"] } } } },
{ "oneOf": [
{ "required": ["key"] },
{ "required": ["keys"] }
Expand Down