Skip to content

Commit

Permalink
formatted useLocalesMap error and added additional checks
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinpolitov committed Mar 14, 2023
1 parent 4222517 commit 54c6a1e
Showing 1 changed file with 54 additions and 13 deletions.
67 changes: 54 additions & 13 deletions components/use-locales-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,64 @@ import { useRouter } from "next/router";
* @typedef {DefaultLocale | "zh-CN" | "es-ES" | "pt-BR" | "ja" | "ko" | "ru"} Locale
* @typedef {{locale?: Locale | undefined; locales?: Locale[] | undefined; defaultLocale?: DefaultLocale | undefined}} TypedRouter
* @typedef {Omit<import('next/router').NextRouter, "locale" | "locales" | "defaultLocale"> & TypedRouter} NextRouter
*/

/**
* @template T
* @type {(localesMap: Record<Locale, T>) => T}
*/
export default function useLocalesMap(localesMap) {
/** @type {NextRouter} */
const router = useRouter();
const { locale, defaultLocale } = router;
const { locale, locales, defaultLocale } = router;

if (!localesMap) {
throw new Error("Pass a locales map as argument to useLocalesMap");
throw new Error("Pass a locales map as argument to useLocalesMap hook.");
}

if (!isObject(localesMap)) {
throw new Error("Locales map must be an object");
if (typeof localesMap !== "object") {
localesMapError(
localesMap,
`Locales map must be an object, but you passed ${typeof localesMap}.`
);
}

if (Array.isArray(localesMap)) {
localesMapError(
localesMap,
"Locales map must be an object, but you passed an array."
);
}

if (!localesMap.hasOwnProperty(defaultLocale)) {
throw new Error(
localesMapError(
localesMap,
`Locales map must contain default locale "${defaultLocale}"`
);
}

if (
localesMap.hasOwnProperty(locale) &&
typeof localesMap[locale] !== typeof localesMap[defaultLocale]
) {
throw new Error(
`Invalid locales map: Shape of "${locale}" must be the same as "${defaultLocale}"`
);
for (const key in localesMap) {
if (!locales.includes(key)) {
const list = locales.map((l) => `"${l}"`).join(", ");

localesMapError(
localesMap,
`"${key}" is not a valid locale.`,
`Available locales are defined in "next.config.js": ${list}.`
);
}

if (typeof localesMap[key] !== typeof localesMap[defaultLocale]) {
localesMapError(
localesMap,
`Shape of "${key}" must be the same as "${defaultLocale}"`
);
}
}

if (["string", "number", "symbol"].includes(typeof localesMap[defaultLocale])) {
if (
["string", "number", "symbol"].includes(typeof localesMap[defaultLocale])
) {
return localesMap[locale] || localesMap[defaultLocale];
}

Expand Down Expand Up @@ -76,3 +103,17 @@ function mergeDeep(target, ...sources) {

return mergeDeep(target, ...sources);
}

/**
* Throw an error with a formatted message.
* @template T
* @param {Record<Locale, T>} localesMap
* @param {string[]} args
*/
export function localesMapError(localesMap, ...args) {
throw new Error(
["Invalid locales map", JSON.stringify(localesMap, null, 2), ...args].join(
"\n"
)
);
}

0 comments on commit 54c6a1e

Please sign in to comment.