astro-loader-i18n
Version:
An Astro content loader for i18n files and folder structures.
199 lines (197 loc) • 6.63 kB
JavaScript
import { glob as b } from "astro/loaders";
import { z as f } from "astro/zod";
const y = /^\/|\/$/g, S = /^\.{0,2}\/|\/$/g, N = /\.{2}/g, R = /\/{2}/g, m = /\/[^/]+$/g, T = "index", A = (e) => new RegExp(`(?<=[./])${e}(?=[./])`, "i");
function j(...e) {
return e.filter(Boolean).join("/");
}
function p(...e) {
const a = e.map((t) => typeof t == "string" ? t.replace(y, "") : t);
return `/${j(...a)}`;
}
const O = (e) => e === "/" ? e : e.replace(y, ""), $ = (e) => e === "/" ? e : e.replace(S, ""), _ = (e, a, t) => {
var s;
const n = A(`(${a.join("|")})`), o = (s = e.match(n)) == null ? void 0 : s[0];
return o || t;
}, h = (e, a) => (a && (e = e.replace(A(a), "")), e = e.replace(N, "."), e = e.replace(R, "/"), e = O(e), e === "" || e === "/" ? T : e), v = (e, a, t) => {
let n = a ? a instanceof URL ? a.pathname : a : void 0;
if (n) {
n = $(n);
const o = e.indexOf(n);
e = o !== -1 ? e.slice(o + n.length) : e;
}
return e = h(e, t), e.includes(T) && (e = e.replace(m, "")), e = e.includes("/") ? e.replace(m, "") : "", e;
};
function q(e) {
const a = b(e);
return {
name: "i18n-loader",
load: async (t) => {
if (!t.config.i18n) throw new Error("i18n configuration is missing in your astro config");
const { locales: n, defaultLocale: o } = t.config.i18n, s = n.flatMap((r) => typeof r == "string" ? r : r.codes), i = t.parseData, P = (r) => {
if (!r.filePath) return i(r);
const c = _(r.filePath, s, o), l = h(r.filePath, c), u = v(r.filePath, e.base, c), d = t.config.base;
return i({ ...r, data: { ...r.data, locale: c, translationId: l, contentPath: u, basePath: d } });
};
t.parseData = P, await a.load(t);
}
};
}
function I(e, a = /* @__PURE__ */ new Set()) {
return Object.entries(e).forEach(([t, n]) => {
a.add(t), n && typeof n == "object" && !Array.isArray(n) && I(n, a);
}), a;
}
function g(e, a, t) {
const n = {};
for (const [o, s] of Object.entries(e))
if (Array.isArray(s))
n[o] = s.map((i) => i && typeof i == "object" && !Array.isArray(i) ? g(i, a, t) : i);
else if (s && typeof s == "object") {
const i = s, P = Object.keys(i).some((c) => a.includes(c));
let r;
P ? r = i[t] ?? void 0 : r = g(i, a, t), n[o] = r;
} else
n[o] = s;
return n;
}
function C(e, a, t) {
if (Object.keys(e).find((n) => a.includes(n))) throw new Error("Top-level locales are not allowed");
return Object.keys(e).length === 0 ? e : g(e, a, t);
}
const M = "und";
function K(e) {
const a = b(e);
return {
name: "i18n-content-loader",
load: async (t) => {
if (!t.config.i18n) throw new Error("i18n configuration is missing in your astro config");
const { locales: n } = t.config.i18n, o = n.flatMap((r) => typeof r == "string" ? r : r.codes), s = t.parseData, i = (r) => {
if (!r.filePath) return s(r);
const c = M, l = h(r.filePath), u = v(r.filePath, e.base), d = t.config.base;
return s({ ...r, data: { ...r.data, locale: c, translationId: l, contentPath: u, basePath: d } });
};
t.parseData = i, await a.load(t);
const P = t.store.entries();
t.store.clear(), P.forEach(([, r]) => {
const c = Array.from(I(r.data)).filter((l) => o.includes(l));
c.length === 0 ? t.store.set(r) : c.forEach((l) => {
const u = C(r.data, c, l);
t.store.set({ ...r, id: `${r.id}/${l}`, data: { ...u, locale: l } });
});
});
}
};
}
const X = (e, a, t) => {
const n = () => f.object(
a.reduce(
(s, i) => (s[i] = e, s),
{}
)
);
return (t ? n().partial() : n()).or(e);
}, w = f.object({
translationId: f.string(),
locale: f.string(),
contentPath: f.string(),
basePath: f.string()
}), F = (e) => w.merge(e), U = f.object({
data: w,
filePath: f.string().optional()
}), k = f.array(U);
function B(e) {
const a = k.safeParse(e);
if (!a.success)
throw new Error(
`Invalid collection entry was provided to astro-i18n-loader. Did you forget to use "extendI18nLoaderSchema" to extend the schema in your "content.config.js" definition? Validation failed with:
${a.error}`
);
}
function W(e) {
const a = e.split("/").filter((t) => t !== "").map((t) => t.startsWith("[") && t.endsWith("]") ? {
spread: t.startsWith("[..."),
param: !0,
value: t.replace("[", "").replace("...", "").replace("]", "")
} : {
spread: !1,
param: !1,
value: t
});
return a.length === 0 ? [{ spread: !1, param: !1, value: "/" }] : a;
}
function L(e, a, t) {
return p(
t,
...e.map((n) => {
var o;
if (n.param) {
if (!a[n.value] && !n.spread)
throw new Error(`No segment value found for route segment "${n.value}". Did you forget to provide it?`);
if ((o = a[n.value]) != null && o.includes("/") && !n.spread)
throw new Error(
`The segment value "${a[n.value]}" for route segment "${n.value}" contains a slash. Did you forget to add "..." to the route pattern?`
);
return a[n.value];
}
return `${n.value}`;
})
);
}
const z = {
localeParamName: "locale",
prefixDefaultLocale: !1,
generateSegments: () => ({})
};
function E(e, a) {
const { data: t } = e;
if (!a.segmentTranslations[t.locale]) throw new Error(`No slugs found for locale ${t.locale}`);
const n = !a.prefixDefaultLocale && t.locale === a.defaultLocale ? void 0 : t.locale;
return {
[a.localeParamName]: n,
...a.segmentTranslations[t.locale],
...a.generateSegments(e)
};
}
function D(e, a) {
B(e);
const { routePattern: t, ...n } = { ...z, ...a }, o = W(t);
return e.map((s) => {
const { translationId: i } = s.data, r = e.filter((u) => u.data.translationId === i).reduce(
(u, d) => ({
...u,
[d.data.locale]: L(o, E(d, n), d.data.basePath)
}),
{}
), c = E(s, n), l = L(o, c, s.data.basePath);
return {
params: c,
props: {
...s,
translations: r,
translatedPath: l
}
};
});
}
function G(e, a) {
return D(e, a);
}
function J(e, a) {
return D(e, a).map(({ props: t }) => t);
}
function Q(e) {
const { locales: a, routePattern: t, basePath: n } = e;
return a.map((o) => ({ data: { locale: o, translationId: t, contentPath: "", basePath: n || "" } }));
}
export {
Q as createI18nCollection,
F as extendI18nLoaderSchema,
K as i18nContentLoader,
q as i18nLoader,
w as i18nLoaderSchema,
J as i18nProps,
G as i18nPropsAndParams,
X as localized,
p as resolvePath
};
//# sourceMappingURL=astro-loader-i18n.js.map