@smart-cloud/publisher-exporter 1.1.42 → 1.1.43
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 +7 -7
- package/package.json +1 -1
package/dist/content-sync.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import A from'fs/promises';import Zr from'http';import Rn from'https';import S from'path';import zn,{createHash}from'crypto';import {request,chromium}from'playwright';import {gunzipSync}from'zlib';import bs from'fast-glob';import {availableParallelism}from'os';import {Worker}from'worker_threads';import {S3Client,HeadObjectCommand,GetObjectCommand,DeleteObjectsCommand,ListObjectsV2Command}from'@aws-sdk/client-s3';import {Upload}from'@aws-sdk/lib-storage';import Eo from'mime-types';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';var Vr=new Set(["post-type","taxonomy","author","date","posts-page","listing"]);function Pe(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))].sort()}function xt(e){return Array.isArray(e)?e.map(xt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,xt(n)])):e}function Kr(e){return JSON.stringify(xt(e))}function oe(e){return createHash("sha256").update(Kr(e)).digest("hex")}function yn(e){return oe({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 At(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 ge(e,t){let n=new URL(At(e)),r=new URL(t,`${n.toString().replace(/\/$/,"")}/`);if(r.origin!==n.origin)throw new Error(`Content-sync URL is outside the source origin: ${t}`);let s=n.pathname.replace(/\/+$/,"");if(s&&r.pathname!==s&&!r.pathname.startsWith(`${s}/`))throw new Error(`Content-sync URL is outside the source site path: ${t}`);return r.hash="",r.toString()}function Ue(e){let t=Pe((e.postTypes??[]).map(r=>String(r).toLowerCase().replace(/[^a-z0-9_-]/g,"")));if(t.length===0)throw new Error("Content-sync requires at least one public post type.");let n=Pe((e.listingPaths??[]).map(r=>{let s=String(r).trim();if(!s)return "";let i=new URL(s,"https://content-sync.invalid/");if(i.origin!=="https://content-sync.invalid"&&/^https?:\/\//i.test(s))throw new Error("Content-sync listing routes must be same-site paths.");let o=`/${i.pathname.replace(/^\/+|\/+$/g,"")}`;return o==="/"?"/":`${o}/`}));return {postTypes:t,listingPaths:n,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 Sn(e,t,n){return oe({schemaVersion:1,sourceOrigin:At(e),ruleId:t.trim(),scope:Ue(n)})}function Pn(e){return oe({schemaVersion:1,...e})}function bn(e){let t=String(e.siteId??"").trim()||String(e.accountId??"").trim()||At(e.sourceOrigin);return `content-sync:${oe({siteIdentity:t,ruleId:e.ruleId.trim(),targetFingerprint:e.targetFingerprint}).slice(0,48)}`}function vn(e){let t=[...e].sort((s,i)=>s.sequence-i.sequence),n=new Map,r=-1;for(let s of t){if(!Number.isSafeInteger(s.sequence)||s.sequence<=r)throw new Error("Content-sync journal events are not strictly ordered.");r=s.sequence;let i=`${s.postType}:${s.postId}`,o=n.get(i);if(!o){n.set(i,{postId:s.postId,postType:s.postType,fromSequence:s.sequence,toSequence:s.sequence,before:s.before,after:s.after,operations:[s.operation],correlationIds:s.correlationId?[s.correlationId]:[]});continue}o.toSequence=s.sequence,o.after=s.after,o.operations.push(s.operation),s.correlationId&&!o.correlationIds.includes(s.correlationId)&&o.correlationIds.push(s.correlationId);}return [...n.values()].sort((s,i)=>s.fromSequence-i.fromSequence)}function wn(e){return e?.status==="publish"&&!!e.url}function Gr(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 Tt(e){let t=Ue(e.scope),n=new Map;vn(e.events);for(let r of e.events)for(let s of [r.before,r.after])for(let i of s?.archiveFamilies??[]){if(!Vr.has(i.kind)||!Gr(i.kind,t))continue;let o={...i,url:ge(e.sourceOrigin,i.url)};n.set(`${o.kind}|${o.url}`,o);}for(let r of t.listingPaths){let s=ge(e.sourceOrigin,r);n.set(`listing|${s}`,{kind:"listing",url:s});}return [...n.values()].sort((r,s)=>r.url.localeCompare(s.url))}function Cn(e){let t=Ue(e.scope),n=vn(e.events),r=new Set,s=new Set,i=new Map(Tt({events:e.events,scope:t,sourceOrigin:e.sourceOrigin}).map(d=>[`${d.kind}|${d.url}`,d]));for(let d of n){let p=d.before,g=d.after,f=wn(p),m=wn(g);m&&g.url&&r.add(ge(e.sourceOrigin,g.url)),f&&p.url&&(!m||p.url!==g.url)&&s.add(ge(e.sourceOrigin,p.url));}let o=new Map(e.resolvedArchiveFamilies.map(d=>[`${d.kind}|${ge(e.sourceOrigin,d.url)}`,{...d,url:ge(e.sourceOrigin,d.url),pageUrls:Pe(d.pageUrls.map(p=>ge(e.sourceOrigin,p)))}])),u=[...i.entries()].map(([d,p])=>{let g=o.get(d);if(!g)throw new Error(`WordPress did not resolve archive family ${d}.`);return {...p,...g}}).sort((d,p)=>d.url.localeCompare(p.url)),a=Pe(u.flatMap(d=>d.pageUrls)),c=t.includeSitemapChain?Pe(e.sitemapUrls.map(d=>ge(e.sourceOrigin,d))):[],l={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:n.length,directRenderUrls:Pe([...r]),archiveFamilyUrls:a,sitemapUrls:c,deleteUrls:Pe([...s]),archiveFamilies:u};return {...l,impactHash:oe(l)}}function qe(e){let{impactHash:t,...n}=e;if(e.schemaVersion!==1||!t)throw new Error("Invalid content-sync impact plan schema.");if(oe(n)!==t)throw new Error("Content-sync impact plan hash mismatch.")}var Yr="wp-json/smartcloud-static-publisher/v1/content-sync/",Xr=25*1024*1024,et=class extends Error{status;code;constructor(t,n,r){super(r),this.name="ContentSyncApiError",this.status=t,this.code=n;}},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){let n=this.options.sourceOrigin.replace(/\/+$/,"")+"/";return new URL(`${Yr}${t}`,n)}async post(t,n){let r=this.endpoint(t),s=Buffer.from(JSON.stringify(n),"utf8"),i=r.protocol==="https:"?Rn:Zr,o=r.protocol==="https:"?new Rn.Agent({rejectUnauthorized:!this.options.ignoreHttpsErrors}):void 0;return new Promise((u,a)=>{let c=i.request(r,{method:"POST",agent:o,headers:{"content-type":"application/json","content-length":String(s.byteLength),"x-static-publisher-token":this.options.runtimeToken},timeout:this.options.timeoutMs},l=>{let d=[],p=0;l.on("data",g=>{if(p+=g.byteLength,p>Xr){l.destroy(new Error("Content-sync API response exceeded the size limit."));return}d.push(g);}),l.on("error",a),l.on("end",()=>{let g=Buffer.concat(d).toString("utf8"),f;try{f=g?JSON.parse(g):{};}catch{a(new et(l.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let m=l.statusCode??500;if(m<200||m>=300){a(new et(m,String(f.code??"request-failed"),String(f.message??`Content-sync API request failed (${m}).`)));return}u(f);});});c.on("timeout",()=>c.destroy(new Error(`Content-sync API request timed out: ${t}`))),c.on("error",a),c.end(s);})}async head(t){return this.post("head",t)}async unboundHead(t){return this.post("head",{postTypes:t})}async events(t){let n=[],r=t.afterSequence,s=new Set(t.postTypes);for(;r<t.throughSequence;){let i=await this.post("events",{...t,afterSequence:r,limit:250});if(i.fromSequence!==r||i.throughSequence!==t.throughSequence||i.nextSequence<r||i.nextSequence>t.throughSequence)throw new Error("Content-sync API returned an inconsistent event page.");if(!Array.isArray(i.items))throw new Error("Content-sync API returned a malformed event page.");let o=r;for(let u of i.items){if(!Number.isSafeInteger(u.sequence)||u.sequence<=o||u.sequence>t.throughSequence||!Number.isSafeInteger(u.postId)||u.postId<=0||!s.has(u.postType)||typeof u.operation!="string"||!u.operation)throw new Error("Content-sync API returned an invalid or out-of-scope journal event.");o=u.sequence;}if(i.items.length>0&&i.nextSequence!==o)throw new Error("Content-sync API event cursor does not match the final returned event.");if(n.push(...i.items),!i.hasMore)break;if(i.nextSequence===r)throw new Error("Content-sync API event pagination did not advance.");r=i.nextSequence;}if(t.throughSequence>t.afterSequence&&n.at(-1)?.sequence!==t.throughSequence)throw new Error("Content-sync API omitted the claimed journal high-water event.");return n}async resolveImpactFamilies(t){let n=await this.post("impact",{families:t});return Array.isArray(n.families)?n.families:[]}async releaseFingerprint(){let t=await this.post("fingerprint",{}),n=String(t.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)}};function nt(e){let t=S.resolve(e);return {state:S.join(t,"content-sync-state.json"),current:S.join(t,"content-sync-current.json"),impact:S.join(t,"content-sync-impact-plan.json"),checkpoint:S.join(t,"content-sync-checkpoint.json"),baseline:S.join(t,"content-sync-baseline.json"),releaseCutoff:S.join(t,"content-sync-release-cutoff.json"),candidateManifest:S.join(t,"content-sync-candidate-manifest.json"),trustedManifest:S.join(t,"crawl-manifest.json"),invalidation:S.join(t,"content-sync-invalidation.json"),deployPlan:S.join(t,"deploy-plan.json")}}async function kt(e){let t=await _e(e.releaseCutoff);if(t===null)return {schemaVersion:1,updatedAt:"",entries:{}};let n=t;if(n.schemaVersion!==1||typeof n.updatedAt!="string"||!n.entries||typeof n.entries!="object"||Array.isArray(n.entries))throw new Error("Invalid content-sync release-cutoff store.");return n}async function In(e,t){await Ae(e.releaseCutoff,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Ae(e,t){await A.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await A.writeFile(n,JSON.stringify(t,null,2),"utf8"),await A.rename(n,e);}async function _e(e){try{return JSON.parse(await A.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 $t(e){let t=await _e(e.baseline);if(t===null)return {schemaVersion:1,updatedAt:"",entries:{}};let n=t;if(n.schemaVersion!==1||typeof n.updatedAt!="string"||!n.entries||typeof n.entries!="object"||Array.isArray(n.entries))throw new Error("Invalid content-sync baseline store.");return n}async function xn(e,t){await Ae(e.baseline,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Et(e){let t=await _e(e.current);if(t===null)return null;let n=t;if(n.schemaVersion!==1||typeof n.jobId!="string"||typeof n.phase!="string"||!Number.isSafeInteger(n.fromSequence)||!Number.isSafeInteger(n.toSequence))throw new Error("Invalid content-sync current-range state.");return n}async function An(e,t){await Ae(e.current,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Tn(e){let t=await _e(e.impact);if(t===null)return null;let n=t;return qe(n),n}async function kn(e,t){qe(t),await Ae(e.impact,t);}async function $n(e,t){await Ae(e.checkpoint,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function rt(e){let t=await _e(e.state);if(t===null)return {schemaVersion:1,updatedAt:"",rules:{}};let n=t;if(n.schemaVersion!==1||typeof n.updatedAt!="string"||!n.rules||typeof n.rules!="object"||Array.isArray(n.rules))throw new Error("Invalid content-sync state store.");return n}async function st(e,t){await Ae(e.state,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Mt(e){await Promise.all([e.current,e.checkpoint].map(async t=>{try{await A.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}));}async function En(e,t){let n=await Et(e);return !n||n.coalesceKey!==t?false:(await Promise.all([e.current,e.checkpoint,e.impact,e.candidateManifest,e.invalidation,e.deployPlan].map(async r=>{try{await A.unlink(r);}catch(s){if(s.code!=="ENOENT")throw s}})),true)}function Fn(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function rs(e){let t=String(e??"").trim();if(!t)return "";let n=t;if(/^https?:\/\//i.test(n))try{n=new URL(n).pathname;}catch{return ""}if(n=n.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!n)return "";let r=n.endsWith("/"),s=n.replace(/^\/+/,"").split("/").map(o=>o.replace(/[^A-Za-z0-9._-]/g,"")).filter(o=>o.length>0&&o!=="."&&o!=="..");if(s.length===0)return "";let i=`/${s.join("/")}`;return r&&S.extname(i)===""&&(i+="/"),i==="/"?"":i}function Ft(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t.trim(),String(n??"")]).filter(([t])=>t.length>0))}function ss(e){if(!e||typeof e!="object")return {};let t={};for(let[n,r]of Object.entries(e)){let s=n.trim();if(!s||!r||typeof r!="object")continue;let i=r,o={};if(typeof i.targetOrigin=="string"){let a=Fn(i.targetOrigin);a&&(o.targetOrigin=a);}let u=Ft(i.extraReplacements);if(Object.keys(u).length>0&&(o.extraReplacements=u),i.s3&&typeof i.s3=="object"){let a={},c=i.s3;typeof c.bucket=="string"&&(a.bucket=c.bucket.trim()),typeof c.prefix=="string"&&(a.prefix=c.prefix.trim()),typeof c.region=="string"&&(a.region=c.region.trim()),typeof c.htmlCacheControl=="string"&&(a.htmlCacheControl=c.htmlCacheControl.trim()),typeof c.assetCacheControl=="string"&&(a.assetCacheControl=c.assetCacheControl.trim()),Object.keys(a).length>0&&(o.s3=a);}if(i.cloudFront&&typeof i.cloudFront=="object"){let a={},c=i.cloudFront;typeof c.distributionId=="string"&&(a.distributionId=c.distributionId.trim()),Array.isArray(c.invalidationPaths)&&(a.invalidationPaths=c.invalidationPaths.map(l=>String(l??"").trim()).filter(l=>l.length>0)),Object.keys(a).length>0&&(o.cloudFront=a);}t[s]=o;}return t}function Ot(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function is(e,t){if(!e||typeof e!="object")return null;let n=e,r=n.command;if(r!=="publish"&&r!=="crawl"&&r!=="deploy"&&r!=="invalidate"&&r!=="retry-timeouts"&&r!=="url"&&r!=="content-sync")return null;let s=Number.parseInt(String(n.intervalMinutes??"0"),10);if(!Number.isFinite(s)||s<1)return null;let i=String(n.id??`${r}-${t+1}`).trim();if(!i)return null;let o=String(n.deploymentProfile??"").trim(),u=String(n.url??"").trim(),a=Array.isArray(n.postTypes)?[...new Set(n.postTypes.map(l=>String(l??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],c=Array.isArray(n.listingPaths)?[...new Set(n.listingPaths.map(l=>String(l??"").trim()).filter(Boolean))]:[];return r==="content-sync"&&a.length===0?null:{id:i,enabled:n.enabled!==false,command:r,intervalMinutes:s,...r==="publish"||r==="crawl"?{crawlMode:n.crawlMode==="incremental"?"incremental":"full"}:{},...(r==="publish"||r==="deploy"||r==="invalidate"||r==="content-sync")&&o?{deploymentProfile:o}:{},...u?{url:u}:{},...a.length>0?{postTypes:a}:{},...c.length>0?{listingPaths:c}:{},...typeof n.includePostTypeArchives=="boolean"?{includePostTypeArchives:n.includePostTypeArchives}:{},...typeof n.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:n.includeTaxonomyArchives}:{},...typeof n.includeAuthorArchives=="boolean"?{includeAuthorArchives:n.includeAuthorArchives}:{},...typeof n.includeDateArchives=="boolean"?{includeDateArchives:n.includeDateArchives}:{},...typeof n.includePostsPage=="boolean"?{includePostsPage:n.includePostsPage}:{},...typeof n.includeSitemapChain=="boolean"?{includeSitemapChain:n.includeSitemapChain}:{}}}function Dn(e){let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.rules)?t.rules.map((r,s)=>is(r,s)).filter(r=>!!r):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:n}}function os(e){if(!e||typeof e!="object")return;let t=e,n={};for(let s of ["accountId","siteId"]){let i=t[s];typeof i=="string"&&i.trim()!==""&&(n[s]=i.trim());}let r=Number(t.lastUpdate??0);return Number.isFinite(r)&&r>0&&(n.lastUpdate=Math.floor(r)),t.subscriber===true&&(n.subscriber=true),Object.keys(n).length>0?n:void 0}function jt(e){let t=e&&typeof e=="object"?e:{},n=String(t.accountId??"").trim(),r=String(t.siteId??"").trim(),s=t.subscriber===true,i=os(t.siteSettings),o={...i??{},...n?{accountId:i?.accountId??n}:{},...r?{siteId:i?.siteId??r}:{},...i?.subscriber===true||s?{subscriber:true}:{}},u={},a=String(t.apiBase??"").trim();a&&(u.apiBase=a);let c=String(t.runtimeToken??t.nonce??"").trim();c&&(u.runtimeToken=c);let l=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();l&&(u.virtualAssetBaseUrl=l),Object.keys(o).length>0&&(u.siteSettings=o);let d=Ot(t.subscriptionType);return d&&(u.subscriptionType=d),u}function as(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function On(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function cs(e,t){let n=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[r,s]of new Headers(t.headers).entries())n.set(r,s);return n}async function jn(e,t,n=5){let r=new URL(On(e)),s=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),i=r.protocol==="http:"?Zr:Rn,o=cs(e,t);return await new Promise((u,a)=>{let c=i.request(r,{method:s,headers:Object.fromEntries(o.entries()),...r.protocol==="https:"?{rejectUnauthorized:false}:{}},l=>{let d=[];l.on("data",p=>{d.push(Buffer.isBuffer(p)?p:Buffer.from(p));}),l.on("error",a),l.on("end",()=>{let p=l.statusCode??0,g=l.headers.location;if(n>0&&g&&[301,302,303,307,308].includes(p)){u(jn(new URL(g,r),{method:p===303?"GET":s},n-1));return}let f=new Headers;for(let[m,h]of Object.entries(l.headers))Array.isArray(h)?f.set(m,h.join(", ")):typeof h=="string"&&f.set(m,h);u(new Response(Buffer.concat(d),{status:p,statusText:l.statusMessage??"",headers:f}));});});c.on("error",a),c.end();})}function us(e){let t=jt(e.wpsuite),n={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},r=String(n.accountId??"").trim(),s=String(n.siteId??"").trim(),i=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();if(e.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...i?{virtualAssetBaseUrl:i}:{},...Object.keys(n).length>0?{siteSettings:n}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!r||!s||!i)return false;as(e.sourceOrigin);let o=globalThis,a={...o.WpSuite??{},siteSettings:n,uploadUrl:i};return t.apiBase&&(a.apiBase=t.apiBase),o.WpSuite=a,true}async function ls(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!us(e)){let s=e.wpsuite?.siteSettings,i=[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): ${i.join(", ")}.`,requests:[]}}}let n=globalThis.fetch,r=[];try{typeof n=="function"&&/^https?:\/\//i.test(t)&&(globalThis.fetch=(async(a,c)=>{let l=On(a);if(l.startsWith(t)){let d=(()=>{try{return new URL(l).pathname}catch{return l}})();try{let p=e.ignoreHttpsErrors&&l.startsWith("https://")?await jn(a,c):await n(a,c);return r.push({path:d,status:p.status,ok:p.ok,error:null}),p}catch(p){throw r.push({path:d,status:null,ok:!1,error:p instanceof Error?p.message:String(p)}),p}}return n(a,c)}));let{getConfig:s}=await import('@smart-cloud/wpsuite-core'),i=await s("publisher"),o=i&&typeof i=="object"?i:null,u=Ot(o?.subscriptionType);return {remote:o,diagnostic:{status:o?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:u??null,error:o?null:"WP Suite publisher config loader returned no configuration.",requests:r}}}catch(s){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:t,subscriptionType:null,error:s instanceof Error?s.message:String(s),requests:r}}}finally{typeof n=="function"&&(globalThis.fetch=n);}}function ds(e,t){let n=ss(t?.deploymentProfiles),r=String(t?.defaultDeploymentProfile??"").trim(),s=n[r]?r:"",i=Ot(t?.subscriptionType),o=jt(e.wpsuite);return {...e,scheduler:Dn(t?.scheduler),deploymentProfiles:n,defaultDeploymentProfile:s,...i?{subscriptionType:i}:{},wpsuite:{...o,...o.siteSettings||i?{siteSettings:{...o.siteSettings??{},...o.siteSettings?.subscriber===true||i==="PROFESSIONAL"||i==="AGENCY"?{subscriber:true}:{}}}:{},...i?{subscriptionType:i}:{}}}}function Dt(e,t){let r=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!r)return t;let s=r.split("/").map(i=>i.trim()).filter(i=>i.length>0&&i!=="."&&i!=="..");return s.length>0?s.join("/"):t}function ps(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Mn(e,t,n){let r=String(t||"").trim();return r&&S.isAbsolute(r)?S.resolve(r):S.resolve(e,Dt(r,n))}async function ne(e,t={}){let n=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",r=await A.readFile(n,"utf8"),s=JSON.parse(r);s.sourceOrigin=s.sourceOrigin.replace(/\/$/,""),s.targetOrigin=Fn(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=rs(s.generated404RequestPath),s.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],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=Ft(s.extraReplacements),s.postCrawlCopyMap=Ft(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=jt(s.wpsuite),s.scheduler=Dn(void 0),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let i=await ls(s);t.onRemotePublisherConfigDiagnostic?.(i.diagnostic);let o=ds(s,i.remote),u=ps(),a=u?S.resolve(u,".."):"";return a?(o.outputDir=Mn(a,o.outputDir,"export"),o.logDir=Mn(a,o.logDir,"logs")):(S.isAbsolute(o.outputDir)||(o.outputDir=Dt(o.outputDir,"export")),S.isAbsolute(o.logDir)||(o.logDir=Dt(o.logDir,"logs"))),o}var gs=".deploy-plan.json",fs="deploy-plan.json",ms=".crawl-incomplete.json",hs="crawl-incomplete.json";function Ln(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Un(e){let t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),n=S.posix.normalize(t);return !t||!n||n==="."||/^[a-zA-Z]:/.test(n)||n.startsWith("../")||n===".."?null:n}function ws(e){let t=String(e||"").trim();if(!t.startsWith("/")||t.startsWith("//")||t.includes("*")||t.includes("#"))return null;try{let n=new URL(t,"https://content-sync.invalid");return n.origin!=="https://content-sync.invalid"?null:`${S.posix.normalize(n.pathname)}${n.search}`}catch{return null}}function me(e){return [...new Set(e.map(Un).filter(t=>t!==null))]}function qn(e,t){let n={generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:S.resolve(e.outputDir),runMode:t.runMode,crawlMode:t.crawlMode,fullSyncRequired:!!t.fullSyncRequired,changedFiles:me(t.changedFiles||[]),deletedFiles:me(t.deletedFiles||[]),rewriteTargets:me(t.rewriteTargets||[])};return t.schemaVersion===2?{...n,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(),uploadGroups:{assets:me(t.uploadGroups?.assets||[]),content:me(t.uploadGroups?.content||[]),listings:me(t.uploadGroups?.listings||[]),sitemapLeaves:me(t.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:me(t.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((t.invalidationPaths||[]).map(ws).filter(r=>r!==null))].sort()}:{schemaVersion:1,...n,runMode:t.runMode}}function ys(e){if(!e||typeof e!="object")return false;let t=e;if(t.schemaVersion===2){let n=t;return n.runMode==="content-sync"&&n.crawlMode==="incremental"&&n.fullSyncRequired===false&&typeof n.generatedAt=="string"&&typeof n.outputDir=="string"&&typeof n.consumerId=="string"&&n.consumerId.trim()!==""&&Number.isSafeInteger(n.fromSequence)&&Number.isSafeInteger(n.toSequence)&&Number(n.toSequence)>=Number(n.fromSequence)&&typeof n.impactHash=="string"&&/^[a-f0-9]{64}$/.test(n.impactHash)&&Array.isArray(n.changedFiles)&&Array.isArray(n.deletedFiles)&&Array.isArray(n.rewriteTargets)&&!!n.uploadGroups&&Array.isArray(n.uploadGroups.assets)&&Array.isArray(n.uploadGroups.content)&&Array.isArray(n.uploadGroups.listings)&&Array.isArray(n.uploadGroups.sitemapLeaves)&&Array.isArray(n.uploadGroups.sitemapIndexes)&&Array.isArray(n.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)}function Lt(e){let t=S.join(S.resolve(e.outputDir),gs),n=Ln();return n?[S.join(n,fs),t]:[t]}function Ut(e){let t=S.join(S.resolve(e.outputDir),ms),n=Ln();return n?[S.join(n,hs),t]:[t]}function he(e,t){let n=S.resolve(e),r=S.resolve(t),s=S.relative(n,r).replace(/\\/g,"/");return Un(s)}async function it(e){let t=S.resolve(e.outputDir);for(let n of Lt(e))try{let r=await A.readFile(n,"utf8"),s=JSON.parse(r);if(!ys(s)||S.resolve(s.outputDir)!==t)continue;return qn(e,s)}catch{}return null}async function qt(e,t){let n=qn(e,t);for(let r of Lt(e)){await A.mkdir(S.dirname(r),{recursive:true});let s=`${r}.${process.pid}.${Date.now()}.tmp`;await A.writeFile(s,JSON.stringify(n,null,2),"utf8"),await A.rename(s,r);}}async function Te(e){for(let t of Lt(e))try{await A.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}async function _n(e,t){let n={schemaVersion:1,startedAt:String(t.startedAt||new Date().toISOString()),outputDir:S.resolve(e.outputDir)};for(let r of Ut(e)){await A.mkdir(S.dirname(r),{recursive:true});let s=`${r}.${process.pid}.tmp`;await A.writeFile(s,JSON.stringify(n,null,2),"utf8"),await A.rename(s,r);}}async function Nn(e){let t=S.resolve(e.outputDir);for(let n of Ut(e)){let r;try{r=await A.readFile(n,"utf8");}catch(i){if(i.code==="ENOENT")continue;throw i}let s;try{s=JSON.parse(r);}catch{throw new Error(`Invalid incomplete crawl marker: ${n}`)}if(s.schemaVersion!==1||typeof s.startedAt!="string"||typeof s.outputDir!="string"||S.resolve(s.outputDir)!==t)throw new Error(`Invalid incomplete crawl marker: ${n}`);return {schemaVersion:1,startedAt:s.startedAt,outputDir:t}}return null}async function Bn(e){for(let t of Ut(e))try{await A.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}function Be(e,t=10){return zn.createHash("sha1").update(e).digest("hex").slice(0,t)}async function Ss(e){await A.mkdir(S.dirname(e),{recursive:true});}async function He(e,t,n){await Ss(e);let r=S.join(S.dirname(e),`.${S.basename(e)}.${process.pid}.${Date.now()}.${zn.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await A.writeFile(r,t,n??"utf8"):await A.writeFile(r,t),await A.rename(r,e);}catch(s){throw await A.unlink(r).catch(()=>{}),s}}function be(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(S.extname(e).toLowerCase())}function ce(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function ke(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function ot(e){return e.replace(/\//g,"\\/")}function Hn(e){return e.replace(/\//g,"\\\\/")}function Ps(e){try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return null;let n=t.pathname==="/"&&!t.search&&!t.hash?"":`${t.pathname}${t.search}${t.hash}`;return `//${t.host}${n}`}catch{return null}}function Wn(e,t,n){if(!t)return;e[t]=n;let r=ot(t),s=ot(n);e[r]=s;let i=Hn(t),o=Hn(n);e[i]=o;let u=ke(t),a=ke(n);e[u]=a;let c=ke(r),l=ke(s);e[c]=l;let d=ke(i),p=ke(o);e[d]=p;}function at(e,t,n){Wn(e,t,n);let r=Ps(t);r&&r!==t&&Wn(e,r,n);}function _t(e,t){let n=t.startsWith("/")?t:`/${t}`,r=(e||"").replace(/\/$/,"");return !r||r==="."||r==="/"?n:`${r}${n}`}function Qn(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function Jn(e,t,n){if(!t)return n;let r=S.dirname(S.resolve(t)),s=S.resolve(e,n.replace(/^\/+/,"")),i=S.relative(r,s).replace(/\\/g,"/");return i?(i.startsWith(".")||(i=`./${i}`),i):"."}var Is=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],xs=new Set([".html",".htm"]),Vn="WPSuite.io Static Publisher",As=Vn.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Ts(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ks(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function $s(e,t,n){return ks(t)?e.replace(new RegExp(`(?<!:)${Ts(t)}`,"g"),n):e.split(t).join(n)}function Es(e,t,n){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!n)return false;let s=S.extname(n).toLowerCase();return xs.has(s)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Ms(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${As}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${Vn}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let r=e.includes(`\r
|
|
1
|
+
import A from'fs/promises';import Yr from'http';import Rn from'https';import S from'path';import zn,{createHash}from'crypto';import {request,chromium}from'playwright';import {gunzipSync}from'zlib';import vs from'fast-glob';import {availableParallelism}from'os';import {Worker}from'worker_threads';import {S3Client,HeadObjectCommand,GetObjectCommand,DeleteObjectsCommand,ListObjectsV2Command}from'@aws-sdk/client-s3';import {Upload}from'@aws-sdk/lib-storage';import Mo from'mime-types';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';var Kr=new Set(["post-type","taxonomy","author","date","posts-page","listing"]);function Pe(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))].sort()}function xt(e){return Array.isArray(e)?e.map(xt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,xt(n)])):e}function Gr(e){return JSON.stringify(xt(e))}function oe(e){return createHash("sha256").update(Gr(e)).digest("hex")}function yn(e){return oe({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 At(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 ge(e,t){let n=new URL(At(e)),r=new URL(t,`${n.toString().replace(/\/$/,"")}/`);if(r.origin!==n.origin)throw new Error(`Content-sync URL is outside the source origin: ${t}`);let s=n.pathname.replace(/\/+$/,"");if(s&&r.pathname!==s&&!r.pathname.startsWith(`${s}/`))throw new Error(`Content-sync URL is outside the source site path: ${t}`);return r.hash="",r.toString()}function Ue(e){let t=Pe((e.postTypes??[]).map(r=>String(r).toLowerCase().replace(/[^a-z0-9_-]/g,"")));if(t.length===0)throw new Error("Content-sync requires at least one public post type.");let n=Pe((e.listingPaths??[]).map(r=>{let s=String(r).trim();if(!s)return "";let i=new URL(s,"https://content-sync.invalid/");if(i.origin!=="https://content-sync.invalid"&&/^https?:\/\//i.test(s))throw new Error("Content-sync listing routes must be same-site paths.");let o=`/${i.pathname.replace(/^\/+|\/+$/g,"")}`;return o==="/"?"/":`${o}/`}));return {postTypes:t,listingPaths:n,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 Sn(e,t,n){return oe({schemaVersion:1,sourceOrigin:At(e),ruleId:t.trim(),scope:Ue(n)})}function Pn(e){return oe({schemaVersion:1,...e})}function bn(e){let t=String(e.siteId??"").trim()||String(e.accountId??"").trim()||At(e.sourceOrigin);return `content-sync:${oe({siteIdentity:t,ruleId:e.ruleId.trim(),targetFingerprint:e.targetFingerprint}).slice(0,48)}`}function vn(e){let t=[...e].sort((s,i)=>s.sequence-i.sequence),n=new Map,r=-1;for(let s of t){if(!Number.isSafeInteger(s.sequence)||s.sequence<=r)throw new Error("Content-sync journal events are not strictly ordered.");r=s.sequence;let i=`${s.postType}:${s.postId}`,o=n.get(i);if(!o){n.set(i,{postId:s.postId,postType:s.postType,fromSequence:s.sequence,toSequence:s.sequence,before:s.before,after:s.after,operations:[s.operation],correlationIds:s.correlationId?[s.correlationId]:[]});continue}o.toSequence=s.sequence,o.after=s.after,o.operations.push(s.operation),s.correlationId&&!o.correlationIds.includes(s.correlationId)&&o.correlationIds.push(s.correlationId);}return [...n.values()].sort((s,i)=>s.fromSequence-i.fromSequence)}function wn(e){return e?.status==="publish"&&!!e.url}function Zr(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 Tt(e){let t=Ue(e.scope),n=new Map;vn(e.events);for(let r of e.events)for(let s of [r.before,r.after])for(let i of s?.archiveFamilies??[]){if(!Kr.has(i.kind)||!Zr(i.kind,t))continue;let o={...i,url:ge(e.sourceOrigin,i.url)};n.set(`${o.kind}|${o.url}`,o);}for(let r of t.listingPaths){let s=ge(e.sourceOrigin,r);n.set(`listing|${s}`,{kind:"listing",url:s});}return [...n.values()].sort((r,s)=>r.url.localeCompare(s.url))}function Cn(e){let t=Ue(e.scope),n=vn(e.events),r=new Set,s=new Set,i=new Map(Tt({events:e.events,scope:t,sourceOrigin:e.sourceOrigin}).map(d=>[`${d.kind}|${d.url}`,d]));for(let d of n){let p=d.before,g=d.after,f=wn(p),m=wn(g);m&&g.url&&r.add(ge(e.sourceOrigin,g.url)),f&&p.url&&(!m||p.url!==g.url)&&s.add(ge(e.sourceOrigin,p.url));}let o=new Map(e.resolvedArchiveFamilies.map(d=>[`${d.kind}|${ge(e.sourceOrigin,d.url)}`,{...d,url:ge(e.sourceOrigin,d.url),pageUrls:Pe(d.pageUrls.map(p=>ge(e.sourceOrigin,p)))}])),u=[...i.entries()].map(([d,p])=>{let g=o.get(d);if(!g)throw new Error(`WordPress did not resolve archive family ${d}.`);return {...p,...g}}).sort((d,p)=>d.url.localeCompare(p.url)),a=Pe(u.flatMap(d=>d.pageUrls)),c=t.includeSitemapChain?Pe(e.sitemapUrls.map(d=>ge(e.sourceOrigin,d))):[],l={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:n.length,directRenderUrls:Pe([...r]),archiveFamilyUrls:a,sitemapUrls:c,deleteUrls:Pe([...s]),archiveFamilies:u};return {...l,impactHash:oe(l)}}function qe(e){let{impactHash:t,...n}=e;if(e.schemaVersion!==1||!t)throw new Error("Invalid content-sync impact plan schema.");if(oe(n)!==t)throw new Error("Content-sync impact plan hash mismatch.")}var Xr="wp-json/smartcloud-static-publisher/v1/content-sync/",es=25*1024*1024,et=class extends Error{status;code;constructor(t,n,r){super(r),this.name="ContentSyncApiError",this.status=t,this.code=n;}},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){let n=this.options.sourceOrigin.replace(/\/+$/,"")+"/";return new URL(`${Xr}${t}`,n)}async post(t,n){let r=this.endpoint(t),s=Buffer.from(JSON.stringify(n),"utf8"),i=r.protocol==="https:"?Rn:Yr,o=r.protocol==="https:"?new Rn.Agent({rejectUnauthorized:!this.options.ignoreHttpsErrors}):void 0;return new Promise((u,a)=>{let c=i.request(r,{method:"POST",agent:o,headers:{"content-type":"application/json","content-length":String(s.byteLength),"x-static-publisher-token":this.options.runtimeToken},timeout:this.options.timeoutMs},l=>{let d=[],p=0;l.on("data",g=>{if(p+=g.byteLength,p>es){l.destroy(new Error("Content-sync API response exceeded the size limit."));return}d.push(g);}),l.on("error",a),l.on("end",()=>{let g=Buffer.concat(d).toString("utf8"),f;try{f=g?JSON.parse(g):{};}catch{a(new et(l.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let m=l.statusCode??500;if(m<200||m>=300){a(new et(m,String(f.code??"request-failed"),String(f.message??`Content-sync API request failed (${m}).`)));return}u(f);});});c.on("timeout",()=>c.destroy(new Error(`Content-sync API request timed out: ${t}`))),c.on("error",a),c.end(s);})}async head(t){return this.post("head",t)}async unboundHead(t){return this.post("head",{postTypes:t})}async events(t){let n=[],r=t.afterSequence,s=new Set(t.postTypes);for(;r<t.throughSequence;){let i=await this.post("events",{...t,afterSequence:r,limit:250});if(i.fromSequence!==r||i.throughSequence!==t.throughSequence||i.nextSequence<r||i.nextSequence>t.throughSequence)throw new Error("Content-sync API returned an inconsistent event page.");if(!Array.isArray(i.items))throw new Error("Content-sync API returned a malformed event page.");let o=r;for(let u of i.items){if(!Number.isSafeInteger(u.sequence)||u.sequence<=o||u.sequence>t.throughSequence||!Number.isSafeInteger(u.postId)||u.postId<=0||!s.has(u.postType)||typeof u.operation!="string"||!u.operation)throw new Error("Content-sync API returned an invalid or out-of-scope journal event.");o=u.sequence;}if(i.items.length>0&&i.nextSequence!==o)throw new Error("Content-sync API event cursor does not match the final returned event.");if(n.push(...i.items),!i.hasMore)break;if(i.nextSequence===r)throw new Error("Content-sync API event pagination did not advance.");r=i.nextSequence;}if(t.throughSequence>t.afterSequence&&n.at(-1)?.sequence!==t.throughSequence)throw new Error("Content-sync API omitted the claimed journal high-water event.");return n}async resolveImpactFamilies(t){let n=await this.post("impact",{families:t});return Array.isArray(n.families)?n.families:[]}async releaseFingerprint(){let t=await this.post("fingerprint",{}),n=String(t.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)}};function nt(e){let t=S.resolve(e);return {state:S.join(t,"content-sync-state.json"),current:S.join(t,"content-sync-current.json"),impact:S.join(t,"content-sync-impact-plan.json"),checkpoint:S.join(t,"content-sync-checkpoint.json"),baseline:S.join(t,"content-sync-baseline.json"),releaseCutoff:S.join(t,"content-sync-release-cutoff.json"),candidateManifest:S.join(t,"content-sync-candidate-manifest.json"),trustedManifest:S.join(t,"crawl-manifest.json"),invalidation:S.join(t,"content-sync-invalidation.json"),deployPlan:S.join(t,"deploy-plan.json")}}async function kt(e){let t=await _e(e.releaseCutoff);if(t===null)return {schemaVersion:1,updatedAt:"",entries:{}};let n=t;if(n.schemaVersion!==1||typeof n.updatedAt!="string"||!n.entries||typeof n.entries!="object"||Array.isArray(n.entries))throw new Error("Invalid content-sync release-cutoff store.");return n}async function In(e,t){await Ae(e.releaseCutoff,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Ae(e,t){await A.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await A.writeFile(n,JSON.stringify(t,null,2),"utf8"),await A.rename(n,e);}async function _e(e){try{return JSON.parse(await A.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 $t(e){let t=await _e(e.baseline);if(t===null)return {schemaVersion:1,updatedAt:"",entries:{}};let n=t;if(n.schemaVersion!==1||typeof n.updatedAt!="string"||!n.entries||typeof n.entries!="object"||Array.isArray(n.entries))throw new Error("Invalid content-sync baseline store.");return n}async function xn(e,t){await Ae(e.baseline,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Et(e){let t=await _e(e.current);if(t===null)return null;let n=t;if(n.schemaVersion!==1||typeof n.jobId!="string"||typeof n.phase!="string"||!Number.isSafeInteger(n.fromSequence)||!Number.isSafeInteger(n.toSequence))throw new Error("Invalid content-sync current-range state.");return n}async function An(e,t){await Ae(e.current,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Tn(e){let t=await _e(e.impact);if(t===null)return null;let n=t;return qe(n),n}async function kn(e,t){qe(t),await Ae(e.impact,t);}async function $n(e,t){await Ae(e.checkpoint,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function rt(e){let t=await _e(e.state);if(t===null)return {schemaVersion:1,updatedAt:"",rules:{}};let n=t;if(n.schemaVersion!==1||typeof n.updatedAt!="string"||!n.rules||typeof n.rules!="object"||Array.isArray(n.rules))throw new Error("Invalid content-sync state store.");return n}async function st(e,t){await Ae(e.state,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Mt(e){await Promise.all([e.current,e.checkpoint].map(async t=>{try{await A.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}));}async function En(e,t){let n=await Et(e);return !n||n.coalesceKey!==t?false:(await Promise.all([e.current,e.checkpoint,e.impact,e.candidateManifest,e.invalidation,e.deployPlan].map(async r=>{try{await A.unlink(r);}catch(s){if(s.code!=="ENOENT")throw s}})),true)}function Fn(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function ss(e){let t=String(e??"").trim();if(!t)return "";let n=t;if(/^https?:\/\//i.test(n))try{n=new URL(n).pathname;}catch{return ""}if(n=n.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!n)return "";let r=n.endsWith("/"),s=n.replace(/^\/+/,"").split("/").map(o=>o.replace(/[^A-Za-z0-9._-]/g,"")).filter(o=>o.length>0&&o!=="."&&o!=="..");if(s.length===0)return "";let i=`/${s.join("/")}`;return r&&S.extname(i)===""&&(i+="/"),i==="/"?"":i}function Ft(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t.trim(),String(n??"")]).filter(([t])=>t.length>0))}function is(e){if(!e||typeof e!="object")return {};let t={};for(let[n,r]of Object.entries(e)){let s=n.trim();if(!s||!r||typeof r!="object")continue;let i=r,o={};if(typeof i.targetOrigin=="string"){let a=Fn(i.targetOrigin);a&&(o.targetOrigin=a);}let u=Ft(i.extraReplacements);if(Object.keys(u).length>0&&(o.extraReplacements=u),i.s3&&typeof i.s3=="object"){let a={},c=i.s3;typeof c.bucket=="string"&&(a.bucket=c.bucket.trim()),typeof c.prefix=="string"&&(a.prefix=c.prefix.trim()),typeof c.region=="string"&&(a.region=c.region.trim()),typeof c.htmlCacheControl=="string"&&(a.htmlCacheControl=c.htmlCacheControl.trim()),typeof c.assetCacheControl=="string"&&(a.assetCacheControl=c.assetCacheControl.trim()),Object.keys(a).length>0&&(o.s3=a);}if(i.cloudFront&&typeof i.cloudFront=="object"){let a={},c=i.cloudFront;typeof c.distributionId=="string"&&(a.distributionId=c.distributionId.trim()),Array.isArray(c.invalidationPaths)&&(a.invalidationPaths=c.invalidationPaths.map(l=>String(l??"").trim()).filter(l=>l.length>0)),Object.keys(a).length>0&&(o.cloudFront=a);}t[s]=o;}return t}function Ot(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function os(e,t){if(!e||typeof e!="object")return null;let n=e,r=n.command;if(r!=="publish"&&r!=="crawl"&&r!=="deploy"&&r!=="invalidate"&&r!=="retry-timeouts"&&r!=="url"&&r!=="content-sync")return null;let s=Number.parseInt(String(n.intervalMinutes??"0"),10);if(!Number.isFinite(s)||s<1)return null;let i=String(n.id??`${r}-${t+1}`).trim();if(!i)return null;let o=String(n.deploymentProfile??"").trim(),u=String(n.url??"").trim(),a=Array.isArray(n.postTypes)?[...new Set(n.postTypes.map(l=>String(l??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],c=Array.isArray(n.listingPaths)?[...new Set(n.listingPaths.map(l=>String(l??"").trim()).filter(Boolean))]:[];return r==="content-sync"&&a.length===0?null:{id:i,enabled:n.enabled!==false,command:r,intervalMinutes:s,...r==="publish"||r==="crawl"?{crawlMode:n.crawlMode==="incremental"?"incremental":"full"}:{},...(r==="publish"||r==="deploy"||r==="invalidate"||r==="content-sync")&&o?{deploymentProfile:o}:{},...u?{url:u}:{},...a.length>0?{postTypes:a}:{},...c.length>0?{listingPaths:c}:{},...typeof n.includePostTypeArchives=="boolean"?{includePostTypeArchives:n.includePostTypeArchives}:{},...typeof n.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:n.includeTaxonomyArchives}:{},...typeof n.includeAuthorArchives=="boolean"?{includeAuthorArchives:n.includeAuthorArchives}:{},...typeof n.includeDateArchives=="boolean"?{includeDateArchives:n.includeDateArchives}:{},...typeof n.includePostsPage=="boolean"?{includePostsPage:n.includePostsPage}:{},...typeof n.includeSitemapChain=="boolean"?{includeSitemapChain:n.includeSitemapChain}:{}}}function Dn(e){let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.rules)?t.rules.map((r,s)=>os(r,s)).filter(r=>!!r):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:n}}function as(e){if(!e||typeof e!="object")return;let t=e,n={};for(let s of ["accountId","siteId"]){let i=t[s];typeof i=="string"&&i.trim()!==""&&(n[s]=i.trim());}let r=Number(t.lastUpdate??0);return Number.isFinite(r)&&r>0&&(n.lastUpdate=Math.floor(r)),t.subscriber===true&&(n.subscriber=true),Object.keys(n).length>0?n:void 0}function jt(e){let t=e&&typeof e=="object"?e:{},n=String(t.accountId??"").trim(),r=String(t.siteId??"").trim(),s=t.subscriber===true,i=as(t.siteSettings),o={...i??{},...n?{accountId:i?.accountId??n}:{},...r?{siteId:i?.siteId??r}:{},...i?.subscriber===true||s?{subscriber:true}:{}},u={},a=String(t.apiBase??"").trim();a&&(u.apiBase=a);let c=String(t.runtimeToken??t.nonce??"").trim();c&&(u.runtimeToken=c);let l=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();l&&(u.virtualAssetBaseUrl=l),Object.keys(o).length>0&&(u.siteSettings=o);let d=Ot(t.subscriptionType);return d&&(u.subscriptionType=d),u}function cs(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function On(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function us(e,t){let n=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[r,s]of new Headers(t.headers).entries())n.set(r,s);return n}async function jn(e,t,n=5){let r=new URL(On(e)),s=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),i=r.protocol==="http:"?Yr:Rn,o=us(e,t);return await new Promise((u,a)=>{let c=i.request(r,{method:s,headers:Object.fromEntries(o.entries()),...r.protocol==="https:"?{rejectUnauthorized:false}:{}},l=>{let d=[];l.on("data",p=>{d.push(Buffer.isBuffer(p)?p:Buffer.from(p));}),l.on("error",a),l.on("end",()=>{let p=l.statusCode??0,g=l.headers.location;if(n>0&&g&&[301,302,303,307,308].includes(p)){u(jn(new URL(g,r),{method:p===303?"GET":s},n-1));return}let f=new Headers;for(let[m,h]of Object.entries(l.headers))Array.isArray(h)?f.set(m,h.join(", ")):typeof h=="string"&&f.set(m,h);u(new Response(Buffer.concat(d),{status:p,statusText:l.statusMessage??"",headers:f}));});});c.on("error",a),c.end();})}function ls(e){let t=jt(e.wpsuite),n={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},r=String(n.accountId??"").trim(),s=String(n.siteId??"").trim(),i=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();if(e.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...i?{virtualAssetBaseUrl:i}:{},...Object.keys(n).length>0?{siteSettings:n}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!r||!s||!i)return false;cs(e.sourceOrigin);let o=globalThis,a={...o.WpSuite??{},siteSettings:n,uploadUrl:i};return t.apiBase&&(a.apiBase=t.apiBase),o.WpSuite=a,true}async function ds(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!ls(e)){let s=e.wpsuite?.siteSettings,i=[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): ${i.join(", ")}.`,requests:[]}}}let n=globalThis.fetch,r=[];try{typeof n=="function"&&/^https?:\/\//i.test(t)&&(globalThis.fetch=(async(a,c)=>{let l=On(a);if(l.startsWith(t)){let d=(()=>{try{return new URL(l).pathname}catch{return l}})();try{let p=e.ignoreHttpsErrors&&l.startsWith("https://")?await jn(a,c):await n(a,c);return r.push({path:d,status:p.status,ok:p.ok,error:null}),p}catch(p){throw r.push({path:d,status:null,ok:!1,error:p instanceof Error?p.message:String(p)}),p}}return n(a,c)}));let{getConfig:s}=await import('@smart-cloud/wpsuite-core'),i=await s("publisher"),o=i&&typeof i=="object"?i:null,u=Ot(o?.subscriptionType);return {remote:o,diagnostic:{status:o?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:u??null,error:o?null:"WP Suite publisher config loader returned no configuration.",requests:r}}}catch(s){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:t,subscriptionType:null,error:s instanceof Error?s.message:String(s),requests:r}}}finally{typeof n=="function"&&(globalThis.fetch=n);}}function ps(e,t){let n=is(t?.deploymentProfiles),r=String(t?.defaultDeploymentProfile??"").trim(),s=n[r]?r:"",i=Ot(t?.subscriptionType),o=jt(e.wpsuite);return {...e,scheduler:Dn(t?.scheduler),deploymentProfiles:n,defaultDeploymentProfile:s,...i?{subscriptionType:i}:{},wpsuite:{...o,...o.siteSettings||i?{siteSettings:{...o.siteSettings??{},...o.siteSettings?.subscriber===true||i==="PROFESSIONAL"||i==="AGENCY"?{subscriber:true}:{}}}:{},...i?{subscriptionType:i}:{}}}}function Dt(e,t){let r=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!r)return t;let s=r.split("/").map(i=>i.trim()).filter(i=>i.length>0&&i!=="."&&i!=="..");return s.length>0?s.join("/"):t}function gs(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Mn(e,t,n){let r=String(t||"").trim();return r&&S.isAbsolute(r)?S.resolve(r):S.resolve(e,Dt(r,n))}async function ne(e,t={}){let n=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",r=await A.readFile(n,"utf8"),s=JSON.parse(r);s.sourceOrigin=s.sourceOrigin.replace(/\/$/,""),s.targetOrigin=Fn(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=ss(s.generated404RequestPath),s.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],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=Ft(s.extraReplacements),s.postCrawlCopyMap=Ft(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=jt(s.wpsuite),s.scheduler=Dn(void 0),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let i=await ds(s);t.onRemotePublisherConfigDiagnostic?.(i.diagnostic);let o=ps(s,i.remote),u=gs(),a=u?S.resolve(u,".."):"";return a?(o.outputDir=Mn(a,o.outputDir,"export"),o.logDir=Mn(a,o.logDir,"logs")):(S.isAbsolute(o.outputDir)||(o.outputDir=Dt(o.outputDir,"export")),S.isAbsolute(o.logDir)||(o.logDir=Dt(o.logDir,"logs"))),o}var fs=".deploy-plan.json",ms="deploy-plan.json",hs=".crawl-incomplete.json",ws="crawl-incomplete.json";function Ln(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Un(e){let t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),n=S.posix.normalize(t);return !t||!n||n==="."||/^[a-zA-Z]:/.test(n)||n.startsWith("../")||n===".."?null:n}function ys(e){let t=String(e||"").trim();if(!t.startsWith("/")||t.startsWith("//")||t.includes("*")||t.includes("#"))return null;try{let n=new URL(t,"https://content-sync.invalid");return n.origin!=="https://content-sync.invalid"?null:`${S.posix.normalize(n.pathname)}${n.search}`}catch{return null}}function me(e){return [...new Set(e.map(Un).filter(t=>t!==null))]}function qn(e,t){let n={generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:S.resolve(e.outputDir),runMode:t.runMode,crawlMode:t.crawlMode,fullSyncRequired:!!t.fullSyncRequired,changedFiles:me(t.changedFiles||[]),deletedFiles:me(t.deletedFiles||[]),rewriteTargets:me(t.rewriteTargets||[])};return t.schemaVersion===2?{...n,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(),uploadGroups:{assets:me(t.uploadGroups?.assets||[]),content:me(t.uploadGroups?.content||[]),listings:me(t.uploadGroups?.listings||[]),sitemapLeaves:me(t.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:me(t.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((t.invalidationPaths||[]).map(ys).filter(r=>r!==null))].sort()}:{schemaVersion:1,...n,runMode:t.runMode}}function Ss(e){if(!e||typeof e!="object")return false;let t=e;if(t.schemaVersion===2){let n=t;return n.runMode==="content-sync"&&n.crawlMode==="incremental"&&n.fullSyncRequired===false&&typeof n.generatedAt=="string"&&typeof n.outputDir=="string"&&typeof n.consumerId=="string"&&n.consumerId.trim()!==""&&Number.isSafeInteger(n.fromSequence)&&Number.isSafeInteger(n.toSequence)&&Number(n.toSequence)>=Number(n.fromSequence)&&typeof n.impactHash=="string"&&/^[a-f0-9]{64}$/.test(n.impactHash)&&Array.isArray(n.changedFiles)&&Array.isArray(n.deletedFiles)&&Array.isArray(n.rewriteTargets)&&!!n.uploadGroups&&Array.isArray(n.uploadGroups.assets)&&Array.isArray(n.uploadGroups.content)&&Array.isArray(n.uploadGroups.listings)&&Array.isArray(n.uploadGroups.sitemapLeaves)&&Array.isArray(n.uploadGroups.sitemapIndexes)&&Array.isArray(n.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)}function Lt(e){let t=S.join(S.resolve(e.outputDir),fs),n=Ln();return n?[S.join(n,ms),t]:[t]}function Ut(e){let t=S.join(S.resolve(e.outputDir),hs),n=Ln();return n?[S.join(n,ws),t]:[t]}function he(e,t){let n=S.resolve(e),r=S.resolve(t),s=S.relative(n,r).replace(/\\/g,"/");return Un(s)}async function it(e){let t=S.resolve(e.outputDir);for(let n of Lt(e))try{let r=await A.readFile(n,"utf8"),s=JSON.parse(r);if(!Ss(s)||S.resolve(s.outputDir)!==t)continue;return qn(e,s)}catch{}return null}async function qt(e,t){let n=qn(e,t);for(let r of Lt(e)){await A.mkdir(S.dirname(r),{recursive:true});let s=`${r}.${process.pid}.${Date.now()}.tmp`;await A.writeFile(s,JSON.stringify(n,null,2),"utf8"),await A.rename(s,r);}}async function Te(e){for(let t of Lt(e))try{await A.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}async function _n(e,t){let n={schemaVersion:1,startedAt:String(t.startedAt||new Date().toISOString()),outputDir:S.resolve(e.outputDir)};for(let r of Ut(e)){await A.mkdir(S.dirname(r),{recursive:true});let s=`${r}.${process.pid}.tmp`;await A.writeFile(s,JSON.stringify(n,null,2),"utf8"),await A.rename(s,r);}}async function Nn(e){let t=S.resolve(e.outputDir);for(let n of Ut(e)){let r;try{r=await A.readFile(n,"utf8");}catch(i){if(i.code==="ENOENT")continue;throw i}let s;try{s=JSON.parse(r);}catch{throw new Error(`Invalid incomplete crawl marker: ${n}`)}if(s.schemaVersion!==1||typeof s.startedAt!="string"||typeof s.outputDir!="string"||S.resolve(s.outputDir)!==t)throw new Error(`Invalid incomplete crawl marker: ${n}`);return {schemaVersion:1,startedAt:s.startedAt,outputDir:t}}return null}async function Bn(e){for(let t of Ut(e))try{await A.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}function Be(e,t=10){return zn.createHash("sha1").update(e).digest("hex").slice(0,t)}async function Ps(e){await A.mkdir(S.dirname(e),{recursive:true});}async function He(e,t,n){await Ps(e);let r=S.join(S.dirname(e),`.${S.basename(e)}.${process.pid}.${Date.now()}.${zn.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await A.writeFile(r,t,n??"utf8"):await A.writeFile(r,t),await A.rename(r,e);}catch(s){throw await A.unlink(r).catch(()=>{}),s}}function be(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(S.extname(e).toLowerCase())}function ce(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function ke(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function ot(e){return e.replace(/\//g,"\\/")}function Hn(e){return e.replace(/\//g,"\\\\/")}function bs(e){try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return null;let n=t.pathname==="/"&&!t.search&&!t.hash?"":`${t.pathname}${t.search}${t.hash}`;return `//${t.host}${n}`}catch{return null}}function Wn(e,t,n){if(!t)return;e[t]=n;let r=ot(t),s=ot(n);e[r]=s;let i=Hn(t),o=Hn(n);e[i]=o;let u=ke(t),a=ke(n);e[u]=a;let c=ke(r),l=ke(s);e[c]=l;let d=ke(i),p=ke(o);e[d]=p;}function at(e,t,n){Wn(e,t,n);let r=bs(t);r&&r!==t&&Wn(e,r,n);}function _t(e,t){let n=t.startsWith("/")?t:`/${t}`,r=(e||"").replace(/\/$/,"");return !r||r==="."||r==="/"?n:`${r}${n}`}function Qn(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function Jn(e,t,n){if(!t)return n;let r=S.dirname(S.resolve(t)),s=S.resolve(e,n.replace(/^\/+/,"")),i=S.relative(r,s).replace(/\\/g,"/");return i?(i.startsWith(".")||(i=`./${i}`),i):"."}var xs=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],As=new Set([".html",".htm"]),Vn="WPSuite.io Static Publisher",Ts=Vn.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function ks(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function $s(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function Es(e,t,n){return $s(t)?e.replace(new RegExp(`(?<!:)${ks(t)}`,"g"),n):e.split(t).join(n)}function Ms(e,t,n){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!n)return false;let s=S.extname(n).toLowerCase();return As.has(s)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Fs(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Ts}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${Vn}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let r=e.includes(`\r
|
|
2
2
|
`)?`\r
|
|
3
3
|
`:`
|
|
4
|
-
`;return e.replace(/<head\b[^>]*>/i,s=>`${s}${r} ${t}`)}function
|
|
5
|
-
`,"utf8");}function
|
|
4
|
+
`;return e.replace(/<head\b[^>]*>/i,s=>`${s}${r} ${t}`)}function Ds(e){let t=ce(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function Os(e,t){let n=[...new Set(t)].filter(i=>i.includes("/")&&!/\\+\//.test(i)).map(i=>[i,ot(i)]).filter(([i,o])=>i!==o).sort((i,o)=>o[0].length-i[0].length);if(!n.length)return e;let r=i=>{let o=i;for(let[u,a]of n)o=o.split(u).join(a);return o},s=e.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(i,o,u,a)=>`${o}${r(u)}${a}`);return s=s.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(i,o,u,a,c)=>Ds(a)?`${o}${r(a)}${c}`:i),s}function js(e,t){if(!t)return null;let n=S.dirname(S.resolve(t)),r=S.resolve(e.outputDir),s=S.relative(n,r).replace(/\\/g,"/");return s?(s.startsWith(".")||(s=`./${s}`),s.endsWith("/")?s:`${s}/`):"./"}function Ls(e,t,n){let r=js(t,n);if(!r)return e;let s=e;for(let i of xs){let o=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),u=new RegExp(`(?:\\.{1,}/)+${o}`,"g"),a=new RegExp(`(?<!\\.)/${o}`,"g");s=s.replace(u,`${r}${i}`).replace(a,`${r}${i}`);let c=i.replace(/\//g,"\\/"),l=r.replace(/\//g,"\\/"),d=c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),p=new RegExp(`(?:\\.{1,}\\\\/)+${d}`,"g"),g=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${d}`,"g"),f=new RegExp(`(?<![\\.\\\\])\\/${d}`,"g");s=s.replace(p,`${l}${c}`).replace(g,`${l}${c}`).replace(f,`${l}${c}`);}return s}function Bt(e,t,n){if(e.urlRewriteMode==="absolute")return t;let r=(()=>{try{return new URL(t,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin)}catch{return null}})(),s=r?r.pathname:Qn(t,e.targetOrigin),i=r?`${r.search}${r.hash}`:"";return e.urlRewriteMode==="root-relative"?`${s}${i}`:`${Jn(e.outputDir,n,s)}${i}`}function Nt(e,t,n,r,s){at(e,n,Bt(t,r,s));}function Us(e,t,n,r,s){if(!n||n===r)return;at(e,n,r);let i=Bt(t,n,s),o=Bt(t,r,s);at(e,i,o);}function Ht(e,t,n,r,s={}){let i=e,o={};Nt(o,t,t.sourceOrigin,t.targetOrigin,r);for(let[a,c]of Object.entries(t.extraReplacements))Nt(o,t,a,c,r);for(let[a,c]of Object.entries(n))Nt(o,t,a,c,r);for(let[a,c]of Object.entries(s)){let l=n[a];!l||l===c||Us(o,t,c,l,r);}let u=Object.entries(o).sort((a,c)=>c[0].length-a[0].length);for(let[a,c]of u)i=Es(i,a,c);return t.urlRewriteMode!=="absolute"&&(i=Ls(i,t,r)),i=Os(i,u.map(([,a])=>a)),Ms(t,i,r)&&(i=Fs(i)),i}async function qs(e,t,n,r){let s=S.join(e.outputDir,r),i=S.extname(s).toLowerCase(),o;try{o=await A.readFile(s,"utf8");}catch(c){if(c.code!=="ENOENT")throw c;return {changed:false}}let a=Ht(o,e,t,i===".js"||i===".mjs"?void 0:s,n);return a!==o?(await He(s,a,"utf8"),{changed:true}):{changed:false}}async function _s(e,t){return await new Promise((n,r)=>{let s=a=>{if(u(),a?.error){r(new Error(a.error));return}n({changed:!!a?.changed});},i=a=>{u(),r(a);},o=a=>{u(),a!==0&&r(new Error(`Rewrite worker exited with code ${a}.`));},u=()=>{e.off("message",s),e.off("error",i),e.off("exit",o);};e.on("message",s),e.on("error",i),e.on("exit",o),e.postMessage({file:t});})}async function ct(e,t,n={}){let s=(n.files?[...new Set(n.files)].map(p=>S.resolve(p)).filter(p=>p.startsWith(S.resolve(e.outputDir))).map(p=>S.relative(e.outputDir,p).replace(/\\/g,"/")).filter(p=>p.length>0):await vs(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(p=>p!=="asset-map.json"&&be(p)),i=0;if(s.length===0)return 0;let o=Math.max(1,Number(e.rewriteConcurrency||e.assetDownloadConcurrency||1)),u=Math.max(1,Math.min(o,s.length,availableParallelism()));await n.onStart?.({totalFiles:s.length,workerCount:u});let a=0,c=0,l=null;if(u===1){for(let p of s){let g=await qs(e,t,n.previousAssetMap??{},p);g.changed&&(i+=1),c+=1,await n.onProgress?.({index:c,totalFiles:s.length,changedTextFiles:i,file:p,changed:g.changed});}return i}let d=Array.from({length:u},async()=>{let p=new Worker(new URL("./rewrite-worker.js",import.meta.url),{workerData:{config:e,assetMap:t,previousAssetMap:n.previousAssetMap??{}}});try{for(;!l;){let g=a;if(g>=s.length)return;a+=1;let f=s[g],m=await _s(p,f);m.changed&&(i+=1),c+=1,await n.onProgress?.({index:c,totalFiles:s.length,changedTextFiles:i,file:f,changed:m.changed});}}catch(g){throw l=g instanceof Error?g:new Error(String(g)),l}finally{await p.terminate().catch(()=>{});}});return await Promise.all(d),i}var ie={error:0,warn:1,info:2,debug:3},Ns=/^(?:authorization|proxyAuthorization|runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken|xStaticPublisherToken|xApiKey)$/i;function ve(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 lt(e){return typeof e=="string"?ve(e):Array.isArray(e)?e.map(t=>lt(t)):e instanceof Error?{name:e.name,message:ve(e.message),...e.stack?{stack:ve(e.stack)}:{}}:e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([t,n])=>[t,Ns.test(t)?"[REDACTED]":lt(n)])):e}function pt(e){return e?lt(e):void 0}var Kn=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",ut=Kn?S.join(Kn,"current-progress.json"):"",Gn=Promise.resolve();function Zn(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function Bs(e,t){let n={...e},r=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","pageQueue","assetQueue","sitemapQueue"]);for(let[s,i]of Object.entries(t)){let o=n[s];if(typeof o=="number"&&typeof i=="number"&&r.has(s)){n[s]=Math.max(o,i);continue}n[s]=i;}return n}function Yn(e,t,n){ut&&(Gn=Gn.then(async()=>{let r=new Date,s=r.toISOString();await A.mkdir(S.dirname(ut),{recursive:true});let i=await A.readFile(ut,"utf8").then(w=>JSON.parse(w)).catch(()=>null),o=i&&typeof i.details=="object"&&i.details?i.details:{},u=Zn(e),a=i?.currentStep||Zn(i?.source||""),c=i?.startedAt||s,l={...i?.stepDurationsSec??{}},d=i?.stepStartedAt||s;if(a&&a!==u&&i?.stepStartedAt){let w=Math.max(0,Math.round((r.getTime()-new Date(i.stepStartedAt).getTime())/1e3));l[a]=(l[a]??0)+w,d=s;}let p=Math.max(0,Math.round((r.getTime()-new Date(d).getTime())/1e3)),g=Math.max(0,Math.round((r.getTime()-new Date(c).getTime())/1e3)),f=ve(t),m=pt(n)??{},h={checkedAt:s,source:e,message:f,details:Bs(o,m),startedAt:c,currentStep:u,stepStartedAt:d,stepElapsedSec:p,totalElapsedSec:g,stepDurationsSec:l};await A.writeFile(ut,JSON.stringify(h,null,2),"utf8");}).catch(()=>{}));}async function Xn(e,t){await A.mkdir(S.dirname(e),{recursive:true}),await A.appendFile(e,`${JSON.stringify(lt(t))}
|
|
5
|
+
`,"utf8");}function Hs(e,t){let n=typeof t?.phase=="string"?t.phase.trim():"";return n||(e==="page"?"render-pages":e==="asset"?"download-assets":e==="sitemap"?"discovery":e==="timing"&&typeof t?.name=="string"&&t.name.trim()||"crawl")}function Ws(e,t,n){let r=pt(n);return {checkedAt:new Date().toISOString(),currentStep:Hs(e,r),level:e,message:ve(t),details:r??{}}}var $e=class{constructor(t,n,r="info"){this.logDir=t;this.logFile=n;this.level=r;this.ensureLogFileReady();}logDir;logFile;level;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;get logPath(){return S.join(this.logDir,this.logFile)}artifactPath(t){return this.logFile.endsWith(".log.jsonl")?S.join(this.logDir,this.logFile.replace(/\.log\.jsonl$/u,`${t}.jsonl`)):S.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 A.mkdir(this.logDir,{recursive:true}),await A.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(t){this.writeQueue=this.writeQueue.then(t).catch(n=>{this.writeError=n instanceof Error?n:new Error(String(n));});}enqueueLine(t){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await A.appendFile(this.logPath,`${t}
|
|
6
6
|
`,"utf8");});}enqueueJsonLine(t,n){this.enqueueTask(()=>Xn(t,n));}accepts(t){return ie[t]<=ie[this.level]}push(t,n,r){if(!this.accepts(t))return;let s=ve(n),i=pt(r),o=JSON.stringify({time:new Date().toISOString(),level:t,message:s,...i||{}});this.enqueueLine(o),t==="error"?console.error(`[ERROR] ${s}`,i?JSON.stringify(i):""):t==="warn"?console.warn(`[WARN] ${s}`,i?JSON.stringify(i):""):console.log(`[${t.toUpperCase().padEnd(5)}] ${s}`);}info(t,n){this.push("info",t,n);}progress(t,n){Yn(this.logFile,t,n);}debug(t,n){this.push("debug",t,n);}warn(t,n){this.push("warn",t,n);}reject(t,n,r,s,i){let o={kind:t,url:n,reason:r,...s?{source:s}:{},...i||{}};this.enqueueJsonLine(this.rejectedPath,o),this.accepts("debug")&&this.push("debug",`Rejected ${t} ${n}: ${r}`,o);}error(t,n){this.enqueueJsonLine(this.errorsPath,{message:t,...n||{}}),this.push("error",t,n);}mark(t){this.marks.set(t,Date.now());}endMark(t,n){let r=this.marks.get(t);if(!r)return;let s=Date.now()-r,i=Number((s/1e3).toFixed(2));this.push("info",`Timing ${t}: ${i}s`,{name:t,ms:s,seconds:i,...n||{}});}async flush(){let t=Date.now()-this.startedAt,n=Number((t/1e3).toFixed(2));if(this.push("info",`Total time: ${n}s`,{name:"total",ms:t,seconds:n}),await this.writeQueue,this.writeError)throw this.writeError}},dt=class{constructor(t,n="info"){this.logDir=t;this.level=typeof n=="boolean"?n?"debug":"info":n,this.ensureLogFileReady();}logDir;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;level;get logPath(){return S.join(this.logDir,"crawl.log.jsonl")}get currentEventPath(){return S.join(this.logDir,"current-crawl-event.json")}get rejectedPath(){return S.join(this.logDir,"rejected.jsonl")}get ignoredPath(){return S.join(this.logDir,"ignored.jsonl")}get skippedPath(){return S.join(this.logDir,"skipped-http.jsonl")}get errorsPath(){return S.join(this.logDir,"errors.jsonl")}get timingsPath(){return S.join(this.logDir,"timings.jsonl")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await A.mkdir(this.logDir,{recursive:true}),await A.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(t){this.writeQueue=this.writeQueue.then(t).catch(n=>{this.writeError=n instanceof Error?n:new Error(String(n));});}enqueueLine(t){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await A.appendFile(this.logPath,`${t}
|
|
7
|
-
`,"utf8");});}enqueueJsonLine(t,n){this.enqueueTask(()=>Xn(t,n));}updateCurrentEvent(t,n,r){let s=Hs(t,n,r);this.enqueueTask(async()=>{await A.mkdir(this.logDir,{recursive:true}),await A.writeFile(this.currentEventPath,JSON.stringify(s,null,2),"utf8");});}push(t,n,r){let s=ve(n),i=pt(r),o=JSON.stringify({time:new Date().toISOString(),level:t,message:s,...i||{}});this.enqueueLine(o),this.updateCurrentEvent(t,s,i),t==="error"?console.error(s,i||""):t==="warn"?console.warn(s,i||""):(ie[this.level]>=ie.debug||["summary","page","sitemap","asset","timing"].includes(t))&&console.log(s);}info(t,n){this.push("info",t,n);}debug(t,n){ie[this.level]<ie.debug||this.push("debug",t,n);}progress(t,n){Yn("crawl.log.jsonl",t,n),this.updateCurrentEvent("progress",t,n);}checkpoint(t,n){this.updateCurrentEvent("checkpoint",t,n);}page(t,n){this.push("page",t,n);}sitemap(t,n){this.push("sitemap",t,n);}asset(t,n){this.push("asset",t,n);}warn(t,n){this.push("warn",t,n);}error(t,n){this.enqueueJsonLine(this.errorsPath,{message:t,...n||{}}),this.push("error",t,n);}summary(t,n){this.push("summary",t,n);}mark(t){this.marks.set(t,Date.now());}endMark(t,n){let r=this.marks.get(t);if(!r)return;let s=Date.now()-r,i={name:t,ms:s,seconds:Number((s/1e3).toFixed(2)),...n||{}};this.enqueueJsonLine(this.timingsPath,i),this.push("timing",`Timing ${t}: ${i.seconds}s`,i);}reject(t,n,r,s){let i={kind:t,url:n,reason:r,source:s};this.enqueueJsonLine(this.rejectedPath,i),ie[this.level]>=ie.debug&&this.push("reject",`Rejected ${t} ${n}: ${r}`,i);}ignore(t,n,r,s){let i={kind:t,url:n,reason:r,source:s};this.enqueueJsonLine(this.ignoredPath,i),ie[this.level]>=ie.debug&&this.push("ignore",`Ignored ${t} ${n}: ${r}`,i);}skip(t,n,r,s){let i={kind:t,url:n,status:r,source:s};this.enqueueJsonLine(this.skippedPath,i),this.push("warn",`Skipped ${t} ${n}: HTTP ${r}`,i);}async flush(){let t=Date.now()-this.startedAt,n={name:"total",ms:t,seconds:Number((t/1e3).toFixed(2))};if(this.enqueueJsonLine(this.timingsPath,n),await this.writeQueue,this.writeError)throw this.writeError}};var Wt="(?:css|js|mjs|json|map|xml|xsl|rss|atom|txt|enc|jws|png|jpe?g|gif|webp|avif|svg|ico|woff2?|ttf|otf|eot|pdf|mp4|webm)";function er(e){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 tr(e){let t=new Set,n=[],r=/\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 i of e.matchAll(r))i[1]&&er(i[1])&&n.push({index:i.index??0,value:i[1]});for(let i of e.matchAll(s))i[1]&&er(i[1])&&n.push({index:i.index??0,value:i[1]});for(let i of n.sort((o,u)=>o.index-u.index))t.add(i.value);return [...t]}var Js=["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"],fr=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"]),mr=new Set(["",".html",".htm"]),Vs=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),Ks=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function Gs(e){let t=[],n="full",r="full",s=false,i=false,o="";for(let u=0;u<e.length;u++){let a=e[u];if(a==="--retry-timeouts")n="retry-timeouts",s=true;else if(a==="--resume")s=true;else if(a==="--resume-rewrite")s=true,i=true;else if(a==="--crawl-mode"){let c=e[++u];if(!c)throw new Error("--crawl-mode requires a value");r=c==="incremental"?"incremental":"full",s||=r==="incremental";}else if(a.startsWith("--crawl-mode="))r=a.slice(13)==="incremental"?"incremental":"full",s||=r==="incremental";else if(a==="--incremental")r="incremental",s=true;else if(a==="--url"){let c=e[++u];if(!c)throw new Error("--url requires a value");n="single-url",s=true,t.push(c);}else if(a.startsWith("--url="))n="single-url",s=true,t.push(a.slice(6));else if(a==="--urls"){let c=e[++u];if(!c)throw new Error("--urls requires a file path");n="single-url",s=true,t.push(`@${c}`);}else if(a==="--content-sync-plan"){let c=e[++u];if(!c)throw new Error("--content-sync-plan requires a file path");n="content-sync",r="incremental",s=true,o=S.resolve(c);}else a.startsWith("--content-sync-plan=")&&(n="content-sync",r="incremental",s=true,o=S.resolve(a.slice(20)));}return {mode:n,crawlMode:r,urls:t,preserveOutput:s,resumeRewrite:i,contentSyncPlanPath:o}}function Yt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Zs(){let e=Yt();return e?S.resolve(e,".."):""}function Ys(){let e=process.env.STATIC_PUBLISHER_WP_ROOT||process.env.WPSUITE_STATIC_PUBLISHER_WP_ROOT||"";return e.trim()?S.resolve(e):""}function Xs(e){let t=e.trim(),n=[{alias:"@storage-root",root:Zs(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@runtime",root:Yt(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@wp-root",root:Ys(),requiredEnv:"STATIC_PUBLISHER_WP_ROOT or WPSUITE_STATIC_PUBLISHER_WP_ROOT"}];for(let r of n){if(t!==r.alias&&!t.startsWith(`${r.alias}/`))continue;if(!r.root)return {resolvedPath:null,alias:r.alias,requiredEnv:r.requiredEnv};let s=t.slice(r.alias.length).replace(/^\/+/,"");return {resolvedPath:s?S.resolve(r.root,s):r.root,alias:r.alias}}return {resolvedPath:S.resolve(t)}}function hr(e){let t=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(t)return S.resolve(t);let n=Yt();return n?S.join(n,"crawl-manifest.json"):S.join(e.outputDir,".crawl-manifest.json")}function wr(){return {schemaVersion:3,updatedAt:"",pages:{},assets:{}}}function nr(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 ei(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,discoveredAssets:Array.isArray(e.discoveredAssets)?e.discoveredAssets.map(n=>String(n)):[],lastCrawledAt:String(e.lastCrawledAt||""),lastSeenRunId:String(e.lastSeenRunId||""),rewriteComplete:e.rewriteComplete===true||!t}}function Jt(e){let t=e?.["content-type"]?.trim();return t||null}function ti(){return {rewriteTargets:new Set,changedFiles:new Set,deletedFiles:new Set}}function Z(e,t,n){let r=he(t.outputDir,n);r&&(e.changedFiles.add(r),e.deletedFiles.delete(r));}function rr(e,t,n){let r=he(t.outputDir,n);r&&(e.deletedFiles.add(r),e.changedFiles.delete(r));}function Ce(e,t){e.rewriteTargets.add(S.resolve(t));}async function ni(e){try{let t=await A.readFile(hr(e),"utf8"),n=JSON.parse(t);if(n&&typeof n=="object"&&n.pages&&typeof n.pages=="object"){if((n.schemaVersion===2||n.schemaVersion===3)&&n.assets&&typeof n.assets=="object")return {schemaVersion:3,updatedAt:String(n.updatedAt||""),pages:Object.fromEntries(Object.entries(n.pages).map(([r,s])=>[r,nr(s)])),assets:Object.fromEntries(Object.entries(n.assets).map(([r,s])=>[r,ei(s)]))};if(n.schemaVersion===1)return {schemaVersion:3,updatedAt:String(n.updatedAt||""),pages:Object.fromEntries(Object.entries(n.pages).map(([r,s])=>[r,nr(s)])),assets:{}}}}catch{}return wr()}function Vt(e){return JSON.parse(JSON.stringify(e))}async function ri(e,t){let n=hr(e);await A.mkdir(S.dirname(n),{recursive:true}),await A.writeFile(n,JSON.stringify(t,null,2),"utf8");}async function we(e,t){if(!t.trackManifest)return;let n=async()=>{let r=Vt(t.manifest);r.updatedAt=new Date().toISOString(),t.manifest.updatedAt=r.updatedAt,await ri(e,r);};t.manifestSaveChain=t.manifestSaveChain.then(n,n),await t.manifestSaveChain;}function ze(e){if(!e)return null;let t=e.trim();return t||null}function si(e,t){let n=new Set,r=new Set([...Object.keys(e),...Object.keys(t)]);for(let s of r){let i=e[s],o=t[s];!i||!o||i===o||n.add(s);}return n}async function ii(e,t,n,r){let s=[...new Set(n.map(u=>u.trim()).filter(Boolean))],i=String(e.wpsuite?.runtimeToken||"").trim();if(s.length===0||!i)return new Map;let o=new URL("/wp-json/smartcloud-static-publisher/v1/change-tokens",e.sourceOrigin).toString();try{let u=await t.post(o,{timeout:3e4,failOnStatusCode:!1,headers:{"content-type":"application/json","x-static-publisher-token":i},data:JSON.stringify({urls:s})});if(!u.ok())return r.warn(`Change token lookup failed with HTTP ${u.status()}`,{endpoint:o,status:u.status()}),new Map;let a=await u.json().catch(()=>null);if(!a||!Array.isArray(a.items))return new Map;let c=new Map;for(let l of a.items)!l||typeof l.url!="string"||c.set(l.url,l);return c}catch(u){return r.warn("Change token lookup failed; falling back to sitemap metadata",{endpoint:o,error:u instanceof Error?`${u.name}: ${u.message.split(/\r?\n/u,1)[0]}`:"Unknown change-token request failure"}),new Map}}async function zt(e,t,n,r,s){if(!n.enabled&&!n.trackManifest)return null;if(n.changeTokenCache.has(r))return n.changeTokenCache.get(r)??null;let o=(await ii(e,t,[r],s)).get(r)??null;return tn(e,r)&&(!o||o.supported!==true||!o.token)&&(o=await ci(e,t,r,s)),o=ai(e,o),n.changeTokenCache.set(r,o),o}function oi(e){return `subscriber=${e.wpsuite?.siteSettings?.subscriber===true?"1":"0"}`}function ai(e,t){if(!t?.supported||!t.token)return t;let n=oi(e);return {...t,token:Be(`${t.token}
|
|
8
|
-
${n}`,40),tokenSource:t.tokenSource?`${t.tokenSource}+site-subscriber`:"site-subscriber"}}async function
|
|
7
|
+
`,"utf8");});}enqueueJsonLine(t,n){this.enqueueTask(()=>Xn(t,n));}updateCurrentEvent(t,n,r){let s=Ws(t,n,r);this.enqueueTask(async()=>{await A.mkdir(this.logDir,{recursive:true}),await A.writeFile(this.currentEventPath,JSON.stringify(s,null,2),"utf8");});}push(t,n,r){let s=ve(n),i=pt(r),o=JSON.stringify({time:new Date().toISOString(),level:t,message:s,...i||{}});this.enqueueLine(o),this.updateCurrentEvent(t,s,i),t==="error"?console.error(s,i||""):t==="warn"?console.warn(s,i||""):(ie[this.level]>=ie.debug||["summary","page","sitemap","asset","timing"].includes(t))&&console.log(s);}info(t,n){this.push("info",t,n);}debug(t,n){ie[this.level]<ie.debug||this.push("debug",t,n);}progress(t,n){Yn("crawl.log.jsonl",t,n),this.updateCurrentEvent("progress",t,n);}checkpoint(t,n){this.updateCurrentEvent("checkpoint",t,n);}page(t,n){this.push("page",t,n);}sitemap(t,n){this.push("sitemap",t,n);}asset(t,n){this.push("asset",t,n);}warn(t,n){this.push("warn",t,n);}error(t,n){this.enqueueJsonLine(this.errorsPath,{message:t,...n||{}}),this.push("error",t,n);}summary(t,n){this.push("summary",t,n);}mark(t){this.marks.set(t,Date.now());}endMark(t,n){let r=this.marks.get(t);if(!r)return;let s=Date.now()-r,i={name:t,ms:s,seconds:Number((s/1e3).toFixed(2)),...n||{}};this.enqueueJsonLine(this.timingsPath,i),this.push("timing",`Timing ${t}: ${i.seconds}s`,i);}reject(t,n,r,s){let i={kind:t,url:n,reason:r,source:s};this.enqueueJsonLine(this.rejectedPath,i),ie[this.level]>=ie.debug&&this.push("reject",`Rejected ${t} ${n}: ${r}`,i);}ignore(t,n,r,s){let i={kind:t,url:n,reason:r,source:s};this.enqueueJsonLine(this.ignoredPath,i),ie[this.level]>=ie.debug&&this.push("ignore",`Ignored ${t} ${n}: ${r}`,i);}skip(t,n,r,s){let i={kind:t,url:n,status:r,source:s};this.enqueueJsonLine(this.skippedPath,i),this.push("warn",`Skipped ${t} ${n}: HTTP ${r}`,i);}async flush(){let t=Date.now()-this.startedAt,n={name:"total",ms:t,seconds:Number((t/1e3).toFixed(2))};if(this.enqueueJsonLine(this.timingsPath,n),await this.writeQueue,this.writeError)throw this.writeError}};var Wt="(?:css|js|mjs|json|map|xml|xsl|rss|atom|txt|enc|jws|png|jpe?g|gif|webp|avif|svg|ico|woff2?|ttf|otf|eot|pdf|mp4|webm)";function er(e){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 tr(e){let t=new Set,n=[],r=/\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 i of e.matchAll(r))i[1]&&er(i[1])&&n.push({index:i.index??0,value:i[1]});for(let i of e.matchAll(s))i[1]&&er(i[1])&&n.push({index:i.index??0,value:i[1]});for(let i of n.sort((o,u)=>o.index-u.index))t.add(i.value);return [...t]}var Vs=["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"],fr=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"]),mr=new Set(["",".html",".htm"]),Ks=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),Gs=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function Zs(e){let t=[],n="full",r="full",s=false,i=false,o="";for(let u=0;u<e.length;u++){let a=e[u];if(a==="--retry-timeouts")n="retry-timeouts",s=true;else if(a==="--resume")s=true;else if(a==="--resume-rewrite")s=true,i=true;else if(a==="--crawl-mode"){let c=e[++u];if(!c)throw new Error("--crawl-mode requires a value");r=c==="incremental"?"incremental":"full",s||=r==="incremental";}else if(a.startsWith("--crawl-mode="))r=a.slice(13)==="incremental"?"incremental":"full",s||=r==="incremental";else if(a==="--incremental")r="incremental",s=true;else if(a==="--url"){let c=e[++u];if(!c)throw new Error("--url requires a value");n="single-url",s=true,t.push(c);}else if(a.startsWith("--url="))n="single-url",s=true,t.push(a.slice(6));else if(a==="--urls"){let c=e[++u];if(!c)throw new Error("--urls requires a file path");n="single-url",s=true,t.push(`@${c}`);}else if(a==="--content-sync-plan"){let c=e[++u];if(!c)throw new Error("--content-sync-plan requires a file path");n="content-sync",r="incremental",s=true,o=S.resolve(c);}else a.startsWith("--content-sync-plan=")&&(n="content-sync",r="incremental",s=true,o=S.resolve(a.slice(20)));}return {mode:n,crawlMode:r,urls:t,preserveOutput:s,resumeRewrite:i,contentSyncPlanPath:o}}function Yt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Ys(){let e=Yt();return e?S.resolve(e,".."):""}function Xs(){let e=process.env.STATIC_PUBLISHER_WP_ROOT||process.env.WPSUITE_STATIC_PUBLISHER_WP_ROOT||"";return e.trim()?S.resolve(e):""}function ei(e){let t=e.trim(),n=[{alias:"@storage-root",root:Ys(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@runtime",root:Yt(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@wp-root",root:Xs(),requiredEnv:"STATIC_PUBLISHER_WP_ROOT or WPSUITE_STATIC_PUBLISHER_WP_ROOT"}];for(let r of n){if(t!==r.alias&&!t.startsWith(`${r.alias}/`))continue;if(!r.root)return {resolvedPath:null,alias:r.alias,requiredEnv:r.requiredEnv};let s=t.slice(r.alias.length).replace(/^\/+/,"");return {resolvedPath:s?S.resolve(r.root,s):r.root,alias:r.alias}}return {resolvedPath:S.resolve(t)}}function hr(e){let t=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(t)return S.resolve(t);let n=Yt();return n?S.join(n,"crawl-manifest.json"):S.join(e.outputDir,".crawl-manifest.json")}function wr(){return {schemaVersion:3,updatedAt:"",pages:{},assets:{}}}function nr(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 ti(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,discoveredAssets:Array.isArray(e.discoveredAssets)?e.discoveredAssets.map(n=>String(n)):[],lastCrawledAt:String(e.lastCrawledAt||""),lastSeenRunId:String(e.lastSeenRunId||""),rewriteComplete:e.rewriteComplete===true||!t}}function Jt(e){let t=e?.["content-type"]?.trim();return t||null}function ni(){return {rewriteTargets:new Set,changedFiles:new Set,deletedFiles:new Set}}function Z(e,t,n){let r=he(t.outputDir,n);r&&(e.changedFiles.add(r),e.deletedFiles.delete(r));}function rr(e,t,n){let r=he(t.outputDir,n);r&&(e.deletedFiles.add(r),e.changedFiles.delete(r));}function Ce(e,t){e.rewriteTargets.add(S.resolve(t));}async function ri(e){try{let t=await A.readFile(hr(e),"utf8"),n=JSON.parse(t);if(n&&typeof n=="object"&&n.pages&&typeof n.pages=="object"){if((n.schemaVersion===2||n.schemaVersion===3)&&n.assets&&typeof n.assets=="object")return {schemaVersion:3,updatedAt:String(n.updatedAt||""),pages:Object.fromEntries(Object.entries(n.pages).map(([r,s])=>[r,nr(s)])),assets:Object.fromEntries(Object.entries(n.assets).map(([r,s])=>[r,ti(s)]))};if(n.schemaVersion===1)return {schemaVersion:3,updatedAt:String(n.updatedAt||""),pages:Object.fromEntries(Object.entries(n.pages).map(([r,s])=>[r,nr(s)])),assets:{}}}}catch{}return wr()}function Vt(e){return JSON.parse(JSON.stringify(e))}async function si(e,t){let n=hr(e);await A.mkdir(S.dirname(n),{recursive:true}),await A.writeFile(n,JSON.stringify(t,null,2),"utf8");}async function we(e,t){if(!t.trackManifest)return;let n=async()=>{let r=Vt(t.manifest);r.updatedAt=new Date().toISOString(),t.manifest.updatedAt=r.updatedAt,await si(e,r);};t.manifestSaveChain=t.manifestSaveChain.then(n,n),await t.manifestSaveChain;}function ze(e){if(!e)return null;let t=e.trim();return t||null}function ii(e,t){let n=new Set,r=new Set([...Object.keys(e),...Object.keys(t)]);for(let s of r){let i=e[s],o=t[s];!i||!o||i===o||n.add(s);}return n}async function oi(e,t,n,r){let s=[...new Set(n.map(u=>u.trim()).filter(Boolean))],i=String(e.wpsuite?.runtimeToken||"").trim();if(s.length===0||!i)return new Map;let o=new URL("/wp-json/smartcloud-static-publisher/v1/change-tokens",e.sourceOrigin).toString();try{let u=await t.post(o,{timeout:3e4,failOnStatusCode:!1,headers:{"content-type":"application/json","x-static-publisher-token":i},data:JSON.stringify({urls:s})});if(!u.ok())return r.warn(`Change token lookup failed with HTTP ${u.status()}`,{endpoint:o,status:u.status()}),new Map;let a=await u.json().catch(()=>null);if(!a||!Array.isArray(a.items))return new Map;let c=new Map;for(let l of a.items)!l||typeof l.url!="string"||c.set(l.url,l);return c}catch(u){return r.warn("Change token lookup failed; falling back to sitemap metadata",{endpoint:o,error:u instanceof Error?`${u.name}: ${u.message.split(/\r?\n/u,1)[0]}`:"Unknown change-token request failure"}),new Map}}async function zt(e,t,n,r,s){if(!n.enabled&&!n.trackManifest)return null;if(n.changeTokenCache.has(r))return n.changeTokenCache.get(r)??null;let o=(await oi(e,t,[r],s)).get(r)??null;return tn(e,r)&&(!o||o.supported!==true||!o.token)&&(o=await ui(e,t,r,s)),o=ci(e,o),n.changeTokenCache.set(r,o),o}function ai(e){return `subscriber=${e.wpsuite?.siteSettings?.subscriber===true?"1":"0"}`}function ci(e,t){if(!t?.supported||!t.token)return t;let n=ai(e);return {...t,token:Be(`${t.token}
|
|
8
|
+
${n}`,40),tokenSource:t.tokenSource?`${t.tokenSource}+site-subscriber`:"site-subscriber"}}async function ui(e,t,n,r){try{let s=await t.get(n,{timeout:Math.min(e.navigationTimeoutMs,15e3),failOnStatusCode:!1});if(s.status()!==404)return r.warn(`Generated 404 fallback token skipped for ${n}`,{url:n,status:s.status(),requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),null;let i=await s.text().catch(()=>""),o=Be(`${n}
|
|
9
9
|
404
|
|
10
|
-
${i}`,40);return r.info(`Using generated 404 fallback change token for ${n}`,{url:n,requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),{url:n,supported:!0,token:o,tokenSource:"generated-404-response-hash",postId:null,dependencyPostIds:[],reason:null}}catch(s){return r.warn(`Generated 404 fallback token lookup failed for ${n}`,{url:n,error:String(s),requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),null}}async function ui(e,t,n,r,s,i){let o=tn(e,s);if(!r.enabled)return {action:"render",changeToken:r.trackManifest?await zt(e,t,r,s,i):null};let u=r.manifest.pages[s];if(!u)return {action:"render",changeToken:await zt(e,t,r,s,i)};let a=await zt(e,t,r,s,i);if(a?.supported&&a.token)return u.changeToken===a.token?o&&!await li(e,t,s,i)?{action:"render",changeToken:a}:{action:"reuse",changeToken:a}:{action:"render",changeToken:a};let c=ze(n.sitemapLastmodByPage[s]);return c&&u.sitemapLastmod&&u.sitemapLastmod===c?{action:"reuse",changeToken:a}:{action:"render",changeToken:a}}async function li(e,t,n,r){try{let i=(await t.get(n,{timeout:Math.min(e.navigationTimeoutMs,15e3),failOnStatusCode:!1})).status();return i===404?!0:(r.warn(`Generated 404 request path no longer returns 404 for ${n}`,{url:n,status:i,requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),!1)}catch(s){return r.warn(`Generated 404 status probe failed for ${n}`,{url:n,error:String(s),requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),false}}async function di(e,t,n,r,s){let i=sr(n.previousManifest,void 0,r,"previous-manifest"),o=0;for(let[p,g]of Object.entries(n.manifest.pages))if(!n.seenPages.has(p)){rr(s,e,g.outputPath);try{await A.unlink(g.outputPath);}catch(f){(f.code||"")!=="ENOENT"&&r.warn(`Failed to remove stale incremental page output for ${p}`,{url:p,outputPath:g.outputPath,error:String(f)});}delete n.manifest.pages[p],o++;}let u=sr(n.manifest,n.runId,r,"active-manifest"),a=new Set,c=new Set;for(let p of u){for(let m of Qe(e,p))a.add(m);let g=n.manifest.assets[p]?.outputPath;g&&c.add(g);let f=Je(e,t.assetMap,p);f&&c.add(f);}for(let p of Object.keys(n.manifest.assets))u.has(p)||delete n.manifest.assets[p];let l=0,d=0;for(let p of i){let g=new Set,f=n.previousManifest.assets[p]?.outputPath;f&&g.add(f);let m=Je(e,t.assetMap,p);if(!u.has(p)&&m)g.add(m);else if(!u.has(p)){let h=Ti(e,p,r,"incremental-cleanup");h&&(g.add(h.originalFilePath),h.hashedFilePath&&g.add(h.hashedFilePath));}for(let h of g)if(!c.has(h)){rr(s,e,h);try{await A.unlink(h),l++;}catch(w){(w.code||"")!=="ENOENT"&&r.warn(`Failed to remove stale incremental asset output for ${p}`,{url:p,outputPath:h,error:String(w)});}}for(let h of Qe(e,p))a.has(h)||Object.prototype.hasOwnProperty.call(t.assetMap,h)&&(delete t.assetMap[h],d++);}(o>0||l>0||d>0)&&r.info(`Incremental cleanup removed ${o} stale pages, ${l} stale assets, ${d} stale asset mappings`,{removedPages:o,removedAssets:l,removedAssetMappings:d,phase:"incremental-cleanup"});}function sr(e,t,n,r){let s=new Set,i=o=>{let u=o.trim();if(u){if(n){let a=ye(u,n,"asset",r??"manifest");if(!a)return;s.add(a.toString());return}s.add(u);}};for(let o of Object.values(e.pages))for(let u of o.discoveredAssets||[])i(u);for(let[o,u]of Object.entries(e.assets||{}))t&&u.lastSeenRunId!==t||i(o);return s}function ir(e,t,n){for(let r of t)for(let s of Qe(e,r))if(n.has(s))return true;return false}function pi(e,t,n,r,s){let i=new Set(n.rewriteTargets);for(let u of Object.values(t.manifest.pages))u.rewriteComplete||i.add(S.resolve(u.outputPath));for(let u of Object.values(t.manifest.assets))u.isText&&!u.rewriteComplete&&i.add(S.resolve(u.outputPath));let o=si(r,s);if(o.size===0)return [...i];for(let u of Object.values(t.manifest.pages))ir(e,u.discoveredAssets,o)&&i.add(S.resolve(u.outputPath));for(let[u,a]of Object.entries(t.manifest.assets)){a.isText&&ir(e,a.discoveredAssets,o)&&i.add(S.resolve(a.outputPath));for(let c of Qe(e,u))if(o.has(c)){Z(n,e,a.outputPath),a.isText&&i.add(S.resolve(a.outputPath));break}}return [...i]}function gi(e,t){let n=t?new Set(Array.from(t,s=>S.resolve(s))):null,r=s=>n===null||n.has(S.resolve(s));for(let s of Object.values(e.manifest.pages))r(s.outputPath)&&(s.rewriteComplete=true);for(let s of Object.values(e.manifest.assets)){if(!s.isText){s.rewriteComplete=true;continue}r(s.outputPath)&&(s.rewriteComplete=true);}}function fi(e,t,n){let r=new Set,s=i=>{if(!i)return;let o=he(e.outputDir,i);o&&r.add(o);};for(let i of t.donePages)s(le(e,i));for(let i of Object.values(n.manifest.pages))i.lastSeenRunId===n.runId&&s(i.outputPath);for(let i of t.doneAssets)s(Je(e,t.assetMap,i));for(let i of Object.values(n.manifest.assets))i.lastSeenRunId===n.runId&&s(i.outputPath);return r}async function mi(e,t,n,r,s){let i=[...r.deletedFiles].sort(),o=fi(e,t,n),u=0;for(let l of [...o].sort()){try{if((await A.stat(S.join(e.outputDir,l))).isFile())continue}catch{}u++,s.warn(`Active output is missing after crawl: ${l}`,{phase:"deploy-plan",file:l,outputPath:S.join(e.outputDir,l)});}if(u>0&&s.warn(`Detected ${u} active output file(s) missing before deploy plan save.`,{phase:"deploy-plan",missingActiveOutputs:u}),i.length===0)return [];let a=[],c=0;for(let l of i){if(!o.has(l)){a.push(l);continue}c++;let d=S.join(e.outputDir,l),p;try{p=(await A.stat(d)).isFile();}catch{p=false;}s.warn(`Deploy plan protected active output from deletion: ${l}`,{phase:"deploy-plan",file:l,outputPath:d,exists:p});}return c>0&&s.info(`Deploy plan skipped ${c} active output deletion(s).`,{phase:"deploy-plan",protectedDeletes:c,deletedFiles:a.length}),a}function Qe(e,t){let n=new Set([t]);try{let r=new URL(t),i=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{i.push(new URL(e.targetOrigin).origin);}catch{}for(let o of i)try{n.add(new URL(o).origin+r.pathname+r.search);}catch{}n.add(r.pathname+r.search),n.add(r.pathname);}catch{}return [...n]}function hi(e,t){let n=new Set([t]);try{let r=new URL(t),i=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{i.push(new URL(e.targetOrigin).origin);}catch{}for(let o of i)try{n.add(new URL(o).origin+r.pathname+r.search);}catch{}n.add(r.pathname+r.search);}catch{}return [...n]}function yr(e,t){let n=e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/"?e.targetOrigin:"https://relative.invalid/";try{let r=new URL(t,n);return S.join(e.outputDir,en(r.pathname))}catch{return null}}function wi(e,t,n){for(let r of hi(e,n)){let s=t[r];if(!s)continue;let i=yr(e,s);if(i)return {outputPath:i,publicUrl:s}}return null}function yi(e,t,n){for(let r of Qe(e,n)){let s=t[r];if(!s)continue;let i=yr(e,s);if(i)return i}return null}function Je(e,t,n){let r=yi(e,t,n);if(r)return r;try{return yt(e,n).originalFilePath}catch{return null}}function Si(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.join(S.resolve(e),"queue-runner-heartbeat.json"):""}async function or(e){let t=Si();if(t)try{let n=await A.readFile(t,"utf8"),r=JSON.parse(n);if(!r||typeof r!="object")return;await A.writeFile(t,JSON.stringify({...r,checkedAt:new Date().toISOString(),status:"running",currentStep:"rewrite",message:e},null,2),"utf8");}catch{}}function Pi(e,t){let n=new Set;for(let r of t.donePages)n.add(S.resolve(le(e,r)));for(let r of t.doneAssets){let s=Je(e,t.assetMap,r);!s||!be(s)||n.add(S.resolve(s));}return [...n]}var ht="re:",gt=new Map;function bi(e){if(!e.startsWith(ht))return null;let t=gt.get(e);if(t!==void 0)return t||null;let n=e.slice(ht.length).trim();if(!n)return gt.set(e,false),null;try{let r=new RegExp(n);return gt.set(e,r),r}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),gt.set(e,false),null}}function Xt(e,t){let n=bi(t);return n?n.test(e):t.startsWith(ht)?false:e.startsWith(t)}function vi(e,t){return t.find(n=>Xt(e,n))}function Sr(e,t){let n=vi(t.pathname,e.blockedPathPrefixes);if(n)return n.startsWith(ht)?`blocked path regex: ${n}`:`blocked path prefix: ${n}`;let r=e.blockedSearchFragments.find(s=>t.search.includes(s));return r?`blocked search fragment: ${r}`:null}function Ci(e){let t=new URL(e.sourceOrigin),n=new Set([t.hostname,...e.allowedAssetHosts]);if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{n.add(new URL(e.targetOrigin).hostname);}catch{}for(let r of Object.keys(e.extraReplacements||{}))try{n.add(new URL(r).hostname);}catch{}return n}function Ri(e,t){return Ci(e).has(t.hostname)}function Ii(e){let t=ce(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function Kt(e){let t=ce(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function xi(e){let t=ce(e).replace(/\\\//g,"/").trim(),n=S.extname(t).toLowerCase();return fr.has(n)||mr.has(n)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function Ee(e){return Ks.some(t=>e.pathname.startsWith(t))}function H(e,t,n=e.sourceOrigin,r,s="url"){let i=Ii(t);if(!i||i.startsWith("data:")||i.startsWith("blob:")||i.startsWith("mailto:")||i.startsWith("tel:")||i.startsWith("#"))return r?.ignore(s,t,"empty or unsupported scheme",n),null;if(Kt(i))return r?.ignore(s,t,"looks like JavaScript/code fragment",n),null;if(xi(i))return r?.ignore(s,t,"looks like JavaScript property access",n),null;try{let o=new URL(i,n);if(Pr(o))return r?.reject(s,t,"malformed URL encoding",n),null;if(!["http:","https:"].includes(o.protocol))return r?.ignore(s,t,"unsupported protocol: ",n),null;if(!Ri(e,o))return r?.ignore(s,o.toString(),"host not allowed",n),null;let u=Sr(e,o);if(u)return r?.reject(s,o.toString(),u,n),null;let a=new URL(e.sourceOrigin);return o.protocol=a.protocol,o.host=a.host,o.hash="",o}catch{return r?.reject(s,t,"invalid URL",n),null}}function Pr(e){try{return decodeURIComponent(e.pathname),decodeURIComponent(e.search),decodeURIComponent(e.hash),!1}catch{return true}}function ye(e,t,n,r){try{let s=new URL(e);return Pr(s)?(t.reject(n,e,"malformed URL encoding",r),null):s.protocol!=="http:"&&s.protocol!=="https:"?(t.reject(n,e,`unsupported protocol: ${s.protocol}`,r),null):s}catch{return t.reject(n,e,"invalid URL",r),null}}function br(e){return fr.has(S.extname(e.pathname).toLowerCase())}function Se(e){return Ee(e)?false:mr.has(S.extname(e.pathname).toLowerCase())}function Me(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function q(e,t){return !!(Me(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(n=>Xt(t.pathname,n))||br(t)||!Se(t)&&!Ee(t))}function le(e,t){let n=new URL(t),r=en(n.pathname);return r.endsWith("/")?r+="index.html":S.extname(r)||(r+="/index.html"),S.join(e.outputDir,r)}function en(e){try{return decodeURIComponent(e)}catch{return e}}function Ai(e){if(!e.generated404RequestPath)return null;try{let t=new URL(e.generated404RequestPath,e.sourceOrigin);return !t.pathname.endsWith("/")&&S.extname(t.pathname)===""&&(t.pathname+="/"),t.hash="",t.toString()}catch{return null}}function tn(e,t){let n=Ai(e);if(!n)return false;try{return new URL(t,e.sourceOrigin).toString()===n}catch{return false}}function yt(e,t){let n=new URL(t),r=en(n.pathname);r.endsWith("/")&&(r+="index.html");let s=!!n.search,i=r,o=S.join(e.outputDir,i),u=_t(e.targetOrigin,i),a=`${u}${n.search}`;if(!s)return {originalPathname:i,originalFilePath:o,originalPublicUrl:u,originalPublicUrlWithSearch:a,preferQueryHashed:s};let c=S.extname(r),d=`${c?r.slice(0,-c.length):r}.${Be(n.search)}${c||".bin"}`;return {originalPathname:i,originalFilePath:o,originalPublicUrl:u,originalPublicUrlWithSearch:a,preferQueryHashed:s,hashedPathname:d,hashedFilePath:S.join(e.outputDir,d),hashedPublicUrl:_t(e.targetOrigin,d)}}function Ti(e,t,n,r){let s=ye(t,n,"asset",r);return s?yt(e,s.toString()):null}function ki(e,t,n,r,s){t[n]=r;try{let i=new URL(n),u=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{u.push(new URL(e.targetOrigin).origin);}catch{}for(let a of u)try{let c=new URL(a);t[c.origin+i.pathname+i.search]=r;}catch{}try{let a=(()=>{let c=new URL(r,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin);return `${c.pathname}${c.search}`})();t[i.pathname+i.search]=a;}catch{}try{let a=new URL(r,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=a;}catch{}try{let a=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=a;}catch{}}catch{}}async function vr(e){try{return await A.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Ve(e){try{return await A.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function $i(e){let t=String(e["content-length"]||"").trim();if(!t)return null;let n=Number.parseInt(t,10);return Number.isFinite(n)&&n>=0?n:null}function Cr(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let n=Date.parse(t);return Number.isFinite(n)?n:null}function Ei(e,t){let n=Cr(t),r=$i(t),s=e?.mtime.getTime();return n!==null&&Math.abs((s??0)-n)>=1e3||r!==null&&e?.size!==r?false:n!==null||r!==null}async function Mi(e,t){if(!t)return;let n=Cr(t);if(n===null)return;let r=await Ve(e);if(!r)return;let s=new Date(n);await A.utimes(e,r.atime,s).catch(()=>{});}function ar(e,t){let n=S.extname(e.pathname).toLowerCase(),r=t["content-type"]||"";return Vs.has(n)||Js.some(s=>r.includes(s))&&!r.startsWith("image/")&&!r.includes("font")}function Fi(e){try{let t=S.extname(new URL(e).pathname).toLowerCase();return t===".js"||t===".mjs"}catch{return false}}function We(e,t){(e.doneAssets.size%25===0||e.doneAssets.size===1||e.doneAssets.size===e.stats.assetsQueued)&&t.progress(`Asset download progress: processed ${e.doneAssets.size}, discovered ${e.stats.assetsQueued}.`,{doneAssets:e.doneAssets.size,assetsQueued:e.stats.assetsQueued,phase:"download-assets"});}function Di(e){return Be(e.toString("base64"),40)}function Oi(e,t,n){let r=e.assetVariantDigestsByOriginalPath.get(t);if(!r||r.size===0)return false;for(let s of r)if(s!==n)return true;return false}function ji(e,t,n){let r=e.assetVariantDigestsByOriginalPath.get(t);r||(r=new Set,e.assetVariantDigestsByOriginalPath.set(t,r)),r.add(n);}async function Gt(e,t,n,r,s,i,o){let u=yt(e,n),a=Di(r),c=u.originalFilePath,l=u.originalPublicUrlWithSearch;if(u.preferQueryHashed&&u.hashedFilePath&&u.hashedPublicUrl&&Oi(s,u.originalFilePath,a)){let f=wi(e,t,n);f?(c=f.outputPath,l=f.publicUrl):(c=u.hashedFilePath,l=u.hashedPublicUrl);}ki(e,t,n,l,u.originalPublicUrl);let d=be(c)?Buffer.from(Ht(r.toString("utf8"),e,t,c),"utf8"):r,p=await vr(c),g=false;return (p===null||!p.equals(d))&&(await He(c,d),g=true),i?.debug(`${g?"Saved":"Skipped unchanged"} asset output ${n}`,{phase:"download-assets",url:n,outputPath:c,bytes:d.length,wroteFile:g}),ji(s,u.originalFilePath,a),await Mi(c,o),s.stats.assetsSaved++,i&&(s.stats.assetsSaved%50===0||s.stats.assetsSaved===1)&&i.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:c,publicUrl:l,wroteFile:g}}function Ke(e,t,n,r,s){let i=()=>{let d=String(s??"").trim();if(!d)return {discoveredFrom:"",discoveredFromType:"unknown"};if(d==="seed-path"||d==="cli"||d==="generated-404-request-path")return {discoveredFrom:d,discoveredFromType:d};if(/^https?:\/\//i.test(d))try{let p=new URL(d);return Me(p)?{discoveredFrom:d,discoveredFromType:"sitemap"}:q(e,p)?{discoveredFrom:d,discoveredFromType:"asset"}:Se(p)&&!Ee(p)?{discoveredFrom:d,discoveredFromType:"page"}:{discoveredFrom:d,discoveredFromType:"url"}}catch{return {discoveredFrom:d,discoveredFromType:"url"}}return {discoveredFrom:d,discoveredFromType:"url"}},o=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,u=H(e,n,o,r,"page");if(!u)return;if(!Se(u)||br(u)){if(q(e,u)){r.info(`Seeded/non-page URL queued as asset: ${u.toString()}`,{url:u.toString(),source:s}),J(e,t,u.toString(),r,s);return}r.reject("page",u.toString(),Ee(u)?"asset/internal path cannot be page":"not page-like",s);return}let a=u.toString(),{discoveredFrom:c,discoveredFromType:l}=i();c&&!t.pageDiscoverySources.has(a)&&t.pageDiscoverySources.set(a,c),!t.donePages.has(a)&&!t.queuedPages.has(a)&&(t.queuedPages.add(a),t.pageQueue.push(a),t.stats.pagesQueued++,r.debug(`Queued discovered page ${a}`,{phase:"discovery",url:a,discoveredFrom:c,discoveredFromType:l,outputPath:le(e,a)}),(t.stats.pagesQueued%25===0||t.stats.pagesQueued===1)&&r.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 J(e,t,n,r,s){let i=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,o=H(e,n,i,r,"asset");if(!o)return;if(!q(e,o)){r.reject("asset",o.toString(),"not a safe asset path/prefix",s);return}let u=o.toString();!t.doneAssets.has(u)&&!t.queuedAssets.has(u)&&(t.queuedAssets.add(u),t.assetQueue.push(u),t.stats.assetsQueued++,(t.stats.assetsQueued%100===0||t.stats.assetsQueued===1)&&r.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 wt(e,t,n,r,s){let i=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,o=H(e,n,i,r,"sitemap");if(!o)return;if(!Me(o)){r.reject("sitemap",o.toString(),"not sitemap-like",s);return}let u=o.toString();!t.doneSitemaps.has(u)&&!t.queuedSitemaps.has(u)&&(t.queuedSitemaps.add(u),t.sitemapQueue.push(u),t.stats.sitemapsQueued++,(t.stats.sitemapsQueued%10===0||t.stats.sitemapsQueued===1)&&r.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 Li(e){let t=ce(e),n=[...t.matchAll(/<url>\s*([\s\S]*?)\s*<\/url>/gi)].map(r=>r[1]);return n.length>0?n.map(r=>{let s=r.match(/<loc>\s*([^<]+?)\s*<\/loc>/i);if(!s?.[1])return null;let i=r.match(/<lastmod>\s*([^<]+?)\s*<\/lastmod>/i);return {loc:s[1].trim(),lastmod:ze(i?.[1]??null)}}).filter(r=>!!r):[...t.matchAll(/<loc>\s*([^<]+?)\s*<\/loc>/gi)].map(r=>({loc:r[1].trim(),lastmod:null})).filter(r=>r.loc)}function Ui(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function qi(e){let t=[],n=/url\(\s*(?:"([^"]+)"|'([^']+)'|([^)]*?))\s*\)/gi;for(let r of e.matchAll(n)){let s=e.slice(Math.max(0,r.index-8),r.index);if(/\bnew\s+$/i.test(s))continue;let i=(r[1]||r[2]||r[3]||"").trim();i&&t.push(i);}return t}function _i(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function Ni(e,t){if(t==="dom-style")return true;let n=(()=>{try{return S.extname(new URL(e).pathname).toLowerCase()}catch{return ""}})();return !(n===".js"||n===".mjs"||n===".map"||t.includes("javascript"))}function Qt(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function Rr(e,t,n,r){let s=[];await A.mkdir(t,{recursive:true});let i=await A.readdir(e,{withFileTypes:true});for(let o of i){let u=S.join(e,o.name),a=S.join(t,o.name);if(o.isDirectory()){s.push(...await Rr(u,a,n,r));continue}await Ir(u,a,n,r)&&s.push(a);}return s}async function Bi(e,t){try{let[n,r]=await Promise.all([A.stat(e),A.stat(t)]);if(n.size!==r.size)return !1;let[s,i]=await Promise.all([A.readFile(e),A.readFile(t)]);return s.equals(i)}catch{return false}}async function Ir(e,t,n,r){let s=S.resolve(t);return n.has(s)?(r.debug("Skipped post-crawl copy over crawled page output",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):await Bi(e,t)?(r.debug("Skipped unchanged post-crawl copy target",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):(await A.mkdir(S.dirname(t),{recursive:true}),await A.copyFile(e,t),true)}async function Hi(e,t,n){let r=Object.entries(e.postCrawlCopyMap||{}).map(([u,a])=>({sourcePath:u.trim(),prefix:String(a||"").trim()}));if(r.length===0)return [];let s=0,i=[],o=new Set([...t.donePages].map(u=>S.resolve(le(e,u))));n.mark("copy-extra-paths");for(let u of r){let a=u.sourcePath,c=u.prefix;if(!a||!c){n.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:a,prefixPath:c});continue}let l=Xs(a);if(!l.resolvedPath){n.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:a,alias:l.alias||"",requiredEnv:l.requiredEnv||"",prefixPath:c});continue}let d=l.resolvedPath,p=Qt(c);if(!p){n.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:a,prefixPath:c});continue}let g;try{g=await A.stat(d);}catch{n.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:a,sourceAbs:d,prefixPath:c});continue}let f=S.resolve(e.outputDir,p);if(g.isDirectory()){let v=await Rr(d,f,o,n);i.push(...v),s+=v.length,v.length>0&&n.progress(`Copied static directory to export: ${d} -> /${p}`,{phase:"copy-extra-paths",sourcePath:d,targetPath:`/${p}`,copiedItems:s,changedFiles:v.length});continue}let m=S.basename(d),h=c.endsWith("/")?S.join(f,m):f;await Ir(d,h,o,n)&&(i.push(h),s++,n.progress(`Copied static file to export: ${d} -> /${Qt(c.endsWith("/")?`${c}${m}`:c)}`,{phase:"copy-extra-paths",sourcePath:d,targetPath:`/${Qt(c.endsWith("/")?`${c}${m}`:c)}`,copiedItems:s}));}return n.endMark("copy-extra-paths",{mappedSources:r.length,copiedItems:s}),i}function Ge(e,t,n,r,s){let i=new Set,o=ce(n).replace(/\\\//g,"/"),u=s==="page-html"?_i(o):o,a=Ni(t,s);if(a){for(let l of qi(u)){let d=H(e,l,t,r,`${s}:css-url`);d&&q(e,d)&&i.add(d.toString());}for(let l of u.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let d=H(e,l[1],t,r,`${s}:css-import`);d&&q(e,d)&&i.add(d.toString());}}if(a||s==="page-html")for(let l of u.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let d=H(e,l[1],t,r,`${s}:xml-stylesheet`);d&&q(e,d)&&i.add(d.toString());}let c=new RegExp(`(?:https?:)?//[^\\s'"<>\\);]+\\.${Wt}(?:\\?[^\\s'"<>\\);]*)?|(?<!\\.)/[^\\s'"<>\\);]+\\.${Wt}(?:\\?[^\\s'"<>\\);]*)?`,"gi");if(s==="page-html")for(let l of o.matchAll(c)){let d=l[0].startsWith("//")?`${new URL(e.sourceOrigin).protocol}${l[0]}`:l[0];if(Kt(d)){r.ignore(`${s}:serialized-url`,d,"looks like JavaScript/code fragment",t);continue}let p=H(e,d,t,r,`${s}:serialized-url`);p&&q(e,p)?i.add(p.toString()):p&&r.ignore("asset",p.toString(),"serialized URL did not pass safe asset path filter",t);}if(s!=="page-html"&&Fi(t))for(let l of tr(o)){if(Kt(l)||!/\.(?:js|mjs)(?:[?#]|$)/i.test(l))continue;let d=H(e,l,t,r,`${s}:relative-asset`);d&&q(e,d)&&i.add(d.toString());}return [...i]}function Wi(e,t,n,r){let s=new Set,i=ce(n);for(let o of i.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let u=o[1],a=H(e,u,t,r,"page-link");a&&(Sr(e,a)||Se(a)&&!Ee(a)&&!q(e,a)&&s.add(a.toString()));}return [...s]}async function cr(e,t,n,r,s,i,o=false){let u=new Map,a=(c,l)=>{let d=[l],p=new Set;for(;d.length>0;){let g=d.pop();if(g===c)return true;p.has(g)||(p.add(g),d.push(...u.get(g)??[]));}return false};for(;n.sitemapQueue.length>0;){let c=n.sitemapQueue.shift();n.queuedSitemaps.delete(c);let l=ye(c,r,"sitemap","sitemap-queue");if(!l)continue;let d=l.toString();if(!n.doneSitemaps.has(d)){n.doneSitemaps.add(d),r.sitemap(`Fetching sitemap ${d}`,{url:d});try{let p=await t.get(d,{timeout:6e4});if(!p.ok()){if(r.skip("sitemap",d,p.status()),o)throw new Error(`Required content-sync sitemap returned HTTP ${p.status()}: ${d}`);continue}let g=await p.body(),f=p.url()||d,m=ye(f,r,"sitemap-response",d);if(!m)continue;let h=m.toString(),w=await Gt(e,n.assetMap,h,g,n,r);Z(s,e,w.outputPath),Ce(s,w.outputPath);let v=g.toString("utf8");/<sitemapindex(?:\s|>)/i.test(v)?n.sitemapIndexUrls.add(h):n.sitemapLeafUrls.add(h);let k=Ge(e,h,v,r,"sitemap");for(let F of k)J(e,n,F,r,h);let E=[];for(let F of Li(v)){let I=H(e,F.loc,h,r,"sitemap-loc");if(!I){if(o)throw new Error(`Content-sync sitemap contains an inadmissible location: ${F.loc}`);continue}if(Me(I)){if(a(h,I.toString()))throw new Error(`Sitemap index cycle detected: ${h} -> ${I.toString()}`);u.has(h)||u.set(h,new Set),u.get(h).add(I.toString()),E.push(I.toString()),wt(e,n,I.toString(),r,h);}else if(o){if(Se(I)&&!q(e,I)){let O=i.requiredUrls.has(I.toString()),b=i.manifest.pages[I.toString()],P=!!b&&!!await Ve(b.outputPath);if(!O&&!P)throw new Error(`Content-sync sitemap coverage is incomplete for ${I.toString()}.`)}r.ignore("sitemap-loc",I.toString(),"content-sync sitemap-only traversal does not enqueue urlset locations",h);}else q(e,I)?J(e,n,I.toString(),r,h):Se(I)?(F.lastmod&&(n.sitemapLastmodByPage[I.toString()]=F.lastmod),Ke(e,n,I.toString(),r,h)):r.reject("sitemap-loc",I.toString(),"not page/sitemap/asset-like",h);}i.trackManifest&&(i.manifest.assets[h]={url:h,outputPath:w.outputPath,isText:!0,contentType:p.headers()["content-type"]??"application/xml",discoveredAssets:[...new Set([...k,...E])],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},await we(e,i));}catch(p){if(r.error(`Failed sitemap ${d}`,{url:d,error:String(p)}),o)throw p}}}}async function zi(e,t,n,r,s,i,o){let u=H(e,r,e.sourceOrigin,s,"asset-fetch");if(!u||!q(e,u))return;let a=u.toString();if(n.doneAssets.has(a))return;let c=i.enabled||i.strictTargeted?i.previousManifest.assets[a]:void 0,l=i.strictTargeted?i.manifest.assets[a]:void 0;if(l?.lastSeenRunId===i.runId&&await Ve(l.outputPath)){n.doneAssets.add(a);for(let p of l.discoveredAssets||[])J(e,n,p,s,a);Z(o,e,l.outputPath),l.isText&&Ce(o,l.outputPath),s.info(`Resumed completed content-sync asset ${a}`,{url:a,source:"content-sync-checkpoint"}),We(n,s);return}let d=(p,g={})=>{if(!c||i.strictTargeted)return false;i.manifest.assets[a]={...c,discoveredAssets:[...c.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId},delete i.manifest.pages[a],n.doneAssets.add(a);for(let f of c.discoveredAssets||[])J(e,n,f,s,a);return s.warn(`Keeping previous incremental asset ${a} after fetch issue.`,{url:a,reason:p,preservedFromPreviousManifest:true,...g,phase:"download-assets"}),We(n,s),true};s.asset(`Fetching asset ${a}`,{url:a});try{let p=Je(e,n.assetMap,a),g=p?await Ve(p):null;if(p&&g)try{let O=await _(`fetch asset headers ${a}`,6e4,()=>t.head(a,{timeout:6e4})),b=O.headers();if(O.ok()&&Ei(g,b)){let P=await vr(p);if(P!==null){let C=O.url()||a,y=ye(C,s,"asset-response",a);if(!y)return;let x=y.toString(),j=await Gt(e,n.assetMap,x,P,n,s,b);j.wroteFile&&(Z(o,e,j.outputPath),be(j.outputPath)&&Ce(o,j.outputPath)),n.doneAssets.add(a),s.info(`Reused existing asset ${a} based on response headers.`,{url:a,filePath:p,lastModified:b["last-modified"]||"",contentLength:b["content-length"]||"",phase:"download-assets"}),We(n,s);let U=ar(u,b),V=c?.discoveredAssets?[...c.discoveredAssets]:[];if(U||c?.isText){let B=P.toString("utf8"),K=Ge(e,x,B,s,"asset:cached");(K.length>0||!c)&&(V=K);for(let $ of V)J(e,n,$,s,x);}if(i.trackManifest){let B=U||!!c?.isText;i.manifest.assets[a]={url:a,outputPath:j.outputPath,isText:B,contentType:Jt(b)||c?.contentType||null,discoveredAssets:V,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!B},delete i.manifest.pages[a],(i.enabled||i.strictTargeted)&&B&&await we(e,i);}return}}}catch{}let f=await _(`fetch asset ${a}`,6e4,()=>t.get(a,{timeout:6e4}));if(!f.ok()){if(d(`http-${f.status()}`,{status:f.status()}))return;if(i.strictTargeted)throw new Error(`Required content-sync asset returned HTTP ${f.status()}: ${a}`);s.skip("asset",a,f.status());return}let m=await _(`read asset response ${a}`,6e4,()=>f.body()),h=f.url()||a,w=ye(h,s,"asset-response",a);if(!w)return;let v=w.toString(),k=f.headers(),E=await Gt(e,n.assetMap,v,m,n,s,k);E.wroteFile&&(Z(o,e,E.outputPath),be(E.outputPath)&&Ce(o,E.outputPath)),n.doneAssets.add(a),We(n,s);let F=ar(u,k),I=[];if(F){let O=m.toString("utf8");I=Ge(e,v,O,s,`asset:${S.extname(u.pathname).toLowerCase()||k["content-type"]||"unknown"}`);for(let b of I)J(e,n,b,s,v);}i.trackManifest&&(i.manifest.assets[a]={url:a,outputPath:E.outputPath,isText:F,contentType:Jt(k),discoveredAssets:I,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!F},delete i.manifest.pages[a],(i.enabled||i.strictTargeted)&&F&&await we(e,i));}catch(p){if(d("fetch-error",{error:String(p)}))return;if(s.error(`Failed asset ${a}`,{url:a,error:String(p)}),i.strictTargeted)throw p}finally{n.doneAssets.has(a)||(n.doneAssets.add(a),We(n,s));}}async function Qi(e,t,n,r,s,i){let o=Math.max(1,Number(e.assetDownloadConcurrency||e.concurrency||1)),u=Array.from({length:o},async()=>{for(;n.assetQueue.length>0;){let a=n.assetQueue.shift();a&&(n.queuedAssets.delete(a),await zi(e,t,n,a,r,s,i));}});await Promise.all(u);}function Ji(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function ue(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function mt(e){return Math.max(15e3,Math.min(6e4,ue(e)))}function Vi(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function nn(e){return e.stats.pagesCompleted}function xr(e){let n=e.options?.browserProcess;return {pid:typeof n?.process?.pid=="number"?n.process.pid:null,kill:typeof n?.kill=="function"?n.kill.bind(n):null}}async function Ki(e,t,n){let r=xr(e);try{if(r.kill){await r.kill(),t.warn(`Force-killed crawl worker browser after ${n}`,{browserPid:r.pid,reason:n});return}if(r.pid!==null){process.kill(r.pid,"SIGKILL"),t.warn(`Sent SIGKILL to crawl worker browser after ${n}`,{browserPid:r.pid,reason:n});return}t.warn(`Could not resolve crawl worker browser PID after ${n}`,{reason:n});}catch(s){t.error(`Failed to force-kill crawl worker browser after ${n}`,{browserPid:r.pid,reason:n,error:String(s)});}}async function _(e,t,n){let r;try{return await Promise.race([n(),new Promise((s,i)=>{r=globalThis.setTimeout(()=>{i(new Error(`${e} timed out after ${Ji(t)}.`));},t);})])}finally{r!==void 0&&globalThis.clearTimeout(r);}}async function Gi(e,t){let n=Vi(e);await t.evaluate(async r=>{await new Promise(s=>{let i=0,o=700,u=Date.now(),a=()=>{window.clearInterval(c),window.scrollTo(0,0),s();},c=window.setInterval(()=>{if(Date.now()-u>=r.maxDurationMs){a();return}window.scrollBy(0,o),i+=o;let l=document.body?.scrollHeight||0,d=document.documentElement?.scrollHeight||0,p=Math.max(l,d);i>=p+window.innerHeight&&a();},120);});},{maxDurationMs:n});}async function Zi(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 Gi(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function Yi(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 Xi(e,t){return e.noJavaScriptRenderPathPrefixes.some(n=>Xt(t,n))}async function eo(e,t,n,r,s=true){let i=new Set;if(s){let u=await t.evaluate(()=>{let a=new Set,c=["href","src","poster","data-src","data-lazy-src","data-original","data-bg","data-background","data-href"],l=new Set,d=["srcset","data-srcset","data-lazy-srcset"];return document.querySelectorAll("*").forEach(p=>{for(let f of c){let m=p.getAttribute(f);m&&a.add(m);}for(let f of d){let m=p.getAttribute(f);m&&m.split(",").forEach(h=>{let w=h.trim().split(/\s+/)[0];w&&a.add(w);});}let g=p.getAttribute("style");g&&l.add(g);}),{attrs:[...a],styles:[...l]}});for(let a of u.attrs)for(let c of Ui(a)){let l=H(e,c,n,r,"dom-attr");l&&q(e,l)&&i.add(l.toString());}for(let a of u.styles)for(let c of Ge(e,n,a,r,"dom-style"))i.add(c);}let o=await t.content();for(let u of Ge(e,n,o,r,"page-html"))i.add(u);return [...i]}async function ur(e,t,n,r,s){let i=le(e,t);await He(i,n,"utf8");let o=await A.stat(i);s?.debug(`Saved page output ${t}`,{phase:"save-pages",url:t,outputPath:i,bytes:o.size}),r.stats.pagesSaved++;let u=Math.min(r.stats.pagesQueued,nn(r)+1);s&&(r.stats.pagesSaved%10===0||r.stats.pagesSaved===1)&&s.progress(`Page progress: processed ${u}, rendered ${r.stats.pagesRendered}, saved ${r.stats.pagesSaved}, discovered ${r.stats.pagesQueued}.`,{donePages:u,claimedPages:r.donePages.size,pagesRendered:r.stats.pagesRendered,pagesSaved:r.stats.pagesSaved,pagesQueued:r.stats.pagesQueued,pageQueue:r.pageQueue.length,phase:"save-pages"});}function to(e){let t=nn(e);return t%5===0||t===1||t===e.stats.pagesQueued}function no(e,t){let n=nn(e);t.progress(`Render progress: processed ${n}, rendered ${e.stats.pagesRendered}, saved ${e.stats.pagesSaved}, discovered ${e.stats.pagesQueued}.`,{donePages:n,claimedPages:e.donePages.size,pagesRendered:e.stats.pagesRendered,pagesSaved:e.stats.pagesSaved,pagesQueued:e.stats.pagesQueued,phase:"render-pages"});}async function ro(e){await e.addInitScript(()=>{Object.defineProperty(window,"__WPSUITE_STATIC_EXPORT__",{value:true,writable:false,configurable:true});let t=n=>{if(n==null||String(n)==="")return true;try{let r=new URL(String(n),window.location.href),s=new URL(window.location.href);return r.hash="",s.hash="",r.href===s.href}catch{return false}};try{let n=window.location.assign.bind(window.location),r=window.location.replace.bind(window.location),s=window.location.reload.bind(window.location);Object.defineProperty(window.location,"assign",{configurable:!0,value:i=>{if(t(i)){console.warn("[smartcloud-static-publisher] blocked same-page location.assign",i??"");return}return n(i)}}),Object.defineProperty(window.location,"replace",{configurable:!0,value:i=>{if(t(i)){console.warn("[smartcloud-static-publisher] blocked same-page location.replace",i??"");return}return r(i)}}),Object.defineProperty(window.location,"reload",{configurable:!0,value:()=>{console.warn("[smartcloud-static-publisher] blocked location.reload");}});}catch{}});}async function so(e,t,n){let r=await e.newContext({viewport:t.viewport,userAgent:"WPSuiteStaticPublisher/0.8 Playwright SitemapOnly",ignoreHTTPSErrors:t.ignoreHttpsErrors,...n?{javaScriptEnabled:false}:{}});return n||await ro(r),r}async function io(e,t,n,r,s,i,o){let u=await chromium.launch({headless:true}),a=xr(u);a.pid!==null&&n.debug(`Launched crawl worker browser PID ${a.pid}`,{browserPid:a.pid});try{for(;t.pageQueue.length>0&&!(e.maxPages>0&&t.donePages.size>=e.maxPages);){let c=t.pageQueue.shift();if(!c)break;t.queuedPages.delete(c);let l=null,d=null;try{let p=ye(c,n,"page","page-queue");if(!p)continue;let g=p.toString();if(c=g,t.queuedPages.delete(c),t.donePages.has(c))continue;t.donePages.add(c),i.enabled&&i.seenPages.add(c);let f=tn(e,c),m=Xi(e,p.pathname);if(!Se(p)||q(e,p)||Ee(p)){if(q(e,p)){n.info(`Worker redirected non-page URL to asset queue: ${c}`,{url:c,source:"worker-guard"}),J(e,t,c,n,"worker-guard");continue}n.reject("page",c,"guard rejected non-page URL before rendering","worker");continue}let h=i.strictTargeted?i.manifest.pages[c]:void 0;if(h?.lastSeenRunId===i.runId&&await Ve(h.outputPath)){i.seenPages.add(c);for(let y of h.discoveredAssets||[])J(e,t,y,n,c);Z(o,e,h.outputPath),Ce(o,h.outputPath),n.info(`Resumed completed content-sync page ${c}`,{url:c,source:"content-sync-checkpoint"});continue}let w=await ui(e,s,t,i,c,n);if(i.enabled&&r!=="single-url"&&r!=="content-sync"){let y=i.manifest.pages[c];if(w.action==="reuse"&&y){for(let x of y.discoveredAssets)J(e,t,x,n,c);for(let x of y.discoveredPages)Ke(e,t,x,n,c);y.lastSeenRunId=i.runId,y.sitemapLastmod=ze(t.sitemapLastmodByPage[c])??y.sitemapLastmod,w.changeToken?.supported&&(y.changeToken=w.changeToken.token,y.tokenSource=w.changeToken.tokenSource??y.tokenSource),n.info(`Incremental reuse skipped unchanged page ${c}`,{url:c,mode:"incremental",reason:w.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}l=await _(`create page context ${c}`,ue(e),()=>so(u,e,m)),d=await _(`create page ${c}`,ue(e),()=>l.newPage());let v=!1,k=new Set;await d.route("**/*",async y=>{let x=y.request();if(x.isNavigationRequest()&&x.frame()===d.mainFrame())try{let j=new URL(x.url()),U=new URL(g);if(j.hash="",U.hash="",j.href===U.href){if(v){n.warn(`Blocked same-page navigation/reload for ${c}`,{url:c,requestUrl:x.url()}),await y.abort("aborted");return}v=!0;}}catch{}await y.continue();}),d.on("response",y=>{try{let x=H(e,y.url(),e.sourceOrigin,n,"network-response");x&&q(e,x)&&(k.add(x.toString()),J(e,t,x.toString(),n,c));}catch{}}),n.page(`Rendering ${c}`,{url:c});let E=null,F=null;try{if(E=await d.goto(c,{waitUntil:"domcontentloaded",timeout:e.navigationTimeoutMs}),E&&E.ok())try{F=await _(`read response body ${c}`,ue(e),()=>E.text());}catch{F=null;}}catch(y){n.warn(`Navigation issue for ${c}; saving current DOM if available`,{url:c,error:String(y)});}if(r==="content-sync"&&E){let y=ye(E.url(),n,"content-sync-final-response",c)?.toString();if(y&&y!==g){if(i.deleteOnMissingUrls.has(c)){await Zt(e,i,o,c,i.deleteOnMissingUrls),n.info(`Removed stale content-sync archive route redirected to ${y}`,{url:c,finalResponseUrl:y,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${c} -> ${y}`)}}if(f){let y=E?.status()??null;if(y!==404){n.error(`Generated 404 request path returned unexpected status for ${c}`,{url:c,expectedStatus:404,status:y,requestPath:e.generated404RequestPath});continue}n.info(`Capturing rendered 404 page for ${c}`,{url:c,status:y,outputPath:le(e,c)});}else if(E&&!E.ok()){if(r==="content-sync"&&(E.status()===404||E.status()===410)&&i.deleteOnMissingUrls.has(c)){await Zt(e,i,o,c,i.deleteOnMissingUrls),n.info(`Removed stale content-sync archive page ${c}`,{url:c,status:E.status(),source:"content-sync-tombstone"}),await d.close();continue}if(r==="content-sync")throw new Error(`Required content-sync route returned HTTP ${E.status()}: ${c}`);n.skip("page",c,E.status(),t.pageDiscoverySources.get(c)),await d.close();continue}m?(n.info(`Rendering without JS execution for ${c}`,{url:c,mode:"no-js"}),await _(`wait for rendered page ${c}`,ue(e),()=>Yi(e,d))):await _(`wait for rendered page ${c}`,ue(e),()=>Zi(e,d)),t.stats.pagesRendered++;let I=await _(`extract rendered assets ${c}`,ue(e),()=>eo(e,d,g,n,!m));for(let y of I)J(e,t,y,n,c);let O=[...new Set([...I,...k])],b=F??await _(`capture rendered html ${c}`,ue(e),()=>d.content()),P=r!=="single-url"&&r!=="content-sync"&&!f?Wi(e,c,b,n):[];if(r!=="single-url"&&r!=="content-sync"&&!f)for(let y of P)Ke(e,t,y,n,c);await ur(e,c,b,t,n);let C=le(e,c);if(Z(o,e,C),Ce(o,C),i.trackManifest){let y=E?.headers();i.manifest.pages[c]={url:c,outputPath:C,contentType:Jt(y),changeToken:w.changeToken?.supported?w.changeToken.token:null,tokenSource:w.changeToken?.supported?w.changeToken.tokenSource??null:null,sitemapLastmod:ze(t.sitemapLastmodByPage[c])??null,discoveredPages:P,discoveredAssets:O,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},(i.enabled||i.strictTargeted)&&await we(e,i);}}catch(p){if(i.strictTargeted)throw n.error(`Failed required content-sync page ${c}`,{url:c,error:String(p)}),p;try{let g=d?await _(`capture partial html ${c}`,ue(e),()=>d.content()):"";if(g&&g.trim()){await ur(e,c,g,t,n);let f=le(e,c);if(Z(o,e,f),Ce(o,f),i.trackManifest){let m=i.manifest.pages[c]??i.previousManifest.pages[c];i.manifest.pages[c]={url:c,outputPath:f,contentType:m?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:ze(t.sitemapLastmodByPage[c])??m?.sitemapLastmod??null,discoveredPages:m?.discoveredPages?[...m.discoveredPages]:[],discoveredAssets:m?.discoveredAssets?[...m.discoveredAssets]:[],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},(i.enabled||i.strictTargeted)&&await we(e,i);}n.warn(`Saved partial DOM for ${c}`,{url:c,error:String(p)});}}catch(g){n.error(`Could not save partial DOM for ${c}`,{url:c,error:String(g)});}n.error(`Failed page ${c}`,{url:c,error:String(p)});}finally{t.stats.pagesCompleted++,to(t)&&no(t,n),d&&await _(`close page ${c}`,mt(e),()=>d.close()).catch(p=>{n.warn(`Timed out while closing page ${c}`,{url:c,browserPid:a.pid,error:String(p)});}),l&&await _(`close page context ${c}`,mt(e),()=>l.close()).catch(p=>{n.warn(`Timed out while closing page context for ${c}`,{url:c,browserPid:a.pid,error:String(p)});});}}}finally{await _("close worker browser",mt(e),()=>u.close()).catch(c=>(n.warn("Timed out while closing crawl worker browser",{browserPid:a.pid,error:String(c)}),Ki(u,n,"browser.close timeout")));}}async function oo(e){try{let t=await A.readFile(e),r=(e.endsWith(".gz")?gunzipSync(t):t).toString("utf8").trim();if(!r)return [];try{let s=JSON.parse(r);if(Array.isArray(s))return s;if(s&&typeof s=="object")return [s]}catch{return r.split(/\r?\n/).map(s=>s.trim()).filter(Boolean).map(s=>{try{let i=JSON.parse(s);return i&&typeof i=="object"?i:null}catch{return null}}).filter(s=>s!==null)}return []}catch{return []}}function lr(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function ao(e){let t=String(e?.job?.command||"").trim(),n=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:n!=="incremental"}function co(e){let t=[e?.archivedAt,e?.job?.endedAt,e?.job?.startedAt];for(let n of t){let r=Date.parse(String(n||""));if(Number.isFinite(r))return r}return 0}async function Ar(e){try{let t=await A.readFile(e,"utf8"),n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function dr(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function uo(e,t){let n=Array.isArray(t?.artifacts)?t.artifacts.filter(r=>String(r?.role||"").trim()==="errors"&&String(r?.storedFileName||"").trim()!=="").sort((r,s)=>dr(r)-dr(s)).map(r=>S.join(e,String(r.storedFileName))):[];return [...new Set([...n,S.join(e,"errors.jsonl"),S.join(e,"errors.json"),S.join(e,"errors.jsonl.gz"),S.join(e,"errors.json.gz")])]}async function pr(e){let t=await Ar(S.join(e,"job.json"));for(let n of uo(e,t)){let r=await oo(n);if(r.length>0)return r}return []}async function lo(e){let t=S.join(e.logDir,"archive"),n;try{n=await A.readdir(t);}catch{return ""}let r="",s=0;for(let i of n){let o=S.join(t,i);if(!(await A.stat(o).catch(()=>null))?.isDirectory())continue;let a=await Ar(S.join(o,"job.json"));if(!ao(a))continue;let c=co(a);c>=s&&(s=c,r=o);}return r}async function po(e){let t=await lo(e),n=t!==""?await pr(t):await pr(e.logDir),r=new Set;for(let s of n)if(lr(s.error)||lr(s.message)){let i=s.url;typeof i=="string"&&i&&r.add(i);}return [...r]}async function go(e){let t=[];for(let n of e)if(n.startsWith("@")){let r=n.slice(1),s=await A.readFile(r,"utf8");t.push(...s.split(/\r?\n/).map(i=>i.trim()).filter(i=>i&&!i.startsWith("#")));}else t.push(n);return t}async function fo(e){if(!e)throw new Error("Content-sync crawl requires an immutable impact plan.");let t=JSON.parse(await A.readFile(e,"utf8"));return qe(t),t}function mo(e,t){let n;try{n=new URL(e);}catch{return false}return t.archiveFamilies.some(r=>{let s=new URL(r.url);if(n.origin!==s.origin)return false;if(n.toString()===s.toString())return true;if(n.searchParams.has("paged")&&n.pathname===s.pathname)return /^\d+$/.test(n.searchParams.get("paged")||"");let i=s.pathname.replace(/\/+$/,""),o=n.pathname.slice(i.length).replace(/^\/+/,""),u=String(r.paginationBase||"page").replace(/^\/+|\/+$/g,"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return n.pathname.startsWith(`${i}/`)&&new RegExp(`^${u}/\\d+/?$`).test(o)})}function ft(e,t,n){let r=n==="page"?le(e,t):yt(e,t).originalFilePath;return he(e.outputDir,r)}async function Zt(e,t,n,r,s){let i=t.manifest.pages[r];if(!i)return;let o=he(e.outputDir,i.outputPath);if(!o)throw new Error(`Manifest-owned page path escaped output root: ${r}`);let u=S.resolve(i.outputPath);Object.entries(t.manifest.pages).some(([c,l])=>c!==r&&!s.has(c)&&S.resolve(l.outputPath)===u)||(await A.rm(i.outputPath,{force:true}),n.deletedFiles.add(o)),delete t.manifest.pages[r];}function ho(e,t){let n=new Set,r=[...t];for(;r.length>0;){let s=r.shift();if(n.has(s))continue;n.add(s);let i=e.assets[s];for(let o of i?.discoveredAssets??[])try{Me(new URL(o))&&r.push(o);}catch{}}return n}async function wo(e,t,n,r,s){let i=ho(n.previousManifest,s);for(let o of i){if(t.doneSitemaps.has(o))continue;let u=n.previousManifest.assets[o];if(!u)continue;let a=he(e.outputDir,u.outputPath);if(!a)throw new Error(`Manifest-owned sitemap path escaped output root: ${o}`);await A.rm(u.outputPath,{force:true}),r.deletedFiles.add(a),delete n.manifest.assets[o];}await we(e,n);}async function yo(e){try{let t=await A.readFile(S.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function So(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 A.mkdir(e,{recursive:true}),await Promise.all(t.map(async n=>{try{await A.unlink(S.join(e,n));}catch(r){if(r.code!=="ENOENT")throw r}}));}function gr(e,t,n,r,s){let i=H(e,n,e.sourceOrigin,r,"manual-url");i&&(Me(i)?wt(e,t,i.toString(),r,s):q(e,i)?J(e,t,i.toString(),r,s):Se(i)?Ke(e,t,i.toString(),r,s):r.reject("manual-url",i.toString(),"not page/sitemap/asset-like",s));}async function Tr(e=process.argv.slice(2)){let t=[],n=await ne(void 0,{onRemotePublisherConfigDiagnostic:P=>{t.push(P);}}),r=t.at(-1)??null,s=Gs(e),i=s.mode==="content-sync"?await fo(s.contentSyncPlanPath):null;if(s.resumeRewrite&&s.mode!=="full")throw new Error("--resume-rewrite is only supported for full crawl/publish jobs.");let o=[];s.mode==="retry-timeouts"&&(o=await po(n)),s.mode==="single-url"&&(o=await go(s.urls)),i&&(o=[...i.directRenderUrls,...i.archiveFamilyUrls]);let u=s.crawlMode==="incremental"&&s.mode==="full",a=u&&typeof n.subscriptionType=="string"&&n.subscriptionType.trim()!=="";if(i&&n.subscriptionType!=="PROFESSIONAL"&&n.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let c=(s.mode==="full"||s.mode==="single-url"||s.mode==="content-sync")&&!s.resumeRewrite,l=s.mode!=="full"||s.resumeRewrite||a,d=l?await yo(n):{},p=a||s.mode==="single-url"||s.mode==="content-sync"?await ni(n):wr(),g=new Set(o),f=new Set;if(i){for(let P of i.archiveFamilies)if(P.foundPosts===0)for(let C of P.pageUrls)f.add(C);for(let P of Object.keys(p.pages))mo(P,i)&&!g.has(P)&&(o.push(P),f.add(P));}let m={enabled:a,trackManifest:c,manifest:Vt(p),previousManifest:Vt(p),runId:i?.jobId??`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve(),strictTargeted:!!i,requiredUrls:g,deleteOnMissingUrls:f};await So(n.logDir);let h=new dt(n.logDir,n.logLevel);if(r){let P={status:r.status,virtualAssetBaseUrl:r.virtualAssetBaseUrl,subscriptionType:r.subscriptionType??null,error:r.error,requests:r.requests,source:"remote-publisher-config"};r.status==="loaded"&&r.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(u&&!a){let P="Incremental crawl requires an active remote publisher subscription; refusing to fall back to a destructive full crawl.";throw h.error(P,{requestedMode:s.crawlMode,subscriptionType:n.subscriptionType??null,source:"incremental-subscription-guard"}),await h.flush(),new Error(P)}let w={pageQueue:[],queuedPages:new Set,donePages:new Set,pageDiscoverySources:new Map,assetQueue:[],queuedAssets:new Set,doneAssets:new Set,sitemapQueue:[],queuedSitemaps:new Set,doneSitemaps:new Set,sitemapIndexUrls:new Set,sitemapLeafUrls:new Set,sitemapLastmodByPage:{},assetMap:{...d},assetVariantDigestsByOriginalPath:new Map,stats:{pagesQueued:0,pagesRendered:0,pagesCompleted:0,assetsQueued:0,sitemapsQueued:0,assetsSaved:0,pagesSaved:0}},v=ti();if(await Te(n),await _n(n,{startedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir)}),l||await A.rm(n.outputDir,{recursive:true,force:true}),await A.mkdir(n.outputDir,{recursive:true}),i){let P=new Set([...i.deleteUrls,...m.deleteOnMissingUrls]);for(let C of i.deleteUrls)await Zt(n,m,v,C,P);}if(s.resumeRewrite)h.info("Resuming final rewrite from existing output.",{phase:"rewrite-text",mode:s.mode,crawlMode:s.crawlMode});else {let P=await request.newContext({ignoreHTTPSErrors:n.ignoreHttpsErrors});try{if(h.mark("discovery"),s.mode==="full"?(n.sitemapPaths.forEach(y=>wt(n,w,y,h)),await cr(n,P,w,h,v,m),n.seedPaths.forEach(y=>gr(n,w,y,h,"seed-path")),n.generated404RequestPath&&Ke(n,w,n.generated404RequestPath,h,"generated-404-request-path")):(o.forEach(y=>gr(n,w,y,h,"cli")),i?.sitemapUrls.forEach(y=>wt(n,w,y,h,"content-sync-impact")),await cr(n,P,w,h,v,m,s.mode==="content-sync"),i&&await wo(n,w,m,v,i.sitemapUrls)),h.endMark("discovery",{pages:w.pageQueue.length,assets:w.assetQueue.length,sitemaps:w.sitemapQueue.length}),h.summary(`Queued ${w.pageQueue.length} pages, ${w.assetQueue.length} assets, ${w.sitemapQueue.length} sitemaps.`,{mode:s.mode,crawlMode:s.crawlMode,queuedPages:w.pageQueue.length,queuedAssets:w.assetQueue.length,queuedSitemaps:w.sitemapQueue.length}),s.mode==="retry-timeouts"&&w.pageQueue.length===0&&w.assetQueue.length===0&&w.sitemapQueue.length===0){h.summary("No timed-out URLs were queued. Skipping retry crawl.",{mode:s.mode,crawlMode:s.crawlMode,queuedPages:0,queuedAssets:0,queuedSitemaps:0}),await h.flush();return}h.mark("render-pages");let C=Array.from({length:Math.max(1,n.concurrency)},()=>io(n,w,h,s.mode,P,m,v));if(await Promise.all(C),h.endMark("render-pages",{pages:w.stats.pagesCompleted}),h.mark("download-assets"),h.progress("Asset download phase started.",{phase:"download-assets",doneAssets:w.doneAssets.size,assetsQueued:w.stats.assetsQueued,assetQueue:w.assetQueue.length}),await Qi(n,P,w,h,m,v),h.endMark("download-assets",{assets:w.doneAssets.size}),m.enabled&&n.maxPages===0&&await di(n,w,m,h,v),s.mode==="full"){let y=await Hi(n,w,h);for(let x of y)Z(v,n,x);}}finally{await _("dispose crawl request context",mt(n),()=>P.dispose()).catch(C=>{h.warn("Timed out while disposing crawl request context",{error:String(C)});});}}m.trackManifest&&await we(n,m),await A.writeFile(S.join(n.outputDir,"asset-map.json"),JSON.stringify(w.assetMap,null,2),"utf8"),JSON.stringify(d,null,2)!==JSON.stringify(w.assetMap,null,2)&&Z(v,n,S.join(n.outputDir,"asset-map.json"));let k=s.mode==="single-url"||s.mode==="content-sync"?Pi(n,w):m.enabled&&!s.resumeRewrite?pi(n,m,v,d,w.assetMap):void 0;h.mark("rewrite-text");let E=s.mode==="single-url"||s.mode==="content-sync"?`Rewriting text files touched by URL crawl: 0/${k?.length??0}`:"Rewriting text files...";h.progress(E,{phase:"rewrite-text",index:0,totalFiles:k?.length,changedTextFiles:0}),await or(E);let F=Date.now(),I=await ct(n,w.assetMap,{files:k,previousAssetMap:d,onStart:({totalFiles:P,workerCount:C})=>{h.info(`Rewrite phase scanning ${P} text files.`,{phase:"rewrite-text",totalFiles:P,workerCount:C});},onProgress:async({index:P,totalFiles:C,changedTextFiles:y,file:x,changed:j})=>{j&&Z(v,n,S.join(n.outputDir,x)),h.checkpoint(`Rewriting text file ${P}/${C}`,{phase:"rewrite-text",index:P,totalFiles:C,changedTextFiles:y,file:x}),h.debug(`${j?"Rewrote":"Checked unchanged"} text file ${P}/${C}: ${x}`,{phase:"rewrite-text",index:P,totalFiles:C,changedTextFiles:y,file:x,changed:j});let U=Date.now();if(!(P===1||P===C||P%50===0||U-F>=5e3))return;F=U;let B=`Rewriting text files: ${P}/${C}`;h.progress(B,{phase:"rewrite-text",index:P,totalFiles:C,changedTextFiles:y,file:x}),await or(B);}});m.trackManifest&&(gi(m,k),await we(n,m)),h.endMark("rewrite-text",{changedTextFiles:I});let O=i?[...v.deletedFiles].sort():m.enabled&&!s.resumeRewrite?await mi(n,w,m,v,h):[],b=[...new Set((k||[]).map(P=>he(n.outputDir,S.isAbsolute(P)?P:S.join(n.outputDir,P))).filter(P=>P!==null))].sort();if(i){let P=[...v.changedFiles].sort(),C=new Set(P),y=new Set(i.directRenderUrls.map($=>ft(n,$,"page")).filter($=>!!$&&C.has($))),x=new Set(i.archiveFamilyUrls.map($=>ft(n,$,"page")).filter($=>!!$&&C.has($))),j=new Set([...w.sitemapLeafUrls].map($=>ft(n,$,"asset")).filter($=>!!$&&C.has($))),U=new Set([...w.sitemapIndexUrls].map($=>ft(n,$,"asset")).filter($=>!!$&&C.has($))),V=new Set([...y,...x,...j,...U]),B=P.filter($=>!V.has($)),K=[...new Set([...i.directRenderUrls,...i.archiveFamilyUrls,...i.sitemapUrls,...w.sitemapLeafUrls,...w.sitemapIndexUrls,...i.deleteUrls].map($=>{let Ye=new URL($);return `${Ye.pathname}${Ye.search}`}))].sort();await qt(n,{schemaVersion:2,generatedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir),runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,changedFiles:P,deletedFiles:O,rewriteTargets:b,consumerId:i.consumerId,fromSequence:i.fromSequence,toSequence:i.toSequence,impactHash:i.impactHash,uploadGroups:{assets:B,content:[...y].sort(),listings:[...x].sort(),sitemapLeaves:[...j].sort(),sitemapIndexes:[...U].reverse()},invalidationPaths:K});}else await qt(n,{schemaVersion:1,generatedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir),runMode:s.mode,crawlMode:s.crawlMode,fullSyncRequired:!(m.enabled&&!s.resumeRewrite),changedFiles:m.enabled&&!s.resumeRewrite?[...v.changedFiles].sort():[],deletedFiles:m.enabled&&!s.resumeRewrite?O:[],rewriteTargets:m.enabled&&!s.resumeRewrite?b:[]});await Bn(n),h.summary(s.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${I} text files.`:`Done. Rendered ${w.stats.pagesRendered} pages, processed ${w.doneSitemaps.size} sitemaps, downloaded ${w.doneAssets.size} assets.`,{mode:s.mode,crawlMode:s.crawlMode,resumeRewrite:s.resumeRewrite,...w.stats,pagesRendered:w.stats.pagesRendered,donePages:w.stats.pagesCompleted,claimedPages:w.donePages.size,doneSitemaps:w.doneSitemaps.size,doneAssets:w.doneAssets.size,changedTextFiles:I}),await h.flush();}function Po(e){let t=e/6e4;if(Number.isInteger(t)&&t>=1)return `${t} minute${t===1?"":"s"}`;let n=Math.ceil(e/1e3);return `${n} second${n===1?"":"s"}`}async function Y(e,t,n){let r=new AbortController,s=globalThis.setTimeout(()=>{r.abort(new Error(`${e} timed out after ${Po(t)}.`));},t);try{return await n({abortController:r,httpOptions:{abortSignal:r.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(s);}}function bo(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function St(e){let t="";for(let r=0;r<e.length;r++){let s=e[r];if(s==="--profile"){let i=(e[r+1]||"").trim();if(!i)throw new Error("Missing value for --profile.");t=i,r+=1;}else if(s.startsWith("--profile=")){let i=s.slice(10).trim();if(!i)throw new Error("Missing value for --profile.");t=i;}}let n=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return t||n||null}function vo(e,t){return {...e,...t??{}}}function Co(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function Fe(e,t){let n=String(t??e.deploymentTargetOverride??"").trim();if(!bo(e)){if(n)throw new Error(`Deployment target "${n}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:e}}let r=String(n||e.defaultDeploymentProfile||"").trim();if(!r)return {name:null,profile:null,config:e};let s=e.deploymentProfiles?.[r];if(!s)throw new Error(`Unknown deployment profile "${r}". Check the linked WPSuite publisher configuration.`);return {name:r,profile:s,config:{...e,targetOrigin:s.targetOrigin??e.targetOrigin,s3:vo(e.s3,s.s3),cloudFront:Co(e.cloudFront,s.cloudFront)}}}var Mr="wpsuite-sha256",Fr="wpsuite-normalized-sha256",Mo=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,un=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Fo=["SIGINT","SIGTERM"],vt=new Set,Pt=new Map,kr=null;function Do(e){vt.add(e);let t=false;return ()=>{t||(t=true,vt.delete(e));}}async function Oo(){let e=[...vt];e.length!==0&&await Promise.allSettled(e.map(async t=>{vt.delete(t),await A.rm(t,{recursive:true,force:true});}));}function jo(){if(!(Pt.size>0))for(let e of Fo){let t=()=>{kr||(kr=Oo().finally(()=>{for(let[n,r]of Pt)process.off(n,r);Pt.clear(),process.exit(1);}));};Pt.set(e,t),process.on(e,t);}}jo();function Lo(e,t){let n=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(n)return S.resolve(n);let r=t.trim();return r?S.join(S.resolve(r),"crawl-manifest.json"):S.join(S.resolve(e),".crawl-manifest.json")}function Dr(e){return S.normalize(e).split(S.sep).join("/")}function $r(e,t){let n=S.relative(S.resolve(e),S.resolve(t));return !n||n.startsWith("..")||S.isAbsolute(n)?null:Dr(n)}async function Uo(e,t,n){let r=Lo(e.outputDir,t),s;try{s=await A.readFile(r,"utf8");}catch(l){return l.code==="ENOENT"?(n.warn("Deploy rewrite guard disabled because the crawl manifest is missing.",{manifestPath:r,source:"deploy-guard"}),null):(n.warn("Deploy rewrite guard disabled because the crawl manifest could not be read.",{manifestPath:r,error:l instanceof Error?l.message:String(l),source:"deploy-guard"}),null)}let i;try{i=JSON.parse(s);}catch(l){return n.warn("Deploy rewrite guard disabled because the crawl manifest is invalid JSON.",{manifestPath:r,error:l instanceof Error?l.message:String(l),source:"deploy-guard"}),null}let o=new Map,u=new Map,a=0,c=0;for(let[l,d]of Object.entries(i.pages||{})){let p=String(d?.outputPath||"").trim(),g=p?$r(e.outputDir,p):null;if(g){let f=typeof d?.contentType=="string"&&d.contentType?d.contentType:null;f&&u.set(g,f);}!p||d?.rewriteComplete===true||g&&(a++,o.has(g)||o.set(g,{kind:"page",sourceUrl:l,outputPath:S.resolve(p),relativePath:g}));}for(let[l,d]of Object.entries(i.assets||{})){let p=String(d?.outputPath||"").trim(),g=d?.isText===true,f=p?$r(e.outputDir,p):null;if(f){let m=typeof d?.contentType=="string"&&d.contentType?d.contentType:null;m&&u.set(f,m);}!p||!g||d?.rewriteComplete===true||f&&(c++,o.has(f)||o.set(f,{kind:"asset",sourceUrl:l,outputPath:S.resolve(p),relativePath:f}));}return {manifestPath:r,byRelativePath:o,contentTypeByRelativePath:u,pendingPages:a,pendingTextAssets:c}}function qo(e){return e&&(un.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 sn(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,n)=>n%2===1?t:qo(t)).join("")}function _o(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,n)=>n%2===1?t:un.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 Ct(e,t){return Array.isArray(e)?e.map(n=>Ct(n,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Ct(r,n)])):typeof e!="string"?e:t&&Mo.test(t)?_o(e):un.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?sn(e):e}function No(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function Bo(e,t){let n=t.trim();if((n.startsWith("{")||n.startsWith("[")||n.startsWith('"'))&&e.startsWith("data-"))try{let s=JSON.parse(n);return JSON.stringify(Ct(s))}catch{}if(e.startsWith("data-")&&/^[A-Za-z0-9+/=]+$/.test(n))try{let s=Buffer.from(n,"base64").toString("utf8"),i=JSON.parse(s),o=JSON.stringify(Ct(i));return Buffer.from(o,"utf8").toString("base64")}catch{}return t}function Ho(e,t){let n=e.toLowerCase();return n==="class"?t.split(/(\s+)/).map((r,s)=>s%2===1?r:sn(r)).join(""):n==="id"||n==="for"||n==="aria-controls"||n==="aria-labelledby"||n==="aria-describedby"||n==="aria-owns"||n==="aria-activedescendant"||n==="name"?sn(t):n==="href"||n==="src"?No(t):Bo(n,t)}function Wo(e){return e.replace(/<([a-z][^\s/>]*)([^<>]*?)>/gi,(t,n,r)=>{if(n.startsWith("/"))return t;let s=r.replace(/\s([:@a-zA-Z_][-:.a-zA-Z0-9_]*?)=(['"])([\s\S]*?)\2/g,(i,o,u,a)=>{let c=Ho(o,a);return ` ${o}=${u}${c}${u}`});return `<${n}${s}>`})}function rn(e){let t=S.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(S.basename(e))}function bt(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function zo(e,t,n,r){let s=new Map,i,o=0;do{o++;let u=await Y(`S3 list objects page ${o} for s3://${t}/${n||""}`,3e5,({httpOptions:a})=>e.send(new ListObjectsV2Command({Bucket:t,Prefix:n||void 0,ContinuationToken:i}),a));for(let a of u.Contents||[]){if(!a.Key)continue;let c=(a.ETag||"").replace(/^"|"$/g,"").toLowerCase(),l=Number(a.Size??0);s.set(a.Key,{etag:c,size:l});}i=u.NextContinuationToken,r.debug(`Listed S3 keys page ${o}: ${s.size} keys so far`);}while(i);return s}async function Qo(e,t,n,r){if(r.has(n))return r.get(n)??null;try{let s=await Y(`S3 head object ${n}`,3e5,({httpOptions:o})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),o)),i={etag:(s.ETag||"").replace(/^"|"$/g,"").toLowerCase(),size:Number(s.ContentLength??0)};return r.set(n,i),i}catch{return r.set(n,null),null}}async function Jo(e,t,n,r){let s=[...new Set(Array.from(n).filter(Boolean))];if(s.length===0)return r.info("No explicitly tombstoned S3 objects to delete."),[];r.info(`Deleting ${s.length} explicitly tombstoned S3 object(s)\u2026`);for(let i=0;i<s.length;i+=1e3){let o=s.slice(i,i+1e3);if(o.length===0)continue;let u=await Y(`S3 delete objects batch ${Math.floor(i/1e3)+1}`,3e5,({httpOptions:a})=>e.send(new DeleteObjectsCommand({Bucket:t,Delete:{Objects:o.map(c=>({Key:c}))}}),a));if(u.Errors&&u.Errors.length>0){let a=u.Errors.map(c=>`${c.Key||"(unknown)"}: ${c.Code||"DeleteFailed"}`);throw new Error(`S3 reported ${a.length} object deletion error(s): ${a.join(", ")}`)}r.info(`Deleted batch of ${o.length} object(s).`);for(let a of o)r.debug(` deleted: ${a}`);}return s}function Vo(e){return createHash("md5").update(e).digest("hex")}function Er(e){return createHash("sha256").update(e).digest("hex")}function on(e){return createHash("sha256").update(Wo(e.toString("utf8"))).digest("hex")}async function Ko(e,t,n,r){if(r.has(n))return r.get(n)??null;try{let o=((await Y(`S3 head object metadata ${n}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),u))).Metadata?.[Mr]||"").trim().toLowerCase()||null;return r.set(n,o),o}catch{return r.set(n,null),null}}async function Go(e,t,n,r,s){if(r.has(n))return r.get(n)??null;try{let o=((await Y(`S3 head object normalized metadata ${n}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),u))).Metadata?.[Fr]||"").trim().toLowerCase();if(o)return r.set(n,o),o}catch{return r.set(n,null),null}if(s.has(n)){let i=s.get(n)??null;return r.set(n,i),i}try{let o=await(await Y(`S3 get object ${n}`,3e5,({httpOptions:a})=>e.send(new GetObjectCommand({Bucket:t,Key:n}),a))).Body?.transformToByteArray(),u=o?on(Buffer.from(o)):null;return s.set(n,u),r.set(n,u),u}catch{return s.set(n,null),r.set(n,null),null}}function Zo(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function Yo(e,t){let n=e,r=Object.entries(t).sort((s,i)=>i[0].length-s[0].length);for(let[s,i]of r)s&&(n=n.split(s).join(i));return n}async function Xo(e,t,n,r){let s=S.join(e,"asset-map.json"),i;try{i=await A.readFile(s,"utf8");}catch(a){if(a.code==="ENOENT")return;throw a}let o=JSON.parse(i);if(!o||typeof o!="object")return;let u=Object.fromEntries(Object.entries(o).map(([a,c])=>{let l=String(c??"");return t.urlRewriteMode==="absolute"&&t.targetOrigin&&n.targetOrigin&&t.targetOrigin!==n.targetOrigin&&(l=l.split(t.targetOrigin).join(n.targetOrigin)),l=Yo(l,r),[a,l]}));await A.writeFile(s,JSON.stringify(u,null,2),"utf8");}async function ea(e,t,n,r,s,i){let o=e.targetOrigin!==t.targetOrigin,u=Object.keys(r).length>0;if(!n||!o&&!u)return {outputDir:e.outputDir,cleanup:async()=>{}};if(o&&e.urlRewriteMode!=="absolute")throw new Error(`Deployment profile "${n}" changes targetOrigin, but the base crawl output must use urlRewriteMode "absolute" for multi-target redeploys.`);let a=S.join(S.dirname(e.outputDir),`.deploy-profile-${Zo(n)}-${Date.now()}`),c=Do(a);s.info(`Preparing deployment profile "${n}" from existing crawl output to ${a}...`);try{if(await A.rm(a,{recursive:!0,force:!0}),i){await A.mkdir(a,{recursive:!0});for(let g of i){let f=S.join(e.outputDir,g),m=S.join(a,g);await A.mkdir(S.dirname(m),{recursive:!0}),await A.copyFile(f,m);}}else await A.cp(e.outputDir,a,{recursive:!0});let l={...e,sourceOrigin:e.targetOrigin,targetOrigin:t.targetOrigin,extraReplacements:r,outputDir:a},d=1;s.info(`Rewriting text files for deployment profile "${n}"...`);let p=await ct(l,{},{files:i,onStart:({totalFiles:g,workerCount:f})=>{d=f,s.info(`Rewriting ${g} text file(s) for deployment profile "${n}" with ${f} worker(s).`);},onProgress:({index:g,totalFiles:f,changedTextFiles:m,file:h,changed:w})=>{let k=`Rewriting [${g}/${f}] ${h} (${w?"rewrote":"checked"}; ${m} changed so far)`;f<=200||g<=5||g%10===0||g===f?(s.progress(k,{file:h,index:g,totalFiles:f,changed:w,changedTextFiles:m,workerCount:d}),s.info(k)):s.debug(k);}});return await Xo(a,e,t,r),s.info(`Prepared deployment profile "${n}" in ${a} (${p} rewritten text file(s)).`),{outputDir:a,cleanup:async()=>{c(),await A.rm(a,{recursive:!0,force:!0});}}}catch(l){throw s.error(`Failed to prepare deployment profile "${n}" temporary output.`,{tempDir:a,outputDir:e.outputDir,error:l instanceof Error?l.message:String(l),...l instanceof Error&&l.stack?{stack:l.stack}:{}}),await A.rm(a,{recursive:true,force:true}).catch(()=>{}),c(),await s.flush().catch(()=>{}),l}}async function Or(e=process.argv.slice(2)){let t=await ne(),n=St(e),r=Fe(t,n),s=S.resolve(r.config.logDir||"logs"),i=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",o=i?S.join(S.resolve(i),"deploy-diff.json"):"",u=new $e(s,"deploy.log.jsonl",r.config.logLevel??"info"),a=r.profile?.extraReplacements??{},c=async()=>{};try{let l=await it(t);if(e.includes("--content-sync")&&l?.schemaVersion!==2)throw new Error("Content-sync deployment requires a valid schema-2 targeted deploy plan.");let p=await Nn(t);if(p)throw new Error(`Deployment blocked: the crawl started at ${p.startedAt} did not complete its final rewrite. Run a successful crawl or resume the rewrite before deploying.`);let g=await ea(t,r.config,r.name,a,u,l?.schemaVersion===2?l.changedFiles:void 0);c=g.cleanup;let f={...r.config,outputDir:g.outputDir},m=f.s3SyncMode??"sdk-upload-delete";if(l?.schemaVersion===2&&l.deletedFiles.length>0&&m!=="sdk-upload-delete")throw new Error("Content-sync tombstones require the sdk-upload-delete S3 sync mode.");let h=l?.schemaVersion!==2&&g.outputDir!==t.outputDir&&(t.targetOrigin!==r.config.targetOrigin||Object.keys(a).length>0),w=!!l&&!l.fullSyncRequired&&!h;if(l?.schemaVersion===2&&!w)throw new Error("Content-sync deployment cannot widen into a full-output deployment.");r.name&&u.info(`Using deployment profile: ${r.name}`),u.info(`Starting deploy \u2014 s3://${f.s3.bucket}/${f.s3.prefix||""} (region: ${f.s3.region})`),u.info(`S3 sync mode: ${m}`),l&&l.fullSyncRequired?u.info("Deploy plan requests a full sync; scanning the whole output tree."):l&&h?u.info("Ignoring incremental deploy plan because deployment-profile rewrites require a full sync."):w&&u.info(`Using incremental deploy plan: ${l.changedFiles.length} changed file(s), ${l.deletedFiles.length} deleted file(s).`),u.mark("deploy");let v=new S3Client({region:f.s3.region}),k=g.outputDir===t.outputDir?await Uo(t,i,u):null,E=l?.schemaVersion===2?[...l.uploadGroups.assets,...l.uploadGroups.content,...l.uploadGroups.listings,...l.uploadGroups.sitemapLeaves,...l.uploadGroups.sitemapIndexes]:l?.changedFiles??[];if(l?.schemaVersion===2){let T=[...new Set(E)],W=[...new Set(l.changedFiles)];if(T.length!==W.length||W.some(R=>!T.includes(R)))throw new Error("Content-sync deploy-plan upload groups do not cover the exact changed-file set.")}let F=w?(await Promise.all(E.map(async T=>{try{return (await A.stat(S.join(f.outputDir,T))).isFile()?T:null}catch{if(l?.schemaVersion===2)throw new Error(`Content-sync planned upload is missing: ${T}`);return null}}))).filter(T=>T!==null):await bs(["**/*"],{cwd:f.outputDir,onlyFiles:!0,dot:!0}),I=[],O=[],b=F.filter(T=>{let W=k?.byRelativePath.get(Dr(T));if(!W)return !0;let R=bt(f.s3.prefix,T);return I.push(T),O.push(R),u.reject(W.kind,W.sourceUrl||T,"rewrite not completed; deploy upload blocked","deploy-guard",{file:T,key:R,outputPath:W.outputPath,manifestPath:k?.manifestPath}),!1}),P=new Set((w?b:F).map(T=>bt(f.s3.prefix,T)));k&&(k.pendingPages>0||k.pendingTextAssets>0)&&u.info(`Deploy rewrite guard loaded ${k.pendingPages} pending page(s) and ${k.pendingTextAssets} pending text asset(s) from crawl manifest.`,{manifestPath:k.manifestPath,pendingPages:k.pendingPages,pendingTextAssets:k.pendingTextAssets,source:"deploy-guard"}),I.length>0&&u.warn(`Deploy rewrite guard blocked ${I.length} file(s) from upload because final crawl rewrite is incomplete.`,{rejected:I.length,manifestPath:k?.manifestPath,source:"deploy-guard"}),w?u.info(`Using ${b.length} eligible planned changed file(s) from deploy plan for upload${I.length>0?` (${I.length} blocked by deploy rewrite guard)`:""}.`):u.info(`Found ${F.length} file(s) in output directory "${f.outputDir}"${I.length>0?`; ${b.length} remain eligible for upload after deploy rewrite guard filtering`:""}.`),u.progress("Deploy preflight: comparing local output with remote S3 state.",{phase:"deploy",mode:m,totalFiles:b.length,scannedFiles:F.length,rejected:I.length,deploymentProfile:r.name||"",s3Bucket:f.s3.bucket,s3Prefix:f.s3.prefix||"",targetedPlan:w,deployGuardEnabled:g.outputDir===t.outputDir});let C=0,y=0,x=0,j=[],U=[],V=[],B=[],K=[],$=new Map,Ye=new Map,Nr=new Map,Br=new Map,Hr=new Map;w||(u.info("Listing existing S3 objects to detect unchanged files..."),$=await zo(v,f.s3.bucket,f.s3.prefix,u),u.info(`Found ${$.size} existing key(s) in S3.`));let Wr=async T=>$.has(T)?$.get(T)??null:w?Qo(v,f.s3.bucket,T,Ye):null;for(let T of b){let W=S.join(f.outputDir,T),R=bt(f.s3.prefix,T),ee=k?.contentTypeByRelativePath.get(T),Oe=ee&&ee!=="application/octet-stream"?ee:Eo.lookup(T)||ee||"application/octet-stream",zr=rn(T)?f.s3.htmlCacheControl:f.s3.assetCacheControl,L=C+y+x+1;b.length<=200||L<=5||L%10===0||L===b.length?(u.progress(`Uploading [${L}/${b.length}] ${R} (${Oe})`,{file:T,key:R,index:L,totalFiles:b.length,contentType:Oe,mode:m}),u.info(`Uploading [${L}/${b.length}] ${R} (${Oe})`)):u.debug(`Uploading [${L}/${b.length}] ${R} (${Oe})`);try{let te=await A.readFile(W),je=await Wr(R),Le=null,Ie=null;if(je){let It=te.byteLength;if(je.size===It){let Xe=je.etag.includes("-");if(je.etag!==""&&!Xe){let Qr=Vo(te);if(je.etag===Qr){y++,b.length<=200||y<=5||y%25===0?(u.progress(`Skipped unchanged [${L}/${b.length}] ${R}`,{file:T,key:R,index:L,totalFiles:b.length,uploaded:C,skipped:y,failed:x,mode:m,reason:"etag-md5-match"}),u.info(`Skipped unchanged [${L}/${b.length}] ${R}`)):u.debug(`Skipped unchanged [${L}/${b.length}] ${R}`),U.push(R);continue}}Le=Er(te);let hn=await Ko(v,f.s3.bucket,R,Nr);if(hn&&hn===Le){y++,b.length<=200||y<=5||y%25===0?(u.progress(`Skipped unchanged [${L}/${b.length}] ${R}`,{file:T,key:R,index:L,totalFiles:b.length,uploaded:C,skipped:y,failed:x,mode:m,reason:"metadata-sha256-match"}),u.info(`Skipped unchanged [${L}/${b.length}] ${R}`)):u.debug(`Skipped unchanged [${L}/${b.length}] ${R}`),U.push(R);continue}}if(rn(T)){Ie=on(te);let Xe=await Go(v,f.s3.bucket,R,Br,Hr);if(Xe&&Xe===Ie){y++,b.length<=200||y<=5||y%25===0?(u.progress(`Skipped semantically unchanged [${L}/${b.length}] ${R}`,{file:T,key:R,index:L,totalFiles:b.length,uploaded:C,skipped:y,failed:x,mode:m,reason:"normalized-html-match"}),u.info(`Skipped semantically unchanged [${L}/${b.length}] ${R}`)):u.debug(`Skipped semantically unchanged [${L}/${b.length}] ${R}`),U.push(R);continue}}}Le=Le??Er(te),Ie=Ie??(rn(T)?on(te):null),await Y(`S3 upload ${R}`,9e5,({abortController:It})=>new Upload({client:v,abortController:It,params:{Bucket:f.s3.bucket,Key:R,Body:te,ContentType:Oe,CacheControl:zr,Metadata:{[Mr]:Le,...Ie?{[Fr]:Ie}:{}}}}).done()),C++,j.push(R),(C%25===0||C===b.length)&&(u.progress(`Uploaded ${C}/${b.length} file(s)\u2026`,{uploaded:C,skipped:y,failed:x,totalFiles:b.length,mode:m}),u.info(`Uploaded ${C}/${b.length} file(s)\u2026`));}catch(te){x++,V.push(R),u.error(`Failed to upload ${R}: ${te.message}`,{key:R,error:String(te)});}}if(u.info(`Upload complete: ${C} uploaded, ${y} skipped unchanged, ${O.length} rejected by guard, ${x} failed.`),V.length>0||O.length>0)throw new Error(`Deployment stopped before deletion because ${V.length} upload(s) failed and ${O.length} upload(s) were rejected.`);if(m==="sdk-upload-delete"){let T=new Set((l?.deletedFiles??[]).map(R=>bt(f.s3.prefix,R))),W=[...T].filter(R=>!P.has(R));if(!w&&(K=[...$.keys()].filter(ee=>!P.has(ee)).filter(ee=>!T.has(ee)),K.length>0)){u.warn(`Protected ${K.length} remote-only S3 object(s) from deletion because the crawl did not provide explicit tombstones.`,{protected:K.length,source:"deploy-delete-guard"});for(let ee of K)u.debug(` protected remote-only object: ${ee}`);}B=await Jo(v,f.s3.bucket,w?W:W.filter(R=>$.has(R)),u);}else u.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion.");o&&(await A.mkdir(S.dirname(o),{recursive:!0}),await A.writeFile(o,JSON.stringify({generatedAt:new Date().toISOString(),mode:m,summary:{totalFiles:F.length,eligibleFiles:b.length,uploaded:j.length,skipped:U.length,rejected:O.length,failed:V.length,deleted:B.length,protected:K.length,...r.name?{profile:r.name}:{}},uploadedKeys:j,skippedKeys:U,rejectedKeys:O,failedKeys:V,deletedKeys:B,protectedRemoteOnlyKeys:K},null,2),"utf8")),l?.schemaVersion!==2&&await Te(t),u.endMark("deploy"),await u.flush();}finally{await c().catch(()=>{});}}function na(e){return String(e||"").replace(/\\/g,"/").replace(/^\/+|\/+$/g,"")}function ra(e,t){let n=e;n.endsWith("/")?n+="index.html":S.posix.basename(n).includes(".")||(n+="/index.html");let r=na(t);return r?`/${r}${n}`.replace(/\/{2,}/g,"/"):n}function jr(e,t){let n=new Set;for(let r of e){let s=new URL(r,"https://content-sync.invalid");if(s.origin!=="https://content-sync.invalid")continue;let i=`${s.pathname}${s.search}`;n.add(i),n.add(`${ra(s.pathname,t)}${s.search}`);}return [...n].sort()}function aa(){let e=String(process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"").trim();return e?S.join(S.resolve(e),"content-sync-invalidation.json"):""}async function ln(e,t){if(!e)return;await A.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await A.writeFile(n,JSON.stringify({...t,updatedAt:new Date().toISOString()},null,2),"utf8"),await A.rename(n,e);}async function ca(e,t,n,r){if(!e)return null;try{let s=JSON.parse(await A.readFile(e,"utf8"));if(s.schemaVersion!==1||s.distributionId!==t||s.impactHash!==n||!Array.isArray(s.batches))throw new Error("Content-sync invalidation state does not match the deploy plan.");let i=s.batches.flatMap(o=>o.paths);return i.length!==r.length||i.some((o,u)=>o!==r[u])?null:s}catch(s){if(s.code==="ENOENT")return null;throw s}}function ua(e,t=3e3){let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}async function pn(e=process.argv.slice(2)){let t=await ne(),n=St(e),r=Fe(t,n),s=r.config,i=new $e(s.logDir||"logs","invalidate.log.jsonl",s.logLevel??"info"),o=e.includes("--content-sync"),u=await it(t);if(o&&u?.schemaVersion!==2)throw new Error("Content-sync invalidation requires a valid schema-2 targeted deploy plan.");if(r.name&&i.info(`Using deployment profile: ${r.name}`),!s.cloudFront.distributionId){i.info("No CloudFront distributionId configured; skipping invalidation."),await i.flush();return}let a=u?.schemaVersion===2?u.invalidationPaths:s.cloudFront.invalidationPaths.length>0?s.cloudFront.invalidationPaths:["/*"],c=u?.schemaVersion===2?jr(a,s.s3.prefix||""):a;if(u?.schemaVersion===2&&c.some(f=>f==="/*"))throw new Error("Content-sync cannot use a whole-distribution invalidation.");if(c.length===0){i.info("The targeted deploy plan has no CloudFront paths to invalidate."),await i.flush();return}let l=s.cloudFront.distributionId,d=new CloudFrontClient({region:"us-east-1",maxAttempts:5});if(i.mark("invalidate"),u?.schemaVersion!==2){let f=`smartcloud-static-publisher-${Date.now()}`;await Y(`CloudFront invalidation for distribution ${l}`,3e5,({httpOptions:m})=>d.send(new CreateInvalidationCommand({DistributionId:l,InvalidationBatch:{CallerReference:f,Paths:{Quantity:c.length,Items:c}}}),m)),i.endMark("invalidate"),await i.flush();return}let p=aa(),g=await ca(p,l,u.impactHash,c);if(!g){let f=createHash("sha256").update(JSON.stringify(c)).digest("hex");g={schemaVersion:1,distributionId:l,impactHash:u.impactHash,updatedAt:new Date().toISOString(),batches:ua(c).map((m,h)=>({index:h,callerReference:`wpsuite-content-sync-${u.impactHash.slice(0,24)}-${f.slice(0,24)}-${h}`,paths:m,invalidationId:null,status:"pending"}))},await ln(p,g);}for(let f of g.batches){if(!f.invalidationId){let m=await Y(`CloudFront targeted invalidation batch ${f.index+1}`,3e5,({httpOptions:w})=>d.send(new CreateInvalidationCommand({DistributionId:l,InvalidationBatch:{CallerReference:f.callerReference,Paths:{Quantity:f.paths.length,Items:f.paths}}}),w)),h=String(m.Invalidation?.Id||"").trim();if(!h)throw new Error("CloudFront did not return an invalidation ID.");f.invalidationId=h,f.status="created",await ln(p,g);}await waitUntilInvalidationCompleted({client:d,maxWaitTime:900,minDelay:2,maxDelay:15},{DistributionId:l,Id:f.invalidationId}),f.status="completed",await ln(p,g),i.info(`CloudFront invalidation batch ${f.index+1}/${g.batches.length} completed.`,{invalidationId:f.invalidationId,pathCount:f.paths.length});}i.endMark("invalidate"),await i.flush();}var qr=["claimed","impact-planned","rendered","deployed","invalidated","verified","acknowledged"];function fn(){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 S.resolve(e)}function De(e,t){return qr.indexOf(e)>=qr.indexOf(t)}async function pe(e,t,n,r,s={}){let i={timestamp:new Date().toISOString(),eventType:t,status:t.endsWith("failed")?"failed":"success",actorSource:"content-sync",jobId:n.id||"",command:"content-sync",message:r,details:s};await A.mkdir(e,{recursive:true}),await A.appendFile(S.join(e,"audit-events.jsonl"),`${JSON.stringify(i)}
|
|
11
|
-
`,"utf8");}function da(e){return Ue({postTypes:e.postTypes??[],listingPaths:e.listingPaths??[],includePostTypeArchives:e.includePostTypeArchives,includeTaxonomyArchives:e.includeTaxonomyArchives,includeAuthorArchives:e.includeAuthorArchives,includeDateArchives:e.includeDateArchives,includePostsPage:e.includePostsPage,includeSitemapChain:e.includeSitemapChain})}function pa(e,t){let n=(e.scheduler?.rules??[]).find(r=>r.command==="content-sync"&&r.id===t);if(!n)throw new Error(`Content-sync scheduler rule not found: ${t}`);if(n.enabled===false)throw new Error(`Content-sync scheduler rule is disabled: ${t}`);return n}async function mn(e,t){if(e.subscriptionType!=="PROFESSIONAL"&&e.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let n=da(t),r=Fe(e,t.deploymentProfile),s=r.name||"",i=Sn(e.sourceOrigin,String(t.id||""),n),o=Pn({sourceOrigin:e.sourceOrigin,targetOrigin:r.config.targetOrigin,deploymentProfile:s,s3Bucket:r.config.s3.bucket,s3Prefix:r.config.s3.prefix,cloudFrontDistributionId:r.config.cloudFront.distributionId,urlRewriteMode:r.config.urlRewriteMode,extraReplacements:r.profile?.extraReplacements??{}}),u=bn({siteId:e.wpsuite?.siteSettings?.siteId,accountId:e.wpsuite?.siteSettings?.accountId,sourceOrigin:e.sourceOrigin,ruleId:String(t.id||""),targetFingerprint:o}),a=`content-sync:${String(t.id||"")}:${oe({scopeFingerprint:i,targetFingerprint:o}).slice(0,32)}`,c=new tt({sourceOrigin:e.sourceOrigin,runtimeToken:String(e.wpsuite?.runtimeToken||""),ignoreHttpsErrors:e.ignoreHttpsErrors}),l=await c.releaseFingerprint(),d=yn({wordpressFingerprint:l,targetFingerprint:o,sourceOrigin:e.sourceOrigin,sitemapPaths:e.sitemapPaths,blockedPathPrefixes:e.blockedPathPrefixes,assetPathPrefixes:e.assetPathPrefixes,noJavaScriptRenderPathPrefixes:e.noJavaScriptRenderPathPrefixes,urlRewriteMode:e.urlRewriteMode});return {rule:t,scope:n,deployment:r,deploymentProfile:s,scopeFingerprint:i,targetFingerprint:o,consumerId:u,coalesceKey:a,client:c,releaseFingerprint:d}}async function ga(e){let t=fn(),n=nt(t),r=await ne(),s=(r.scheduler?.rules??[]).filter(c=>c.command==="content-sync"&&c.enabled!==false);if(s.length===0)return 0;let i=await $t(n),o=await rt(n),u=await kt(n),a=0;for(let c of s){let l=await mn(r,c),d=u.entries[l.coalesceKey];if(!d||d.releaseJobId!==e||d.scopeFingerprint!==l.scopeFingerprint||d.targetFingerprint!==l.targetFingerprint||d.releaseFingerprint!==l.releaseFingerprint)throw new Error(`The normal release has no matching pre-crawl content-sync cutoff for rule ${String(c.id||"")}.`);let p=oe({releaseJobId:e,releaseFingerprint:l.releaseFingerprint,scopeFingerprint:l.scopeFingerprint,targetFingerprint:l.targetFingerprint,sequence:d.sequence}),g=await l.client.establishBaseline({consumerId:l.consumerId,scopeFingerprint:l.scopeFingerprint,baselineId:p,postTypes:l.scope.postTypes,sequence:d.sequence}),f={schemaVersion:1,ruleId:String(c.id||""),consumerId:l.consumerId,coalesceKey:l.coalesceKey,scopeFingerprint:l.scopeFingerprint,targetFingerprint:l.targetFingerprint,releaseFingerprint:l.releaseFingerprint,baselineId:p,deploymentProfile:l.deploymentProfile,committedSequence:g.committedSequence,releaseJobId:e,verifiedAt:new Date().toISOString()};i.entries[l.coalesceKey]=f;let m=o.rules[l.coalesceKey];o.rules[l.coalesceKey]={ruleId:String(c.id||""),consumerId:l.consumerId,coalesceKey:l.coalesceKey,committedSequence:g.committedSequence,observedHeadSequence:g.headSequence,lag:Math.max(0,g.headSequence-g.committedSequence),lastSuccessfulJobId:m?.lastSuccessfulJobId||e,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:g.headSequence>g.committedSequence,retryAttempt:0,nextRetryAt:null,lastError:null,baselineStatus:"ready",baselineReason:null};let h=await En(n,l.coalesceKey);await pe(t,"content-sync-baseline-established",{id:e},"A normal release established a verified content-sync baseline.",{ruleId:c.id,consumerId:l.consumerId,committedSequence:g.committedSequence,supersededCurrent:h}),a++;}return await xn(n,i),await st(n,o),await A.rm(n.releaseCutoff,{force:true}),a}async function fa(e){let t=fn(),n=nt(t),r=await ne(),s=(r.scheduler?.rules??[]).filter(u=>u.command==="content-sync"&&u.enabled!==false);if(s.length===0)return 0;let i=await kt(n),o=0;for(let u of s){let a=await mn(r,u),c=Object.values(i.entries).find(p=>p.releaseJobId===e&&p.ruleId===String(u.id||""));if(c){if(c.coalesceKey===a.coalesceKey&&c.scopeFingerprint===a.scopeFingerprint&&c.targetFingerprint===a.targetFingerprint&&c.releaseFingerprint===a.releaseFingerprint){o++;continue}throw new Error(`The normal release scope changed after its journal cutoff was captured for rule ${String(u.id||"")}. Start a new normal publish instead of resuming this release.`)}let l=await a.client.unboundHead(a.scope.postTypes),d={schemaVersion:1,releaseJobId:e,ruleId:String(u.id||""),coalesceKey:a.coalesceKey,scopeFingerprint:a.scopeFingerprint,targetFingerprint:a.targetFingerprint,releaseFingerprint:a.releaseFingerprint,sequence:l.headSequence,capturedAt:new Date().toISOString()};i.entries[a.coalesceKey]=d,await pe(t,"content-sync-release-cutoff-captured",{id:e},"A normal release captured its pre-crawl content-sync journal cutoff.",{ruleId:u.id,consumerId:a.consumerId,sequence:l.headSequence}),o++;}return await In(n,i),o}async function ma(e,t){let n=JSON.parse(await A.readFile(S.join(e,"current-run.json"),"utf8"));if(n.id!==t||n.command!=="content-sync"||!String(n.ruleId||"").trim())throw new Error("The active queue job is not the requested content-sync job.");return n}async function gn(e,t,n=0){let r=e.protocol==="https:"?Rn:Zr,s=e.protocol==="https:"?new Rn.Agent({rejectUnauthorized:!t}):void 0;return new Promise((i,o)=>{let u=r.get(e,{agent:s,timeout:3e4,headers:{"user-agent":"WP-Suite-Content-Sync/1"}},a=>{let c=a.statusCode??500,l=a.headers.location;if(c>=300&&c<400&&l&&n<5){a.resume(),gn(new URL(l,e),t,n+1).then(i,o);return}let d=[],p=0;a.on("data",g=>{p+=g.byteLength,p<=1048576&&d.push(g);}),a.on("error",o),a.on("end",()=>i({status:c,body:Buffer.concat(d).toString("utf8")}));});u.on("timeout",()=>u.destroy(new Error(`Verification timed out: ${e}`))),u.on("error",o);})}async function ha(e,t,n){let r=t.deployment.config.targetOrigin;if(!/^https?:\/\//i.test(r))throw new Error("Content-sync verification requires an absolute HTTP(S) target origin.");let s=new Set;n.directRenderUrls[0]&&s.add(n.directRenderUrls[0]);for(let i of n.archiveFamilies)i.pageUrls[0]&&s.add(i.pageUrls[0]),i.pageUrls.at(-1)&&s.add(i.pageUrls.at(-1));for(let i of n.sitemapUrls)s.add(i);for(let i of s){let o=new URL(i),u=new URL(`${o.pathname}${o.search}`,r),a=await gn(u,e.ignoreHttpsErrors);if(a.status<200||a.status>=400)throw new Error(`Content-sync verification failed (${a.status}): ${u}`)}for(let i of n.deleteUrls.slice(0,10)){let o=new URL(i),u=new URL(`${o.pathname}${o.search}`,r),a=await gn(u,e.ignoreHttpsErrors);if(a.status>=200&&a.status<300)throw new Error(`Deleted content is still publicly available: ${u}`)}}async function wa(e){let t=await A.readFile(e.candidateManifest,"utf8");JSON.parse(t);let n=`${e.trustedManifest}.${process.pid}.tmp`;await A.writeFile(n,t,"utf8"),await A.rename(n,e.trustedManifest);}async function ya(e,t){try{let n=JSON.parse(await A.readFile(e.candidateManifest,"utf8"));if([...Object.values(n.pages??{}),...Object.values(n.assets??{})].some(s=>s?.lastSeenRunId===t))return "resumed"}catch(n){if(n.code!=="ENOENT")throw new Error(`The content-sync candidate manifest is invalid: ${n instanceof Error?n.message:String(n)}`,{cause:n})}return await A.copyFile(e.trustedManifest,e.candidateManifest).catch(n=>{throw new Error(`A trusted crawl manifest is required before content-sync: ${n instanceof Error?n.message:String(n)}`,{cause:n})}),"initialized"}async function Re(e,t,n,r,s={},i=0){t.phase=n,await An(e,t),await $n(e,{schemaVersion:1,jobId:t.jobId,phase:n,completedItems:r,totalItems:r,attempt:i,updatedAt:new Date().toISOString(),details:s}),await pe(S.dirname(e.state),"content-sync-checkpoint",{id:t.jobId},`Content-sync checkpoint completed: ${n}.`,{phase:n,completedItems:r,totalItems:r,attempt:i,...s});}async function Sa(e){let t=fn(),n=nt(t),r=await ma(t,e),s=await ne(),i=pa(s,String(r.ruleId)),o=await mn(s,i);if(r.coalesceKey&&r.coalesceKey!==o.coalesceKey)throw new Error("Queued content-sync demand no longer matches the active rule scope.");let a=(await $t(n)).entries[o.coalesceKey];if(!a||a.scopeFingerprint!==o.scopeFingerprint||a.targetFingerprint!==o.targetFingerprint||a.releaseFingerprint!==o.releaseFingerprint)throw await pe(t,"content-sync-baseline-rejected",r,"Content-sync requires a new verified full or incremental release baseline.",{ruleId:i.id,reason:a?"mismatch":"missing"}),new Error("Content-sync baseline is missing or stale. Run a successful normal publish first.");let c=await Et(n),l=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:a.baselineId,postTypes:o.scope.postTypes});if(c&&c.jobId!==r.id)throw new Error("Another immutable content-sync range is still active.");if(c||(c={schemaVersion:1,jobId:r.id,ruleId:String(i.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,scopeFingerprint:o.scopeFingerprint,targetFingerprint:o.targetFingerprint,baselineId:a.baselineId,fromSequence:l.committedSequence,toSequence:l.headSequence,phase:"claimed",impactHash:null,startedAt:new Date().toISOString(),updatedAt:new Date().toISOString()},await Re(n,c,"claimed",0,{fromSequence:c.fromSequence,toSequence:c.toSequence}),await pe(t,"content-sync-range-claimed",r,"Content-sync claimed a closed journal range.",{fromSequence:c.fromSequence,toSequence:c.toSequence})),c.fromSequence===c.toSequence){let m=await rt(n);m.rules[o.coalesceKey]={ruleId:String(i.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,committedSequence:c.toSequence,observedHeadSequence:l.headSequence,lag:Math.max(0,l.headSequence-c.toSequence),lastSuccessfulJobId:r.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:false,retryAttempt:0,nextRetryAt:null,lastError:null},await st(n,m),await Mt(n);return}let d=await Tn(n);if(!De(c.phase,"impact-planned")){let m=await o.client.events({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:a.baselineId,postTypes:o.scope.postTypes,afterSequence:c.fromSequence,throughSequence:c.toSequence}),h=Tt({events:m,scope:o.scope,sourceOrigin:s.sourceOrigin}),w=await o.client.resolveImpactFamilies(h);d=Cn({jobId:r.id,ruleId:String(i.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,scopeFingerprint:o.scopeFingerprint,targetFingerprint:o.targetFingerprint,baselineId:a.baselineId,sourceOrigin:s.sourceOrigin,scope:o.scope,fromSequence:c.fromSequence,toSequence:c.toSequence,events:m,resolvedArchiveFamilies:w,sitemapUrls:s.sitemapPaths}),await kn(n,d),c.impactHash=d.impactHash,await Re(n,c,"impact-planned",m.length,{eventCount:m.length,foldedCount:d.foldedCount,impactHash:d.impactHash}),await pe(t,"content-sync-impact-planned",r,"Content-sync persisted an immutable impact plan.",{impactHash:d.impactHash,eventCount:m.length});}if(!d||d.jobId!==r.id||c.impactHash!==d.impactHash)throw new Error("The immutable content-sync impact plan is missing or mismatched.");if(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH=n.candidateManifest,!De(c.phase,"rendered")){let m=await ya(n,r.id);await pe(t,m==="resumed"?"content-sync-render-resumed":"content-sync-render-initialized",r,m==="resumed"?"Content-sync resumed its candidate crawl manifest.":"Content-sync initialized a candidate crawl manifest.",{impactHash:d.impactHash}),await Tr(["--content-sync-plan",n.impact]),await Re(n,c,"rendered",d.directRenderUrls.length+d.archiveFamilyUrls.length,{impactHash:d.impactHash},r.attempt??0);}let p=o.deploymentProfile?["--profile",o.deploymentProfile]:[];if(De(c.phase,"deployed")||(await Or([...p,"--content-sync"]),await Re(n,c,"deployed",1,{impactHash:d.impactHash}),await pe(t,"content-sync-deployed",r,"Content-sync targeted deployment completed.",{impactHash:d.impactHash})),De(c.phase,"invalidated")?De(c.phase,"verified")||await pn([...p,"--content-sync"]):(await pn([...p,"--content-sync"]),await Re(n,c,"invalidated",1,{impactHash:d.impactHash})),De(c.phase,"verified")||(await ha(s,o,d),await wa(n),await Re(n,c,"verified",1,{impactHash:d.impactHash})),l=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:a.baselineId,postTypes:o.scope.postTypes}),l.committedSequence===c.fromSequence)await o.client.acknowledge({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:a.baselineId,expectedSequence:c.fromSequence,sequence:c.toSequence,postTypes:o.scope.postTypes});else if(l.committedSequence!==c.toSequence)throw new Error("Content-sync acknowledgement cursor is in an unexpected state.");await Re(n,c,"acknowledged",1,{sequence:c.toSequence}),await pe(t,"content-sync-cursor-acknowledged",r,"Content-sync committed its journal cursor after verification.",{sequence:c.toSequence});let g=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:a.baselineId,postTypes:o.scope.postTypes}),f=await rt(n);f.rules[o.coalesceKey]={ruleId:String(i.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,committedSequence:c.toSequence,observedHeadSequence:g.headSequence,lag:Math.max(0,g.headSequence-c.toSequence),lastSuccessfulJobId:r.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:g.headSequence>c.toSequence,retryAttempt:0,nextRetryAt:null,lastError:null},await st(n,f),await Te(s),await A.rm(S.join(t,"content-sync-invalidation.json"),{force:true}),await A.rm(n.candidateManifest,{force:true}),await Mt(n);}async function _r(e=process.argv.slice(2)){let n=e.indexOf("--capture-baseline-cutoffs");if(n>=0){let o=String(e[n+1]||"").trim();if(!o)throw new Error("--capture-baseline-cutoffs requires a release job ID.");await fa(o);return}let r=e.indexOf("--establish-baselines");if(r>=0){let o=String(e[r+1]||"").trim();if(!o)throw new Error("--establish-baselines requires a release job ID.");await ga(o);return}let s=e.indexOf("--job-id"),i=s>=0?String(e[s+1]||"").trim():"";if(!i)throw new Error("Content-sync requires --job-id.");await Sa(i);}_r().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1);});
|
|
10
|
+
${i}`,40);return r.info(`Using generated 404 fallback change token for ${n}`,{url:n,requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),{url:n,supported:!0,token:o,tokenSource:"generated-404-response-hash",postId:null,dependencyPostIds:[],reason:null}}catch(s){return r.warn(`Generated 404 fallback token lookup failed for ${n}`,{url:n,error:String(s),requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),null}}async function li(e,t,n,r,s,i){let o=tn(e,s);if(!r.enabled)return {action:"render",changeToken:r.trackManifest?await zt(e,t,r,s,i):null};let u=r.manifest.pages[s];if(!u)return {action:"render",changeToken:await zt(e,t,r,s,i)};let a=await zt(e,t,r,s,i);if(a?.supported&&a.token)return u.changeToken===a.token?o&&!await di(e,t,s,i)?{action:"render",changeToken:a}:{action:"reuse",changeToken:a}:{action:"render",changeToken:a};let c=ze(n.sitemapLastmodByPage[s]);return c&&u.sitemapLastmod&&u.sitemapLastmod===c?{action:"reuse",changeToken:a}:{action:"render",changeToken:a}}async function di(e,t,n,r){try{let i=(await t.get(n,{timeout:Math.min(e.navigationTimeoutMs,15e3),failOnStatusCode:!1})).status();return i===404?!0:(r.warn(`Generated 404 request path no longer returns 404 for ${n}`,{url:n,status:i,requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),!1)}catch(s){return r.warn(`Generated 404 status probe failed for ${n}`,{url:n,error:String(s),requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),false}}async function pi(e,t,n,r,s){let i=sr(n.previousManifest,void 0,r,"previous-manifest"),o=0;for(let[p,g]of Object.entries(n.manifest.pages))if(!n.seenPages.has(p)){rr(s,e,g.outputPath);try{await A.unlink(g.outputPath);}catch(f){(f.code||"")!=="ENOENT"&&r.warn(`Failed to remove stale incremental page output for ${p}`,{url:p,outputPath:g.outputPath,error:String(f)});}delete n.manifest.pages[p],o++;}let u=sr(n.manifest,n.runId,r,"active-manifest"),a=new Set,c=new Set;for(let p of u){for(let m of Qe(e,p))a.add(m);let g=n.manifest.assets[p]?.outputPath;g&&c.add(g);let f=Je(e,t.assetMap,p);f&&c.add(f);}for(let p of Object.keys(n.manifest.assets))u.has(p)||delete n.manifest.assets[p];let l=0,d=0;for(let p of i){let g=new Set,f=n.previousManifest.assets[p]?.outputPath;f&&g.add(f);let m=Je(e,t.assetMap,p);if(!u.has(p)&&m)g.add(m);else if(!u.has(p)){let h=ki(e,p,r,"incremental-cleanup");h&&(g.add(h.originalFilePath),h.hashedFilePath&&g.add(h.hashedFilePath));}for(let h of g)if(!c.has(h)){rr(s,e,h);try{await A.unlink(h),l++;}catch(w){(w.code||"")!=="ENOENT"&&r.warn(`Failed to remove stale incremental asset output for ${p}`,{url:p,outputPath:h,error:String(w)});}}for(let h of Qe(e,p))a.has(h)||Object.prototype.hasOwnProperty.call(t.assetMap,h)&&(delete t.assetMap[h],d++);}(o>0||l>0||d>0)&&r.info(`Incremental cleanup removed ${o} stale pages, ${l} stale assets, ${d} stale asset mappings`,{removedPages:o,removedAssets:l,removedAssetMappings:d,phase:"incremental-cleanup"});}function sr(e,t,n,r){let s=new Set,i=o=>{let u=o.trim();if(u){if(n){let a=ye(u,n,"asset",r??"manifest");if(!a)return;s.add(a.toString());return}s.add(u);}};for(let o of Object.values(e.pages))for(let u of o.discoveredAssets||[])i(u);for(let[o,u]of Object.entries(e.assets||{}))t&&u.lastSeenRunId!==t||i(o);return s}function ir(e,t,n){for(let r of t)for(let s of Qe(e,r))if(n.has(s))return true;return false}function gi(e,t,n,r,s){let i=new Set(n.rewriteTargets);for(let u of Object.values(t.manifest.pages))u.rewriteComplete||i.add(S.resolve(u.outputPath));for(let u of Object.values(t.manifest.assets))u.isText&&!u.rewriteComplete&&i.add(S.resolve(u.outputPath));let o=ii(r,s);if(o.size===0)return [...i];for(let u of Object.values(t.manifest.pages))ir(e,u.discoveredAssets,o)&&i.add(S.resolve(u.outputPath));for(let[u,a]of Object.entries(t.manifest.assets)){a.isText&&ir(e,a.discoveredAssets,o)&&i.add(S.resolve(a.outputPath));for(let c of Qe(e,u))if(o.has(c)){Z(n,e,a.outputPath),a.isText&&i.add(S.resolve(a.outputPath));break}}return [...i]}function fi(e,t){let n=t?new Set(Array.from(t,s=>S.resolve(s))):null,r=s=>n===null||n.has(S.resolve(s));for(let s of Object.values(e.manifest.pages))r(s.outputPath)&&(s.rewriteComplete=true);for(let s of Object.values(e.manifest.assets)){if(!s.isText){s.rewriteComplete=true;continue}r(s.outputPath)&&(s.rewriteComplete=true);}}function mi(e,t,n){let r=new Set,s=i=>{if(!i)return;let o=he(e.outputDir,i);o&&r.add(o);};for(let i of t.donePages)s(le(e,i));for(let i of Object.values(n.manifest.pages))i.lastSeenRunId===n.runId&&s(i.outputPath);for(let i of t.doneAssets)s(Je(e,t.assetMap,i));for(let i of Object.values(n.manifest.assets))i.lastSeenRunId===n.runId&&s(i.outputPath);return r}async function hi(e,t,n,r,s){let i=[...r.deletedFiles].sort(),o=mi(e,t,n),u=0;for(let l of [...o].sort()){try{if((await A.stat(S.join(e.outputDir,l))).isFile())continue}catch{}u++,s.warn(`Active output is missing after crawl: ${l}`,{phase:"deploy-plan",file:l,outputPath:S.join(e.outputDir,l)});}if(u>0&&s.warn(`Detected ${u} active output file(s) missing before deploy plan save.`,{phase:"deploy-plan",missingActiveOutputs:u}),i.length===0)return [];let a=[],c=0;for(let l of i){if(!o.has(l)){a.push(l);continue}c++;let d=S.join(e.outputDir,l),p;try{p=(await A.stat(d)).isFile();}catch{p=false;}s.warn(`Deploy plan protected active output from deletion: ${l}`,{phase:"deploy-plan",file:l,outputPath:d,exists:p});}return c>0&&s.info(`Deploy plan skipped ${c} active output deletion(s).`,{phase:"deploy-plan",protectedDeletes:c,deletedFiles:a.length}),a}function Qe(e,t){let n=new Set([t]);try{let r=new URL(t),i=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{i.push(new URL(e.targetOrigin).origin);}catch{}for(let o of i)try{n.add(new URL(o).origin+r.pathname+r.search);}catch{}n.add(r.pathname+r.search),n.add(r.pathname);}catch{}return [...n]}function wi(e,t){let n=new Set([t]);try{let r=new URL(t),i=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{i.push(new URL(e.targetOrigin).origin);}catch{}for(let o of i)try{n.add(new URL(o).origin+r.pathname+r.search);}catch{}n.add(r.pathname+r.search);}catch{}return [...n]}function yr(e,t){let n=e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/"?e.targetOrigin:"https://relative.invalid/";try{let r=new URL(t,n);return S.join(e.outputDir,en(r.pathname))}catch{return null}}function yi(e,t,n){for(let r of wi(e,n)){let s=t[r];if(!s)continue;let i=yr(e,s);if(i)return {outputPath:i,publicUrl:s}}return null}function Si(e,t,n){for(let r of Qe(e,n)){let s=t[r];if(!s)continue;let i=yr(e,s);if(i)return i}return null}function Je(e,t,n){let r=Si(e,t,n);if(r)return r;try{return yt(e,n).originalFilePath}catch{return null}}function Pi(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.join(S.resolve(e),"queue-runner-heartbeat.json"):""}async function or(e){let t=Pi();if(t)try{let n=await A.readFile(t,"utf8"),r=JSON.parse(n);if(!r||typeof r!="object")return;await A.writeFile(t,JSON.stringify({...r,checkedAt:new Date().toISOString(),status:"running",currentStep:"rewrite",message:e},null,2),"utf8");}catch{}}function bi(e,t){let n=new Set;for(let r of t.donePages)n.add(S.resolve(le(e,r)));for(let r of t.doneAssets){let s=Je(e,t.assetMap,r);!s||!be(s)||n.add(S.resolve(s));}return [...n]}var ht="re:",gt=new Map;function vi(e){if(!e.startsWith(ht))return null;let t=gt.get(e);if(t!==void 0)return t||null;let n=e.slice(ht.length).trim();if(!n)return gt.set(e,false),null;try{let r=new RegExp(n);return gt.set(e,r),r}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),gt.set(e,false),null}}function Xt(e,t){let n=vi(t);return n?n.test(e):t.startsWith(ht)?false:e.startsWith(t)}function Ci(e,t){return t.find(n=>Xt(e,n))}function Sr(e,t){let n=Ci(t.pathname,e.blockedPathPrefixes);if(n)return n.startsWith(ht)?`blocked path regex: ${n}`:`blocked path prefix: ${n}`;let r=e.blockedSearchFragments.find(s=>t.search.includes(s));return r?`blocked search fragment: ${r}`:null}function Ri(e){let t=new URL(e.sourceOrigin),n=new Set([t.hostname,...e.allowedAssetHosts]);if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{n.add(new URL(e.targetOrigin).hostname);}catch{}for(let r of Object.keys(e.extraReplacements||{}))try{n.add(new URL(r).hostname);}catch{}return n}function Ii(e,t){return Ri(e).has(t.hostname)}function xi(e){let t=ce(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function Kt(e){let t=ce(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function Ai(e){let t=ce(e).replace(/\\\//g,"/").trim(),n=S.extname(t).toLowerCase();return fr.has(n)||mr.has(n)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function Ee(e){return Gs.some(t=>e.pathname.startsWith(t))}function H(e,t,n=e.sourceOrigin,r,s="url"){let i=xi(t);if(!i||i.startsWith("data:")||i.startsWith("blob:")||i.startsWith("mailto:")||i.startsWith("tel:")||i.startsWith("#"))return r?.ignore(s,t,"empty or unsupported scheme",n),null;if(Kt(i))return r?.ignore(s,t,"looks like JavaScript/code fragment",n),null;if(Ai(i))return r?.ignore(s,t,"looks like JavaScript property access",n),null;try{let o=new URL(i,n);if(Pr(o))return r?.reject(s,t,"malformed URL encoding",n),null;if(!["http:","https:"].includes(o.protocol))return r?.ignore(s,t,"unsupported protocol: ",n),null;if(!Ii(e,o))return r?.ignore(s,o.toString(),"host not allowed",n),null;let u=Sr(e,o);if(u)return r?.reject(s,o.toString(),u,n),null;let a=new URL(e.sourceOrigin);return o.protocol=a.protocol,o.host=a.host,o.hash="",o}catch{return r?.reject(s,t,"invalid URL",n),null}}function Pr(e){try{return decodeURIComponent(e.pathname),decodeURIComponent(e.search),decodeURIComponent(e.hash),!1}catch{return true}}function ye(e,t,n,r){try{let s=new URL(e);return Pr(s)?(t.reject(n,e,"malformed URL encoding",r),null):s.protocol!=="http:"&&s.protocol!=="https:"?(t.reject(n,e,`unsupported protocol: ${s.protocol}`,r),null):s}catch{return t.reject(n,e,"invalid URL",r),null}}function br(e){return fr.has(S.extname(e.pathname).toLowerCase())}function Se(e){return Ee(e)?false:mr.has(S.extname(e.pathname).toLowerCase())}function Me(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function q(e,t){return !!(Me(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(n=>Xt(t.pathname,n))||br(t)||!Se(t)&&!Ee(t))}function le(e,t){let n=new URL(t),r=en(n.pathname);return r.endsWith("/")?r+="index.html":S.extname(r)||(r+="/index.html"),S.join(e.outputDir,r)}function en(e){try{return decodeURIComponent(e)}catch{return e}}function Ti(e){if(!e.generated404RequestPath)return null;try{let t=new URL(e.generated404RequestPath,e.sourceOrigin);return !t.pathname.endsWith("/")&&S.extname(t.pathname)===""&&(t.pathname+="/"),t.hash="",t.toString()}catch{return null}}function tn(e,t){let n=Ti(e);if(!n)return false;try{return new URL(t,e.sourceOrigin).toString()===n}catch{return false}}function yt(e,t){let n=new URL(t),r=en(n.pathname);r.endsWith("/")&&(r+="index.html");let s=!!n.search,i=r,o=S.join(e.outputDir,i),u=_t(e.targetOrigin,i),a=`${u}${n.search}`;if(!s)return {originalPathname:i,originalFilePath:o,originalPublicUrl:u,originalPublicUrlWithSearch:a,preferQueryHashed:s};let c=S.extname(r),d=`${c?r.slice(0,-c.length):r}.${Be(n.search)}${c||".bin"}`;return {originalPathname:i,originalFilePath:o,originalPublicUrl:u,originalPublicUrlWithSearch:a,preferQueryHashed:s,hashedPathname:d,hashedFilePath:S.join(e.outputDir,d),hashedPublicUrl:_t(e.targetOrigin,d)}}function ki(e,t,n,r){let s=ye(t,n,"asset",r);return s?yt(e,s.toString()):null}function $i(e,t,n,r,s){t[n]=r;try{let i=new URL(n),u=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{u.push(new URL(e.targetOrigin).origin);}catch{}for(let a of u)try{let c=new URL(a);t[c.origin+i.pathname+i.search]=r;}catch{}try{let a=(()=>{let c=new URL(r,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin);return `${c.pathname}${c.search}`})();t[i.pathname+i.search]=a;}catch{}try{let a=new URL(r,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=a;}catch{}try{let a=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=a;}catch{}}catch{}}async function vr(e){try{return await A.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Ve(e){try{return await A.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function Ei(e){let t=String(e["content-length"]||"").trim();if(!t)return null;let n=Number.parseInt(t,10);return Number.isFinite(n)&&n>=0?n:null}function Cr(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let n=Date.parse(t);return Number.isFinite(n)?n:null}function Mi(e,t){let n=Cr(t),r=Ei(t),s=e?.mtime.getTime();return n!==null&&Math.abs((s??0)-n)>=1e3||r!==null&&e?.size!==r?false:n!==null||r!==null}async function Fi(e,t){if(!t)return;let n=Cr(t);if(n===null)return;let r=await Ve(e);if(!r)return;let s=new Date(n);await A.utimes(e,r.atime,s).catch(()=>{});}function ar(e,t){let n=S.extname(e.pathname).toLowerCase(),r=t["content-type"]||"";return Ks.has(n)||Vs.some(s=>r.includes(s))&&!r.startsWith("image/")&&!r.includes("font")}function Di(e){try{let t=S.extname(new URL(e).pathname).toLowerCase();return t===".js"||t===".mjs"}catch{return false}}function We(e,t){(e.doneAssets.size%25===0||e.doneAssets.size===1||e.doneAssets.size===e.stats.assetsQueued)&&t.progress(`Asset download progress: processed ${e.doneAssets.size}, discovered ${e.stats.assetsQueued}.`,{doneAssets:e.doneAssets.size,assetsQueued:e.stats.assetsQueued,phase:"download-assets"});}function Oi(e){return Be(e.toString("base64"),40)}function ji(e,t,n){let r=e.assetVariantDigestsByOriginalPath.get(t);if(!r||r.size===0)return false;for(let s of r)if(s!==n)return true;return false}function Li(e,t,n){let r=e.assetVariantDigestsByOriginalPath.get(t);r||(r=new Set,e.assetVariantDigestsByOriginalPath.set(t,r)),r.add(n);}async function Gt(e,t,n,r,s,i,o){let u=yt(e,n),a=Oi(r),c=u.originalFilePath,l=u.originalPublicUrlWithSearch;if(u.preferQueryHashed&&u.hashedFilePath&&u.hashedPublicUrl&&ji(s,u.originalFilePath,a)){let f=yi(e,t,n);f?(c=f.outputPath,l=f.publicUrl):(c=u.hashedFilePath,l=u.hashedPublicUrl);}$i(e,t,n,l,u.originalPublicUrl);let d=be(c)?Buffer.from(Ht(r.toString("utf8"),e,t,c),"utf8"):r,p=await vr(c),g=false;return (p===null||!p.equals(d))&&(await He(c,d),g=true),i?.debug(`${g?"Saved":"Skipped unchanged"} asset output ${n}`,{phase:"download-assets",url:n,outputPath:c,bytes:d.length,wroteFile:g}),Li(s,u.originalFilePath,a),await Fi(c,o),s.stats.assetsSaved++,i&&(s.stats.assetsSaved%50===0||s.stats.assetsSaved===1)&&i.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:c,publicUrl:l,wroteFile:g}}function Ke(e,t,n,r,s){let i=()=>{let d=String(s??"").trim();if(!d)return {discoveredFrom:"",discoveredFromType:"unknown"};if(d==="seed-path"||d==="cli"||d==="generated-404-request-path")return {discoveredFrom:d,discoveredFromType:d};if(/^https?:\/\//i.test(d))try{let p=new URL(d);return Me(p)?{discoveredFrom:d,discoveredFromType:"sitemap"}:q(e,p)?{discoveredFrom:d,discoveredFromType:"asset"}:Se(p)&&!Ee(p)?{discoveredFrom:d,discoveredFromType:"page"}:{discoveredFrom:d,discoveredFromType:"url"}}catch{return {discoveredFrom:d,discoveredFromType:"url"}}return {discoveredFrom:d,discoveredFromType:"url"}},o=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,u=H(e,n,o,r,"page");if(!u)return;if(!Se(u)||br(u)){if(q(e,u)){r.info(`Seeded/non-page URL queued as asset: ${u.toString()}`,{url:u.toString(),source:s}),J(e,t,u.toString(),r,s);return}r.reject("page",u.toString(),Ee(u)?"asset/internal path cannot be page":"not page-like",s);return}let a=u.toString(),{discoveredFrom:c,discoveredFromType:l}=i();c&&!t.pageDiscoverySources.has(a)&&t.pageDiscoverySources.set(a,c),!t.donePages.has(a)&&!t.queuedPages.has(a)&&(t.queuedPages.add(a),t.pageQueue.push(a),t.stats.pagesQueued++,r.debug(`Queued discovered page ${a}`,{phase:"discovery",url:a,discoveredFrom:c,discoveredFromType:l,outputPath:le(e,a)}),(t.stats.pagesQueued%25===0||t.stats.pagesQueued===1)&&r.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 J(e,t,n,r,s){let i=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,o=H(e,n,i,r,"asset");if(!o)return;if(!q(e,o)){r.reject("asset",o.toString(),"not a safe asset path/prefix",s);return}let u=o.toString();!t.doneAssets.has(u)&&!t.queuedAssets.has(u)&&(t.queuedAssets.add(u),t.assetQueue.push(u),t.stats.assetsQueued++,(t.stats.assetsQueued%100===0||t.stats.assetsQueued===1)&&r.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 wt(e,t,n,r,s){let i=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,o=H(e,n,i,r,"sitemap");if(!o)return;if(!Me(o)){r.reject("sitemap",o.toString(),"not sitemap-like",s);return}let u=o.toString();!t.doneSitemaps.has(u)&&!t.queuedSitemaps.has(u)&&(t.queuedSitemaps.add(u),t.sitemapQueue.push(u),t.stats.sitemapsQueued++,(t.stats.sitemapsQueued%10===0||t.stats.sitemapsQueued===1)&&r.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 Ui(e){let t=ce(e),n=[...t.matchAll(/<url>\s*([\s\S]*?)\s*<\/url>/gi)].map(r=>r[1]);return n.length>0?n.map(r=>{let s=r.match(/<loc>\s*([^<]+?)\s*<\/loc>/i);if(!s?.[1])return null;let i=r.match(/<lastmod>\s*([^<]+?)\s*<\/lastmod>/i);return {loc:s[1].trim(),lastmod:ze(i?.[1]??null)}}).filter(r=>!!r):[...t.matchAll(/<loc>\s*([^<]+?)\s*<\/loc>/gi)].map(r=>({loc:r[1].trim(),lastmod:null})).filter(r=>r.loc)}function qi(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function _i(e){let t=[],n=/url\(\s*(?:"([^"]+)"|'([^']+)'|([^)]*?))\s*\)/gi;for(let r of e.matchAll(n)){let s=e.slice(Math.max(0,r.index-8),r.index);if(/\bnew\s+$/i.test(s))continue;let i=(r[1]||r[2]||r[3]||"").trim();i&&t.push(i);}return t}function Ni(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function Bi(e,t){if(t==="dom-style")return true;let n=(()=>{try{return S.extname(new URL(e).pathname).toLowerCase()}catch{return ""}})();return !(n===".js"||n===".mjs"||n===".map"||t.includes("javascript"))}function Qt(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function Rr(e,t,n,r){let s=[];await A.mkdir(t,{recursive:true});let i=await A.readdir(e,{withFileTypes:true});for(let o of i){let u=S.join(e,o.name),a=S.join(t,o.name);if(o.isDirectory()){s.push(...await Rr(u,a,n,r));continue}await Ir(u,a,n,r)&&s.push(a);}return s}async function Hi(e,t){try{let[n,r]=await Promise.all([A.stat(e),A.stat(t)]);if(n.size!==r.size)return !1;let[s,i]=await Promise.all([A.readFile(e),A.readFile(t)]);return s.equals(i)}catch{return false}}async function Ir(e,t,n,r){let s=S.resolve(t);return n.has(s)?(r.debug("Skipped post-crawl copy over crawled page output",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):await Hi(e,t)?(r.debug("Skipped unchanged post-crawl copy target",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):(await A.mkdir(S.dirname(t),{recursive:true}),await A.copyFile(e,t),true)}async function Wi(e,t,n){let r=Object.entries(e.postCrawlCopyMap||{}).map(([u,a])=>({sourcePath:u.trim(),prefix:String(a||"").trim()}));if(r.length===0)return [];let s=0,i=[],o=new Set([...t.donePages].map(u=>S.resolve(le(e,u))));n.mark("copy-extra-paths");for(let u of r){let a=u.sourcePath,c=u.prefix;if(!a||!c){n.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:a,prefixPath:c});continue}let l=ei(a);if(!l.resolvedPath){n.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:a,alias:l.alias||"",requiredEnv:l.requiredEnv||"",prefixPath:c});continue}let d=l.resolvedPath,p=Qt(c);if(!p){n.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:a,prefixPath:c});continue}let g;try{g=await A.stat(d);}catch{n.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:a,sourceAbs:d,prefixPath:c});continue}let f=S.resolve(e.outputDir,p);if(g.isDirectory()){let v=await Rr(d,f,o,n);i.push(...v),s+=v.length,v.length>0&&n.progress(`Copied static directory to export: ${d} -> /${p}`,{phase:"copy-extra-paths",sourcePath:d,targetPath:`/${p}`,copiedItems:s,changedFiles:v.length});continue}let m=S.basename(d),h=c.endsWith("/")?S.join(f,m):f;await Ir(d,h,o,n)&&(i.push(h),s++,n.progress(`Copied static file to export: ${d} -> /${Qt(c.endsWith("/")?`${c}${m}`:c)}`,{phase:"copy-extra-paths",sourcePath:d,targetPath:`/${Qt(c.endsWith("/")?`${c}${m}`:c)}`,copiedItems:s}));}return n.endMark("copy-extra-paths",{mappedSources:r.length,copiedItems:s}),i}function Ge(e,t,n,r,s){let i=new Set,o=ce(n).replace(/\\\//g,"/"),u=s==="page-html"?Ni(o):o,a=Bi(t,s);if(a){for(let l of _i(u)){let d=H(e,l,t,r,`${s}:css-url`);d&&q(e,d)&&i.add(d.toString());}for(let l of u.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let d=H(e,l[1],t,r,`${s}:css-import`);d&&q(e,d)&&i.add(d.toString());}}if(a||s==="page-html")for(let l of u.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let d=H(e,l[1],t,r,`${s}:xml-stylesheet`);d&&q(e,d)&&i.add(d.toString());}let c=new RegExp(`(?:https?:)?//[^\\s'"<>\\);]+\\.${Wt}(?:\\?[^\\s'"<>\\);]*)?|(?<!\\.)/[^\\s'"<>\\);]+\\.${Wt}(?:\\?[^\\s'"<>\\);]*)?`,"gi");if(s==="page-html")for(let l of o.matchAll(c)){let d=l[0].startsWith("//")?`${new URL(e.sourceOrigin).protocol}${l[0]}`:l[0];if(Kt(d)){r.ignore(`${s}:serialized-url`,d,"looks like JavaScript/code fragment",t);continue}let p=H(e,d,t,r,`${s}:serialized-url`);p&&q(e,p)?i.add(p.toString()):p&&r.ignore("asset",p.toString(),"serialized URL did not pass safe asset path filter",t);}if(s!=="page-html"&&Di(t))for(let l of tr(o)){if(Kt(l)||!/\.(?:js|mjs)(?:[?#]|$)/i.test(l))continue;let d=H(e,l,t,r,`${s}:relative-asset`);d&&q(e,d)&&i.add(d.toString());}return [...i]}function zi(e,t,n,r){let s=new Set,i=ce(n);for(let o of i.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let u=o[1],a=H(e,u,t,r,"page-link");a&&(Sr(e,a)||Se(a)&&!Ee(a)&&!q(e,a)&&s.add(a.toString()));}return [...s]}async function cr(e,t,n,r,s,i,o=false){let u=new Map,a=(c,l)=>{let d=[l],p=new Set;for(;d.length>0;){let g=d.pop();if(g===c)return true;p.has(g)||(p.add(g),d.push(...u.get(g)??[]));}return false};for(;n.sitemapQueue.length>0;){let c=n.sitemapQueue.shift();n.queuedSitemaps.delete(c);let l=ye(c,r,"sitemap","sitemap-queue");if(!l)continue;let d=l.toString();if(!n.doneSitemaps.has(d)){n.doneSitemaps.add(d),r.sitemap(`Fetching sitemap ${d}`,{url:d});try{let p=await t.get(d,{timeout:6e4});if(!p.ok()){if(r.skip("sitemap",d,p.status()),o)throw new Error(`Required content-sync sitemap returned HTTP ${p.status()}: ${d}`);continue}let g=await p.body(),f=p.url()||d,m=ye(f,r,"sitemap-response",d);if(!m)continue;let h=m.toString(),w=await Gt(e,n.assetMap,h,g,n,r);Z(s,e,w.outputPath),Ce(s,w.outputPath);let v=g.toString("utf8");/<sitemapindex(?:\s|>)/i.test(v)?n.sitemapIndexUrls.add(h):n.sitemapLeafUrls.add(h);let k=Ge(e,h,v,r,"sitemap");for(let F of k)J(e,n,F,r,h);let E=[];for(let F of Ui(v)){let I=H(e,F.loc,h,r,"sitemap-loc");if(!I){if(o)throw new Error(`Content-sync sitemap contains an inadmissible location: ${F.loc}`);continue}if(Me(I)){if(a(h,I.toString()))throw new Error(`Sitemap index cycle detected: ${h} -> ${I.toString()}`);u.has(h)||u.set(h,new Set),u.get(h).add(I.toString()),E.push(I.toString()),wt(e,n,I.toString(),r,h);}else if(o){if(Se(I)&&!q(e,I)){let O=i.requiredUrls.has(I.toString()),b=i.manifest.pages[I.toString()],P=!!b&&!!await Ve(b.outputPath);if(!O&&!P)throw new Error(`Content-sync sitemap coverage is incomplete for ${I.toString()}.`)}r.ignore("sitemap-loc",I.toString(),"content-sync sitemap-only traversal does not enqueue urlset locations",h);}else q(e,I)?J(e,n,I.toString(),r,h):Se(I)?(F.lastmod&&(n.sitemapLastmodByPage[I.toString()]=F.lastmod),Ke(e,n,I.toString(),r,h)):r.reject("sitemap-loc",I.toString(),"not page/sitemap/asset-like",h);}i.trackManifest&&(i.manifest.assets[h]={url:h,outputPath:w.outputPath,isText:!0,contentType:p.headers()["content-type"]??"application/xml",discoveredAssets:[...new Set([...k,...E])],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},await we(e,i));}catch(p){if(r.error(`Failed sitemap ${d}`,{url:d,error:String(p)}),o)throw p}}}}async function Qi(e,t,n,r,s,i,o){let u=H(e,r,e.sourceOrigin,s,"asset-fetch");if(!u||!q(e,u))return;let a=u.toString();if(n.doneAssets.has(a))return;let c=i.enabled||i.strictTargeted?i.previousManifest.assets[a]:void 0,l=i.strictTargeted?i.manifest.assets[a]:void 0;if(l?.lastSeenRunId===i.runId&&await Ve(l.outputPath)){n.doneAssets.add(a);for(let p of l.discoveredAssets||[])J(e,n,p,s,a);Z(o,e,l.outputPath),l.isText&&Ce(o,l.outputPath),s.info(`Resumed completed content-sync asset ${a}`,{url:a,source:"content-sync-checkpoint"}),We(n,s);return}let d=(p,g={})=>{if(!c||i.strictTargeted)return false;i.manifest.assets[a]={...c,discoveredAssets:[...c.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId},delete i.manifest.pages[a],n.doneAssets.add(a);for(let f of c.discoveredAssets||[])J(e,n,f,s,a);return s.warn(`Keeping previous incremental asset ${a} after fetch issue.`,{url:a,reason:p,preservedFromPreviousManifest:true,...g,phase:"download-assets"}),We(n,s),true};s.asset(`Fetching asset ${a}`,{url:a});try{let p=Je(e,n.assetMap,a),g=p?await Ve(p):null;if(p&&g)try{let O=await _(`fetch asset headers ${a}`,6e4,()=>t.head(a,{timeout:6e4})),b=O.headers();if(O.ok()&&Mi(g,b)){let P=await vr(p);if(P!==null){let C=O.url()||a,y=ye(C,s,"asset-response",a);if(!y)return;let x=y.toString(),j=await Gt(e,n.assetMap,x,P,n,s,b);j.wroteFile&&(Z(o,e,j.outputPath),be(j.outputPath)&&Ce(o,j.outputPath)),n.doneAssets.add(a),s.info(`Reused existing asset ${a} based on response headers.`,{url:a,filePath:p,lastModified:b["last-modified"]||"",contentLength:b["content-length"]||"",phase:"download-assets"}),We(n,s);let U=ar(u,b),V=c?.discoveredAssets?[...c.discoveredAssets]:[];if(U||c?.isText){let B=P.toString("utf8"),K=Ge(e,x,B,s,"asset:cached");(K.length>0||!c)&&(V=K);for(let $ of V)J(e,n,$,s,x);}if(i.trackManifest){let B=U||!!c?.isText;i.manifest.assets[a]={url:a,outputPath:j.outputPath,isText:B,contentType:Jt(b)||c?.contentType||null,discoveredAssets:V,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!B},delete i.manifest.pages[a],(i.enabled||i.strictTargeted)&&B&&await we(e,i);}return}}}catch{}let f=await _(`fetch asset ${a}`,6e4,()=>t.get(a,{timeout:6e4}));if(!f.ok()){if(d(`http-${f.status()}`,{status:f.status()}))return;if(i.strictTargeted)throw new Error(`Required content-sync asset returned HTTP ${f.status()}: ${a}`);s.skip("asset",a,f.status());return}let m=await _(`read asset response ${a}`,6e4,()=>f.body()),h=f.url()||a,w=ye(h,s,"asset-response",a);if(!w)return;let v=w.toString(),k=f.headers(),E=await Gt(e,n.assetMap,v,m,n,s,k);E.wroteFile&&(Z(o,e,E.outputPath),be(E.outputPath)&&Ce(o,E.outputPath)),n.doneAssets.add(a),We(n,s);let F=ar(u,k),I=[];if(F){let O=m.toString("utf8");I=Ge(e,v,O,s,`asset:${S.extname(u.pathname).toLowerCase()||k["content-type"]||"unknown"}`);for(let b of I)J(e,n,b,s,v);}i.trackManifest&&(i.manifest.assets[a]={url:a,outputPath:E.outputPath,isText:F,contentType:Jt(k),discoveredAssets:I,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!F},delete i.manifest.pages[a],(i.enabled||i.strictTargeted)&&F&&await we(e,i));}catch(p){if(d("fetch-error",{error:String(p)}))return;if(s.error(`Failed asset ${a}`,{url:a,error:String(p)}),i.strictTargeted)throw p}finally{n.doneAssets.has(a)||(n.doneAssets.add(a),We(n,s));}}async function Ji(e,t,n,r,s,i){let o=Math.max(1,Number(e.assetDownloadConcurrency||e.concurrency||1)),u=Array.from({length:o},async()=>{for(;n.assetQueue.length>0;){let a=n.assetQueue.shift();a&&(n.queuedAssets.delete(a),await Qi(e,t,n,a,r,s,i));}});await Promise.all(u);}function Vi(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function ue(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function mt(e){return Math.max(15e3,Math.min(6e4,ue(e)))}function Ki(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function nn(e){return e.stats.pagesCompleted}function xr(e){let n=e.options?.browserProcess;return {pid:typeof n?.process?.pid=="number"?n.process.pid:null,kill:typeof n?.kill=="function"?n.kill.bind(n):null}}async function Gi(e,t,n){let r=xr(e);try{if(r.kill){await r.kill(),t.warn(`Force-killed crawl worker browser after ${n}`,{browserPid:r.pid,reason:n});return}if(r.pid!==null){process.kill(r.pid,"SIGKILL"),t.warn(`Sent SIGKILL to crawl worker browser after ${n}`,{browserPid:r.pid,reason:n});return}t.warn(`Could not resolve crawl worker browser PID after ${n}`,{reason:n});}catch(s){t.error(`Failed to force-kill crawl worker browser after ${n}`,{browserPid:r.pid,reason:n,error:String(s)});}}async function _(e,t,n){let r;try{return await Promise.race([n(),new Promise((s,i)=>{r=globalThis.setTimeout(()=>{i(new Error(`${e} timed out after ${Vi(t)}.`));},t);})])}finally{r!==void 0&&globalThis.clearTimeout(r);}}async function Zi(e,t){let n=Ki(e);await t.evaluate(async r=>{await new Promise(s=>{let i=0,o=700,u=Date.now(),a=()=>{window.clearInterval(c),window.scrollTo(0,0),s();},c=window.setInterval(()=>{if(Date.now()-u>=r.maxDurationMs){a();return}window.scrollBy(0,o),i+=o;let l=document.body?.scrollHeight||0,d=document.documentElement?.scrollHeight||0,p=Math.max(l,d);i>=p+window.innerHeight&&a();},120);});},{maxDurationMs:n});}async function Yi(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 Zi(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function Xi(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 eo(e,t){return e.noJavaScriptRenderPathPrefixes.some(n=>Xt(t,n))}async function to(e,t,n,r,s=true){let i=new Set;if(s){let u=await t.evaluate(()=>{let a=new Set,c=["href","src","poster","data-src","data-lazy-src","data-original","data-bg","data-background","data-href"],l=new Set,d=["srcset","data-srcset","data-lazy-srcset"];return document.querySelectorAll("*").forEach(p=>{for(let f of c){let m=p.getAttribute(f);m&&a.add(m);}for(let f of d){let m=p.getAttribute(f);m&&m.split(",").forEach(h=>{let w=h.trim().split(/\s+/)[0];w&&a.add(w);});}let g=p.getAttribute("style");g&&l.add(g);}),{attrs:[...a],styles:[...l]}});for(let a of u.attrs)for(let c of qi(a)){let l=H(e,c,n,r,"dom-attr");l&&q(e,l)&&i.add(l.toString());}for(let a of u.styles)for(let c of Ge(e,n,a,r,"dom-style"))i.add(c);}let o=await t.content();for(let u of Ge(e,n,o,r,"page-html"))i.add(u);return [...i]}async function ur(e,t,n,r,s){let i=le(e,t);await He(i,n,"utf8");let o=await A.stat(i);s?.debug(`Saved page output ${t}`,{phase:"save-pages",url:t,outputPath:i,bytes:o.size}),r.stats.pagesSaved++;let u=Math.min(r.stats.pagesQueued,nn(r)+1);s&&(r.stats.pagesSaved%10===0||r.stats.pagesSaved===1)&&s.progress(`Page progress: processed ${u}, rendered ${r.stats.pagesRendered}, saved ${r.stats.pagesSaved}, discovered ${r.stats.pagesQueued}.`,{donePages:u,claimedPages:r.donePages.size,pagesRendered:r.stats.pagesRendered,pagesSaved:r.stats.pagesSaved,pagesQueued:r.stats.pagesQueued,pageQueue:r.pageQueue.length,phase:"save-pages"});}function no(e){let t=nn(e);return t%5===0||t===1||t===e.stats.pagesQueued}function ro(e,t){let n=nn(e);t.progress(`Render progress: processed ${n}, rendered ${e.stats.pagesRendered}, saved ${e.stats.pagesSaved}, discovered ${e.stats.pagesQueued}.`,{donePages:n,claimedPages:e.donePages.size,pagesRendered:e.stats.pagesRendered,pagesSaved:e.stats.pagesSaved,pagesQueued:e.stats.pagesQueued,phase:"render-pages"});}async function so(e){await e.addInitScript(()=>{Object.defineProperty(window,"__WPSUITE_STATIC_EXPORT__",{value:true,writable:false,configurable:true});let t=n=>{if(n==null||String(n)==="")return true;try{let r=new URL(String(n),window.location.href),s=new URL(window.location.href);return r.hash="",s.hash="",r.href===s.href}catch{return false}};try{let n=window.location.assign.bind(window.location),r=window.location.replace.bind(window.location),s=window.location.reload.bind(window.location);Object.defineProperty(window.location,"assign",{configurable:!0,value:i=>{if(t(i)){console.warn("[smartcloud-static-publisher] blocked same-page location.assign",i??"");return}return n(i)}}),Object.defineProperty(window.location,"replace",{configurable:!0,value:i=>{if(t(i)){console.warn("[smartcloud-static-publisher] blocked same-page location.replace",i??"");return}return r(i)}}),Object.defineProperty(window.location,"reload",{configurable:!0,value:()=>{console.warn("[smartcloud-static-publisher] blocked location.reload");}});}catch{}});}async function io(e,t,n){let r=await e.newContext({viewport:t.viewport,userAgent:"WPSuiteStaticPublisher/0.8 Playwright SitemapOnly",ignoreHTTPSErrors:t.ignoreHttpsErrors,...n?{javaScriptEnabled:false}:{}});return n||await so(r),r}async function oo(e,t,n,r,s,i,o){let u=await chromium.launch({headless:true}),a=xr(u);a.pid!==null&&n.debug(`Launched crawl worker browser PID ${a.pid}`,{browserPid:a.pid});try{for(;t.pageQueue.length>0&&!(e.maxPages>0&&t.donePages.size>=e.maxPages);){let c=t.pageQueue.shift();if(!c)break;t.queuedPages.delete(c);let l=null,d=null;try{let p=ye(c,n,"page","page-queue");if(!p)continue;let g=p.toString();if(c=g,t.queuedPages.delete(c),t.donePages.has(c))continue;t.donePages.add(c),i.enabled&&i.seenPages.add(c);let f=tn(e,c),m=eo(e,p.pathname);if(!Se(p)||q(e,p)||Ee(p)){if(q(e,p)){n.info(`Worker redirected non-page URL to asset queue: ${c}`,{url:c,source:"worker-guard"}),J(e,t,c,n,"worker-guard");continue}n.reject("page",c,"guard rejected non-page URL before rendering","worker");continue}let h=i.strictTargeted?i.manifest.pages[c]:void 0;if(h?.lastSeenRunId===i.runId&&await Ve(h.outputPath)){i.seenPages.add(c);for(let y of h.discoveredAssets||[])J(e,t,y,n,c);Z(o,e,h.outputPath),Ce(o,h.outputPath),n.info(`Resumed completed content-sync page ${c}`,{url:c,source:"content-sync-checkpoint"});continue}let w=await li(e,s,t,i,c,n);if(i.enabled&&r!=="single-url"&&r!=="content-sync"){let y=i.manifest.pages[c];if(w.action==="reuse"&&y){for(let x of y.discoveredAssets)J(e,t,x,n,c);for(let x of y.discoveredPages)Ke(e,t,x,n,c);y.lastSeenRunId=i.runId,y.sitemapLastmod=ze(t.sitemapLastmodByPage[c])??y.sitemapLastmod,w.changeToken?.supported&&(y.changeToken=w.changeToken.token,y.tokenSource=w.changeToken.tokenSource??y.tokenSource),n.info(`Incremental reuse skipped unchanged page ${c}`,{url:c,mode:"incremental",reason:w.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}l=await _(`create page context ${c}`,ue(e),()=>io(u,e,m)),d=await _(`create page ${c}`,ue(e),()=>l.newPage());let v=!1,k=new Set;await d.route("**/*",async y=>{let x=y.request();if(x.isNavigationRequest()&&x.frame()===d.mainFrame())try{let j=new URL(x.url()),U=new URL(g);if(j.hash="",U.hash="",j.href===U.href){if(v){n.warn(`Blocked same-page navigation/reload for ${c}`,{url:c,requestUrl:x.url()}),await y.abort("aborted");return}v=!0;}}catch{}await y.continue();}),d.on("response",y=>{try{let x=H(e,y.url(),e.sourceOrigin,n,"network-response");x&&q(e,x)&&(k.add(x.toString()),J(e,t,x.toString(),n,c));}catch{}}),n.page(`Rendering ${c}`,{url:c});let E=null,F=null;try{if(E=await d.goto(c,{waitUntil:"domcontentloaded",timeout:e.navigationTimeoutMs}),E&&E.ok())try{F=await _(`read response body ${c}`,ue(e),()=>E.text());}catch{F=null;}}catch(y){n.warn(`Navigation issue for ${c}; saving current DOM if available`,{url:c,error:String(y)});}if(r==="content-sync"&&E){let y=ye(E.url(),n,"content-sync-final-response",c)?.toString();if(y&&y!==g){if(i.deleteOnMissingUrls.has(c)){await Zt(e,i,o,c,i.deleteOnMissingUrls),n.info(`Removed stale content-sync archive route redirected to ${y}`,{url:c,finalResponseUrl:y,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${c} -> ${y}`)}}if(f){let y=E?.status()??null;if(y!==404){n.error(`Generated 404 request path returned unexpected status for ${c}`,{url:c,expectedStatus:404,status:y,requestPath:e.generated404RequestPath});continue}n.info(`Capturing rendered 404 page for ${c}`,{url:c,status:y,outputPath:le(e,c)});}else if(E&&!E.ok()){if(r==="content-sync"&&(E.status()===404||E.status()===410)&&i.deleteOnMissingUrls.has(c)){await Zt(e,i,o,c,i.deleteOnMissingUrls),n.info(`Removed stale content-sync archive page ${c}`,{url:c,status:E.status(),source:"content-sync-tombstone"}),await d.close();continue}if(r==="content-sync")throw new Error(`Required content-sync route returned HTTP ${E.status()}: ${c}`);n.skip("page",c,E.status(),t.pageDiscoverySources.get(c)),await d.close();continue}m?(n.info(`Rendering without JS execution for ${c}`,{url:c,mode:"no-js"}),await _(`wait for rendered page ${c}`,ue(e),()=>Xi(e,d))):await _(`wait for rendered page ${c}`,ue(e),()=>Yi(e,d)),t.stats.pagesRendered++;let I=await _(`extract rendered assets ${c}`,ue(e),()=>to(e,d,g,n,!m));for(let y of I)J(e,t,y,n,c);let O=[...new Set([...I,...k])],b=F??await _(`capture rendered html ${c}`,ue(e),()=>d.content()),P=r!=="single-url"&&r!=="content-sync"&&!f?zi(e,c,b,n):[];if(r!=="single-url"&&r!=="content-sync"&&!f)for(let y of P)Ke(e,t,y,n,c);await ur(e,c,b,t,n);let C=le(e,c);if(Z(o,e,C),Ce(o,C),i.trackManifest){let y=E?.headers();i.manifest.pages[c]={url:c,outputPath:C,contentType:Jt(y),changeToken:w.changeToken?.supported?w.changeToken.token:null,tokenSource:w.changeToken?.supported?w.changeToken.tokenSource??null:null,sitemapLastmod:ze(t.sitemapLastmodByPage[c])??null,discoveredPages:P,discoveredAssets:O,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},(i.enabled||i.strictTargeted)&&await we(e,i);}}catch(p){if(i.strictTargeted)throw n.error(`Failed required content-sync page ${c}`,{url:c,error:String(p)}),p;try{let g=d?await _(`capture partial html ${c}`,ue(e),()=>d.content()):"";if(g&&g.trim()){await ur(e,c,g,t,n);let f=le(e,c);if(Z(o,e,f),Ce(o,f),i.trackManifest){let m=i.manifest.pages[c]??i.previousManifest.pages[c];i.manifest.pages[c]={url:c,outputPath:f,contentType:m?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:ze(t.sitemapLastmodByPage[c])??m?.sitemapLastmod??null,discoveredPages:m?.discoveredPages?[...m.discoveredPages]:[],discoveredAssets:m?.discoveredAssets?[...m.discoveredAssets]:[],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},(i.enabled||i.strictTargeted)&&await we(e,i);}n.warn(`Saved partial DOM for ${c}`,{url:c,error:String(p)});}}catch(g){n.error(`Could not save partial DOM for ${c}`,{url:c,error:String(g)});}n.error(`Failed page ${c}`,{url:c,error:String(p)});}finally{t.stats.pagesCompleted++,no(t)&&ro(t,n),d&&await _(`close page ${c}`,mt(e),()=>d.close()).catch(p=>{n.warn(`Timed out while closing page ${c}`,{url:c,browserPid:a.pid,error:String(p)});}),l&&await _(`close page context ${c}`,mt(e),()=>l.close()).catch(p=>{n.warn(`Timed out while closing page context for ${c}`,{url:c,browserPid:a.pid,error:String(p)});});}}}finally{await _("close worker browser",mt(e),()=>u.close()).catch(c=>(n.warn("Timed out while closing crawl worker browser",{browserPid:a.pid,error:String(c)}),Gi(u,n,"browser.close timeout")));}}async function ao(e){try{let t=await A.readFile(e),r=(e.endsWith(".gz")?gunzipSync(t):t).toString("utf8").trim();if(!r)return [];try{let s=JSON.parse(r);if(Array.isArray(s))return s;if(s&&typeof s=="object")return [s]}catch{return r.split(/\r?\n/).map(s=>s.trim()).filter(Boolean).map(s=>{try{let i=JSON.parse(s);return i&&typeof i=="object"?i:null}catch{return null}}).filter(s=>s!==null)}return []}catch{return []}}function lr(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function co(e){let t=String(e?.job?.command||"").trim(),n=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:n!=="incremental"}function uo(e){let t=[e?.archivedAt,e?.job?.endedAt,e?.job?.startedAt];for(let n of t){let r=Date.parse(String(n||""));if(Number.isFinite(r))return r}return 0}async function Ar(e){try{let t=await A.readFile(e,"utf8"),n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function dr(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function lo(e,t){let n=Array.isArray(t?.artifacts)?t.artifacts.filter(r=>String(r?.role||"").trim()==="errors"&&String(r?.storedFileName||"").trim()!=="").sort((r,s)=>dr(r)-dr(s)).map(r=>S.join(e,String(r.storedFileName))):[];return [...new Set([...n,S.join(e,"errors.jsonl"),S.join(e,"errors.json"),S.join(e,"errors.jsonl.gz"),S.join(e,"errors.json.gz")])]}async function pr(e){let t=await Ar(S.join(e,"job.json"));for(let n of lo(e,t)){let r=await ao(n);if(r.length>0)return r}return []}async function po(e){let t=S.join(e.logDir,"archive"),n;try{n=await A.readdir(t);}catch{return ""}let r="",s=0;for(let i of n){let o=S.join(t,i);if(!(await A.stat(o).catch(()=>null))?.isDirectory())continue;let a=await Ar(S.join(o,"job.json"));if(!co(a))continue;let c=uo(a);c>=s&&(s=c,r=o);}return r}async function go(e){let t=await po(e),n=t!==""?await pr(t):await pr(e.logDir),r=new Set;for(let s of n)if(lr(s.error)||lr(s.message)){let i=s.url;typeof i=="string"&&i&&r.add(i);}return [...r]}async function fo(e){let t=[];for(let n of e)if(n.startsWith("@")){let r=n.slice(1),s=await A.readFile(r,"utf8");t.push(...s.split(/\r?\n/).map(i=>i.trim()).filter(i=>i&&!i.startsWith("#")));}else t.push(n);return t}async function mo(e){if(!e)throw new Error("Content-sync crawl requires an immutable impact plan.");let t=JSON.parse(await A.readFile(e,"utf8"));return qe(t),t}function ho(e,t){let n;try{n=new URL(e);}catch{return false}return t.archiveFamilies.some(r=>{let s=new URL(r.url);if(n.origin!==s.origin)return false;if(n.toString()===s.toString())return true;if(n.searchParams.has("paged")&&n.pathname===s.pathname)return /^\d+$/.test(n.searchParams.get("paged")||"");let i=s.pathname.replace(/\/+$/,""),o=n.pathname.slice(i.length).replace(/^\/+/,""),u=String(r.paginationBase||"page").replace(/^\/+|\/+$/g,"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return n.pathname.startsWith(`${i}/`)&&new RegExp(`^${u}/\\d+/?$`).test(o)})}function ft(e,t,n){let r=n==="page"?le(e,t):yt(e,t).originalFilePath;return he(e.outputDir,r)}async function Zt(e,t,n,r,s){let i=t.manifest.pages[r];if(!i)return;let o=he(e.outputDir,i.outputPath);if(!o)throw new Error(`Manifest-owned page path escaped output root: ${r}`);let u=S.resolve(i.outputPath);Object.entries(t.manifest.pages).some(([c,l])=>c!==r&&!s.has(c)&&S.resolve(l.outputPath)===u)||(await A.rm(i.outputPath,{force:true}),n.deletedFiles.add(o)),delete t.manifest.pages[r];}function wo(e,t){let n=new Set,r=[...t];for(;r.length>0;){let s=r.shift();if(n.has(s))continue;n.add(s);let i=e.assets[s];for(let o of i?.discoveredAssets??[])try{Me(new URL(o))&&r.push(o);}catch{}}return n}async function yo(e,t,n,r,s){let i=wo(n.previousManifest,s);for(let o of i){if(t.doneSitemaps.has(o))continue;let u=n.previousManifest.assets[o];if(!u)continue;let a=he(e.outputDir,u.outputPath);if(!a)throw new Error(`Manifest-owned sitemap path escaped output root: ${o}`);await A.rm(u.outputPath,{force:true}),r.deletedFiles.add(a),delete n.manifest.assets[o];}await we(e,n);}async function So(e){try{let t=await A.readFile(S.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function Po(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 A.mkdir(e,{recursive:true}),await Promise.all(t.map(async n=>{try{await A.unlink(S.join(e,n));}catch(r){if(r.code!=="ENOENT")throw r}}));}function gr(e,t,n,r,s){let i=H(e,n,e.sourceOrigin,r,"manual-url");i&&(Me(i)?wt(e,t,i.toString(),r,s):q(e,i)?J(e,t,i.toString(),r,s):Se(i)?Ke(e,t,i.toString(),r,s):r.reject("manual-url",i.toString(),"not page/sitemap/asset-like",s));}async function Tr(e=process.argv.slice(2)){let t=[],n=await ne(void 0,{onRemotePublisherConfigDiagnostic:P=>{t.push(P);}}),r=t.at(-1)??null,s=Zs(e),i=s.mode==="content-sync"?await mo(s.contentSyncPlanPath):null;if(s.resumeRewrite&&s.mode!=="full")throw new Error("--resume-rewrite is only supported for full crawl/publish jobs.");let o=[];s.mode==="retry-timeouts"&&(o=await go(n)),s.mode==="single-url"&&(o=await fo(s.urls)),i&&(o=[...i.directRenderUrls,...i.archiveFamilyUrls]);let u=s.crawlMode==="incremental"&&s.mode==="full",a=u&&typeof n.subscriptionType=="string"&&n.subscriptionType.trim()!=="";if(i&&n.subscriptionType!=="PROFESSIONAL"&&n.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let c=(s.mode==="full"||s.mode==="single-url"||s.mode==="content-sync")&&!s.resumeRewrite,l=s.mode!=="full"||s.resumeRewrite||a,d=l?await So(n):{},p=a||s.mode==="single-url"||s.mode==="content-sync"?await ri(n):wr(),g=new Set(o),f=new Set;if(i){for(let P of i.archiveFamilies)if(P.foundPosts===0)for(let C of P.pageUrls)f.add(C);for(let P of Object.keys(p.pages))ho(P,i)&&!g.has(P)&&(o.push(P),f.add(P));}let m={enabled:a,trackManifest:c,manifest:Vt(p),previousManifest:Vt(p),runId:i?.jobId??`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve(),strictTargeted:!!i,requiredUrls:g,deleteOnMissingUrls:f};await Po(n.logDir);let h=new dt(n.logDir,n.logLevel);if(r){let P={status:r.status,virtualAssetBaseUrl:r.virtualAssetBaseUrl,subscriptionType:r.subscriptionType??null,error:r.error,requests:r.requests,source:"remote-publisher-config"};r.status==="loaded"&&r.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(u&&!a){let P="Incremental crawl requires an active remote publisher subscription; refusing to fall back to a destructive full crawl.";throw h.error(P,{requestedMode:s.crawlMode,subscriptionType:n.subscriptionType??null,source:"incremental-subscription-guard"}),await h.flush(),new Error(P)}let w={pageQueue:[],queuedPages:new Set,donePages:new Set,pageDiscoverySources:new Map,assetQueue:[],queuedAssets:new Set,doneAssets:new Set,sitemapQueue:[],queuedSitemaps:new Set,doneSitemaps:new Set,sitemapIndexUrls:new Set,sitemapLeafUrls:new Set,sitemapLastmodByPage:{},assetMap:{...d},assetVariantDigestsByOriginalPath:new Map,stats:{pagesQueued:0,pagesRendered:0,pagesCompleted:0,assetsQueued:0,sitemapsQueued:0,assetsSaved:0,pagesSaved:0}},v=ni();if(await Te(n),await _n(n,{startedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir)}),l||await A.rm(n.outputDir,{recursive:true,force:true}),await A.mkdir(n.outputDir,{recursive:true}),i){let P=new Set([...i.deleteUrls,...m.deleteOnMissingUrls]);for(let C of i.deleteUrls)await Zt(n,m,v,C,P);}if(s.resumeRewrite)h.info("Resuming final rewrite from existing output.",{phase:"rewrite-text",mode:s.mode,crawlMode:s.crawlMode});else {let P=await request.newContext({ignoreHTTPSErrors:n.ignoreHttpsErrors});try{if(h.mark("discovery"),s.mode==="full"?(n.sitemapPaths.forEach(y=>wt(n,w,y,h)),await cr(n,P,w,h,v,m),n.seedPaths.forEach(y=>gr(n,w,y,h,"seed-path")),n.generated404RequestPath&&Ke(n,w,n.generated404RequestPath,h,"generated-404-request-path")):(o.forEach(y=>gr(n,w,y,h,"cli")),i?.sitemapUrls.forEach(y=>wt(n,w,y,h,"content-sync-impact")),await cr(n,P,w,h,v,m,s.mode==="content-sync"),i&&await yo(n,w,m,v,i.sitemapUrls)),h.endMark("discovery",{pages:w.pageQueue.length,assets:w.assetQueue.length,sitemaps:w.sitemapQueue.length}),h.summary(`Queued ${w.pageQueue.length} pages, ${w.assetQueue.length} assets, ${w.sitemapQueue.length} sitemaps.`,{mode:s.mode,crawlMode:s.crawlMode,queuedPages:w.pageQueue.length,queuedAssets:w.assetQueue.length,queuedSitemaps:w.sitemapQueue.length}),s.mode==="retry-timeouts"&&w.pageQueue.length===0&&w.assetQueue.length===0&&w.sitemapQueue.length===0){h.summary("No timed-out URLs were queued. Skipping retry crawl.",{mode:s.mode,crawlMode:s.crawlMode,queuedPages:0,queuedAssets:0,queuedSitemaps:0}),await h.flush();return}h.mark("render-pages");let C=Array.from({length:Math.max(1,n.concurrency)},()=>oo(n,w,h,s.mode,P,m,v));if(await Promise.all(C),h.endMark("render-pages",{pages:w.stats.pagesCompleted}),h.mark("download-assets"),h.progress("Asset download phase started.",{phase:"download-assets",doneAssets:w.doneAssets.size,assetsQueued:w.stats.assetsQueued,assetQueue:w.assetQueue.length}),await Ji(n,P,w,h,m,v),h.endMark("download-assets",{assets:w.doneAssets.size}),m.enabled&&n.maxPages===0&&await pi(n,w,m,h,v),s.mode==="full"){let y=await Wi(n,w,h);for(let x of y)Z(v,n,x);}}finally{await _("dispose crawl request context",mt(n),()=>P.dispose()).catch(C=>{h.warn("Timed out while disposing crawl request context",{error:String(C)});});}}m.trackManifest&&await we(n,m),await A.writeFile(S.join(n.outputDir,"asset-map.json"),JSON.stringify(w.assetMap,null,2),"utf8"),JSON.stringify(d,null,2)!==JSON.stringify(w.assetMap,null,2)&&Z(v,n,S.join(n.outputDir,"asset-map.json"));let k=s.mode==="single-url"||s.mode==="content-sync"?bi(n,w):m.enabled&&!s.resumeRewrite?gi(n,m,v,d,w.assetMap):void 0;h.mark("rewrite-text");let E=s.mode==="single-url"||s.mode==="content-sync"?`Rewriting text files touched by URL crawl: 0/${k?.length??0}`:"Rewriting text files...";h.progress(E,{phase:"rewrite-text",index:0,totalFiles:k?.length,changedTextFiles:0}),await or(E);let F=Date.now(),I=await ct(n,w.assetMap,{files:k,previousAssetMap:d,onStart:({totalFiles:P,workerCount:C})=>{h.info(`Rewrite phase scanning ${P} text files.`,{phase:"rewrite-text",totalFiles:P,workerCount:C});},onProgress:async({index:P,totalFiles:C,changedTextFiles:y,file:x,changed:j})=>{j&&Z(v,n,S.join(n.outputDir,x)),h.checkpoint(`Rewriting text file ${P}/${C}`,{phase:"rewrite-text",index:P,totalFiles:C,changedTextFiles:y,file:x}),h.debug(`${j?"Rewrote":"Checked unchanged"} text file ${P}/${C}: ${x}`,{phase:"rewrite-text",index:P,totalFiles:C,changedTextFiles:y,file:x,changed:j});let U=Date.now();if(!(P===1||P===C||P%50===0||U-F>=5e3))return;F=U;let B=`Rewriting text files: ${P}/${C}`;h.progress(B,{phase:"rewrite-text",index:P,totalFiles:C,changedTextFiles:y,file:x}),await or(B);}});m.trackManifest&&(fi(m,k),await we(n,m)),h.endMark("rewrite-text",{changedTextFiles:I});let O=i?[...v.deletedFiles].sort():m.enabled&&!s.resumeRewrite?await hi(n,w,m,v,h):[],b=[...new Set((k||[]).map(P=>he(n.outputDir,S.isAbsolute(P)?P:S.join(n.outputDir,P))).filter(P=>P!==null))].sort();if(i){let P=[...v.changedFiles].sort(),C=new Set(P),y=new Set(i.directRenderUrls.map($=>ft(n,$,"page")).filter($=>!!$&&C.has($))),x=new Set(i.archiveFamilyUrls.map($=>ft(n,$,"page")).filter($=>!!$&&C.has($))),j=new Set([...w.sitemapLeafUrls].map($=>ft(n,$,"asset")).filter($=>!!$&&C.has($))),U=new Set([...w.sitemapIndexUrls].map($=>ft(n,$,"asset")).filter($=>!!$&&C.has($))),V=new Set([...y,...x,...j,...U]),B=P.filter($=>!V.has($)),K=[...new Set([...i.directRenderUrls,...i.archiveFamilyUrls,...i.sitemapUrls,...w.sitemapLeafUrls,...w.sitemapIndexUrls,...i.deleteUrls].map($=>{let Ye=new URL($);return `${Ye.pathname}${Ye.search}`}))].sort();await qt(n,{schemaVersion:2,generatedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir),runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,changedFiles:P,deletedFiles:O,rewriteTargets:b,consumerId:i.consumerId,fromSequence:i.fromSequence,toSequence:i.toSequence,impactHash:i.impactHash,uploadGroups:{assets:B,content:[...y].sort(),listings:[...x].sort(),sitemapLeaves:[...j].sort(),sitemapIndexes:[...U].reverse()},invalidationPaths:K});}else await qt(n,{schemaVersion:1,generatedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir),runMode:s.mode,crawlMode:s.crawlMode,fullSyncRequired:!(m.enabled&&!s.resumeRewrite),changedFiles:m.enabled&&!s.resumeRewrite?[...v.changedFiles].sort():[],deletedFiles:m.enabled&&!s.resumeRewrite?O:[],rewriteTargets:m.enabled&&!s.resumeRewrite?b:[]});await Bn(n),h.summary(s.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${I} text files.`:`Done. Rendered ${w.stats.pagesRendered} pages, processed ${w.doneSitemaps.size} sitemaps, downloaded ${w.doneAssets.size} assets.`,{mode:s.mode,crawlMode:s.crawlMode,resumeRewrite:s.resumeRewrite,...w.stats,pagesRendered:w.stats.pagesRendered,donePages:w.stats.pagesCompleted,claimedPages:w.donePages.size,doneSitemaps:w.doneSitemaps.size,doneAssets:w.doneAssets.size,changedTextFiles:I}),await h.flush();}function bo(e){let t=e/6e4;if(Number.isInteger(t)&&t>=1)return `${t} minute${t===1?"":"s"}`;let n=Math.ceil(e/1e3);return `${n} second${n===1?"":"s"}`}async function Y(e,t,n){let r=new AbortController,s=globalThis.setTimeout(()=>{r.abort(new Error(`${e} timed out after ${bo(t)}.`));},t);try{return await n({abortController:r,httpOptions:{abortSignal:r.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(s);}}function vo(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function St(e){let t="";for(let r=0;r<e.length;r++){let s=e[r];if(s==="--profile"){let i=(e[r+1]||"").trim();if(!i)throw new Error("Missing value for --profile.");t=i,r+=1;}else if(s.startsWith("--profile=")){let i=s.slice(10).trim();if(!i)throw new Error("Missing value for --profile.");t=i;}}let n=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return t||n||null}function Co(e,t){return {...e,...t??{}}}function Ro(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function Fe(e,t){let n=String(t??e.deploymentTargetOverride??"").trim();if(!vo(e)){if(n)throw new Error(`Deployment target "${n}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:e}}let r=String(n||e.defaultDeploymentProfile||"").trim();if(!r)return {name:null,profile:null,config:e};let s=e.deploymentProfiles?.[r];if(!s)throw new Error(`Unknown deployment profile "${r}". Check the linked WPSuite publisher configuration.`);return {name:r,profile:s,config:{...e,targetOrigin:s.targetOrigin??e.targetOrigin,s3:Co(e.s3,s.s3),cloudFront:Ro(e.cloudFront,s.cloudFront)}}}var Mr="wpsuite-sha256",Fr="wpsuite-normalized-sha256",Fo=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,un=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Do=["SIGINT","SIGTERM"],vt=new Set,Pt=new Map,kr=null;function Oo(e){vt.add(e);let t=false;return ()=>{t||(t=true,vt.delete(e));}}async function jo(){let e=[...vt];e.length!==0&&await Promise.allSettled(e.map(async t=>{vt.delete(t),await A.rm(t,{recursive:true,force:true});}));}function Lo(){if(!(Pt.size>0))for(let e of Do){let t=()=>{kr||(kr=jo().finally(()=>{for(let[n,r]of Pt)process.off(n,r);Pt.clear(),process.exit(1);}));};Pt.set(e,t),process.on(e,t);}}Lo();function Uo(e,t){let n=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(n)return S.resolve(n);let r=t.trim();return r?S.join(S.resolve(r),"crawl-manifest.json"):S.join(S.resolve(e),".crawl-manifest.json")}function Dr(e){return S.normalize(e).split(S.sep).join("/")}function $r(e,t){let n=S.relative(S.resolve(e),S.resolve(t));return !n||n.startsWith("..")||S.isAbsolute(n)?null:Dr(n)}async function qo(e,t,n){let r=Uo(e.outputDir,t),s;try{s=await A.readFile(r,"utf8");}catch(l){return l.code==="ENOENT"?(n.warn("Deploy rewrite guard disabled because the crawl manifest is missing.",{manifestPath:r,source:"deploy-guard"}),null):(n.warn("Deploy rewrite guard disabled because the crawl manifest could not be read.",{manifestPath:r,error:l instanceof Error?l.message:String(l),source:"deploy-guard"}),null)}let i;try{i=JSON.parse(s);}catch(l){return n.warn("Deploy rewrite guard disabled because the crawl manifest is invalid JSON.",{manifestPath:r,error:l instanceof Error?l.message:String(l),source:"deploy-guard"}),null}let o=new Map,u=new Map,a=0,c=0;for(let[l,d]of Object.entries(i.pages||{})){let p=String(d?.outputPath||"").trim(),g=p?$r(e.outputDir,p):null;if(g){let f=typeof d?.contentType=="string"&&d.contentType?d.contentType:null;f&&u.set(g,f);}!p||d?.rewriteComplete===true||g&&(a++,o.has(g)||o.set(g,{kind:"page",sourceUrl:l,outputPath:S.resolve(p),relativePath:g}));}for(let[l,d]of Object.entries(i.assets||{})){let p=String(d?.outputPath||"").trim(),g=d?.isText===true,f=p?$r(e.outputDir,p):null;if(f){let m=typeof d?.contentType=="string"&&d.contentType?d.contentType:null;m&&u.set(f,m);}!p||!g||d?.rewriteComplete===true||f&&(c++,o.has(f)||o.set(f,{kind:"asset",sourceUrl:l,outputPath:S.resolve(p),relativePath:f}));}return {manifestPath:r,byRelativePath:o,contentTypeByRelativePath:u,pendingPages:a,pendingTextAssets:c}}function _o(e){return e&&(un.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 sn(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,n)=>n%2===1?t:_o(t)).join("")}function No(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,n)=>n%2===1?t:un.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 Ct(e,t){return Array.isArray(e)?e.map(n=>Ct(n,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Ct(r,n)])):typeof e!="string"?e:t&&Fo.test(t)?No(e):un.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?sn(e):e}function Bo(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function Ho(e,t){let n=t.trim();if((n.startsWith("{")||n.startsWith("[")||n.startsWith('"'))&&e.startsWith("data-"))try{let s=JSON.parse(n);return JSON.stringify(Ct(s))}catch{}if(e.startsWith("data-")&&/^[A-Za-z0-9+/=]+$/.test(n))try{let s=Buffer.from(n,"base64").toString("utf8"),i=JSON.parse(s),o=JSON.stringify(Ct(i));return Buffer.from(o,"utf8").toString("base64")}catch{}return t}function Wo(e,t){let n=e.toLowerCase();return n==="class"?t.split(/(\s+)/).map((r,s)=>s%2===1?r:sn(r)).join(""):n==="id"||n==="for"||n==="aria-controls"||n==="aria-labelledby"||n==="aria-describedby"||n==="aria-owns"||n==="aria-activedescendant"||n==="name"?sn(t):n==="href"||n==="src"?Bo(t):Ho(n,t)}function zo(e){return e.replace(/<([a-z][^\s/>]*)([^<>]*?)>/gi,(t,n,r)=>{if(n.startsWith("/"))return t;let s=r.replace(/\s([:@a-zA-Z_][-:.a-zA-Z0-9_]*?)=(['"])([\s\S]*?)\2/g,(i,o,u,a)=>{let c=Wo(o,a);return ` ${o}=${u}${c}${u}`});return `<${n}${s}>`})}function rn(e){let t=S.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(S.basename(e))}function bt(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function Qo(e,t,n,r){let s=new Map,i,o=0;do{o++;let u=await Y(`S3 list objects page ${o} for s3://${t}/${n||""}`,3e5,({httpOptions:a})=>e.send(new ListObjectsV2Command({Bucket:t,Prefix:n||void 0,ContinuationToken:i}),a));for(let a of u.Contents||[]){if(!a.Key)continue;let c=(a.ETag||"").replace(/^"|"$/g,"").toLowerCase(),l=Number(a.Size??0);s.set(a.Key,{etag:c,size:l});}i=u.NextContinuationToken,r.debug(`Listed S3 keys page ${o}: ${s.size} keys so far`);}while(i);return s}async function Jo(e,t,n,r){if(r.has(n))return r.get(n)??null;try{let s=await Y(`S3 head object ${n}`,3e5,({httpOptions:o})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),o)),i={etag:(s.ETag||"").replace(/^"|"$/g,"").toLowerCase(),size:Number(s.ContentLength??0)};return r.set(n,i),i}catch{return r.set(n,null),null}}async function Vo(e,t,n,r){let s=[...new Set(Array.from(n).filter(Boolean))];if(s.length===0)return r.info("No explicitly tombstoned S3 objects to delete."),[];r.info(`Deleting ${s.length} explicitly tombstoned S3 object(s)\u2026`);for(let i=0;i<s.length;i+=1e3){let o=s.slice(i,i+1e3);if(o.length===0)continue;let u=await Y(`S3 delete objects batch ${Math.floor(i/1e3)+1}`,3e5,({httpOptions:a})=>e.send(new DeleteObjectsCommand({Bucket:t,Delete:{Objects:o.map(c=>({Key:c}))}}),a));if(u.Errors&&u.Errors.length>0){let a=u.Errors.map(c=>`${c.Key||"(unknown)"}: ${c.Code||"DeleteFailed"}`);throw new Error(`S3 reported ${a.length} object deletion error(s): ${a.join(", ")}`)}r.info(`Deleted batch of ${o.length} object(s).`);for(let a of o)r.debug(` deleted: ${a}`);}return s}function Ko(e){return createHash("md5").update(e).digest("hex")}function Er(e){return createHash("sha256").update(e).digest("hex")}function on(e){return createHash("sha256").update(zo(e.toString("utf8"))).digest("hex")}async function Go(e,t,n,r){if(r.has(n))return r.get(n)??null;try{let o=((await Y(`S3 head object metadata ${n}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),u))).Metadata?.[Mr]||"").trim().toLowerCase()||null;return r.set(n,o),o}catch{return r.set(n,null),null}}async function Zo(e,t,n,r,s){if(r.has(n))return r.get(n)??null;try{let o=((await Y(`S3 head object normalized metadata ${n}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),u))).Metadata?.[Fr]||"").trim().toLowerCase();if(o)return r.set(n,o),o}catch{return r.set(n,null),null}if(s.has(n)){let i=s.get(n)??null;return r.set(n,i),i}try{let o=await(await Y(`S3 get object ${n}`,3e5,({httpOptions:a})=>e.send(new GetObjectCommand({Bucket:t,Key:n}),a))).Body?.transformToByteArray(),u=o?on(Buffer.from(o)):null;return s.set(n,u),r.set(n,u),u}catch{return s.set(n,null),r.set(n,null),null}}function Yo(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function Xo(e,t){let n=e,r=Object.entries(t).sort((s,i)=>i[0].length-s[0].length);for(let[s,i]of r)s&&(n=n.split(s).join(i));return n}async function ea(e,t,n,r){let s=S.join(e,"asset-map.json"),i;try{i=await A.readFile(s,"utf8");}catch(a){if(a.code==="ENOENT")return;throw a}let o=JSON.parse(i);if(!o||typeof o!="object")return;let u=Object.fromEntries(Object.entries(o).map(([a,c])=>{let l=String(c??"");return t.urlRewriteMode==="absolute"&&t.targetOrigin&&n.targetOrigin&&t.targetOrigin!==n.targetOrigin&&(l=l.split(t.targetOrigin).join(n.targetOrigin)),l=Xo(l,r),[a,l]}));await A.writeFile(s,JSON.stringify(u,null,2),"utf8");}async function ta(e,t,n,r,s,i){let o=e.targetOrigin!==t.targetOrigin,u=Object.keys(r).length>0;if(!n||!o&&!u)return {outputDir:e.outputDir,cleanup:async()=>{}};if(o&&e.urlRewriteMode!=="absolute")throw new Error(`Deployment profile "${n}" changes targetOrigin, but the base crawl output must use urlRewriteMode "absolute" for multi-target redeploys.`);let a=S.join(S.dirname(e.outputDir),`.deploy-profile-${Yo(n)}-${Date.now()}`),c=Oo(a);s.info(`Preparing deployment profile "${n}" from existing crawl output to ${a}...`);try{if(await A.rm(a,{recursive:!0,force:!0}),i){await A.mkdir(a,{recursive:!0});for(let g of i){let f=S.join(e.outputDir,g),m=S.join(a,g);await A.mkdir(S.dirname(m),{recursive:!0}),await A.copyFile(f,m);}}else await A.cp(e.outputDir,a,{recursive:!0});let l={...e,sourceOrigin:e.targetOrigin,targetOrigin:t.targetOrigin,extraReplacements:r,outputDir:a},d=1;s.info(`Rewriting text files for deployment profile "${n}"...`);let p=await ct(l,{},{files:i,onStart:({totalFiles:g,workerCount:f})=>{d=f,s.info(`Rewriting ${g} text file(s) for deployment profile "${n}" with ${f} worker(s).`);},onProgress:({index:g,totalFiles:f,changedTextFiles:m,file:h,changed:w})=>{let k=`Rewriting [${g}/${f}] ${h} (${w?"rewrote":"checked"}; ${m} changed so far)`;f<=200||g<=5||g%10===0||g===f?(s.progress(k,{file:h,index:g,totalFiles:f,changed:w,changedTextFiles:m,workerCount:d}),s.info(k)):s.debug(k);}});return await ea(a,e,t,r),s.info(`Prepared deployment profile "${n}" in ${a} (${p} rewritten text file(s)).`),{outputDir:a,cleanup:async()=>{c(),await A.rm(a,{recursive:!0,force:!0});}}}catch(l){throw s.error(`Failed to prepare deployment profile "${n}" temporary output.`,{tempDir:a,outputDir:e.outputDir,error:l instanceof Error?l.message:String(l),...l instanceof Error&&l.stack?{stack:l.stack}:{}}),await A.rm(a,{recursive:true,force:true}).catch(()=>{}),c(),await s.flush().catch(()=>{}),l}}async function Or(e=process.argv.slice(2)){let t=await ne(),n=St(e),r=Fe(t,n),s=S.resolve(r.config.logDir||"logs"),i=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",o=i?S.join(S.resolve(i),"deploy-diff.json"):"",u=new $e(s,"deploy.log.jsonl",r.config.logLevel??"info"),a=r.profile?.extraReplacements??{},c=async()=>{};try{let l=await it(t);if(e.includes("--content-sync")&&l?.schemaVersion!==2)throw new Error("Content-sync deployment requires a valid schema-2 targeted deploy plan.");let p=await Nn(t);if(p)throw new Error(`Deployment blocked: the crawl started at ${p.startedAt} did not complete its final rewrite. Run a successful crawl or resume the rewrite before deploying.`);let g=await ta(t,r.config,r.name,a,u,l?.schemaVersion===2?l.changedFiles:void 0);c=g.cleanup;let f={...r.config,outputDir:g.outputDir},m=f.s3SyncMode??"sdk-upload-delete";if(l?.schemaVersion===2&&l.deletedFiles.length>0&&m!=="sdk-upload-delete")throw new Error("Content-sync tombstones require the sdk-upload-delete S3 sync mode.");let h=l?.schemaVersion!==2&&g.outputDir!==t.outputDir&&(t.targetOrigin!==r.config.targetOrigin||Object.keys(a).length>0),w=!!l&&!l.fullSyncRequired&&!h;if(l?.schemaVersion===2&&!w)throw new Error("Content-sync deployment cannot widen into a full-output deployment.");r.name&&u.info(`Using deployment profile: ${r.name}`),u.info(`Starting deploy \u2014 s3://${f.s3.bucket}/${f.s3.prefix||""} (region: ${f.s3.region})`),u.info(`S3 sync mode: ${m}`),l&&l.fullSyncRequired?u.info("Deploy plan requests a full sync; scanning the whole output tree."):l&&h?u.info("Ignoring incremental deploy plan because deployment-profile rewrites require a full sync."):w&&u.info(`Using incremental deploy plan: ${l.changedFiles.length} changed file(s), ${l.deletedFiles.length} deleted file(s).`),u.mark("deploy");let v=new S3Client({region:f.s3.region}),k=g.outputDir===t.outputDir?await qo(t,i,u):null,E=l?.schemaVersion===2?[...l.uploadGroups.assets,...l.uploadGroups.content,...l.uploadGroups.listings,...l.uploadGroups.sitemapLeaves,...l.uploadGroups.sitemapIndexes]:l?.changedFiles??[];if(l?.schemaVersion===2){let T=[...new Set(E)],W=[...new Set(l.changedFiles)];if(T.length!==W.length||W.some(R=>!T.includes(R)))throw new Error("Content-sync deploy-plan upload groups do not cover the exact changed-file set.")}let F=w?(await Promise.all(E.map(async T=>{try{return (await A.stat(S.join(f.outputDir,T))).isFile()?T:null}catch{if(l?.schemaVersion===2)throw new Error(`Content-sync planned upload is missing: ${T}`);return null}}))).filter(T=>T!==null):await vs(["**/*"],{cwd:f.outputDir,onlyFiles:!0,dot:!0}),I=[],O=[],b=F.filter(T=>{let W=k?.byRelativePath.get(Dr(T));if(!W)return !0;let R=bt(f.s3.prefix,T);return I.push(T),O.push(R),u.reject(W.kind,W.sourceUrl||T,"rewrite not completed; deploy upload blocked","deploy-guard",{file:T,key:R,outputPath:W.outputPath,manifestPath:k?.manifestPath}),!1}),P=new Set((w?b:F).map(T=>bt(f.s3.prefix,T)));k&&(k.pendingPages>0||k.pendingTextAssets>0)&&u.info(`Deploy rewrite guard loaded ${k.pendingPages} pending page(s) and ${k.pendingTextAssets} pending text asset(s) from crawl manifest.`,{manifestPath:k.manifestPath,pendingPages:k.pendingPages,pendingTextAssets:k.pendingTextAssets,source:"deploy-guard"}),I.length>0&&u.warn(`Deploy rewrite guard blocked ${I.length} file(s) from upload because final crawl rewrite is incomplete.`,{rejected:I.length,manifestPath:k?.manifestPath,source:"deploy-guard"}),w?u.info(`Using ${b.length} eligible planned changed file(s) from deploy plan for upload${I.length>0?` (${I.length} blocked by deploy rewrite guard)`:""}.`):u.info(`Found ${F.length} file(s) in output directory "${f.outputDir}"${I.length>0?`; ${b.length} remain eligible for upload after deploy rewrite guard filtering`:""}.`),u.progress("Deploy preflight: comparing local output with remote S3 state.",{phase:"deploy",mode:m,totalFiles:b.length,scannedFiles:F.length,rejected:I.length,deploymentProfile:r.name||"",s3Bucket:f.s3.bucket,s3Prefix:f.s3.prefix||"",targetedPlan:w,deployGuardEnabled:g.outputDir===t.outputDir});let C=0,y=0,x=0,j=[],U=[],V=[],B=[],K=[],$=new Map,Ye=new Map,Br=new Map,Hr=new Map,Wr=new Map;w||(u.info("Listing existing S3 objects to detect unchanged files..."),$=await Qo(v,f.s3.bucket,f.s3.prefix,u),u.info(`Found ${$.size} existing key(s) in S3.`));let zr=async T=>$.has(T)?$.get(T)??null:w?Jo(v,f.s3.bucket,T,Ye):null;for(let T of b){let W=S.join(f.outputDir,T),R=bt(f.s3.prefix,T),ee=k?.contentTypeByRelativePath.get(T),Oe=ee&&ee!=="application/octet-stream"?ee:Mo.lookup(T)||ee||"application/octet-stream",Qr=rn(T)?f.s3.htmlCacheControl:f.s3.assetCacheControl,L=C+y+x+1;b.length<=200||L<=5||L%10===0||L===b.length?(u.progress(`Uploading [${L}/${b.length}] ${R} (${Oe})`,{file:T,key:R,index:L,totalFiles:b.length,contentType:Oe,mode:m}),u.info(`Uploading [${L}/${b.length}] ${R} (${Oe})`)):u.debug(`Uploading [${L}/${b.length}] ${R} (${Oe})`);try{let te=await A.readFile(W),je=await zr(R),Le=null,Ie=null;if(je){let It=te.byteLength;if(je.size===It){let Xe=je.etag.includes("-");if(je.etag!==""&&!Xe){let Jr=Ko(te);if(je.etag===Jr){y++,b.length<=200||y<=5||y%25===0?(u.progress(`Skipped unchanged [${L}/${b.length}] ${R}`,{file:T,key:R,index:L,totalFiles:b.length,uploaded:C,skipped:y,failed:x,mode:m,reason:"etag-md5-match"}),u.info(`Skipped unchanged [${L}/${b.length}] ${R}`)):u.debug(`Skipped unchanged [${L}/${b.length}] ${R}`),U.push(R);continue}}Le=Er(te);let hn=await Go(v,f.s3.bucket,R,Br);if(hn&&hn===Le){y++,b.length<=200||y<=5||y%25===0?(u.progress(`Skipped unchanged [${L}/${b.length}] ${R}`,{file:T,key:R,index:L,totalFiles:b.length,uploaded:C,skipped:y,failed:x,mode:m,reason:"metadata-sha256-match"}),u.info(`Skipped unchanged [${L}/${b.length}] ${R}`)):u.debug(`Skipped unchanged [${L}/${b.length}] ${R}`),U.push(R);continue}}if(rn(T)){Ie=on(te);let Xe=await Zo(v,f.s3.bucket,R,Hr,Wr);if(Xe&&Xe===Ie){y++,b.length<=200||y<=5||y%25===0?(u.progress(`Skipped semantically unchanged [${L}/${b.length}] ${R}`,{file:T,key:R,index:L,totalFiles:b.length,uploaded:C,skipped:y,failed:x,mode:m,reason:"normalized-html-match"}),u.info(`Skipped semantically unchanged [${L}/${b.length}] ${R}`)):u.debug(`Skipped semantically unchanged [${L}/${b.length}] ${R}`),U.push(R);continue}}}Le=Le??Er(te),Ie=Ie??(rn(T)?on(te):null),await Y(`S3 upload ${R}`,9e5,({abortController:It})=>new Upload({client:v,abortController:It,params:{Bucket:f.s3.bucket,Key:R,Body:te,ContentType:Oe,CacheControl:Qr,Metadata:{[Mr]:Le,...Ie?{[Fr]:Ie}:{}}}}).done()),C++,j.push(R),(C%25===0||C===b.length)&&(u.progress(`Uploaded ${C}/${b.length} file(s)\u2026`,{uploaded:C,skipped:y,failed:x,totalFiles:b.length,mode:m}),u.info(`Uploaded ${C}/${b.length} file(s)\u2026`));}catch(te){x++,V.push(R),u.error(`Failed to upload ${R}: ${te.message}`,{key:R,error:String(te)});}}if(u.info(`Upload complete: ${C} uploaded, ${y} skipped unchanged, ${O.length} rejected by guard, ${x} failed.`),V.length>0||O.length>0)throw new Error(`Deployment stopped before deletion because ${V.length} upload(s) failed and ${O.length} upload(s) were rejected.`);if(m==="sdk-upload-delete"){let T=new Set((l?.deletedFiles??[]).map(R=>bt(f.s3.prefix,R))),W=[...T].filter(R=>!P.has(R));if(!w&&(K=[...$.keys()].filter(ee=>!P.has(ee)).filter(ee=>!T.has(ee)),K.length>0)){u.warn(`Protected ${K.length} remote-only S3 object(s) from deletion because the crawl did not provide explicit tombstones.`,{protected:K.length,source:"deploy-delete-guard"});for(let ee of K)u.debug(` protected remote-only object: ${ee}`);}B=await Vo(v,f.s3.bucket,w?W:W.filter(R=>$.has(R)),u);}else u.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion.");o&&(await A.mkdir(S.dirname(o),{recursive:!0}),await A.writeFile(o,JSON.stringify({generatedAt:new Date().toISOString(),mode:m,summary:{totalFiles:F.length,eligibleFiles:b.length,uploaded:j.length,skipped:U.length,rejected:O.length,failed:V.length,deleted:B.length,protected:K.length,...r.name?{profile:r.name}:{}},uploadedKeys:j,skippedKeys:U,rejectedKeys:O,failedKeys:V,deletedKeys:B,protectedRemoteOnlyKeys:K},null,2),"utf8")),l?.schemaVersion!==2&&await Te(t),u.endMark("deploy"),await u.flush();}finally{await c().catch(()=>{});}}function ra(e){return String(e||"").replace(/\\/g,"/").replace(/^\/+|\/+$/g,"")}function sa(e,t){let n=e;n.endsWith("/")?n+="index.html":S.posix.basename(n).includes(".")||(n+="/index.html");let r=ra(t);return r?`/${r}${n}`.replace(/\/{2,}/g,"/"):n}function jr(e,t){let n=new Set;for(let r of e){let s=new URL(r,"https://content-sync.invalid");if(s.origin!=="https://content-sync.invalid")continue;let i=`${s.pathname}${s.search}`;n.add(i),n.add(`${sa(s.pathname,t)}${s.search}`);}return [...n].sort()}function ca(){let e=String(process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"").trim();return e?S.join(S.resolve(e),"content-sync-invalidation.json"):""}async function ln(e,t){if(!e)return;await A.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await A.writeFile(n,JSON.stringify({...t,updatedAt:new Date().toISOString()},null,2),"utf8"),await A.rename(n,e);}async function ua(e,t,n,r){if(!e)return null;try{let s=JSON.parse(await A.readFile(e,"utf8"));if(s.schemaVersion!==1||s.distributionId!==t||s.impactHash!==n||!Array.isArray(s.batches))throw new Error("Content-sync invalidation state does not match the deploy plan.");let i=s.batches.flatMap(o=>o.paths);return i.length!==r.length||i.some((o,u)=>o!==r[u])?null:s}catch(s){if(s.code==="ENOENT")return null;throw s}}function la(e,t=3e3){let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}async function pn(e=process.argv.slice(2)){let t=await ne(),n=St(e),r=Fe(t,n),s=r.config,i=new $e(s.logDir||"logs","invalidate.log.jsonl",s.logLevel??"info"),o=e.includes("--content-sync"),u=await it(t);if(o&&u?.schemaVersion!==2)throw new Error("Content-sync invalidation requires a valid schema-2 targeted deploy plan.");if(r.name&&i.info(`Using deployment profile: ${r.name}`),!s.cloudFront.distributionId){i.info("No CloudFront distributionId configured; skipping invalidation."),await i.flush();return}let a=u?.schemaVersion===2?u.invalidationPaths:s.cloudFront.invalidationPaths.length>0?s.cloudFront.invalidationPaths:["/*"],c=u?.schemaVersion===2?jr(a,s.s3.prefix||""):a;if(u?.schemaVersion===2&&c.some(f=>f==="/*"))throw new Error("Content-sync cannot use a whole-distribution invalidation.");if(c.length===0){i.info("The targeted deploy plan has no CloudFront paths to invalidate."),await i.flush();return}let l=s.cloudFront.distributionId,d=new CloudFrontClient({region:"us-east-1",maxAttempts:5});if(i.mark("invalidate"),u?.schemaVersion!==2){let f=`smartcloud-static-publisher-${Date.now()}`;await Y(`CloudFront invalidation for distribution ${l}`,3e5,({httpOptions:m})=>d.send(new CreateInvalidationCommand({DistributionId:l,InvalidationBatch:{CallerReference:f,Paths:{Quantity:c.length,Items:c}}}),m)),i.endMark("invalidate"),await i.flush();return}let p=ca(),g=await ua(p,l,u.impactHash,c);if(!g){let f=createHash("sha256").update(JSON.stringify(c)).digest("hex");g={schemaVersion:1,distributionId:l,impactHash:u.impactHash,updatedAt:new Date().toISOString(),batches:la(c).map((m,h)=>({index:h,callerReference:`wpsuite-content-sync-${u.impactHash.slice(0,24)}-${f.slice(0,24)}-${h}`,paths:m,invalidationId:null,status:"pending"}))},await ln(p,g);}for(let f of g.batches){if(!f.invalidationId){let m=await Y(`CloudFront targeted invalidation batch ${f.index+1}`,3e5,({httpOptions:w})=>d.send(new CreateInvalidationCommand({DistributionId:l,InvalidationBatch:{CallerReference:f.callerReference,Paths:{Quantity:f.paths.length,Items:f.paths}}}),w)),h=String(m.Invalidation?.Id||"").trim();if(!h)throw new Error("CloudFront did not return an invalidation ID.");f.invalidationId=h,f.status="created",await ln(p,g);}await waitUntilInvalidationCompleted({client:d,maxWaitTime:900,minDelay:2,maxDelay:15},{DistributionId:l,Id:f.invalidationId}),f.status="completed",await ln(p,g),i.info(`CloudFront invalidation batch ${f.index+1}/${g.batches.length} completed.`,{invalidationId:f.invalidationId,pathCount:f.paths.length});}i.endMark("invalidate"),await i.flush();}var qr=["claimed","impact-planned","rendered","deployed","invalidated","verified","acknowledged"];function fn(){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 S.resolve(e)}function De(e,t){return qr.indexOf(e)>=qr.indexOf(t)}async function pe(e,t,n,r,s={}){let i={timestamp:new Date().toISOString(),eventType:t,status:t.endsWith("failed")?"failed":"success",actorSource:"content-sync",jobId:n.id||"",command:"content-sync",message:r,details:s};await A.mkdir(e,{recursive:true}),await A.appendFile(S.join(e,"audit-events.jsonl"),`${JSON.stringify(i)}
|
|
11
|
+
`,"utf8");}function pa(e){return Ue({postTypes:e.postTypes??[],listingPaths:e.listingPaths??[],includePostTypeArchives:e.includePostTypeArchives,includeTaxonomyArchives:e.includeTaxonomyArchives,includeAuthorArchives:e.includeAuthorArchives,includeDateArchives:e.includeDateArchives,includePostsPage:e.includePostsPage,includeSitemapChain:e.includeSitemapChain})}function ga(e,t){let n=(e.scheduler?.rules??[]).find(r=>r.command==="content-sync"&&r.id===t);if(!n)throw new Error(`Content-sync scheduler rule not found: ${t}`);if(n.enabled===false)throw new Error(`Content-sync scheduler rule is disabled: ${t}`);return n}async function mn(e,t){if(e.subscriptionType!=="PROFESSIONAL"&&e.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let n=pa(t),r=Fe(e,t.deploymentProfile),s=r.name||"",i=Sn(e.sourceOrigin,String(t.id||""),n),o=Pn({sourceOrigin:e.sourceOrigin,targetOrigin:r.config.targetOrigin,deploymentProfile:s,s3Bucket:r.config.s3.bucket,s3Prefix:r.config.s3.prefix,cloudFrontDistributionId:r.config.cloudFront.distributionId,urlRewriteMode:r.config.urlRewriteMode,extraReplacements:r.profile?.extraReplacements??{}}),u=bn({siteId:e.wpsuite?.siteSettings?.siteId,accountId:e.wpsuite?.siteSettings?.accountId,sourceOrigin:e.sourceOrigin,ruleId:String(t.id||""),targetFingerprint:o}),a=`content-sync:${String(t.id||"")}:${oe({scopeFingerprint:i,targetFingerprint:o}).slice(0,32)}`,c=new tt({sourceOrigin:e.sourceOrigin,runtimeToken:String(e.wpsuite?.runtimeToken||""),ignoreHttpsErrors:e.ignoreHttpsErrors}),l=await c.releaseFingerprint(),d=yn({wordpressFingerprint:l,targetFingerprint:o,sourceOrigin:e.sourceOrigin,sitemapPaths:e.sitemapPaths,blockedPathPrefixes:e.blockedPathPrefixes,assetPathPrefixes:e.assetPathPrefixes,noJavaScriptRenderPathPrefixes:e.noJavaScriptRenderPathPrefixes,urlRewriteMode:e.urlRewriteMode});return {rule:t,scope:n,deployment:r,deploymentProfile:s,scopeFingerprint:i,targetFingerprint:o,consumerId:u,coalesceKey:a,client:c,releaseFingerprint:d}}async function fa(e){let t=fn(),n=nt(t),r=await ne(),s=(r.scheduler?.rules??[]).filter(c=>c.command==="content-sync"&&c.enabled!==false);if(s.length===0)return 0;let i=await $t(n),o=await rt(n),u=await kt(n),a=0;for(let c of s){let l=await mn(r,c),d=u.entries[l.coalesceKey];if(!d||d.releaseJobId!==e||d.scopeFingerprint!==l.scopeFingerprint||d.targetFingerprint!==l.targetFingerprint||d.releaseFingerprint!==l.releaseFingerprint)throw new Error(`The normal release has no matching pre-crawl content-sync cutoff for rule ${String(c.id||"")}.`);let p=oe({releaseJobId:e,releaseFingerprint:l.releaseFingerprint,scopeFingerprint:l.scopeFingerprint,targetFingerprint:l.targetFingerprint,sequence:d.sequence}),g=await l.client.establishBaseline({consumerId:l.consumerId,scopeFingerprint:l.scopeFingerprint,baselineId:p,postTypes:l.scope.postTypes,sequence:d.sequence}),f={schemaVersion:1,ruleId:String(c.id||""),consumerId:l.consumerId,coalesceKey:l.coalesceKey,scopeFingerprint:l.scopeFingerprint,targetFingerprint:l.targetFingerprint,releaseFingerprint:l.releaseFingerprint,baselineId:p,deploymentProfile:l.deploymentProfile,committedSequence:g.committedSequence,releaseJobId:e,verifiedAt:new Date().toISOString()};i.entries[l.coalesceKey]=f;let m=o.rules[l.coalesceKey];o.rules[l.coalesceKey]={ruleId:String(c.id||""),consumerId:l.consumerId,coalesceKey:l.coalesceKey,committedSequence:g.committedSequence,observedHeadSequence:g.headSequence,lag:Math.max(0,g.headSequence-g.committedSequence),lastSuccessfulJobId:m?.lastSuccessfulJobId||e,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:g.headSequence>g.committedSequence,retryAttempt:0,nextRetryAt:null,lastError:null,baselineStatus:"ready",baselineReason:null};let h=await En(n,l.coalesceKey);await pe(t,"content-sync-baseline-established",{id:e},"A normal release established a verified content-sync baseline.",{ruleId:c.id,consumerId:l.consumerId,committedSequence:g.committedSequence,supersededCurrent:h}),a++;}return await xn(n,i),await st(n,o),await A.rm(n.releaseCutoff,{force:true}),a}async function ma(e){let t=fn(),n=nt(t),r=await ne(),s=(r.scheduler?.rules??[]).filter(u=>u.command==="content-sync"&&u.enabled!==false);if(s.length===0)return 0;let i=await kt(n),o=0;for(let u of s){let a=await mn(r,u),c=Object.values(i.entries).find(p=>p.releaseJobId===e&&p.ruleId===String(u.id||""));if(c){if(c.coalesceKey===a.coalesceKey&&c.scopeFingerprint===a.scopeFingerprint&&c.targetFingerprint===a.targetFingerprint&&c.releaseFingerprint===a.releaseFingerprint){o++;continue}throw new Error(`The normal release scope changed after its journal cutoff was captured for rule ${String(u.id||"")}. Start a new normal publish instead of resuming this release.`)}let l=await a.client.unboundHead(a.scope.postTypes),d={schemaVersion:1,releaseJobId:e,ruleId:String(u.id||""),coalesceKey:a.coalesceKey,scopeFingerprint:a.scopeFingerprint,targetFingerprint:a.targetFingerprint,releaseFingerprint:a.releaseFingerprint,sequence:l.headSequence,capturedAt:new Date().toISOString()};i.entries[a.coalesceKey]=d,await pe(t,"content-sync-release-cutoff-captured",{id:e},"A normal release captured its pre-crawl content-sync journal cutoff.",{ruleId:u.id,consumerId:a.consumerId,sequence:l.headSequence}),o++;}return await In(n,i),o}async function ha(e,t){let n=JSON.parse(await A.readFile(S.join(e,"current-run.json"),"utf8"));if(n.id!==t||n.command!=="content-sync"||!String(n.ruleId||"").trim())throw new Error("The active queue job is not the requested content-sync job.");return n}async function gn(e,t,n=0){let r=e.protocol==="https:"?Rn:Yr,s=e.protocol==="https:"?new Rn.Agent({rejectUnauthorized:!t}):void 0;return new Promise((i,o)=>{let u=r.get(e,{agent:s,timeout:3e4,headers:{"user-agent":"WP-Suite-Content-Sync/1"}},a=>{let c=a.statusCode??500,l=a.headers.location;if(c>=300&&c<400&&l&&n<5){a.resume(),gn(new URL(l,e),t,n+1).then(i,o);return}let d=[],p=0;a.on("data",g=>{p+=g.byteLength,p<=1048576&&d.push(g);}),a.on("error",o),a.on("end",()=>i({status:c,body:Buffer.concat(d).toString("utf8")}));});u.on("timeout",()=>u.destroy(new Error(`Verification timed out: ${e}`))),u.on("error",o);})}function _r(e){let t=new URL(e);return t.hash="",t.href}function wa(e){let t=new Map,n=new Map,r=i=>{t.set(_r(i),i);},s=i=>{if(!i)return;let o=_r(i);t.has(o)||n.set(o,i);};for(let i of e.archiveFamilies)if(i.foundPosts===0)for(let o of i.pageUrls)r(o);for(let i of e.deleteUrls)r(i);s(e.directRenderUrls[0]);for(let i of e.archiveFamilies)s(i.pageUrls[0]),s(i.pageUrls.at(-1));for(let i of e.sitemapUrls)s(i);return {expectedAvailable:[...n.values()],expectedMissing:[...t.values()]}}async function ya(e,t,n){let r=t.deployment.config.targetOrigin;if(!/^https?:\/\//i.test(r))throw new Error("Content-sync verification requires an absolute HTTP(S) target origin.");let s=wa(n);for(let i of s.expectedAvailable){let o=new URL(i),u=new URL(`${o.pathname}${o.search}`,r),a=await gn(u,e.ignoreHttpsErrors);if(a.status<200||a.status>=400)throw new Error(`Content-sync verification failed (${a.status}): ${u}`)}for(let i of s.expectedMissing.slice(0,10)){let o=new URL(i),u=new URL(`${o.pathname}${o.search}`,r),a=await gn(u,e.ignoreHttpsErrors);if(a.status>=200&&a.status<300)throw new Error(`Deleted content is still publicly available: ${u}`)}}async function Sa(e){let t=await A.readFile(e.candidateManifest,"utf8");JSON.parse(t);let n=`${e.trustedManifest}.${process.pid}.tmp`;await A.writeFile(n,t,"utf8"),await A.rename(n,e.trustedManifest);}async function Pa(e,t){try{let n=JSON.parse(await A.readFile(e.candidateManifest,"utf8"));if([...Object.values(n.pages??{}),...Object.values(n.assets??{})].some(s=>s?.lastSeenRunId===t))return "resumed"}catch(n){if(n.code!=="ENOENT")throw new Error(`The content-sync candidate manifest is invalid: ${n instanceof Error?n.message:String(n)}`,{cause:n})}return await A.copyFile(e.trustedManifest,e.candidateManifest).catch(n=>{throw new Error(`A trusted crawl manifest is required before content-sync: ${n instanceof Error?n.message:String(n)}`,{cause:n})}),"initialized"}async function Re(e,t,n,r,s={},i=0){t.phase=n,await An(e,t),await $n(e,{schemaVersion:1,jobId:t.jobId,phase:n,completedItems:r,totalItems:r,attempt:i,updatedAt:new Date().toISOString(),details:s}),await pe(S.dirname(e.state),"content-sync-checkpoint",{id:t.jobId},`Content-sync checkpoint completed: ${n}.`,{phase:n,completedItems:r,totalItems:r,attempt:i,...s});}async function ba(e){let t=fn(),n=nt(t),r=await ha(t,e),s=await ne(),i=ga(s,String(r.ruleId)),o=await mn(s,i);if(r.coalesceKey&&r.coalesceKey!==o.coalesceKey)throw new Error("Queued content-sync demand no longer matches the active rule scope.");let a=(await $t(n)).entries[o.coalesceKey];if(!a||a.scopeFingerprint!==o.scopeFingerprint||a.targetFingerprint!==o.targetFingerprint||a.releaseFingerprint!==o.releaseFingerprint)throw await pe(t,"content-sync-baseline-rejected",r,"Content-sync requires a new verified full or incremental release baseline.",{ruleId:i.id,reason:a?"mismatch":"missing"}),new Error("Content-sync baseline is missing or stale. Run a successful normal publish first.");let c=await Et(n),l=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:a.baselineId,postTypes:o.scope.postTypes});if(c&&c.jobId!==r.id)throw new Error("Another immutable content-sync range is still active.");if(c||(c={schemaVersion:1,jobId:r.id,ruleId:String(i.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,scopeFingerprint:o.scopeFingerprint,targetFingerprint:o.targetFingerprint,baselineId:a.baselineId,fromSequence:l.committedSequence,toSequence:l.headSequence,phase:"claimed",impactHash:null,startedAt:new Date().toISOString(),updatedAt:new Date().toISOString()},await Re(n,c,"claimed",0,{fromSequence:c.fromSequence,toSequence:c.toSequence}),await pe(t,"content-sync-range-claimed",r,"Content-sync claimed a closed journal range.",{fromSequence:c.fromSequence,toSequence:c.toSequence})),c.fromSequence===c.toSequence){let m=await rt(n);m.rules[o.coalesceKey]={ruleId:String(i.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,committedSequence:c.toSequence,observedHeadSequence:l.headSequence,lag:Math.max(0,l.headSequence-c.toSequence),lastSuccessfulJobId:r.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:false,retryAttempt:0,nextRetryAt:null,lastError:null},await st(n,m),await Mt(n);return}let d=await Tn(n);if(!De(c.phase,"impact-planned")){let m=await o.client.events({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:a.baselineId,postTypes:o.scope.postTypes,afterSequence:c.fromSequence,throughSequence:c.toSequence}),h=Tt({events:m,scope:o.scope,sourceOrigin:s.sourceOrigin}),w=await o.client.resolveImpactFamilies(h);d=Cn({jobId:r.id,ruleId:String(i.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,scopeFingerprint:o.scopeFingerprint,targetFingerprint:o.targetFingerprint,baselineId:a.baselineId,sourceOrigin:s.sourceOrigin,scope:o.scope,fromSequence:c.fromSequence,toSequence:c.toSequence,events:m,resolvedArchiveFamilies:w,sitemapUrls:s.sitemapPaths}),await kn(n,d),c.impactHash=d.impactHash,await Re(n,c,"impact-planned",m.length,{eventCount:m.length,foldedCount:d.foldedCount,impactHash:d.impactHash}),await pe(t,"content-sync-impact-planned",r,"Content-sync persisted an immutable impact plan.",{impactHash:d.impactHash,eventCount:m.length});}if(!d||d.jobId!==r.id||c.impactHash!==d.impactHash)throw new Error("The immutable content-sync impact plan is missing or mismatched.");if(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH=n.candidateManifest,!De(c.phase,"rendered")){let m=await Pa(n,r.id);await pe(t,m==="resumed"?"content-sync-render-resumed":"content-sync-render-initialized",r,m==="resumed"?"Content-sync resumed its candidate crawl manifest.":"Content-sync initialized a candidate crawl manifest.",{impactHash:d.impactHash}),await Tr(["--content-sync-plan",n.impact]),await Re(n,c,"rendered",d.directRenderUrls.length+d.archiveFamilyUrls.length,{impactHash:d.impactHash},r.attempt??0);}let p=o.deploymentProfile?["--profile",o.deploymentProfile]:[];if(De(c.phase,"deployed")||(await Or([...p,"--content-sync"]),await Re(n,c,"deployed",1,{impactHash:d.impactHash}),await pe(t,"content-sync-deployed",r,"Content-sync targeted deployment completed.",{impactHash:d.impactHash})),De(c.phase,"invalidated")?De(c.phase,"verified")||await pn([...p,"--content-sync"]):(await pn([...p,"--content-sync"]),await Re(n,c,"invalidated",1,{impactHash:d.impactHash})),De(c.phase,"verified")||(await ya(s,o,d),await Sa(n),await Re(n,c,"verified",1,{impactHash:d.impactHash})),l=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:a.baselineId,postTypes:o.scope.postTypes}),l.committedSequence===c.fromSequence)await o.client.acknowledge({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:a.baselineId,expectedSequence:c.fromSequence,sequence:c.toSequence,postTypes:o.scope.postTypes});else if(l.committedSequence!==c.toSequence)throw new Error("Content-sync acknowledgement cursor is in an unexpected state.");await Re(n,c,"acknowledged",1,{sequence:c.toSequence}),await pe(t,"content-sync-cursor-acknowledged",r,"Content-sync committed its journal cursor after verification.",{sequence:c.toSequence});let g=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:a.baselineId,postTypes:o.scope.postTypes}),f=await rt(n);f.rules[o.coalesceKey]={ruleId:String(i.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,committedSequence:c.toSequence,observedHeadSequence:g.headSequence,lag:Math.max(0,g.headSequence-c.toSequence),lastSuccessfulJobId:r.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:g.headSequence>c.toSequence,retryAttempt:0,nextRetryAt:null,lastError:null},await st(n,f),await Te(s),await A.rm(S.join(t,"content-sync-invalidation.json"),{force:true}),await A.rm(n.candidateManifest,{force:true}),await Mt(n);}async function Nr(e=process.argv.slice(2)){let n=e.indexOf("--capture-baseline-cutoffs");if(n>=0){let o=String(e[n+1]||"").trim();if(!o)throw new Error("--capture-baseline-cutoffs requires a release job ID.");await ma(o);return}let r=e.indexOf("--establish-baselines");if(r>=0){let o=String(e[r+1]||"").trim();if(!o)throw new Error("--establish-baselines requires a release job ID.");await fa(o);return}let s=e.indexOf("--job-id"),i=s>=0?String(e[s+1]||"").trim():"";if(!i)throw new Error("Content-sync requires --job-id.");await ba(i);}Nr().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1);});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smart-cloud/publisher-exporter",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.43",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Headless Playwright static publisher for WordPress/Elementor sites with sitemap-only page discovery, strict asset capture, escaped URL rewrite, structured logs, and targeted retry modes.",
|