wuchale
Version:
Protobuf-like i18n from plain code
58 lines (57 loc) • 2 kB
JavaScript
import { compile, match } from "path-to-regexp";
export const localizeDefault = (url, loc) => {
const localized = `/${loc}${url}`;
if (!localized.endsWith('/')) {
return localized;
}
return localized.slice(0, -1);
};
export const getLocaleDefault = (url, locales) => {
let iSecondSlash = url.pathname.indexOf('/', 2);
if (iSecondSlash === -1) {
iSecondSlash = url.pathname.length;
}
const locale = url.pathname.slice(1, iSecondSlash);
if (locales.includes(locale)) {
return locale;
}
return null;
};
const getParams = (path, pattern) => {
const matched = match(pattern, { decode: false })(path);
if (!matched) {
return;
}
return matched.params;
};
export const fillParams = (params, destPattern) => {
const compiled = compile(destPattern, { encode: false });
return compiled(params);
};
export function URLMatcher(manifest, locales) {
const manifestWithLocales = manifest.map(([pattern, localized]) => {
const locAndLocalizeds = locales.map((loc, i) => [loc, localized[i]]);
return [
pattern,
locAndLocalizeds,
Object.fromEntries(locAndLocalizeds),
];
});
return (url) => {
for (const [pattern, locAndLocalizeds, altPatterns] of manifestWithLocales) {
for (const [locale, locPattern] of locAndLocalizeds) {
const params = getParams(url.pathname, locPattern);
if (params) {
return { path: fillParams(params, pattern), locale, params, altPatterns };
}
}
}
for (const [pattern, , altPatterns] of manifestWithLocales) {
const params = getParams(url.pathname, pattern);
if (params) {
return { path: fillParams(params, pattern), locale: null, params, altPatterns };
}
}
return { path: null, locale: null, altPatterns: {}, params: {} };
};
}