@smart-cloud/publisher-exporter 1.1.40 → 1.1.41
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 +8 -8
- package/dist/invalidate.js +3 -3
- package/package.json +1 -1
package/dist/content-sync.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import T from'fs/promises';import Vr from'http';import bn from'https';import S from'path';import Bn,{createHash}from'crypto';import {request,chromium}from'playwright';import {gunzipSync}from'zlib';import ys 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 xo from'mime-types';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';var zr=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 Rt(e){return Array.isArray(e)?e.map(Rt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,Rt(n)])):e}function Qr(e){return JSON.stringify(Rt(e))}function oe(e){return createHash("sha256").update(Qr(e)).digest("hex")}function It(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(It(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 je(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 hn(e,t,n){return oe({schemaVersion:1,sourceOrigin:It(e),ruleId:t.trim(),scope:je(n)})}function wn(e){return oe({schemaVersion:1,...e})}function yn(e){let t=String(e.siteId??"").trim()||String(e.accountId??"").trim()||It(e.sourceOrigin);return `content-sync:${oe({siteIdentity:t,ruleId:e.ruleId.trim(),targetFingerprint:e.targetFingerprint}).slice(0,48)}`}function Sn(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 fn(e){return e?.status==="publish"&&!!e.url}function Jr(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 At(e){let t=je(e.scope),n=new Map;Sn(e.events);for(let r of e.events)for(let s of [r.before,r.after])for(let i of s?.archiveFamilies??[]){if(!zr.has(i.kind)||!Jr(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 Pn(e){let t=je(e.scope),n=Sn(e.events),r=new Set,s=new Set,i=new Map(At({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,m=fn(p),f=fn(g);f&&g.url&&r.add(ge(e.sourceOrigin,g.url)),m&&p.url&&(!f||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 Le(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 Kr="wp-json/smartcloud-static-publisher/v1/content-sync/",Gr=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(`${Kr}${t}`,n)}async post(t,n){let r=this.endpoint(t),s=Buffer.from(JSON.stringify(n),"utf8"),i=r.protocol==="https:"?bn:Vr,o=r.protocol==="https:"?new bn.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>Gr){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"),m;try{m=g?JSON.parse(g):{};}catch{a(new et(l.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let f=l.statusCode??500;if(f<200||f>=300){a(new et(f,String(m.code??"request-failed"),String(m.message??`Content-sync API request failed (${f}).`)));return}u(m);});});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")}}async function Tt(e){let t=await qe(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 vn(e,t){await Ae(e.releaseCutoff,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Ae(e,t){await T.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await T.writeFile(n,JSON.stringify(t,null,2),"utf8"),await T.rename(n,e);}async function qe(e){try{return JSON.parse(await T.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 xt(e){let t=await qe(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 Cn(e,t){await Ae(e.baseline,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Rn(e){let t=await qe(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 In(e,t){await Ae(e.current,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function An(e){let t=await qe(e.impact);if(t===null)return null;let n=t;return Le(n),n}async function Tn(e,t){Le(t),await Ae(e.impact,t);}async function xn(e,t){await Ae(e.checkpoint,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function kt(e){let t=await qe(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 $t(e,t){await Ae(e.state,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Et(e){await Promise.all([e.current,e.checkpoint].map(async t=>{try{await T.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}));}function $n(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function es(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 Mt(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t.trim(),String(n??"")]).filter(([t])=>t.length>0))}function ts(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=$n(i.targetOrigin);a&&(o.targetOrigin=a);}let u=Mt(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 Dt(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function ns(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 En(e){let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.rules)?t.rules.map((r,s)=>ns(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 rs(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 Ot(e){let t=e&&typeof e=="object"?e:{},n=String(t.accountId??"").trim(),r=String(t.siteId??"").trim(),s=t.subscriber===true,i=rs(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=Dt(t.subscriptionType);return d&&(u.subscriptionType=d),u}function ss(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Mn(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function is(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 Fn(e,t,n=5){let r=new URL(Mn(e)),s=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),i=r.protocol==="http:"?Vr:bn,o=is(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(Fn(new URL(g,r),{method:p===303?"GET":s},n-1));return}let m=new Headers;for(let[f,h]of Object.entries(l.headers))Array.isArray(h)?m.set(f,h.join(", ")):typeof h=="string"&&m.set(f,h);u(new Response(Buffer.concat(d),{status:p,statusText:l.statusMessage??"",headers:m}));});});c.on("error",a),c.end();})}function os(e){let t=Ot(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;ss(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 as(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!os(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=Mn(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 Fn(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=Dt(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 cs(e,t){let n=ts(t?.deploymentProfiles),r=String(t?.defaultDeploymentProfile??"").trim(),s=n[r]?r:"",i=Dt(t?.subscriptionType),o=Ot(e.wpsuite);return {...e,scheduler:En(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 Ft(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 us(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function kn(e,t,n){let r=String(t||"").trim();return r&&S.isAbsolute(r)?S.resolve(r):S.resolve(e,Ft(r,n))}async function ne(e,t={}){let n=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",r=await T.readFile(n,"utf8"),s=JSON.parse(r);s.sourceOrigin=s.sourceOrigin.replace(/\/$/,""),s.targetOrigin=$n(s.targetOrigin),s.ignoreHttpsErrors??=false,s.outputDir=String(s.outputDir||"export").trim()||"export",s.urlRewriteMode||=s.targetOrigin==="."?"relative":"absolute",s.noJavaScriptRenderPathPrefixes||=[],s.seedPaths||=[],s.generated404RequestPath=es(s.generated404RequestPath),s.sitemapPaths||=["/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=Mt(s.extraReplacements),s.postCrawlCopyMap=Mt(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=Ot(s.wpsuite),s.scheduler=En(void 0),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let i=await as(s);t.onRemotePublisherConfigDiagnostic?.(i.diagnostic);let o=cs(s,i.remote),u=us(),a=u?S.resolve(u,".."):"";return a?(o.outputDir=kn(a,o.outputDir,"export"),o.logDir=kn(a,o.logDir,"logs")):(S.isAbsolute(o.outputDir)||(o.outputDir=Ft(o.outputDir,"export")),S.isAbsolute(o.logDir)||(o.logDir=Ft(o.logDir,"logs"))),o}var ls=".deploy-plan.json",ds="deploy-plan.json",ps=".crawl-incomplete.json",gs="crawl-incomplete.json";function Dn(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function On(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 ms(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 fe(e){return [...new Set(e.map(On).filter(t=>t!==null))]}function jn(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:fe(t.changedFiles||[]),deletedFiles:fe(t.deletedFiles||[]),rewriteTargets:fe(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:fe(t.uploadGroups?.assets||[]),content:fe(t.uploadGroups?.content||[]),listings:fe(t.uploadGroups?.listings||[]),sitemapLeaves:fe(t.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:fe(t.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((t.invalidationPaths||[]).map(ms).filter(r=>r!==null))].sort()}:{schemaVersion:1,...n,runMode:t.runMode}}function fs(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 jt(e){let t=S.join(S.resolve(e.outputDir),ls),n=Dn();return n?[S.join(n,ds),t]:[t]}function Lt(e){let t=S.join(S.resolve(e.outputDir),ps),n=Dn();return n?[S.join(n,gs),t]:[t]}function he(e,t){let n=S.resolve(e),r=S.resolve(t),s=S.relative(n,r).replace(/\\/g,"/");return On(s)}async function rt(e){let t=S.resolve(e.outputDir);for(let n of jt(e))try{let r=await T.readFile(n,"utf8"),s=JSON.parse(r);if(!fs(s)||S.resolve(s.outputDir)!==t)continue;return jn(e,s)}catch{}return null}async function Ut(e,t){let n=jn(e,t);for(let r of jt(e)){await T.mkdir(S.dirname(r),{recursive:true});let s=`${r}.${process.pid}.${Date.now()}.tmp`;await T.writeFile(s,JSON.stringify(n,null,2),"utf8"),await T.rename(s,r);}}async function Te(e){for(let t of jt(e))try{await T.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}async function Ln(e,t){let n={schemaVersion:1,startedAt:String(t.startedAt||new Date().toISOString()),outputDir:S.resolve(e.outputDir)};for(let r of Lt(e)){await T.mkdir(S.dirname(r),{recursive:true});let s=`${r}.${process.pid}.tmp`;await T.writeFile(s,JSON.stringify(n,null,2),"utf8"),await T.rename(s,r);}}async function Un(e){let t=S.resolve(e.outputDir);for(let n of Lt(e)){let r;try{r=await T.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 qn(e){for(let t of Lt(e))try{await T.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}function Ne(e,t=10){return Bn.createHash("sha1").update(e).digest("hex").slice(0,t)}async function hs(e){await T.mkdir(S.dirname(e),{recursive:true});}async function Be(e,t,n){await hs(e);let r=S.join(S.dirname(e),`.${S.basename(e)}.${process.pid}.${Date.now()}.${Bn.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await T.writeFile(r,t,n??"utf8"):await T.writeFile(r,t),await T.rename(r,e);}catch(s){throw await T.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 xe(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function st(e){return e.replace(/\//g,"\\/")}function _n(e){return e.replace(/\//g,"\\\\/")}function ws(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 Nn(e,t,n){if(!t)return;e[t]=n;let r=st(t),s=st(n);e[r]=s;let i=_n(t),o=_n(n);e[i]=o;let u=xe(t),a=xe(n);e[u]=a;let c=xe(r),l=xe(s);e[c]=l;let d=xe(i),p=xe(o);e[d]=p;}function it(e,t,n){Nn(e,t,n);let r=ws(t);r&&r!==t&&Nn(e,r,n);}function qt(e,t){let n=t.startsWith("/")?t:`/${t}`,r=(e||"").replace(/\/$/,"");return !r||r==="."||r==="/"?n:`${r}${n}`}function Hn(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function Wn(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 vs=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Cs=new Set([".html",".htm"]),zn="WPSuite.io Static Publisher",Rs=zn.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Is(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function As(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function Ts(e,t,n){return As(t)?e.replace(new RegExp(`(?<!:)${Is(t)}`,"g"),n):e.split(t).join(n)}function xs(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 Cs.has(s)?/<head\b|<html\b|<!doctype html/i.test(t):false}function ks(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Rs}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${zn}" />`;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 Gr from'http';import Cn from'https';import S from'path';import Wn,{createHash}from'crypto';import {request,chromium}from'playwright';import {gunzipSync}from'zlib';import Ps 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 $o from'mime-types';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';var Jr=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 Rt(e){return Array.isArray(e)?e.map(Rt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,Rt(n)])):e}function Vr(e){return JSON.stringify(Rt(e))}function oe(e){return createHash("sha256").update(Vr(e)).digest("hex")}function It(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(It(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 yn(e,t,n){return oe({schemaVersion:1,sourceOrigin:It(e),ruleId:t.trim(),scope:Ue(n)})}function Sn(e){return oe({schemaVersion:1,...e})}function Pn(e){let t=String(e.siteId??"").trim()||String(e.accountId??"").trim()||It(e.sourceOrigin);return `content-sync:${oe({siteIdentity:t,ruleId:e.ruleId.trim(),targetFingerprint:e.targetFingerprint}).slice(0,48)}`}function bn(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 Kr(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 xt(e){let t=Ue(e.scope),n=new Map;bn(e.events);for(let r of e.events)for(let s of [r.before,r.after])for(let i of s?.archiveFamilies??[]){if(!Jr.has(i.kind)||!Kr(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 vn(e){let t=Ue(e.scope),n=bn(e.events),r=new Set,s=new Set,i=new Map(xt({events:e.events,scope:t,sourceOrigin:e.sourceOrigin}).map(d=>[`${d.kind}|${d.url}`,d]));for(let d of n){let p=d.before,f=d.after,g=wn(p),m=wn(f);m&&f.url&&r.add(ge(e.sourceOrigin,f.url)),g&&p.url&&(!m||p.url!==f.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 f=o.get(d);if(!f)throw new Error(`WordPress did not resolve archive family ${d}.`);return {...p,...f}}).sort((d,p)=>d.url.localeCompare(p.url)),c=Pe(u.flatMap(d=>d.pageUrls)),a=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:c,sitemapUrls:a,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 Zr="wp-json/smartcloud-static-publisher/v1/content-sync/",Yr=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(`${Zr}${t}`,n)}async post(t,n){let r=this.endpoint(t),s=Buffer.from(JSON.stringify(n),"utf8"),i=r.protocol==="https:"?Cn:Gr,o=r.protocol==="https:"?new Cn.Agent({rejectUnauthorized:!this.options.ignoreHttpsErrors}):void 0;return new Promise((u,c)=>{let a=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",f=>{if(p+=f.byteLength,p>Yr){l.destroy(new Error("Content-sync API response exceeded the size limit."));return}d.push(f);}),l.on("error",c),l.on("end",()=>{let f=Buffer.concat(d).toString("utf8"),g;try{g=f?JSON.parse(f):{};}catch{c(new et(l.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let m=l.statusCode??500;if(m<200||m>=300){c(new et(m,String(g.code??"request-failed"),String(g.message??`Content-sync API request failed (${m}).`)));return}u(g);});});a.on("timeout",()=>a.destroy(new Error(`Content-sync API request timed out: ${t}`))),a.on("error",c),a.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 At(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 Rn(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 Tt(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 In(e,t){await Ae(e.baseline,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function kt(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 xn(e,t){await Ae(e.current,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function An(e){let t=await _e(e.impact);if(t===null)return null;let n=t;return qe(n),n}async function Tn(e,t){qe(t),await Ae(e.impact,t);}async function kn(e,t){await Ae(e.checkpoint,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function $t(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 Et(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 $n(e,t){let n=await kt(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 Mn(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function ns(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 rs(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 c=Mn(i.targetOrigin);c&&(o.targetOrigin=c);}let u=Ft(i.extraReplacements);if(Object.keys(u).length>0&&(o.extraReplacements=u),i.s3&&typeof i.s3=="object"){let c={},a=i.s3;typeof a.bucket=="string"&&(c.bucket=a.bucket.trim()),typeof a.prefix=="string"&&(c.prefix=a.prefix.trim()),typeof a.region=="string"&&(c.region=a.region.trim()),typeof a.htmlCacheControl=="string"&&(c.htmlCacheControl=a.htmlCacheControl.trim()),typeof a.assetCacheControl=="string"&&(c.assetCacheControl=a.assetCacheControl.trim()),Object.keys(c).length>0&&(o.s3=c);}if(i.cloudFront&&typeof i.cloudFront=="object"){let c={},a=i.cloudFront;typeof a.distributionId=="string"&&(c.distributionId=a.distributionId.trim()),Array.isArray(a.invalidationPaths)&&(c.invalidationPaths=a.invalidationPaths.map(l=>String(l??"").trim()).filter(l=>l.length>0)),Object.keys(c).length>0&&(o.cloudFront=c);}t[s]=o;}return t}function Ot(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function ss(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(),c=Array.isArray(n.postTypes)?[...new Set(n.postTypes.map(l=>String(l??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],a=Array.isArray(n.listingPaths)?[...new Set(n.listingPaths.map(l=>String(l??"").trim()).filter(Boolean))]:[];return r==="content-sync"&&c.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}:{},...c.length>0?{postTypes:c}:{},...a.length>0?{listingPaths:a}:{},...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 Fn(e){let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.rules)?t.rules.map((r,s)=>ss(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 is(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=is(t.siteSettings),o={...i??{},...n?{accountId:i?.accountId??n}:{},...r?{siteId:i?.siteId??r}:{},...i?.subscriber===true||s?{subscriber:true}:{}},u={},c=String(t.apiBase??"").trim();c&&(u.apiBase=c);let a=String(t.runtimeToken??t.nonce??"").trim();a&&(u.runtimeToken=a);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 os(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Dn(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function as(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 On(e,t,n=5){let r=new URL(Dn(e)),s=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),i=r.protocol==="http:"?Gr:Cn,o=as(e,t);return await new Promise((u,c)=>{let a=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",c),l.on("end",()=>{let p=l.statusCode??0,f=l.headers.location;if(n>0&&f&&[301,302,303,307,308].includes(p)){u(On(new URL(f,r),{method:p===303?"GET":s},n-1));return}let g=new Headers;for(let[m,h]of Object.entries(l.headers))Array.isArray(h)?g.set(m,h.join(", ")):typeof h=="string"&&g.set(m,h);u(new Response(Buffer.concat(d),{status:p,statusText:l.statusMessage??"",headers:g}));});});a.on("error",c),a.end();})}function cs(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;os(e.sourceOrigin);let o=globalThis,c={...o.WpSuite??{},siteSettings:n,uploadUrl:i};return t.apiBase&&(c.apiBase=t.apiBase),o.WpSuite=c,true}async function us(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!cs(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(c,a)=>{let l=Dn(c);if(l.startsWith(t)){let d=(()=>{try{return new URL(l).pathname}catch{return l}})();try{let p=e.ignoreHttpsErrors&&l.startsWith("https://")?await On(c,a):await n(c,a);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(c,a)}));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 ls(e,t){let n=rs(t?.deploymentProfiles),r=String(t?.defaultDeploymentProfile??"").trim(),s=n[r]?r:"",i=Ot(t?.subscriptionType),o=jt(e.wpsuite);return {...e,scheduler:Fn(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 ds(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function En(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=Mn(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=ns(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=Fn(void 0),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let i=await us(s);t.onRemotePublisherConfigDiagnostic?.(i.diagnostic);let o=ls(s,i.remote),u=ds(),c=u?S.resolve(u,".."):"";return c?(o.outputDir=En(c,o.outputDir,"export"),o.logDir=En(c,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 ps=".deploy-plan.json",gs="deploy-plan.json",fs=".crawl-incomplete.json",ms="crawl-incomplete.json";function jn(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Ln(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 hs(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(Ln).filter(t=>t!==null))]}function Un(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(hs).filter(r=>r!==null))].sort()}:{schemaVersion:1,...n,runMode:t.runMode}}function ws(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),ps),n=jn();return n?[S.join(n,gs),t]:[t]}function Ut(e){let t=S.join(S.resolve(e.outputDir),fs),n=jn();return n?[S.join(n,ms),t]:[t]}function he(e,t){let n=S.resolve(e),r=S.resolve(t),s=S.relative(n,r).replace(/\\/g,"/");return Ln(s)}async function rt(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(!ws(s)||S.resolve(s.outputDir)!==t)continue;return Un(e,s)}catch{}return null}async function qt(e,t){let n=Un(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 qn(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 _n(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 Nn(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 Wn.createHash("sha1").update(e).digest("hex").slice(0,t)}async function ys(e){await A.mkdir(S.dirname(e),{recursive:true});}async function He(e,t,n){await ys(e);let r=S.join(S.dirname(e),`.${S.basename(e)}.${process.pid}.${Date.now()}.${Wn.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 st(e){return e.replace(/\//g,"\\/")}function Bn(e){return e.replace(/\//g,"\\\\/")}function Ss(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 Hn(e,t,n){if(!t)return;e[t]=n;let r=st(t),s=st(n);e[r]=s;let i=Bn(t),o=Bn(n);e[i]=o;let u=ke(t),c=ke(n);e[u]=c;let a=ke(r),l=ke(s);e[a]=l;let d=ke(i),p=ke(o);e[d]=p;}function it(e,t,n){Hn(e,t,n);let r=Ss(t);r&&r!==t&&Hn(e,r,n);}function _t(e,t){let n=t.startsWith("/")?t:`/${t}`,r=(e||"").replace(/\/$/,"");return !r||r==="."||r==="/"?n:`${r}${n}`}function zn(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function Qn(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 Rs=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Is=new Set([".html",".htm"]),Jn="WPSuite.io Static Publisher",xs=Jn.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function As(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ts(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function ks(e,t,n){return Ts(t)?e.replace(new RegExp(`(?<!:)${As(t)}`,"g"),n):e.split(t).join(n)}function $s(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 Is.has(s)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Es(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${xs}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${Jn}" />`;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
|
|
6
|
-
`,"utf8");});}enqueueJsonLine(t,n){this.enqueueTask(()=>
|
|
7
|
-
`,"utf8");});}enqueueJsonLine(t,n){this.enqueueTask(()=>Gn(t,n));}updateCurrentEvent(t,n,r){let s=_s(t,n,r);this.enqueueTask(async()=>{await T.mkdir(this.logDir,{recursive:true}),await T.writeFile(this.currentEventPath,JSON.stringify(s,null,2),"utf8");});}push(t,n,r){let s=ve(n),i=lt(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){Kn("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 Ht="(?: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 Zn(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 Yn(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]&&Zn(i[1])&&n.push({index:i.index??0,value:i[1]});for(let i of e.matchAll(s))i[1]&&Zn(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 Ws=["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"],dr=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"]),pr=new Set(["",".html",".htm"]),zs=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),Qs=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function Js(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 Zt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Vs(){let e=Zt();return e?S.resolve(e,".."):""}function Ks(){let e=process.env.STATIC_PUBLISHER_WP_ROOT||process.env.WPSUITE_STATIC_PUBLISHER_WP_ROOT||"";return e.trim()?S.resolve(e):""}function Gs(e){let t=e.trim(),n=[{alias:"@storage-root",root:Vs(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@runtime",root:Zt(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@wp-root",root:Ks(),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 gr(e){let t=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(t)return S.resolve(t);let n=Zt();return n?S.join(n,"crawl-manifest.json"):S.join(e.outputDir,".crawl-manifest.json")}function mr(){return {schemaVersion:3,updatedAt:"",pages:{},assets:{}}}function Xn(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 Zs(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 Qt(e){let t=e?.["content-type"]?.trim();return t||null}function Ys(){return {rewriteTargets:new Set,changedFiles:new Set,deletedFiles:new Set}}function G(e,t,n){let r=he(t.outputDir,n);r&&(e.changedFiles.add(r),e.deletedFiles.delete(r));}function er(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 Xs(e){try{let t=await T.readFile(gr(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,Xn(s)])),assets:Object.fromEntries(Object.entries(n.assets).map(([r,s])=>[r,Zs(s)]))};if(n.schemaVersion===1)return {schemaVersion:3,updatedAt:String(n.updatedAt||""),pages:Object.fromEntries(Object.entries(n.pages).map(([r,s])=>[r,Xn(s)])),assets:{}}}}catch{}return mr()}function Jt(e){return JSON.parse(JSON.stringify(e))}async function ei(e,t){let n=gr(e);await T.mkdir(S.dirname(n),{recursive:true}),await T.writeFile(n,JSON.stringify(t,null,2),"utf8");}async function we(e,t){if(!t.trackManifest)return;let n=async()=>{let r=Jt(t.manifest);r.updatedAt=new Date().toISOString(),t.manifest.updatedAt=r.updatedAt,await ei(e,r);};t.manifestSaveChain=t.manifestSaveChain.then(n,n),await t.manifestSaveChain;}function We(e){if(!e)return null;let t=e.trim();return t||null}function ti(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 ni(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 Wt(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 ni(e,t,[r],s)).get(r)??null;return en(e,r)&&(!o||o.supported!==true||!o.token)&&(o=await ii(e,t,r,s)),o=si(e,o),n.changeTokenCache.set(r,o),o}function ri(e){return `subscriber=${e.wpsuite?.siteSettings?.subscriber===true?"1":"0"}`}function si(e,t){if(!t?.supported||!t.token)return t;let n=ri(e);return {...t,token:Ne(`${t.token}
|
|
8
|
-
${n}`,40),tokenSource:t.tokenSource?`${t.tokenSource}+site-subscriber`:"site-subscriber"}}async function
|
|
4
|
+
`;return e.replace(/<head\b[^>]*>/i,s=>`${s}${r} ${t}`)}function Ms(e){let t=ce(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function Fs(e,t){let n=[...new Set(t)].filter(i=>i.includes("/")&&!/\\+\//.test(i)).map(i=>[i,st(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,c]of n)o=o.split(u).join(c);return o},s=e.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(i,o,u,c)=>`${o}${r(u)}${c}`);return s=s.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(i,o,u,c,a)=>Ms(c)?`${o}${r(c)}${a}`:i),s}function Ds(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 Os(e,t,n){let r=Ds(t,n);if(!r)return e;let s=e;for(let i of Rs){let o=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),u=new RegExp(`(?:\\.{1,}/)+${o}`,"g"),c=new RegExp(`(?<!\\.)/${o}`,"g");s=s.replace(u,`${r}${i}`).replace(c,`${r}${i}`);let a=i.replace(/\//g,"\\/"),l=r.replace(/\//g,"\\/"),d=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),p=new RegExp(`(?:\\.{1,}\\\\/)+${d}`,"g"),f=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${d}`,"g"),g=new RegExp(`(?<![\\.\\\\])\\/${d}`,"g");s=s.replace(p,`${l}${a}`).replace(f,`${l}${a}`).replace(g,`${l}${a}`);}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:zn(t,e.targetOrigin),i=r?`${r.search}${r.hash}`:"";return e.urlRewriteMode==="root-relative"?`${s}${i}`:`${Qn(e.outputDir,n,s)}${i}`}function Nt(e,t,n,r,s){it(e,n,Bt(t,r,s));}function js(e,t,n,r,s){if(!n||n===r)return;it(e,n,r);let i=Bt(t,n,s),o=Bt(t,r,s);it(e,i,o);}function Ht(e,t,n,r,s={}){let i=e,o={};Nt(o,t,t.sourceOrigin,t.targetOrigin,r);for(let[c,a]of Object.entries(t.extraReplacements))Nt(o,t,c,a,r);for(let[c,a]of Object.entries(n))Nt(o,t,c,a,r);for(let[c,a]of Object.entries(s)){let l=n[c];!l||l===a||js(o,t,a,l,r);}let u=Object.entries(o).sort((c,a)=>a[0].length-c[0].length);for(let[c,a]of u)i=ks(i,c,a);return t.urlRewriteMode!=="absolute"&&(i=Os(i,t,r)),i=Fs(i,u.map(([,c])=>c)),$s(t,i,r)&&(i=Es(i)),i}async function Ls(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(a){if(a.code!=="ENOENT")throw a;return {changed:false}}let c=Ht(o,e,t,i===".js"||i===".mjs"?void 0:s,n);return c!==o?(await He(s,c,"utf8"),{changed:true}):{changed:false}}async function Us(e,t){return await new Promise((n,r)=>{let s=c=>{if(u(),c?.error){r(new Error(c.error));return}n({changed:!!c?.changed});},i=c=>{u(),r(c);},o=c=>{u(),c!==0&&r(new Error(`Rewrite worker exited with code ${c}.`));},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 ot(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 Ps(["**/*"],{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 c=0,a=0,l=null;if(u===1){for(let p of s){let f=await Ls(e,t,n.previousAssetMap??{},p);f.changed&&(i+=1),a+=1,await n.onProgress?.({index:a,totalFiles:s.length,changedTextFiles:i,file:p,changed:f.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 f=c;if(f>=s.length)return;c+=1;let g=s[f],m=await Us(p,g);m.changed&&(i+=1),a+=1,await n.onProgress?.({index:a,totalFiles:s.length,changedTextFiles:i,file:g,changed:m.changed});}}catch(f){throw l=f instanceof Error?f:new Error(String(f)),l}finally{await p.terminate().catch(()=>{});}});return await Promise.all(d),i}var ie={error:0,warn:1,info:2,debug:3},qs=/^(?: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 ct(e){return typeof e=="string"?ve(e):Array.isArray(e)?e.map(t=>ct(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,qs.test(t)?"[REDACTED]":ct(n)])):e}function lt(e){return e?ct(e):void 0}var Vn=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",at=Vn?S.join(Vn,"current-progress.json"):"",Kn=Promise.resolve();function Gn(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function _s(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 Zn(e,t,n){at&&(Kn=Kn.then(async()=>{let r=new Date,s=r.toISOString();await A.mkdir(S.dirname(at),{recursive:true});let i=await A.readFile(at,"utf8").then(w=>JSON.parse(w)).catch(()=>null),o=i&&typeof i.details=="object"&&i.details?i.details:{},u=Gn(e),c=i?.currentStep||Gn(i?.source||""),a=i?.startedAt||s,l={...i?.stepDurationsSec??{}},d=i?.stepStartedAt||s;if(c&&c!==u&&i?.stepStartedAt){let w=Math.max(0,Math.round((r.getTime()-new Date(i.stepStartedAt).getTime())/1e3));l[c]=(l[c]??0)+w,d=s;}let p=Math.max(0,Math.round((r.getTime()-new Date(d).getTime())/1e3)),f=Math.max(0,Math.round((r.getTime()-new Date(a).getTime())/1e3)),g=ve(t),m=lt(n)??{},h={checkedAt:s,source:e,message:g,details:_s(o,m),startedAt:a,currentStep:u,stepStartedAt:d,stepElapsedSec:p,totalElapsedSec:f,stepDurationsSec:l};await A.writeFile(at,JSON.stringify(h,null,2),"utf8");}).catch(()=>{}));}async function Yn(e,t){await A.mkdir(S.dirname(e),{recursive:true}),await A.appendFile(e,`${JSON.stringify(ct(t))}
|
|
5
|
+
`,"utf8");}function Ns(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 Bs(e,t,n){let r=lt(n);return {checkedAt:new Date().toISOString(),currentStep:Ns(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
|
+
`,"utf8");});}enqueueJsonLine(t,n){this.enqueueTask(()=>Yn(t,n));}accepts(t){return ie[t]<=ie[this.level]}push(t,n,r){if(!this.accepts(t))return;let s=ve(n),i=lt(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){Zn(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}},ut=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(()=>Yn(t,n));}updateCurrentEvent(t,n,r){let s=Bs(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=lt(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){Zn("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 Xn(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 er(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]&&Xn(i[1])&&n.push({index:i.index??0,value:i[1]});for(let i of e.matchAll(s))i[1]&&Xn(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 Qs=["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"],gr=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"]),fr=new Set(["",".html",".htm"]),Js=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),Vs=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function Ks(e){let t=[],n="full",r="full",s=false,i=false,o="";for(let u=0;u<e.length;u++){let c=e[u];if(c==="--retry-timeouts")n="retry-timeouts",s=true;else if(c==="--resume")s=true;else if(c==="--resume-rewrite")s=true,i=true;else if(c==="--crawl-mode"){let a=e[++u];if(!a)throw new Error("--crawl-mode requires a value");r=a==="incremental"?"incremental":"full",s||=r==="incremental";}else if(c.startsWith("--crawl-mode="))r=c.slice(13)==="incremental"?"incremental":"full",s||=r==="incremental";else if(c==="--incremental")r="incremental",s=true;else if(c==="--url"){let a=e[++u];if(!a)throw new Error("--url requires a value");n="single-url",s=true,t.push(a);}else if(c.startsWith("--url="))n="single-url",s=true,t.push(c.slice(6));else if(c==="--urls"){let a=e[++u];if(!a)throw new Error("--urls requires a file path");n="single-url",s=true,t.push(`@${a}`);}else if(c==="--content-sync-plan"){let a=e[++u];if(!a)throw new Error("--content-sync-plan requires a file path");n="content-sync",r="incremental",s=true,o=S.resolve(a);}else c.startsWith("--content-sync-plan=")&&(n="content-sync",r="incremental",s=true,o=S.resolve(c.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 Gs(){let e=Yt();return e?S.resolve(e,".."):""}function Zs(){let e=process.env.STATIC_PUBLISHER_WP_ROOT||process.env.WPSUITE_STATIC_PUBLISHER_WP_ROOT||"";return e.trim()?S.resolve(e):""}function Ys(e){let t=e.trim(),n=[{alias:"@storage-root",root:Gs(),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:Zs(),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 mr(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 hr(){return {schemaVersion:3,updatedAt:"",pages:{},assets:{}}}function tr(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 Xs(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 ei(){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 nr(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 ti(e){try{let t=await A.readFile(mr(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,tr(s)])),assets:Object.fromEntries(Object.entries(n.assets).map(([r,s])=>[r,Xs(s)]))};if(n.schemaVersion===1)return {schemaVersion:3,updatedAt:String(n.updatedAt||""),pages:Object.fromEntries(Object.entries(n.pages).map(([r,s])=>[r,tr(s)])),assets:{}}}}catch{}return hr()}function Vt(e){return JSON.parse(JSON.stringify(e))}async function ni(e,t){let n=mr(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 ni(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 ri(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 si(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 c=await u.json().catch(()=>null);if(!c||!Array.isArray(c.items))return new Map;let a=new Map;for(let l of c.items)!l||typeof l.url!="string"||a.set(l.url,l);return a}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 si(e,t,[r],s)).get(r)??null;return tn(e,r)&&(!o||o.supported!==true||!o.token)&&(o=await ai(e,t,r,s)),o=oi(e,o),n.changeTokenCache.set(r,o),o}function ii(e){return `subscriber=${e.wpsuite?.siteSettings?.subscriber===true?"1":"0"}`}function oi(e,t){if(!t?.supported||!t.token)return t;let n=ii(e);return {...t,token:Be(`${t.token}
|
|
8
|
+
${n}`,40),tokenSource:t.tokenSource?`${t.tokenSource}+site-subscriber`:"site-subscriber"}}async function ai(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 oi(e,t,n,r,s,i){let o=en(e,s);if(!r.enabled)return {action:"render",changeToken:r.trackManifest?await Wt(e,t,r,s,i):null};let u=r.manifest.pages[s];if(!u)return {action:"render",changeToken:await Wt(e,t,r,s,i)};let a=await Wt(e,t,r,s,i);if(a?.supported&&a.token)return u.changeToken===a.token?o&&!await ai(e,t,s,i)?{action:"render",changeToken:a}:{action:"reuse",changeToken:a}:{action:"render",changeToken:a};let c=We(n.sitemapLastmodByPage[s]);return c&&u.sitemapLastmod&&u.sitemapLastmod===c?{action:"reuse",changeToken:a}:{action:"render",changeToken:a}}async function ai(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 ci(e,t,n,r,s){let i=tr(n.previousManifest,void 0,r,"previous-manifest"),o=0;for(let[p,g]of Object.entries(n.manifest.pages))if(!n.seenPages.has(p)){er(s,e,g.outputPath);try{await T.unlink(g.outputPath);}catch(m){(m.code||"")!=="ENOENT"&&r.warn(`Failed to remove stale incremental page output for ${p}`,{url:p,outputPath:g.outputPath,error:String(m)});}delete n.manifest.pages[p],o++;}let u=tr(n.manifest,n.runId,r,"active-manifest"),a=new Set,c=new Set;for(let p of u){for(let f of ze(e,p))a.add(f);let g=n.manifest.assets[p]?.outputPath;g&&c.add(g);let m=Qe(e,t.assetMap,p);m&&c.add(m);}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,m=n.previousManifest.assets[p]?.outputPath;m&&g.add(m);let f=Qe(e,t.assetMap,p);if(!u.has(p)&&f)g.add(f);else if(!u.has(p)){let h=Ii(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)){er(s,e,h);try{await T.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 ze(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 tr(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 nr(e,t,n){for(let r of t)for(let s of ze(e,r))if(n.has(s))return true;return false}function ui(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=ti(r,s);if(o.size===0)return [...i];for(let u of Object.values(t.manifest.pages))nr(e,u.discoveredAssets,o)&&i.add(S.resolve(u.outputPath));for(let[u,a]of Object.entries(t.manifest.assets)){a.isText&&nr(e,a.discoveredAssets,o)&&i.add(S.resolve(a.outputPath));for(let c of ze(e,u))if(o.has(c)){G(n,e,a.outputPath),a.isText&&i.add(S.resolve(a.outputPath));break}}return [...i]}function li(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 di(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(Qe(e,t.assetMap,i));for(let i of Object.values(n.manifest.assets))i.lastSeenRunId===n.runId&&s(i.outputPath);return r}async function pi(e,t,n,r,s){let i=[...r.deletedFiles].sort(),o=di(e,t,n),u=0;for(let l of [...o].sort()){try{if((await T.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 T.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 ze(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 gi(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 fr(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,Xt(r.pathname))}catch{return null}}function mi(e,t,n){for(let r of gi(e,n)){let s=t[r];if(!s)continue;let i=fr(e,s);if(i)return {outputPath:i,publicUrl:s}}return null}function fi(e,t,n){for(let r of ze(e,n)){let s=t[r];if(!s)continue;let i=fr(e,s);if(i)return i}return null}function Qe(e,t,n){let r=fi(e,t,n);if(r)return r;try{return ht(e,n).originalFilePath}catch{return null}}function hi(){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 rr(e){let t=hi();if(t)try{let n=await T.readFile(t,"utf8"),r=JSON.parse(n);if(!r||typeof r!="object")return;await T.writeFile(t,JSON.stringify({...r,checkedAt:new Date().toISOString(),status:"running",currentStep:"rewrite",message:e},null,2),"utf8");}catch{}}function wi(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=Qe(e,t.assetMap,r);!s||!be(s)||n.add(S.resolve(s));}return [...n]}var mt="re:",dt=new Map;function yi(e){if(!e.startsWith(mt))return null;let t=dt.get(e);if(t!==void 0)return t||null;let n=e.slice(mt.length).trim();if(!n)return dt.set(e,false),null;try{let r=new RegExp(n);return dt.set(e,r),r}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),dt.set(e,false),null}}function Yt(e,t){let n=yi(t);return n?n.test(e):t.startsWith(mt)?false:e.startsWith(t)}function Si(e,t){return t.find(n=>Yt(e,n))}function hr(e,t){let n=Si(t.pathname,e.blockedPathPrefixes);if(n)return n.startsWith(mt)?`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 Pi(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 bi(e,t){return Pi(e).has(t.hostname)}function vi(e){let t=ce(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function Vt(e){let t=ce(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function Ci(e){let t=ce(e).replace(/\\\//g,"/").trim(),n=S.extname(t).toLowerCase();return dr.has(n)||pr.has(n)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function $e(e){return Qs.some(t=>e.pathname.startsWith(t))}function H(e,t,n=e.sourceOrigin,r,s="url"){let i=vi(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(Vt(i))return r?.ignore(s,t,"looks like JavaScript/code fragment",n),null;if(Ci(i))return r?.ignore(s,t,"looks like JavaScript property access",n),null;try{let o=new URL(i,n);if(wr(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(!bi(e,o))return r?.ignore(s,o.toString(),"host not allowed",n),null;let u=hr(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 wr(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 wr(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 yr(e){return dr.has(S.extname(e.pathname).toLowerCase())}function Se(e){return $e(e)?false:pr.has(S.extname(e.pathname).toLowerCase())}function Ee(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function q(e,t){return !!(Ee(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(n=>Yt(t.pathname,n))||yr(t)||!Se(t)&&!$e(t))}function le(e,t){let n=new URL(t),r=Xt(n.pathname);return r.endsWith("/")?r+="index.html":S.extname(r)||(r+="/index.html"),S.join(e.outputDir,r)}function Xt(e){try{return decodeURIComponent(e)}catch{return e}}function Ri(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 en(e,t){let n=Ri(e);if(!n)return false;try{return new URL(t,e.sourceOrigin).toString()===n}catch{return false}}function ht(e,t){let n=new URL(t),r=Xt(n.pathname);r.endsWith("/")&&(r+="index.html");let s=!!n.search,i=r,o=S.join(e.outputDir,i),u=qt(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}.${Ne(n.search)}${c||".bin"}`;return {originalPathname:i,originalFilePath:o,originalPublicUrl:u,originalPublicUrlWithSearch:a,preferQueryHashed:s,hashedPathname:d,hashedFilePath:S.join(e.outputDir,d),hashedPublicUrl:qt(e.targetOrigin,d)}}function Ii(e,t,n,r){let s=ye(t,n,"asset",r);return s?ht(e,s.toString()):null}function Ai(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 Sr(e){try{return await T.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Je(e){try{return await T.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function Ti(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 Pr(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let n=Date.parse(t);return Number.isFinite(n)?n:null}function xi(e,t){let n=Pr(t),r=Ti(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 ki(e,t){if(!t)return;let n=Pr(t);if(n===null)return;let r=await Je(e);if(!r)return;let s=new Date(n);await T.utimes(e,r.atime,s).catch(()=>{});}function sr(e,t){let n=S.extname(e.pathname).toLowerCase(),r=t["content-type"]||"";return zs.has(n)||Ws.some(s=>r.includes(s))&&!r.startsWith("image/")&&!r.includes("font")}function $i(e){try{let t=S.extname(new URL(e).pathname).toLowerCase();return t===".js"||t===".mjs"}catch{return false}}function He(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 Ei(e){return Ne(e.toString("base64"),40)}function Mi(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 Fi(e,t,n){let r=e.assetVariantDigestsByOriginalPath.get(t);r||(r=new Set,e.assetVariantDigestsByOriginalPath.set(t,r)),r.add(n);}async function Kt(e,t,n,r,s,i,o){let u=ht(e,n),a=Ei(r),c=u.originalFilePath,l=u.originalPublicUrlWithSearch;if(u.preferQueryHashed&&u.hashedFilePath&&u.hashedPublicUrl&&Mi(s,u.originalFilePath,a)){let m=mi(e,t,n);m?(c=m.outputPath,l=m.publicUrl):(c=u.hashedFilePath,l=u.hashedPublicUrl);}Ai(e,t,n,l,u.originalPublicUrl);let d=be(c)?Buffer.from(Bt(r.toString("utf8"),e,t,c),"utf8"):r,p=await Sr(c),g=false;return (p===null||!p.equals(d))&&(await Be(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}),Fi(s,u.originalFilePath,a),await ki(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 Ve(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 Ee(p)?{discoveredFrom:d,discoveredFromType:"sitemap"}:q(e,p)?{discoveredFrom:d,discoveredFromType:"asset"}:Se(p)&&!$e(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)||yr(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(),$e(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 ft(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(!Ee(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 Di(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:We(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 Oi(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function ji(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 Li(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function Ui(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 zt(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function br(e,t,n,r){let s=[];await T.mkdir(t,{recursive:true});let i=await T.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 br(u,a,n,r));continue}await vr(u,a,n,r)&&s.push(a);}return s}async function qi(e,t){try{let[n,r]=await Promise.all([T.stat(e),T.stat(t)]);if(n.size!==r.size)return !1;let[s,i]=await Promise.all([T.readFile(e),T.readFile(t)]);return s.equals(i)}catch{return false}}async function vr(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 qi(e,t)?(r.debug("Skipped unchanged post-crawl copy target",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):(await T.mkdir(S.dirname(t),{recursive:true}),await T.copyFile(e,t),true)}async function _i(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=Gs(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=zt(c);if(!p){n.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:a,prefixPath:c});continue}let g;try{g=await T.stat(d);}catch{n.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:a,sourceAbs:d,prefixPath:c});continue}let m=S.resolve(e.outputDir,p);if(g.isDirectory()){let v=await br(d,m,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 f=S.basename(d),h=c.endsWith("/")?S.join(m,f):m;await vr(d,h,o,n)&&(i.push(h),s++,n.progress(`Copied static file to export: ${d} -> /${zt(c.endsWith("/")?`${c}${f}`:c)}`,{phase:"copy-extra-paths",sourcePath:d,targetPath:`/${zt(c.endsWith("/")?`${c}${f}`:c)}`,copiedItems:s}));}return n.endMark("copy-extra-paths",{mappedSources:r.length,copiedItems:s}),i}function Ke(e,t,n,r,s){let i=new Set,o=ce(n).replace(/\\\//g,"/"),u=s==="page-html"?Li(o):o,a=Ui(t,s);if(a){for(let l of ji(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'"<>\\);]+\\.${Ht}(?:\\?[^\\s'"<>\\);]*)?|(?<!\\.)/[^\\s'"<>\\);]+\\.${Ht}(?:\\?[^\\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(Vt(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"&&$i(t))for(let l of Yn(o)){if(Vt(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 Ni(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&&(hr(e,a)||Se(a)&&!$e(a)&&!q(e,a)&&s.add(a.toString()));}return [...s]}async function ir(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(),m=p.url()||d,f=ye(m,r,"sitemap-response",d);if(!f)continue;let h=f.toString(),w=await Kt(e,n.assetMap,h,g,n,r);G(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=Ke(e,h,v,r,"sitemap");for(let F of k)J(e,n,F,r,h);let E=[];for(let F of Di(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(Ee(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()),ft(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 Je(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),Ve(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 Bi(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 Je(l.outputPath)){n.doneAssets.add(a);for(let p of l.discoveredAssets||[])J(e,n,p,s,a);G(o,e,l.outputPath),l.isText&&Ce(o,l.outputPath),s.info(`Resumed completed content-sync asset ${a}`,{url:a,source:"content-sync-checkpoint"}),He(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 m of c.discoveredAssets||[])J(e,n,m,s,a);return s.warn(`Keeping previous incremental asset ${a} after fetch issue.`,{url:a,reason:p,preservedFromPreviousManifest:true,...g,phase:"download-assets"}),He(n,s),true};s.asset(`Fetching asset ${a}`,{url:a});try{let p=Qe(e,n.assetMap,a),g=p?await Je(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()&&xi(g,b)){let P=await Sr(p);if(P!==null){let C=O.url()||a,y=ye(C,s,"asset-response",a);if(!y)return;let A=y.toString(),j=await Kt(e,n.assetMap,A,P,n,s,b);j.wroteFile&&(G(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"}),He(n,s);let U=sr(u,b),V=c?.discoveredAssets?[...c.discoveredAssets]:[];if(U||c?.isText){let B=P.toString("utf8"),K=Ke(e,A,B,s,"asset:cached");(K.length>0||!c)&&(V=K);for(let $ of V)J(e,n,$,s,A);}if(i.trackManifest){let B=U||!!c?.isText;i.manifest.assets[a]={url:a,outputPath:j.outputPath,isText:B,contentType:Qt(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 m=await _(`fetch asset ${a}`,6e4,()=>t.get(a,{timeout:6e4}));if(!m.ok()){if(d(`http-${m.status()}`,{status:m.status()}))return;if(i.strictTargeted)throw new Error(`Required content-sync asset returned HTTP ${m.status()}: ${a}`);s.skip("asset",a,m.status());return}let f=await _(`read asset response ${a}`,6e4,()=>m.body()),h=m.url()||a,w=ye(h,s,"asset-response",a);if(!w)return;let v=w.toString(),k=m.headers(),E=await Kt(e,n.assetMap,v,f,n,s,k);E.wroteFile&&(G(o,e,E.outputPath),be(E.outputPath)&&Ce(o,E.outputPath)),n.doneAssets.add(a),He(n,s);let F=sr(u,k),I=[];if(F){let O=f.toString("utf8");I=Ke(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:Qt(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),He(n,s));}}async function Hi(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 Bi(e,t,n,a,r,s,i));}});await Promise.all(u);}function Wi(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 gt(e){return Math.max(15e3,Math.min(6e4,ue(e)))}function zi(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function tn(e){return e.stats.pagesCompleted}function Cr(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 Qi(e,t,n){let r=Cr(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 ${Wi(t)}.`));},t);})])}finally{r!==void 0&&globalThis.clearTimeout(r);}}async function Ji(e,t){let n=zi(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 Vi(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 Ji(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function Ki(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 Gi(e,t){return e.noJavaScriptRenderPathPrefixes.some(n=>Yt(t,n))}async function Zi(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 m of c){let f=p.getAttribute(m);f&&a.add(f);}for(let m of d){let f=p.getAttribute(m);f&&f.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 Oi(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 Ke(e,n,a,r,"dom-style"))i.add(c);}let o=await t.content();for(let u of Ke(e,n,o,r,"page-html"))i.add(u);return [...i]}async function or(e,t,n,r,s){let i=le(e,t);await Be(i,n,"utf8");let o=await T.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,tn(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 Yi(e){let t=tn(e);return t%5===0||t===1||t===e.stats.pagesQueued}function Xi(e,t){let n=tn(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 eo(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 to(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 eo(r),r}async function no(e,t,n,r,s,i,o){let u=await chromium.launch({headless:true}),a=Cr(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 m=en(e,c),f=Gi(e,p.pathname);if(!Se(p)||q(e,p)||$e(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 Je(h.outputPath)){i.seenPages.add(c);for(let y of h.discoveredAssets||[])J(e,t,y,n,c);G(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 oi(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 A of y.discoveredAssets)J(e,t,A,n,c);for(let A of y.discoveredPages)Ve(e,t,A,n,c);y.lastSeenRunId=i.runId,y.sitemapLastmod=We(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),()=>to(u,e,f)),d=await _(`create page ${c}`,ue(e),()=>l.newPage());let v=!1,k=new Set;await d.route("**/*",async y=>{let A=y.request();if(A.isNavigationRequest()&&A.frame()===d.mainFrame())try{let j=new URL(A.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:A.url()}),await y.abort("aborted");return}v=!0;}}catch{}await y.continue();}),d.on("response",y=>{try{let A=H(e,y.url(),e.sourceOrigin,n,"network-response");A&&q(e,A)&&(k.add(A.toString()),J(e,t,A.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 Gt(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(m){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 Gt(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}f?(n.info(`Rendering without JS execution for ${c}`,{url:c,mode:"no-js"}),await _(`wait for rendered page ${c}`,ue(e),()=>Ki(e,d))):await _(`wait for rendered page ${c}`,ue(e),()=>Vi(e,d)),t.stats.pagesRendered++;let I=await _(`extract rendered assets ${c}`,ue(e),()=>Zi(e,d,g,n,!f));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"&&!m?Ni(e,c,b,n):[];if(r!=="single-url"&&r!=="content-sync"&&!m)for(let y of P)Ve(e,t,y,n,c);await or(e,c,b,t,n);let C=le(e,c);if(G(o,e,C),Ce(o,C),i.trackManifest){let y=E?.headers();i.manifest.pages[c]={url:c,outputPath:C,contentType:Qt(y),changeToken:w.changeToken?.supported?w.changeToken.token:null,tokenSource:w.changeToken?.supported?w.changeToken.tokenSource??null:null,sitemapLastmod:We(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 or(e,c,g,t,n);let m=le(e,c);if(G(o,e,m),Ce(o,m),i.trackManifest){let f=i.manifest.pages[c]??i.previousManifest.pages[c];i.manifest.pages[c]={url:c,outputPath:m,contentType:f?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:We(t.sitemapLastmodByPage[c])??f?.sitemapLastmod??null,discoveredPages:f?.discoveredPages?[...f.discoveredPages]:[],discoveredAssets:f?.discoveredAssets?[...f.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++,Yi(t)&&Xi(t,n),d&&await _(`close page ${c}`,gt(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}`,gt(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",gt(e),()=>u.close()).catch(c=>(n.warn("Timed out while closing crawl worker browser",{browserPid:a.pid,error:String(c)}),Qi(u,n,"browser.close timeout")));}}async function ro(e){try{let t=await T.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 ar(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function so(e){let t=String(e?.job?.command||"").trim(),n=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:n!=="incremental"}function io(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 Rr(e){try{let t=await T.readFile(e,"utf8"),n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function cr(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function oo(e,t){let n=Array.isArray(t?.artifacts)?t.artifacts.filter(r=>String(r?.role||"").trim()==="errors"&&String(r?.storedFileName||"").trim()!=="").sort((r,s)=>cr(r)-cr(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 ur(e){let t=await Rr(S.join(e,"job.json"));for(let n of oo(e,t)){let r=await ro(n);if(r.length>0)return r}return []}async function ao(e){let t=S.join(e.logDir,"archive"),n;try{n=await T.readdir(t);}catch{return ""}let r="",s=0;for(let i of n){let o=S.join(t,i);if(!(await T.stat(o).catch(()=>null))?.isDirectory())continue;let a=await Rr(S.join(o,"job.json"));if(!so(a))continue;let c=io(a);c>=s&&(s=c,r=o);}return r}async function co(e){let t=await ao(e),n=t!==""?await ur(t):await ur(e.logDir),r=new Set;for(let s of n)if(ar(s.error)||ar(s.message)){let i=s.url;typeof i=="string"&&i&&r.add(i);}return [...r]}async function uo(e){let t=[];for(let n of e)if(n.startsWith("@")){let r=n.slice(1),s=await T.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 lo(e){if(!e)throw new Error("Content-sync crawl requires an immutable impact plan.");let t=JSON.parse(await T.readFile(e,"utf8"));return Le(t),t}function po(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 pt(e,t,n){let r=n==="page"?le(e,t):ht(e,t).originalFilePath;return he(e.outputDir,r)}async function Gt(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 T.rm(i.outputPath,{force:true}),n.deletedFiles.add(o)),delete t.manifest.pages[r];}function go(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{Ee(new URL(o))&&r.push(o);}catch{}}return n}async function mo(e,t,n,r,s){let i=go(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 T.rm(u.outputPath,{force:true}),r.deletedFiles.add(a),delete n.manifest.assets[o];}await we(e,n);}async function fo(e){try{let t=await T.readFile(S.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function ho(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 T.mkdir(e,{recursive:true}),await Promise.all(t.map(async n=>{try{await T.unlink(S.join(e,n));}catch(r){if(r.code!=="ENOENT")throw r}}));}function lr(e,t,n,r,s){let i=H(e,n,e.sourceOrigin,r,"manual-url");i&&(Ee(i)?ft(e,t,i.toString(),r,s):q(e,i)?J(e,t,i.toString(),r,s):Se(i)?Ve(e,t,i.toString(),r,s):r.reject("manual-url",i.toString(),"not page/sitemap/asset-like",s));}async function Ir(e=process.argv.slice(2)){let t=[],n=await ne(void 0,{onRemotePublisherConfigDiagnostic:P=>{t.push(P);}}),r=t.at(-1)??null,s=Js(e),i=s.mode==="content-sync"?await lo(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 co(n)),s.mode==="single-url"&&(o=await uo(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 fo(n):{},p=a||s.mode==="single-url"||s.mode==="content-sync"?await Xs(n):mr(),g=new Set(o),m=new Set;if(i){for(let P of i.archiveFamilies)if(P.foundPosts===0)for(let C of P.pageUrls)m.add(C);for(let P of Object.keys(p.pages))po(P,i)&&!g.has(P)&&(o.push(P),m.add(P));}let f={enabled:a,trackManifest:c,manifest:Jt(p),previousManifest:Jt(p),runId:i?.jobId??`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve(),strictTargeted:!!i,requiredUrls:g,deleteOnMissingUrls:m};await ho(n.logDir);let h=new ut(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=Ys();if(await Te(n),await Ln(n,{startedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir)}),l||await T.rm(n.outputDir,{recursive:true,force:true}),await T.mkdir(n.outputDir,{recursive:true}),i){let P=new Set([...i.deleteUrls,...f.deleteOnMissingUrls]);for(let C of i.deleteUrls)await Gt(n,f,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=>ft(n,w,y,h)),await ir(n,P,w,h,v,f),n.seedPaths.forEach(y=>lr(n,w,y,h,"seed-path")),n.generated404RequestPath&&Ve(n,w,n.generated404RequestPath,h,"generated-404-request-path")):(o.forEach(y=>lr(n,w,y,h,"cli")),i?.sitemapUrls.forEach(y=>ft(n,w,y,h,"content-sync-impact")),await ir(n,P,w,h,v,f,s.mode==="content-sync"),i&&await mo(n,w,f,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)},()=>no(n,w,h,s.mode,P,f,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 Hi(n,P,w,h,f,v),h.endMark("download-assets",{assets:w.doneAssets.size}),f.enabled&&n.maxPages===0&&await ci(n,w,f,h,v),s.mode==="full"){let y=await _i(n,w,h);for(let A of y)G(v,n,A);}}finally{await _("dispose crawl request context",gt(n),()=>P.dispose()).catch(C=>{h.warn("Timed out while disposing crawl request context",{error:String(C)});});}}f.trackManifest&&await we(n,f),await T.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)&&G(v,n,S.join(n.outputDir,"asset-map.json"));let k=s.mode==="single-url"||s.mode==="content-sync"?wi(n,w):f.enabled&&!s.resumeRewrite?ui(n,f,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 rr(E);let F=Date.now(),I=await ot(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:A,changed:j})=>{j&&G(v,n,S.join(n.outputDir,A)),h.checkpoint(`Rewriting text file ${P}/${C}`,{phase:"rewrite-text",index:P,totalFiles:C,changedTextFiles:y,file:A}),h.debug(`${j?"Rewrote":"Checked unchanged"} text file ${P}/${C}: ${A}`,{phase:"rewrite-text",index:P,totalFiles:C,changedTextFiles:y,file:A,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:A}),await rr(B);}});f.trackManifest&&(li(f,k),await we(n,f)),h.endMark("rewrite-text",{changedTextFiles:I});let O=i?[...v.deletedFiles].sort():f.enabled&&!s.resumeRewrite?await pi(n,w,f,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($=>pt(n,$,"page")).filter($=>!!$&&C.has($))),A=new Set(i.archiveFamilyUrls.map($=>pt(n,$,"page")).filter($=>!!$&&C.has($))),j=new Set([...w.sitemapLeafUrls].map($=>pt(n,$,"asset")).filter($=>!!$&&C.has($))),U=new Set([...w.sitemapIndexUrls].map($=>pt(n,$,"asset")).filter($=>!!$&&C.has($))),V=new Set([...y,...A,...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 Ut(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:[...A].sort(),sitemapLeaves:[...j].sort(),sitemapIndexes:[...U].reverse()},invalidationPaths:K});}else await Ut(n,{schemaVersion:1,generatedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir),runMode:s.mode,crawlMode:s.crawlMode,fullSyncRequired:!(f.enabled&&!s.resumeRewrite),changedFiles:f.enabled&&!s.resumeRewrite?[...v.changedFiles].sort():[],deletedFiles:f.enabled&&!s.resumeRewrite?O:[],rewriteTargets:f.enabled&&!s.resumeRewrite?b:[]});await qn(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 wo(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 Z(e,t,n){let r=new AbortController,s=globalThis.setTimeout(()=>{r.abort(new Error(`${e} timed out after ${wo(t)}.`));},t);try{return await n({abortController:r,httpOptions:{abortSignal:r.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(s);}}function yo(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function wt(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 So(e,t){return {...e,...t??{}}}function Po(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function Me(e,t){let n=String(t??e.deploymentTargetOverride??"").trim();if(!yo(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:So(e.s3,s.s3),cloudFront:Po(e.cloudFront,s.cloudFront)}}}var kr="wpsuite-sha256",$r="wpsuite-normalized-sha256",ko=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,cn=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,$o=["SIGINT","SIGTERM"],Pt=new Set,yt=new Map,Ar=null;function Eo(e){Pt.add(e);let t=false;return ()=>{t||(t=true,Pt.delete(e));}}async function Mo(){let e=[...Pt];e.length!==0&&await Promise.allSettled(e.map(async t=>{Pt.delete(t),await T.rm(t,{recursive:true,force:true});}));}function Fo(){if(!(yt.size>0))for(let e of $o){let t=()=>{Ar||(Ar=Mo().finally(()=>{for(let[n,r]of yt)process.off(n,r);yt.clear(),process.exit(1);}));};yt.set(e,t),process.on(e,t);}}Fo();function Do(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 Er(e){return S.normalize(e).split(S.sep).join("/")}function Tr(e,t){let n=S.relative(S.resolve(e),S.resolve(t));return !n||n.startsWith("..")||S.isAbsolute(n)?null:Er(n)}async function Oo(e,t,n){let r=Do(e.outputDir,t),s;try{s=await T.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?Tr(e.outputDir,p):null;if(g){let m=typeof d?.contentType=="string"&&d.contentType?d.contentType:null;m&&u.set(g,m);}!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,m=p?Tr(e.outputDir,p):null;if(m){let f=typeof d?.contentType=="string"&&d.contentType?d.contentType:null;f&&u.set(m,f);}!p||!g||d?.rewriteComplete===true||m&&(c++,o.has(m)||o.set(m,{kind:"asset",sourceUrl:l,outputPath:S.resolve(p),relativePath:m}));}return {manifestPath:r,byRelativePath:o,contentTypeByRelativePath:u,pendingPages:a,pendingTextAssets:c}}function jo(e){return e&&(cn.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 rn(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,n)=>n%2===1?t:jo(t)).join("")}function Lo(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,n)=>n%2===1?t:cn.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 bt(e,t){return Array.isArray(e)?e.map(n=>bt(n,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,bt(r,n)])):typeof e!="string"?e:t&&ko.test(t)?Lo(e):cn.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?rn(e):e}function Uo(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function qo(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(bt(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(bt(i));return Buffer.from(o,"utf8").toString("base64")}catch{}return t}function _o(e,t){let n=e.toLowerCase();return n==="class"?t.split(/(\s+)/).map((r,s)=>s%2===1?r:rn(r)).join(""):n==="id"||n==="for"||n==="aria-controls"||n==="aria-labelledby"||n==="aria-describedby"||n==="aria-owns"||n==="aria-activedescendant"||n==="name"?rn(t):n==="href"||n==="src"?Uo(t):qo(n,t)}function No(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=_o(o,a);return ` ${o}=${u}${c}${u}`});return `<${n}${s}>`})}function nn(e){let t=S.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(S.basename(e))}function St(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function Bo(e,t,n,r){let s=new Map,i,o=0;do{o++;let u=await Z(`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 Ho(e,t,n,r){if(r.has(n))return r.get(n)??null;try{let s=await Z(`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 Wo(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 Z(`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 zo(e){return createHash("md5").update(e).digest("hex")}function xr(e){return createHash("sha256").update(e).digest("hex")}function sn(e){return createHash("sha256").update(No(e.toString("utf8"))).digest("hex")}async function Qo(e,t,n,r){if(r.has(n))return r.get(n)??null;try{let o=((await Z(`S3 head object metadata ${n}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),u))).Metadata?.[kr]||"").trim().toLowerCase()||null;return r.set(n,o),o}catch{return r.set(n,null),null}}async function Jo(e,t,n,r,s){if(r.has(n))return r.get(n)??null;try{let o=((await Z(`S3 head object normalized metadata ${n}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),u))).Metadata?.[$r]||"").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 Z(`S3 get object ${n}`,3e5,({httpOptions:a})=>e.send(new GetObjectCommand({Bucket:t,Key:n}),a))).Body?.transformToByteArray(),u=o?sn(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 Vo(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function Ko(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 Go(e,t,n,r){let s=S.join(e,"asset-map.json"),i;try{i=await T.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=Ko(l,r),[a,l]}));await T.writeFile(s,JSON.stringify(u,null,2),"utf8");}async function Zo(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-${Vo(n)}-${Date.now()}`),c=Eo(a);s.info(`Preparing deployment profile "${n}" from existing crawl output to ${a}...`);try{if(await T.rm(a,{recursive:!0,force:!0}),i){await T.mkdir(a,{recursive:!0});for(let g of i){let m=S.join(e.outputDir,g),f=S.join(a,g);await T.mkdir(S.dirname(f),{recursive:!0}),await T.copyFile(m,f);}}else await T.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 ot(l,{},{files:i,onStart:({totalFiles:g,workerCount:m})=>{d=m,s.info(`Rewriting ${g} text file(s) for deployment profile "${n}" with ${m} worker(s).`);},onProgress:({index:g,totalFiles:m,changedTextFiles:f,file:h,changed:w})=>{let k=`Rewriting [${g}/${m}] ${h} (${w?"rewrote":"checked"}; ${f} changed so far)`;m<=200||g<=5||g%10===0||g===m?(s.progress(k,{file:h,index:g,totalFiles:m,changed:w,changedTextFiles:f,workerCount:d}),s.info(k)):s.debug(k);}});return await Go(a,e,t,r),s.info(`Prepared deployment profile "${n}" in ${a} (${p} rewritten text file(s)).`),{outputDir:a,cleanup:async()=>{c(),await T.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 T.rm(a,{recursive:true,force:true}).catch(()=>{}),c(),await s.flush().catch(()=>{}),l}}async function Mr(e=process.argv.slice(2)){let t=await ne(),n=wt(e),r=Me(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 ke(s,"deploy.log.jsonl",r.config.logLevel??"info"),a=r.profile?.extraReplacements??{},c=async()=>{};try{let l=await rt(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 Un(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 Zo(t,r.config,r.name,a,u,l?.schemaVersion===2?l.changedFiles:void 0);c=g.cleanup;let m={...r.config,outputDir:g.outputDir},f=m.s3SyncMode??"sdk-upload-delete";if(l?.schemaVersion===2&&l.deletedFiles.length>0&&f!=="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://${m.s3.bucket}/${m.s3.prefix||""} (region: ${m.s3.region})`),u.info(`S3 sync mode: ${f}`),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:m.s3.region}),k=g.outputDir===t.outputDir?await Oo(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 x=[...new Set(E)],W=[...new Set(l.changedFiles)];if(x.length!==W.length||W.some(R=>!x.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 x=>{try{return (await T.stat(S.join(m.outputDir,x))).isFile()?x:null}catch{if(l?.schemaVersion===2)throw new Error(`Content-sync planned upload is missing: ${x}`);return null}}))).filter(x=>x!==null):await ys(["**/*"],{cwd:m.outputDir,onlyFiles:!0,dot:!0}),I=[],O=[],b=F.filter(x=>{let W=k?.byRelativePath.get(Er(x));if(!W)return !0;let R=St(m.s3.prefix,x);return I.push(x),O.push(R),u.reject(W.kind,W.sourceUrl||x,"rewrite not completed; deploy upload blocked","deploy-guard",{file:x,key:R,outputPath:W.outputPath,manifestPath:k?.manifestPath}),!1}),P=new Set((w?b:F).map(x=>St(m.s3.prefix,x)));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 "${m.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:f,totalFiles:b.length,scannedFiles:F.length,rejected:I.length,deploymentProfile:r.name||"",s3Bucket:m.s3.bucket,s3Prefix:m.s3.prefix||"",targetedPlan:w,deployGuardEnabled:g.outputDir===t.outputDir});let C=0,y=0,A=0,j=[],U=[],V=[],B=[],K=[],$=new Map,Ye=new Map,Ur=new Map,qr=new Map,_r=new Map;w||(u.info("Listing existing S3 objects to detect unchanged files..."),$=await Bo(v,m.s3.bucket,m.s3.prefix,u),u.info(`Found ${$.size} existing key(s) in S3.`));let Nr=async x=>$.has(x)?$.get(x)??null:w?Ho(v,m.s3.bucket,x,Ye):null;for(let x of b){let W=S.join(m.outputDir,x),R=St(m.s3.prefix,x),X=k?.contentTypeByRelativePath.get(x),Fe=X&&X!=="application/octet-stream"?X:xo.lookup(x)||X||"application/octet-stream",Br=nn(x)?m.s3.htmlCacheControl:m.s3.assetCacheControl,L=C+y+A+1;b.length<=200||L<=5||L%10===0||L===b.length?(u.progress(`Uploading [${L}/${b.length}] ${R} (${Fe})`,{file:x,key:R,index:L,totalFiles:b.length,contentType:Fe,mode:f}),u.info(`Uploading [${L}/${b.length}] ${R} (${Fe})`)):u.debug(`Uploading [${L}/${b.length}] ${R} (${Fe})`);try{let ee=await T.readFile(W),De=await Nr(R),Oe=null,Ie=null;if(De){let Ct=ee.byteLength;if(De.size===Ct){let Xe=De.etag.includes("-");if(De.etag!==""&&!Xe){let Hr=zo(ee);if(De.etag===Hr){y++,b.length<=200||y<=5||y%25===0?(u.progress(`Skipped unchanged [${L}/${b.length}] ${R}`,{file:x,key:R,index:L,totalFiles:b.length,uploaded:C,skipped:y,failed:A,mode:f,reason:"etag-md5-match"}),u.info(`Skipped unchanged [${L}/${b.length}] ${R}`)):u.debug(`Skipped unchanged [${L}/${b.length}] ${R}`),U.push(R);continue}}Oe=xr(ee);let mn=await Qo(v,m.s3.bucket,R,Ur);if(mn&&mn===Oe){y++,b.length<=200||y<=5||y%25===0?(u.progress(`Skipped unchanged [${L}/${b.length}] ${R}`,{file:x,key:R,index:L,totalFiles:b.length,uploaded:C,skipped:y,failed:A,mode:f,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(nn(x)){Ie=sn(ee);let Xe=await Jo(v,m.s3.bucket,R,qr,_r);if(Xe&&Xe===Ie){y++,b.length<=200||y<=5||y%25===0?(u.progress(`Skipped semantically unchanged [${L}/${b.length}] ${R}`,{file:x,key:R,index:L,totalFiles:b.length,uploaded:C,skipped:y,failed:A,mode:f,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}}}Oe=Oe??xr(ee),Ie=Ie??(nn(x)?sn(ee):null),await Z(`S3 upload ${R}`,9e5,({abortController:Ct})=>new Upload({client:v,abortController:Ct,params:{Bucket:m.s3.bucket,Key:R,Body:ee,ContentType:Fe,CacheControl:Br,Metadata:{[kr]:Oe,...Ie?{[$r]: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:A,totalFiles:b.length,mode:f}),u.info(`Uploaded ${C}/${b.length} file(s)\u2026`));}catch(ee){A++,V.push(R),u.error(`Failed to upload ${R}: ${ee.message}`,{key:R,error:String(ee)});}}if(u.info(`Upload complete: ${C} uploaded, ${y} skipped unchanged, ${O.length} rejected by guard, ${A} 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(f==="sdk-upload-delete"){let x=new Set((l?.deletedFiles??[]).map(R=>St(m.s3.prefix,R))),W=[...x].filter(R=>!P.has(R));if(!w&&(K=[...$.keys()].filter(X=>!P.has(X)).filter(X=>!x.has(X)),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 X of K)u.debug(` protected remote-only object: ${X}`);}B=await Wo(v,m.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 T.mkdir(S.dirname(o),{recursive:!0}),await T.writeFile(o,JSON.stringify({generatedAt:new Date().toISOString(),mode:f,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 ea(){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 un(e,t){if(!e)return;await T.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await T.writeFile(n,JSON.stringify({...t,updatedAt:new Date().toISOString()},null,2),"utf8"),await T.rename(n,e);}async function ta(e,t,n){if(!e)return null;try{let r=JSON.parse(await T.readFile(e,"utf8"));if(r.schemaVersion!==1||r.distributionId!==t||r.impactHash!==n||!Array.isArray(r.batches))throw new Error("Content-sync invalidation state does not match the deploy plan.");return r}catch(r){if(r.code==="ENOENT")return null;throw r}}function na(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 Dr(e=process.argv.slice(2)){let t=await ne(),n=wt(e),r=Me(t,n),s=r.config,i=new ke(s.logDir||"logs","invalidate.log.jsonl",s.logLevel??"info"),o=e.includes("--content-sync"),u=await rt(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:["/*"];if(u?.schemaVersion===2&&a.some(g=>g==="/*"))throw new Error("Content-sync cannot use a whole-distribution invalidation.");if(a.length===0){i.info("The targeted deploy plan has no CloudFront paths to invalidate."),await i.flush();return}let c=s.cloudFront.distributionId,l=new CloudFrontClient({region:"us-east-1",maxAttempts:5});if(i.mark("invalidate"),u?.schemaVersion!==2){let g=`smartcloud-static-publisher-${Date.now()}`;await Z(`CloudFront invalidation for distribution ${c}`,3e5,({httpOptions:m})=>l.send(new CreateInvalidationCommand({DistributionId:c,InvalidationBatch:{CallerReference:g,Paths:{Quantity:a.length,Items:a}}}),m)),i.endMark("invalidate"),await i.flush();return}let d=ea(),p=await ta(d,c,u.impactHash);p||(p={schemaVersion:1,distributionId:c,impactHash:u.impactHash,updatedAt:new Date().toISOString(),batches:na(a).map((g,m)=>({index:m,callerReference:`wpsuite-content-sync-${u.impactHash.slice(0,32)}-${m}`,paths:g,invalidationId:null,status:"pending"}))},await un(d,p));for(let g of p.batches){if(!g.invalidationId){let m=await Z(`CloudFront targeted invalidation batch ${g.index+1}`,3e5,({httpOptions:h})=>l.send(new CreateInvalidationCommand({DistributionId:c,InvalidationBatch:{CallerReference:g.callerReference,Paths:{Quantity:g.paths.length,Items:g.paths}}}),h)),f=String(m.Invalidation?.Id||"").trim();if(!f)throw new Error("CloudFront did not return an invalidation ID.");g.invalidationId=f,g.status="created",await un(d,p);}await waitUntilInvalidationCompleted({client:l,maxWaitTime:900,minDelay:2,maxDelay:15},{DistributionId:c,Id:g.invalidationId}),g.status="completed",await un(d,p),i.info(`CloudFront invalidation batch ${g.index+1}/${p.batches.length} completed.`,{invalidationId:g.invalidationId,pathCount:g.paths.length});}i.endMark("invalidate"),await i.flush();}var jr=["claimed","impact-planned","rendered","deployed","invalidated","verified","acknowledged"];function pn(){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 Ge(e,t){return jr.indexOf(e)>=jr.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 T.mkdir(e,{recursive:true}),await T.appendFile(S.join(e,"audit-events.jsonl"),`${JSON.stringify(i)}
|
|
11
|
-
`,"utf8");}function sa(e){return je({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 ia(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 gn(e,t){if(e.subscriptionType!=="PROFESSIONAL"&&e.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let n=sa(t),r=Me(e,t.deploymentProfile),s=r.name||"",i=hn(e.sourceOrigin,String(t.id||""),n),o=wn({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=yn({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=oe({schemaVersion:1,wordpressFingerprint:l,targetFingerprint:o,sourceOrigin:e.sourceOrigin,sitemapPaths:[...e.sitemapPaths].sort(),blockedPathPrefixes:[...e.blockedPathPrefixes].sort(),assetPathPrefixes:[...e.assetPathPrefixes].sort(),noJavaScriptRenderPathPrefixes:[...e.noJavaScriptRenderPathPrefixes].sort(),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 oa(e){let t=pn(),n=nt(t),r=await ne(),s=(r.scheduler?.rules??[]).filter(a=>a.command==="content-sync"&&a.enabled!==false);if(s.length===0)return 0;let i=await xt(n),o=await Tt(n),u=0;for(let a of s){let c=await gn(r,a),l=o.entries[c.coalesceKey];if(!l||l.releaseJobId!==e||l.scopeFingerprint!==c.scopeFingerprint||l.targetFingerprint!==c.targetFingerprint||l.releaseFingerprint!==c.releaseFingerprint)throw new Error(`The normal release has no matching pre-crawl content-sync cutoff for rule ${String(a.id||"")}.`);let d=oe({releaseJobId:e,releaseFingerprint:c.releaseFingerprint,scopeFingerprint:c.scopeFingerprint,targetFingerprint:c.targetFingerprint,sequence:l.sequence}),p=await c.client.establishBaseline({consumerId:c.consumerId,scopeFingerprint:c.scopeFingerprint,baselineId:d,postTypes:c.scope.postTypes,sequence:l.sequence}),g={schemaVersion:1,ruleId:String(a.id||""),consumerId:c.consumerId,coalesceKey:c.coalesceKey,scopeFingerprint:c.scopeFingerprint,targetFingerprint:c.targetFingerprint,releaseFingerprint:c.releaseFingerprint,baselineId:d,deploymentProfile:c.deploymentProfile,committedSequence:p.committedSequence,releaseJobId:e,verifiedAt:new Date().toISOString()};i.entries[c.coalesceKey]=g,await pe(t,"content-sync-baseline-established",{id:e},"A normal release established a verified content-sync baseline.",{ruleId:a.id,consumerId:c.consumerId,committedSequence:p.committedSequence}),u++;}return await Cn(n,i),await T.rm(n.releaseCutoff,{force:true}),u}async function aa(e){let t=pn(),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 Tt(n),o=0;for(let u of s){let a=await gn(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 vn(n,i),o}async function ca(e,t){let n=JSON.parse(await T.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 dn(e,t,n=0){let r=e.protocol==="https:"?bn:Vr,s=e.protocol==="https:"?new bn.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(),dn(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 ua(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 dn(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 dn(u,e.ignoreHttpsErrors);if(a.status>=200&&a.status<300)throw new Error(`Deleted content is still publicly available: ${u}`)}}async function la(e){let t=await T.readFile(e.candidateManifest,"utf8");JSON.parse(t);let n=`${e.trustedManifest}.${process.pid}.tmp`;await T.writeFile(n,t,"utf8"),await T.rename(n,e.trustedManifest);}async function da(e,t){try{let n=JSON.parse(await T.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 T.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 In(e,t),await xn(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 pa(e){let t=pn(),n=nt(t),r=await ca(t,e),s=await ne(),i=ia(s,String(r.ruleId)),o=await gn(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 xt(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 Rn(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 f=await kt(n);f.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 $t(n,f),await Et(n);return}let d=await An(n);if(!Ge(c.phase,"impact-planned")){let f=await o.client.events({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:a.baselineId,postTypes:o.scope.postTypes,afterSequence:c.fromSequence,throughSequence:c.toSequence}),h=At({events:f,scope:o.scope,sourceOrigin:s.sourceOrigin}),w=await o.client.resolveImpactFamilies(h);d=Pn({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:f,resolvedArchiveFamilies:w,sitemapUrls:s.sitemapPaths}),await Tn(n,d),c.impactHash=d.impactHash,await Re(n,c,"impact-planned",f.length,{eventCount:f.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:f.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,!Ge(c.phase,"rendered")){let f=await da(n,r.id);await pe(t,f==="resumed"?"content-sync-render-resumed":"content-sync-render-initialized",r,f==="resumed"?"Content-sync resumed its candidate crawl manifest.":"Content-sync initialized a candidate crawl manifest.",{impactHash:d.impactHash}),await Ir(["--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(Ge(c.phase,"deployed")||(await Mr([...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})),Ge(c.phase,"invalidated")||(await Dr([...p,"--content-sync"]),await Re(n,c,"invalidated",1,{impactHash:d.impactHash})),Ge(c.phase,"verified")||(await ua(s,o,d),await la(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}),m=await kt(n);m.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 $t(n,m),await Te(s),await T.rm(S.join(t,"content-sync-invalidation.json"),{force:true}),await T.rm(n.candidateManifest,{force:true}),await Et(n);}async function Lr(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 aa(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 oa(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 pa(i);}Lr().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 ci(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 c=await zt(e,t,r,s,i);if(c?.supported&&c.token)return u.changeToken===c.token?o&&!await ui(e,t,s,i)?{action:"render",changeToken:c}:{action:"reuse",changeToken:c}:{action:"render",changeToken:c};let a=ze(n.sitemapLastmodByPage[s]);return a&&u.sitemapLastmod&&u.sitemapLastmod===a?{action:"reuse",changeToken:c}:{action:"render",changeToken:c}}async function ui(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 li(e,t,n,r,s){let i=rr(n.previousManifest,void 0,r,"previous-manifest"),o=0;for(let[p,f]of Object.entries(n.manifest.pages))if(!n.seenPages.has(p)){nr(s,e,f.outputPath);try{await A.unlink(f.outputPath);}catch(g){(g.code||"")!=="ENOENT"&&r.warn(`Failed to remove stale incremental page output for ${p}`,{url:p,outputPath:f.outputPath,error:String(g)});}delete n.manifest.pages[p],o++;}let u=rr(n.manifest,n.runId,r,"active-manifest"),c=new Set,a=new Set;for(let p of u){for(let m of Qe(e,p))c.add(m);let f=n.manifest.assets[p]?.outputPath;f&&a.add(f);let g=Je(e,t.assetMap,p);g&&a.add(g);}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 f=new Set,g=n.previousManifest.assets[p]?.outputPath;g&&f.add(g);let m=Je(e,t.assetMap,p);if(!u.has(p)&&m)f.add(m);else if(!u.has(p)){let h=Ai(e,p,r,"incremental-cleanup");h&&(f.add(h.originalFilePath),h.hashedFilePath&&f.add(h.hashedFilePath));}for(let h of f)if(!a.has(h)){nr(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))c.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 rr(e,t,n,r){let s=new Set,i=o=>{let u=o.trim();if(u){if(n){let c=ye(u,n,"asset",r??"manifest");if(!c)return;s.add(c.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 sr(e,t,n){for(let r of t)for(let s of Qe(e,r))if(n.has(s))return true;return false}function di(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=ri(r,s);if(o.size===0)return [...i];for(let u of Object.values(t.manifest.pages))sr(e,u.discoveredAssets,o)&&i.add(S.resolve(u.outputPath));for(let[u,c]of Object.entries(t.manifest.assets)){c.isText&&sr(e,c.discoveredAssets,o)&&i.add(S.resolve(c.outputPath));for(let a of Qe(e,u))if(o.has(a)){Z(n,e,c.outputPath),c.isText&&i.add(S.resolve(c.outputPath));break}}return [...i]}function pi(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 gi(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 fi(e,t,n,r,s){let i=[...r.deletedFiles].sort(),o=gi(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 c=[],a=0;for(let l of i){if(!o.has(l)){c.push(l);continue}a++;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 a>0&&s.info(`Deploy plan skipped ${a} active output deletion(s).`,{phase:"deploy-plan",protectedDeletes:a,deletedFiles:c.length}),c}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 mi(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 wr(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 hi(e,t,n){for(let r of mi(e,n)){let s=t[r];if(!s)continue;let i=wr(e,s);if(i)return {outputPath:i,publicUrl:s}}return null}function wi(e,t,n){for(let r of Qe(e,n)){let s=t[r];if(!s)continue;let i=wr(e,s);if(i)return i}return null}function Je(e,t,n){let r=wi(e,t,n);if(r)return r;try{return ht(e,n).originalFilePath}catch{return null}}function yi(){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 ir(e){let t=yi();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 Si(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 ft="re:",dt=new Map;function Pi(e){if(!e.startsWith(ft))return null;let t=dt.get(e);if(t!==void 0)return t||null;let n=e.slice(ft.length).trim();if(!n)return dt.set(e,false),null;try{let r=new RegExp(n);return dt.set(e,r),r}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),dt.set(e,false),null}}function Xt(e,t){let n=Pi(t);return n?n.test(e):t.startsWith(ft)?false:e.startsWith(t)}function bi(e,t){return t.find(n=>Xt(e,n))}function yr(e,t){let n=bi(t.pathname,e.blockedPathPrefixes);if(n)return n.startsWith(ft)?`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 vi(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 Ci(e,t){return vi(e).has(t.hostname)}function Ri(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 Ii(e){let t=ce(e).replace(/\\\//g,"/").trim(),n=S.extname(t).toLowerCase();return gr.has(n)||fr.has(n)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function Ee(e){return Vs.some(t=>e.pathname.startsWith(t))}function H(e,t,n=e.sourceOrigin,r,s="url"){let i=Ri(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(Ii(i))return r?.ignore(s,t,"looks like JavaScript property access",n),null;try{let o=new URL(i,n);if(Sr(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(!Ci(e,o))return r?.ignore(s,o.toString(),"host not allowed",n),null;let u=yr(e,o);if(u)return r?.reject(s,o.toString(),u,n),null;let c=new URL(e.sourceOrigin);return o.protocol=c.protocol,o.host=c.host,o.hash="",o}catch{return r?.reject(s,t,"invalid URL",n),null}}function Sr(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 Sr(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 Pr(e){return gr.has(S.extname(e.pathname).toLowerCase())}function Se(e){return Ee(e)?false:fr.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))||Pr(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 xi(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=xi(e);if(!n)return false;try{return new URL(t,e.sourceOrigin).toString()===n}catch{return false}}function ht(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),c=`${u}${n.search}`;if(!s)return {originalPathname:i,originalFilePath:o,originalPublicUrl:u,originalPublicUrlWithSearch:c,preferQueryHashed:s};let a=S.extname(r),d=`${a?r.slice(0,-a.length):r}.${Be(n.search)}${a||".bin"}`;return {originalPathname:i,originalFilePath:o,originalPublicUrl:u,originalPublicUrlWithSearch:c,preferQueryHashed:s,hashedPathname:d,hashedFilePath:S.join(e.outputDir,d),hashedPublicUrl:_t(e.targetOrigin,d)}}function Ai(e,t,n,r){let s=ye(t,n,"asset",r);return s?ht(e,s.toString()):null}function Ti(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 c of u)try{let a=new URL(c);t[a.origin+i.pathname+i.search]=r;}catch{}try{let c=(()=>{let a=new URL(r,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin);return `${a.pathname}${a.search}`})();t[i.pathname+i.search]=c;}catch{}try{let c=new URL(r,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=c;}catch{}try{let c=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=c;}catch{}}catch{}}async function br(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 ki(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 vr(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let n=Date.parse(t);return Number.isFinite(n)?n:null}function $i(e,t){let n=vr(t),r=ki(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 Ei(e,t){if(!t)return;let n=vr(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 or(e,t){let n=S.extname(e.pathname).toLowerCase(),r=t["content-type"]||"";return Js.has(n)||Qs.some(s=>r.includes(s))&&!r.startsWith("image/")&&!r.includes("font")}function Mi(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 Fi(e){return Be(e.toString("base64"),40)}function Di(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 Oi(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=ht(e,n),c=Fi(r),a=u.originalFilePath,l=u.originalPublicUrlWithSearch;if(u.preferQueryHashed&&u.hashedFilePath&&u.hashedPublicUrl&&Di(s,u.originalFilePath,c)){let g=hi(e,t,n);g?(a=g.outputPath,l=g.publicUrl):(a=u.hashedFilePath,l=u.hashedPublicUrl);}Ti(e,t,n,l,u.originalPublicUrl);let d=be(a)?Buffer.from(Ht(r.toString("utf8"),e,t,a),"utf8"):r,p=await br(a),f=false;return (p===null||!p.equals(d))&&(await He(a,d),f=true),i?.debug(`${f?"Saved":"Skipped unchanged"} asset output ${n}`,{phase:"download-assets",url:n,outputPath:a,bytes:d.length,wroteFile:f}),Oi(s,u.originalFilePath,c),await Ei(a,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:a,publicUrl:l,wroteFile:f}}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)||Pr(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 c=u.toString(),{discoveredFrom:a,discoveredFromType:l}=i();a&&!t.pageDiscoverySources.has(c)&&t.pageDiscoverySources.set(c,a),!t.donePages.has(c)&&!t.queuedPages.has(c)&&(t.queuedPages.add(c),t.pageQueue.push(c),t.stats.pagesQueued++,r.debug(`Queued discovered page ${c}`,{phase:"discovery",url:c,discoveredFrom:a,discoveredFromType:l,outputPath:le(e,c)}),(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 mt(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 ji(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 Li(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function Ui(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 qi(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function _i(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 Cr(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),c=S.join(t,o.name);if(o.isDirectory()){s.push(...await Cr(u,c,n,r));continue}await Rr(u,c,n,r)&&s.push(c);}return s}async function Ni(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 Rr(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 Ni(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 Bi(e,t,n){let r=Object.entries(e.postCrawlCopyMap||{}).map(([u,c])=>({sourcePath:u.trim(),prefix:String(c||"").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 c=u.sourcePath,a=u.prefix;if(!c||!a){n.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:c,prefixPath:a});continue}let l=Ys(c);if(!l.resolvedPath){n.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:c,alias:l.alias||"",requiredEnv:l.requiredEnv||"",prefixPath:a});continue}let d=l.resolvedPath,p=Qt(a);if(!p){n.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:c,prefixPath:a});continue}let f;try{f=await A.stat(d);}catch{n.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:c,sourceAbs:d,prefixPath:a});continue}let g=S.resolve(e.outputDir,p);if(f.isDirectory()){let v=await Cr(d,g,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=a.endsWith("/")?S.join(g,m):g;await Rr(d,h,o,n)&&(i.push(h),s++,n.progress(`Copied static file to export: ${d} -> /${Qt(a.endsWith("/")?`${a}${m}`:a)}`,{phase:"copy-extra-paths",sourcePath:d,targetPath:`/${Qt(a.endsWith("/")?`${a}${m}`:a)}`,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"?qi(o):o,c=_i(t,s);if(c){for(let l of Ui(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(c||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 a=new RegExp(`(?:https?:)?//[^\\s'"<>\\);]+\\.${Wt}(?:\\?[^\\s'"<>\\);]*)?|(?<!\\.)/[^\\s'"<>\\);]+\\.${Wt}(?:\\?[^\\s'"<>\\);]*)?`,"gi");if(s==="page-html")for(let l of o.matchAll(a)){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"&&Mi(t))for(let l of er(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 Hi(e,t,n,r){let s=new Set,i=ce(n);for(let o of i.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let u=o[1],c=H(e,u,t,r,"page-link");c&&(yr(e,c)||Se(c)&&!Ee(c)&&!q(e,c)&&s.add(c.toString()));}return [...s]}async function ar(e,t,n,r,s,i,o=false){let u=new Map,c=(a,l)=>{let d=[l],p=new Set;for(;d.length>0;){let f=d.pop();if(f===a)return true;p.has(f)||(p.add(f),d.push(...u.get(f)??[]));}return false};for(;n.sitemapQueue.length>0;){let a=n.sitemapQueue.shift();n.queuedSitemaps.delete(a);let l=ye(a,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 f=await p.body(),g=p.url()||d,m=ye(g,r,"sitemap-response",d);if(!m)continue;let h=m.toString(),w=await Gt(e,n.assetMap,h,f,n,r);Z(s,e,w.outputPath),Ce(s,w.outputPath);let v=f.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 ji(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(c(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()),mt(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 Wi(e,t,n,r,s,i,o){let u=H(e,r,e.sourceOrigin,s,"asset-fetch");if(!u||!q(e,u))return;let c=u.toString();if(n.doneAssets.has(c))return;let a=i.enabled||i.strictTargeted?i.previousManifest.assets[c]:void 0,l=i.strictTargeted?i.manifest.assets[c]:void 0;if(l?.lastSeenRunId===i.runId&&await Ve(l.outputPath)){n.doneAssets.add(c);for(let p of l.discoveredAssets||[])J(e,n,p,s,c);Z(o,e,l.outputPath),l.isText&&Ce(o,l.outputPath),s.info(`Resumed completed content-sync asset ${c}`,{url:c,source:"content-sync-checkpoint"}),We(n,s);return}let d=(p,f={})=>{if(!a||i.strictTargeted)return false;i.manifest.assets[c]={...a,discoveredAssets:[...a.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId},delete i.manifest.pages[c],n.doneAssets.add(c);for(let g of a.discoveredAssets||[])J(e,n,g,s,c);return s.warn(`Keeping previous incremental asset ${c} after fetch issue.`,{url:c,reason:p,preservedFromPreviousManifest:true,...f,phase:"download-assets"}),We(n,s),true};s.asset(`Fetching asset ${c}`,{url:c});try{let p=Je(e,n.assetMap,c),f=p?await Ve(p):null;if(p&&f)try{let O=await _(`fetch asset headers ${c}`,6e4,()=>t.head(c,{timeout:6e4})),b=O.headers();if(O.ok()&&$i(f,b)){let P=await br(p);if(P!==null){let C=O.url()||c,y=ye(C,s,"asset-response",c);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(c),s.info(`Reused existing asset ${c} based on response headers.`,{url:c,filePath:p,lastModified:b["last-modified"]||"",contentLength:b["content-length"]||"",phase:"download-assets"}),We(n,s);let U=or(u,b),V=a?.discoveredAssets?[...a.discoveredAssets]:[];if(U||a?.isText){let B=P.toString("utf8"),K=Ge(e,x,B,s,"asset:cached");(K.length>0||!a)&&(V=K);for(let $ of V)J(e,n,$,s,x);}if(i.trackManifest){let B=U||!!a?.isText;i.manifest.assets[c]={url:c,outputPath:j.outputPath,isText:B,contentType:Jt(b)||a?.contentType||null,discoveredAssets:V,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!B},delete i.manifest.pages[c],(i.enabled||i.strictTargeted)&&B&&await we(e,i);}return}}}catch{}let g=await _(`fetch asset ${c}`,6e4,()=>t.get(c,{timeout:6e4}));if(!g.ok()){if(d(`http-${g.status()}`,{status:g.status()}))return;if(i.strictTargeted)throw new Error(`Required content-sync asset returned HTTP ${g.status()}: ${c}`);s.skip("asset",c,g.status());return}let m=await _(`read asset response ${c}`,6e4,()=>g.body()),h=g.url()||c,w=ye(h,s,"asset-response",c);if(!w)return;let v=w.toString(),k=g.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(c),We(n,s);let F=or(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[c]={url:c,outputPath:E.outputPath,isText:F,contentType:Jt(k),discoveredAssets:I,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!F},delete i.manifest.pages[c],(i.enabled||i.strictTargeted)&&F&&await we(e,i));}catch(p){if(d("fetch-error",{error:String(p)}))return;if(s.error(`Failed asset ${c}`,{url:c,error:String(p)}),i.strictTargeted)throw p}finally{n.doneAssets.has(c)||(n.doneAssets.add(c),We(n,s));}}async function zi(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 c=n.assetQueue.shift();c&&(n.queuedAssets.delete(c),await Wi(e,t,n,c,r,s,i));}});await Promise.all(u);}function Qi(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 gt(e){return Math.max(15e3,Math.min(6e4,ue(e)))}function Ji(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function nn(e){return e.stats.pagesCompleted}function Ir(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 Vi(e,t,n){let r=Ir(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 ${Qi(t)}.`));},t);})])}finally{r!==void 0&&globalThis.clearTimeout(r);}}async function Ki(e,t){let n=Ji(e);await t.evaluate(async r=>{await new Promise(s=>{let i=0,o=700,u=Date.now(),c=()=>{window.clearInterval(a),window.scrollTo(0,0),s();},a=window.setInterval(()=>{if(Date.now()-u>=r.maxDurationMs){c();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&&c();},120);});},{maxDurationMs:n});}async function Gi(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 Ki(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function Zi(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 Yi(e,t){return e.noJavaScriptRenderPathPrefixes.some(n=>Xt(t,n))}async function Xi(e,t,n,r,s=true){let i=new Set;if(s){let u=await t.evaluate(()=>{let c=new Set,a=["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 g of a){let m=p.getAttribute(g);m&&c.add(m);}for(let g of d){let m=p.getAttribute(g);m&&m.split(",").forEach(h=>{let w=h.trim().split(/\s+/)[0];w&&c.add(w);});}let f=p.getAttribute("style");f&&l.add(f);}),{attrs:[...c],styles:[...l]}});for(let c of u.attrs)for(let a of Li(c)){let l=H(e,a,n,r,"dom-attr");l&&q(e,l)&&i.add(l.toString());}for(let c of u.styles)for(let a of Ge(e,n,c,r,"dom-style"))i.add(a);}let o=await t.content();for(let u of Ge(e,n,o,r,"page-html"))i.add(u);return [...i]}async function cr(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 eo(e){let t=nn(e);return t%5===0||t===1||t===e.stats.pagesQueued}function to(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 no(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 ro(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 no(r),r}async function so(e,t,n,r,s,i,o){let u=await chromium.launch({headless:true}),c=Ir(u);c.pid!==null&&n.debug(`Launched crawl worker browser PID ${c.pid}`,{browserPid:c.pid});try{for(;t.pageQueue.length>0&&!(e.maxPages>0&&t.donePages.size>=e.maxPages);){let a=t.pageQueue.shift();if(!a)break;t.queuedPages.delete(a);let l=null,d=null;try{let p=ye(a,n,"page","page-queue");if(!p)continue;let f=p.toString();if(a=f,t.queuedPages.delete(a),t.donePages.has(a))continue;t.donePages.add(a),i.enabled&&i.seenPages.add(a);let g=tn(e,a),m=Yi(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: ${a}`,{url:a,source:"worker-guard"}),J(e,t,a,n,"worker-guard");continue}n.reject("page",a,"guard rejected non-page URL before rendering","worker");continue}let h=i.strictTargeted?i.manifest.pages[a]:void 0;if(h?.lastSeenRunId===i.runId&&await Ve(h.outputPath)){i.seenPages.add(a);for(let y of h.discoveredAssets||[])J(e,t,y,n,a);Z(o,e,h.outputPath),Ce(o,h.outputPath),n.info(`Resumed completed content-sync page ${a}`,{url:a,source:"content-sync-checkpoint"});continue}let w=await ci(e,s,t,i,a,n);if(i.enabled&&r!=="single-url"&&r!=="content-sync"){let y=i.manifest.pages[a];if(w.action==="reuse"&&y){for(let x of y.discoveredAssets)J(e,t,x,n,a);for(let x of y.discoveredPages)Ke(e,t,x,n,a);y.lastSeenRunId=i.runId,y.sitemapLastmod=ze(t.sitemapLastmodByPage[a])??y.sitemapLastmod,w.changeToken?.supported&&(y.changeToken=w.changeToken.token,y.tokenSource=w.changeToken.tokenSource??y.tokenSource),n.info(`Incremental reuse skipped unchanged page ${a}`,{url:a,mode:"incremental",reason:w.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}l=await _(`create page context ${a}`,ue(e),()=>ro(u,e,m)),d=await _(`create page ${a}`,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(f);if(j.hash="",U.hash="",j.href===U.href){if(v){n.warn(`Blocked same-page navigation/reload for ${a}`,{url:a,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,a));}catch{}}),n.page(`Rendering ${a}`,{url:a});let E=null,F=null;try{if(E=await d.goto(a,{waitUntil:"domcontentloaded",timeout:e.navigationTimeoutMs}),E&&E.ok())try{F=await _(`read response body ${a}`,ue(e),()=>E.text());}catch{F=null;}}catch(y){n.warn(`Navigation issue for ${a}; saving current DOM if available`,{url:a,error:String(y)});}if(r==="content-sync"&&E){let y=ye(E.url(),n,"content-sync-final-response",a)?.toString();if(y&&y!==f){if(i.deleteOnMissingUrls.has(a)){await Zt(e,i,o,a,i.deleteOnMissingUrls),n.info(`Removed stale content-sync archive route redirected to ${y}`,{url:a,finalResponseUrl:y,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${a} -> ${y}`)}}if(g){let y=E?.status()??null;if(y!==404){n.error(`Generated 404 request path returned unexpected status for ${a}`,{url:a,expectedStatus:404,status:y,requestPath:e.generated404RequestPath});continue}n.info(`Capturing rendered 404 page for ${a}`,{url:a,status:y,outputPath:le(e,a)});}else if(E&&!E.ok()){if(r==="content-sync"&&(E.status()===404||E.status()===410)&&i.deleteOnMissingUrls.has(a)){await Zt(e,i,o,a,i.deleteOnMissingUrls),n.info(`Removed stale content-sync archive page ${a}`,{url:a,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()}: ${a}`);n.skip("page",a,E.status(),t.pageDiscoverySources.get(a)),await d.close();continue}m?(n.info(`Rendering without JS execution for ${a}`,{url:a,mode:"no-js"}),await _(`wait for rendered page ${a}`,ue(e),()=>Zi(e,d))):await _(`wait for rendered page ${a}`,ue(e),()=>Gi(e,d)),t.stats.pagesRendered++;let I=await _(`extract rendered assets ${a}`,ue(e),()=>Xi(e,d,f,n,!m));for(let y of I)J(e,t,y,n,a);let O=[...new Set([...I,...k])],b=F??await _(`capture rendered html ${a}`,ue(e),()=>d.content()),P=r!=="single-url"&&r!=="content-sync"&&!g?Hi(e,a,b,n):[];if(r!=="single-url"&&r!=="content-sync"&&!g)for(let y of P)Ke(e,t,y,n,a);await cr(e,a,b,t,n);let C=le(e,a);if(Z(o,e,C),Ce(o,C),i.trackManifest){let y=E?.headers();i.manifest.pages[a]={url:a,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[a])??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 ${a}`,{url:a,error:String(p)}),p;try{let f=d?await _(`capture partial html ${a}`,ue(e),()=>d.content()):"";if(f&&f.trim()){await cr(e,a,f,t,n);let g=le(e,a);if(Z(o,e,g),Ce(o,g),i.trackManifest){let m=i.manifest.pages[a]??i.previousManifest.pages[a];i.manifest.pages[a]={url:a,outputPath:g,contentType:m?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:ze(t.sitemapLastmodByPage[a])??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 ${a}`,{url:a,error:String(p)});}}catch(f){n.error(`Could not save partial DOM for ${a}`,{url:a,error:String(f)});}n.error(`Failed page ${a}`,{url:a,error:String(p)});}finally{t.stats.pagesCompleted++,eo(t)&&to(t,n),d&&await _(`close page ${a}`,gt(e),()=>d.close()).catch(p=>{n.warn(`Timed out while closing page ${a}`,{url:a,browserPid:c.pid,error:String(p)});}),l&&await _(`close page context ${a}`,gt(e),()=>l.close()).catch(p=>{n.warn(`Timed out while closing page context for ${a}`,{url:a,browserPid:c.pid,error:String(p)});});}}}finally{await _("close worker browser",gt(e),()=>u.close()).catch(a=>(n.warn("Timed out while closing crawl worker browser",{browserPid:c.pid,error:String(a)}),Vi(u,n,"browser.close timeout")));}}async function io(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 ur(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function oo(e){let t=String(e?.job?.command||"").trim(),n=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:n!=="incremental"}function ao(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 xr(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 lr(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function co(e,t){let n=Array.isArray(t?.artifacts)?t.artifacts.filter(r=>String(r?.role||"").trim()==="errors"&&String(r?.storedFileName||"").trim()!=="").sort((r,s)=>lr(r)-lr(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 dr(e){let t=await xr(S.join(e,"job.json"));for(let n of co(e,t)){let r=await io(n);if(r.length>0)return r}return []}async function uo(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 c=await xr(S.join(o,"job.json"));if(!oo(c))continue;let a=ao(c);a>=s&&(s=a,r=o);}return r}async function lo(e){let t=await uo(e),n=t!==""?await dr(t):await dr(e.logDir),r=new Set;for(let s of n)if(ur(s.error)||ur(s.message)){let i=s.url;typeof i=="string"&&i&&r.add(i);}return [...r]}async function po(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 go(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 fo(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 pt(e,t,n){let r=n==="page"?le(e,t):ht(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(([a,l])=>a!==r&&!s.has(a)&&S.resolve(l.outputPath)===u)||(await A.rm(i.outputPath,{force:true}),n.deletedFiles.add(o)),delete t.manifest.pages[r];}function mo(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 ho(e,t,n,r,s){let i=mo(n.previousManifest,s);for(let o of i){if(t.doneSitemaps.has(o))continue;let u=n.previousManifest.assets[o];if(!u)continue;let c=he(e.outputDir,u.outputPath);if(!c)throw new Error(`Manifest-owned sitemap path escaped output root: ${o}`);await A.rm(u.outputPath,{force:true}),r.deletedFiles.add(c),delete n.manifest.assets[o];}await we(e,n);}async function wo(e){try{let t=await A.readFile(S.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function yo(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 pr(e,t,n,r,s){let i=H(e,n,e.sourceOrigin,r,"manual-url");i&&(Me(i)?mt(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 Ar(e=process.argv.slice(2)){let t=[],n=await ne(void 0,{onRemotePublisherConfigDiagnostic:P=>{t.push(P);}}),r=t.at(-1)??null,s=Ks(e),i=s.mode==="content-sync"?await go(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 lo(n)),s.mode==="single-url"&&(o=await po(s.urls)),i&&(o=[...i.directRenderUrls,...i.archiveFamilyUrls]);let u=s.crawlMode==="incremental"&&s.mode==="full",c=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 a=(s.mode==="full"||s.mode==="single-url"||s.mode==="content-sync")&&!s.resumeRewrite,l=s.mode!=="full"||s.resumeRewrite||c,d=l?await wo(n):{},p=c||s.mode==="single-url"||s.mode==="content-sync"?await ti(n):hr(),f=new Set(o),g=new Set;if(i){for(let P of i.archiveFamilies)if(P.foundPosts===0)for(let C of P.pageUrls)g.add(C);for(let P of Object.keys(p.pages))fo(P,i)&&!f.has(P)&&(o.push(P),g.add(P));}let m={enabled:c,trackManifest:a,manifest:Vt(p),previousManifest:Vt(p),runId:i?.jobId??`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve(),strictTargeted:!!i,requiredUrls:f,deleteOnMissingUrls:g};await yo(n.logDir);let h=new ut(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&&!c){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=ei();if(await Te(n),await qn(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=>mt(n,w,y,h)),await ar(n,P,w,h,v,m),n.seedPaths.forEach(y=>pr(n,w,y,h,"seed-path")),n.generated404RequestPath&&Ke(n,w,n.generated404RequestPath,h,"generated-404-request-path")):(o.forEach(y=>pr(n,w,y,h,"cli")),i?.sitemapUrls.forEach(y=>mt(n,w,y,h,"content-sync-impact")),await ar(n,P,w,h,v,m,s.mode==="content-sync"),i&&await ho(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)},()=>so(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 zi(n,P,w,h,m,v),h.endMark("download-assets",{assets:w.doneAssets.size}),m.enabled&&n.maxPages===0&&await li(n,w,m,h,v),s.mode==="full"){let y=await Bi(n,w,h);for(let x of y)Z(v,n,x);}}finally{await _("dispose crawl request context",gt(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"?Si(n,w):m.enabled&&!s.resumeRewrite?di(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 ir(E);let F=Date.now(),I=await ot(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 ir(B);}});m.trackManifest&&(pi(m,k),await we(n,m)),h.endMark("rewrite-text",{changedTextFiles:I});let O=i?[...v.deletedFiles].sort():m.enabled&&!s.resumeRewrite?await fi(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($=>pt(n,$,"page")).filter($=>!!$&&C.has($))),x=new Set(i.archiveFamilyUrls.map($=>pt(n,$,"page")).filter($=>!!$&&C.has($))),j=new Set([...w.sitemapLeafUrls].map($=>pt(n,$,"asset")).filter($=>!!$&&C.has($))),U=new Set([...w.sitemapIndexUrls].map($=>pt(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 Nn(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 So(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 ${So(t)}.`));},t);try{return await n({abortController:r,httpOptions:{abortSignal:r.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(s);}}function Po(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function wt(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 bo(e,t){return {...e,...t??{}}}function vo(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function Fe(e,t){let n=String(t??e.deploymentTargetOverride??"").trim();if(!Po(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:bo(e.s3,s.s3),cloudFront:vo(e.cloudFront,s.cloudFront)}}}var Er="wpsuite-sha256",Mr="wpsuite-normalized-sha256",Eo=/(?:^|[-_:.])(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,Mo=["SIGINT","SIGTERM"],Pt=new Set,yt=new Map,Tr=null;function Fo(e){Pt.add(e);let t=false;return ()=>{t||(t=true,Pt.delete(e));}}async function Do(){let e=[...Pt];e.length!==0&&await Promise.allSettled(e.map(async t=>{Pt.delete(t),await A.rm(t,{recursive:true,force:true});}));}function Oo(){if(!(yt.size>0))for(let e of Mo){let t=()=>{Tr||(Tr=Do().finally(()=>{for(let[n,r]of yt)process.off(n,r);yt.clear(),process.exit(1);}));};yt.set(e,t),process.on(e,t);}}Oo();function jo(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 Fr(e){return S.normalize(e).split(S.sep).join("/")}function kr(e,t){let n=S.relative(S.resolve(e),S.resolve(t));return !n||n.startsWith("..")||S.isAbsolute(n)?null:Fr(n)}async function Lo(e,t,n){let r=jo(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,c=0,a=0;for(let[l,d]of Object.entries(i.pages||{})){let p=String(d?.outputPath||"").trim(),f=p?kr(e.outputDir,p):null;if(f){let g=typeof d?.contentType=="string"&&d.contentType?d.contentType:null;g&&u.set(f,g);}!p||d?.rewriteComplete===true||f&&(c++,o.has(f)||o.set(f,{kind:"page",sourceUrl:l,outputPath:S.resolve(p),relativePath:f}));}for(let[l,d]of Object.entries(i.assets||{})){let p=String(d?.outputPath||"").trim(),f=d?.isText===true,g=p?kr(e.outputDir,p):null;if(g){let m=typeof d?.contentType=="string"&&d.contentType?d.contentType:null;m&&u.set(g,m);}!p||!f||d?.rewriteComplete===true||g&&(a++,o.has(g)||o.set(g,{kind:"asset",sourceUrl:l,outputPath:S.resolve(p),relativePath:g}));}return {manifestPath:r,byRelativePath:o,contentTypeByRelativePath:u,pendingPages:c,pendingTextAssets:a}}function Uo(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:Uo(t)).join("")}function qo(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 bt(e,t){return Array.isArray(e)?e.map(n=>bt(n,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,bt(r,n)])):typeof e!="string"?e:t&&Eo.test(t)?qo(e):un.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?sn(e):e}function _o(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function No(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(bt(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(bt(i));return Buffer.from(o,"utf8").toString("base64")}catch{}return t}function Bo(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"?_o(t):No(n,t)}function Ho(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,c)=>{let a=Bo(o,c);return ` ${o}=${u}${a}${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 St(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function Wo(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:c})=>e.send(new ListObjectsV2Command({Bucket:t,Prefix:n||void 0,ContinuationToken:i}),c));for(let c of u.Contents||[]){if(!c.Key)continue;let a=(c.ETag||"").replace(/^"|"$/g,"").toLowerCase(),l=Number(c.Size??0);s.set(c.Key,{etag:a,size:l});}i=u.NextContinuationToken,r.debug(`Listed S3 keys page ${o}: ${s.size} keys so far`);}while(i);return s}async function zo(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 Qo(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:c})=>e.send(new DeleteObjectsCommand({Bucket:t,Delete:{Objects:o.map(a=>({Key:a}))}}),c));if(u.Errors&&u.Errors.length>0){let c=u.Errors.map(a=>`${a.Key||"(unknown)"}: ${a.Code||"DeleteFailed"}`);throw new Error(`S3 reported ${c.length} object deletion error(s): ${c.join(", ")}`)}r.info(`Deleted batch of ${o.length} object(s).`);for(let c of o)r.debug(` deleted: ${c}`);}return s}function Jo(e){return createHash("md5").update(e).digest("hex")}function $r(e){return createHash("sha256").update(e).digest("hex")}function on(e){return createHash("sha256").update(Ho(e.toString("utf8"))).digest("hex")}async function Vo(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?.[Er]||"").trim().toLowerCase()||null;return r.set(n,o),o}catch{return r.set(n,null),null}}async function Ko(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?.[Mr]||"").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:c})=>e.send(new GetObjectCommand({Bucket:t,Key:n}),c))).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 Go(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function Zo(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 Yo(e,t,n,r){let s=S.join(e,"asset-map.json"),i;try{i=await A.readFile(s,"utf8");}catch(c){if(c.code==="ENOENT")return;throw c}let o=JSON.parse(i);if(!o||typeof o!="object")return;let u=Object.fromEntries(Object.entries(o).map(([c,a])=>{let l=String(a??"");return t.urlRewriteMode==="absolute"&&t.targetOrigin&&n.targetOrigin&&t.targetOrigin!==n.targetOrigin&&(l=l.split(t.targetOrigin).join(n.targetOrigin)),l=Zo(l,r),[c,l]}));await A.writeFile(s,JSON.stringify(u,null,2),"utf8");}async function Xo(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 c=S.join(S.dirname(e.outputDir),`.deploy-profile-${Go(n)}-${Date.now()}`),a=Fo(c);s.info(`Preparing deployment profile "${n}" from existing crawl output to ${c}...`);try{if(await A.rm(c,{recursive:!0,force:!0}),i){await A.mkdir(c,{recursive:!0});for(let f of i){let g=S.join(e.outputDir,f),m=S.join(c,f);await A.mkdir(S.dirname(m),{recursive:!0}),await A.copyFile(g,m);}}else await A.cp(e.outputDir,c,{recursive:!0});let l={...e,sourceOrigin:e.targetOrigin,targetOrigin:t.targetOrigin,extraReplacements:r,outputDir:c},d=1;s.info(`Rewriting text files for deployment profile "${n}"...`);let p=await ot(l,{},{files:i,onStart:({totalFiles:f,workerCount:g})=>{d=g,s.info(`Rewriting ${f} text file(s) for deployment profile "${n}" with ${g} worker(s).`);},onProgress:({index:f,totalFiles:g,changedTextFiles:m,file:h,changed:w})=>{let k=`Rewriting [${f}/${g}] ${h} (${w?"rewrote":"checked"}; ${m} changed so far)`;g<=200||f<=5||f%10===0||f===g?(s.progress(k,{file:h,index:f,totalFiles:g,changed:w,changedTextFiles:m,workerCount:d}),s.info(k)):s.debug(k);}});return await Yo(c,e,t,r),s.info(`Prepared deployment profile "${n}" in ${c} (${p} rewritten text file(s)).`),{outputDir:c,cleanup:async()=>{a(),await A.rm(c,{recursive:!0,force:!0});}}}catch(l){throw s.error(`Failed to prepare deployment profile "${n}" temporary output.`,{tempDir:c,outputDir:e.outputDir,error:l instanceof Error?l.message:String(l),...l instanceof Error&&l.stack?{stack:l.stack}:{}}),await A.rm(c,{recursive:true,force:true}).catch(()=>{}),a(),await s.flush().catch(()=>{}),l}}async function Dr(e=process.argv.slice(2)){let t=await ne(),n=wt(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"),c=r.profile?.extraReplacements??{},a=async()=>{};try{let l=await rt(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 _n(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 f=await Xo(t,r.config,r.name,c,u,l?.schemaVersion===2?l.changedFiles:void 0);a=f.cleanup;let g={...r.config,outputDir:f.outputDir},m=g.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&&f.outputDir!==t.outputDir&&(t.targetOrigin!==r.config.targetOrigin||Object.keys(c).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://${g.s3.bucket}/${g.s3.prefix||""} (region: ${g.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:g.s3.region}),k=f.outputDir===t.outputDir?await Lo(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(g.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 Ps(["**/*"],{cwd:g.outputDir,onlyFiles:!0,dot:!0}),I=[],O=[],b=F.filter(T=>{let W=k?.byRelativePath.get(Fr(T));if(!W)return !0;let R=St(g.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=>St(g.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 "${g.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:g.s3.bucket,s3Prefix:g.s3.prefix||"",targetedPlan:w,deployGuardEnabled:f.outputDir===t.outputDir});let C=0,y=0,x=0,j=[],U=[],V=[],B=[],K=[],$=new Map,Ye=new Map,_r=new Map,Nr=new Map,Br=new Map;w||(u.info("Listing existing S3 objects to detect unchanged files..."),$=await Wo(v,g.s3.bucket,g.s3.prefix,u),u.info(`Found ${$.size} existing key(s) in S3.`));let Hr=async T=>$.has(T)?$.get(T)??null:w?zo(v,g.s3.bucket,T,Ye):null;for(let T of b){let W=S.join(g.outputDir,T),R=St(g.s3.prefix,T),ee=k?.contentTypeByRelativePath.get(T),Oe=ee&&ee!=="application/octet-stream"?ee:$o.lookup(T)||ee||"application/octet-stream",Wr=rn(T)?g.s3.htmlCacheControl:g.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 Hr(R),Le=null,Ie=null;if(je){let Ct=te.byteLength;if(je.size===Ct){let Xe=je.etag.includes("-");if(je.etag!==""&&!Xe){let zr=Jo(te);if(je.etag===zr){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=$r(te);let hn=await Vo(v,g.s3.bucket,R,_r);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 Ko(v,g.s3.bucket,R,Nr,Br);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??$r(te),Ie=Ie??(rn(T)?on(te):null),await Y(`S3 upload ${R}`,9e5,({abortController:Ct})=>new Upload({client:v,abortController:Ct,params:{Bucket:g.s3.bucket,Key:R,Body:te,ContentType:Oe,CacheControl:Wr,Metadata:{[Er]:Le,...Ie?{[Mr]: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=>St(g.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 Qo(v,g.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 a().catch(()=>{});}}function ta(e){return String(e||"").replace(/\\/g,"/").replace(/^\/+|\/+$/g,"")}function na(e,t){let n=e;n.endsWith("/")?n+="index.html":S.posix.basename(n).includes(".")||(n+="/index.html");let r=ta(t);return r?`/${r}${n}`.replace(/\/{2,}/g,"/"):n}function Or(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(`${na(s.pathname,t)}${s.search}`);}return [...n].sort()}function oa(){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 aa(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 ca(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=wt(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 rt(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 c=u?.schemaVersion===2?u.invalidationPaths:s.cloudFront.invalidationPaths.length>0?s.cloudFront.invalidationPaths:["/*"],a=u?.schemaVersion===2?Or(c,s.s3.prefix||""):c;if(u?.schemaVersion===2&&a.some(g=>g==="/*"))throw new Error("Content-sync cannot use a whole-distribution invalidation.");if(a.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 g=`smartcloud-static-publisher-${Date.now()}`;await Y(`CloudFront invalidation for distribution ${l}`,3e5,({httpOptions:m})=>d.send(new CreateInvalidationCommand({DistributionId:l,InvalidationBatch:{CallerReference:g,Paths:{Quantity:a.length,Items:a}}}),m)),i.endMark("invalidate"),await i.flush();return}let p=oa(),f=await aa(p,l,u.impactHash,a);if(!f){let g=createHash("sha256").update(JSON.stringify(a)).digest("hex");f={schemaVersion:1,distributionId:l,impactHash:u.impactHash,updatedAt:new Date().toISOString(),batches:ca(a).map((m,h)=>({index:h,callerReference:`wpsuite-content-sync-${u.impactHash.slice(0,24)}-${g.slice(0,24)}-${h}`,paths:m,invalidationId:null,status:"pending"}))},await ln(p,f);}for(let g of f.batches){if(!g.invalidationId){let m=await Y(`CloudFront targeted invalidation batch ${g.index+1}`,3e5,({httpOptions:w})=>d.send(new CreateInvalidationCommand({DistributionId:l,InvalidationBatch:{CallerReference:g.callerReference,Paths:{Quantity:g.paths.length,Items:g.paths}}}),w)),h=String(m.Invalidation?.Id||"").trim();if(!h)throw new Error("CloudFront did not return an invalidation ID.");g.invalidationId=h,g.status="created",await ln(p,f);}await waitUntilInvalidationCompleted({client:d,maxWaitTime:900,minDelay:2,maxDelay:15},{DistributionId:l,Id:g.invalidationId}),g.status="completed",await ln(p,f),i.info(`CloudFront invalidation batch ${g.index+1}/${f.batches.length} completed.`,{invalidationId:g.invalidationId,pathCount:g.paths.length});}i.endMark("invalidate"),await i.flush();}var Ur=["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 Ur.indexOf(e)>=Ur.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 la(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 da(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=la(t),r=Fe(e,t.deploymentProfile),s=r.name||"",i=yn(e.sourceOrigin,String(t.id||""),n),o=Sn({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=Pn({siteId:e.wpsuite?.siteSettings?.siteId,accountId:e.wpsuite?.siteSettings?.accountId,sourceOrigin:e.sourceOrigin,ruleId:String(t.id||""),targetFingerprint:o}),c=`content-sync:${String(t.id||"")}:${oe({scopeFingerprint:i,targetFingerprint:o}).slice(0,32)}`,a=new tt({sourceOrigin:e.sourceOrigin,runtimeToken:String(e.wpsuite?.runtimeToken||""),ignoreHttpsErrors:e.ignoreHttpsErrors}),l=await a.releaseFingerprint(),d=oe({schemaVersion:1,wordpressFingerprint:l,targetFingerprint:o,sourceOrigin:e.sourceOrigin,sitemapPaths:[...e.sitemapPaths].sort(),blockedPathPrefixes:[...e.blockedPathPrefixes].sort(),assetPathPrefixes:[...e.assetPathPrefixes].sort(),noJavaScriptRenderPathPrefixes:[...e.noJavaScriptRenderPathPrefixes].sort(),urlRewriteMode:e.urlRewriteMode});return {rule:t,scope:n,deployment:r,deploymentProfile:s,scopeFingerprint:i,targetFingerprint:o,consumerId:u,coalesceKey:c,client:a,releaseFingerprint:d}}async function pa(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 Tt(n),o=await At(n),u=0;for(let c of s){let a=await mn(r,c),l=o.entries[a.coalesceKey];if(!l||l.releaseJobId!==e||l.scopeFingerprint!==a.scopeFingerprint||l.targetFingerprint!==a.targetFingerprint||l.releaseFingerprint!==a.releaseFingerprint)throw new Error(`The normal release has no matching pre-crawl content-sync cutoff for rule ${String(c.id||"")}.`);let d=oe({releaseJobId:e,releaseFingerprint:a.releaseFingerprint,scopeFingerprint:a.scopeFingerprint,targetFingerprint:a.targetFingerprint,sequence:l.sequence}),p=await a.client.establishBaseline({consumerId:a.consumerId,scopeFingerprint:a.scopeFingerprint,baselineId:d,postTypes:a.scope.postTypes,sequence:l.sequence}),f={schemaVersion:1,ruleId:String(c.id||""),consumerId:a.consumerId,coalesceKey:a.coalesceKey,scopeFingerprint:a.scopeFingerprint,targetFingerprint:a.targetFingerprint,releaseFingerprint:a.releaseFingerprint,baselineId:d,deploymentProfile:a.deploymentProfile,committedSequence:p.committedSequence,releaseJobId:e,verifiedAt:new Date().toISOString()};i.entries[a.coalesceKey]=f;let g=await $n(n,a.coalesceKey);await pe(t,"content-sync-baseline-established",{id:e},"A normal release established a verified content-sync baseline.",{ruleId:c.id,consumerId:a.consumerId,committedSequence:p.committedSequence,supersededCurrent:g}),u++;}return await In(n,i),await A.rm(n.releaseCutoff,{force:true}),u}async function ga(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 At(n),o=0;for(let u of s){let c=await mn(r,u),a=Object.values(i.entries).find(p=>p.releaseJobId===e&&p.ruleId===String(u.id||""));if(a){if(a.coalesceKey===c.coalesceKey&&a.scopeFingerprint===c.scopeFingerprint&&a.targetFingerprint===c.targetFingerprint&&a.releaseFingerprint===c.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 c.client.unboundHead(c.scope.postTypes),d={schemaVersion:1,releaseJobId:e,ruleId:String(u.id||""),coalesceKey:c.coalesceKey,scopeFingerprint:c.scopeFingerprint,targetFingerprint:c.targetFingerprint,releaseFingerprint:c.releaseFingerprint,sequence:l.headSequence,capturedAt:new Date().toISOString()};i.entries[c.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:c.consumerId,sequence:l.headSequence}),o++;}return await Rn(n,i),o}async function fa(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:"?Cn:Gr,s=e.protocol==="https:"?new Cn.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"}},c=>{let a=c.statusCode??500,l=c.headers.location;if(a>=300&&a<400&&l&&n<5){c.resume(),gn(new URL(l,e),t,n+1).then(i,o);return}let d=[],p=0;c.on("data",f=>{p+=f.byteLength,p<=1048576&&d.push(f);}),c.on("error",o),c.on("end",()=>i({status:a,body:Buffer.concat(d).toString("utf8")}));});u.on("timeout",()=>u.destroy(new Error(`Verification timed out: ${e}`))),u.on("error",o);})}async function ma(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),c=await gn(u,e.ignoreHttpsErrors);if(c.status<200||c.status>=400)throw new Error(`Content-sync verification failed (${c.status}): ${u}`)}for(let i of n.deleteUrls.slice(0,10)){let o=new URL(i),u=new URL(`${o.pathname}${o.search}`,r),c=await gn(u,e.ignoreHttpsErrors);if(c.status>=200&&c.status<300)throw new Error(`Deleted content is still publicly available: ${u}`)}}async function ha(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 wa(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 xn(e,t),await kn(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 ya(e){let t=fn(),n=nt(t),r=await fa(t,e),s=await ne(),i=da(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 c=(await Tt(n)).entries[o.coalesceKey];if(!c||c.scopeFingerprint!==o.scopeFingerprint||c.targetFingerprint!==o.targetFingerprint||c.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:c?"mismatch":"missing"}),new Error("Content-sync baseline is missing or stale. Run a successful normal publish first.");let a=await kt(n),l=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:c.baselineId,postTypes:o.scope.postTypes});if(a&&a.jobId!==r.id)throw new Error("Another immutable content-sync range is still active.");if(a||(a={schemaVersion:1,jobId:r.id,ruleId:String(i.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,scopeFingerprint:o.scopeFingerprint,targetFingerprint:o.targetFingerprint,baselineId:c.baselineId,fromSequence:l.committedSequence,toSequence:l.headSequence,phase:"claimed",impactHash:null,startedAt:new Date().toISOString(),updatedAt:new Date().toISOString()},await Re(n,a,"claimed",0,{fromSequence:a.fromSequence,toSequence:a.toSequence}),await pe(t,"content-sync-range-claimed",r,"Content-sync claimed a closed journal range.",{fromSequence:a.fromSequence,toSequence:a.toSequence})),a.fromSequence===a.toSequence){let m=await $t(n);m.rules[o.coalesceKey]={ruleId:String(i.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,committedSequence:a.toSequence,observedHeadSequence:l.headSequence,lag:Math.max(0,l.headSequence-a.toSequence),lastSuccessfulJobId:r.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:false,retryAttempt:0,nextRetryAt:null,lastError:null},await Et(n,m),await Mt(n);return}let d=await An(n);if(!De(a.phase,"impact-planned")){let m=await o.client.events({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:c.baselineId,postTypes:o.scope.postTypes,afterSequence:a.fromSequence,throughSequence:a.toSequence}),h=xt({events:m,scope:o.scope,sourceOrigin:s.sourceOrigin}),w=await o.client.resolveImpactFamilies(h);d=vn({jobId:r.id,ruleId:String(i.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,scopeFingerprint:o.scopeFingerprint,targetFingerprint:o.targetFingerprint,baselineId:c.baselineId,sourceOrigin:s.sourceOrigin,scope:o.scope,fromSequence:a.fromSequence,toSequence:a.toSequence,events:m,resolvedArchiveFamilies:w,sitemapUrls:s.sitemapPaths}),await Tn(n,d),a.impactHash=d.impactHash,await Re(n,a,"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||a.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(a.phase,"rendered")){let m=await wa(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 Ar(["--content-sync-plan",n.impact]),await Re(n,a,"rendered",d.directRenderUrls.length+d.archiveFamilyUrls.length,{impactHash:d.impactHash},r.attempt??0);}let p=o.deploymentProfile?["--profile",o.deploymentProfile]:[];if(De(a.phase,"deployed")||(await Dr([...p,"--content-sync"]),await Re(n,a,"deployed",1,{impactHash:d.impactHash}),await pe(t,"content-sync-deployed",r,"Content-sync targeted deployment completed.",{impactHash:d.impactHash})),De(a.phase,"invalidated")?De(a.phase,"verified")||await pn([...p,"--content-sync"]):(await pn([...p,"--content-sync"]),await Re(n,a,"invalidated",1,{impactHash:d.impactHash})),De(a.phase,"verified")||(await ma(s,o,d),await ha(n),await Re(n,a,"verified",1,{impactHash:d.impactHash})),l=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:c.baselineId,postTypes:o.scope.postTypes}),l.committedSequence===a.fromSequence)await o.client.acknowledge({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:c.baselineId,expectedSequence:a.fromSequence,sequence:a.toSequence,postTypes:o.scope.postTypes});else if(l.committedSequence!==a.toSequence)throw new Error("Content-sync acknowledgement cursor is in an unexpected state.");await Re(n,a,"acknowledged",1,{sequence:a.toSequence}),await pe(t,"content-sync-cursor-acknowledged",r,"Content-sync committed its journal cursor after verification.",{sequence:a.toSequence});let f=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:c.baselineId,postTypes:o.scope.postTypes}),g=await $t(n);g.rules[o.coalesceKey]={ruleId:String(i.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,committedSequence:a.toSequence,observedHeadSequence:f.headSequence,lag:Math.max(0,f.headSequence-a.toSequence),lastSuccessfulJobId:r.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:f.headSequence>a.toSequence,retryAttempt:0,nextRetryAt:null,lastError:null},await Et(n,g),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 qr(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 ga(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 pa(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 ya(i);}qr().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1);});
|
package/dist/invalidate.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import b from'fs/promises';import X from'http';import ee from'https';import h from'path';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';function j(r){let e=r.trim();return e==="."?".":e.replace(/\/$/,"")}function te(r){let e=String(r??"").trim();if(!e)return "";let t=e;if(/^https?:\/\//i.test(t))try{t=new URL(t).pathname;}catch{return ""}if(t=t.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!t)return "";let n=t.endsWith("/"),i=t.replace(/^\/+/,"").split("/").map(o=>o.replace(/[^A-Za-z0-9._-]/g,"")).filter(o=>o.length>0&&o!=="."&&o!=="..");if(i.length===0)return "";let s=`/${i.join("/")}`;return n&&h.extname(s)===""&&(s+="/"),s==="/"?"":s}function k(r){return !r||typeof r!="object"?{}:Object.fromEntries(Object.entries(r).map(([e,t])=>[e.trim(),String(t??"")]).filter(([e])=>e.length>0))}function re(r){if(!r||typeof r!="object")return {};let e={};for(let[t,n]of Object.entries(r)){let i=t.trim();if(!i||!n||typeof n!="object")continue;let s=n,o={};if(typeof s.targetOrigin=="string"){let a=j(s.targetOrigin);a&&(o.targetOrigin=a);}let u=k(s.extraReplacements);if(Object.keys(u).length>0&&(o.extraReplacements=u),s.s3&&typeof s.s3=="object"){let a={},l=s.s3;typeof l.bucket=="string"&&(a.bucket=l.bucket.trim()),typeof l.prefix=="string"&&(a.prefix=l.prefix.trim()),typeof l.region=="string"&&(a.region=l.region.trim()),typeof l.htmlCacheControl=="string"&&(a.htmlCacheControl=l.htmlCacheControl.trim()),typeof l.assetCacheControl=="string"&&(a.assetCacheControl=l.assetCacheControl.trim()),Object.keys(a).length>0&&(o.s3=a);}if(s.cloudFront&&typeof s.cloudFront=="object"){let a={},l=s.cloudFront;typeof l.distributionId=="string"&&(a.distributionId=l.distributionId.trim()),Array.isArray(l.invalidationPaths)&&(a.invalidationPaths=l.invalidationPaths.map(c=>String(c??"").trim()).filter(c=>c.length>0)),Object.keys(a).length>0&&(o.cloudFront=a);}e[i]=o;}return e}function L(r){return r==="PROFESSIONAL"||r==="AGENCY"?r:void 0}function ie(r,e){if(!r||typeof r!="object")return null;let t=r,n=t.command;if(n!=="publish"&&n!=="crawl"&&n!=="deploy"&&n!=="invalidate"&&n!=="retry-timeouts"&&n!=="url"&&n!=="content-sync")return null;let i=Number.parseInt(String(t.intervalMinutes??"0"),10);if(!Number.isFinite(i)||i<1)return null;let s=String(t.id??`${n}-${e+1}`).trim();if(!s)return null;let o=String(t.deploymentProfile??"").trim(),u=String(t.url??"").trim(),a=Array.isArray(t.postTypes)?[...new Set(t.postTypes.map(c=>String(c??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],l=Array.isArray(t.listingPaths)?[...new Set(t.listingPaths.map(c=>String(c??"").trim()).filter(Boolean))]:[];return n==="content-sync"&&a.length===0?null:{id:s,enabled:t.enabled!==false,command:n,intervalMinutes:i,...n==="publish"||n==="crawl"?{crawlMode:t.crawlMode==="incremental"?"incremental":"full"}:{},...(n==="publish"||n==="deploy"||n==="invalidate"||n==="content-sync")&&o?{deploymentProfile:o}:{},...u?{url:u}:{},...a.length>0?{postTypes:a}:{},...l.length>0?{listingPaths:l}:{},...typeof t.includePostTypeArchives=="boolean"?{includePostTypeArchives:t.includePostTypeArchives}:{},...typeof t.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:t.includeTaxonomyArchives}:{},...typeof t.includeAuthorArchives=="boolean"?{includeAuthorArchives:t.includeAuthorArchives}:{},...typeof t.includeDateArchives=="boolean"?{includeDateArchives:t.includeDateArchives}:{},...typeof t.includePostsPage=="boolean"?{includePostsPage:t.includePostsPage}:{},...typeof t.includeSitemapChain=="boolean"?{includeSitemapChain:t.includeSitemapChain}:{}}}function U(r){let e=r&&typeof r=="object"?r:{},t=Array.isArray(e.rules)?e.rules.map((n,i)=>ie(n,i)).filter(n=>!!n):[];return {enabled:e.enabled===true,timezone:typeof e.timezone=="string"&&e.timezone.trim()!==""?e.timezone.trim():"UTC",rules:t}}function ne(r){if(!r||typeof r!="object")return;let e=r,t={};for(let i of ["accountId","siteId"]){let s=e[i];typeof s=="string"&&s.trim()!==""&&(t[i]=s.trim());}let n=Number(e.lastUpdate??0);return Number.isFinite(n)&&n>0&&(t.lastUpdate=Math.floor(n)),e.subscriber===true&&(t.subscriber=true),Object.keys(t).length>0?t:void 0}function x(r){let e=r&&typeof r=="object"?r:{},t=String(e.accountId??"").trim(),n=String(e.siteId??"").trim(),i=e.subscriber===true,s=ne(e.siteSettings),o={...s??{},...t?{accountId:s?.accountId??t}:{},...n?{siteId:s?.siteId??n}:{},...s?.subscriber===true||i?{subscriber:true}:{}},u={},a=String(e.apiBase??"").trim();a&&(u.apiBase=a);let l=String(e.runtimeToken??e.nonce??"").trim();l&&(u.runtimeToken=l);let c=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();c&&(u.virtualAssetBaseUrl=c),Object.keys(o).length>0&&(u.siteSettings=o);let d=L(e.subscriptionType);return d&&(u.subscriptionType=d),u}function se(r){try{let e=new URL(r);globalThis.location=e;}catch{}}function _(r){return typeof r=="string"?r:r instanceof URL?r.toString():r.url}function oe(r,e){let t=new Headers(r instanceof Request?r.headers:void 0);if(e?.headers)for(let[n,i]of new Headers(e.headers).entries())t.set(n,i);return t}async function $(r,e,t=5){let n=new URL(_(r)),i=String(e?.method??(r instanceof Request?r.method:"GET")).toUpperCase(),s=n.protocol==="http:"?X:ee,o=oe(r,e);return await new Promise((u,a)=>{let l=s.request(n,{method:i,headers:Object.fromEntries(o.entries()),...n.protocol==="https:"?{rejectUnauthorized:false}:{}},c=>{let d=[];c.on("data",g=>{d.push(Buffer.isBuffer(g)?g:Buffer.from(g));}),c.on("error",a),c.on("end",()=>{let g=c.statusCode??0,p=c.headers.location;if(t>0&&p&&[301,302,303,307,308].includes(g)){u($(new URL(p,n),{method:g===303?"GET":i},t-1));return}let m=new Headers;for(let[w,f]of Object.entries(c.headers))Array.isArray(f)?m.set(w,f.join(", ")):typeof f=="string"&&m.set(w,f);u(new Response(Buffer.concat(d),{status:g,statusText:c.statusMessage??"",headers:m}));});});l.on("error",a),l.end();})}function ae(r){let e=x(r.wpsuite),t={...e.siteSettings??{},...e.siteSettings?.subscriber===true||e.subscriptionType==="PROFESSIONAL"||e.subscriptionType==="AGENCY"?{subscriber:true}:{}},n=String(t.accountId??"").trim(),i=String(t.siteId??"").trim(),s=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();if(r.wpsuite={...e.apiBase?{apiBase:e.apiBase}:{},...e.runtimeToken?{runtimeToken:e.runtimeToken}:{},...s?{virtualAssetBaseUrl:s}:{},...Object.keys(t).length>0?{siteSettings:t}:{},...e.subscriptionType?{subscriptionType:e.subscriptionType}:{}},!n||!i||!s)return false;se(r.sourceOrigin);let o=globalThis,a={...o.WpSuite??{},siteSettings:t,uploadUrl:s};return e.apiBase&&(a.apiBase=e.apiBase),o.WpSuite=a,true}async function le(r){let e=String(r.wpsuite?.virtualAssetBaseUrl??r.wpsuite?.uploadUrl??"").trim();if(!ae(r)){let i=r.wpsuite?.siteSettings,s=[String(i?.accountId??"").trim()?"":"accountId",String(i?.siteId??"").trim()?"":"siteId",e?"":"virtualAssetBaseUrl"].filter(Boolean);return {remote:null,diagnostic:{status:"invalid-runtime",virtualAssetBaseUrl:e,subscriptionType:null,error:`Missing WP Suite runtime field(s): ${s.join(", ")}.`,requests:[]}}}let t=globalThis.fetch,n=[];try{typeof t=="function"&&/^https?:\/\//i.test(e)&&(globalThis.fetch=(async(a,l)=>{let c=_(a);if(c.startsWith(e)){let d=(()=>{try{return new URL(c).pathname}catch{return c}})();try{let g=r.ignoreHttpsErrors&&c.startsWith("https://")?await $(a,l):await t(a,l);return n.push({path:d,status:g.status,ok:g.ok,error:null}),g}catch(g){throw n.push({path:d,status:null,ok:!1,error:g instanceof Error?g.message:String(g)}),g}}return t(a,l)}));let{getConfig:i}=await import('@smart-cloud/wpsuite-core'),s=await i("publisher"),o=s&&typeof s=="object"?s:null,u=L(o?.subscriptionType);return {remote:o,diagnostic:{status:o?"loaded":"unavailable",virtualAssetBaseUrl:e,subscriptionType:u??null,error:o?null:"WP Suite publisher config loader returned no configuration.",requests:n}}}catch(i){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:e,subscriptionType:null,error:i instanceof Error?i.message:String(i),requests:n}}}finally{typeof t=="function"&&(globalThis.fetch=t);}}function ue(r,e){let t=re(e?.deploymentProfiles),n=String(e?.defaultDeploymentProfile??"").trim(),i=t[n]?n:"",s=L(e?.subscriptionType),o=x(r.wpsuite);return {...r,scheduler:U(e?.scheduler),deploymentProfiles:t,defaultDeploymentProfile:i,...s?{subscriptionType:s}:{},wpsuite:{...o,...o.siteSettings||s?{siteSettings:{...o.siteSettings??{},...o.siteSettings?.subscriber===true||s==="PROFESSIONAL"||s==="AGENCY"?{subscriber:true}:{}}}:{},...s?{subscriptionType:s}:{}}}}function E(r,e){let n=String(r||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!n)return e;let i=n.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return i.length>0?i.join("/"):e}function ce(){let r=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return r.trim()?h.resolve(r):""}function N(r,e,t){let n=String(e||"").trim();return n&&h.isAbsolute(n)?h.resolve(n):h.resolve(r,E(n,t))}async function C(r,e={}){let t=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",n=await b.readFile(t,"utf8"),i=JSON.parse(n);i.sourceOrigin=i.sourceOrigin.replace(/\/$/,""),i.targetOrigin=j(i.targetOrigin),i.ignoreHttpsErrors??=false,i.outputDir=String(i.outputDir||"export").trim()||"export",i.urlRewriteMode||=i.targetOrigin==="."?"relative":"absolute",i.noJavaScriptRenderPathPrefixes||=[],i.seedPaths||=[],i.generated404RequestPath=te(i.generated404RequestPath),i.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],i.allowedAssetHosts||=[],i.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],i.blockedPathPrefixes||=[],i.blockedSearchFragments||=[],i.concurrency||=1,i.maxPages||=0,i.extraReplacements=k(i.extraReplacements),i.postCrawlCopyMap=k(i.postCrawlCopyMap),i.logDir=String(i.logDir||"logs").trim()||"logs",i.verbose??=false,i.logLevel||=i.verbose?"debug":"info",i.s3SyncMode||="sdk-upload-delete",i.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},i.readiness.timeoutMs??=1500,i.readiness.fallbackWaitMs??=1500,i.viewport||={width:1440,height:1200},i.navigationTimeoutMs||=3e4,i.assetDownloadConcurrency=Number(i.assetDownloadConcurrency)>0?Number(i.assetDownloadConcurrency):i.concurrency,i.rewriteConcurrency=Number(i.rewriteConcurrency)>0?Number(i.rewriteConcurrency):i.assetDownloadConcurrency,i.wpsuite=x(i.wpsuite),i.scheduler=U(void 0),i.deploymentProfiles={},i.defaultDeploymentProfile="",i.deploymentTargetOverride=String(i.deploymentTargetOverride??"").trim();let s=await le(i);e.onRemotePublisherConfigDiagnostic?.(s.diagnostic);let o=ue(i,s.remote),u=ce(),a=u?h.resolve(u,".."):"";return a?(o.outputDir=N(a,o.outputDir,"export"),o.logDir=N(a,o.logDir,"logs")):(h.isAbsolute(o.outputDir)||(o.outputDir=E(o.outputDir,"export")),h.isAbsolute(o.logDir)||(o.logDir=E(o.logDir,"logs"))),o}function ge(r){let e=r/6e4;if(Number.isInteger(e)&&e>=1)return `${e} minute${"s"}`;let t=Math.ceil(r/1e3);return `${t} second${t===1?"":"s"}`}async function M(r,e,t){let n=new AbortController,i=globalThis.setTimeout(()=>{n.abort(new Error(`${r} timed out after ${ge(e)}.`));},e);try{return await t({abortController:n,httpOptions:{abortSignal:n.signal,requestTimeout:e}})}finally{globalThis.clearTimeout(i);}}var de=".deploy-plan.json",me="deploy-plan.json";function he(){let r=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return r.trim()?h.resolve(r):""}function fe(r){let e=String(r||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),t=h.posix.normalize(e);return !e||!t||t==="."||/^[a-zA-Z]:/.test(t)||t.startsWith("../")||t===".."?null:t}function ye(r){let e=String(r||"").trim();if(!e.startsWith("/")||e.startsWith("//")||e.includes("*")||e.includes("#"))return null;try{let t=new URL(e,"https://content-sync.invalid");return t.origin!=="https://content-sync.invalid"?null:`${h.posix.normalize(t.pathname)}${t.search}`}catch{return null}}function P(r){return [...new Set(r.map(fe).filter(e=>e!==null))]}function Pe(r,e){let t={generatedAt:String(e.generatedAt||new Date().toISOString()),outputDir:h.resolve(r.outputDir),runMode:e.runMode,crawlMode:e.crawlMode,fullSyncRequired:!!e.fullSyncRequired,changedFiles:P(e.changedFiles||[]),deletedFiles:P(e.deletedFiles||[]),rewriteTargets:P(e.rewriteTargets||[])};return e.schemaVersion===2?{...t,schemaVersion:2,runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,consumerId:String(e.consumerId||"").trim(),fromSequence:Math.max(0,Number(e.fromSequence)||0),toSequence:Math.max(0,Number(e.toSequence)||0),impactHash:String(e.impactHash||"").trim(),uploadGroups:{assets:P(e.uploadGroups?.assets||[]),content:P(e.uploadGroups?.content||[]),listings:P(e.uploadGroups?.listings||[]),sitemapLeaves:P(e.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:P(e.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((e.invalidationPaths||[]).map(ye).filter(n=>n!==null))].sort()}:{schemaVersion:1,...t,runMode:e.runMode}}function be(r){if(!r||typeof r!="object")return false;let e=r;if(e.schemaVersion===2){let t=e;return t.runMode==="content-sync"&&t.crawlMode==="incremental"&&t.fullSyncRequired===false&&typeof t.generatedAt=="string"&&typeof t.outputDir=="string"&&typeof t.consumerId=="string"&&t.consumerId.trim()!==""&&Number.isSafeInteger(t.fromSequence)&&Number.isSafeInteger(t.toSequence)&&Number(t.toSequence)>=Number(t.fromSequence)&&typeof t.impactHash=="string"&&/^[a-f0-9]{64}$/.test(t.impactHash)&&Array.isArray(t.changedFiles)&&Array.isArray(t.deletedFiles)&&Array.isArray(t.rewriteTargets)&&!!t.uploadGroups&&Array.isArray(t.uploadGroups.assets)&&Array.isArray(t.uploadGroups.content)&&Array.isArray(t.uploadGroups.listings)&&Array.isArray(t.uploadGroups.sitemapLeaves)&&Array.isArray(t.uploadGroups.sitemapIndexes)&&Array.isArray(t.invalidationPaths)}return e.schemaVersion===1&&typeof e.generatedAt=="string"&&typeof e.outputDir=="string"&&(e.runMode==="full"||e.runMode==="retry-timeouts"||e.runMode==="single-url")&&(e.crawlMode==="full"||e.crawlMode==="incremental")&&typeof e.fullSyncRequired=="boolean"&&Array.isArray(e.changedFiles)&&Array.isArray(e.deletedFiles)&&Array.isArray(e.rewriteTargets)}function we(r){let e=h.join(h.resolve(r.outputDir),de),t=he();return t?[h.join(t,me),e]:[e]}async function q(r){let e=h.resolve(r.outputDir);for(let t of we(r))try{let n=await b.readFile(t,"utf8"),i=JSON.parse(n);if(!be(i)||h.resolve(i.outputDir)!==e)continue;return Pe(r,i)}catch{}return null}function Se(r){return typeof r.subscriptionType=="string"&&r.subscriptionType.trim()!==""}function W(r){let e="";for(let n=0;n<r.length;n++){let i=r[n];if(i==="--profile"){let s=(r[n+1]||"").trim();if(!s)throw new Error("Missing value for --profile.");e=s,n+=1;}else if(i.startsWith("--profile=")){let s=i.slice(10).trim();if(!s)throw new Error("Missing value for --profile.");e=s;}}let t=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return e||t||null}function ve(r,e){return {...r,...e??{}}}function Ie(r,e){return {...r,...e??{},invalidationPaths:[...(e?.invalidationPaths??r.invalidationPaths)||[]]}}function B(r,e){let t=String(e??r.deploymentTargetOverride??"").trim();if(!Se(r)){if(t)throw new Error(`Deployment target "${t}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:r}}let n=String(t||r.defaultDeploymentProfile||"").trim();if(!n)return {name:null,profile:null,config:r};let i=r.deploymentProfiles?.[n];if(!i)throw new Error(`Unknown deployment profile "${n}". Check the linked WPSuite publisher configuration.`);return {name:n,profile:i,config:{...r,targetOrigin:i.targetOrigin??r.targetOrigin,s3:ve(r.s3,i.s3),cloudFront:Ie(r.cloudFront,i.cloudFront)}}}var H={error:0,warn:1,info:2,debug:3},Ce=/^(?:authorization|proxyAuthorization|runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken|xStaticPublisherToken|xApiKey)$/i;function I(r){return r.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 T(r){return typeof r=="string"?I(r):Array.isArray(r)?r.map(e=>T(e)):r instanceof Error?{name:r.name,message:I(r.message),...r.stack?{stack:I(r.stack)}:{}}:r&&typeof r=="object"?Object.fromEntries(Object.entries(r).map(([e,t])=>[e,Ce.test(e)?"[REDACTED]":T(t)])):r}function V(r){return r?T(r):void 0}var z=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",D=z?h.join(z,"current-progress.json"):"",J=Promise.resolve();function G(r){return r.includes("crawl")?"crawl":r.includes("deploy")?"deploy":r.includes("invalidate")?"invalidate":r}function De(r,e){let t={...r},n=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","pageQueue","assetQueue","sitemapQueue"]);for(let[i,s]of Object.entries(e)){let o=t[i];if(typeof o=="number"&&typeof s=="number"&&n.has(i)){t[i]=Math.max(o,s);continue}t[i]=s;}return t}function Te(r,e,t){D&&(J=J.then(async()=>{let n=new Date,i=n.toISOString();await b.mkdir(h.dirname(D),{recursive:true});let s=await b.readFile(D,"utf8").then(A=>JSON.parse(A)).catch(()=>null),o=s&&typeof s.details=="object"&&s.details?s.details:{},u=G(r),a=s?.currentStep||G(s?.source||""),l=s?.startedAt||i,c={...s?.stepDurationsSec??{}},d=s?.stepStartedAt||i;if(a&&a!==u&&s?.stepStartedAt){let A=Math.max(0,Math.round((n.getTime()-new Date(s.stepStartedAt).getTime())/1e3));c[a]=(c[a]??0)+A,d=i;}let g=Math.max(0,Math.round((n.getTime()-new Date(d).getTime())/1e3)),p=Math.max(0,Math.round((n.getTime()-new Date(l).getTime())/1e3)),m=I(e),w=V(t)??{},f={checkedAt:i,source:r,message:m,details:De(o,w),startedAt:l,currentStep:u,stepStartedAt:d,stepElapsedSec:g,totalElapsedSec:p,stepDurationsSec:c};await b.writeFile(D,JSON.stringify(f,null,2),"utf8");}).catch(()=>{}));}async function Re(r,e){await b.mkdir(h.dirname(r),{recursive:true}),await b.appendFile(r,`${JSON.stringify(T(e))}
|
|
2
|
-
`,"utf8");}var v=class{constructor(e,t,n="info"){this.logDir=e;this.logFile=t;this.level=n;this.ensureLogFileReady();}logDir;logFile;level;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;get logPath(){return
|
|
3
|
-
`,"utf8");});}enqueueJsonLine(e,t){this.enqueueTask(()=>
|
|
1
|
+
import w from'fs/promises';import ee from'http';import te from'https';import y from'path';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';import {createHash}from'crypto';function j(r){let e=r.trim();return e==="."?".":e.replace(/\/$/,"")}function re(r){let e=String(r??"").trim();if(!e)return "";let t=e;if(/^https?:\/\//i.test(t))try{t=new URL(t).pathname;}catch{return ""}if(t=t.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!t)return "";let n=t.endsWith("/"),i=t.replace(/^\/+/,"").split("/").map(o=>o.replace(/[^A-Za-z0-9._-]/g,"")).filter(o=>o.length>0&&o!=="."&&o!=="..");if(i.length===0)return "";let s=`/${i.join("/")}`;return n&&y.extname(s)===""&&(s+="/"),s==="/"?"":s}function k(r){return !r||typeof r!="object"?{}:Object.fromEntries(Object.entries(r).map(([e,t])=>[e.trim(),String(t??"")]).filter(([e])=>e.length>0))}function ie(r){if(!r||typeof r!="object")return {};let e={};for(let[t,n]of Object.entries(r)){let i=t.trim();if(!i||!n||typeof n!="object")continue;let s=n,o={};if(typeof s.targetOrigin=="string"){let a=j(s.targetOrigin);a&&(o.targetOrigin=a);}let u=k(s.extraReplacements);if(Object.keys(u).length>0&&(o.extraReplacements=u),s.s3&&typeof s.s3=="object"){let a={},l=s.s3;typeof l.bucket=="string"&&(a.bucket=l.bucket.trim()),typeof l.prefix=="string"&&(a.prefix=l.prefix.trim()),typeof l.region=="string"&&(a.region=l.region.trim()),typeof l.htmlCacheControl=="string"&&(a.htmlCacheControl=l.htmlCacheControl.trim()),typeof l.assetCacheControl=="string"&&(a.assetCacheControl=l.assetCacheControl.trim()),Object.keys(a).length>0&&(o.s3=a);}if(s.cloudFront&&typeof s.cloudFront=="object"){let a={},l=s.cloudFront;typeof l.distributionId=="string"&&(a.distributionId=l.distributionId.trim()),Array.isArray(l.invalidationPaths)&&(a.invalidationPaths=l.invalidationPaths.map(c=>String(c??"").trim()).filter(c=>c.length>0)),Object.keys(a).length>0&&(o.cloudFront=a);}e[i]=o;}return e}function L(r){return r==="PROFESSIONAL"||r==="AGENCY"?r:void 0}function ne(r,e){if(!r||typeof r!="object")return null;let t=r,n=t.command;if(n!=="publish"&&n!=="crawl"&&n!=="deploy"&&n!=="invalidate"&&n!=="retry-timeouts"&&n!=="url"&&n!=="content-sync")return null;let i=Number.parseInt(String(t.intervalMinutes??"0"),10);if(!Number.isFinite(i)||i<1)return null;let s=String(t.id??`${n}-${e+1}`).trim();if(!s)return null;let o=String(t.deploymentProfile??"").trim(),u=String(t.url??"").trim(),a=Array.isArray(t.postTypes)?[...new Set(t.postTypes.map(c=>String(c??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],l=Array.isArray(t.listingPaths)?[...new Set(t.listingPaths.map(c=>String(c??"").trim()).filter(Boolean))]:[];return n==="content-sync"&&a.length===0?null:{id:s,enabled:t.enabled!==false,command:n,intervalMinutes:i,...n==="publish"||n==="crawl"?{crawlMode:t.crawlMode==="incremental"?"incremental":"full"}:{},...(n==="publish"||n==="deploy"||n==="invalidate"||n==="content-sync")&&o?{deploymentProfile:o}:{},...u?{url:u}:{},...a.length>0?{postTypes:a}:{},...l.length>0?{listingPaths:l}:{},...typeof t.includePostTypeArchives=="boolean"?{includePostTypeArchives:t.includePostTypeArchives}:{},...typeof t.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:t.includeTaxonomyArchives}:{},...typeof t.includeAuthorArchives=="boolean"?{includeAuthorArchives:t.includeAuthorArchives}:{},...typeof t.includeDateArchives=="boolean"?{includeDateArchives:t.includeDateArchives}:{},...typeof t.includePostsPage=="boolean"?{includePostsPage:t.includePostsPage}:{},...typeof t.includeSitemapChain=="boolean"?{includeSitemapChain:t.includeSitemapChain}:{}}}function U(r){let e=r&&typeof r=="object"?r:{},t=Array.isArray(e.rules)?e.rules.map((n,i)=>ne(n,i)).filter(n=>!!n):[];return {enabled:e.enabled===true,timezone:typeof e.timezone=="string"&&e.timezone.trim()!==""?e.timezone.trim():"UTC",rules:t}}function se(r){if(!r||typeof r!="object")return;let e=r,t={};for(let i of ["accountId","siteId"]){let s=e[i];typeof s=="string"&&s.trim()!==""&&(t[i]=s.trim());}let n=Number(e.lastUpdate??0);return Number.isFinite(n)&&n>0&&(t.lastUpdate=Math.floor(n)),e.subscriber===true&&(t.subscriber=true),Object.keys(t).length>0?t:void 0}function x(r){let e=r&&typeof r=="object"?r:{},t=String(e.accountId??"").trim(),n=String(e.siteId??"").trim(),i=e.subscriber===true,s=se(e.siteSettings),o={...s??{},...t?{accountId:s?.accountId??t}:{},...n?{siteId:s?.siteId??n}:{},...s?.subscriber===true||i?{subscriber:true}:{}},u={},a=String(e.apiBase??"").trim();a&&(u.apiBase=a);let l=String(e.runtimeToken??e.nonce??"").trim();l&&(u.runtimeToken=l);let c=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();c&&(u.virtualAssetBaseUrl=c),Object.keys(o).length>0&&(u.siteSettings=o);let d=L(e.subscriptionType);return d&&(u.subscriptionType=d),u}function oe(r){try{let e=new URL(r);globalThis.location=e;}catch{}}function $(r){return typeof r=="string"?r:r instanceof URL?r.toString():r.url}function ae(r,e){let t=new Headers(r instanceof Request?r.headers:void 0);if(e?.headers)for(let[n,i]of new Headers(e.headers).entries())t.set(n,i);return t}async function _(r,e,t=5){let n=new URL($(r)),i=String(e?.method??(r instanceof Request?r.method:"GET")).toUpperCase(),s=n.protocol==="http:"?ee:te,o=ae(r,e);return await new Promise((u,a)=>{let l=s.request(n,{method:i,headers:Object.fromEntries(o.entries()),...n.protocol==="https:"?{rejectUnauthorized:false}:{}},c=>{let d=[];c.on("data",p=>{d.push(Buffer.isBuffer(p)?p:Buffer.from(p));}),c.on("error",a),c.on("end",()=>{let p=c.statusCode??0,m=c.headers.location;if(t>0&&m&&[301,302,303,307,308].includes(p)){u(_(new URL(m,n),{method:p===303?"GET":i},t-1));return}let g=new Headers;for(let[f,h]of Object.entries(c.headers))Array.isArray(h)?g.set(f,h.join(", ")):typeof h=="string"&&g.set(f,h);u(new Response(Buffer.concat(d),{status:p,statusText:c.statusMessage??"",headers:g}));});});l.on("error",a),l.end();})}function le(r){let e=x(r.wpsuite),t={...e.siteSettings??{},...e.siteSettings?.subscriber===true||e.subscriptionType==="PROFESSIONAL"||e.subscriptionType==="AGENCY"?{subscriber:true}:{}},n=String(t.accountId??"").trim(),i=String(t.siteId??"").trim(),s=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();if(r.wpsuite={...e.apiBase?{apiBase:e.apiBase}:{},...e.runtimeToken?{runtimeToken:e.runtimeToken}:{},...s?{virtualAssetBaseUrl:s}:{},...Object.keys(t).length>0?{siteSettings:t}:{},...e.subscriptionType?{subscriptionType:e.subscriptionType}:{}},!n||!i||!s)return false;oe(r.sourceOrigin);let o=globalThis,a={...o.WpSuite??{},siteSettings:t,uploadUrl:s};return e.apiBase&&(a.apiBase=e.apiBase),o.WpSuite=a,true}async function ue(r){let e=String(r.wpsuite?.virtualAssetBaseUrl??r.wpsuite?.uploadUrl??"").trim();if(!le(r)){let i=r.wpsuite?.siteSettings,s=[String(i?.accountId??"").trim()?"":"accountId",String(i?.siteId??"").trim()?"":"siteId",e?"":"virtualAssetBaseUrl"].filter(Boolean);return {remote:null,diagnostic:{status:"invalid-runtime",virtualAssetBaseUrl:e,subscriptionType:null,error:`Missing WP Suite runtime field(s): ${s.join(", ")}.`,requests:[]}}}let t=globalThis.fetch,n=[];try{typeof t=="function"&&/^https?:\/\//i.test(e)&&(globalThis.fetch=(async(a,l)=>{let c=$(a);if(c.startsWith(e)){let d=(()=>{try{return new URL(c).pathname}catch{return c}})();try{let p=r.ignoreHttpsErrors&&c.startsWith("https://")?await _(a,l):await t(a,l);return n.push({path:d,status:p.status,ok:p.ok,error:null}),p}catch(p){throw n.push({path:d,status:null,ok:!1,error:p instanceof Error?p.message:String(p)}),p}}return t(a,l)}));let{getConfig:i}=await import('@smart-cloud/wpsuite-core'),s=await i("publisher"),o=s&&typeof s=="object"?s:null,u=L(o?.subscriptionType);return {remote:o,diagnostic:{status:o?"loaded":"unavailable",virtualAssetBaseUrl:e,subscriptionType:u??null,error:o?null:"WP Suite publisher config loader returned no configuration.",requests:n}}}catch(i){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:e,subscriptionType:null,error:i instanceof Error?i.message:String(i),requests:n}}}finally{typeof t=="function"&&(globalThis.fetch=t);}}function ce(r,e){let t=ie(e?.deploymentProfiles),n=String(e?.defaultDeploymentProfile??"").trim(),i=t[n]?n:"",s=L(e?.subscriptionType),o=x(r.wpsuite);return {...r,scheduler:U(e?.scheduler),deploymentProfiles:t,defaultDeploymentProfile:i,...s?{subscriptionType:s}:{},wpsuite:{...o,...o.siteSettings||s?{siteSettings:{...o.siteSettings??{},...o.siteSettings?.subscriber===true||s==="PROFESSIONAL"||s==="AGENCY"?{subscriber:true}:{}}}:{},...s?{subscriptionType:s}:{}}}}function E(r,e){let n=String(r||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!n)return e;let i=n.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return i.length>0?i.join("/"):e}function ge(){let r=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return r.trim()?y.resolve(r):""}function N(r,e,t){let n=String(e||"").trim();return n&&y.isAbsolute(n)?y.resolve(n):y.resolve(r,E(n,t))}async function D(r,e={}){let t=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",n=await w.readFile(t,"utf8"),i=JSON.parse(n);i.sourceOrigin=i.sourceOrigin.replace(/\/$/,""),i.targetOrigin=j(i.targetOrigin),i.ignoreHttpsErrors??=false,i.outputDir=String(i.outputDir||"export").trim()||"export",i.urlRewriteMode||=i.targetOrigin==="."?"relative":"absolute",i.noJavaScriptRenderPathPrefixes||=[],i.seedPaths||=[],i.generated404RequestPath=re(i.generated404RequestPath),i.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],i.allowedAssetHosts||=[],i.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],i.blockedPathPrefixes||=[],i.blockedSearchFragments||=[],i.concurrency||=1,i.maxPages||=0,i.extraReplacements=k(i.extraReplacements),i.postCrawlCopyMap=k(i.postCrawlCopyMap),i.logDir=String(i.logDir||"logs").trim()||"logs",i.verbose??=false,i.logLevel||=i.verbose?"debug":"info",i.s3SyncMode||="sdk-upload-delete",i.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},i.readiness.timeoutMs??=1500,i.readiness.fallbackWaitMs??=1500,i.viewport||={width:1440,height:1200},i.navigationTimeoutMs||=3e4,i.assetDownloadConcurrency=Number(i.assetDownloadConcurrency)>0?Number(i.assetDownloadConcurrency):i.concurrency,i.rewriteConcurrency=Number(i.rewriteConcurrency)>0?Number(i.rewriteConcurrency):i.assetDownloadConcurrency,i.wpsuite=x(i.wpsuite),i.scheduler=U(void 0),i.deploymentProfiles={},i.defaultDeploymentProfile="",i.deploymentTargetOverride=String(i.deploymentTargetOverride??"").trim();let s=await ue(i);e.onRemotePublisherConfigDiagnostic?.(s.diagnostic);let o=ce(i,s.remote),u=ge(),a=u?y.resolve(u,".."):"";return a?(o.outputDir=N(a,o.outputDir,"export"),o.logDir=N(a,o.logDir,"logs")):(y.isAbsolute(o.outputDir)||(o.outputDir=E(o.outputDir,"export")),y.isAbsolute(o.logDir)||(o.logDir=E(o.logDir,"logs"))),o}function pe(r){let e=r/6e4;if(Number.isInteger(e)&&e>=1)return `${e} minute${"s"}`;let t=Math.ceil(r/1e3);return `${t} second${t===1?"":"s"}`}async function M(r,e,t){let n=new AbortController,i=globalThis.setTimeout(()=>{n.abort(new Error(`${r} timed out after ${pe(e)}.`));},e);try{return await t({abortController:n,httpOptions:{abortSignal:n.signal,requestTimeout:e}})}finally{globalThis.clearTimeout(i);}}function me(r){return String(r||"").replace(/\\/g,"/").replace(/^\/+|\/+$/g,"")}function he(r,e){let t=r;t.endsWith("/")?t+="index.html":y.posix.basename(t).includes(".")||(t+="/index.html");let n=me(e);return n?`/${n}${t}`.replace(/\/{2,}/g,"/"):t}function q(r,e){let t=new Set;for(let n of r){let i=new URL(n,"https://content-sync.invalid");if(i.origin!=="https://content-sync.invalid")continue;let s=`${i.pathname}${i.search}`;t.add(s),t.add(`${he(i.pathname,e)}${i.search}`);}return [...t].sort()}var ye=".deploy-plan.json",Pe="deploy-plan.json";function be(){let r=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return r.trim()?y.resolve(r):""}function we(r){let e=String(r||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),t=y.posix.normalize(e);return !e||!t||t==="."||/^[a-zA-Z]:/.test(t)||t.startsWith("../")||t===".."?null:t}function Se(r){let e=String(r||"").trim();if(!e.startsWith("/")||e.startsWith("//")||e.includes("*")||e.includes("#"))return null;try{let t=new URL(e,"https://content-sync.invalid");return t.origin!=="https://content-sync.invalid"?null:`${y.posix.normalize(t.pathname)}${t.search}`}catch{return null}}function b(r){return [...new Set(r.map(we).filter(e=>e!==null))]}function ve(r,e){let t={generatedAt:String(e.generatedAt||new Date().toISOString()),outputDir:y.resolve(r.outputDir),runMode:e.runMode,crawlMode:e.crawlMode,fullSyncRequired:!!e.fullSyncRequired,changedFiles:b(e.changedFiles||[]),deletedFiles:b(e.deletedFiles||[]),rewriteTargets:b(e.rewriteTargets||[])};return e.schemaVersion===2?{...t,schemaVersion:2,runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,consumerId:String(e.consumerId||"").trim(),fromSequence:Math.max(0,Number(e.fromSequence)||0),toSequence:Math.max(0,Number(e.toSequence)||0),impactHash:String(e.impactHash||"").trim(),uploadGroups:{assets:b(e.uploadGroups?.assets||[]),content:b(e.uploadGroups?.content||[]),listings:b(e.uploadGroups?.listings||[]),sitemapLeaves:b(e.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:b(e.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((e.invalidationPaths||[]).map(Se).filter(n=>n!==null))].sort()}:{schemaVersion:1,...t,runMode:e.runMode}}function Ie(r){if(!r||typeof r!="object")return false;let e=r;if(e.schemaVersion===2){let t=e;return t.runMode==="content-sync"&&t.crawlMode==="incremental"&&t.fullSyncRequired===false&&typeof t.generatedAt=="string"&&typeof t.outputDir=="string"&&typeof t.consumerId=="string"&&t.consumerId.trim()!==""&&Number.isSafeInteger(t.fromSequence)&&Number.isSafeInteger(t.toSequence)&&Number(t.toSequence)>=Number(t.fromSequence)&&typeof t.impactHash=="string"&&/^[a-f0-9]{64}$/.test(t.impactHash)&&Array.isArray(t.changedFiles)&&Array.isArray(t.deletedFiles)&&Array.isArray(t.rewriteTargets)&&!!t.uploadGroups&&Array.isArray(t.uploadGroups.assets)&&Array.isArray(t.uploadGroups.content)&&Array.isArray(t.uploadGroups.listings)&&Array.isArray(t.uploadGroups.sitemapLeaves)&&Array.isArray(t.uploadGroups.sitemapIndexes)&&Array.isArray(t.invalidationPaths)}return e.schemaVersion===1&&typeof e.generatedAt=="string"&&typeof e.outputDir=="string"&&(e.runMode==="full"||e.runMode==="retry-timeouts"||e.runMode==="single-url")&&(e.crawlMode==="full"||e.crawlMode==="incremental")&&typeof e.fullSyncRequired=="boolean"&&Array.isArray(e.changedFiles)&&Array.isArray(e.deletedFiles)&&Array.isArray(e.rewriteTargets)}function Ce(r){let e=y.join(y.resolve(r.outputDir),ye),t=be();return t?[y.join(t,Pe),e]:[e]}async function W(r){let e=y.resolve(r.outputDir);for(let t of Ce(r))try{let n=await w.readFile(t,"utf8"),i=JSON.parse(n);if(!Ie(i)||y.resolve(i.outputDir)!==e)continue;return ve(r,i)}catch{}return null}function De(r){return typeof r.subscriptionType=="string"&&r.subscriptionType.trim()!==""}function B(r){let e="";for(let n=0;n<r.length;n++){let i=r[n];if(i==="--profile"){let s=(r[n+1]||"").trim();if(!s)throw new Error("Missing value for --profile.");e=s,n+=1;}else if(i.startsWith("--profile=")){let s=i.slice(10).trim();if(!s)throw new Error("Missing value for --profile.");e=s;}}let t=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return e||t||null}function Te(r,e){return {...r,...e??{}}}function Re(r,e){return {...r,...e??{},invalidationPaths:[...(e?.invalidationPaths??r.invalidationPaths)||[]]}}function H(r,e){let t=String(e??r.deploymentTargetOverride??"").trim();if(!De(r)){if(t)throw new Error(`Deployment target "${t}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:r}}let n=String(t||r.defaultDeploymentProfile||"").trim();if(!n)return {name:null,profile:null,config:r};let i=r.deploymentProfiles?.[n];if(!i)throw new Error(`Unknown deployment profile "${n}". Check the linked WPSuite publisher configuration.`);return {name:n,profile:i,config:{...r,targetOrigin:i.targetOrigin??r.targetOrigin,s3:Te(r.s3,i.s3),cloudFront:Re(r.cloudFront,i.cloudFront)}}}var z={error:0,warn:1,info:2,debug:3},Ae=/^(?:authorization|proxyAuthorization|runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken|xStaticPublisherToken|xApiKey)$/i;function C(r){return r.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 R(r){return typeof r=="string"?C(r):Array.isArray(r)?r.map(e=>R(e)):r instanceof Error?{name:r.name,message:C(r.message),...r.stack?{stack:C(r.stack)}:{}}:r&&typeof r=="object"?Object.fromEntries(Object.entries(r).map(([e,t])=>[e,Ae.test(e)?"[REDACTED]":R(t)])):r}function Q(r){return r?R(r):void 0}var J=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",T=J?y.join(J,"current-progress.json"):"",G=Promise.resolve();function V(r){return r.includes("crawl")?"crawl":r.includes("deploy")?"deploy":r.includes("invalidate")?"invalidate":r}function ke(r,e){let t={...r},n=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","pageQueue","assetQueue","sitemapQueue"]);for(let[i,s]of Object.entries(e)){let o=t[i];if(typeof o=="number"&&typeof s=="number"&&n.has(i)){t[i]=Math.max(o,s);continue}t[i]=s;}return t}function Ee(r,e,t){T&&(G=G.then(async()=>{let n=new Date,i=n.toISOString();await w.mkdir(y.dirname(T),{recursive:true});let s=await w.readFile(T,"utf8").then(I=>JSON.parse(I)).catch(()=>null),o=s&&typeof s.details=="object"&&s.details?s.details:{},u=V(r),a=s?.currentStep||V(s?.source||""),l=s?.startedAt||i,c={...s?.stepDurationsSec??{}},d=s?.stepStartedAt||i;if(a&&a!==u&&s?.stepStartedAt){let I=Math.max(0,Math.round((n.getTime()-new Date(s.stepStartedAt).getTime())/1e3));c[a]=(c[a]??0)+I,d=i;}let p=Math.max(0,Math.round((n.getTime()-new Date(d).getTime())/1e3)),m=Math.max(0,Math.round((n.getTime()-new Date(l).getTime())/1e3)),g=C(e),f=Q(t)??{},h={checkedAt:i,source:r,message:g,details:ke(o,f),startedAt:l,currentStep:u,stepStartedAt:d,stepElapsedSec:p,totalElapsedSec:m,stepDurationsSec:c};await w.writeFile(T,JSON.stringify(h,null,2),"utf8");}).catch(()=>{}));}async function Le(r,e){await w.mkdir(y.dirname(r),{recursive:true}),await w.appendFile(r,`${JSON.stringify(R(e))}
|
|
2
|
+
`,"utf8");}var v=class{constructor(e,t,n="info"){this.logDir=e;this.logFile=t;this.level=n;this.ensureLogFileReady();}logDir;logFile;level;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;get logPath(){return y.join(this.logDir,this.logFile)}artifactPath(e){return this.logFile.endsWith(".log.jsonl")?y.join(this.logDir,this.logFile.replace(/\.log\.jsonl$/u,`${e}.jsonl`)):y.join(this.logDir,`${this.logFile}${e}.jsonl`)}get errorsPath(){return this.artifactPath(".errors")}get rejectedPath(){return this.artifactPath(".rejected")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await w.mkdir(this.logDir,{recursive:true}),await w.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(e){this.writeQueue=this.writeQueue.then(e).catch(t=>{this.writeError=t instanceof Error?t:new Error(String(t));});}enqueueLine(e){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await w.appendFile(this.logPath,`${e}
|
|
3
|
+
`,"utf8");});}enqueueJsonLine(e,t){this.enqueueTask(()=>Le(e,t));}accepts(e){return z[e]<=z[this.level]}push(e,t,n){if(!this.accepts(e))return;let i=C(t),s=Q(n),o=JSON.stringify({time:new Date().toISOString(),level:e,message:i,...s||{}});this.enqueueLine(o),e==="error"?console.error(`[ERROR] ${i}`,s?JSON.stringify(s):""):e==="warn"?console.warn(`[WARN] ${i}`,s?JSON.stringify(s):""):console.log(`[${e.toUpperCase().padEnd(5)}] ${i}`);}info(e,t){this.push("info",e,t);}progress(e,t){Ee(this.logFile,e,t);}debug(e,t){this.push("debug",e,t);}warn(e,t){this.push("warn",e,t);}reject(e,t,n,i,s){let o={kind:e,url:t,reason:n,...i?{source:i}:{},...s||{}};this.enqueueJsonLine(this.rejectedPath,o),this.accepts("debug")&&this.push("debug",`Rejected ${e} ${t}: ${n}`,o);}error(e,t){this.enqueueJsonLine(this.errorsPath,{message:e,...t||{}}),this.push("error",e,t);}mark(e){this.marks.set(e,Date.now());}endMark(e,t){let n=this.marks.get(e);if(!n)return;let i=Date.now()-n,s=Number((i/1e3).toFixed(2));this.push("info",`Timing ${e}: ${s}s`,{name:e,ms:i,seconds:s,...t||{}});}async flush(){let e=Date.now()-this.startedAt,t=Number((e/1e3).toFixed(2));if(this.push("info",`Total time: ${t}s`,{name:"total",ms:e,seconds:t}),await this.writeQueue,this.writeError)throw this.writeError}};function Oe(){let r=String(process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"").trim();return r?y.join(y.resolve(r),"content-sync-invalidation.json"):""}async function F(r,e){if(!r)return;await w.mkdir(y.dirname(r),{recursive:true});let t=`${r}.${process.pid}.${Date.now()}.tmp`;await w.writeFile(t,JSON.stringify({...e,updatedAt:new Date().toISOString()},null,2),"utf8"),await w.rename(t,r);}async function Ne(r,e,t,n){if(!r)return null;try{let i=JSON.parse(await w.readFile(r,"utf8"));if(i.schemaVersion!==1||i.distributionId!==e||i.impactHash!==t||!Array.isArray(i.batches))throw new Error("Content-sync invalidation state does not match the deploy plan.");let s=i.batches.flatMap(o=>o.paths);return s.length!==n.length||s.some((o,u)=>o!==n[u])?null:i}catch(i){if(i.code==="ENOENT")return null;throw i}}function je(r,e=3e3){let t=[];for(let n=0;n<r.length;n+=e)t.push(r.slice(n,n+e));return t}async function Z(r=process.argv.slice(2)){let e=await D(),t=B(r),n=H(e,t),i=n.config,s=new v(i.logDir||"logs","invalidate.log.jsonl",i.logLevel??"info"),o=r.includes("--content-sync"),u=await W(e);if(o&&u?.schemaVersion!==2)throw new Error("Content-sync invalidation requires a valid schema-2 targeted deploy plan.");if(n.name&&s.info(`Using deployment profile: ${n.name}`),!i.cloudFront.distributionId){s.info("No CloudFront distributionId configured; skipping invalidation."),await s.flush();return}let a=u?.schemaVersion===2?u.invalidationPaths:i.cloudFront.invalidationPaths.length>0?i.cloudFront.invalidationPaths:["/*"],l=u?.schemaVersion===2?q(a,i.s3.prefix||""):a;if(u?.schemaVersion===2&&l.some(g=>g==="/*"))throw new Error("Content-sync cannot use a whole-distribution invalidation.");if(l.length===0){s.info("The targeted deploy plan has no CloudFront paths to invalidate."),await s.flush();return}let c=i.cloudFront.distributionId,d=new CloudFrontClient({region:"us-east-1",maxAttempts:5});if(s.mark("invalidate"),u?.schemaVersion!==2){let g=`smartcloud-static-publisher-${Date.now()}`;await M(`CloudFront invalidation for distribution ${c}`,3e5,({httpOptions:f})=>d.send(new CreateInvalidationCommand({DistributionId:c,InvalidationBatch:{CallerReference:g,Paths:{Quantity:l.length,Items:l}}}),f)),s.endMark("invalidate"),await s.flush();return}let p=Oe(),m=await Ne(p,c,u.impactHash,l);if(!m){let g=createHash("sha256").update(JSON.stringify(l)).digest("hex");m={schemaVersion:1,distributionId:c,impactHash:u.impactHash,updatedAt:new Date().toISOString(),batches:je(l).map((f,h)=>({index:h,callerReference:`wpsuite-content-sync-${u.impactHash.slice(0,24)}-${g.slice(0,24)}-${h}`,paths:f,invalidationId:null,status:"pending"}))},await F(p,m);}for(let g of m.batches){if(!g.invalidationId){let f=await M(`CloudFront targeted invalidation batch ${g.index+1}`,3e5,({httpOptions:I})=>d.send(new CreateInvalidationCommand({DistributionId:c,InvalidationBatch:{CallerReference:g.callerReference,Paths:{Quantity:g.paths.length,Items:g.paths}}}),I)),h=String(f.Invalidation?.Id||"").trim();if(!h)throw new Error("CloudFront did not return an invalidation ID.");g.invalidationId=h,g.status="created",await F(p,m);}await waitUntilInvalidationCompleted({client:d,maxWaitTime:900,minDelay:2,maxDelay:15},{DistributionId:c,Id:g.invalidationId}),g.status="completed",await F(p,m),s.info(`CloudFront invalidation batch ${g.index+1}/${m.batches.length} completed.`,{invalidationId:g.invalidationId,pathCount:g.paths.length});}s.endMark("invalidate"),await s.flush();}Z().catch(async r=>{console.error(r);try{let e=await D().catch(()=>null),t=new v(e?.logDir??"logs","invalidate.log.jsonl","debug");t.error(`Unhandled error: ${r instanceof Error?r.message:String(r)}`,r instanceof Error?{stack:r.stack}:void 0),await t.flush();}catch{}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.41",
|
|
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.",
|