wikimedica-disease-search/app/src/data/model.js

129 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @module
* Définit le modèle de données utilisé par lapplication.
*/
import PropTypes from 'prop-types';
/**
* Types de termes existants.
*/
export const termTypes = {
disease: 'Maladie',
symptom: 'Symptôme',
sign: 'Signe',
};
/**
* Crée un valideur de type de propriété React supportant lextension
* `.isRequired` pour marquer une propriété comme requise.
*
* @param basicValidator Fonction basique de validation.
* @return Fonction augmentée supportant lextension `.isRequired`.
*/
const makePropType = basicValidator =>
{
const validator = (props, propName, componentName) =>
{
// Version optionnelle : on nappelle le valideur que si la propriété a
// été passée
if (propName in props)
{
return basicValidator(props, propName, componentName);
}
};
validator.isRequired = (props, propName, componentName) =>
{
// Version obligatoire : on jette une erreur si la propriété na pas
// été passée puis on procède à la validation
if (!(propName in props))
{
return new Error(
`Missing prop “${propName}” in props supplied to `
+ `${componentName}.`
);
}
return basicValidator(props, propName, componentName);
};
return validator;
};
/**
* Type de terme.
*/
export const TermType = PropTypes.oneOf(Object.values(termTypes));
/**
* URL.
*/
const URL = makePropType((props, propName, componentName) =>
{
const value = props[propName];
if (typeof value !== 'string')
{
return new Error(
`URL passed as ${componentName}s ${propName} prop must be `
+ `a string, not a ${typeof value}.`
);
}
if (!value.startsWith('http://') && !value.startsWith('https://'))
{
return new Error(
`URL “${value}”, passed as ${componentName}s ${propName} `
+ 'prop, does not start with “http://” or “https://”.'
);
}
});
/**
* Terme.
*
* Peut être une maladie, un symptôme ou un signe.
*/
export const Term = PropTypes.exact({
// Identifiant unique
id: PropTypes.string.isRequired,
// Nom canonique
name: PropTypes.string.isRequired,
// Noms alternatifs
alias: PropTypes.arrayOf(PropTypes.string).isRequired,
// Types (maladie, symptôme, signe)
types: PropTypes.arrayOf(TermType).isRequired,
// Facteur dimportance
weight: PropTypes.number.isRequired,
// Adresse de la ressource de référence
url: URL.isRequired,
});
/**
* Relation entre deux termes.
*/
export const Relation = makePropType((props, propName) =>
{
const value = props[propName];
if (!Array.isArray(value))
{
return new Error(
`Relation ${propName} must be an array.`
);
}
if (value.length !== 2)
{
return new Error(
`Relation ${propName} must contain exactly two entries.`
);
}
});