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