UNPKG

@astrolicious/i18n

Version:

Yet another i18n integration for Astro with server and client utilities, type safety and translations built-in.

4 lines 6.54 kB
import{relative as $}from"node:path";import{fileURLToPath as N}from"node:url";import W from"@inox-tools/aik-route-config";import{defineIntegration as _,hasIntegration as Z,withPlugins as G}from"astro-integration-kit";import{AstroError as E}from"astro/errors";import{z as H}from"astro/zod";import{simpleSitemapAndIndex as M}from"sitemap";import{withoutTrailingSlash as B}from"ufo";import{normalizePath as J}from"vite";import{AstroError as v}from"astro/errors";var q=new Set(["404","500"]),A=o=>{let l=o;l.endsWith("/")&&(l=l.slice(0,-1));let m=l.split("/").pop()??"";return q.has(m)},k=o=>o.issues.map(m=>` ${m.path.join(".")} ${`${m.message}.`}`).join(` `),P=o=>new v(o,"Please open an issue on GitHub at https://github.com/astrolicious/i18n/issues"),w=({segments:o})=>`/${o.map(m=>m.map(c=>c.dynamic?`[${c.content}]`:c.content).join("")).join("/")}`,D=o=>o?Array.isArray(o)?o:Object.entries(o).map(([l,m])=>({locale:l,params:m})):[],j=(o,l)=>l.trailingSlash==="never"?o:l.build.format==="directory"&&!o.endsWith("/")?`${o}/`:o;function L(o,l,m,c){let{changefreq:g,priority:h,lastmod:b}=m,a=b?.toISOString(),f=(n,p)=>{if(!n.route)return[];let d=[],y=o.filter(t=>t.route&&t.route.pattern===n.route.pattern&&t.route.locale!==n.route.locale);if(d.push({lang:n.route.locale,url:p}),n.routeData.params.length===0){for(let t of y)d.push({lang:t.route.locale,url:j(`${new URL(p).origin}${t.route.injectedRoute.pattern}`,c)});return[...d].sort((t,u)=>t.lang.localeCompare(u.lang,"en",{numeric:!0}))}let e=n.pages.indexOf(p),s=n.sitemapOptions.filter(t=>t.dynamicParams&&(Array.isArray(t.dynamicParams)?t.dynamicParams:Object.entries(t.dynamicParams)).length>0)[e];if(!s||!s.dynamicParams)return[];for(let t of y){let u=D(s.dynamicParams).find(O=>O.locale===t.route.locale);if(!u)continue;let S=t.route.injectedRoute.pattern;for(let[O,C]of Object.entries(u.params)){if(!C)throw P("This situation should never occur (value is not set)");S=S.replace(`[${O}]`,C)}S=j(`${new URL(p).origin}${S}`,c),d.push({lang:t.route.locale,url:S})}return[...d].sort((t,u)=>t.lang.localeCompare(u.lang,"en",{numeric:!0}))},r=[];for(let n of o)for(let p of n.pages){let d=[];if(n.route){let e=f({...n,route:n.route},p);d.push(...e)}let y={url:p,links:d};g&&Object.assign(y,{changefreq:g}),a&&Object.assign(y,{lastmod:a}),h&&Object.assign(y,{priority:h}),r.push(y)}return[...r].sort((n,p)=>n.url.localeCompare(p.url,"en",{numeric:!0}))}import{z as i}from"astro/zod";import{EnumChangefreq as z}from"sitemap";var x=i.object({customPages:i.array(i.string().url()).optional(),entryLimit:i.number().min(1).optional().default(45e3),changefreq:i.nativeEnum(z).optional(),lastmod:i.date().optional(),priority:i.number().min(0).max(1).optional()}),F=i.object({internal:i.object({i18n:i.object({defaultLocale:i.string(),locales:i.array(i.string())}),routes:i.array(i.object({locale:i.string(),params:i.array(i.string()),pattern:i.string(),injectedRoute:i.object({pattern:i.string(),entrypoint:i.string(),prerender:i.boolean().optional()})}))})}),I=x.and(F);import{z as R}from"astro/zod";var U=R.union([R.literal(!1),R.object({dynamicParams:R.union([R.record(R.record(R.string().optional())),R.array(R.object({locale:R.string(),params:R.record(R.string())}))]).optional()}).and(x.pick({lastmod:!0,priority:!0,changefreq:!0}).partial())]).optional().default({});var T="sitemap-index.xml",Rt=_({name:"astro-i18n/sitemap",optionsSchema:I,setup({options:o,name:l}){let m=o.internal.routes.map(g=>({pages:[],route:g,routeData:void 0,sitemapOptions:[],include:!0})),c;return G({name:l,plugins:[W],hooks:{"astro:config:setup":({defineRouteConfig:g,...h})=>{let{logger:b}=h;if(Z(h,{name:"@astrojs/sitemap"}))throw new E("Cannot use both `@astrolicious/i18n` sitemap and `@astrojs/sitemap` integrations at the same time.","Remove the `@astrojs/sitemap` integration from your project.");c=h.config,g({importName:"i18n:astro/sitemap",callbackHandler:({routeData:a},f)=>{let r=U.safeParse(f);if(!r.success)throw new E(k(r.error),"Check your usage of `astro:i18n/sitemap`");for(let n of a){let p=m.find(d=>d.route?.injectedRoute.pattern===w(n));if(p&&(p.routeData=n,p.include=r.data!==!1,r.data!==!1&&((r.data.changefreq||r.data.lastmod||r.data.priority)&&b.warn(`Setting \`changefreq\`, \`lastmod\` or \`priority\` on a route basis is not implemented yet (eg. on "${n.component}")`),p.sitemapOptions.push(r.data),p.route))){let{locale:d,injectedRoute:y}=p.route,e=D(r.data.dynamicParams)?.find(s=>s.locale===d);if(e){let s=y.pattern;for(let[t,u]of Object.entries(e.params))u&&(s=s.replace(`[${t}]`,u));p.pages.push(s)}}}}})},"astro:build:done":async g=>{let{logger:h}=g;for(let a of m)a.pages.length===0&&a.route&&a.pages.push(a.route.injectedRoute.pattern);for(let a of m.filter(f=>!f.routeData)){let f=g.routes.find(r=>B(a.route?.injectedRoute.pattern)===w(r));if(!f)throw P("This situation should never occur (a corresponding routeData should always be found)");a.routeData=f,a.include=f.type==="page"}let b=[...m,...g.routes.filter(a=>!m.map(f=>w(f.routeData)).includes(w(a))).map(a=>({include:!0,routeData:a,pages:[],route:void 0,sitemapOptions:[]}))];try{if(!c.site){h.warn("The Sitemap integration requires the `site` astro.config option. Skipping.");return}let{customPages:a,entryLimit:f}=o;if(!c.site){h.warn("The `site` astro.config option is required. Skipping.");return}let r=new URL(c.base,c.site),n=g.pages.filter(e=>!A(e.pathname)).map(e=>{e.pathname!==""&&!r.pathname.endsWith("/")&&(r.pathname+="/"),e.pathname.startsWith("/")&&(e.pathname=e.pathname.slice(1));let s=r.pathname+e.pathname;return new URL(s,r).href}),p=b.reduce((e,s)=>{let t=s.routeData;if(!t||t.type!=="page")return e;if(t.pathname){if(A(t.pathname??t.route))return e;let u=r.pathname;u.endsWith("/")?u+=t.generate(t.pathname).substring(1):u+=t.generate(t.pathname);let S=new URL(u,r).href;e.push(j(S,c))}return e},[]);if(n=Array.from(new Set([...n,...p,...a??[]])),n=n.filter(e=>{let s=J(`/${$(c.base,new URL(e).pathname)}`),t=b.filter(u=>!u.include);for(let{routeData:u}of t)if(u.pattern.test(s))return!1;return!0}),n.length===0){h.warn(`No pages found! \`${T}\` not created.`);return}for(let e of b.filter(s=>s.include))e.pages=e.pages.map(s=>s.startsWith("/")?j(new URL(s,r).href,c):s);let d=L(b.filter(e=>e.include),r.href,o,c),y=N(g.dir);await M({hostname:r.href,destinationDir:y,sourceData:d,limit:f,gzip:!1}),h.info(`\`${T}\` created at \`${$(process.cwd(),y)}\``)}catch(a){if(a instanceof H.ZodError)h.warn(k(a));else throw a}}}})}});export{Rt as integration}; //# sourceMappingURL=integration.js.map