UNPKG

astro-loader-i18n

Version:

An Astro content loader for i18n files and folder structures.

271 lines (269 loc) 8.85 kB
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