@smart-cloud/publisher-exporter 1.1.62 → 1.1.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/content-sync.js +6 -6
- package/dist/queue-runner.js +3 -3
- package/dist/remote-worker.js +2 -2
- package/package.json +1 -1
package/dist/content-sync.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import D,{readFile}from'fs/promises';import po from'http';import gn from'https';import v from'path';import Fn,{createHash}from'crypto';import {request,chromium}from'playwright';import {gunzipSync}from'zlib';import Uo from'fast-glob';import {availableParallelism}from'os';import {Worker}from'worker_threads';import {LambdaClient,InvokeCommand}from'@aws-sdk/client-lambda';import {S3Client,GetObjectCommand,PutObjectCommand,ListObjectsV2Command,HeadObjectCommand,DeleteObjectsCommand}from'@aws-sdk/client-s3';import {fromTemporaryCredentials}from'@aws-sdk/credential-providers';import {Upload}from'@aws-sdk/lib-storage';import Vs from'mime-types';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';var oo=new Set(["post-type","taxonomy","author","date","posts-page","listing"]);function Te(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))].sort()}function io(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))]}function ao(e){return new URL(e).pathname.split("/").filter(Boolean).some(r=>{try{return decodeURIComponent(r).endsWith("__trashed")}catch{return r.endsWith("__trashed")}})}function pr(e){return Array.isArray(e)?e.map(pr):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>[t,pr(r)])):e}function co(e){return JSON.stringify(pr(e))}function be(e){return createHash("sha256").update(co(e)).digest("hex")}function an(e){return be({schemaVersion:1,wordpressFingerprint:e.wordpressFingerprint,targetFingerprint:e.targetFingerprint,sourceOrigin:e.sourceOrigin,sitemapPaths:[...e.sitemapPaths].sort(),blockedPathPrefixes:[...e.blockedPathPrefixes].sort(),assetPathPrefixes:[...e.assetPathPrefixes].sort(),noJavaScriptRenderPathPrefixes:[...e.noJavaScriptRenderPathPrefixes].sort(),urlRewriteMode:e.urlRewriteMode})}function gr(e){let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error(`Unsupported source origin protocol: ${t.protocol}`);return t.hash="",t.search="",t.pathname=t.pathname.replace(/\/+$/,""),t.toString().replace(/\/$/,"")}function le(e,t){lo(t);let r=new URL(gr(e)),n=new URL(t,`${r.toString().replace(/\/$/,"")}/`);if(n.origin!==r.origin)throw new Error(`Content-sync URL is outside the source origin: ${t}`);let s=r.pathname.replace(/\/+$/,"");if(s&&n.pathname!==s&&!n.pathname.startsWith(`${s}/`))throw new Error(`Content-sync URL is outside the source site path: ${t}`);return n.hash="",n.toString()}function lo(e){let r=String(e).split(/[?#]/,1)[0];for(let s=0;s<3;s+=1)try{let o=decodeURIComponent(r);if(o===r)break;r=o;}catch{throw new Error(`Content-sync URL has malformed encoding: ${e}`)}if(r.includes("\0")||r.includes("\\"))throw new Error(`Content-sync URL has an unsafe path: ${e}`);if(r.replace(/^[a-z][a-z0-9+.-]*:\/\/[^/]*/i,"").split("/").some(s=>s==="."||s===".."))throw new Error(`Content-sync URL has an unsafe path: ${e}`)}function ct(e){let t=Te((e.postTypes??[]).map(n=>String(n).toLowerCase().replace(/[^a-z0-9_-]/g,"")));if(t.length===0)throw new Error("Content-sync requires at least one public post type.");let r=Te((e.listingPaths??[]).map(n=>{let s=String(n).trim();if(!s)return "";let o=new URL(s,"https://content-sync.invalid/");if(o.origin!=="https://content-sync.invalid"&&/^https?:\/\//i.test(s))throw new Error("Content-sync listing routes must be same-site paths.");let a=`/${o.pathname.replace(/^\/+|\/+$/g,"")}`;return a==="/"?"/":`${a}/`}));return {postTypes:t,listingPaths:r,includeSubsites:e.includeSubsites===true,includePostTypeArchives:e.includePostTypeArchives!==false,includeTaxonomyArchives:e.includeTaxonomyArchives!==false,includeAuthorArchives:e.includeAuthorArchives===true,includeDateArchives:e.includeDateArchives===true,includePostsPage:e.includePostsPage!==false,includeSitemapChain:e.includeSitemapChain!==false}}function cn(e,t,r){return be({schemaVersion:1,sourceOrigin:gr(e),ruleId:t.trim(),scope:ct(r)})}function ln(e){return be({schemaVersion:1,...e})}function un(e){let t=String(e.siteId??"").trim()||String(e.accountId??"").trim()||gr(e.sourceOrigin);return `content-sync:${be({siteIdentity:t,ruleId:e.ruleId.trim(),targetFingerprint:e.targetFingerprint}).slice(0,48)}`}function dn(e){let t=[...e].sort((s,o)=>s.sequence-o.sequence),r=new Map,n=-1;for(let s of t){if(!Number.isSafeInteger(s.sequence)||s.sequence<=n)throw new Error("Content-sync journal events are not strictly ordered.");if(n=s.sequence,!Number.isSafeInteger(s.blogId)||s.blogId<1)throw new Error("Content-sync journal event has an invalid multisite identity.");let o=`${s.blogId}:${s.postType}:${s.postId}`,a=r.get(o);if(!a){r.set(o,{postId:s.postId,blogId:s.blogId,postType:s.postType,fromSequence:s.sequence,toSequence:s.sequence,before:s.before,after:s.after,operations:[s.operation],correlationIds:s.correlationId?[s.correlationId]:[]});continue}a.toSequence=s.sequence,a.after=s.after,a.operations.push(s.operation),s.correlationId&&!a.correlationIds.includes(s.correlationId)&&a.correlationIds.push(s.correlationId);}return [...r.values()].sort((s,o)=>s.fromSequence-o.fromSequence)}function on(e){return e?.status==="publish"&&!!e.url}function uo(e,t){return e==="post-type"?t.includePostTypeArchives:e==="taxonomy"?t.includeTaxonomyArchives:e==="author"?t.includeAuthorArchives:e==="date"?t.includeDateArchives:e==="posts-page"?t.includePostsPage:e==="listing"}function mr(e){let t=ct(e.scope),r=new Map;dn(e.events);for(let n of e.events)for(let s of [n.before,n.after])for(let o of s?.archiveFamilies??[]){if(!oo.has(o.kind)||!uo(o.kind,t))continue;let a={...o,url:le(e.sourceOrigin,o.url)};r.set(`${a.kind}|${a.url}`,a);}for(let n of t.listingPaths){let s=le(e.sourceOrigin,n);r.set(`listing|${s}`,{kind:"listing",url:s});}return [...r.values()].sort((n,s)=>n.url.localeCompare(s.url))}function pn(e){let t=ct(e.scope),r=dn(e.events),n=new Set,s=new Set,o=new Map,a=new Map(mr({events:e.events,scope:t,sourceOrigin:e.sourceOrigin}).map(p=>[`${p.kind}|${p.url}`,p]));for(let p of r){let y=p.before,m=p.after,h=on(y),w=on(m);w&&m.url&&n.add(le(e.sourceOrigin,m.url)),h&&y.url&&(!w||y.url!==m.url)&&s.add(le(e.sourceOrigin,y.url));}for(let p of [...e.events].sort((y,m)=>y.sequence-m.sequence)){for(let y of [p.before,p.after])for(let m of y?.resourceDeleteUrls??[])o.set(le(e.sourceOrigin,m),"delete");for(let y of p.after?.resourceRenderUrls??[])o.set(le(e.sourceOrigin,y),"render");}let c=[...o].filter(([,p])=>p==="render").map(([p])=>p),i=[...o].filter(([,p])=>p==="delete").map(([p])=>p),l=new Map(e.resolvedArchiveFamilies.map(p=>[`${p.kind}|${le(e.sourceOrigin,p.url)}`,{...p,url:le(e.sourceOrigin,p.url),pageUrls:Te(p.pageUrls.map(y=>le(e.sourceOrigin,y)))}])),d=[...a.entries()].map(([p,y])=>{let m=l.get(p);if(!m)throw new Error(`WordPress did not resolve archive family ${p}.`);return {...y,...m}}).sort((p,y)=>p.url.localeCompare(y.url)),u=Te(d.flatMap(p=>p.pageUrls)),g=t.includeSitemapChain?io(e.sitemapUrls.map(p=>le(e.sourceOrigin,p))):[],f={schemaVersion:1,generatedAt:new Date().toISOString(),jobId:e.jobId,ruleId:e.ruleId,consumerId:e.consumerId,coalesceKey:e.coalesceKey,scopeFingerprint:e.scopeFingerprint,targetFingerprint:e.targetFingerprint,baselineId:e.baselineId,fromSequence:e.fromSequence,toSequence:e.toSequence,eventCount:e.events.length,foldedCount:r.length,directRenderUrls:Te([...n]),archiveFamilyUrls:u,sitemapUrls:g,deleteUrls:Te([...s]),resourceRenderUrls:Te(c),resourceDeleteUrls:Te(i),archiveFamilies:d};return {...f,impactHash:be(f)}}function lt(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(be(r)!==t)throw new Error("Content-sync impact plan hash mismatch.");for(let n of [...e.directRenderUrls,...e.deleteUrls,...e.resourceRenderUrls,...e.resourceDeleteUrls])if(ao(n))throw new Error(`Content-sync impact contains a WordPress trash alias instead of the last public URL: ${n}`)}var go="wp-json/smartcloud-static-publisher/v1/content-sync/",mo=25*1024*1024,It=class extends Error{status;code;constructor(t,r,n){super(n),this.name="ContentSyncApiError",this.status=t,this.code=r;}},At=class{options;constructor(t){if(!t.runtimeToken.trim())throw new Error("Content-sync requires a WordPress runtime token.");this.options={...t,timeoutMs:t.timeoutMs??6e4};}endpoint(t,r="content-sync"){let n=this.options.sourceOrigin.replace(/\/+$/,"")+"/",s=r==="content-sync"?go:`wp-json/smartcloud-static-publisher/v1/${r}/`;return new URL(`${s}${t}`,n)}async post(t,r,n="content-sync"){let s=this.endpoint(t,n),o=Buffer.from(JSON.stringify(r),"utf8"),a=s.protocol==="https:"?gn:po,c=s.protocol==="https:"?new gn.Agent({rejectUnauthorized:!this.options.ignoreHttpsErrors}):void 0;return new Promise((i,l)=>{let d=a.request(s,{method:"POST",agent:c,headers:{"content-type":"application/json","content-length":String(o.byteLength),"x-static-publisher-token":this.options.runtimeToken},timeout:this.options.timeoutMs},u=>{let g=[],f=0;u.on("data",p=>{if(f+=p.byteLength,f>mo){u.destroy(new Error("Content-sync API response exceeded the size limit."));return}g.push(p);}),u.on("error",l),u.on("end",()=>{let p=Buffer.concat(g).toString("utf8"),y;try{y=p?JSON.parse(p):{};}catch{l(new It(u.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let m=u.statusCode??500;if(m<200||m>=300){l(new It(m,String(y.code??"request-failed"),String(y.message??`Content-sync API request failed (${m}).`)));return}i(y);});});d.on("timeout",()=>d.destroy(new Error(`Content-sync API request timed out: ${t}`))),d.on("error",l),d.end(o);})}async head(t){return this.post("head",t)}async unboundHead(t,r){return this.post("head",{postTypes:t,includeSubsites:r})}async events(t){let r=[],n=t.afterSequence,s=new Set(t.postTypes);for(;n<t.throughSequence;){let o=await this.post("events",{...t,afterSequence:n,limit:250});if(o.fromSequence!==n||o.throughSequence!==t.throughSequence||o.nextSequence<n||o.nextSequence>t.throughSequence)throw new Error("Content-sync API returned an inconsistent event page.");if(!Array.isArray(o.items))throw new Error("Content-sync API returned a malformed event page.");let a=n;for(let c of o.items){if(!Number.isSafeInteger(c.sequence)||c.sequence<=a||c.sequence>t.throughSequence||!Number.isSafeInteger(c.postId)||c.postId<=0||!Number.isSafeInteger(c.blogId)||c.blogId<=0||!s.has(c.postType)||typeof c.operation!="string"||!c.operation)throw new Error("Content-sync API returned an invalid or out-of-scope journal event.");a=c.sequence;}if(o.items.length>0&&o.nextSequence!==a)throw new Error("Content-sync API event cursor does not match the final returned event.");if(r.push(...o.items),!o.hasMore)break;if(o.nextSequence===n)throw new Error("Content-sync API event pagination did not advance.");n=o.nextSequence;}if(t.throughSequence>t.afterSequence&&r.at(-1)?.sequence!==t.throughSequence)throw new Error("Content-sync API omitted the claimed journal high-water event.");return r}async resolveImpactFamilies(t,r){let n=await this.post("impact",{families:t,includeSubsites:r});return Array.isArray(n.families)?n.families:[]}async releaseFingerprint(t=false){let r=await this.post("fingerprint",{includeSubsites:t}),n=String(r.fingerprint||"").trim();if(!/^[a-f0-9]{64}$/.test(n))throw new Error("WordPress returned an invalid release fingerprint.");return n}async establishBaseline(t){return this.post("baseline",t)}async acknowledge(t){return this.post("ack",t)}async importCookieObservations(t){return this.post("cookie-observations",t,"privacy")}};function Tt(e){let t=v.resolve(e);return {state:v.join(t,"content-sync-state.json"),current:v.join(t,"content-sync-current.json"),impact:v.join(t,"content-sync-impact-plan.json"),checkpoint:v.join(t,"content-sync-checkpoint.json"),baseline:v.join(t,"content-sync-baseline.json"),activeRules:v.join(t,"content-sync-active-rules.json"),releaseCutoff:v.join(t,"content-sync-release-cutoff.json"),candidateManifest:v.join(t,"content-sync-candidate-manifest.json"),trustedManifest:v.join(t,"crawl-manifest.json"),invalidation:v.join(t,"content-sync-invalidation.json"),deployPlan:v.join(t,"deploy-plan.json")}}async function fr(e){let t=await ut(e.releaseCutoff);if(t===null)return {schemaVersion:1,updatedAt:"",entries:{}};let r=t;if(r.schemaVersion!==1||typeof r.updatedAt!="string"||!r.entries||typeof r.entries!="object"||Array.isArray(r.entries))throw new Error("Invalid content-sync release-cutoff store.");return r}async function mn(e,t){await He(e.releaseCutoff,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function He(e,t){await D.mkdir(v.dirname(e),{recursive:true});let r=`${e}.${process.pid}.${Date.now()}.tmp`;await D.writeFile(r,JSON.stringify(t,null,2),"utf8"),await D.rename(r,e);}async function ut(e){try{return JSON.parse(await D.readFile(e,"utf8"))}catch(t){if(t.code==="ENOENT")return null;throw new Error(`Invalid or unreadable content-sync state file ${e}: ${t instanceof Error?t.message:String(t)}`,{cause:t})}}async function hr(e){let t=await ut(e.baseline);if(t===null)return {schemaVersion:1,updatedAt:"",entries:{}};let r=t;if(r.schemaVersion!==1||typeof r.updatedAt!="string"||!r.entries||typeof r.entries!="object"||Array.isArray(r.entries))throw new Error("Invalid content-sync baseline store.");return r}async function fn(e,t){await He(e.baseline,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function wr(e){let t=await ut(e.current);if(t===null)return null;let r=t;if(r.schemaVersion!==1||typeof r.jobId!="string"||typeof r.phase!="string"||!Number.isSafeInteger(r.fromSequence)||!Number.isSafeInteger(r.toSequence))throw new Error("Invalid content-sync current-range state.");return r}async function hn(e,t){await He(e.current,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function wn(e){let t=await ut(e.impact);if(t===null)return null;let r=t;return lt(r),r}async function yn(e,t){lt(t),await He(e.impact,t);}async function Sn(e,t){await He(e.checkpoint,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Et(e){let t=await ut(e.state);if(t===null)return {schemaVersion:1,updatedAt:"",rules:{}};let r=t;if(r.schemaVersion!==1||typeof r.updatedAt!="string"||!r.rules||typeof r.rules!="object"||Array.isArray(r.rules))throw new Error("Invalid content-sync state store.");return r}async function $t(e,t){await He(e.state,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function yr(e){await Promise.all([e.current,e.checkpoint].map(async t=>{try{await D.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}));}async function bn(e,t){let r=await wr(e);return !r||r.coalesceKey!==t?false:(await Promise.all([e.current,e.checkpoint,e.impact,e.candidateManifest,e.invalidation,e.deployPlan].map(async n=>{try{await D.unlink(n);}catch(s){if(s.code!=="ENOENT")throw s}})),true)}var Sr=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function dt(e){let t=new Set;for(let r of [...e,...Sr]){let n=String(r||"").trim();n&&t.add(n);}return [...t]}function br(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function Pn(e){if(!e||!/^https?:\/\//i.test(e))return false;try{return br(new URL(e))}catch{return false}}function vn(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function yo(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(a=>a.replace(/[^A-Za-z0-9._-]/g,"")).filter(a=>a.length>0&&a!=="."&&a!=="..");if(s.length===0)return "";let o=`/${s.join("/")}`;return n&&v.extname(o)===""&&(o+="/"),o==="/"?"":o}function Pr(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function So(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,a={};if(typeof o.targetOrigin=="string"){let i=vn(o.targetOrigin);i&&(a.targetOrigin=i);}let c=Pr(o.extraReplacements);if(Object.keys(c).length>0&&(a.extraReplacements=c),o.s3&&typeof o.s3=="object"){let i={},l=o.s3;typeof l.bucket=="string"&&(i.bucket=l.bucket.trim()),typeof l.prefix=="string"&&(i.prefix=l.prefix.trim()),typeof l.region=="string"&&(i.region=l.region.trim()),typeof l.htmlCacheControl=="string"&&(i.htmlCacheControl=l.htmlCacheControl.trim()),typeof l.assetCacheControl=="string"&&(i.assetCacheControl=l.assetCacheControl.trim()),Object.keys(i).length>0&&(a.s3=i);}if(o.cloudFront&&typeof o.cloudFront=="object"){let i={},l=o.cloudFront;typeof l.distributionId=="string"&&(i.distributionId=l.distributionId.trim()),Array.isArray(l.invalidationPaths)&&(i.invalidationPaths=l.invalidationPaths.map(d=>String(d??"").trim()).filter(d=>d.length>0)),Object.keys(i).length>0&&(a.cloudFront=i);}t[s]=a;}return t}function vr(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function bo(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 a=String(r.deploymentProfile??"").trim(),c=String(r.url??"").trim(),i=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"&&i.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")&&a?{deploymentProfile:a}:{},...c?{url:c}:{},...i.length>0?{postTypes:i}:{},...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 Cn(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((n,s)=>bo(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 Po(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:{},a=t.deploy&&typeof t.deploy=="object"?t.deploy:{},c=(i,l)=>({enabled:typeof i.enabled=="boolean"?i.enabled:r.enabled===true,concurrency:Math.min(100,Math.max(1,Number(i.concurrency||l.concurrency))),batchSize:Math.min(500,Math.max(1,Number(i.batchSize||l.batchSize))),maxAttempts:Math.min(5,Math.max(1,Number(i.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(a,{concurrency:8,batchSize:50})}}function Ro(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 Cr(e){let t=e&&typeof e=="object"?e:{},r=String(t.accountId??"").trim(),n=String(t.siteId??"").trim(),s=t.subscriber===true,o=Ro(t.siteSettings),a={...o??{},...r?{accountId:o?.accountId??r}:{},...n?{siteId:o?.siteId??n}:{},...o?.subscriber===true||s?{subscriber:true}:{}},c={},i=String(t.apiBase??"").trim();i&&(c.apiBase=i);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(a).length>0&&(c.siteSettings=a);let u=vr(t.subscriptionType);return u&&(c.subscriptionType=u),c}function vo(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function kn(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function Co(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 xn(e,t,r=5){let n=new URL(kn(e)),s=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),o=n.protocol==="http:"?po:gn,a=Co(e,t);return await new Promise((c,i)=>{let l=o.request(n,{method:s,headers:Object.fromEntries(a.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",i),d.on("end",()=>{let g=d.statusCode??0,f=d.headers.location;if(r>0&&f&&[301,302,303,307,308].includes(g)){c(xn(new URL(f,n),{method:g===303?"GET":s},r-1));return}let p=new Headers;for(let[y,m]of Object.entries(d.headers))Array.isArray(m)?p.set(y,m.join(", ")):typeof m=="string"&&p.set(y,m);c(new Response(Buffer.concat(u),{status:g,statusText:d.statusMessage??"",headers:p}));});});l.on("error",i),l.end();})}function ko(e){let t=Cr(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;vo(e.sourceOrigin);let a=globalThis,i={...a.WpSuite??{},siteSettings:r,uploadUrl:o};return t.apiBase&&(i.apiBase=t.apiBase),a.WpSuite=i,true}async function xo(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!ko(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(i,l)=>{let d=kn(i);if(d.startsWith(t)){let u=(()=>{try{return new URL(d).pathname}catch{return d}})();try{let g=e.ignoreHttpsErrors&&d.startsWith("https://")?await xn(i,l):await r(i,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(i,l)}));let{getConfig:s}=await import('@smart-cloud/wpsuite-core'),o=await s("publisher"),a=o&&typeof o=="object"?o:null,c=vr(a?.subscriptionType);return {remote:a,diagnostic:{status:a?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:c??null,error:a?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 Io(e,t){let r=So(t?.deploymentProfiles),n=String(t?.defaultDeploymentProfile??"").trim(),s=r[n]?n:"",o=vr(t?.subscriptionType),a=Cr(e.wpsuite);return {...e,scheduler:Cn(t?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:s,...o?{subscriptionType:o}:{},wpsuite:{...a,...a.siteSettings||o?{siteSettings:{...a.siteSettings??{},...a.siteSettings?.subscriber===true||o==="PROFESSIONAL"||o==="AGENCY"?{subscriber:true}:{}}}:{},...o?{subscriptionType:o}:{}}}}function Rr(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 Ao(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?v.resolve(e):""}function Rn(e,t,r){let n=String(t||"").trim();return n&&v.isAbsolute(n)?v.resolve(n):v.resolve(e,Rr(n,r))}async function ue(e,t={}){let r=String(e??"").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",n=await D.readFile(r,"utf8"),s=JSON.parse(n);s.sourceOrigin=s.sourceOrigin.replace(/\/$/,""),s.targetOrigin=vn(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=yo(s.generated404RequestPath),s.sitemapPaths||=[...Sr],s.allowedAssetHosts||=[],s.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],s.blockedPathPrefixes||=[],s.blockedSearchFragments||=[],s.concurrency||=1,s.maxPages||=0,s.extraReplacements=Pr(s.extraReplacements),s.postCrawlCopyMap=Pr(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=Number(s.assetDownloadConcurrency)>0?Number(s.assetDownloadConcurrency):s.concurrency,s.rewriteConcurrency=Number(s.rewriteConcurrency)>0?Number(s.rewriteConcurrency):s.assetDownloadConcurrency,s.wpsuite=Cr(s.wpsuite),s.scheduler=Cn(void 0),s.remoteWorkers=Po(s.remoteWorkers),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let o=await xo(s);t.onRemotePublisherConfigDiagnostic?.(o.diagnostic);let a=Io(s,o.remote),c=Ao(),i=c?v.resolve(c,".."):"";return i?(a.outputDir=Rn(i,a.outputDir,"export"),a.logDir=Rn(i,a.logDir,"logs")):(v.isAbsolute(a.outputDir)||(a.outputDir=Rr(a.outputDir,"export")),v.isAbsolute(a.logDir)||(a.logDir=Rr(a.logDir,"logs"))),a}var To=".deploy-plan.json",Eo="deploy-plan.json",$o=".crawl-incomplete.json",Oo="crawl-incomplete.json";function In(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?v.resolve(e):""}function An(e){let t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),r=v.posix.normalize(t);return !t||!r||r==="."||/^[a-zA-Z]:/.test(r)||r.startsWith("../")||r===".."?null:r}function Mo(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:`${v.posix.normalize(r.pathname)}${r.search}`}catch{return null}}function de(e){return [...new Set(e.map(An).filter(t=>t!==null))]}function Tn(e,t){let r={generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:v.resolve(e.outputDir),runMode:t.runMode,crawlMode:t.crawlMode,fullSyncRequired:!!t.fullSyncRequired,changedFiles:de(t.changedFiles||[]),deletedFiles:de(t.deletedFiles||[]),rewriteTargets:de(t.rewriteTargets||[]),revalidateFiles:de(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:de(t.uploadGroups?.assets||[]),content:de(t.uploadGroups?.content||[]),listings:de(t.uploadGroups?.listings||[]),resources:de(t.uploadGroups?.resources||[]),sitemapLeaves:de(t.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:de(t.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((t.invalidationPaths||[]).map(Mo).filter(n=>n!==null))].sort()}:{schemaVersion:1,...r,runMode:t.runMode}}function Do(e){if(!e||typeof e!="object")return false;let t=e;if(t.schemaVersion===2){let r=t;return r.runMode==="content-sync"&&r.crawlMode==="incremental"&&r.fullSyncRequired===false&&typeof r.generatedAt=="string"&&typeof r.outputDir=="string"&&typeof r.consumerId=="string"&&r.consumerId.trim()!==""&&Number.isSafeInteger(r.fromSequence)&&Number.isSafeInteger(r.toSequence)&&Number(r.toSequence)>=Number(r.fromSequence)&&typeof r.impactHash=="string"&&/^[a-f0-9]{64}$/.test(r.impactHash)&&Array.isArray(r.resolvedSitemapUrls)&&Array.isArray(r.changedFiles)&&Array.isArray(r.deletedFiles)&&Array.isArray(r.rewriteTargets)&&(r.revalidateFiles===void 0||Array.isArray(r.revalidateFiles))&&!!r.uploadGroups&&Array.isArray(r.uploadGroups.assets)&&Array.isArray(r.uploadGroups.content)&&Array.isArray(r.uploadGroups.listings)&&Array.isArray(r.uploadGroups.resources)&&Array.isArray(r.uploadGroups.sitemapLeaves)&&Array.isArray(r.uploadGroups.sitemapIndexes)&&Array.isArray(r.invalidationPaths)}return t.schemaVersion===1&&typeof t.generatedAt=="string"&&typeof t.outputDir=="string"&&(t.runMode==="full"||t.runMode==="retry-timeouts"||t.runMode==="single-url")&&(t.crawlMode==="full"||t.crawlMode==="incremental")&&typeof t.fullSyncRequired=="boolean"&&Array.isArray(t.changedFiles)&&Array.isArray(t.deletedFiles)&&Array.isArray(t.rewriteTargets)&&(t.revalidateFiles===void 0||Array.isArray(t.revalidateFiles))}function kr(e){let t=v.join(v.resolve(e.outputDir),To),r=In();return r?[v.join(r,Eo),t]:[t]}function xr(e){let t=v.join(v.resolve(e.outputDir),$o),r=In();return r?[v.join(r,Oo),t]:[t]}function ge(e,t){let r=v.resolve(e),n=v.resolve(t),s=v.relative(r,n).replace(/\\/g,"/");return An(s)}async function ze(e){let t=v.resolve(e.outputDir);for(let r of kr(e))try{let n=await D.readFile(r,"utf8"),s=JSON.parse(n);if(!Do(s)||v.resolve(s.outputDir)!==t)continue;return Tn(e,s)}catch{}return null}async function Ir(e,t){let r=Tn(e,t);for(let n of kr(e)){await D.mkdir(v.dirname(n),{recursive:true});let s=`${n}.${process.pid}.${Date.now()}.tmp`;await D.writeFile(s,JSON.stringify(r,null,2),"utf8"),await D.rename(s,n);}}async function Me(e){for(let t of kr(e))try{await D.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}async function En(e,t){let r={schemaVersion:1,startedAt:String(t.startedAt||new Date().toISOString()),outputDir:v.resolve(e.outputDir)};for(let n of xr(e)){await D.mkdir(v.dirname(n),{recursive:true});let s=`${n}.${process.pid}.tmp`;await D.writeFile(s,JSON.stringify(r,null,2),"utf8"),await D.rename(s,n);}}async function $n(e){let t=v.resolve(e.outputDir);for(let r of xr(e)){let n;try{n=await D.readFile(r,"utf8");}catch(o){if(o.code==="ENOENT")continue;throw o}let s;try{s=JSON.parse(n);}catch{throw new Error(`Invalid incomplete crawl marker: ${r}`)}if(s.schemaVersion!==1||typeof s.startedAt!="string"||typeof s.outputDir!="string"||v.resolve(s.outputDir)!==t)throw new Error(`Invalid incomplete crawl marker: ${r}`);return {schemaVersion:1,startedAt:s.startedAt,outputDir:t}}return null}async function On(e){for(let t of xr(e))try{await D.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}function De(e,t=10){return Fn.createHash("sha1").update(e).digest("hex").slice(0,t)}async function Fo(e){await D.mkdir(v.dirname(e),{recursive:true});}async function Fe(e,t,r){await Fo(e);let n=v.join(v.dirname(e),`.${v.basename(e)}.${process.pid}.${Date.now()}.${Fn.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await D.writeFile(n,t,r??"utf8"):await D.writeFile(n,t),await D.rename(n,e);}catch(s){throw await D.unlink(n).catch(()=>{}),s}}function $e(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(v.extname(e).toLowerCase())}function Re(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function Qe(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function Ot(e){return e.replace(/\//g,"\\/")}function Mn(e){return e.replace(/\//g,"\\\\/")}function jo(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 Dn(e,t,r){if(!t)return;e[t]=r;let n=Ot(t),s=Ot(r);e[n]=s;let o=Mn(t),a=Mn(r);e[o]=a;let c=Qe(t),i=Qe(r);e[c]=i;let l=Qe(n),d=Qe(s);e[l]=d;let u=Qe(o),g=Qe(a);e[u]=g;}function Mt(e,t,r){Dn(e,t,r);let n=jo(t);n&&n!==t&&Dn(e,n,r);}function Ar(e,t){let r=t.startsWith("/")?t:`/${t}`,n=(e||"").replace(/\/$/,"");return !n||n==="."||n==="/"?r:`${n}${r}`}function jn(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function Un(e,t,r){if(!t)return r;let n=v.dirname(v.resolve(t)),s=v.resolve(e,r.replace(/^\/+/,"")),o=v.relative(n,s).replace(/\\/g,"/");return o?(o.startsWith(".")||(o=`./${o}`),o):"."}async function $r(e,t){return (t?[...new Set(t)].map(n=>v.resolve(n)).filter(n=>n.startsWith(v.resolve(e.outputDir))).map(n=>v.relative(e.outputDir,n).replace(/\\/g,"/")).filter(n=>n.length>0):await Uo(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(n=>n!=="asset-map.json"&&$e(n))}var No=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],_o=new Set([".html",".htm"]),Ln="WPSuite.io Static Publisher",Bo=Ln.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Vo(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ko(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function Ho(e,t,r){return Ko(t)?e.replace(new RegExp(`(?<!:)${Vo(t)}`,"g"),r):e.split(t).join(r)}function zo(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let s=v.extname(r).toLowerCase();return _o.has(s)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Qo(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Bo}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${Ln}" />`;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 D,{readFile}from'fs/promises';import po from'http';import gn from'https';import v from'path';import Fn,{createHash}from'crypto';import {request,chromium}from'playwright';import {gunzipSync}from'zlib';import Uo from'fast-glob';import {availableParallelism}from'os';import {Worker}from'worker_threads';import {LambdaClient,InvokeCommand}from'@aws-sdk/client-lambda';import {S3Client,GetObjectCommand,PutObjectCommand,ListObjectsV2Command,HeadObjectCommand,DeleteObjectsCommand}from'@aws-sdk/client-s3';import {fromTemporaryCredentials}from'@aws-sdk/credential-providers';import {Upload}from'@aws-sdk/lib-storage';import Vs from'mime-types';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';var oo=new Set(["post-type","taxonomy","author","date","posts-page","listing"]);function Ae(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))].sort()}function io(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))]}function ao(e){return new URL(e).pathname.split("/").filter(Boolean).some(r=>{try{return decodeURIComponent(r).endsWith("__trashed")}catch{return r.endsWith("__trashed")}})}function pr(e){return Array.isArray(e)?e.map(pr):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>[t,pr(r)])):e}function co(e){return JSON.stringify(pr(e))}function be(e){return createHash("sha256").update(co(e)).digest("hex")}function an(e){return be({schemaVersion:1,wordpressFingerprint:e.wordpressFingerprint,targetFingerprint:e.targetFingerprint,sourceOrigin:e.sourceOrigin,sitemapPaths:[...e.sitemapPaths].sort(),blockedPathPrefixes:[...e.blockedPathPrefixes].sort(),assetPathPrefixes:[...e.assetPathPrefixes].sort(),noJavaScriptRenderPathPrefixes:[...e.noJavaScriptRenderPathPrefixes].sort(),urlRewriteMode:e.urlRewriteMode})}function gr(e){let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error(`Unsupported source origin protocol: ${t.protocol}`);return t.hash="",t.search="",t.pathname=t.pathname.replace(/\/+$/,""),t.toString().replace(/\/$/,"")}function le(e,t){lo(t);let r=new URL(gr(e)),n=new URL(t,`${r.toString().replace(/\/$/,"")}/`);if(n.origin!==r.origin)throw new Error(`Content-sync URL is outside the source origin: ${t}`);let s=r.pathname.replace(/\/+$/,"");if(s&&n.pathname!==s&&!n.pathname.startsWith(`${s}/`))throw new Error(`Content-sync URL is outside the source site path: ${t}`);return n.hash="",n.toString()}function lo(e){let r=String(e).split(/[?#]/,1)[0];for(let s=0;s<3;s+=1)try{let o=decodeURIComponent(r);if(o===r)break;r=o;}catch{throw new Error(`Content-sync URL has malformed encoding: ${e}`)}if(r.includes("\0")||r.includes("\\"))throw new Error(`Content-sync URL has an unsafe path: ${e}`);if(r.replace(/^[a-z][a-z0-9+.-]*:\/\/[^/]*/i,"").split("/").some(s=>s==="."||s===".."))throw new Error(`Content-sync URL has an unsafe path: ${e}`)}function ct(e){let t=Ae((e.postTypes??[]).map(n=>String(n).toLowerCase().replace(/[^a-z0-9_-]/g,"")));if(t.length===0)throw new Error("Content-sync requires at least one public post type.");let r=Ae((e.listingPaths??[]).map(n=>{let s=String(n).trim();if(!s)return "";let o=new URL(s,"https://content-sync.invalid/");if(o.origin!=="https://content-sync.invalid"&&/^https?:\/\//i.test(s))throw new Error("Content-sync listing routes must be same-site paths.");let a=`/${o.pathname.replace(/^\/+|\/+$/g,"")}`;return a==="/"?"/":`${a}/`}));return {postTypes:t,listingPaths:r,includeSubsites:e.includeSubsites===true,includePostTypeArchives:e.includePostTypeArchives!==false,includeTaxonomyArchives:e.includeTaxonomyArchives!==false,includeAuthorArchives:e.includeAuthorArchives===true,includeDateArchives:e.includeDateArchives===true,includePostsPage:e.includePostsPage!==false,includeSitemapChain:e.includeSitemapChain!==false}}function cn(e,t,r){return be({schemaVersion:1,sourceOrigin:gr(e),ruleId:t.trim(),scope:ct(r)})}function ln(e){return be({schemaVersion:1,...e})}function un(e){let t=String(e.siteId??"").trim()||String(e.accountId??"").trim()||gr(e.sourceOrigin);return `content-sync:${be({siteIdentity:t,ruleId:e.ruleId.trim(),targetFingerprint:e.targetFingerprint}).slice(0,48)}`}function dn(e){let t=[...e].sort((s,o)=>s.sequence-o.sequence),r=new Map,n=-1;for(let s of t){if(!Number.isSafeInteger(s.sequence)||s.sequence<=n)throw new Error("Content-sync journal events are not strictly ordered.");if(n=s.sequence,!Number.isSafeInteger(s.blogId)||s.blogId<1)throw new Error("Content-sync journal event has an invalid multisite identity.");let o=`${s.blogId}:${s.postType}:${s.postId}`,a=r.get(o);if(!a){r.set(o,{postId:s.postId,blogId:s.blogId,postType:s.postType,fromSequence:s.sequence,toSequence:s.sequence,before:s.before,after:s.after,operations:[s.operation],correlationIds:s.correlationId?[s.correlationId]:[]});continue}a.toSequence=s.sequence,a.after=s.after,a.operations.push(s.operation),s.correlationId&&!a.correlationIds.includes(s.correlationId)&&a.correlationIds.push(s.correlationId);}return [...r.values()].sort((s,o)=>s.fromSequence-o.fromSequence)}function on(e){return e?.status==="publish"&&!!e.url}function uo(e,t){return e==="post-type"?t.includePostTypeArchives:e==="taxonomy"?t.includeTaxonomyArchives:e==="author"?t.includeAuthorArchives:e==="date"?t.includeDateArchives:e==="posts-page"?t.includePostsPage:e==="listing"}function mr(e){let t=ct(e.scope),r=new Map;dn(e.events);for(let n of e.events)for(let s of [n.before,n.after])for(let o of s?.archiveFamilies??[]){if(!oo.has(o.kind)||!uo(o.kind,t))continue;let a={...o,url:le(e.sourceOrigin,o.url)};r.set(`${a.kind}|${a.url}`,a);}for(let n of t.listingPaths){let s=le(e.sourceOrigin,n);r.set(`listing|${s}`,{kind:"listing",url:s});}return [...r.values()].sort((n,s)=>n.url.localeCompare(s.url))}function pn(e){let t=ct(e.scope),r=dn(e.events),n=new Set,s=new Set,o=new Map,a=new Map(mr({events:e.events,scope:t,sourceOrigin:e.sourceOrigin}).map(p=>[`${p.kind}|${p.url}`,p]));for(let p of r){let y=p.before,m=p.after,h=on(y),w=on(m);w&&m.url&&n.add(le(e.sourceOrigin,m.url)),h&&y.url&&(!w||y.url!==m.url)&&s.add(le(e.sourceOrigin,y.url));}for(let p of [...e.events].sort((y,m)=>y.sequence-m.sequence)){for(let y of [p.before,p.after])for(let m of y?.resourceDeleteUrls??[])o.set(le(e.sourceOrigin,m),"delete");for(let y of p.after?.resourceRenderUrls??[])o.set(le(e.sourceOrigin,y),"render");}let c=[...o].filter(([,p])=>p==="render").map(([p])=>p),i=[...o].filter(([,p])=>p==="delete").map(([p])=>p),l=new Map(e.resolvedArchiveFamilies.map(p=>[`${p.kind}|${le(e.sourceOrigin,p.url)}`,{...p,url:le(e.sourceOrigin,p.url),pageUrls:Ae(p.pageUrls.map(y=>le(e.sourceOrigin,y)))}])),d=[...a.entries()].map(([p,y])=>{let m=l.get(p);if(!m)throw new Error(`WordPress did not resolve archive family ${p}.`);return {...y,...m}}).sort((p,y)=>p.url.localeCompare(y.url)),u=Ae(d.flatMap(p=>p.pageUrls)),g=t.includeSitemapChain?io(e.sitemapUrls.map(p=>le(e.sourceOrigin,p))):[],f={schemaVersion:1,generatedAt:new Date().toISOString(),jobId:e.jobId,ruleId:e.ruleId,consumerId:e.consumerId,coalesceKey:e.coalesceKey,scopeFingerprint:e.scopeFingerprint,targetFingerprint:e.targetFingerprint,baselineId:e.baselineId,fromSequence:e.fromSequence,toSequence:e.toSequence,eventCount:e.events.length,foldedCount:r.length,directRenderUrls:Ae([...n]),archiveFamilyUrls:u,sitemapUrls:g,deleteUrls:Ae([...s]),resourceRenderUrls:Ae(c),resourceDeleteUrls:Ae(i),archiveFamilies:d};return {...f,impactHash:be(f)}}function lt(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(be(r)!==t)throw new Error("Content-sync impact plan hash mismatch.");for(let n of [...e.directRenderUrls,...e.deleteUrls,...e.resourceRenderUrls,...e.resourceDeleteUrls])if(ao(n))throw new Error(`Content-sync impact contains a WordPress trash alias instead of the last public URL: ${n}`)}var go="wp-json/smartcloud-static-publisher/v1/content-sync/",mo=25*1024*1024,It=class extends Error{status;code;constructor(t,r,n){super(n),this.name="ContentSyncApiError",this.status=t,this.code=r;}},Tt=class{options;constructor(t){if(!t.runtimeToken.trim())throw new Error("Content-sync requires a WordPress runtime token.");this.options={...t,timeoutMs:t.timeoutMs??6e4};}endpoint(t,r="content-sync"){let n=this.options.sourceOrigin.replace(/\/+$/,"")+"/",s=r==="content-sync"?go:`wp-json/smartcloud-static-publisher/v1/${r}/`;return new URL(`${s}${t}`,n)}async post(t,r,n="content-sync"){let s=this.endpoint(t,n),o=Buffer.from(JSON.stringify(r),"utf8"),a=s.protocol==="https:"?gn:po,c=s.protocol==="https:"?new gn.Agent({rejectUnauthorized:!this.options.ignoreHttpsErrors}):void 0;return new Promise((i,l)=>{let d=a.request(s,{method:"POST",agent:c,headers:{"content-type":"application/json","content-length":String(o.byteLength),"x-static-publisher-token":this.options.runtimeToken},timeout:this.options.timeoutMs},u=>{let g=[],f=0;u.on("data",p=>{if(f+=p.byteLength,f>mo){u.destroy(new Error("Content-sync API response exceeded the size limit."));return}g.push(p);}),u.on("error",l),u.on("end",()=>{let p=Buffer.concat(g).toString("utf8"),y;try{y=p?JSON.parse(p):{};}catch{l(new It(u.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let m=u.statusCode??500;if(m<200||m>=300){l(new It(m,String(y.code??"request-failed"),String(y.message??`Content-sync API request failed (${m}).`)));return}i(y);});});d.on("timeout",()=>d.destroy(new Error(`Content-sync API request timed out: ${t}`))),d.on("error",l),d.end(o);})}async head(t){return this.post("head",t)}async unboundHead(t,r){return this.post("head",{postTypes:t,includeSubsites:r})}async events(t){let r=[],n=t.afterSequence,s=new Set(t.postTypes);for(;n<t.throughSequence;){let o=await this.post("events",{...t,afterSequence:n,limit:250});if(o.fromSequence!==n||o.throughSequence!==t.throughSequence||o.nextSequence<n||o.nextSequence>t.throughSequence)throw new Error("Content-sync API returned an inconsistent event page.");if(!Array.isArray(o.items))throw new Error("Content-sync API returned a malformed event page.");let a=n;for(let c of o.items){if(!Number.isSafeInteger(c.sequence)||c.sequence<=a||c.sequence>t.throughSequence||!Number.isSafeInteger(c.postId)||c.postId<=0||!Number.isSafeInteger(c.blogId)||c.blogId<=0||!s.has(c.postType)||typeof c.operation!="string"||!c.operation)throw new Error("Content-sync API returned an invalid or out-of-scope journal event.");a=c.sequence;}if(o.items.length>0&&o.nextSequence!==a)throw new Error("Content-sync API event cursor does not match the final returned event.");if(r.push(...o.items),!o.hasMore)break;if(o.nextSequence===n)throw new Error("Content-sync API event pagination did not advance.");n=o.nextSequence;}if(t.throughSequence>t.afterSequence&&r.at(-1)?.sequence!==t.throughSequence)throw new Error("Content-sync API omitted the claimed journal high-water event.");return r}async resolveImpactFamilies(t,r){let n=await this.post("impact",{families:t,includeSubsites:r});return Array.isArray(n.families)?n.families:[]}async releaseFingerprint(t=false){let r=await this.post("fingerprint",{includeSubsites:t}),n=String(r.fingerprint||"").trim();if(!/^[a-f0-9]{64}$/.test(n))throw new Error("WordPress returned an invalid release fingerprint.");return n}async establishBaseline(t){return this.post("baseline",t)}async acknowledge(t){return this.post("ack",t)}async importCookieObservations(t){return this.post("cookie-observations",t,"privacy")}};function At(e){let t=v.resolve(e);return {state:v.join(t,"content-sync-state.json"),current:v.join(t,"content-sync-current.json"),impact:v.join(t,"content-sync-impact-plan.json"),checkpoint:v.join(t,"content-sync-checkpoint.json"),baseline:v.join(t,"content-sync-baseline.json"),activeRules:v.join(t,"content-sync-active-rules.json"),releaseCutoff:v.join(t,"content-sync-release-cutoff.json"),candidateManifest:v.join(t,"content-sync-candidate-manifest.json"),trustedManifest:v.join(t,"crawl-manifest.json"),invalidation:v.join(t,"content-sync-invalidation.json"),deployPlan:v.join(t,"deploy-plan.json")}}async function fr(e){let t=await ut(e.releaseCutoff);if(t===null)return {schemaVersion:1,updatedAt:"",entries:{}};let r=t;if(r.schemaVersion!==1||typeof r.updatedAt!="string"||!r.entries||typeof r.entries!="object"||Array.isArray(r.entries))throw new Error("Invalid content-sync release-cutoff store.");return r}async function mn(e,t){await He(e.releaseCutoff,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function He(e,t){await D.mkdir(v.dirname(e),{recursive:true});let r=`${e}.${process.pid}.${Date.now()}.tmp`;await D.writeFile(r,JSON.stringify(t,null,2),"utf8"),await D.rename(r,e);}async function ut(e){try{return JSON.parse(await D.readFile(e,"utf8"))}catch(t){if(t.code==="ENOENT")return null;throw new Error(`Invalid or unreadable content-sync state file ${e}: ${t instanceof Error?t.message:String(t)}`,{cause:t})}}async function hr(e){let t=await ut(e.baseline);if(t===null)return {schemaVersion:1,updatedAt:"",entries:{}};let r=t;if(r.schemaVersion!==1||typeof r.updatedAt!="string"||!r.entries||typeof r.entries!="object"||Array.isArray(r.entries))throw new Error("Invalid content-sync baseline store.");return r}async function fn(e,t){await He(e.baseline,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function wr(e){let t=await ut(e.current);if(t===null)return null;let r=t;if(r.schemaVersion!==1||typeof r.jobId!="string"||typeof r.phase!="string"||!Number.isSafeInteger(r.fromSequence)||!Number.isSafeInteger(r.toSequence))throw new Error("Invalid content-sync current-range state.");return r}async function hn(e,t){await He(e.current,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function wn(e){let t=await ut(e.impact);if(t===null)return null;let r=t;return lt(r),r}async function yn(e,t){lt(t),await He(e.impact,t);}async function Sn(e,t){await He(e.checkpoint,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Et(e){let t=await ut(e.state);if(t===null)return {schemaVersion:1,updatedAt:"",rules:{}};let r=t;if(r.schemaVersion!==1||typeof r.updatedAt!="string"||!r.rules||typeof r.rules!="object"||Array.isArray(r.rules))throw new Error("Invalid content-sync state store.");return r}async function $t(e,t){await He(e.state,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function yr(e){await Promise.all([e.current,e.checkpoint].map(async t=>{try{await D.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}));}async function bn(e,t){let r=await wr(e);return !r||r.coalesceKey!==t?false:(await Promise.all([e.current,e.checkpoint,e.impact,e.candidateManifest,e.invalidation,e.deployPlan].map(async n=>{try{await D.unlink(n);}catch(s){if(s.code!=="ENOENT")throw s}})),true)}var Sr=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function dt(e){let t=new Set;for(let r of [...e,...Sr]){let n=String(r||"").trim();n&&t.add(n);}return [...t]}function br(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function Pn(e){if(!e||!/^https?:\/\//i.test(e))return false;try{return br(new URL(e))}catch{return false}}function vn(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function yo(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(a=>a.replace(/[^A-Za-z0-9._-]/g,"")).filter(a=>a.length>0&&a!=="."&&a!=="..");if(s.length===0)return "";let o=`/${s.join("/")}`;return n&&v.extname(o)===""&&(o+="/"),o==="/"?"":o}function Pr(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function So(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,a={};if(typeof o.targetOrigin=="string"){let i=vn(o.targetOrigin);i&&(a.targetOrigin=i);}let c=Pr(o.extraReplacements);if(Object.keys(c).length>0&&(a.extraReplacements=c),o.s3&&typeof o.s3=="object"){let i={},l=o.s3;typeof l.bucket=="string"&&(i.bucket=l.bucket.trim()),typeof l.prefix=="string"&&(i.prefix=l.prefix.trim()),typeof l.region=="string"&&(i.region=l.region.trim()),typeof l.htmlCacheControl=="string"&&(i.htmlCacheControl=l.htmlCacheControl.trim()),typeof l.assetCacheControl=="string"&&(i.assetCacheControl=l.assetCacheControl.trim()),Object.keys(i).length>0&&(a.s3=i);}if(o.cloudFront&&typeof o.cloudFront=="object"){let i={},l=o.cloudFront;typeof l.distributionId=="string"&&(i.distributionId=l.distributionId.trim()),Array.isArray(l.invalidationPaths)&&(i.invalidationPaths=l.invalidationPaths.map(d=>String(d??"").trim()).filter(d=>d.length>0)),Object.keys(i).length>0&&(a.cloudFront=i);}t[s]=a;}return t}function vr(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function bo(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 a=String(r.deploymentProfile??"").trim(),c=String(r.url??"").trim(),i=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"&&i.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")&&a?{deploymentProfile:a}:{},...c?{url:c}:{},...i.length>0?{postTypes:i}:{},...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 Cn(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((n,s)=>bo(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 Po(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:{},a=t.deploy&&typeof t.deploy=="object"?t.deploy:{},c=(i,l)=>({enabled:typeof i.enabled=="boolean"?i.enabled:r.enabled===true,concurrency:Math.min(100,Math.max(1,Number(i.concurrency||l.concurrency))),batchSize:Math.min(500,Math.max(1,Number(i.batchSize||l.batchSize))),maxAttempts:Math.min(5,Math.max(1,Number(i.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(a,{concurrency:8,batchSize:50})}}function Ro(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 Cr(e){let t=e&&typeof e=="object"?e:{},r=String(t.accountId??"").trim(),n=String(t.siteId??"").trim(),s=t.subscriber===true,o=Ro(t.siteSettings),a={...o??{},...r?{accountId:o?.accountId??r}:{},...n?{siteId:o?.siteId??n}:{},...o?.subscriber===true||s?{subscriber:true}:{}},c={},i=String(t.apiBase??"").trim();i&&(c.apiBase=i);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(a).length>0&&(c.siteSettings=a);let u=vr(t.subscriptionType);return u&&(c.subscriptionType=u),c}function vo(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function kn(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function Co(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 xn(e,t,r=5){let n=new URL(kn(e)),s=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),o=n.protocol==="http:"?po:gn,a=Co(e,t);return await new Promise((c,i)=>{let l=o.request(n,{method:s,headers:Object.fromEntries(a.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",i),d.on("end",()=>{let g=d.statusCode??0,f=d.headers.location;if(r>0&&f&&[301,302,303,307,308].includes(g)){c(xn(new URL(f,n),{method:g===303?"GET":s},r-1));return}let p=new Headers;for(let[y,m]of Object.entries(d.headers))Array.isArray(m)?p.set(y,m.join(", ")):typeof m=="string"&&p.set(y,m);c(new Response(Buffer.concat(u),{status:g,statusText:d.statusMessage??"",headers:p}));});});l.on("error",i),l.end();})}function ko(e){let t=Cr(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;vo(e.sourceOrigin);let a=globalThis,i={...a.WpSuite??{},siteSettings:r,uploadUrl:o};return t.apiBase&&(i.apiBase=t.apiBase),a.WpSuite=i,true}async function xo(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!ko(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(i,l)=>{let d=kn(i);if(d.startsWith(t)){let u=(()=>{try{return new URL(d).pathname}catch{return d}})();try{let g=e.ignoreHttpsErrors&&d.startsWith("https://")?await xn(i,l):await r(i,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(i,l)}));let{getConfig:s}=await import('@smart-cloud/wpsuite-core'),o=await s("publisher"),a=o&&typeof o=="object"?o:null,c=vr(a?.subscriptionType);return {remote:a,diagnostic:{status:a?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:c??null,error:a?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 Io(e,t){let r=So(t?.deploymentProfiles),n=String(t?.defaultDeploymentProfile??"").trim(),s=r[n]?n:"",o=vr(t?.subscriptionType),a=Cr(e.wpsuite);return {...e,scheduler:Cn(t?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:s,...o?{subscriptionType:o}:{},wpsuite:{...a,...a.siteSettings||o?{siteSettings:{...a.siteSettings??{},...a.siteSettings?.subscriber===true||o==="PROFESSIONAL"||o==="AGENCY"?{subscriber:true}:{}}}:{},...o?{subscriptionType:o}:{}}}}function Rr(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 To(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?v.resolve(e):""}function Rn(e,t,r){let n=String(t||"").trim();return n&&v.isAbsolute(n)?v.resolve(n):v.resolve(e,Rr(n,r))}async function ue(e,t={}){let r=String(e??"").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",n=await D.readFile(r,"utf8"),s=JSON.parse(n);s.sourceOrigin=s.sourceOrigin.replace(/\/$/,""),s.targetOrigin=vn(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=yo(s.generated404RequestPath),s.sitemapPaths||=[...Sr],s.allowedAssetHosts||=[],s.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],s.blockedPathPrefixes||=[],s.blockedSearchFragments||=[],s.concurrency||=1,s.maxPages||=0,s.extraReplacements=Pr(s.extraReplacements),s.postCrawlCopyMap=Pr(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=Number(s.assetDownloadConcurrency)>0?Number(s.assetDownloadConcurrency):s.concurrency,s.rewriteConcurrency=Number(s.rewriteConcurrency)>0?Number(s.rewriteConcurrency):s.assetDownloadConcurrency,s.wpsuite=Cr(s.wpsuite),s.scheduler=Cn(void 0),s.remoteWorkers=Po(s.remoteWorkers),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let o=await xo(s);t.onRemotePublisherConfigDiagnostic?.(o.diagnostic);let a=Io(s,o.remote),c=To(),i=c?v.resolve(c,".."):"";return i?(a.outputDir=Rn(i,a.outputDir,"export"),a.logDir=Rn(i,a.logDir,"logs")):(v.isAbsolute(a.outputDir)||(a.outputDir=Rr(a.outputDir,"export")),v.isAbsolute(a.logDir)||(a.logDir=Rr(a.logDir,"logs"))),a}var Ao=".deploy-plan.json",Eo="deploy-plan.json",$o=".crawl-incomplete.json",Oo="crawl-incomplete.json";function In(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?v.resolve(e):""}function Tn(e){let t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),r=v.posix.normalize(t);return !t||!r||r==="."||/^[a-zA-Z]:/.test(r)||r.startsWith("../")||r===".."?null:r}function Mo(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:`${v.posix.normalize(r.pathname)}${r.search}`}catch{return null}}function de(e){return [...new Set(e.map(Tn).filter(t=>t!==null))]}function An(e,t){let r={generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:v.resolve(e.outputDir),runMode:t.runMode,crawlMode:t.crawlMode,fullSyncRequired:!!t.fullSyncRequired,changedFiles:de(t.changedFiles||[]),deletedFiles:de(t.deletedFiles||[]),rewriteTargets:de(t.rewriteTargets||[]),revalidateFiles:de(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:de(t.uploadGroups?.assets||[]),content:de(t.uploadGroups?.content||[]),listings:de(t.uploadGroups?.listings||[]),resources:de(t.uploadGroups?.resources||[]),sitemapLeaves:de(t.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:de(t.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((t.invalidationPaths||[]).map(Mo).filter(n=>n!==null))].sort()}:{schemaVersion:1,...r,runMode:t.runMode}}function Do(e){if(!e||typeof e!="object")return false;let t=e;if(t.schemaVersion===2){let r=t;return r.runMode==="content-sync"&&r.crawlMode==="incremental"&&r.fullSyncRequired===false&&typeof r.generatedAt=="string"&&typeof r.outputDir=="string"&&typeof r.consumerId=="string"&&r.consumerId.trim()!==""&&Number.isSafeInteger(r.fromSequence)&&Number.isSafeInteger(r.toSequence)&&Number(r.toSequence)>=Number(r.fromSequence)&&typeof r.impactHash=="string"&&/^[a-f0-9]{64}$/.test(r.impactHash)&&Array.isArray(r.resolvedSitemapUrls)&&Array.isArray(r.changedFiles)&&Array.isArray(r.deletedFiles)&&Array.isArray(r.rewriteTargets)&&(r.revalidateFiles===void 0||Array.isArray(r.revalidateFiles))&&!!r.uploadGroups&&Array.isArray(r.uploadGroups.assets)&&Array.isArray(r.uploadGroups.content)&&Array.isArray(r.uploadGroups.listings)&&Array.isArray(r.uploadGroups.resources)&&Array.isArray(r.uploadGroups.sitemapLeaves)&&Array.isArray(r.uploadGroups.sitemapIndexes)&&Array.isArray(r.invalidationPaths)}return t.schemaVersion===1&&typeof t.generatedAt=="string"&&typeof t.outputDir=="string"&&(t.runMode==="full"||t.runMode==="retry-timeouts"||t.runMode==="single-url")&&(t.crawlMode==="full"||t.crawlMode==="incremental")&&typeof t.fullSyncRequired=="boolean"&&Array.isArray(t.changedFiles)&&Array.isArray(t.deletedFiles)&&Array.isArray(t.rewriteTargets)&&(t.revalidateFiles===void 0||Array.isArray(t.revalidateFiles))}function kr(e){let t=v.join(v.resolve(e.outputDir),Ao),r=In();return r?[v.join(r,Eo),t]:[t]}function xr(e){let t=v.join(v.resolve(e.outputDir),$o),r=In();return r?[v.join(r,Oo),t]:[t]}function ge(e,t){let r=v.resolve(e),n=v.resolve(t),s=v.relative(r,n).replace(/\\/g,"/");return Tn(s)}async function ze(e){let t=v.resolve(e.outputDir);for(let r of kr(e))try{let n=await D.readFile(r,"utf8"),s=JSON.parse(n);if(!Do(s)||v.resolve(s.outputDir)!==t)continue;return An(e,s)}catch{}return null}async function Ir(e,t){let r=An(e,t);for(let n of kr(e)){await D.mkdir(v.dirname(n),{recursive:true});let s=`${n}.${process.pid}.${Date.now()}.tmp`;await D.writeFile(s,JSON.stringify(r,null,2),"utf8"),await D.rename(s,n);}}async function Me(e){for(let t of kr(e))try{await D.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}async function En(e,t){let r={schemaVersion:1,startedAt:String(t.startedAt||new Date().toISOString()),outputDir:v.resolve(e.outputDir)};for(let n of xr(e)){await D.mkdir(v.dirname(n),{recursive:true});let s=`${n}.${process.pid}.tmp`;await D.writeFile(s,JSON.stringify(r,null,2),"utf8"),await D.rename(s,n);}}async function $n(e){let t=v.resolve(e.outputDir);for(let r of xr(e)){let n;try{n=await D.readFile(r,"utf8");}catch(o){if(o.code==="ENOENT")continue;throw o}let s;try{s=JSON.parse(n);}catch{throw new Error(`Invalid incomplete crawl marker: ${r}`)}if(s.schemaVersion!==1||typeof s.startedAt!="string"||typeof s.outputDir!="string"||v.resolve(s.outputDir)!==t)throw new Error(`Invalid incomplete crawl marker: ${r}`);return {schemaVersion:1,startedAt:s.startedAt,outputDir:t}}return null}async function On(e){for(let t of xr(e))try{await D.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}function De(e,t=10){return Fn.createHash("sha1").update(e).digest("hex").slice(0,t)}async function Fo(e){await D.mkdir(v.dirname(e),{recursive:true});}async function Fe(e,t,r){await Fo(e);let n=v.join(v.dirname(e),`.${v.basename(e)}.${process.pid}.${Date.now()}.${Fn.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await D.writeFile(n,t,r??"utf8"):await D.writeFile(n,t),await D.rename(n,e);}catch(s){throw await D.unlink(n).catch(()=>{}),s}}function $e(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(v.extname(e).toLowerCase())}function Re(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function Qe(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function Ot(e){return e.replace(/\//g,"\\/")}function Mn(e){return e.replace(/\//g,"\\\\/")}function jo(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 Dn(e,t,r){if(!t)return;e[t]=r;let n=Ot(t),s=Ot(r);e[n]=s;let o=Mn(t),a=Mn(r);e[o]=a;let c=Qe(t),i=Qe(r);e[c]=i;let l=Qe(n),d=Qe(s);e[l]=d;let u=Qe(o),g=Qe(a);e[u]=g;}function Mt(e,t,r){Dn(e,t,r);let n=jo(t);n&&n!==t&&Dn(e,n,r);}function Tr(e,t){let r=t.startsWith("/")?t:`/${t}`,n=(e||"").replace(/\/$/,"");return !n||n==="."||n==="/"?r:`${n}${r}`}function jn(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function Un(e,t,r){if(!t)return r;let n=v.dirname(v.resolve(t)),s=v.resolve(e,r.replace(/^\/+/,"")),o=v.relative(n,s).replace(/\\/g,"/");return o?(o.startsWith(".")||(o=`./${o}`),o):"."}async function $r(e,t){return (t?[...new Set(t)].map(n=>v.resolve(n)).filter(n=>n.startsWith(v.resolve(e.outputDir))).map(n=>v.relative(e.outputDir,n).replace(/\\/g,"/")).filter(n=>n.length>0):await Uo(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(n=>n!=="asset-map.json"&&$e(n))}var No=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],_o=new Set([".html",".htm"]),Ln="WPSuite.io Static Publisher",Bo=Ln.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Vo(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ko(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function Ho(e,t,r){return Ko(t)?e.replace(new RegExp(`(?<!:)${Vo(t)}`,"g"),r):e.split(t).join(r)}function zo(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let s=v.extname(r).toLowerCase();return _o.has(s)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Qo(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Bo}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${Ln}" />`;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 Jo(e){let t=Re(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function Go(e,t){let r=[...new Set(t)].filter(o=>o.includes("/")&&!/\\+\//.test(o)).map(o=>[o,Ot(o)]).filter(([o,a])=>o!==a).sort((o,a)=>a[0].length-o[0].length);if(!r.length)return e;let n=o=>{let a=o;for(let[c,i]of r)a=a.split(c).join(i);return a},s=e.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(o,a,c,i)=>`${a}${n(c)}${i}`);return s=s.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(o,a,c,i,l)=>Jo(i)?`${a}${n(i)}${l}`:o),s}function Zo(e,t){if(!t)return null;let r=v.dirname(v.resolve(t)),n=v.resolve(e.outputDir),s=v.relative(r,n).replace(/\\/g,"/");return s?(s.startsWith(".")||(s=`./${s}`),s.endsWith("/")?s:`${s}/`):"./"}function Yo(e,t,r){let n=Zo(t,r);if(!n)return e;let s=e;for(let o of No){let a=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=new RegExp(`(?:\\.{1,}/)+${a}`,"g"),i=new RegExp(`(?<!\\.)/${a}`,"g");s=s.replace(c,`${n}${o}`).replace(i,`${n}${o}`);let l=o.replace(/\//g,"\\/"),d=n.replace(/\//g,"\\/"),u=l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),g=new RegExp(`(?:\\.{1,}\\\\/)+${u}`,"g"),f=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${u}`,"g"),p=new RegExp(`(?<![\\.\\\\])\\/${u}`,"g");s=s.replace(g,`${d}${l}`).replace(f,`${d}${l}`).replace(p,`${d}${l}`);}return s}function Er(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:jn(t,e.targetOrigin),o=n?`${n.search}${n.hash}`:"";return e.urlRewriteMode==="root-relative"?`${s}${o}`:`${Un(e.outputDir,r,s)}${o}`}function
|
|
4
|
+
`;return e.replace(/<head\b[^>]*>/i,s=>`${s}${n} ${t}`)}function Jo(e){let t=Re(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function Go(e,t){let r=[...new Set(t)].filter(o=>o.includes("/")&&!/\\+\//.test(o)).map(o=>[o,Ot(o)]).filter(([o,a])=>o!==a).sort((o,a)=>a[0].length-o[0].length);if(!r.length)return e;let n=o=>{let a=o;for(let[c,i]of r)a=a.split(c).join(i);return a},s=e.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(o,a,c,i)=>`${a}${n(c)}${i}`);return s=s.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(o,a,c,i,l)=>Jo(i)?`${a}${n(i)}${l}`:o),s}function Zo(e,t){if(!t)return null;let r=v.dirname(v.resolve(t)),n=v.resolve(e.outputDir),s=v.relative(r,n).replace(/\\/g,"/");return s?(s.startsWith(".")||(s=`./${s}`),s.endsWith("/")?s:`${s}/`):"./"}function Yo(e,t,r){let n=Zo(t,r);if(!n)return e;let s=e;for(let o of No){let a=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=new RegExp(`(?:\\.{1,}/)+${a}`,"g"),i=new RegExp(`(?<!\\.)/${a}`,"g");s=s.replace(c,`${n}${o}`).replace(i,`${n}${o}`);let l=o.replace(/\//g,"\\/"),d=n.replace(/\//g,"\\/"),u=l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),g=new RegExp(`(?:\\.{1,}\\\\/)+${u}`,"g"),f=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${u}`,"g"),p=new RegExp(`(?<![\\.\\\\])\\/${u}`,"g");s=s.replace(g,`${d}${l}`).replace(f,`${d}${l}`).replace(p,`${d}${l}`);}return s}function Er(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:jn(t,e.targetOrigin),o=n?`${n.search}${n.hash}`:"";return e.urlRewriteMode==="root-relative"?`${s}${o}`:`${Un(e.outputDir,r,s)}${o}`}function Ar(e,t,r,n,s){Mt(e,r,Er(t,n,s));}function Xo(e,t,r,n,s){if(!r||r===n)return;Mt(e,r,n);let o=Er(t,r,s),a=Er(t,n,s);Mt(e,o,a);}function Or(e,t,r,n,s={}){let o=e,a={};Ar(a,t,t.sourceOrigin,t.targetOrigin,n);for(let[i,l]of Object.entries(t.extraReplacements))Ar(a,t,i,l,n);for(let[i,l]of Object.entries(r))Ar(a,t,i,l,n);for(let[i,l]of Object.entries(s)){let d=r[i];!d||d===l||Xo(a,t,l,d,n);}let c=Object.entries(a).sort((i,l)=>l[0].length-i[0].length);for(let[i,l]of c)o=Ho(o,i,l);return t.urlRewriteMode!=="absolute"&&(o=Yo(o,t,n)),o=Go(o,c.map(([,i])=>i)),zo(t,o,n)&&(o=Qo(o)),o}async function ei(e,t,r,n){let s=v.join(e.outputDir,n),o=v.extname(s).toLowerCase(),a;try{a=await D.readFile(s,"utf8");}catch(l){if(l.code!=="ENOENT")throw l;return {changed:false}}let i=Or(a,e,t,o===".js"||o===".mjs"?void 0:s,r);return i!==a?(await Fe(s,i,"utf8"),{changed:true}):{changed:false}}async function ti(e,t){return await new Promise((r,n)=>{let s=i=>{if(c(),i?.error){n(new Error(i.error));return}r({changed:!!i?.changed});},o=i=>{c(),n(i);},a=i=>{c(),i!==0&&n(new Error(`Rewrite worker exited with code ${i}.`));},c=()=>{e.off("message",s),e.off("error",o),e.off("exit",a);};e.on("message",s),e.on("error",o),e.on("exit",a),e.postMessage({file:t});})}async function Dt(e,t,r={}){let n=await $r(e,r.files),s=0;if(n.length===0)return 0;let o=Math.max(1,Number(e.rewriteConcurrency||e.assetDownloadConcurrency||1)),a=Math.max(1,Math.min(o,n.length,availableParallelism()));await r.onStart?.({totalFiles:n.length,workerCount:a});let c=0,i=0,l=null;if(a===1){for(let u of n){let g=await ei(e,t,r.previousAssetMap??{},u);g.changed&&(s+=1),i+=1,await r.onProgress?.({index:i,totalFiles:n.length,changedTextFiles:s,file:u,changed:g.changed});}return s}let d=Array.from({length:a},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 g=c;if(g>=n.length)return;c+=1;let f=n[g],p=await ti(u,f);p.changed&&(s+=1),i+=1,await r.onProgress?.({index:i,totalFiles:n.length,changedTextFiles:s,file:f,changed:p.changed});}}catch(g){throw l=g instanceof Error?g:new Error(String(g)),l}finally{await u.terminate().catch(()=>{});}});return await Promise.all(d),s}var fe={error:0,warn:1,info:2,debug:3},ri=/^(?:authorization|proxyAuthorization|runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken|xStaticPublisherToken|xApiKey)$/i;function je(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 jt(e){return typeof e=="string"?je(e):Array.isArray(e)?e.map(t=>jt(t)):e instanceof Error?{name:e.name,message:je(e.message),...e.stack?{stack:je(e.stack)}:{}}:e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([t,r])=>[t,ri.test(t)?"[REDACTED]":jt(r)])):e}function Lt(e){return e?jt(e):void 0}var qn=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",Ft=qn?v.join(qn,"current-progress.json"):"",Wn=Promise.resolve();function Nn(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function ni(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 a=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,i]of Object.entries(t)){let l=r[c];if(typeof l=="number"&&typeof i=="number"&&a.has(c)){r[c]=Math.max(l,i);continue}r[c]=i;}return r}function _n(e,t,r){Ft&&(Wn=Wn.then(async()=>{let n=new Date,s=n.toISOString();await D.mkdir(v.dirname(Ft),{recursive:true});let o=await D.readFile(Ft,"utf8").then(h=>JSON.parse(h)).catch(()=>null),a=o&&typeof o.details=="object"&&o.details?o.details:{},c=Nn(e),i=o?.currentStep||Nn(o?.source||""),l=o?.startedAt||s,d={...o?.stepDurationsSec??{}},u=o?.stepStartedAt||s;if(i&&i!==c&&o?.stepStartedAt){let h=Math.max(0,Math.round((n.getTime()-new Date(o.stepStartedAt).getTime())/1e3));d[i]=(d[i]??0)+h,u=s;}let g=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)),p=je(t),y=Lt(r)??{},m={checkedAt:s,source:e,message:p,details:ni(a,y),startedAt:l,currentStep:c,stepStartedAt:u,stepElapsedSec:g,totalElapsedSec:f,stepDurationsSec:d};await D.writeFile(Ft,JSON.stringify(m,null,2),"utf8");}).catch(()=>{}));}async function Bn(e,t){await D.mkdir(v.dirname(e),{recursive:true}),await D.appendFile(e,`${JSON.stringify(jt(t))}
|
|
5
5
|
`,"utf8");}function si(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 oi(e,t,r){let n=Lt(r);return {checkedAt:new Date().toISOString(),currentStep:si(e,n),level:e,message:je(t),details:n??{}}}var Je=class{constructor(t,r,n="info"){this.logDir=t;this.logFile=r;this.level=n;this.ensureLogFileReady();}logDir;logFile;level;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;get logPath(){return v.join(this.logDir,this.logFile)}artifactPath(t){return this.logFile.endsWith(".log.jsonl")?v.join(this.logDir,this.logFile.replace(/\.log\.jsonl$/u,`${t}.jsonl`)):v.join(this.logDir,`${this.logFile}${t}.jsonl`)}get errorsPath(){return this.artifactPath(".errors")}get rejectedPath(){return this.artifactPath(".rejected")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await D.mkdir(this.logDir,{recursive:true}),await D.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 D.appendFile(this.logPath,`${t}
|
|
6
6
|
`,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>Bn(t,r));}accepts(t){return fe[t]<=fe[this.level]}push(t,r,n){if(!this.accepts(t))return;let s=je(r),o=Lt(n),a=JSON.stringify({time:new Date().toISOString(),level:t,message:s,...o||{}});this.enqueueLine(a),t==="error"?console.error(`[ERROR] ${s}`,o?JSON.stringify(o):""):t==="warn"?console.warn(`[WARN] ${s}`,o?JSON.stringify(o):""):console.log(`[${t.toUpperCase().padEnd(5)}] ${s}`);}info(t,r){this.push("info",t,r);}progress(t,r){_n(this.logFile,t,r);}debug(t,r){this.push("debug",t,r);}warn(t,r){this.push("warn",t,r);}reject(t,r,n,s,o){let a={kind:t,url:r,reason:n,...s?{source:s}:{},...o||{}};this.enqueueJsonLine(this.rejectedPath,a),this.accepts("debug")&&this.push("debug",`Rejected ${t} ${r}: ${n}`,a);}error(t,r){this.enqueueJsonLine(this.errorsPath,{message:t,...r||{}}),this.push("error",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=Number((s/1e3).toFixed(2));this.push("info",`Timing ${t}: ${o}s`,{name:t,ms:s,seconds:o,...r||{}});}async flush(){let t=Date.now()-this.startedAt,r=Number((t/1e3).toFixed(2));if(this.push("info",`Total time: ${r}s`,{name:"total",ms:t,seconds:r}),await this.writeQueue,this.writeError)throw this.writeError}},Ut=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 v.join(this.logDir,"crawl.log.jsonl")}get currentEventPath(){return v.join(this.logDir,"current-crawl-event.json")}get rejectedPath(){return v.join(this.logDir,"rejected.jsonl")}get ignoredPath(){return v.join(this.logDir,"ignored.jsonl")}get skippedPath(){return v.join(this.logDir,"skipped-http.jsonl")}get errorsPath(){return v.join(this.logDir,"errors.jsonl")}get timingsPath(){return v.join(this.logDir,"timings.jsonl")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await D.mkdir(this.logDir,{recursive:true}),await D.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 D.appendFile(this.logPath,`${t}
|
|
7
7
|
`,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>Bn(t,r));}updateCurrentEvent(t,r,n){let s=oi(t,r,n);this.enqueueTask(async()=>{await D.mkdir(this.logDir,{recursive:true}),await D.writeFile(this.currentEventPath,JSON.stringify(s,null,2),"utf8");});}push(t,r,n){let s=je(r),o=Lt(n),a=JSON.stringify({time:new Date().toISOString(),level:t,message:s,...o||{}});this.enqueueLine(a),this.updateCurrentEvent(t,s,o),t==="error"?console.error(s,o||""):t==="warn"?console.warn(s,o||""):(fe[this.level]>=fe.debug||["summary","page","sitemap","asset","timing"].includes(t))&&console.log(s);}info(t,r){this.push("info",t,r);}debug(t,r){fe[this.level]<fe.debug||this.push("debug",t,r);}progress(t,r){_n("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),fe[this.level]>=fe.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),fe[this.level]>=fe.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 Vn="(?: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 Hn(e){let t=new RegExp(`(?:https?:)?//[^\\s'"<>\\);]+\\.${Vn}(?:[?#][^\\s'"<>\\);]*)?(?=[\\s'"<>\\);]|$)|(?<![A-Za-z0-9._-])/[^\\s'"<>\\);]+\\.${Vn}(?:[?#][^\\s'"<>\\);]*)?(?=[\\s'"<>\\);]|$)`,"gi");return [...e.matchAll(t)].map(r=>r[0])}function Kn(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 zn(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]&&Kn(o[1])&&r.push({index:o.index??0,value:o[1]});for(let o of e.matchAll(s))o[1]&&Kn(o[1])&&r.push({index:o.index??0,value:o[1]});for(let o of r.sort((a,c)=>a.index-c.index))t.add(o.value);return [...t]}function Qn(e,t){let r=v.relative(t,e);return r===""||!r.startsWith("..")&&!v.isAbsolute(r)}function Jn(e,t,r,n){let s=v.resolve(e),o=v.resolve(t),a=v.extname(s).toLowerCase();return !Qn(s,o)||a!==".html"&&a!==".htm"||r.has(s)?false:!n.some(c=>Qn(s,v.resolve(c)))}function Gn(e,t){return typeof e=="string"&&e.length>0&&t?.supported===true&&typeof t.token=="string"&&t.token.length>0&&e===t.token}function Zn(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(a=>o.startsWith(a))}catch{return false}}function Yn(e){return e<1}function Xn(e){let t=String(e??"").toLowerCase();return t==="strict"?"Strict":t==="lax"?"Lax":t==="none"?"None":"Unspecified"}function ai(e){let t=e.pathname||"/";if(!t.startsWith("/")||t==="/")return "/";let r=t.lastIndexOf("/");return r<=0?"/":t.slice(0,r)}function gt(e){return `${e.name.toLowerCase()}
|
|
8
8
|
${e.domain.toLowerCase()}
|
|
9
9
|
${e.path}`}function es(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 a=s.slice(0,o).trim();if(!a||[...a].some(y=>y<=" "||"=;,".includes(y)))return null;let c=r.hostname.toLowerCase(),i=ai(r),l=null,d=true,u=false,g=false,f="Unspecified",p=false;for(let y of n){let m=y.indexOf("="),h=(m<0?y:y.slice(0,m)).trim().toLowerCase(),w=m<0?"":y.slice(m+1).trim();if(h==="domain"&&w)c=w.toLowerCase();else if(h==="path"&&w.startsWith("/"))i=w;else if(h==="expires"){let k=Date.parse(w);Number.isFinite(k)&&(l=Math.floor(k/1e3),d=false);}else if(h==="max-age"&&/^-?\d+$/u.test(w)){let k=Number.parseInt(w,10);l=Math.floor(Date.now()/1e3)+k,d=false;}else h==="secure"?u=true:h==="httponly"?g=true:h==="samesite"?f=Xn(w):h==="partitioned"&&(p=true);}return {name:a,domain:c,path:i,expires:l,session:d,secure:u,httpOnly:g,sameSite:f,partitioned:p}}function ci(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:Xn(e.sameSite),partitioned:e.partitioned===true}}function ts(e,t){let r=new Map(e.map(n=>[gt(n),n.value]));return t.filter(n=>r.get(gt(n))!==n.value).map(ci)}function li(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 qt=class{#e=new Map;add(t){if(!t)return;let r={...t,domain:t.domain.toLowerCase(),path:t.path||"/"},n=gt(r),s=this.#e.get(n);this.#e.set(n,s?li(s,r):r);}addAll(t){for(let r of t)this.add(r);}artifact(){return {schemaVersion:1,observations:[...this.#e.values()].sort((t,r)=>gt(t).localeCompare(gt(r)))}}};async function Wt(e,t){await D.mkdir(v.dirname(e),{recursive:true});let r=`${e}.${process.pid}.tmp`;await D.writeFile(r,`${JSON.stringify(t,null,2)}
|
|
10
|
-
`,{encoding:"utf8",mode:384}),await D.rename(r,e);}function mt(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 ft(e,t){let r=mt(t);if(r===null)throw new Error(`Unsafe output URL pathname: ${t}`);let n=v.resolve(e),s=v.resolve(n,r.replace(/^\/+/,""));if(s!==n&&!s.startsWith(`${n}${v.sep}`))throw new Error(`Output path escapes configured root: ${t}`);return s}var Y=1,rs=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function ve(e,t){let r=String(e??"").trim();if(!rs.test(r))throw new Error(`${t} must match ${rs.source} and be at most 128 characters.`);return r}function ns(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 Nt(e,...t){let r=ns(e),n=t.map((s,o)=>{let a=String(s??"").replace(/^\/+|\/+$/g,"");if(!a||a.split("/").some(c=>c==="."||c===".."))throw new Error(`Unsafe S3 key segment at index ${o}.`);return a});return `${r}${n.join("/")}`}function Oe(e){return createHash("sha256").update(e).digest("hex")}function _t(e,t){let r=String(e??"").replace(/^\/+/,""),n=ns(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 se(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 wi(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!==Y)throw new Error(`Remote worker protocol mismatch: expected ${Y}, 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:se(t.region,"region"),...se(t.roleArn,"roleArn",{optional:true})?{roleArn:se(t.roleArn,"roleArn")}:{},...se(t.roleSessionName,"roleSessionName",{optional:true})?{roleSessionName:se(t.roleSessionName,"roleSessionName")}:{},workspace:{bucket:se(r.bucket,"workspace.bucket"),prefix:String(r.prefix??"")},functions:{render:se(n.render,"functions.render"),rewrite:se(n.rewrite,"functions.rewrite"),"deploy-copy":se(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 a=s;return {id:se(a.id,`targets[${o}].id`),bucketName:se(a.bucketName,`targets[${o}].bucketName`),prefix:String(a.prefix??""),region:se(a.region,`targets[${o}].region`)}}):[],protocolVersion:Y}}async function Bt(e){let t=v.resolve(e);try{return wi(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 Ze=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],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!==Y||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=_t(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=_t(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(Oe(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],n=`${t}-${Date.now()}`,s=await this.lambda.send(new InvokeCommand({FunctionName:r,InvocationType:"RequestResponse",Payload:Buffer.from(JSON.stringify({schemaVersion:Y,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=_t(t.key,this.config.workspace.prefix),n=typeof t.body=="string"?Buffer.from(t.body,"utf8"):t.body,s=Oe(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}:{}}}};function yi(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!==Y||!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 Vt=class{#e;#r;#t;#n;#s=0;constructor(t){this.#e=t.client,this.#r=ve(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=ve(`render-${this.#s}-${Oe(t.url).slice(0,24)}-a${n}`,"taskId");try{let o=await this.#e.invoke({schemaVersion:Y,operation:"render",jobId:this.#r,taskId:s,sourceOrigin:new URL(t.sourceOrigin).origin,urls:[t.url],options:t.options}),c=yi(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: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 Pi(e,t){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.slice(n,n+t));return r}function Ri(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 vi(e,t){if(!e||typeof e!="object")throw new Error("Remote rewrite result must be a JSON object.");let r=e;if(r.schemaVersion!==Y||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 Kt(e,t,r){let n=r.options??{},s=await $r(e,n.files);if(s.length===0)return 0;let o=ve(r.jobId,"jobId"),a=Nt(r.client.config.workspace.prefix,"jobs",o,"rewrite-inputs"),c=`${a}/config.json`.replace(/\/+/g,"/"),i=`${a}/asset-map.json`.replace(/\/+/g,"/"),l=`${a}/previous-asset-map.json`.replace(/\/+/g,"/");await Promise.all([r.client.writeWorkspaceObject({key:c,body:JSON.stringify(Ri(e)),contentType:"application/json; charset=utf-8"}),r.client.writeWorkspaceObject({key:i,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),g=Math.max(1,Math.min(Math.max(1,r.concurrency),u));await n.onStart?.({totalFiles:s.length,workerCount:g});let f=[],p=0,y=0;await Promise.all(Array.from({length:Math.min(16,s.length)},async()=>{for(;;){let E=p;if(E>=s.length)return;p+=1;let $=s[E],C=v.join(e.outputDir,$),S=`${a}/files/${Oe($)}.txt`.replace(/\/+/g,"/");await r.client.writeWorkspaceObject({key:S,body:await D.readFile(C),contentType:"text/plain; charset=utf-8"}),f[E]={relativePath:$,key:S,fullPath:C},y+=1,await r.onStageProgress?.({index:y,totalFiles:s.length,file:$});}}));let m=Pi(f,d),h=0,w=0,k=0,I=Array.from({length:g},async()=>{for(;;){let E=h;if(E>=m.length)return;h+=1;let $=m[E],C=null,S=null;for(let b=1;b<=Math.max(1,Math.min(5,r.maxAttempts));b+=1){let T=ve(`rewrite-${E+1}-a${b}-${Oe($.map(A=>A.relativePath).join(`
|
|
11
|
-
`)).slice(0,16)}`,"taskId"),q={schemaVersion:Y,operation:"rewrite",jobId:o,taskId:T,configKey:c,assetMapKey:i,previousAssetMapKey:l,items:$.map(A=>({inputKey:A.key,outputKey:A.key,relativePath:A.relativePath}))};try{let A=await r.client.invoke(q);S=vi(await r.client.readResult(A),A);break}catch(A){C=A;}}if(!S)throw new Error(`Remote rewrite batch ${E+1}/${m.length} failed: ${C instanceof Error?C.message:String(C)}`,{cause:C});for(let b of $){let T=S.detail.objects.find(q=>q.outputKey===b.key);if(!T)throw new Error(`Remote rewrite result omitted ${b.relativePath}.`);await Fe(b.fullPath,Buffer.from(await r.client.readObject(T.output))),T.changed&&(k+=1),w+=1,await n.onProgress?.({index:w,totalFiles:s.length,changedTextFiles:k,file:b.relativePath,changed:T.changed});}}});return await Promise.all(I),k}var Ci="remote-workers.json";function Ht(e={}){let t=String(e.explicitPath??"").trim();if(t)return v.resolve(t);let r=String(e.runtimeDir??process.env.STATIC_PUBLISHER_RUNTIME_DIR??process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR??"").trim();return r?v.join(v.resolve(r),Ci):""}function is(e,t,r,n=250){let s=Math.max(1,Math.floor(n)),o=[],a=new Set;for(let c of [e,...t]){let i=c.trim();if(!(!i||a.has(i)||r(i))&&(a.add(i),o.push(i),o.length>=s))break}return o}var Ai=["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"],ws=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"]),ys=new Set(["",".html",".htm"]),Ti=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),Ei=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function $i(e){let t=[],r="full",n="full",s=false,o=false,a="",c=null,i="";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,a=v.resolve(u);}else if(d.startsWith("--content-sync-plan="))r="content-sync",n="incremental",s=true,a=v.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");i=v.resolve(u);}else d.startsWith("--remote-worker-config=")&&(i=v.resolve(d.slice(23)));}return {mode:r,crawlMode:n,urls:t,preserveOutput:s,resumeRewrite:o,contentSyncPlanPath:a,remoteRender:c,remoteWorkerConfigPath:i}}function Pt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?v.resolve(e):""}function Oi(){let e=Pt();return e?v.join(e,"privacy","cookie-observations.json"):null}function Mi(){let e=Pt();return e?v.resolve(e,".."):""}function Di(){let e=process.env.STATIC_PUBLISHER_WP_ROOT||process.env.WPSUITE_STATIC_PUBLISHER_WP_ROOT||"";return e.trim()?v.resolve(e):""}function Fi(e){let t=e.trim(),r=[{alias:"@storage-root",root:Mi(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@runtime",root:Pt(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@wp-root",root:Di(),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?v.resolve(n.root,s):n.root,alias:n.alias}}return {resolvedPath:v.resolve(t)}}function Ss(e){let t=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(t)return v.resolve(t);let r=Pt();return r?v.join(r,"crawl-manifest.json"):v.join(e.outputDir,".crawl-manifest.json")}function bs(){return {schemaVersion:6,updatedAt:"",pages:{},assets:{}}}function cs(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 ji(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 Lr(e){let t=e?.["content-type"]?.trim();return t||null}function qr(e){let t=e?.["cache-control"]?.trim();return t||null}function Ui(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 Li(){return {rewriteTargets:new Set,changedFiles:new Set,deletedFiles:new Set,revalidateFiles:new Set}}function zt(e,t,r,n){let s=ge(t.outputDir,r);s&&(Ui(n)?e.revalidateFiles.add(s):e.revalidateFiles.delete(s));}function ne(e,t,r){let n=ge(t.outputDir,r);n&&(e.changedFiles.add(n),e.deletedFiles.delete(n));}function Wr(e,t,r){let n=ge(t.outputDir,r);n&&(e.deletedFiles.add(n),e.changedFiles.delete(n),e.revalidateFiles.delete(n));}function ke(e,t){e.rewriteTargets.add(v.resolve(t));}async function qi(e){try{let t=await D.readFile(Ss(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,cs(s)])),assets:Object.fromEntries(Object.entries(r.assets).map(([n,s])=>[n,ji(s)]))};if(r.schemaVersion===1)return {schemaVersion:6,updatedAt:String(r.updatedAt||""),pages:Object.fromEntries(Object.entries(r.pages).map(([n,s])=>[n,cs(s)])),assets:{}}}}catch{}return bs()}function Nr(e){return JSON.parse(JSON.stringify(e))}async function Wi(e,t){let r=Ss(e);await D.mkdir(v.dirname(r),{recursive:true}),await D.writeFile(r,JSON.stringify(t,null,2),"utf8");}async function xe(e,t){if(!t.trackManifest)return;let r=async()=>{let n=Nr(t.manifest);n.updatedAt=new Date().toISOString(),t.manifest.updatedAt=n.updatedAt,await Wi(e,n);};t.manifestSaveChain=t.manifestSaveChain.then(r,r),await t.manifestSaveChain;}function Ue(e){if(!e)return null;let t=e.trim();return t||null}function Ni(e,t){let r=new Set,n=new Set([...Object.keys(e),...Object.keys(t)]);for(let s of n){let o=e[s],a=t[s];!o||!a||o===a||r.add(s);}return r}async function Ps(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 a=new URL("/wp-json/smartcloud-static-publisher/v1/change-tokens",e.sourceOrigin).toString();try{let c=await t.post(a,{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:a,status:c.status()}),new Map;let i=await c.json().catch(()=>null);if(!i||!Array.isArray(i.items))return new Map;let l=new Map;for(let d of i.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:a,error:c instanceof Error?`${c.name}: ${c.message.split(/\r?\n/u,1)[0]}`:"Unknown change-token request failure"}),new Map}}async function Jt(e,t,r,n,s){if(!r.enabled&&!r.trackManifest)return null;if(r.changeTokenCache.has(n))return r.changeTokenCache.get(n)??null;let a=(await Ps(e,t,[n],s)).get(n)??null;return Xt(e,n)&&(!a||a.supported!==true||!a.token)&&(a=await Vi(e,t,n,s)),a=vs(e,a),r.changeTokenCache.set(n,a),a}async function Rs(e,t,r,n,s){if(!r.trackManifest)return;let o=[...new Set(n.map(a=>a.trim()).filter(Boolean))].filter(a=>!r.changeTokenCache.has(a));for(let a=0;a<o.length;a+=250){let c=o.slice(a,a+250),i=await Ps(e,t,c,s);for(let l of c)r.changeTokenCache.set(l,vs(e,i.get(l)??null));}}async function _i(e,t,r,n,s,o){if(!(!n.trackManifest||n.changeTokenCache.has(s)))for(;!n.changeTokenCache.has(s);){if(!n.pageChangeTokenPrimePromise){let a=is(s,r.pageQueue,i=>n.changeTokenCache.has(i));if(a.length===0)return;o.info(`Loading ${a.length} page change tokens in bulk.`,{phase:"prime-page-change-tokens",batchSize:a.length,remainingPages:r.pageQueue.length});let c=Rs(e,t,n,a,o).finally(()=>{n.pageChangeTokenPrimePromise===c&&(n.pageChangeTokenPrimePromise=null);});n.pageChangeTokenPrimePromise=c;}await n.pageChangeTokenPrimePromise;}}function Bi(e){return `subscriber=${e.wpsuite?.siteSettings?.subscriber===true?"1":"0"}`}function vs(e,t){if(!t?.supported||!t.token||t.tokenSource==="wp-media-file")return t;let r=Bi(e);return {...t,token:De(`${t.token}
|
|
10
|
+
`,{encoding:"utf8",mode:384}),await D.rename(r,e);}function mt(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 ft(e,t){let r=mt(t);if(r===null)throw new Error(`Unsafe output URL pathname: ${t}`);let n=v.resolve(e),s=v.resolve(n,r.replace(/^\/+/,""));if(s!==n&&!s.startsWith(`${n}${v.sep}`))throw new Error(`Output path escapes configured root: ${t}`);return s}var Y=1,rs=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function ve(e,t){let r=String(e??"").trim();if(!rs.test(r))throw new Error(`${t} must match ${rs.source} and be at most 128 characters.`);return r}function ns(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 Nt(e,...t){let r=ns(e),n=t.map((s,o)=>{let a=String(s??"").replace(/^\/+|\/+$/g,"");if(!a||a.split("/").some(c=>c==="."||c===".."))throw new Error(`Unsafe S3 key segment at index ${o}.`);return a});return `${r}${n.join("/")}`}function Oe(e){return createHash("sha256").update(e).digest("hex")}function _t(e,t){let r=String(e??"").replace(/^\/+/,""),n=ns(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 se(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 wi(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!==Y)throw new Error(`Remote worker protocol mismatch: expected ${Y}, 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:se(t.region,"region"),...se(t.roleArn,"roleArn",{optional:true})?{roleArn:se(t.roleArn,"roleArn")}:{},...se(t.roleSessionName,"roleSessionName",{optional:true})?{roleSessionName:se(t.roleSessionName,"roleSessionName")}:{},workspace:{bucket:se(r.bucket,"workspace.bucket"),prefix:String(r.prefix??"")},functions:{render:se(n.render,"functions.render"),rewrite:se(n.rewrite,"functions.rewrite"),"deploy-copy":se(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 a=s;return {id:se(a.id,`targets[${o}].id`),bucketName:se(a.bucketName,`targets[${o}].bucketName`),prefix:String(a.prefix??""),region:se(a.region,`targets[${o}].region`)}}):[],protocolVersion:Y}}async function Bt(e){let t=v.resolve(e);try{return wi(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 Ze=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],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!==Y||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=_t(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=_t(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(Oe(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],n=`${t}-${Date.now()}`,s=await this.lambda.send(new InvokeCommand({FunctionName:r,InvocationType:"RequestResponse",Payload:Buffer.from(JSON.stringify({schemaVersion:Y,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=_t(t.key,this.config.workspace.prefix),n=typeof t.body=="string"?Buffer.from(t.body,"utf8"):t.body,s=Oe(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}:{}}}};function yi(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!==Y||!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 Vt=class{#e;#r;#t;#n;#s=0;constructor(t){this.#e=t.client,this.#r=ve(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=ve(`render-${this.#s}-${Oe(t.url).slice(0,24)}-a${n}`,"taskId");try{let o=await this.#e.invoke({schemaVersion:Y,operation:"render",jobId:this.#r,taskId:s,sourceOrigin:new URL(t.sourceOrigin).origin,urls:[t.url],options:t.options}),c=yi(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: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 Pi(e,t){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.slice(n,n+t));return r}function Ri(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 vi(e,t){if(!e||typeof e!="object")throw new Error("Remote rewrite result must be a JSON object.");let r=e;if(r.schemaVersion!==Y||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 Kt(e,t,r){let n=r.options??{},s=await $r(e,n.files);if(s.length===0)return 0;let o=ve(r.jobId,"jobId"),a=Nt(r.client.config.workspace.prefix,"jobs",o,"rewrite-inputs"),c=`${a}/config.json`.replace(/\/+/g,"/"),i=`${a}/asset-map.json`.replace(/\/+/g,"/"),l=`${a}/previous-asset-map.json`.replace(/\/+/g,"/");await Promise.all([r.client.writeWorkspaceObject({key:c,body:JSON.stringify(Ri(e)),contentType:"application/json; charset=utf-8"}),r.client.writeWorkspaceObject({key:i,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),g=Math.max(1,Math.min(Math.max(1,r.concurrency),u));await n.onStart?.({totalFiles:s.length,workerCount:g});let f=[],p=0,y=0;await Promise.all(Array.from({length:Math.min(16,s.length)},async()=>{for(;;){let E=p;if(E>=s.length)return;p+=1;let $=s[E],C=v.join(e.outputDir,$),S=`${a}/files/${Oe($)}.txt`.replace(/\/+/g,"/");await r.client.writeWorkspaceObject({key:S,body:await D.readFile(C),contentType:"text/plain; charset=utf-8"}),f[E]={relativePath:$,key:S,fullPath:C},y+=1,await r.onStageProgress?.({index:y,totalFiles:s.length,file:$});}}));let m=Pi(f,d),h=0,w=0,k=0,I=Array.from({length:g},async()=>{for(;;){let E=h;if(E>=m.length)return;h+=1;let $=m[E],C=null,S=null;for(let b=1;b<=Math.max(1,Math.min(5,r.maxAttempts));b+=1){let A=ve(`rewrite-${E+1}-a${b}-${Oe($.map(T=>T.relativePath).join(`
|
|
11
|
+
`)).slice(0,16)}`,"taskId"),q={schemaVersion:Y,operation:"rewrite",jobId:o,taskId:A,configKey:c,assetMapKey:i,previousAssetMapKey:l,items:$.map(T=>({inputKey:T.key,outputKey:T.key,relativePath:T.relativePath}))};try{let T=await r.client.invoke(q);S=vi(await r.client.readResult(T),T);break}catch(T){C=T;}}if(!S)throw new Error(`Remote rewrite batch ${E+1}/${m.length} failed: ${C instanceof Error?C.message:String(C)}`,{cause:C});for(let b of $){let A=S.detail.objects.find(q=>q.outputKey===b.key);if(!A)throw new Error(`Remote rewrite result omitted ${b.relativePath}.`);await Fe(b.fullPath,Buffer.from(await r.client.readObject(A.output))),A.changed&&(k+=1),w+=1,await n.onProgress?.({index:w,totalFiles:s.length,changedTextFiles:k,file:b.relativePath,changed:A.changed});}}});return await Promise.all(I),k}var Ci="remote-workers.json";function Ht(e={}){let t=String(e.explicitPath??"").trim();if(t)return v.resolve(t);let r=String(e.runtimeDir??process.env.STATIC_PUBLISHER_RUNTIME_DIR??process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR??"").trim();return r?v.join(v.resolve(r),Ci):""}function is(e,t,r,n=250){let s=Math.max(1,Math.floor(n)),o=[],a=new Set;for(let c of [e,...t]){let i=c.trim();if(!(!i||a.has(i)||r(i))&&(a.add(i),o.push(i),o.length>=s))break}return o}var Ti=["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"],ws=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"]),ys=new Set(["",".html",".htm"]),Ai=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),Ei=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function $i(e){let t=[],r="full",n="full",s=false,o=false,a="",c=null,i="";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,a=v.resolve(u);}else if(d.startsWith("--content-sync-plan="))r="content-sync",n="incremental",s=true,a=v.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");i=v.resolve(u);}else d.startsWith("--remote-worker-config=")&&(i=v.resolve(d.slice(23)));}return {mode:r,crawlMode:n,urls:t,preserveOutput:s,resumeRewrite:o,contentSyncPlanPath:a,remoteRender:c,remoteWorkerConfigPath:i}}function Pt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?v.resolve(e):""}function Oi(){let e=Pt();return e?v.join(e,"privacy","cookie-observations.json"):null}function Mi(){let e=Pt();return e?v.resolve(e,".."):""}function Di(){let e=process.env.STATIC_PUBLISHER_WP_ROOT||process.env.WPSUITE_STATIC_PUBLISHER_WP_ROOT||"";return e.trim()?v.resolve(e):""}function Fi(e){let t=e.trim(),r=[{alias:"@storage-root",root:Mi(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@runtime",root:Pt(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@wp-root",root:Di(),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?v.resolve(n.root,s):n.root,alias:n.alias}}return {resolvedPath:v.resolve(t)}}function Ss(e){let t=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(t)return v.resolve(t);let r=Pt();return r?v.join(r,"crawl-manifest.json"):v.join(e.outputDir,".crawl-manifest.json")}function bs(){return {schemaVersion:6,updatedAt:"",pages:{},assets:{}}}function cs(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 ji(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 Lr(e){let t=e?.["content-type"]?.trim();return t||null}function qr(e){let t=e?.["cache-control"]?.trim();return t||null}function Ui(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 Li(){return {rewriteTargets:new Set,changedFiles:new Set,deletedFiles:new Set,revalidateFiles:new Set}}function zt(e,t,r,n){let s=ge(t.outputDir,r);s&&(Ui(n)?e.revalidateFiles.add(s):e.revalidateFiles.delete(s));}function ne(e,t,r){let n=ge(t.outputDir,r);n&&(e.changedFiles.add(n),e.deletedFiles.delete(n));}function Wr(e,t,r){let n=ge(t.outputDir,r);n&&(e.deletedFiles.add(n),e.changedFiles.delete(n),e.revalidateFiles.delete(n));}function ke(e,t){e.rewriteTargets.add(v.resolve(t));}async function qi(e){try{let t=await D.readFile(Ss(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,cs(s)])),assets:Object.fromEntries(Object.entries(r.assets).map(([n,s])=>[n,ji(s)]))};if(r.schemaVersion===1)return {schemaVersion:6,updatedAt:String(r.updatedAt||""),pages:Object.fromEntries(Object.entries(r.pages).map(([n,s])=>[n,cs(s)])),assets:{}}}}catch{}return bs()}function Nr(e){return JSON.parse(JSON.stringify(e))}async function Wi(e,t){let r=Ss(e);await D.mkdir(v.dirname(r),{recursive:true}),await D.writeFile(r,JSON.stringify(t,null,2),"utf8");}async function xe(e,t){if(!t.trackManifest)return;let r=async()=>{let n=Nr(t.manifest);n.updatedAt=new Date().toISOString(),t.manifest.updatedAt=n.updatedAt,await Wi(e,n);};t.manifestSaveChain=t.manifestSaveChain.then(r,r),await t.manifestSaveChain;}function Ue(e){if(!e)return null;let t=e.trim();return t||null}function Ni(e,t){let r=new Set,n=new Set([...Object.keys(e),...Object.keys(t)]);for(let s of n){let o=e[s],a=t[s];!o||!a||o===a||r.add(s);}return r}async function Ps(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 a=new URL("/wp-json/smartcloud-static-publisher/v1/change-tokens",e.sourceOrigin).toString();try{let c=await t.post(a,{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:a,status:c.status()}),new Map;let i=await c.json().catch(()=>null);if(!i||!Array.isArray(i.items))return new Map;let l=new Map;for(let d of i.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:a,error:c instanceof Error?`${c.name}: ${c.message.split(/\r?\n/u,1)[0]}`:"Unknown change-token request failure"}),new Map}}async function Jt(e,t,r,n,s){if(!r.enabled&&!r.trackManifest)return null;if(r.changeTokenCache.has(n))return r.changeTokenCache.get(n)??null;let a=(await Ps(e,t,[n],s)).get(n)??null;return Xt(e,n)&&(!a||a.supported!==true||!a.token)&&(a=await Vi(e,t,n,s)),a=vs(e,a),r.changeTokenCache.set(n,a),a}async function Rs(e,t,r,n,s){if(!r.trackManifest)return;let o=[...new Set(n.map(a=>a.trim()).filter(Boolean))].filter(a=>!r.changeTokenCache.has(a));for(let a=0;a<o.length;a+=250){let c=o.slice(a,a+250),i=await Ps(e,t,c,s);for(let l of c)r.changeTokenCache.set(l,vs(e,i.get(l)??null));}}async function _i(e,t,r,n,s,o){if(!(!n.trackManifest||n.changeTokenCache.has(s)))for(;!n.changeTokenCache.has(s);){if(!n.pageChangeTokenPrimePromise){let a=is(s,r.pageQueue,i=>n.changeTokenCache.has(i));if(a.length===0)return;o.info(`Loading ${a.length} page change tokens in bulk.`,{phase:"prime-page-change-tokens",batchSize:a.length,remainingPages:r.pageQueue.length});let c=Rs(e,t,n,a,o).finally(()=>{n.pageChangeTokenPrimePromise===c&&(n.pageChangeTokenPrimePromise=null);});n.pageChangeTokenPrimePromise=c;}await n.pageChangeTokenPrimePromise;}}function Bi(e){return `subscriber=${e.wpsuite?.siteSettings?.subscriber===true?"1":"0"}`}function vs(e,t){if(!t?.supported||!t.token||t.tokenSource==="wp-media-file")return t;let r=Bi(e);return {...t,token:De(`${t.token}
|
|
12
12
|
${r}`,40),tokenSource:t.tokenSource?`${t.tokenSource}+site-subscriber`:"site-subscriber"}}async function Vi(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(()=>""),a=De(`${r}
|
|
13
13
|
404
|
|
14
|
-
${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:a,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 Cs(e,t,r,n,s,o){let a=Xt(e,s);if(await _i(e,t,r,n,s,o),!n.enabled)return {action:"render",changeToken:n.trackManifest?await Jt(e,t,n,s,o):null};let c=n.manifest.pages[s];if(!c)return {action:"render",changeToken:await Jt(e,t,n,s,o)};let i=await Jt(e,t,n,s,o);if(i?.supported&&i.token)return c.changeToken===i.token?a&&!await Ki(e,t,s,o)?{action:"render",changeToken:i}:{action:"reuse",changeToken:i}:{action:"render",changeToken:i};let l=Ue(r.sitemapLastmodByPage[s]);return l&&c.sitemapLastmod&&c.sitemapLastmod===l?{action:"reuse",changeToken:i}:{action:"render",changeToken:i}}async function Ki(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 Hi(e,t,r,n,s){let o=ls(r.previousManifest,void 0,n,"previous-manifest"),a=0;for(let[g,f]of Object.entries(r.manifest.pages))if(!r.seenPages.has(g)){Wr(s,e,f.outputPath);try{await D.unlink(f.outputPath);}catch(p){(p.code||"")!=="ENOENT"&&n.warn(`Failed to remove stale incremental page output for ${g}`,{url:g,outputPath:f.outputPath,error:String(p)});}delete r.manifest.pages[g],a++;}let c=ls(r.manifest,r.runId,n,"active-manifest"),i=new Set,l=new Set;for(let g of c){for(let y of yt(e,g))i.add(y);let f=r.manifest.assets[g]?.outputPath;f&&l.add(f);let p=Xe(e,t.assetMap,g);p&&l.add(p);}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(Yn(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,p=r.previousManifest.assets[g]?.outputPath;p&&f.add(p);let y=Xe(e,t.assetMap,g);if(!c.has(g)&&y)f.add(y);else if(!c.has(g)){let m=ua(e,g,n,"incremental-cleanup");m&&(f.add(m.originalFilePath),m.hashedFilePath&&f.add(m.hashedFilePath));}for(let m of f)if(!l.has(m)){Wr(s,e,m);try{await D.unlink(m),d++;}catch(h){(h.code||"")!=="ENOENT"&&n.warn(`Failed to remove stale incremental asset output for ${g}`,{url:g,outputPath:m,error:String(h)});}}for(let m of yt(e,g))i.has(m)||Object.prototype.hasOwnProperty.call(t.assetMap,m)&&(delete t.assetMap[m],u++);}(a>0||d>0||u>0)&&n.info(`Incremental cleanup removed ${a} stale pages, ${d} stale assets, ${u} stale asset mappings`,{removedPages:a,removedAssets:d,removedAssetMappings:u,phase:"incremental-cleanup"});}async function zi(e,t,r,n){let s=new Set([...Object.values(t.manifest.pages),...Object.values(t.manifest.assets)].map(i=>String(i.outputPath||"").trim()).filter(Boolean).map(i=>v.resolve(i))),o=Object.values(e.postCrawlCopyMap||{}).map(i=>Gt(String(i||""))).filter(i=>!!i).map(i=>v.resolve(e.outputDir,i)),c=(await Uo(["**/*.html","**/*.htm"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(i=>Jn(v.join(e.outputDir,i),e.outputDir,s,o));for(let i of c){let l=v.join(e.outputDir,i);Wr(n,e,l),await D.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 ls(e,t,r,n){let s=new Set,o=a=>{let c=a.trim();if(c){if(r){let i=we(c,r,"asset",n??"manifest");if(!i)return;s.add(i.toString());return}s.add(c);}};for(let a of Object.values(e.pages))for(let c of a.discoveredAssets||[])o(c);for(let[a,c]of Object.entries(e.assets||{}))t&&c.lastSeenRunId!==t||o(a);return s}function us(e,t,r){for(let n of t)for(let s of yt(e,n))if(r.has(s))return true;return false}function Qi(e,t,r,n,s){let o=new Set(r.rewriteTargets);for(let c of r.changedFiles)o.add(v.resolve(e.outputDir,c));for(let c of Object.values(t.manifest.pages))c.rewriteComplete||o.add(v.resolve(c.outputPath));for(let c of Object.values(t.manifest.assets))c.isText&&!c.rewriteComplete&&o.add(v.resolve(c.outputPath));let a=Ni(n,s);if(a.size===0)return [...o];for(let c of Object.values(t.manifest.pages))us(e,c.discoveredAssets,a)&&o.add(v.resolve(c.outputPath));for(let[c,i]of Object.entries(t.manifest.assets)){i.isText&&us(e,i.discoveredAssets,a)&&o.add(v.resolve(i.outputPath));for(let l of yt(e,c))if(a.has(l)){ne(r,e,i.outputPath),i.isText&&o.add(v.resolve(i.outputPath));break}}return [...o]}function Ji(e,t){let r=t?new Set(Array.from(t,s=>v.resolve(s))):null,n=s=>r===null||r.has(v.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 Gi(e,t,r){let n=new Set,s=o=>{if(!o)return;let a=ge(e.outputDir,o);a&&n.add(a);};for(let o of t.donePages)s(he(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(Xe(e,t.assetMap,o));for(let o of Object.values(r.manifest.assets))o.lastSeenRunId===r.runId&&s(o.outputPath);return n}async function Zi(e,t,r,n,s){let o=[...n.deletedFiles].sort(),a=Gi(e,t,r),c=0;for(let d of [...a].sort()){try{if((await D.stat(v.join(e.outputDir,d))).isFile())continue}catch{}c++,s.warn(`Active output is missing after crawl: ${d}`,{phase:"deploy-plan",file:d,outputPath:v.join(e.outputDir,d)});}if(c>0&&s.warn(`Detected ${c} active output file(s) missing before deploy plan save.`,{phase:"deploy-plan",missingActiveOutputs:c}),o.length===0)return [];let i=[],l=0;for(let d of o){if(!a.has(d)){i.push(d);continue}l++;let u=v.join(e.outputDir,d),g;try{g=(await D.stat(u)).isFile();}catch{g=false;}s.warn(`Deploy plan protected active output from deletion: ${d}`,{phase:"deploy-plan",file:d,outputPath:u,exists:g});}return l>0&&s.info(`Deploy plan skipped ${l} active output deletion(s).`,{phase:"deploy-plan",protectedDeletes:l,deletedFiles:i.length}),i}function yt(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 a of o)try{r.add(new URL(a).origin+n.pathname+n.search);}catch{}r.add(n.pathname+n.search),r.add(n.pathname);}catch{}return [...r]}function Yi(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 a of o)try{r.add(new URL(a).origin+n.pathname+n.search);}catch{}r.add(n.pathname+n.search);}catch{}return [...r]}function ks(e,t){let r=e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/"?e.targetOrigin:"https://relative.invalid/";try{let n=new URL(t,r);return ft(e.outputDir,n.pathname)}catch{return null}}function Xi(e,t,r){for(let n of Yi(e,r)){let s=t[n];if(!s)continue;let o=ks(e,s);if(o)return {outputPath:o,publicUrl:s}}return null}function ea(e,t,r){for(let n of yt(e,r)){let s=t[n];if(!s)continue;let o=ks(e,s);if(o)return o}return null}function Xe(e,t,r){let n=ea(e,t,r);if(n)return n;try{return er(e,r).originalFilePath}catch{return null}}function ta(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?v.join(v.resolve(e),"queue-runner-heartbeat.json"):""}async function jr(e){let t=ta();if(t)try{let r=await D.readFile(t,"utf8"),n=JSON.parse(r);if(!n||typeof n!="object")return;await D.writeFile(t,JSON.stringify({...n,checkedAt:new Date().toISOString(),status:"running",currentStep:"rewrite",message:e},null,2),"utf8");}catch{}}function ra(e,t){let r=new Set;for(let n of t.donePages)r.add(v.resolve(he(e,n)));for(let n of t.doneAssets){let s=Xe(e,t.assetMap,n);!s||!$e(s)||r.add(v.resolve(s));}for(let n of t.doneSitemaps){let s=Xe(e,t.assetMap,n);!s||!$e(s)||r.add(v.resolve(s));}return [...r]}var Zt="re:",Qt=new Map;function na(e){if(!e.startsWith(Zt))return null;let t=Qt.get(e);if(t!==void 0)return t||null;let r=e.slice(Zt.length).trim();if(!r)return Qt.set(e,false),null;try{let n=new RegExp(r);return Qt.set(e,n),n}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),Qt.set(e,false),null}}function Hr(e,t){let r=na(t);return r?r.test(e):t.startsWith(Zt)?false:e.startsWith(t)}function sa(e,t){return t.find(r=>Hr(e,r))}function xs(e,t){let r=sa(t.pathname,e.blockedPathPrefixes);if(r)return r.startsWith(Zt)?`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 oa(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 ia(e,t){return oa(e).has(t.hostname)}function aa(e){let t=Re(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function _r(e){let t=Re(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function ca(e){let t=Re(e).replace(/\\\//g,"/").trim(),r=v.extname(t).toLowerCase();return ws.has(r)||ys.has(r)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function qe(e){return Ei.some(t=>e.pathname.startsWith(t))}function Z(e,t,r=e.sourceOrigin,n,s="url",o=false){let a=aa(t);if(!a||a.startsWith("data:")||a.startsWith("blob:")||a.startsWith("mailto:")||a.startsWith("tel:")||a.startsWith("#"))return n?.ignore(s,t,"empty or unsupported scheme",r),null;if(_r(a))return n?.ignore(s,t,"looks like JavaScript/code fragment",r),null;if(ca(a))return n?.ignore(s,t,"looks like JavaScript property access",r),null;try{let c=new URL(a,r);if(Is(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(!ia(e,c))return n?.ignore(s,c.toString(),"host not allowed",r),null;let i=xs(e,c);if(i&&!(o&&br(c)))return n?.reject(s,c.toString(),i,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 Is(e){try{return decodeURIComponent(e.pathname),decodeURIComponent(e.search),decodeURIComponent(e.hash),!1}catch{return true}}function we(e,t,r,n){try{let s=new URL(e);return Is(s)?(t.reject(r,e,"malformed URL encoding",n),null):mt(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 As(e){return ws.has(v.extname(e.pathname).toLowerCase())}function Ie(e){return qe(e)?false:ys.has(v.extname(e.pathname).toLowerCase())}function tt(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function _(e,t){return !!(tt(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(r=>Hr(t.pathname,r))||As(t)||!Ie(t)&&!qe(t))}function he(e,t){let r=new URL(t),n=mt(r.pathname);if(n===null)throw new Error(`Unsafe page URL pathname: ${r.pathname}`);return n.endsWith("/")?n+="index.html":v.extname(n)||(n+="/index.html"),ft(e.outputDir,n)}function la(e){if(!e.generated404RequestPath)return null;try{let t=new URL(e.generated404RequestPath,e.sourceOrigin);return !t.pathname.endsWith("/")&&v.extname(t.pathname)===""&&(t.pathname+="/"),t.hash="",t.toString()}catch{return null}}function Xt(e,t){let r=la(e);if(!r)return false;try{return new URL(t,e.sourceOrigin).toString()===r}catch{return false}}function er(e,t){let r=new URL(t),n=mt(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,a=ft(e.outputDir,o),c=Ar(e.targetOrigin,o),i=`${c}${r.search}`;if(!s)return {originalPathname:o,originalFilePath:a,originalPublicUrl:c,originalPublicUrlWithSearch:i,preferQueryHashed:s};let l=v.extname(n),u=`${l?n.slice(0,-l.length):n}.${De(r.search)}${l||".bin"}`;return {originalPathname:o,originalFilePath:a,originalPublicUrl:c,originalPublicUrlWithSearch:i,preferQueryHashed:s,hashedPathname:u,hashedFilePath:ft(e.outputDir,u),hashedPublicUrl:Ar(e.targetOrigin,u)}}function ua(e,t,r,n){let s=we(t,r,"asset",n);return s?er(e,s.toString()):null}function da(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 i of c)try{let l=new URL(i);t[l.origin+o.pathname+o.search]=n;}catch{}try{let i=(()=>{let l=new URL(n,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin);return `${l.pathname}${l.search}`})();t[o.pathname+o.search]=i;}catch{}try{let i=new URL(n,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[o.pathname]=i;}catch{}try{let i=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[o.pathname]=i;}catch{}}catch{}}async function Ts(e){try{return await D.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Le(e){try{return await D.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function pa(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 Es(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let r=Date.parse(t);return Number.isFinite(r)?r:null}function ga(e,t){let r=Es(t),n=pa(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 ma(e,t){if(!t)return;let r=Es(t);if(r===null)return;let n=await Le(e);if(!n)return;let s=new Date(r);await D.utimes(e,n.atime,s).catch(()=>{});}function ds(e,t){let r=v.extname(e.pathname).toLowerCase(),n=t["content-type"]||"";return Ti.has(r)||Ai.some(s=>n.includes(s))&&!n.startsWith("image/")&&!n.includes("font")}function fa(e){try{let t=v.extname(new URL(e).pathname).toLowerCase();return t===".js"||t===".mjs"}catch{return false}}function Ye(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 ha(e){return De(e.toString("base64"),40)}function wa(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 ya(e,t,r){let n=e.assetVariantDigestsByOriginalPath.get(t);n||(n=new Set,e.assetVariantDigestsByOriginalPath.set(t,n)),n.add(r);}async function Br(e,t,r,n,s,o,a){let c=er(e,r),i=ha(n),l=c.originalFilePath,d=c.originalPublicUrlWithSearch;if(c.preferQueryHashed&&c.hashedFilePath&&c.hashedPublicUrl&&wa(s,c.originalFilePath,i)){let p=Xi(e,t,r);p?(l=p.outputPath,d=p.publicUrl):(l=c.hashedFilePath,d=c.hashedPublicUrl);}da(e,t,r,d,c.originalPublicUrl);let u=$e(l)?Buffer.from(Or(n.toString("utf8"),e,t,l),"utf8"):n,g=await Ts(l),f=false;return (g===null||!g.equals(u))&&(await Fe(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}),ya(s,c.originalFilePath,i),await ma(l,a),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 We(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 tt(g)?{discoveredFrom:u,discoveredFromType:"sitemap"}:_(e,g)?{discoveredFrom:u,discoveredFromType:"asset"}:Ie(g)&&!qe(g)?{discoveredFrom:u,discoveredFromType:"page"}:{discoveredFrom:u,discoveredFromType:"url"}}catch{return {discoveredFrom:u,discoveredFromType:"url"}}return {discoveredFrom:u,discoveredFromType:"url"}},a=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,c=Z(e,r,a,n,"page");if(!c)return;if(!Ie(c)||As(c)){if(_(e,c)){n.info(`Seeded/non-page URL queued as asset: ${c.toString()}`,{url:c.toString(),source:s}),Q(e,t,c.toString(),n,s);return}n.reject("page",c.toString(),qe(c)?"asset/internal path cannot be page":"not page-like",s);return}let i=c.toString(),{discoveredFrom:l,discoveredFromType:d}=o();l&&!t.pageDiscoverySources.has(i)&&t.pageDiscoverySources.set(i,l),!t.donePages.has(i)&&!t.queuedPages.has(i)&&(t.queuedPages.add(i),t.pageQueue.push(i),t.stats.pagesQueued++,n.debug(`Queued discovered page ${i}`,{phase:"discovery",url:i,discoveredFrom:l,discoveredFromType:d,outputPath:he(e,i)}),(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 Q(e,t,r,n,s){let o=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,a=Z(e,r,o,n,"asset");if(!a)return;if(!_(e,a)){n.reject("asset",a.toString(),"not a safe asset path/prefix",s);return}let c=a.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 Yt(e,t,r,n,s){let o=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,a=Z(e,r,o,n,"sitemap",Pn(s));if(!a)return;if(!tt(a)){n.reject("sitemap",a.toString(),"not sitemap-like",s);return}let c=a.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 Sa(e){let t=Re(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:Ue(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 ba(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function Pa(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 Ra(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function va(e,t){if(t==="dom-style")return true;let r=(()=>{try{return v.extname(new URL(e).pathname).toLowerCase()}catch{return ""}})();return !(r===".js"||r===".mjs"||r===".map"||t.includes("javascript"))}function Gt(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function $s(e,t,r,n){let s=[];await D.mkdir(t,{recursive:true});let o=await D.readdir(e,{withFileTypes:true});for(let a of o){let c=v.join(e,a.name),i=v.join(t,a.name);if(a.isDirectory()){s.push(...await $s(c,i,r,n));continue}await Os(c,i,r,n)&&s.push(i);}return s}async function Ca(e,t){try{let[r,n]=await Promise.all([D.stat(e),D.stat(t)]);if(r.size!==n.size)return !1;let[s,o]=await Promise.all([D.readFile(e),D.readFile(t)]);return s.equals(o)}catch{return false}}async function Os(e,t,r,n){let s=v.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 Ca(e,t)?(n.debug("Skipped unchanged post-crawl copy target",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):(await D.mkdir(v.dirname(t),{recursive:true}),await D.copyFile(e,t),true)}async function ka(e,t,r){let n=Object.entries(e.postCrawlCopyMap||{}).map(([c,i])=>({sourcePath:c.trim(),prefix:String(i||"").trim()}));if(n.length===0)return [];let s=0,o=[],a=new Set([...t.donePages].map(c=>v.resolve(he(e,c))));r.mark("copy-extra-paths");for(let c of n){let i=c.sourcePath,l=c.prefix;if(!i||!l){r.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:i,prefixPath:l});continue}let d=Fi(i);if(!d.resolvedPath){r.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:i,alias:d.alias||"",requiredEnv:d.requiredEnv||"",prefixPath:l});continue}let u=d.resolvedPath,g=Gt(l);if(!g){r.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:i,prefixPath:l});continue}let f;try{f=await D.stat(u);}catch{r.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:i,sourceAbs:u,prefixPath:l});continue}let p=v.resolve(e.outputDir,g);if(f.isDirectory()){let w=await $s(u,p,a,r);o.push(...w),s+=w.length,w.length>0&&r.progress(`Copied static directory to export: ${u} -> /${g}`,{phase:"copy-extra-paths",sourcePath:u,targetPath:`/${g}`,copiedItems:s,changedFiles:w.length});continue}let y=v.basename(u),m=l.endsWith("/")?v.join(p,y):p;await Os(u,m,a,r)&&(o.push(m),s++,r.progress(`Copied static file to export: ${u} -> /${Gt(l.endsWith("/")?`${l}${y}`:l)}`,{phase:"copy-extra-paths",sourcePath:u,targetPath:`/${Gt(l.endsWith("/")?`${l}${y}`:l)}`,copiedItems:s}));}return r.endMark("copy-extra-paths",{mappedSources:n.length,copiedItems:s}),o}function et(e,t,r,n,s){let o=new Set,a=Re(r).replace(/\\\//g,"/"),c=s==="page-html"?Ra(a):a,i=va(t,s);if(i){for(let l of Pa(c)){let d=Z(e,l,t,n,`${s}:css-url`);d&&_(e,d)&&o.add(d.toString());}for(let l of c.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let d=Z(e,l[1],t,n,`${s}:css-import`);d&&_(e,d)&&o.add(d.toString());}}if(i||s==="page-html")for(let l of c.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let d=Z(e,l[1],t,n,`${s}:xml-stylesheet`);d&&_(e,d)&&o.add(d.toString());}if(s==="page-html")for(let l of Hn(a)){let d=l.startsWith("//")?`${new URL(e.sourceOrigin).protocol}${l}`:l;if(_r(d)){n.ignore(`${s}:serialized-url`,d,"looks like JavaScript/code fragment",t);continue}let u=Z(e,d,t,n,`${s}:serialized-url`);u&&_(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"&&fa(t))for(let l of zn(a)){if(_r(l)||!/\.(?:js|mjs)(?:[?#]|$)/i.test(l))continue;let d=Z(e,l,t,n,`${s}:relative-asset`);d&&_(e,d)&&o.add(d.toString());}return [...o]}function Ms(e,t,r,n){let s=new Set,o=Re(r);for(let a of o.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let c=a[1],i=Z(e,c,t,n,"page-link");i&&(xs(e,i)||Ie(i)&&!qe(i)&&!_(e,i)&&s.add(i.toString()));}return [...s]}async function ps(e,t,r,n,s,o,a=false,c=[]){let i=new Set(c),l=0,d=new Map,u=(g,f)=>{let p=[f],y=new Set;for(;p.length>0;){let m=p.pop();if(m===g)return true;y.has(m)||(y.add(m),p.push(...d.get(m)??[]));}return false};for(;r.sitemapQueue.length>0;){let g=r.sitemapQueue.shift();r.queuedSitemaps.delete(g);let f=we(g,n,"sitemap","sitemap-queue");if(!f)continue;let p=f.toString();if(r.doneSitemaps.has(p))continue;r.doneSitemaps.add(p),n.sitemap(`Fetching sitemap ${p}`,{url:p});let y=true;try{let m=await t.get(p,{timeout:6e4});if(y=!1,!m.ok()){if(n.skip("sitemap",p,m.status()),a&&!i.has(p))throw new Error(`Required child content-sync sitemap returned HTTP ${m.status()}: ${p}`);continue}let h=await m.body(),w=m.url()||p,k=we(w,n,"sitemap-response",p);if(!k)continue;let I=k.toString();r.successfulSitemaps.add(p),r.successfulSitemaps.add(I),i.has(p)&&(r.resolvedSitemapRoots.add(I),l+=1);let E=await Br(e,r.assetMap,I,h,r,n);ne(s,e,E.outputPath),ke(s,E.outputPath);let $=h.toString("utf8");/<sitemapindex(?:\s|>)/i.test($)?r.sitemapIndexUrls.add(I):r.sitemapLeafUrls.add(I);let C=et(e,I,$,n,"sitemap");for(let b of C)Q(e,r,b,n,I);let S=[];for(let b of Sa($)){let T=Z(e,b.loc,I,n,"sitemap-loc",!0);if(!T){if(a)throw new Error(`Content-sync sitemap contains an inadmissible location: ${b.loc}`);continue}if(tt(T)){if(u(I,T.toString()))throw new Error(`Sitemap index cycle detected: ${I} -> ${T.toString()}`);if(d.has(I)||d.set(I,new Set),d.get(I).add(T.toString()),S.push(T.toString()),a&&r.doneSitemaps.has(T.toString())&&!r.successfulSitemaps.has(T.toString()))throw new Error(`Required child content-sync sitemap was not resolved: ${T.toString()}`);Yt(e,r,T.toString(),n,I);}else if(a){if(Ie(T)&&!_(e,T)){let q=o.requiredUrls.has(T.toString()),A=o.manifest.pages[T.toString()],B=!!A&&!!await Le(A.outputPath);if(!q&&!B)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",I);}else _(e,T)?Q(e,r,T.toString(),n,I):Ie(T)?(b.lastmod&&(r.sitemapLastmodByPage[T.toString()]=b.lastmod),We(e,r,T.toString(),n,I)):n.reject("sitemap-loc",T.toString(),"not page/sitemap/asset-like",I);}o.trackManifest&&(o.manifest.assets[I]={url:I,outputPath:E.outputPath,isText:!0,contentType:m.headers()["content-type"]??"application/xml",cacheControl:qr(m.headers()),changeToken:null,tokenSource:null,discoveredAssets:[...new Set([...C,...S])],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0,rewriteComplete:!1},await xe(e,o));}catch(m){n.error(`Failed sitemap ${p}`,{url:p,error:String(m)});let h=a&&i.has(p)&&y;if(a&&!h)throw m}}if(a&&i.size>0&&l===0)throw new Error(`None of the configured content-sync sitemap roots could be resolved: ${[...i].join(", ")}`)}async function xa(e,t,r,n,s,o,a){let c=Z(e,n,e.sourceOrigin,s,"asset-fetch");if(!c||!_(e,c))return;let i=c.toString();if(r.doneAssets.has(i))return;let l=o.enabled||o.strictTargeted?o.previousManifest.assets[i]:void 0,d=o.trackManifest?await Jt(e,t,o,i,s):null,u=d?.token??null,g=Gn(l?.changeToken,d),f=o.strictTargeted&&(!d?.supported||!d.token)&&Zn(e.sourceOrigin,i),p=o.strictTargeted?o.manifest.assets[i]:void 0;if(p?.lastSeenRunId===o.runId&&await Le(p.outputPath)){r.doneAssets.add(i);for(let m of p.discoveredAssets||[])Q(e,r,m,s,i);ne(a,e,p.outputPath),zt(a,e,p.outputPath,p.cacheControl),p.isText&&ke(a,p.outputPath),s.info(`Resumed completed content-sync asset ${i}`,{url:i,source:"content-sync-checkpoint"}),Ye(r,s);return}if(l&&(g||f)&&await Le(l.outputPath)){o.manifest.assets[i]={...l,changeToken:u,tokenSource:d?.tokenSource??l.tokenSource,discoveredAssets:[...l.discoveredAssets||[]],lastSeenRunId:o.runId,unreferencedRuns:0},delete o.manifest.pages[i],r.doneAssets.add(i);for(let m of l.discoveredAssets||[])Q(e,r,m,s,i);zt(a,e,l.outputPath,l.cacheControl),s.info(`Reused unchanged trusted asset ${i}.`,{url:i,tokenSource:d?.tokenSource??"unknown",phase:"download-assets",source:g?"asset-change-token-match":"content-sync-release-fingerprint"}),Ye(r,s);return}let y=(m,h={})=>{if(!l||o.strictTargeted)return false;o.manifest.assets[i]={...l,discoveredAssets:[...l.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0},delete o.manifest.pages[i],r.doneAssets.add(i);for(let w of l.discoveredAssets||[])Q(e,r,w,s,i);return s.warn(`Keeping previous incremental asset ${i} after fetch issue.`,{url:i,reason:m,preservedFromPreviousManifest:true,...h,phase:"download-assets"}),Ye(r,s),true};s.asset(`Fetching asset ${i}`,{url:i});try{let m=Xe(e,r.assetMap,i),h=m?await Le(m):null;if(m&&h&&!o.strictTargeted)try{let A=await G(`fetch asset headers ${i}`,6e4,()=>t.head(i,{timeout:6e4})),B=A.headers();if(A.ok()&&ga(h,B)){let X=await Ts(m);if(X!==null){let N=A.url()||i,x=we(N,s,"asset-response",i);if(!x)return;let U=x.toString(),j=await Br(e,r.assetMap,U,X,r,s,B);j.wroteFile&&(ne(a,e,j.outputPath),$e(j.outputPath)&&ke(a,j.outputPath));let P=qr(B)||l?.cacheControl||null;zt(a,e,j.outputPath,P),r.doneAssets.add(i),s.info(`Reused existing asset ${i} based on response headers.`,{url:i,filePath:m,lastModified:B["last-modified"]||"",contentLength:B["content-length"]||"",phase:"download-assets"}),Ye(r,s);let M=ds(c,B),F=l?.discoveredAssets?[...l.discoveredAssets]:[];if(M||l?.isText){let W=X.toString("utf8"),H=et(e,U,W,s,"asset:cached");(H.length>0||!l)&&(F=H);for(let Se of F)Q(e,r,Se,s,U);}if(o.trackManifest){let W=M||!!l?.isText;o.manifest.assets[i]={url:i,outputPath:j.outputPath,isText:W,contentType:Lr(B)||l?.contentType||null,cacheControl:P,changeToken:d?.supported?d.token:null,tokenSource:d?.supported?d.tokenSource??null:null,discoveredAssets:F,lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0,rewriteComplete:!W},delete o.manifest.pages[i],(o.enabled||o.strictTargeted)&&W&&await xe(e,o);}return}}}catch{}let w=await G(`fetch asset ${i}`,6e4,()=>t.get(i,{timeout:6e4}));if(!w.ok()){if(y(`http-${w.status()}`,{status:w.status()}))return;if(o.strictTargeted)throw new Error(`Required content-sync asset returned HTTP ${w.status()}: ${i}`);s.skip("asset",i,w.status());return}let k=await G(`read asset response ${i}`,6e4,()=>w.body()),I=w.url()||i,E=we(I,s,"asset-response",i);if(!E)return;let $=E.toString(),C=w.headers(),S=await Br(e,r.assetMap,$,k,r,s,C);S.wroteFile&&(ne(a,e,S.outputPath),$e(S.outputPath)&&ke(a,S.outputPath));let b=qr(C);zt(a,e,S.outputPath,b),r.doneAssets.add(i),Ye(r,s);let T=ds(c,C),q=[];if(T){let A=k.toString("utf8");q=et(e,$,A,s,`asset:${v.extname(c.pathname).toLowerCase()||C["content-type"]||"unknown"}`);for(let B of q)Q(e,r,B,s,$);}o.trackManifest&&(o.manifest.assets[i]={url:i,outputPath:S.outputPath,isText:T,contentType:Lr(C),cacheControl:b,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[i],(o.enabled||o.strictTargeted)&&T&&await xe(e,o));}catch(m){if(y("fetch-error",{error:String(m)}))return;if(s.error(`Failed asset ${i}`,{url:i,error:String(m)}),o.strictTargeted)throw m}finally{r.doneAssets.has(i)||(r.doneAssets.add(i),Ye(r,s));}}async function Ia(e,t,r,n,s,o){let a=Math.max(1,Number(e.assetDownloadConcurrency||e.concurrency||1)),c=Array.from({length:a},async()=>{for(;r.assetQueue.length>0;){let i=r.assetQueue.shift();i&&(r.queuedAssets.delete(i),await xa(e,t,r,i,n,s,o));}});await Promise.all(c);}function Aa(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function Ce(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function wt(e){return Math.max(15e3,Math.min(6e4,Ce(e)))}function Ds(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function zr(e){return e.stats.pagesCompleted}function Vr(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 Ur(e,t,r){let n=Vr(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 G(e,t,r){let n;try{return await Promise.race([r(),new Promise((s,o)=>{n=globalThis.setTimeout(()=>{o(new St(e,t));},t);})])}finally{n!==void 0&&globalThis.clearTimeout(n);}}var St=class extends Error{constructor(r,n){super(`${r} timed out after ${Aa(n)}.`);this.operation=r;this.timeoutMs=n;this.name="OperationTimeoutError";}operation;timeoutMs};async function Ta(e,t){let r=Ds(e);await t.evaluate(async n=>{await new Promise(s=>{let o=0,a=700,c=Date.now(),i=()=>{window.clearInterval(l),window.scrollTo(0,0),s();},l=window.setInterval(()=>{if(Date.now()-c>=n.maxDurationMs){i();return}window.scrollBy(0,a),o+=a;let d=document.body?.scrollHeight||0,u=document.documentElement?.scrollHeight||0,g=Math.max(d,u);o>=g+window.innerHeight&&i();},120);});},{maxDurationMs:r});}async function Ea(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 Ta(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function $a(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 Fs(e,t){return e.noJavaScriptRenderPathPrefixes.some(r=>Hr(t,r))}async function Oa(e,t,r,n,s=true){let o=new Set;if(s){let c=await t.evaluate(()=>{let i=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(p=>{for(let m of l){let h=p.getAttribute(m);h&&i.add(h);}for(let m of u){let h=p.getAttribute(m);h&&h.split(",").forEach(w=>{let k=w.trim().split(/\s+/)[0];k&&i.add(k);});}let y=p.getAttribute("style");y&&d.add(y),p.shadowRoot&&g(p.shadowRoot);});};return g(document),{attrs:[...i],styles:[...d]}});for(let i of c.attrs)for(let l of ba(i)){let d=Z(e,l,r,n,"dom-attr");d&&_(e,d)&&o.add(d.toString());}for(let i of c.styles)for(let l of et(e,r,i,n,"dom-style"))o.add(l);}let a=await t.content();for(let c of et(e,r,a,n,"page-html"))o.add(c);return [...o]}async function Kr(e,t,r,n,s){let o=he(e,t);await Fe(o,r,"utf8");let a=await D.stat(o);s?.debug(`Saved page output ${t}`,{phase:"save-pages",url:t,outputPath:o,bytes:a.size}),n.stats.pagesSaved++;let c=Math.min(n.stats.pagesQueued,zr(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 js(e){let t=zr(e);return t%5===0||t===1||t===e.stats.pagesQueued}function Us(e,t){let r=zr(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 Ma(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 Da(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 Ma(n),n}async function Fa(e,t,r,n,s,o,a,c,i){for(;t.pageQueue.length>0&&!(e.maxPages>0&&t.donePages.size>=e.maxPages);){let l=t.pageQueue.shift();if(!l)break;t.queuedPages.delete(l);try{let d=we(l,r,"page","page-queue");if(!d)continue;let u=d.toString();if(l=u,t.queuedPages.delete(l),t.donePages.has(l))continue;t.donePages.add(l),o.enabled&&o.seenPages.add(l);let g=Xt(e,l),f=Fs(e,d.pathname);if(!Ie(d)||_(e,d)||qe(d)){if(_(e,d)){r.info(`Remote worker redirected non-page URL to asset queue: ${l}`,{url:l,source:"remote-worker-guard"}),Q(e,t,l,r,"remote-worker-guard");continue}r.reject("page",l,"guard rejected non-page URL before remote rendering","remote-worker");continue}let p=o.strictTargeted?o.manifest.pages[l]:void 0;if(p?.lastSeenRunId===o.runId&&await Le(p.outputPath)){o.seenPages.add(l);for(let C of p.discoveredAssets||[])Q(e,t,C,r,l);ne(a,e,p.outputPath),ke(a,p.outputPath),r.info(`Resumed completed content-sync page ${l}`,{url:l,source:"content-sync-checkpoint"});continue}let y=await Cs(e,s,t,o,l,r);if(o.enabled&&n!=="single-url"&&n!=="content-sync"){let C=o.manifest.pages[l];if(y.action==="reuse"&&C){for(let S of C.discoveredAssets)Q(e,t,S,r,l);for(let S of C.discoveredPages)We(e,t,S,r,l);C.lastSeenRunId=o.runId,C.sitemapLastmod=Ue(t.sitemapLastmodByPage[l])??C.sitemapLastmod,y.changeToken?.supported&&(C.changeToken=y.changeToken.token,C.tokenSource=y.changeToken.tokenSource??C.tokenSource),r.info(`Incremental reuse skipped unchanged page ${l}`,{url:l,mode:"incremental",reason:y.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}r.page(`Rendering remotely ${l}`,{url:l,execution:"lambda"});let m=await i.render({sourceOrigin:e.sourceOrigin,url:l,options:{ignoreHttpsErrors:e.ignoreHttpsErrors,javaScriptEnabled:!f,viewport:e.viewport,navigationTimeoutMs:e.navigationTimeoutMs,autoScrollTimeoutMs:Ds(e),readiness:e.readiness}}),h=m.page,w=h.finalUrl?we(h.finalUrl,r,"remote-final-response",l)?.toString():void 0;if(n==="content-sync"&&w&&w!==u){if(o.deleteOnMissingUrls.has(l)){await bt(e,o,a,l,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive route redirected to ${w}`,{url:l,finalResponseUrl:w,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${l} -> ${w}`)}let k=h.httpStatus;if(g){if(k!==404){r.error(`Generated 404 request path returned unexpected status for ${l}`,{url:l,expectedStatus:404,status:k,requestPath:e.generated404RequestPath,execution:"lambda"});continue}}else if(k!==null&&k>=400){if(n==="content-sync"&&(k===404||k===410)&&o.deleteOnMissingUrls.has(l)){await bt(e,o,a,l,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive page ${l}`,{url:l,status:k,source:"content-sync-tombstone"});continue}if(n==="content-sync")throw new Error(`Required content-sync route returned HTTP ${k}: ${l}`);r.skip("page",l,k,t.pageDiscoverySources.get(l));continue}t.stats.pagesRendered++;let I=new Set(et(e,u,m.html,r,"remote-page-html"));for(let C of [...h.discoveredAssets,...h.networkUrls]){let S=Z(e,C,u,r,"remote-render");S&&_(e,S)&&I.add(S.toString());}for(let C of I)Q(e,t,C,r,l);let E=n!=="single-url"&&n!=="content-sync"&&!g?[...new Set([...Ms(e,l,m.html,r),...h.discoveredPages])]:[];for(let C of E)We(e,t,C,r,l);for(let C of h.cookies){let S=C.sameSite==="Strict"||C.sameSite==="Lax"||C.sameSite==="None"?C.sameSite:"Unspecified",b=!Number.isFinite(C.expires)||C.expires<=0;c.add({name:C.name,domain:C.domain,path:C.path||"/",expires:b?null:C.expires,session:b,secure:C.secure,httpOnly:C.httpOnly,sameSite:S,partitioned:C.partitioned===!0});}await Kr(e,l,m.html,t,r);let $=he(e,l);ne(a,e,$),ke(a,$),o.trackManifest&&(o.manifest.pages[l]={url:l,outputPath:$,contentType:h.contentType?.trim()||null,changeToken:y.changeToken?.supported?y.changeToken.token:null,tokenSource:y.changeToken?.supported?y.changeToken.tokenSource??null:null,sitemapLastmod:Ue(t.sitemapLastmodByPage[l])??null,discoveredPages:E,discoveredAssets:[...I],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,rewriteComplete:!1},(o.enabled||o.strictTargeted)&&await xe(e,o)),r.debug(`Remote render completed ${l}`,{url:l,taskId:m.taskId,attempts:m.attempts,execution:"lambda"});}catch(d){if(r.error(`Failed remote page ${l}`,{url:l,error:String(d),execution:"lambda"}),o.strictTargeted)throw d}finally{t.stats.pagesCompleted++,js(t)&&Us(t,r);}}}async function ja(e,t,r,n,s,o,a,c){let i=await chromium.launch({headless:true}),l=Vr(i);l.pid!==null&&r.debug(`Launched crawl worker browser PID ${l.pid}`,{browserPid:l.pid});try{for(;t.pageQueue.length>0;){i||(i=await chromium.launch({headless:!0}),l=Vr(i),l.pid!==null&&r.debug(`Relaunched crawl worker browser PID ${l.pid}`,{browserPid:l.pid}));let d=i;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,p=!1,y=[],m=new Set;try{let h=we(u,r,"page","page-queue");if(!h)continue;let w=h.toString();if(u=w,t.queuedPages.delete(u),t.donePages.has(u))continue;t.donePages.add(u),o.enabled&&o.seenPages.add(u);let k=Xt(e,u),I=Fs(e,h.pathname);if(!Ie(h)||_(e,h)||qe(h)){if(_(e,h)){r.info(`Worker redirected non-page URL to asset queue: ${u}`,{url:u,source:"worker-guard"}),Q(e,t,u,r,"worker-guard");continue}r.reject("page",u,"guard rejected non-page URL before rendering","worker");continue}let E=o.strictTargeted?o.manifest.pages[u]:void 0;if(E?.lastSeenRunId===o.runId&&await Le(E.outputPath)){o.seenPages.add(u);for(let x of E.discoveredAssets||[])Q(e,t,x,r,u);ne(a,e,E.outputPath),ke(a,E.outputPath),r.info(`Resumed completed content-sync page ${u}`,{url:u,source:"content-sync-checkpoint"});continue}let $=await Cs(e,s,t,o,u,r);if(o.enabled&&n!=="single-url"&&n!=="content-sync"){let x=o.manifest.pages[u];if($.action==="reuse"&&x){for(let U of x.discoveredAssets)Q(e,t,U,r,u);for(let U of x.discoveredPages)We(e,t,U,r,u);x.lastSeenRunId=o.runId,x.sitemapLastmod=Ue(t.sitemapLastmodByPage[u])??x.sitemapLastmod,$.changeToken?.supported&&(x.changeToken=$.changeToken.token,x.tokenSource=$.changeToken.tokenSource??x.tokenSource),r.info(`Incremental reuse skipped unchanged page ${u}`,{url:u,mode:"incremental",reason:$.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}g=await G(`create page context ${u}`,Ce(e),()=>Da(d,e,I)),f=await G(`create page ${u}`,Ce(e),()=>g.newPage()),y=await g.cookies();let C=!1,S=new Set;await f.route("**/*",async x=>{let U=x.request();try{let j=Z(e,U.url(),e.sourceOrigin,r,"network-request");j&&_(e,j)&&(S.add(j.toString()),Q(e,t,j.toString(),r,u));}catch{}if(U.isNavigationRequest()&&U.frame()===f.mainFrame())try{let j=new URL(U.url()),P=new URL(w);if(j.hash="",P.hash="",j.href===P.href){if(C){r.warn(`Blocked same-page navigation/reload for ${u}`,{url:u,requestUrl:U.url()});try{await x.abort("aborted");}catch(M){r.debug(`Ignored canceled route while blocking reload for ${u}`,{url:u,error:String(M)});}return}C=!0;}}catch{}try{await x.continue();}catch(j){r.debug(`Ignored canceled network route for ${u}`,{url:u,requestUrl:U.url(),error:String(j)});}}),f.on("response",x=>{try{let j=Z(e,x.url(),e.sourceOrigin,r,"network-response");j&&_(e,j)&&(S.add(j.toString()),Q(e,t,j.toString(),r,u));}catch{}let U=x.headerValues("set-cookie").then(j=>{for(let P of j)c.add(es(P,x.url()));}).catch(()=>{}).then(()=>{});m.add(U),U.finally(()=>m.delete(U));}),r.page(`Rendering ${u}`,{url:u});let b=null,T=null;try{if(b=await f.goto(u,{waitUntil:"domcontentloaded",timeout:e.navigationTimeoutMs}),b&&b.ok())try{T=await G(`read response body ${u}`,Ce(e),()=>b.text());}catch{T=null;}}catch(x){r.warn(`Navigation issue for ${u}; saving current DOM if available`,{url:u,error:String(x)});}if(n==="content-sync"&&b){let x=we(b.url(),r,"content-sync-final-response",u)?.toString();if(x&&x!==w){if(o.deleteOnMissingUrls.has(u)){await bt(e,o,a,u,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive route redirected to ${x}`,{url:u,finalResponseUrl:x,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${u} -> ${x}`)}}if(k){let x=b?.status()??null;if(x!==404){r.error(`Generated 404 request path returned unexpected status for ${u}`,{url:u,expectedStatus:404,status:x,requestPath:e.generated404RequestPath});continue}r.info(`Capturing rendered 404 page for ${u}`,{url:u,status:x,outputPath:he(e,u)});}else if(b&&!b.ok()){if(n==="content-sync"&&(b.status()===404||b.status()===410)&&o.deleteOnMissingUrls.has(u)){await bt(e,o,a,u,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive page ${u}`,{url:u,status:b.status(),source:"content-sync-tombstone"}),await f.close();continue}if(n==="content-sync")throw new Error(`Required content-sync route returned HTTP ${b.status()}: ${u}`);r.skip("page",u,b.status(),t.pageDiscoverySources.get(u)),await f.close();continue}I?(r.info(`Rendering without JS execution for ${u}`,{url:u,mode:"no-js"}),await G(`wait for rendered page ${u}`,Ce(e),()=>$a(e,f))):await G(`wait for rendered page ${u}`,Ce(e),()=>Ea(e,f)),t.stats.pagesRendered++;let q=await G(`extract rendered assets ${u}`,Ce(e),()=>Oa(e,f,w,r,!I));for(let x of q)Q(e,t,x,r,u);let A=[...new Set([...q,...S])],B=T??await G(`capture rendered html ${u}`,Ce(e),()=>f.content()),X=n!=="single-url"&&n!=="content-sync"&&!k?Ms(e,u,B,r):[];if(n!=="single-url"&&n!=="content-sync"&&!k)for(let x of X)We(e,t,x,r,u);await Kr(e,u,B,t,r);let N=he(e,u);if(ne(a,e,N),ke(a,N),o.trackManifest){let x=b?.headers();o.manifest.pages[u]={url:u,outputPath:N,contentType:Lr(x),changeToken:$.changeToken?.supported?$.changeToken.token:null,tokenSource:$.changeToken?.supported?$.changeToken.tokenSource??null:null,sitemapLastmod:Ue(t.sitemapLastmodByPage[u])??null,discoveredPages:X,discoveredAssets:A,lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,rewriteComplete:!1},(o.enabled||o.strictTargeted)&&await xe(e,o);}}catch(h){if(p=h instanceof St,o.strictTargeted)throw r.error(`Failed required content-sync page ${u}`,{url:u,error:String(h)}),h;if(p)r.warn(`Skipped partial DOM for timed-out page ${u}`,{url:u,error:String(h),recovery:"recycle-worker-browser"});else try{let w=f?await G(`capture partial html ${u}`,Ce(e),()=>f.content()):"";if(w&&w.trim()){await Kr(e,u,w,t,r);let k=he(e,u);if(ne(a,e,k),ke(a,k),o.trackManifest){let I=o.manifest.pages[u]??o.previousManifest.pages[u];o.manifest.pages[u]={url:u,outputPath:k,contentType:I?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:Ue(t.sitemapLastmodByPage[u])??I?.sitemapLastmod??null,discoveredPages:I?.discoveredPages?[...I.discoveredPages]:[],discoveredAssets:I?.discoveredAssets?[...I.discoveredAssets]:[],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,rewriteComplete:!1},(o.enabled||o.strictTargeted)&&await xe(e,o);}r.warn(`Saved partial DOM for ${u}`,{url:u,error:String(h)});}}catch(w){w instanceof St&&(p=!0),r.error(`Could not save partial DOM for ${u}`,{url:u,error:String(w)});}r.error(`Failed page ${u}`,{url:u,error:String(h)});}finally{if(!p&&f&&await G(`drain network routes ${u}`,wt(e),()=>f.unrouteAll({behavior:"wait"})).catch(h=>{p=!0,r.warn(`Could not drain network routes for ${u}`,{url:u,browserPid:l.pid,error:String(h),recovery:"recycle-worker-browser"});}),p&&(i=null,await Ur(d,r,`page operation timeout for ${u}`),await d.close().catch(()=>{})),m.size>0&&await Promise.allSettled([...m]),!p&&g)try{let h=await g.cookies();c.addAll(ts(y,h));}catch{}t.stats.pagesCompleted++,js(t)&&Us(t,r),!p&&f&&await G(`close page ${u}`,wt(e),()=>f.close()).catch(h=>{p=!0,r.warn(`Timed out while closing page ${u}`,{url:u,browserPid:l.pid,error:String(h),recovery:"recycle-worker-browser"});}),!p&&g&&await G(`close page context ${u}`,wt(e),()=>g.close()).catch(h=>{p=!0,r.warn(`Timed out while closing page context for ${u}`,{url:u,browserPid:l.pid,error:String(h),recovery:"recycle-worker-browser"});}),p&&i===d&&(i=null,await Ur(d,r,`page cleanup timeout for ${u}`),await d.close().catch(()=>{}));}}}finally{if(i){let d=i;await G("close worker browser",wt(e),()=>d.close()).catch(u=>(r.warn("Timed out while closing crawl worker browser",{browserPid:l.pid,error:String(u)}),Ur(d,r,"browser.close timeout")));}}}async function Ua(e){try{let t=await D.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 gs(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function La(e){let t=String(e?.job?.command||"").trim(),r=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:r!=="incremental"}function qa(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 Ls(e){try{let t=await D.readFile(e,"utf8"),r=JSON.parse(t);return r&&typeof r=="object"&&!Array.isArray(r)?r:null}catch{return null}}function ms(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function Wa(e,t){let r=Array.isArray(t?.artifacts)?t.artifacts.filter(n=>String(n?.role||"").trim()==="errors"&&String(n?.storedFileName||"").trim()!=="").sort((n,s)=>ms(n)-ms(s)).map(n=>v.join(e,String(n.storedFileName))):[];return [...new Set([...r,v.join(e,"errors.jsonl"),v.join(e,"errors.json"),v.join(e,"errors.jsonl.gz"),v.join(e,"errors.json.gz")])]}async function fs(e){let t=await Ls(v.join(e,"job.json"));for(let r of Wa(e,t)){let n=await Ua(r);if(n.length>0)return n}return []}async function Na(e){let t=v.join(e.logDir,"archive"),r;try{r=await D.readdir(t);}catch{return ""}let n="",s=0;for(let o of r){let a=v.join(t,o);if(!(await D.stat(a).catch(()=>null))?.isDirectory())continue;let i=await Ls(v.join(a,"job.json"));if(!La(i))continue;let l=qa(i);l>=s&&(s=l,n=a);}return n}async function _a(e){let t=await Na(e),r=t!==""?await fs(t):await fs(e.logDir),n=new Set;for(let s of r)if(gs(s.error)||gs(s.message)){let o=s.url;typeof o=="string"&&o&&n.add(o);}return [...n]}async function Ba(e){let t=[];for(let r of e)if(r.startsWith("@")){let n=r.slice(1),s=await D.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 Va(e){if(!e)throw new Error("Content-sync crawl requires an immutable impact plan.");let t=JSON.parse(await D.readFile(e,"utf8"));return lt(t),t}function Ka(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(/\/+$/,""),a=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(a)})}function ht(e,t,r){let n=r==="page"?he(e,t):er(e,t).originalFilePath;return ge(e.outputDir,n)}async function bt(e,t,r,n,s){let o=t.manifest.pages[n];if(!o)return;let a=ge(e.outputDir,o.outputPath);if(!a)throw new Error(`Manifest-owned page path escaped output root: ${n}`);let c=v.resolve(o.outputPath);Object.entries(t.manifest.pages).some(([l,d])=>l!==n&&!s.has(l)&&v.resolve(d.outputPath)===c)||(await D.rm(o.outputPath,{force:true}),r.deletedFiles.add(a),r.revalidateFiles.delete(a)),delete t.manifest.pages[n];}async function Ha(e,t,r,n,s){let o=t.manifest.assets[n];if(!o)return;let a=ge(e.outputDir,o.outputPath);if(!a)throw new Error(`Manifest-owned resource path escaped output root: ${n}`);let c=v.resolve(o.outputPath);Object.entries(t.manifest.assets).some(([l,d])=>l!==n&&!s.has(l)&&v.resolve(d.outputPath)===c)||(await D.rm(o.outputPath,{force:true}),r.deletedFiles.add(a)),delete t.manifest.assets[n];}function za(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 a of o?.discoveredAssets??[])try{tt(new URL(a))&&n.push(a);}catch{}}return r}async function Qa(e,t,r,n,s){let o=za(r.previousManifest,s);for(let a of o){if(t.successfulSitemaps.has(a))continue;let c=r.previousManifest.assets[a];if(!c)continue;let i=ge(e.outputDir,c.outputPath);if(!i)throw new Error(`Manifest-owned sitemap path escaped output root: ${a}`);await D.rm(c.outputPath,{force:true}),n.deletedFiles.add(i),delete r.manifest.assets[a];}await xe(e,r);}async function Ja(e){try{let t=await D.readFile(v.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function Ga(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 D.mkdir(e,{recursive:true}),await Promise.all(t.map(async r=>{try{await D.unlink(v.join(e,r));}catch(n){if(n.code!=="ENOENT")throw n}}));}function hs(e,t,r,n,s){let o=Z(e,r,e.sourceOrigin,n,"manual-url");o&&(tt(o)?Yt(e,t,o.toString(),n,s):_(e,o)?Q(e,t,o.toString(),n,s):Ie(o)?We(e,t,o.toString(),n,s):n.reject("manual-url",o.toString(),"not page/sitemap/asset-like",s));}async function qs(e=process.argv.slice(2)){let t=[],r=await ue(void 0,{onRemotePublisherConfigDiagnostic:P=>{t.push(P);}}),n=dt(r.sitemapPaths),s=t.at(-1)??null,o=$i(e),a=o.mode==="content-sync"?await Va(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 _a(r)),o.mode==="single-url"&&(c=await Ba(o.urls)),a&&(c=[...a.directRenderUrls,...a.archiveFamilyUrls,...a.resourceRenderUrls]);let i=o.crawlMode==="incremental"&&o.mode==="full",l=i&&typeof r.subscriptionType=="string"&&r.subscriptionType.trim()!=="";if(a&&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 Ja(r):{},f=l||o.mode==="single-url"||o.mode==="content-sync"?await qi(r):bs(),p=new Set(c),y=new Set;if(a){for(let P of a.archiveFamilies)if(P.foundPosts===0)for(let M of P.pageUrls)y.add(M);for(let P of Object.keys(f.pages))Ka(P,a)&&!p.has(P)&&(c.push(P),y.add(P));}let m={enabled:l,trackManifest:d,manifest:Nr(f),previousManifest:Nr(f),runId:a?.jobId??`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,pageChangeTokenPrimePromise:null,manifestSaveChain:Promise.resolve(),strictTargeted:!!a,requiredUrls:p,deleteOnMissingUrls:y};await Ga(r.logDir);let h=new Ut(r.logDir,r.logLevel),w=o.remoteRender??r.remoteWorkers?.render?.enabled===true,k=Ht({explicitPath:o.remoteWorkerConfigPath,runtimeDir:Pt()}),I=null,E=null,$=Math.max(1,r.concurrency),C=r.remoteWorkers?.rewrite?.enabled===true;if(w&&!o.resumeRewrite||C){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 P=await Bt(k);E=new Ze(P);}if(w&&!o.resumeRewrite){if(!E)throw new Error("Remote render worker client was not initialized.");I=new Vt({client:E,jobId:`crawl-${De(m.runId,40)}`,maxAttempts:r.remoteWorkers?.render?.maxAttempts??2,onRetry:P=>{h.warn(`Retrying remote render for ${P.url}`,{url:P.url,attempt:P.attempt,maxAttempts:P.maxAttempts,reason:P.reason,execution:"lambda"});}}),$=Math.max(1,Math.min(100,r.remoteWorkers?.render?.concurrency??r.concurrency)),h.info("Lambda page rendering is enabled.",{remoteWorkerConfigPath:v.resolve(k),concurrency:$,maxAttempts:r.remoteWorkers?.render?.maxAttempts??2,batchSize:1,execution:"lambda"});}if(s){let P={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?h.info("Loaded remote WP Suite publisher configuration.",P):h.warn("Remote WP Suite publisher configuration is unavailable or has no active subscription type.",P);}if(i&&!l){let P="Incremental crawl requires an active remote publisher subscription; refusing to fall back to a destructive full crawl.";throw h.error(P,{requestedMode:o.crawlMode,subscriptionType:r.subscriptionType??null,source:"incremental-subscription-guard"}),await h.flush(),new Error(P)}let S={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}},b=Li(),T=new qt,q=Oi();if(q&&!o.resumeRewrite&&await Wt(q,T.artifact()),await Me(r),await En(r,{startedAt:new Date().toISOString(),outputDir:v.resolve(r.outputDir)}),u||await D.rm(r.outputDir,{recursive:true,force:true}),await D.mkdir(r.outputDir,{recursive:true}),a){let P=new Set([...a.deleteUrls,...m.deleteOnMissingUrls]);for(let F of a.deleteUrls)await bt(r,m,b,F,P);let M=new Set(a.resourceDeleteUrls);for(let F of a.resourceDeleteUrls)await Ha(r,m,b,F,M);}if(o.resumeRewrite)h.info("Resuming final rewrite from existing output.",{phase:"rewrite-text",mode:o.mode,crawlMode:o.crawlMode});else {let P=await request.newContext({ignoreHTTPSErrors:r.ignoreHttpsErrors});try{if(h.mark("discovery"),o.mode==="full"?(n.forEach(F=>Yt(r,S,F,h)),await ps(r,P,S,h,b,m),r.seedPaths.forEach(F=>hs(r,S,F,h,"seed-path")),r.generated404RequestPath&&We(r,S,r.generated404RequestPath,h,"generated-404-request-path")):(c.forEach(F=>hs(r,S,F,h,"cli")),a?.sitemapUrls.forEach(F=>Yt(r,S,F,h,"content-sync-impact")),await ps(r,P,S,h,b,m,o.mode==="content-sync",a?.sitemapUrls??[]),a&&await Qa(r,S,m,b,a.sitemapUrls)),h.endMark("discovery",{pages:S.pageQueue.length,assets:S.assetQueue.length,sitemaps:S.sitemapQueue.length}),h.summary(`Queued ${S.pageQueue.length} pages, ${S.assetQueue.length} assets, ${S.sitemapQueue.length} sitemaps.`,{mode:o.mode,crawlMode:o.crawlMode,queuedPages:S.pageQueue.length,queuedAssets:S.assetQueue.length,queuedSitemaps:S.sitemapQueue.length}),o.mode==="retry-timeouts"&&S.pageQueue.length===0&&S.assetQueue.length===0&&S.sitemapQueue.length===0){h.summary("No timed-out URLs were queued. Skipping retry crawl.",{mode:o.mode,crawlMode:o.crawlMode,queuedPages:0,queuedAssets:0,queuedSitemaps:0}),await h.flush(),q&&await Wt(q,T.artifact());return}h.mark("render-pages");let M=Array.from({length:$},()=>I?Fa(r,S,h,o.mode,P,m,b,T,I):ja(r,S,h,o.mode,P,m,b,T));if(await Promise.all(M),q&&await Wt(q,T.artifact()),h.endMark("render-pages",{pages:S.stats.pagesCompleted}),h.mark("download-assets"),h.progress("Asset download phase started.",{phase:"download-assets",doneAssets:S.doneAssets.size,assetsQueued:S.stats.assetsQueued,assetQueue:S.assetQueue.length}),await Rs(r,P,m,[...S.assetQueue],h),await Ia(r,P,S,h,m,b),h.endMark("download-assets",{assets:S.doneAssets.size}),m.enabled&&r.maxPages===0&&(await Hi(r,S,m,h,b),o.mode==="full"&&await zi(r,m,h,b)),o.mode==="full"){let F=await ka(r,S,h);for(let W of F)ne(b,r,W);}}finally{await G("dispose crawl request context",wt(r),()=>P.dispose()).catch(M=>{h.warn("Timed out while disposing crawl request context",{error:String(M)});});}}m.trackManifest&&await xe(r,m),await D.writeFile(v.join(r.outputDir,"asset-map.json"),JSON.stringify(S.assetMap,null,2),"utf8"),JSON.stringify(g,null,2)!==JSON.stringify(S.assetMap,null,2)&&ne(b,r,v.join(r.outputDir,"asset-map.json"));let A=o.mode==="single-url"||o.mode==="content-sync"?ra(r,S):m.enabled&&!o.resumeRewrite?Qi(r,m,b,g,S.assetMap):void 0;h.mark("rewrite-text");let B=o.mode==="single-url"||o.mode==="content-sync"?`Rewriting text files touched by URL crawl: 0/${A?.length??0}`:"Rewriting text files...";h.progress(B,{phase:"rewrite-text",index:0,totalFiles:A?.length,changedTextFiles:0}),await jr(B);let X=Date.now(),N={files:A,previousAssetMap:g,onStart:({totalFiles:P,workerCount:M})=>{h.info(`Rewrite phase scanning ${P} text files.`,{phase:"rewrite-text",totalFiles:P,workerCount:M});},onProgress:async({index:P,totalFiles:M,changedTextFiles:F,file:W,changed:H})=>{H&&ne(b,r,v.join(r.outputDir,W)),h.checkpoint(`Rewriting text file ${P}/${M}`,{phase:"rewrite-text",index:P,totalFiles:M,changedTextFiles:F,file:W}),h.debug(`${H?"Rewrote":"Checked unchanged"} text file ${P}/${M}: ${W}`,{phase:"rewrite-text",index:P,totalFiles:M,changedTextFiles:F,file:W,changed:H});let Se=Date.now();if(!(P===1||P===M||P%50===0||Se-X>=5e3))return;X=Se;let _e=`Rewriting text files: ${P}/${M}`;h.progress(_e,{phase:"rewrite-text",index:P,totalFiles:M,changedTextFiles:F,file:W}),await jr(_e);}},x=C&&E?await Kt(r,S.assetMap,{client:E,jobId:`crawl-${De(m.runId,40)}`,concurrency:r.remoteWorkers?.rewrite?.concurrency??r.rewriteConcurrency,batchSize:r.remoteWorkers?.rewrite?.batchSize??25,maxAttempts:r.remoteWorkers?.rewrite?.maxAttempts??2,onStageProgress:async({index:P,totalFiles:M,file:F})=>{let W=Date.now();if(P!==1&&P!==M&&P%25!==0&&W-X<5e3)return;X=W;let H=`Staging text files for Lambda rewrite: ${P}/${M}`;h.progress(H,{phase:"rewrite-stage",index:P,totalFiles:M,file:F,execution:"lambda"}),await jr(H);},options:N}):await Dt(r,S.assetMap,N);m.trackManifest&&(Ji(m,A),await xe(r,m)),h.endMark("rewrite-text",{changedTextFiles:x});let U=a?[...b.deletedFiles].sort():m.enabled&&!o.resumeRewrite?await Zi(r,S,m,b,h):[],j=[...new Set((A||[]).map(P=>ge(r.outputDir,v.isAbsolute(P)?P:v.join(r.outputDir,P))).filter(P=>P!==null))].sort();if(a){let P=[...b.changedFiles].sort(),M=new Set(P),F=new Set(a.directRenderUrls.map(R=>ht(r,R,"page")).filter(R=>!!R&&M.has(R))),W=new Set(a.archiveFamilyUrls.map(R=>ht(r,R,"page")).filter(R=>!!R&&M.has(R))),H=new Set(a.resourceRenderUrls.map(R=>ht(r,R,"asset")).filter(R=>!!R&&M.has(R))),Se=new Set([...S.sitemapLeafUrls].map(R=>ht(r,R,"asset")).filter(R=>!!R&&M.has(R))),st=new Set([...S.sitemapIndexUrls].map(R=>ht(r,R,"asset")).filter(R=>!!R&&M.has(R))),_e=new Set([...F,...W,...H,...Se,...st]),ur=P.filter(R=>!_e.has(R)),dr=[...new Set([...a.directRenderUrls,...a.archiveFamilyUrls,...S.resolvedSitemapRoots,...S.sitemapLeafUrls,...S.sitemapIndexUrls,...a.deleteUrls,...a.resourceRenderUrls,...a.resourceDeleteUrls].map(R=>{let V=new URL(R);return `${V.pathname}${V.search}`}))].sort();await Ir(r,{schemaVersion:2,generatedAt:new Date().toISOString(),outputDir:v.resolve(r.outputDir),runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,changedFiles:P,deletedFiles:U,rewriteTargets:j,revalidateFiles:[...b.revalidateFiles].sort(),consumerId:a.consumerId,fromSequence:a.fromSequence,toSequence:a.toSequence,impactHash:a.impactHash,resolvedSitemapUrls:[...S.resolvedSitemapRoots],uploadGroups:{assets:ur,content:[...F].sort(),listings:[...W].sort(),resources:[...H].sort(),sitemapLeaves:[...Se].sort(),sitemapIndexes:[...st].reverse()},invalidationPaths:dr});}else await Ir(r,{schemaVersion:1,generatedAt:new Date().toISOString(),outputDir:v.resolve(r.outputDir),runMode:o.mode,crawlMode:o.crawlMode,fullSyncRequired:!(m.enabled&&!o.resumeRewrite),changedFiles:m.enabled&&!o.resumeRewrite?[...b.changedFiles].sort():[],deletedFiles:m.enabled&&!o.resumeRewrite?U:[],rewriteTargets:m.enabled&&!o.resumeRewrite?j:[],revalidateFiles:[...b.revalidateFiles].sort()});await On(r),h.summary(o.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${x} text files.`:`Done. Rendered ${S.stats.pagesRendered} pages, processed ${S.doneSitemaps.size} sitemaps and ${S.doneAssets.size} assets.`,{mode:o.mode,crawlMode:o.crawlMode,resumeRewrite:o.resumeRewrite,...S.stats,pagesRendered:S.stats.pagesRendered,donePages:S.stats.pagesCompleted,claimedPages:S.donePages.size,doneSitemaps:S.doneSitemaps.size,doneAssets:S.doneAssets.size,changedTextFiles:x}),await h.flush();}function Za(e){let t=e/6e4;if(Number.isInteger(t)&&t>=1)return `${t} minute${t===1?"":"s"}`;let r=Math.ceil(e/1e3);return `${r} second${r===1?"":"s"}`}async function oe(e,t,r){let n=new AbortController,s=globalThis.setTimeout(()=>{n.abort(new Error(`${e} timed out after ${Za(t)}.`));},t);try{return await r({abortController:n,httpOptions:{abortSignal:n.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(s);}}function Ya(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function tr(e){let t="";for(let n=0;n<e.length;n++){let s=e[n];if(s==="--profile"){let o=(e[n+1]||"").trim();if(!o)throw new Error("Missing value for --profile.");t=o,n+=1;}else if(s.startsWith("--profile=")){let o=s.slice(10).trim();if(!o)throw new Error("Missing value for --profile.");t=o;}}let r=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return t||r||null}function Xa(e,t){return {...e,...t??{}}}function ec(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function rt(e,t){let r=String(t??e.deploymentTargetOverride??"").trim();if(!Ya(e)){if(r)throw new Error(`Deployment target "${r}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:e}}let n=String(r||e.defaultDeploymentProfile||"").trim();if(!n)return {name:null,profile:null,config:e};let s=e.deploymentProfiles?.[n];if(!s)throw new Error(`Unknown deployment profile "${n}". Check the linked WPSuite publisher configuration.`);return {name:n,profile:s,config:{...e,targetOrigin:s.targetOrigin??e.targetOrigin,s3:Xa(e.s3,s.s3),cloudFront:ec(e.cloudFront,s.cloudFront)}}}var Ks="wpsuite-sha256",Hs="wpsuite-normalized-sha256",zs="public, max-age=0, must-revalidate",cc=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,Gr=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,lc=["SIGINT","SIGTERM"],sr=new Set,rr=new Map,Ws=null;function uc(e){sr.add(e);let t=false;return ()=>{t||(t=true,sr.delete(e));}}async function dc(){let e=[...sr];e.length!==0&&await Promise.allSettled(e.map(async t=>{sr.delete(t),await D.rm(t,{recursive:true,force:true});}));}function pc(){if(!(rr.size>0))for(let e of lc){let t=()=>{Ws||(Ws=dc().finally(()=>{for(let[r,n]of rr)process.off(r,n);rr.clear(),process.exit(1);}));};rr.set(e,t),process.on(e,t);}}pc();function gc(e,t){let r=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(r)return v.resolve(r);let n=t.trim();return n?v.join(v.resolve(n),"crawl-manifest.json"):v.join(v.resolve(e),".crawl-manifest.json")}function Rt(e){return v.normalize(e).split(v.sep).join("/")}function Ns(e,t){let r=v.relative(v.resolve(e),v.resolve(t));return !r||r.startsWith("..")||v.isAbsolute(r)?null:Rt(r)}async function mc(e,t,r){let n=gc(e.outputDir,t),s;try{s=await D.readFile(n,"utf8");}catch(d){return d.code==="ENOENT"?(r.warn("Deploy rewrite guard disabled because the crawl manifest is missing.",{manifestPath:n,source:"deploy-guard"}),null):(r.warn("Deploy rewrite guard disabled because the crawl manifest could not be read.",{manifestPath:n,error:d instanceof Error?d.message:String(d),source:"deploy-guard"}),null)}let o;try{o=JSON.parse(s);}catch(d){return r.warn("Deploy rewrite guard disabled because the crawl manifest is invalid JSON.",{manifestPath:n,error:d instanceof Error?d.message:String(d),source:"deploy-guard"}),null}let a=new Map,c=new Map,i=0,l=0;for(let[d,u]of Object.entries(o.pages||{})){let g=String(u?.outputPath||"").trim(),f=g?Ns(e.outputDir,g):null;if(f){let p=typeof u?.contentType=="string"&&u.contentType?u.contentType:null;p&&c.set(f,p);}!g||u?.rewriteComplete===true||f&&(i++,a.has(f)||a.set(f,{kind:"page",sourceUrl:d,outputPath:v.resolve(g),relativePath:f}));}for(let[d,u]of Object.entries(o.assets||{})){let g=String(u?.outputPath||"").trim(),f=u?.isText===true,p=g?Ns(e.outputDir,g):null;if(p){let y=typeof u?.contentType=="string"&&u.contentType?u.contentType:null;y&&c.set(p,y);}!g||!f||u?.rewriteComplete===true||p&&(l++,a.has(p)||a.set(p,{kind:"asset",sourceUrl:d,outputPath:v.resolve(g),relativePath:p}));}return {manifestPath:n,byRelativePath:a,contentTypeByRelativePath:c,pendingPages:i,pendingTextAssets:l}}function fc(e){return e&&(Gr.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)?"__hex__":/^[0-9]{8,}$/.test(e)?"__num__":/^(?=.*[a-z])(?=.*\d)[a-z0-9]{8,}$/i.test(e)?"__alnum__":e)}function Qr(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,r)=>r%2===1?t:fc(t)).join("")}function hc(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,r)=>r%2===1?t:Gr.test(t)?"__uuid__":/^[0-9a-f]{6,}$/i.test(t)?"__hex__":/^[0-9]{6,}$/.test(t)?"__num__":/^[a-z0-9_-]{6,}$/i.test(t)?"__id__":t).join("")}function or(e,t){return Array.isArray(e)?e.map(r=>or(r,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([r,n])=>[r,or(n,r)])):typeof e!="string"?e:t&&cc.test(t)?hc(e):Gr.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?Qr(e):e}function wc(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function yc(e,t){let r=t.trim();if((r.startsWith("{")||r.startsWith("[")||r.startsWith('"'))&&e.startsWith("data-"))try{let s=JSON.parse(r);return JSON.stringify(or(s))}catch{}if(e.startsWith("data-")&&/^[A-Za-z0-9+/=]+$/.test(r))try{let s=Buffer.from(r,"base64").toString("utf8"),o=JSON.parse(s),a=JSON.stringify(or(o));return Buffer.from(a,"utf8").toString("base64")}catch{}return t}function Sc(e,t){let r=e.toLowerCase();return r==="class"?t.split(/(\s+)/).map((n,s)=>s%2===1?n:Qr(n)).join(""):r==="id"||r==="for"||r==="aria-controls"||r==="aria-labelledby"||r==="aria-describedby"||r==="aria-owns"||r==="aria-activedescendant"||r==="name"?Qr(t):r==="href"||r==="src"?wc(t):yc(r,t)}function bc(e){return e.replace(/<([a-z][^\s/>]*)([^<>]*?)>/gi,(t,r,n)=>{if(r.startsWith("/"))return t;let s=n.replace(/\s([:@a-zA-Z_][-:.a-zA-Z0-9_]*?)=(['"])([\s\S]*?)\2/g,(o,a,c,i)=>{let l=Sc(a,i);return ` ${a}=${c}${l}${c}`});return `<${r}${s}>`})}function vt(e){let t=v.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(v.basename(e))}function nr(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function Pc(e,t,r,n){let s=new Map,o,a=0;do{a++;let c=await oe(`S3 list objects page ${a} for s3://${t}/${r||""}`,3e5,({httpOptions:i})=>e.send(new ListObjectsV2Command({Bucket:t,Prefix:r||void 0,ContinuationToken:o}),i));for(let i of c.Contents||[]){if(!i.Key)continue;let l=(i.ETag||"").replace(/^"|"$/g,"").toLowerCase(),d=Number(i.Size??0);s.set(i.Key,{etag:l,size:d,cacheControl:void 0});}o=c.NextContinuationToken,n.debug(`Listed S3 keys page ${a}: ${s.size} keys so far`);}while(o);return s}async function Rc(e,t,r,n){if(n.has(r))return n.get(r)??null;try{let s=await oe(`S3 head object ${r}`,3e5,({httpOptions:a})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),a)),o={etag:(s.ETag||"").replace(/^"|"$/g,"").toLowerCase(),size:Number(s.ContentLength??0),cacheControl:s.CacheControl?.trim()||null};return n.set(r,o),o}catch{return n.set(r,null),null}}async function vc(e,t,r,n){if(n.cacheControl!==void 0)return n.cacheControl;try{let s=await oe(`S3 head cache metadata ${r}`,3e5,({httpOptions:o})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),o));n.cacheControl=s.CacheControl?.trim()||null;}catch{n.cacheControl=null;}return n.cacheControl}function _s(e){return String(e||"").split(",").map(t=>t.trim().toLowerCase()).filter(Boolean).sort().join(",")}async function Cc(e,t,r,n){let s=[...new Set(Array.from(r).filter(Boolean))];if(s.length===0)return n.info("No explicitly tombstoned S3 objects to delete."),[];n.info(`Deleting ${s.length} explicitly tombstoned S3 object(s)\u2026`);for(let o=0;o<s.length;o+=1e3){let a=s.slice(o,o+1e3);if(a.length===0)continue;let c=await oe(`S3 delete objects batch ${Math.floor(o/1e3)+1}`,3e5,({httpOptions:i})=>e.send(new DeleteObjectsCommand({Bucket:t,Delete:{Objects:a.map(l=>({Key:l}))}}),i));if(c.Errors&&c.Errors.length>0){let i=c.Errors.map(l=>`${l.Key||"(unknown)"}: ${l.Code||"DeleteFailed"}`);throw new Error(`S3 reported ${i.length} object deletion error(s): ${i.join(", ")}`)}n.info(`Deleted batch of ${a.length} object(s).`);for(let i of a)n.debug(` deleted: ${i}`);}return s}function kc(e){return createHash("md5").update(e).digest("hex")}function Ct(e){return createHash("sha256").update(e).digest("hex")}function ir(e){return createHash("sha256").update(bc(e.toString("utf8"))).digest("hex")}async function xc(e,t,r,n){if(n.has(r))return n.get(r)??null;try{let a=((await oe(`S3 head object metadata ${r}`,3e5,({httpOptions:c})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),c))).Metadata?.[Ks]||"").trim().toLowerCase()||null;return n.set(r,a),a}catch{return n.set(r,null),null}}async function Ic(e,t,r,n,s){if(n.has(r))return n.get(r)??null;try{let a=((await oe(`S3 head object normalized metadata ${r}`,3e5,({httpOptions:c})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),c))).Metadata?.[Hs]||"").trim().toLowerCase();if(a)return n.set(r,a),a}catch{return n.set(r,null),null}if(s.has(r)){let o=s.get(r)??null;return n.set(r,o),o}try{let a=await(await oe(`S3 get object ${r}`,3e5,({httpOptions:i})=>e.send(new GetObjectCommand({Bucket:t,Key:r}),i))).Body?.transformToByteArray(),c=a?ir(Buffer.from(a)):null;return s.set(r,c),n.set(r,c),c}catch{return s.set(r,null),n.set(r,null),null}}function Ac(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function Tc(e,t){let r=e,n=Object.entries(t).sort((s,o)=>o[0].length-s[0].length);for(let[s,o]of n)s&&(r=r.split(s).join(o));return r}async function Ec(e,t,r,n){let s=v.join(e,"asset-map.json"),o;try{o=await D.readFile(s,"utf8");}catch(i){if(i.code==="ENOENT")return;throw i}let a=JSON.parse(o);if(!a||typeof a!="object")return;let c=Object.fromEntries(Object.entries(a).map(([i,l])=>{let d=String(l??"");return t.urlRewriteMode==="absolute"&&t.targetOrigin&&r.targetOrigin&&t.targetOrigin!==r.targetOrigin&&(d=d.split(t.targetOrigin).join(r.targetOrigin)),d=Tc(d,n),[i,d]}));await D.writeFile(s,JSON.stringify(c,null,2),"utf8");}async function $c(e,t,r,n,s,o,a){let c=e.targetOrigin!==t.targetOrigin,i=Object.keys(n).length>0;if(!r||!c&&!i)return {outputDir:e.outputDir,cleanup:async()=>{}};if(c&&e.urlRewriteMode!=="absolute")throw new Error(`Deployment profile "${r}" changes targetOrigin, but the base crawl output must use urlRewriteMode "absolute" for multi-target redeploys.`);let l=v.join(v.dirname(e.outputDir),`.deploy-profile-${Ac(r)}-${Date.now()}`),d=uc(l);s.info(`Preparing deployment profile "${r}" from existing crawl output to ${l}...`);try{if(await D.rm(l,{recursive:!0,force:!0}),o){await D.mkdir(l,{recursive:!0});for(let y of o){let m=v.join(e.outputDir,y),h=v.join(l,y);await D.mkdir(v.dirname(h),{recursive:!0}),await D.copyFile(m,h);}}else await D.cp(e.outputDir,l,{recursive:!0});let u={...e,sourceOrigin:e.targetOrigin,targetOrigin:t.targetOrigin,extraReplacements:n,outputDir:l},g=1;s.info(`Rewriting text files for deployment profile "${r}"...`);let f={files:o,onStart:({totalFiles:y,workerCount:m})=>{g=m,s.info(`Rewriting ${y} text file(s) for deployment profile "${r}" with ${m} worker(s).`);},onProgress:({index:y,totalFiles:m,changedTextFiles:h,file:w,changed:k})=>{let E=`Rewriting [${y}/${m}] ${w} (${k?"rewrote":"checked"}; ${h} changed so far)`;m<=200||y<=5||y%10===0||y===m?(s.progress(E,{file:w,index:y,totalFiles:m,changed:k,changedTextFiles:h,workerCount:g}),s.info(E)):s.debug(E);}},p=a?await Kt(u,{},{...a,options:f}):await Dt(u,{},f);return await Ec(l,e,t,n),s.info(`Prepared deployment profile "${r}" in ${l} (${p} rewritten text file(s)).`),{outputDir:l,cleanup:async()=>{d(),await D.rm(l,{recursive:!0,force:!0});}}}catch(u){throw s.error(`Failed to prepare deployment profile "${r}" temporary output.`,{tempDir:l,outputDir:e.outputDir,error:u instanceof Error?u.message:String(u),...u instanceof Error&&u.stack?{stack:u.stack}:{}}),await D.rm(l,{recursive:true,force:true}).catch(()=>{}),d(),await s.flush().catch(()=>{}),u}}function Oc(e,t){let r=s=>s.replace(/^\/+|\/+$/g,""),n=e.targets.find(s=>s.bucketName===t.s3.bucket&&r(s.prefix)===r(t.s3.prefix)&&s.region===t.s3.region);if(!n)throw new Error(`No CDK Lambda deployment target matches s3://${t.s3.bucket}/${t.s3.prefix||""} in ${t.s3.region}. Redeploy the CDK with this target and reinstall remote-workers.json.`);return n}function Mc(e,t){if(!e||typeof e!="object")throw new Error("Remote deploy result must be a JSON object.");let r=e;if(r.schemaVersion!==Y||r.response?.operation!=="deploy-copy"||r.response.jobId!==t.jobId||r.response.taskId!==t.taskId||!r.detail||!Array.isArray(r.detail.objects)||!Array.isArray(r.detail.deletedKeys)||!Array.isArray(r.detail.deleteErrors))throw new Error("Remote deploy result has an invalid envelope.");return r}async function Bs(e){let t=null;for(let r=1;r<=Math.max(1,Math.min(5,e.maxAttempts));r+=1){let n=ve(`deploy-${e.batchIndex}-a${r}-${Date.now()}`,"taskId");try{let s=await e.client.invoke({schemaVersion:Y,operation:"deploy-copy",jobId:e.jobId,taskId:n,targetId:e.targetId,items:e.items,...e.deleteRelativeKeys?{deleteRelativeKeys:e.deleteRelativeKeys}:{}}),o=Mc(await e.client.readResult(s),s);if(o.response.status==="partial")throw new Error(`Worker reported ${o.response.failedItems} failed item(s).`);return o}catch(s){t=s;}}throw new Error(`Remote deploy task failed after ${e.maxAttempts} attempt(s): ${t instanceof Error?t.message:String(t)}`,{cause:t})}async function Dc(e){let t=Oc(e.remoteConfig,e.config),r=ve(`deploy-${Date.now()}-${Ct(Buffer.from(`${t.id}:${e.config.outputDir}`)).slice(0,12)}`,"jobId"),n=Nt(e.remoteConfig.workspace.prefix,"jobs",r,"deploy-inputs");e.log.progress(`Staging export for Lambda deploy: 0/${e.files.length}`,{phase:"deploy-stage",index:0,totalFiles:e.files.length,uploaded:0,skipped:0,failed:0,mode:"lambda-s3-copy"});let s=0,o=[],a=Math.max(1,Math.min(16,e.concurrency*2)),c=0;await Promise.all(Array.from({length:Math.min(a,e.files.length)},async()=>{for(;;){let w=c;if(w>=e.files.length)return;c+=1;let k=e.files[w],I=await D.readFile(v.join(e.config.outputDir,k)),E=e.contentTypeByRelativePath?.get(k)||Vs.lookup(k)||"application/octet-stream",$=e.revalidateFiles.has(Rt(k))?zs:vt(k)?e.config.s3.htmlCacheControl:e.config.s3.assetCacheControl,C=Ct(I),S=vt(k)?ir(I):void 0,b=`${n}/files/${Ct(Buffer.from(k))}-${v.basename(k)}`.replace(/\/+/g,"/");await e.client.writeWorkspaceObject({key:b,body:I,contentType:String(E),cacheControl:$,metadata:{"wpsuite-sha256":C,...S?{"wpsuite-normalized-sha256":S}:{}}}),o[w]={sourceKey:b,targetRelativeKey:k,sha256:C,...S?{normalizedSha256:S}:{},bytes:I.byteLength,contentType:String(E),cacheControl:$},s+=1,(s===e.files.length||s<=5||s%25===0)&&e.log.progress(`Staging export for Lambda deploy: ${s}/${e.files.length}`,{phase:"deploy-stage",index:s,totalFiles:e.files.length,staged:s,mode:"lambda-s3-copy"});}}));let i=[],l=Math.max(1,Math.min(500,e.batchSize));for(let w=0;w<o.length;w+=l)i.push(o.slice(w,w+l));let d=[],u=[],g=[],f=0,p=0,y=0,m=Math.max(1,Math.min(Math.max(1,e.concurrency),i.length));if(e.log.progress(`Lambda deploy: 0/${e.files.length}`,{phase:"deploy-copy",index:0,totalFiles:e.files.length,uploaded:0,skipped:0,failed:0,mode:"lambda-s3-copy",workerCount:m,completedBatches:0,totalBatches:i.length}),await Promise.all(Array.from({length:m},async()=>{for(;;){let w=y;if(w>=i.length)return;y+=1;let k=Date.now(),I=await Bs({client:e.client,jobId:r,targetId:t.id,batchIndex:w+1,items:i[w],maxAttempts:e.maxAttempts}),E=0,$=0,C=0;for(let b of I.detail.objects)f+=1,b.status==="copied"?(d.push(b.targetKey),E+=1):b.status==="skipped"?(u.push(b.targetKey),$+=1):(g.push(b.targetKey),C+=1),e.log.debug(`Lambda deploy ${b.status}: ${b.targetKey}`,{phase:"deploy-copy",batch:w+1,sourceKey:b.sourceKey,targetKey:b.targetKey,status:b.status,...b.error?{error:b.error}:{}});p+=1;let S=Date.now()-k;e.log.info(`Lambda deploy batch ${w+1}/${i.length} completed: ${E} copied, ${$} skipped unchanged, ${C} failed.`,{phase:"deploy-copy",batch:w+1,totalBatches:i.length,items:I.detail.objects.length,copied:E,skipped:$,failed:C,elapsedMs:S,elapsedSeconds:Math.round(S/10)/100,workerExporterVersion:I.response.exporterVersion,...I.requestId?{lambdaRequestId:I.requestId}:{},...I.completedAt?{workerCompletedAt:I.completedAt}:{}}),e.log.progress(`Lambda deploy: ${f}/${e.files.length}`,{phase:"deploy-copy",index:f,totalFiles:e.files.length,uploaded:d.length,skipped:u.length,failed:g.length,mode:"lambda-s3-copy",workerCount:m,completedBatches:p,totalBatches:i.length});}})),g.length>0)throw new Error(`Remote deployment failed for ${g.length} object(s).`);let h=[];for(let w=0;w<e.deletedFiles.length;w+=1e3){let k=e.deletedFiles.slice(w,w+1e3);if(k.length===0)continue;let I=await Bs({client:e.client,jobId:r,targetId:t.id,batchIndex:i.length+Math.floor(w/1e3)+1,items:[],deleteRelativeKeys:k,maxAttempts:e.maxAttempts});h.push(...I.detail.deletedKeys),e.log.progress(`Lambda deploy deletions: ${h.length}/${e.deletedFiles.length}`,{phase:"deploy-delete",index:h.length,totalFiles:e.deletedFiles.length,deleted:h.length,mode:"lambda-s3-copy"});}return {uploadedKeys:d,skippedKeys:u,failedKeys:g,deletedKeys:h}}async function Qs(e=process.argv.slice(2)){let t=await ue(),r=tr(e),n=rt(t,r),s=v.resolve(n.config.logDir||"logs"),o=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",a=o?v.join(v.resolve(o),"deploy-diff.json"):"",c=new Je(s,"deploy.log.jsonl",n.config.logLevel??"info"),i=n.profile?.extraReplacements??{},l=async()=>{};try{let d=await ze(t);if(e.includes("--content-sync")&&d?.schemaVersion!==2)throw new Error("Content-sync deployment requires a valid schema-2 targeted deploy plan.");let g=await $n(t);if(g)throw new Error(`Deployment blocked: the crawl started at ${g.startedAt} did not complete its final rewrite. Run a successful crawl or resume the rewrite before deploying.`);let f=t.remoteWorkers?.rewrite?.enabled===!0,p=t.remoteWorkers?.deploy?.enabled===!0,y=null,m=null;if(f||p){let R=Ht({runtimeDir:o});if(!R)throw new Error("Remote Lambda workers are enabled, but the runtime directory is unknown.");y=await Bt(R),m=new Ze(y);}let h=await $c(t,n.config,n.name,i,c,d?.schemaVersion===2?d.changedFiles:void 0,f&&m?{client:m,jobId:`profile-${Date.now()}`,concurrency:t.remoteWorkers?.rewrite?.concurrency??t.rewriteConcurrency,batchSize:t.remoteWorkers?.rewrite?.batchSize??25,maxAttempts:t.remoteWorkers?.rewrite?.maxAttempts??2,onStageProgress:({index:R,totalFiles:V,file:O})=>{(R===1||R===V||R%25===0)&&c.progress(`Staging deployment-profile rewrite: ${R}/${V}`,{phase:"rewrite-stage",index:R,totalFiles:V,file:O,execution:"lambda"});}}:void 0);l=h.cleanup;let w={...n.config,outputDir:h.outputDir},k=w.s3SyncMode??"sdk-upload-delete";if(d?.schemaVersion===2&&d.deletedFiles.length>0&&k!=="sdk-upload-delete")throw new Error("Content-sync tombstones require the sdk-upload-delete S3 sync mode.");let I=d?.schemaVersion!==2&&h.outputDir!==t.outputDir&&(t.targetOrigin!==n.config.targetOrigin||Object.keys(i).length>0),E=!!d&&!d.fullSyncRequired&&!I;if(d?.schemaVersion===2&&!E)throw new Error("Content-sync deployment cannot widen into a full-output deployment.");n.name&&c.info(`Using deployment profile: ${n.name}`),c.info(`Starting deploy \u2014 s3://${w.s3.bucket}/${w.s3.prefix||""} (region: ${w.s3.region})`),c.info(`S3 sync mode: ${k}`),d&&d.fullSyncRequired?c.info("Deploy plan requests a full sync; scanning the whole output tree."):d&&I?c.info("Ignoring incremental deploy plan because deployment-profile rewrites require a full sync."):E&&c.info(`Using incremental deploy plan: ${d.changedFiles.length} changed file(s), ${d.deletedFiles.length} deleted file(s).`),c.mark("deploy");let $=new S3Client({region:w.s3.region}),C=h.outputDir===t.outputDir?await mc(t,o,c):null,S=d?.schemaVersion===2?[...d.uploadGroups.assets,...d.uploadGroups.content,...d.uploadGroups.listings,...d.uploadGroups.resources,...d.uploadGroups.sitemapLeaves,...d.uploadGroups.sitemapIndexes]:d?.changedFiles??[];if(d?.schemaVersion===2){let R=[...new Set(S)],V=[...new Set(d.changedFiles)];if(R.length!==V.length||V.some(O=>!R.includes(O)))throw new Error("Content-sync deploy-plan upload groups do not cover the exact changed-file set.")}let b=E?(await Promise.all(S.map(async R=>{try{return (await D.stat(v.join(w.outputDir,R))).isFile()?R:null}catch{if(d?.schemaVersion===2)throw new Error(`Content-sync planned upload is missing: ${R}`);return null}}))).filter(R=>R!==null):await Uo(["**/*"],{cwd:w.outputDir,onlyFiles:!0,dot:!0}),T=[],q=[],A=b.filter(R=>{let V=C?.byRelativePath.get(Rt(R));if(!V)return !0;let O=nr(w.s3.prefix,R);return T.push(R),q.push(O),c.reject(V.kind,V.sourceUrl||R,"rewrite not completed; deploy upload blocked","deploy-guard",{file:R,key:O,outputPath:V.outputPath,manifestPath:C?.manifestPath}),!1}),B=new Set((d?.revalidateFiles||[]).map(Rt)),X=new Set((E?A:b).map(R=>nr(w.s3.prefix,R)));C&&(C.pendingPages>0||C.pendingTextAssets>0)&&c.info(`Deploy rewrite guard loaded ${C.pendingPages} pending page(s) and ${C.pendingTextAssets} pending text asset(s) from crawl manifest.`,{manifestPath:C.manifestPath,pendingPages:C.pendingPages,pendingTextAssets:C.pendingTextAssets,source:"deploy-guard"}),T.length>0&&c.warn(`Deploy rewrite guard blocked ${T.length} file(s) from upload because final crawl rewrite is incomplete.`,{rejected:T.length,manifestPath:C?.manifestPath,source:"deploy-guard"}),E?c.info(`Using ${A.length} eligible planned changed file(s) from deploy plan for upload${T.length>0?` (${T.length} blocked by deploy rewrite guard)`:""}.`):c.info(`Found ${b.length} file(s) in output directory "${w.outputDir}"${T.length>0?`; ${A.length} remain eligible for upload after deploy rewrite guard filtering`:""}.`),c.progress("Deploy preflight: comparing local output with remote S3 state.",{phase:"deploy",mode:k,totalFiles:A.length,scannedFiles:b.length,rejected:T.length,deploymentProfile:n.name||"",s3Bucket:w.s3.bucket,s3Prefix:w.s3.prefix||"",targetedPlan:E,deployGuardEnabled:h.outputDir===t.outputDir});let N=0,x=0,U=0,j=[],P=[],M=[],F=[],W=[],H=new Map,Se=new Map,st=new Map,_e=new Map,ur=new Map;if(p){if(!m||!y)throw new Error("Remote deploy worker client was not initialized.");if(k!=="sdk-upload-delete"&&k!=="sdk-upload-only")throw new Error(`Unsupported remote deploy mode: ${k}`);let R=await Dc({client:m,remoteConfig:y,config:w,files:A,deletedFiles:k==="sdk-upload-delete"?d?.deletedFiles??[]:[],revalidateFiles:B,contentTypeByRelativePath:C?.contentTypeByRelativePath,concurrency:w.remoteWorkers?.deploy?.concurrency??w.assetDownloadConcurrency,batchSize:w.remoteWorkers?.deploy?.batchSize??50,maxAttempts:w.remoteWorkers?.deploy?.maxAttempts??2,log:c});j.push(...R.uploadedKeys),P.push(...R.skippedKeys),M.push(...R.failedKeys),F=R.deletedKeys,N=j.length,x=P.length,U=M.length,c.info(`Lambda deploy complete: ${N} copied, ${x} skipped unchanged, ${F.length} deleted, ${U} failed.`),a&&(await D.mkdir(v.dirname(a),{recursive:!0}),await D.writeFile(a,JSON.stringify({generatedAt:new Date().toISOString(),mode:"lambda-s3-copy",summary:{totalFiles:b.length,eligibleFiles:A.length,uploaded:N,skipped:x,rejected:q.length,failed:U,deleted:F.length,protected:0,...n.name?{profile:n.name}:{}},uploadedKeys:j,skippedKeys:P,rejectedKeys:q,failedKeys:M,deletedKeys:F,protectedRemoteOnlyKeys:[]},null,2),"utf8")),d?.schemaVersion!==2&&await Me(t),c.endMark("deploy"),await c.flush();return}E||(c.info("Listing existing S3 objects to detect unchanged files..."),H=await Pc($,w.s3.bucket,w.s3.prefix,c),c.info(`Found ${H.size} existing key(s) in S3.`));let dr=async R=>H.has(R)?H.get(R)??null:E?Rc($,w.s3.bucket,R,Se):null;for(let R of A){let V=v.join(w.outputDir,R),O=nr(w.s3.prefix,R),ae=C?.contentTypeByRelativePath.get(R),ot=ae&&ae!=="application/octet-stream"?ae:Vs.lookup(R)||ae||"application/octet-stream",rn=B.has(Rt(R)),nn=rn?zs:vt(R)?w.s3.htmlCacheControl:w.s3.assetCacheControl,z=N+x+U+1;A.length<=200||z<=5||z%10===0||z===A.length?(c.progress(`Uploading [${z}/${A.length}] ${O} (${ot})`,{file:R,key:O,index:z,totalFiles:A.length,contentType:ot,mode:k}),c.info(`Uploading [${z}/${A.length}] ${O} (${ot})`)):c.debug(`Uploading [${z}/${A.length}] ${O} (${ot})`);try{let ce=await D.readFile(V),Be=await dr(O),it=null,Ve=null;if(Be){let at=!rn||_s(await vc($,w.s3.bucket,O,Be))===_s(nn),ro=ce.byteLength;if(Be.size===ro){let xt=Be.etag.includes("-");if(Be.etag!==""&&!xt){let no=kc(ce);if(Be.etag===no&&at){x++,A.length<=200||x<=5||x%25===0?(c.progress(`Skipped unchanged [${z}/${A.length}] ${O}`,{file:R,key:O,index:z,totalFiles:A.length,uploaded:N,skipped:x,failed:U,mode:k,reason:"etag-md5-match"}),c.info(`Skipped unchanged [${z}/${A.length}] ${O}`)):c.debug(`Skipped unchanged [${z}/${A.length}] ${O}`),P.push(O);continue}}it=Ct(ce);let sn=await xc($,w.s3.bucket,O,st);if(sn&&sn===it&&at){x++,A.length<=200||x<=5||x%25===0?(c.progress(`Skipped unchanged [${z}/${A.length}] ${O}`,{file:R,key:O,index:z,totalFiles:A.length,uploaded:N,skipped:x,failed:U,mode:k,reason:"metadata-sha256-match"}),c.info(`Skipped unchanged [${z}/${A.length}] ${O}`)):c.debug(`Skipped unchanged [${z}/${A.length}] ${O}`),P.push(O);continue}}if(vt(R)){Ve=ir(ce);let xt=await Ic($,w.s3.bucket,O,_e,ur);if(xt&&xt===Ve&&at){x++,A.length<=200||x<=5||x%25===0?(c.progress(`Skipped semantically unchanged [${z}/${A.length}] ${O}`,{file:R,key:O,index:z,totalFiles:A.length,uploaded:N,skipped:x,failed:U,mode:k,reason:"normalized-html-match"}),c.info(`Skipped semantically unchanged [${z}/${A.length}] ${O}`)):c.debug(`Skipped semantically unchanged [${z}/${A.length}] ${O}`),P.push(O);continue}}}it=it??Ct(ce),Ve=Ve??(vt(R)?ir(ce):null),await oe(`S3 upload ${O}`,9e5,({abortController:at})=>new Upload({client:$,abortController:at,params:{Bucket:w.s3.bucket,Key:O,Body:ce,ContentType:ot,CacheControl:nn,Metadata:{[Ks]:it,...Ve?{[Hs]:Ve}:{}}}}).done()),N++,j.push(O),(N%25===0||N===A.length)&&(c.progress(`Uploaded ${N}/${A.length} file(s)\u2026`,{uploaded:N,skipped:x,failed:U,totalFiles:A.length,mode:k}),c.info(`Uploaded ${N}/${A.length} file(s)\u2026`));}catch(ce){U++,M.push(O),c.error(`Failed to upload ${O}: ${ce.message}`,{key:O,error:String(ce)});}}if(c.info(`Upload complete: ${N} uploaded, ${x} skipped unchanged, ${q.length} rejected by guard, ${U} failed.`),M.length>0||q.length>0)throw new Error(`Deployment stopped before deletion because ${M.length} upload(s) failed and ${q.length} upload(s) were rejected.`);if(k==="sdk-upload-delete"){let R=new Set((d?.deletedFiles??[]).map(O=>nr(w.s3.prefix,O))),V=[...R].filter(O=>!X.has(O));if(!E&&(W=[...H.keys()].filter(ae=>!X.has(ae)).filter(ae=>!R.has(ae)),W.length>0)){c.warn(`Protected ${W.length} remote-only S3 object(s) from deletion because the crawl did not provide explicit tombstones.`,{protected:W.length,source:"deploy-delete-guard"});for(let ae of W)c.debug(` protected remote-only object: ${ae}`);}F=await Cc($,w.s3.bucket,E?V:V.filter(O=>H.has(O)),c);}else c.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion.");a&&(await D.mkdir(v.dirname(a),{recursive:!0}),await D.writeFile(a,JSON.stringify({generatedAt:new Date().toISOString(),mode:k,summary:{totalFiles:b.length,eligibleFiles:A.length,uploaded:j.length,skipped:P.length,rejected:q.length,failed:M.length,deleted:F.length,protected:W.length,...n.name?{profile:n.name}:{}},uploadedKeys:j,skippedKeys:P,rejectedKeys:q,failedKeys:M,deletedKeys:F,protectedRemoteOnlyKeys:W},null,2),"utf8")),d?.schemaVersion!==2&&await Me(t),c.endMark("deploy"),await c.flush();}finally{await l().catch(()=>{});}}function jc(e){let t=e;return t.endsWith("/")?t+="index.html":v.posix.basename(t).includes(".")||(t+="/index.html"),t}function Uc(e,t){let r=t.trim().replace(/^\/+|\/+$/g,"");if(!r)return null;let n=`/${r}`;return e===n||e.startsWith(`${n}/`)?e:`${n}${e.startsWith("/")?e:`/${e}`}`}function Js(e,t){let r=new Set;for(let n of e){let s=new URL(n,"https://content-sync.invalid");if(s.origin!=="https://content-sync.invalid")continue;let o=`${s.pathname}${s.search}`,a=jc(s.pathname);r.add(o),r.add(`${a}${s.search}`);let c=Uc(a,t);c&&r.add(`${c}${s.search}`);}return [...r].sort()}function Nc(){let e=String(process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"").trim();return e?v.join(v.resolve(e),"content-sync-invalidation.json"):""}async function Zr(e,t){if(!e)return;await D.mkdir(v.dirname(e),{recursive:true});let r=`${e}.${process.pid}.${Date.now()}.tmp`;await D.writeFile(r,JSON.stringify({...t,updatedAt:new Date().toISOString()},null,2),"utf8"),await D.rename(r,e);}async function _c(e,t,r,n){if(!e)return null;try{let s=JSON.parse(await D.readFile(e,"utf8"));if(s.schemaVersion!==1||s.distributionId!==t||s.impactHash!==r||!Array.isArray(s.batches))throw new Error("Content-sync invalidation state does not match the deploy plan.");let o=s.batches.flatMap(a=>a.paths);return o.length!==n.length||o.some((a,c)=>a!==n[c])?null:s}catch(s){if(s.code==="ENOENT")return null;throw s}}function Bc(e,t=3e3){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.slice(n,n+t));return r}async function Zs(e=process.argv.slice(2)){let t=await ue(),r=tr(e),n=rt(t,r),s=n.config,o=new Je(s.logDir||"logs","invalidate.log.jsonl",s.logLevel??"info"),a=e.includes("--content-sync"),c=await ze(t);if(a&&c?.schemaVersion!==2)throw new Error("Content-sync invalidation requires a valid schema-2 targeted deploy plan.");if(n.name&&o.info(`Using deployment profile: ${n.name}`),!s.cloudFront.distributionId){o.info("No CloudFront distributionId configured; skipping invalidation."),await o.flush();return}let i=c?.schemaVersion===2?c.invalidationPaths:s.cloudFront.invalidationPaths.length>0?s.cloudFront.invalidationPaths:["/*"],l=c?.schemaVersion===2?Js(i,s.s3.prefix||""):i;if(c?.schemaVersion===2&&l.some(p=>p==="/*"))throw new Error("Content-sync cannot use a whole-distribution invalidation.");if(l.length===0){o.info("The targeted deploy plan has no CloudFront paths to invalidate."),await o.flush();return}let d=s.cloudFront.distributionId,u=new CloudFrontClient({region:"us-east-1",maxAttempts:5});if(o.mark("invalidate"),c?.schemaVersion!==2){let p=`smartcloud-static-publisher-${Date.now()}`;await oe(`CloudFront invalidation for distribution ${d}`,3e5,({httpOptions:y})=>u.send(new CreateInvalidationCommand({DistributionId:d,InvalidationBatch:{CallerReference:p,Paths:{Quantity:l.length,Items:l}}}),y)),o.endMark("invalidate"),await o.flush();return}let g=Nc(),f=await _c(g,d,c.impactHash,l);if(!f){let p=createHash("sha256").update(JSON.stringify(l)).digest("hex");f={schemaVersion:1,distributionId:d,impactHash:c.impactHash,updatedAt:new Date().toISOString(),batches:Bc(l).map((y,m)=>({index:m,callerReference:`wpsuite-content-sync-${c.impactHash.slice(0,24)}-${p.slice(0,24)}-${m}`,paths:y,invalidationId:null,status:"pending"}))},await Zr(g,f);}for(let p of f.batches){if(!p.invalidationId){let y=await oe(`CloudFront targeted invalidation batch ${p.index+1}`,3e5,({httpOptions:h})=>u.send(new CreateInvalidationCommand({DistributionId:d,InvalidationBatch:{CallerReference:p.callerReference,Paths:{Quantity:p.paths.length,Items:p.paths}}}),h)),m=String(y.Invalidation?.Id||"").trim();if(!m)throw new Error("CloudFront did not return an invalidation ID.");p.invalidationId=m,p.status="created",await Zr(g,f);}await waitUntilInvalidationCompleted({client:u,maxWaitTime:900,minDelay:2,maxDelay:15},{DistributionId:d,Id:p.invalidationId}),p.status="completed",await Zr(g,f),o.info(`CloudFront invalidation batch ${p.index+1}/${f.batches.length} completed.`,{invalidationId:p.invalidationId,pathCount:p.paths.length});}o.endMark("invalidate"),await o.flush();}function lr(e){let t=new URL(e);return t.hash="",t.href}function Ys(e,t,r){let n=new Set([...t].map(i=>lr(i))),s=new Map,o=new Map,a=i=>{s.set(lr(i),i);},c=i=>{if(!i)return;let l=lr(i);s.has(l)||o.set(l,i);};for(let i of e.deleteUrls)a(i);for(let i of e.resourceDeleteUrls)a(i);for(let i of e.archiveFamilies)if(i.foundPosts===0)for(let l of i.pageUrls)n.has(lr(l))||a(l);for(let i of e.directRenderUrls)c(i);for(let i of e.resourceRenderUrls)c(i);for(let i of e.archiveFamilies)c(i.pageUrls[0]),c(i.pageUrls.at(-1));for(let i of r)c(i);return {expectedAvailable:[...o.values()],expectedMissing:[...s.values()]}}var eo=["claimed","impact-planned","rendered","deployed","invalidated","verified","acknowledged"];function en(){let e=String(process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"").trim();if(!e)throw new Error("Content-sync requires a runtime directory.");return v.resolve(e)}function nt(e,t){return eo.indexOf(e)>=eo.indexOf(t)}async function Ae(e,t,r,n,s={}){let o={timestamp:new Date().toISOString(),eventType:t,status:t.endsWith("failed")?"failed":"success",actorSource:"content-sync",jobId:r.id||"",command:"content-sync",message:n,details:s};await D.mkdir(e,{recursive:true}),await D.appendFile(v.join(e,"audit-events.jsonl"),`${JSON.stringify(o)}
|
|
15
|
-
`,"utf8");}function Kc(e){return ct({postTypes:e.postTypes??[],listingPaths:e.listingPaths??[],includeSubsites:e.includeSubsites,includePostTypeArchives:e.includePostTypeArchives,includeTaxonomyArchives:e.includeTaxonomyArchives,includeAuthorArchives:e.includeAuthorArchives,includeDateArchives:e.includeDateArchives,includePostsPage:e.includePostsPage,includeSitemapChain:e.includeSitemapChain})}function Hc(e,t){let r=(e.scheduler?.rules??[]).find(n=>n.command==="content-sync"&&n.id===t);if(!r)throw new Error(`Content-sync scheduler rule not found: ${t}`);if(r.enabled===false)throw new Error(`Content-sync scheduler rule is disabled: ${t}`);return r}async function tn(e,t){if(e.subscriptionType!=="PROFESSIONAL"&&e.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let r=Kc(t),n=rt(e,t.deploymentProfile),s=n.name||"",o=cn(e.sourceOrigin,String(t.id||""),r),a=ln({sourceOrigin:e.sourceOrigin,targetOrigin:n.config.targetOrigin,deploymentProfile:s,s3Bucket:n.config.s3.bucket,s3Prefix:n.config.s3.prefix,cloudFrontDistributionId:n.config.cloudFront.distributionId,urlRewriteMode:n.config.urlRewriteMode,extraReplacements:n.profile?.extraReplacements??{}}),c=un({siteId:e.wpsuite?.siteSettings?.siteId,accountId:e.wpsuite?.siteSettings?.accountId,sourceOrigin:e.sourceOrigin,ruleId:String(t.id||""),targetFingerprint:a}),i=`content-sync:${String(t.id||"")}:${be({scopeFingerprint:o,targetFingerprint:a}).slice(0,32)}`,l=new At({sourceOrigin:e.sourceOrigin,runtimeToken:String(e.wpsuite?.runtimeToken||""),ignoreHttpsErrors:e.ignoreHttpsErrors}),d=await l.releaseFingerprint(r.includeSubsites),u=an({wordpressFingerprint:d,targetFingerprint:a,sourceOrigin:e.sourceOrigin,sitemapPaths:dt(e.sitemapPaths),blockedPathPrefixes:e.blockedPathPrefixes,assetPathPrefixes:e.assetPathPrefixes,noJavaScriptRenderPathPrefixes:e.noJavaScriptRenderPathPrefixes,urlRewriteMode:e.urlRewriteMode});return {rule:t,scope:r,deployment:n,deploymentProfile:s,scopeFingerprint:o,targetFingerprint:a,consumerId:c,coalesceKey:i,client:l,releaseFingerprint:u}}async function zc(e){let t=en(),r=Tt(t),n=await ue(),s=(n.scheduler?.rules??[]).filter(l=>l.command==="content-sync"&&l.enabled!==false);if(s.length===0)return 0;let o=await hr(r),a=await Et(r),c=await fr(r),i=0;for(let l of s){let d=await tn(n,l),u=c.entries[d.coalesceKey];if(!u||u.releaseJobId!==e||u.scopeFingerprint!==d.scopeFingerprint||u.targetFingerprint!==d.targetFingerprint||u.releaseFingerprint!==d.releaseFingerprint)throw new Error(`The normal release has no matching pre-crawl content-sync cutoff for rule ${String(l.id||"")}.`);let g=be({releaseJobId:e,releaseFingerprint:d.releaseFingerprint,scopeFingerprint:d.scopeFingerprint,targetFingerprint:d.targetFingerprint,sequence:u.sequence}),f=await d.client.establishBaseline({consumerId:d.consumerId,scopeFingerprint:d.scopeFingerprint,baselineId:g,postTypes:d.scope.postTypes,includeSubsites:d.scope.includeSubsites,sequence:u.sequence}),p={schemaVersion:1,ruleId:String(l.id||""),consumerId:d.consumerId,coalesceKey:d.coalesceKey,scopeFingerprint:d.scopeFingerprint,targetFingerprint:d.targetFingerprint,releaseFingerprint:d.releaseFingerprint,baselineId:g,deploymentProfile:d.deploymentProfile,committedSequence:f.committedSequence,releaseJobId:e,verifiedAt:new Date().toISOString()};o.entries[d.coalesceKey]=p;let y=a.rules[d.coalesceKey];a.rules[d.coalesceKey]={ruleId:String(l.id||""),consumerId:d.consumerId,coalesceKey:d.coalesceKey,committedSequence:f.committedSequence,observedHeadSequence:f.headSequence,lag:Math.max(0,f.headSequence-f.committedSequence),lastSuccessfulJobId:y?.lastSuccessfulJobId||e,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:f.headSequence>f.committedSequence,retryAttempt:0,nextRetryAt:null,lastError:null,baselineStatus:"ready",baselineReason:null};let m=await bn(r,d.coalesceKey);await Ae(t,"content-sync-baseline-established",{id:e},"A normal release established a verified content-sync baseline.",{ruleId:l.id,consumerId:d.consumerId,committedSequence:f.committedSequence,supersededCurrent:m}),i++;}return await fn(r,o),await $t(r,a),await D.rm(r.releaseCutoff,{force:true}),i}async function Qc(e){let t=en(),r=Tt(t),n=await ue(),s=(n.scheduler?.rules??[]).filter(c=>c.command==="content-sync"&&c.enabled!==false);if(s.length===0)return 0;let o=await fr(r),a=0;for(let c of s){let i=await tn(n,c),l=Object.values(o.entries).find(g=>g.releaseJobId===e&&g.ruleId===String(c.id||""));if(l){if(l.coalesceKey===i.coalesceKey&&l.scopeFingerprint===i.scopeFingerprint&&l.targetFingerprint===i.targetFingerprint&&l.releaseFingerprint===i.releaseFingerprint){a++;continue}throw new Error(`The normal release scope changed after its journal cutoff was captured for rule ${String(c.id||"")}. Start a new normal publish instead of resuming this release.`)}let d=await i.client.unboundHead(i.scope.postTypes,i.scope.includeSubsites),u={schemaVersion:1,releaseJobId:e,ruleId:String(c.id||""),coalesceKey:i.coalesceKey,scopeFingerprint:i.scopeFingerprint,targetFingerprint:i.targetFingerprint,releaseFingerprint:i.releaseFingerprint,sequence:d.headSequence,capturedAt:new Date().toISOString()};o.entries[i.coalesceKey]=u,await Ae(t,"content-sync-release-cutoff-captured",{id:e},"A normal release captured its pre-crawl content-sync journal cutoff.",{ruleId:c.id,consumerId:i.consumerId,sequence:d.headSequence}),a++;}return await mn(r,o),a}async function Jc(e,t){let r=JSON.parse(await D.readFile(v.join(e,"current-run.json"),"utf8"));if(r.id!==t||r.command!=="content-sync"||!String(r.ruleId||"").trim())throw new Error("The active queue job is not the requested content-sync job.");return r}async function Xr(e,t,r=0){let n=e.protocol==="https:"?gn:po,s=e.protocol==="https:"?new gn.Agent({rejectUnauthorized:!t}):void 0;return new Promise((o,a)=>{let c=n.get(e,{agent:s,timeout:3e4,headers:{"user-agent":"WP-Suite-Content-Sync/1"}},i=>{let l=i.statusCode??500,d=i.headers.location;if(l>=300&&l<400&&d&&r<5){i.resume(),Xr(new URL(d,e),t,r+1).then(o,a);return}let u=[],g=0;i.on("data",f=>{g+=f.byteLength,g<=1048576&&u.push(f);}),i.on("error",a),i.on("end",()=>o({status:l,body:Buffer.concat(u).toString("utf8"),contentType:String(i.headers["content-type"]||"")}));});c.on("timeout",()=>c.destroy(new Error(`Verification timed out: ${e}`))),c.on("error",a);})}async function Gc(e,t,r,n){let s=t.deployment.config.targetOrigin;if(!/^https?:\/\//i.test(s))throw new Error("Content-sync verification requires an absolute HTTP(S) target origin.");let o=JSON.parse(await D.readFile(n,"utf8")),a=new Set;for(let[d,u]of Object.entries(o.pages??{}))a.add(d),typeof u.url=="string"&&a.add(u.url);let c=await ze(e);if(c?.schemaVersion!==2||c.impactHash!==r.impactHash)throw new Error("Content-sync verification requires the matching targeted deploy plan.");let i=Ys(r,a,c.resolvedSitemapUrls),l=new Set(r.resourceRenderUrls.map(d=>{let u=new URL(d);return u.hash="",u.href}));for(let d of i.expectedAvailable){let u=new URL(d),g=new URL(`${u.pathname}${u.search}`,s),f=await Xr(g,e.ignoreHttpsErrors);if(f.status<200||f.status>=400)throw new Error(`Content-sync verification failed (${f.status}): ${g}`);let p=new URL(d);if(p.hash="",l.has(p.href)){if(!f.contentType.toLowerCase().startsWith("application/json"))throw new Error(`Resource verification expected application/json: ${g}`);try{JSON.parse(f.body);}catch{throw new Error(`Resource verification received invalid JSON: ${g}`)}}}for(let d of i.expectedMissing){let u=new URL(d),g=new URL(`${u.pathname}${u.search}`,s),f=await Xr(g,e.ignoreHttpsErrors);if(f.status>=200&&f.status<300)throw new Error(`Deleted content is still publicly available: ${g}`)}}async function Zc(e){let t=await D.readFile(e.candidateManifest,"utf8");JSON.parse(t);let r=`${e.trustedManifest}.${process.pid}.tmp`;await D.writeFile(r,t,"utf8"),await D.rename(r,e.trustedManifest);}async function Yc(e,t){try{let r=JSON.parse(await D.readFile(e.candidateManifest,"utf8"));if([...Object.values(r.pages??{}),...Object.values(r.assets??{})].some(s=>s?.lastSeenRunId===t))return "resumed"}catch(r){if(r.code!=="ENOENT")throw new Error(`The content-sync candidate manifest is invalid: ${r instanceof Error?r.message:String(r)}`,{cause:r})}return await D.copyFile(e.trustedManifest,e.candidateManifest).catch(r=>{throw new Error(`A trusted crawl manifest is required before content-sync: ${r instanceof Error?r.message:String(r)}`,{cause:r})}),"initialized"}async function Ne(e,t,r,n,s={},o=0,a=async()=>{}){t.phase=r,await hn(e,t),await Sn(e,{schemaVersion:1,jobId:t.jobId,phase:r,completedItems:n,totalItems:n,attempt:o,updatedAt:new Date().toISOString(),details:s}),await Ae(v.dirname(e.state),"content-sync-checkpoint",{id:t.jobId},`Content-sync checkpoint completed: ${r}.`,{phase:r,completedItems:n,totalItems:n,attempt:o,...s}),await a(r,t);}async function Xc(e,t={}){let r={loadConfig:ue,resolveRuleContext:tn,runCrawl:qs,runDeploy:Qs,runInvalidate:Zs,verifyDeployment:Gc,promoteCandidateManifest:Zc,clearDeployPlan:Me,afterCheckpoint:async()=>{},...t},n=en(),s=Tt(n),o=await Jc(n,e),a=await r.loadConfig(),c=Hc(a,String(o.ruleId)),i=await r.resolveRuleContext(a,c);if(o.coalesceKey&&o.coalesceKey!==i.coalesceKey)throw new Error("Queued content-sync demand no longer matches the active rule scope.");let d=(await hr(s)).entries[i.coalesceKey];if(!d||d.scopeFingerprint!==i.scopeFingerprint||d.targetFingerprint!==i.targetFingerprint||d.releaseFingerprint!==i.releaseFingerprint)throw await Ae(n,"content-sync-baseline-rejected",o,"Content-sync requires a new verified full or incremental release baseline.",{ruleId:c.id,reason:d?"mismatch":"missing"}),new Error("Content-sync baseline is missing or stale. Run a successful normal publish first.");let u=await wr(s),g=await i.client.head({consumerId:i.consumerId,scopeFingerprint:i.scopeFingerprint,baselineId:d.baselineId,postTypes:i.scope.postTypes,includeSubsites:i.scope.includeSubsites});if(u&&u.jobId!==o.id)throw new Error("Another immutable content-sync range is still active.");if(u||(u={schemaVersion:1,jobId:o.id,ruleId:String(c.id||""),consumerId:i.consumerId,coalesceKey:i.coalesceKey,scopeFingerprint:i.scopeFingerprint,targetFingerprint:i.targetFingerprint,baselineId:d.baselineId,fromSequence:g.committedSequence,toSequence:g.headSequence,phase:"claimed",impactHash:null,startedAt:new Date().toISOString(),updatedAt:new Date().toISOString()},await Ne(s,u,"claimed",0,{fromSequence:u.fromSequence,toSequence:u.toSequence},0,r.afterCheckpoint),await Ae(n,"content-sync-range-claimed",o,"Content-sync claimed a closed journal range.",{fromSequence:u.fromSequence,toSequence:u.toSequence})),u.fromSequence===u.toSequence){let h=await Et(s);h.rules[i.coalesceKey]={ruleId:String(c.id||""),consumerId:i.consumerId,coalesceKey:i.coalesceKey,committedSequence:u.toSequence,observedHeadSequence:g.headSequence,lag:Math.max(0,g.headSequence-u.toSequence),lastSuccessfulJobId:o.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:false,retryAttempt:0,nextRetryAt:null,lastError:null},await $t(s,h),await yr(s);return}let f=await wn(s);if(!nt(u.phase,"impact-planned")){let h=await i.client.events({consumerId:i.consumerId,scopeFingerprint:i.scopeFingerprint,baselineId:d.baselineId,postTypes:i.scope.postTypes,includeSubsites:i.scope.includeSubsites,afterSequence:u.fromSequence,throughSequence:u.toSequence}),w=mr({events:h,scope:i.scope,sourceOrigin:a.sourceOrigin}),k=await i.client.resolveImpactFamilies(w,i.scope.includeSubsites);f=pn({jobId:o.id,ruleId:String(c.id||""),consumerId:i.consumerId,coalesceKey:i.coalesceKey,scopeFingerprint:i.scopeFingerprint,targetFingerprint:i.targetFingerprint,baselineId:d.baselineId,sourceOrigin:a.sourceOrigin,scope:i.scope,fromSequence:u.fromSequence,toSequence:u.toSequence,events:h,resolvedArchiveFamilies:k,sitemapUrls:dt(a.sitemapPaths)}),await yn(s,f),u.impactHash=f.impactHash,await Ne(s,u,"impact-planned",h.length,{eventCount:h.length,foldedCount:f.foldedCount,impactHash:f.impactHash},0,r.afterCheckpoint),await Ae(n,"content-sync-impact-planned",o,"Content-sync persisted an immutable impact plan.",{impactHash:f.impactHash,eventCount:h.length});}if(!f||f.jobId!==o.id||u.impactHash!==f.impactHash)throw new Error("The immutable content-sync impact plan is missing or mismatched.");if(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH=s.candidateManifest,!nt(u.phase,"rendered")){let h=await Yc(s,o.id);await Ae(n,h==="resumed"?"content-sync-render-resumed":"content-sync-render-initialized",o,h==="resumed"?"Content-sync resumed its candidate crawl manifest.":"Content-sync initialized a candidate crawl manifest.",{impactHash:f.impactHash}),await r.runCrawl(["--content-sync-plan",s.impact]),await Ne(s,u,"rendered",f.directRenderUrls.length+f.archiveFamilyUrls.length+f.resourceRenderUrls.length,{impactHash:f.impactHash},o.attempt??0,r.afterCheckpoint);}let p=i.deploymentProfile?["--profile",i.deploymentProfile]:[];if(nt(u.phase,"deployed")||(await r.runDeploy([...p,"--content-sync"]),await Ne(s,u,"deployed",1,{impactHash:f.impactHash},0,r.afterCheckpoint),await Ae(n,"content-sync-deployed",o,"Content-sync targeted deployment completed.",{impactHash:f.impactHash})),nt(u.phase,"invalidated")?nt(u.phase,"verified")||await r.runInvalidate([...p,"--content-sync"]):(await r.runInvalidate([...p,"--content-sync"]),await Ne(s,u,"invalidated",1,{impactHash:f.impactHash},0,r.afterCheckpoint)),nt(u.phase,"verified")||(await r.verifyDeployment(a,i,f,s.candidateManifest),await r.promoteCandidateManifest(s),await Ne(s,u,"verified",1,{impactHash:f.impactHash},0,r.afterCheckpoint)),g=await i.client.head({consumerId:i.consumerId,scopeFingerprint:i.scopeFingerprint,baselineId:d.baselineId,postTypes:i.scope.postTypes,includeSubsites:i.scope.includeSubsites}),g.committedSequence===u.fromSequence)await i.client.acknowledge({consumerId:i.consumerId,scopeFingerprint:i.scopeFingerprint,baselineId:d.baselineId,expectedSequence:u.fromSequence,sequence:u.toSequence,postTypes:i.scope.postTypes,includeSubsites:i.scope.includeSubsites});else if(g.committedSequence!==u.toSequence)throw new Error("Content-sync acknowledgement cursor is in an unexpected state.");await Ne(s,u,"acknowledged",1,{sequence:u.toSequence},0,r.afterCheckpoint),await Ae(n,"content-sync-cursor-acknowledged",o,"Content-sync committed its journal cursor after verification.",{sequence:u.toSequence});let y=await i.client.head({consumerId:i.consumerId,scopeFingerprint:i.scopeFingerprint,baselineId:d.baselineId,postTypes:i.scope.postTypes,includeSubsites:i.scope.includeSubsites}),m=await Et(s);m.rules[i.coalesceKey]={ruleId:String(c.id||""),consumerId:i.consumerId,coalesceKey:i.coalesceKey,committedSequence:u.toSequence,observedHeadSequence:y.headSequence,lag:Math.max(0,y.headSequence-u.toSequence),lastSuccessfulJobId:o.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:y.headSequence>u.toSequence,retryAttempt:0,nextRetryAt:null,lastError:null},await $t(s,m),await r.clearDeployPlan(a),await D.rm(v.join(n,"content-sync-invalidation.json"),{force:true}),await D.rm(s.candidateManifest,{force:true}),await yr(s);}async function to(e=process.argv.slice(2)){let r=e.indexOf("--capture-baseline-cutoffs");if(r>=0){let a=String(e[r+1]||"").trim();if(!a)throw new Error("--capture-baseline-cutoffs requires a release job ID.");await Qc(a);return}let n=e.indexOf("--establish-baselines");if(n>=0){let a=String(e[n+1]||"").trim();if(!a)throw new Error("--establish-baselines requires a release job ID.");await zc(a);return}let s=e.indexOf("--job-id"),o=s>=0?String(e[s+1]||"").trim():"";if(!o)throw new Error("Content-sync requires --job-id.");await Xc(o);}to().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1);});
|
|
14
|
+
${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:a,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 Cs(e,t,r,n,s,o){let a=Xt(e,s);if(await _i(e,t,r,n,s,o),!n.enabled)return {action:"render",changeToken:n.trackManifest?await Jt(e,t,n,s,o):null};let c=n.manifest.pages[s];if(!c)return {action:"render",changeToken:await Jt(e,t,n,s,o)};let i=await Jt(e,t,n,s,o);if(i?.supported&&i.token)return c.changeToken===i.token?a&&!await Ki(e,t,s,o)?{action:"render",changeToken:i}:{action:"reuse",changeToken:i}:{action:"render",changeToken:i};let l=Ue(r.sitemapLastmodByPage[s]);return l&&c.sitemapLastmod&&c.sitemapLastmod===l?{action:"reuse",changeToken:i}:{action:"render",changeToken:i}}async function Ki(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 Hi(e,t,r,n,s){let o=ls(r.previousManifest,void 0,n,"previous-manifest"),a=0;for(let[g,f]of Object.entries(r.manifest.pages))if(!r.seenPages.has(g)){Wr(s,e,f.outputPath);try{await D.unlink(f.outputPath);}catch(p){(p.code||"")!=="ENOENT"&&n.warn(`Failed to remove stale incremental page output for ${g}`,{url:g,outputPath:f.outputPath,error:String(p)});}delete r.manifest.pages[g],a++;}let c=ls(r.manifest,r.runId,n,"active-manifest"),i=new Set,l=new Set;for(let g of c){for(let y of yt(e,g))i.add(y);let f=r.manifest.assets[g]?.outputPath;f&&l.add(f);let p=Xe(e,t.assetMap,g);p&&l.add(p);}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(Yn(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,p=r.previousManifest.assets[g]?.outputPath;p&&f.add(p);let y=Xe(e,t.assetMap,g);if(!c.has(g)&&y)f.add(y);else if(!c.has(g)){let m=ua(e,g,n,"incremental-cleanup");m&&(f.add(m.originalFilePath),m.hashedFilePath&&f.add(m.hashedFilePath));}for(let m of f)if(!l.has(m)){Wr(s,e,m);try{await D.unlink(m),d++;}catch(h){(h.code||"")!=="ENOENT"&&n.warn(`Failed to remove stale incremental asset output for ${g}`,{url:g,outputPath:m,error:String(h)});}}for(let m of yt(e,g))i.has(m)||Object.prototype.hasOwnProperty.call(t.assetMap,m)&&(delete t.assetMap[m],u++);}(a>0||d>0||u>0)&&n.info(`Incremental cleanup removed ${a} stale pages, ${d} stale assets, ${u} stale asset mappings`,{removedPages:a,removedAssets:d,removedAssetMappings:u,phase:"incremental-cleanup"});}async function zi(e,t,r,n){let s=new Set([...Object.values(t.manifest.pages),...Object.values(t.manifest.assets)].map(i=>String(i.outputPath||"").trim()).filter(Boolean).map(i=>v.resolve(i))),o=Object.values(e.postCrawlCopyMap||{}).map(i=>Gt(String(i||""))).filter(i=>!!i).map(i=>v.resolve(e.outputDir,i)),c=(await Uo(["**/*.html","**/*.htm"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(i=>Jn(v.join(e.outputDir,i),e.outputDir,s,o));for(let i of c){let l=v.join(e.outputDir,i);Wr(n,e,l),await D.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 ls(e,t,r,n){let s=new Set,o=a=>{let c=a.trim();if(c){if(r){let i=we(c,r,"asset",n??"manifest");if(!i)return;s.add(i.toString());return}s.add(c);}};for(let a of Object.values(e.pages))for(let c of a.discoveredAssets||[])o(c);for(let[a,c]of Object.entries(e.assets||{}))t&&c.lastSeenRunId!==t||o(a);return s}function us(e,t,r){for(let n of t)for(let s of yt(e,n))if(r.has(s))return true;return false}function Qi(e,t,r,n,s){let o=new Set(r.rewriteTargets);for(let c of r.changedFiles)o.add(v.resolve(e.outputDir,c));for(let c of Object.values(t.manifest.pages))c.rewriteComplete||o.add(v.resolve(c.outputPath));for(let c of Object.values(t.manifest.assets))c.isText&&!c.rewriteComplete&&o.add(v.resolve(c.outputPath));let a=Ni(n,s);if(a.size===0)return [...o];for(let c of Object.values(t.manifest.pages))us(e,c.discoveredAssets,a)&&o.add(v.resolve(c.outputPath));for(let[c,i]of Object.entries(t.manifest.assets)){i.isText&&us(e,i.discoveredAssets,a)&&o.add(v.resolve(i.outputPath));for(let l of yt(e,c))if(a.has(l)){ne(r,e,i.outputPath),i.isText&&o.add(v.resolve(i.outputPath));break}}return [...o]}function Ji(e,t){let r=t?new Set(Array.from(t,s=>v.resolve(s))):null,n=s=>r===null||r.has(v.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 Gi(e,t,r){let n=new Set,s=o=>{if(!o)return;let a=ge(e.outputDir,o);a&&n.add(a);};for(let o of t.donePages)s(he(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(Xe(e,t.assetMap,o));for(let o of Object.values(r.manifest.assets))o.lastSeenRunId===r.runId&&s(o.outputPath);return n}async function Zi(e,t,r,n,s){let o=[...n.deletedFiles].sort(),a=Gi(e,t,r),c=0;for(let d of [...a].sort()){try{if((await D.stat(v.join(e.outputDir,d))).isFile())continue}catch{}c++,s.warn(`Active output is missing after crawl: ${d}`,{phase:"deploy-plan",file:d,outputPath:v.join(e.outputDir,d)});}if(c>0&&s.warn(`Detected ${c} active output file(s) missing before deploy plan save.`,{phase:"deploy-plan",missingActiveOutputs:c}),o.length===0)return [];let i=[],l=0;for(let d of o){if(!a.has(d)){i.push(d);continue}l++;let u=v.join(e.outputDir,d),g;try{g=(await D.stat(u)).isFile();}catch{g=false;}s.warn(`Deploy plan protected active output from deletion: ${d}`,{phase:"deploy-plan",file:d,outputPath:u,exists:g});}return l>0&&s.info(`Deploy plan skipped ${l} active output deletion(s).`,{phase:"deploy-plan",protectedDeletes:l,deletedFiles:i.length}),i}function yt(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 a of o)try{r.add(new URL(a).origin+n.pathname+n.search);}catch{}r.add(n.pathname+n.search),r.add(n.pathname);}catch{}return [...r]}function Yi(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 a of o)try{r.add(new URL(a).origin+n.pathname+n.search);}catch{}r.add(n.pathname+n.search);}catch{}return [...r]}function ks(e,t){let r=e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/"?e.targetOrigin:"https://relative.invalid/";try{let n=new URL(t,r);return ft(e.outputDir,n.pathname)}catch{return null}}function Xi(e,t,r){for(let n of Yi(e,r)){let s=t[n];if(!s)continue;let o=ks(e,s);if(o)return {outputPath:o,publicUrl:s}}return null}function ea(e,t,r){for(let n of yt(e,r)){let s=t[n];if(!s)continue;let o=ks(e,s);if(o)return o}return null}function Xe(e,t,r){let n=ea(e,t,r);if(n)return n;try{return er(e,r).originalFilePath}catch{return null}}function ta(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?v.join(v.resolve(e),"queue-runner-heartbeat.json"):""}async function jr(e){let t=ta();if(t)try{let r=await D.readFile(t,"utf8"),n=JSON.parse(r);if(!n||typeof n!="object")return;await D.writeFile(t,JSON.stringify({...n,checkedAt:new Date().toISOString(),status:"running",currentStep:"rewrite",message:e},null,2),"utf8");}catch{}}function ra(e,t){let r=new Set;for(let n of t.donePages)r.add(v.resolve(he(e,n)));for(let n of t.doneAssets){let s=Xe(e,t.assetMap,n);!s||!$e(s)||r.add(v.resolve(s));}for(let n of t.doneSitemaps){let s=Xe(e,t.assetMap,n);!s||!$e(s)||r.add(v.resolve(s));}return [...r]}var Zt="re:",Qt=new Map;function na(e){if(!e.startsWith(Zt))return null;let t=Qt.get(e);if(t!==void 0)return t||null;let r=e.slice(Zt.length).trim();if(!r)return Qt.set(e,false),null;try{let n=new RegExp(r);return Qt.set(e,n),n}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),Qt.set(e,false),null}}function Hr(e,t){let r=na(t);return r?r.test(e):t.startsWith(Zt)?false:e.startsWith(t)}function sa(e,t){return t.find(r=>Hr(e,r))}function xs(e,t){let r=sa(t.pathname,e.blockedPathPrefixes);if(r)return r.startsWith(Zt)?`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 oa(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 ia(e,t){return oa(e).has(t.hostname)}function aa(e){let t=Re(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function _r(e){let t=Re(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function ca(e){let t=Re(e).replace(/\\\//g,"/").trim(),r=v.extname(t).toLowerCase();return ws.has(r)||ys.has(r)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function qe(e){return Ei.some(t=>e.pathname.startsWith(t))}function Z(e,t,r=e.sourceOrigin,n,s="url",o=false){let a=aa(t);if(!a||a.startsWith("data:")||a.startsWith("blob:")||a.startsWith("mailto:")||a.startsWith("tel:")||a.startsWith("#"))return n?.ignore(s,t,"empty or unsupported scheme",r),null;if(_r(a))return n?.ignore(s,t,"looks like JavaScript/code fragment",r),null;if(ca(a))return n?.ignore(s,t,"looks like JavaScript property access",r),null;try{let c=new URL(a,r);if(Is(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(!ia(e,c))return n?.ignore(s,c.toString(),"host not allowed",r),null;let i=xs(e,c);if(i&&!(o&&br(c)))return n?.reject(s,c.toString(),i,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 Is(e){try{return decodeURIComponent(e.pathname),decodeURIComponent(e.search),decodeURIComponent(e.hash),!1}catch{return true}}function we(e,t,r,n){try{let s=new URL(e);return Is(s)?(t.reject(r,e,"malformed URL encoding",n),null):mt(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 Ts(e){return ws.has(v.extname(e.pathname).toLowerCase())}function Ie(e){return qe(e)?false:ys.has(v.extname(e.pathname).toLowerCase())}function tt(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function _(e,t){return !!(tt(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(r=>Hr(t.pathname,r))||Ts(t)||!Ie(t)&&!qe(t))}function he(e,t){let r=new URL(t),n=mt(r.pathname);if(n===null)throw new Error(`Unsafe page URL pathname: ${r.pathname}`);return n.endsWith("/")?n+="index.html":v.extname(n)||(n+="/index.html"),ft(e.outputDir,n)}function la(e){if(!e.generated404RequestPath)return null;try{let t=new URL(e.generated404RequestPath,e.sourceOrigin);return !t.pathname.endsWith("/")&&v.extname(t.pathname)===""&&(t.pathname+="/"),t.hash="",t.toString()}catch{return null}}function Xt(e,t){let r=la(e);if(!r)return false;try{return new URL(t,e.sourceOrigin).toString()===r}catch{return false}}function er(e,t){let r=new URL(t),n=mt(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,a=ft(e.outputDir,o),c=Tr(e.targetOrigin,o),i=`${c}${r.search}`;if(!s)return {originalPathname:o,originalFilePath:a,originalPublicUrl:c,originalPublicUrlWithSearch:i,preferQueryHashed:s};let l=v.extname(n),u=`${l?n.slice(0,-l.length):n}.${De(r.search)}${l||".bin"}`;return {originalPathname:o,originalFilePath:a,originalPublicUrl:c,originalPublicUrlWithSearch:i,preferQueryHashed:s,hashedPathname:u,hashedFilePath:ft(e.outputDir,u),hashedPublicUrl:Tr(e.targetOrigin,u)}}function ua(e,t,r,n){let s=we(t,r,"asset",n);return s?er(e,s.toString()):null}function da(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 i of c)try{let l=new URL(i);t[l.origin+o.pathname+o.search]=n;}catch{}try{let i=(()=>{let l=new URL(n,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin);return `${l.pathname}${l.search}`})();t[o.pathname+o.search]=i;}catch{}try{let i=new URL(n,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[o.pathname]=i;}catch{}try{let i=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[o.pathname]=i;}catch{}}catch{}}async function As(e){try{return await D.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Le(e){try{return await D.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function pa(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 Es(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let r=Date.parse(t);return Number.isFinite(r)?r:null}function ga(e,t){let r=Es(t),n=pa(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 ma(e,t){if(!t)return;let r=Es(t);if(r===null)return;let n=await Le(e);if(!n)return;let s=new Date(r);await D.utimes(e,n.atime,s).catch(()=>{});}function ds(e,t){let r=v.extname(e.pathname).toLowerCase(),n=t["content-type"]||"";return Ai.has(r)||Ti.some(s=>n.includes(s))&&!n.startsWith("image/")&&!n.includes("font")}function fa(e){try{let t=v.extname(new URL(e).pathname).toLowerCase();return t===".js"||t===".mjs"}catch{return false}}function Ye(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 ha(e){return De(e.toString("base64"),40)}function wa(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 ya(e,t,r){let n=e.assetVariantDigestsByOriginalPath.get(t);n||(n=new Set,e.assetVariantDigestsByOriginalPath.set(t,n)),n.add(r);}async function Br(e,t,r,n,s,o,a){let c=er(e,r),i=ha(n),l=c.originalFilePath,d=c.originalPublicUrlWithSearch;if(c.preferQueryHashed&&c.hashedFilePath&&c.hashedPublicUrl&&wa(s,c.originalFilePath,i)){let p=Xi(e,t,r);p?(l=p.outputPath,d=p.publicUrl):(l=c.hashedFilePath,d=c.hashedPublicUrl);}da(e,t,r,d,c.originalPublicUrl);let u=$e(l)?Buffer.from(Or(n.toString("utf8"),e,t,l),"utf8"):n,g=await As(l),f=false;return (g===null||!g.equals(u))&&(await Fe(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}),ya(s,c.originalFilePath,i),await ma(l,a),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 We(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 tt(g)?{discoveredFrom:u,discoveredFromType:"sitemap"}:_(e,g)?{discoveredFrom:u,discoveredFromType:"asset"}:Ie(g)&&!qe(g)?{discoveredFrom:u,discoveredFromType:"page"}:{discoveredFrom:u,discoveredFromType:"url"}}catch{return {discoveredFrom:u,discoveredFromType:"url"}}return {discoveredFrom:u,discoveredFromType:"url"}},a=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,c=Z(e,r,a,n,"page");if(!c)return;if(!Ie(c)||Ts(c)){if(_(e,c)){n.info(`Seeded/non-page URL queued as asset: ${c.toString()}`,{url:c.toString(),source:s}),Q(e,t,c.toString(),n,s);return}n.reject("page",c.toString(),qe(c)?"asset/internal path cannot be page":"not page-like",s);return}let i=c.toString(),{discoveredFrom:l,discoveredFromType:d}=o();l&&!t.pageDiscoverySources.has(i)&&t.pageDiscoverySources.set(i,l),!t.donePages.has(i)&&!t.queuedPages.has(i)&&(t.queuedPages.add(i),t.pageQueue.push(i),t.stats.pagesQueued++,n.debug(`Queued discovered page ${i}`,{phase:"discovery",url:i,discoveredFrom:l,discoveredFromType:d,outputPath:he(e,i)}),(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 Q(e,t,r,n,s){let o=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,a=Z(e,r,o,n,"asset");if(!a)return;if(!_(e,a)){n.reject("asset",a.toString(),"not a safe asset path/prefix",s);return}let c=a.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 Yt(e,t,r,n,s){let o=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,a=Z(e,r,o,n,"sitemap",Pn(s));if(!a)return;if(!tt(a)){n.reject("sitemap",a.toString(),"not sitemap-like",s);return}let c=a.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 Sa(e){let t=Re(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:Ue(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 ba(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function Pa(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 Ra(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function va(e,t){if(t==="dom-style")return true;let r=(()=>{try{return v.extname(new URL(e).pathname).toLowerCase()}catch{return ""}})();return !(r===".js"||r===".mjs"||r===".map"||t.includes("javascript"))}function Gt(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function $s(e,t,r,n){let s=[];await D.mkdir(t,{recursive:true});let o=await D.readdir(e,{withFileTypes:true});for(let a of o){let c=v.join(e,a.name),i=v.join(t,a.name);if(a.isDirectory()){s.push(...await $s(c,i,r,n));continue}await Os(c,i,r,n)&&s.push(i);}return s}async function Ca(e,t){try{let[r,n]=await Promise.all([D.stat(e),D.stat(t)]);if(r.size!==n.size)return !1;let[s,o]=await Promise.all([D.readFile(e),D.readFile(t)]);return s.equals(o)}catch{return false}}async function Os(e,t,r,n){let s=v.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 Ca(e,t)?(n.debug("Skipped unchanged post-crawl copy target",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):(await D.mkdir(v.dirname(t),{recursive:true}),await D.copyFile(e,t),true)}async function ka(e,t,r){let n=Object.entries(e.postCrawlCopyMap||{}).map(([c,i])=>({sourcePath:c.trim(),prefix:String(i||"").trim()}));if(n.length===0)return [];let s=0,o=[],a=new Set([...t.donePages].map(c=>v.resolve(he(e,c))));r.mark("copy-extra-paths");for(let c of n){let i=c.sourcePath,l=c.prefix;if(!i||!l){r.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:i,prefixPath:l});continue}let d=Fi(i);if(!d.resolvedPath){r.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:i,alias:d.alias||"",requiredEnv:d.requiredEnv||"",prefixPath:l});continue}let u=d.resolvedPath,g=Gt(l);if(!g){r.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:i,prefixPath:l});continue}let f;try{f=await D.stat(u);}catch{r.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:i,sourceAbs:u,prefixPath:l});continue}let p=v.resolve(e.outputDir,g);if(f.isDirectory()){let w=await $s(u,p,a,r);o.push(...w),s+=w.length,w.length>0&&r.progress(`Copied static directory to export: ${u} -> /${g}`,{phase:"copy-extra-paths",sourcePath:u,targetPath:`/${g}`,copiedItems:s,changedFiles:w.length});continue}let y=v.basename(u),m=l.endsWith("/")?v.join(p,y):p;await Os(u,m,a,r)&&(o.push(m),s++,r.progress(`Copied static file to export: ${u} -> /${Gt(l.endsWith("/")?`${l}${y}`:l)}`,{phase:"copy-extra-paths",sourcePath:u,targetPath:`/${Gt(l.endsWith("/")?`${l}${y}`:l)}`,copiedItems:s}));}return r.endMark("copy-extra-paths",{mappedSources:n.length,copiedItems:s}),o}function et(e,t,r,n,s){let o=new Set,a=Re(r).replace(/\\\//g,"/"),c=s==="page-html"?Ra(a):a,i=va(t,s);if(i){for(let l of Pa(c)){let d=Z(e,l,t,n,`${s}:css-url`);d&&_(e,d)&&o.add(d.toString());}for(let l of c.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let d=Z(e,l[1],t,n,`${s}:css-import`);d&&_(e,d)&&o.add(d.toString());}}if(i||s==="page-html")for(let l of c.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let d=Z(e,l[1],t,n,`${s}:xml-stylesheet`);d&&_(e,d)&&o.add(d.toString());}if(s==="page-html")for(let l of Hn(a)){let d=l.startsWith("//")?`${new URL(e.sourceOrigin).protocol}${l}`:l;if(_r(d)){n.ignore(`${s}:serialized-url`,d,"looks like JavaScript/code fragment",t);continue}let u=Z(e,d,t,n,`${s}:serialized-url`);u&&_(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"&&fa(t))for(let l of zn(a)){if(_r(l)||!/\.(?:js|mjs)(?:[?#]|$)/i.test(l))continue;let d=Z(e,l,t,n,`${s}:relative-asset`);d&&_(e,d)&&o.add(d.toString());}return [...o]}function Ms(e,t,r,n){let s=new Set,o=Re(r);for(let a of o.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let c=a[1],i=Z(e,c,t,n,"page-link");i&&(xs(e,i)||Ie(i)&&!qe(i)&&!_(e,i)&&s.add(i.toString()));}return [...s]}async function ps(e,t,r,n,s,o,a=false,c=[]){let i=new Set(c),l=0,d=new Map,u=(g,f)=>{let p=[f],y=new Set;for(;p.length>0;){let m=p.pop();if(m===g)return true;y.has(m)||(y.add(m),p.push(...d.get(m)??[]));}return false};for(;r.sitemapQueue.length>0;){let g=r.sitemapQueue.shift();r.queuedSitemaps.delete(g);let f=we(g,n,"sitemap","sitemap-queue");if(!f)continue;let p=f.toString();if(r.doneSitemaps.has(p))continue;r.doneSitemaps.add(p),n.sitemap(`Fetching sitemap ${p}`,{url:p});let y=true;try{let m=await t.get(p,{timeout:6e4});if(y=!1,!m.ok()){if(n.skip("sitemap",p,m.status()),a&&!i.has(p))throw new Error(`Required child content-sync sitemap returned HTTP ${m.status()}: ${p}`);continue}let h=await m.body(),w=m.url()||p,k=we(w,n,"sitemap-response",p);if(!k)continue;let I=k.toString();r.successfulSitemaps.add(p),r.successfulSitemaps.add(I),i.has(p)&&(r.resolvedSitemapRoots.add(I),l+=1);let E=await Br(e,r.assetMap,I,h,r,n);ne(s,e,E.outputPath),ke(s,E.outputPath);let $=h.toString("utf8");/<sitemapindex(?:\s|>)/i.test($)?r.sitemapIndexUrls.add(I):r.sitemapLeafUrls.add(I);let C=et(e,I,$,n,"sitemap");for(let b of C)Q(e,r,b,n,I);let S=[];for(let b of Sa($)){let A=Z(e,b.loc,I,n,"sitemap-loc",!0);if(!A){if(a)throw new Error(`Content-sync sitemap contains an inadmissible location: ${b.loc}`);continue}if(tt(A)){if(u(I,A.toString()))throw new Error(`Sitemap index cycle detected: ${I} -> ${A.toString()}`);if(d.has(I)||d.set(I,new Set),d.get(I).add(A.toString()),S.push(A.toString()),a&&r.doneSitemaps.has(A.toString())&&!r.successfulSitemaps.has(A.toString()))throw new Error(`Required child content-sync sitemap was not resolved: ${A.toString()}`);Yt(e,r,A.toString(),n,I);}else if(a){if(Ie(A)&&!_(e,A)){let q=o.requiredUrls.has(A.toString()),T=o.manifest.pages[A.toString()],B=!!T&&!!await Le(T.outputPath);if(!q&&!B)throw new Error(`Content-sync sitemap coverage is incomplete for ${A.toString()}.`)}n.ignore("sitemap-loc",A.toString(),"content-sync sitemap-only traversal does not enqueue urlset locations",I);}else _(e,A)?Q(e,r,A.toString(),n,I):Ie(A)?(b.lastmod&&(r.sitemapLastmodByPage[A.toString()]=b.lastmod),We(e,r,A.toString(),n,I)):n.reject("sitemap-loc",A.toString(),"not page/sitemap/asset-like",I);}o.trackManifest&&(o.manifest.assets[I]={url:I,outputPath:E.outputPath,isText:!0,contentType:m.headers()["content-type"]??"application/xml",cacheControl:qr(m.headers()),changeToken:null,tokenSource:null,discoveredAssets:[...new Set([...C,...S])],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0,rewriteComplete:!1},await xe(e,o));}catch(m){n.error(`Failed sitemap ${p}`,{url:p,error:String(m)});let h=a&&i.has(p)&&y;if(a&&!h)throw m}}if(a&&i.size>0&&l===0)throw new Error(`None of the configured content-sync sitemap roots could be resolved: ${[...i].join(", ")}`)}async function xa(e,t,r,n,s,o,a){let c=Z(e,n,e.sourceOrigin,s,"asset-fetch");if(!c||!_(e,c))return;let i=c.toString();if(r.doneAssets.has(i))return;let l=o.enabled||o.strictTargeted?o.previousManifest.assets[i]:void 0,d=o.trackManifest?await Jt(e,t,o,i,s):null,u=d?.token??null,g=Gn(l?.changeToken,d),f=o.strictTargeted&&(!d?.supported||!d.token)&&Zn(e.sourceOrigin,i),p=o.strictTargeted?o.manifest.assets[i]:void 0;if(p?.lastSeenRunId===o.runId&&await Le(p.outputPath)){r.doneAssets.add(i);for(let m of p.discoveredAssets||[])Q(e,r,m,s,i);ne(a,e,p.outputPath),zt(a,e,p.outputPath,p.cacheControl),p.isText&&ke(a,p.outputPath),s.info(`Resumed completed content-sync asset ${i}`,{url:i,source:"content-sync-checkpoint"}),Ye(r,s);return}if(l&&(g||f)&&await Le(l.outputPath)){o.manifest.assets[i]={...l,changeToken:u,tokenSource:d?.tokenSource??l.tokenSource,discoveredAssets:[...l.discoveredAssets||[]],lastSeenRunId:o.runId,unreferencedRuns:0},delete o.manifest.pages[i],r.doneAssets.add(i);for(let m of l.discoveredAssets||[])Q(e,r,m,s,i);zt(a,e,l.outputPath,l.cacheControl),s.info(`Reused unchanged trusted asset ${i}.`,{url:i,tokenSource:d?.tokenSource??"unknown",phase:"download-assets",source:g?"asset-change-token-match":"content-sync-release-fingerprint"}),Ye(r,s);return}let y=(m,h={})=>{if(!l||o.strictTargeted)return false;o.manifest.assets[i]={...l,discoveredAssets:[...l.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0},delete o.manifest.pages[i],r.doneAssets.add(i);for(let w of l.discoveredAssets||[])Q(e,r,w,s,i);return s.warn(`Keeping previous incremental asset ${i} after fetch issue.`,{url:i,reason:m,preservedFromPreviousManifest:true,...h,phase:"download-assets"}),Ye(r,s),true};s.asset(`Fetching asset ${i}`,{url:i});try{let m=Xe(e,r.assetMap,i),h=m?await Le(m):null;if(m&&h&&!o.strictTargeted)try{let T=await G(`fetch asset headers ${i}`,6e4,()=>t.head(i,{timeout:6e4})),B=T.headers();if(T.ok()&&ga(h,B)){let X=await As(m);if(X!==null){let N=T.url()||i,x=we(N,s,"asset-response",i);if(!x)return;let U=x.toString(),j=await Br(e,r.assetMap,U,X,r,s,B);j.wroteFile&&(ne(a,e,j.outputPath),$e(j.outputPath)&&ke(a,j.outputPath));let P=qr(B)||l?.cacheControl||null;zt(a,e,j.outputPath,P),r.doneAssets.add(i),s.info(`Reused existing asset ${i} based on response headers.`,{url:i,filePath:m,lastModified:B["last-modified"]||"",contentLength:B["content-length"]||"",phase:"download-assets"}),Ye(r,s);let M=ds(c,B),F=l?.discoveredAssets?[...l.discoveredAssets]:[];if(M||l?.isText){let W=X.toString("utf8"),H=et(e,U,W,s,"asset:cached");(H.length>0||!l)&&(F=H);for(let Se of F)Q(e,r,Se,s,U);}if(o.trackManifest){let W=M||!!l?.isText;o.manifest.assets[i]={url:i,outputPath:j.outputPath,isText:W,contentType:Lr(B)||l?.contentType||null,cacheControl:P,changeToken:d?.supported?d.token:null,tokenSource:d?.supported?d.tokenSource??null:null,discoveredAssets:F,lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,unreferencedRuns:0,rewriteComplete:!W},delete o.manifest.pages[i],(o.enabled||o.strictTargeted)&&W&&await xe(e,o);}return}}}catch{}let w=await G(`fetch asset ${i}`,6e4,()=>t.get(i,{timeout:6e4}));if(!w.ok()){if(y(`http-${w.status()}`,{status:w.status()}))return;if(o.strictTargeted)throw new Error(`Required content-sync asset returned HTTP ${w.status()}: ${i}`);s.skip("asset",i,w.status());return}let k=await G(`read asset response ${i}`,6e4,()=>w.body()),I=w.url()||i,E=we(I,s,"asset-response",i);if(!E)return;let $=E.toString(),C=w.headers(),S=await Br(e,r.assetMap,$,k,r,s,C);S.wroteFile&&(ne(a,e,S.outputPath),$e(S.outputPath)&&ke(a,S.outputPath));let b=qr(C);zt(a,e,S.outputPath,b),r.doneAssets.add(i),Ye(r,s);let A=ds(c,C),q=[];if(A){let T=k.toString("utf8");q=et(e,$,T,s,`asset:${v.extname(c.pathname).toLowerCase()||C["content-type"]||"unknown"}`);for(let B of q)Q(e,r,B,s,$);}o.trackManifest&&(o.manifest.assets[i]={url:i,outputPath:S.outputPath,isText:A,contentType:Lr(C),cacheControl:b,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:!A},delete o.manifest.pages[i],(o.enabled||o.strictTargeted)&&A&&await xe(e,o));}catch(m){if(y("fetch-error",{error:String(m)}))return;if(s.error(`Failed asset ${i}`,{url:i,error:String(m)}),o.strictTargeted)throw m}finally{r.doneAssets.has(i)||(r.doneAssets.add(i),Ye(r,s));}}async function Ia(e,t,r,n,s,o){let a=Math.max(1,Number(e.assetDownloadConcurrency||e.concurrency||1)),c=Array.from({length:a},async()=>{for(;r.assetQueue.length>0;){let i=r.assetQueue.shift();i&&(r.queuedAssets.delete(i),await xa(e,t,r,i,n,s,o));}});await Promise.all(c);}function Ta(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function Ce(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function wt(e){return Math.max(15e3,Math.min(6e4,Ce(e)))}function Ds(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function zr(e){return e.stats.pagesCompleted}function Vr(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 Ur(e,t,r){let n=Vr(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 G(e,t,r){let n;try{return await Promise.race([r(),new Promise((s,o)=>{n=globalThis.setTimeout(()=>{o(new St(e,t));},t);})])}finally{n!==void 0&&globalThis.clearTimeout(n);}}var St=class extends Error{constructor(r,n){super(`${r} timed out after ${Ta(n)}.`);this.operation=r;this.timeoutMs=n;this.name="OperationTimeoutError";}operation;timeoutMs};async function Aa(e,t){let r=Ds(e);await t.evaluate(async n=>{await new Promise(s=>{let o=0,a=700,c=Date.now(),i=()=>{window.clearInterval(l),window.scrollTo(0,0),s();},l=window.setInterval(()=>{if(Date.now()-c>=n.maxDurationMs){i();return}window.scrollBy(0,a),o+=a;let d=document.body?.scrollHeight||0,u=document.documentElement?.scrollHeight||0,g=Math.max(d,u);o>=g+window.innerHeight&&i();},120);});},{maxDurationMs:r});}async function Ea(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 Aa(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function $a(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 Fs(e,t){return e.noJavaScriptRenderPathPrefixes.some(r=>Hr(t,r))}async function Oa(e,t,r,n,s=true){let o=new Set;if(s){let c=await t.evaluate(()=>{let i=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(p=>{for(let m of l){let h=p.getAttribute(m);h&&i.add(h);}for(let m of u){let h=p.getAttribute(m);h&&h.split(",").forEach(w=>{let k=w.trim().split(/\s+/)[0];k&&i.add(k);});}let y=p.getAttribute("style");y&&d.add(y),p.shadowRoot&&g(p.shadowRoot);});};return g(document),{attrs:[...i],styles:[...d]}});for(let i of c.attrs)for(let l of ba(i)){let d=Z(e,l,r,n,"dom-attr");d&&_(e,d)&&o.add(d.toString());}for(let i of c.styles)for(let l of et(e,r,i,n,"dom-style"))o.add(l);}let a=await t.content();for(let c of et(e,r,a,n,"page-html"))o.add(c);return [...o]}async function Kr(e,t,r,n,s){let o=he(e,t);await Fe(o,r,"utf8");let a=await D.stat(o);s?.debug(`Saved page output ${t}`,{phase:"save-pages",url:t,outputPath:o,bytes:a.size}),n.stats.pagesSaved++;let c=Math.min(n.stats.pagesQueued,zr(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 js(e){let t=zr(e);return t%5===0||t===1||t===e.stats.pagesQueued}function Us(e,t){let r=zr(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 Ma(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 Da(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 Ma(n),n}async function Fa(e,t,r,n,s,o,a,c,i){for(;t.pageQueue.length>0&&!(e.maxPages>0&&t.donePages.size>=e.maxPages);){let l=t.pageQueue.shift();if(!l)break;t.queuedPages.delete(l);try{let d=we(l,r,"page","page-queue");if(!d)continue;let u=d.toString();if(l=u,t.queuedPages.delete(l),t.donePages.has(l))continue;t.donePages.add(l),o.enabled&&o.seenPages.add(l);let g=Xt(e,l),f=Fs(e,d.pathname);if(!Ie(d)||_(e,d)||qe(d)){if(_(e,d)){r.info(`Remote worker redirected non-page URL to asset queue: ${l}`,{url:l,source:"remote-worker-guard"}),Q(e,t,l,r,"remote-worker-guard");continue}r.reject("page",l,"guard rejected non-page URL before remote rendering","remote-worker");continue}let p=o.strictTargeted?o.manifest.pages[l]:void 0;if(p?.lastSeenRunId===o.runId&&await Le(p.outputPath)){o.seenPages.add(l);for(let C of p.discoveredAssets||[])Q(e,t,C,r,l);ne(a,e,p.outputPath),ke(a,p.outputPath),r.info(`Resumed completed content-sync page ${l}`,{url:l,source:"content-sync-checkpoint"});continue}let y=await Cs(e,s,t,o,l,r);if(o.enabled&&n!=="single-url"&&n!=="content-sync"){let C=o.manifest.pages[l];if(y.action==="reuse"&&C){for(let S of C.discoveredAssets)Q(e,t,S,r,l);for(let S of C.discoveredPages)We(e,t,S,r,l);C.lastSeenRunId=o.runId,C.sitemapLastmod=Ue(t.sitemapLastmodByPage[l])??C.sitemapLastmod,y.changeToken?.supported&&(C.changeToken=y.changeToken.token,C.tokenSource=y.changeToken.tokenSource??C.tokenSource),r.info(`Incremental reuse skipped unchanged page ${l}`,{url:l,mode:"incremental",reason:y.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}r.page(`Rendering remotely ${l}`,{url:l,execution:"lambda"});let m=await i.render({sourceOrigin:e.sourceOrigin,url:l,options:{ignoreHttpsErrors:e.ignoreHttpsErrors,javaScriptEnabled:!f,viewport:e.viewport,navigationTimeoutMs:e.navigationTimeoutMs,autoScrollTimeoutMs:Ds(e),readiness:e.readiness}}),h=m.page,w=h.finalUrl?we(h.finalUrl,r,"remote-final-response",l)?.toString():void 0;if(n==="content-sync"&&w&&w!==u){if(o.deleteOnMissingUrls.has(l)){await bt(e,o,a,l,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive route redirected to ${w}`,{url:l,finalResponseUrl:w,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${l} -> ${w}`)}let k=h.httpStatus;if(g){if(k!==404){r.error(`Generated 404 request path returned unexpected status for ${l}`,{url:l,expectedStatus:404,status:k,requestPath:e.generated404RequestPath,execution:"lambda"});continue}}else if(k!==null&&k>=400){if(n==="content-sync"&&(k===404||k===410)&&o.deleteOnMissingUrls.has(l)){await bt(e,o,a,l,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive page ${l}`,{url:l,status:k,source:"content-sync-tombstone"});continue}if(n==="content-sync")throw new Error(`Required content-sync route returned HTTP ${k}: ${l}`);r.skip("page",l,k,t.pageDiscoverySources.get(l));continue}t.stats.pagesRendered++;let I=new Set(et(e,u,m.html,r,"remote-page-html"));for(let C of [...h.discoveredAssets,...h.networkUrls]){let S=Z(e,C,u,r,"remote-render");S&&_(e,S)&&I.add(S.toString());}for(let C of I)Q(e,t,C,r,l);let E=n!=="single-url"&&n!=="content-sync"&&!g?[...new Set([...Ms(e,l,m.html,r),...h.discoveredPages])]:[];for(let C of E)We(e,t,C,r,l);for(let C of h.cookies){let S=C.sameSite==="Strict"||C.sameSite==="Lax"||C.sameSite==="None"?C.sameSite:"Unspecified",b=!Number.isFinite(C.expires)||C.expires<=0;c.add({name:C.name,domain:C.domain,path:C.path||"/",expires:b?null:C.expires,session:b,secure:C.secure,httpOnly:C.httpOnly,sameSite:S,partitioned:C.partitioned===!0});}await Kr(e,l,m.html,t,r);let $=he(e,l);ne(a,e,$),ke(a,$),o.trackManifest&&(o.manifest.pages[l]={url:l,outputPath:$,contentType:h.contentType?.trim()||null,changeToken:y.changeToken?.supported?y.changeToken.token:null,tokenSource:y.changeToken?.supported?y.changeToken.tokenSource??null:null,sitemapLastmod:Ue(t.sitemapLastmodByPage[l])??null,discoveredPages:E,discoveredAssets:[...I],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,rewriteComplete:!1},(o.enabled||o.strictTargeted)&&await xe(e,o)),r.debug(`Remote render completed ${l}`,{url:l,taskId:m.taskId,attempts:m.attempts,execution:"lambda"});}catch(d){if(r.error(`Failed remote page ${l}`,{url:l,error:String(d),execution:"lambda"}),o.strictTargeted)throw d}finally{t.stats.pagesCompleted++,js(t)&&Us(t,r);}}}async function ja(e,t,r,n,s,o,a,c){let i=await chromium.launch({headless:true}),l=Vr(i);l.pid!==null&&r.debug(`Launched crawl worker browser PID ${l.pid}`,{browserPid:l.pid});try{for(;t.pageQueue.length>0;){i||(i=await chromium.launch({headless:!0}),l=Vr(i),l.pid!==null&&r.debug(`Relaunched crawl worker browser PID ${l.pid}`,{browserPid:l.pid}));let d=i;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,p=!1,y=[],m=new Set;try{let h=we(u,r,"page","page-queue");if(!h)continue;let w=h.toString();if(u=w,t.queuedPages.delete(u),t.donePages.has(u))continue;t.donePages.add(u),o.enabled&&o.seenPages.add(u);let k=Xt(e,u),I=Fs(e,h.pathname);if(!Ie(h)||_(e,h)||qe(h)){if(_(e,h)){r.info(`Worker redirected non-page URL to asset queue: ${u}`,{url:u,source:"worker-guard"}),Q(e,t,u,r,"worker-guard");continue}r.reject("page",u,"guard rejected non-page URL before rendering","worker");continue}let E=o.strictTargeted?o.manifest.pages[u]:void 0;if(E?.lastSeenRunId===o.runId&&await Le(E.outputPath)){o.seenPages.add(u);for(let x of E.discoveredAssets||[])Q(e,t,x,r,u);ne(a,e,E.outputPath),ke(a,E.outputPath),r.info(`Resumed completed content-sync page ${u}`,{url:u,source:"content-sync-checkpoint"});continue}let $=await Cs(e,s,t,o,u,r);if(o.enabled&&n!=="single-url"&&n!=="content-sync"){let x=o.manifest.pages[u];if($.action==="reuse"&&x){for(let U of x.discoveredAssets)Q(e,t,U,r,u);for(let U of x.discoveredPages)We(e,t,U,r,u);x.lastSeenRunId=o.runId,x.sitemapLastmod=Ue(t.sitemapLastmodByPage[u])??x.sitemapLastmod,$.changeToken?.supported&&(x.changeToken=$.changeToken.token,x.tokenSource=$.changeToken.tokenSource??x.tokenSource),r.info(`Incremental reuse skipped unchanged page ${u}`,{url:u,mode:"incremental",reason:$.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}g=await G(`create page context ${u}`,Ce(e),()=>Da(d,e,I)),f=await G(`create page ${u}`,Ce(e),()=>g.newPage()),y=await g.cookies();let C=!1,S=new Set;await f.route("**/*",async x=>{let U=x.request();try{let j=Z(e,U.url(),e.sourceOrigin,r,"network-request");j&&_(e,j)&&(S.add(j.toString()),Q(e,t,j.toString(),r,u));}catch{}if(U.isNavigationRequest()&&U.frame()===f.mainFrame())try{let j=new URL(U.url()),P=new URL(w);if(j.hash="",P.hash="",j.href===P.href){if(C){r.warn(`Blocked same-page navigation/reload for ${u}`,{url:u,requestUrl:U.url()});try{await x.abort("aborted");}catch(M){r.debug(`Ignored canceled route while blocking reload for ${u}`,{url:u,error:String(M)});}return}C=!0;}}catch{}try{await x.continue();}catch(j){r.debug(`Ignored canceled network route for ${u}`,{url:u,requestUrl:U.url(),error:String(j)});}}),f.on("response",x=>{try{let j=Z(e,x.url(),e.sourceOrigin,r,"network-response");j&&_(e,j)&&(S.add(j.toString()),Q(e,t,j.toString(),r,u));}catch{}let U=x.headerValues("set-cookie").then(j=>{for(let P of j)c.add(es(P,x.url()));}).catch(()=>{}).then(()=>{});m.add(U),U.finally(()=>m.delete(U));}),r.page(`Rendering ${u}`,{url:u});let b=null,A=null;try{if(b=await f.goto(u,{waitUntil:"domcontentloaded",timeout:e.navigationTimeoutMs}),b&&b.ok())try{A=await G(`read response body ${u}`,Ce(e),()=>b.text());}catch{A=null;}}catch(x){r.warn(`Navigation issue for ${u}; saving current DOM if available`,{url:u,error:String(x)});}if(n==="content-sync"&&b){let x=we(b.url(),r,"content-sync-final-response",u)?.toString();if(x&&x!==w){if(o.deleteOnMissingUrls.has(u)){await bt(e,o,a,u,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive route redirected to ${x}`,{url:u,finalResponseUrl:x,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${u} -> ${x}`)}}if(k){let x=b?.status()??null;if(x!==404){r.error(`Generated 404 request path returned unexpected status for ${u}`,{url:u,expectedStatus:404,status:x,requestPath:e.generated404RequestPath});continue}r.info(`Capturing rendered 404 page for ${u}`,{url:u,status:x,outputPath:he(e,u)});}else if(b&&!b.ok()){if(n==="content-sync"&&(b.status()===404||b.status()===410)&&o.deleteOnMissingUrls.has(u)){await bt(e,o,a,u,o.deleteOnMissingUrls),r.info(`Removed stale content-sync archive page ${u}`,{url:u,status:b.status(),source:"content-sync-tombstone"}),await f.close();continue}if(n==="content-sync")throw new Error(`Required content-sync route returned HTTP ${b.status()}: ${u}`);r.skip("page",u,b.status(),t.pageDiscoverySources.get(u)),await f.close();continue}I?(r.info(`Rendering without JS execution for ${u}`,{url:u,mode:"no-js"}),await G(`wait for rendered page ${u}`,Ce(e),()=>$a(e,f))):await G(`wait for rendered page ${u}`,Ce(e),()=>Ea(e,f)),t.stats.pagesRendered++;let q=await G(`extract rendered assets ${u}`,Ce(e),()=>Oa(e,f,w,r,!I));for(let x of q)Q(e,t,x,r,u);let T=[...new Set([...q,...S])],B=A??await G(`capture rendered html ${u}`,Ce(e),()=>f.content()),X=n!=="single-url"&&n!=="content-sync"&&!k?Ms(e,u,B,r):[];if(n!=="single-url"&&n!=="content-sync"&&!k)for(let x of X)We(e,t,x,r,u);await Kr(e,u,B,t,r);let N=he(e,u);if(ne(a,e,N),ke(a,N),o.trackManifest){let x=b?.headers();o.manifest.pages[u]={url:u,outputPath:N,contentType:Lr(x),changeToken:$.changeToken?.supported?$.changeToken.token:null,tokenSource:$.changeToken?.supported?$.changeToken.tokenSource??null:null,sitemapLastmod:Ue(t.sitemapLastmodByPage[u])??null,discoveredPages:X,discoveredAssets:T,lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,rewriteComplete:!1},(o.enabled||o.strictTargeted)&&await xe(e,o);}}catch(h){if(p=h instanceof St,o.strictTargeted)throw r.error(`Failed required content-sync page ${u}`,{url:u,error:String(h)}),h;if(p)r.warn(`Skipped partial DOM for timed-out page ${u}`,{url:u,error:String(h),recovery:"recycle-worker-browser"});else try{let w=f?await G(`capture partial html ${u}`,Ce(e),()=>f.content()):"";if(w&&w.trim()){await Kr(e,u,w,t,r);let k=he(e,u);if(ne(a,e,k),ke(a,k),o.trackManifest){let I=o.manifest.pages[u]??o.previousManifest.pages[u];o.manifest.pages[u]={url:u,outputPath:k,contentType:I?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:Ue(t.sitemapLastmodByPage[u])??I?.sitemapLastmod??null,discoveredPages:I?.discoveredPages?[...I.discoveredPages]:[],discoveredAssets:I?.discoveredAssets?[...I.discoveredAssets]:[],lastCrawledAt:new Date().toISOString(),lastSeenRunId:o.runId,rewriteComplete:!1},(o.enabled||o.strictTargeted)&&await xe(e,o);}r.warn(`Saved partial DOM for ${u}`,{url:u,error:String(h)});}}catch(w){w instanceof St&&(p=!0),r.error(`Could not save partial DOM for ${u}`,{url:u,error:String(w)});}r.error(`Failed page ${u}`,{url:u,error:String(h)});}finally{if(!p&&f&&await G(`drain network routes ${u}`,wt(e),()=>f.unrouteAll({behavior:"wait"})).catch(h=>{p=!0,r.warn(`Could not drain network routes for ${u}`,{url:u,browserPid:l.pid,error:String(h),recovery:"recycle-worker-browser"});}),p&&(i=null,await Ur(d,r,`page operation timeout for ${u}`),await d.close().catch(()=>{})),m.size>0&&await Promise.allSettled([...m]),!p&&g)try{let h=await g.cookies();c.addAll(ts(y,h));}catch{}t.stats.pagesCompleted++,js(t)&&Us(t,r),!p&&f&&await G(`close page ${u}`,wt(e),()=>f.close()).catch(h=>{p=!0,r.warn(`Timed out while closing page ${u}`,{url:u,browserPid:l.pid,error:String(h),recovery:"recycle-worker-browser"});}),!p&&g&&await G(`close page context ${u}`,wt(e),()=>g.close()).catch(h=>{p=!0,r.warn(`Timed out while closing page context for ${u}`,{url:u,browserPid:l.pid,error:String(h),recovery:"recycle-worker-browser"});}),p&&i===d&&(i=null,await Ur(d,r,`page cleanup timeout for ${u}`),await d.close().catch(()=>{}));}}}finally{if(i){let d=i;await G("close worker browser",wt(e),()=>d.close()).catch(u=>(r.warn("Timed out while closing crawl worker browser",{browserPid:l.pid,error:String(u)}),Ur(d,r,"browser.close timeout")));}}}async function Ua(e){try{let t=await D.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 gs(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function La(e){let t=String(e?.job?.command||"").trim(),r=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:r!=="incremental"}function qa(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 Ls(e){try{let t=await D.readFile(e,"utf8"),r=JSON.parse(t);return r&&typeof r=="object"&&!Array.isArray(r)?r:null}catch{return null}}function ms(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function Wa(e,t){let r=Array.isArray(t?.artifacts)?t.artifacts.filter(n=>String(n?.role||"").trim()==="errors"&&String(n?.storedFileName||"").trim()!=="").sort((n,s)=>ms(n)-ms(s)).map(n=>v.join(e,String(n.storedFileName))):[];return [...new Set([...r,v.join(e,"errors.jsonl"),v.join(e,"errors.json"),v.join(e,"errors.jsonl.gz"),v.join(e,"errors.json.gz")])]}async function fs(e){let t=await Ls(v.join(e,"job.json"));for(let r of Wa(e,t)){let n=await Ua(r);if(n.length>0)return n}return []}async function Na(e){let t=v.join(e.logDir,"archive"),r;try{r=await D.readdir(t);}catch{return ""}let n="",s=0;for(let o of r){let a=v.join(t,o);if(!(await D.stat(a).catch(()=>null))?.isDirectory())continue;let i=await Ls(v.join(a,"job.json"));if(!La(i))continue;let l=qa(i);l>=s&&(s=l,n=a);}return n}async function _a(e){let t=await Na(e),r=t!==""?await fs(t):await fs(e.logDir),n=new Set;for(let s of r)if(gs(s.error)||gs(s.message)){let o=s.url;typeof o=="string"&&o&&n.add(o);}return [...n]}async function Ba(e){let t=[];for(let r of e)if(r.startsWith("@")){let n=r.slice(1),s=await D.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 Va(e){if(!e)throw new Error("Content-sync crawl requires an immutable impact plan.");let t=JSON.parse(await D.readFile(e,"utf8"));return lt(t),t}function Ka(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(/\/+$/,""),a=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(a)})}function ht(e,t,r){let n=r==="page"?he(e,t):er(e,t).originalFilePath;return ge(e.outputDir,n)}async function bt(e,t,r,n,s){let o=t.manifest.pages[n];if(!o)return;let a=ge(e.outputDir,o.outputPath);if(!a)throw new Error(`Manifest-owned page path escaped output root: ${n}`);let c=v.resolve(o.outputPath);Object.entries(t.manifest.pages).some(([l,d])=>l!==n&&!s.has(l)&&v.resolve(d.outputPath)===c)||(await D.rm(o.outputPath,{force:true}),r.deletedFiles.add(a),r.revalidateFiles.delete(a)),delete t.manifest.pages[n];}async function Ha(e,t,r,n,s){let o=t.manifest.assets[n];if(!o)return;let a=ge(e.outputDir,o.outputPath);if(!a)throw new Error(`Manifest-owned resource path escaped output root: ${n}`);let c=v.resolve(o.outputPath);Object.entries(t.manifest.assets).some(([l,d])=>l!==n&&!s.has(l)&&v.resolve(d.outputPath)===c)||(await D.rm(o.outputPath,{force:true}),r.deletedFiles.add(a)),delete t.manifest.assets[n];}function za(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 a of o?.discoveredAssets??[])try{tt(new URL(a))&&n.push(a);}catch{}}return r}async function Qa(e,t,r,n,s){let o=za(r.previousManifest,s);for(let a of o){if(t.successfulSitemaps.has(a))continue;let c=r.previousManifest.assets[a];if(!c)continue;let i=ge(e.outputDir,c.outputPath);if(!i)throw new Error(`Manifest-owned sitemap path escaped output root: ${a}`);await D.rm(c.outputPath,{force:true}),n.deletedFiles.add(i),delete r.manifest.assets[a];}await xe(e,r);}async function Ja(e){try{let t=await D.readFile(v.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function Ga(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 D.mkdir(e,{recursive:true}),await Promise.all(t.map(async r=>{try{await D.unlink(v.join(e,r));}catch(n){if(n.code!=="ENOENT")throw n}}));}function hs(e,t,r,n,s){let o=Z(e,r,e.sourceOrigin,n,"manual-url");o&&(tt(o)?Yt(e,t,o.toString(),n,s):_(e,o)?Q(e,t,o.toString(),n,s):Ie(o)?We(e,t,o.toString(),n,s):n.reject("manual-url",o.toString(),"not page/sitemap/asset-like",s));}async function qs(e=process.argv.slice(2)){let t=[],r=await ue(void 0,{onRemotePublisherConfigDiagnostic:P=>{t.push(P);}}),n=dt(r.sitemapPaths),s=t.at(-1)??null,o=$i(e),a=o.mode==="content-sync"?await Va(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 _a(r)),o.mode==="single-url"&&(c=await Ba(o.urls)),a&&(c=[...a.directRenderUrls,...a.archiveFamilyUrls,...a.resourceRenderUrls]);let i=o.crawlMode==="incremental"&&o.mode==="full",l=i&&typeof r.subscriptionType=="string"&&r.subscriptionType.trim()!=="";if(a&&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 Ja(r):{},f=l||o.mode==="single-url"||o.mode==="content-sync"?await qi(r):bs(),p=new Set(c),y=new Set;if(a){for(let P of a.archiveFamilies)if(P.foundPosts===0)for(let M of P.pageUrls)y.add(M);for(let P of Object.keys(f.pages))Ka(P,a)&&!p.has(P)&&(c.push(P),y.add(P));}let m={enabled:l,trackManifest:d,manifest:Nr(f),previousManifest:Nr(f),runId:a?.jobId??`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,pageChangeTokenPrimePromise:null,manifestSaveChain:Promise.resolve(),strictTargeted:!!a,requiredUrls:p,deleteOnMissingUrls:y};await Ga(r.logDir);let h=new Ut(r.logDir,r.logLevel),w=o.remoteRender??r.remoteWorkers?.render?.enabled===true,k=Ht({explicitPath:o.remoteWorkerConfigPath,runtimeDir:Pt()}),I=null,E=null,$=Math.max(1,r.concurrency),C=r.remoteWorkers?.rewrite?.enabled===true;if(w&&!o.resumeRewrite||C){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 P=await Bt(k);E=new Ze(P);}if(w&&!o.resumeRewrite){if(!E)throw new Error("Remote render worker client was not initialized.");I=new Vt({client:E,jobId:`crawl-${De(m.runId,40)}`,maxAttempts:r.remoteWorkers?.render?.maxAttempts??2,onRetry:P=>{h.warn(`Retrying remote render for ${P.url}`,{url:P.url,attempt:P.attempt,maxAttempts:P.maxAttempts,reason:P.reason,execution:"lambda"});}}),$=Math.max(1,Math.min(100,r.remoteWorkers?.render?.concurrency??r.concurrency)),h.info("Lambda page rendering is enabled.",{remoteWorkerConfigPath:v.resolve(k),concurrency:$,maxAttempts:r.remoteWorkers?.render?.maxAttempts??2,batchSize:1,execution:"lambda"});}if(s){let P={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?h.info("Loaded remote WP Suite publisher configuration.",P):h.warn("Remote WP Suite publisher configuration is unavailable or has no active subscription type.",P);}if(i&&!l){let P="Incremental crawl requires an active remote publisher subscription; refusing to fall back to a destructive full crawl.";throw h.error(P,{requestedMode:o.crawlMode,subscriptionType:r.subscriptionType??null,source:"incremental-subscription-guard"}),await h.flush(),new Error(P)}let S={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}},b=Li(),A=new qt,q=Oi();if(q&&!o.resumeRewrite&&await Wt(q,A.artifact()),await Me(r),await En(r,{startedAt:new Date().toISOString(),outputDir:v.resolve(r.outputDir)}),u||await D.rm(r.outputDir,{recursive:true,force:true}),await D.mkdir(r.outputDir,{recursive:true}),a){let P=new Set([...a.deleteUrls,...m.deleteOnMissingUrls]);for(let F of a.deleteUrls)await bt(r,m,b,F,P);let M=new Set(a.resourceDeleteUrls);for(let F of a.resourceDeleteUrls)await Ha(r,m,b,F,M);}if(o.resumeRewrite)h.info("Resuming final rewrite from existing output.",{phase:"rewrite-text",mode:o.mode,crawlMode:o.crawlMode});else {let P=await request.newContext({ignoreHTTPSErrors:r.ignoreHttpsErrors});try{if(h.mark("discovery"),o.mode==="full"?(n.forEach(F=>Yt(r,S,F,h)),await ps(r,P,S,h,b,m),r.seedPaths.forEach(F=>hs(r,S,F,h,"seed-path")),r.generated404RequestPath&&We(r,S,r.generated404RequestPath,h,"generated-404-request-path")):(c.forEach(F=>hs(r,S,F,h,"cli")),a?.sitemapUrls.forEach(F=>Yt(r,S,F,h,"content-sync-impact")),await ps(r,P,S,h,b,m,o.mode==="content-sync",a?.sitemapUrls??[]),a&&await Qa(r,S,m,b,a.sitemapUrls)),h.endMark("discovery",{pages:S.pageQueue.length,assets:S.assetQueue.length,sitemaps:S.sitemapQueue.length}),h.summary(`Queued ${S.pageQueue.length} pages, ${S.assetQueue.length} assets, ${S.sitemapQueue.length} sitemaps.`,{mode:o.mode,crawlMode:o.crawlMode,queuedPages:S.pageQueue.length,queuedAssets:S.assetQueue.length,queuedSitemaps:S.sitemapQueue.length}),o.mode==="retry-timeouts"&&S.pageQueue.length===0&&S.assetQueue.length===0&&S.sitemapQueue.length===0){h.summary("No timed-out URLs were queued. Skipping retry crawl.",{mode:o.mode,crawlMode:o.crawlMode,queuedPages:0,queuedAssets:0,queuedSitemaps:0}),await h.flush(),q&&await Wt(q,A.artifact());return}h.mark("render-pages");let M=Array.from({length:$},()=>I?Fa(r,S,h,o.mode,P,m,b,A,I):ja(r,S,h,o.mode,P,m,b,A));if(await Promise.all(M),q&&await Wt(q,A.artifact()),h.endMark("render-pages",{pages:S.stats.pagesCompleted}),h.mark("download-assets"),h.progress("Asset download phase started.",{phase:"download-assets",doneAssets:S.doneAssets.size,assetsQueued:S.stats.assetsQueued,assetQueue:S.assetQueue.length}),await Rs(r,P,m,[...S.assetQueue],h),await Ia(r,P,S,h,m,b),h.endMark("download-assets",{assets:S.doneAssets.size}),m.enabled&&r.maxPages===0&&(await Hi(r,S,m,h,b),o.mode==="full"&&await zi(r,m,h,b)),o.mode==="full"){let F=await ka(r,S,h);for(let W of F)ne(b,r,W);}}finally{await G("dispose crawl request context",wt(r),()=>P.dispose()).catch(M=>{h.warn("Timed out while disposing crawl request context",{error:String(M)});});}}m.trackManifest&&await xe(r,m),await D.writeFile(v.join(r.outputDir,"asset-map.json"),JSON.stringify(S.assetMap,null,2),"utf8"),JSON.stringify(g,null,2)!==JSON.stringify(S.assetMap,null,2)&&ne(b,r,v.join(r.outputDir,"asset-map.json"));let T=o.mode==="single-url"||o.mode==="content-sync"?ra(r,S):m.enabled&&!o.resumeRewrite?Qi(r,m,b,g,S.assetMap):void 0;h.mark("rewrite-text");let B=o.mode==="single-url"||o.mode==="content-sync"?`Rewriting text files touched by URL crawl: 0/${T?.length??0}`:"Rewriting text files...";h.progress(B,{phase:"rewrite-text",index:0,totalFiles:T?.length,changedTextFiles:0}),await jr(B);let X=Date.now(),N={files:T,previousAssetMap:g,onStart:({totalFiles:P,workerCount:M})=>{h.info(`Rewrite phase scanning ${P} text files.`,{phase:"rewrite-text",totalFiles:P,workerCount:M});},onProgress:async({index:P,totalFiles:M,changedTextFiles:F,file:W,changed:H})=>{H&&ne(b,r,v.join(r.outputDir,W)),h.checkpoint(`Rewriting text file ${P}/${M}`,{phase:"rewrite-text",index:P,totalFiles:M,changedTextFiles:F,file:W}),h.debug(`${H?"Rewrote":"Checked unchanged"} text file ${P}/${M}: ${W}`,{phase:"rewrite-text",index:P,totalFiles:M,changedTextFiles:F,file:W,changed:H});let Se=Date.now();if(!(P===1||P===M||P%50===0||Se-X>=5e3))return;X=Se;let _e=`Rewriting text files: ${P}/${M}`;h.progress(_e,{phase:"rewrite-text",index:P,totalFiles:M,changedTextFiles:F,file:W}),await jr(_e);}},x=C&&E?await Kt(r,S.assetMap,{client:E,jobId:`crawl-${De(m.runId,40)}`,concurrency:r.remoteWorkers?.rewrite?.concurrency??r.rewriteConcurrency,batchSize:r.remoteWorkers?.rewrite?.batchSize??25,maxAttempts:r.remoteWorkers?.rewrite?.maxAttempts??2,onStageProgress:async({index:P,totalFiles:M,file:F})=>{let W=Date.now();if(P!==1&&P!==M&&P%25!==0&&W-X<5e3)return;X=W;let H=`Staging text files for Lambda rewrite: ${P}/${M}`;h.progress(H,{phase:"rewrite-stage",index:P,totalFiles:M,file:F,execution:"lambda"}),await jr(H);},options:N}):await Dt(r,S.assetMap,N);m.trackManifest&&(Ji(m,T),await xe(r,m)),h.endMark("rewrite-text",{changedTextFiles:x});let U=a?[...b.deletedFiles].sort():m.enabled&&!o.resumeRewrite?await Zi(r,S,m,b,h):[],j=[...new Set((T||[]).map(P=>ge(r.outputDir,v.isAbsolute(P)?P:v.join(r.outputDir,P))).filter(P=>P!==null))].sort();if(a){let P=[...b.changedFiles].sort(),M=new Set(P),F=new Set(a.directRenderUrls.map(R=>ht(r,R,"page")).filter(R=>!!R&&M.has(R))),W=new Set(a.archiveFamilyUrls.map(R=>ht(r,R,"page")).filter(R=>!!R&&M.has(R))),H=new Set(a.resourceRenderUrls.map(R=>ht(r,R,"asset")).filter(R=>!!R&&M.has(R))),Se=new Set([...S.sitemapLeafUrls].map(R=>ht(r,R,"asset")).filter(R=>!!R&&M.has(R))),st=new Set([...S.sitemapIndexUrls].map(R=>ht(r,R,"asset")).filter(R=>!!R&&M.has(R))),_e=new Set([...F,...W,...H,...Se,...st]),ur=P.filter(R=>!_e.has(R)),dr=[...new Set([...a.directRenderUrls,...a.archiveFamilyUrls,...S.resolvedSitemapRoots,...S.sitemapLeafUrls,...S.sitemapIndexUrls,...a.deleteUrls,...a.resourceRenderUrls,...a.resourceDeleteUrls].map(R=>{let V=new URL(R);return `${V.pathname}${V.search}`}))].sort();await Ir(r,{schemaVersion:2,generatedAt:new Date().toISOString(),outputDir:v.resolve(r.outputDir),runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,changedFiles:P,deletedFiles:U,rewriteTargets:j,revalidateFiles:[...b.revalidateFiles].sort(),consumerId:a.consumerId,fromSequence:a.fromSequence,toSequence:a.toSequence,impactHash:a.impactHash,resolvedSitemapUrls:[...S.resolvedSitemapRoots],uploadGroups:{assets:ur,content:[...F].sort(),listings:[...W].sort(),resources:[...H].sort(),sitemapLeaves:[...Se].sort(),sitemapIndexes:[...st].reverse()},invalidationPaths:dr});}else await Ir(r,{schemaVersion:1,generatedAt:new Date().toISOString(),outputDir:v.resolve(r.outputDir),runMode:o.mode,crawlMode:o.crawlMode,fullSyncRequired:!(m.enabled&&!o.resumeRewrite),changedFiles:m.enabled&&!o.resumeRewrite?[...b.changedFiles].sort():[],deletedFiles:m.enabled&&!o.resumeRewrite?U:[],rewriteTargets:m.enabled&&!o.resumeRewrite?j:[],revalidateFiles:[...b.revalidateFiles].sort()});await On(r),h.summary(o.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${x} text files.`:`Done. Rendered ${S.stats.pagesRendered} pages, processed ${S.doneSitemaps.size} sitemaps and ${S.doneAssets.size} assets.`,{mode:o.mode,crawlMode:o.crawlMode,resumeRewrite:o.resumeRewrite,...S.stats,pagesRendered:S.stats.pagesRendered,donePages:S.stats.pagesCompleted,claimedPages:S.donePages.size,doneSitemaps:S.doneSitemaps.size,doneAssets:S.doneAssets.size,changedTextFiles:x}),await h.flush();}function Za(e){let t=e/6e4;if(Number.isInteger(t)&&t>=1)return `${t} minute${t===1?"":"s"}`;let r=Math.ceil(e/1e3);return `${r} second${r===1?"":"s"}`}async function oe(e,t,r){let n=new AbortController,s=globalThis.setTimeout(()=>{n.abort(new Error(`${e} timed out after ${Za(t)}.`));},t);try{return await r({abortController:n,httpOptions:{abortSignal:n.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(s);}}function Ya(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function tr(e){let t="";for(let n=0;n<e.length;n++){let s=e[n];if(s==="--profile"){let o=(e[n+1]||"").trim();if(!o)throw new Error("Missing value for --profile.");t=o,n+=1;}else if(s.startsWith("--profile=")){let o=s.slice(10).trim();if(!o)throw new Error("Missing value for --profile.");t=o;}}let r=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return t||r||null}function Xa(e,t){return {...e,...t??{}}}function ec(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function rt(e,t){let r=String(t??e.deploymentTargetOverride??"").trim();if(!Ya(e)){if(r)throw new Error(`Deployment target "${r}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:e}}let n=String(r||e.defaultDeploymentProfile||"").trim();if(!n)return {name:null,profile:null,config:e};let s=e.deploymentProfiles?.[n];if(!s)throw new Error(`Unknown deployment profile "${n}". Check the linked WPSuite publisher configuration.`);return {name:n,profile:s,config:{...e,targetOrigin:s.targetOrigin??e.targetOrigin,s3:Xa(e.s3,s.s3),cloudFront:ec(e.cloudFront,s.cloudFront)}}}var Ks="wpsuite-sha256",Hs="wpsuite-normalized-sha256",zs="public, max-age=0, must-revalidate",cc=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,Gr=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,lc=["SIGINT","SIGTERM"],sr=new Set,rr=new Map,Ws=null;function uc(e){sr.add(e);let t=false;return ()=>{t||(t=true,sr.delete(e));}}async function dc(){let e=[...sr];e.length!==0&&await Promise.allSettled(e.map(async t=>{sr.delete(t),await D.rm(t,{recursive:true,force:true});}));}function pc(){if(!(rr.size>0))for(let e of lc){let t=()=>{Ws||(Ws=dc().finally(()=>{for(let[r,n]of rr)process.off(r,n);rr.clear(),process.exit(1);}));};rr.set(e,t),process.on(e,t);}}pc();function gc(e,t){let r=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(r)return v.resolve(r);let n=t.trim();return n?v.join(v.resolve(n),"crawl-manifest.json"):v.join(v.resolve(e),".crawl-manifest.json")}function Rt(e){return v.normalize(e).split(v.sep).join("/")}function Ns(e,t){let r=v.relative(v.resolve(e),v.resolve(t));return !r||r.startsWith("..")||v.isAbsolute(r)?null:Rt(r)}async function mc(e,t,r){let n=gc(e.outputDir,t),s;try{s=await D.readFile(n,"utf8");}catch(d){return d.code==="ENOENT"?(r.warn("Deploy rewrite guard disabled because the crawl manifest is missing.",{manifestPath:n,source:"deploy-guard"}),null):(r.warn("Deploy rewrite guard disabled because the crawl manifest could not be read.",{manifestPath:n,error:d instanceof Error?d.message:String(d),source:"deploy-guard"}),null)}let o;try{o=JSON.parse(s);}catch(d){return r.warn("Deploy rewrite guard disabled because the crawl manifest is invalid JSON.",{manifestPath:n,error:d instanceof Error?d.message:String(d),source:"deploy-guard"}),null}let a=new Map,c=new Map,i=0,l=0;for(let[d,u]of Object.entries(o.pages||{})){let g=String(u?.outputPath||"").trim(),f=g?Ns(e.outputDir,g):null;if(f){let p=typeof u?.contentType=="string"&&u.contentType?u.contentType:null;p&&c.set(f,p);}!g||u?.rewriteComplete===true||f&&(i++,a.has(f)||a.set(f,{kind:"page",sourceUrl:d,outputPath:v.resolve(g),relativePath:f}));}for(let[d,u]of Object.entries(o.assets||{})){let g=String(u?.outputPath||"").trim(),f=u?.isText===true,p=g?Ns(e.outputDir,g):null;if(p){let y=typeof u?.contentType=="string"&&u.contentType?u.contentType:null;y&&c.set(p,y);}!g||!f||u?.rewriteComplete===true||p&&(l++,a.has(p)||a.set(p,{kind:"asset",sourceUrl:d,outputPath:v.resolve(g),relativePath:p}));}return {manifestPath:n,byRelativePath:a,contentTypeByRelativePath:c,pendingPages:i,pendingTextAssets:l}}function fc(e){return e&&(Gr.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)?"__hex__":/^[0-9]{8,}$/.test(e)?"__num__":/^(?=.*[a-z])(?=.*\d)[a-z0-9]{8,}$/i.test(e)?"__alnum__":e)}function Qr(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,r)=>r%2===1?t:fc(t)).join("")}function hc(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,r)=>r%2===1?t:Gr.test(t)?"__uuid__":/^[0-9a-f]{6,}$/i.test(t)?"__hex__":/^[0-9]{6,}$/.test(t)?"__num__":/^[a-z0-9_-]{6,}$/i.test(t)?"__id__":t).join("")}function or(e,t){return Array.isArray(e)?e.map(r=>or(r,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([r,n])=>[r,or(n,r)])):typeof e!="string"?e:t&&cc.test(t)?hc(e):Gr.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?Qr(e):e}function wc(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function yc(e,t){let r=t.trim();if((r.startsWith("{")||r.startsWith("[")||r.startsWith('"'))&&e.startsWith("data-"))try{let s=JSON.parse(r);return JSON.stringify(or(s))}catch{}if(e.startsWith("data-")&&/^[A-Za-z0-9+/=]+$/.test(r))try{let s=Buffer.from(r,"base64").toString("utf8"),o=JSON.parse(s),a=JSON.stringify(or(o));return Buffer.from(a,"utf8").toString("base64")}catch{}return t}function Sc(e,t){let r=e.toLowerCase();return r==="class"?t.split(/(\s+)/).map((n,s)=>s%2===1?n:Qr(n)).join(""):r==="id"||r==="for"||r==="aria-controls"||r==="aria-labelledby"||r==="aria-describedby"||r==="aria-owns"||r==="aria-activedescendant"||r==="name"?Qr(t):r==="href"||r==="src"?wc(t):yc(r,t)}function bc(e){return e.replace(/<([a-z][^\s/>]*)([^<>]*?)>/gi,(t,r,n)=>{if(r.startsWith("/"))return t;let s=n.replace(/\s([:@a-zA-Z_][-:.a-zA-Z0-9_]*?)=(['"])([\s\S]*?)\2/g,(o,a,c,i)=>{let l=Sc(a,i);return ` ${a}=${c}${l}${c}`});return `<${r}${s}>`})}function vt(e){let t=v.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(v.basename(e))}function nr(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function Pc(e,t,r,n){let s=new Map,o,a=0;do{a++;let c=await oe(`S3 list objects page ${a} for s3://${t}/${r||""}`,3e5,({httpOptions:i})=>e.send(new ListObjectsV2Command({Bucket:t,Prefix:r||void 0,ContinuationToken:o}),i));for(let i of c.Contents||[]){if(!i.Key)continue;let l=(i.ETag||"").replace(/^"|"$/g,"").toLowerCase(),d=Number(i.Size??0);s.set(i.Key,{etag:l,size:d,cacheControl:void 0});}o=c.NextContinuationToken,n.debug(`Listed S3 keys page ${a}: ${s.size} keys so far`);}while(o);return s}async function Rc(e,t,r,n){if(n.has(r))return n.get(r)??null;try{let s=await oe(`S3 head object ${r}`,3e5,({httpOptions:a})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),a)),o={etag:(s.ETag||"").replace(/^"|"$/g,"").toLowerCase(),size:Number(s.ContentLength??0),cacheControl:s.CacheControl?.trim()||null};return n.set(r,o),o}catch{return n.set(r,null),null}}async function vc(e,t,r,n){if(n.cacheControl!==void 0)return n.cacheControl;try{let s=await oe(`S3 head cache metadata ${r}`,3e5,({httpOptions:o})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),o));n.cacheControl=s.CacheControl?.trim()||null;}catch{n.cacheControl=null;}return n.cacheControl}function _s(e){return String(e||"").split(",").map(t=>t.trim().toLowerCase()).filter(Boolean).sort().join(",")}async function Cc(e,t,r,n){let s=[...new Set(Array.from(r).filter(Boolean))];if(s.length===0)return n.info("No explicitly tombstoned S3 objects to delete."),[];n.info(`Deleting ${s.length} explicitly tombstoned S3 object(s)\u2026`);for(let o=0;o<s.length;o+=1e3){let a=s.slice(o,o+1e3);if(a.length===0)continue;let c=await oe(`S3 delete objects batch ${Math.floor(o/1e3)+1}`,3e5,({httpOptions:i})=>e.send(new DeleteObjectsCommand({Bucket:t,Delete:{Objects:a.map(l=>({Key:l}))}}),i));if(c.Errors&&c.Errors.length>0){let i=c.Errors.map(l=>`${l.Key||"(unknown)"}: ${l.Code||"DeleteFailed"}`);throw new Error(`S3 reported ${i.length} object deletion error(s): ${i.join(", ")}`)}n.info(`Deleted batch of ${a.length} object(s).`);for(let i of a)n.debug(` deleted: ${i}`);}return s}function kc(e){return createHash("md5").update(e).digest("hex")}function Ct(e){return createHash("sha256").update(e).digest("hex")}function ir(e){return createHash("sha256").update(bc(e.toString("utf8"))).digest("hex")}async function xc(e,t,r,n){if(n.has(r))return n.get(r)??null;try{let a=((await oe(`S3 head object metadata ${r}`,3e5,({httpOptions:c})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),c))).Metadata?.[Ks]||"").trim().toLowerCase()||null;return n.set(r,a),a}catch{return n.set(r,null),null}}async function Ic(e,t,r,n,s){if(n.has(r))return n.get(r)??null;try{let a=((await oe(`S3 head object normalized metadata ${r}`,3e5,({httpOptions:c})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),c))).Metadata?.[Hs]||"").trim().toLowerCase();if(a)return n.set(r,a),a}catch{return n.set(r,null),null}if(s.has(r)){let o=s.get(r)??null;return n.set(r,o),o}try{let a=await(await oe(`S3 get object ${r}`,3e5,({httpOptions:i})=>e.send(new GetObjectCommand({Bucket:t,Key:r}),i))).Body?.transformToByteArray(),c=a?ir(Buffer.from(a)):null;return s.set(r,c),n.set(r,c),c}catch{return s.set(r,null),n.set(r,null),null}}function Tc(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function Ac(e,t){let r=e,n=Object.entries(t).sort((s,o)=>o[0].length-s[0].length);for(let[s,o]of n)s&&(r=r.split(s).join(o));return r}async function Ec(e,t,r,n){let s=v.join(e,"asset-map.json"),o;try{o=await D.readFile(s,"utf8");}catch(i){if(i.code==="ENOENT")return;throw i}let a=JSON.parse(o);if(!a||typeof a!="object")return;let c=Object.fromEntries(Object.entries(a).map(([i,l])=>{let d=String(l??"");return t.urlRewriteMode==="absolute"&&t.targetOrigin&&r.targetOrigin&&t.targetOrigin!==r.targetOrigin&&(d=d.split(t.targetOrigin).join(r.targetOrigin)),d=Ac(d,n),[i,d]}));await D.writeFile(s,JSON.stringify(c,null,2),"utf8");}async function $c(e,t,r,n,s,o,a){let c=e.targetOrigin!==t.targetOrigin,i=Object.keys(n).length>0;if(!r||!c&&!i)return {outputDir:e.outputDir,cleanup:async()=>{}};if(c&&e.urlRewriteMode!=="absolute")throw new Error(`Deployment profile "${r}" changes targetOrigin, but the base crawl output must use urlRewriteMode "absolute" for multi-target redeploys.`);let l=v.join(v.dirname(e.outputDir),`.deploy-profile-${Tc(r)}-${Date.now()}`),d=uc(l);s.info(`Preparing deployment profile "${r}" from existing crawl output to ${l}...`);try{if(await D.rm(l,{recursive:!0,force:!0}),o){await D.mkdir(l,{recursive:!0});for(let y of o){let m=v.join(e.outputDir,y),h=v.join(l,y);await D.mkdir(v.dirname(h),{recursive:!0}),await D.copyFile(m,h);}}else await D.cp(e.outputDir,l,{recursive:!0});let u={...e,sourceOrigin:e.targetOrigin,targetOrigin:t.targetOrigin,extraReplacements:n,outputDir:l},g=1;s.info(`Rewriting text files for deployment profile "${r}"...`);let f={files:o,onStart:({totalFiles:y,workerCount:m})=>{g=m,s.info(`Rewriting ${y} text file(s) for deployment profile "${r}" with ${m} worker(s).`);},onProgress:({index:y,totalFiles:m,changedTextFiles:h,file:w,changed:k})=>{let E=`Rewriting [${y}/${m}] ${w} (${k?"rewrote":"checked"}; ${h} changed so far)`;m<=200||y<=5||y%10===0||y===m?(s.progress(E,{file:w,index:y,totalFiles:m,changed:k,changedTextFiles:h,workerCount:g}),s.info(E)):s.debug(E);}},p=a?await Kt(u,{},{...a,options:f}):await Dt(u,{},f);return await Ec(l,e,t,n),s.info(`Prepared deployment profile "${r}" in ${l} (${p} rewritten text file(s)).`),{outputDir:l,cleanup:async()=>{d(),await D.rm(l,{recursive:!0,force:!0});}}}catch(u){throw s.error(`Failed to prepare deployment profile "${r}" temporary output.`,{tempDir:l,outputDir:e.outputDir,error:u instanceof Error?u.message:String(u),...u instanceof Error&&u.stack?{stack:u.stack}:{}}),await D.rm(l,{recursive:true,force:true}).catch(()=>{}),d(),await s.flush().catch(()=>{}),u}}function Oc(e,t){let r=s=>s.replace(/^\/+|\/+$/g,""),n=e.targets.find(s=>s.bucketName===t.s3.bucket&&r(s.prefix)===r(t.s3.prefix)&&s.region===t.s3.region);if(!n)throw new Error(`No CDK Lambda deployment target matches s3://${t.s3.bucket}/${t.s3.prefix||""} in ${t.s3.region}. Redeploy the CDK with this target and reinstall remote-workers.json.`);return n}function Mc(e,t){if(!e||typeof e!="object")throw new Error("Remote deploy result must be a JSON object.");let r=e;if(r.schemaVersion!==Y||r.response?.operation!=="deploy-copy"||r.response.jobId!==t.jobId||r.response.taskId!==t.taskId||!r.detail||!Array.isArray(r.detail.objects)||!Array.isArray(r.detail.deletedKeys)||!Array.isArray(r.detail.deleteErrors))throw new Error("Remote deploy result has an invalid envelope.");return r}async function Bs(e){let t=null;for(let r=1;r<=Math.max(1,Math.min(5,e.maxAttempts));r+=1){let n=ve(`deploy-${e.batchIndex}-a${r}-${Date.now()}`,"taskId");try{let s=await e.client.invoke({schemaVersion:Y,operation:"deploy-copy",jobId:e.jobId,taskId:n,targetId:e.targetId,items:e.items,...e.deleteRelativeKeys?{deleteRelativeKeys:e.deleteRelativeKeys}:{}}),o=Mc(await e.client.readResult(s),s);if(o.response.status==="partial")throw new Error(`Worker reported ${o.response.failedItems} failed item(s).`);return o}catch(s){t=s;}}throw new Error(`Remote deploy task failed after ${e.maxAttempts} attempt(s): ${t instanceof Error?t.message:String(t)}`,{cause:t})}async function Dc(e){let t=Oc(e.remoteConfig,e.config),r=ve(`deploy-${Date.now()}-${Ct(Buffer.from(`${t.id}:${e.config.outputDir}`)).slice(0,12)}`,"jobId"),n=Nt(e.remoteConfig.workspace.prefix,"jobs",r,"deploy-inputs");e.log.progress(`Staging export for Lambda deploy: 0/${e.files.length}`,{phase:"deploy-stage",index:0,totalFiles:e.files.length,uploaded:0,skipped:0,failed:0,mode:"lambda-s3-copy"});let s=0,o=[],a=Math.max(1,Math.min(16,e.concurrency*2)),c=0;await Promise.all(Array.from({length:Math.min(a,e.files.length)},async()=>{for(;;){let w=c;if(w>=e.files.length)return;c+=1;let k=e.files[w],I=await D.readFile(v.join(e.config.outputDir,k)),E=e.contentTypeByRelativePath?.get(k)||Vs.lookup(k)||"application/octet-stream",$=e.revalidateFiles.has(Rt(k))?zs:vt(k)?e.config.s3.htmlCacheControl:e.config.s3.assetCacheControl,C=Ct(I),S=vt(k)?ir(I):void 0,b=`${n}/files/${Ct(Buffer.from(k))}-${v.basename(k)}`.replace(/\/+/g,"/");await e.client.writeWorkspaceObject({key:b,body:I,contentType:String(E),cacheControl:$,metadata:{"wpsuite-sha256":C,...S?{"wpsuite-normalized-sha256":S}:{}}}),o[w]={sourceKey:b,targetRelativeKey:k,sha256:C,...S?{normalizedSha256:S}:{},bytes:I.byteLength,contentType:String(E),cacheControl:$},s+=1,(s===e.files.length||s<=5||s%25===0)&&e.log.progress(`Staging export for Lambda deploy: ${s}/${e.files.length}`,{phase:"deploy-stage",index:s,totalFiles:e.files.length,staged:s,mode:"lambda-s3-copy"});}}));let i=[],l=Math.max(1,Math.min(500,e.batchSize));for(let w=0;w<o.length;w+=l)i.push(o.slice(w,w+l));let d=[],u=[],g=[],f=0,p=0,y=0,m=Math.max(1,Math.min(Math.max(1,e.concurrency),i.length));if(e.log.progress(`Lambda deploy: 0/${e.files.length}`,{phase:"deploy-copy",index:0,totalFiles:e.files.length,uploaded:0,skipped:0,failed:0,mode:"lambda-s3-copy",workerCount:m,completedBatches:0,totalBatches:i.length}),await Promise.all(Array.from({length:m},async()=>{for(;;){let w=y;if(w>=i.length)return;y+=1;let k=Date.now(),I=await Bs({client:e.client,jobId:r,targetId:t.id,batchIndex:w+1,items:i[w],maxAttempts:e.maxAttempts}),E=0,$=0,C=0;for(let b of I.detail.objects)f+=1,b.status==="copied"?(d.push(b.targetKey),E+=1):b.status==="skipped"?(u.push(b.targetKey),$+=1):(g.push(b.targetKey),C+=1),e.log.debug(`Lambda deploy ${b.status}: ${b.targetKey}`,{phase:"deploy-copy",batch:w+1,sourceKey:b.sourceKey,targetKey:b.targetKey,status:b.status,...b.error?{error:b.error}:{}});p+=1;let S=Date.now()-k;e.log.info(`Lambda deploy batch ${w+1}/${i.length} completed: ${E} copied, ${$} skipped unchanged, ${C} failed.`,{phase:"deploy-copy",batch:w+1,totalBatches:i.length,items:I.detail.objects.length,copied:E,skipped:$,failed:C,elapsedMs:S,elapsedSeconds:Math.round(S/10)/100,workerExporterVersion:I.response.exporterVersion,...I.requestId?{lambdaRequestId:I.requestId}:{},...I.completedAt?{workerCompletedAt:I.completedAt}:{}}),e.log.progress(`Lambda deploy: ${f}/${e.files.length}`,{phase:"deploy-copy",index:f,totalFiles:e.files.length,uploaded:d.length,skipped:u.length,failed:g.length,mode:"lambda-s3-copy",workerCount:m,completedBatches:p,totalBatches:i.length});}})),g.length>0)throw new Error(`Remote deployment failed for ${g.length} object(s).`);let h=[];for(let w=0;w<e.deletedFiles.length;w+=1e3){let k=e.deletedFiles.slice(w,w+1e3);if(k.length===0)continue;let I=await Bs({client:e.client,jobId:r,targetId:t.id,batchIndex:i.length+Math.floor(w/1e3)+1,items:[],deleteRelativeKeys:k,maxAttempts:e.maxAttempts});h.push(...I.detail.deletedKeys),e.log.progress(`Lambda deploy deletions: ${h.length}/${e.deletedFiles.length}`,{phase:"deploy-delete",index:h.length,totalFiles:e.deletedFiles.length,deleted:h.length,mode:"lambda-s3-copy"});}return {uploadedKeys:d,skippedKeys:u,failedKeys:g,deletedKeys:h}}async function Qs(e=process.argv.slice(2)){let t=await ue(),r=tr(e),n=rt(t,r),s=v.resolve(n.config.logDir||"logs"),o=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",a=o?v.join(v.resolve(o),"deploy-diff.json"):"",c=new Je(s,"deploy.log.jsonl",n.config.logLevel??"info"),i=n.profile?.extraReplacements??{},l=async()=>{};try{let d=await ze(t);if(e.includes("--content-sync")&&d?.schemaVersion!==2)throw new Error("Content-sync deployment requires a valid schema-2 targeted deploy plan.");let g=await $n(t);if(g)throw new Error(`Deployment blocked: the crawl started at ${g.startedAt} did not complete its final rewrite. Run a successful crawl or resume the rewrite before deploying.`);let f=t.remoteWorkers?.rewrite?.enabled===!0,p=t.remoteWorkers?.deploy?.enabled===!0,y=null,m=null;if(f||p){let R=Ht({runtimeDir:o});if(!R)throw new Error("Remote Lambda workers are enabled, but the runtime directory is unknown.");y=await Bt(R),m=new Ze(y);}let h=await $c(t,n.config,n.name,i,c,d?.schemaVersion===2?d.changedFiles:void 0,f&&m?{client:m,jobId:`profile-${Date.now()}`,concurrency:t.remoteWorkers?.rewrite?.concurrency??t.rewriteConcurrency,batchSize:t.remoteWorkers?.rewrite?.batchSize??25,maxAttempts:t.remoteWorkers?.rewrite?.maxAttempts??2,onStageProgress:({index:R,totalFiles:V,file:O})=>{(R===1||R===V||R%25===0)&&c.progress(`Staging deployment-profile rewrite: ${R}/${V}`,{phase:"rewrite-stage",index:R,totalFiles:V,file:O,execution:"lambda"});}}:void 0);l=h.cleanup;let w={...n.config,outputDir:h.outputDir},k=w.s3SyncMode??"sdk-upload-delete";if(d?.schemaVersion===2&&d.deletedFiles.length>0&&k!=="sdk-upload-delete")throw new Error("Content-sync tombstones require the sdk-upload-delete S3 sync mode.");let I=d?.schemaVersion!==2&&h.outputDir!==t.outputDir&&(t.targetOrigin!==n.config.targetOrigin||Object.keys(i).length>0),E=!!d&&!d.fullSyncRequired&&!I;if(d?.schemaVersion===2&&!E)throw new Error("Content-sync deployment cannot widen into a full-output deployment.");n.name&&c.info(`Using deployment profile: ${n.name}`),c.info(`Starting deploy \u2014 s3://${w.s3.bucket}/${w.s3.prefix||""} (region: ${w.s3.region})`),c.info(`S3 sync mode: ${k}`),d&&d.fullSyncRequired?c.info("Deploy plan requests a full sync; scanning the whole output tree."):d&&I?c.info("Ignoring incremental deploy plan because deployment-profile rewrites require a full sync."):E&&c.info(`Using incremental deploy plan: ${d.changedFiles.length} changed file(s), ${d.deletedFiles.length} deleted file(s).`),c.mark("deploy");let $=new S3Client({region:w.s3.region}),C=h.outputDir===t.outputDir?await mc(t,o,c):null,S=d?.schemaVersion===2?[...d.uploadGroups.assets,...d.uploadGroups.content,...d.uploadGroups.listings,...d.uploadGroups.resources,...d.uploadGroups.sitemapLeaves,...d.uploadGroups.sitemapIndexes]:d?.changedFiles??[];if(d?.schemaVersion===2){let R=[...new Set(S)],V=[...new Set(d.changedFiles)];if(R.length!==V.length||V.some(O=>!R.includes(O)))throw new Error("Content-sync deploy-plan upload groups do not cover the exact changed-file set.")}let b=E?(await Promise.all(S.map(async R=>{try{return (await D.stat(v.join(w.outputDir,R))).isFile()?R:null}catch{if(d?.schemaVersion===2)throw new Error(`Content-sync planned upload is missing: ${R}`);return null}}))).filter(R=>R!==null):await Uo(["**/*"],{cwd:w.outputDir,onlyFiles:!0,dot:!0}),A=[],q=[],T=b.filter(R=>{let V=C?.byRelativePath.get(Rt(R));if(!V)return !0;let O=nr(w.s3.prefix,R);return A.push(R),q.push(O),c.reject(V.kind,V.sourceUrl||R,"rewrite not completed; deploy upload blocked","deploy-guard",{file:R,key:O,outputPath:V.outputPath,manifestPath:C?.manifestPath}),!1}),B=new Set((d?.revalidateFiles||[]).map(Rt)),X=new Set((E?T:b).map(R=>nr(w.s3.prefix,R)));C&&(C.pendingPages>0||C.pendingTextAssets>0)&&c.info(`Deploy rewrite guard loaded ${C.pendingPages} pending page(s) and ${C.pendingTextAssets} pending text asset(s) from crawl manifest.`,{manifestPath:C.manifestPath,pendingPages:C.pendingPages,pendingTextAssets:C.pendingTextAssets,source:"deploy-guard"}),A.length>0&&c.warn(`Deploy rewrite guard blocked ${A.length} file(s) from upload because final crawl rewrite is incomplete.`,{rejected:A.length,manifestPath:C?.manifestPath,source:"deploy-guard"}),E?c.info(`Using ${T.length} eligible planned changed file(s) from deploy plan for upload${A.length>0?` (${A.length} blocked by deploy rewrite guard)`:""}.`):c.info(`Found ${b.length} file(s) in output directory "${w.outputDir}"${A.length>0?`; ${T.length} remain eligible for upload after deploy rewrite guard filtering`:""}.`),c.progress("Deploy preflight: comparing local output with remote S3 state.",{phase:"deploy",mode:k,totalFiles:T.length,scannedFiles:b.length,rejected:A.length,deploymentProfile:n.name||"",s3Bucket:w.s3.bucket,s3Prefix:w.s3.prefix||"",targetedPlan:E,deployGuardEnabled:h.outputDir===t.outputDir});let N=0,x=0,U=0,j=[],P=[],M=[],F=[],W=[],H=new Map,Se=new Map,st=new Map,_e=new Map,ur=new Map;if(p){if(!m||!y)throw new Error("Remote deploy worker client was not initialized.");if(k!=="sdk-upload-delete"&&k!=="sdk-upload-only")throw new Error(`Unsupported remote deploy mode: ${k}`);let R=await Dc({client:m,remoteConfig:y,config:w,files:T,deletedFiles:k==="sdk-upload-delete"?d?.deletedFiles??[]:[],revalidateFiles:B,contentTypeByRelativePath:C?.contentTypeByRelativePath,concurrency:w.remoteWorkers?.deploy?.concurrency??w.assetDownloadConcurrency,batchSize:w.remoteWorkers?.deploy?.batchSize??50,maxAttempts:w.remoteWorkers?.deploy?.maxAttempts??2,log:c});j.push(...R.uploadedKeys),P.push(...R.skippedKeys),M.push(...R.failedKeys),F=R.deletedKeys,N=j.length,x=P.length,U=M.length,c.info(`Lambda deploy complete: ${N} copied, ${x} skipped unchanged, ${F.length} deleted, ${U} failed.`),a&&(await D.mkdir(v.dirname(a),{recursive:!0}),await D.writeFile(a,JSON.stringify({generatedAt:new Date().toISOString(),mode:"lambda-s3-copy",summary:{totalFiles:b.length,eligibleFiles:T.length,uploaded:N,skipped:x,rejected:q.length,failed:U,deleted:F.length,protected:0,...n.name?{profile:n.name}:{}},uploadedKeys:j,skippedKeys:P,rejectedKeys:q,failedKeys:M,deletedKeys:F,protectedRemoteOnlyKeys:[]},null,2),"utf8")),d?.schemaVersion!==2&&await Me(t),c.endMark("deploy"),await c.flush();return}E||(c.info("Listing existing S3 objects to detect unchanged files..."),H=await Pc($,w.s3.bucket,w.s3.prefix,c),c.info(`Found ${H.size} existing key(s) in S3.`));let dr=async R=>H.has(R)?H.get(R)??null:E?Rc($,w.s3.bucket,R,Se):null;for(let R of T){let V=v.join(w.outputDir,R),O=nr(w.s3.prefix,R),ae=C?.contentTypeByRelativePath.get(R),ot=ae&&ae!=="application/octet-stream"?ae:Vs.lookup(R)||ae||"application/octet-stream",rn=B.has(Rt(R)),nn=rn?zs:vt(R)?w.s3.htmlCacheControl:w.s3.assetCacheControl,z=N+x+U+1;T.length<=200||z<=5||z%10===0||z===T.length?(c.progress(`Uploading [${z}/${T.length}] ${O} (${ot})`,{file:R,key:O,index:z,totalFiles:T.length,contentType:ot,mode:k}),c.info(`Uploading [${z}/${T.length}] ${O} (${ot})`)):c.debug(`Uploading [${z}/${T.length}] ${O} (${ot})`);try{let ce=await D.readFile(V),Be=await dr(O),it=null,Ve=null;if(Be){let at=!rn||_s(await vc($,w.s3.bucket,O,Be))===_s(nn),ro=ce.byteLength;if(Be.size===ro){let xt=Be.etag.includes("-");if(Be.etag!==""&&!xt){let no=kc(ce);if(Be.etag===no&&at){x++,T.length<=200||x<=5||x%25===0?(c.progress(`Skipped unchanged [${z}/${T.length}] ${O}`,{file:R,key:O,index:z,totalFiles:T.length,uploaded:N,skipped:x,failed:U,mode:k,reason:"etag-md5-match"}),c.info(`Skipped unchanged [${z}/${T.length}] ${O}`)):c.debug(`Skipped unchanged [${z}/${T.length}] ${O}`),P.push(O);continue}}it=Ct(ce);let sn=await xc($,w.s3.bucket,O,st);if(sn&&sn===it&&at){x++,T.length<=200||x<=5||x%25===0?(c.progress(`Skipped unchanged [${z}/${T.length}] ${O}`,{file:R,key:O,index:z,totalFiles:T.length,uploaded:N,skipped:x,failed:U,mode:k,reason:"metadata-sha256-match"}),c.info(`Skipped unchanged [${z}/${T.length}] ${O}`)):c.debug(`Skipped unchanged [${z}/${T.length}] ${O}`),P.push(O);continue}}if(vt(R)){Ve=ir(ce);let xt=await Ic($,w.s3.bucket,O,_e,ur);if(xt&&xt===Ve&&at){x++,T.length<=200||x<=5||x%25===0?(c.progress(`Skipped semantically unchanged [${z}/${T.length}] ${O}`,{file:R,key:O,index:z,totalFiles:T.length,uploaded:N,skipped:x,failed:U,mode:k,reason:"normalized-html-match"}),c.info(`Skipped semantically unchanged [${z}/${T.length}] ${O}`)):c.debug(`Skipped semantically unchanged [${z}/${T.length}] ${O}`),P.push(O);continue}}}it=it??Ct(ce),Ve=Ve??(vt(R)?ir(ce):null),await oe(`S3 upload ${O}`,9e5,({abortController:at})=>new Upload({client:$,abortController:at,params:{Bucket:w.s3.bucket,Key:O,Body:ce,ContentType:ot,CacheControl:nn,Metadata:{[Ks]:it,...Ve?{[Hs]:Ve}:{}}}}).done()),N++,j.push(O),(N%25===0||N===T.length)&&(c.progress(`Uploaded ${N}/${T.length} file(s)\u2026`,{uploaded:N,skipped:x,failed:U,totalFiles:T.length,mode:k}),c.info(`Uploaded ${N}/${T.length} file(s)\u2026`));}catch(ce){U++,M.push(O),c.error(`Failed to upload ${O}: ${ce.message}`,{key:O,error:String(ce)});}}if(c.info(`Upload complete: ${N} uploaded, ${x} skipped unchanged, ${q.length} rejected by guard, ${U} failed.`),M.length>0||q.length>0)throw new Error(`Deployment stopped before deletion because ${M.length} upload(s) failed and ${q.length} upload(s) were rejected.`);if(k==="sdk-upload-delete"){let R=new Set((d?.deletedFiles??[]).map(O=>nr(w.s3.prefix,O))),V=[...R].filter(O=>!X.has(O));if(!E&&(W=[...H.keys()].filter(ae=>!X.has(ae)).filter(ae=>!R.has(ae)),W.length>0)){c.warn(`Protected ${W.length} remote-only S3 object(s) from deletion because the crawl did not provide explicit tombstones.`,{protected:W.length,source:"deploy-delete-guard"});for(let ae of W)c.debug(` protected remote-only object: ${ae}`);}F=await Cc($,w.s3.bucket,E?V:V.filter(O=>H.has(O)),c);}else c.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion.");a&&(await D.mkdir(v.dirname(a),{recursive:!0}),await D.writeFile(a,JSON.stringify({generatedAt:new Date().toISOString(),mode:k,summary:{totalFiles:b.length,eligibleFiles:T.length,uploaded:j.length,skipped:P.length,rejected:q.length,failed:M.length,deleted:F.length,protected:W.length,...n.name?{profile:n.name}:{}},uploadedKeys:j,skippedKeys:P,rejectedKeys:q,failedKeys:M,deletedKeys:F,protectedRemoteOnlyKeys:W},null,2),"utf8")),d?.schemaVersion!==2&&await Me(t),c.endMark("deploy"),await c.flush();}finally{await l().catch(()=>{});}}function jc(e){let t=e;return t.endsWith("/")?t+="index.html":v.posix.basename(t).includes(".")||(t+="/index.html"),t}function Uc(e,t){let r=t.trim().replace(/^\/+|\/+$/g,"");if(!r)return null;let n=`/${r}`;return e===n||e.startsWith(`${n}/`)?e:`${n}${e.startsWith("/")?e:`/${e}`}`}function Js(e,t){let r=new Set;for(let n of e){let s=new URL(n,"https://content-sync.invalid");if(s.origin!=="https://content-sync.invalid")continue;let o=`${s.pathname}${s.search}`,a=jc(s.pathname);r.add(o),r.add(`${a}${s.search}`);let c=Uc(a,t);c&&r.add(`${c}${s.search}`);}return [...r].sort()}function Nc(){let e=String(process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"").trim();return e?v.join(v.resolve(e),"content-sync-invalidation.json"):""}async function Zr(e,t){if(!e)return;await D.mkdir(v.dirname(e),{recursive:true});let r=`${e}.${process.pid}.${Date.now()}.tmp`;await D.writeFile(r,JSON.stringify({...t,updatedAt:new Date().toISOString()},null,2),"utf8"),await D.rename(r,e);}async function _c(e,t,r,n){if(!e)return null;try{let s=JSON.parse(await D.readFile(e,"utf8"));if(s.schemaVersion!==1||s.distributionId!==t||s.impactHash!==r||!Array.isArray(s.batches))throw new Error("Content-sync invalidation state does not match the deploy plan.");let o=s.batches.flatMap(a=>a.paths);return o.length!==n.length||o.some((a,c)=>a!==n[c])?null:s}catch(s){if(s.code==="ENOENT")return null;throw s}}function Bc(e,t=3e3){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.slice(n,n+t));return r}async function Zs(e=process.argv.slice(2)){let t=await ue(),r=tr(e),n=rt(t,r),s=n.config,o=new Je(s.logDir||"logs","invalidate.log.jsonl",s.logLevel??"info"),a=e.includes("--content-sync"),c=await ze(t);if(a&&c?.schemaVersion!==2)throw new Error("Content-sync invalidation requires a valid schema-2 targeted deploy plan.");if(n.name&&o.info(`Using deployment profile: ${n.name}`),!s.cloudFront.distributionId){o.info("No CloudFront distributionId configured; skipping invalidation."),await o.flush();return}let i=c?.schemaVersion===2?c.invalidationPaths:s.cloudFront.invalidationPaths.length>0?s.cloudFront.invalidationPaths:["/*"],l=c?.schemaVersion===2?Js(i,s.s3.prefix||""):i;if(c?.schemaVersion===2&&l.some(p=>p==="/*"))throw new Error("Content-sync cannot use a whole-distribution invalidation.");if(l.length===0){o.info("The targeted deploy plan has no CloudFront paths to invalidate."),await o.flush();return}let d=s.cloudFront.distributionId,u=new CloudFrontClient({region:"us-east-1",maxAttempts:5});if(o.mark("invalidate"),c?.schemaVersion!==2){let p=`smartcloud-static-publisher-${Date.now()}`;await oe(`CloudFront invalidation for distribution ${d}`,3e5,({httpOptions:y})=>u.send(new CreateInvalidationCommand({DistributionId:d,InvalidationBatch:{CallerReference:p,Paths:{Quantity:l.length,Items:l}}}),y)),o.endMark("invalidate"),await o.flush();return}let g=Nc(),f=await _c(g,d,c.impactHash,l);if(!f){let p=createHash("sha256").update(JSON.stringify(l)).digest("hex");f={schemaVersion:1,distributionId:d,impactHash:c.impactHash,updatedAt:new Date().toISOString(),batches:Bc(l).map((y,m)=>({index:m,callerReference:`wpsuite-content-sync-${c.impactHash.slice(0,24)}-${p.slice(0,24)}-${m}`,paths:y,invalidationId:null,status:"pending"}))},await Zr(g,f);}for(let p of f.batches){if(!p.invalidationId){let y=await oe(`CloudFront targeted invalidation batch ${p.index+1}`,3e5,({httpOptions:h})=>u.send(new CreateInvalidationCommand({DistributionId:d,InvalidationBatch:{CallerReference:p.callerReference,Paths:{Quantity:p.paths.length,Items:p.paths}}}),h)),m=String(y.Invalidation?.Id||"").trim();if(!m)throw new Error("CloudFront did not return an invalidation ID.");p.invalidationId=m,p.status="created",await Zr(g,f);}await waitUntilInvalidationCompleted({client:u,maxWaitTime:900,minDelay:2,maxDelay:15},{DistributionId:d,Id:p.invalidationId}),p.status="completed",await Zr(g,f),o.info(`CloudFront invalidation batch ${p.index+1}/${f.batches.length} completed.`,{invalidationId:p.invalidationId,pathCount:p.paths.length});}o.endMark("invalidate"),await o.flush();}function lr(e){let t=new URL(e);return t.hash="",t.href}function Ys(e,t,r){let n=new Set([...t].map(i=>lr(i))),s=new Map,o=new Map,a=i=>{s.set(lr(i),i);},c=i=>{if(!i)return;let l=lr(i);s.has(l)||o.set(l,i);};for(let i of e.deleteUrls)a(i);for(let i of e.resourceDeleteUrls)a(i);for(let i of e.archiveFamilies)if(i.foundPosts===0)for(let l of i.pageUrls)n.has(lr(l))||a(l);for(let i of e.directRenderUrls)c(i);for(let i of e.resourceRenderUrls)c(i);for(let i of e.archiveFamilies)c(i.pageUrls[0]),c(i.pageUrls.at(-1));for(let i of r)c(i);return {expectedAvailable:[...o.values()],expectedMissing:[...s.values()]}}var eo=["claimed","impact-planned","rendered","deployed","invalidated","verified","acknowledged"];function en(){let e=String(process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"").trim();if(!e)throw new Error("Content-sync requires a runtime directory.");return v.resolve(e)}function nt(e,t){return eo.indexOf(e)>=eo.indexOf(t)}async function Te(e,t,r,n,s={}){let o={timestamp:new Date().toISOString(),eventType:t,status:t.endsWith("failed")?"failed":"success",actorSource:"content-sync",jobId:r.id||"",command:"content-sync",message:n,details:s};await D.mkdir(e,{recursive:true}),await D.appendFile(v.join(e,"audit-events.jsonl"),`${JSON.stringify(o)}
|
|
15
|
+
`,"utf8");}function Kc(e){return ct({postTypes:e.postTypes??[],listingPaths:e.listingPaths??[],includeSubsites:e.includeSubsites,includePostTypeArchives:e.includePostTypeArchives,includeTaxonomyArchives:e.includeTaxonomyArchives,includeAuthorArchives:e.includeAuthorArchives,includeDateArchives:e.includeDateArchives,includePostsPage:e.includePostsPage,includeSitemapChain:e.includeSitemapChain})}function Hc(e,t){let r=(e.scheduler?.rules??[]).filter(s=>s.command==="content-sync"&&s.id===t);if(r.length===0)throw new Error(`Content-sync scheduler rule not found: ${t}`);if(r.length>1)throw new Error(`Content-sync scheduler rule ID is not unique: ${t}`);let n=r[0];if(n.enabled===false)throw new Error(`Content-sync scheduler rule is disabled: ${t}`);return n}async function tn(e,t){if(e.subscriptionType!=="PROFESSIONAL"&&e.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let r=Kc(t),n=rt(e,t.deploymentProfile),s=n.name||"",o=cn(e.sourceOrigin,String(t.id||""),r),a=ln({sourceOrigin:e.sourceOrigin,targetOrigin:n.config.targetOrigin,deploymentProfile:s,s3Bucket:n.config.s3.bucket,s3Prefix:n.config.s3.prefix,cloudFrontDistributionId:n.config.cloudFront.distributionId,urlRewriteMode:n.config.urlRewriteMode,extraReplacements:n.profile?.extraReplacements??{}}),c=un({siteId:e.wpsuite?.siteSettings?.siteId,accountId:e.wpsuite?.siteSettings?.accountId,sourceOrigin:e.sourceOrigin,ruleId:String(t.id||""),targetFingerprint:a}),i=`content-sync:${String(t.id||"")}:${be({scopeFingerprint:o,targetFingerprint:a}).slice(0,32)}`,l=new Tt({sourceOrigin:e.sourceOrigin,runtimeToken:String(e.wpsuite?.runtimeToken||""),ignoreHttpsErrors:e.ignoreHttpsErrors}),d=await l.releaseFingerprint(r.includeSubsites),u=an({wordpressFingerprint:d,targetFingerprint:a,sourceOrigin:e.sourceOrigin,sitemapPaths:dt(e.sitemapPaths),blockedPathPrefixes:e.blockedPathPrefixes,assetPathPrefixes:e.assetPathPrefixes,noJavaScriptRenderPathPrefixes:e.noJavaScriptRenderPathPrefixes,urlRewriteMode:e.urlRewriteMode});return {rule:t,scope:r,deployment:n,deploymentProfile:s,scopeFingerprint:o,targetFingerprint:a,consumerId:c,coalesceKey:i,client:l,releaseFingerprint:u}}async function zc(e){let t=en(),r=At(t),n=await ue(),s=(n.scheduler?.rules??[]).filter(l=>l.command==="content-sync"&&l.enabled!==false);if(s.length===0)return 0;let o=await hr(r),a=await Et(r),c=await fr(r),i=0;for(let l of s){let d=await tn(n,l),u=c.entries[d.coalesceKey];if(!u||u.releaseJobId!==e||u.scopeFingerprint!==d.scopeFingerprint||u.targetFingerprint!==d.targetFingerprint||u.releaseFingerprint!==d.releaseFingerprint)throw new Error(`The normal release has no matching pre-crawl content-sync cutoff for rule ${String(l.id||"")}.`);let g=be({releaseJobId:e,releaseFingerprint:d.releaseFingerprint,scopeFingerprint:d.scopeFingerprint,targetFingerprint:d.targetFingerprint,sequence:u.sequence}),f=await d.client.establishBaseline({consumerId:d.consumerId,scopeFingerprint:d.scopeFingerprint,baselineId:g,postTypes:d.scope.postTypes,includeSubsites:d.scope.includeSubsites,sequence:u.sequence}),p={schemaVersion:1,ruleId:String(l.id||""),consumerId:d.consumerId,coalesceKey:d.coalesceKey,scopeFingerprint:d.scopeFingerprint,targetFingerprint:d.targetFingerprint,releaseFingerprint:d.releaseFingerprint,baselineId:g,deploymentProfile:d.deploymentProfile,committedSequence:f.committedSequence,releaseJobId:e,verifiedAt:new Date().toISOString()};o.entries[d.coalesceKey]=p;let y=a.rules[d.coalesceKey];a.rules[d.coalesceKey]={ruleId:String(l.id||""),consumerId:d.consumerId,coalesceKey:d.coalesceKey,committedSequence:f.committedSequence,observedHeadSequence:f.headSequence,lag:Math.max(0,f.headSequence-f.committedSequence),lastSuccessfulJobId:y?.lastSuccessfulJobId||e,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:f.headSequence>f.committedSequence,retryAttempt:0,nextRetryAt:null,lastError:null,baselineStatus:"ready",baselineReason:null};let m=await bn(r,d.coalesceKey);await Te(t,"content-sync-baseline-established",{id:e},"A normal release established a verified content-sync baseline.",{ruleId:l.id,consumerId:d.consumerId,committedSequence:f.committedSequence,supersededCurrent:m}),i++;}return await fn(r,o),await $t(r,a),await D.rm(r.releaseCutoff,{force:true}),i}async function Qc(e){let t=en(),r=At(t),n=await ue(),s=(n.scheduler?.rules??[]).filter(c=>c.command==="content-sync"&&c.enabled!==false);if(s.length===0)return 0;let o=await fr(r),a=0;for(let c of s){let i=await tn(n,c),l=Object.values(o.entries).find(g=>g.releaseJobId===e&&g.ruleId===String(c.id||""));if(l){if(l.coalesceKey===i.coalesceKey&&l.scopeFingerprint===i.scopeFingerprint&&l.targetFingerprint===i.targetFingerprint&&l.releaseFingerprint===i.releaseFingerprint){a++;continue}throw new Error(`The normal release scope changed after its journal cutoff was captured for rule ${String(c.id||"")}. Start a new normal publish instead of resuming this release.`)}let d=await i.client.unboundHead(i.scope.postTypes,i.scope.includeSubsites),u={schemaVersion:1,releaseJobId:e,ruleId:String(c.id||""),coalesceKey:i.coalesceKey,scopeFingerprint:i.scopeFingerprint,targetFingerprint:i.targetFingerprint,releaseFingerprint:i.releaseFingerprint,sequence:d.headSequence,capturedAt:new Date().toISOString()};o.entries[i.coalesceKey]=u,await Te(t,"content-sync-release-cutoff-captured",{id:e},"A normal release captured its pre-crawl content-sync journal cutoff.",{ruleId:c.id,consumerId:i.consumerId,sequence:d.headSequence}),a++;}return await mn(r,o),a}async function Jc(e,t){let r=JSON.parse(await D.readFile(v.join(e,"current-run.json"),"utf8"));if(r.id!==t||r.command!=="content-sync"||!String(r.ruleId||"").trim())throw new Error("The active queue job is not the requested content-sync job.");return r}async function Xr(e,t,r=0){let n=e.protocol==="https:"?gn:po,s=e.protocol==="https:"?new gn.Agent({rejectUnauthorized:!t}):void 0;return new Promise((o,a)=>{let c=n.get(e,{agent:s,timeout:3e4,headers:{"user-agent":"WP-Suite-Content-Sync/1"}},i=>{let l=i.statusCode??500,d=i.headers.location;if(l>=300&&l<400&&d&&r<5){i.resume(),Xr(new URL(d,e),t,r+1).then(o,a);return}let u=[],g=0;i.on("data",f=>{g+=f.byteLength,g<=1048576&&u.push(f);}),i.on("error",a),i.on("end",()=>o({status:l,body:Buffer.concat(u).toString("utf8"),contentType:String(i.headers["content-type"]||"")}));});c.on("timeout",()=>c.destroy(new Error(`Verification timed out: ${e}`))),c.on("error",a);})}async function Gc(e,t,r,n){let s=t.deployment.config.targetOrigin;if(!/^https?:\/\//i.test(s))throw new Error("Content-sync verification requires an absolute HTTP(S) target origin.");let o=JSON.parse(await D.readFile(n,"utf8")),a=new Set;for(let[d,u]of Object.entries(o.pages??{}))a.add(d),typeof u.url=="string"&&a.add(u.url);let c=await ze(e);if(c?.schemaVersion!==2||c.impactHash!==r.impactHash)throw new Error("Content-sync verification requires the matching targeted deploy plan.");let i=Ys(r,a,c.resolvedSitemapUrls),l=new Set(r.resourceRenderUrls.map(d=>{let u=new URL(d);return u.hash="",u.href}));for(let d of i.expectedAvailable){let u=new URL(d),g=new URL(`${u.pathname}${u.search}`,s),f=await Xr(g,e.ignoreHttpsErrors);if(f.status<200||f.status>=400)throw new Error(`Content-sync verification failed (${f.status}): ${g}`);let p=new URL(d);if(p.hash="",l.has(p.href)){if(!f.contentType.toLowerCase().startsWith("application/json"))throw new Error(`Resource verification expected application/json: ${g}`);try{JSON.parse(f.body);}catch{throw new Error(`Resource verification received invalid JSON: ${g}`)}}}for(let d of i.expectedMissing){let u=new URL(d),g=new URL(`${u.pathname}${u.search}`,s),f=await Xr(g,e.ignoreHttpsErrors);if(f.status>=200&&f.status<300)throw new Error(`Deleted content is still publicly available: ${g}`)}}async function Zc(e){let t=await D.readFile(e.candidateManifest,"utf8");JSON.parse(t);let r=`${e.trustedManifest}.${process.pid}.tmp`;await D.writeFile(r,t,"utf8"),await D.rename(r,e.trustedManifest);}async function Yc(e,t){try{let r=JSON.parse(await D.readFile(e.candidateManifest,"utf8"));if([...Object.values(r.pages??{}),...Object.values(r.assets??{})].some(s=>s?.lastSeenRunId===t))return "resumed"}catch(r){if(r.code!=="ENOENT")throw new Error(`The content-sync candidate manifest is invalid: ${r instanceof Error?r.message:String(r)}`,{cause:r})}return await D.copyFile(e.trustedManifest,e.candidateManifest).catch(r=>{throw new Error(`A trusted crawl manifest is required before content-sync: ${r instanceof Error?r.message:String(r)}`,{cause:r})}),"initialized"}async function Ne(e,t,r,n,s={},o=0,a=async()=>{}){t.phase=r,await hn(e,t),await Sn(e,{schemaVersion:1,jobId:t.jobId,phase:r,completedItems:n,totalItems:n,attempt:o,updatedAt:new Date().toISOString(),details:s}),await Te(v.dirname(e.state),"content-sync-checkpoint",{id:t.jobId},`Content-sync checkpoint completed: ${r}.`,{phase:r,completedItems:n,totalItems:n,attempt:o,...s}),await a(r,t);}async function Xc(e,t={}){let r={loadConfig:ue,resolveRuleContext:tn,runCrawl:qs,runDeploy:Qs,runInvalidate:Zs,verifyDeployment:Gc,promoteCandidateManifest:Zc,clearDeployPlan:Me,afterCheckpoint:async()=>{},...t},n=en(),s=At(n),o=await Jc(n,e),a=await r.loadConfig(),c=Hc(a,String(o.ruleId)),i=await r.resolveRuleContext(a,c);if(o.coalesceKey&&o.coalesceKey!==i.coalesceKey)throw new Error("Queued content-sync demand no longer matches the active rule scope.");let d=(await hr(s)).entries[i.coalesceKey];if(!d||d.scopeFingerprint!==i.scopeFingerprint||d.targetFingerprint!==i.targetFingerprint||d.releaseFingerprint!==i.releaseFingerprint)throw await Te(n,"content-sync-baseline-rejected",o,"Content-sync requires a new verified full or incremental release baseline.",{ruleId:c.id,reason:d?"mismatch":"missing"}),new Error("Content-sync baseline is missing or stale. Run a successful normal publish first.");let u=await wr(s),g=await i.client.head({consumerId:i.consumerId,scopeFingerprint:i.scopeFingerprint,baselineId:d.baselineId,postTypes:i.scope.postTypes,includeSubsites:i.scope.includeSubsites});if(u&&u.jobId!==o.id)throw new Error("Another immutable content-sync range is still active.");if(u||(u={schemaVersion:1,jobId:o.id,ruleId:String(c.id||""),consumerId:i.consumerId,coalesceKey:i.coalesceKey,scopeFingerprint:i.scopeFingerprint,targetFingerprint:i.targetFingerprint,baselineId:d.baselineId,fromSequence:g.committedSequence,toSequence:g.headSequence,phase:"claimed",impactHash:null,startedAt:new Date().toISOString(),updatedAt:new Date().toISOString()},await Ne(s,u,"claimed",0,{fromSequence:u.fromSequence,toSequence:u.toSequence},0,r.afterCheckpoint),await Te(n,"content-sync-range-claimed",o,"Content-sync claimed a closed journal range.",{fromSequence:u.fromSequence,toSequence:u.toSequence})),u.fromSequence===u.toSequence){let h=await Et(s);h.rules[i.coalesceKey]={ruleId:String(c.id||""),consumerId:i.consumerId,coalesceKey:i.coalesceKey,committedSequence:u.toSequence,observedHeadSequence:g.headSequence,lag:Math.max(0,g.headSequence-u.toSequence),lastSuccessfulJobId:o.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:false,retryAttempt:0,nextRetryAt:null,lastError:null},await $t(s,h),await yr(s);return}let f=await wn(s);if(!nt(u.phase,"impact-planned")){let h=await i.client.events({consumerId:i.consumerId,scopeFingerprint:i.scopeFingerprint,baselineId:d.baselineId,postTypes:i.scope.postTypes,includeSubsites:i.scope.includeSubsites,afterSequence:u.fromSequence,throughSequence:u.toSequence}),w=mr({events:h,scope:i.scope,sourceOrigin:a.sourceOrigin}),k=await i.client.resolveImpactFamilies(w,i.scope.includeSubsites);f=pn({jobId:o.id,ruleId:String(c.id||""),consumerId:i.consumerId,coalesceKey:i.coalesceKey,scopeFingerprint:i.scopeFingerprint,targetFingerprint:i.targetFingerprint,baselineId:d.baselineId,sourceOrigin:a.sourceOrigin,scope:i.scope,fromSequence:u.fromSequence,toSequence:u.toSequence,events:h,resolvedArchiveFamilies:k,sitemapUrls:dt(a.sitemapPaths)}),await yn(s,f),u.impactHash=f.impactHash,await Ne(s,u,"impact-planned",h.length,{eventCount:h.length,foldedCount:f.foldedCount,impactHash:f.impactHash},0,r.afterCheckpoint),await Te(n,"content-sync-impact-planned",o,"Content-sync persisted an immutable impact plan.",{impactHash:f.impactHash,eventCount:h.length});}if(!f||f.jobId!==o.id||u.impactHash!==f.impactHash)throw new Error("The immutable content-sync impact plan is missing or mismatched.");if(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH=s.candidateManifest,!nt(u.phase,"rendered")){let h=await Yc(s,o.id);await Te(n,h==="resumed"?"content-sync-render-resumed":"content-sync-render-initialized",o,h==="resumed"?"Content-sync resumed its candidate crawl manifest.":"Content-sync initialized a candidate crawl manifest.",{impactHash:f.impactHash}),await r.runCrawl(["--content-sync-plan",s.impact]),await Ne(s,u,"rendered",f.directRenderUrls.length+f.archiveFamilyUrls.length+f.resourceRenderUrls.length,{impactHash:f.impactHash},o.attempt??0,r.afterCheckpoint);}let p=i.deploymentProfile?["--profile",i.deploymentProfile]:[];if(nt(u.phase,"deployed")||(await r.runDeploy([...p,"--content-sync"]),await Ne(s,u,"deployed",1,{impactHash:f.impactHash},0,r.afterCheckpoint),await Te(n,"content-sync-deployed",o,"Content-sync targeted deployment completed.",{impactHash:f.impactHash})),nt(u.phase,"invalidated")?nt(u.phase,"verified")||await r.runInvalidate([...p,"--content-sync"]):(await r.runInvalidate([...p,"--content-sync"]),await Ne(s,u,"invalidated",1,{impactHash:f.impactHash},0,r.afterCheckpoint)),nt(u.phase,"verified")||(await r.verifyDeployment(a,i,f,s.candidateManifest),await r.promoteCandidateManifest(s),await Ne(s,u,"verified",1,{impactHash:f.impactHash},0,r.afterCheckpoint)),g=await i.client.head({consumerId:i.consumerId,scopeFingerprint:i.scopeFingerprint,baselineId:d.baselineId,postTypes:i.scope.postTypes,includeSubsites:i.scope.includeSubsites}),g.committedSequence===u.fromSequence)await i.client.acknowledge({consumerId:i.consumerId,scopeFingerprint:i.scopeFingerprint,baselineId:d.baselineId,expectedSequence:u.fromSequence,sequence:u.toSequence,postTypes:i.scope.postTypes,includeSubsites:i.scope.includeSubsites});else if(g.committedSequence!==u.toSequence)throw new Error("Content-sync acknowledgement cursor is in an unexpected state.");await Ne(s,u,"acknowledged",1,{sequence:u.toSequence},0,r.afterCheckpoint),await Te(n,"content-sync-cursor-acknowledged",o,"Content-sync committed its journal cursor after verification.",{sequence:u.toSequence});let y=await i.client.head({consumerId:i.consumerId,scopeFingerprint:i.scopeFingerprint,baselineId:d.baselineId,postTypes:i.scope.postTypes,includeSubsites:i.scope.includeSubsites}),m=await Et(s);m.rules[i.coalesceKey]={ruleId:String(c.id||""),consumerId:i.consumerId,coalesceKey:i.coalesceKey,committedSequence:u.toSequence,observedHeadSequence:y.headSequence,lag:Math.max(0,y.headSequence-u.toSequence),lastSuccessfulJobId:o.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:y.headSequence>u.toSequence,retryAttempt:0,nextRetryAt:null,lastError:null},await $t(s,m),await r.clearDeployPlan(a),await D.rm(v.join(n,"content-sync-invalidation.json"),{force:true}),await D.rm(s.candidateManifest,{force:true}),await yr(s);}async function to(e=process.argv.slice(2)){let r=e.indexOf("--capture-baseline-cutoffs");if(r>=0){let a=String(e[r+1]||"").trim();if(!a)throw new Error("--capture-baseline-cutoffs requires a release job ID.");await Qc(a);return}let n=e.indexOf("--establish-baselines");if(n>=0){let a=String(e[n+1]||"").trim();if(!a)throw new Error("--establish-baselines requires a release job ID.");await zc(a);return}let s=e.indexOf("--job-id"),o=s>=0?String(e[s+1]||"").trim():"";if(!o)throw new Error("Content-sync requires --job-id.");await Xc(o);}to().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1);});
|