@jxsuite/compiler 5.1.0 → 5.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/package.json +1 -1
- package/src/site/site-build.ts +9 -12
package/dist/cli.js
CHANGED
|
@@ -661,7 +661,7 @@ ${Object.entries(e).map(([r,n])=>` ${JSON.stringify(r)}: ${JSON.stringify(n
|
|
|
661
661
|
</script>`}function Bwe(e,t){try{if(nu())return typeof ywe(dq(t,"x.js")).resolve(e)==="string";return typeof Bun.resolveSync(e,t)==="string"}catch{return!1}}async function Eq(e,t=W0,r=!0){let n=[],s=new Set,i=new Map,o=new Map,a=id(e,"assets"),c=0,l=async(u)=>{if(!o.has(u.specifier))o.set(u.specifier,await mx(u.specifier,t,{target:"browser"}));return o.get(u.specifier)},A=async(u)=>[...pwe(u,"utf8").matchAll(/(?:from|import)\s*["']([^"']+)["']/g)].map((g)=>g[1]);for(let u=0;u<fq;u++){let d=0,g=[];try{g=mwe(a,{recursive:!0}).map(String).filter((p)=>p.endsWith(".js")).map((p)=>dq(a,p))}catch{return G0(e,i,n,c)}for(let p of g){let m=[];try{m=await A(p)}catch{continue}for(let E of m){let y=am.find((w)=>E.startsWith(`${w.specifier}/`));if(!y||s.has(E))continue;s.add(E);let C=E.slice(y.specifier.length+1),B=id(e,`${y.assetDir.replace(/^\//,"")}${C}`);V0(sd(B),{recursive:!0});try{await Ia(`export * from ${JSON.stringify(E)};
|
|
662
662
|
`,{outfile:B,resolveDir:t},{minify:r,resolver:Qwe(y,B,await l(y),i),target:"browser"}),c+=1,d+=1}catch(w){n.push(`Bundling runtime subpath "${E}": ${w.message}`)}}}if(d===0)return G0(e,i,n,c)}return n.push(`Runtime subpath resolution did not settle in ${fq} passes — a package subpath `+"graph this deep is more likely a cycle in the scan than a real dependency chain."),G0(e,i,n,c)}function Qwe(e,t,r,n){return{filter:/.*/,resolve:({importer:s,path:i})=>{if(vE(s))return;if(am.find((a)=>i===a.specifier||i.startsWith(`${a.specifier}/`))!==void 0)return{external:!0,path:i};if(r===void 0||!i.startsWith("."))return;if(id(sd(s),i)!==r)return;return n.set(id(sd(t),i),e.specifier),{external:!0,path:i}}}}function G0(e,t,r,n){let s=n;for(let[i,o]of t){if(gwe(i))continue;try{V0(sd(i),{recursive:!0}),Ewe(i,`export * from ${JSON.stringify(o)};
|
|
663
663
|
`,"utf8"),s+=1}catch(a){r.push(`Writing shared core stub ${Iwe(e,i)}: ${a.message}`)}}return{errors:r,written:s}}var am,W0,fq=10;var yq=P(()=>{NE();ks();am=[{assetDir:"/assets/@vue/reactivity/",assetPath:"/assets/vue-reactivity.js",fallback:Xc,specifier:"@vue/reactivity"},{assetDir:"/assets/lit-html/",assetPath:"/assets/lit-html.js",fallback:Zc,specifier:"lit-html"}];W0=import.meta.dirname});import{cpSync as cm,existsSync as _i,mkdirSync as ys,readFileSync as wwe,readdirSync as bwe,rmSync as Swe,statSync as xwe,writeFileSync as $n}from"node:fs";import{createHash as Rwe}from"node:crypto";import{basename as Dwe,dirname as Is,join as Wo,relative as kwe,resolve as Ct,sep as vwe}from"node:path";async function Bq(e,t={}){let{clean:r=!0,verbose:n=!1}=t,s=[],i=n?console.log.bind(console):()=>{};i("Loading project.json...");let{config:o}=zi(e);if("contentTypes"in o)throw Error('project.json declares "contentTypes", which is no longer supported. Run `bun scripts/migrate-project-extensions.ts <project>` to migrate to "extensions" + "content", then `jx schema`.');let a=Ct(e,o.build.outDir),c=Ct(e,"pages"),l=Ct(e,"public"),A=o.build.trailingSlash??"always",u=o.build.minify!==!1,d=new Map,g=new Map,p=new Map,m=(L)=>{let Y=L.toSorted(),pe=`/assets/elements-${Rwe("sha1").update(Y.join("\x00")).digest("hex").slice(0,12)}.js`;return p.set(pe,Y),pe},E=hq(),y=E.imports,C=new Set,B=fR(),{errors:w,i18n:Q}=TE(o);for(let L of w)s.push(L),console.error(L);for(let L of E.warnings)console.warn(L);let x=new Map,R=(L,Y,q)=>{let pe=x.get(L);if(pe!==void 0&&pe.entryPath!==Y)throw Error(`"${q}" and "${pe.specifier}" both map to ${L} — rename one`);x.set(L,{entryPath:Y,specifier:q})},D=(L,Y)=>{if(!hx(L))return L;try{let q=DE(L,Y??e,e);if(!da(L)&&!_i(q))return console.warn(`Sidecar "${L}" not found at ${q} — emitting unbundled`),L;let pe=da(L)?L:`./${kwe(e,q)}`,Be=TS(pe);return R(Be,q,L),d.set(Be,{entryPath:q,specifier:L}),Be}catch(q){return s.push(`Sidecar "${L}": ${q.message}`),L}},U=(L)=>{let Y=$S(L);try{let q=DE(`npm:${L}`,e,e);return R(Y,q,L),g.set(Y,q),Y}catch(q){return s.push(`$head specifier "${L}": ${q.message}`),L}},_=await Ji(e,o),T=_.formats;if(T.entries.length>0)i(` Registered ${T.entries.length} format(s): ${T.entries.map((L)=>L.name).join(", ")}`);let O=_.serverMounts().filter((L)=>{if(!L.project)return!0;let Y=o[L.project.key];return Y!==void 0&&typeof Y==="object"&&Object.keys(Y).length>0});if(O.length>0&&!o.build.adapter){let L=O.map((Y)=>Y.project?`"${Y.project.key}"`:`"${Y.server.basePath}"`).join(", ");throw Error(`project.json declares dynamic section(s) ${L} served by extension mounts, but `+'build.adapter is "static". Dynamic tables need a server-capable adapter — set '+'build.adapter to "cloudflare-workers", "cloudflare-pages", "node", or "bun".')}if(r&&_i(a))Swe(a,{force:!0,recursive:!0});if(ys(a,{recursive:!0}),!_i(c))throw Error(`pages/ directory not found in ${e}`);i("Discovering pages...");let J=await aR(c,T);i(` Found ${J.length} page(s)`),i("Loading project sections...");let se=await wR(e,o,_),V=Object.keys(se);if(V.length>0)i(` Loaded ${V.length} section(s): ${V.join(", ")}`);let{errors:W,mounts:z}=await SR(_,o,e);s.push(...W);for(let L of W)console.error(L);if(z.length>0)i(` Mounted ${z.length} asset dir(s): ${z.map((L)=>L.urlPrefix).join(", ")}`);let oe=new Set,Te=_?await $we(_,o,e):[],j=await AR(J,e,se,_,o,Q);for(let L of j)L.locale=Rs(L.urlPattern,Q);i(` ${j.length} route(s) after expansion`);let X=0,ae=Ct(e,"components"),K=[],pt=new Map,rt=new Map;if(_i(ae)){i("Compiling components...");let L=[".json",...T.documentExtensions("component")],Y=bwe(ae).filter((Be)=>L.some((Bt)=>Be.endsWith(Bt))),q=Ct(a,"components");ys(q,{recursive:!0});let pe=new Map;for(let Be of Y){let Bt=Ct(ae,Be);try{let{tagName:Qt}=await Sa(Bt,T);if(Qt)pe.set(Bt,Qt)}catch{}}for(let Be of Y)try{let Bt=Ct(ae,Be),Qt=await Fp(Bt,{...o.$media?{$media:o.$media}:{},formats:T,resolveElementPath:(ye,et)=>{let br=et?Ct(et,ye):Ct(ye),la=pe.get(br);return la?`./${la}.js`:ye.replace(/\.json$/,".js")},rewriteSrc:D});for(let ye of Qt.files){let et=ye.tagName?`${ye.tagName}.js`:Dwe(ye.path);if(!K.includes(ye.tagName))$n(Ct(q,et),ye.content,"utf8"),K.push(ye.tagName),X+=1}let tr=await Sa(Bt,T);if(tr.tagName){rt.set(tr.tagName,tr);let ye=wa(tr,o.defaults),et=zx(tr.tagName,tr.style,tr,o.$media??{},ye);if(et){if(ye===null)pt.set(tr.tagName,et);Ay(et,z,oe),$n(Ct(q,`${tr.tagName}.css`),et,"utf8"),X+=1}}}catch(Bt){let Qt=Bt;s.push(`Error compiling component ${Be}: ${Qt.message}`),console.error(`Error compiling component ${Be}: ${Qt.message}`)}i(` Compiled ${K.length} component(s): ${K.join(", ")}`)}let er=[];if(o.build.adapter)for(let[,L]of rt){let Y=Bh(L);for(let q of Y){let pe=`./components/${q.src.replace(/^\.\//,"")}`;er.push({exportName:q.exportName,src:pe})}}let ie=o.images.optimize&&o.images.service==="cloudflare",lr=o.images.optimize&&!ie?_J(e):null,Ar=ie?new Map:null;if(ie)console.log('images.service is "cloudflare" — srcsets use /cdn-cgi/image transform URLs. '+"Ensure Image Transformations are enabled for your zone (Cloudflare dashboard → "+"Images → Transformations); these URLs do not work on *.pages.dev / *.workers.dev previews.");let Gt=o.url,Dt=jc(Gt),Lt=Boolean(Gt)&&o.build.sitemap!==!1,fn=[],dn=j.filter((L)=>!L.urlPattern.includes(":")&&!L.urlPattern.includes("*")),aa=Q===null?new Map:await oR(dn,T),ji=dn.map((L)=>({translationKey:aa.get(L.urlPattern),urlPattern:L.urlPattern})),Uc=nR(ji,Q,Gt??"",A),{conflicts:hn,sets:Hi}=iy(ji,Q);for(let L of hn){let[Y,q]=L.urlPatterns,pe=L.declared?"Give one of them a different $translationKey.":"Move one out of the locale tree, or give it its own $translationKey.",Be=`${q} and ${Y} are both the "${L.locale}" version of "${L.key}". A translation set names one URL per language, so ${q} is `+`dropped from it — it carries no alternates and no switcher. ${pe}`;if(L.declared)s.push(Be),console.error(Be);else console.warn(Be)}let li=tR(j,Q);if(li.length>0)console.warn(`i18n.routing is "prefix-always", but ${li.length} route(s) sit outside the locale tree and are served as "${Q?.defaultLocale}": ${li.slice(0,10).join(", ")}${li.length>10?`, and ${li.length-10} more`:""}. Move them under a locale directory, or use "prefix-except-default".`);if(Q!==null&&Q.routing==="prefix-always"&&!o.build.adapter&&!j.some((L)=>L.urlPattern==="/"))console.warn('i18n.routing is "prefix-always" and no page claims "/", so the site root is a 404. '+'Locale negotiation answers "/" only when build.adapter is set — a static deployment has '+`no runtime to read Accept-Language. Add a redirect from "/" to "/${Q.defaultLocale.toLowerCase()}/", set build.adapter, or use "prefix-except-default".`);let ca=new Set,jd=new Set;for(let L of j){let Y=rR(L.urlPattern,Q);if(Y&&!ca.has(Y.segment))ca.add(Y.segment),console.warn(`Routes under /${Y.segment}/ are served as "${Q?.defaultLocale}" — `+`i18n.locales declares "${Y.meant}", not "${Y.segment}". Rename the directory to "${Y.meant.toLowerCase()}" or declare the shorter tag.`);try{i(` Compiling ${L.urlPattern} ...`);let q=await Nwe(L,o,e,se,lr,rt,Ar,T,_,D,z,Te,U,{alternates:Uc.get(L.urlPattern)??[],i18n:Q,translations:Hi.get(L.urlPattern)??[]},y,m);for(let ye of q.unregisteredRelations)if(!jd.has(ye))jd.add(ye),console.warn(`<link rel="${ye}"> — "${ye}" is not an IANA link relation, and a relation nobody recognizes does nothing. Check the spelling, or use an absolute `+"URI if it is an extension relation (RFC 8288 §2.1.2).");let pe=new Set;for(let[ye,et]of rt)if(wh(et))pe.add(ye);if(K.length>0)q.html=Lwe(q.html,K,pt,pe,q.files.map((ye)=>ye.content).join(`
|
|
664
|
-
`),y);for(let ye of pq(q.html))C.add(ye);Ay(q.html,z,oe),dR(q.html,B);let Be=Sq(L.urlPattern,a,A);ys(Is(Be),{recursive:!0});let Bt=!L.urlPattern.includes(":")&&!L.urlPattern.includes("*"),Qt=!hu(L.urlPattern)&&!Kx(q.html);if(Lt&&!q.excludeFromSitemap&&Qt&&Bt){let ye=Uc.get(L.urlPattern)??[];fn.push({lastmod:typeof L.sourceMtime==="string"&&L.sourceMtime!==""?L.sourceMtime:Owe(xwe(L.sourcePath).mtime),loc:Ki(sl(L.urlPattern,A),Gt),...ye.length>0&&{alternates:ye}})}let tr=[];for(let ye of T.withCapability("serialize")){if(!ye.exportTarget)continue;try{let et=await ye.call("serialize",q.doc,{buildScope:(br)=>fu(br,null),componentDefs:rt,evaluateTemplate:(br,la)=>{if(!xe(br))return;return dr(br,la)??br},mode:"export"});if(et){let br=Be.replace(/\.html$/,ye.extensions[0]);tr.push({content:et,path:br,type:ye.mediaTypeEssence})}}catch(et){let br=et;s.push(`Error exporting ${ye.name} for ${L.urlPattern}: ${br.message}`)}}
|
|
664
|
+
`),y);for(let ye of pq(q.html))C.add(ye);Ay(q.html,z,oe),dR(q.html,B);let Be=Sq(L.urlPattern,a,A);ys(Is(Be),{recursive:!0});let Bt=!L.urlPattern.includes(":")&&!L.urlPattern.includes("*"),Qt=!hu(L.urlPattern)&&!Kx(q.html);if(Lt&&!q.excludeFromSitemap&&Qt&&Bt){let ye=Uc.get(L.urlPattern)??[];fn.push({lastmod:typeof L.sourceMtime==="string"&&L.sourceMtime!==""?L.sourceMtime:Owe(xwe(L.sourcePath).mtime),loc:Ki(sl(L.urlPattern,A),Gt),...ye.length>0&&{alternates:ye}})}let tr=[];for(let ye of T.withCapability("serialize")){if(!ye.exportTarget||hu(L.urlPattern))continue;try{let et=await ye.call("serialize",q.doc,{buildScope:(br)=>fu(br,null),componentDefs:rt,evaluateTemplate:(br,la)=>{if(!xe(br))return;return dr(br,la)??br},mode:"export"});if(et){let br=Be.replace(/\.html$/,ye.extensions[0]);tr.push({content:et,path:br,type:ye.mediaTypeEssence})}}catch(et){let br=et;s.push(`Error exporting ${ye.name} for ${L.urlPattern}: ${br.message}`)}}for(let ye of tr)if(ye.type!==null)q.html=Zx(q.html,{href:eR(a,ye.path),type:ye.type});$n(Be,_S(q.html,Dt),"utf8"),X+=1;for(let ye of tr)$n(ye.path,ye.content,"utf8"),X+=1;for(let ye of q.files){let et=Ct(Is(Be),ye.path);ys(Is(et),{recursive:!0}),$n(et,ye.content,"utf8"),X+=1}if(q.serverHandler){let ye=Ct(Is(Be),"_server.js");$n(ye,q.serverHandler,"utf8"),X+=1}}catch(q){let pe=q,Be=`Error compiling ${L.urlPattern}: ${pe.message}`;s.push(Be),console.error(Be)}}if(lr&&o.images.optimize){UJ(e,lr,{prune:s.length===0});let L=Ct(xA(e),"_optimized");if(_i(L)){let q=Ct(a,"images/_optimized");ys(q,{recursive:!0}),cm(L,q,{recursive:!0})}let Y=Object.keys(lr.entries).length;if(Y>0)i(` Optimized ${Y} image(s)`)}if(o.build.adapter){let{adapter:L}=o.build;i("Generating site-wide server worker...");let Y=new Map;for(let Qt of er)if(!Y.has(Qt.exportName))Y.set(Qt.exportName,Qt);let{mounts:q,connectors:pe}=Twe(O,_,o);if(q.length>0)i(` Mounting ${q.length} extension route(s): ${q.map((Qt)=>Qt.basePath).join(", ")}`);let Bt=L==="cloudflare-pages"&&Y.size===0&&q.length===0?null:GQ([...Y.values()],{adapter:L,base:Dt,connectors:pe,i18n:Q,mounts:q});if(Bt){let Qt=L==="cloudflare-pages"?"_worker.js":"worker.js";try{await Ex(Bt,{adapter:L,outfile:Ct(a,Qt),projectRoot:e}),X+=1,i(` Generated dist/${Qt} (bundled, ${Y.size} server function(s))`)}catch(tr){let ye=`Error bundling dist/${Qt}: ${tr.message}`;s.push(ye),console.error(ye)}if(L==="cloudflare-pages")$n(Ct(a,"_routes.json"),`${JSON.stringify({exclude:[],include:Q&&Q.locales.length>1?["/","/_jx/*"]:["/_jx/*"],version:1},null,2)}
|
|
665
665
|
`,"utf8"),X+=1}}if(C.size>0){i(`Bundling ${C.size} client runtime module(s)...`);let L=await gq({...E,assetPaths:[...C]},a,void 0,u);X+=L.written;for(let Y of L.errors)s.push(Y),console.error(Y)}if(g.size>0){i(`Copying ${g.size} package asset(s)...`);for(let[L,Y]of g){let q=Ct(a,L.replace(/^\//,""));ys(Is(q),{recursive:!0}),cm(Y,q),X+=1,i(` ${Y} → ${L}`)}}if(d.size>0){i(`Bundling ${d.size} client sidecar module(s)...`);for(let[L,Y]of d)try{let q=Ct(a,L.replace(/^\//,""));ys(Is(q),{recursive:!0}),await kE({entryPath:Y.entryPath,outfile:q},{external:dx,minify:u,target:"browser"}),X+=1,i(` ${Y.specifier} → ${L}`)}catch(q){let pe=`Error bundling sidecar "${Y.specifier}": ${q.message}`;s.push(pe),console.error(pe)}}if(p.size>0){i(`Bundling ${p.size} npm element set(s)...`);for(let[L,Y]of p){let q=Ct(a,L.replace(/^\//,""));ys(Is(q),{recursive:!0});try{await Ia(`${Y.map((pe)=>`import ${JSON.stringify(pe)};`).join(`
|
|
666
666
|
`)}
|
|
667
667
|
`,{outfile:q,resolveDir:e},{minify:u,target:"browser"}),X+=1,i(` ${Y.length} element(s) → ${L}`)}catch(pe){let Be=`Error bundling npm $elements [${Y.join(", ")}]: ${pe.message}`;s.push(Be),console.error(Be)}}}if(C.size>0){let L=await Eq(a,void 0,u);if(L.written>0)i(`Bundling ${L.written} runtime subpath module(s)...`);X+=L.written;for(let Y of L.errors)s.push(Y),console.error(Y)}for(let L of _.emitters()){let Y=L.project?.key,q=Y?o[Y]:void 0;if(Y&&(q==null||typeof q==="object"&&Object.keys(q).length===0))continue;try{let pe=await L.call("emit",q??null,{projectConfig:o,root:e,routes:j,sections:se});for(let Be of pe??[]){let Bt=Ct(a,Be.path.replace(/^\//,""));if(!Bt.startsWith(a+vwe))throw Error(`emit path escapes outDir: ${Be.path}`);ys(Is(Bt),{recursive:!0}),$n(Bt,Be.content),X+=1,i(` ${L.name} emitted ${Be.path}`)}}catch(pe){let Be=`Error in ${L.name}.emit: ${pe.message}`;s.push(Be),console.error(Be)}}if(o.redirects&&Object.keys(o.redirects).length>0){i("Generating redirects...");let L=new Set(j.map((q)=>q.urlPattern)),Y=Pwe(o.redirects,a,{basePath:Dt,compiledUrls:L,trailingSlash:o.build.trailingSlash});X+=Y.files,s.push(...Y.errors)}if(Lt)i(`Generating sitemap (${fn.length} URL(s))...`),X+=Hwe(fn,a);else if(!Gt&&o.build.sitemap!==!1)console.warn("sitemap.xml skipped — set `url` in project.json to enable sitemap generation.");if(oe.size>0){let{copied:L,missing:Y}=xR(oe,z,a);X+=L,i(`Copying ${L} mounted asset(s)...`);for(let q of Y)console.warn(`Referenced asset not found: ${q}`)}if(_i(l))i("Copying public/ assets..."),cm(l,a,{recursive:!0});if(Lt)X+=Jwe(a,Gt);{let L=[aq(o),lq(o,new Date)];for(let pe of L){for(let Be of pe.errors)s.push(Be),console.error(Be);for(let Be of pe.warnings)console.warn(Be)}let{skipped:Y,written:q}=Aq(L.flatMap((pe)=>pe.files),a,_i);X+=q;for(let pe of Y)i(` ${pe} — kept the copy from public/`)}{let L=Y0(o.serviceWorker);if(L!==null){let Y=L===!1?sq():nq(L,a,Dt);for(let q of Y.warnings)console.warn(q);for(let q of Y.errors)s.push(q),console.error(q);$n(Wo(a,Y.path),Y.source,"utf8"),X+=1,i(L===!1?" sw.js — tombstone (unregisters and clears)":" sw.js")}}{let{errors:L,rules:Y}=ER(o.build,B);s.push(...L);let q=IR([...Y,...yR(a)],Dt);if(q.length>0){i("Writing response headers..."),X+=CR(a,q);let{adapter:pe,deploy:Be}=o.build;if(pe==="node"||pe==="bun")console.warn(`The "${pe}" adapter serves no static assets, so dist/_headers is documentation `+"rather than configuration — apply these headers at the reverse proxy in front of it.");else if(pe===void 0&&Be===void 0)if(_i(Ct(l,"CNAME")))console.warn("GitHub Pages ignores dist/_headers and serves its own Cache-Control: max-age=600, so the generated caching and security rules will not take effect. Deploy behind a host that reads _headers (Cloudflare Pages, Cloudflare Workers assets, Netlify) to apply them.");else i(" note: _headers is read by Cloudflare Pages, Cloudflare Workers assets and Netlify; other static hosts ignore it and serve their own Cache-Control.")}X+=BR(a)}if(o.copy){i("Copying mapped files...");for(let[L,Y]of Object.entries(o.copy)){let q=Ct(e,L),pe=Ct(a,Y);ys(Is(pe),{recursive:!0}),cm(q,pe)}}if(i(`
|
package/package.json
CHANGED
package/src/site/site-build.ts
CHANGED
|
@@ -784,11 +784,12 @@ export async function buildSite(
|
|
|
784
784
|
/*
|
|
785
785
|
* Serialize the export sidecars (formats with exportTarget: true, e.g. Markdown) BEFORE the page
|
|
786
786
|
* is written, so its `<head>` advertises exactly the twins that exist: a link to a file the
|
|
787
|
-
* build did not write is worse than no link.
|
|
787
|
+
* build did not write is worse than no link. The not-found page has none: it is served for
|
|
788
|
+
* whatever URL was mistyped, so there is nothing for a twin to be a twin of.
|
|
788
789
|
*/
|
|
789
790
|
const sidecars: { content: string; path: string; type: string | null }[] = [];
|
|
790
791
|
for (const fmt of formatRegistry.withCapability("serialize")) {
|
|
791
|
-
if (!fmt.exportTarget) {
|
|
792
|
+
if (!fmt.exportTarget || isNotFoundRoute(route.urlPattern)) {
|
|
792
793
|
continue;
|
|
793
794
|
}
|
|
794
795
|
try {
|
|
@@ -813,16 +814,12 @@ export async function buildSite(
|
|
|
813
814
|
errors.push(`Error exporting ${fmt.name} for ${route.urlPattern}: ${err.message}`);
|
|
814
815
|
}
|
|
815
816
|
}
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
href: outputUrlPath(outDir, sidecar.path),
|
|
823
|
-
type: sidecar.type,
|
|
824
|
-
});
|
|
825
|
-
}
|
|
817
|
+
for (const sidecar of sidecars) {
|
|
818
|
+
if (sidecar.type !== null) {
|
|
819
|
+
result.html = withAlternateLink(result.html, {
|
|
820
|
+
href: outputUrlPath(outDir, sidecar.path),
|
|
821
|
+
type: sidecar.type,
|
|
822
|
+
});
|
|
826
823
|
}
|
|
827
824
|
}
|
|
828
825
|
|