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