@smart-cloud/publisher-exporter 1.1.65 → 1.1.66
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/README.md +20 -8
- package/dist/content-sync.js +15 -14
- package/dist/crawl.js +13 -12
- package/dist/deploy.js +6 -6
- package/dist/invalidate.js +2 -2
- package/dist/queue-runner.js +3 -3
- package/dist/remote-worker-health.js +1 -1
- package/dist/remote-worker.js +3 -3
- package/package.json +2 -1
- package/remote-workers.example.json +3 -0
package/dist/crawl.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import {request,chromium}from'playwright';import O,{readFile}from'fs/promises';import w from'path';import {gunzipSync}from'zlib';import us from'fast-glob';import ro from'mime-types';import wr,{createHash}from'crypto';import Kn from'http';import Jn from'https';import {availableParallelism}from'os';import {Worker}from'worker_threads';import {LambdaClient,InvokeCommand}from'@aws-sdk/client-lambda';import {S3Client,GetObjectCommand,PutObjectCommand,CopyObjectCommand}from'@aws-sdk/client-s3';import {fromTemporaryCredentials}from'@aws-sdk/credential-providers';var Dn=".deploy-plan.json",Fn="deploy-plan.json",Wn=".crawl-incomplete.json",qn="crawl-incomplete.json";function er(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?w.resolve(e):""}function tr(e){let t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),r=w.posix.normalize(t);return !t||!r||r==="."||/^[a-zA-Z]:/.test(r)||r.startsWith("../")||r===".."?null:r}function Nn(e){let t=String(e||"").trim();if(!t.startsWith("/")||t.startsWith("//")||t.includes("*")||t.includes("#"))return null;try{let r=new URL(t,"https://content-sync.invalid");return r.origin!=="https://content-sync.invalid"?null:`${w.posix.normalize(r.pathname)}${r.search}`}catch{return null}}function se(e){return [...new Set(e.map(tr).filter(t=>t!==null))]}function _n(e,t){let r={generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:w.resolve(e.outputDir),runMode:t.runMode,crawlMode:t.crawlMode,fullSyncRequired:!!t.fullSyncRequired,changedFiles:se(t.changedFiles||[]),deletedFiles:se(t.deletedFiles||[]),rewriteTargets:se(t.rewriteTargets||[]),revalidateFiles:se(t.revalidateFiles||[])};return t.schemaVersion===2?{...r,schemaVersion:2,runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,consumerId:String(t.consumerId||"").trim(),fromSequence:Math.max(0,Number(t.fromSequence)||0),toSequence:Math.max(0,Number(t.toSequence)||0),impactHash:String(t.impactHash||"").trim(),resolvedSitemapUrls:[...new Set((t.resolvedSitemapUrls||[]).map(n=>String(n||"").trim()).filter(n=>{try{let s=new URL(n);return s.protocol==="http:"||s.protocol==="https:"}catch{return false}}))],uploadGroups:{assets:se(t.uploadGroups?.assets||[]),content:se(t.uploadGroups?.content||[]),listings:se(t.uploadGroups?.listings||[]),resources:se(t.uploadGroups?.resources||[]),sitemapLeaves:se(t.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:se(t.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((t.invalidationPaths||[]).map(Nn).filter(n=>n!==null))].sort()}:{schemaVersion:1,...r,runMode:t.runMode}}function rr(e){let t=w.join(w.resolve(e.outputDir),Dn),r=er();return r?[w.join(r,Fn),t]:[t]}function nr(e){let t=w.join(w.resolve(e.outputDir),Wn),r=er();return r?[w.join(r,qn),t]:[t]}function Y(e,t){let r=w.resolve(e),n=w.resolve(t),s=w.relative(r,n).replace(/\\/g,"/");return tr(s)}async function wt(e,t){let r=_n(e,t);for(let n of rr(e)){await O.mkdir(w.dirname(n),{recursive:true});let s=`${n}.${process.pid}.${Date.now()}.tmp`;await O.writeFile(s,JSON.stringify(r,null,2),"utf8"),await O.rename(s,n);}}async function sr(e){for(let t of rr(e))try{await O.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}async function or(e,t){let r={schemaVersion:1,startedAt:String(t.startedAt||new Date().toISOString()),outputDir:w.resolve(e.outputDir)};for(let n of nr(e)){await O.mkdir(w.dirname(n),{recursive:true});let s=`${n}.${process.pid}.tmp`;await O.writeFile(s,JSON.stringify(r,null,2),"utf8"),await O.rename(s,n);}}async function ir(e){for(let t of nr(e))try{await O.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}function Bn(e){return new URL(e).pathname.split("/").filter(Boolean).some(r=>{try{return decodeURIComponent(r).endsWith("__trashed")}catch{return r.endsWith("__trashed")}})}function yt(e){return Array.isArray(e)?e.map(yt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>[t,yt(r)])):e}function Hn(e){return JSON.stringify(yt(e))}function zn(e){return createHash("sha256").update(Hn(e)).digest("hex")}function ar(e){let{impactHash:t,...r}=e;if(e.schemaVersion!==1||!t)throw new Error("Invalid content-sync impact plan schema.");if(!Array.isArray(e.resourceRenderUrls)||!Array.isArray(e.resourceDeleteUrls))throw new Error("Invalid content-sync resource impact contract.");if(zn(r)!==t)throw new Error("Content-sync impact plan hash mismatch.");for(let n of [...e.directRenderUrls,...e.deleteUrls,...e.resourceRenderUrls,...e.resourceDeleteUrls])if(Bn(n))throw new Error(`Content-sync impact contains a WordPress trash alias instead of the last public URL: ${n}`)}var bt=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function cr(e){let t=new Set;for(let r of [...e,...bt]){let n=String(r||"").trim();n&&t.add(n);}return [...t]}function St(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function ur(e){if(!e||!/^https?:\/\//i.test(e))return false;try{return St(new URL(e))}catch{return false}}function dr(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function Gn(e){let t=String(e??"").trim();if(!t)return "";let r=t;if(/^https?:\/\//i.test(r))try{r=new URL(r).pathname;}catch{return ""}if(r=r.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!r)return "";let n=r.endsWith("/"),s=r.replace(/^\/+/,"").split("/").map(i=>i.replace(/[^A-Za-z0-9._-]/g,"")).filter(i=>i.length>0&&i!=="."&&i!=="..");if(s.length===0)return "";let o=`/${s.join("/")}`;return n&&w.extname(o)===""&&(o+="/"),o==="/"?"":o}function Pt(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function Zn(e){if(!e||typeof e!="object")return {};let t={};for(let[r,n]of Object.entries(e)){let s=r.trim();if(!s||!n||typeof n!="object")continue;let o=n,i={};if(typeof o.targetOrigin=="string"){let a=dr(o.targetOrigin);a&&(i.targetOrigin=a);}let c=Pt(o.extraReplacements);if(Object.keys(c).length>0&&(i.extraReplacements=c),o.s3&&typeof o.s3=="object"){let a={},l=o.s3;typeof l.bucket=="string"&&(a.bucket=l.bucket.trim()),typeof l.prefix=="string"&&(a.prefix=l.prefix.trim()),typeof l.region=="string"&&(a.region=l.region.trim()),typeof l.htmlCacheControl=="string"&&(a.htmlCacheControl=l.htmlCacheControl.trim()),typeof l.assetCacheControl=="string"&&(a.assetCacheControl=l.assetCacheControl.trim()),Object.keys(a).length>0&&(i.s3=a);}if(o.cloudFront&&typeof o.cloudFront=="object"){let a={},l=o.cloudFront;typeof l.distributionId=="string"&&(a.distributionId=l.distributionId.trim()),Array.isArray(l.invalidationPaths)&&(a.invalidationPaths=l.invalidationPaths.map(d=>String(d??"").trim()).filter(d=>d.length>0)),Object.keys(a).length>0&&(i.cloudFront=a);}t[s]=i;}return t}function vt(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function Yn(e,t){if(!e||typeof e!="object")return null;let r=e,n=r.command;if(n!=="publish"&&n!=="crawl"&&n!=="deploy"&&n!=="invalidate"&&n!=="retry-timeouts"&&n!=="url"&&n!=="content-sync")return null;let s=Number.parseInt(String(r.intervalMinutes??"0"),10);if(!Number.isFinite(s)||s<1)return null;let o=String(r.id??`${n}-${t+1}`).trim();if(!o)return null;let i=String(r.deploymentProfile??"").trim(),c=String(r.url??"").trim(),a=Array.isArray(r.postTypes)?[...new Set(r.postTypes.map(d=>String(d??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],l=Array.isArray(r.listingPaths)?[...new Set(r.listingPaths.map(d=>String(d??"").trim()).filter(Boolean))]:[];return n==="content-sync"&&a.length===0?null:{id:o,enabled:r.enabled!==false,command:n,intervalMinutes:s,...n==="publish"||n==="crawl"?{crawlMode:r.crawlMode==="incremental"?"incremental":"full"}:{},...(n==="publish"||n==="deploy"||n==="invalidate"||n==="content-sync")&&i?{deploymentProfile:i}:{},...c?{url:c}:{},...a.length>0?{postTypes:a}:{},...l.length>0?{listingPaths:l}:{},...typeof r.includeSubsites=="boolean"?{includeSubsites:r.includeSubsites}:{},...typeof r.includePostTypeArchives=="boolean"?{includePostTypeArchives:r.includePostTypeArchives}:{},...typeof r.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:r.includeTaxonomyArchives}:{},...typeof r.includeAuthorArchives=="boolean"?{includeAuthorArchives:r.includeAuthorArchives}:{},...typeof r.includeDateArchives=="boolean"?{includeDateArchives:r.includeDateArchives}:{},...typeof r.includePostsPage=="boolean"?{includePostsPage:r.includePostsPage}:{},...typeof r.includeSitemapChain=="boolean"?{includeSitemapChain:r.includeSitemapChain}:{}}}function pr(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((n,s)=>Yn(n,s)).filter(n=>!!n):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:r}}function Xn(e){let t=e&&typeof e=="object"?e:{},r=t.render&&typeof t.render=="object"?t.render:{},n=Number(r.concurrency??0),s=Number(r.maxAttempts??0),o=t.rewrite&&typeof t.rewrite=="object"?t.rewrite:{},i=t.deploy&&typeof t.deploy=="object"?t.deploy:{},c=(a,l)=>({enabled:typeof a.enabled=="boolean"?a.enabled:r.enabled===true,concurrency:Math.min(100,Math.max(1,Number(a.concurrency||l.concurrency))),batchSize:Math.min(500,Math.max(1,Number(a.batchSize||l.batchSize))),maxAttempts:Math.min(5,Math.max(1,Number(a.maxAttempts||2)))});return {render:{enabled:r.enabled===true,...Number.isInteger(n)&&n>0?{concurrency:n}:{},...Number.isInteger(s)&&s>0?{maxAttempts:Math.min(5,s)}:{}},rewrite:c(o,{concurrency:8,batchSize:25}),deploy:c(i,{concurrency:8,batchSize:50})}}function es(e){if(!e||typeof e!="object")return;let t=e,r={};for(let s of ["accountId","siteId"]){let o=t[s];typeof o=="string"&&o.trim()!==""&&(r[s]=o.trim());}let n=Number(t.lastUpdate??0);return Number.isFinite(n)&&n>0&&(r.lastUpdate=Math.floor(n)),t.subscriber===true&&(r.subscriber=true),Object.keys(r).length>0?r:void 0}function kt(e){let t=e&&typeof e=="object"?e:{},r=String(t.accountId??"").trim(),n=String(t.siteId??"").trim(),s=t.subscriber===true,o=es(t.siteSettings),i={...o??{},...r?{accountId:o?.accountId??r}:{},...n?{siteId:o?.siteId??n}:{},...o?.subscriber===true||s?{subscriber:true}:{}},c={},a=String(t.apiBase??"").trim();a&&(c.apiBase=a);let l=String(t.runtimeToken??t.nonce??"").trim();l&&(c.runtimeToken=l);let d=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();d&&(c.virtualAssetBaseUrl=d),Object.keys(i).length>0&&(c.siteSettings=i);let u=vt(t.subscriptionType);return u&&(c.subscriptionType=u),c}function ts(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function mr(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function rs(e,t){let r=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[n,s]of new Headers(t.headers).entries())r.set(n,s);return r}async function gr(e,t,r=5){let n=new URL(mr(e)),s=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),o=n.protocol==="http:"?Kn:Jn,i=rs(e,t);return await new Promise((c,a)=>{let l=o.request(n,{method:s,headers:Object.fromEntries(i.entries()),...n.protocol==="https:"?{rejectUnauthorized:false}:{}},d=>{let u=[];d.on("data",g=>{u.push(Buffer.isBuffer(g)?g:Buffer.from(g));}),d.on("error",a),d.on("end",()=>{let g=d.statusCode??0,f=d.headers.location;if(r>0&&f&&[301,302,303,307,308].includes(g)){c(gr(new URL(f,n),{method:g===303?"GET":s},r-1));return}let h=new Headers;for(let[b,p]of Object.entries(d.headers))Array.isArray(p)?h.set(b,p.join(", ")):typeof p=="string"&&h.set(b,p);c(new Response(Buffer.concat(u),{status:g,statusText:d.statusMessage??"",headers:h}));});});l.on("error",a),l.end();})}function ns(e){let t=kt(e.wpsuite),r={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},n=String(r.accountId??"").trim(),s=String(r.siteId??"").trim(),o=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();if(e.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...o?{virtualAssetBaseUrl:o}:{},...Object.keys(r).length>0?{siteSettings:r}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!n||!s||!o)return false;ts(e.sourceOrigin);let i=globalThis,a={...i.WpSuite??{},siteSettings:r,uploadUrl:o};return t.apiBase&&(a.apiBase=t.apiBase),i.WpSuite=a,true}async function ss(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!ns(e)){let s=e.wpsuite?.siteSettings,o=[String(s?.accountId??"").trim()?"":"accountId",String(s?.siteId??"").trim()?"":"siteId",t?"":"virtualAssetBaseUrl"].filter(Boolean);return {remote:null,diagnostic:{status:"invalid-runtime",virtualAssetBaseUrl:t,subscriptionType:null,error:`Missing WP Suite runtime field(s): ${o.join(", ")}.`,requests:[]}}}let r=globalThis.fetch,n=[];try{typeof r=="function"&&/^https?:\/\//i.test(t)&&(globalThis.fetch=(async(a,l)=>{let d=mr(a);if(d.startsWith(t)){let u=(()=>{try{return new URL(d).pathname}catch{return d}})();try{let g=e.ignoreHttpsErrors&&d.startsWith("https://")?await gr(a,l):await r(a,l);return n.push({path:u,status:g.status,ok:g.ok,error:null}),g}catch(g){throw n.push({path:u,status:null,ok:!1,error:g instanceof Error?g.message:String(g)}),g}}return r(a,l)}));let{getConfig:s}=await import('@smart-cloud/wpsuite-core'),o=await s("publisher"),i=o&&typeof o=="object"?o:null,c=vt(i?.subscriptionType);return {remote:i,diagnostic:{status:i?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:c??null,error:i?null:"WP Suite publisher config loader returned no configuration.",requests:n}}}catch(s){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:t,subscriptionType:null,error:s instanceof Error?s.message:String(s),requests:n}}}finally{typeof r=="function"&&(globalThis.fetch=r);}}function os(e,t){let r=Zn(t?.deploymentProfiles),n=String(t?.defaultDeploymentProfile??"").trim(),s=r[n]?n:"",o=vt(t?.subscriptionType),i=kt(e.wpsuite);return {...e,scheduler:pr(t?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:s,...o?{subscriptionType:o}:{},wpsuite:{...i,...i.siteSettings||o?{siteSettings:{...i.siteSettings??{},...i.siteSettings?.subscriber===true||o==="PROFESSIONAL"||o==="AGENCY"?{subscriber:true}:{}}}:{},...o?{subscriptionType:o}:{}}}}function Rt(e,t){let n=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!n)return t;let s=n.split("/").map(o=>o.trim()).filter(o=>o.length>0&&o!=="."&&o!=="..");return s.length>0?s.join("/"):t}function is(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?w.resolve(e):""}function lr(e,t,r){let n=String(t||"").trim();return n&&w.isAbsolute(n)?w.resolve(n):w.resolve(e,Rt(n,r))}async function Xe(e,t={}){let r=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",n=await O.readFile(r,"utf8"),s=JSON.parse(n);s.sourceOrigin=s.sourceOrigin.replace(/\/$/,""),s.targetOrigin=dr(s.targetOrigin),s.ignoreHttpsErrors??=false,s.outputDir=String(s.outputDir||"export").trim()||"export",s.urlRewriteMode||=s.targetOrigin==="."?"relative":"absolute",s.noJavaScriptRenderPathPrefixes||=[],s.seedPaths||=[],s.generated404RequestPath=Gn(s.generated404RequestPath),s.sitemapPaths||=[...bt],s.allowedAssetHosts||=[],s.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],s.blockedPathPrefixes||=[],s.blockedSearchFragments||=[];let o=Number(s.processingConcurrency)>0?Math.min(100,Math.max(1,Number(s.processingConcurrency))):null;s.concurrency=o??s.concurrency??1,s.maxPages||=0,s.extraReplacements=Pt(s.extraReplacements),s.postCrawlCopyMap=Pt(s.postCrawlCopyMap),s.logDir=String(s.logDir||"logs").trim()||"logs",s.verbose??=false,s.logLevel||=s.verbose?"debug":"info",s.s3SyncMode||="sdk-upload-delete",s.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},s.readiness.timeoutMs??=1500,s.readiness.fallbackWaitMs??=1500,s.viewport||={width:1440,height:1200},s.navigationTimeoutMs||=3e4,s.assetDownloadConcurrency=o??(Number(s.assetDownloadConcurrency)>0?Number(s.assetDownloadConcurrency):s.concurrency),s.rewriteConcurrency=o??(Number(s.rewriteConcurrency)>0?Number(s.rewriteConcurrency):s.assetDownloadConcurrency),s.wpsuite=kt(s.wpsuite),s.scheduler=pr(void 0),s.remoteWorkers=Xn(s.remoteWorkers),typeof s.lambdaDelegationEnabled=="boolean"&&(s.remoteWorkers.render??={},s.remoteWorkers.rewrite??={},s.remoteWorkers.deploy??={},s.remoteWorkers.render.enabled=s.lambdaDelegationEnabled,s.remoteWorkers.rewrite.enabled=s.lambdaDelegationEnabled,s.remoteWorkers.deploy.enabled=s.lambdaDelegationEnabled),o!==null&&(s.processingConcurrency=o,s.remoteWorkers.render??={},s.remoteWorkers.rewrite??={},s.remoteWorkers.deploy??={},s.remoteWorkers.render.concurrency=o,s.remoteWorkers.rewrite.concurrency=o,s.remoteWorkers.deploy.concurrency=o),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let i=await ss(s);t.onRemotePublisherConfigDiagnostic?.(i.diagnostic);let c=os(s,i.remote),a=is(),l=a?w.resolve(a,".."):"";return l?(c.outputDir=lr(l,c.outputDir,"export"),c.logDir=lr(l,c.logDir,"logs")):(w.isAbsolute(c.outputDir)||(c.outputDir=Rt(c.outputDir,"export")),w.isAbsolute(c.logDir)||(c.logDir=Rt(c.logDir,"logs"))),c}function oe(e,t=10){return wr.createHash("sha1").update(e).digest("hex").slice(0,t)}async function as(e){await O.mkdir(w.dirname(e),{recursive:true});}async function me(e,t,r){await as(e);let n=w.join(w.dirname(e),`.${w.basename(e)}.${process.pid}.${Date.now()}.${wr.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await O.writeFile(n,t,r??"utf8"):await O.writeFile(n,t),await O.rename(n,e);}catch(s){throw await O.unlink(n).catch(()=>{}),s}}function ie(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(w.extname(e).toLowerCase())}function ge(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function $e(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function et(e){return e.replace(/\//g,"\\/")}function hr(e){return e.replace(/\//g,"\\\\/")}function cs(e){try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return null;let r=t.pathname==="/"&&!t.search&&!t.hash?"":`${t.pathname}${t.search}${t.hash}`;return `//${t.host}${r}`}catch{return null}}function fr(e,t,r){if(!t)return;e[t]=r;let n=et(t),s=et(r);e[n]=s;let o=hr(t),i=hr(r);e[o]=i;let c=$e(t),a=$e(r);e[c]=a;let l=$e(n),d=$e(s);e[l]=d;let u=$e(o),g=$e(i);e[u]=g;}function tt(e,t,r){fr(e,t,r);let n=cs(t);n&&n!==t&&fr(e,n,r);}function Ct(e,t){let r=t.startsWith("/")?t:`/${t}`,n=(e||"").replace(/\/$/,"");return !n||n==="."||n==="/"?r:`${n}${r}`}function yr(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function br(e,t,r){if(!t)return r;let n=w.dirname(w.resolve(t)),s=w.resolve(e,r.replace(/^\/+/,"")),o=w.relative(n,s).replace(/\\/g,"/");return o?(o.startsWith(".")||(o=`./${o}`),o):"."}async function Tt(e,t){return (t?[...new Set(t)].map(n=>w.resolve(n)).filter(n=>n.startsWith(w.resolve(e.outputDir))).map(n=>w.relative(e.outputDir,n).replace(/\\/g,"/")).filter(n=>n.length>0):await us(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(n=>n!=="asset-map.json"&&ie(n))}var ms=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],gs=new Set([".html",".htm"]),Sr="WPSuite.io Static Publisher",hs=Sr.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function fs(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ws(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function ys(e,t,r){return ws(t)?e.replace(new RegExp(`(?<!:)${fs(t)}`,"g"),r):e.split(t).join(r)}function bs(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let s=w.extname(r).toLowerCase();return gs.has(s)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Ss(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${hs}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${Sr}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let n=e.includes(`\r
|
|
1
|
+
import {request,chromium}from'playwright';import M,{readFile}from'fs/promises';import w from'path';import {gunzipSync}from'zlib';import ms from'fast-glob';import Br from'mime-types';import Sr,{createHash}from'crypto';import Yn from'http';import Xn from'https';import {availableParallelism}from'os';import {Worker}from'worker_threads';import {LambdaClient,InvokeCommand}from'@aws-sdk/client-lambda';import {DynamoDBClient,GetItemCommand}from'@aws-sdk/client-dynamodb';import {S3Client,GetObjectCommand,PutObjectCommand,CopyObjectCommand}from'@aws-sdk/client-s3';import {fromTemporaryCredentials}from'@aws-sdk/credential-providers';var Nn=".deploy-plan.json",_n="deploy-plan.json",Bn=".crawl-incomplete.json",Vn="crawl-incomplete.json";function nr(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?w.resolve(e):""}function sr(e){let t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),r=w.posix.normalize(t);return !t||!r||r==="."||/^[a-zA-Z]:/.test(r)||r.startsWith("../")||r===".."?null:r}function Hn(e){let t=String(e||"").trim();if(!t.startsWith("/")||t.startsWith("//")||t.includes("*")||t.includes("#"))return null;try{let r=new URL(t,"https://content-sync.invalid");return r.origin!=="https://content-sync.invalid"?null:`${w.posix.normalize(r.pathname)}${r.search}`}catch{return null}}function se(e){return [...new Set(e.map(sr).filter(t=>t!==null))]}function zn(e,t){let r={generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:w.resolve(e.outputDir),runMode:t.runMode,crawlMode:t.crawlMode,fullSyncRequired:!!t.fullSyncRequired,changedFiles:se(t.changedFiles||[]),deletedFiles:se(t.deletedFiles||[]),rewriteTargets:se(t.rewriteTargets||[]),revalidateFiles:se(t.revalidateFiles||[])};return t.schemaVersion===2?{...r,schemaVersion:2,runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,consumerId:String(t.consumerId||"").trim(),fromSequence:Math.max(0,Number(t.fromSequence)||0),toSequence:Math.max(0,Number(t.toSequence)||0),impactHash:String(t.impactHash||"").trim(),resolvedSitemapUrls:[...new Set((t.resolvedSitemapUrls||[]).map(n=>String(n||"").trim()).filter(n=>{try{let s=new URL(n);return s.protocol==="http:"||s.protocol==="https:"}catch{return false}}))],uploadGroups:{assets:se(t.uploadGroups?.assets||[]),content:se(t.uploadGroups?.content||[]),listings:se(t.uploadGroups?.listings||[]),resources:se(t.uploadGroups?.resources||[]),sitemapLeaves:se(t.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:se(t.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((t.invalidationPaths||[]).map(Hn).filter(n=>n!==null))].sort()}:{schemaVersion:1,...r,runMode:t.runMode}}function or(e){let t=w.join(w.resolve(e.outputDir),Nn),r=nr();return r?[w.join(r,_n),t]:[t]}function ir(e){let t=w.join(w.resolve(e.outputDir),Bn),r=nr();return r?[w.join(r,Vn),t]:[t]}function Z(e,t){let r=w.resolve(e),n=w.resolve(t),s=w.relative(r,n).replace(/\\/g,"/");return sr(s)}async function bt(e,t){let r=zn(e,t);for(let n of or(e)){await M.mkdir(w.dirname(n),{recursive:true});let s=`${n}.${process.pid}.${Date.now()}.tmp`;await M.writeFile(s,JSON.stringify(r,null,2),"utf8"),await M.rename(s,n);}}async function ar(e){for(let t of or(e))try{await M.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}async function cr(e,t){let r={schemaVersion:1,startedAt:String(t.startedAt||new Date().toISOString()),outputDir:w.resolve(e.outputDir)};for(let n of ir(e)){await M.mkdir(w.dirname(n),{recursive:true});let s=`${n}.${process.pid}.tmp`;await M.writeFile(s,JSON.stringify(r,null,2),"utf8"),await M.rename(s,n);}}async function ur(e){for(let t of ir(e))try{await M.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}function Kn(e){return new URL(e).pathname.split("/").filter(Boolean).some(r=>{try{return decodeURIComponent(r).endsWith("__trashed")}catch{return r.endsWith("__trashed")}})}function St(e){return Array.isArray(e)?e.map(St):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>[t,St(r)])):e}function Jn(e){return JSON.stringify(St(e))}function Gn(e){return createHash("sha256").update(Jn(e)).digest("hex")}function lr(e){let{impactHash:t,...r}=e;if(e.schemaVersion!==1||!t)throw new Error("Invalid content-sync impact plan schema.");if(!Array.isArray(e.resourceRenderUrls)||!Array.isArray(e.resourceDeleteUrls))throw new Error("Invalid content-sync resource impact contract.");if(Gn(r)!==t)throw new Error("Content-sync impact plan hash mismatch.");for(let n of [...e.directRenderUrls,...e.deleteUrls,...e.resourceRenderUrls,...e.resourceDeleteUrls])if(Kn(n))throw new Error(`Content-sync impact contains a WordPress trash alias instead of the last public URL: ${n}`)}var Pt=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function dr(e){let t=new Set;for(let r of [...e,...Pt]){let n=String(r||"").trim();n&&t.add(n);}return [...t]}function Rt(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function pr(e){if(!e||!/^https?:\/\//i.test(e))return false;try{return Rt(new URL(e))}catch{return false}}function hr(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function es(e){let t=String(e??"").trim();if(!t)return "";let r=t;if(/^https?:\/\//i.test(r))try{r=new URL(r).pathname;}catch{return ""}if(r=r.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!r)return "";let n=r.endsWith("/"),s=r.replace(/^\/+/,"").split("/").map(i=>i.replace(/[^A-Za-z0-9._-]/g,"")).filter(i=>i.length>0&&i!=="."&&i!=="..");if(s.length===0)return "";let o=`/${s.join("/")}`;return n&&w.extname(o)===""&&(o+="/"),o==="/"?"":o}function vt(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function ts(e){if(!e||typeof e!="object")return {};let t={};for(let[r,n]of Object.entries(e)){let s=r.trim();if(!s||!n||typeof n!="object")continue;let o=n,i={};if(typeof o.targetOrigin=="string"){let a=hr(o.targetOrigin);a&&(i.targetOrigin=a);}let c=vt(o.extraReplacements);if(Object.keys(c).length>0&&(i.extraReplacements=c),o.s3&&typeof o.s3=="object"){let a={},l=o.s3;typeof l.bucket=="string"&&(a.bucket=l.bucket.trim()),typeof l.prefix=="string"&&(a.prefix=l.prefix.trim()),typeof l.region=="string"&&(a.region=l.region.trim()),typeof l.htmlCacheControl=="string"&&(a.htmlCacheControl=l.htmlCacheControl.trim()),typeof l.assetCacheControl=="string"&&(a.assetCacheControl=l.assetCacheControl.trim()),Object.keys(a).length>0&&(i.s3=a);}if(o.cloudFront&&typeof o.cloudFront=="object"){let a={},l=o.cloudFront;typeof l.distributionId=="string"&&(a.distributionId=l.distributionId.trim()),Array.isArray(l.invalidationPaths)&&(a.invalidationPaths=l.invalidationPaths.map(d=>String(d??"").trim()).filter(d=>d.length>0)),Object.keys(a).length>0&&(i.cloudFront=a);}t[s]=i;}return t}function Ct(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function rs(e,t){if(!e||typeof e!="object")return null;let r=e,n=r.command;if(n!=="publish"&&n!=="crawl"&&n!=="deploy"&&n!=="invalidate"&&n!=="retry-timeouts"&&n!=="url"&&n!=="content-sync")return null;let s=Number.parseInt(String(r.intervalMinutes??"0"),10);if(!Number.isFinite(s)||s<1)return null;let o=String(r.id??`${n}-${t+1}`).trim();if(!o)return null;let i=String(r.deploymentProfile??"").trim(),c=String(r.url??"").trim(),a=Array.isArray(r.postTypes)?[...new Set(r.postTypes.map(d=>String(d??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],l=Array.isArray(r.listingPaths)?[...new Set(r.listingPaths.map(d=>String(d??"").trim()).filter(Boolean))]:[];return n==="content-sync"&&a.length===0?null:{id:o,enabled:r.enabled!==false,command:n,intervalMinutes:s,...n==="publish"||n==="crawl"?{crawlMode:r.crawlMode==="incremental"?"incremental":"full"}:{},...(n==="publish"||n==="deploy"||n==="invalidate"||n==="content-sync")&&i?{deploymentProfile:i}:{},...c?{url:c}:{},...a.length>0?{postTypes:a}:{},...l.length>0?{listingPaths:l}:{},...typeof r.includeSubsites=="boolean"?{includeSubsites:r.includeSubsites}:{},...typeof r.includePostTypeArchives=="boolean"?{includePostTypeArchives:r.includePostTypeArchives}:{},...typeof r.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:r.includeTaxonomyArchives}:{},...typeof r.includeAuthorArchives=="boolean"?{includeAuthorArchives:r.includeAuthorArchives}:{},...typeof r.includeDateArchives=="boolean"?{includeDateArchives:r.includeDateArchives}:{},...typeof r.includePostsPage=="boolean"?{includePostsPage:r.includePostsPage}:{},...typeof r.includeSitemapChain=="boolean"?{includeSitemapChain:r.includeSitemapChain}:{}}}function gr(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((n,s)=>rs(n,s)).filter(n=>!!n):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:r}}function ns(e){let t=e&&typeof e=="object"?e:{},r=t.render&&typeof t.render=="object"?t.render:{},n=Number(r.concurrency??0),s=Number(r.batchSize??0),o=Number(r.maxAttempts??0),i=t.rewrite&&typeof t.rewrite=="object"?t.rewrite:{},c=t.deploy&&typeof t.deploy=="object"?t.deploy:{},a=(l,d)=>({enabled:typeof l.enabled=="boolean"?l.enabled:r.enabled===true,concurrency:Math.min(100,Math.max(1,Number(l.concurrency||d.concurrency))),batchSize:Math.min(500,Math.max(1,Number(l.batchSize||d.batchSize))),maxAttempts:Math.min(5,Math.max(1,Number(l.maxAttempts||2)))});return {render:{enabled:r.enabled===true,...Number.isInteger(n)&&n>0?{concurrency:n}:{},batchSize:Number.isInteger(s)&&s>0?Math.min(20,s):5,...Number.isInteger(o)&&o>0?{maxAttempts:Math.min(5,o)}:{}},rewrite:a(i,{concurrency:8,batchSize:25}),deploy:a(c,{concurrency:8,batchSize:50})}}function ss(e){if(!e||typeof e!="object")return;let t=e,r={};for(let s of ["accountId","siteId"]){let o=t[s];typeof o=="string"&&o.trim()!==""&&(r[s]=o.trim());}let n=Number(t.lastUpdate??0);return Number.isFinite(n)&&n>0&&(r.lastUpdate=Math.floor(n)),t.subscriber===true&&(r.subscriber=true),Object.keys(r).length>0?r:void 0}function xt(e){let t=e&&typeof e=="object"?e:{},r=String(t.accountId??"").trim(),n=String(t.siteId??"").trim(),s=t.subscriber===true,o=ss(t.siteSettings),i={...o??{},...r?{accountId:o?.accountId??r}:{},...n?{siteId:o?.siteId??n}:{},...o?.subscriber===true||s?{subscriber:true}:{}},c={},a=String(t.apiBase??"").trim();a&&(c.apiBase=a);let l=String(t.runtimeToken??t.nonce??"").trim();l&&(c.runtimeToken=l);let d=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();d&&(c.virtualAssetBaseUrl=d),Object.keys(i).length>0&&(c.siteSettings=i);let u=Ct(t.subscriptionType);return u&&(c.subscriptionType=u),c}function os(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function fr(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function is(e,t){let r=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[n,s]of new Headers(t.headers).entries())r.set(n,s);return r}async function wr(e,t,r=5){let n=new URL(fr(e)),s=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),o=n.protocol==="http:"?Yn:Xn,i=is(e,t);return await new Promise((c,a)=>{let l=o.request(n,{method:s,headers:Object.fromEntries(i.entries()),...n.protocol==="https:"?{rejectUnauthorized:false}:{}},d=>{let u=[];d.on("data",h=>{u.push(Buffer.isBuffer(h)?h:Buffer.from(h));}),d.on("error",a),d.on("end",()=>{let h=d.statusCode??0,f=d.headers.location;if(r>0&&f&&[301,302,303,307,308].includes(h)){c(wr(new URL(f,n),{method:h===303?"GET":s},r-1));return}let g=new Headers;for(let[y,p]of Object.entries(d.headers))Array.isArray(p)?g.set(y,p.join(", ")):typeof p=="string"&&g.set(y,p);c(new Response(Buffer.concat(u),{status:h,statusText:d.statusMessage??"",headers:g}));});});l.on("error",a),l.end();})}function as(e){let t=xt(e.wpsuite),r={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},n=String(r.accountId??"").trim(),s=String(r.siteId??"").trim(),o=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();if(e.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...o?{virtualAssetBaseUrl:o}:{},...Object.keys(r).length>0?{siteSettings:r}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!n||!s||!o)return false;os(e.sourceOrigin);let i=globalThis,a={...i.WpSuite??{},siteSettings:r,uploadUrl:o};return t.apiBase&&(a.apiBase=t.apiBase),i.WpSuite=a,true}async function cs(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!as(e)){let s=e.wpsuite?.siteSettings,o=[String(s?.accountId??"").trim()?"":"accountId",String(s?.siteId??"").trim()?"":"siteId",t?"":"virtualAssetBaseUrl"].filter(Boolean);return {remote:null,diagnostic:{status:"invalid-runtime",virtualAssetBaseUrl:t,subscriptionType:null,error:`Missing WP Suite runtime field(s): ${o.join(", ")}.`,requests:[]}}}let r=globalThis.fetch,n=[];try{typeof r=="function"&&/^https?:\/\//i.test(t)&&(globalThis.fetch=(async(a,l)=>{let d=fr(a);if(d.startsWith(t)){let u=(()=>{try{return new URL(d).pathname}catch{return d}})();try{let h=e.ignoreHttpsErrors&&d.startsWith("https://")?await wr(a,l):await r(a,l);return n.push({path:u,status:h.status,ok:h.ok,error:null}),h}catch(h){throw n.push({path:u,status:null,ok:!1,error:h instanceof Error?h.message:String(h)}),h}}return r(a,l)}));let{getConfig:s}=await import('@smart-cloud/wpsuite-core'),o=await s("publisher"),i=o&&typeof o=="object"?o:null,c=Ct(i?.subscriptionType);return {remote:i,diagnostic:{status:i?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:c??null,error:i?null:"WP Suite publisher config loader returned no configuration.",requests:n}}}catch(s){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:t,subscriptionType:null,error:s instanceof Error?s.message:String(s),requests:n}}}finally{typeof r=="function"&&(globalThis.fetch=r);}}function us(e,t){let r=ts(t?.deploymentProfiles),n=String(t?.defaultDeploymentProfile??"").trim(),s=r[n]?n:"",o=Ct(t?.subscriptionType),i=xt(e.wpsuite);return {...e,scheduler:gr(t?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:s,...o?{subscriptionType:o}:{},wpsuite:{...i,...i.siteSettings||o?{siteSettings:{...i.siteSettings??{},...i.siteSettings?.subscriber===true||o==="PROFESSIONAL"||o==="AGENCY"?{subscriber:true}:{}}}:{},...o?{subscriptionType:o}:{}}}}function kt(e,t){let n=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!n)return t;let s=n.split("/").map(o=>o.trim()).filter(o=>o.length>0&&o!=="."&&o!=="..");return s.length>0?s.join("/"):t}function ls(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?w.resolve(e):""}function mr(e,t,r){let n=String(t||"").trim();return n&&w.isAbsolute(n)?w.resolve(n):w.resolve(e,kt(n,r))}async function tt(e,t={}){let r=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",n=await M.readFile(r,"utf8"),s=JSON.parse(n);s.sourceOrigin=s.sourceOrigin.replace(/\/$/,""),s.targetOrigin=hr(s.targetOrigin),s.ignoreHttpsErrors??=false,s.outputDir=String(s.outputDir||"export").trim()||"export",s.urlRewriteMode||=s.targetOrigin==="."?"relative":"absolute",s.noJavaScriptRenderPathPrefixes||=[],s.seedPaths||=[],s.generated404RequestPath=es(s.generated404RequestPath),s.sitemapPaths||=[...Pt],s.allowedAssetHosts||=[],s.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],s.blockedPathPrefixes||=[],s.blockedSearchFragments||=[];let o=Number(s.processingConcurrency)>0?Math.min(100,Math.max(1,Number(s.processingConcurrency))):null;s.concurrency=o??s.concurrency??1,s.maxPages||=0,s.extraReplacements=vt(s.extraReplacements),s.postCrawlCopyMap=vt(s.postCrawlCopyMap),s.logDir=String(s.logDir||"logs").trim()||"logs",s.verbose??=false,s.logLevel||=s.verbose?"debug":"info",s.s3SyncMode||="sdk-upload-delete",s.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},s.readiness.timeoutMs??=1500,s.readiness.fallbackWaitMs??=1500,s.viewport||={width:1440,height:1200},s.navigationTimeoutMs||=3e4,s.assetDownloadConcurrency=o??(Number(s.assetDownloadConcurrency)>0?Number(s.assetDownloadConcurrency):s.concurrency),s.rewriteConcurrency=o??(Number(s.rewriteConcurrency)>0?Number(s.rewriteConcurrency):s.assetDownloadConcurrency),s.wpsuite=xt(s.wpsuite),s.scheduler=gr(void 0),s.remoteWorkers=ns(s.remoteWorkers),typeof s.lambdaDelegationEnabled=="boolean"&&(s.remoteWorkers.render??={},s.remoteWorkers.rewrite??={},s.remoteWorkers.deploy??={},s.remoteWorkers.render.enabled=s.lambdaDelegationEnabled,s.remoteWorkers.rewrite.enabled=s.lambdaDelegationEnabled,s.remoteWorkers.deploy.enabled=s.lambdaDelegationEnabled),o!==null&&(s.processingConcurrency=o,s.remoteWorkers.render??={},s.remoteWorkers.rewrite??={},s.remoteWorkers.deploy??={},s.remoteWorkers.render.concurrency=o,s.remoteWorkers.rewrite.concurrency=o,s.remoteWorkers.deploy.concurrency=o),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let i=await cs(s);t.onRemotePublisherConfigDiagnostic?.(i.diagnostic);let c=us(s,i.remote),a=ls(),l=a?w.resolve(a,".."):"";return l?(c.outputDir=mr(l,c.outputDir,"export"),c.logDir=mr(l,c.logDir,"logs")):(w.isAbsolute(c.outputDir)||(c.outputDir=kt(c.outputDir,"export")),w.isAbsolute(c.logDir)||(c.logDir=kt(c.logDir,"logs"))),c}function oe(e,t=10){return Sr.createHash("sha1").update(e).digest("hex").slice(0,t)}async function ds(e){await M.mkdir(w.dirname(e),{recursive:true});}async function me(e,t,r){await ds(e);let n=w.join(w.dirname(e),`.${w.basename(e)}.${process.pid}.${Date.now()}.${Sr.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await M.writeFile(n,t,r??"utf8"):await M.writeFile(n,t),await M.rename(n,e);}catch(s){throw await M.unlink(n).catch(()=>{}),s}}function ie(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(w.extname(e).toLowerCase())}function he(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function $e(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function rt(e){return e.replace(/\//g,"\\/")}function yr(e){return e.replace(/\//g,"\\\\/")}function ps(e){try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return null;let r=t.pathname==="/"&&!t.search&&!t.hash?"":`${t.pathname}${t.search}${t.hash}`;return `//${t.host}${r}`}catch{return null}}function br(e,t,r){if(!t)return;e[t]=r;let n=rt(t),s=rt(r);e[n]=s;let o=yr(t),i=yr(r);e[o]=i;let c=$e(t),a=$e(r);e[c]=a;let l=$e(n),d=$e(s);e[l]=d;let u=$e(o),h=$e(i);e[u]=h;}function nt(e,t,r){br(e,t,r);let n=ps(t);n&&n!==t&&br(e,n,r);}function At(e,t){let r=t.startsWith("/")?t:`/${t}`,n=(e||"").replace(/\/$/,"");return !n||n==="."||n==="/"?r:`${n}${r}`}function Pr(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function Rr(e,t,r){if(!t)return r;let n=w.dirname(w.resolve(t)),s=w.resolve(e,r.replace(/^\/+/,"")),o=w.relative(n,s).replace(/\\/g,"/");return o?(o.startsWith(".")||(o=`./${o}`),o):"."}async function Et(e,t){return (t?[...new Set(t)].map(n=>w.resolve(n)).filter(n=>n.startsWith(w.resolve(e.outputDir))).map(n=>w.relative(e.outputDir,n).replace(/\\/g,"/")).filter(n=>n.length>0):await ms(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(n=>n!=="asset-map.json"&&ie(n))}var ws=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],ys=new Set([".html",".htm"]),vr="WPSuite.io Static Publisher",bs=vr.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Ss(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ps(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function Rs(e,t,r){return Ps(t)?e.replace(new RegExp(`(?<!:)${Ss(t)}`,"g"),r):e.split(t).join(r)}function vs(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let s=w.extname(r).toLowerCase();return ys.has(s)?/<head\b|<html\b|<!doctype html/i.test(t):false}function ks(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${bs}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${vr}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let n=e.includes(`\r
|
|
2
2
|
`)?`\r
|
|
3
3
|
`:`
|
|
4
|
-
`;return e.replace(/<head\b[^>]*>/i,s=>`${s}${n} ${t}`)}function
|
|
5
|
-
`,"utf8");}function
|
|
6
|
-
`,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>
|
|
4
|
+
`;return e.replace(/<head\b[^>]*>/i,s=>`${s}${n} ${t}`)}function Cs(e){let t=he(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function xs(e,t){let r=[...new Set(t)].filter(o=>o.includes("/")&&!/\\+\//.test(o)).map(o=>[o,rt(o)]).filter(([o,i])=>o!==i).sort((o,i)=>i[0].length-o[0].length);if(!r.length)return e;let n=o=>{let i=o;for(let[c,a]of r)i=i.split(c).join(a);return i},s=e.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(o,i,c,a)=>`${i}${n(c)}${a}`);return s=s.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(o,i,c,a,l)=>Cs(a)?`${i}${n(a)}${l}`:o),s}function As(e,t){if(!t)return null;let r=w.dirname(w.resolve(t)),n=w.resolve(e.outputDir),s=w.relative(r,n).replace(/\\/g,"/");return s?(s.startsWith(".")||(s=`./${s}`),s.endsWith("/")?s:`${s}/`):"./"}function Ts(e,t,r){let n=As(t,r);if(!n)return e;let s=e;for(let o of ws){let i=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=new RegExp(`(?:\\.{1,}/)+${i}`,"g"),a=new RegExp(`(?<!\\.)/${i}`,"g");s=s.replace(c,`${n}${o}`).replace(a,`${n}${o}`);let l=o.replace(/\//g,"\\/"),d=n.replace(/\//g,"\\/"),u=l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),h=new RegExp(`(?:\\.{1,}\\\\/)+${u}`,"g"),f=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${u}`,"g"),g=new RegExp(`(?<![\\.\\\\])\\/${u}`,"g");s=s.replace(h,`${d}${l}`).replace(f,`${d}${l}`).replace(g,`${d}${l}`);}return s}function It(e,t,r){if(e.urlRewriteMode==="absolute")return t;let n=(()=>{try{return new URL(t,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin)}catch{return null}})(),s=n?n.pathname:Pr(t,e.targetOrigin),o=n?`${n.search}${n.hash}`:"";return e.urlRewriteMode==="root-relative"?`${s}${o}`:`${Rr(e.outputDir,r,s)}${o}`}function Tt(e,t,r,n,s){nt(e,r,It(t,n,s));}function Is(e,t,r,n,s){if(!r||r===n)return;nt(e,r,n);let o=It(t,r,s),i=It(t,n,s);nt(e,o,i);}function Ot(e,t,r,n,s={}){let o=e,i={};Tt(i,t,t.sourceOrigin,t.targetOrigin,n);for(let[a,l]of Object.entries(t.extraReplacements))Tt(i,t,a,l,n);for(let[a,l]of Object.entries(r))Tt(i,t,a,l,n);for(let[a,l]of Object.entries(s)){let d=r[a];!d||d===l||Is(i,t,l,d,n);}let c=Object.entries(i).sort((a,l)=>l[0].length-a[0].length);for(let[a,l]of c)o=Rs(o,a,l);return t.urlRewriteMode!=="absolute"&&(o=Ts(o,t,n)),o=xs(o,c.map(([,a])=>a)),vs(t,o,n)&&(o=ks(o)),o}async function Es(e,t,r,n){let s=w.join(e.outputDir,n),o=w.extname(s).toLowerCase(),i;try{i=await M.readFile(s,"utf8");}catch(l){if(l.code!=="ENOENT")throw l;return {changed:false}}let a=Ot(i,e,t,o===".js"||o===".mjs"?void 0:s,r);return a!==i?(await me(s,a,"utf8"),{changed:true}):{changed:false}}async function Os(e,t){return await new Promise((r,n)=>{let s=a=>{if(c(),a?.error){n(new Error(a.error));return}r({changed:!!a?.changed});},o=a=>{c(),n(a);},i=a=>{c(),a!==0&&n(new Error(`Rewrite worker exited with code ${a}.`));},c=()=>{e.off("message",s),e.off("error",o),e.off("exit",i);};e.on("message",s),e.on("error",o),e.on("exit",i),e.postMessage({file:t});})}async function kr(e,t,r={}){let n=await Et(e,r.files),s=0;if(n.length===0)return 0;let o=Math.max(1,Number(e.rewriteConcurrency||e.assetDownloadConcurrency||1)),i=Math.max(1,Math.min(o,n.length,availableParallelism()));await r.onStart?.({totalFiles:n.length,workerCount:i});let c=0,a=0,l=null;if(i===1){for(let u of n){let h=await Es(e,t,r.previousAssetMap??{},u);h.changed&&(s+=1),a+=1,await r.onProgress?.({index:a,totalFiles:n.length,changedTextFiles:s,file:u,changed:h.changed});}return s}let d=Array.from({length:i},async()=>{let u=new Worker(new URL("./rewrite-worker.js",import.meta.url),{workerData:{config:e,assetMap:t,previousAssetMap:r.previousAssetMap??{}}});try{for(;!l;){let h=c;if(h>=n.length)return;c+=1;let f=n[h],g=await Os(u,f);g.changed&&(s+=1),a+=1,await r.onProgress?.({index:a,totalFiles:n.length,changedTextFiles:s,file:f,changed:g.changed});}}catch(h){throw l=h instanceof Error?h:new Error(String(h)),l}finally{await u.terminate().catch(()=>{});}});return await Promise.all(d),s}var ke={error:0,warn:1,info:2,debug:3},Ms=/^(?:authorization|proxyAuthorization|runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken|xStaticPublisherToken|xApiKey)$/i;function ge(e){return e.replace(/((?:x-static-publisher-token|authorization|proxy-authorization|x-api-key|aws-access-key-id|aws-secret-access-key|aws-session-token)\s*:\s*)[^\r\n]+/gi,"$1[REDACTED]").replace(/\b(Basic|Bearer)\s+[^\s]+/gi,"$1 [REDACTED]").replace(/([?&](?:token|access_token|refresh_token|api_key|key|nonce)=)[^&\s]+/gi,"$1[REDACTED]").replace(/((?:"|')?(?:runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken)(?:"|')?\s*[:=]\s*(?:"|'))[^"']+/gi,"$1[REDACTED]")}function ot(e){return typeof e=="string"?ge(e):Array.isArray(e)?e.map(t=>ot(t)):e instanceof Error?{name:e.name,message:ge(e.message),...e.stack?{stack:ge(e.stack)}:{}}:e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([t,r])=>[t,Ms.test(t)?"[REDACTED]":ot(r)])):e}function Mt(e){return e?ot(e):void 0}var Cr=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",st=Cr?w.join(Cr,"current-progress.json"):"",xr=Promise.resolve();function Ar(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function $s(e,t){let r={...e},n=typeof e.phase=="string"?e.phase.trim():"",s=typeof t.phase=="string"?t.phase.trim():"";if(s!==""&&(s==="deploy"||s.startsWith("deploy-"))&&n!==s)for(let c of ["index","totalFiles","staged","uploaded","skipped","failed","deleted","workerCount","completedBatches","totalBatches"])delete r[c];let i=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","completedBatches","totalBatches","pageQueue","assetQueue","sitemapQueue"]);for(let[c,a]of Object.entries(t)){let l=r[c];if(typeof l=="number"&&typeof a=="number"&&i.has(c)){r[c]=Math.max(l,a);continue}r[c]=a;}return r}function js(e,t,r){st&&(xr=xr.then(async()=>{let n=new Date,s=n.toISOString();await M.mkdir(w.dirname(st),{recursive:true});let o=await M.readFile(st,"utf8").then(m=>JSON.parse(m)).catch(()=>null),i=o&&typeof o.details=="object"&&o.details?o.details:{},c=Ar(e),a=o?.currentStep||Ar(o?.source||""),l=o?.startedAt||s,d={...o?.stepDurationsSec??{}},u=o?.stepStartedAt||s;if(a&&a!==c&&o?.stepStartedAt){let m=Math.max(0,Math.round((n.getTime()-new Date(o.stepStartedAt).getTime())/1e3));d[a]=(d[a]??0)+m,u=s;}let h=Math.max(0,Math.round((n.getTime()-new Date(u).getTime())/1e3)),f=Math.max(0,Math.round((n.getTime()-new Date(l).getTime())/1e3)),g=ge(t),y=Mt(r)??{},p={checkedAt:s,source:e,message:g,details:$s(i,y),startedAt:l,currentStep:c,stepStartedAt:u,stepElapsedSec:h,totalElapsedSec:f,stepDurationsSec:d};await M.writeFile(st,JSON.stringify(p,null,2),"utf8");}).catch(()=>{}));}async function Us(e,t){await M.mkdir(w.dirname(e),{recursive:true}),await M.appendFile(e,`${JSON.stringify(ot(t))}
|
|
5
|
+
`,"utf8");}function Ls(e,t){let r=typeof t?.phase=="string"?t.phase.trim():"";return r||(e==="page"?"render-pages":e==="asset"?"download-assets":e==="sitemap"?"discovery":e==="timing"&&typeof t?.name=="string"&&t.name.trim()||"crawl")}function Ds(e,t,r){let n=Mt(r);return {checkedAt:new Date().toISOString(),currentStep:Ls(e,n),level:e,message:ge(t),details:n??{}}}var je=class{constructor(t,r="info"){this.logDir=t;this.level=typeof r=="boolean"?r?"debug":"info":r,this.ensureLogFileReady();}logDir;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;level;get logPath(){return w.join(this.logDir,"crawl.log.jsonl")}get currentEventPath(){return w.join(this.logDir,"current-crawl-event.json")}get rejectedPath(){return w.join(this.logDir,"rejected.jsonl")}get ignoredPath(){return w.join(this.logDir,"ignored.jsonl")}get skippedPath(){return w.join(this.logDir,"skipped-http.jsonl")}get errorsPath(){return w.join(this.logDir,"errors.jsonl")}get timingsPath(){return w.join(this.logDir,"timings.jsonl")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await M.mkdir(this.logDir,{recursive:true}),await M.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(t){this.writeQueue=this.writeQueue.then(t).catch(r=>{this.writeError=r instanceof Error?r:new Error(String(r));});}enqueueLine(t){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await M.appendFile(this.logPath,`${t}
|
|
6
|
+
`,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>Us(t,r));}updateCurrentEvent(t,r,n){let s=Ds(t,r,n);this.enqueueTask(async()=>{await M.mkdir(this.logDir,{recursive:true}),await M.writeFile(this.currentEventPath,JSON.stringify(s,null,2),"utf8");});}push(t,r,n){let s=ge(r),o=Mt(n),i=JSON.stringify({time:new Date().toISOString(),level:t,message:s,...o||{}});this.enqueueLine(i),this.updateCurrentEvent(t,s,o),t==="error"?console.error(s,o||""):t==="warn"?console.warn(s,o||""):(ke[this.level]>=ke.debug||["summary","page","sitemap","asset","timing"].includes(t))&&console.log(s);}info(t,r){this.push("info",t,r);}debug(t,r){ke[this.level]<ke.debug||this.push("debug",t,r);}progress(t,r){js("crawl.log.jsonl",t,r),this.updateCurrentEvent("progress",t,r);}checkpoint(t,r){this.updateCurrentEvent("checkpoint",t,r);}page(t,r){this.push("page",t,r);}sitemap(t,r){this.push("sitemap",t,r);}asset(t,r){this.push("asset",t,r);}warn(t,r){this.push("warn",t,r);}error(t,r){this.enqueueJsonLine(this.errorsPath,{message:t,...r||{}}),this.push("error",t,r);}summary(t,r){this.push("summary",t,r);}mark(t){this.marks.set(t,Date.now());}endMark(t,r){let n=this.marks.get(t);if(!n)return;let s=Date.now()-n,o={name:t,ms:s,seconds:Number((s/1e3).toFixed(2)),...r||{}};this.enqueueJsonLine(this.timingsPath,o),this.push("timing",`Timing ${t}: ${o.seconds}s`,o);}reject(t,r,n,s){let o={kind:t,url:r,reason:n,source:s};this.enqueueJsonLine(this.rejectedPath,o),ke[this.level]>=ke.debug&&this.push("reject",`Rejected ${t} ${r}: ${n}`,o);}ignore(t,r,n,s){let o={kind:t,url:r,reason:n,source:s};this.enqueueJsonLine(this.ignoredPath,o),ke[this.level]>=ke.debug&&this.push("ignore",`Ignored ${t} ${r}: ${n}`,o);}skip(t,r,n,s){let o={kind:t,url:r,status:n,source:s};this.enqueueJsonLine(this.skippedPath,o),this.push("warn",`Skipped ${t} ${r}: HTTP ${n}`,o);}async flush(){let t=Date.now()-this.startedAt,r={name:"total",ms:t,seconds:Number((t/1e3).toFixed(2))};if(this.enqueueJsonLine(this.timingsPath,r),await this.writeQueue,this.writeError)throw this.writeError}};var Tr="(?:css|js|mjs|json|map|xml|xsl|rss|atom|txt|enc|jws|png|jpe?g|gif|webp|avif|svg|ico|woff2?|ttf|otf|eot|pdf|mp4|webm)";function Er(e){let t=new RegExp(`(?:https?:)?//[^\\s'"<>\\);]+\\.${Tr}(?:[?#][^\\s'"<>\\);]*)?(?=[\\s'"<>\\);]|$)|(?<![A-Za-z0-9._-])/[^\\s'"<>\\);]+\\.${Tr}(?:[?#][^\\s'"<>\\);]*)?(?=[\\s'"<>\\);]|$)`,"gi");return [...e.matchAll(t)].map(r=>r[0])}function Ir(e){return !!e&&/^(?:\.{1,2}\/)?[A-Za-z0-9@_][A-Za-z0-9@._/-]*\.(?:js|mjs)(?:[?#][^\s<>\\]*)?$/i.test(e)&&!e.startsWith("/")&&!e.startsWith("//")&&!/^[a-z][a-z0-9+.-]*:/i.test(e)&&!/(?:^|\/)node_modules(?:\/|$)|(?:^|\/)\.pnpm(?:\/|$)/i.test(e)}function Or(e){let t=new Set,r=[],n=/\bimport\s*\(\s*["'`]([^"'`\s<>\\]+)["'`]\s*\)/g,s=/\b(?:[A-Za-z_$][\w$]*\.)?u\s*=\s*(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*=>\s*["'`]([^"'`\s<>\\]+)["'`]/g;for(let o of e.matchAll(n))o[1]&&Ir(o[1])&&r.push({index:o.index??0,value:o[1]});for(let o of e.matchAll(s))o[1]&&Ir(o[1])&&r.push({index:o.index??0,value:o[1]});for(let o of r.sort((i,c)=>i.index-c.index))t.add(o.value);return [...t]}function Mr(e,t){let r=w.relative(t,e);return r===""||!r.startsWith("..")&&!w.isAbsolute(r)}function $r(e,t,r,n){let s=w.resolve(e),o=w.resolve(t),i=w.extname(s).toLowerCase();return !Mr(s,o)||i!==".html"&&i!==".htm"||r.has(s)?false:!n.some(c=>Mr(s,w.resolve(c)))}function $t(e,t){return typeof e=="string"&&e.length>0&&t?.supported===true&&typeof t.token=="string"&&t.token.length>0&&e===t.token}function jt(e,t){try{let r=new URL(e),n=new URL(t,r);if(n.origin!==r.origin)return !1;let s=r.pathname.replace(/\/+$/,"");if(s&&n.pathname!==s&&!n.pathname.startsWith(`${s}/`))return !1;let o=s?n.pathname.slice(s.length)||"/":n.pathname;return ["/wp-includes/","/wp-content/plugins/","/wp-content/themes/","/wp-content/mu-plugins/"].some(i=>o.startsWith(i))}catch{return false}}function jr(e){return e<1}function Ur(e){let t=String(e??"").toLowerCase();return t==="strict"?"Strict":t==="lax"?"Lax":t==="none"?"None":"Unspecified"}function Ws(e){let t=e.pathname||"/";if(!t.startsWith("/")||t==="/")return "/";let r=t.lastIndexOf("/");return r<=0?"/":t.slice(0,r)}function Be(e){return `${e.name.toLowerCase()}
|
|
7
7
|
${e.domain.toLowerCase()}
|
|
8
|
-
${e.path}`}function
|
|
9
|
-
`,{encoding:"utf8",mode:384}),await O.rename(r,e);}function Be(e){let t=e;for(let n=0;n<3;n+=1){if(/%(?:2f|5c)/i.test(t))return null;try{let s=decodeURIComponent(t);if(s===t)break;t=s;}catch{return null}}return t.includes("\0")||t.includes("\\")||t.split("/").some(n=>n==="."||n==="..")?null:t}function He(e,t){let r=Be(t);if(r===null)throw new Error(`Unsafe output URL pathname: ${t}`);let n=w.resolve(e),s=w.resolve(n,r.replace(/^\/+/,""));if(s!==n&&!s.startsWith(`${n}${w.sep}`))throw new Error(`Output path escapes configured root: ${t}`);return s}var V=1,Ur=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function X(e,t){let r=String(e??"").trim();if(!Ur.test(r))throw new Error(`${t} must match ${Ur.source} and be at most 128 characters.`);return r}function Lr(e){let t=String(e??"").trim().replace(/^\/+|\/+$/g,"");if(!t)return "";let r=t.split("/").filter(Boolean);if(r.some(n=>n==="."||n===".."))throw new Error("S3 prefix contains an unsafe dot path segment.");return `${r.join("/")}/`}function Ut(e,...t){let r=Lr(e),n=t.map((s,o)=>{let i=String(s??"").replace(/^\/+|\/+$/g,"");if(!i||i.split("/").some(c=>c==="."||c===".."))throw new Error(`Unsafe S3 key segment at index ${o}.`);return i});return `${r}${n.join("/")}`}function ee(e){return createHash("sha256").update(e).digest("hex")}function fe(e,t){let r=String(e??"").replace(/^\/+/,""),n=Lr(t);if(!r||r.includes("\0"))throw new Error("S3 object key is empty or invalid.");if(n&&!r.startsWith(n))throw new Error(`S3 object key is outside the configured workspace prefix: ${r}`);if(r.split("/").some(s=>s===".."))throw new Error("S3 object key contains an unsafe parent segment.");return r}function z(e,t,{optional:r=false}={}){if(!(r&&(e==null||e===""))){if(typeof e!="string"||!e.trim())throw new Error(`${t} must be a non-empty string.`);return e.trim()}}function zs(e){if(!e||typeof e!="object")throw new Error("Remote worker config must be a JSON object.");let t=e;if(t.schemaVersion!==1)throw new Error(`Unsupported remote worker config version: ${String(t.schemaVersion)}.`);if(t.protocolVersion!==V)throw new Error(`Remote worker protocol mismatch: expected ${V}, received ${String(t.protocolVersion)}.`);let r=t.workspace,n=t.functions;if(!r||!n)throw new Error("Remote worker config requires workspace and functions objects.");return {schemaVersion:1,region:z(t.region,"region"),...z(t.roleArn,"roleArn",{optional:true})?{roleArn:z(t.roleArn,"roleArn")}:{},...z(t.roleSessionName,"roleSessionName",{optional:true})?{roleSessionName:z(t.roleSessionName,"roleSessionName")}:{},workspace:{bucket:z(r.bucket,"workspace.bucket"),prefix:String(r.prefix??"")},functions:{render:z(n.render,"functions.render"),...z(n.asset,"functions.asset",{optional:true})?{asset:z(n.asset,"functions.asset")}:{},rewrite:z(n.rewrite,"functions.rewrite"),"deploy-copy":z(n["deploy-copy"],"functions.deploy-copy")},targets:Array.isArray(t.targets)?t.targets.map((s,o)=>{if(!s||typeof s!="object")throw new Error(`targets[${o}] must be an object.`);let i=s;return {id:z(i.id,`targets[${o}].id`),bucketName:z(i.bucketName,`targets[${o}].bucketName`),prefix:String(i.prefix??""),region:z(i.region,`targets[${o}].region`)}}):[],protocolVersion:V}}async function Wr(e){let t=w.resolve(e);try{return zs(JSON.parse(await readFile(t,"utf8")))}catch(r){throw new Error(`Unable to load remote worker config ${t}: ${r instanceof Error?r.message:String(r)}`,{cause:r})}}var it=class{config;lambda;s3;constructor(t,r={}){this.config=t;let n=t.roleArn?fromTemporaryCredentials({params:{RoleArn:t.roleArn,RoleSessionName:t.roleSessionName??"publisher-exporter-remote-worker"},clientConfig:{region:t.region}}):void 0;this.lambda=new LambdaClient({region:t.region,...n?{credentials:n}:{},...r}),this.s3=new S3Client({region:t.region,...n?{credentials:n}:{}});}async invoke(t){let r=t.operation==="health"?this.config.functions.render:this.config.functions[t.operation];if(!r)throw new Error(`Remote worker configuration does not provide a ${t.operation} function. Redeploy the Lambda workers and reinstall remote-workers.json.`);let n=await this.lambda.send(new InvokeCommand({FunctionName:r,InvocationType:"RequestResponse",Payload:Buffer.from(JSON.stringify(t),"utf8")})),s=n.Payload?JSON.parse(new TextDecoder().decode(n.Payload)):null;if(n.FunctionError)throw new Error(`Remote ${t.operation} worker failed (${n.FunctionError}): ${JSON.stringify(s)}`);if(!s||typeof s!="object")throw new Error(`Remote ${t.operation} worker returned no JSON response.`);let o=s;if(o.schemaVersion!==V||o.operation!==t.operation||o.jobId!==t.jobId||o.taskId!==t.taskId)throw new Error(`Remote ${t.operation} worker returned a mismatched response.`);return o}async readResult(t){if(!t.resultKey)throw new Error(`Remote ${t.operation} response does not contain a resultKey.`);let r=fe(t.resultKey,this.config.workspace.prefix),n=await this.s3.send(new GetObjectCommand({Bucket:this.config.workspace.bucket,Key:r}));if(!n.Body)throw new Error(`Remote worker result has no body: ${r}`);return JSON.parse(await n.Body.transformToString("utf8"))}async readObject(t){if(t.bucket!==this.config.workspace.bucket)throw new Error(`Remote worker object bucket mismatch: ${t.bucket}.`);let r=fe(t.key,this.config.workspace.prefix),n=await this.s3.send(new GetObjectCommand({Bucket:this.config.workspace.bucket,Key:r,...t.versionId?{VersionId:t.versionId}:{}}));if(!n.Body)throw new Error(`Remote worker object has no body: ${r}`);let s=await n.Body.transformToByteArray();if(s.byteLength!==t.bytes)throw new Error(`Remote worker object length mismatch for ${r}: expected ${t.bytes}, received ${s.byteLength}.`);if(ee(s)!==t.sha256)throw new Error(`Remote worker object checksum mismatch for ${r}.`);return s}async readObjectText(t){return new TextDecoder("utf8",{fatal:true}).decode(await this.readObject(t))}async health(t){let r=this.config.functions[t];if(!r)throw new Error(`Remote worker configuration does not provide a ${t} function.`);let n=`${t}-${Date.now()}`,s=await this.lambda.send(new InvokeCommand({FunctionName:r,InvocationType:"RequestResponse",Payload:Buffer.from(JSON.stringify({schemaVersion:V,operation:"health",jobId:"health",taskId:n}),"utf8")})),o=s.Payload?JSON.parse(new TextDecoder().decode(s.Payload)):null;if(s.FunctionError||!o||typeof o!="object")throw new Error(`Remote ${t} health check failed: ${JSON.stringify(o)}`);return o}async writeWorkspaceObject(t){let r=fe(t.key,this.config.workspace.prefix),n=typeof t.body=="string"?Buffer.from(t.body,"utf8"):t.body,s=ee(n),o=await this.s3.send(new PutObjectCommand({Bucket:this.config.workspace.bucket,Key:r,Body:n,ContentType:t.contentType,...t.cacheControl?{CacheControl:t.cacheControl}:{},Metadata:{sha256:s,...t.metadata??{}}}));return {bucket:this.config.workspace.bucket,key:r,sha256:s,bytes:n.byteLength,contentType:t.contentType,...o.ETag?{etag:o.ETag}:{},...o.VersionId?{versionId:o.VersionId}:{}}}async copyWorkspaceObject(t,r){if(t.bucket!==this.config.workspace.bucket)throw new Error(`Remote worker object bucket mismatch: ${t.bucket}.`);let n=fe(t.key,this.config.workspace.prefix),s=fe(r,this.config.workspace.prefix),o=`${t.bucket}/${n.split("/").map(c=>encodeURIComponent(c)).join("/")}`,i=await this.s3.send(new CopyObjectCommand({Bucket:t.bucket,Key:s,CopySource:o,MetadataDirective:"COPY"}));return {...t,key:s,...i.CopyObjectResult?.ETag?{etag:i.CopyObjectResult.ETag}:{},...i.VersionId?{versionId:i.VersionId}:{}}}};function Qs(e,t,r){if(!e||typeof e!="object")throw new Error("Remote render result must be a JSON object.");let n=e;if(n.schemaVersion!==V||!n.response||n.response.operation!=="render"||n.response.jobId!==t.jobId||n.response.taskId!==t.taskId||!n.detail||!Array.isArray(n.detail.pages)||n.detail.pages.length!==1)throw new Error("Remote render result has an invalid envelope.");let s=n.detail.pages[0];if(!s||s.requestedUrl!==r)throw new Error("Remote render result does not match the requested URL.");return n}var at=class{#e;#r;#t;#n;#s=0;constructor(t){this.#e=t.client,this.#r=X(t.jobId,"jobId"),this.#t=Math.max(1,Math.min(5,t.maxAttempts??2)),this.#n=t.onRetry;}async render(t){let r=null;for(let n=1;n<=this.#t;n+=1){this.#s+=1;let s=X(`render-${this.#s}-${ee(t.url).slice(0,24)}-a${n}`,"taskId");try{let o=await this.#e.invoke({schemaVersion:V,operation:"render",jobId:this.#r,taskId:s,sourceOrigin:new URL(t.sourceOrigin).origin,urls:[t.url],options:t.options}),c=Qs(await this.#e.readResult(o),o,t.url).detail.pages[0];if(c.outcome==="failed"||c.outcome==="deferred")throw new Error(c.error||`Remote render ended with ${c.outcome}.`);if(!c.html)throw new Error("Remote render completed without an HTML object.");return {page:c,html:t.downloadHtml===!1?null:await this.#e.readObjectText(c.html),taskId:s,attempts:n}}catch(o){r=o,n<this.#t&&this.#n?.({url:t.url,attempt:n,maxAttempts:this.#t,reason:o instanceof Error?o.message:String(o)});}}throw new Error(`Remote render failed after ${this.#t} attempt(s) for ${t.url}: ${r instanceof Error?r.message:String(r)}`,{cause:r})}};function Ks(e,t,r){if(!e||typeof e!="object")throw new Error("Remote asset result must be a JSON object.");let n=e;if(n.schemaVersion!==V||n.response?.operation!=="asset"||n.response.jobId!==t.jobId||n.response.taskId!==t.taskId||!n.detail||!Array.isArray(n.detail.assets)||n.detail.assets.length!==r.length)throw new Error("Remote asset result has an invalid envelope.");for(let s=0;s<r.length;s+=1)if(n.detail.assets[s]?.requestedUrl!==r[s])throw new Error("Remote asset result does not match the requested URLs.");return n}var ct=class{#e;#r;#t;#n=0;constructor(t){this.#e=t.client,this.#r=X(t.jobId,"jobId"),this.#t=Math.max(1,Math.min(5,t.maxAttempts??2));}async fetch(t){let r=[...t.urls];if(r.length<1||r.length>20)throw new Error("Remote asset batches require between 1 and 20 URLs.");let n=null;for(let s=1;s<=this.#t;s+=1){this.#n+=1;let o=X(`asset-${this.#n}-${ee(r.join(`
|
|
10
|
-
`)).slice(0,24)}-a${
|
|
11
|
-
`)).slice(0,
|
|
12
|
-
`)).slice(0,16)}`,"taskId")
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
${e.path}`}function Lr(e,t){let r;try{r=new URL(t);}catch{return null}let n=e.split(";"),s=n.shift()?.trim()??"",o=s.indexOf("=");if(o<=0)return null;let i=s.slice(0,o).trim();if(!i||[...i].some(y=>y<=" "||"=;,".includes(y)))return null;let c=r.hostname.toLowerCase(),a=Ws(r),l=null,d=true,u=false,h=false,f="Unspecified",g=false;for(let y of n){let p=y.indexOf("="),m=(p<0?y:y.slice(0,p)).trim().toLowerCase(),b=p<0?"":y.slice(p+1).trim();if(m==="domain"&&b)c=b.toLowerCase();else if(m==="path"&&b.startsWith("/"))a=b;else if(m==="expires"){let k=Date.parse(b);Number.isFinite(k)&&(l=Math.floor(k/1e3),d=false);}else if(m==="max-age"&&/^-?\d+$/u.test(b)){let k=Number.parseInt(b,10);l=Math.floor(Date.now()/1e3)+k,d=false;}else m==="secure"?u=true:m==="httponly"?h=true:m==="samesite"?f=Ur(b):m==="partitioned"&&(g=true);}return {name:i,domain:c,path:a,expires:l,session:d,secure:u,httpOnly:h,sameSite:f,partitioned:g}}function qs(e){let t=!Number.isFinite(e.expires)||e.expires<=0;return {name:e.name,domain:e.domain.toLowerCase(),path:e.path||"/",expires:t?null:e.expires,session:t,secure:e.secure,httpOnly:e.httpOnly,sameSite:Ur(e.sameSite),partitioned:e.partitioned===true}}function Dr(e,t){let r=new Map(e.map(n=>[Be(n),n.value]));return t.filter(n=>r.get(Be(n))!==n.value).map(qs)}function Ns(e,t){let r=e.session||t.session;return {...e,expires:r?null:Math.max(e.expires??0,t.expires??0)||null,session:r,secure:e.secure&&t.secure,httpOnly:e.httpOnly&&t.httpOnly,sameSite:e.sameSite===t.sameSite?e.sameSite:"Unspecified",partitioned:e.partitioned&&t.partitioned}}var it=class{#e=new Map;add(t){if(!t)return;let r={...t,domain:t.domain.toLowerCase(),path:t.path||"/"},n=Be(r),s=this.#e.get(n);this.#e.set(n,s?Ns(s,r):r);}addAll(t){for(let r of t)this.add(r);}artifact(){return {schemaVersion:1,observations:[...this.#e.values()].sort((t,r)=>Be(t).localeCompare(Be(r)))}}};async function at(e,t){await M.mkdir(w.dirname(e),{recursive:true});let r=`${e}.${process.pid}.tmp`;await M.writeFile(r,`${JSON.stringify(t,null,2)}
|
|
9
|
+
`,{encoding:"utf8",mode:384}),await M.rename(r,e);}function Ve(e){let t=e;for(let n=0;n<3;n+=1){if(/%(?:2f|5c)/i.test(t))return null;try{let s=decodeURIComponent(t);if(s===t)break;t=s;}catch{return null}}return t.includes("\0")||t.includes("\\")||t.split("/").some(n=>n==="."||n==="..")?null:t}function He(e,t){let r=Ve(t);if(r===null)throw new Error(`Unsafe output URL pathname: ${t}`);let n=w.resolve(e),s=w.resolve(n,r.replace(/^\/+/,""));if(s!==n&&!s.startsWith(`${n}${w.sep}`))throw new Error(`Output path escapes configured root: ${t}`);return s}var B=1,Fr=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function X(e,t){let r=String(e??"").trim();if(!Fr.test(r))throw new Error(`${t} must match ${Fr.source} and be at most 128 characters.`);return r}function Wr(e){let t=String(e??"").trim().replace(/^\/+|\/+$/g,"");if(!t)return "";let r=t.split("/").filter(Boolean);if(r.some(n=>n==="."||n===".."))throw new Error("S3 prefix contains an unsafe dot path segment.");return `${r.join("/")}/`}function Dt(e,...t){let r=Wr(e),n=t.map((s,o)=>{let i=String(s??"").replace(/^\/+|\/+$/g,"");if(!i||i.split("/").some(c=>c==="."||c===".."))throw new Error(`Unsafe S3 key segment at index ${o}.`);return i});return `${r}${n.join("/")}`}function ee(e){return createHash("sha256").update(e).digest("hex")}function fe(e,t){let r=String(e??"").replace(/^\/+/,""),n=Wr(t);if(!r||r.includes("\0"))throw new Error("S3 object key is empty or invalid.");if(n&&!r.startsWith(n))throw new Error(`S3 object key is outside the configured workspace prefix: ${r}`);if(r.split("/").some(s=>s===".."))throw new Error("S3 object key contains an unsafe parent segment.");return r}function z(e,t,{optional:r=false}={}){if(!(r&&(e==null||e===""))){if(typeof e!="string"||!e.trim())throw new Error(`${t} must be a non-empty string.`);return e.trim()}}function Ys(e){if(!e||typeof e!="object")throw new Error("Remote worker config must be a JSON object.");let t=e;if(t.schemaVersion!==1)throw new Error(`Unsupported remote worker config version: ${String(t.schemaVersion)}.`);if(t.protocolVersion!==B)throw new Error(`Remote worker protocol mismatch: expected ${B}, received ${String(t.protocolVersion)}.`);let r=t.workspace,n=t.functions;if(!r||!n)throw new Error("Remote worker config requires workspace and functions objects.");return {schemaVersion:1,region:z(t.region,"region"),...z(t.roleArn,"roleArn",{optional:true})?{roleArn:z(t.roleArn,"roleArn")}:{},...z(t.roleSessionName,"roleSessionName",{optional:true})?{roleSessionName:z(t.roleSessionName,"roleSessionName")}:{},workspace:{bucket:z(r.bucket,"workspace.bucket"),prefix:String(r.prefix??"")},...t.status&&typeof t.status=="object"?{status:{tableName:z(t.status.tableName,"status.tableName")}}:{},functions:{render:z(n.render,"functions.render"),...z(n.asset,"functions.asset",{optional:true})?{asset:z(n.asset,"functions.asset")}:{},rewrite:z(n.rewrite,"functions.rewrite"),"deploy-copy":z(n["deploy-copy"],"functions.deploy-copy")},targets:Array.isArray(t.targets)?t.targets.map((s,o)=>{if(!s||typeof s!="object")throw new Error(`targets[${o}] must be an object.`);let i=s;return {id:z(i.id,`targets[${o}].id`),bucketName:z(i.bucketName,`targets[${o}].bucketName`),prefix:String(i.prefix??""),region:z(i.region,`targets[${o}].region`)}}):[],protocolVersion:B}}async function _r(e){let t=w.resolve(e);try{return Ys(JSON.parse(await readFile(t,"utf8")))}catch(r){throw new Error(`Unable to load remote worker config ${t}: ${r instanceof Error?r.message:String(r)}`,{cause:r})}}var ct=class{config;lambda;s3;dynamodb;#e;constructor(t,r={},n={}){this.config=t;let s=t.roleArn?fromTemporaryCredentials({params:{RoleArn:t.roleArn,RoleSessionName:t.roleSessionName??"publisher-exporter-remote-worker"},clientConfig:{region:t.region}}):void 0;this.lambda=new LambdaClient({region:t.region,...s?{credentials:s}:{},...r}),this.s3=new S3Client({region:t.region,...s?{credentials:s}:{}}),this.dynamodb=t.status?new DynamoDBClient({region:t.region,...s?{credentials:s}:{}}):null,this.#e=n;}async#n(t){if(!this.dynamodb||!this.config.status)return null;let n=(await this.dynamodb.send(new GetItemCommand({TableName:this.config.status.tableName,ConsistentRead:true,Key:{jobId:{S:t.jobId},taskId:{S:t.taskId}}}))).Item;if(!n)return null;let s=n.operation?.S,o=n.status?.S;return !s||!["render","asset","rewrite","deploy-copy"].includes(s)||!o||!["running","succeeded","partial","failed"].includes(o)?null:{jobId:n.jobId?.S??t.jobId,taskId:n.taskId?.S??t.taskId,operation:s,status:o,completedItems:Number(n.completedItems?.N??0),failedItems:Number(n.failedItems?.N??0),totalItems:Number(n.totalItems?.N??0),sequence:Number(n.sequence?.N??0),updatedAt:n.updatedAt?.S??new Date(0).toISOString(),requestId:n.requestId?.S??null}}async#t(t,r){let n=this.lambda.send(new InvokeCommand({FunctionName:r,InvocationType:"RequestResponse",Payload:Buffer.from(JSON.stringify(t),"utf8")}));if(t.operation==="health"||!this.dynamodb||!this.#e.onProgress)return await n;let s=false,o=n.finally(()=>{s=true;}),i=Math.max(500,Math.min(3e4,this.#e.progressPollIntervalMs??2e3)),c=-1;for(;!s;){await Promise.race([o.then(()=>{},()=>{}),new Promise(a=>setTimeout(a,i))]);try{let a=await this.#n(t);a&&a.sequence>c&&(c=a.sequence,await this.#e.onProgress(a));}catch(a){await this.#e.onProgressError?.(a instanceof Error?a:new Error(String(a)));}}return await o}async invoke(t){let r=t.operation==="health"?this.config.functions.render:this.config.functions[t.operation];if(!r)throw new Error(`Remote worker configuration does not provide a ${t.operation} function. Redeploy the Lambda workers and reinstall remote-workers.json.`);let n=await this.#t(t,r),s=n.Payload?JSON.parse(new TextDecoder().decode(n.Payload)):null;if(n.FunctionError)throw new Error(`Remote ${t.operation} worker failed (${n.FunctionError}): ${JSON.stringify(s)}`);if(!s||typeof s!="object")throw new Error(`Remote ${t.operation} worker returned no JSON response.`);let o=s;if(o.schemaVersion!==B||o.operation!==t.operation||o.jobId!==t.jobId||o.taskId!==t.taskId)throw new Error(`Remote ${t.operation} worker returned a mismatched response.`);return o}async readResult(t){if(!t.resultKey)throw new Error(`Remote ${t.operation} response does not contain a resultKey.`);let r=fe(t.resultKey,this.config.workspace.prefix),n=await this.s3.send(new GetObjectCommand({Bucket:this.config.workspace.bucket,Key:r}));if(!n.Body)throw new Error(`Remote worker result has no body: ${r}`);return JSON.parse(await n.Body.transformToString("utf8"))}async readObject(t){if(t.bucket!==this.config.workspace.bucket)throw new Error(`Remote worker object bucket mismatch: ${t.bucket}.`);let r=fe(t.key,this.config.workspace.prefix),n=await this.s3.send(new GetObjectCommand({Bucket:this.config.workspace.bucket,Key:r,...t.versionId?{VersionId:t.versionId}:{}}));if(!n.Body)throw new Error(`Remote worker object has no body: ${r}`);let s=await n.Body.transformToByteArray();if(s.byteLength!==t.bytes)throw new Error(`Remote worker object length mismatch for ${r}: expected ${t.bytes}, received ${s.byteLength}.`);if(ee(s)!==t.sha256)throw new Error(`Remote worker object checksum mismatch for ${r}.`);return s}async readObjectText(t){return new TextDecoder("utf8",{fatal:true}).decode(await this.readObject(t))}async health(t){let r=this.config.functions[t];if(!r)throw new Error(`Remote worker configuration does not provide a ${t} function.`);let n=`${t}-${Date.now()}`,s=await this.lambda.send(new InvokeCommand({FunctionName:r,InvocationType:"RequestResponse",Payload:Buffer.from(JSON.stringify({schemaVersion:B,operation:"health",jobId:"health",taskId:n}),"utf8")})),o=s.Payload?JSON.parse(new TextDecoder().decode(s.Payload)):null;if(s.FunctionError||!o||typeof o!="object")throw new Error(`Remote ${t} health check failed: ${JSON.stringify(o)}`);return o}async writeWorkspaceObject(t){let r=fe(t.key,this.config.workspace.prefix),n=typeof t.body=="string"?Buffer.from(t.body,"utf8"):t.body,s=ee(n),o=await this.s3.send(new PutObjectCommand({Bucket:this.config.workspace.bucket,Key:r,Body:n,ContentType:t.contentType,...t.cacheControl?{CacheControl:t.cacheControl}:{},Metadata:{sha256:s,...t.metadata??{}}}));return {bucket:this.config.workspace.bucket,key:r,sha256:s,bytes:n.byteLength,contentType:t.contentType,...o.ETag?{etag:o.ETag}:{},...o.VersionId?{versionId:o.VersionId}:{}}}async copyWorkspaceObject(t,r){if(t.bucket!==this.config.workspace.bucket)throw new Error(`Remote worker object bucket mismatch: ${t.bucket}.`);let n=fe(t.key,this.config.workspace.prefix),s=fe(r,this.config.workspace.prefix),o=`${t.bucket}/${n.split("/").map(c=>encodeURIComponent(c)).join("/")}`,i=await this.s3.send(new CopyObjectCommand({Bucket:t.bucket,Key:s,CopySource:o,MetadataDirective:"COPY"}));return {...t,key:s,...i.CopyObjectResult?.ETag?{etag:i.CopyObjectResult.ETag}:{},...i.VersionId?{versionId:i.VersionId}:{}}}};function Xs(e,t,r){if(!e||typeof e!="object")throw new Error("Remote render result must be a JSON object.");let n=e;if(n.schemaVersion!==B||!n.response||n.response.operation!=="render"||n.response.jobId!==t.jobId||n.response.taskId!==t.taskId||!n.detail||!Array.isArray(n.detail.pages)||n.detail.pages.length!==r.length)throw new Error("Remote render result has an invalid envelope.");for(let[s,o]of r.entries())if(n.detail.pages[s]?.requestedUrl!==o)throw new Error("Remote render result does not match the requested URLs.");return n}function Ft(e){return e instanceof Error?e.message:String(e)}var ut=class{#e;#n;#t;#s;#c;#u;#r=[];#l=0;#o=0;#i=false;constructor(t){this.#e=t.client,this.#n=X(t.jobId,"jobId"),this.#t=Math.max(1,Math.min(5,t.maxAttempts??2)),this.#s=t.onRetry,this.#c=Math.max(1,Math.min(20,t.batchSize??1)),this.#u=Math.max(1,Math.min(100,t.maxConcurrentBatches??1));}async renderBatch(t){let r=[...new Set(t.urls)];if(r.length<1||r.length>20)throw new Error("Remote render batches require between 1 and 20 unique URLs.");let n=new Map,s=new Map,o=r;for(let i=1;i<=this.#t&&o.length>0;i+=1){this.#l+=1;let c=X(`render-${this.#l}-${ee(o.join(`
|
|
10
|
+
`)).slice(0,24)}-a${i}`,"taskId"),a=[];try{let l=await this.#e.invoke({schemaVersion:B,operation:"render",jobId:this.#n,taskId:c,sourceOrigin:new URL(t.sourceOrigin).origin,urls:o,options:t.options}),d=Xs(await this.#e.readResult(l),l,o);for(let u of d.detail.pages){if(u.outcome==="failed"||u.outcome==="deferred"||!u.html){let h=u.error||`Remote render ended with ${u.outcome}.`;s.set(u.requestedUrl,h),a.push(u.requestedUrl);continue}try{n.set(u.requestedUrl,{page:u,html:t.downloadHtml===!1?null:await this.#e.readObjectText(u.html),taskId:c,attempts:i}),s.delete(u.requestedUrl);}catch(h){s.set(u.requestedUrl,Ft(h)),a.push(u.requestedUrl);}}}catch(l){let d=Ft(l);for(let u of o)s.set(u,d),a.push(u);}if(i<this.#t)for(let l of a)this.#s?.({url:l,attempt:i,maxAttempts:this.#t,reason:s.get(l)??"Remote render failed."});o=a;}return {pages:r.flatMap(i=>{let c=n.get(i);return c?[c]:[]}),failures:o.map(i=>({url:i,attempts:this.#t,error:s.get(i)??"Remote render failed."}))}}async render(t){let r=JSON.stringify({sourceOrigin:new URL(t.sourceOrigin).origin,options:t.options,downloadHtml:t.downloadHtml!==false});return await new Promise((n,s)=>{this.#r.push({input:t,key:r,resolve:n,reject:s}),this.#a();})}#a(){this.#i||this.#r.length===0||(this.#i=true,setTimeout(()=>{this.#i=false,this.#d();},0));}#d(){for(;this.#o<this.#u&&this.#r.length>0;){let t=this.#r.shift();if(!t)break;let r=[t];for(let n=0;n<this.#r.length&&r.length<this.#c;){let s=this.#r[n];s?.key===t.key?(r.push(s),this.#r.splice(n,1)):n+=1;}this.#o+=1,this.renderBatch({sourceOrigin:t.input.sourceOrigin,urls:r.map(n=>n.input.url),options:t.input.options,...t.input.downloadHtml===void 0?{}:{downloadHtml:t.input.downloadHtml}}).then(n=>{let s=new Map(n.pages.map(i=>[i.page.requestedUrl,i])),o=new Map(n.failures.map(i=>[i.url,i]));for(let i of r){let c=s.get(i.input.url);if(c){i.resolve(c);continue}let a=o.get(i.input.url);i.reject(new Error(`Remote render failed after ${a?.attempts??this.#t} attempt(s) for ${i.input.url}: ${a?.error??"Unknown remote render failure."}`));}}).catch(n=>{let s=Ft(n);for(let o of r)o.reject(new Error(s,{cause:n}));}).finally(()=>{this.#o-=1,this.#a();});}this.#r.length>0&&this.#a();}};function eo(e,t,r){if(!e||typeof e!="object")throw new Error("Remote asset result must be a JSON object.");let n=e;if(n.schemaVersion!==B||n.response?.operation!=="asset"||n.response.jobId!==t.jobId||n.response.taskId!==t.taskId||!n.detail||!Array.isArray(n.detail.assets)||n.detail.assets.length!==r.length)throw new Error("Remote asset result has an invalid envelope.");for(let s=0;s<r.length;s+=1)if(n.detail.assets[s]?.requestedUrl!==r[s])throw new Error("Remote asset result does not match the requested URLs.");return n}var lt=class{#e;#n;#t;#s=0;constructor(t){this.#e=t.client,this.#n=X(t.jobId,"jobId"),this.#t=Math.max(1,Math.min(5,t.maxAttempts??2));}async fetch(t){let r=[...t.urls];if(r.length<1||r.length>20)throw new Error("Remote asset batches require between 1 and 20 URLs.");let n=null;for(let s=1;s<=this.#t;s+=1){this.#s+=1;let o=X(`asset-${this.#s}-${ee(r.join(`
|
|
11
|
+
`)).slice(0,24)}-a${s}`,"taskId");try{let i=await this.#e.invoke({schemaVersion:B,operation:"asset",jobId:this.#n,taskId:o,urls:r,options:{ignoreHttpsErrors:t.ignoreHttpsErrors,timeoutMs:Math.max(1e3,Math.min(12e4,t.timeoutMs??6e4))}});return {assets:eo(await this.#e.readResult(i),i,r).detail.assets,taskId:o,attempts:s}}catch(i){n=i;}}throw new Error(`Remote asset batch failed after ${this.#t} attempt(s): ${n instanceof Error?n.message:String(n)}`,{cause:n})}};function Vr(e,t){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.slice(n,n+t));return r}function Hr(e){return {sourceOrigin:e.sourceOrigin,targetOrigin:e.targetOrigin,urlRewriteMode:e.urlRewriteMode,outputDir:"/workspace",extraReplacements:e.extraReplacements,wpsuite:{...e.wpsuite?.subscriptionType?{subscriptionType:e.wpsuite.subscriptionType}:{},...e.wpsuite?.siteSettings?{siteSettings:{subscriber:e.wpsuite.siteSettings.subscriber===true}}:{}}}}function zr(e,t){if(!e||typeof e!="object")throw new Error("Remote rewrite result must be a JSON object.");let r=e;if(r.schemaVersion!==B||r.response?.operation!=="rewrite"||r.response.jobId!==t.jobId||r.response.taskId!==t.taskId||!r.detail||!Array.isArray(r.detail.objects))throw new Error("Remote rewrite result has an invalid envelope.");return r}async function Qr(e,t,r){let n=r.options??{},s=await Et(e,n.files);if(s.length===0)return 0;let o=X(r.jobId,"jobId"),i=Dt(r.client.config.workspace.prefix,"jobs",o,"rewrite-inputs"),c=`${i}/config.json`.replace(/\/+/g,"/"),a=`${i}/asset-map.json`.replace(/\/+/g,"/"),l=`${i}/previous-asset-map.json`.replace(/\/+/g,"/");await Promise.all([r.client.writeWorkspaceObject({key:c,body:JSON.stringify(Hr(e)),contentType:"application/json; charset=utf-8"}),r.client.writeWorkspaceObject({key:a,body:JSON.stringify(t),contentType:"application/json; charset=utf-8"}),r.client.writeWorkspaceObject({key:l,body:JSON.stringify(n.previousAssetMap??{}),contentType:"application/json; charset=utf-8"})]);let d=Math.max(1,Math.min(500,r.batchSize)),u=Math.ceil(s.length/d),h=Math.max(1,Math.min(Math.max(1,r.concurrency),u));await n.onStart?.({totalFiles:s.length,workerCount:h});let f=[],g=0,y=0;await Promise.all(Array.from({length:Math.min(16,s.length)},async()=>{for(;;){let O=g;if(O>=s.length)return;g+=1;let A=s[O],x=w.join(e.outputDir,A),v=Br.lookup(A),C=v?Br.contentType(v)||v:"text/plain; charset=utf-8",T=`${i}/files/${ee(A)}.txt`.replace(/\/+/g,"/");await r.client.writeWorkspaceObject({key:T,body:await M.readFile(x),contentType:C}),f[O]={relativePath:A,key:T,fullPath:x,contentType:C},y+=1,await r.onStageProgress?.({index:y,totalFiles:s.length,file:A});}}));let p=Vr(f,d),m=0,b=0,k=0,R=Array.from({length:h},async()=>{for(;;){let O=m;if(O>=p.length)return;m+=1;let A=p[O],x=null,v=null;for(let C=1;C<=Math.max(1,Math.min(5,r.maxAttempts));C+=1){let T=X(`rewrite-${O+1}-a${C}-${ee(A.map(D=>D.relativePath).join(`
|
|
12
|
+
`)).slice(0,16)}`,"taskId"),Q={schemaVersion:B,operation:"rewrite",jobId:o,taskId:T,configKey:c,assetMapKey:a,previousAssetMapKey:l,items:A.map(D=>({inputKey:D.key,outputKey:D.key,relativePath:D.relativePath,contentType:D.contentType}))};try{let D=await r.client.invoke(Q);v=zr(await r.client.readResult(D),D);break}catch(D){x=D;}}if(!v)throw new Error(`Remote rewrite batch ${O+1}/${p.length} failed: ${x instanceof Error?x.message:String(x)}`,{cause:x});for(let C of A){let T=v.detail.objects.find(Q=>Q.outputKey===C.key);if(!T)throw new Error(`Remote rewrite result omitted ${C.relativePath}.`);await me(C.fullPath,Buffer.from(await r.client.readObject(T.output))),T.changed&&(k+=1),b+=1,await n.onProgress?.({index:b,totalFiles:s.length,changedTextFiles:k,file:C.relativePath,changed:T.changed});}}});return await Promise.all(R),k}async function Kr(e,t,r,n){let s=n.relativePaths?new Set([...n.relativePaths].map(p=>p.replace(/\\/g,"/"))):null,o=Object.values(t.objects).filter(p=>p.isText&&(!s||s.has(p.relativePath))).sort((p,m)=>p.relativePath.localeCompare(m.relativePath));if(o.length===0)return 0;let i=X(n.jobId,"jobId"),c=Dt(n.client.config.workspace.prefix,"jobs",i,"rewrite-config"),a=`${c}/config.json`.replace(/\/+/g,"/"),l=`${c}/asset-map.json`.replace(/\/+/g,"/");await Promise.all([n.client.writeWorkspaceObject({key:a,body:JSON.stringify(Hr(e)),contentType:"application/json; charset=utf-8"}),n.client.writeWorkspaceObject({key:l,body:JSON.stringify(r),contentType:"application/json; charset=utf-8"})]);let d=Math.max(1,Math.min(500,n.batchSize)),u=Vr(o,d),h=Math.max(1,Math.min(Math.max(1,n.concurrency),u.length)),f=0,g=0,y=0;return await Promise.all(Array.from({length:h},async()=>{for(;;){let p=f;if(p>=u.length)return;f+=1;let m=u[p],b=null,k=null;for(let R=1;R<=Math.max(1,Math.min(5,n.maxAttempts));R+=1){let O=X(`rewrite-object-${p+1}-a${R}-${ee(m.map(A=>A.relativePath).join(`
|
|
13
|
+
`)).slice(0,16)}`,"taskId");try{let A=await n.client.invoke({schemaVersion:B,operation:"rewrite",jobId:i,taskId:O,configKey:a,assetMapKey:l,items:m.map(x=>({inputKey:x.object.key,outputKey:x.object.key,relativePath:x.relativePath,contentType:x.contentType||x.object.contentType}))});b=zr(await n.client.readResult(A),A);break}catch(A){k=A;}}if(!b)throw new Error(`Remote object rewrite batch ${p+1}/${u.length} failed: ${k instanceof Error?k.message:String(k)}`,{cause:k});for(let R of m){let O=b.detail.objects.find(A=>A.outputKey===R.object.key);if(!O)throw new Error(`Remote rewrite result omitted ${R.relativePath}.`);R.object=O.output,O.changed&&(y+=1),g+=1,await n.onProgress?.({index:g,totalFiles:o.length,changedTextFiles:y,file:R.relativePath,changed:O.changed});}}})),t.assetMap={...r},t.generatedAt=new Date().toISOString(),y}var no="remote-workers.json";function Jr(e={}){let t=String(e.explicitPath??"").trim();if(t)return w.resolve(t);let r=String(e.runtimeDir??process.env.STATIC_PUBLISHER_RUNTIME_DIR??process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR??"").trim();return r?w.join(w.resolve(r),no):""}function Gr(e,t,r,n=250){let s=Math.max(1,Math.floor(n)),o=[],i=new Set;for(let c of [e,...t]){let a=c.trim();if(!(!a||i.has(a)||r(a))&&(i.add(a),o.push(a),o.length>=s))break}return o}function so(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?w.resolve(e):""}function dt(e){let t=String(process.env.STATIC_PUBLISHER_REMOTE_EXPORT_MANIFEST_PATH||"").trim();if(t)return w.resolve(t);let r=so();if(r)return w.join(r,"remote-export-manifest.json");let n=w.resolve(e.outputDir);return w.join(w.dirname(n),`.${w.basename(n)}-remote-export-manifest.json`)}function qt(e){let t=w.posix.normalize(String(e||"").replace(/\\/g,"/").replace(/^\/+/,""));if(!t||t==="."||t===".."||t.startsWith("../")||/^[A-Za-z]:/.test(t))throw new Error(`Invalid remote export relative path: ${e}`);return t}function Yr(e,t,r){let n=r?.workspace.bucket===t.workspace.bucket&&r.workspace.prefix===t.workspace.prefix;return {schemaVersion:1,generatedAt:new Date().toISOString(),jobId:e,workspace:{...t.workspace},objects:n?{...r.objects}:{},assetMap:n?{...r.assetMap}:{}}}function Le(e,t){let r=qt(t.relativePath);if(t.object.bucket!==e.workspace.bucket)throw new Error(`Remote export object bucket mismatch for ${r}.`);fe(t.object.key,e.workspace.prefix),e.objects[r]={...t,relativePath:r},e.generatedAt=new Date().toISOString();}function Xr(e,t){delete e.objects[qt(t)],e.generatedAt=new Date().toISOString();}async function en(e,t){t.generatedAt=new Date().toISOString();let r=dt(e);await M.mkdir(w.dirname(r),{recursive:true}),await me(r,`${JSON.stringify(t,null,2)}
|
|
14
|
+
`,"utf8");}async function tn(e){try{let t=JSON.parse(await M.readFile(dt(e),"utf8"));if(t.schemaVersion!==1||typeof t.jobId!="string"||!t.workspace||typeof t.workspace.bucket!="string"||typeof t.workspace.prefix!="string"||!t.objects||typeof t.objects!="object"||!t.assetMap||typeof t.assetMap!="object")return null;let r=t;for(let[n,s]of Object.entries(r.objects)){if(qt(n),!s||s.relativePath!==n||s.object?.bucket!==r.workspace.bucket)return null;fe(s.object.key,r.workspace.prefix);}return r}catch{return null}}var co=["text/css","javascript","image/","font/","application/font","application/json","application/xml","text/xml","application/rss+xml","application/atom+xml","application/xslt+xml","text/xsl","image/svg+xml"],gn=new Set([".css",".js",".mjs",".json",".map",".xml",".xsl",".rss",".atom",".txt",".enc",".jws",".png",".jpg",".jpeg",".gif",".webp",".avif",".svg",".ico",".woff",".woff2",".ttf",".otf",".eot",".pdf",".mp4",".webm"]),fn=new Set(["",".html",".htm"]),uo=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),lo=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function po(e){let t=[],r="full",n="full",s=false,o=false,i="",c=null,a="";for(let l=0;l<e.length;l++){let d=e[l];if(d==="--retry-timeouts")r="retry-timeouts",s=true;else if(d==="--resume")s=true;else if(d==="--resume-rewrite")s=true,o=true;else if(d==="--crawl-mode"){let u=e[++l];if(!u)throw new Error("--crawl-mode requires a value");n=u==="incremental"?"incremental":"full",s||=n==="incremental";}else if(d.startsWith("--crawl-mode="))n=d.slice(13)==="incremental"?"incremental":"full",s||=n==="incremental";else if(d==="--incremental")n="incremental",s=true;else if(d==="--url"){let u=e[++l];if(!u)throw new Error("--url requires a value");r="single-url",s=true,t.push(u);}else if(d.startsWith("--url="))r="single-url",s=true,t.push(d.slice(6));else if(d==="--urls"){let u=e[++l];if(!u)throw new Error("--urls requires a file path");r="single-url",s=true,t.push(`@${u}`);}else if(d==="--content-sync-plan"){let u=e[++l];if(!u)throw new Error("--content-sync-plan requires a file path");r="content-sync",n="incremental",s=true,i=w.resolve(u);}else if(d.startsWith("--content-sync-plan="))r="content-sync",n="incremental",s=true,i=w.resolve(d.slice(20));else if(d==="--remote-render")c=true;else if(d==="--local-render")c=false;else if(d==="--remote-worker-config"){let u=e[++l];if(!u)throw new Error("--remote-worker-config requires a file path");a=w.resolve(u);}else d.startsWith("--remote-worker-config=")&&(a=w.resolve(d.slice(23)));}return {mode:r,crawlMode:n,urls:t,preserveOutput:s,resumeRewrite:o,contentSyncPlanPath:i,remoteRender:c,remoteWorkerConfigPath:a}}function Ze(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?w.resolve(e):""}function mo(){let e=Ze();return e?w.join(e,"privacy","cookie-observations.json"):null}function ho(){let e=Ze();return e?w.resolve(e,".."):""}function go(){let e=process.env.STATIC_PUBLISHER_WP_ROOT||process.env.WPSUITE_STATIC_PUBLISHER_WP_ROOT||"";return e.trim()?w.resolve(e):""}function fo(e){let t=e.trim(),r=[{alias:"@storage-root",root:ho(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@runtime",root:Ze(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@wp-root",root:go(),requiredEnv:"STATIC_PUBLISHER_WP_ROOT or WPSUITE_STATIC_PUBLISHER_WP_ROOT"}];for(let n of r){if(t!==n.alias&&!t.startsWith(`${n.alias}/`))continue;if(!n.root)return {resolvedPath:null,alias:n.alias,requiredEnv:n.requiredEnv};let s=t.slice(n.alias.length).replace(/^\/+/,"");return {resolvedPath:s?w.resolve(n.root,s):n.root,alias:n.alias}}return {resolvedPath:w.resolve(t)}}function wn(e){let t=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(t)return w.resolve(t);let r=Ze();return r?w.join(r,"crawl-manifest.json"):w.join(e.outputDir,".crawl-manifest.json")}function yn(){return {schemaVersion:6,updatedAt:"",pages:{},assets:{}}}function nn(e){return {url:String(e.url||""),outputPath:String(e.outputPath||""),contentType:typeof e.contentType=="string"&&e.contentType?e.contentType:null,changeToken:typeof e.changeToken=="string"?e.changeToken:null,tokenSource:typeof e.tokenSource=="string"?e.tokenSource:null,sitemapLastmod:typeof e.sitemapLastmod=="string"?e.sitemapLastmod:null,discoveredPages:Array.isArray(e.discoveredPages)?e.discoveredPages.map(t=>String(t)):[],discoveredAssets:Array.isArray(e.discoveredAssets)?e.discoveredAssets.map(t=>String(t)):[],lastCrawledAt:String(e.lastCrawledAt||""),lastSeenRunId:String(e.lastSeenRunId||""),rewriteComplete:e.rewriteComplete===true}}function wo(e){let t=e.isText===true;return {url:String(e.url||""),outputPath:String(e.outputPath||""),isText:t,contentType:typeof e.contentType=="string"&&e.contentType?e.contentType:null,cacheControl:typeof e.cacheControl=="string"&&e.cacheControl?e.cacheControl:null,changeToken:typeof e.changeToken=="string"?e.changeToken:null,tokenSource:typeof e.tokenSource=="string"?e.tokenSource:null,discoveredAssets:Array.isArray(e.discoveredAssets)?e.discoveredAssets.map(r=>String(r)):[],lastCrawledAt:String(e.lastCrawledAt||""),lastSeenRunId:String(e.lastSeenRunId||""),unreferencedRuns:Math.max(0,Number(e.unreferencedRuns)||0),rewriteComplete:e.rewriteComplete===true||!t}}function Bt(e){let t=e?.["content-type"]?.trim();return t||null}function Vt(e){let t=e?.["cache-control"]?.trim();return t||null}function yo(e){return e?e.split(",").map(t=>t.trim().toLowerCase()).some(t=>t==="no-cache"||t==="no-store"||/^max-age\s*=\s*0$/.test(t)):false}function bo(){return {rewriteTargets:new Set,changedFiles:new Set,deletedFiles:new Set,revalidateFiles:new Set}}function De(e,t,r,n){let s=Z(t.outputDir,r);s&&(yo(n)?e.revalidateFiles.add(s):e.revalidateFiles.delete(s));}function J(e,t,r){let n=Z(t.outputDir,r);n&&(e.changedFiles.add(n),e.deletedFiles.delete(n));}function Ht(e,t,r){let n=Z(t.outputDir,r);n&&(e.deletedFiles.add(n),e.changedFiles.delete(n),e.revalidateFiles.delete(n));}function te(e,t){e.rewriteTargets.add(w.resolve(t));}async function So(e){try{let t=await M.readFile(wn(e),"utf8"),r=JSON.parse(t);if(r&&typeof r=="object"&&r.pages&&typeof r.pages=="object"){if((r.schemaVersion===2||r.schemaVersion===3||r.schemaVersion===4||r.schemaVersion===5||r.schemaVersion===6)&&r.assets&&typeof r.assets=="object")return {schemaVersion:6,updatedAt:String(r.updatedAt||""),pages:Object.fromEntries(Object.entries(r.pages).map(([n,s])=>[n,nn(s)])),assets:Object.fromEntries(Object.entries(r.assets).map(([n,s])=>[n,wo(s)]))};if(r.schemaVersion===1)return {schemaVersion:6,updatedAt:String(r.updatedAt||""),pages:Object.fromEntries(Object.entries(r.pages).map(([n,s])=>[n,nn(s)])),assets:{}}}}catch{}return yn()}function zt(e){return JSON.parse(JSON.stringify(e))}async function Po(e,t){let r=wn(e);await M.mkdir(w.dirname(r),{recursive:true}),await M.writeFile(r,JSON.stringify(t,null,2),"utf8");}async function be(e,t,r=false){if(!t.trackManifest)return;t.manifestPendingChanges+=1;let n=Date.now();if(!r&&t.manifestPendingChanges<25&&n-t.lastManifestSavedAt<5e3)return;t.manifestPendingChanges=0,t.lastManifestSavedAt=n;let s=async()=>{let o=zt(t.manifest);o.updatedAt=new Date().toISOString(),t.manifest.updatedAt=o.updatedAt,await Po(e,o);};t.manifestSaveChain=t.manifestSaveChain.then(s,s),await t.manifestSaveChain;}function Te(e){if(!e)return null;let t=e.trim();return t||null}function Ro(e,t){let r=new Set,n=new Set([...Object.keys(e),...Object.keys(t)]);for(let s of n){let o=e[s],i=t[s];!o||!i||o===i||r.add(s);}return r}async function bn(e,t,r,n){let s=[...new Set(r.map(c=>c.trim()).filter(Boolean))],o=String(e.wpsuite?.runtimeToken||"").trim();if(s.length===0||!o)return new Map;let i=new URL("/wp-json/smartcloud-static-publisher/v1/change-tokens",e.sourceOrigin).toString();try{let c=await t.post(i,{timeout:3e4,failOnStatusCode:!1,headers:{"content-type":"application/json","x-static-publisher-token":o},data:JSON.stringify({urls:s})});if(!c.ok())return n.warn(`Change token lookup failed with HTTP ${c.status()}`,{endpoint:i,status:c.status()}),new Map;let a=await c.json().catch(()=>null);if(!a||!Array.isArray(a.items))return new Map;let l=new Map;for(let d of a.items)!d||typeof d.url!="string"||l.set(d.url,d);return l}catch(c){return n.warn("Change token lookup failed; falling back to sitemap metadata",{endpoint:i,error:c instanceof Error?`${c.name}: ${c.message.split(/\r?\n/u,1)[0]}`:"Unknown change-token request failure"}),new Map}}async function mt(e,t,r,n,s){if(!r.enabled&&!r.trackManifest)return null;if(r.changeTokenCache.has(n))return r.changeTokenCache.get(n)??null;let i=(await bn(e,t,[n],s)).get(n)??null;return yt(e,n)&&(!i||i.supported!==true||!i.token)&&(i=await Co(e,t,n,s)),i=Sn(e,i),r.changeTokenCache.set(n,i),i}async function Xt(e,t,r,n,s){if(!r.trackManifest)return;let o=[...new Set(n.map(i=>i.trim()).filter(Boolean))].filter(i=>!r.changeTokenCache.has(i));for(let i=0;i<o.length;i+=250){let c=o.slice(i,i+250),a=await bn(e,t,c,s);for(let l of c)r.changeTokenCache.set(l,Sn(e,a.get(l)??null));}}async function vo(e,t,r,n,s,o){if(!(!n.trackManifest||n.changeTokenCache.has(s)))for(;!n.changeTokenCache.has(s);){if(!n.pageChangeTokenPrimePromise){let i=Gr(s,r.pageQueue,a=>n.changeTokenCache.has(a));if(i.length===0)return;o.info(`Loading ${i.length} page change tokens in bulk.`,{phase:"prime-page-change-tokens",batchSize:i.length,remainingPages:r.pageQueue.length});let c=Xt(e,t,n,i,o).finally(()=>{n.pageChangeTokenPrimePromise===c&&(n.pageChangeTokenPrimePromise=null);});n.pageChangeTokenPrimePromise=c;}await n.pageChangeTokenPrimePromise;}}function ko(e){return `subscriber=${e.wpsuite?.siteSettings?.subscriber===true?"1":"0"}`}function Sn(e,t){if(!t?.supported||!t.token||t.tokenSource==="wp-media-file")return t;let r=ko(e);return {...t,token:oe(`${t.token}
|
|
15
|
+
${r}`,40),tokenSource:t.tokenSource?`${t.tokenSource}+site-subscriber`:"site-subscriber"}}async function Co(e,t,r,n){try{let s=await t.get(r,{timeout:Math.min(e.navigationTimeoutMs,15e3),failOnStatusCode:!1});if(s.status()!==404)return n.warn(`Generated 404 fallback token skipped for ${r}`,{url:r,status:s.status(),requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),null;let o=await s.text().catch(()=>""),i=oe(`${r}
|
|
15
16
|
404
|
|
16
|
-
${o}`,40);return n.info(`Using generated 404 fallback change token for ${r}`,{url:r,requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),{url:r,supported:!0,token:i,tokenSource:"generated-404-response-hash",postId:null,dependencyPostIds:[],reason:null}}catch(s){return n.warn(`Generated 404 fallback token lookup failed for ${r}`,{url:r,error:String(s),requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),null}}async function fn(e,t,r,n,s,o){let i=ft(e,s);if(await yo(e,t,r,n,s,o),!n.enabled)return {action:"render",changeToken:n.trackManifest?await dt(e,t,n,s,o):null};let c=n.manifest.pages[s];if(!c)return {action:"render",changeToken:await dt(e,t,n,s,o)};let a=await dt(e,t,n,s,o);if(a?.supported&&a.token)return c.changeToken===a.token?i&&!await Po(e,t,s,o)?{action:"render",changeToken:a}:{action:"reuse",changeToken:a}:{action:"render",changeToken:a};let l=Ie(r.sitemapLastmodByPage[s]);return l&&c.sitemapLastmod&&c.sitemapLastmod===l?{action:"reuse",changeToken:a}:{action:"render",changeToken:a}}async function Po(e,t,r,n){try{let o=(await t.get(r,{timeout:Math.min(e.navigationTimeoutMs,15e3),failOnStatusCode:!1})).status();return o===404?!0:(n.warn(`Generated 404 request path no longer returns 404 for ${r}`,{url:r,status:o,requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),!1)}catch(s){return n.warn(`Generated 404 status probe failed for ${r}`,{url:r,error:String(s),requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),false}}async function Ro(e,t,r,n,s){let o=en(r.previousManifest,void 0,n,"previous-manifest"),i=0;for(let[g,f]of Object.entries(r.manifest.pages))if(!r.seenPages.has(g)){_t(s,e,f.outputPath);try{await O.unlink(f.outputPath);}catch(h){(h.code||"")!=="ENOENT"&&n.warn(`Failed to remove stale incremental page output for ${g}`,{url:g,outputPath:f.outputPath,error:String(h)});}delete r.manifest.pages[g],i++;}let c=en(r.manifest,r.runId,n,"active-manifest"),a=new Set,l=new Set;for(let g of c){for(let b of Ke(e,g))a.add(b);let f=r.manifest.assets[g]?.outputPath;f&&l.add(f);let h=Fe(e,t.assetMap,g);h&&l.add(h);}for(let g of Object.keys(r.manifest.assets)){if(c.has(g)){r.manifest.assets[g].unreferencedRuns=0;continue}let f=r.manifest.assets[g];if(Or(f.unreferencedRuns)){f.unreferencedRuns+=1,n.warn(`Deferred deletion of newly unreferenced incremental asset ${g}.`,{url:g,unreferencedRuns:f.unreferencedRuns,phase:"incremental-cleanup",source:"asset-deletion-grace"});continue}delete r.manifest.assets[g];}let d=0,u=0;for(let g of o){if(r.manifest.assets[g])continue;let f=new Set,h=r.previousManifest.assets[g]?.outputPath;h&&f.add(h);let b=Fe(e,t.assetMap,g);if(!c.has(g)&&b)f.add(b);else if(!c.has(g)){let p=Wo(e,g,n,"incremental-cleanup");p&&(f.add(p.originalFilePath),p.hashedFilePath&&f.add(p.hashedFilePath));}for(let p of f)if(!l.has(p)){_t(s,e,p);try{await O.unlink(p),d++;}catch(m){(m.code||"")!=="ENOENT"&&n.warn(`Failed to remove stale incremental asset output for ${g}`,{url:g,outputPath:p,error:String(m)});}}for(let p of Ke(e,g))a.has(p)||Object.prototype.hasOwnProperty.call(t.assetMap,p)&&(delete t.assetMap[p],u++);}(i>0||d>0||u>0)&&n.info(`Incremental cleanup removed ${i} stale pages, ${d} stale assets, ${u} stale asset mappings`,{removedPages:i,removedAssets:d,removedAssetMappings:u,phase:"incremental-cleanup"});}async function vo(e,t,r,n){let s=new Set([...Object.values(t.manifest.pages),...Object.values(t.manifest.assets)].map(a=>String(a.outputPath||"").trim()).filter(Boolean).map(a=>w.resolve(a))),o=Object.values(e.postCrawlCopyMap||{}).map(a=>pt(String(a||""))).filter(a=>!!a).map(a=>w.resolve(e.outputDir,a)),c=(await us(["**/*.html","**/*.htm"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(a=>Er(w.join(e.outputDir,a),e.outputDir,s,o));for(let a of c){let l=w.join(e.outputDir,a);_t(n,e,l),await O.unlink(l);}c.length>0&&r.info(`Removed ${c.length} orphaned HTML output file(s) that are absent from the current crawl manifest.`,{phase:"incremental-cleanup",source:"manifest-output-reconciliation",removedPages:c.length,samples:c.slice(0,20)});}function en(e,t,r,n){let s=new Set,o=i=>{let c=i.trim();if(c){if(r){let a=re(c,r,"asset",n??"manifest");if(!a)return;s.add(a.toString());return}s.add(c);}};for(let i of Object.values(e.pages))for(let c of i.discoveredAssets||[])o(c);for(let[i,c]of Object.entries(e.assets||{}))t&&c.lastSeenRunId!==t||o(i);return s}function tn(e,t,r){for(let n of t)for(let s of Ke(e,n))if(r.has(s))return true;return false}function ko(e,t,r,n,s){let o=new Set(r.rewriteTargets);for(let c of r.changedFiles)o.add(w.resolve(e.outputDir,c));for(let c of Object.values(t.manifest.pages))c.rewriteComplete||o.add(w.resolve(c.outputPath));for(let c of Object.values(t.manifest.assets))c.isText&&!c.rewriteComplete&&o.add(w.resolve(c.outputPath));let i=wo(n,s);if(i.size===0)return [...o];for(let c of Object.values(t.manifest.pages))tn(e,c.discoveredAssets,i)&&o.add(w.resolve(c.outputPath));for(let[c,a]of Object.entries(t.manifest.assets)){a.isText&&tn(e,a.discoveredAssets,i)&&o.add(w.resolve(a.outputPath));for(let l of Ke(e,c))if(i.has(l)){Q(r,e,a.outputPath),a.isText&&o.add(w.resolve(a.outputPath));break}}return [...o]}function Co(e,t){let r=t?new Set(Array.from(t,s=>w.resolve(s))):null,n=s=>r===null||r.has(w.resolve(s));for(let s of Object.values(e.manifest.pages))n(s.outputPath)&&(s.rewriteComplete=true);for(let s of Object.values(e.manifest.assets)){if(!s.isText){s.rewriteComplete=true;continue}n(s.outputPath)&&(s.rewriteComplete=true);}}function xo(e,t,r){let n=new Set,s=o=>{if(!o)return;let i=Y(e.outputDir,o);i&&n.add(i);};for(let o of t.donePages)s(le(e,o));for(let o of Object.values(r.manifest.pages))o.lastSeenRunId===r.runId&&s(o.outputPath);for(let o of t.doneAssets)s(Fe(e,t.assetMap,o));for(let o of Object.values(r.manifest.assets))o.lastSeenRunId===r.runId&&s(o.outputPath);return n}async function Ao(e,t,r,n,s,o){let i=[...n.deletedFiles].sort(),c=xo(e,t,r),a=0;for(let u of [...c].sort())if(!o?.objects[u]){try{if((await O.stat(w.join(e.outputDir,u))).isFile())continue}catch{}a++,s.warn(`Active output is missing after crawl: ${u}`,{phase:"deploy-plan",file:u,outputPath:w.join(e.outputDir,u)});}if(a>0&&s.warn(`Detected ${a} active output file(s) missing before deploy plan save.`,{phase:"deploy-plan",missingActiveOutputs:a}),i.length===0)return [];let l=[],d=0;for(let u of i){if(!c.has(u)){l.push(u);continue}d++;let g=w.join(e.outputDir,u),f;try{f=(await O.stat(g)).isFile();}catch{f=false;}s.warn(`Deploy plan protected active output from deletion: ${u}`,{phase:"deploy-plan",file:u,outputPath:g,exists:f});}return d>0&&s.info(`Deploy plan skipped ${d} active output deletion(s).`,{phase:"deploy-plan",protectedDeletes:d,deletedFiles:l.length}),l}function Ke(e,t){let r=new Set([t]);try{let n=new URL(t),o=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{o.push(new URL(e.targetOrigin).origin);}catch{}for(let i of o)try{r.add(new URL(i).origin+n.pathname+n.search);}catch{}r.add(n.pathname+n.search),r.add(n.pathname);}catch{}return [...r]}function To(e,t){let r=new Set([t]);try{let n=new URL(t),o=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{o.push(new URL(e.targetOrigin).origin);}catch{}for(let i of o)try{r.add(new URL(i).origin+n.pathname+n.search);}catch{}r.add(n.pathname+n.search);}catch{}return [...r]}function wn(e,t){let r=e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/"?e.targetOrigin:"https://relative.invalid/";try{let n=new URL(t,r);return He(e.outputDir,n.pathname)}catch{return null}}function yn(e,t,r){for(let n of To(e,r)){let s=t[n];if(!s)continue;let o=wn(e,s);if(o)return {outputPath:o,publicUrl:s}}return null}function Io(e,t,r){for(let n of Ke(e,r)){let s=t[n];if(!s)continue;let o=wn(e,s);if(o)return o}return null}function Fe(e,t,r){let n=Io(e,t,r);if(n)return n;try{return Ye(e,r).originalFilePath}catch{return null}}function Eo(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?w.join(w.resolve(e),"queue-runner-heartbeat.json"):""}async function Ft(e){let t=Eo();if(t)try{let r=await O.readFile(t,"utf8"),n=JSON.parse(r);if(!n||typeof n!="object")return;await O.writeFile(t,JSON.stringify({...n,checkedAt:new Date().toISOString(),status:"running",currentStep:"rewrite",message:e},null,2),"utf8");}catch{}}function Oo(e,t){let r=new Set;for(let n of t.donePages)r.add(w.resolve(le(e,n)));for(let n of t.doneAssets){let s=Fe(e,t.assetMap,n);!s||!ie(s)||r.add(w.resolve(s));}for(let n of t.doneSitemaps){let s=Fe(e,t.assetMap,n);!s||!ie(s)||r.add(w.resolve(s));}return [...r]}var mt="re:",lt=new Map;function Mo(e){if(!e.startsWith(mt))return null;let t=lt.get(e);if(t!==void 0)return t||null;let r=e.slice(mt.length).trim();if(!r)return lt.set(e,false),null;try{let n=new RegExp(r);return lt.set(e,n),n}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),lt.set(e,false),null}}function Zt(e,t){let r=Mo(t);return r?r.test(e):t.startsWith(mt)?false:e.startsWith(t)}function $o(e,t){return t.find(r=>Zt(e,r))}function bn(e,t){let r=$o(t.pathname,e.blockedPathPrefixes);if(r)return r.startsWith(mt)?`blocked path regex: ${r}`:`blocked path prefix: ${r}`;let n=e.blockedSearchFragments.find(s=>t.search.includes(s));return n?`blocked search fragment: ${n}`:null}function jo(e){let t=new URL(e.sourceOrigin),r=new Set([t.hostname,...e.allowedAssetHosts]);if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{r.add(new URL(e.targetOrigin).hostname);}catch{}for(let n of Object.keys(e.extraReplacements||{}))try{r.add(new URL(n).hostname);}catch{}return r}function Uo(e,t){return jo(e).has(t.hostname)}function Lo(e){let t=ge(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function Bt(e){let t=ge(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function Do(e){let t=ge(e).replace(/\\\//g,"/").trim(),r=w.extname(t).toLowerCase();return ln.has(r)||dn.has(r)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function Oe(e){return oo.some(t=>e.pathname.startsWith(t))}function H(e,t,r=e.sourceOrigin,n,s="url",o=false){let i=Lo(t);if(!i||i.startsWith("data:")||i.startsWith("blob:")||i.startsWith("mailto:")||i.startsWith("tel:")||i.startsWith("#"))return n?.ignore(s,t,"empty or unsupported scheme",r),null;if(Bt(i))return n?.ignore(s,t,"looks like JavaScript/code fragment",r),null;if(Do(i))return n?.ignore(s,t,"looks like JavaScript property access",r),null;try{let c=new URL(i,r);if(Sn(c))return n?.reject(s,t,"malformed URL encoding",r),null;if(!["http:","https:"].includes(c.protocol))return n?.ignore(s,t,"unsupported protocol: ",r),null;if(!Uo(e,c))return n?.ignore(s,c.toString(),"host not allowed",r),null;let a=bn(e,c);if(a&&!(o&&St(c)))return n?.reject(s,c.toString(),a,r),null;let l=new URL(e.sourceOrigin);return c.protocol=l.protocol,c.host=l.host,c.hash="",c}catch{return n?.reject(s,t,"invalid URL",r),null}}function Sn(e){try{return decodeURIComponent(e.pathname),decodeURIComponent(e.search),decodeURIComponent(e.hash),!1}catch{return true}}function re(e,t,r,n){try{let s=new URL(e);return Sn(s)?(t.reject(r,e,"malformed URL encoding",n),null):Be(s.pathname)===null?(t.reject(r,e,"unsafe URL pathname",n),null):s.protocol!=="http:"&&s.protocol!=="https:"?(t.reject(r,e,`unsupported protocol: ${s.protocol}`,n),null):s}catch{return t.reject(r,e,"invalid URL",n),null}}function Pn(e){return ln.has(w.extname(e.pathname).toLowerCase())}function Se(e){return Oe(e)?false:dn.has(w.extname(e.pathname).toLowerCase())}function qe(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function W(e,t){return !!(qe(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(r=>Zt(t.pathname,r))||Pn(t)||!Se(t)&&!Oe(t))}function le(e,t){let r=new URL(t),n=Be(r.pathname);if(n===null)throw new Error(`Unsafe page URL pathname: ${r.pathname}`);return n.endsWith("/")?n+="index.html":w.extname(n)||(n+="/index.html"),He(e.outputDir,n)}function Fo(e){if(!e.generated404RequestPath)return null;try{let t=new URL(e.generated404RequestPath,e.sourceOrigin);return !t.pathname.endsWith("/")&&w.extname(t.pathname)===""&&(t.pathname+="/"),t.hash="",t.toString()}catch{return null}}function ft(e,t){let r=Fo(e);if(!r)return false;try{return new URL(t,e.sourceOrigin).toString()===r}catch{return false}}function Ye(e,t){let r=new URL(t),n=Be(r.pathname);if(n===null)throw new Error(`Unsafe asset URL pathname: ${r.pathname}`);n.endsWith("/")&&(n+="index.html");let s=!!r.search,o=n,i=He(e.outputDir,o),c=Ct(e.targetOrigin,o),a=`${c}${r.search}`;if(!s)return {originalPathname:o,originalFilePath:i,originalPublicUrl:c,originalPublicUrlWithSearch:a,preferQueryHashed:s};let l=w.extname(n),u=`${l?n.slice(0,-l.length):n}.${oe(r.search)}${l||".bin"}`;return {originalPathname:o,originalFilePath:i,originalPublicUrl:c,originalPublicUrlWithSearch:a,preferQueryHashed:s,hashedPathname:u,hashedFilePath:He(e.outputDir,u),hashedPublicUrl:Ct(e.targetOrigin,u)}}function Wo(e,t,r,n){let s=re(t,r,"asset",n);return s?Ye(e,s.toString()):null}function Ht(e,t,r,n,s){t[r]=n;try{let o=new URL(r),c=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{c.push(new URL(e.targetOrigin).origin);}catch{}for(let a of c)try{let l=new URL(a);t[l.origin+o.pathname+o.search]=n;}catch{}try{let a=(()=>{let l=new URL(n,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin);return `${l.pathname}${l.search}`})();t[o.pathname+o.search]=a;}catch{}try{let a=new URL(n,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[o.pathname]=a;}catch{}try{let a=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[o.pathname]=a;}catch{}}catch{}}async function Rn(e){try{return await O.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Ee(e){try{return await O.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function qo(e){let t=String(e["content-length"]||"").trim();if(!t)return null;let r=Number.parseInt(t,10);return Number.isFinite(r)&&r>=0?r:null}function vn(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let r=Date.parse(t);return Number.isFinite(r)?r:null}function No(e,t){let r=vn(t),n=qo(t),s=e?.mtime.getTime();return r!==null&&Math.abs((s??0)-r)>=1e3||n!==null&&e?.size!==n?false:r!==null||n!==null}async function _o(e,t){if(!t)return;let r=vn(t);if(r===null)return;let n=await Ee(e);if(!n)return;let s=new Date(r);await O.utimes(e,n.atime,s).catch(()=>{});}function zt(e,t){let r=w.extname(e.pathname).toLowerCase(),n=t["content-type"]||"";return so.has(r)||no.some(s=>n.includes(s))&&!n.startsWith("image/")&&!n.includes("font")}function Vo(e){try{let t=w.extname(new URL(e).pathname).toLowerCase();return t===".js"||t===".mjs"}catch{return false}}function Ce(e,t){(e.doneAssets.size%25===0||e.doneAssets.size===1||e.doneAssets.size===e.stats.assetsQueued)&&t.progress(`Asset processing progress: processed ${e.doneAssets.size}, discovered ${e.stats.assetsQueued}.`,{doneAssets:e.doneAssets.size,assetsQueued:e.stats.assetsQueued,phase:"download-assets"});}function Bo(e){return oe(e.toString("base64"),40)}function kn(e,t,r){let n=e.assetVariantDigestsByOriginalPath.get(t);if(!n||n.size===0)return false;for(let s of n)if(s!==r)return true;return false}function Cn(e,t,r){let n=e.assetVariantDigestsByOriginalPath.get(t);n||(n=new Set,e.assetVariantDigestsByOriginalPath.set(t,n)),n.add(r);}async function Qt(e,t,r,n,s,o,i){let c=Ye(e,r),a=Bo(n),l=c.originalFilePath,d=c.originalPublicUrlWithSearch;if(c.preferQueryHashed&&c.hashedFilePath&&c.hashedPublicUrl&&kn(s,c.originalFilePath,a)){let h=yn(e,t,r);h?(l=h.outputPath,d=h.publicUrl):(l=c.hashedFilePath,d=c.hashedPublicUrl);}Ht(e,t,r,d,c.originalPublicUrl);let u=ie(l)?Buffer.from(It(n.toString("utf8"),e,t,l),"utf8"):n,g=await Rn(l),f=false;return (g===null||!g.equals(u))&&(await me(l,u),f=true),o?.debug(`${f?"Saved":"Skipped unchanged"} asset output ${r}`,{phase:"download-assets",url:r,outputPath:l,bytes:u.length,wroteFile:f}),Cn(s,c.originalFilePath,a),await _o(l,i),s.stats.assetsSaved++,o&&(s.stats.assetsSaved%50===0||s.stats.assetsSaved===1)&&o.progress(`Asset progress: saved ${s.stats.assetsSaved}, discovered ${s.stats.assetsQueued}, pending ${s.assetQueue.length}.`,{assetsSaved:s.stats.assetsSaved,assetsQueued:s.stats.assetsQueued,assetQueue:s.assetQueue.length,phase:"download-assets"}),{outputPath:l,publicUrl:d,wroteFile:f}}function Me(e,t,r,n,s){let o=()=>{let u=String(s??"").trim();if(!u)return {discoveredFrom:"",discoveredFromType:"unknown"};if(u==="seed-path"||u==="cli"||u==="generated-404-request-path")return {discoveredFrom:u,discoveredFromType:u};if(/^https?:\/\//i.test(u))try{let g=new URL(u);return qe(g)?{discoveredFrom:u,discoveredFromType:"sitemap"}:W(e,g)?{discoveredFrom:u,discoveredFromType:"asset"}:Se(g)&&!Oe(g)?{discoveredFrom:u,discoveredFromType:"page"}:{discoveredFrom:u,discoveredFromType:"url"}}catch{return {discoveredFrom:u,discoveredFromType:"url"}}return {discoveredFrom:u,discoveredFromType:"url"}},i=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,c=H(e,r,i,n,"page");if(!c)return;if(!Se(c)||Pn(c)){if(W(e,c)){n.info(`Seeded/non-page URL queued as asset: ${c.toString()}`,{url:c.toString(),source:s}),F(e,t,c.toString(),n,s);return}n.reject("page",c.toString(),Oe(c)?"asset/internal path cannot be page":"not page-like",s);return}let a=c.toString(),{discoveredFrom:l,discoveredFromType:d}=o();l&&!t.pageDiscoverySources.has(a)&&t.pageDiscoverySources.set(a,l),!t.donePages.has(a)&&!t.queuedPages.has(a)&&(t.queuedPages.add(a),t.pageQueue.push(a),t.stats.pagesQueued++,n.debug(`Queued discovered page ${a}`,{phase:"discovery",url:a,discoveredFrom:l,discoveredFromType:d,outputPath:le(e,a)}),(t.stats.pagesQueued%25===0||t.stats.pagesQueued===1)&&n.progress(`Discovery progress: pages ${t.stats.pagesQueued}, assets ${t.stats.assetsQueued}, sitemaps ${t.stats.sitemapsQueued}.`,{pagesQueued:t.stats.pagesQueued,assetsQueued:t.stats.assetsQueued,sitemapsQueued:t.stats.sitemapsQueued,pageQueue:t.pageQueue.length,phase:"discovery"}));}function F(e,t,r,n,s){let o=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,i=H(e,r,o,n,"asset");if(!i)return;if(!W(e,i)){n.reject("asset",i.toString(),"not a safe asset path/prefix",s);return}let c=i.toString();!t.doneAssets.has(c)&&!t.queuedAssets.has(c)&&(t.queuedAssets.add(c),t.assetQueue.push(c),t.stats.assetsQueued++,(t.stats.assetsQueued%100===0||t.stats.assetsQueued===1)&&n.progress(`Discovery progress: pages ${t.stats.pagesQueued}, assets ${t.stats.assetsQueued}, sitemaps ${t.stats.sitemapsQueued}.`,{pagesQueued:t.stats.pagesQueued,assetsQueued:t.stats.assetsQueued,sitemapsQueued:t.stats.sitemapsQueued,assetQueue:t.assetQueue.length,phase:"discovery"}));}function gt(e,t,r,n,s){let o=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,i=H(e,r,o,n,"sitemap",ur(s));if(!i)return;if(!qe(i)){n.reject("sitemap",i.toString(),"not sitemap-like",s);return}let c=i.toString();!t.doneSitemaps.has(c)&&!t.queuedSitemaps.has(c)&&(t.queuedSitemaps.add(c),t.sitemapQueue.push(c),t.stats.sitemapsQueued++,(t.stats.sitemapsQueued%10===0||t.stats.sitemapsQueued===1)&&n.progress(`Discovery progress: pages ${t.stats.pagesQueued}, assets ${t.stats.assetsQueued}, sitemaps ${t.stats.sitemapsQueued}.`,{pagesQueued:t.stats.pagesQueued,assetsQueued:t.stats.assetsQueued,sitemapsQueued:t.stats.sitemapsQueued,sitemapQueue:t.sitemapQueue.length,phase:"discovery"}));}function Ho(e){let t=ge(e),r=[...t.matchAll(/<url>\s*([\s\S]*?)\s*<\/url>/gi)].map(n=>n[1]);return r.length>0?r.map(n=>{let s=n.match(/<loc>\s*([^<]+?)\s*<\/loc>/i);if(!s?.[1])return null;let o=n.match(/<lastmod>\s*([^<]+?)\s*<\/lastmod>/i);return {loc:s[1].trim(),lastmod:Ie(o?.[1]??null)}}).filter(n=>!!n):[...t.matchAll(/<loc>\s*([^<]+?)\s*<\/loc>/gi)].map(n=>({loc:n[1].trim(),lastmod:null})).filter(n=>n.loc)}function zo(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function Qo(e){let t=[],r=/url\(\s*(?:"([^"]+)"|'([^']+)'|([^)]*?))\s*\)/gi;for(let n of e.matchAll(r)){let s=e.slice(Math.max(0,n.index-8),n.index);if(/\bnew\s+$/i.test(s))continue;let o=(n[1]||n[2]||n[3]||"").trim();o&&t.push(o);}return t}function Ko(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function Jo(e,t){if(t==="dom-style")return true;let r=(()=>{try{return w.extname(new URL(e).pathname).toLowerCase()}catch{return ""}})();return !(r===".js"||r===".mjs"||r===".map"||t.includes("javascript"))}function pt(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function xn(e,t,r,n){let s=[];await O.mkdir(t,{recursive:true});let o=await O.readdir(e,{withFileTypes:true});for(let i of o){let c=w.join(e,i.name),a=w.join(t,i.name);if(i.isDirectory()){s.push(...await xn(c,a,r,n));continue}await An(c,a,r,n)&&s.push(a);}return s}async function Go(e,t){try{let[r,n]=await Promise.all([O.stat(e),O.stat(t)]);if(r.size!==n.size)return !1;let[s,o]=await Promise.all([O.readFile(e),O.readFile(t)]);return s.equals(o)}catch{return false}}async function An(e,t,r,n){let s=w.resolve(t);return r.has(s)?(n.debug("Skipped post-crawl copy over crawled page output",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):await Go(e,t)?(n.debug("Skipped unchanged post-crawl copy target",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):(await O.mkdir(w.dirname(t),{recursive:true}),await O.copyFile(e,t),true)}async function Zo(e,t,r){let n=Object.entries(e.postCrawlCopyMap||{}).map(([c,a])=>({sourcePath:c.trim(),prefix:String(a||"").trim()}));if(n.length===0)return [];let s=0,o=[],i=new Set([...t.donePages].map(c=>w.resolve(le(e,c))));r.mark("copy-extra-paths");for(let c of n){let a=c.sourcePath,l=c.prefix;if(!a||!l){r.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:a,prefixPath:l});continue}let d=lo(a);if(!d.resolvedPath){r.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:a,alias:d.alias||"",requiredEnv:d.requiredEnv||"",prefixPath:l});continue}let u=d.resolvedPath,g=pt(l);if(!g){r.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:a,prefixPath:l});continue}let f;try{f=await O.stat(u);}catch{r.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:a,sourceAbs:u,prefixPath:l});continue}let h=w.resolve(e.outputDir,g);if(f.isDirectory()){let S=await xn(u,h,i,r);o.push(...S),s+=S.length,S.length>0&&r.progress(`Copied static directory to export: ${u} -> /${g}`,{phase:"copy-extra-paths",sourcePath:u,targetPath:`/${g}`,copiedItems:s,changedFiles:S.length});continue}let b=w.basename(u),p=l.endsWith("/")?w.join(h,b):h;await An(u,p,i,r)&&(o.push(p),s++,r.progress(`Copied static file to export: ${u} -> /${pt(l.endsWith("/")?`${l}${b}`:l)}`,{phase:"copy-extra-paths",sourcePath:u,targetPath:`/${pt(l.endsWith("/")?`${l}${b}`:l)}`,copiedItems:s}));}return r.endMark("copy-extra-paths",{mappedSources:n.length,copiedItems:s}),o}function We(e,t,r,n,s){let o=new Set,i=ge(r).replace(/\\\//g,"/"),c=s==="page-html"?Ko(i):i,a=Jo(t,s);if(a){for(let l of Qo(c)){let d=H(e,l,t,n,`${s}:css-url`);d&&W(e,d)&&o.add(d.toString());}for(let l of c.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let d=H(e,l[1],t,n,`${s}:css-import`);d&&W(e,d)&&o.add(d.toString());}}if(a||s==="page-html")for(let l of c.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let d=H(e,l[1],t,n,`${s}:xml-stylesheet`);d&&W(e,d)&&o.add(d.toString());}if(s==="page-html")for(let l of Ar(i)){let d=l.startsWith("//")?`${new URL(e.sourceOrigin).protocol}${l}`:l;if(Bt(d)){n.ignore(`${s}:serialized-url`,d,"looks like JavaScript/code fragment",t);continue}let u=H(e,d,t,n,`${s}:serialized-url`);u&&W(e,u)?o.add(u.toString()):u&&n.ignore("asset",u.toString(),"serialized URL did not pass safe asset path filter",t);}if(s!=="page-html"&&Vo(t))for(let l of Tr(i)){if(Bt(l)||!/\.(?:js|mjs)(?:[?#]|$)/i.test(l))continue;let d=H(e,l,t,n,`${s}:relative-asset`);d&&W(e,d)&&o.add(d.toString());}return [...o]}function Tn(e,t,r,n){let s=new Set,o=ge(r);for(let i of o.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let c=i[1],a=H(e,c,t,n,"page-link");a&&(bn(e,a)||Se(a)&&!Oe(a)&&!W(e,a)&&s.add(a.toString()));}return [...s]}async function rn(e,t,r,n,s,o,i=false,c=[]){let a=new Set(c),l=0,d=new Map,u=(g,f)=>{let h=[f],b=new Set;for(;h.length>0;){let p=h.pop();if(p===g)return true;b.has(p)||(b.add(p),h.push(...d.get(p)??[]));}return false};for(;r.sitemapQueue.length>0;){let g=r.sitemapQueue.shift();r.queuedSitemaps.delete(g);let f=re(g,n,"sitemap","sitemap-queue");if(!f)continue;let h=f.toString();if(r.doneSitemaps.has(h))continue;r.doneSitemaps.add(h),n.sitemap(`Fetching sitemap ${h}`,{url:h});let b=true;try{let p=await t.get(h,{timeout:6e4});if(b=!1,!p.ok()){if(n.skip("sitemap",h,p.status()),i&&!a.has(h))throw new Error(`Required child content-sync sitemap returned HTTP ${p.status()}: ${h}`);continue}let m=await p.body(),S=p.url()||h,k=re(S,n,"sitemap-response",h);if(!k)continue;let R=k.toString();r.successfulSitemaps.add(h),r.successfulSitemaps.add(R),a.has(h)&&(r.resolvedSitemapRoots.add(R),l+=1);let T=await Qt(e,r.assetMap,R,m,r,n);Q(s,e,T.outputPath),te(s,T.outputPath);let x=m.toString("utf8");/<sitemapindex(?:\s|>)/i.test(x)?r.sitemapIndexUrls.add(R):r.sitemapLeafUrls.add(R);let C=We(e,R,x,n,"sitemap");for(let A of C)F(e,r,A,n,R);let v=[];for(let A of Ho(x)){let I=H(e,A.loc,R,n,"sitemap-loc",!0);if(!I){if(i)throw new Error(`Content-sync sitemap contains an inadmissible location: ${A.loc}`);continue}if(qe(I)){if(u(R,I.toString()))throw new Error(`Sitemap index cycle detected: ${R} -> ${I.toString()}`);if(d.has(R)||d.set(R,new Set),d.get(R).add(I.toString()),v.push(I.toString()),i&&r.doneSitemaps.has(I.toString())&&!r.successfulSitemaps.has(I.toString()))throw new Error(`Required child content-sync sitemap was not resolved: ${I.toString()}`);gt(e,r,I.toString(),n,R);}else if(i){if(Se(I)&&!W(e,I)){let N=o.requiredUrls.has(I.toString()),P=o.manifest.pages[I.toString()],M=!!P&&!!await Ee(P.outputPath);if(!N&&!M)throw new Error(`Content-sync sitemap coverage is incomplete for ${I.toString()}.`)}n.ignore("sitemap-loc",I.toString(),"content-sync sitemap-only traversal does not enqueue urlset locations",R);}else W(e,I)?F(e,r,I.toString(),n,R):Se(I)?(A.lastmod&&(r.sitemapLastmodByPage[I.toString()]=A.lastmod),Me(e,r,I.toString(),n,R)):n.reject("sitemap-loc",I.toString(),"not page/sitemap/asset-like",R);}o.trackManifest&&(o.manifest.assets[R]={url:R,outputPath:T.outputPath,isText:!0,contentType:p.headers()["content-type"]??"application/xml",cacheControl:Nt(p.headers()),changeToken:null,tokenSource:null,discoveredAssets:[...new Set([...C,...v])],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0,rewriteComplete:!1},await be(e,o));}catch(p){n.error(`Failed sitemap ${h}`,{url:h,error:String(p)});let m=i&&a.has(h)&&b;if(i&&!m)throw p}}if(i&&a.size>0&&l===0)throw new Error(`None of the configured content-sync sitemap roots could be resolved: ${[...a].join(", ")}`)}async function Yo(e,t,r,n,s,o,i){let c=H(e,n,e.sourceOrigin,s,"asset-fetch");if(!c||!W(e,c))return;let a=c.toString();if(r.doneAssets.has(a))return;let l=o.enabled||o.strictTargeted?o.previousManifest.assets[a]:void 0,d=o.trackManifest?await dt(e,t,o,a,s):null,u=d?.token??null,g=Ot(l?.changeToken,d),f=o.strictTargeted&&(!d?.supported||!d.token)&&Mt(e.sourceOrigin,a),h=o.strictTargeted?o.manifest.assets[a]:void 0;if(h?.lastSeenRunId===o.runId&&await Ee(h.outputPath)){r.doneAssets.add(a);for(let p of h.discoveredAssets||[])F(e,r,p,s,a);Q(i,e,h.outputPath),De(i,e,h.outputPath,h.cacheControl),h.isText&&te(i,h.outputPath),s.info(`Resumed completed content-sync asset ${a}`,{url:a,source:"content-sync-checkpoint"}),Ce(r,s);return}if(l&&(g||f)&&await Ee(l.outputPath)){o.manifest.assets[a]={...l,changeToken:u,tokenSource:d?.tokenSource??l.tokenSource,discoveredAssets:[...l.discoveredAssets||[]],lastSeenRunId:o.runId,unreferencedRuns:0},delete o.manifest.pages[a],r.doneAssets.add(a);for(let p of l.discoveredAssets||[])F(e,r,p,s,a);De(i,e,l.outputPath,l.cacheControl),s.info(`Reused unchanged trusted asset ${a}.`,{url:a,tokenSource:d?.tokenSource??"unknown",phase:"download-assets",source:g?"asset-change-token-match":"content-sync-release-fingerprint"}),Ce(r,s);return}let b=(p,m={})=>{if(!l||o.strictTargeted)return false;o.manifest.assets[a]={...l,discoveredAssets:[...l.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0},delete o.manifest.pages[a],r.doneAssets.add(a);for(let S of l.discoveredAssets||[])F(e,r,S,s,a);return s.warn(`Keeping previous incremental asset ${a} after fetch issue.`,{url:a,reason:p,preservedFromPreviousManifest:true,...m,phase:"download-assets"}),Ce(r,s),true};s.asset(`Fetching asset ${a}`,{url:a});try{let p=Fe(e,r.assetMap,a),m=p?await Ee(p):null;if(p&&m&&!o.strictTargeted)try{let P=await B(`fetch asset headers ${a}`,6e4,()=>t.head(a,{timeout:6e4})),M=P.headers();if(P.ok()&&No(m,M)){let J=await Rn(p);if(J!==null){let G=P.url()||a,E=re(G,s,"asset-response",a);if(!E)return;let D=E.toString(),L=await Qt(e,r.assetMap,D,J,r,s,M);L.wroteFile&&(Q(i,e,L.outputPath),ie(L.outputPath)&&te(i,L.outputPath));let Z=Nt(M)||l?.cacheControl||null;De(i,e,L.outputPath,Z),r.doneAssets.add(a),s.info(`Reused existing asset ${a} based on response headers.`,{url:a,filePath:p,lastModified:M["last-modified"]||"",contentLength:M["content-length"]||"",phase:"download-assets"}),Ce(r,s);let de=zt(c,M),ne=l?.discoveredAssets?[...l.discoveredAssets]:[];if(de||l?.isText){let Pe=J.toString("utf8"),Ne=We(e,D,Pe,s,"asset:cached");(Ne.length>0||!l)&&(ne=Ne);for(let y of ne)F(e,r,y,s,D);}if(o.trackManifest){let Pe=de||!!l?.isText;o.manifest.assets[a]={url:a,outputPath:L.outputPath,isText:Pe,contentType:qt(M)||l?.contentType||null,cacheControl:Z,changeToken:d?.supported?d.token:null,tokenSource:d?.supported?d.tokenSource??null:null,discoveredAssets:ne,lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0,rewriteComplete:!Pe},delete o.manifest.pages[a],(o.enabled||o.strictTargeted)&&Pe&&await be(e,o);}return}}}catch{}let S=await B(`fetch asset ${a}`,6e4,()=>t.get(a,{timeout:6e4}));if(!S.ok()){if(b(`http-${S.status()}`,{status:S.status()}))return;if(o.strictTargeted)throw new Error(`Required content-sync asset returned HTTP ${S.status()}: ${a}`);s.skip("asset",a,S.status());return}let k=await B(`read asset response ${a}`,6e4,()=>S.body()),R=S.url()||a,T=re(R,s,"asset-response",a);if(!T)return;let x=T.toString(),C=S.headers(),v=await Qt(e,r.assetMap,x,k,r,s,C);v.wroteFile&&(Q(i,e,v.outputPath),ie(v.outputPath)&&te(i,v.outputPath));let A=Nt(C);De(i,e,v.outputPath,A),r.doneAssets.add(a),Ce(r,s);let I=zt(c,C),N=[];if(I){let P=k.toString("utf8");N=We(e,x,P,s,`asset:${w.extname(c.pathname).toLowerCase()||C["content-type"]||"unknown"}`);for(let M of N)F(e,r,M,s,x);}o.trackManifest&&(o.manifest.assets[a]={url:a,outputPath:v.outputPath,isText:I,contentType:qt(C),cacheControl:A,changeToken:d?.supported?d.token:null,tokenSource:d?.supported?d.tokenSource??null:null,discoveredAssets:N,lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0,rewriteComplete:!I},delete o.manifest.pages[a],(o.enabled||o.strictTargeted)&&I&&await be(e,o));}catch(p){if(b("fetch-error",{error:String(p)}))return;if(s.error(`Failed asset ${a}`,{url:a,error:String(p)}),o.strictTargeted)throw p}finally{r.doneAssets.has(a)||(r.doneAssets.add(a),Ce(r,s));}}async function Xo(e,t,r,n,s,o){let i=Math.max(1,Number(e.assetDownloadConcurrency||e.concurrency||1)),c=Array.from({length:i},async()=>{for(;r.assetQueue.length>0;){let a=r.assetQueue.shift();a&&(r.queuedAssets.delete(a),await Yo(e,t,r,a,n,s,o));}});await Promise.all(c);}function ht(e,t){let r=Y(e.outputDir,t);if(!r)throw new Error(`Remote export output is outside outputDir: ${t}`);return r}function ei(e,t){return zt(e,{"content-type":t})}function nn(e){return /(?:^|\/)index\.html?$|\.html?$/i.test(e)}async function ti(e,t,r,n,s,o,i,c,a){let l=Math.max(1,Math.min(100,a)),d=20;for(;r.assetQueue.length>0;){let u=r.assetQueue.splice(0,l*d);for(let b of u)r.queuedAssets.delete(b);await Gt(e,t,s,u,n);let g=[];for(let b of u){let p=s.manifest.assets[b],m=p?Y(e.outputDir,p.outputPath):null,S=m?i.objects[m]:void 0,k=s.changeTokenCache.get(b)??null;if(!(s.enabled&&p&&S?.kind==="asset"&&S.sourceUrl===b&&(Ot(p.changeToken,k)||(!k?.supported||!k.token)&&Mt(e.sourceOrigin,b)))||!p||!m||!S){g.push(b);continue}s.manifest.assets[b]={...p,changeToken:k?.token??null,tokenSource:k?.tokenSource??p.tokenSource,lastSeenRunId:s.runId,unreferencedRuns:0};for(let T of p.discoveredAssets||[])F(e,r,T,n,b);r.doneAssets.add(b),De(o,e,p.outputPath,p.cacheControl),n.info(`Reused unchanged S3-native asset ${b}.`,{url:b,relativePath:m,tokenSource:k?.tokenSource??"release-fingerprint",phase:"download-assets",execution:"lambda"}),Ce(r,n);}if(g.length===0)continue;let f=[];for(let b=0;b<g.length;b+=d)f.push(g.slice(b,b+d));let h=await Promise.all(f.map(b=>c.fetch({urls:b,ignoreHttpsErrors:e.ignoreHttpsErrors,timeoutMs:6e4})));for(let b of h)for(let p of b.assets){let m=p.requestedUrl;try{if(p.outcome!=="fetched"||!p.object||!p.finalUrl){let A=p.error||`Remote asset fetch ended with ${p.outcome}.`;if(n.error(`Failed remote asset ${m}`,{url:m,status:p.httpStatus,outcome:p.outcome,error:A,execution:"lambda"}),s.strictTargeted)throw new Error(A);continue}let S=re(p.finalUrl,n,"remote-asset-response",m);if(!S)continue;let k=Ye(e,S.toString()),R=k.originalFilePath,T=k.originalPublicUrlWithSearch;if(k.preferQueryHashed&&k.hashedFilePath&&k.hashedPublicUrl&&kn(r,k.originalFilePath,p.object.sha256)){let A=yn(e,r.assetMap,S.toString());R=A?.outputPath??k.hashedFilePath,T=A?.publicUrl??k.hashedPublicUrl;}Ht(e,r.assetMap,S.toString(),T,k.originalPublicUrl),S.toString()!==m&&Ht(e,r.assetMap,m,T,k.originalPublicUrl),Cn(r,k.originalFilePath,p.object.sha256);let x=ht(e,R),C=p.contentType?.trim()||"application/octet-stream",v=ei(S,C);Le(i,{relativePath:x,sourceUrl:m,kind:"asset",contentType:C,cacheControl:p.cacheControl,isText:v,object:p.object}),Q(o,e,R),v&&te(o,R),De(o,e,R,p.cacheControl);for(let A of p.discoveredAssets)F(e,r,A,n,S.toString());r.stats.assetsSaved++,s.trackManifest&&(s.manifest.assets[m]={url:m,outputPath:R,isText:v,contentType:C,cacheControl:p.cacheControl,changeToken:null,tokenSource:null,discoveredAssets:[...p.discoveredAssets],lastCrawledAt:new Date().toISOString(),lastSeenRunId:s.runId,unreferencedRuns:0,rewriteComplete:!v},delete s.manifest.pages[m]),n.debug(`Remote asset fetch completed ${m}`,{url:m,finalUrl:S.toString(),relativePath:x,bytes:p.object.bytes,taskId:b.taskId,attempts:b.attempts,execution:"lambda"});}finally{r.doneAssets.add(m),Ce(r,n);}}}}async function ri(e,t,r,n){for(let s of [...t.changedFiles].sort()){if(r.objects[s])continue;let o=w.join(e.outputDir,s),i=await O.readFile(o).catch(d=>{throw new Error(`Coordinator-owned output is missing before S3 staging: ${s}`,{cause:d})}),c=ie(o),a=String(ro.lookup(s)||"")||(c?"text/plain; charset=utf-8":"application/octet-stream"),l=await n.writeWorkspaceObject({key:`${r.workspace.prefix}jobs/${r.jobId}/coordinator/${oe(s,40)}-${w.basename(s)}`,body:i,contentType:a,cacheControl:nn(s)?e.s3.htmlCacheControl:e.s3.assetCacheControl});Le(r,{relativePath:s,sourceUrl:null,kind:"generated",contentType:a,cacheControl:nn(s)?e.s3.htmlCacheControl:e.s3.assetCacheControl,isText:c,object:l});}}function ni(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function ye(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function Qe(e){return Math.max(15e3,Math.min(6e4,ye(e)))}function In(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function Yt(e){return e.stats.pagesCompleted}function Kt(e){let r=e.options?.browserProcess;return {pid:typeof r?.process?.pid=="number"?r.process.pid:null,kill:typeof r?.kill=="function"?r.kill.bind(r):null}}async function Wt(e,t,r){let n=Kt(e);try{if(n.kill){await n.kill(),t.warn(`Force-killed crawl worker browser after ${r}`,{browserPid:n.pid,reason:r});return}if(n.pid!==null){process.kill(n.pid,"SIGKILL"),t.warn(`Sent SIGKILL to crawl worker browser after ${r}`,{browserPid:n.pid,reason:r});return}t.warn(`Could not resolve crawl worker browser PID after ${r}`,{reason:r});}catch(s){t.error(`Failed to force-kill crawl worker browser after ${r}`,{browserPid:n.pid,reason:r,error:String(s)});}}async function B(e,t,r){let n;try{return await Promise.race([r(),new Promise((s,o)=>{n=globalThis.setTimeout(()=>{o(new Je(e,t));},t);})])}finally{n!==void 0&&globalThis.clearTimeout(n);}}var Je=class extends Error{constructor(r,n){super(`${r} timed out after ${ni(n)}.`);this.operation=r;this.timeoutMs=n;this.name="OperationTimeoutError";}operation;timeoutMs};async function si(e,t){let r=In(e);await t.evaluate(async n=>{await new Promise(s=>{let o=0,i=700,c=Date.now(),a=()=>{window.clearInterval(l),window.scrollTo(0,0),s();},l=window.setInterval(()=>{if(Date.now()-c>=n.maxDurationMs){a();return}window.scrollBy(0,i),o+=i;let d=document.body?.scrollHeight||0,u=document.documentElement?.scrollHeight||0,g=Math.max(d,u);o>=g+window.innerHeight&&a();},120);});},{maxDurationMs:r});}async function oi(e,t){await t.waitForLoadState("domcontentloaded",{timeout:e.readiness.timeoutMs}).catch(()=>{}),e.readiness.waitForSelector&&await t.waitForSelector(e.readiness.waitForSelector,{timeout:e.readiness.timeoutMs}).catch(()=>{}),e.readiness.waitForFunction&&await t.waitForFunction(e.readiness.waitForFunction,void 0,{timeout:e.readiness.timeoutMs}).catch(()=>{}),await si(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function ii(e,t){await t.waitForLoadState("domcontentloaded",{timeout:e.readiness.timeoutMs}).catch(()=>{}),await t.waitForLoadState("load",{timeout:e.readiness.timeoutMs}).catch(()=>{}),e.readiness.waitForSelector&&await t.waitForSelector(e.readiness.waitForSelector,{timeout:e.readiness.timeoutMs}).catch(()=>{}),await t.waitForTimeout(e.readiness.fallbackWaitMs);}function En(e,t){return e.noJavaScriptRenderPathPrefixes.some(r=>Zt(t,r))}async function ai(e,t,r,n,s=true){let o=new Set;if(s){let c=await t.evaluate(()=>{let a=new Set,l=["href","src","poster","data-src","data-lazy-src","data-original","data-bg","data-background","data-href","data-resource-url"],d=new Set,u=["srcset","data-srcset","data-lazy-srcset"],g=f=>{f.querySelectorAll("*").forEach(h=>{for(let p of l){let m=h.getAttribute(p);m&&a.add(m);}for(let p of u){let m=h.getAttribute(p);m&&m.split(",").forEach(S=>{let k=S.trim().split(/\s+/)[0];k&&a.add(k);});}let b=h.getAttribute("style");b&&d.add(b),h.shadowRoot&&g(h.shadowRoot);});};return g(document),{attrs:[...a],styles:[...d]}});for(let a of c.attrs)for(let l of zo(a)){let d=H(e,l,r,n,"dom-attr");d&&W(e,d)&&o.add(d.toString());}for(let a of c.styles)for(let l of We(e,r,a,n,"dom-style"))o.add(l);}let i=await t.content();for(let c of We(e,r,i,n,"page-html"))o.add(c);return [...o]}async function sn(e){return await e.evaluate(()=>{document.querySelectorAll("#wpsuite-consent-root").forEach(t=>t.remove()),document.documentElement.classList.remove("wpsuite-consent-scroll-locked"),document.body.classList.remove("wpsuite-consent-scroll-locked");}),e.content()}async function Jt(e,t,r,n,s){let o=le(e,t);await me(o,r,"utf8");let i=await O.stat(o);s?.debug(`Saved page output ${t}`,{phase:"save-pages",url:t,outputPath:o,bytes:i.size}),n.stats.pagesSaved++;let c=Math.min(n.stats.pagesQueued,Yt(n)+1);s&&(n.stats.pagesSaved%10===0||n.stats.pagesSaved===1)&&s.progress(`Page progress: processed ${c}, rendered ${n.stats.pagesRendered}, saved ${n.stats.pagesSaved}, discovered ${n.stats.pagesQueued}.`,{donePages:c,claimedPages:n.donePages.size,pagesRendered:n.stats.pagesRendered,pagesSaved:n.stats.pagesSaved,pagesQueued:n.stats.pagesQueued,pageQueue:n.pageQueue.length,phase:"save-pages"});}function On(e){let t=Yt(e);return t%5===0||t===1||t===e.stats.pagesQueued}function Mn(e,t){let r=Yt(e);t.progress(`Render progress: processed ${r}, rendered ${e.stats.pagesRendered}, saved ${e.stats.pagesSaved}, discovered ${e.stats.pagesQueued}.`,{donePages:r,claimedPages:e.donePages.size,pagesRendered:e.stats.pagesRendered,pagesSaved:e.stats.pagesSaved,pagesQueued:e.stats.pagesQueued,phase:"render-pages"});}async function ci(e){await e.addInitScript(()=>{Object.defineProperty(window,"__WPSUITE_STATIC_EXPORT__",{value:true,writable:false,configurable:true});let t=r=>{if(r==null||String(r)==="")return true;try{let n=new URL(String(r),window.location.href),s=new URL(window.location.href);return n.hash="",s.hash="",n.href===s.href}catch{return false}};try{let r=window.location.assign.bind(window.location),n=window.location.replace.bind(window.location),s=window.location.reload.bind(window.location);Object.defineProperty(window.location,"assign",{configurable:!0,value:o=>{if(t(o)){console.warn("[smartcloud-static-publisher] blocked same-page location.assign",o??"");return}return r(o)}}),Object.defineProperty(window.location,"replace",{configurable:!0,value:o=>{if(t(o)){console.warn("[smartcloud-static-publisher] blocked same-page location.replace",o??"");return}return n(o)}}),Object.defineProperty(window.location,"reload",{configurable:!0,value:()=>{console.warn("[smartcloud-static-publisher] blocked location.reload");}});}catch{}});}async function ui(e,t,r){let n=await e.newContext({viewport:t.viewport,userAgent:"WPSuiteStaticPublisher/0.8 Playwright SitemapOnly",ignoreHTTPSErrors:t.ignoreHttpsErrors,...r?{javaScriptEnabled:false}:{}});return r||await ci(n),n}async function li(e,t,r,n,s,o,i,c,a,l){for(;t.pageQueue.length>0&&!(e.maxPages>0&&t.donePages.size>=e.maxPages);){let d=t.pageQueue.shift();if(!d)break;t.queuedPages.delete(d);try{let u=re(d,r,"page","page-queue");if(!u)continue;let g=u.toString();if(d=g,t.queuedPages.delete(d),t.donePages.has(d))continue;t.donePages.add(d),o.enabled&&o.seenPages.add(d);let f=ft(e,d),h=En(e,u.pathname);if(!Se(u)||W(e,u)||Oe(u)){if(W(e,u)){r.info(`Remote worker redirected non-page URL to asset queue: ${d}`,{url:d,source:"remote-worker-guard"}),F(e,t,d,r,"remote-worker-guard");continue}r.reject("page",d,"guard rejected non-page URL before remote rendering","remote-worker");continue}let b=o.strictTargeted?o.manifest.pages[d]:void 0;if(b?.lastSeenRunId===o.runId&&await Ee(b.outputPath)){o.seenPages.add(d);for(let v of b.discoveredAssets||[])F(e,t,v,r,d);Q(i,e,b.outputPath),te(i,b.outputPath),r.info(`Resumed completed content-sync page ${d}`,{url:d,source:"content-sync-checkpoint"});continue}let p=await fn(e,s,t,o,d,r);if(o.enabled&&n!=="single-url"&&n!=="content-sync"){let v=o.manifest.pages[d];if(p.action==="reuse"&&v){for(let A of v.discoveredAssets)F(e,t,A,r,d);for(let A of v.discoveredPages)Me(e,t,A,r,d);v.lastSeenRunId=o.runId,v.sitemapLastmod=Ie(t.sitemapLastmodByPage[d])??v.sitemapLastmod,p.changeToken?.supported&&(v.changeToken=p.changeToken.token,v.tokenSource=p.changeToken.tokenSource??v.tokenSource),r.info(`Incremental reuse skipped unchanged page ${d}`,{url:d,mode:"incremental",reason:p.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}r.page(`Rendering remotely ${d}`,{url:d,execution:"lambda"});let m=await a.render({sourceOrigin:e.sourceOrigin,url:d,options:{ignoreHttpsErrors:e.ignoreHttpsErrors,javaScriptEnabled:!h,viewport:e.viewport,navigationTimeoutMs:e.navigationTimeoutMs,autoScrollTimeoutMs:In(e),readiness:e.readiness},downloadHtml:!l}),S=m.page,k=S.finalUrl?re(S.finalUrl,r,"remote-final-response",d)?.toString():void 0;if(n==="content-sync"&&k&&k!==g){if(o.deleteOnMissingUrls.has(d)){await Ge(e,o,i,d,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive route redirected to ${k}`,{url:d,finalResponseUrl:k,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${d} -> ${k}`)}let R=S.httpStatus;if(f){if(R!==404){r.error(`Generated 404 request path returned unexpected status for ${d}`,{url:d,expectedStatus:404,status:R,requestPath:e.generated404RequestPath,execution:"lambda"});continue}}else if(R!==null&&R>=400){if(n==="content-sync"&&(R===404||R===410)&&o.deleteOnMissingUrls.has(d)){await Ge(e,o,i,d,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive page ${d}`,{url:d,status:R,source:"content-sync-tombstone"});continue}if(n==="content-sync")throw new Error(`Required content-sync route returned HTTP ${R}: ${d}`);r.skip("page",d,R,t.pageDiscoverySources.get(d));continue}t.stats.pagesRendered++;let T=new Set;if(!l){if(m.html===null)throw new Error("Remote render did not return HTML for local output mode.");for(let v of We(e,g,m.html,r,"remote-page-html"))T.add(v);}for(let v of [...S.discoveredAssets,...S.networkUrls]){let A=H(e,v,g,r,"remote-render");A&&W(e,A)&&T.add(A.toString());}for(let v of T)F(e,t,v,r,d);let x=n!=="single-url"&&n!=="content-sync"&&!f?[...new Set([...!l&&m.html!==null?Tn(e,d,m.html,r):[],...S.discoveredPages])]:[];for(let v of x)Me(e,t,v,r,d);for(let v of S.cookies){let A=v.sameSite==="Strict"||v.sameSite==="Lax"||v.sameSite==="None"?v.sameSite:"Unspecified",I=!Number.isFinite(v.expires)||v.expires<=0;c.add({name:v.name,domain:v.domain,path:v.path||"/",expires:I?null:v.expires,session:I,secure:v.secure,httpOnly:v.httpOnly,sameSite:A,partitioned:v.partitioned===!0});}let C=le(e,d);if(l){if(!S.html)throw new Error("Remote render completed without a workspace HTML object.");Le(l,{relativePath:ht(e,C),sourceUrl:d,kind:"page",contentType:S.contentType?.trim()||"text/html; charset=utf-8",cacheControl:e.s3.htmlCacheControl,isText:!0,object:S.html});}else {if(m.html===null)throw new Error("Remote render did not return HTML for local output mode.");await Jt(e,d,m.html,t,r);}Q(i,e,C),te(i,C),o.trackManifest&&(o.manifest.pages[d]={url:d,outputPath:C,contentType:S.contentType?.trim()||null,changeToken:p.changeToken?.supported?p.changeToken.token:null,tokenSource:p.changeToken?.supported?p.changeToken.tokenSource??null:null,sitemapLastmod:Ie(t.sitemapLastmodByPage[d])??null,discoveredPages:x,discoveredAssets:[...T],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,rewriteComplete:!1},(o.enabled||o.strictTargeted)&&await be(e,o)),r.debug(`Remote render completed ${d}`,{url:d,taskId:m.taskId,attempts:m.attempts,execution:"lambda"});}catch(u){if(r.error(`Failed remote page ${d}`,{url:d,error:String(u),execution:"lambda"}),o.strictTargeted)throw u}finally{t.stats.pagesCompleted++,On(t)&&Mn(t,r);}}}async function di(e,t,r,n,s,o,i,c){let a=await chromium.launch({headless:true}),l=Kt(a);l.pid!==null&&r.debug(`Launched crawl worker browser PID ${l.pid}`,{browserPid:l.pid});try{for(;t.pageQueue.length>0;){a||(a=await chromium.launch({headless:!0}),l=Kt(a),l.pid!==null&&r.debug(`Relaunched crawl worker browser PID ${l.pid}`,{browserPid:l.pid}));let d=a;if(e.maxPages>0&&t.donePages.size>=e.maxPages)break;let u=t.pageQueue.shift();if(!u)break;t.queuedPages.delete(u);let g=null,f=null,h=!1,b=[],p=new Set;try{let m=re(u,r,"page","page-queue");if(!m)continue;let S=m.toString();if(u=S,t.queuedPages.delete(u),t.donePages.has(u))continue;t.donePages.add(u),o.enabled&&o.seenPages.add(u);let k=ft(e,u),R=En(e,m.pathname);if(!Se(m)||W(e,m)||Oe(m)){if(W(e,m)){r.info(`Worker redirected non-page URL to asset queue: ${u}`,{url:u,source:"worker-guard"}),F(e,t,u,r,"worker-guard");continue}r.reject("page",u,"guard rejected non-page URL before rendering","worker");continue}let T=o.strictTargeted?o.manifest.pages[u]:void 0;if(T?.lastSeenRunId===o.runId&&await Ee(T.outputPath)){o.seenPages.add(u);for(let E of T.discoveredAssets||[])F(e,t,E,r,u);Q(i,e,T.outputPath),te(i,T.outputPath),r.info(`Resumed completed content-sync page ${u}`,{url:u,source:"content-sync-checkpoint"});continue}let x=await fn(e,s,t,o,u,r);if(o.enabled&&n!=="single-url"&&n!=="content-sync"){let E=o.manifest.pages[u];if(x.action==="reuse"&&E){for(let D of E.discoveredAssets)F(e,t,D,r,u);for(let D of E.discoveredPages)Me(e,t,D,r,u);E.lastSeenRunId=o.runId,E.sitemapLastmod=Ie(t.sitemapLastmodByPage[u])??E.sitemapLastmod,x.changeToken?.supported&&(E.changeToken=x.changeToken.token,E.tokenSource=x.changeToken.tokenSource??E.tokenSource),r.info(`Incremental reuse skipped unchanged page ${u}`,{url:u,mode:"incremental",reason:x.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}g=await B(`create page context ${u}`,ye(e),()=>ui(d,e,R)),f=await B(`create page ${u}`,ye(e),()=>g.newPage()),b=await g.cookies();let C=!1,v=new Set;await f.route("**/*",async E=>{let D=E.request();try{let L=H(e,D.url(),e.sourceOrigin,r,"network-request");L&&W(e,L)&&(v.add(L.toString()),F(e,t,L.toString(),r,u));}catch{}if(D.isNavigationRequest()&&D.frame()===f.mainFrame())try{let L=new URL(D.url()),Z=new URL(S);if(L.hash="",Z.hash="",L.href===Z.href){if(C){r.warn(`Blocked same-page navigation/reload for ${u}`,{url:u,requestUrl:D.url()});try{await E.abort("aborted");}catch(de){r.debug(`Ignored canceled route while blocking reload for ${u}`,{url:u,error:String(de)});}return}C=!0;}}catch{}try{await E.continue();}catch(L){r.debug(`Ignored canceled network route for ${u}`,{url:u,requestUrl:D.url(),error:String(L)});}}),f.on("response",E=>{try{let L=H(e,E.url(),e.sourceOrigin,r,"network-response");L&&W(e,L)&&(v.add(L.toString()),F(e,t,L.toString(),r,u));}catch{}let D=E.headerValues("set-cookie").then(L=>{for(let Z of L)c.add($r(Z,E.url()));}).catch(()=>{}).then(()=>{});p.add(D),D.finally(()=>p.delete(D));}),r.page(`Rendering ${u}`,{url:u});let A=null,I=null;try{if(A=await f.goto(u,{waitUntil:"domcontentloaded",timeout:e.navigationTimeoutMs}),A&&A.ok())try{I=await B(`read response body ${u}`,ye(e),()=>A.text());}catch{I=null;}}catch(E){r.warn(`Navigation issue for ${u}; saving current DOM if available`,{url:u,error:String(E)});}if(n==="content-sync"&&A){let E=re(A.url(),r,"content-sync-final-response",u)?.toString();if(E&&E!==S){if(o.deleteOnMissingUrls.has(u)){await Ge(e,o,i,u,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive route redirected to ${E}`,{url:u,finalResponseUrl:E,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${u} -> ${E}`)}}if(k){let E=A?.status()??null;if(E!==404){r.error(`Generated 404 request path returned unexpected status for ${u}`,{url:u,expectedStatus:404,status:E,requestPath:e.generated404RequestPath});continue}r.info(`Capturing rendered 404 page for ${u}`,{url:u,status:E,outputPath:le(e,u)});}else if(A&&!A.ok()){if(n==="content-sync"&&(A.status()===404||A.status()===410)&&o.deleteOnMissingUrls.has(u)){await Ge(e,o,i,u,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive page ${u}`,{url:u,status:A.status(),source:"content-sync-tombstone"}),await f.close();continue}if(n==="content-sync")throw new Error(`Required content-sync route returned HTTP ${A.status()}: ${u}`);r.skip("page",u,A.status(),t.pageDiscoverySources.get(u)),await f.close();continue}R?(r.info(`Rendering without JS execution for ${u}`,{url:u,mode:"no-js"}),await B(`wait for rendered page ${u}`,ye(e),()=>ii(e,f))):await B(`wait for rendered page ${u}`,ye(e),()=>oi(e,f)),t.stats.pagesRendered++;let N=await B(`extract rendered assets ${u}`,ye(e),()=>ai(e,f,S,r,!R));for(let E of N)F(e,t,E,r,u);let P=[...new Set([...N,...v])],M=I??await B(`capture rendered html ${u}`,ye(e),()=>sn(f)),J=n!=="single-url"&&n!=="content-sync"&&!k?Tn(e,u,M,r):[];if(n!=="single-url"&&n!=="content-sync"&&!k)for(let E of J)Me(e,t,E,r,u);await Jt(e,u,M,t,r);let G=le(e,u);if(Q(i,e,G),te(i,G),o.trackManifest){let E=A?.headers();o.manifest.pages[u]={url:u,outputPath:G,contentType:qt(E),changeToken:x.changeToken?.supported?x.changeToken.token:null,tokenSource:x.changeToken?.supported?x.changeToken.tokenSource??null:null,sitemapLastmod:Ie(t.sitemapLastmodByPage[u])??null,discoveredPages:J,discoveredAssets:P,lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,rewriteComplete:!1},(o.enabled||o.strictTargeted)&&await be(e,o);}}catch(m){if(h=m instanceof Je,o.strictTargeted)throw r.error(`Failed required content-sync page ${u}`,{url:u,error:String(m)}),m;if(h)r.warn(`Skipped partial DOM for timed-out page ${u}`,{url:u,error:String(m),recovery:"recycle-worker-browser"});else try{let S=f?await B(`capture partial html ${u}`,ye(e),()=>sn(f)):"";if(S&&S.trim()){await Jt(e,u,S,t,r);let k=le(e,u);if(Q(i,e,k),te(i,k),o.trackManifest){let R=o.manifest.pages[u]??o.previousManifest.pages[u];o.manifest.pages[u]={url:u,outputPath:k,contentType:R?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:Ie(t.sitemapLastmodByPage[u])??R?.sitemapLastmod??null,discoveredPages:R?.discoveredPages?[...R.discoveredPages]:[],discoveredAssets:R?.discoveredAssets?[...R.discoveredAssets]:[],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,rewriteComplete:!1},(o.enabled||o.strictTargeted)&&await be(e,o);}r.warn(`Saved partial DOM for ${u}`,{url:u,error:String(m)});}}catch(S){S instanceof Je&&(h=!0),r.error(`Could not save partial DOM for ${u}`,{url:u,error:String(S)});}r.error(`Failed page ${u}`,{url:u,error:String(m)});}finally{if(!h&&f&&await B(`drain network routes ${u}`,Qe(e),()=>f.unrouteAll({behavior:"wait"})).catch(m=>{h=!0,r.warn(`Could not drain network routes for ${u}`,{url:u,browserPid:l.pid,error:String(m),recovery:"recycle-worker-browser"});}),h&&(a=null,await Wt(d,r,`page operation timeout for ${u}`),await d.close().catch(()=>{})),p.size>0&&await Promise.allSettled([...p]),!h&&g)try{let m=await g.cookies();c.addAll(jr(b,m));}catch{}t.stats.pagesCompleted++,On(t)&&Mn(t,r),!h&&f&&await B(`close page ${u}`,Qe(e),()=>f.close()).catch(m=>{h=!0,r.warn(`Timed out while closing page ${u}`,{url:u,browserPid:l.pid,error:String(m),recovery:"recycle-worker-browser"});}),!h&&g&&await B(`close page context ${u}`,Qe(e),()=>g.close()).catch(m=>{h=!0,r.warn(`Timed out while closing page context for ${u}`,{url:u,browserPid:l.pid,error:String(m),recovery:"recycle-worker-browser"});}),h&&a===d&&(a=null,await Wt(d,r,`page cleanup timeout for ${u}`),await d.close().catch(()=>{}));}}}finally{if(a){let d=a;await B("close worker browser",Qe(e),()=>d.close()).catch(u=>(r.warn("Timed out while closing crawl worker browser",{browserPid:l.pid,error:String(u)}),Wt(d,r,"browser.close timeout")));}}}async function pi(e){try{let t=await O.readFile(e),n=(e.endsWith(".gz")?gunzipSync(t):t).toString("utf8").trim();if(!n)return [];try{let s=JSON.parse(n);if(Array.isArray(s))return s;if(s&&typeof s=="object")return [s]}catch{return n.split(/\r?\n/).map(s=>s.trim()).filter(Boolean).map(s=>{try{let o=JSON.parse(s);return o&&typeof o=="object"?o:null}catch{return null}}).filter(s=>s!==null)}return []}catch{return []}}function on(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function mi(e){let t=String(e?.job?.command||"").trim(),r=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:r!=="incremental"}function gi(e){let t=[e?.archivedAt,e?.job?.endedAt,e?.job?.startedAt];for(let r of t){let n=Date.parse(String(r||""));if(Number.isFinite(n))return n}return 0}async function $n(e){try{let t=await O.readFile(e,"utf8"),r=JSON.parse(t);return r&&typeof r=="object"&&!Array.isArray(r)?r:null}catch{return null}}function an(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function hi(e,t){let r=Array.isArray(t?.artifacts)?t.artifacts.filter(n=>String(n?.role||"").trim()==="errors"&&String(n?.storedFileName||"").trim()!=="").sort((n,s)=>an(n)-an(s)).map(n=>w.join(e,String(n.storedFileName))):[];return [...new Set([...r,w.join(e,"errors.jsonl"),w.join(e,"errors.json"),w.join(e,"errors.jsonl.gz"),w.join(e,"errors.json.gz")])]}async function cn(e){let t=await $n(w.join(e,"job.json"));for(let r of hi(e,t)){let n=await pi(r);if(n.length>0)return n}return []}async function fi(e){let t=w.join(e.logDir,"archive"),r;try{r=await O.readdir(t);}catch{return ""}let n="",s=0;for(let o of r){let i=w.join(t,o);if(!(await O.stat(i).catch(()=>null))?.isDirectory())continue;let a=await $n(w.join(i,"job.json"));if(!mi(a))continue;let l=gi(a);l>=s&&(s=l,n=i);}return n}async function wi(e){let t=await fi(e),r=t!==""?await cn(t):await cn(e.logDir),n=new Set;for(let s of r)if(on(s.error)||on(s.message)){let o=s.url;typeof o=="string"&&o&&n.add(o);}return [...n]}async function yi(e){let t=[];for(let r of e)if(r.startsWith("@")){let n=r.slice(1),s=await O.readFile(n,"utf8");t.push(...s.split(/\r?\n/).map(o=>o.trim()).filter(o=>o&&!o.startsWith("#")));}else t.push(r);return t}async function bi(e){if(!e)throw new Error("Content-sync crawl requires an immutable impact plan.");let t=JSON.parse(await O.readFile(e,"utf8"));return ar(t),t}function Si(e,t){let r;try{r=new URL(e);}catch{return false}return t.archiveFamilies.some(n=>{let s=new URL(n.url);if(r.origin!==s.origin)return false;if(r.toString()===s.toString())return true;if(r.searchParams.has("paged")&&r.pathname===s.pathname)return /^\d+$/.test(r.searchParams.get("paged")||"");let o=s.pathname.replace(/\/+$/,""),i=r.pathname.slice(o.length).replace(/^\/+/,""),c=String(n.paginationBase||"page").replace(/^\/+|\/+$/g,"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return r.pathname.startsWith(`${o}/`)&&new RegExp(`^${c}/\\d+/?$`).test(i)})}function ze(e,t,r){let n=r==="page"?le(e,t):Ye(e,t).originalFilePath;return Y(e.outputDir,n)}async function Ge(e,t,r,n,s){let o=t.manifest.pages[n];if(!o)return;let i=Y(e.outputDir,o.outputPath);if(!i)throw new Error(`Manifest-owned page path escaped output root: ${n}`);let c=w.resolve(o.outputPath);Object.entries(t.manifest.pages).some(([l,d])=>l!==n&&!s.has(l)&&w.resolve(d.outputPath)===c)||(await O.rm(o.outputPath,{force:true}),r.deletedFiles.add(i),r.revalidateFiles.delete(i)),delete t.manifest.pages[n];}async function Pi(e,t,r,n,s){let o=t.manifest.assets[n];if(!o)return;let i=Y(e.outputDir,o.outputPath);if(!i)throw new Error(`Manifest-owned resource path escaped output root: ${n}`);let c=w.resolve(o.outputPath);Object.entries(t.manifest.assets).some(([l,d])=>l!==n&&!s.has(l)&&w.resolve(d.outputPath)===c)||(await O.rm(o.outputPath,{force:true}),r.deletedFiles.add(i)),delete t.manifest.assets[n];}function Ri(e,t){let r=new Set,n=[...t];for(;n.length>0;){let s=n.shift();if(r.has(s))continue;r.add(s);let o=e.assets[s];for(let i of o?.discoveredAssets??[])try{qe(new URL(i))&&n.push(i);}catch{}}return r}async function vi(e,t,r,n,s){let o=Ri(r.previousManifest,s);for(let i of o){if(t.successfulSitemaps.has(i))continue;let c=r.previousManifest.assets[i];if(!c)continue;let a=Y(e.outputDir,c.outputPath);if(!a)throw new Error(`Manifest-owned sitemap path escaped output root: ${i}`);await O.rm(c.outputPath,{force:true}),n.deletedFiles.add(a),delete r.manifest.assets[i];}await be(e,r);}async function ki(e){try{let t=await O.readFile(w.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function Ci(e){let t=["crawl.log.jsonl","current-crawl-event.json","rejected.jsonl","ignored.jsonl","skipped-http.jsonl","errors.jsonl","timings.jsonl","rejected.json","ignored.json","skipped-http.json","errors.json","timings.json"];await O.mkdir(e,{recursive:true}),await Promise.all(t.map(async r=>{try{await O.unlink(w.join(e,r));}catch(n){if(n.code!=="ENOENT")throw n}}));}function un(e,t,r,n,s){let o=H(e,r,e.sourceOrigin,n,"manual-url");o&&(qe(o)?gt(e,t,o.toString(),n,s):W(e,o)?F(e,t,o.toString(),n,s):Se(o)?Me(e,t,o.toString(),n,s):n.reject("manual-url",o.toString(),"not page/sitemap/asset-like",s));}async function jn(e=process.argv.slice(2)){let t=[],r=await Xe(void 0,{onRemotePublisherConfigDiagnostic:y=>{t.push(y);}}),n=cr(r.sitemapPaths),s=t.at(-1)??null,o=io(e),i=o.mode==="content-sync"?await bi(o.contentSyncPlanPath):null;if(o.resumeRewrite&&o.mode!=="full")throw new Error("--resume-rewrite is only supported for full crawl/publish jobs.");let c=[];o.mode==="retry-timeouts"&&(c=await wi(r)),o.mode==="single-url"&&(c=await yi(o.urls)),i&&(c=[...i.directRenderUrls,...i.archiveFamilyUrls,...i.resourceRenderUrls]);let a=o.crawlMode==="incremental"&&o.mode==="full",l=a&&typeof r.subscriptionType=="string"&&r.subscriptionType.trim()!=="";if(i&&r.subscriptionType!=="PROFESSIONAL"&&r.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let d=(o.mode==="full"||o.mode==="single-url"||o.mode==="content-sync")&&!o.resumeRewrite,u=o.mode!=="full"||o.resumeRewrite||l,g=u?await ki(r):{},f=l||o.mode==="single-url"||o.mode==="content-sync"?await ho(r):mn(),h=new Set(c),b=new Set;if(i){for(let y of i.archiveFamilies)if(y.foundPosts===0)for(let $ of y.pageUrls)b.add($);for(let y of Object.keys(f.pages))Si(y,i)&&!h.has(y)&&(c.push(y),b.add(y));}let p={enabled:l,trackManifest:d,manifest:Vt(f),previousManifest:Vt(f),runId:i?.jobId??`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,pageChangeTokenPrimePromise:null,manifestSaveChain:Promise.resolve(),manifestPendingChanges:0,lastManifestSavedAt:Date.now(),strictTargeted:!!i,requiredUrls:h,deleteOnMissingUrls:b};await Ci(r.logDir);let m=new je(r.logDir,r.logLevel),S=o.remoteRender??r.remoteWorkers?.render?.enabled===true,k=Hr({explicitPath:o.remoteWorkerConfigPath,runtimeDir:Ze()}),R=null,T=null,x=null,C=null,v=Math.max(1,r.concurrency),A=r.remoteWorkers?.rewrite?.enabled===true,I=r.remoteWorkers?.deploy?.enabled===true,N=S&&A&&I&&!o.resumeRewrite;if(!N&&o.mode==="full"&&!o.resumeRewrite&&await O.rm(ut(r),{force:true}),S&&!o.resumeRewrite||A){if(!k)throw new Error("Remote Lambda workers are enabled, but the runtime directory is unknown. Run through queue-runner with --runtime-dir, set STATIC_PUBLISHER_RUNTIME_DIR, or use --remote-worker-config for a diagnostic run.");let y=await Wr(k);if(x=new it(y),N){if(!y.functions.asset)throw new Error("Full Lambda delegation requires an asset worker. Redeploy the Lambda worker stack and reinstall remote-workers.json.");let $=u?await Zr(r):null;C=Kr(`crawl-${oe(p.runId,40)}`,y,$),T=new ct({client:x,jobId:C.jobId,maxAttempts:2}),m.info("S3-native Lambda data plane is enabled.",{execution:"lambda",assetWorker:y.functions.asset,workspaceBucket:y.workspace.bucket,workspacePrefix:y.workspace.prefix});}}if(S&&!o.resumeRewrite){if(!x)throw new Error("Remote render worker client was not initialized.");R=new at({client:x,jobId:`crawl-${oe(p.runId,40)}`,maxAttempts:r.remoteWorkers?.render?.maxAttempts??2,onRetry:y=>{m.warn(`Retrying remote render for ${y.url}`,{url:y.url,attempt:y.attempt,maxAttempts:y.maxAttempts,reason:y.reason,execution:"lambda"});}}),v=Math.max(1,Math.min(100,N?r.concurrency:r.remoteWorkers?.render?.concurrency??r.concurrency)),m.info("Lambda page rendering is enabled.",{remoteWorkerConfigPath:w.resolve(k),concurrency:v,maxAttempts:r.remoteWorkers?.render?.maxAttempts??2,batchSize:1,execution:"lambda"});}if(s){let y={status:s.status,virtualAssetBaseUrl:s.virtualAssetBaseUrl,subscriptionType:s.subscriptionType??null,error:s.error,requests:s.requests,source:"remote-publisher-config"};s.status==="loaded"&&s.subscriptionType?m.info("Loaded remote WP Suite publisher configuration.",y):m.warn("Remote WP Suite publisher configuration is unavailable or has no active subscription type.",y);}if(a&&!l){let y="Incremental crawl requires an active remote publisher subscription; refusing to fall back to a destructive full crawl.";throw m.error(y,{requestedMode:o.crawlMode,subscriptionType:r.subscriptionType??null,source:"incremental-subscription-guard"}),await m.flush(),new Error(y)}let P={pageQueue:[],queuedPages:new Set,donePages:new Set,pageDiscoverySources:new Map,assetQueue:[],queuedAssets:new Set,doneAssets:new Set,sitemapQueue:[],queuedSitemaps:new Set,doneSitemaps:new Set,successfulSitemaps:new Set,resolvedSitemapRoots:new Set,sitemapIndexUrls:new Set,sitemapLeafUrls:new Set,sitemapLastmodByPage:{},assetMap:{...g},assetVariantDigestsByOriginalPath:new Map,stats:{pagesQueued:0,pagesRendered:0,pagesCompleted:0,assetsQueued:0,sitemapsQueued:0,assetsSaved:0,pagesSaved:0}},M=go(),J=new st,G=ao();if(G&&!o.resumeRewrite&&await ot(G,J.artifact()),await sr(r),await or(r,{startedAt:new Date().toISOString(),outputDir:w.resolve(r.outputDir)}),u||await O.rm(r.outputDir,{recursive:true,force:true}),await O.mkdir(r.outputDir,{recursive:true}),i){let y=new Set([...i.deleteUrls,...p.deleteOnMissingUrls]);for(let j of i.deleteUrls)await Ge(r,p,M,j,y);let $=new Set(i.resourceDeleteUrls);for(let j of i.resourceDeleteUrls)await Pi(r,p,M,j,$);}if(o.resumeRewrite)m.info("Resuming final rewrite from existing output.",{phase:"rewrite-text",mode:o.mode,crawlMode:o.crawlMode});else {let y=await request.newContext({ignoreHTTPSErrors:r.ignoreHttpsErrors});try{if(m.mark("discovery"),o.mode==="full"?(n.forEach(j=>gt(r,P,j,m)),await rn(r,y,P,m,M,p),r.seedPaths.forEach(j=>un(r,P,j,m,"seed-path")),r.generated404RequestPath&&Me(r,P,r.generated404RequestPath,m,"generated-404-request-path")):(c.forEach(j=>un(r,P,j,m,"cli")),i?.sitemapUrls.forEach(j=>gt(r,P,j,m,"content-sync-impact")),await rn(r,y,P,m,M,p,o.mode==="content-sync",i?.sitemapUrls??[]),i&&await vi(r,P,p,M,i.sitemapUrls)),m.endMark("discovery",{pages:P.pageQueue.length,assets:P.assetQueue.length,sitemaps:P.sitemapQueue.length}),m.summary(`Queued ${P.pageQueue.length} pages, ${P.assetQueue.length} assets, ${P.sitemapQueue.length} sitemaps.`,{mode:o.mode,crawlMode:o.crawlMode,queuedPages:P.pageQueue.length,queuedAssets:P.assetQueue.length,queuedSitemaps:P.sitemapQueue.length}),o.mode==="retry-timeouts"&&P.pageQueue.length===0&&P.assetQueue.length===0&&P.sitemapQueue.length===0){m.summary("No timed-out URLs were queued. Skipping retry crawl.",{mode:o.mode,crawlMode:o.crawlMode,queuedPages:0,queuedAssets:0,queuedSitemaps:0}),await m.flush(),G&&await ot(G,J.artifact());return}m.mark("render-pages");let $=Array.from({length:v},()=>R?li(r,P,m,o.mode,y,p,M,J,R,C??void 0):di(r,P,m,o.mode,y,p,M,J));if(await Promise.all($),G&&await ot(G,J.artifact()),m.endMark("render-pages",{pages:P.stats.pagesCompleted}),m.mark("download-assets"),m.progress("Asset download phase started.",{phase:"download-assets",doneAssets:P.doneAssets.size,assetsQueued:P.stats.assetsQueued,assetQueue:P.assetQueue.length}),C&&T?await ti(r,y,P,m,p,M,C,T,r.concurrency):(await Gt(r,y,p,[...P.assetQueue],m),await Xo(r,y,P,m,p,M)),m.endMark("download-assets",{assets:P.doneAssets.size}),p.enabled&&r.maxPages===0&&(await Ro(r,P,p,m,M),o.mode==="full"&&await vo(r,p,m,M)),o.mode==="full"){let j=await Zo(r,P,m);for(let q of j)if(Q(M,r,q),C&&x){let K=ht(r,q),xe=await O.readFile(q),Ae=ie(q),Te=await x.writeWorkspaceObject({key:`${C.workspace.prefix}jobs/${C.jobId}/copied/${oe(K,40)}-${w.basename(K)}`,body:xe,contentType:Ae?"text/plain; charset=utf-8":"application/octet-stream"});Le(C,{relativePath:K,sourceUrl:null,kind:"generated",contentType:Te.contentType,cacheControl:null,isText:Ae,object:Te}),Ae&&te(M,q);}}}finally{await B("dispose crawl request context",Qe(r),()=>y.dispose()).catch($=>{m.warn("Timed out while disposing crawl request context",{error:String($)});});}}if(p.trackManifest&&await be(r,p,true),C)for(let y of M.deletedFiles)Jr(C,y);let E=JSON.stringify(P.assetMap,null,2);if(await O.writeFile(w.join(r.outputDir,"asset-map.json"),E,"utf8"),C&&x){let y=await x.writeWorkspaceObject({key:`${C.workspace.prefix}jobs/${C.jobId}/generated/asset-map.json`,body:E,contentType:"application/json; charset=utf-8"});Le(C,{relativePath:"asset-map.json",sourceUrl:null,kind:"generated",contentType:"application/json; charset=utf-8",cacheControl:r.s3.assetCacheControl,isText:true,object:y});}JSON.stringify(g,null,2)!==JSON.stringify(P.assetMap,null,2)&&Q(M,r,w.join(r.outputDir,"asset-map.json")),C&&x&&await ri(r,M,C,x);let D=o.mode==="single-url"||o.mode==="content-sync"?Oo(r,P):p.enabled&&!o.resumeRewrite?ko(r,p,M,g,P.assetMap):void 0;m.mark("rewrite-text");let L=o.mode==="single-url"||o.mode==="content-sync"?`Rewriting text files touched by URL crawl: 0/${D?.length??0}`:"Rewriting text files...";m.progress(L,{phase:"rewrite-text",index:0,totalFiles:D?.length,changedTextFiles:0}),await Ft(L);let Z=Date.now(),de={files:D,previousAssetMap:g,onStart:({totalFiles:y,workerCount:$})=>{m.info(`Rewrite phase scanning ${y} text files.`,{phase:"rewrite-text",totalFiles:y,workerCount:$});},onProgress:async({index:y,totalFiles:$,changedTextFiles:j,file:q,changed:K})=>{K&&Q(M,r,w.join(r.outputDir,q)),m.checkpoint(`Rewriting text file ${y}/${$}`,{phase:"rewrite-text",index:y,totalFiles:$,changedTextFiles:j,file:q}),m.debug(`${K?"Rewrote":"Checked unchanged"} text file ${y}/${$}: ${q}`,{phase:"rewrite-text",index:y,totalFiles:$,changedTextFiles:j,file:q,changed:K});let xe=Date.now();if(!(y===1||y===$||y%50===0||xe-Z>=5e3))return;Z=xe;let Te=`Rewriting text files: ${y}/${$}`;m.progress(Te,{phase:"rewrite-text",index:y,totalFiles:$,changedTextFiles:j,file:q}),await Ft(Te);}},ne;if(C&&x){let y=D?.map(j=>ht(r,w.isAbsolute(j)?j:w.join(r.outputDir,j))),$=Object.values(C.objects).filter(j=>j.isText&&(!y||y.includes(j.relativePath))).length;await de.onStart?.({totalFiles:$,workerCount:Math.min(r.concurrency,$)}),ne=await Br(r,C,P.assetMap,{client:x,jobId:C.jobId,concurrency:r.concurrency,batchSize:25,maxAttempts:2,...y?{relativePaths:y}:{},onProgress:de.onProgress}),await Gr(r,C);}else A&&x?ne=await Vr(r,P.assetMap,{client:x,jobId:`crawl-${oe(p.runId,40)}`,concurrency:r.remoteWorkers?.rewrite?.concurrency??r.rewriteConcurrency,batchSize:r.remoteWorkers?.rewrite?.batchSize??25,maxAttempts:r.remoteWorkers?.rewrite?.maxAttempts??2,onStageProgress:async({index:y,totalFiles:$,file:j})=>{let q=Date.now();if(y!==1&&y!==$&&y%25!==0&&q-Z<5e3)return;Z=q;let K=`Staging text files for Lambda rewrite: ${y}/${$}`;m.progress(K,{phase:"rewrite-stage",index:y,totalFiles:$,file:j,execution:"lambda"}),await Ft(K);},options:de}):ne=await Pr(r,P.assetMap,de);p.trackManifest&&(Co(p,D),await be(r,p,true)),m.endMark("rewrite-text",{changedTextFiles:ne});let Pe=i?[...M.deletedFiles].sort():p.enabled&&!o.resumeRewrite?await Ao(r,P,p,M,m,C):[],Ne=[...new Set((D||[]).map(y=>Y(r.outputDir,w.isAbsolute(y)?y:w.join(r.outputDir,y))).filter(y=>y!==null))].sort();if(i){let y=[...M.changedFiles].sort(),$=new Set(y),j=new Set(i.directRenderUrls.map(U=>ze(r,U,"page")).filter(U=>!!U&&$.has(U))),q=new Set(i.archiveFamilyUrls.map(U=>ze(r,U,"page")).filter(U=>!!U&&$.has(U))),K=new Set(i.resourceRenderUrls.map(U=>ze(r,U,"asset")).filter(U=>!!U&&$.has(U))),xe=new Set([...P.sitemapLeafUrls].map(U=>ze(r,U,"asset")).filter(U=>!!U&&$.has(U))),Ae=new Set([...P.sitemapIndexUrls].map(U=>ze(r,U,"asset")).filter(U=>!!U&&$.has(U))),Te=new Set([...j,...q,...K,...xe,...Ae]),Un=y.filter(U=>!Te.has(U)),Ln=[...new Set([...i.directRenderUrls,...i.archiveFamilyUrls,...P.resolvedSitemapRoots,...P.sitemapLeafUrls,...P.sitemapIndexUrls,...i.deleteUrls,...i.resourceRenderUrls,...i.resourceDeleteUrls].map(U=>{let Xt=new URL(U);return `${Xt.pathname}${Xt.search}`}))].sort();await wt(r,{schemaVersion:2,generatedAt:new Date().toISOString(),outputDir:w.resolve(r.outputDir),runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,changedFiles:y,deletedFiles:Pe,rewriteTargets:Ne,revalidateFiles:[...M.revalidateFiles].sort(),consumerId:i.consumerId,fromSequence:i.fromSequence,toSequence:i.toSequence,impactHash:i.impactHash,resolvedSitemapUrls:[...P.resolvedSitemapRoots],uploadGroups:{assets:Un,content:[...j].sort(),listings:[...q].sort(),resources:[...K].sort(),sitemapLeaves:[...xe].sort(),sitemapIndexes:[...Ae].reverse()},invalidationPaths:Ln});}else await wt(r,{schemaVersion:1,generatedAt:new Date().toISOString(),outputDir:w.resolve(r.outputDir),runMode:o.mode,crawlMode:o.crawlMode,fullSyncRequired:!(p.enabled&&!o.resumeRewrite),changedFiles:p.enabled&&!o.resumeRewrite?[...M.changedFiles].sort():[],deletedFiles:p.enabled&&!o.resumeRewrite?Pe:[],rewriteTargets:p.enabled&&!o.resumeRewrite?Ne:[],revalidateFiles:[...M.revalidateFiles].sort()});await ir(r),m.summary(o.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${ne} text files.`:`Done. Rendered ${P.stats.pagesRendered} pages, processed ${P.doneSitemaps.size} sitemaps and ${P.doneAssets.size} assets.`,{mode:o.mode,crawlMode:o.crawlMode,resumeRewrite:o.resumeRewrite,...P.stats,pagesRendered:P.stats.pagesRendered,donePages:P.stats.pagesCompleted,claimedPages:P.donePages.size,doneSitemaps:P.doneSitemaps.size,doneAssets:P.doneAssets.size,changedTextFiles:ne}),await m.flush();}jn().catch(async e=>{let t=he(e instanceof Error?e.message:String(e));console.error(t);try{let n=(await Xe().catch(()=>null))?.logDir??"logs",s=new je(n,"debug");s.error(`Unhandled error: ${t}`,e instanceof Error&&e.stack?{stack:he(e.stack)}:void 0),await s.flush();}catch{}process.exit(1);});
|
|
17
|
+
${o}`,40);return n.info(`Using generated 404 fallback change token for ${r}`,{url:r,requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),{url:r,supported:!0,token:i,tokenSource:"generated-404-response-hash",postId:null,dependencyPostIds:[],reason:null}}catch(s){return n.warn(`Generated 404 fallback token lookup failed for ${r}`,{url:r,error:String(s),requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),null}}async function Pn(e,t,r,n,s,o){let i=yt(e,s);if(await vo(e,t,r,n,s,o),!n.enabled)return {action:"render",changeToken:n.trackManifest?await mt(e,t,n,s,o):null};let c=n.manifest.pages[s];if(!c)return {action:"render",changeToken:await mt(e,t,n,s,o)};let a=await mt(e,t,n,s,o);if(a?.supported&&a.token)return c.changeToken===a.token?i&&!await xo(e,t,s,o)?{action:"render",changeToken:a}:{action:"reuse",changeToken:a}:{action:"render",changeToken:a};let l=Te(r.sitemapLastmodByPage[s]);return l&&c.sitemapLastmod&&c.sitemapLastmod===l?{action:"reuse",changeToken:a}:{action:"render",changeToken:a}}async function xo(e,t,r,n){try{let o=(await t.get(r,{timeout:Math.min(e.navigationTimeoutMs,15e3),failOnStatusCode:!1})).status();return o===404?!0:(n.warn(`Generated 404 request path no longer returns 404 for ${r}`,{url:r,status:o,requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),!1)}catch(s){return n.warn(`Generated 404 status probe failed for ${r}`,{url:r,error:String(s),requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),false}}async function Ao(e,t,r,n,s){let o=sn(r.previousManifest,void 0,n,"previous-manifest"),i=0;for(let[h,f]of Object.entries(r.manifest.pages))if(!r.seenPages.has(h)){Ht(s,e,f.outputPath);try{await M.unlink(f.outputPath);}catch(g){(g.code||"")!=="ENOENT"&&n.warn(`Failed to remove stale incremental page output for ${h}`,{url:h,outputPath:f.outputPath,error:String(g)});}delete r.manifest.pages[h],i++;}let c=sn(r.manifest,r.runId,n,"active-manifest"),a=new Set,l=new Set;for(let h of c){for(let y of Ke(e,h))a.add(y);let f=r.manifest.assets[h]?.outputPath;f&&l.add(f);let g=Fe(e,t.assetMap,h);g&&l.add(g);}for(let h of Object.keys(r.manifest.assets)){if(c.has(h)){r.manifest.assets[h].unreferencedRuns=0;continue}let f=r.manifest.assets[h];if(jr(f.unreferencedRuns)){f.unreferencedRuns+=1,n.warn(`Deferred deletion of newly unreferenced incremental asset ${h}.`,{url:h,unreferencedRuns:f.unreferencedRuns,phase:"incremental-cleanup",source:"asset-deletion-grace"});continue}delete r.manifest.assets[h];}let d=0,u=0;for(let h of o){if(r.manifest.assets[h])continue;let f=new Set,g=r.previousManifest.assets[h]?.outputPath;g&&f.add(g);let y=Fe(e,t.assetMap,h);if(!c.has(h)&&y)f.add(y);else if(!c.has(h)){let p=Vo(e,h,n,"incremental-cleanup");p&&(f.add(p.originalFilePath),p.hashedFilePath&&f.add(p.hashedFilePath));}for(let p of f)if(!l.has(p)){Ht(s,e,p);try{await M.unlink(p),d++;}catch(m){(m.code||"")!=="ENOENT"&&n.warn(`Failed to remove stale incremental asset output for ${h}`,{url:h,outputPath:p,error:String(m)});}}for(let p of Ke(e,h))a.has(p)||Object.prototype.hasOwnProperty.call(t.assetMap,p)&&(delete t.assetMap[p],u++);}(i>0||d>0||u>0)&&n.info(`Incremental cleanup removed ${i} stale pages, ${d} stale assets, ${u} stale asset mappings`,{removedPages:i,removedAssets:d,removedAssetMappings:u,phase:"incremental-cleanup"});}async function To(e,t,r,n){let s=new Set([...Object.values(t.manifest.pages),...Object.values(t.manifest.assets)].map(a=>String(a.outputPath||"").trim()).filter(Boolean).map(a=>w.resolve(a))),o=Object.values(e.postCrawlCopyMap||{}).map(a=>ht(String(a||""))).filter(a=>!!a).map(a=>w.resolve(e.outputDir,a)),c=(await ms(["**/*.html","**/*.htm"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(a=>$r(w.join(e.outputDir,a),e.outputDir,s,o));for(let a of c){let l=w.join(e.outputDir,a);Ht(n,e,l),await M.unlink(l);}c.length>0&&r.info(`Removed ${c.length} orphaned HTML output file(s) that are absent from the current crawl manifest.`,{phase:"incremental-cleanup",source:"manifest-output-reconciliation",removedPages:c.length,samples:c.slice(0,20)});}function sn(e,t,r,n){let s=new Set,o=i=>{let c=i.trim();if(c){if(r){let a=re(c,r,"asset",n??"manifest");if(!a)return;s.add(a.toString());return}s.add(c);}};for(let i of Object.values(e.pages))for(let c of i.discoveredAssets||[])o(c);for(let[i,c]of Object.entries(e.assets||{}))t&&c.lastSeenRunId!==t||o(i);return s}function on(e,t,r){for(let n of t)for(let s of Ke(e,n))if(r.has(s))return true;return false}function Io(e,t,r,n,s){let o=new Set(r.rewriteTargets);for(let c of r.changedFiles)o.add(w.resolve(e.outputDir,c));for(let c of Object.values(t.manifest.pages))c.rewriteComplete||o.add(w.resolve(c.outputPath));for(let c of Object.values(t.manifest.assets))c.isText&&!c.rewriteComplete&&o.add(w.resolve(c.outputPath));let i=Ro(n,s);if(i.size===0)return [...o];for(let c of Object.values(t.manifest.pages))on(e,c.discoveredAssets,i)&&o.add(w.resolve(c.outputPath));for(let[c,a]of Object.entries(t.manifest.assets)){a.isText&&on(e,a.discoveredAssets,i)&&o.add(w.resolve(a.outputPath));for(let l of Ke(e,c))if(i.has(l)){J(r,e,a.outputPath),a.isText&&o.add(w.resolve(a.outputPath));break}}return [...o]}function Eo(e,t){let r=t?new Set(Array.from(t,s=>w.resolve(s))):null,n=s=>r===null||r.has(w.resolve(s));for(let s of Object.values(e.manifest.pages))n(s.outputPath)&&(s.rewriteComplete=true);for(let s of Object.values(e.manifest.assets)){if(!s.isText){s.rewriteComplete=true;continue}n(s.outputPath)&&(s.rewriteComplete=true);}}function Oo(e,t,r){let n=new Set,s=o=>{if(!o)return;let i=Z(e.outputDir,o);i&&n.add(i);};for(let o of t.donePages)s(le(e,o));for(let o of Object.values(r.manifest.pages))o.lastSeenRunId===r.runId&&s(o.outputPath);for(let o of t.doneAssets)s(Fe(e,t.assetMap,o));for(let o of Object.values(r.manifest.assets))o.lastSeenRunId===r.runId&&s(o.outputPath);return n}async function Mo(e,t,r,n,s,o){let i=[...n.deletedFiles].sort(),c=Oo(e,t,r),a=0;for(let u of [...c].sort())if(!o?.objects[u]){try{if((await M.stat(w.join(e.outputDir,u))).isFile())continue}catch{}a++,s.warn(`Active output is missing after crawl: ${u}`,{phase:"deploy-plan",file:u,outputPath:w.join(e.outputDir,u)});}if(a>0&&s.warn(`Detected ${a} active output file(s) missing before deploy plan save.`,{phase:"deploy-plan",missingActiveOutputs:a}),i.length===0)return [];let l=[],d=0;for(let u of i){if(!c.has(u)){l.push(u);continue}d++;let h=w.join(e.outputDir,u),f;try{f=(await M.stat(h)).isFile();}catch{f=false;}s.warn(`Deploy plan protected active output from deletion: ${u}`,{phase:"deploy-plan",file:u,outputPath:h,exists:f});}return d>0&&s.info(`Deploy plan skipped ${d} active output deletion(s).`,{phase:"deploy-plan",protectedDeletes:d,deletedFiles:l.length}),l}function Ke(e,t){let r=new Set([t]);try{let n=new URL(t),o=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{o.push(new URL(e.targetOrigin).origin);}catch{}for(let i of o)try{r.add(new URL(i).origin+n.pathname+n.search);}catch{}r.add(n.pathname+n.search),r.add(n.pathname);}catch{}return [...r]}function $o(e,t){let r=new Set([t]);try{let n=new URL(t),o=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{o.push(new URL(e.targetOrigin).origin);}catch{}for(let i of o)try{r.add(new URL(i).origin+n.pathname+n.search);}catch{}r.add(n.pathname+n.search);}catch{}return [...r]}function Rn(e,t){let r=e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/"?e.targetOrigin:"https://relative.invalid/";try{let n=new URL(t,r);return He(e.outputDir,n.pathname)}catch{return null}}function vn(e,t,r){for(let n of $o(e,r)){let s=t[n];if(!s)continue;let o=Rn(e,s);if(o)return {outputPath:o,publicUrl:s}}return null}function jo(e,t,r){for(let n of Ke(e,r)){let s=t[n];if(!s)continue;let o=Rn(e,s);if(o)return o}return null}function Fe(e,t,r){let n=jo(e,t,r);if(n)return n;try{return Ye(e,r).originalFilePath}catch{return null}}function Uo(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?w.join(w.resolve(e),"queue-runner-heartbeat.json"):""}async function Nt(e){let t=Uo();if(t)try{let r=await M.readFile(t,"utf8"),n=JSON.parse(r);if(!n||typeof n!="object")return;await M.writeFile(t,JSON.stringify({...n,checkedAt:new Date().toISOString(),status:"running",currentStep:"rewrite",message:e},null,2),"utf8");}catch{}}function Lo(e,t){let r=new Set;for(let n of t.donePages)r.add(w.resolve(le(e,n)));for(let n of t.doneAssets){let s=Fe(e,t.assetMap,n);!s||!ie(s)||r.add(w.resolve(s));}for(let n of t.doneSitemaps){let s=Fe(e,t.assetMap,n);!s||!ie(s)||r.add(w.resolve(s));}return [...r]}var gt="re:",pt=new Map;function Do(e){if(!e.startsWith(gt))return null;let t=pt.get(e);if(t!==void 0)return t||null;let r=e.slice(gt.length).trim();if(!r)return pt.set(e,false),null;try{let n=new RegExp(r);return pt.set(e,n),n}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),pt.set(e,false),null}}function er(e,t){let r=Do(t);return r?r.test(e):t.startsWith(gt)?false:e.startsWith(t)}function Fo(e,t){return t.find(r=>er(e,r))}function kn(e,t){let r=Fo(t.pathname,e.blockedPathPrefixes);if(r)return r.startsWith(gt)?`blocked path regex: ${r}`:`blocked path prefix: ${r}`;let n=e.blockedSearchFragments.find(s=>t.search.includes(s));return n?`blocked search fragment: ${n}`:null}function Wo(e){let t=new URL(e.sourceOrigin),r=new Set([t.hostname,...e.allowedAssetHosts]);if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{r.add(new URL(e.targetOrigin).hostname);}catch{}for(let n of Object.keys(e.extraReplacements||{}))try{r.add(new URL(n).hostname);}catch{}return r}function qo(e,t){return Wo(e).has(t.hostname)}function No(e){let t=he(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function Qt(e){let t=he(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function _o(e){let t=he(e).replace(/\\\//g,"/").trim(),r=w.extname(t).toLowerCase();return gn.has(r)||fn.has(r)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function Ee(e){return lo.some(t=>e.pathname.startsWith(t))}function H(e,t,r=e.sourceOrigin,n,s="url",o=false){let i=No(t);if(!i||i.startsWith("data:")||i.startsWith("blob:")||i.startsWith("mailto:")||i.startsWith("tel:")||i.startsWith("#"))return n?.ignore(s,t,"empty or unsupported scheme",r),null;if(Qt(i))return n?.ignore(s,t,"looks like JavaScript/code fragment",r),null;if(_o(i))return n?.ignore(s,t,"looks like JavaScript property access",r),null;try{let c=new URL(i,r);if(Cn(c))return n?.reject(s,t,"malformed URL encoding",r),null;if(!["http:","https:"].includes(c.protocol))return n?.ignore(s,t,"unsupported protocol: ",r),null;if(!qo(e,c))return n?.ignore(s,c.toString(),"host not allowed",r),null;let a=kn(e,c);if(a&&!(o&&Rt(c)))return n?.reject(s,c.toString(),a,r),null;let l=new URL(e.sourceOrigin);return c.protocol=l.protocol,c.host=l.host,c.hash="",c}catch{return n?.reject(s,t,"invalid URL",r),null}}function Cn(e){try{return decodeURIComponent(e.pathname),decodeURIComponent(e.search),decodeURIComponent(e.hash),!1}catch{return true}}function re(e,t,r,n){try{let s=new URL(e);return Cn(s)?(t.reject(r,e,"malformed URL encoding",n),null):Ve(s.pathname)===null?(t.reject(r,e,"unsafe URL pathname",n),null):s.protocol!=="http:"&&s.protocol!=="https:"?(t.reject(r,e,`unsupported protocol: ${s.protocol}`,n),null):s}catch{return t.reject(r,e,"invalid URL",n),null}}function xn(e){return gn.has(w.extname(e.pathname).toLowerCase())}function Se(e){return Ee(e)?false:fn.has(w.extname(e.pathname).toLowerCase())}function qe(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function q(e,t){return !!(qe(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(r=>er(t.pathname,r))||xn(t)||!Se(t)&&!Ee(t))}function le(e,t){let r=new URL(t),n=Ve(r.pathname);if(n===null)throw new Error(`Unsafe page URL pathname: ${r.pathname}`);return n.endsWith("/")?n+="index.html":w.extname(n)||(n+="/index.html"),He(e.outputDir,n)}function Bo(e){if(!e.generated404RequestPath)return null;try{let t=new URL(e.generated404RequestPath,e.sourceOrigin);return !t.pathname.endsWith("/")&&w.extname(t.pathname)===""&&(t.pathname+="/"),t.hash="",t.toString()}catch{return null}}function yt(e,t){let r=Bo(e);if(!r)return false;try{return new URL(t,e.sourceOrigin).toString()===r}catch{return false}}function Ye(e,t){let r=new URL(t),n=Ve(r.pathname);if(n===null)throw new Error(`Unsafe asset URL pathname: ${r.pathname}`);n.endsWith("/")&&(n+="index.html");let s=!!r.search,o=n,i=He(e.outputDir,o),c=At(e.targetOrigin,o),a=`${c}${r.search}`;if(!s)return {originalPathname:o,originalFilePath:i,originalPublicUrl:c,originalPublicUrlWithSearch:a,preferQueryHashed:s};let l=w.extname(n),u=`${l?n.slice(0,-l.length):n}.${oe(r.search)}${l||".bin"}`;return {originalPathname:o,originalFilePath:i,originalPublicUrl:c,originalPublicUrlWithSearch:a,preferQueryHashed:s,hashedPathname:u,hashedFilePath:He(e.outputDir,u),hashedPublicUrl:At(e.targetOrigin,u)}}function Vo(e,t,r,n){let s=re(t,r,"asset",n);return s?Ye(e,s.toString()):null}function Kt(e,t,r,n,s){t[r]=n;try{let o=new URL(r),c=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{c.push(new URL(e.targetOrigin).origin);}catch{}for(let a of c)try{let l=new URL(a);t[l.origin+o.pathname+o.search]=n;}catch{}try{let a=(()=>{let l=new URL(n,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin);return `${l.pathname}${l.search}`})();t[o.pathname+o.search]=a;}catch{}try{let a=new URL(n,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[o.pathname]=a;}catch{}try{let a=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[o.pathname]=a;}catch{}}catch{}}async function An(e){try{return await M.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Ie(e){try{return await M.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function Ho(e){let t=String(e["content-length"]||"").trim();if(!t)return null;let r=Number.parseInt(t,10);return Number.isFinite(r)&&r>=0?r:null}function Tn(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let r=Date.parse(t);return Number.isFinite(r)?r:null}function zo(e,t){let r=Tn(t),n=Ho(t),s=e?.mtime.getTime();return r!==null&&Math.abs((s??0)-r)>=1e3||n!==null&&e?.size!==n?false:r!==null||n!==null}async function Qo(e,t){if(!t)return;let r=Tn(t);if(r===null)return;let n=await Ie(e);if(!n)return;let s=new Date(r);await M.utimes(e,n.atime,s).catch(()=>{});}function Jt(e,t){let r=w.extname(e.pathname).toLowerCase(),n=t["content-type"]||"";return uo.has(r)||co.some(s=>n.includes(s))&&!n.startsWith("image/")&&!n.includes("font")}function Ko(e){try{let t=w.extname(new URL(e).pathname).toLowerCase();return t===".js"||t===".mjs"}catch{return false}}function Ce(e,t){(e.doneAssets.size%25===0||e.doneAssets.size===1||e.doneAssets.size===e.stats.assetsQueued)&&t.progress(`Asset processing progress: processed ${e.doneAssets.size}, discovered ${e.stats.assetsQueued}.`,{doneAssets:e.doneAssets.size,assetsQueued:e.stats.assetsQueued,phase:"download-assets"});}function Jo(e){return oe(e.toString("base64"),40)}function In(e,t,r){let n=e.assetVariantDigestsByOriginalPath.get(t);if(!n||n.size===0)return false;for(let s of n)if(s!==r)return true;return false}function En(e,t,r){let n=e.assetVariantDigestsByOriginalPath.get(t);n||(n=new Set,e.assetVariantDigestsByOriginalPath.set(t,n)),n.add(r);}async function Gt(e,t,r,n,s,o,i){let c=Ye(e,r),a=Jo(n),l=c.originalFilePath,d=c.originalPublicUrlWithSearch;if(c.preferQueryHashed&&c.hashedFilePath&&c.hashedPublicUrl&&In(s,c.originalFilePath,a)){let g=vn(e,t,r);g?(l=g.outputPath,d=g.publicUrl):(l=c.hashedFilePath,d=c.hashedPublicUrl);}Kt(e,t,r,d,c.originalPublicUrl);let u=ie(l)?Buffer.from(Ot(n.toString("utf8"),e,t,l),"utf8"):n,h=await An(l),f=false;return (h===null||!h.equals(u))&&(await me(l,u),f=true),o?.debug(`${f?"Saved":"Skipped unchanged"} asset output ${r}`,{phase:"download-assets",url:r,outputPath:l,bytes:u.length,wroteFile:f}),En(s,c.originalFilePath,a),await Qo(l,i),s.stats.assetsSaved++,o&&(s.stats.assetsSaved%50===0||s.stats.assetsSaved===1)&&o.progress(`Asset progress: saved ${s.stats.assetsSaved}, discovered ${s.stats.assetsQueued}, pending ${s.assetQueue.length}.`,{assetsSaved:s.stats.assetsSaved,assetsQueued:s.stats.assetsQueued,assetQueue:s.assetQueue.length,phase:"download-assets"}),{outputPath:l,publicUrl:d,wroteFile:f}}function Oe(e,t,r,n,s){let o=()=>{let u=String(s??"").trim();if(!u)return {discoveredFrom:"",discoveredFromType:"unknown"};if(u==="seed-path"||u==="cli"||u==="generated-404-request-path")return {discoveredFrom:u,discoveredFromType:u};if(/^https?:\/\//i.test(u))try{let h=new URL(u);return qe(h)?{discoveredFrom:u,discoveredFromType:"sitemap"}:q(e,h)?{discoveredFrom:u,discoveredFromType:"asset"}:Se(h)&&!Ee(h)?{discoveredFrom:u,discoveredFromType:"page"}:{discoveredFrom:u,discoveredFromType:"url"}}catch{return {discoveredFrom:u,discoveredFromType:"url"}}return {discoveredFrom:u,discoveredFromType:"url"}},i=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,c=H(e,r,i,n,"page");if(!c)return;if(!Se(c)||xn(c)){if(q(e,c)){n.info(`Seeded/non-page URL queued as asset: ${c.toString()}`,{url:c.toString(),source:s}),W(e,t,c.toString(),n,s);return}n.reject("page",c.toString(),Ee(c)?"asset/internal path cannot be page":"not page-like",s);return}let a=c.toString(),{discoveredFrom:l,discoveredFromType:d}=o();l&&!t.pageDiscoverySources.has(a)&&t.pageDiscoverySources.set(a,l),!t.donePages.has(a)&&!t.queuedPages.has(a)&&(t.queuedPages.add(a),t.pageQueue.push(a),t.stats.pagesQueued++,n.debug(`Queued discovered page ${a}`,{phase:"discovery",url:a,discoveredFrom:l,discoveredFromType:d,outputPath:le(e,a)}),(t.stats.pagesQueued%25===0||t.stats.pagesQueued===1)&&n.progress(`Discovery progress: pages ${t.stats.pagesQueued}, assets ${t.stats.assetsQueued}, sitemaps ${t.stats.sitemapsQueued}.`,{pagesQueued:t.stats.pagesQueued,assetsQueued:t.stats.assetsQueued,sitemapsQueued:t.stats.sitemapsQueued,pageQueue:t.pageQueue.length,phase:"discovery"}));}function W(e,t,r,n,s){let o=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,i=H(e,r,o,n,"asset");if(!i)return;if(!q(e,i)){n.reject("asset",i.toString(),"not a safe asset path/prefix",s);return}let c=i.toString();!t.doneAssets.has(c)&&!t.queuedAssets.has(c)&&(t.queuedAssets.add(c),t.assetQueue.push(c),t.stats.assetsQueued++,(t.stats.assetsQueued%100===0||t.stats.assetsQueued===1)&&n.progress(`Discovery progress: pages ${t.stats.pagesQueued}, assets ${t.stats.assetsQueued}, sitemaps ${t.stats.sitemapsQueued}.`,{pagesQueued:t.stats.pagesQueued,assetsQueued:t.stats.assetsQueued,sitemapsQueued:t.stats.sitemapsQueued,assetQueue:t.assetQueue.length,phase:"discovery"}));}function ft(e,t,r,n,s){let o=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,i=H(e,r,o,n,"sitemap",pr(s));if(!i)return;if(!qe(i)){n.reject("sitemap",i.toString(),"not sitemap-like",s);return}let c=i.toString();!t.doneSitemaps.has(c)&&!t.queuedSitemaps.has(c)&&(t.queuedSitemaps.add(c),t.sitemapQueue.push(c),t.stats.sitemapsQueued++,(t.stats.sitemapsQueued%10===0||t.stats.sitemapsQueued===1)&&n.progress(`Discovery progress: pages ${t.stats.pagesQueued}, assets ${t.stats.assetsQueued}, sitemaps ${t.stats.sitemapsQueued}.`,{pagesQueued:t.stats.pagesQueued,assetsQueued:t.stats.assetsQueued,sitemapsQueued:t.stats.sitemapsQueued,sitemapQueue:t.sitemapQueue.length,phase:"discovery"}));}function Go(e){let t=he(e),r=[...t.matchAll(/<url>\s*([\s\S]*?)\s*<\/url>/gi)].map(n=>n[1]);return r.length>0?r.map(n=>{let s=n.match(/<loc>\s*([^<]+?)\s*<\/loc>/i);if(!s?.[1])return null;let o=n.match(/<lastmod>\s*([^<]+?)\s*<\/lastmod>/i);return {loc:s[1].trim(),lastmod:Te(o?.[1]??null)}}).filter(n=>!!n):[...t.matchAll(/<loc>\s*([^<]+?)\s*<\/loc>/gi)].map(n=>({loc:n[1].trim(),lastmod:null})).filter(n=>n.loc)}function Zo(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function Yo(e){let t=[],r=/url\(\s*(?:"([^"]+)"|'([^']+)'|([^)]*?))\s*\)/gi;for(let n of e.matchAll(r)){let s=e.slice(Math.max(0,n.index-8),n.index);if(/\bnew\s+$/i.test(s))continue;let o=(n[1]||n[2]||n[3]||"").trim();o&&t.push(o);}return t}function Xo(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function ei(e,t){if(t==="dom-style")return true;let r=(()=>{try{return w.extname(new URL(e).pathname).toLowerCase()}catch{return ""}})();return !(r===".js"||r===".mjs"||r===".map"||t.includes("javascript"))}function ht(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function On(e,t,r,n){let s=[];await M.mkdir(t,{recursive:true});let o=await M.readdir(e,{withFileTypes:true});for(let i of o){let c=w.join(e,i.name),a=w.join(t,i.name);if(i.isDirectory()){s.push(...await On(c,a,r,n));continue}await Mn(c,a,r,n)&&s.push(a);}return s}async function ti(e,t){try{let[r,n]=await Promise.all([M.stat(e),M.stat(t)]);if(r.size!==n.size)return !1;let[s,o]=await Promise.all([M.readFile(e),M.readFile(t)]);return s.equals(o)}catch{return false}}async function Mn(e,t,r,n){let s=w.resolve(t);return r.has(s)?(n.debug("Skipped post-crawl copy over crawled page output",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):await ti(e,t)?(n.debug("Skipped unchanged post-crawl copy target",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):(await M.mkdir(w.dirname(t),{recursive:true}),await M.copyFile(e,t),true)}async function ri(e,t,r){let n=Object.entries(e.postCrawlCopyMap||{}).map(([c,a])=>({sourcePath:c.trim(),prefix:String(a||"").trim()}));if(n.length===0)return [];let s=0,o=[],i=new Set([...t.donePages].map(c=>w.resolve(le(e,c))));r.mark("copy-extra-paths");for(let c of n){let a=c.sourcePath,l=c.prefix;if(!a||!l){r.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:a,prefixPath:l});continue}let d=fo(a);if(!d.resolvedPath){r.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:a,alias:d.alias||"",requiredEnv:d.requiredEnv||"",prefixPath:l});continue}let u=d.resolvedPath,h=ht(l);if(!h){r.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:a,prefixPath:l});continue}let f;try{f=await M.stat(u);}catch{r.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:a,sourceAbs:u,prefixPath:l});continue}let g=w.resolve(e.outputDir,h);if(f.isDirectory()){let b=await On(u,g,i,r);o.push(...b),s+=b.length,b.length>0&&r.progress(`Copied static directory to export: ${u} -> /${h}`,{phase:"copy-extra-paths",sourcePath:u,targetPath:`/${h}`,copiedItems:s,changedFiles:b.length});continue}let y=w.basename(u),p=l.endsWith("/")?w.join(g,y):g;await Mn(u,p,i,r)&&(o.push(p),s++,r.progress(`Copied static file to export: ${u} -> /${ht(l.endsWith("/")?`${l}${y}`:l)}`,{phase:"copy-extra-paths",sourcePath:u,targetPath:`/${ht(l.endsWith("/")?`${l}${y}`:l)}`,copiedItems:s}));}return r.endMark("copy-extra-paths",{mappedSources:n.length,copiedItems:s}),o}function We(e,t,r,n,s){let o=new Set,i=he(r).replace(/\\\//g,"/"),c=s==="page-html"?Xo(i):i,a=ei(t,s);if(a){for(let l of Yo(c)){let d=H(e,l,t,n,`${s}:css-url`);d&&q(e,d)&&o.add(d.toString());}for(let l of c.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let d=H(e,l[1],t,n,`${s}:css-import`);d&&q(e,d)&&o.add(d.toString());}}if(a||s==="page-html")for(let l of c.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let d=H(e,l[1],t,n,`${s}:xml-stylesheet`);d&&q(e,d)&&o.add(d.toString());}if(s==="page-html")for(let l of Er(i)){let d=l.startsWith("//")?`${new URL(e.sourceOrigin).protocol}${l}`:l;if(Qt(d)){n.ignore(`${s}:serialized-url`,d,"looks like JavaScript/code fragment",t);continue}let u=H(e,d,t,n,`${s}:serialized-url`);u&&q(e,u)?o.add(u.toString()):u&&n.ignore("asset",u.toString(),"serialized URL did not pass safe asset path filter",t);}if(s!=="page-html"&&Ko(t))for(let l of Or(i)){if(Qt(l)||!/\.(?:js|mjs)(?:[?#]|$)/i.test(l))continue;let d=H(e,l,t,n,`${s}:relative-asset`);d&&q(e,d)&&o.add(d.toString());}return [...o]}function $n(e,t,r,n){let s=new Set,o=he(r);for(let i of o.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let c=i[1],a=H(e,c,t,n,"page-link");a&&(kn(e,a)||Se(a)&&!Ee(a)&&!q(e,a)&&s.add(a.toString()));}return [...s]}async function an(e,t,r,n,s,o,i=false,c=[]){let a=new Set(c),l=0,d=new Map,u=(h,f)=>{let g=[f],y=new Set;for(;g.length>0;){let p=g.pop();if(p===h)return true;y.has(p)||(y.add(p),g.push(...d.get(p)??[]));}return false};for(;r.sitemapQueue.length>0;){let h=r.sitemapQueue.shift();r.queuedSitemaps.delete(h);let f=re(h,n,"sitemap","sitemap-queue");if(!f)continue;let g=f.toString();if(r.doneSitemaps.has(g))continue;r.doneSitemaps.add(g),n.sitemap(`Fetching sitemap ${g}`,{url:g});let y=true;try{let p=await t.get(g,{timeout:6e4});if(y=!1,!p.ok()){if(n.skip("sitemap",g,p.status()),i&&!a.has(g))throw new Error(`Required child content-sync sitemap returned HTTP ${p.status()}: ${g}`);continue}let m=await p.body(),b=p.url()||g,k=re(b,n,"sitemap-response",g);if(!k)continue;let R=k.toString();r.successfulSitemaps.add(g),r.successfulSitemaps.add(R),a.has(g)&&(r.resolvedSitemapRoots.add(R),l+=1);let O=await Gt(e,r.assetMap,R,m,r,n);J(s,e,O.outputPath),te(s,O.outputPath);let A=m.toString("utf8");/<sitemapindex(?:\s|>)/i.test(A)?r.sitemapIndexUrls.add(R):r.sitemapLeafUrls.add(R);let x=We(e,R,A,n,"sitemap");for(let C of x)W(e,r,C,n,R);let v=[];for(let C of Go(A)){let T=H(e,C.loc,R,n,"sitemap-loc",!0);if(!T){if(i)throw new Error(`Content-sync sitemap contains an inadmissible location: ${C.loc}`);continue}if(qe(T)){if(u(R,T.toString()))throw new Error(`Sitemap index cycle detected: ${R} -> ${T.toString()}`);if(d.has(R)||d.set(R,new Set),d.get(R).add(T.toString()),v.push(T.toString()),i&&r.doneSitemaps.has(T.toString())&&!r.successfulSitemaps.has(T.toString()))throw new Error(`Required child content-sync sitemap was not resolved: ${T.toString()}`);ft(e,r,T.toString(),n,R);}else if(i){if(Se(T)&&!q(e,T)){let Q=o.requiredUrls.has(T.toString()),D=o.manifest.pages[T.toString()],P=!!D&&!!await Ie(D.outputPath);if(!Q&&!P)throw new Error(`Content-sync sitemap coverage is incomplete for ${T.toString()}.`)}n.ignore("sitemap-loc",T.toString(),"content-sync sitemap-only traversal does not enqueue urlset locations",R);}else q(e,T)?W(e,r,T.toString(),n,R):Se(T)?(C.lastmod&&(r.sitemapLastmodByPage[T.toString()]=C.lastmod),Oe(e,r,T.toString(),n,R)):n.reject("sitemap-loc",T.toString(),"not page/sitemap/asset-like",R);}o.trackManifest&&(o.manifest.assets[R]={url:R,outputPath:O.outputPath,isText:!0,contentType:p.headers()["content-type"]??"application/xml",cacheControl:Vt(p.headers()),changeToken:null,tokenSource:null,discoveredAssets:[...new Set([...x,...v])],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0,rewriteComplete:!1},await be(e,o));}catch(p){n.error(`Failed sitemap ${g}`,{url:g,error:String(p)});let m=i&&a.has(g)&&y;if(i&&!m)throw p}}if(i&&a.size>0&&l===0)throw new Error(`None of the configured content-sync sitemap roots could be resolved: ${[...a].join(", ")}`)}async function ni(e,t,r,n,s,o,i){let c=H(e,n,e.sourceOrigin,s,"asset-fetch");if(!c||!q(e,c))return;let a=c.toString();if(r.doneAssets.has(a))return;let l=o.enabled||o.strictTargeted?o.previousManifest.assets[a]:void 0,d=o.trackManifest?await mt(e,t,o,a,s):null,u=d?.token??null,h=$t(l?.changeToken,d),f=o.strictTargeted&&(!d?.supported||!d.token)&&jt(e.sourceOrigin,a),g=o.strictTargeted?o.manifest.assets[a]:void 0;if(g?.lastSeenRunId===o.runId&&await Ie(g.outputPath)){r.doneAssets.add(a);for(let p of g.discoveredAssets||[])W(e,r,p,s,a);J(i,e,g.outputPath),De(i,e,g.outputPath,g.cacheControl),g.isText&&te(i,g.outputPath),s.info(`Resumed completed content-sync asset ${a}`,{url:a,source:"content-sync-checkpoint"}),Ce(r,s);return}if(l&&(h||f)&&await Ie(l.outputPath)){o.manifest.assets[a]={...l,changeToken:u,tokenSource:d?.tokenSource??l.tokenSource,discoveredAssets:[...l.discoveredAssets||[]],lastSeenRunId:o.runId,unreferencedRuns:0},delete o.manifest.pages[a],r.doneAssets.add(a);for(let p of l.discoveredAssets||[])W(e,r,p,s,a);De(i,e,l.outputPath,l.cacheControl),s.info(`Reused unchanged trusted asset ${a}.`,{url:a,tokenSource:d?.tokenSource??"unknown",phase:"download-assets",source:h?"asset-change-token-match":"content-sync-release-fingerprint"}),Ce(r,s);return}let y=(p,m={})=>{if(!l||o.strictTargeted)return false;o.manifest.assets[a]={...l,discoveredAssets:[...l.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0},delete o.manifest.pages[a],r.doneAssets.add(a);for(let b of l.discoveredAssets||[])W(e,r,b,s,a);return s.warn(`Keeping previous incremental asset ${a} after fetch issue.`,{url:a,reason:p,preservedFromPreviousManifest:true,...m,phase:"download-assets"}),Ce(r,s),true};s.asset(`Fetching asset ${a}`,{url:a});try{let p=Fe(e,r.assetMap,a),m=p?await Ie(p):null;if(p&&m&&!o.strictTargeted)try{let D=await V(`fetch asset headers ${a}`,6e4,()=>t.head(a,{timeout:6e4})),P=D.headers();if(D.ok()&&zo(m,P)){let j=await An(p);if(j!==null){let Y=D.url()||a,I=re(Y,s,"asset-response",a);if(!I)return;let F=I.toString(),U=await Gt(e,r.assetMap,F,j,r,s,P);U.wroteFile&&(J(i,e,U.outputPath),ie(U.outputPath)&&te(i,U.outputPath));let ne=Vt(P)||l?.cacheControl||null;De(i,e,U.outputPath,ne),r.doneAssets.add(a),s.info(`Reused existing asset ${a} based on response headers.`,{url:a,filePath:p,lastModified:P["last-modified"]||"",contentLength:P["content-length"]||"",phase:"download-assets"}),Ce(r,s);let de=Jt(c,P),Pe=l?.discoveredAssets?[...l.discoveredAssets]:[];if(de||l?.isText){let G=j.toString("utf8"),Ne=We(e,F,G,s,"asset:cached");(Ne.length>0||!l)&&(Pe=Ne);for(let Xe of Pe)W(e,r,Xe,s,F);}if(o.trackManifest){let G=de||!!l?.isText;o.manifest.assets[a]={url:a,outputPath:U.outputPath,isText:G,contentType:Bt(P)||l?.contentType||null,cacheControl:ne,changeToken:d?.supported?d.token:null,tokenSource:d?.supported?d.tokenSource??null:null,discoveredAssets:Pe,lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0,rewriteComplete:!G},delete o.manifest.pages[a],(o.enabled||o.strictTargeted)&&G&&await be(e,o);}return}}}catch{}let b=await V(`fetch asset ${a}`,6e4,()=>t.get(a,{timeout:6e4}));if(!b.ok()){if(y(`http-${b.status()}`,{status:b.status()}))return;if(o.strictTargeted)throw new Error(`Required content-sync asset returned HTTP ${b.status()}: ${a}`);s.skip("asset",a,b.status());return}let k=await V(`read asset response ${a}`,6e4,()=>b.body()),R=b.url()||a,O=re(R,s,"asset-response",a);if(!O)return;let A=O.toString(),x=b.headers(),v=await Gt(e,r.assetMap,A,k,r,s,x);v.wroteFile&&(J(i,e,v.outputPath),ie(v.outputPath)&&te(i,v.outputPath));let C=Vt(x);De(i,e,v.outputPath,C),r.doneAssets.add(a),Ce(r,s);let T=Jt(c,x),Q=[];if(T){let D=k.toString("utf8");Q=We(e,A,D,s,`asset:${w.extname(c.pathname).toLowerCase()||x["content-type"]||"unknown"}`);for(let P of Q)W(e,r,P,s,A);}o.trackManifest&&(o.manifest.assets[a]={url:a,outputPath:v.outputPath,isText:T,contentType:Bt(x),cacheControl:C,changeToken:d?.supported?d.token:null,tokenSource:d?.supported?d.tokenSource??null:null,discoveredAssets:Q,lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0,rewriteComplete:!T},delete o.manifest.pages[a],(o.enabled||o.strictTargeted)&&T&&await be(e,o));}catch(p){if(y("fetch-error",{error:String(p)}))return;if(s.error(`Failed asset ${a}`,{url:a,error:String(p)}),o.strictTargeted)throw p}finally{r.doneAssets.has(a)||(r.doneAssets.add(a),Ce(r,s));}}async function si(e,t,r,n,s,o){let i=Math.max(1,Number(e.assetDownloadConcurrency||e.concurrency||1)),c=Array.from({length:i},async()=>{for(;r.assetQueue.length>0;){let a=r.assetQueue.shift();a&&(r.queuedAssets.delete(a),await ni(e,t,r,a,n,s,o));}});await Promise.all(c);}function wt(e,t){let r=Z(e.outputDir,t);if(!r)throw new Error(`Remote export output is outside outputDir: ${t}`);return r}function oi(e,t){return Jt(e,{"content-type":t})}function cn(e){return /(?:^|\/)index\.html?$|\.html?$/i.test(e)}async function ii(e,t,r,n,s,o,i,c,a){let l=Math.max(1,Math.min(100,a)),d=20;for(;r.assetQueue.length>0;){let u=r.assetQueue.splice(0,l*d);for(let y of u)r.queuedAssets.delete(y);await Xt(e,t,s,u,n);let h=[];for(let y of u){let p=s.manifest.assets[y],m=p?Z(e.outputDir,p.outputPath):null,b=m?i.objects[m]:void 0,k=s.changeTokenCache.get(y)??null;if(!(s.enabled&&p&&b?.kind==="asset"&&b.sourceUrl===y&&($t(p.changeToken,k)||(!k?.supported||!k.token)&&jt(e.sourceOrigin,y)))||!p||!m||!b){h.push(y);continue}s.manifest.assets[y]={...p,changeToken:k?.token??null,tokenSource:k?.tokenSource??p.tokenSource,lastSeenRunId:s.runId,unreferencedRuns:0};for(let O of p.discoveredAssets||[])W(e,r,O,n,y);r.doneAssets.add(y),De(o,e,p.outputPath,p.cacheControl),n.info(`Reused unchanged S3-native asset ${y}.`,{url:y,relativePath:m,tokenSource:k?.tokenSource??"release-fingerprint",phase:"download-assets",execution:"lambda"}),Ce(r,n);}if(h.length===0)continue;let f=[];for(let y=0;y<h.length;y+=d)f.push(h.slice(y,y+d));let g=await Promise.all(f.map(y=>c.fetch({urls:y,ignoreHttpsErrors:e.ignoreHttpsErrors,timeoutMs:6e4})));for(let y of g)for(let p of y.assets){let m=p.requestedUrl;try{if(p.outcome!=="fetched"||!p.object||!p.finalUrl){let C=p.error||`Remote asset fetch ended with ${p.outcome}.`;if(n.error(`Failed remote asset ${m}`,{url:m,status:p.httpStatus,outcome:p.outcome,error:C,execution:"lambda"}),s.strictTargeted)throw new Error(C);continue}let b=re(p.finalUrl,n,"remote-asset-response",m);if(!b)continue;let k=Ye(e,b.toString()),R=k.originalFilePath,O=k.originalPublicUrlWithSearch;if(k.preferQueryHashed&&k.hashedFilePath&&k.hashedPublicUrl&&In(r,k.originalFilePath,p.object.sha256)){let C=vn(e,r.assetMap,b.toString());R=C?.outputPath??k.hashedFilePath,O=C?.publicUrl??k.hashedPublicUrl;}Kt(e,r.assetMap,b.toString(),O,k.originalPublicUrl),b.toString()!==m&&Kt(e,r.assetMap,m,O,k.originalPublicUrl),En(r,k.originalFilePath,p.object.sha256);let A=wt(e,R),x=p.contentType?.trim()||"application/octet-stream",v=oi(b,x);Le(i,{relativePath:A,sourceUrl:m,kind:"asset",contentType:x,cacheControl:p.cacheControl,isText:v,object:p.object}),J(o,e,R),v&&te(o,R),De(o,e,R,p.cacheControl);for(let C of p.discoveredAssets)W(e,r,C,n,b.toString());r.stats.assetsSaved++,s.trackManifest&&(s.manifest.assets[m]={url:m,outputPath:R,isText:v,contentType:x,cacheControl:p.cacheControl,changeToken:null,tokenSource:null,discoveredAssets:[...p.discoveredAssets],lastCrawledAt:new Date().toISOString(),lastSeenRunId:s.runId,unreferencedRuns:0,rewriteComplete:!v},delete s.manifest.pages[m]),n.debug(`Remote asset fetch completed ${m}`,{url:m,finalUrl:b.toString(),relativePath:A,bytes:p.object.bytes,taskId:y.taskId,attempts:y.attempts,execution:"lambda"});}finally{r.doneAssets.add(m),Ce(r,n);}}}}async function ai(e,t,r,n){for(let s of [...t.changedFiles].sort()){if(r.objects[s])continue;let o=w.join(e.outputDir,s),i=await M.readFile(o).catch(d=>{throw new Error(`Coordinator-owned output is missing before S3 staging: ${s}`,{cause:d})}),c=ie(o),a=String(Br.lookup(s)||"")||(c?"text/plain; charset=utf-8":"application/octet-stream"),l=await n.writeWorkspaceObject({key:`${r.workspace.prefix}jobs/${r.jobId}/coordinator/${oe(s,40)}-${w.basename(s)}`,body:i,contentType:a,cacheControl:cn(s)?e.s3.htmlCacheControl:e.s3.assetCacheControl});Le(r,{relativePath:s,sourceUrl:null,kind:"generated",contentType:a,cacheControl:cn(s)?e.s3.htmlCacheControl:e.s3.assetCacheControl,isText:c,object:l});}}function ci(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function ye(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function Qe(e){return Math.max(15e3,Math.min(6e4,ye(e)))}function jn(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function tr(e){return e.stats.pagesCompleted}function Zt(e){let r=e.options?.browserProcess;return {pid:typeof r?.process?.pid=="number"?r.process.pid:null,kill:typeof r?.kill=="function"?r.kill.bind(r):null}}async function _t(e,t,r){let n=Zt(e);try{if(n.kill){await n.kill(),t.warn(`Force-killed crawl worker browser after ${r}`,{browserPid:n.pid,reason:r});return}if(n.pid!==null){process.kill(n.pid,"SIGKILL"),t.warn(`Sent SIGKILL to crawl worker browser after ${r}`,{browserPid:n.pid,reason:r});return}t.warn(`Could not resolve crawl worker browser PID after ${r}`,{reason:r});}catch(s){t.error(`Failed to force-kill crawl worker browser after ${r}`,{browserPid:n.pid,reason:r,error:String(s)});}}async function V(e,t,r){let n;try{return await Promise.race([r(),new Promise((s,o)=>{n=globalThis.setTimeout(()=>{o(new Je(e,t));},t);})])}finally{n!==void 0&&globalThis.clearTimeout(n);}}var Je=class extends Error{constructor(r,n){super(`${r} timed out after ${ci(n)}.`);this.operation=r;this.timeoutMs=n;this.name="OperationTimeoutError";}operation;timeoutMs};async function ui(e,t){let r=jn(e);await t.evaluate(async n=>{await new Promise(s=>{let o=0,i=700,c=Date.now(),a=()=>{window.clearInterval(l),window.scrollTo(0,0),s();},l=window.setInterval(()=>{if(Date.now()-c>=n.maxDurationMs){a();return}window.scrollBy(0,i),o+=i;let d=document.body?.scrollHeight||0,u=document.documentElement?.scrollHeight||0,h=Math.max(d,u);o>=h+window.innerHeight&&a();},120);});},{maxDurationMs:r});}async function li(e,t){await t.waitForLoadState("domcontentloaded",{timeout:e.readiness.timeoutMs}).catch(()=>{}),e.readiness.waitForSelector&&await t.waitForSelector(e.readiness.waitForSelector,{timeout:e.readiness.timeoutMs}).catch(()=>{}),e.readiness.waitForFunction&&await t.waitForFunction(e.readiness.waitForFunction,void 0,{timeout:e.readiness.timeoutMs}).catch(()=>{}),await ui(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function di(e,t){await t.waitForLoadState("domcontentloaded",{timeout:e.readiness.timeoutMs}).catch(()=>{}),await t.waitForLoadState("load",{timeout:e.readiness.timeoutMs}).catch(()=>{}),e.readiness.waitForSelector&&await t.waitForSelector(e.readiness.waitForSelector,{timeout:e.readiness.timeoutMs}).catch(()=>{}),await t.waitForTimeout(e.readiness.fallbackWaitMs);}function Un(e,t){return e.noJavaScriptRenderPathPrefixes.some(r=>er(t,r))}async function pi(e,t,r,n,s=true){let o=new Set;if(s){let c=await t.evaluate(()=>{let a=new Set,l=["href","src","poster","data-src","data-lazy-src","data-original","data-bg","data-background","data-href","data-resource-url"],d=new Set,u=["srcset","data-srcset","data-lazy-srcset"],h=f=>{f.querySelectorAll("*").forEach(g=>{for(let p of l){let m=g.getAttribute(p);m&&a.add(m);}for(let p of u){let m=g.getAttribute(p);m&&m.split(",").forEach(b=>{let k=b.trim().split(/\s+/)[0];k&&a.add(k);});}let y=g.getAttribute("style");y&&d.add(y),g.shadowRoot&&h(g.shadowRoot);});};return h(document),{attrs:[...a],styles:[...d]}});for(let a of c.attrs)for(let l of Zo(a)){let d=H(e,l,r,n,"dom-attr");d&&q(e,d)&&o.add(d.toString());}for(let a of c.styles)for(let l of We(e,r,a,n,"dom-style"))o.add(l);}let i=await t.content();for(let c of We(e,r,i,n,"page-html"))o.add(c);return [...o]}async function un(e){return await e.evaluate(()=>{document.querySelectorAll("#wpsuite-consent-root").forEach(t=>t.remove()),document.documentElement.classList.remove("wpsuite-consent-scroll-locked"),document.body.classList.remove("wpsuite-consent-scroll-locked");}),e.content()}async function Yt(e,t,r,n,s){let o=le(e,t);await me(o,r,"utf8");let i=await M.stat(o);s?.debug(`Saved page output ${t}`,{phase:"save-pages",url:t,outputPath:o,bytes:i.size}),n.stats.pagesSaved++;let c=Math.min(n.stats.pagesQueued,tr(n)+1);s&&(n.stats.pagesSaved%10===0||n.stats.pagesSaved===1)&&s.progress(`Page progress: processed ${c}, rendered ${n.stats.pagesRendered}, saved ${n.stats.pagesSaved}, discovered ${n.stats.pagesQueued}.`,{donePages:c,claimedPages:n.donePages.size,pagesRendered:n.stats.pagesRendered,pagesSaved:n.stats.pagesSaved,pagesQueued:n.stats.pagesQueued,pageQueue:n.pageQueue.length,phase:"save-pages"});}function Ln(e){let t=tr(e);return t%5===0||t===1||t===e.stats.pagesQueued}function Dn(e,t){let r=tr(e);t.progress(`Render progress: processed ${r}, rendered ${e.stats.pagesRendered}, saved ${e.stats.pagesSaved}, discovered ${e.stats.pagesQueued}.`,{donePages:r,claimedPages:e.donePages.size,pagesRendered:e.stats.pagesRendered,pagesSaved:e.stats.pagesSaved,pagesQueued:e.stats.pagesQueued,phase:"render-pages"});}async function mi(e){await e.addInitScript(()=>{Object.defineProperty(window,"__WPSUITE_STATIC_EXPORT__",{value:true,writable:false,configurable:true});let t=r=>{if(r==null||String(r)==="")return true;try{let n=new URL(String(r),window.location.href),s=new URL(window.location.href);return n.hash="",s.hash="",n.href===s.href}catch{return false}};try{let r=window.location.assign.bind(window.location),n=window.location.replace.bind(window.location),s=window.location.reload.bind(window.location);Object.defineProperty(window.location,"assign",{configurable:!0,value:o=>{if(t(o)){console.warn("[smartcloud-static-publisher] blocked same-page location.assign",o??"");return}return r(o)}}),Object.defineProperty(window.location,"replace",{configurable:!0,value:o=>{if(t(o)){console.warn("[smartcloud-static-publisher] blocked same-page location.replace",o??"");return}return n(o)}}),Object.defineProperty(window.location,"reload",{configurable:!0,value:()=>{console.warn("[smartcloud-static-publisher] blocked location.reload");}});}catch{}});}async function hi(e,t,r){let n=await e.newContext({viewport:t.viewport,userAgent:"WPSuiteStaticPublisher/0.8 Playwright SitemapOnly",ignoreHTTPSErrors:t.ignoreHttpsErrors,...r?{javaScriptEnabled:false}:{}});return r||await mi(n),n}async function gi(e,t,r,n,s,o,i,c,a,l){for(;t.pageQueue.length>0&&!(e.maxPages>0&&t.donePages.size>=e.maxPages);){let d=t.pageQueue.shift();if(!d)break;t.queuedPages.delete(d);try{let u=re(d,r,"page","page-queue");if(!u)continue;let h=u.toString();if(d=h,t.queuedPages.delete(d),t.donePages.has(d))continue;t.donePages.add(d),o.enabled&&o.seenPages.add(d);let f=yt(e,d),g=Un(e,u.pathname);if(!Se(u)||q(e,u)||Ee(u)){if(q(e,u)){r.info(`Remote worker redirected non-page URL to asset queue: ${d}`,{url:d,source:"remote-worker-guard"}),W(e,t,d,r,"remote-worker-guard");continue}r.reject("page",d,"guard rejected non-page URL before remote rendering","remote-worker");continue}let y=o.strictTargeted?o.manifest.pages[d]:void 0;if(y?.lastSeenRunId===o.runId&&await Ie(y.outputPath)){o.seenPages.add(d);for(let v of y.discoveredAssets||[])W(e,t,v,r,d);J(i,e,y.outputPath),te(i,y.outputPath),r.info(`Resumed completed content-sync page ${d}`,{url:d,source:"content-sync-checkpoint"});continue}let p=await Pn(e,s,t,o,d,r);if(o.enabled&&n!=="single-url"&&n!=="content-sync"){let v=o.manifest.pages[d];if(p.action==="reuse"&&v){for(let C of v.discoveredAssets)W(e,t,C,r,d);for(let C of v.discoveredPages)Oe(e,t,C,r,d);v.lastSeenRunId=o.runId,v.sitemapLastmod=Te(t.sitemapLastmodByPage[d])??v.sitemapLastmod,p.changeToken?.supported&&(v.changeToken=p.changeToken.token,v.tokenSource=p.changeToken.tokenSource??v.tokenSource),r.info(`Incremental reuse skipped unchanged page ${d}`,{url:d,mode:"incremental",reason:p.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}r.page(`Rendering remotely ${d}`,{url:d,execution:"lambda"});let m=await a.render({sourceOrigin:e.sourceOrigin,url:d,options:{ignoreHttpsErrors:e.ignoreHttpsErrors,javaScriptEnabled:!g,viewport:e.viewport,navigationTimeoutMs:e.navigationTimeoutMs,autoScrollTimeoutMs:jn(e),readiness:e.readiness},downloadHtml:!l}),b=m.page,k=b.finalUrl?re(b.finalUrl,r,"remote-final-response",d)?.toString():void 0;if(n==="content-sync"&&k&&k!==h){if(o.deleteOnMissingUrls.has(d)){await Ge(e,o,i,d,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive route redirected to ${k}`,{url:d,finalResponseUrl:k,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${d} -> ${k}`)}let R=b.httpStatus;if(f){if(R!==404){r.error(`Generated 404 request path returned unexpected status for ${d}`,{url:d,expectedStatus:404,status:R,requestPath:e.generated404RequestPath,execution:"lambda"});continue}}else if(R!==null&&R>=400){if(n==="content-sync"&&(R===404||R===410)&&o.deleteOnMissingUrls.has(d)){await Ge(e,o,i,d,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive page ${d}`,{url:d,status:R,source:"content-sync-tombstone"});continue}if(n==="content-sync")throw new Error(`Required content-sync route returned HTTP ${R}: ${d}`);r.skip("page",d,R,t.pageDiscoverySources.get(d));continue}t.stats.pagesRendered++;let O=new Set;if(!l){if(m.html===null)throw new Error("Remote render did not return HTML for local output mode.");for(let v of We(e,h,m.html,r,"remote-page-html"))O.add(v);}for(let v of [...b.discoveredAssets,...b.networkUrls]){let C=H(e,v,h,r,"remote-render");C&&q(e,C)&&O.add(C.toString());}for(let v of O)W(e,t,v,r,d);let A=n!=="single-url"&&n!=="content-sync"&&!f?[...new Set([...!l&&m.html!==null?$n(e,d,m.html,r):[],...b.discoveredPages])]:[];for(let v of A)Oe(e,t,v,r,d);for(let v of b.cookies){let C=v.sameSite==="Strict"||v.sameSite==="Lax"||v.sameSite==="None"?v.sameSite:"Unspecified",T=!Number.isFinite(v.expires)||v.expires<=0;c.add({name:v.name,domain:v.domain,path:v.path||"/",expires:T?null:v.expires,session:T,secure:v.secure,httpOnly:v.httpOnly,sameSite:C,partitioned:v.partitioned===!0});}let x=le(e,d);if(l){if(!b.html)throw new Error("Remote render completed without a workspace HTML object.");Le(l,{relativePath:wt(e,x),sourceUrl:d,kind:"page",contentType:b.contentType?.trim()||"text/html; charset=utf-8",cacheControl:e.s3.htmlCacheControl,isText:!0,object:b.html});}else {if(m.html===null)throw new Error("Remote render did not return HTML for local output mode.");await Yt(e,d,m.html,t,r);}J(i,e,x),te(i,x),o.trackManifest&&(o.manifest.pages[d]={url:d,outputPath:x,contentType:b.contentType?.trim()||null,changeToken:p.changeToken?.supported?p.changeToken.token:null,tokenSource:p.changeToken?.supported?p.changeToken.tokenSource??null:null,sitemapLastmod:Te(t.sitemapLastmodByPage[d])??null,discoveredPages:A,discoveredAssets:[...O],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,rewriteComplete:!1},(o.enabled||o.strictTargeted)&&await be(e,o)),r.debug(`Remote render completed ${d}`,{url:d,taskId:m.taskId,attempts:m.attempts,execution:"lambda"});}catch(u){if(r.error(`Failed remote page ${d}`,{url:d,error:String(u),execution:"lambda"}),o.strictTargeted)throw u}finally{t.stats.pagesCompleted++,Ln(t)&&Dn(t,r);}}}async function fi(e,t,r,n,s,o,i,c){let a=await chromium.launch({headless:true}),l=Zt(a);l.pid!==null&&r.debug(`Launched crawl worker browser PID ${l.pid}`,{browserPid:l.pid});try{for(;t.pageQueue.length>0;){a||(a=await chromium.launch({headless:!0}),l=Zt(a),l.pid!==null&&r.debug(`Relaunched crawl worker browser PID ${l.pid}`,{browserPid:l.pid}));let d=a;if(e.maxPages>0&&t.donePages.size>=e.maxPages)break;let u=t.pageQueue.shift();if(!u)break;t.queuedPages.delete(u);let h=null,f=null,g=!1,y=[],p=new Set;try{let m=re(u,r,"page","page-queue");if(!m)continue;let b=m.toString();if(u=b,t.queuedPages.delete(u),t.donePages.has(u))continue;t.donePages.add(u),o.enabled&&o.seenPages.add(u);let k=yt(e,u),R=Un(e,m.pathname);if(!Se(m)||q(e,m)||Ee(m)){if(q(e,m)){r.info(`Worker redirected non-page URL to asset queue: ${u}`,{url:u,source:"worker-guard"}),W(e,t,u,r,"worker-guard");continue}r.reject("page",u,"guard rejected non-page URL before rendering","worker");continue}let O=o.strictTargeted?o.manifest.pages[u]:void 0;if(O?.lastSeenRunId===o.runId&&await Ie(O.outputPath)){o.seenPages.add(u);for(let I of O.discoveredAssets||[])W(e,t,I,r,u);J(i,e,O.outputPath),te(i,O.outputPath),r.info(`Resumed completed content-sync page ${u}`,{url:u,source:"content-sync-checkpoint"});continue}let A=await Pn(e,s,t,o,u,r);if(o.enabled&&n!=="single-url"&&n!=="content-sync"){let I=o.manifest.pages[u];if(A.action==="reuse"&&I){for(let F of I.discoveredAssets)W(e,t,F,r,u);for(let F of I.discoveredPages)Oe(e,t,F,r,u);I.lastSeenRunId=o.runId,I.sitemapLastmod=Te(t.sitemapLastmodByPage[u])??I.sitemapLastmod,A.changeToken?.supported&&(I.changeToken=A.changeToken.token,I.tokenSource=A.changeToken.tokenSource??I.tokenSource),r.info(`Incremental reuse skipped unchanged page ${u}`,{url:u,mode:"incremental",reason:A.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}h=await V(`create page context ${u}`,ye(e),()=>hi(d,e,R)),f=await V(`create page ${u}`,ye(e),()=>h.newPage()),y=await h.cookies();let x=!1,v=new Set;await f.route("**/*",async I=>{let F=I.request();try{let U=H(e,F.url(),e.sourceOrigin,r,"network-request");U&&q(e,U)&&(v.add(U.toString()),W(e,t,U.toString(),r,u));}catch{}if(F.isNavigationRequest()&&F.frame()===f.mainFrame())try{let U=new URL(F.url()),ne=new URL(b);if(U.hash="",ne.hash="",U.href===ne.href){if(x){r.warn(`Blocked same-page navigation/reload for ${u}`,{url:u,requestUrl:F.url()});try{await I.abort("aborted");}catch(de){r.debug(`Ignored canceled route while blocking reload for ${u}`,{url:u,error:String(de)});}return}x=!0;}}catch{}try{await I.continue();}catch(U){r.debug(`Ignored canceled network route for ${u}`,{url:u,requestUrl:F.url(),error:String(U)});}}),f.on("response",I=>{try{let U=H(e,I.url(),e.sourceOrigin,r,"network-response");U&&q(e,U)&&(v.add(U.toString()),W(e,t,U.toString(),r,u));}catch{}let F=I.headerValues("set-cookie").then(U=>{for(let ne of U)c.add(Lr(ne,I.url()));}).catch(()=>{}).then(()=>{});p.add(F),F.finally(()=>p.delete(F));}),r.page(`Rendering ${u}`,{url:u});let C=null,T=null;try{if(C=await f.goto(u,{waitUntil:"domcontentloaded",timeout:e.navigationTimeoutMs}),C&&C.ok())try{T=await V(`read response body ${u}`,ye(e),()=>C.text());}catch{T=null;}}catch(I){r.warn(`Navigation issue for ${u}; saving current DOM if available`,{url:u,error:String(I)});}if(n==="content-sync"&&C){let I=re(C.url(),r,"content-sync-final-response",u)?.toString();if(I&&I!==b){if(o.deleteOnMissingUrls.has(u)){await Ge(e,o,i,u,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive route redirected to ${I}`,{url:u,finalResponseUrl:I,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${u} -> ${I}`)}}if(k){let I=C?.status()??null;if(I!==404){r.error(`Generated 404 request path returned unexpected status for ${u}`,{url:u,expectedStatus:404,status:I,requestPath:e.generated404RequestPath});continue}r.info(`Capturing rendered 404 page for ${u}`,{url:u,status:I,outputPath:le(e,u)});}else if(C&&!C.ok()){if(n==="content-sync"&&(C.status()===404||C.status()===410)&&o.deleteOnMissingUrls.has(u)){await Ge(e,o,i,u,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive page ${u}`,{url:u,status:C.status(),source:"content-sync-tombstone"}),await f.close();continue}if(n==="content-sync")throw new Error(`Required content-sync route returned HTTP ${C.status()}: ${u}`);r.skip("page",u,C.status(),t.pageDiscoverySources.get(u)),await f.close();continue}R?(r.info(`Rendering without JS execution for ${u}`,{url:u,mode:"no-js"}),await V(`wait for rendered page ${u}`,ye(e),()=>di(e,f))):await V(`wait for rendered page ${u}`,ye(e),()=>li(e,f)),t.stats.pagesRendered++;let Q=await V(`extract rendered assets ${u}`,ye(e),()=>pi(e,f,b,r,!R));for(let I of Q)W(e,t,I,r,u);let D=[...new Set([...Q,...v])],P=T??await V(`capture rendered html ${u}`,ye(e),()=>un(f)),j=n!=="single-url"&&n!=="content-sync"&&!k?$n(e,u,P,r):[];if(n!=="single-url"&&n!=="content-sync"&&!k)for(let I of j)Oe(e,t,I,r,u);await Yt(e,u,P,t,r);let Y=le(e,u);if(J(i,e,Y),te(i,Y),o.trackManifest){let I=C?.headers();o.manifest.pages[u]={url:u,outputPath:Y,contentType:Bt(I),changeToken:A.changeToken?.supported?A.changeToken.token:null,tokenSource:A.changeToken?.supported?A.changeToken.tokenSource??null:null,sitemapLastmod:Te(t.sitemapLastmodByPage[u])??null,discoveredPages:j,discoveredAssets:D,lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,rewriteComplete:!1},(o.enabled||o.strictTargeted)&&await be(e,o);}}catch(m){if(g=m instanceof Je,o.strictTargeted)throw r.error(`Failed required content-sync page ${u}`,{url:u,error:String(m)}),m;if(g)r.warn(`Skipped partial DOM for timed-out page ${u}`,{url:u,error:String(m),recovery:"recycle-worker-browser"});else try{let b=f?await V(`capture partial html ${u}`,ye(e),()=>un(f)):"";if(b&&b.trim()){await Yt(e,u,b,t,r);let k=le(e,u);if(J(i,e,k),te(i,k),o.trackManifest){let R=o.manifest.pages[u]??o.previousManifest.pages[u];o.manifest.pages[u]={url:u,outputPath:k,contentType:R?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:Te(t.sitemapLastmodByPage[u])??R?.sitemapLastmod??null,discoveredPages:R?.discoveredPages?[...R.discoveredPages]:[],discoveredAssets:R?.discoveredAssets?[...R.discoveredAssets]:[],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,rewriteComplete:!1},(o.enabled||o.strictTargeted)&&await be(e,o);}r.warn(`Saved partial DOM for ${u}`,{url:u,error:String(m)});}}catch(b){b instanceof Je&&(g=!0),r.error(`Could not save partial DOM for ${u}`,{url:u,error:String(b)});}r.error(`Failed page ${u}`,{url:u,error:String(m)});}finally{if(!g&&f&&await V(`drain network routes ${u}`,Qe(e),()=>f.unrouteAll({behavior:"wait"})).catch(m=>{g=!0,r.warn(`Could not drain network routes for ${u}`,{url:u,browserPid:l.pid,error:String(m),recovery:"recycle-worker-browser"});}),g&&(a=null,await _t(d,r,`page operation timeout for ${u}`),await d.close().catch(()=>{})),p.size>0&&await Promise.allSettled([...p]),!g&&h)try{let m=await h.cookies();c.addAll(Dr(y,m));}catch{}t.stats.pagesCompleted++,Ln(t)&&Dn(t,r),!g&&f&&await V(`close page ${u}`,Qe(e),()=>f.close()).catch(m=>{g=!0,r.warn(`Timed out while closing page ${u}`,{url:u,browserPid:l.pid,error:String(m),recovery:"recycle-worker-browser"});}),!g&&h&&await V(`close page context ${u}`,Qe(e),()=>h.close()).catch(m=>{g=!0,r.warn(`Timed out while closing page context for ${u}`,{url:u,browserPid:l.pid,error:String(m),recovery:"recycle-worker-browser"});}),g&&a===d&&(a=null,await _t(d,r,`page cleanup timeout for ${u}`),await d.close().catch(()=>{}));}}}finally{if(a){let d=a;await V("close worker browser",Qe(e),()=>d.close()).catch(u=>(r.warn("Timed out while closing crawl worker browser",{browserPid:l.pid,error:String(u)}),_t(d,r,"browser.close timeout")));}}}async function wi(e){try{let t=await M.readFile(e),n=(e.endsWith(".gz")?gunzipSync(t):t).toString("utf8").trim();if(!n)return [];try{let s=JSON.parse(n);if(Array.isArray(s))return s;if(s&&typeof s=="object")return [s]}catch{return n.split(/\r?\n/).map(s=>s.trim()).filter(Boolean).map(s=>{try{let o=JSON.parse(s);return o&&typeof o=="object"?o:null}catch{return null}}).filter(s=>s!==null)}return []}catch{return []}}function ln(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function yi(e){let t=String(e?.job?.command||"").trim(),r=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:r!=="incremental"}function bi(e){let t=[e?.archivedAt,e?.job?.endedAt,e?.job?.startedAt];for(let r of t){let n=Date.parse(String(r||""));if(Number.isFinite(n))return n}return 0}async function Fn(e){try{let t=await M.readFile(e,"utf8"),r=JSON.parse(t);return r&&typeof r=="object"&&!Array.isArray(r)?r:null}catch{return null}}function dn(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function Si(e,t){let r=Array.isArray(t?.artifacts)?t.artifacts.filter(n=>String(n?.role||"").trim()==="errors"&&String(n?.storedFileName||"").trim()!=="").sort((n,s)=>dn(n)-dn(s)).map(n=>w.join(e,String(n.storedFileName))):[];return [...new Set([...r,w.join(e,"errors.jsonl"),w.join(e,"errors.json"),w.join(e,"errors.jsonl.gz"),w.join(e,"errors.json.gz")])]}async function pn(e){let t=await Fn(w.join(e,"job.json"));for(let r of Si(e,t)){let n=await wi(r);if(n.length>0)return n}return []}async function Pi(e){let t=w.join(e.logDir,"archive"),r;try{r=await M.readdir(t);}catch{return ""}let n="",s=0;for(let o of r){let i=w.join(t,o);if(!(await M.stat(i).catch(()=>null))?.isDirectory())continue;let a=await Fn(w.join(i,"job.json"));if(!yi(a))continue;let l=bi(a);l>=s&&(s=l,n=i);}return n}async function Ri(e){let t=await Pi(e),r=t!==""?await pn(t):await pn(e.logDir),n=new Set;for(let s of r)if(ln(s.error)||ln(s.message)){let o=s.url;typeof o=="string"&&o&&n.add(o);}return [...n]}async function vi(e){let t=[];for(let r of e)if(r.startsWith("@")){let n=r.slice(1),s=await M.readFile(n,"utf8");t.push(...s.split(/\r?\n/).map(o=>o.trim()).filter(o=>o&&!o.startsWith("#")));}else t.push(r);return t}async function ki(e){if(!e)throw new Error("Content-sync crawl requires an immutable impact plan.");let t=JSON.parse(await M.readFile(e,"utf8"));return lr(t),t}function Ci(e,t){let r;try{r=new URL(e);}catch{return false}return t.archiveFamilies.some(n=>{let s=new URL(n.url);if(r.origin!==s.origin)return false;if(r.toString()===s.toString())return true;if(r.searchParams.has("paged")&&r.pathname===s.pathname)return /^\d+$/.test(r.searchParams.get("paged")||"");let o=s.pathname.replace(/\/+$/,""),i=r.pathname.slice(o.length).replace(/^\/+/,""),c=String(n.paginationBase||"page").replace(/^\/+|\/+$/g,"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return r.pathname.startsWith(`${o}/`)&&new RegExp(`^${c}/\\d+/?$`).test(i)})}function ze(e,t,r){let n=r==="page"?le(e,t):Ye(e,t).originalFilePath;return Z(e.outputDir,n)}async function Ge(e,t,r,n,s){let o=t.manifest.pages[n];if(!o)return;let i=Z(e.outputDir,o.outputPath);if(!i)throw new Error(`Manifest-owned page path escaped output root: ${n}`);let c=w.resolve(o.outputPath);Object.entries(t.manifest.pages).some(([l,d])=>l!==n&&!s.has(l)&&w.resolve(d.outputPath)===c)||(await M.rm(o.outputPath,{force:true}),r.deletedFiles.add(i),r.revalidateFiles.delete(i)),delete t.manifest.pages[n];}async function xi(e,t,r,n,s){let o=t.manifest.assets[n];if(!o)return;let i=Z(e.outputDir,o.outputPath);if(!i)throw new Error(`Manifest-owned resource path escaped output root: ${n}`);let c=w.resolve(o.outputPath);Object.entries(t.manifest.assets).some(([l,d])=>l!==n&&!s.has(l)&&w.resolve(d.outputPath)===c)||(await M.rm(o.outputPath,{force:true}),r.deletedFiles.add(i)),delete t.manifest.assets[n];}function Ai(e,t){let r=new Set,n=[...t];for(;n.length>0;){let s=n.shift();if(r.has(s))continue;r.add(s);let o=e.assets[s];for(let i of o?.discoveredAssets??[])try{qe(new URL(i))&&n.push(i);}catch{}}return r}async function Ti(e,t,r,n,s){let o=Ai(r.previousManifest,s);for(let i of o){if(t.successfulSitemaps.has(i))continue;let c=r.previousManifest.assets[i];if(!c)continue;let a=Z(e.outputDir,c.outputPath);if(!a)throw new Error(`Manifest-owned sitemap path escaped output root: ${i}`);await M.rm(c.outputPath,{force:true}),n.deletedFiles.add(a),delete r.manifest.assets[i];}await be(e,r);}async function Ii(e){try{let t=await M.readFile(w.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function Ei(e){let t=["crawl.log.jsonl","current-crawl-event.json","rejected.jsonl","ignored.jsonl","skipped-http.jsonl","errors.jsonl","timings.jsonl","rejected.json","ignored.json","skipped-http.json","errors.json","timings.json"];await M.mkdir(e,{recursive:true}),await Promise.all(t.map(async r=>{try{await M.unlink(w.join(e,r));}catch(n){if(n.code!=="ENOENT")throw n}}));}function mn(e,t,r,n,s){let o=H(e,r,e.sourceOrigin,n,"manual-url");o&&(qe(o)?ft(e,t,o.toString(),n,s):q(e,o)?W(e,t,o.toString(),n,s):Se(o)?Oe(e,t,o.toString(),n,s):n.reject("manual-url",o.toString(),"not page/sitemap/asset-like",s));}async function Wn(e=process.argv.slice(2)){let t=[],r=await tt(void 0,{onRemotePublisherConfigDiagnostic:S=>{t.push(S);}}),n=dr(r.sitemapPaths),s=t.at(-1)??null,o=po(e),i=o.mode==="content-sync"?await ki(o.contentSyncPlanPath):null;if(o.resumeRewrite&&o.mode!=="full")throw new Error("--resume-rewrite is only supported for full crawl/publish jobs.");let c=[];o.mode==="retry-timeouts"&&(c=await Ri(r)),o.mode==="single-url"&&(c=await vi(o.urls)),i&&(c=[...i.directRenderUrls,...i.archiveFamilyUrls,...i.resourceRenderUrls]);let a=o.crawlMode==="incremental"&&o.mode==="full",l=a&&typeof r.subscriptionType=="string"&&r.subscriptionType.trim()!=="";if(i&&r.subscriptionType!=="PROFESSIONAL"&&r.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let d=(o.mode==="full"||o.mode==="single-url"||o.mode==="content-sync")&&!o.resumeRewrite,u=o.mode!=="full"||o.resumeRewrite||l,h=u?await Ii(r):{},f=l||o.mode==="single-url"||o.mode==="content-sync"?await So(r):yn(),g=new Set(c),y=new Set;if(i){for(let S of i.archiveFamilies)if(S.foundPosts===0)for(let $ of S.pageUrls)y.add($);for(let S of Object.keys(f.pages))Ci(S,i)&&!g.has(S)&&(c.push(S),y.add(S));}let p={enabled:l,trackManifest:d,manifest:zt(f),previousManifest:zt(f),runId:i?.jobId??`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,pageChangeTokenPrimePromise:null,manifestSaveChain:Promise.resolve(),manifestPendingChanges:0,lastManifestSavedAt:Date.now(),strictTargeted:!!i,requiredUrls:g,deleteOnMissingUrls:y};await Ei(r.logDir);let m=new je(r.logDir,r.logLevel),b=o.remoteRender??r.remoteWorkers?.render?.enabled===true,k=Jr({explicitPath:o.remoteWorkerConfigPath,runtimeDir:Ze()}),R=null,O=null,A=null,x=null,v=Math.max(1,r.concurrency),C=1,T=r.remoteWorkers?.rewrite?.enabled===true,Q=r.remoteWorkers?.deploy?.enabled===true,D=b&&T&&Q&&!o.resumeRewrite;if(!D&&o.mode==="full"&&!o.resumeRewrite&&await M.rm(dt(r),{force:true}),b&&!o.resumeRewrite||T){if(!k)throw new Error("Remote Lambda workers are enabled, but the runtime directory is unknown. Run through queue-runner with --runtime-dir, set STATIC_PUBLISHER_RUNTIME_DIR, or use --remote-worker-config for a diagnostic run.");let S=await _r(k),$=false;if(A=new ct(S,{},{onProgress:E=>{m.progress(`Lambda ${E.operation} batch: ${E.completedItems+E.failedItems}/${E.totalItems}`,{remoteWorkerOperation:E.operation,remoteWorkerTaskId:E.taskId,remoteWorkerStatus:E.status,remoteWorkerCompletedItems:E.completedItems,remoteWorkerFailedItems:E.failedItems,remoteWorkerTotalItems:E.totalItems,remoteWorkerUpdatedAt:E.updatedAt});},onProgressError:E=>{$||($=true,m.warn("Lambda progress status could not be read; task execution continues.",{error:E.message}));}}),D){if(!S.functions.asset)throw new Error("Full Lambda delegation requires an asset worker. Redeploy the Lambda worker stack and reinstall remote-workers.json.");let E=u?await tn(r):null;x=Yr(`crawl-${oe(p.runId,40)}`,S,E),O=new lt({client:A,jobId:x.jobId,maxAttempts:2}),m.info("S3-native Lambda data plane is enabled.",{execution:"lambda",assetWorker:S.functions.asset,workspaceBucket:S.workspace.bucket,workspacePrefix:S.workspace.prefix});}}if(b&&!o.resumeRewrite){if(!A)throw new Error("Remote render worker client was not initialized.");v=Math.max(1,Math.min(100,D?r.concurrency:r.remoteWorkers?.render?.concurrency??r.concurrency)),C=Math.max(1,Math.min(20,r.remoteWorkers?.render?.batchSize??5)),R=new ut({client:A,jobId:`crawl-${oe(p.runId,40)}`,maxAttempts:r.remoteWorkers?.render?.maxAttempts??2,batchSize:C,maxConcurrentBatches:v,onRetry:S=>{m.warn(`Retrying remote render for ${S.url}`,{url:S.url,attempt:S.attempt,maxAttempts:S.maxAttempts,reason:S.reason,execution:"lambda"});}}),m.info("Lambda page rendering is enabled.",{remoteWorkerConfigPath:w.resolve(k),concurrency:v,maxAttempts:r.remoteWorkers?.render?.maxAttempts??2,batchSize:C,execution:"lambda"});}if(s){let S={status:s.status,virtualAssetBaseUrl:s.virtualAssetBaseUrl,subscriptionType:s.subscriptionType??null,error:s.error,requests:s.requests,source:"remote-publisher-config"};s.status==="loaded"&&s.subscriptionType?m.info("Loaded remote WP Suite publisher configuration.",S):m.warn("Remote WP Suite publisher configuration is unavailable or has no active subscription type.",S);}if(a&&!l){let S="Incremental crawl requires an active remote publisher subscription; refusing to fall back to a destructive full crawl.";throw m.error(S,{requestedMode:o.crawlMode,subscriptionType:r.subscriptionType??null,source:"incremental-subscription-guard"}),await m.flush(),new Error(S)}let P={pageQueue:[],queuedPages:new Set,donePages:new Set,pageDiscoverySources:new Map,assetQueue:[],queuedAssets:new Set,doneAssets:new Set,sitemapQueue:[],queuedSitemaps:new Set,doneSitemaps:new Set,successfulSitemaps:new Set,resolvedSitemapRoots:new Set,sitemapIndexUrls:new Set,sitemapLeafUrls:new Set,sitemapLastmodByPage:{},assetMap:{...h},assetVariantDigestsByOriginalPath:new Map,stats:{pagesQueued:0,pagesRendered:0,pagesCompleted:0,assetsQueued:0,sitemapsQueued:0,assetsSaved:0,pagesSaved:0}},j=bo(),Y=new it,I=mo();if(I&&!o.resumeRewrite&&await at(I,Y.artifact()),await ar(r),await cr(r,{startedAt:new Date().toISOString(),outputDir:w.resolve(r.outputDir)}),u||await M.rm(r.outputDir,{recursive:true,force:true}),await M.mkdir(r.outputDir,{recursive:true}),i){let S=new Set([...i.deleteUrls,...p.deleteOnMissingUrls]);for(let E of i.deleteUrls)await Ge(r,p,j,E,S);let $=new Set(i.resourceDeleteUrls);for(let E of i.resourceDeleteUrls)await xi(r,p,j,E,$);}if(o.resumeRewrite)m.info("Resuming final rewrite from existing output.",{phase:"rewrite-text",mode:o.mode,crawlMode:o.crawlMode});else {let S=await request.newContext({ignoreHTTPSErrors:r.ignoreHttpsErrors});try{if(m.mark("discovery"),o.mode==="full"?(n.forEach(E=>ft(r,P,E,m)),await an(r,S,P,m,j,p),r.seedPaths.forEach(E=>mn(r,P,E,m,"seed-path")),r.generated404RequestPath&&Oe(r,P,r.generated404RequestPath,m,"generated-404-request-path")):(c.forEach(E=>mn(r,P,E,m,"cli")),i?.sitemapUrls.forEach(E=>ft(r,P,E,m,"content-sync-impact")),await an(r,S,P,m,j,p,o.mode==="content-sync",i?.sitemapUrls??[]),i&&await Ti(r,P,p,j,i.sitemapUrls)),m.endMark("discovery",{pages:P.pageQueue.length,assets:P.assetQueue.length,sitemaps:P.sitemapQueue.length}),m.summary(`Queued ${P.pageQueue.length} pages, ${P.assetQueue.length} assets, ${P.sitemapQueue.length} sitemaps.`,{mode:o.mode,crawlMode:o.crawlMode,queuedPages:P.pageQueue.length,queuedAssets:P.assetQueue.length,queuedSitemaps:P.sitemapQueue.length}),o.mode==="retry-timeouts"&&P.pageQueue.length===0&&P.assetQueue.length===0&&P.sitemapQueue.length===0){m.summary("No timed-out URLs were queued. Skipping retry crawl.",{mode:o.mode,crawlMode:o.crawlMode,queuedPages:0,queuedAssets:0,queuedSitemaps:0}),await m.flush(),I&&await at(I,Y.artifact());return}m.mark("render-pages");let $=Array.from({length:R?v*C:v},()=>R?gi(r,P,m,o.mode,S,p,j,Y,R,x??void 0):fi(r,P,m,o.mode,S,p,j,Y));if(await Promise.all($),I&&await at(I,Y.artifact()),m.endMark("render-pages",{pages:P.stats.pagesCompleted}),m.mark("download-assets"),m.progress("Asset download phase started.",{phase:"download-assets",doneAssets:P.doneAssets.size,assetsQueued:P.stats.assetsQueued,assetQueue:P.assetQueue.length}),x&&O?await ii(r,S,P,m,p,j,x,O,r.concurrency):(await Xt(r,S,p,[...P.assetQueue],m),await si(r,S,P,m,p,j)),m.endMark("download-assets",{assets:P.doneAssets.size}),p.enabled&&r.maxPages===0&&(await Ao(r,P,p,m,j),o.mode==="full"&&await To(r,p,m,j)),o.mode==="full"){let E=await ri(r,P,m);for(let N of E)if(J(j,r,N),x&&A){let K=wt(r,N),xe=await M.readFile(N),Ae=ie(N),Me=String(Br.lookup(K)||"")||(Ae?"text/plain; charset=utf-8":"application/octet-stream"),et=await A.writeWorkspaceObject({key:`${x.workspace.prefix}jobs/${x.jobId}/copied/${oe(K,40)}-${w.basename(K)}`,body:xe,contentType:Me});Le(x,{relativePath:K,sourceUrl:null,kind:"generated",contentType:et.contentType,cacheControl:null,isText:Ae,object:et}),Ae&&te(j,N);}}}finally{await V("dispose crawl request context",Qe(r),()=>S.dispose()).catch($=>{m.warn("Timed out while disposing crawl request context",{error:String($)});});}}if(p.trackManifest&&await be(r,p,true),x)for(let S of j.deletedFiles)Xr(x,S);let F=JSON.stringify(P.assetMap,null,2);if(await M.writeFile(w.join(r.outputDir,"asset-map.json"),F,"utf8"),x&&A){let S=await A.writeWorkspaceObject({key:`${x.workspace.prefix}jobs/${x.jobId}/generated/asset-map.json`,body:F,contentType:"application/json; charset=utf-8"});Le(x,{relativePath:"asset-map.json",sourceUrl:null,kind:"generated",contentType:"application/json; charset=utf-8",cacheControl:r.s3.assetCacheControl,isText:true,object:S});}JSON.stringify(h,null,2)!==JSON.stringify(P.assetMap,null,2)&&J(j,r,w.join(r.outputDir,"asset-map.json")),x&&A&&await ai(r,j,x,A);let U=o.mode==="single-url"||o.mode==="content-sync"?Lo(r,P):p.enabled&&!o.resumeRewrite?Io(r,p,j,h,P.assetMap):void 0;m.mark("rewrite-text");let ne=o.mode==="single-url"||o.mode==="content-sync"?`Rewriting text files touched by URL crawl: 0/${U?.length??0}`:"Rewriting text files...";m.progress(ne,{phase:"rewrite-text",index:0,totalFiles:U?.length,changedTextFiles:0}),await Nt(ne);let de=Date.now(),Pe={files:U,previousAssetMap:h,onStart:({totalFiles:S,workerCount:$})=>{m.info(`Rewrite phase scanning ${S} text files.`,{phase:"rewrite-text",totalFiles:S,workerCount:$});},onProgress:async({index:S,totalFiles:$,changedTextFiles:E,file:N,changed:K})=>{K&&J(j,r,w.join(r.outputDir,N)),m.checkpoint(`Rewriting text file ${S}/${$}`,{phase:"rewrite-text",index:S,totalFiles:$,changedTextFiles:E,file:N}),m.debug(`${K?"Rewrote":"Checked unchanged"} text file ${S}/${$}: ${N}`,{phase:"rewrite-text",index:S,totalFiles:$,changedTextFiles:E,file:N,changed:K});let xe=Date.now();if(!(S===1||S===$||S%50===0||xe-de>=5e3))return;de=xe;let Me=`Rewriting text files: ${S}/${$}`;m.progress(Me,{phase:"rewrite-text",index:S,totalFiles:$,changedTextFiles:E,file:N}),await Nt(Me);}},G;if(x&&A){let S=U?.map(E=>wt(r,w.isAbsolute(E)?E:w.join(r.outputDir,E))),$=Object.values(x.objects).filter(E=>E.isText&&(!S||S.includes(E.relativePath))).length;await Pe.onStart?.({totalFiles:$,workerCount:Math.min(r.concurrency,$)}),G=await Kr(r,x,P.assetMap,{client:A,jobId:x.jobId,concurrency:r.concurrency,batchSize:25,maxAttempts:2,...S?{relativePaths:S}:{},onProgress:Pe.onProgress}),await en(r,x);}else T&&A?G=await Qr(r,P.assetMap,{client:A,jobId:`crawl-${oe(p.runId,40)}`,concurrency:r.remoteWorkers?.rewrite?.concurrency??r.rewriteConcurrency,batchSize:r.remoteWorkers?.rewrite?.batchSize??25,maxAttempts:r.remoteWorkers?.rewrite?.maxAttempts??2,onStageProgress:async({index:S,totalFiles:$,file:E})=>{let N=Date.now();if(S!==1&&S!==$&&S%25!==0&&N-de<5e3)return;de=N;let K=`Staging text files for Lambda rewrite: ${S}/${$}`;m.progress(K,{phase:"rewrite-stage",index:S,totalFiles:$,file:E,execution:"lambda"}),await Nt(K);},options:Pe}):G=await kr(r,P.assetMap,Pe);p.trackManifest&&(Eo(p,U),await be(r,p,true)),m.endMark("rewrite-text",{changedTextFiles:G});let Ne=i?[...j.deletedFiles].sort():p.enabled&&!o.resumeRewrite?await Mo(r,P,p,j,m,x):[],Xe=[...new Set((U||[]).map(S=>Z(r.outputDir,w.isAbsolute(S)?S:w.join(r.outputDir,S))).filter(S=>S!==null))].sort();if(i){let S=[...j.changedFiles].sort(),$=new Set(S),E=new Set(i.directRenderUrls.map(L=>ze(r,L,"page")).filter(L=>!!L&&$.has(L))),N=new Set(i.archiveFamilyUrls.map(L=>ze(r,L,"page")).filter(L=>!!L&&$.has(L))),K=new Set(i.resourceRenderUrls.map(L=>ze(r,L,"asset")).filter(L=>!!L&&$.has(L))),xe=new Set([...P.sitemapLeafUrls].map(L=>ze(r,L,"asset")).filter(L=>!!L&&$.has(L))),Ae=new Set([...P.sitemapIndexUrls].map(L=>ze(r,L,"asset")).filter(L=>!!L&&$.has(L))),Me=new Set([...E,...N,...K,...xe,...Ae]),et=S.filter(L=>!Me.has(L)),qn=[...new Set([...i.directRenderUrls,...i.archiveFamilyUrls,...P.resolvedSitemapRoots,...P.sitemapLeafUrls,...P.sitemapIndexUrls,...i.deleteUrls,...i.resourceRenderUrls,...i.resourceDeleteUrls].map(L=>{let rr=new URL(L);return `${rr.pathname}${rr.search}`}))].sort();await bt(r,{schemaVersion:2,generatedAt:new Date().toISOString(),outputDir:w.resolve(r.outputDir),runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,changedFiles:S,deletedFiles:Ne,rewriteTargets:Xe,revalidateFiles:[...j.revalidateFiles].sort(),consumerId:i.consumerId,fromSequence:i.fromSequence,toSequence:i.toSequence,impactHash:i.impactHash,resolvedSitemapUrls:[...P.resolvedSitemapRoots],uploadGroups:{assets:et,content:[...E].sort(),listings:[...N].sort(),resources:[...K].sort(),sitemapLeaves:[...xe].sort(),sitemapIndexes:[...Ae].reverse()},invalidationPaths:qn});}else await bt(r,{schemaVersion:1,generatedAt:new Date().toISOString(),outputDir:w.resolve(r.outputDir),runMode:o.mode,crawlMode:o.crawlMode,fullSyncRequired:!(p.enabled&&!o.resumeRewrite),changedFiles:p.enabled&&!o.resumeRewrite?[...j.changedFiles].sort():[],deletedFiles:p.enabled&&!o.resumeRewrite?Ne:[],rewriteTargets:p.enabled&&!o.resumeRewrite?Xe:[],revalidateFiles:[...j.revalidateFiles].sort()});await ur(r),m.summary(o.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${G} text files.`:`Done. Rendered ${P.stats.pagesRendered} pages, processed ${P.doneSitemaps.size} sitemaps and ${P.doneAssets.size} assets.`,{mode:o.mode,crawlMode:o.crawlMode,resumeRewrite:o.resumeRewrite,...P.stats,pagesRendered:P.stats.pagesRendered,donePages:P.stats.pagesCompleted,claimedPages:P.donePages.size,doneSitemaps:P.doneSitemaps.size,doneAssets:P.doneAssets.size,changedTextFiles:G}),await m.flush();}Wn().catch(async e=>{let t=ge(e instanceof Error?e.message:String(e));console.error(t);try{let n=(await tt().catch(()=>null))?.logDir??"logs",s=new je(n,"debug");s.error(`Unhandled error: ${t}`,e instanceof Error&&e.stack?{stack:ge(e.stack)}:void 0),await s.flush();}catch{}process.exit(1);});
|