// @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) { throw new Error( 'Input city is not precise enough, more than one city was found' ) } return filteredResponse[0].codeCommune } } 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, }