// @ts-check const Sentry = require('@sentry/node') const { default: axios } = require('axios') const { log, errors } = require('cozy-konnector-libs') const API_URL = 'https://apicarto.ign.fr/api/codes-postaux/communes' /** * Return inseeCode given a postalCode * @param {string} postalCode * @param {string} [city] * @return {Promise<string>} inseeCode */ async function getInseeCode(postalCode, city) { try { log('info', `Query getInseeCode for postalCode ${postalCode} / ${city}`) const response = await axios.get(`${API_URL}/${postalCode}`) if (response.data.length === 1) { return response.data[0].codeCommune } else { if (!city) throw new Error('No city') const parsedCity = sanitizeCity(city) const filteredResponse = response.data.filter(commune => sanitizeCity(commune.nomCommune).includes(parsedCity) ) if (filteredResponse.length === 1) { return filteredResponse[0].codeCommune } if (filteredResponse.length > 1) { // Try to get the same length of the city input for (const commune of filteredResponse) { if (commune.nomCommune.length === city.length) { return commune.codeCommune } } } throw new Error('No match could be found') } } catch (error) { const errorMessage = `Query getInseeCode failed for postalCode ${postalCode} / ${city}` log('error', errorMessage) Sentry.captureException(errorMessage) throw errors.USER_ACTION_NEEDED } } /** * Clean city input and remove all characters such as (^, ¨, ʼ, ', -, é, è) * @param {string} city * @return {string} parsedCity */ function sanitizeCity(city) { return city .toLowerCase() .replace(/\bst\b/i, 'saint') .replace(/[âêîôûäëïöü-\sʼ'’éàèç]/g, match => REPLACE_CHARS[match]) .trim() } const REPLACE_CHARS = { â: 'a', ê: 'e', î: 'i', ô: 'o', û: 'u', ä: 'a', ë: 'e', ï: 'i', ö: 'o', ü: 'u', '-': '', ' ': '', ʼ: '', "'": '', '’': '', é: 'e', à: 'a', è: 'e', ç: 'c', } module.exports = { getInseeCode, }