mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-13 05:48:36 +03:00
Using prettier for linting
This commit is contained in:
@@ -1,64 +1,64 @@
|
||||
import Joi from 'joi'
|
||||
import Joi from "joi";
|
||||
|
||||
import createEventSchema from './eventSchema'
|
||||
import siteSchema from './siteSchema'
|
||||
import associationsSchema from './associationsSchema'
|
||||
import sourceSchema from './sourceSchema'
|
||||
import shapeSchema from './shapeSchema'
|
||||
import createEventSchema from "./eventSchema";
|
||||
import siteSchema from "./siteSchema";
|
||||
import associationsSchema from "./associationsSchema";
|
||||
import sourceSchema from "./sourceSchema";
|
||||
import shapeSchema from "./shapeSchema";
|
||||
|
||||
import { calcDatetime, capitalize } from '../../common/utilities'
|
||||
import { calcDatetime, capitalize } from "../../common/utilities";
|
||||
|
||||
/*
|
||||
* Create an error notification object
|
||||
* Types: ['error', 'warning', 'good', 'neural']
|
||||
*/
|
||||
function makeError (type, id, message) {
|
||||
function makeError(type, id, message) {
|
||||
return {
|
||||
type: 'error',
|
||||
type: "error",
|
||||
id,
|
||||
message: `${type} ${id}: ${message}`
|
||||
}
|
||||
message: `${type} ${id}: ${message}`,
|
||||
};
|
||||
}
|
||||
|
||||
function isValidDate (d) {
|
||||
return d instanceof Date && !isNaN(d)
|
||||
function isValidDate(d) {
|
||||
return d instanceof Date && !isNaN(d);
|
||||
}
|
||||
|
||||
function findDuplicateAssociations (associations) {
|
||||
const seenSet = new Set([])
|
||||
const duplicates = []
|
||||
function findDuplicateAssociations(associations) {
|
||||
const seenSet = new Set([]);
|
||||
const duplicates = [];
|
||||
associations.forEach((item) => {
|
||||
if (seenSet.has(item.id)) {
|
||||
duplicates.push({
|
||||
id: item.id,
|
||||
error: makeError(
|
||||
'Association',
|
||||
"Association",
|
||||
item.id,
|
||||
'association was found more than once. Ignoring duplicate.'
|
||||
)
|
||||
})
|
||||
"association was found more than once. Ignoring duplicate."
|
||||
),
|
||||
});
|
||||
} else {
|
||||
seenSet.add(item.id)
|
||||
seenSet.add(item.id);
|
||||
}
|
||||
})
|
||||
return duplicates
|
||||
});
|
||||
return duplicates;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate domain schema
|
||||
*/
|
||||
export function validateDomain (domain, features) {
|
||||
export function validateDomain(domain, features) {
|
||||
const sanitizedDomain = {
|
||||
events: [],
|
||||
sites: [],
|
||||
associations: [],
|
||||
sources: {},
|
||||
shapes: [],
|
||||
notifications: domain ? domain.notifications : null
|
||||
}
|
||||
notifications: domain ? domain.notifications : null,
|
||||
};
|
||||
|
||||
if (domain === undefined) {
|
||||
return sanitizedDomain
|
||||
return sanitizedDomain;
|
||||
}
|
||||
|
||||
const discardedDomain = {
|
||||
@@ -66,104 +66,105 @@ export function validateDomain (domain, features) {
|
||||
sites: [],
|
||||
associations: [],
|
||||
sources: [],
|
||||
shapes: []
|
||||
}
|
||||
shapes: [],
|
||||
};
|
||||
|
||||
function validateArrayItem (item, domainKey, schema) {
|
||||
const result = Joi.validate(item, schema)
|
||||
function validateArrayItem(item, domainKey, schema) {
|
||||
const result = Joi.validate(item, schema);
|
||||
if (result.error !== null) {
|
||||
const id = item.id || '-'
|
||||
const domainStr = capitalize(domainKey)
|
||||
const error = makeError(domainStr, id, result.error.message)
|
||||
const id = item.id || "-";
|
||||
const domainStr = capitalize(domainKey);
|
||||
const error = makeError(domainStr, id, result.error.message);
|
||||
|
||||
discardedDomain[domainKey].push(Object.assign(item, { error }))
|
||||
discardedDomain[domainKey].push(Object.assign(item, { error }));
|
||||
} else {
|
||||
sanitizedDomain[domainKey].push(item)
|
||||
sanitizedDomain[domainKey].push(item);
|
||||
}
|
||||
}
|
||||
|
||||
function validateArray (items, domainKey, schema) {
|
||||
function validateArray(items, domainKey, schema) {
|
||||
items.forEach((item) => {
|
||||
validateArrayItem(item, domainKey, schema)
|
||||
})
|
||||
validateArrayItem(item, domainKey, schema);
|
||||
});
|
||||
}
|
||||
|
||||
function validateObject (obj, domainKey, itemSchema) {
|
||||
function validateObject(obj, domainKey, itemSchema) {
|
||||
Object.keys(obj).forEach((key) => {
|
||||
const vl = obj[key]
|
||||
const result = Joi.validate(vl, itemSchema)
|
||||
const vl = obj[key];
|
||||
const result = Joi.validate(vl, itemSchema);
|
||||
if (result.error !== null) {
|
||||
const id = vl.id || '-'
|
||||
const domainStr = capitalize(domainKey)
|
||||
const id = vl.id || "-";
|
||||
const domainStr = capitalize(domainKey);
|
||||
discardedDomain[domainKey].push({
|
||||
...vl,
|
||||
error: makeError(domainStr, id, result.error.message)
|
||||
})
|
||||
error: makeError(domainStr, id, result.error.message),
|
||||
});
|
||||
} else {
|
||||
sanitizedDomain[domainKey][key] = vl
|
||||
sanitizedDomain[domainKey][key] = vl;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (!Array.isArray(features.CUSTOM_EVENT_FIELDS)) {
|
||||
features.CUSTOM_EVENT_FIELDS = []
|
||||
features.CUSTOM_EVENT_FIELDS = [];
|
||||
}
|
||||
|
||||
const eventSchema = createEventSchema(features.CUSTOM_EVENT_FIELDS)
|
||||
validateArray(domain.events, 'events', eventSchema)
|
||||
validateArray(domain.sites, 'sites', siteSchema)
|
||||
validateArray(domain.associations, 'associations', associationsSchema)
|
||||
validateObject(domain.sources, 'sources', sourceSchema)
|
||||
validateObject(domain.shapes, 'shapes', shapeSchema)
|
||||
const eventSchema = createEventSchema(features.CUSTOM_EVENT_FIELDS);
|
||||
validateArray(domain.events, "events", eventSchema);
|
||||
validateArray(domain.sites, "sites", siteSchema);
|
||||
validateArray(domain.associations, "associations", associationsSchema);
|
||||
validateObject(domain.sources, "sources", sourceSchema);
|
||||
validateObject(domain.shapes, "shapes", shapeSchema);
|
||||
|
||||
// NB: [lat, lon] array is best format for projecting into map
|
||||
sanitizedDomain.shapes = sanitizedDomain.shapes.map((shape) => ({
|
||||
name: shape.name,
|
||||
points: shape.items.map((coords) => coords.replace(/\s/g, '').split(','))
|
||||
}))
|
||||
points: shape.items.map((coords) => coords.replace(/\s/g, "").split(",")),
|
||||
}));
|
||||
|
||||
const duplicateAssociations = findDuplicateAssociations(domain.associations)
|
||||
const duplicateAssociations = findDuplicateAssociations(domain.associations);
|
||||
// Duplicated associations
|
||||
if (duplicateAssociations.length > 0) {
|
||||
sanitizedDomain.notifications.push({
|
||||
message: `Associations are required to be unique. Ignoring duplicates for now.`,
|
||||
message:
|
||||
"Associations are required to be unique. Ignoring duplicates for now.",
|
||||
items: duplicateAssociations,
|
||||
type: 'error'
|
||||
})
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
sanitizedDomain.associations = domain.associations
|
||||
sanitizedDomain.associations = domain.associations;
|
||||
|
||||
// append events with datetime and sort
|
||||
sanitizedDomain.events = sanitizedDomain.events.filter((event, idx) => {
|
||||
event.id = idx
|
||||
event.datetime = calcDatetime(event.date, event.time)
|
||||
event.id = idx;
|
||||
event.datetime = calcDatetime(event.date, event.time);
|
||||
if (!isValidDate(event.datetime)) {
|
||||
discardedDomain['events'].push({
|
||||
discardedDomain.events.push({
|
||||
...event,
|
||||
error: makeError(
|
||||
'events',
|
||||
"events",
|
||||
event.id,
|
||||
`Invalid date. It's been dropped, as otherwise timemap won't work as expected.`
|
||||
)
|
||||
})
|
||||
return false
|
||||
"Invalid date. It's been dropped, as otherwise timemap won't work as expected."
|
||||
),
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true
|
||||
})
|
||||
return true;
|
||||
});
|
||||
|
||||
sanitizedDomain.events.sort((a, b) => a.datetime - b.datetime)
|
||||
sanitizedDomain.events.sort((a, b) => a.datetime - b.datetime);
|
||||
|
||||
// Message the number of failed items in domain
|
||||
Object.keys(discardedDomain).forEach((disc) => {
|
||||
const len = discardedDomain[disc].length
|
||||
const len = discardedDomain[disc].length;
|
||||
if (len) {
|
||||
sanitizedDomain.notifications.push({
|
||||
message: `${len} invalid ${disc} not displayed.`,
|
||||
items: discardedDomain[disc],
|
||||
type: 'error'
|
||||
})
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return sanitizedDomain
|
||||
return sanitizedDomain;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user