@smart-cloud/publisher-exporter 1.1.37 → 1.1.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import {spawn}from'child_process';import {existsSync,readFileSync}from'fs';import o from'path';import {fileURLToPath}from'url';var c=o.dirname(fileURLToPath(import.meta.url)),i=o.resolve(c,"..");function f(){try{let r=readFileSync(o.join(i,"package.json"),"utf8"),e=JSON.parse(r);if(typeof e.version=="string"&&e.version.trim())return e.version.trim()}catch{}return "unknown"}function g(){console.log(`publisher-exporter <command> [args]
2
+ import {spawn}from'child_process';import {existsSync,readFileSync}from'fs';import o from'path';import {fileURLToPath}from'url';var p=o.dirname(fileURLToPath(import.meta.url)),l=o.resolve(p,"..");function f(){try{let n=readFileSync(o.join(l,"package.json"),"utf8"),e=JSON.parse(n);if(typeof e.version=="string"&&e.version.trim())return e.version.trim()}catch{}return "unknown"}function g(){console.log(`publisher-exporter <command> [args]
3
3
 
4
4
  Commands:
5
5
  crawl Run the crawl phase
6
6
  deploy Deploy the prepared output
7
7
  invalidate Request CloudFront invalidation
8
8
  publish Run crawl, deploy, then invalidate
9
+ content-sync Run an internal claimed content-sync job
9
10
  queue-runner Process queued jobs from runtime JSON
10
11
  prune-logs Delete archived log directories older than a retention window
11
12
  install-browsers Install Playwright Chromium into the current/shared browsers path
@@ -19,4 +20,4 @@ Examples:
19
20
  publisher-exporter prune-logs --runtime-dir /srv/site/runtime --older-than-days 30
20
21
  publisher-exporter install-browsers
21
22
  publisher-exporter --version
22
- `);}function v(){console.log(f());}function p(r){let e=o.join(c,`${r}.js`);if(!existsSync(e))throw new Error(`Missing CLI entrypoint: ${e}`);return e}function y(){let r=[o.join(i,"node_modules","playwright","cli.js"),o.join(i,"node_modules","playwright-core","cli.js")];for(let e of r)if(existsSync(e))return e;throw new Error("Playwright CLI was not found under this package. Run `npm install` first.")}function t(r,e){return new Promise((n,s)=>{let a=spawn(process.execPath,[r,...e],{cwd:i,env:process.env,stdio:"inherit"});a.on("error",s),a.on("close",(d,l)=>{if(l){s(new Error(`Command terminated by signal ${l}.`));return}n(d??1);});})}async function b(r){for(let e of ["crawl","deploy","invalidate"]){let n=await t(p(e),r);if(n!==0)return n}return 0}async function x(){let[r="help",...e]=process.argv.slice(2);if(["version","--version","-v"].includes(r)){v();return}if(["help","--help","-h"].includes(r)){g();return}if(r==="publish"){process.exitCode=await b(e);return}if(r==="install-browsers"){let n=e.length>0?e:["install","chromium"];process.exitCode=await t(y(),n);return}if(r==="crawl"||r==="deploy"||r==="invalidate"||r==="queue-runner"||r==="prune-logs"){process.exitCode=await t(p(r),e);return}throw new Error(`Unknown command: ${r}`)}x().catch(r=>{console.error(r instanceof Error?r.message:String(r)),process.exit(1);});
23
+ `);}function v(){console.log(f());}function a(n){let e=o.join(p,`${n}.js`);if(!existsSync(e))throw new Error(`Missing CLI entrypoint: ${e}`);return e}function y(){let n=[o.join(l,"node_modules","playwright","cli.js"),o.join(l,"node_modules","playwright-core","cli.js")];for(let e of n)if(existsSync(e))return e;throw new Error("Playwright CLI was not found under this package. Run `npm install` first.")}function i(n,e){return new Promise((r,s)=>{let t=spawn(process.execPath,[n,...e],{cwd:l,env:process.env,stdio:"inherit"});t.on("error",s),t.on("close",(d,c)=>{if(c){s(new Error(`Command terminated by signal ${c}.`));return}r(d??1);});})}async function b(n){let e=`direct-publish-${Date.now()}`,r=await i(a("content-sync"),["--capture-baseline-cutoffs",e]);if(r!==0)return r;for(let s of ["crawl","deploy","invalidate"]){let t=await i(a(s),n);if(t!==0)return t}return i(a("content-sync"),["--establish-baselines",e])}async function x(){let[n="help",...e]=process.argv.slice(2);if(["version","--version","-v"].includes(n)){v();return}if(["help","--help","-h"].includes(n)){g();return}if(n==="publish"){process.exitCode=await b(e);return}if(n==="install-browsers"){let r=e.length>0?e:["install","chromium"];process.exitCode=await i(y(),r);return}if(n==="crawl"||n==="deploy"||n==="invalidate"||n==="queue-runner"||n==="prune-logs"||n==="content-sync"){process.exitCode=await i(a(n),e);return}throw new Error(`Unknown command: ${n}`)}x().catch(n=>{console.error(n instanceof Error?n.message:String(n)),process.exit(1);});
@@ -0,0 +1,11 @@
1
+ import x from'fs/promises';import zr from'http';import yn from'https';import S from'path';import qn,{createHash}from'crypto';import {request,chromium}from'playwright';import {gunzipSync}from'zlib';import fs 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 Ro from'mime-types';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';var Br=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 bt(e){return Array.isArray(e)?e.map(bt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,bt(n)])):e}function Hr(e){return JSON.stringify(bt(e))}function oe(e){return createHash("sha256").update(Hr(e)).digest("hex")}function vt(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(vt(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 Oe(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 gn(e,t,n){return oe({schemaVersion:1,sourceOrigin:vt(e),ruleId:t.trim(),scope:Oe(n)})}function mn(e){return oe({schemaVersion:1,...e})}function fn(e){let t=String(e.siteId??"").trim()||String(e.accountId??"").trim()||vt(e.sourceOrigin);return `content-sync:${oe({siteIdentity:t,ruleId:e.ruleId.trim(),targetFingerprint:e.targetFingerprint}).slice(0,48)}`}function hn(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 pn(e){return e?.status==="publish"&&!!e.url}function Wr(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 Ct(e){let t=Oe(e.scope),n=new Map;hn(e.events);for(let r of e.events)for(let s of [r.before,r.after])for(let i of s?.archiveFamilies??[]){if(!Br.has(i.kind)||!Wr(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 wn(e){let t=Oe(e.scope),n=hn(e.events),r=new Set,s=new Set,i=new Map(Ct({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=pn(p),f=pn(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 je(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 Qr="wp-json/smartcloud-static-publisher/v1/content-sync/",Jr=25*1024*1024,Xe=class extends Error{status;code;constructor(t,n,r){super(r),this.name="ContentSyncApiError",this.status=t,this.code=n;}},et=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(`${Qr}${t}`,n)}async post(t,n){let r=this.endpoint(t),s=Buffer.from(JSON.stringify(n),"utf8"),i=r.protocol==="https:"?yn:zr,o=r.protocol==="https:"?new yn.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>Jr){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 Xe(l.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let f=l.statusCode??500;if(f<200||f>=300){a(new Xe(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 tt(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 Rt(e){let t=await Le(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 Sn(e,t){await Ie(e.releaseCutoff,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Ie(e,t){await x.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await x.writeFile(n,JSON.stringify(t,null,2),"utf8"),await x.rename(n,e);}async function Le(e){try{return JSON.parse(await x.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 It(e){let t=await Le(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 Pn(e,t){await Ie(e.baseline,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function bn(e){let t=await Le(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 vn(e,t){await Ie(e.current,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Cn(e){let t=await Le(e.impact);if(t===null)return null;let n=t;return je(n),n}async function Rn(e,t){je(t),await Ie(e.impact,t);}async function In(e,t){await Ie(e.checkpoint,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function At(e){let t=await Le(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 xt(e,t){await Ie(e.state,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Tt(e){await Promise.all([e.current,e.checkpoint].map(async t=>{try{await x.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}));}function xn(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function Zr(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 $t(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t.trim(),String(n??"")]).filter(([t])=>t.length>0))}function Yr(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=xn(i.targetOrigin);a&&(o.targetOrigin=a);}let u=$t(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 Et(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function Xr(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 Tn(e){let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.rules)?t.rules.map((r,s)=>Xr(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 es(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 Mt(e){let t=e&&typeof e=="object"?e:{},n=String(t.accountId??"").trim(),r=String(t.siteId??"").trim(),s=t.subscriber===true,i=es(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=Et(t.subscriptionType);return d&&(u.subscriptionType=d),u}function ts(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function $n(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function ns(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 kn(e,t,n=5){let r=new URL($n(e)),s=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),i=r.protocol==="http:"?zr:yn,o=ns(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(kn(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 rs(e){let t=Mt(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;ts(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 ss(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!rs(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=$n(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 kn(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=Et(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 is(e,t){let n=Yr(t?.deploymentProfiles),r=String(t?.defaultDeploymentProfile??"").trim(),s=n[r]?r:"",i=Et(t?.subscriptionType),o=Mt(e.wpsuite);return {...e,scheduler:Tn(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 kt(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 os(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function An(e,t,n){let r=String(t||"").trim();return r&&S.isAbsolute(r)?S.resolve(r):S.resolve(e,kt(r,n))}async function ne(e,t={}){let n=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",r=await x.readFile(n,"utf8"),s=JSON.parse(r);s.sourceOrigin=s.sourceOrigin.replace(/\/$/,""),s.targetOrigin=xn(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=Zr(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=$t(s.extraReplacements),s.postCrawlCopyMap=$t(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=Mt(s.wpsuite),s.scheduler=Tn(void 0),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let i=await ss(s);t.onRemotePublisherConfigDiagnostic?.(i.diagnostic);let o=is(s,i.remote),u=os(),a=u?S.resolve(u,".."):"";return a?(o.outputDir=An(a,o.outputDir,"export"),o.logDir=An(a,o.logDir,"logs")):(S.isAbsolute(o.outputDir)||(o.outputDir=kt(o.outputDir,"export")),S.isAbsolute(o.logDir)||(o.logDir=kt(o.logDir,"logs"))),o}var as=".deploy-plan.json",cs="deploy-plan.json",us=".crawl-incomplete.json",ls="crawl-incomplete.json";function En(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Mn(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 ds(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(Mn).filter(t=>t!==null))]}function Fn(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(ds).filter(r=>r!==null))].sort()}:{schemaVersion:1,...n,runMode:t.runMode}}function ps(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 Ft(e){let t=S.join(S.resolve(e.outputDir),as),n=En();return n?[S.join(n,cs),t]:[t]}function Dt(e){let t=S.join(S.resolve(e.outputDir),us),n=En();return n?[S.join(n,ls),t]:[t]}function he(e,t){let n=S.resolve(e),r=S.resolve(t),s=S.relative(n,r).replace(/\\/g,"/");return Mn(s)}async function nt(e){let t=S.resolve(e.outputDir);for(let n of Ft(e))try{let r=await x.readFile(n,"utf8"),s=JSON.parse(r);if(!ps(s)||S.resolve(s.outputDir)!==t)continue;return Fn(e,s)}catch{}return null}async function Ot(e,t){let n=Fn(e,t);for(let r of Ft(e)){await x.mkdir(S.dirname(r),{recursive:true});let s=`${r}.${process.pid}.${Date.now()}.tmp`;await x.writeFile(s,JSON.stringify(n,null,2),"utf8"),await x.rename(s,r);}}async function Ae(e){for(let t of Ft(e))try{await x.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}async function Dn(e,t){let n={schemaVersion:1,startedAt:String(t.startedAt||new Date().toISOString()),outputDir:S.resolve(e.outputDir)};for(let r of Dt(e)){await x.mkdir(S.dirname(r),{recursive:true});let s=`${r}.${process.pid}.tmp`;await x.writeFile(s,JSON.stringify(n,null,2),"utf8"),await x.rename(s,r);}}async function On(e){let t=S.resolve(e.outputDir);for(let n of Dt(e)){let r;try{r=await x.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 jn(e){for(let t of Dt(e))try{await x.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}function _e(e,t=10){return qn.createHash("sha1").update(e).digest("hex").slice(0,t)}async function gs(e){await x.mkdir(S.dirname(e),{recursive:true});}async function Ne(e,t,n){await gs(e);let r=S.join(S.dirname(e),`.${S.basename(e)}.${process.pid}.${Date.now()}.${qn.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await x.writeFile(r,t,n??"utf8"):await x.writeFile(r,t),await x.rename(r,e);}catch(s){throw await x.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(/&quot;/g,'"').replace(/&#34;/g,'"').replace(/&apos;/g,"'").replace(/&#39;/g,"'").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">")}function xe(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function rt(e){return e.replace(/\//g,"\\/")}function Un(e){return e.replace(/\//g,"\\\\/")}function ms(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 Ln(e,t,n){if(!t)return;e[t]=n;let r=rt(t),s=rt(n);e[r]=s;let i=Un(t),o=Un(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 st(e,t,n){Ln(e,t,n);let r=ms(t);r&&r!==t&&Ln(e,r,n);}function jt(e,t){let n=t.startsWith("/")?t:`/${t}`,r=(e||"").replace(/\/$/,"");return !r||r==="."||r==="/"?n:`${r}${n}`}function _n(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function Nn(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 Ss=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Ps=new Set([".html",".htm"]),Bn="WPSuite.io Static Publisher",bs=Bn.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function vs(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Cs(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function Rs(e,t,n){return Cs(t)?e.replace(new RegExp(`(?<!:)${vs(t)}`,"g"),n):e.split(t).join(n)}function Is(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 Ps.has(s)?/<head\b|<html\b|<!doctype html/i.test(t):false}function As(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${bs}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${Bn}" />`;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
+ `)?`\r
3
+ `:`
4
+ `;return e.replace(/<head\b[^>]*>/i,s=>`${s}${r} ${t}`)}function xs(e){let t=ce(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function Ts(e,t){let n=[...new Set(t)].filter(i=>i.includes("/")&&!/\\+\//.test(i)).map(i=>[i,rt(i)]).filter(([i,o])=>i!==o).sort((i,o)=>o[0].length-i[0].length);if(!n.length)return e;let r=i=>{let o=i;for(let[u,a]of n)o=o.split(u).join(a);return o},s=e.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(i,o,u,a)=>`${o}${r(u)}${a}`);return s=s.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(i,o,u,a,c)=>xs(a)?`${o}${r(a)}${c}`:i),s}function $s(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 ks(e,t,n){let r=$s(t,n);if(!r)return e;let s=e;for(let i of Ss){let o=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),u=new RegExp(`(?:\\.{1,}/)+${o}`,"g"),a=new RegExp(`(?<!\\.)/${o}`,"g");s=s.replace(u,`${r}${i}`).replace(a,`${r}${i}`);let c=i.replace(/\//g,"\\/"),l=r.replace(/\//g,"\\/"),d=c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),p=new RegExp(`(?:\\.{1,}\\\\/)+${d}`,"g"),g=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${d}`,"g"),m=new RegExp(`(?<![\\.\\\\])\\/${d}`,"g");s=s.replace(p,`${l}${c}`).replace(g,`${l}${c}`).replace(m,`${l}${c}`);}return s}function Lt(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:_n(t,e.targetOrigin),i=r?`${r.search}${r.hash}`:"";return e.urlRewriteMode==="root-relative"?`${s}${i}`:`${Nn(e.outputDir,n,s)}${i}`}function Ut(e,t,n,r,s){st(e,n,Lt(t,r,s));}function Es(e,t,n,r,s){if(!n||n===r)return;st(e,n,r);let i=Lt(t,n,s),o=Lt(t,r,s);st(e,i,o);}function qt(e,t,n,r,s={}){let i=e,o={};Ut(o,t,t.sourceOrigin,t.targetOrigin,r);for(let[a,c]of Object.entries(t.extraReplacements))Ut(o,t,a,c,r);for(let[a,c]of Object.entries(n))Ut(o,t,a,c,r);for(let[a,c]of Object.entries(s)){let l=n[a];!l||l===c||Es(o,t,c,l,r);}let u=Object.entries(o).sort((a,c)=>c[0].length-a[0].length);for(let[a,c]of u)i=Rs(i,a,c);return t.urlRewriteMode!=="absolute"&&(i=ks(i,t,r)),i=Ts(i,u.map(([,a])=>a)),Is(t,i,r)&&(i=As(i)),i}async function Ms(e,t,n,r){let s=S.join(e.outputDir,r),i=S.extname(s).toLowerCase(),o;try{o=await x.readFile(s,"utf8");}catch(c){if(c.code!=="ENOENT")throw c;return {changed:false}}let a=qt(o,e,t,i===".js"||i===".mjs"?void 0:s,n);return a!==o?(await Ne(s,a,"utf8"),{changed:true}):{changed:false}}async function Fs(e,t){return await new Promise((n,r)=>{let s=a=>{if(u(),a?.error){r(new Error(a.error));return}n({changed:!!a?.changed});},i=a=>{u(),r(a);},o=a=>{u(),a!==0&&r(new Error(`Rewrite worker exited with code ${a}.`));},u=()=>{e.off("message",s),e.off("error",i),e.off("exit",o);};e.on("message",s),e.on("error",i),e.on("exit",o),e.postMessage({file:t});})}async function it(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 fs(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(p=>p!=="asset-map.json"&&be(p)),i=0;if(s.length===0)return 0;let o=Math.max(1,Number(e.rewriteConcurrency||e.assetDownloadConcurrency||1)),u=Math.max(1,Math.min(o,s.length,availableParallelism()));await n.onStart?.({totalFiles:s.length,workerCount:u});let a=0,c=0,l=null;if(u===1){for(let p of s){let g=await Ms(e,t,n.previousAssetMap??{},p);g.changed&&(i+=1),c+=1,await n.onProgress?.({index:c,totalFiles:s.length,changedTextFiles:i,file:p,changed:g.changed});}return i}let d=Array.from({length:u},async()=>{let p=new Worker(new URL("./rewrite-worker.js",import.meta.url),{workerData:{config:e,assetMap:t,previousAssetMap:n.previousAssetMap??{}}});try{for(;!l;){let g=a;if(g>=s.length)return;a+=1;let m=s[g],f=await Fs(p,m);f.changed&&(i+=1),c+=1,await n.onProgress?.({index:c,totalFiles:s.length,changedTextFiles:i,file:m,changed:f.changed});}}catch(g){throw l=g instanceof Error?g:new Error(String(g)),l}finally{await p.terminate().catch(()=>{});}});return await Promise.all(d),i}var ie={error:0,warn:1,info:2,debug:3},Hn=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",ot=Hn?S.join(Hn,"current-progress.json"):"",Wn=Promise.resolve();function zn(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function Ds(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 Qn(e,t,n){ot&&(Wn=Wn.then(async()=>{let r=new Date,s=r.toISOString();await x.mkdir(S.dirname(ot),{recursive:true});let i=await x.readFile(ot,"utf8").then(f=>JSON.parse(f)).catch(()=>null),o=i&&typeof i.details=="object"&&i.details?i.details:{},u=zn(e),a=i?.currentStep||zn(i?.source||""),c=i?.startedAt||s,l={...i?.stepDurationsSec??{}},d=i?.stepStartedAt||s;if(a&&a!==u&&i?.stepStartedAt){let f=Math.max(0,Math.round((r.getTime()-new Date(i.stepStartedAt).getTime())/1e3));l[a]=(l[a]??0)+f,d=s;}let p=Math.max(0,Math.round((r.getTime()-new Date(d).getTime())/1e3)),g=Math.max(0,Math.round((r.getTime()-new Date(c).getTime())/1e3)),m={checkedAt:s,source:e,message:t,details:Ds(o,n??{}),startedAt:c,currentStep:u,stepStartedAt:d,stepElapsedSec:p,totalElapsedSec:g,stepDurationsSec:l};await x.writeFile(ot,JSON.stringify(m,null,2),"utf8");}).catch(()=>{}));}async function Jn(e,t){await x.mkdir(S.dirname(e),{recursive:true}),await x.appendFile(e,`${JSON.stringify(t)}
5
+ `,"utf8");}function Os(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 js(e,t,n){return {checkedAt:new Date().toISOString(),currentStep:Os(e,n),level:e,message:t,details:n??{}}}var Te=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 x.mkdir(this.logDir,{recursive:true}),await x.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 x.appendFile(this.logPath,`${t}
6
+ `,"utf8");});}enqueueJsonLine(t,n){this.enqueueTask(()=>Jn(t,n));}accepts(t){return ie[t]<=ie[this.level]}push(t,n,r){if(!this.accepts(t))return;let s=JSON.stringify({time:new Date().toISOString(),level:t,message:n,...r||{}});this.enqueueLine(s),t==="error"?console.error(`[ERROR] ${n}`,r?JSON.stringify(r):""):t==="warn"?console.warn(`[WARN] ${n}`,r?JSON.stringify(r):""):console.log(`[${t.toUpperCase().padEnd(5)}] ${n}`);}info(t,n){this.push("info",t,n);}progress(t,n){Qn(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}},at=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 x.mkdir(this.logDir,{recursive:true}),await x.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 x.appendFile(this.logPath,`${t}
7
+ `,"utf8");});}enqueueJsonLine(t,n){this.enqueueTask(()=>Jn(t,n));}updateCurrentEvent(t,n,r){let s=js(t,n,r);this.enqueueTask(async()=>{await x.mkdir(this.logDir,{recursive:true}),await x.writeFile(this.currentEventPath,JSON.stringify(s,null,2),"utf8");});}push(t,n,r){let s=JSON.stringify({time:new Date().toISOString(),level:t,message:n,...r||{}});this.enqueueLine(s),this.updateCurrentEvent(t,n,r),t==="error"?console.error(n,r||""):t==="warn"?console.warn(n,r||""):(ie[this.level]>=ie.debug||["summary","page","sitemap","asset","timing"].includes(t))&&console.log(n);}info(t,n){this.push("info",t,n);}debug(t,n){ie[this.level]<ie.debug||this.push("debug",t,n);}progress(t,n){Qn("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 _t="(?: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 Vn(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 Kn(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]&&Vn(i[1])&&n.push({index:i.index??0,value:i[1]});for(let i of e.matchAll(s))i[1]&&Vn(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 _s=["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"],cr=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"]),ur=new Set(["",".html",".htm"]),Ns=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),Bs=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function Hs(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 Vt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Ws(){let e=Vt();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 Qs(e){let t=e.trim(),n=[{alias:"@storage-root",root:Ws(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@runtime",root:Vt(),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 lr(e){let t=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(t)return S.resolve(t);let n=Vt();return n?S.join(n,"crawl-manifest.json"):S.join(e.outputDir,".crawl-manifest.json")}function dr(){return {schemaVersion:3,updatedAt:"",pages:{},assets:{}}}function Gn(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 Js(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 Ht(e){let t=e?.["content-type"]?.trim();return t||null}function Vs(){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 Zn(e,t,n){let r=he(t.outputDir,n);r&&(e.deletedFiles.add(r),e.changedFiles.delete(r));}function ve(e,t){e.rewriteTargets.add(S.resolve(t));}async function Ks(e){try{let t=await x.readFile(lr(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,Gn(s)])),assets:Object.fromEntries(Object.entries(n.assets).map(([r,s])=>[r,Js(s)]))};if(n.schemaVersion===1)return {schemaVersion:3,updatedAt:String(n.updatedAt||""),pages:Object.fromEntries(Object.entries(n.pages).map(([r,s])=>[r,Gn(s)])),assets:{}}}}catch{}return dr()}function Wt(e){return JSON.parse(JSON.stringify(e))}async function Gs(e,t){let n=lr(e);await x.mkdir(S.dirname(n),{recursive:true}),await x.writeFile(n,JSON.stringify(t,null,2),"utf8");}async function we(e,t){if(!t.trackManifest)return;let n=async()=>{let r=Wt(t.manifest);r.updatedAt=new Date().toISOString(),t.manifest.updatedAt=r.updatedAt,await Gs(e,r);};t.manifestSaveChain=t.manifestSaveChain.then(n,n),await t.manifestSaveChain;}function He(e){if(!e)return null;let t=e.trim();return t||null}function Zs(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 Ys(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:String(u)}),new Map}}async function Nt(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 Ys(e,t,[r],s)).get(r)??null;return Zt(e,r)&&(!o||o.supported!==true||!o.token)&&(o=await ti(e,t,r,s)),o=ei(e,o),n.changeTokenCache.set(r,o),o}function Xs(e){return `subscriber=${e.wpsuite?.siteSettings?.subscriber===true?"1":"0"}`}function ei(e,t){if(!t?.supported||!t.token)return t;let n=Xs(e);return {...t,token:_e(`${t.token}
8
+ ${n}`,40),tokenSource:t.tokenSource?`${t.tokenSource}+site-subscriber`:"site-subscriber"}}async function ti(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=_e(`${n}
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 ni(e,t,n,r,s,i){let o=Zt(e,s);if(!r.enabled)return {action:"render",changeToken:r.trackManifest?await Nt(e,t,r,s,i):null};let u=r.manifest.pages[s];if(!u)return {action:"render",changeToken:await Nt(e,t,r,s,i)};let a=await Nt(e,t,r,s,i);if(a?.supported&&a.token)return u.changeToken===a.token?o&&!await ri(e,t,s,i)?{action:"render",changeToken:a}:{action:"reuse",changeToken:a}:{action:"render",changeToken:a};let c=He(n.sitemapLastmodByPage[s]);return c&&u.sitemapLastmod&&u.sitemapLastmod===c?{action:"reuse",changeToken:a}:{action:"render",changeToken:a}}async function ri(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 si(e,t,n,r,s){let i=Yn(n.previousManifest,void 0,r,"previous-manifest"),o=0;for(let[p,g]of Object.entries(n.manifest.pages))if(!n.seenPages.has(p)){Zn(s,e,g.outputPath);try{await x.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=Yn(n.manifest,n.runId,r,"active-manifest"),a=new Set,c=new Set;for(let p of u){for(let f of We(e,p))a.add(f);let g=n.manifest.assets[p]?.outputPath;g&&c.add(g);let m=ze(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=ze(e,t.assetMap,p);if(!u.has(p)&&f)g.add(f);else if(!u.has(p)){let h=bi(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)){Zn(s,e,h);try{await x.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 We(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 Yn(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 Xn(e,t,n){for(let r of t)for(let s of We(e,r))if(n.has(s))return true;return false}function ii(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=Zs(r,s);if(o.size===0)return [...i];for(let u of Object.values(t.manifest.pages))Xn(e,u.discoveredAssets,o)&&i.add(S.resolve(u.outputPath));for(let[u,a]of Object.entries(t.manifest.assets)){a.isText&&Xn(e,a.discoveredAssets,o)&&i.add(S.resolve(a.outputPath));for(let c of We(e,u))if(o.has(c)){G(n,e,a.outputPath),a.isText&&i.add(S.resolve(a.outputPath));break}}return [...i]}function oi(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 ai(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(ze(e,t.assetMap,i));for(let i of Object.values(n.manifest.assets))i.lastSeenRunId===n.runId&&s(i.outputPath);return r}async function ci(e,t,n,r,s){let i=[...r.deletedFiles].sort(),o=ai(e,t,n),u=0;for(let l of [...o].sort()){try{if((await x.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 x.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 We(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 ui(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 pr(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,Gt(r.pathname))}catch{return null}}function li(e,t,n){for(let r of ui(e,n)){let s=t[r];if(!s)continue;let i=pr(e,s);if(i)return {outputPath:i,publicUrl:s}}return null}function di(e,t,n){for(let r of We(e,n)){let s=t[r];if(!s)continue;let i=pr(e,s);if(i)return i}return null}function ze(e,t,n){let r=di(e,t,n);if(r)return r;try{return gt(e,n).originalFilePath}catch{return null}}function pi(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.join(S.resolve(e),"queue-runner-heartbeat.json"):""}async function er(e){let t=pi();if(t)try{let n=await x.readFile(t,"utf8"),r=JSON.parse(n);if(!r||typeof r!="object")return;await x.writeFile(t,JSON.stringify({...r,checkedAt:new Date().toISOString(),status:"running",currentStep:"rewrite",message:e},null,2),"utf8");}catch{}}function gi(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=ze(e,t.assetMap,r);!s||!be(s)||n.add(S.resolve(s));}return [...n]}var dt="re:",ct=new Map;function mi(e){if(!e.startsWith(dt))return null;let t=ct.get(e);if(t!==void 0)return t||null;let n=e.slice(dt.length).trim();if(!n)return ct.set(e,false),null;try{let r=new RegExp(n);return ct.set(e,r),r}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),ct.set(e,false),null}}function Kt(e,t){let n=mi(t);return n?n.test(e):t.startsWith(dt)?false:e.startsWith(t)}function fi(e,t){return t.find(n=>Kt(e,n))}function gr(e,t){let n=fi(t.pathname,e.blockedPathPrefixes);if(n)return n.startsWith(dt)?`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 hi(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 wi(e,t){return hi(e).has(t.hostname)}function yi(e){let t=ce(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function zt(e){let t=ce(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function Si(e){let t=ce(e).replace(/\\\//g,"/").trim(),n=S.extname(t).toLowerCase();return cr.has(n)||ur.has(n)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function $e(e){return Bs.some(t=>e.pathname.startsWith(t))}function H(e,t,n=e.sourceOrigin,r,s="url"){let i=yi(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(zt(i))return r?.ignore(s,t,"looks like JavaScript/code fragment",n),null;if(Si(i))return r?.ignore(s,t,"looks like JavaScript property access",n),null;try{let o=new URL(i,n);if(mr(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(!wi(e,o))return r?.ignore(s,o.toString(),"host not allowed",n),null;let u=gr(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 mr(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 mr(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 fr(e){return cr.has(S.extname(e.pathname).toLowerCase())}function Se(e){return $e(e)?false:ur.has(S.extname(e.pathname).toLowerCase())}function ke(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function q(e,t){return !!(ke(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(n=>Kt(t.pathname,n))||fr(t)||!Se(t)&&!$e(t))}function le(e,t){let n=new URL(t),r=Gt(n.pathname);return r.endsWith("/")?r+="index.html":S.extname(r)||(r+="/index.html"),S.join(e.outputDir,r)}function Gt(e){try{return decodeURIComponent(e)}catch{return e}}function Pi(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 Zt(e,t){let n=Pi(e);if(!n)return false;try{return new URL(t,e.sourceOrigin).toString()===n}catch{return false}}function gt(e,t){let n=new URL(t),r=Gt(n.pathname);r.endsWith("/")&&(r+="index.html");let s=!!n.search,i=r,o=S.join(e.outputDir,i),u=jt(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}.${_e(n.search)}${c||".bin"}`;return {originalPathname:i,originalFilePath:o,originalPublicUrl:u,originalPublicUrlWithSearch:a,preferQueryHashed:s,hashedPathname:d,hashedFilePath:S.join(e.outputDir,d),hashedPublicUrl:jt(e.targetOrigin,d)}}function bi(e,t,n,r){let s=ye(t,n,"asset",r);return s?gt(e,s.toString()):null}function vi(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 hr(e){try{return await x.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Qe(e){try{return await x.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function Ci(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 wr(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let n=Date.parse(t);return Number.isFinite(n)?n:null}function Ri(e,t){let n=wr(t),r=Ci(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 Ii(e,t){if(!t)return;let n=wr(t);if(n===null)return;let r=await Qe(e);if(!r)return;let s=new Date(n);await x.utimes(e,r.atime,s).catch(()=>{});}function tr(e,t){let n=S.extname(e.pathname).toLowerCase(),r=t["content-type"]||"";return Ns.has(n)||_s.some(s=>r.includes(s))&&!r.startsWith("image/")&&!r.includes("font")}function Ai(e){try{let t=S.extname(new URL(e).pathname).toLowerCase();return t===".js"||t===".mjs"}catch{return false}}function Be(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 xi(e){return _e(e.toString("base64"),40)}function Ti(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 $i(e,t,n){let r=e.assetVariantDigestsByOriginalPath.get(t);r||(r=new Set,e.assetVariantDigestsByOriginalPath.set(t,r)),r.add(n);}async function Qt(e,t,n,r,s,i,o){let u=gt(e,n),a=xi(r),c=u.originalFilePath,l=u.originalPublicUrlWithSearch;if(u.preferQueryHashed&&u.hashedFilePath&&u.hashedPublicUrl&&Ti(s,u.originalFilePath,a)){let m=li(e,t,n);m?(c=m.outputPath,l=m.publicUrl):(c=u.hashedFilePath,l=u.hashedPublicUrl);}vi(e,t,n,l,u.originalPublicUrl);let d=be(c)?Buffer.from(qt(r.toString("utf8"),e,t,c),"utf8"):r,p=await hr(c),g=false;return (p===null||!p.equals(d))&&(await Ne(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}),$i(s,u.originalFilePath,a),await Ii(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 Je(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 ke(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)||fr(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 pt(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(!ke(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 ki(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:He(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 Ei(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function Mi(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 Fi(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function Di(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 Bt(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function yr(e,t,n,r){let s=[];await x.mkdir(t,{recursive:true});let i=await x.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 yr(u,a,n,r));continue}await Sr(u,a,n,r)&&s.push(a);}return s}async function Oi(e,t){try{let[n,r]=await Promise.all([x.stat(e),x.stat(t)]);if(n.size!==r.size)return !1;let[s,i]=await Promise.all([x.readFile(e),x.readFile(t)]);return s.equals(i)}catch{return false}}async function Sr(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 Oi(e,t)?(r.debug("Skipped unchanged post-crawl copy target",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):(await x.mkdir(S.dirname(t),{recursive:true}),await x.copyFile(e,t),true)}async function ji(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=Qs(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=Bt(c);if(!p){n.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:a,prefixPath:c});continue}let g;try{g=await x.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 yr(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 Sr(d,h,o,n)&&(i.push(h),s++,n.progress(`Copied static file to export: ${d} -> /${Bt(c.endsWith("/")?`${c}${f}`:c)}`,{phase:"copy-extra-paths",sourcePath:d,targetPath:`/${Bt(c.endsWith("/")?`${c}${f}`:c)}`,copiedItems:s}));}return n.endMark("copy-extra-paths",{mappedSources:r.length,copiedItems:s}),i}function Ve(e,t,n,r,s){let i=new Set,o=ce(n).replace(/\\\//g,"/"),u=s==="page-html"?Fi(o):o,a=Di(t,s);if(a){for(let l of Mi(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'"<>\\);]+\\.${_t}(?:\\?[^\\s'"<>\\);]*)?|(?<!\\.)/[^\\s'"<>\\);]+\\.${_t}(?:\\?[^\\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(zt(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"&&Ai(t))for(let l of Kn(o)){if(zt(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 Ui(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&&(gr(e,a)||Se(a)&&!$e(a)&&!q(e,a)&&s.add(a.toString()));}return [...s]}async function nr(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 Qt(e,n.assetMap,h,g,n,r);G(s,e,w.outputPath),ve(s,w.outputPath);let v=g.toString("utf8");/<sitemapindex(?:\s|>)/i.test(v)?n.sitemapIndexUrls.add(h):n.sitemapLeafUrls.add(h);let $=Ve(e,h,v,r,"sitemap");for(let F of $)J(e,n,F,r,h);let E=[];for(let F of ki(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(ke(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()),pt(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 Qe(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),Je(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([...$,...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 Li(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 Qe(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&&ve(o,l.outputPath),s.info(`Resumed completed content-sync asset ${a}`,{url:a,source:"content-sync-checkpoint"}),Be(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"}),Be(n,s),true};s.asset(`Fetching asset ${a}`,{url:a});try{let p=ze(e,n.assetMap,a),g=p?await Qe(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()&&Ri(g,b)){let P=await hr(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 Qt(e,n.assetMap,A,P,n,s,b);j.wroteFile&&(G(o,e,j.outputPath),be(j.outputPath)&&ve(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"}),Be(n,s);let L=tr(u,b),V=c?.discoveredAssets?[...c.discoveredAssets]:[];if(L||c?.isText){let B=P.toString("utf8"),K=Ve(e,A,B,s,"asset:cached");(K.length>0||!c)&&(V=K);for(let k of V)J(e,n,k,s,A);}if(i.trackManifest){let B=L||!!c?.isText;i.manifest.assets[a]={url:a,outputPath:j.outputPath,isText:B,contentType:Ht(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(),$=m.headers(),E=await Qt(e,n.assetMap,v,f,n,s,$);E.wroteFile&&(G(o,e,E.outputPath),be(E.outputPath)&&ve(o,E.outputPath)),n.doneAssets.add(a),Be(n,s);let F=tr(u,$),I=[];if(F){let O=f.toString("utf8");I=Ve(e,v,O,s,`asset:${S.extname(u.pathname).toLowerCase()||$["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:Ht($),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),Be(n,s));}}async function qi(e,t,n,r,s,i){let o=Math.max(1,Number(e.assetDownloadConcurrency||e.concurrency||1)),u=Array.from({length:o},async()=>{for(;n.assetQueue.length>0;){let a=n.assetQueue.shift();a&&(n.queuedAssets.delete(a),await Li(e,t,n,a,r,s,i));}});await Promise.all(u);}function _i(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 lt(e){return Math.max(15e3,Math.min(6e4,ue(e)))}function Ni(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function Yt(e){return e.stats.pagesCompleted}function Pr(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 Bi(e,t,n){let r=Pr(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 ${_i(t)}.`));},t);})])}finally{r!==void 0&&globalThis.clearTimeout(r);}}async function Hi(e,t){let n=Ni(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 Wi(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 Hi(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 Qi(e,t){return e.noJavaScriptRenderPathPrefixes.some(n=>Kt(t,n))}async function Ji(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 Ei(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 Ve(e,n,a,r,"dom-style"))i.add(c);}let o=await t.content();for(let u of Ve(e,n,o,r,"page-html"))i.add(u);return [...i]}async function rr(e,t,n,r,s){let i=le(e,t);await Ne(i,n,"utf8");let o=await x.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,Yt(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 Vi(e){let t=Yt(e);return t%5===0||t===1||t===e.stats.pagesQueued}function Ki(e,t){let n=Yt(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 Gi(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 Zi(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 Gi(r),r}async function Yi(e,t,n,r,s,i,o){let u=await chromium.launch({headless:true}),a=Pr(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=Zt(e,c),f=Qi(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 Qe(h.outputPath)){i.seenPages.add(c);for(let y of h.discoveredAssets||[])J(e,t,y,n,c);G(o,e,h.outputPath),ve(o,h.outputPath),n.info(`Resumed completed content-sync page ${c}`,{url:c,source:"content-sync-checkpoint"});continue}let w=await ni(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)Je(e,t,A,n,c);y.lastSeenRunId=i.runId,y.sitemapLastmod=He(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),()=>Zi(u,e,f)),d=await _(`create page ${c}`,ue(e),()=>l.newPage());let v=!1,$=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()),L=new URL(g);if(j.hash="",L.hash="",j.href===L.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)&&($.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 Jt(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 Jt(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),()=>zi(e,d))):await _(`wait for rendered page ${c}`,ue(e),()=>Wi(e,d)),t.stats.pagesRendered++;let I=await _(`extract rendered assets ${c}`,ue(e),()=>Ji(e,d,g,n,!f));for(let y of I)J(e,t,y,n,c);let O=[...new Set([...I,...$])],b=F??await _(`capture rendered html ${c}`,ue(e),()=>d.content()),P=r!=="single-url"&&r!=="content-sync"&&!m?Ui(e,c,b,n):[];if(r!=="single-url"&&r!=="content-sync"&&!m)for(let y of P)Je(e,t,y,n,c);await rr(e,c,b,t,n);let C=le(e,c);if(G(o,e,C),ve(o,C),i.trackManifest){let y=E?.headers();i.manifest.pages[c]={url:c,outputPath:C,contentType:Ht(y),changeToken:w.changeToken?.supported?w.changeToken.token:null,tokenSource:w.changeToken?.supported?w.changeToken.tokenSource??null:null,sitemapLastmod:He(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 rr(e,c,g,t,n);let m=le(e,c);if(G(o,e,m),ve(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:He(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++,Vi(t)&&Ki(t,n),d&&await _(`close page ${c}`,lt(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}`,lt(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",lt(e),()=>u.close()).catch(c=>(n.warn("Timed out while closing crawl worker browser",{browserPid:a.pid,error:String(c)}),Bi(u,n,"browser.close timeout")));}}async function Xi(e){try{let t=await x.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 sr(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function eo(e){let t=String(e?.job?.command||"").trim(),n=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:n!=="incremental"}function to(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 br(e){try{let t=await x.readFile(e,"utf8"),n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function ir(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function no(e,t){let n=Array.isArray(t?.artifacts)?t.artifacts.filter(r=>String(r?.role||"").trim()==="errors"&&String(r?.storedFileName||"").trim()!=="").sort((r,s)=>ir(r)-ir(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 or(e){let t=await br(S.join(e,"job.json"));for(let n of no(e,t)){let r=await Xi(n);if(r.length>0)return r}return []}async function ro(e){let t=S.join(e.logDir,"archive"),n;try{n=await x.readdir(t);}catch{return ""}let r="",s=0;for(let i of n){let o=S.join(t,i);if(!(await x.stat(o).catch(()=>null))?.isDirectory())continue;let a=await br(S.join(o,"job.json"));if(!eo(a))continue;let c=to(a);c>=s&&(s=c,r=o);}return r}async function so(e){let t=await ro(e),n=t!==""?await or(t):await or(e.logDir),r=new Set;for(let s of n)if(sr(s.error)||sr(s.message)){let i=s.url;typeof i=="string"&&i&&r.add(i);}return [...r]}async function io(e){let t=[];for(let n of e)if(n.startsWith("@")){let r=n.slice(1),s=await x.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 oo(e){if(!e)throw new Error("Content-sync crawl requires an immutable impact plan.");let t=JSON.parse(await x.readFile(e,"utf8"));return je(t),t}function ao(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 ut(e,t,n){let r=n==="page"?le(e,t):gt(e,t).originalFilePath;return he(e.outputDir,r)}async function Jt(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 x.rm(i.outputPath,{force:true}),n.deletedFiles.add(o)),delete t.manifest.pages[r];}function co(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{ke(new URL(o))&&r.push(o);}catch{}}return n}async function uo(e,t,n,r,s){let i=co(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 x.rm(u.outputPath,{force:true}),r.deletedFiles.add(a),delete n.manifest.assets[o];}await we(e,n);}async function lo(e){try{let t=await x.readFile(S.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function po(e){let t=["crawl.log.jsonl","current-crawl-event.json","rejected.jsonl","ignored.jsonl","skipped-http.jsonl","errors.jsonl","timings.jsonl","rejected.json","ignored.json","skipped-http.json","errors.json","timings.json"];await x.mkdir(e,{recursive:true}),await Promise.all(t.map(async n=>{try{await x.unlink(S.join(e,n));}catch(r){if(r.code!=="ENOENT")throw r}}));}function ar(e,t,n,r,s){let i=H(e,n,e.sourceOrigin,r,"manual-url");i&&(ke(i)?pt(e,t,i.toString(),r,s):q(e,i)?J(e,t,i.toString(),r,s):Se(i)?Je(e,t,i.toString(),r,s):r.reject("manual-url",i.toString(),"not page/sitemap/asset-like",s));}async function vr(e=process.argv.slice(2)){let t=[],n=await ne(void 0,{onRemotePublisherConfigDiagnostic:P=>{t.push(P);}}),r=t.at(-1)??null,s=Hs(e),i=s.mode==="content-sync"?await oo(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 so(n)),s.mode==="single-url"&&(o=await io(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 lo(n):{},p=a||s.mode==="single-url"||s.mode==="content-sync"?await Ks(n):dr(),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))ao(P,i)&&!g.has(P)&&(o.push(P),m.add(P));}let f={enabled:a,trackManifest:c,manifest:Wt(p),previousManifest:Wt(p),runId:i?.jobId??`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve(),strictTargeted:!!i,requiredUrls:g,deleteOnMissingUrls:m};await po(n.logDir);let h=new at(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=Vs();if(await Ae(n),await Dn(n,{startedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir)}),l||await x.rm(n.outputDir,{recursive:true,force:true}),await x.mkdir(n.outputDir,{recursive:true}),i){let P=new Set([...i.deleteUrls,...f.deleteOnMissingUrls]);for(let C of i.deleteUrls)await Jt(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=>pt(n,w,y,h)),await nr(n,P,w,h,v,f),n.seedPaths.forEach(y=>ar(n,w,y,h,"seed-path")),n.generated404RequestPath&&Je(n,w,n.generated404RequestPath,h,"generated-404-request-path")):(o.forEach(y=>ar(n,w,y,h,"cli")),i?.sitemapUrls.forEach(y=>pt(n,w,y,h,"content-sync-impact")),await nr(n,P,w,h,v,f,s.mode==="content-sync"),i&&await uo(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)},()=>Yi(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 qi(n,P,w,h,f,v),h.endMark("download-assets",{assets:w.doneAssets.size}),f.enabled&&n.maxPages===0&&await si(n,w,f,h,v),s.mode==="full"){let y=await ji(n,w,h);for(let A of y)G(v,n,A);}}finally{await _("dispose crawl request context",lt(n),()=>P.dispose()).catch(C=>{h.warn("Timed out while disposing crawl request context",{error:String(C)});});}}f.trackManifest&&await we(n,f),await x.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 $=s.mode==="single-url"||s.mode==="content-sync"?gi(n,w):f.enabled&&!s.resumeRewrite?ii(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/${$?.length??0}`:"Rewriting text files...";h.progress(E,{phase:"rewrite-text",index:0,totalFiles:$?.length,changedTextFiles:0}),await er(E);let F=Date.now(),I=await it(n,w.assetMap,{files:$,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 L=Date.now();if(!(P===1||P===C||P%50===0||L-F>=5e3))return;F=L;let B=`Rewriting text files: ${P}/${C}`;h.progress(B,{phase:"rewrite-text",index:P,totalFiles:C,changedTextFiles:y,file:A}),await er(B);}});f.trackManifest&&(oi(f,$),await we(n,f)),h.endMark("rewrite-text",{changedTextFiles:I});let O=i?[...v.deletedFiles].sort():f.enabled&&!s.resumeRewrite?await ci(n,w,f,v,h):[],b=[...new Set(($||[]).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(k=>ut(n,k,"page")).filter(k=>!!k&&C.has(k))),A=new Set(i.archiveFamilyUrls.map(k=>ut(n,k,"page")).filter(k=>!!k&&C.has(k))),j=new Set([...w.sitemapLeafUrls].map(k=>ut(n,k,"asset")).filter(k=>!!k&&C.has(k))),L=new Set([...w.sitemapIndexUrls].map(k=>ut(n,k,"asset")).filter(k=>!!k&&C.has(k))),V=new Set([...y,...A,...j,...L]),B=P.filter(k=>!V.has(k)),K=[...new Set([...i.directRenderUrls,...i.archiveFamilyUrls,...i.sitemapUrls,...w.sitemapLeafUrls,...w.sitemapIndexUrls,...i.deleteUrls].map(k=>{let Ze=new URL(k);return `${Ze.pathname}${Ze.search}`}))].sort();await Ot(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:[...L].reverse()},invalidationPaths:K});}else await Ot(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 jn(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 go(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 ${go(t)}.`));},t);try{return await n({abortController:r,httpOptions:{abortSignal:r.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(s);}}function mo(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function mt(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 fo(e,t){return {...e,...t??{}}}function ho(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function Ee(e,t){let n=String(t??e.deploymentTargetOverride??"").trim();if(!mo(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:fo(e.s3,s.s3),cloudFront:ho(e.cloudFront,s.cloudFront)}}}var Ar="wpsuite-sha256",xr="wpsuite-normalized-sha256",Io=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,sn=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Ao=["SIGINT","SIGTERM"],wt=new Set,ft=new Map,Cr=null;function xo(e){wt.add(e);let t=false;return ()=>{t||(t=true,wt.delete(e));}}async function To(){let e=[...wt];e.length!==0&&await Promise.allSettled(e.map(async t=>{wt.delete(t),await x.rm(t,{recursive:true,force:true});}));}function $o(){if(!(ft.size>0))for(let e of Ao){let t=()=>{Cr||(Cr=To().finally(()=>{for(let[n,r]of ft)process.off(n,r);ft.clear(),process.exit(1);}));};ft.set(e,t),process.on(e,t);}}$o();function ko(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 Tr(e){return S.normalize(e).split(S.sep).join("/")}function Rr(e,t){let n=S.relative(S.resolve(e),S.resolve(t));return !n||n.startsWith("..")||S.isAbsolute(n)?null:Tr(n)}async function Eo(e,t,n){let r=ko(e.outputDir,t),s;try{s=await x.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?Rr(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?Rr(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 Mo(e){return e&&(sn.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 en(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,n)=>n%2===1?t:Mo(t)).join("")}function Fo(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,n)=>n%2===1?t:sn.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 yt(e,t){return Array.isArray(e)?e.map(n=>yt(n,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,yt(r,n)])):typeof e!="string"?e:t&&Io.test(t)?Fo(e):sn.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?en(e):e}function Do(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function Oo(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(yt(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(yt(i));return Buffer.from(o,"utf8").toString("base64")}catch{}return t}function jo(e,t){let n=e.toLowerCase();return n==="class"?t.split(/(\s+)/).map((r,s)=>s%2===1?r:en(r)).join(""):n==="id"||n==="for"||n==="aria-controls"||n==="aria-labelledby"||n==="aria-describedby"||n==="aria-owns"||n==="aria-activedescendant"||n==="name"?en(t):n==="href"||n==="src"?Do(t):Oo(n,t)}function Uo(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=jo(o,a);return ` ${o}=${u}${c}${u}`});return `<${n}${s}>`})}function Xt(e){let t=S.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(S.basename(e))}function ht(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function Lo(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 qo(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 _o(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 No(e){return createHash("md5").update(e).digest("hex")}function Ir(e){return createHash("sha256").update(e).digest("hex")}function tn(e){return createHash("sha256").update(Uo(e.toString("utf8"))).digest("hex")}async function Bo(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?.[Ar]||"").trim().toLowerCase()||null;return r.set(n,o),o}catch{return r.set(n,null),null}}async function Ho(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?.[xr]||"").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?tn(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 Wo(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 Qo(e,t,n,r){let s=S.join(e,"asset-map.json"),i;try{i=await x.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=zo(l,r),[a,l]}));await x.writeFile(s,JSON.stringify(u,null,2),"utf8");}async function Jo(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-${Wo(n)}-${Date.now()}`),c=xo(a);s.info(`Preparing deployment profile "${n}" from existing crawl output to ${a}...`);try{if(await x.rm(a,{recursive:!0,force:!0}),i){await x.mkdir(a,{recursive:!0});for(let g of i){let m=S.join(e.outputDir,g),f=S.join(a,g);await x.mkdir(S.dirname(f),{recursive:!0}),await x.copyFile(m,f);}}else await x.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 it(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 $=`Rewriting [${g}/${m}] ${h} (${w?"rewrote":"checked"}; ${f} changed so far)`;m<=200||g<=5||g%10===0||g===m?(s.progress($,{file:h,index:g,totalFiles:m,changed:w,changedTextFiles:f,workerCount:d}),s.info($)):s.debug($);}});return await Qo(a,e,t,r),s.info(`Prepared deployment profile "${n}" in ${a} (${p} rewritten text file(s)).`),{outputDir:a,cleanup:async()=>{c(),await x.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 x.rm(a,{recursive:true,force:true}).catch(()=>{}),c(),await s.flush().catch(()=>{}),l}}async function $r(e=process.argv.slice(2)){let t=await ne(),n=mt(e),r=Ee(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 Te(s,"deploy.log.jsonl",r.config.logLevel??"info"),a=r.profile?.extraReplacements??{},c=async()=>{};try{let l=await nt(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 On(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 Jo(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}),$=g.outputDir===t.outputDir?await Eo(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 x.stat(S.join(m.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 fs(["**/*"],{cwd:m.outputDir,onlyFiles:!0,dot:!0}),I=[],O=[],b=F.filter(T=>{let W=$?.byRelativePath.get(Tr(T));if(!W)return !0;let R=ht(m.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:$?.manifestPath}),!1}),P=new Set((w?b:F).map(T=>ht(m.s3.prefix,T)));$&&($.pendingPages>0||$.pendingTextAssets>0)&&u.info(`Deploy rewrite guard loaded ${$.pendingPages} pending page(s) and ${$.pendingTextAssets} pending text asset(s) from crawl manifest.`,{manifestPath:$.manifestPath,pendingPages:$.pendingPages,pendingTextAssets:$.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:$?.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=[],L=[],V=[],B=[],K=[],k=new Map,Ze=new Map,Or=new Map,jr=new Map,Ur=new Map;w||(u.info("Listing existing S3 objects to detect unchanged files..."),k=await Lo(v,m.s3.bucket,m.s3.prefix,u),u.info(`Found ${k.size} existing key(s) in S3.`));let Lr=async T=>k.has(T)?k.get(T)??null:w?qo(v,m.s3.bucket,T,Ze):null;for(let T of b){let W=S.join(m.outputDir,T),R=ht(m.s3.prefix,T),X=$?.contentTypeByRelativePath.get(T),Me=X&&X!=="application/octet-stream"?X:Ro.lookup(T)||X||"application/octet-stream",qr=Xt(T)?m.s3.htmlCacheControl:m.s3.assetCacheControl,U=C+y+A+1;b.length<=200||U<=5||U%10===0||U===b.length?(u.progress(`Uploading [${U}/${b.length}] ${R} (${Me})`,{file:T,key:R,index:U,totalFiles:b.length,contentType:Me,mode:f}),u.info(`Uploading [${U}/${b.length}] ${R} (${Me})`)):u.debug(`Uploading [${U}/${b.length}] ${R} (${Me})`);try{let ee=await x.readFile(W),Fe=await Lr(R),De=null,Re=null;if(Fe){let Pt=ee.byteLength;if(Fe.size===Pt){let Ye=Fe.etag.includes("-");if(Fe.etag!==""&&!Ye){let _r=No(ee);if(Fe.etag===_r){y++,b.length<=200||y<=5||y%25===0?(u.progress(`Skipped unchanged [${U}/${b.length}] ${R}`,{file:T,key:R,index:U,totalFiles:b.length,uploaded:C,skipped:y,failed:A,mode:f,reason:"etag-md5-match"}),u.info(`Skipped unchanged [${U}/${b.length}] ${R}`)):u.debug(`Skipped unchanged [${U}/${b.length}] ${R}`),L.push(R);continue}}De=Ir(ee);let dn=await Bo(v,m.s3.bucket,R,Or);if(dn&&dn===De){y++,b.length<=200||y<=5||y%25===0?(u.progress(`Skipped unchanged [${U}/${b.length}] ${R}`,{file:T,key:R,index:U,totalFiles:b.length,uploaded:C,skipped:y,failed:A,mode:f,reason:"metadata-sha256-match"}),u.info(`Skipped unchanged [${U}/${b.length}] ${R}`)):u.debug(`Skipped unchanged [${U}/${b.length}] ${R}`),L.push(R);continue}}if(Xt(T)){Re=tn(ee);let Ye=await Ho(v,m.s3.bucket,R,jr,Ur);if(Ye&&Ye===Re){y++,b.length<=200||y<=5||y%25===0?(u.progress(`Skipped semantically unchanged [${U}/${b.length}] ${R}`,{file:T,key:R,index:U,totalFiles:b.length,uploaded:C,skipped:y,failed:A,mode:f,reason:"normalized-html-match"}),u.info(`Skipped semantically unchanged [${U}/${b.length}] ${R}`)):u.debug(`Skipped semantically unchanged [${U}/${b.length}] ${R}`),L.push(R);continue}}}De=De??Ir(ee),Re=Re??(Xt(T)?tn(ee):null),await Z(`S3 upload ${R}`,9e5,({abortController:Pt})=>new Upload({client:v,abortController:Pt,params:{Bucket:m.s3.bucket,Key:R,Body:ee,ContentType:Me,CacheControl:qr,Metadata:{[Ar]:De,...Re?{[xr]:Re}:{}}}}).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 T=new Set((l?.deletedFiles??[]).map(R=>ht(m.s3.prefix,R))),W=[...T].filter(R=>!P.has(R));if(!w&&(K=[...k.keys()].filter(X=>!P.has(X)).filter(X=>!T.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 _o(v,m.s3.bucket,w?W:W.filter(R=>k.has(R)),u);}else u.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion.");o&&(await x.mkdir(S.dirname(o),{recursive:!0}),await x.writeFile(o,JSON.stringify({generatedAt:new Date().toISOString(),mode:f,summary:{totalFiles:F.length,eligibleFiles:b.length,uploaded:j.length,skipped:L.length,rejected:O.length,failed:V.length,deleted:B.length,protected:K.length,...r.name?{profile:r.name}:{}},uploadedKeys:j,skippedKeys:L,rejectedKeys:O,failedKeys:V,deletedKeys:B,protectedRemoteOnlyKeys:K},null,2),"utf8")),l?.schemaVersion!==2&&await Ae(t),u.endMark("deploy"),await u.flush();}finally{await c().catch(()=>{});}}function Go(){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 on(e,t){if(!e)return;await x.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await x.writeFile(n,JSON.stringify({...t,updatedAt:new Date().toISOString()},null,2),"utf8"),await x.rename(n,e);}async function Zo(e,t,n){if(!e)return null;try{let r=JSON.parse(await x.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 Yo(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 Er(e=process.argv.slice(2)){let t=await ne(),n=mt(e),r=Ee(t,n),s=r.config,i=new Te(s.logDir||"logs","invalidate.log.jsonl",s.logLevel??"info"),o=e.includes("--content-sync"),u=await nt(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=Go(),p=await Zo(d,c,u.impactHash);p||(p={schemaVersion:1,distributionId:c,impactHash:u.impactHash,updatedAt:new Date().toISOString(),batches:Yo(a).map((g,m)=>({index:m,callerReference:`wpsuite-content-sync-${u.impactHash.slice(0,32)}-${m}`,paths:g,invalidationId:null,status:"pending"}))},await on(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 on(d,p);}await waitUntilInvalidationCompleted({client:l,maxWaitTime:900,minDelay:2,maxDelay:15},{DistributionId:c,Id:g.invalidationId}),g.status="completed",await on(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 Fr=["claimed","impact-planned","rendered","deployed","invalidated","verified","acknowledged"];function un(){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 Ke(e,t){return Fr.indexOf(e)>=Fr.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 x.mkdir(e,{recursive:true}),await x.appendFile(S.join(e,"audit-events.jsonl"),`${JSON.stringify(i)}
11
+ `,"utf8");}function ea(e){return Oe({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 ta(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 ln(e,t){if(e.subscriptionType!=="PROFESSIONAL"&&e.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let n=ea(t),r=Ee(e,t.deploymentProfile),s=r.name||"",i=gn(e.sourceOrigin,String(t.id||""),n),o=mn({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=fn({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 et({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 na(e){let t=un(),n=tt(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 It(n),o=await Rt(n),u=0;for(let a of s){let c=await ln(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 Pn(n,i),await x.rm(n.releaseCutoff,{force:true}),u}async function ra(e){let t=un(),n=tt(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 Rt(n),o=0;for(let u of s){let a=await ln(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 Sn(n,i),o}async function sa(e,t){let n=JSON.parse(await x.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 cn(e,t,n=0){let r=e.protocol==="https:"?yn:zr,s=e.protocol==="https:"?new yn.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(),cn(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 ia(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 cn(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 cn(u,e.ignoreHttpsErrors);if(a.status>=200&&a.status<300)throw new Error(`Deleted content is still publicly available: ${u}`)}}async function oa(e){let t=await x.readFile(e.candidateManifest,"utf8");JSON.parse(t);let n=`${e.trustedManifest}.${process.pid}.tmp`;await x.writeFile(n,t,"utf8"),await x.rename(n,e.trustedManifest);}async function aa(e,t){try{let n=JSON.parse(await x.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 x.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 Ce(e,t,n,r,s={},i=0){t.phase=n,await vn(e,t),await In(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 ca(e){let t=un(),n=tt(t),r=await sa(t,e),s=await ne(),i=ta(s,String(r.ruleId)),o=await ln(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 It(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 bn(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 Ce(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 At(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 xt(n,f),await Tt(n);return}let d=await Cn(n);if(!Ke(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=Ct({events:f,scope:o.scope,sourceOrigin:s.sourceOrigin}),w=await o.client.resolveImpactFamilies(h);d=wn({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 Rn(n,d),c.impactHash=d.impactHash,await Ce(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,!Ke(c.phase,"rendered")){let f=await aa(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 vr(["--content-sync-plan",n.impact]),await Ce(n,c,"rendered",d.directRenderUrls.length+d.archiveFamilyUrls.length,{impactHash:d.impactHash},r.attempt??0);}let p=o.deploymentProfile?["--profile",o.deploymentProfile]:[];if(Ke(c.phase,"deployed")||(await $r([...p,"--content-sync"]),await Ce(n,c,"deployed",1,{impactHash:d.impactHash}),await pe(t,"content-sync-deployed",r,"Content-sync targeted deployment completed.",{impactHash:d.impactHash})),Ke(c.phase,"invalidated")||(await Er([...p,"--content-sync"]),await Ce(n,c,"invalidated",1,{impactHash:d.impactHash})),Ke(c.phase,"verified")||(await ia(s,o,d),await oa(n),await Ce(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 Ce(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 At(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 xt(n,m),await Ae(s),await x.rm(S.join(t,"content-sync-invalidation.json"),{force:true}),await x.rm(n.candidateManifest,{force:true}),await Tt(n);}async function Dr(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 ra(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 na(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 ca(i);}Dr().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1);});