@smart-cloud/publisher-exporter 1.1.56 → 1.1.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/content-sync.js +10 -10
- package/dist/crawl.js +8 -8
- package/dist/queue-runner.js +3 -3
- package/package.json +1 -1
package/dist/content-sync.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import T from'fs/promises';import ws from'http';import Fn from'https';import S from'path';import nr,{createHash}from'crypto';import {request,chromium}from'playwright';import {gunzipSync}from'zlib';import Ns from'fast-glob';import {availableParallelism}from'os';import {Worker}from'worker_threads';import {S3Client,ListObjectsV2Command,HeadObjectCommand,GetObjectCommand,DeleteObjectsCommand}from'@aws-sdk/client-s3';import {Upload}from'@aws-sdk/lib-storage';import ta from'mime-types';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';var ps=new Set(["post-type","taxonomy","author","date","posts-page","listing"]);function ke(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))].sort()}function gs(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))]}function fs(e){return new URL(e).pathname.split("/").filter(Boolean).some(n=>{try{return decodeURIComponent(n).endsWith("__trashed")}catch{return n.endsWith("__trashed")}})}function Ut(e){return Array.isArray(e)?e.map(Ut):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,Ut(n)])):e}function ms(e){return JSON.stringify(Ut(e))}function ue(e){return createHash("sha256").update(ms(e)).digest("hex")}function Tn(e){return ue({schemaVersion:1,wordpressFingerprint:e.wordpressFingerprint,targetFingerprint:e.targetFingerprint,sourceOrigin:e.sourceOrigin,sitemapPaths:[...e.sitemapPaths].sort(),blockedPathPrefixes:[...e.blockedPathPrefixes].sort(),assetPathPrefixes:[...e.assetPathPrefixes].sort(),noJavaScriptRenderPathPrefixes:[...e.noJavaScriptRenderPathPrefixes].sort(),urlRewriteMode:e.urlRewriteMode})}function Lt(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 he(e,t){let n=new URL(Lt(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 Qe(e){let t=ke((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=ke((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 a=`/${i.pathname.replace(/^\/+|\/+$/g,"")}`;return a==="/"?"/":`${a}/`}));return {postTypes:t,listingPaths:n,includeSubsites:e.includeSubsites===true,includePostTypeArchives:e.includePostTypeArchives!==false,includeTaxonomyArchives:e.includeTaxonomyArchives!==false,includeAuthorArchives:e.includeAuthorArchives===true,includeDateArchives:e.includeDateArchives===true,includePostsPage:e.includePostsPage!==false,includeSitemapChain:e.includeSitemapChain!==false}}function kn(e,t,n){return ue({schemaVersion:1,sourceOrigin:Lt(e),ruleId:t.trim(),scope:Qe(n)})}function $n(e){return ue({schemaVersion:1,...e})}function En(e){let t=String(e.siteId??"").trim()||String(e.accountId??"").trim()||Lt(e.sourceOrigin);return `content-sync:${ue({siteIdentity:t,ruleId:e.ruleId.trim(),targetFingerprint:e.targetFingerprint}).slice(0,48)}`}function Mn(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.");if(r=s.sequence,!Number.isSafeInteger(s.blogId)||s.blogId<1)throw new Error("Content-sync journal event has an invalid multisite identity.");let i=`${s.blogId}:${s.postType}:${s.postId}`,a=n.get(i);if(!a){n.set(i,{postId:s.postId,blogId:s.blogId,postType:s.postType,fromSequence:s.sequence,toSequence:s.sequence,before:s.before,after:s.after,operations:[s.operation],correlationIds:s.correlationId?[s.correlationId]:[]});continue}a.toSequence=s.sequence,a.after=s.after,a.operations.push(s.operation),s.correlationId&&!a.correlationIds.includes(s.correlationId)&&a.correlationIds.push(s.correlationId);}return [...n.values()].sort((s,i)=>s.fromSequence-i.fromSequence)}function An(e){return e?.status==="publish"&&!!e.url}function hs(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 jt(e){let t=Qe(e.scope),n=new Map;Mn(e.events);for(let r of e.events)for(let s of [r.before,r.after])for(let i of s?.archiveFamilies??[]){if(!ps.has(i.kind)||!hs(i.kind,t))continue;let a={...i,url:he(e.sourceOrigin,i.url)};n.set(`${a.kind}|${a.url}`,a);}for(let r of t.listingPaths){let s=he(e.sourceOrigin,r);n.set(`listing|${s}`,{kind:"listing",url:s});}return [...n.values()].sort((r,s)=>r.url.localeCompare(s.url))}function Dn(e){let t=Qe(e.scope),n=Mn(e.events),r=new Set,s=new Set,i=new Map(jt({events:e.events,scope:t,sourceOrigin:e.sourceOrigin}).map(d=>[`${d.kind}|${d.url}`,d]));for(let d of n){let p=d.before,f=d.after,g=An(p),y=An(f);y&&f.url&&r.add(he(e.sourceOrigin,f.url)),g&&p.url&&(!y||p.url!==f.url)&&s.add(he(e.sourceOrigin,p.url));}let a=new Map(e.resolvedArchiveFamilies.map(d=>[`${d.kind}|${he(e.sourceOrigin,d.url)}`,{...d,url:he(e.sourceOrigin,d.url),pageUrls:ke(d.pageUrls.map(p=>he(e.sourceOrigin,p)))}])),c=[...i.entries()].map(([d,p])=>{let f=a.get(d);if(!f)throw new Error(`WordPress did not resolve archive family ${d}.`);return {...p,...f}}).sort((d,p)=>d.url.localeCompare(p.url)),o=ke(c.flatMap(d=>d.pageUrls)),l=t.includeSitemapChain?gs(e.sitemapUrls.map(d=>he(e.sourceOrigin,d))):[],u={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:ke([...r]),archiveFamilyUrls:o,sitemapUrls:l,deleteUrls:ke([...s]),archiveFamilies:c};return {...u,impactHash:ue(u)}}function Je(e){let{impactHash:t,...n}=e;if(e.schemaVersion!==1||!t)throw new Error("Invalid content-sync impact plan schema.");if(ue(n)!==t)throw new Error("Content-sync impact plan hash mismatch.");for(let r of [...e.directRenderUrls,...e.deleteUrls])if(fs(r))throw new Error(`Content-sync impact contains a WordPress trash alias instead of the last public URL: ${r}`)}var ys="wp-json/smartcloud-static-publisher/v1/content-sync/",Ss=25*1024*1024,ot=class extends Error{status;code;constructor(t,n,r){super(r),this.name="ContentSyncApiError",this.status=t,this.code=n;}},at=class{options;constructor(t){if(!t.runtimeToken.trim())throw new Error("Content-sync requires a WordPress runtime token.");this.options={...t,timeoutMs:t.timeoutMs??6e4};}endpoint(t){let n=this.options.sourceOrigin.replace(/\/+$/,"")+"/";return new URL(`${ys}${t}`,n)}async post(t,n){let r=this.endpoint(t),s=Buffer.from(JSON.stringify(n),"utf8"),i=r.protocol==="https:"?Fn:ws,a=r.protocol==="https:"?new Fn.Agent({rejectUnauthorized:!this.options.ignoreHttpsErrors}):void 0;return new Promise((c,o)=>{let l=i.request(r,{method:"POST",agent:a,headers:{"content-type":"application/json","content-length":String(s.byteLength),"x-static-publisher-token":this.options.runtimeToken},timeout:this.options.timeoutMs},u=>{let d=[],p=0;u.on("data",f=>{if(p+=f.byteLength,p>Ss){u.destroy(new Error("Content-sync API response exceeded the size limit."));return}d.push(f);}),u.on("error",o),u.on("end",()=>{let f=Buffer.concat(d).toString("utf8"),g;try{g=f?JSON.parse(f):{};}catch{o(new ot(u.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let y=u.statusCode??500;if(y<200||y>=300){o(new ot(y,String(g.code??"request-failed"),String(g.message??`Content-sync API request failed (${y}).`)));return}c(g);});});l.on("timeout",()=>l.destroy(new Error(`Content-sync API request timed out: ${t}`))),l.on("error",o),l.end(s);})}async head(t){return this.post("head",t)}async unboundHead(t,n){return this.post("head",{postTypes:t,includeSubsites:n})}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 a=r;for(let c of i.items){if(!Number.isSafeInteger(c.sequence)||c.sequence<=a||c.sequence>t.throughSequence||!Number.isSafeInteger(c.postId)||c.postId<=0||!Number.isSafeInteger(c.blogId)||c.blogId<=0||!s.has(c.postType)||typeof c.operation!="string"||!c.operation)throw new Error("Content-sync API returned an invalid or out-of-scope journal event.");a=c.sequence;}if(i.items.length>0&&i.nextSequence!==a)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,n){let r=await this.post("impact",{families:t,includeSubsites:n});return Array.isArray(r.families)?r.families:[]}async releaseFingerprint(t=false){let n=await this.post("fingerprint",{includeSubsites:t}),r=String(n.fingerprint||"").trim();if(!/^[a-f0-9]{64}$/.test(r))throw new Error("WordPress returned an invalid release fingerprint.");return r}async establishBaseline(t){return this.post("baseline",t)}async acknowledge(t){return this.post("ack",t)}};function ct(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"),activeRules:S.join(t,"content-sync-active-rules.json"),releaseCutoff:S.join(t,"content-sync-release-cutoff.json"),candidateManifest:S.join(t,"content-sync-candidate-manifest.json"),trustedManifest:S.join(t,"crawl-manifest.json"),invalidation:S.join(t,"content-sync-invalidation.json"),deployPlan:S.join(t,"deploy-plan.json")}}async function qt(e){let t=await Ve(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 On(e,t){await Ee(e.releaseCutoff,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Ee(e,t){await T.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await T.writeFile(n,JSON.stringify(t,null,2),"utf8"),await T.rename(n,e);}async function Ve(e){try{return JSON.parse(await T.readFile(e,"utf8"))}catch(t){if(t.code==="ENOENT")return null;throw new Error(`Invalid or unreadable content-sync state file ${e}: ${t instanceof Error?t.message:String(t)}`,{cause:t})}}async function _t(e){let t=await Ve(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 Un(e,t){await Ee(e.baseline,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Nt(e){let t=await Ve(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 Ln(e,t){await Ee(e.current,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function jn(e){let t=await Ve(e.impact);if(t===null)return null;let n=t;return Je(n),n}async function qn(e,t){Je(t),await Ee(e.impact,t);}async function _n(e,t){await Ee(e.checkpoint,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function ut(e){let t=await Ve(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 lt(e,t){await Ee(e.state,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Bt(e){await Promise.all([e.current,e.checkpoint].map(async t=>{try{await T.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}));}async function Nn(e,t){let n=await Nt(e);return !n||n.coalesceKey!==t?false:(await Promise.all([e.current,e.checkpoint,e.impact,e.candidateManifest,e.invalidation,e.deployPlan].map(async r=>{try{await T.unlink(r);}catch(s){if(s.code!=="ENOENT")throw s}})),true)}var Wt=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function Ke(e){let t=new Set;for(let n of [...e,...Wt]){let r=String(n||"").trim();r&&t.add(r);}return [...t]}function Ht(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function Bn(e){if(!e||!/^https?:\/\//i.test(e))return false;try{return Ht(new URL(e))}catch{return false}}function Hn(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function Cs(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(a=>a.replace(/[^A-Za-z0-9._-]/g,"")).filter(a=>a.length>0&&a!=="."&&a!=="..");if(s.length===0)return "";let i=`/${s.join("/")}`;return r&&S.extname(i)===""&&(i+="/"),i==="/"?"":i}function zt(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t.trim(),String(n??"")]).filter(([t])=>t.length>0))}function Rs(e){if(!e||typeof e!="object")return {};let t={};for(let[n,r]of Object.entries(e)){let s=n.trim();if(!s||!r||typeof r!="object")continue;let i=r,a={};if(typeof i.targetOrigin=="string"){let o=Hn(i.targetOrigin);o&&(a.targetOrigin=o);}let c=zt(i.extraReplacements);if(Object.keys(c).length>0&&(a.extraReplacements=c),i.s3&&typeof i.s3=="object"){let o={},l=i.s3;typeof l.bucket=="string"&&(o.bucket=l.bucket.trim()),typeof l.prefix=="string"&&(o.prefix=l.prefix.trim()),typeof l.region=="string"&&(o.region=l.region.trim()),typeof l.htmlCacheControl=="string"&&(o.htmlCacheControl=l.htmlCacheControl.trim()),typeof l.assetCacheControl=="string"&&(o.assetCacheControl=l.assetCacheControl.trim()),Object.keys(o).length>0&&(a.s3=o);}if(i.cloudFront&&typeof i.cloudFront=="object"){let o={},l=i.cloudFront;typeof l.distributionId=="string"&&(o.distributionId=l.distributionId.trim()),Array.isArray(l.invalidationPaths)&&(o.invalidationPaths=l.invalidationPaths.map(u=>String(u??"").trim()).filter(u=>u.length>0)),Object.keys(o).length>0&&(a.cloudFront=o);}t[s]=a;}return t}function Jt(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function xs(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 a=String(n.deploymentProfile??"").trim(),c=String(n.url??"").trim(),o=Array.isArray(n.postTypes)?[...new Set(n.postTypes.map(u=>String(u??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],l=Array.isArray(n.listingPaths)?[...new Set(n.listingPaths.map(u=>String(u??"").trim()).filter(Boolean))]:[];return r==="content-sync"&&o.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")&&a?{deploymentProfile:a}:{},...c?{url:c}:{},...o.length>0?{postTypes:o}:{},...l.length>0?{listingPaths:l}:{},...typeof n.includeSubsites=="boolean"?{includeSubsites:n.includeSubsites}:{},...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 zn(e){let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.rules)?t.rules.map((r,s)=>xs(r,s)).filter(r=>!!r):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:n}}function Is(e){if(!e||typeof e!="object")return;let t=e,n={};for(let s of ["accountId","siteId"]){let i=t[s];typeof i=="string"&&i.trim()!==""&&(n[s]=i.trim());}let r=Number(t.lastUpdate??0);return Number.isFinite(r)&&r>0&&(n.lastUpdate=Math.floor(r)),t.subscriber===true&&(n.subscriber=true),Object.keys(n).length>0?n:void 0}function Vt(e){let t=e&&typeof e=="object"?e:{},n=String(t.accountId??"").trim(),r=String(t.siteId??"").trim(),s=t.subscriber===true,i=Is(t.siteSettings),a={...i??{},...n?{accountId:i?.accountId??n}:{},...r?{siteId:i?.siteId??r}:{},...i?.subscriber===true||s?{subscriber:true}:{}},c={},o=String(t.apiBase??"").trim();o&&(c.apiBase=o);let l=String(t.runtimeToken??t.nonce??"").trim();l&&(c.runtimeToken=l);let u=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();u&&(c.virtualAssetBaseUrl=u),Object.keys(a).length>0&&(c.siteSettings=a);let d=Jt(t.subscriptionType);return d&&(c.subscriptionType=d),c}function As(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Qn(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function Ts(e,t){let n=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[r,s]of new Headers(t.headers).entries())n.set(r,s);return n}async function Jn(e,t,n=5){let r=new URL(Qn(e)),s=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),i=r.protocol==="http:"?ws:Fn,a=Ts(e,t);return await new Promise((c,o)=>{let l=i.request(r,{method:s,headers:Object.fromEntries(a.entries()),...r.protocol==="https:"?{rejectUnauthorized:false}:{}},u=>{let d=[];u.on("data",p=>{d.push(Buffer.isBuffer(p)?p:Buffer.from(p));}),u.on("error",o),u.on("end",()=>{let p=u.statusCode??0,f=u.headers.location;if(n>0&&f&&[301,302,303,307,308].includes(p)){c(Jn(new URL(f,r),{method:p===303?"GET":s},n-1));return}let g=new Headers;for(let[y,m]of Object.entries(u.headers))Array.isArray(m)?g.set(y,m.join(", ")):typeof m=="string"&&g.set(y,m);c(new Response(Buffer.concat(d),{status:p,statusText:u.statusMessage??"",headers:g}));});});l.on("error",o),l.end();})}function ks(e){let t=Vt(e.wpsuite),n={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},r=String(n.accountId??"").trim(),s=String(n.siteId??"").trim(),i=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();if(e.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...i?{virtualAssetBaseUrl:i}:{},...Object.keys(n).length>0?{siteSettings:n}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!r||!s||!i)return false;As(e.sourceOrigin);let a=globalThis,o={...a.WpSuite??{},siteSettings:n,uploadUrl:i};return t.apiBase&&(o.apiBase=t.apiBase),a.WpSuite=o,true}async function $s(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!ks(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(o,l)=>{let u=Qn(o);if(u.startsWith(t)){let d=(()=>{try{return new URL(u).pathname}catch{return u}})();try{let p=e.ignoreHttpsErrors&&u.startsWith("https://")?await Jn(o,l):await n(o,l);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(o,l)}));let{getConfig:s}=await import('@smart-cloud/wpsuite-core'),i=await s("publisher"),a=i&&typeof i=="object"?i:null,c=Jt(a?.subscriptionType);return {remote:a,diagnostic:{status:a?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:c??null,error:a?null:"WP Suite publisher config loader returned no configuration.",requests: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 Es(e,t){let n=Rs(t?.deploymentProfiles),r=String(t?.defaultDeploymentProfile??"").trim(),s=n[r]?r:"",i=Jt(t?.subscriptionType),a=Vt(e.wpsuite);return {...e,scheduler:zn(t?.scheduler),deploymentProfiles:n,defaultDeploymentProfile:s,...i?{subscriptionType:i}:{},wpsuite:{...a,...a.siteSettings||i?{siteSettings:{...a.siteSettings??{},...a.siteSettings?.subscriber===true||i==="PROFESSIONAL"||i==="AGENCY"?{subscriber:true}:{}}}:{},...i?{subscriptionType:i}:{}}}}function Qt(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 Ms(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Wn(e,t,n){let r=String(t||"").trim();return r&&S.isAbsolute(r)?S.resolve(r):S.resolve(e,Qt(r,n))}async function se(e,t={}){let n=String(e??"").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",r=await T.readFile(n,"utf8"),s=JSON.parse(r);s.sourceOrigin=s.sourceOrigin.replace(/\/$/,""),s.targetOrigin=Hn(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=Cs(s.generated404RequestPath),s.sitemapPaths||=[...Wt],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=zt(s.extraReplacements),s.postCrawlCopyMap=zt(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=Vt(s.wpsuite),s.scheduler=zn(void 0),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let i=await $s(s);t.onRemotePublisherConfigDiagnostic?.(i.diagnostic);let a=Es(s,i.remote),c=Ms(),o=c?S.resolve(c,".."):"";return o?(a.outputDir=Wn(o,a.outputDir,"export"),a.logDir=Wn(o,a.logDir,"logs")):(S.isAbsolute(a.outputDir)||(a.outputDir=Qt(a.outputDir,"export")),S.isAbsolute(a.logDir)||(a.logDir=Qt(a.logDir,"logs"))),a}var Ds=".deploy-plan.json",Fs="deploy-plan.json",Os=".crawl-incomplete.json",Us="crawl-incomplete.json";function Vn(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Kn(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 Ls(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 ye(e){return [...new Set(e.map(Kn).filter(t=>t!==null))]}function Gn(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:ye(t.changedFiles||[]),deletedFiles:ye(t.deletedFiles||[]),rewriteTargets:ye(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(),resolvedSitemapUrls:[...new Set((t.resolvedSitemapUrls||[]).map(r=>String(r||"").trim()).filter(r=>{try{let s=new URL(r);return s.protocol==="http:"||s.protocol==="https:"}catch{return false}}))],uploadGroups:{assets:ye(t.uploadGroups?.assets||[]),content:ye(t.uploadGroups?.content||[]),listings:ye(t.uploadGroups?.listings||[]),sitemapLeaves:ye(t.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:ye(t.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((t.invalidationPaths||[]).map(Ls).filter(r=>r!==null))].sort()}:{schemaVersion:1,...n,runMode:t.runMode}}function js(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.resolvedSitemapUrls)&&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 Kt(e){let t=S.join(S.resolve(e.outputDir),Ds),n=Vn();return n?[S.join(n,Fs),t]:[t]}function Gt(e){let t=S.join(S.resolve(e.outputDir),Os),n=Vn();return n?[S.join(n,Us),t]:[t]}function Se(e,t){let n=S.resolve(e),r=S.resolve(t),s=S.relative(n,r).replace(/\\/g,"/");return Kn(s)}async function Me(e){let t=S.resolve(e.outputDir);for(let n of Kt(e))try{let r=await T.readFile(n,"utf8"),s=JSON.parse(r);if(!js(s)||S.resolve(s.outputDir)!==t)continue;return Gn(e,s)}catch{}return null}async function Zt(e,t){let n=Gn(e,t);for(let r of Kt(e)){await T.mkdir(S.dirname(r),{recursive:true});let s=`${r}.${process.pid}.${Date.now()}.tmp`;await T.writeFile(s,JSON.stringify(n,null,2),"utf8"),await T.rename(s,r);}}async function De(e){for(let t of Kt(e))try{await T.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}async function Zn(e,t){let n={schemaVersion:1,startedAt:String(t.startedAt||new Date().toISOString()),outputDir:S.resolve(e.outputDir)};for(let r of Gt(e)){await T.mkdir(S.dirname(r),{recursive:true});let s=`${r}.${process.pid}.tmp`;await T.writeFile(s,JSON.stringify(n,null,2),"utf8"),await T.rename(s,r);}}async function Yn(e){let t=S.resolve(e.outputDir);for(let n of Gt(e)){let r;try{r=await T.readFile(n,"utf8");}catch(i){if(i.code==="ENOENT")continue;throw i}let s;try{s=JSON.parse(r);}catch{throw new Error(`Invalid incomplete crawl marker: ${n}`)}if(s.schemaVersion!==1||typeof s.startedAt!="string"||typeof s.outputDir!="string"||S.resolve(s.outputDir)!==t)throw new Error(`Invalid incomplete crawl marker: ${n}`);return {schemaVersion:1,startedAt:s.startedAt,outputDir:t}}return null}async function Xn(e){for(let t of Gt(e))try{await T.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}function Ze(e,t=10){return nr.createHash("sha1").update(e).digest("hex").slice(0,t)}async function qs(e){await T.mkdir(S.dirname(e),{recursive:true});}async function Ye(e,t,n){await qs(e);let r=S.join(S.dirname(e),`.${S.basename(e)}.${process.pid}.${Date.now()}.${nr.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await T.writeFile(r,t,n??"utf8"):await T.writeFile(r,t),await T.rename(r,e);}catch(s){throw await T.unlink(r).catch(()=>{}),s}}function be(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(S.extname(e).toLowerCase())}function de(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function Fe(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function dt(e){return e.replace(/\//g,"\\/")}function er(e){return e.replace(/\//g,"\\\\/")}function _s(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 tr(e,t,n){if(!t)return;e[t]=n;let r=dt(t),s=dt(n);e[r]=s;let i=er(t),a=er(n);e[i]=a;let c=Fe(t),o=Fe(n);e[c]=o;let l=Fe(r),u=Fe(s);e[l]=u;let d=Fe(i),p=Fe(a);e[d]=p;}function pt(e,t,n){tr(e,t,n);let r=_s(t);r&&r!==t&&tr(e,r,n);}function Yt(e,t){let n=t.startsWith("/")?t:`/${t}`,r=(e||"").replace(/\/$/,"");return !r||r==="."||r==="/"?n:`${r}${n}`}function rr(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function sr(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 zs=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Qs=new Set([".html",".htm"]),ir="WPSuite.io Static Publisher",Js=ir.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Vs(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ks(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function Gs(e,t,n){return Ks(t)?e.replace(new RegExp(`(?<!:)${Vs(t)}`,"g"),n):e.split(t).join(n)}function Zs(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 Qs.has(s)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Ys(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Js}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${ir}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let r=e.includes(`\r
|
|
1
|
+
import A from'fs/promises';import bs from'http';import Ln from'https';import S from'path';import ir,{createHash}from'crypto';import {request,chromium}from'playwright';import {gunzipSync}from'zlib';import Hs from'fast-glob';import {availableParallelism}from'os';import {Worker}from'worker_threads';import {S3Client,ListObjectsV2Command,HeadObjectCommand,GetObjectCommand,DeleteObjectsCommand}from'@aws-sdk/client-s3';import {Upload}from'@aws-sdk/lib-storage';import na from'mime-types';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';var ms=new Set(["post-type","taxonomy","author","date","posts-page","listing"]);function ke(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))].sort()}function hs(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))]}function ws(e){return new URL(e).pathname.split("/").filter(Boolean).some(n=>{try{return decodeURIComponent(n).endsWith("__trashed")}catch{return n.endsWith("__trashed")}})}function Lt(e){return Array.isArray(e)?e.map(Lt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,Lt(n)])):e}function ys(e){return JSON.stringify(Lt(e))}function ue(e){return createHash("sha256").update(ys(e)).digest("hex")}function En(e){return ue({schemaVersion:1,wordpressFingerprint:e.wordpressFingerprint,targetFingerprint:e.targetFingerprint,sourceOrigin:e.sourceOrigin,sitemapPaths:[...e.sitemapPaths].sort(),blockedPathPrefixes:[...e.blockedPathPrefixes].sort(),assetPathPrefixes:[...e.assetPathPrefixes].sort(),noJavaScriptRenderPathPrefixes:[...e.noJavaScriptRenderPathPrefixes].sort(),urlRewriteMode:e.urlRewriteMode})}function jt(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 he(e,t){let n=new URL(jt(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 Qe(e){let t=ke((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=ke((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 a=`/${i.pathname.replace(/^\/+|\/+$/g,"")}`;return a==="/"?"/":`${a}/`}));return {postTypes:t,listingPaths:n,includeSubsites:e.includeSubsites===true,includePostTypeArchives:e.includePostTypeArchives!==false,includeTaxonomyArchives:e.includeTaxonomyArchives!==false,includeAuthorArchives:e.includeAuthorArchives===true,includeDateArchives:e.includeDateArchives===true,includePostsPage:e.includePostsPage!==false,includeSitemapChain:e.includeSitemapChain!==false}}function Mn(e,t,n){return ue({schemaVersion:1,sourceOrigin:jt(e),ruleId:t.trim(),scope:Qe(n)})}function Dn(e){return ue({schemaVersion:1,...e})}function Fn(e){let t=String(e.siteId??"").trim()||String(e.accountId??"").trim()||jt(e.sourceOrigin);return `content-sync:${ue({siteIdentity:t,ruleId:e.ruleId.trim(),targetFingerprint:e.targetFingerprint}).slice(0,48)}`}function On(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.");if(r=s.sequence,!Number.isSafeInteger(s.blogId)||s.blogId<1)throw new Error("Content-sync journal event has an invalid multisite identity.");let i=`${s.blogId}:${s.postType}:${s.postId}`,a=n.get(i);if(!a){n.set(i,{postId:s.postId,blogId:s.blogId,postType:s.postType,fromSequence:s.sequence,toSequence:s.sequence,before:s.before,after:s.after,operations:[s.operation],correlationIds:s.correlationId?[s.correlationId]:[]});continue}a.toSequence=s.sequence,a.after=s.after,a.operations.push(s.operation),s.correlationId&&!a.correlationIds.includes(s.correlationId)&&a.correlationIds.push(s.correlationId);}return [...n.values()].sort((s,i)=>s.fromSequence-i.fromSequence)}function $n(e){return e?.status==="publish"&&!!e.url}function Ss(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 qt(e){let t=Qe(e.scope),n=new Map;On(e.events);for(let r of e.events)for(let s of [r.before,r.after])for(let i of s?.archiveFamilies??[]){if(!ms.has(i.kind)||!Ss(i.kind,t))continue;let a={...i,url:he(e.sourceOrigin,i.url)};n.set(`${a.kind}|${a.url}`,a);}for(let r of t.listingPaths){let s=he(e.sourceOrigin,r);n.set(`listing|${s}`,{kind:"listing",url:s});}return [...n.values()].sort((r,s)=>r.url.localeCompare(s.url))}function Un(e){let t=Qe(e.scope),n=On(e.events),r=new Set,s=new Set,i=new Map(qt({events:e.events,scope:t,sourceOrigin:e.sourceOrigin}).map(u=>[`${u.kind}|${u.url}`,u]));for(let u of n){let p=u.before,f=u.after,g=$n(p),y=$n(f);y&&f.url&&r.add(he(e.sourceOrigin,f.url)),g&&p.url&&(!y||p.url!==f.url)&&s.add(he(e.sourceOrigin,p.url));}let a=new Map(e.resolvedArchiveFamilies.map(u=>[`${u.kind}|${he(e.sourceOrigin,u.url)}`,{...u,url:he(e.sourceOrigin,u.url),pageUrls:ke(u.pageUrls.map(p=>he(e.sourceOrigin,p)))}])),c=[...i.entries()].map(([u,p])=>{let f=a.get(u);if(!f)throw new Error(`WordPress did not resolve archive family ${u}.`);return {...p,...f}}).sort((u,p)=>u.url.localeCompare(p.url)),o=ke(c.flatMap(u=>u.pageUrls)),d=t.includeSitemapChain?hs(e.sitemapUrls.map(u=>he(e.sourceOrigin,u))):[],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:ke([...r]),archiveFamilyUrls:o,sitemapUrls:d,deleteUrls:ke([...s]),archiveFamilies:c};return {...l,impactHash:ue(l)}}function Je(e){let{impactHash:t,...n}=e;if(e.schemaVersion!==1||!t)throw new Error("Invalid content-sync impact plan schema.");if(ue(n)!==t)throw new Error("Content-sync impact plan hash mismatch.");for(let r of [...e.directRenderUrls,...e.deleteUrls])if(ws(r))throw new Error(`Content-sync impact contains a WordPress trash alias instead of the last public URL: ${r}`)}var Ps="wp-json/smartcloud-static-publisher/v1/content-sync/",vs=25*1024*1024,ct=class extends Error{status;code;constructor(t,n,r){super(r),this.name="ContentSyncApiError",this.status=t,this.code=n;}},ut=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(`${Ps}${t}`,n)}async post(t,n){let r=this.endpoint(t),s=Buffer.from(JSON.stringify(n),"utf8"),i=r.protocol==="https:"?Ln:bs,a=r.protocol==="https:"?new Ln.Agent({rejectUnauthorized:!this.options.ignoreHttpsErrors}):void 0;return new Promise((c,o)=>{let d=i.request(r,{method:"POST",agent:a,headers:{"content-type":"application/json","content-length":String(s.byteLength),"x-static-publisher-token":this.options.runtimeToken},timeout:this.options.timeoutMs},l=>{let u=[],p=0;l.on("data",f=>{if(p+=f.byteLength,p>vs){l.destroy(new Error("Content-sync API response exceeded the size limit."));return}u.push(f);}),l.on("error",o),l.on("end",()=>{let f=Buffer.concat(u).toString("utf8"),g;try{g=f?JSON.parse(f):{};}catch{o(new ct(l.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let y=l.statusCode??500;if(y<200||y>=300){o(new ct(y,String(g.code??"request-failed"),String(g.message??`Content-sync API request failed (${y}).`)));return}c(g);});});d.on("timeout",()=>d.destroy(new Error(`Content-sync API request timed out: ${t}`))),d.on("error",o),d.end(s);})}async head(t){return this.post("head",t)}async unboundHead(t,n){return this.post("head",{postTypes:t,includeSubsites:n})}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 a=r;for(let c of i.items){if(!Number.isSafeInteger(c.sequence)||c.sequence<=a||c.sequence>t.throughSequence||!Number.isSafeInteger(c.postId)||c.postId<=0||!Number.isSafeInteger(c.blogId)||c.blogId<=0||!s.has(c.postType)||typeof c.operation!="string"||!c.operation)throw new Error("Content-sync API returned an invalid or out-of-scope journal event.");a=c.sequence;}if(i.items.length>0&&i.nextSequence!==a)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,n){let r=await this.post("impact",{families:t,includeSubsites:n});return Array.isArray(r.families)?r.families:[]}async releaseFingerprint(t=false){let n=await this.post("fingerprint",{includeSubsites:t}),r=String(n.fingerprint||"").trim();if(!/^[a-f0-9]{64}$/.test(r))throw new Error("WordPress returned an invalid release fingerprint.");return r}async establishBaseline(t){return this.post("baseline",t)}async acknowledge(t){return this.post("ack",t)}};function lt(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"),activeRules:S.join(t,"content-sync-active-rules.json"),releaseCutoff:S.join(t,"content-sync-release-cutoff.json"),candidateManifest:S.join(t,"content-sync-candidate-manifest.json"),trustedManifest:S.join(t,"crawl-manifest.json"),invalidation:S.join(t,"content-sync-invalidation.json"),deployPlan:S.join(t,"deploy-plan.json")}}async function _t(e){let t=await Ve(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 jn(e,t){await Ee(e.releaseCutoff,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Ee(e,t){await A.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await A.writeFile(n,JSON.stringify(t,null,2),"utf8"),await A.rename(n,e);}async function Ve(e){try{return JSON.parse(await A.readFile(e,"utf8"))}catch(t){if(t.code==="ENOENT")return null;throw new Error(`Invalid or unreadable content-sync state file ${e}: ${t instanceof Error?t.message:String(t)}`,{cause:t})}}async function Nt(e){let t=await Ve(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 qn(e,t){await Ee(e.baseline,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Bt(e){let t=await Ve(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 _n(e,t){await Ee(e.current,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Nn(e){let t=await Ve(e.impact);if(t===null)return null;let n=t;return Je(n),n}async function Bn(e,t){Je(t),await Ee(e.impact,t);}async function Wn(e,t){await Ee(e.checkpoint,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function dt(e){let t=await Ve(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 pt(e,t){await Ee(e.state,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Wt(e){await Promise.all([e.current,e.checkpoint].map(async t=>{try{await A.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}));}async function Hn(e,t){let n=await Bt(e);return !n||n.coalesceKey!==t?false:(await Promise.all([e.current,e.checkpoint,e.impact,e.candidateManifest,e.invalidation,e.deployPlan].map(async r=>{try{await A.unlink(r);}catch(s){if(s.code!=="ENOENT")throw s}})),true)}var Ht=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function Ke(e){let t=new Set;for(let n of [...e,...Ht]){let r=String(n||"").trim();r&&t.add(r);}return [...t]}function zt(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function zn(e){if(!e||!/^https?:\/\//i.test(e))return false;try{return zt(new URL(e))}catch{return false}}function Jn(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function xs(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(a=>a.replace(/[^A-Za-z0-9._-]/g,"")).filter(a=>a.length>0&&a!=="."&&a!=="..");if(s.length===0)return "";let i=`/${s.join("/")}`;return r&&S.extname(i)===""&&(i+="/"),i==="/"?"":i}function Qt(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t.trim(),String(n??"")]).filter(([t])=>t.length>0))}function As(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,a={};if(typeof i.targetOrigin=="string"){let o=Jn(i.targetOrigin);o&&(a.targetOrigin=o);}let c=Qt(i.extraReplacements);if(Object.keys(c).length>0&&(a.extraReplacements=c),i.s3&&typeof i.s3=="object"){let o={},d=i.s3;typeof d.bucket=="string"&&(o.bucket=d.bucket.trim()),typeof d.prefix=="string"&&(o.prefix=d.prefix.trim()),typeof d.region=="string"&&(o.region=d.region.trim()),typeof d.htmlCacheControl=="string"&&(o.htmlCacheControl=d.htmlCacheControl.trim()),typeof d.assetCacheControl=="string"&&(o.assetCacheControl=d.assetCacheControl.trim()),Object.keys(o).length>0&&(a.s3=o);}if(i.cloudFront&&typeof i.cloudFront=="object"){let o={},d=i.cloudFront;typeof d.distributionId=="string"&&(o.distributionId=d.distributionId.trim()),Array.isArray(d.invalidationPaths)&&(o.invalidationPaths=d.invalidationPaths.map(l=>String(l??"").trim()).filter(l=>l.length>0)),Object.keys(o).length>0&&(a.cloudFront=o);}t[s]=a;}return t}function Vt(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function Ts(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 a=String(n.deploymentProfile??"").trim(),c=String(n.url??"").trim(),o=Array.isArray(n.postTypes)?[...new Set(n.postTypes.map(l=>String(l??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],d=Array.isArray(n.listingPaths)?[...new Set(n.listingPaths.map(l=>String(l??"").trim()).filter(Boolean))]:[];return r==="content-sync"&&o.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")&&a?{deploymentProfile:a}:{},...c?{url:c}:{},...o.length>0?{postTypes:o}:{},...d.length>0?{listingPaths:d}:{},...typeof n.includeSubsites=="boolean"?{includeSubsites:n.includeSubsites}:{},...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 Vn(e){let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.rules)?t.rules.map((r,s)=>Ts(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 ks(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 Kt(e){let t=e&&typeof e=="object"?e:{},n=String(t.accountId??"").trim(),r=String(t.siteId??"").trim(),s=t.subscriber===true,i=ks(t.siteSettings),a={...i??{},...n?{accountId:i?.accountId??n}:{},...r?{siteId:i?.siteId??r}:{},...i?.subscriber===true||s?{subscriber:true}:{}},c={},o=String(t.apiBase??"").trim();o&&(c.apiBase=o);let d=String(t.runtimeToken??t.nonce??"").trim();d&&(c.runtimeToken=d);let l=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();l&&(c.virtualAssetBaseUrl=l),Object.keys(a).length>0&&(c.siteSettings=a);let u=Vt(t.subscriptionType);return u&&(c.subscriptionType=u),c}function $s(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Kn(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function Es(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 Gn(e,t,n=5){let r=new URL(Kn(e)),s=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),i=r.protocol==="http:"?bs:Ln,a=Es(e,t);return await new Promise((c,o)=>{let d=i.request(r,{method:s,headers:Object.fromEntries(a.entries()),...r.protocol==="https:"?{rejectUnauthorized:false}:{}},l=>{let u=[];l.on("data",p=>{u.push(Buffer.isBuffer(p)?p:Buffer.from(p));}),l.on("error",o),l.on("end",()=>{let p=l.statusCode??0,f=l.headers.location;if(n>0&&f&&[301,302,303,307,308].includes(p)){c(Gn(new URL(f,r),{method:p===303?"GET":s},n-1));return}let g=new Headers;for(let[y,h]of Object.entries(l.headers))Array.isArray(h)?g.set(y,h.join(", ")):typeof h=="string"&&g.set(y,h);c(new Response(Buffer.concat(u),{status:p,statusText:l.statusMessage??"",headers:g}));});});d.on("error",o),d.end();})}function Ms(e){let t=Kt(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;$s(e.sourceOrigin);let a=globalThis,o={...a.WpSuite??{},siteSettings:n,uploadUrl:i};return t.apiBase&&(o.apiBase=t.apiBase),a.WpSuite=o,true}async function Ds(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!Ms(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(o,d)=>{let l=Kn(o);if(l.startsWith(t)){let u=(()=>{try{return new URL(l).pathname}catch{return l}})();try{let p=e.ignoreHttpsErrors&&l.startsWith("https://")?await Gn(o,d):await n(o,d);return r.push({path:u,status:p.status,ok:p.ok,error:null}),p}catch(p){throw r.push({path:u,status:null,ok:!1,error:p instanceof Error?p.message:String(p)}),p}}return n(o,d)}));let{getConfig:s}=await import('@smart-cloud/wpsuite-core'),i=await s("publisher"),a=i&&typeof i=="object"?i:null,c=Vt(a?.subscriptionType);return {remote:a,diagnostic:{status:a?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:c??null,error:a?null:"WP Suite publisher config loader returned no configuration.",requests: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 Fs(e,t){let n=As(t?.deploymentProfiles),r=String(t?.defaultDeploymentProfile??"").trim(),s=n[r]?r:"",i=Vt(t?.subscriptionType),a=Kt(e.wpsuite);return {...e,scheduler:Vn(t?.scheduler),deploymentProfiles:n,defaultDeploymentProfile:s,...i?{subscriptionType:i}:{},wpsuite:{...a,...a.siteSettings||i?{siteSettings:{...a.siteSettings??{},...a.siteSettings?.subscriber===true||i==="PROFESSIONAL"||i==="AGENCY"?{subscriber:true}:{}}}:{},...i?{subscriptionType:i}:{}}}}function Jt(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 Qn(e,t,n){let r=String(t||"").trim();return r&&S.isAbsolute(r)?S.resolve(r):S.resolve(e,Jt(r,n))}async function ie(e,t={}){let n=String(e??"").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",r=await A.readFile(n,"utf8"),s=JSON.parse(r);s.sourceOrigin=s.sourceOrigin.replace(/\/$/,""),s.targetOrigin=Jn(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=xs(s.generated404RequestPath),s.sitemapPaths||=[...Ht],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=Qt(s.extraReplacements),s.postCrawlCopyMap=Qt(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=Kt(s.wpsuite),s.scheduler=Vn(void 0),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let i=await Ds(s);t.onRemotePublisherConfigDiagnostic?.(i.diagnostic);let a=Fs(s,i.remote),c=Os(),o=c?S.resolve(c,".."):"";return o?(a.outputDir=Qn(o,a.outputDir,"export"),a.logDir=Qn(o,a.logDir,"logs")):(S.isAbsolute(a.outputDir)||(a.outputDir=Jt(a.outputDir,"export")),S.isAbsolute(a.logDir)||(a.logDir=Jt(a.logDir,"logs"))),a}var Us=".deploy-plan.json",Ls="deploy-plan.json",js=".crawl-incomplete.json",qs="crawl-incomplete.json";function Zn(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Yn(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 _s(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 ye(e){return [...new Set(e.map(Yn).filter(t=>t!==null))]}function Xn(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:ye(t.changedFiles||[]),deletedFiles:ye(t.deletedFiles||[]),rewriteTargets:ye(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(),resolvedSitemapUrls:[...new Set((t.resolvedSitemapUrls||[]).map(r=>String(r||"").trim()).filter(r=>{try{let s=new URL(r);return s.protocol==="http:"||s.protocol==="https:"}catch{return false}}))],uploadGroups:{assets:ye(t.uploadGroups?.assets||[]),content:ye(t.uploadGroups?.content||[]),listings:ye(t.uploadGroups?.listings||[]),sitemapLeaves:ye(t.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:ye(t.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((t.invalidationPaths||[]).map(_s).filter(r=>r!==null))].sort()}:{schemaVersion:1,...n,runMode:t.runMode}}function Ns(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.resolvedSitemapUrls)&&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 Gt(e){let t=S.join(S.resolve(e.outputDir),Us),n=Zn();return n?[S.join(n,Ls),t]:[t]}function Zt(e){let t=S.join(S.resolve(e.outputDir),js),n=Zn();return n?[S.join(n,qs),t]:[t]}function Se(e,t){let n=S.resolve(e),r=S.resolve(t),s=S.relative(n,r).replace(/\\/g,"/");return Yn(s)}async function Me(e){let t=S.resolve(e.outputDir);for(let n of Gt(e))try{let r=await A.readFile(n,"utf8"),s=JSON.parse(r);if(!Ns(s)||S.resolve(s.outputDir)!==t)continue;return Xn(e,s)}catch{}return null}async function Yt(e,t){let n=Xn(e,t);for(let r of Gt(e)){await A.mkdir(S.dirname(r),{recursive:true});let s=`${r}.${process.pid}.${Date.now()}.tmp`;await A.writeFile(s,JSON.stringify(n,null,2),"utf8"),await A.rename(s,r);}}async function De(e){for(let t of Gt(e))try{await A.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}async function er(e,t){let n={schemaVersion:1,startedAt:String(t.startedAt||new Date().toISOString()),outputDir:S.resolve(e.outputDir)};for(let r of Zt(e)){await A.mkdir(S.dirname(r),{recursive:true});let s=`${r}.${process.pid}.tmp`;await A.writeFile(s,JSON.stringify(n,null,2),"utf8"),await A.rename(s,r);}}async function tr(e){let t=S.resolve(e.outputDir);for(let n of Zt(e)){let r;try{r=await A.readFile(n,"utf8");}catch(i){if(i.code==="ENOENT")continue;throw i}let s;try{s=JSON.parse(r);}catch{throw new Error(`Invalid incomplete crawl marker: ${n}`)}if(s.schemaVersion!==1||typeof s.startedAt!="string"||typeof s.outputDir!="string"||S.resolve(s.outputDir)!==t)throw new Error(`Invalid incomplete crawl marker: ${n}`);return {schemaVersion:1,startedAt:s.startedAt,outputDir:t}}return null}async function nr(e){for(let t of Zt(e))try{await A.unlink(t);}catch(n){if(n.code!=="ENOENT")throw n}}function Ze(e,t=10){return ir.createHash("sha1").update(e).digest("hex").slice(0,t)}async function Bs(e){await A.mkdir(S.dirname(e),{recursive:true});}async function Ye(e,t,n){await Bs(e);let r=S.join(S.dirname(e),`.${S.basename(e)}.${process.pid}.${Date.now()}.${ir.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await A.writeFile(r,t,n??"utf8"):await A.writeFile(r,t),await A.rename(r,e);}catch(s){throw await A.unlink(r).catch(()=>{}),s}}function be(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(S.extname(e).toLowerCase())}function de(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function Fe(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function gt(e){return e.replace(/\//g,"\\/")}function rr(e){return e.replace(/\//g,"\\\\/")}function Ws(e){try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return null;let n=t.pathname==="/"&&!t.search&&!t.hash?"":`${t.pathname}${t.search}${t.hash}`;return `//${t.host}${n}`}catch{return null}}function sr(e,t,n){if(!t)return;e[t]=n;let r=gt(t),s=gt(n);e[r]=s;let i=rr(t),a=rr(n);e[i]=a;let c=Fe(t),o=Fe(n);e[c]=o;let d=Fe(r),l=Fe(s);e[d]=l;let u=Fe(i),p=Fe(a);e[u]=p;}function ft(e,t,n){sr(e,t,n);let r=Ws(t);r&&r!==t&&sr(e,r,n);}function Xt(e,t){let n=t.startsWith("/")?t:`/${t}`,r=(e||"").replace(/\/$/,"");return !r||r==="."||r==="/"?n:`${r}${n}`}function or(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function ar(e,t,n){if(!t)return n;let r=S.dirname(S.resolve(t)),s=S.resolve(e,n.replace(/^\/+/,"")),i=S.relative(r,s).replace(/\\/g,"/");return i?(i.startsWith(".")||(i=`./${i}`),i):"."}var Vs=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Ks=new Set([".html",".htm"]),cr="WPSuite.io Static Publisher",Gs=cr.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Zs(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ys(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function Xs(e,t,n){return Ys(t)?e.replace(new RegExp(`(?<!:)${Zs(t)}`,"g"),n):e.split(t).join(n)}function ei(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 Ks.has(s)?/<head\b|<html\b|<!doctype html/i.test(t):false}function ti(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Gs}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${cr}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let r=e.includes(`\r
|
|
2
2
|
`)?`\r
|
|
3
3
|
`:`
|
|
4
|
-
`;return e.replace(/<head\b[^>]*>/i,s=>`${s}${r} ${t}`)}function
|
|
5
|
-
`,"utf8");}function
|
|
6
|
-
`,"utf8");});}enqueueJsonLine(t,n){this.enqueueTask(()=>
|
|
7
|
-
`,"utf8");});}enqueueJsonLine(t,n){this.enqueueTask(()=>
|
|
4
|
+
`;return e.replace(/<head\b[^>]*>/i,s=>`${s}${r} ${t}`)}function ni(e){let t=de(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function ri(e,t){let n=[...new Set(t)].filter(i=>i.includes("/")&&!/\\+\//.test(i)).map(i=>[i,gt(i)]).filter(([i,a])=>i!==a).sort((i,a)=>a[0].length-i[0].length);if(!n.length)return e;let r=i=>{let a=i;for(let[c,o]of n)a=a.split(c).join(o);return a},s=e.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(i,a,c,o)=>`${a}${r(c)}${o}`);return s=s.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(i,a,c,o,d)=>ni(o)?`${a}${r(o)}${d}`:i),s}function si(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 ii(e,t,n){let r=si(t,n);if(!r)return e;let s=e;for(let i of Vs){let a=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=new RegExp(`(?:\\.{1,}/)+${a}`,"g"),o=new RegExp(`(?<!\\.)/${a}`,"g");s=s.replace(c,`${r}${i}`).replace(o,`${r}${i}`);let d=i.replace(/\//g,"\\/"),l=r.replace(/\//g,"\\/"),u=d.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),p=new RegExp(`(?:\\.{1,}\\\\/)+${u}`,"g"),f=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${u}`,"g"),g=new RegExp(`(?<![\\.\\\\])\\/${u}`,"g");s=s.replace(p,`${l}${d}`).replace(f,`${l}${d}`).replace(g,`${l}${d}`);}return s}function tn(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:or(t,e.targetOrigin),i=r?`${r.search}${r.hash}`:"";return e.urlRewriteMode==="root-relative"?`${s}${i}`:`${ar(e.outputDir,n,s)}${i}`}function en(e,t,n,r,s){ft(e,n,tn(t,r,s));}function oi(e,t,n,r,s){if(!n||n===r)return;ft(e,n,r);let i=tn(t,n,s),a=tn(t,r,s);ft(e,i,a);}function nn(e,t,n,r,s={}){let i=e,a={};en(a,t,t.sourceOrigin,t.targetOrigin,r);for(let[o,d]of Object.entries(t.extraReplacements))en(a,t,o,d,r);for(let[o,d]of Object.entries(n))en(a,t,o,d,r);for(let[o,d]of Object.entries(s)){let l=n[o];!l||l===d||oi(a,t,d,l,r);}let c=Object.entries(a).sort((o,d)=>d[0].length-o[0].length);for(let[o,d]of c)i=Xs(i,o,d);return t.urlRewriteMode!=="absolute"&&(i=ii(i,t,r)),i=ri(i,c.map(([,o])=>o)),ei(t,i,r)&&(i=ti(i)),i}async function ai(e,t,n,r){let s=S.join(e.outputDir,r),i=S.extname(s).toLowerCase(),a;try{a=await A.readFile(s,"utf8");}catch(d){if(d.code!=="ENOENT")throw d;return {changed:false}}let o=nn(a,e,t,i===".js"||i===".mjs"?void 0:s,n);return o!==a?(await Ye(s,o,"utf8"),{changed:true}):{changed:false}}async function ci(e,t){return await new Promise((n,r)=>{let s=o=>{if(c(),o?.error){r(new Error(o.error));return}n({changed:!!o?.changed});},i=o=>{c(),r(o);},a=o=>{c(),o!==0&&r(new Error(`Rewrite worker exited with code ${o}.`));},c=()=>{e.off("message",s),e.off("error",i),e.off("exit",a);};e.on("message",s),e.on("error",i),e.on("exit",a),e.postMessage({file:t});})}async function mt(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 Hs(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(p=>p!=="asset-map.json"&&be(p)),i=0;if(s.length===0)return 0;let a=Math.max(1,Number(e.rewriteConcurrency||e.assetDownloadConcurrency||1)),c=Math.max(1,Math.min(a,s.length,availableParallelism()));await n.onStart?.({totalFiles:s.length,workerCount:c});let o=0,d=0,l=null;if(c===1){for(let p of s){let f=await ai(e,t,n.previousAssetMap??{},p);f.changed&&(i+=1),d+=1,await n.onProgress?.({index:d,totalFiles:s.length,changedTextFiles:i,file:p,changed:f.changed});}return i}let u=Array.from({length:c},async()=>{let p=new Worker(new URL("./rewrite-worker.js",import.meta.url),{workerData:{config:e,assetMap:t,previousAssetMap:n.previousAssetMap??{}}});try{for(;!l;){let f=o;if(f>=s.length)return;o+=1;let g=s[f],y=await ci(p,g);y.changed&&(i+=1),d+=1,await n.onProgress?.({index:d,totalFiles:s.length,changedTextFiles:i,file:g,changed:y.changed});}}catch(f){throw l=f instanceof Error?f:new Error(String(f)),l}finally{await p.terminate().catch(()=>{});}});return await Promise.all(u),i}var ce={error:0,warn:1,info:2,debug:3},ui=/^(?:authorization|proxyAuthorization|runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken|xStaticPublisherToken|xApiKey)$/i;function Re(e){return e.replace(/((?:x-static-publisher-token|authorization|proxy-authorization|x-api-key|aws-access-key-id|aws-secret-access-key|aws-session-token)\s*:\s*)[^\r\n]+/gi,"$1[REDACTED]").replace(/\b(Basic|Bearer)\s+[^\s]+/gi,"$1 [REDACTED]").replace(/([?&](?:token|access_token|refresh_token|api_key|key|nonce)=)[^&\s]+/gi,"$1[REDACTED]").replace(/((?:"|')?(?:runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken)(?:"|')?\s*[:=]\s*(?:"|'))[^"']+/gi,"$1[REDACTED]")}function wt(e){return typeof e=="string"?Re(e):Array.isArray(e)?e.map(t=>wt(t)):e instanceof Error?{name:e.name,message:Re(e.message),...e.stack?{stack:Re(e.stack)}:{}}:e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([t,n])=>[t,ui.test(t)?"[REDACTED]":wt(n)])):e}function St(e){return e?wt(e):void 0}var ur=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",ht=ur?S.join(ur,"current-progress.json"):"",lr=Promise.resolve();function dr(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function li(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 a=n[s];if(typeof a=="number"&&typeof i=="number"&&r.has(s)){n[s]=Math.max(a,i);continue}n[s]=i;}return n}function pr(e,t,n){ht&&(lr=lr.then(async()=>{let r=new Date,s=r.toISOString();await A.mkdir(S.dirname(ht),{recursive:true});let i=await A.readFile(ht,"utf8").then(m=>JSON.parse(m)).catch(()=>null),a=i&&typeof i.details=="object"&&i.details?i.details:{},c=dr(e),o=i?.currentStep||dr(i?.source||""),d=i?.startedAt||s,l={...i?.stepDurationsSec??{}},u=i?.stepStartedAt||s;if(o&&o!==c&&i?.stepStartedAt){let m=Math.max(0,Math.round((r.getTime()-new Date(i.stepStartedAt).getTime())/1e3));l[o]=(l[o]??0)+m,u=s;}let p=Math.max(0,Math.round((r.getTime()-new Date(u).getTime())/1e3)),f=Math.max(0,Math.round((r.getTime()-new Date(d).getTime())/1e3)),g=Re(t),y=St(n)??{},h={checkedAt:s,source:e,message:g,details:li(a,y),startedAt:d,currentStep:c,stepStartedAt:u,stepElapsedSec:p,totalElapsedSec:f,stepDurationsSec:l};await A.writeFile(ht,JSON.stringify(h,null,2),"utf8");}).catch(()=>{}));}async function gr(e,t){await A.mkdir(S.dirname(e),{recursive:true}),await A.appendFile(e,`${JSON.stringify(wt(t))}
|
|
5
|
+
`,"utf8");}function di(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 pi(e,t,n){let r=St(n);return {checkedAt:new Date().toISOString(),currentStep:di(e,r),level:e,message:Re(t),details:r??{}}}var Oe=class{constructor(t,n,r="info"){this.logDir=t;this.logFile=n;this.level=r;this.ensureLogFileReady();}logDir;logFile;level;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;get logPath(){return S.join(this.logDir,this.logFile)}artifactPath(t){return this.logFile.endsWith(".log.jsonl")?S.join(this.logDir,this.logFile.replace(/\.log\.jsonl$/u,`${t}.jsonl`)):S.join(this.logDir,`${this.logFile}${t}.jsonl`)}get errorsPath(){return this.artifactPath(".errors")}get rejectedPath(){return this.artifactPath(".rejected")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await A.mkdir(this.logDir,{recursive:true}),await A.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(t){this.writeQueue=this.writeQueue.then(t).catch(n=>{this.writeError=n instanceof Error?n:new Error(String(n));});}enqueueLine(t){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await A.appendFile(this.logPath,`${t}
|
|
6
|
+
`,"utf8");});}enqueueJsonLine(t,n){this.enqueueTask(()=>gr(t,n));}accepts(t){return ce[t]<=ce[this.level]}push(t,n,r){if(!this.accepts(t))return;let s=Re(n),i=St(r),a=JSON.stringify({time:new Date().toISOString(),level:t,message:s,...i||{}});this.enqueueLine(a),t==="error"?console.error(`[ERROR] ${s}`,i?JSON.stringify(i):""):t==="warn"?console.warn(`[WARN] ${s}`,i?JSON.stringify(i):""):console.log(`[${t.toUpperCase().padEnd(5)}] ${s}`);}info(t,n){this.push("info",t,n);}progress(t,n){pr(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 a={kind:t,url:n,reason:r,...s?{source:s}:{},...i||{}};this.enqueueJsonLine(this.rejectedPath,a),this.accepts("debug")&&this.push("debug",`Rejected ${t} ${n}: ${r}`,a);}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}},yt=class{constructor(t,n="info"){this.logDir=t;this.level=typeof n=="boolean"?n?"debug":"info":n,this.ensureLogFileReady();}logDir;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;level;get logPath(){return S.join(this.logDir,"crawl.log.jsonl")}get currentEventPath(){return S.join(this.logDir,"current-crawl-event.json")}get rejectedPath(){return S.join(this.logDir,"rejected.jsonl")}get ignoredPath(){return S.join(this.logDir,"ignored.jsonl")}get skippedPath(){return S.join(this.logDir,"skipped-http.jsonl")}get errorsPath(){return S.join(this.logDir,"errors.jsonl")}get timingsPath(){return S.join(this.logDir,"timings.jsonl")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await A.mkdir(this.logDir,{recursive:true}),await A.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(t){this.writeQueue=this.writeQueue.then(t).catch(n=>{this.writeError=n instanceof Error?n:new Error(String(n));});}enqueueLine(t){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await A.appendFile(this.logPath,`${t}
|
|
7
|
+
`,"utf8");});}enqueueJsonLine(t,n){this.enqueueTask(()=>gr(t,n));}updateCurrentEvent(t,n,r){let s=pi(t,n,r);this.enqueueTask(async()=>{await A.mkdir(this.logDir,{recursive:true}),await A.writeFile(this.currentEventPath,JSON.stringify(s,null,2),"utf8");});}push(t,n,r){let s=Re(n),i=St(r),a=JSON.stringify({time:new Date().toISOString(),level:t,message:s,...i||{}});this.enqueueLine(a),this.updateCurrentEvent(t,s,i),t==="error"?console.error(s,i||""):t==="warn"?console.warn(s,i||""):(ce[this.level]>=ce.debug||["summary","page","sitemap","asset","timing"].includes(t))&&console.log(s);}info(t,n){this.push("info",t,n);}debug(t,n){ce[this.level]<ce.debug||this.push("debug",t,n);}progress(t,n){pr("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),ce[this.level]>=ce.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),ce[this.level]>=ce.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 rn="(?: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 fr(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 mr(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]&&fr(i[1])&&n.push({index:i.index??0,value:i[1]});for(let i of e.matchAll(s))i[1]&&fr(i[1])&&n.push({index:i.index??0,value:i[1]});for(let i of n.sort((a,c)=>a.index-c.index))t.add(i.value);return [...t]}function hr(e,t){return typeof e=="string"&&e.length>0&&t?.supported===true&&typeof t.token=="string"&&t.token.length>0&&e===t.token}function wr(e,t){try{let n=new URL(e),r=new URL(t,n);if(r.origin!==n.origin)return !1;let s=n.pathname.replace(/\/+$/,"");if(s&&r.pathname!==s&&!r.pathname.startsWith(`${s}/`))return !1;let i=s?r.pathname.slice(s.length)||"/":r.pathname;return ["/wp-includes/","/wp-content/plugins/","/wp-content/themes/","/wp-content/mu-plugins/"].some(a=>i.startsWith(a))}catch{return false}}function yr(e){return e<1}function Sr(e){let t=String(e??"").toLowerCase();return t==="strict"?"Strict":t==="lax"?"Lax":t==="none"?"None":"Unspecified"}function fi(e){let t=e.pathname||"/";if(!t.startsWith("/")||t==="/")return "/";let n=t.lastIndexOf("/");return n<=0?"/":t.slice(0,n)}function Xe(e){return `${e.name.toLowerCase()}
|
|
8
8
|
${e.domain.toLowerCase()}
|
|
9
|
-
${e.path}`}function
|
|
10
|
-
`,{encoding:"utf8",mode:384}),await
|
|
11
|
-
${n}`,40),tokenSource:t.tokenSource?`${t.tokenSource}+site-subscriber`:"site-subscriber"}}async function
|
|
9
|
+
${e.path}`}function br(e,t){let n;try{n=new URL(t);}catch{return null}let r=e.split(";"),s=r.shift()?.trim()??"",i=s.indexOf("=");if(i<=0)return null;let a=s.slice(0,i).trim();if(!a||[...a].some(y=>y<=" "||"=;,".includes(y)))return null;let c=n.hostname.toLowerCase(),o=fi(n),d=null,l=true,u=false,p=false,f="Unspecified",g=false;for(let y of r){let h=y.indexOf("="),m=(h<0?y:y.slice(0,h)).trim().toLowerCase(),w=h<0?"":y.slice(h+1).trim();if(m==="domain"&&w)c=w.toLowerCase();else if(m==="path"&&w.startsWith("/"))o=w;else if(m==="expires"){let P=Date.parse(w);Number.isFinite(P)&&(d=Math.floor(P/1e3),l=false);}else if(m==="max-age"&&/^-?\d+$/u.test(w)){let P=Number.parseInt(w,10);d=Math.floor(Date.now()/1e3)+P,l=false;}else m==="secure"?u=true:m==="httponly"?p=true:m==="samesite"?f=Sr(w):m==="partitioned"&&(g=true);}return {name:a,domain:c,path:o,expires:d,session:l,secure:u,httpOnly:p,sameSite:f,partitioned:g}}function mi(e){let t=!Number.isFinite(e.expires)||e.expires<=0;return {name:e.name,domain:e.domain.toLowerCase(),path:e.path||"/",expires:t?null:e.expires,session:t,secure:e.secure,httpOnly:e.httpOnly,sameSite:Sr(e.sameSite),partitioned:e.partitioned===true}}function Pr(e,t){let n=new Map(e.map(r=>[Xe(r),r.value]));return t.filter(r=>n.get(Xe(r))!==r.value).map(mi)}function hi(e,t){let n=e.session||t.session;return {...e,expires:n?null:Math.max(e.expires??0,t.expires??0)||null,session:n,secure:e.secure&&t.secure,httpOnly:e.httpOnly&&t.httpOnly,sameSite:e.sameSite===t.sameSite?e.sameSite:"Unspecified",partitioned:e.partitioned&&t.partitioned}}var bt=class{#e=new Map;add(t){if(!t)return;let n={...t,domain:t.domain.toLowerCase(),path:t.path||"/"},r=Xe(n),s=this.#e.get(r);this.#e.set(r,s?hi(s,n):n);}addAll(t){for(let n of t)this.add(n);}artifact(){return {schemaVersion:1,observations:[...this.#e.values()].sort((t,n)=>Xe(t).localeCompare(Xe(n)))}}};async function Pt(e,t){await A.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.tmp`;await A.writeFile(n,`${JSON.stringify(t,null,2)}
|
|
10
|
+
`,{encoding:"utf8",mode:384}),await A.rename(n,e);}var Si=["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"],Or=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"]),bi=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),Pi=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function vi(e){let t=[],n="full",r="full",s=false,i=false,a="";for(let c=0;c<e.length;c++){let o=e[c];if(o==="--retry-timeouts")n="retry-timeouts",s=true;else if(o==="--resume")s=true;else if(o==="--resume-rewrite")s=true,i=true;else if(o==="--crawl-mode"){let d=e[++c];if(!d)throw new Error("--crawl-mode requires a value");r=d==="incremental"?"incremental":"full",s||=r==="incremental";}else if(o.startsWith("--crawl-mode="))r=o.slice(13)==="incremental"?"incremental":"full",s||=r==="incremental";else if(o==="--incremental")r="incremental",s=true;else if(o==="--url"){let d=e[++c];if(!d)throw new Error("--url requires a value");n="single-url",s=true,t.push(d);}else if(o.startsWith("--url="))n="single-url",s=true,t.push(o.slice(6));else if(o==="--urls"){let d=e[++c];if(!d)throw new Error("--urls requires a file path");n="single-url",s=true,t.push(`@${d}`);}else if(o==="--content-sync-plan"){let d=e[++c];if(!d)throw new Error("--content-sync-plan requires a file path");n="content-sync",r="incremental",s=true,a=S.resolve(d);}else o.startsWith("--content-sync-plan=")&&(n="content-sync",r="incremental",s=true,a=S.resolve(o.slice(20)));}return {mode:n,crawlMode:r,urls:t,preserveOutput:s,resumeRewrite:i,contentSyncPlanPath:a}}function At(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?S.resolve(e):""}function Ci(){let e=At();return e?S.join(e,"privacy","cookie-observations.json"):null}function Ri(){let e=At();return e?S.resolve(e,".."):""}function Ii(){let e=process.env.STATIC_PUBLISHER_WP_ROOT||process.env.WPSUITE_STATIC_PUBLISHER_WP_ROOT||"";return e.trim()?S.resolve(e):""}function xi(e){let t=e.trim(),n=[{alias:"@storage-root",root:Ri(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@runtime",root:At(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@wp-root",root:Ii(),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=At();return n?S.join(n,"crawl-manifest.json"):S.join(e.outputDir,".crawl-manifest.json")}function jr(){return {schemaVersion:5,updatedAt:"",pages:{},assets:{}}}function Cr(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 Ai(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,changeToken:typeof e.changeToken=="string"?e.changeToken:null,tokenSource:typeof e.tokenSource=="string"?e.tokenSource:null,discoveredAssets:Array.isArray(e.discoveredAssets)?e.discoveredAssets.map(n=>String(n)):[],lastCrawledAt:String(e.lastCrawledAt||""),lastSeenRunId:String(e.lastSeenRunId||""),unreferencedRuns:Math.max(0,Number(e.unreferencedRuns)||0),rewriteComplete:e.rewriteComplete===true||!t}}function cn(e){let t=e?.["content-type"]?.trim();return t||null}function Ti(){return {rewriteTargets:new Set,changedFiles:new Set,deletedFiles:new Set}}function te(e,t,n){let r=Se(t.outputDir,n);r&&(e.changedFiles.add(r),e.deletedFiles.delete(r));}function Rr(e,t,n){let r=Se(t.outputDir,n);r&&(e.deletedFiles.add(r),e.changedFiles.delete(r));}function Ie(e,t){e.rewriteTargets.add(S.resolve(t));}async function ki(e){try{let t=await A.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.schemaVersion===4||n.schemaVersion===5)&&n.assets&&typeof n.assets=="object")return {schemaVersion:5,updatedAt:String(n.updatedAt||""),pages:Object.fromEntries(Object.entries(n.pages).map(([r,s])=>[r,Cr(s)])),assets:Object.fromEntries(Object.entries(n.assets).map(([r,s])=>[r,Ai(s)]))};if(n.schemaVersion===1)return {schemaVersion:5,updatedAt:String(n.updatedAt||""),pages:Object.fromEntries(Object.entries(n.pages).map(([r,s])=>[r,Cr(s)])),assets:{}}}}catch{}return jr()}function un(e){return JSON.parse(JSON.stringify(e))}async function $i(e,t){let n=Lr(e);await A.mkdir(S.dirname(n),{recursive:true}),await A.writeFile(n,JSON.stringify(t,null,2),"utf8");}async function Pe(e,t){if(!t.trackManifest)return;let n=async()=>{let r=un(t.manifest);r.updatedAt=new Date().toISOString(),t.manifest.updatedAt=r.updatedAt,await $i(e,r);};t.manifestSaveChain=t.manifestSaveChain.then(n,n),await t.manifestSaveChain;}function tt(e){if(!e)return null;let t=e.trim();return t||null}function Ei(e,t){let n=new Set,r=new Set([...Object.keys(e),...Object.keys(t)]);for(let s of r){let i=e[s],a=t[s];!i||!a||i===a||n.add(s);}return n}async function qr(e,t,n,r){let s=[...new Set(n.map(c=>c.trim()).filter(Boolean))],i=String(e.wpsuite?.runtimeToken||"").trim();if(s.length===0||!i)return new Map;let a=new URL("/wp-json/smartcloud-static-publisher/v1/change-tokens",e.sourceOrigin).toString();try{let c=await t.post(a,{timeout:3e4,failOnStatusCode:!1,headers:{"content-type":"application/json","x-static-publisher-token":i},data:JSON.stringify({urls:s})});if(!c.ok())return r.warn(`Change token lookup failed with HTTP ${c.status()}`,{endpoint:a,status:c.status()}),new Map;let o=await c.json().catch(()=>null);if(!o||!Array.isArray(o.items))return new Map;let d=new Map;for(let l of o.items)!l||typeof l.url!="string"||d.set(l.url,l);return d}catch(c){return r.warn("Change token lookup failed; falling back to sitemap metadata",{endpoint:a,error:c instanceof Error?`${c.name}: ${c.message.split(/\r?\n/u,1)[0]}`:"Unknown change-token request failure"}),new Map}}async function Rt(e,t,n,r,s){if(!n.enabled&&!n.trackManifest)return null;if(n.changeTokenCache.has(r))return n.changeTokenCache.get(r)??null;let a=(await qr(e,t,[r],s)).get(r)??null;return hn(e,r)&&(!a||a.supported!==true||!a.token)&&(a=await Fi(e,t,r,s)),a=_r(e,a),n.changeTokenCache.set(r,a),a}async function Mi(e,t,n,r,s){if(!n.trackManifest)return;let i=[...new Set(r.map(a=>a.trim()).filter(Boolean))].filter(a=>!n.changeTokenCache.has(a));for(let a=0;a<i.length;a+=250){let c=i.slice(a,a+250),o=await qr(e,t,c,s);for(let d of c)n.changeTokenCache.set(d,_r(e,o.get(d)??null));}}function Di(e){return `subscriber=${e.wpsuite?.siteSettings?.subscriber===true?"1":"0"}`}function _r(e,t){if(!t?.supported||!t.token||t.tokenSource==="wp-media-file")return t;let n=Di(e);return {...t,token:Ze(`${t.token}
|
|
11
|
+
${n}`,40),tokenSource:t.tokenSource?`${t.tokenSource}+site-subscriber`:"site-subscriber"}}async function Fi(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(()=>""),a=Ze(`${n}
|
|
12
12
|
404
|
|
13
|
-
${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:a,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 Di(e,t,n,r,s,i){let a=gn(e,s);if(!r.enabled)return {action:"render",changeToken:r.trackManifest?await vt(e,t,r,s,i):null};let c=r.manifest.pages[s];if(!c)return {action:"render",changeToken:await vt(e,t,r,s,i)};let o=await vt(e,t,r,s,i);if(o?.supported&&o.token)return c.changeToken===o.token?a&&!await Fi(e,t,s,i)?{action:"render",changeToken:o}:{action:"reuse",changeToken:o}:{action:"render",changeToken:o};let l=et(n.sitemapLastmodByPage[s]);return l&&c.sitemapLastmod&&c.sitemapLastmod===l?{action:"reuse",changeToken:o}:{action:"render",changeToken:o}}async function Fi(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 Oi(e,t,n,r,s){let i=Pr(n.previousManifest,void 0,r,"previous-manifest"),a=0;for(let[p,f]of Object.entries(n.manifest.pages))if(!n.seenPages.has(p)){br(s,e,f.outputPath);try{await T.unlink(f.outputPath);}catch(g){(g.code||"")!=="ENOENT"&&r.warn(`Failed to remove stale incremental page output for ${p}`,{url:p,outputPath:f.outputPath,error:String(g)});}delete n.manifest.pages[p],a++;}let c=Pr(n.manifest,n.runId,r,"active-manifest"),o=new Set,l=new Set;for(let p of c){for(let y of tt(e,p))o.add(y);let f=n.manifest.assets[p]?.outputPath;f&&l.add(f);let g=je(e,t.assetMap,p);g&&l.add(g);}for(let p of Object.keys(n.manifest.assets)){if(c.has(p)){n.manifest.assets[p].unreferencedRuns=0;continue}let f=n.manifest.assets[p];if(mr(f.unreferencedRuns)){f.unreferencedRuns+=1,r.warn(`Deferred deletion of newly unreferenced incremental asset ${p}.`,{url:p,unreferencedRuns:f.unreferencedRuns,phase:"incremental-cleanup",source:"asset-deletion-grace"});continue}delete n.manifest.assets[p];}let u=0,d=0;for(let p of i){if(n.manifest.assets[p])continue;let f=new Set,g=n.previousManifest.assets[p]?.outputPath;g&&f.add(g);let y=je(e,t.assetMap,p);if(!c.has(p)&&y)f.add(y);else if(!c.has(p)){let m=Yi(e,p,r,"incremental-cleanup");m&&(f.add(m.originalFilePath),m.hashedFilePath&&f.add(m.hashedFilePath));}for(let m of f)if(!l.has(m)){br(s,e,m);try{await T.unlink(m),u++;}catch(h){(h.code||"")!=="ENOENT"&&r.warn(`Failed to remove stale incremental asset output for ${p}`,{url:p,outputPath:m,error:String(h)});}}for(let m of tt(e,p))o.has(m)||Object.prototype.hasOwnProperty.call(t.assetMap,m)&&(delete t.assetMap[m],d++);}(a>0||u>0||d>0)&&r.info(`Incremental cleanup removed ${a} stale pages, ${u} stale assets, ${d} stale asset mappings`,{removedPages:a,removedAssets:u,removedAssetMappings:d,phase:"incremental-cleanup"});}function Pr(e,t,n,r){let s=new Set,i=a=>{let c=a.trim();if(c){if(n){let o=ve(c,n,"asset",r??"manifest");if(!o)return;s.add(o.toString());return}s.add(c);}};for(let a of Object.values(e.pages))for(let c of a.discoveredAssets||[])i(c);for(let[a,c]of Object.entries(e.assets||{}))t&&c.lastSeenRunId!==t||i(a);return s}function vr(e,t,n){for(let r of t)for(let s of tt(e,r))if(n.has(s))return true;return false}function Ui(e,t,n,r,s){let i=new Set(n.rewriteTargets);for(let c of n.changedFiles)i.add(S.resolve(e.outputDir,c));for(let c of Object.values(t.manifest.pages))c.rewriteComplete||i.add(S.resolve(c.outputPath));for(let c of Object.values(t.manifest.assets))c.isText&&!c.rewriteComplete&&i.add(S.resolve(c.outputPath));let a=ki(r,s);if(a.size===0)return [...i];for(let c of Object.values(t.manifest.pages))vr(e,c.discoveredAssets,a)&&i.add(S.resolve(c.outputPath));for(let[c,o]of Object.entries(t.manifest.assets)){o.isText&&vr(e,o.discoveredAssets,a)&&i.add(S.resolve(o.outputPath));for(let l of tt(e,c))if(a.has(l)){X(n,e,o.outputPath),o.isText&&i.add(S.resolve(o.outputPath));break}}return [...i]}function Li(e,t){let n=t?new Set(Array.from(t,s=>S.resolve(s))):null,r=s=>n===null||n.has(S.resolve(s));for(let s of Object.values(e.manifest.pages))r(s.outputPath)&&(s.rewriteComplete=true);for(let s of Object.values(e.manifest.assets)){if(!s.isText){s.rewriteComplete=true;continue}r(s.outputPath)&&(s.rewriteComplete=true);}}function ji(e,t,n){let r=new Set,s=i=>{if(!i)return;let a=Se(e.outputDir,i);a&&r.add(a);};for(let i of t.donePages)s(ge(e,i));for(let i of Object.values(n.manifest.pages))i.lastSeenRunId===n.runId&&s(i.outputPath);for(let i of t.doneAssets)s(je(e,t.assetMap,i));for(let i of Object.values(n.manifest.assets))i.lastSeenRunId===n.runId&&s(i.outputPath);return r}async function qi(e,t,n,r,s){let i=[...r.deletedFiles].sort(),a=ji(e,t,n),c=0;for(let u of [...a].sort()){try{if((await T.stat(S.join(e.outputDir,u))).isFile())continue}catch{}c++,s.warn(`Active output is missing after crawl: ${u}`,{phase:"deploy-plan",file:u,outputPath:S.join(e.outputDir,u)});}if(c>0&&s.warn(`Detected ${c} active output file(s) missing before deploy plan save.`,{phase:"deploy-plan",missingActiveOutputs:c}),i.length===0)return [];let o=[],l=0;for(let u of i){if(!a.has(u)){o.push(u);continue}l++;let d=S.join(e.outputDir,u),p;try{p=(await T.stat(d)).isFile();}catch{p=false;}s.warn(`Deploy plan protected active output from deletion: ${u}`,{phase:"deploy-plan",file:u,outputPath:d,exists:p});}return l>0&&s.info(`Deploy plan skipped ${l} active output deletion(s).`,{phase:"deploy-plan",protectedDeletes:l,deletedFiles:o.length}),o}function tt(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 a of i)try{n.add(new URL(a).origin+r.pathname+r.search);}catch{}n.add(r.pathname+r.search),n.add(r.pathname);}catch{}return [...n]}function _i(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 a of i)try{n.add(new URL(a).origin+r.pathname+r.search);}catch{}n.add(r.pathname+r.search);}catch{}return [...n]}function Lr(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,pn(r.pathname))}catch{return null}}function Ni(e,t,n){for(let r of _i(e,n)){let s=t[r];if(!s)continue;let i=Lr(e,s);if(i)return {outputPath:i,publicUrl:s}}return null}function Bi(e,t,n){for(let r of tt(e,n)){let s=t[r];if(!s)continue;let i=Lr(e,s);if(i)return i}return null}function je(e,t,n){let r=Bi(e,t,n);if(r)return r;try{return At(e,n).originalFilePath}catch{return null}}function Wi(){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 Cr(e){let t=Wi();if(t)try{let n=await T.readFile(t,"utf8"),r=JSON.parse(n);if(!r||typeof r!="object")return;await T.writeFile(t,JSON.stringify({...r,checkedAt:new Date().toISOString(),status:"running",currentStep:"rewrite",message:e},null,2),"utf8");}catch{}}function Hi(e,t){let n=new Set;for(let r of t.donePages)n.add(S.resolve(ge(e,r)));for(let r of t.doneAssets){let s=je(e,t.assetMap,r);!s||!be(s)||n.add(S.resolve(s));}for(let r of t.doneSitemaps){let s=je(e,t.assetMap,r);!s||!be(s)||n.add(S.resolve(s));}return [...n]}var Rt="re:",bt=new Map;function zi(e){if(!e.startsWith(Rt))return null;let t=bt.get(e);if(t!==void 0)return t||null;let n=e.slice(Rt.length).trim();if(!n)return bt.set(e,false),null;try{let r=new RegExp(n);return bt.set(e,r),r}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),bt.set(e,false),null}}function dn(e,t){let n=zi(t);return n?n.test(e):t.startsWith(Rt)?false:e.startsWith(t)}function Qi(e,t){return t.find(n=>dn(e,n))}function jr(e,t){let n=Qi(t.pathname,e.blockedPathPrefixes);if(n)return n.startsWith(Rt)?`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 Ji(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 Vi(e,t){return Ji(e).has(t.hostname)}function Ki(e){let t=de(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function cn(e){let t=de(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function Gi(e){let t=de(e).replace(/\\\//g,"/").trim(),n=S.extname(t).toLowerCase();return Er.has(n)||Mr.has(n)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function qe(e){return Si.some(t=>e.pathname.startsWith(t))}function z(e,t,n=e.sourceOrigin,r,s="url",i=false){let a=Ki(t);if(!a||a.startsWith("data:")||a.startsWith("blob:")||a.startsWith("mailto:")||a.startsWith("tel:")||a.startsWith("#"))return r?.ignore(s,t,"empty or unsupported scheme",n),null;if(cn(a))return r?.ignore(s,t,"looks like JavaScript/code fragment",n),null;if(Gi(a))return r?.ignore(s,t,"looks like JavaScript property access",n),null;try{let c=new URL(a,n);if(qr(c))return r?.reject(s,t,"malformed URL encoding",n),null;if(!["http:","https:"].includes(c.protocol))return r?.ignore(s,t,"unsupported protocol: ",n),null;if(!Vi(e,c))return r?.ignore(s,c.toString(),"host not allowed",n),null;let o=jr(e,c);if(o&&!(i&&Ht(c)))return r?.reject(s,c.toString(),o,n),null;let l=new URL(e.sourceOrigin);return c.protocol=l.protocol,c.host=l.host,c.hash="",c}catch{return r?.reject(s,t,"invalid URL",n),null}}function qr(e){try{return decodeURIComponent(e.pathname),decodeURIComponent(e.search),decodeURIComponent(e.hash),!1}catch{return true}}function ve(e,t,n,r){try{let s=new URL(e);return qr(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 _r(e){return Er.has(S.extname(e.pathname).toLowerCase())}function Ce(e){return qe(e)?false:Mr.has(S.extname(e.pathname).toLowerCase())}function _e(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function B(e,t){return !!(_e(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(n=>dn(t.pathname,n))||_r(t)||!Ce(t)&&!qe(t))}function ge(e,t){let n=new URL(t),r=pn(n.pathname);return r.endsWith("/")?r+="index.html":S.extname(r)||(r+="/index.html"),S.join(e.outputDir,r)}function pn(e){try{return decodeURIComponent(e)}catch{return e}}function Zi(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 gn(e,t){let n=Zi(e);if(!n)return false;try{return new URL(t,e.sourceOrigin).toString()===n}catch{return false}}function At(e,t){let n=new URL(t),r=pn(n.pathname);r.endsWith("/")&&(r+="index.html");let s=!!n.search,i=r,a=S.join(e.outputDir,i),c=Yt(e.targetOrigin,i),o=`${c}${n.search}`;if(!s)return {originalPathname:i,originalFilePath:a,originalPublicUrl:c,originalPublicUrlWithSearch:o,preferQueryHashed:s};let l=S.extname(r),d=`${l?r.slice(0,-l.length):r}.${Ze(n.search)}${l||".bin"}`;return {originalPathname:i,originalFilePath:a,originalPublicUrl:c,originalPublicUrlWithSearch:o,preferQueryHashed:s,hashedPathname:d,hashedFilePath:S.join(e.outputDir,d),hashedPublicUrl:Yt(e.targetOrigin,d)}}function Yi(e,t,n,r){let s=ve(t,n,"asset",r);return s?At(e,s.toString()):null}function Xi(e,t,n,r,s){t[n]=r;try{let i=new URL(n),c=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{c.push(new URL(e.targetOrigin).origin);}catch{}for(let o of c)try{let l=new URL(o);t[l.origin+i.pathname+i.search]=r;}catch{}try{let o=(()=>{let l=new URL(r,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin);return `${l.pathname}${l.search}`})();t[i.pathname+i.search]=o;}catch{}try{let o=new URL(r,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=o;}catch{}try{let o=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=o;}catch{}}catch{}}async function Nr(e){try{return await T.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Le(e){try{return await T.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function eo(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 Br(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let n=Date.parse(t);return Number.isFinite(n)?n:null}function to(e,t){let n=Br(t),r=eo(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 no(e,t){if(!t)return;let n=Br(t);if(n===null)return;let r=await Le(e);if(!r)return;let s=new Date(n);await T.utimes(e,r.atime,s).catch(()=>{});}function Rr(e,t){let n=S.extname(e.pathname).toLowerCase(),r=t["content-type"]||"";return yi.has(n)||wi.some(s=>r.includes(s))&&!r.startsWith("image/")&&!r.includes("font")}function ro(e){try{let t=S.extname(new URL(e).pathname).toLowerCase();return t===".js"||t===".mjs"}catch{return false}}function Ue(e,t){(e.doneAssets.size%25===0||e.doneAssets.size===1||e.doneAssets.size===e.stats.assetsQueued)&&t.progress(`Asset processing progress: processed ${e.doneAssets.size}, discovered ${e.stats.assetsQueued}.`,{doneAssets:e.doneAssets.size,assetsQueued:e.stats.assetsQueued,phase:"download-assets"});}function so(e){return Ze(e.toString("base64"),40)}function io(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 oo(e,t,n){let r=e.assetVariantDigestsByOriginalPath.get(t);r||(r=new Set,e.assetVariantDigestsByOriginalPath.set(t,r)),r.add(n);}async function un(e,t,n,r,s,i,a){let c=At(e,n),o=so(r),l=c.originalFilePath,u=c.originalPublicUrlWithSearch;if(c.preferQueryHashed&&c.hashedFilePath&&c.hashedPublicUrl&&io(s,c.originalFilePath,o)){let g=Ni(e,t,n);g?(l=g.outputPath,u=g.publicUrl):(l=c.hashedFilePath,u=c.hashedPublicUrl);}Xi(e,t,n,u,c.originalPublicUrl);let d=be(l)?Buffer.from(tn(r.toString("utf8"),e,t,l),"utf8"):r,p=await Nr(l),f=false;return (p===null||!p.equals(d))&&(await Ye(l,d),f=true),i?.debug(`${f?"Saved":"Skipped unchanged"} asset output ${n}`,{phase:"download-assets",url:n,outputPath:l,bytes:d.length,wroteFile:f}),oo(s,c.originalFilePath,o),await no(l,a),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:l,publicUrl:u,wroteFile:f}}function nt(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 _e(p)?{discoveredFrom:d,discoveredFromType:"sitemap"}:B(e,p)?{discoveredFrom:d,discoveredFromType:"asset"}:Ce(p)&&!qe(p)?{discoveredFrom:d,discoveredFromType:"page"}:{discoveredFrom:d,discoveredFromType:"url"}}catch{return {discoveredFrom:d,discoveredFromType:"url"}}return {discoveredFrom:d,discoveredFromType:"url"}},a=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,c=z(e,n,a,r,"page");if(!c)return;if(!Ce(c)||_r(c)){if(B(e,c)){r.info(`Seeded/non-page URL queued as asset: ${c.toString()}`,{url:c.toString(),source:s}),H(e,t,c.toString(),r,s);return}r.reject("page",c.toString(),qe(c)?"asset/internal path cannot be page":"not page-like",s);return}let o=c.toString(),{discoveredFrom:l,discoveredFromType:u}=i();l&&!t.pageDiscoverySources.has(o)&&t.pageDiscoverySources.set(o,l),!t.donePages.has(o)&&!t.queuedPages.has(o)&&(t.queuedPages.add(o),t.pageQueue.push(o),t.stats.pagesQueued++,r.debug(`Queued discovered page ${o}`,{phase:"discovery",url:o,discoveredFrom:l,discoveredFromType:u,outputPath:ge(e,o)}),(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 H(e,t,n,r,s){let i=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,a=z(e,n,i,r,"asset");if(!a)return;if(!B(e,a)){r.reject("asset",a.toString(),"not a safe asset path/prefix",s);return}let c=a.toString();!t.doneAssets.has(c)&&!t.queuedAssets.has(c)&&(t.queuedAssets.add(c),t.assetQueue.push(c),t.stats.assetsQueued++,(t.stats.assetsQueued%100===0||t.stats.assetsQueued===1)&&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 xt(e,t,n,r,s){let i=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,a=z(e,n,i,r,"sitemap",Bn(s));if(!a)return;if(!_e(a)){r.reject("sitemap",a.toString(),"not sitemap-like",s);return}let c=a.toString();!t.doneSitemaps.has(c)&&!t.queuedSitemaps.has(c)&&(t.queuedSitemaps.add(c),t.sitemapQueue.push(c),t.stats.sitemapsQueued++,(t.stats.sitemapsQueued%10===0||t.stats.sitemapsQueued===1)&&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 ao(e){let t=de(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:et(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 co(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function uo(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 lo(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function po(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 sn(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function Wr(e,t,n,r){let s=[];await T.mkdir(t,{recursive:true});let i=await T.readdir(e,{withFileTypes:true});for(let a of i){let c=S.join(e,a.name),o=S.join(t,a.name);if(a.isDirectory()){s.push(...await Wr(c,o,n,r));continue}await Hr(c,o,n,r)&&s.push(o);}return s}async function go(e,t){try{let[n,r]=await Promise.all([T.stat(e),T.stat(t)]);if(n.size!==r.size)return !1;let[s,i]=await Promise.all([T.readFile(e),T.readFile(t)]);return s.equals(i)}catch{return false}}async function Hr(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 go(e,t)?(r.debug("Skipped unchanged post-crawl copy target",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):(await T.mkdir(S.dirname(t),{recursive:true}),await T.copyFile(e,t),true)}async function fo(e,t,n){let r=Object.entries(e.postCrawlCopyMap||{}).map(([c,o])=>({sourcePath:c.trim(),prefix:String(o||"").trim()}));if(r.length===0)return [];let s=0,i=[],a=new Set([...t.donePages].map(c=>S.resolve(ge(e,c))));n.mark("copy-extra-paths");for(let c of r){let o=c.sourcePath,l=c.prefix;if(!o||!l){n.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:o,prefixPath:l});continue}let u=Ri(o);if(!u.resolvedPath){n.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:o,alias:u.alias||"",requiredEnv:u.requiredEnv||"",prefixPath:l});continue}let d=u.resolvedPath,p=sn(l);if(!p){n.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:o,prefixPath:l});continue}let f;try{f=await T.stat(d);}catch{n.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:o,sourceAbs:d,prefixPath:l});continue}let g=S.resolve(e.outputDir,p);if(f.isDirectory()){let w=await Wr(d,g,a,n);i.push(...w),s+=w.length,w.length>0&&n.progress(`Copied static directory to export: ${d} -> /${p}`,{phase:"copy-extra-paths",sourcePath:d,targetPath:`/${p}`,copiedItems:s,changedFiles:w.length});continue}let y=S.basename(d),m=l.endsWith("/")?S.join(g,y):g;await Hr(d,m,a,n)&&(i.push(m),s++,n.progress(`Copied static file to export: ${d} -> /${sn(l.endsWith("/")?`${l}${y}`:l)}`,{phase:"copy-extra-paths",sourcePath:d,targetPath:`/${sn(l.endsWith("/")?`${l}${y}`:l)}`,copiedItems:s}));}return n.endMark("copy-extra-paths",{mappedSources:r.length,copiedItems:s}),i}function rt(e,t,n,r,s){let i=new Set,a=de(n).replace(/\\\//g,"/"),c=s==="page-html"?lo(a):a,o=po(t,s);if(o){for(let u of uo(c)){let d=z(e,u,t,r,`${s}:css-url`);d&&B(e,d)&&i.add(d.toString());}for(let u of c.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let d=z(e,u[1],t,r,`${s}:css-import`);d&&B(e,d)&&i.add(d.toString());}}if(o||s==="page-html")for(let u of c.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let d=z(e,u[1],t,r,`${s}:xml-stylesheet`);d&&B(e,d)&&i.add(d.toString());}let l=new RegExp(`(?:https?:)?//[^\\s'"<>\\);]+\\.${nn}(?:\\?[^\\s'"<>\\);]*)?|(?<!\\.)/[^\\s'"<>\\);]+\\.${nn}(?:\\?[^\\s'"<>\\);]*)?`,"gi");if(s==="page-html")for(let u of a.matchAll(l)){let d=u[0].startsWith("//")?`${new URL(e.sourceOrigin).protocol}${u[0]}`:u[0];if(cn(d)){r.ignore(`${s}:serialized-url`,d,"looks like JavaScript/code fragment",t);continue}let p=z(e,d,t,r,`${s}:serialized-url`);p&&B(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"&&ro(t))for(let u of pr(a)){if(cn(u)||!/\.(?:js|mjs)(?:[?#]|$)/i.test(u))continue;let d=z(e,u,t,r,`${s}:relative-asset`);d&&B(e,d)&&i.add(d.toString());}return [...i]}function mo(e,t,n,r){let s=new Set,i=de(n);for(let a of i.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let c=a[1],o=z(e,c,t,r,"page-link");o&&(jr(e,o)||Ce(o)&&!qe(o)&&!B(e,o)&&s.add(o.toString()));}return [...s]}async function xr(e,t,n,r,s,i,a=false,c=[]){let o=new Set(c),l=0,u=new Map,d=(p,f)=>{let g=[f],y=new Set;for(;g.length>0;){let m=g.pop();if(m===p)return true;y.has(m)||(y.add(m),g.push(...u.get(m)??[]));}return false};for(;n.sitemapQueue.length>0;){let p=n.sitemapQueue.shift();n.queuedSitemaps.delete(p);let f=ve(p,r,"sitemap","sitemap-queue");if(!f)continue;let g=f.toString();if(n.doneSitemaps.has(g))continue;n.doneSitemaps.add(g),r.sitemap(`Fetching sitemap ${g}`,{url:g});let y=true;try{let m=await t.get(g,{timeout:6e4});if(y=!1,!m.ok()){if(r.skip("sitemap",g,m.status()),a&&!o.has(g))throw new Error(`Required child content-sync sitemap returned HTTP ${m.status()}: ${g}`);continue}let h=await m.body(),w=m.url()||g,v=ve(w,r,"sitemap-response",g);if(!v)continue;let x=v.toString();n.successfulSitemaps.add(g),n.successfulSitemaps.add(x),o.has(g)&&(n.resolvedSitemapRoots.add(x),l+=1);let j=await un(e,n.assetMap,x,h,n,r);X(s,e,j.outputPath),xe(s,j.outputPath);let U=h.toString("utf8");/<sitemapindex(?:\s|>)/i.test(U)?n.sitemapIndexUrls.add(x):n.sitemapLeafUrls.add(x);let $=rt(e,x,U,r,"sitemap");for(let q of $)H(e,n,q,r,x);let C=[];for(let q of ao(U)){let R=z(e,q.loc,x,r,"sitemap-loc",!0);if(!R){if(a)throw new Error(`Content-sync sitemap contains an inadmissible location: ${q.loc}`);continue}if(_e(R)){if(d(x,R.toString()))throw new Error(`Sitemap index cycle detected: ${x} -> ${R.toString()}`);if(u.has(x)||u.set(x,new Set),u.get(x).add(R.toString()),C.push(R.toString()),a&&n.doneSitemaps.has(R.toString())&&!n.successfulSitemaps.has(R.toString()))throw new Error(`Required child content-sync sitemap was not resolved: ${R.toString()}`);xt(e,n,R.toString(),r,x);}else if(a){if(Ce(R)&&!B(e,R)){let M=i.requiredUrls.has(R.toString()),b=i.manifest.pages[R.toString()],A=!!b&&!!await Le(b.outputPath);if(!M&&!A)throw new Error(`Content-sync sitemap coverage is incomplete for ${R.toString()}.`)}r.ignore("sitemap-loc",R.toString(),"content-sync sitemap-only traversal does not enqueue urlset locations",x);}else B(e,R)?H(e,n,R.toString(),r,x):Ce(R)?(q.lastmod&&(n.sitemapLastmodByPage[R.toString()]=q.lastmod),nt(e,n,R.toString(),r,x)):r.reject("sitemap-loc",R.toString(),"not page/sitemap/asset-like",x);}i.trackManifest&&(i.manifest.assets[x]={url:x,outputPath:j.outputPath,isText:!0,contentType:m.headers()["content-type"]??"application/xml",changeToken:null,tokenSource:null,discoveredAssets:[...new Set([...$,...C])],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,unreferencedRuns:0,rewriteComplete:!1},await Pe(e,i));}catch(m){r.error(`Failed sitemap ${g}`,{url:g,error:String(m)});let h=a&&o.has(g)&&y;if(a&&!h)throw m}}if(a&&o.size>0&&l===0)throw new Error(`None of the configured content-sync sitemap roots could be resolved: ${[...o].join(", ")}`)}async function ho(e,t,n,r,s,i,a){let c=z(e,r,e.sourceOrigin,s,"asset-fetch");if(!c||!B(e,c))return;let o=c.toString();if(n.doneAssets.has(o))return;let l=i.enabled||i.strictTargeted?i.previousManifest.assets[o]:void 0,u=i.trackManifest?await vt(e,t,i,o,s):null,d=u?.token??null,p=gr(l?.changeToken,u),f=i.strictTargeted&&(!u?.supported||!u.token)&&fr(e.sourceOrigin,o),g=i.strictTargeted?i.manifest.assets[o]:void 0;if(g?.lastSeenRunId===i.runId&&await Le(g.outputPath)){n.doneAssets.add(o);for(let m of g.discoveredAssets||[])H(e,n,m,s,o);X(a,e,g.outputPath),g.isText&&xe(a,g.outputPath),s.info(`Resumed completed content-sync asset ${o}`,{url:o,source:"content-sync-checkpoint"}),Ue(n,s);return}if(l&&(p||f)&&await Le(l.outputPath)){i.manifest.assets[o]={...l,changeToken:d,tokenSource:u?.tokenSource??l.tokenSource,discoveredAssets:[...l.discoveredAssets||[]],lastSeenRunId:i.runId,unreferencedRuns:0},delete i.manifest.pages[o],n.doneAssets.add(o);for(let m of l.discoveredAssets||[])H(e,n,m,s,o);s.info(`Reused unchanged trusted asset ${o}.`,{url:o,tokenSource:u?.tokenSource??"unknown",phase:"download-assets",source:p?"asset-change-token-match":"content-sync-release-fingerprint"}),Ue(n,s);return}let y=(m,h={})=>{if(!l||i.strictTargeted)return false;i.manifest.assets[o]={...l,discoveredAssets:[...l.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,unreferencedRuns:0},delete i.manifest.pages[o],n.doneAssets.add(o);for(let w of l.discoveredAssets||[])H(e,n,w,s,o);return s.warn(`Keeping previous incremental asset ${o} after fetch issue.`,{url:o,reason:m,preservedFromPreviousManifest:true,...h,phase:"download-assets"}),Ue(n,s),true};s.asset(`Fetching asset ${o}`,{url:o});try{let m=je(e,n.assetMap,o),h=m?await Le(m):null;if(m&&h)try{let M=await W(`fetch asset headers ${o}`,6e4,()=>t.head(o,{timeout:6e4})),b=M.headers();if(M.ok()&&to(h,b)){let A=await Nr(m);if(A!==null){let P=M.url()||o,E=ve(P,s,"asset-response",o);if(!E)return;let D=E.toString(),L=await un(e,n.assetMap,D,A,n,s,b);L.wroteFile&&(X(a,e,L.outputPath),be(L.outputPath)&&xe(a,L.outputPath)),n.doneAssets.add(o),s.info(`Reused existing asset ${o} based on response headers.`,{url:o,filePath:m,lastModified:b["last-modified"]||"",contentLength:b["content-length"]||"",phase:"download-assets"}),Ue(n,s);let Z=Rr(c,b),te=l?.discoveredAssets?[...l.discoveredAssets]:[];if(Z||l?.isText){let ce=A.toString("utf8"),F=rt(e,D,ce,s,"asset:cached");(F.length>0||!l)&&(te=F);for(let Ae of te)H(e,n,Ae,s,D);}if(i.trackManifest){let ce=Z||!!l?.isText;i.manifest.assets[o]={url:o,outputPath:L.outputPath,isText:ce,contentType:on(b)||l?.contentType||null,changeToken:u?.supported?u.token:null,tokenSource:u?.supported?u.tokenSource??null:null,discoveredAssets:te,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,unreferencedRuns:0,rewriteComplete:!ce},delete i.manifest.pages[o],(i.enabled||i.strictTargeted)&&ce&&await Pe(e,i);}return}}}catch{}let w=await W(`fetch asset ${o}`,6e4,()=>t.get(o,{timeout:6e4}));if(!w.ok()){if(y(`http-${w.status()}`,{status:w.status()}))return;if(i.strictTargeted)throw new Error(`Required content-sync asset returned HTTP ${w.status()}: ${o}`);s.skip("asset",o,w.status());return}let v=await W(`read asset response ${o}`,6e4,()=>w.body()),x=w.url()||o,j=ve(x,s,"asset-response",o);if(!j)return;let U=j.toString(),$=w.headers(),C=await un(e,n.assetMap,U,v,n,s,$);C.wroteFile&&(X(a,e,C.outputPath),be(C.outputPath)&&xe(a,C.outputPath)),n.doneAssets.add(o),Ue(n,s);let q=Rr(c,$),R=[];if(q){let M=v.toString("utf8");R=rt(e,U,M,s,`asset:${S.extname(c.pathname).toLowerCase()||$["content-type"]||"unknown"}`);for(let b of R)H(e,n,b,s,U);}i.trackManifest&&(i.manifest.assets[o]={url:o,outputPath:C.outputPath,isText:q,contentType:on($),changeToken:u?.supported?u.token:null,tokenSource:u?.supported?u.tokenSource??null:null,discoveredAssets:R,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,unreferencedRuns:0,rewriteComplete:!q},delete i.manifest.pages[o],(i.enabled||i.strictTargeted)&&q&&await Pe(e,i));}catch(m){if(y("fetch-error",{error:String(m)}))return;if(s.error(`Failed asset ${o}`,{url:o,error:String(m)}),i.strictTargeted)throw m}finally{n.doneAssets.has(o)||(n.doneAssets.add(o),Ue(n,s));}}async function wo(e,t,n,r,s,i){let a=Math.max(1,Number(e.assetDownloadConcurrency||e.concurrency||1)),c=Array.from({length:a},async()=>{for(;n.assetQueue.length>0;){let o=n.assetQueue.shift();o&&(n.queuedAssets.delete(o),await ho(e,t,n,o,r,s,i));}});await Promise.all(c);}function yo(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function pe(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function Ct(e){return Math.max(15e3,Math.min(6e4,pe(e)))}function So(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function fn(e){return e.stats.pagesCompleted}function zr(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 bo(e,t,n){let r=zr(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 W(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 ${yo(t)}.`));},t);})])}finally{r!==void 0&&globalThis.clearTimeout(r);}}async function Po(e,t){let n=So(e);await t.evaluate(async r=>{await new Promise(s=>{let i=0,a=700,c=Date.now(),o=()=>{window.clearInterval(l),window.scrollTo(0,0),s();},l=window.setInterval(()=>{if(Date.now()-c>=r.maxDurationMs){o();return}window.scrollBy(0,a),i+=a;let u=document.body?.scrollHeight||0,d=document.documentElement?.scrollHeight||0,p=Math.max(u,d);i>=p+window.innerHeight&&o();},120);});},{maxDurationMs:n});}async function vo(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 Po(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function Co(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 Ro(e,t){return e.noJavaScriptRenderPathPrefixes.some(n=>dn(t,n))}async function xo(e,t,n,r,s=true){let i=new Set;if(s){let c=await t.evaluate(()=>{let o=new Set,l=["href","src","poster","data-src","data-lazy-src","data-original","data-bg","data-background","data-href"],u=new Set,d=["srcset","data-srcset","data-lazy-srcset"],p=f=>{f.querySelectorAll("*").forEach(g=>{for(let m of l){let h=g.getAttribute(m);h&&o.add(h);}for(let m of d){let h=g.getAttribute(m);h&&h.split(",").forEach(w=>{let v=w.trim().split(/\s+/)[0];v&&o.add(v);});}let y=g.getAttribute("style");y&&u.add(y),g.shadowRoot&&p(g.shadowRoot);});};return p(document),{attrs:[...o],styles:[...u]}});for(let o of c.attrs)for(let l of co(o)){let u=z(e,l,n,r,"dom-attr");u&&B(e,u)&&i.add(u.toString());}for(let o of c.styles)for(let l of rt(e,n,o,r,"dom-style"))i.add(l);}let a=await t.content();for(let c of rt(e,n,a,r,"page-html"))i.add(c);return [...i]}async function Ir(e,t,n,r,s){let i=ge(e,t);await Ye(i,n,"utf8");let a=await T.stat(i);s?.debug(`Saved page output ${t}`,{phase:"save-pages",url:t,outputPath:i,bytes:a.size}),r.stats.pagesSaved++;let c=Math.min(r.stats.pagesQueued,fn(r)+1);s&&(r.stats.pagesSaved%10===0||r.stats.pagesSaved===1)&&s.progress(`Page progress: processed ${c}, rendered ${r.stats.pagesRendered}, saved ${r.stats.pagesSaved}, discovered ${r.stats.pagesQueued}.`,{donePages:c,claimedPages:r.donePages.size,pagesRendered:r.stats.pagesRendered,pagesSaved:r.stats.pagesSaved,pagesQueued:r.stats.pagesQueued,pageQueue:r.pageQueue.length,phase:"save-pages"});}function Io(e){let t=fn(e);return t%5===0||t===1||t===e.stats.pagesQueued}function Ao(e,t){let n=fn(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 To(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 ko(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 To(r),r}async function $o(e,t,n,r,s,i,a,c){let o=await chromium.launch({headless:true}),l=zr(o);l.pid!==null&&n.debug(`Launched crawl worker browser PID ${l.pid}`,{browserPid:l.pid});try{for(;t.pageQueue.length>0&&!(e.maxPages>0&&t.donePages.size>=e.maxPages);){let u=t.pageQueue.shift();if(!u)break;t.queuedPages.delete(u);let d=null,p=null,f=[],g=new Set;try{let y=ve(u,n,"page","page-queue");if(!y)continue;let m=y.toString();if(u=m,t.queuedPages.delete(u),t.donePages.has(u))continue;t.donePages.add(u),i.enabled&&i.seenPages.add(u);let h=gn(e,u),w=Ro(e,y.pathname);if(!Ce(y)||B(e,y)||qe(y)){if(B(e,y)){n.info(`Worker redirected non-page URL to asset queue: ${u}`,{url:u,source:"worker-guard"}),H(e,t,u,n,"worker-guard");continue}n.reject("page",u,"guard rejected non-page URL before rendering","worker");continue}let v=i.strictTargeted?i.manifest.pages[u]:void 0;if(v?.lastSeenRunId===i.runId&&await Le(v.outputPath)){i.seenPages.add(u);for(let P of v.discoveredAssets||[])H(e,t,P,n,u);X(a,e,v.outputPath),xe(a,v.outputPath),n.info(`Resumed completed content-sync page ${u}`,{url:u,source:"content-sync-checkpoint"});continue}let x=await Di(e,s,t,i,u,n);if(i.enabled&&r!=="single-url"&&r!=="content-sync"){let P=i.manifest.pages[u];if(x.action==="reuse"&&P){for(let E of P.discoveredAssets)H(e,t,E,n,u);for(let E of P.discoveredPages)nt(e,t,E,n,u);P.lastSeenRunId=i.runId,P.sitemapLastmod=et(t.sitemapLastmodByPage[u])??P.sitemapLastmod,x.changeToken?.supported&&(P.changeToken=x.changeToken.token,P.tokenSource=x.changeToken.tokenSource??P.tokenSource),n.info(`Incremental reuse skipped unchanged page ${u}`,{url:u,mode:"incremental",reason:x.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}d=await W(`create page context ${u}`,pe(e),()=>ko(o,e,w)),p=await W(`create page ${u}`,pe(e),()=>d.newPage()),f=await d.cookies();let j=!1,U=new Set;await p.route("**/*",async P=>{let E=P.request();try{let D=z(e,E.url(),e.sourceOrigin,n,"network-request");D&&B(e,D)&&(U.add(D.toString()),H(e,t,D.toString(),n,u));}catch{}if(E.isNavigationRequest()&&E.frame()===p.mainFrame())try{let D=new URL(E.url()),L=new URL(m);if(D.hash="",L.hash="",D.href===L.href){if(j){n.warn(`Blocked same-page navigation/reload for ${u}`,{url:u,requestUrl:E.url()}),await P.abort("aborted");return}j=!0;}}catch{}await P.continue();}),p.on("response",P=>{try{let D=z(e,P.url(),e.sourceOrigin,n,"network-response");D&&B(e,D)&&(U.add(D.toString()),H(e,t,D.toString(),n,u));}catch{}let E=P.headerValues("set-cookie").then(D=>{for(let L of D)c.add(wr(L,P.url()));}).catch(()=>{}).then(()=>{});g.add(E),E.finally(()=>g.delete(E));}),n.page(`Rendering ${u}`,{url:u});let $=null,C=null;try{if($=await p.goto(u,{waitUntil:"domcontentloaded",timeout:e.navigationTimeoutMs}),$&&$.ok())try{C=await W(`read response body ${u}`,pe(e),()=>$.text());}catch{C=null;}}catch(P){n.warn(`Navigation issue for ${u}; saving current DOM if available`,{url:u,error:String(P)});}if(r==="content-sync"&&$){let P=ve($.url(),n,"content-sync-final-response",u)?.toString();if(P&&P!==m){if(i.deleteOnMissingUrls.has(u)){await ln(e,i,a,u,i.deleteOnMissingUrls),n.info(`Removed stale content-sync archive route redirected to ${P}`,{url:u,finalResponseUrl:P,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${u} -> ${P}`)}}if(h){let P=$?.status()??null;if(P!==404){n.error(`Generated 404 request path returned unexpected status for ${u}`,{url:u,expectedStatus:404,status:P,requestPath:e.generated404RequestPath});continue}n.info(`Capturing rendered 404 page for ${u}`,{url:u,status:P,outputPath:ge(e,u)});}else if($&&!$.ok()){if(r==="content-sync"&&($.status()===404||$.status()===410)&&i.deleteOnMissingUrls.has(u)){await ln(e,i,a,u,i.deleteOnMissingUrls),n.info(`Removed stale content-sync archive page ${u}`,{url:u,status:$.status(),source:"content-sync-tombstone"}),await p.close();continue}if(r==="content-sync")throw new Error(`Required content-sync route returned HTTP ${$.status()}: ${u}`);n.skip("page",u,$.status(),t.pageDiscoverySources.get(u)),await p.close();continue}w?(n.info(`Rendering without JS execution for ${u}`,{url:u,mode:"no-js"}),await W(`wait for rendered page ${u}`,pe(e),()=>Co(e,p))):await W(`wait for rendered page ${u}`,pe(e),()=>vo(e,p)),t.stats.pagesRendered++;let q=await W(`extract rendered assets ${u}`,pe(e),()=>xo(e,p,m,n,!w));for(let P of q)H(e,t,P,n,u);let R=[...new Set([...q,...U])],M=C??await W(`capture rendered html ${u}`,pe(e),()=>p.content()),b=r!=="single-url"&&r!=="content-sync"&&!h?mo(e,u,M,n):[];if(r!=="single-url"&&r!=="content-sync"&&!h)for(let P of b)nt(e,t,P,n,u);await Ir(e,u,M,t,n);let A=ge(e,u);if(X(a,e,A),xe(a,A),i.trackManifest){let P=$?.headers();i.manifest.pages[u]={url:u,outputPath:A,contentType:on(P),changeToken:x.changeToken?.supported?x.changeToken.token:null,tokenSource:x.changeToken?.supported?x.changeToken.tokenSource??null:null,sitemapLastmod:et(t.sitemapLastmodByPage[u])??null,discoveredPages:b,discoveredAssets:R,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},(i.enabled||i.strictTargeted)&&await Pe(e,i);}}catch(y){if(i.strictTargeted)throw n.error(`Failed required content-sync page ${u}`,{url:u,error:String(y)}),y;try{let m=p?await W(`capture partial html ${u}`,pe(e),()=>p.content()):"";if(m&&m.trim()){await Ir(e,u,m,t,n);let h=ge(e,u);if(X(a,e,h),xe(a,h),i.trackManifest){let w=i.manifest.pages[u]??i.previousManifest.pages[u];i.manifest.pages[u]={url:u,outputPath:h,contentType:w?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:et(t.sitemapLastmodByPage[u])??w?.sitemapLastmod??null,discoveredPages:w?.discoveredPages?[...w.discoveredPages]:[],discoveredAssets:w?.discoveredAssets?[...w.discoveredAssets]:[],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},(i.enabled||i.strictTargeted)&&await Pe(e,i);}n.warn(`Saved partial DOM for ${u}`,{url:u,error:String(y)});}}catch(m){n.error(`Could not save partial DOM for ${u}`,{url:u,error:String(m)});}n.error(`Failed page ${u}`,{url:u,error:String(y)});}finally{if(g.size>0&&await Promise.allSettled([...g]),d)try{let y=await d.cookies();c.addAll(yr(f,y));}catch{}t.stats.pagesCompleted++,Io(t)&&Ao(t,n),p&&await W(`close page ${u}`,Ct(e),()=>p.close()).catch(y=>{n.warn(`Timed out while closing page ${u}`,{url:u,browserPid:l.pid,error:String(y)});}),d&&await W(`close page context ${u}`,Ct(e),()=>d.close()).catch(y=>{n.warn(`Timed out while closing page context for ${u}`,{url:u,browserPid:l.pid,error:String(y)});});}}}finally{await W("close worker browser",Ct(e),()=>o.close()).catch(u=>(n.warn("Timed out while closing crawl worker browser",{browserPid:l.pid,error:String(u)}),bo(o,n,"browser.close timeout")));}}async function Eo(e){try{let t=await T.readFile(e),r=(e.endsWith(".gz")?gunzipSync(t):t).toString("utf8").trim();if(!r)return [];try{let s=JSON.parse(r);if(Array.isArray(s))return s;if(s&&typeof s=="object")return [s]}catch{return r.split(/\r?\n/).map(s=>s.trim()).filter(Boolean).map(s=>{try{let i=JSON.parse(s);return i&&typeof i=="object"?i:null}catch{return null}}).filter(s=>s!==null)}return []}catch{return []}}function Ar(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function Mo(e){let t=String(e?.job?.command||"").trim(),n=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:n!=="incremental"}function Do(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 Qr(e){try{let t=await T.readFile(e,"utf8"),n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function Tr(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function Fo(e,t){let n=Array.isArray(t?.artifacts)?t.artifacts.filter(r=>String(r?.role||"").trim()==="errors"&&String(r?.storedFileName||"").trim()!=="").sort((r,s)=>Tr(r)-Tr(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 kr(e){let t=await Qr(S.join(e,"job.json"));for(let n of Fo(e,t)){let r=await Eo(n);if(r.length>0)return r}return []}async function Oo(e){let t=S.join(e.logDir,"archive"),n;try{n=await T.readdir(t);}catch{return ""}let r="",s=0;for(let i of n){let a=S.join(t,i);if(!(await T.stat(a).catch(()=>null))?.isDirectory())continue;let o=await Qr(S.join(a,"job.json"));if(!Mo(o))continue;let l=Do(o);l>=s&&(s=l,r=a);}return r}async function Uo(e){let t=await Oo(e),n=t!==""?await kr(t):await kr(e.logDir),r=new Set;for(let s of n)if(Ar(s.error)||Ar(s.message)){let i=s.url;typeof i=="string"&&i&&r.add(i);}return [...r]}async function Lo(e){let t=[];for(let n of e)if(n.startsWith("@")){let r=n.slice(1),s=await T.readFile(r,"utf8");t.push(...s.split(/\r?\n/).map(i=>i.trim()).filter(i=>i&&!i.startsWith("#")));}else t.push(n);return t}async function jo(e){if(!e)throw new Error("Content-sync crawl requires an immutable impact plan.");let t=JSON.parse(await T.readFile(e,"utf8"));return Je(t),t}function qo(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(/\/+$/,""),a=n.pathname.slice(i.length).replace(/^\/+/,""),c=String(r.paginationBase||"page").replace(/^\/+|\/+$/g,"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return n.pathname.startsWith(`${i}/`)&&new RegExp(`^${c}/\\d+/?$`).test(a)})}function Pt(e,t,n){let r=n==="page"?ge(e,t):At(e,t).originalFilePath;return Se(e.outputDir,r)}async function ln(e,t,n,r,s){let i=t.manifest.pages[r];if(!i)return;let a=Se(e.outputDir,i.outputPath);if(!a)throw new Error(`Manifest-owned page path escaped output root: ${r}`);let c=S.resolve(i.outputPath);Object.entries(t.manifest.pages).some(([l,u])=>l!==r&&!s.has(l)&&S.resolve(u.outputPath)===c)||(await T.rm(i.outputPath,{force:true}),n.deletedFiles.add(a)),delete t.manifest.pages[r];}function _o(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 a of i?.discoveredAssets??[])try{_e(new URL(a))&&r.push(a);}catch{}}return n}async function No(e,t,n,r,s){let i=_o(n.previousManifest,s);for(let a of i){if(t.successfulSitemaps.has(a))continue;let c=n.previousManifest.assets[a];if(!c)continue;let o=Se(e.outputDir,c.outputPath);if(!o)throw new Error(`Manifest-owned sitemap path escaped output root: ${a}`);await T.rm(c.outputPath,{force:true}),r.deletedFiles.add(o),delete n.manifest.assets[a];}await Pe(e,n);}async function Bo(e){try{let t=await T.readFile(S.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function Wo(e){let t=["crawl.log.jsonl","current-crawl-event.json","rejected.jsonl","ignored.jsonl","skipped-http.jsonl","errors.jsonl","timings.jsonl","rejected.json","ignored.json","skipped-http.json","errors.json","timings.json"];await T.mkdir(e,{recursive:true}),await Promise.all(t.map(async n=>{try{await T.unlink(S.join(e,n));}catch(r){if(r.code!=="ENOENT")throw r}}));}function $r(e,t,n,r,s){let i=z(e,n,e.sourceOrigin,r,"manual-url");i&&(_e(i)?xt(e,t,i.toString(),r,s):B(e,i)?H(e,t,i.toString(),r,s):Ce(i)?nt(e,t,i.toString(),r,s):r.reject("manual-url",i.toString(),"not page/sitemap/asset-like",s));}async function Jr(e=process.argv.slice(2)){let t=[],n=await se(void 0,{onRemotePublisherConfigDiagnostic:b=>{t.push(b);}}),r=Ke(n.sitemapPaths),s=t.at(-1)??null,i=bi(e),a=i.mode==="content-sync"?await jo(i.contentSyncPlanPath):null;if(i.resumeRewrite&&i.mode!=="full")throw new Error("--resume-rewrite is only supported for full crawl/publish jobs.");let c=[];i.mode==="retry-timeouts"&&(c=await Uo(n)),i.mode==="single-url"&&(c=await Lo(i.urls)),a&&(c=[...a.directRenderUrls,...a.archiveFamilyUrls]);let o=i.crawlMode==="incremental"&&i.mode==="full",l=o&&typeof n.subscriptionType=="string"&&n.subscriptionType.trim()!=="";if(a&&n.subscriptionType!=="PROFESSIONAL"&&n.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let u=(i.mode==="full"||i.mode==="single-url"||i.mode==="content-sync")&&!i.resumeRewrite,d=i.mode!=="full"||i.resumeRewrite||l,p=d?await Bo(n):{},f=l||i.mode==="single-url"||i.mode==="content-sync"?await Ai(n):Fr(),g=new Set(c),y=new Set;if(a){for(let b of a.archiveFamilies)if(b.foundPosts===0)for(let A of b.pageUrls)y.add(A);for(let b of Object.keys(f.pages))qo(b,a)&&!g.has(b)&&(c.push(b),y.add(b));}let m={enabled:l,trackManifest:u,manifest:an(f),previousManifest:an(f),runId:a?.jobId??`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve(),strictTargeted:!!a,requiredUrls:g,deleteOnMissingUrls:y};await Wo(n.logDir);let h=new ht(n.logDir,n.logLevel);if(s){let b={status:s.status,virtualAssetBaseUrl:s.virtualAssetBaseUrl,subscriptionType:s.subscriptionType??null,error:s.error,requests:s.requests,source:"remote-publisher-config"};s.status==="loaded"&&s.subscriptionType?h.info("Loaded remote WP Suite publisher configuration.",b):h.warn("Remote WP Suite publisher configuration is unavailable or has no active subscription type.",b);}if(o&&!l){let b="Incremental crawl requires an active remote publisher subscription; refusing to fall back to a destructive full crawl.";throw h.error(b,{requestedMode:i.crawlMode,subscriptionType:n.subscriptionType??null,source:"incremental-subscription-guard"}),await h.flush(),new Error(b)}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,successfulSitemaps:new Set,resolvedSitemapRoots:new Set,sitemapIndexUrls:new Set,sitemapLeafUrls:new Set,sitemapLastmodByPage:{},assetMap:{...p},assetVariantDigestsByOriginalPath:new Map,stats:{pagesQueued:0,pagesRendered:0,pagesCompleted:0,assetsQueued:0,sitemapsQueued:0,assetsSaved:0,pagesSaved:0}},v=Ii(),x=new yt,j=Pi();if(j&&!i.resumeRewrite&&await St(j,x.artifact()),await De(n),await Zn(n,{startedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir)}),d||await T.rm(n.outputDir,{recursive:true,force:true}),await T.mkdir(n.outputDir,{recursive:true}),a){let b=new Set([...a.deleteUrls,...m.deleteOnMissingUrls]);for(let A of a.deleteUrls)await ln(n,m,v,A,b);}if(i.resumeRewrite)h.info("Resuming final rewrite from existing output.",{phase:"rewrite-text",mode:i.mode,crawlMode:i.crawlMode});else {let b=await request.newContext({ignoreHTTPSErrors:n.ignoreHttpsErrors});try{if(h.mark("discovery"),i.mode==="full"?(r.forEach(P=>xt(n,w,P,h)),await xr(n,b,w,h,v,m),n.seedPaths.forEach(P=>$r(n,w,P,h,"seed-path")),n.generated404RequestPath&&nt(n,w,n.generated404RequestPath,h,"generated-404-request-path")):(c.forEach(P=>$r(n,w,P,h,"cli")),a?.sitemapUrls.forEach(P=>xt(n,w,P,h,"content-sync-impact")),await xr(n,b,w,h,v,m,i.mode==="content-sync",a?.sitemapUrls??[]),a&&await No(n,w,m,v,a.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:i.mode,crawlMode:i.crawlMode,queuedPages:w.pageQueue.length,queuedAssets:w.assetQueue.length,queuedSitemaps:w.sitemapQueue.length}),i.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:i.mode,crawlMode:i.crawlMode,queuedPages:0,queuedAssets:0,queuedSitemaps:0}),await h.flush(),j&&await St(j,x.artifact());return}h.mark("render-pages");let A=Array.from({length:Math.max(1,n.concurrency)},()=>$o(n,w,h,i.mode,b,m,v,x));if(await Promise.all(A),j&&await St(j,x.artifact()),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 $i(n,b,m,[...w.assetQueue],h),await wo(n,b,w,h,m,v),h.endMark("download-assets",{assets:w.doneAssets.size}),m.enabled&&n.maxPages===0&&await Oi(n,w,m,h,v),i.mode==="full"){let P=await fo(n,w,h);for(let E of P)X(v,n,E);}}finally{await W("dispose crawl request context",Ct(n),()=>b.dispose()).catch(A=>{h.warn("Timed out while disposing crawl request context",{error:String(A)});});}}m.trackManifest&&await Pe(n,m),await T.writeFile(S.join(n.outputDir,"asset-map.json"),JSON.stringify(w.assetMap,null,2),"utf8"),JSON.stringify(p,null,2)!==JSON.stringify(w.assetMap,null,2)&&X(v,n,S.join(n.outputDir,"asset-map.json"));let U=i.mode==="single-url"||i.mode==="content-sync"?Hi(n,w):m.enabled&&!i.resumeRewrite?Ui(n,m,v,p,w.assetMap):void 0;h.mark("rewrite-text");let $=i.mode==="single-url"||i.mode==="content-sync"?`Rewriting text files touched by URL crawl: 0/${U?.length??0}`:"Rewriting text files...";h.progress($,{phase:"rewrite-text",index:0,totalFiles:U?.length,changedTextFiles:0}),await Cr($);let C=Date.now(),q=await gt(n,w.assetMap,{files:U,previousAssetMap:p,onStart:({totalFiles:b,workerCount:A})=>{h.info(`Rewrite phase scanning ${b} text files.`,{phase:"rewrite-text",totalFiles:b,workerCount:A});},onProgress:async({index:b,totalFiles:A,changedTextFiles:P,file:E,changed:D})=>{D&&X(v,n,S.join(n.outputDir,E)),h.checkpoint(`Rewriting text file ${b}/${A}`,{phase:"rewrite-text",index:b,totalFiles:A,changedTextFiles:P,file:E}),h.debug(`${D?"Rewrote":"Checked unchanged"} text file ${b}/${A}: ${E}`,{phase:"rewrite-text",index:b,totalFiles:A,changedTextFiles:P,file:E,changed:D});let L=Date.now();if(!(b===1||b===A||b%50===0||L-C>=5e3))return;C=L;let te=`Rewriting text files: ${b}/${A}`;h.progress(te,{phase:"rewrite-text",index:b,totalFiles:A,changedTextFiles:P,file:E}),await Cr(te);}});m.trackManifest&&(Li(m,U),await Pe(n,m)),h.endMark("rewrite-text",{changedTextFiles:q});let R=a?[...v.deletedFiles].sort():m.enabled&&!i.resumeRewrite?await qi(n,w,m,v,h):[],M=[...new Set((U||[]).map(b=>Se(n.outputDir,S.isAbsolute(b)?b:S.join(n.outputDir,b))).filter(b=>b!==null))].sort();if(a){let b=[...v.changedFiles].sort(),A=new Set(b),P=new Set(a.directRenderUrls.map(F=>Pt(n,F,"page")).filter(F=>!!F&&A.has(F))),E=new Set(a.archiveFamilyUrls.map(F=>Pt(n,F,"page")).filter(F=>!!F&&A.has(F))),D=new Set([...w.sitemapLeafUrls].map(F=>Pt(n,F,"asset")).filter(F=>!!F&&A.has(F))),L=new Set([...w.sitemapIndexUrls].map(F=>Pt(n,F,"asset")).filter(F=>!!F&&A.has(F))),Z=new Set([...P,...E,...D,...L]),te=b.filter(F=>!Z.has(F)),ce=[...new Set([...a.directRenderUrls,...a.archiveFamilyUrls,...w.resolvedSitemapRoots,...w.sitemapLeafUrls,...w.sitemapIndexUrls,...a.deleteUrls].map(F=>{let Ae=new URL(F);return `${Ae.pathname}${Ae.search}`}))].sort();await Zt(n,{schemaVersion:2,generatedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir),runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,changedFiles:b,deletedFiles:R,rewriteTargets:M,consumerId:a.consumerId,fromSequence:a.fromSequence,toSequence:a.toSequence,impactHash:a.impactHash,resolvedSitemapUrls:[...w.resolvedSitemapRoots],uploadGroups:{assets:te,content:[...P].sort(),listings:[...E].sort(),sitemapLeaves:[...D].sort(),sitemapIndexes:[...L].reverse()},invalidationPaths:ce});}else await Zt(n,{schemaVersion:1,generatedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir),runMode:i.mode,crawlMode:i.crawlMode,fullSyncRequired:!(m.enabled&&!i.resumeRewrite),changedFiles:m.enabled&&!i.resumeRewrite?[...v.changedFiles].sort():[],deletedFiles:m.enabled&&!i.resumeRewrite?R:[],rewriteTargets:m.enabled&&!i.resumeRewrite?M:[]});await Xn(n),h.summary(i.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${q} text files.`:`Done. Rendered ${w.stats.pagesRendered} pages, processed ${w.doneSitemaps.size} sitemaps and ${w.doneAssets.size} assets.`,{mode:i.mode,crawlMode:i.crawlMode,resumeRewrite:i.resumeRewrite,...w.stats,pagesRendered:w.stats.pagesRendered,donePages:w.stats.pagesCompleted,claimedPages:w.donePages.size,doneSitemaps:w.doneSitemaps.size,doneAssets:w.doneAssets.size,changedTextFiles:q}),await h.flush();}function Ho(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 ee(e,t,n){let r=new AbortController,s=globalThis.setTimeout(()=>{r.abort(new Error(`${e} timed out after ${Ho(t)}.`));},t);try{return await n({abortController:r,httpOptions:{abortSignal:r.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(s);}}function zo(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function Tt(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 Qo(e,t){return {...e,...t??{}}}function Jo(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function Ne(e,t){let n=String(t??e.deploymentTargetOverride??"").trim();if(!zo(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:Qo(e.s3,s.s3),cloudFront:Jo(e.cloudFront,s.cloudFront)}}}var Zr="wpsuite-sha256",Yr="wpsuite-normalized-sha256",na=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,bn=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,ra=["SIGINT","SIGTERM"],Et=new Set,kt=new Map,Vr=null;function sa(e){Et.add(e);let t=false;return ()=>{t||(t=true,Et.delete(e));}}async function ia(){let e=[...Et];e.length!==0&&await Promise.allSettled(e.map(async t=>{Et.delete(t),await T.rm(t,{recursive:true,force:true});}));}function oa(){if(!(kt.size>0))for(let e of ra){let t=()=>{Vr||(Vr=ia().finally(()=>{for(let[n,r]of kt)process.off(n,r);kt.clear(),process.exit(1);}));};kt.set(e,t),process.on(e,t);}}oa();function aa(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 Xr(e){return S.normalize(e).split(S.sep).join("/")}function Kr(e,t){let n=S.relative(S.resolve(e),S.resolve(t));return !n||n.startsWith("..")||S.isAbsolute(n)?null:Xr(n)}async function ca(e,t,n){let r=aa(e.outputDir,t),s;try{s=await T.readFile(r,"utf8");}catch(u){return u.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:u instanceof Error?u.message:String(u),source:"deploy-guard"}),null)}let i;try{i=JSON.parse(s);}catch(u){return n.warn("Deploy rewrite guard disabled because the crawl manifest is invalid JSON.",{manifestPath:r,error:u instanceof Error?u.message:String(u),source:"deploy-guard"}),null}let a=new Map,c=new Map,o=0,l=0;for(let[u,d]of Object.entries(i.pages||{})){let p=String(d?.outputPath||"").trim(),f=p?Kr(e.outputDir,p):null;if(f){let g=typeof d?.contentType=="string"&&d.contentType?d.contentType:null;g&&c.set(f,g);}!p||d?.rewriteComplete===true||f&&(o++,a.has(f)||a.set(f,{kind:"page",sourceUrl:u,outputPath:S.resolve(p),relativePath:f}));}for(let[u,d]of Object.entries(i.assets||{})){let p=String(d?.outputPath||"").trim(),f=d?.isText===true,g=p?Kr(e.outputDir,p):null;if(g){let y=typeof d?.contentType=="string"&&d.contentType?d.contentType:null;y&&c.set(g,y);}!p||!f||d?.rewriteComplete===true||g&&(l++,a.has(g)||a.set(g,{kind:"asset",sourceUrl:u,outputPath:S.resolve(p),relativePath:g}));}return {manifestPath:r,byRelativePath:a,contentTypeByRelativePath:c,pendingPages:o,pendingTextAssets:l}}function ua(e){return e&&(bn.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 hn(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,n)=>n%2===1?t:ua(t)).join("")}function la(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,n)=>n%2===1?t:bn.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 Mt(e,t){return Array.isArray(e)?e.map(n=>Mt(n,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Mt(r,n)])):typeof e!="string"?e:t&&na.test(t)?la(e):bn.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?hn(e):e}function da(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function pa(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(Mt(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),a=JSON.stringify(Mt(i));return Buffer.from(a,"utf8").toString("base64")}catch{}return t}function ga(e,t){let n=e.toLowerCase();return n==="class"?t.split(/(\s+)/).map((r,s)=>s%2===1?r:hn(r)).join(""):n==="id"||n==="for"||n==="aria-controls"||n==="aria-labelledby"||n==="aria-describedby"||n==="aria-owns"||n==="aria-activedescendant"||n==="name"?hn(t):n==="href"||n==="src"?da(t):pa(n,t)}function fa(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,a,c,o)=>{let l=ga(a,o);return ` ${a}=${c}${l}${c}`});return `<${n}${s}>`})}function mn(e){let t=S.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(S.basename(e))}function $t(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function ma(e,t,n,r){let s=new Map,i,a=0;do{a++;let c=await ee(`S3 list objects page ${a} for s3://${t}/${n||""}`,3e5,({httpOptions:o})=>e.send(new ListObjectsV2Command({Bucket:t,Prefix:n||void 0,ContinuationToken:i}),o));for(let o of c.Contents||[]){if(!o.Key)continue;let l=(o.ETag||"").replace(/^"|"$/g,"").toLowerCase(),u=Number(o.Size??0);s.set(o.Key,{etag:l,size:u});}i=c.NextContinuationToken,r.debug(`Listed S3 keys page ${a}: ${s.size} keys so far`);}while(i);return s}async function ha(e,t,n,r){if(r.has(n))return r.get(n)??null;try{let s=await ee(`S3 head object ${n}`,3e5,({httpOptions:a})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),a)),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 wa(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 a=s.slice(i,i+1e3);if(a.length===0)continue;let c=await ee(`S3 delete objects batch ${Math.floor(i/1e3)+1}`,3e5,({httpOptions:o})=>e.send(new DeleteObjectsCommand({Bucket:t,Delete:{Objects:a.map(l=>({Key:l}))}}),o));if(c.Errors&&c.Errors.length>0){let o=c.Errors.map(l=>`${l.Key||"(unknown)"}: ${l.Code||"DeleteFailed"}`);throw new Error(`S3 reported ${o.length} object deletion error(s): ${o.join(", ")}`)}r.info(`Deleted batch of ${a.length} object(s).`);for(let o of a)r.debug(` deleted: ${o}`);}return s}function ya(e){return createHash("md5").update(e).digest("hex")}function Gr(e){return createHash("sha256").update(e).digest("hex")}function wn(e){return createHash("sha256").update(fa(e.toString("utf8"))).digest("hex")}async function Sa(e,t,n,r){if(r.has(n))return r.get(n)??null;try{let a=((await ee(`S3 head object metadata ${n}`,3e5,({httpOptions:c})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),c))).Metadata?.[Zr]||"").trim().toLowerCase()||null;return r.set(n,a),a}catch{return r.set(n,null),null}}async function ba(e,t,n,r,s){if(r.has(n))return r.get(n)??null;try{let a=((await ee(`S3 head object normalized metadata ${n}`,3e5,({httpOptions:c})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),c))).Metadata?.[Yr]||"").trim().toLowerCase();if(a)return r.set(n,a),a}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 a=await(await ee(`S3 get object ${n}`,3e5,({httpOptions:o})=>e.send(new GetObjectCommand({Bucket:t,Key:n}),o))).Body?.transformToByteArray(),c=a?wn(Buffer.from(a)):null;return s.set(n,c),r.set(n,c),c}catch{return s.set(n,null),r.set(n,null),null}}function Pa(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function va(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 Ca(e,t,n,r){let s=S.join(e,"asset-map.json"),i;try{i=await T.readFile(s,"utf8");}catch(o){if(o.code==="ENOENT")return;throw o}let a=JSON.parse(i);if(!a||typeof a!="object")return;let c=Object.fromEntries(Object.entries(a).map(([o,l])=>{let u=String(l??"");return t.urlRewriteMode==="absolute"&&t.targetOrigin&&n.targetOrigin&&t.targetOrigin!==n.targetOrigin&&(u=u.split(t.targetOrigin).join(n.targetOrigin)),u=va(u,r),[o,u]}));await T.writeFile(s,JSON.stringify(c,null,2),"utf8");}async function Ra(e,t,n,r,s,i){let a=e.targetOrigin!==t.targetOrigin,c=Object.keys(r).length>0;if(!n||!a&&!c)return {outputDir:e.outputDir,cleanup:async()=>{}};if(a&&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 o=S.join(S.dirname(e.outputDir),`.deploy-profile-${Pa(n)}-${Date.now()}`),l=sa(o);s.info(`Preparing deployment profile "${n}" from existing crawl output to ${o}...`);try{if(await T.rm(o,{recursive:!0,force:!0}),i){await T.mkdir(o,{recursive:!0});for(let f of i){let g=S.join(e.outputDir,f),y=S.join(o,f);await T.mkdir(S.dirname(y),{recursive:!0}),await T.copyFile(g,y);}}else await T.cp(e.outputDir,o,{recursive:!0});let u={...e,sourceOrigin:e.targetOrigin,targetOrigin:t.targetOrigin,extraReplacements:r,outputDir:o},d=1;s.info(`Rewriting text files for deployment profile "${n}"...`);let p=await gt(u,{},{files:i,onStart:({totalFiles:f,workerCount:g})=>{d=g,s.info(`Rewriting ${f} text file(s) for deployment profile "${n}" with ${g} worker(s).`);},onProgress:({index:f,totalFiles:g,changedTextFiles:y,file:m,changed:h})=>{let v=`Rewriting [${f}/${g}] ${m} (${h?"rewrote":"checked"}; ${y} changed so far)`;g<=200||f<=5||f%10===0||f===g?(s.progress(v,{file:m,index:f,totalFiles:g,changed:h,changedTextFiles:y,workerCount:d}),s.info(v)):s.debug(v);}});return await Ca(o,e,t,r),s.info(`Prepared deployment profile "${n}" in ${o} (${p} rewritten text file(s)).`),{outputDir:o,cleanup:async()=>{l(),await T.rm(o,{recursive:!0,force:!0});}}}catch(u){throw s.error(`Failed to prepare deployment profile "${n}" temporary output.`,{tempDir:o,outputDir:e.outputDir,error:u instanceof Error?u.message:String(u),...u instanceof Error&&u.stack?{stack:u.stack}:{}}),await T.rm(o,{recursive:true,force:true}).catch(()=>{}),l(),await s.flush().catch(()=>{}),u}}async function es(e=process.argv.slice(2)){let t=await se(),n=Tt(e),r=Ne(t,n),s=S.resolve(r.config.logDir||"logs"),i=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",a=i?S.join(S.resolve(i),"deploy-diff.json"):"",c=new Oe(s,"deploy.log.jsonl",r.config.logLevel??"info"),o=r.profile?.extraReplacements??{},l=async()=>{};try{let u=await Me(t);if(e.includes("--content-sync")&&u?.schemaVersion!==2)throw new Error("Content-sync deployment requires a valid schema-2 targeted deploy plan.");let p=await Yn(t);if(p)throw new Error(`Deployment blocked: the crawl started at ${p.startedAt} did not complete its final rewrite. Run a successful crawl or resume the rewrite before deploying.`);let f=await Ra(t,r.config,r.name,o,c,u?.schemaVersion===2?u.changedFiles:void 0);l=f.cleanup;let g={...r.config,outputDir:f.outputDir},y=g.s3SyncMode??"sdk-upload-delete";if(u?.schemaVersion===2&&u.deletedFiles.length>0&&y!=="sdk-upload-delete")throw new Error("Content-sync tombstones require the sdk-upload-delete S3 sync mode.");let m=u?.schemaVersion!==2&&f.outputDir!==t.outputDir&&(t.targetOrigin!==r.config.targetOrigin||Object.keys(o).length>0),h=!!u&&!u.fullSyncRequired&&!m;if(u?.schemaVersion===2&&!h)throw new Error("Content-sync deployment cannot widen into a full-output deployment.");r.name&&c.info(`Using deployment profile: ${r.name}`),c.info(`Starting deploy \u2014 s3://${g.s3.bucket}/${g.s3.prefix||""} (region: ${g.s3.region})`),c.info(`S3 sync mode: ${y}`),u&&u.fullSyncRequired?c.info("Deploy plan requests a full sync; scanning the whole output tree."):u&&m?c.info("Ignoring incremental deploy plan because deployment-profile rewrites require a full sync."):h&&c.info(`Using incremental deploy plan: ${u.changedFiles.length} changed file(s), ${u.deletedFiles.length} deleted file(s).`),c.mark("deploy");let w=new S3Client({region:g.s3.region}),v=f.outputDir===t.outputDir?await ca(t,i,c):null,x=u?.schemaVersion===2?[...u.uploadGroups.assets,...u.uploadGroups.content,...u.uploadGroups.listings,...u.uploadGroups.sitemapLeaves,...u.uploadGroups.sitemapIndexes]:u?.changedFiles??[];if(u?.schemaVersion===2){let k=[...new Set(x)],J=[...new Set(u.changedFiles)];if(k.length!==J.length||J.some(I=>!k.includes(I)))throw new Error("Content-sync deploy-plan upload groups do not cover the exact changed-file set.")}let j=h?(await Promise.all(x.map(async k=>{try{return (await T.stat(S.join(g.outputDir,k))).isFile()?k:null}catch{if(u?.schemaVersion===2)throw new Error(`Content-sync planned upload is missing: ${k}`);return null}}))).filter(k=>k!==null):await Ns(["**/*"],{cwd:g.outputDir,onlyFiles:!0,dot:!0}),U=[],$=[],C=j.filter(k=>{let J=v?.byRelativePath.get(Xr(k));if(!J)return !0;let I=$t(g.s3.prefix,k);return U.push(k),$.push(I),c.reject(J.kind,J.sourceUrl||k,"rewrite not completed; deploy upload blocked","deploy-guard",{file:k,key:I,outputPath:J.outputPath,manifestPath:v?.manifestPath}),!1}),q=new Set((h?C:j).map(k=>$t(g.s3.prefix,k)));v&&(v.pendingPages>0||v.pendingTextAssets>0)&&c.info(`Deploy rewrite guard loaded ${v.pendingPages} pending page(s) and ${v.pendingTextAssets} pending text asset(s) from crawl manifest.`,{manifestPath:v.manifestPath,pendingPages:v.pendingPages,pendingTextAssets:v.pendingTextAssets,source:"deploy-guard"}),U.length>0&&c.warn(`Deploy rewrite guard blocked ${U.length} file(s) from upload because final crawl rewrite is incomplete.`,{rejected:U.length,manifestPath:v?.manifestPath,source:"deploy-guard"}),h?c.info(`Using ${C.length} eligible planned changed file(s) from deploy plan for upload${U.length>0?` (${U.length} blocked by deploy rewrite guard)`:""}.`):c.info(`Found ${j.length} file(s) in output directory "${g.outputDir}"${U.length>0?`; ${C.length} remain eligible for upload after deploy rewrite guard filtering`:""}.`),c.progress("Deploy preflight: comparing local output with remote S3 state.",{phase:"deploy",mode:y,totalFiles:C.length,scannedFiles:j.length,rejected:U.length,deploymentProfile:r.name||"",s3Bucket:g.s3.bucket,s3Prefix:g.s3.prefix||"",targetedPlan:h,deployGuardEnabled:f.outputDir===t.outputDir});let R=0,M=0,b=0,A=[],P=[],E=[],D=[],L=[],Z=new Map,te=new Map,ce=new Map,F=new Map,Ae=new Map;h||(c.info("Listing existing S3 objects to detect unchanged files..."),Z=await ma(w,g.s3.bucket,g.s3.prefix,c),c.info(`Found ${Z.size} existing key(s) in S3.`));let cs=async k=>Z.has(k)?Z.get(k)??null:h?ha(w,g.s3.bucket,k,te):null;for(let k of C){let J=S.join(g.outputDir,k),I=$t(g.s3.prefix,k),ne=v?.contentTypeByRelativePath.get(k),We=ne&&ne!=="application/octet-stream"?ne:ta.lookup(k)||ne||"application/octet-stream",us=mn(k)?g.s3.htmlCacheControl:g.s3.assetCacheControl,N=R+M+b+1;C.length<=200||N<=5||N%10===0||N===C.length?(c.progress(`Uploading [${N}/${C.length}] ${I} (${We})`,{file:k,key:I,index:N,totalFiles:C.length,contentType:We,mode:y}),c.info(`Uploading [${N}/${C.length}] ${I} (${We})`)):c.debug(`Uploading [${N}/${C.length}] ${I} (${We})`);try{let re=await T.readFile(J),He=await cs(I),ze=null,Te=null;if(He){let Ot=re.byteLength;if(He.size===Ot){let it=He.etag.includes("-");if(He.etag!==""&&!it){let ls=ya(re);if(He.etag===ls){M++,C.length<=200||M<=5||M%25===0?(c.progress(`Skipped unchanged [${N}/${C.length}] ${I}`,{file:k,key:I,index:N,totalFiles:C.length,uploaded:R,skipped:M,failed:b,mode:y,reason:"etag-md5-match"}),c.info(`Skipped unchanged [${N}/${C.length}] ${I}`)):c.debug(`Skipped unchanged [${N}/${C.length}] ${I}`),P.push(I);continue}}ze=Gr(re);let In=await Sa(w,g.s3.bucket,I,ce);if(In&&In===ze){M++,C.length<=200||M<=5||M%25===0?(c.progress(`Skipped unchanged [${N}/${C.length}] ${I}`,{file:k,key:I,index:N,totalFiles:C.length,uploaded:R,skipped:M,failed:b,mode:y,reason:"metadata-sha256-match"}),c.info(`Skipped unchanged [${N}/${C.length}] ${I}`)):c.debug(`Skipped unchanged [${N}/${C.length}] ${I}`),P.push(I);continue}}if(mn(k)){Te=wn(re);let it=await ba(w,g.s3.bucket,I,F,Ae);if(it&&it===Te){M++,C.length<=200||M<=5||M%25===0?(c.progress(`Skipped semantically unchanged [${N}/${C.length}] ${I}`,{file:k,key:I,index:N,totalFiles:C.length,uploaded:R,skipped:M,failed:b,mode:y,reason:"normalized-html-match"}),c.info(`Skipped semantically unchanged [${N}/${C.length}] ${I}`)):c.debug(`Skipped semantically unchanged [${N}/${C.length}] ${I}`),P.push(I);continue}}}ze=ze??Gr(re),Te=Te??(mn(k)?wn(re):null),await ee(`S3 upload ${I}`,9e5,({abortController:Ot})=>new Upload({client:w,abortController:Ot,params:{Bucket:g.s3.bucket,Key:I,Body:re,ContentType:We,CacheControl:us,Metadata:{[Zr]:ze,...Te?{[Yr]:Te}:{}}}}).done()),R++,A.push(I),(R%25===0||R===C.length)&&(c.progress(`Uploaded ${R}/${C.length} file(s)\u2026`,{uploaded:R,skipped:M,failed:b,totalFiles:C.length,mode:y}),c.info(`Uploaded ${R}/${C.length} file(s)\u2026`));}catch(re){b++,E.push(I),c.error(`Failed to upload ${I}: ${re.message}`,{key:I,error:String(re)});}}if(c.info(`Upload complete: ${R} uploaded, ${M} skipped unchanged, ${$.length} rejected by guard, ${b} failed.`),E.length>0||$.length>0)throw new Error(`Deployment stopped before deletion because ${E.length} upload(s) failed and ${$.length} upload(s) were rejected.`);if(y==="sdk-upload-delete"){let k=new Set((u?.deletedFiles??[]).map(I=>$t(g.s3.prefix,I))),J=[...k].filter(I=>!q.has(I));if(!h&&(L=[...Z.keys()].filter(ne=>!q.has(ne)).filter(ne=>!k.has(ne)),L.length>0)){c.warn(`Protected ${L.length} remote-only S3 object(s) from deletion because the crawl did not provide explicit tombstones.`,{protected:L.length,source:"deploy-delete-guard"});for(let ne of L)c.debug(` protected remote-only object: ${ne}`);}D=await wa(w,g.s3.bucket,h?J:J.filter(I=>Z.has(I)),c);}else c.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion.");a&&(await T.mkdir(S.dirname(a),{recursive:!0}),await T.writeFile(a,JSON.stringify({generatedAt:new Date().toISOString(),mode:y,summary:{totalFiles:j.length,eligibleFiles:C.length,uploaded:A.length,skipped:P.length,rejected:$.length,failed:E.length,deleted:D.length,protected:L.length,...r.name?{profile:r.name}:{}},uploadedKeys:A,skippedKeys:P,rejectedKeys:$,failedKeys:E,deletedKeys:D,protectedRemoteOnlyKeys:L},null,2),"utf8")),u?.schemaVersion!==2&&await De(t),c.endMark("deploy"),await c.flush();}finally{await l().catch(()=>{});}}function Ia(e){let t=e;return t.endsWith("/")?t+="index.html":S.posix.basename(t).includes(".")||(t+="/index.html"),t}function Aa(e,t){let n=t.trim().replace(/^\/+|\/+$/g,"");if(!n)return null;let r=`/${n}`;return e===r||e.startsWith(`${r}/`)?e:`${r}${e.startsWith("/")?e:`/${e}`}`}function ts(e,t){let n=new Set;for(let r of e){let s=new URL(r,"https://content-sync.invalid");if(s.origin!=="https://content-sync.invalid")continue;let i=`${s.pathname}${s.search}`,a=Ia(s.pathname);n.add(i),n.add(`${a}${s.search}`);let c=Aa(a,t);c&&n.add(`${c}${s.search}`);}return [...n].sort()}function Ea(){let e=String(process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"").trim();return e?S.join(S.resolve(e),"content-sync-invalidation.json"):""}async function Pn(e,t){if(!e)return;await T.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await T.writeFile(n,JSON.stringify({...t,updatedAt:new Date().toISOString()},null,2),"utf8"),await T.rename(n,e);}async function Ma(e,t,n,r){if(!e)return null;try{let s=JSON.parse(await T.readFile(e,"utf8"));if(s.schemaVersion!==1||s.distributionId!==t||s.impactHash!==n||!Array.isArray(s.batches))throw new Error("Content-sync invalidation state does not match the deploy plan.");let i=s.batches.flatMap(a=>a.paths);return i.length!==r.length||i.some((a,c)=>a!==r[c])?null:s}catch(s){if(s.code==="ENOENT")return null;throw s}}function Da(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 rs(e=process.argv.slice(2)){let t=await se(),n=Tt(e),r=Ne(t,n),s=r.config,i=new Oe(s.logDir||"logs","invalidate.log.jsonl",s.logLevel??"info"),a=e.includes("--content-sync"),c=await Me(t);if(a&&c?.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 o=c?.schemaVersion===2?c.invalidationPaths:s.cloudFront.invalidationPaths.length>0?s.cloudFront.invalidationPaths:["/*"],l=c?.schemaVersion===2?ts(o,s.s3.prefix||""):o;if(c?.schemaVersion===2&&l.some(g=>g==="/*"))throw new Error("Content-sync cannot use a whole-distribution invalidation.");if(l.length===0){i.info("The targeted deploy plan has no CloudFront paths to invalidate."),await i.flush();return}let u=s.cloudFront.distributionId,d=new CloudFrontClient({region:"us-east-1",maxAttempts:5});if(i.mark("invalidate"),c?.schemaVersion!==2){let g=`smartcloud-static-publisher-${Date.now()}`;await ee(`CloudFront invalidation for distribution ${u}`,3e5,({httpOptions:y})=>d.send(new CreateInvalidationCommand({DistributionId:u,InvalidationBatch:{CallerReference:g,Paths:{Quantity:l.length,Items:l}}}),y)),i.endMark("invalidate"),await i.flush();return}let p=Ea(),f=await Ma(p,u,c.impactHash,l);if(!f){let g=createHash("sha256").update(JSON.stringify(l)).digest("hex");f={schemaVersion:1,distributionId:u,impactHash:c.impactHash,updatedAt:new Date().toISOString(),batches:Da(l).map((y,m)=>({index:m,callerReference:`wpsuite-content-sync-${c.impactHash.slice(0,24)}-${g.slice(0,24)}-${m}`,paths:y,invalidationId:null,status:"pending"}))},await Pn(p,f);}for(let g of f.batches){if(!g.invalidationId){let y=await ee(`CloudFront targeted invalidation batch ${g.index+1}`,3e5,({httpOptions:h})=>d.send(new CreateInvalidationCommand({DistributionId:u,InvalidationBatch:{CallerReference:g.callerReference,Paths:{Quantity:g.paths.length,Items:g.paths}}}),h)),m=String(y.Invalidation?.Id||"").trim();if(!m)throw new Error("CloudFront did not return an invalidation ID.");g.invalidationId=m,g.status="created",await Pn(p,f);}await waitUntilInvalidationCompleted({client:d,maxWaitTime:900,minDelay:2,maxDelay:15},{DistributionId:u,Id:g.invalidationId}),g.status="completed",await Pn(p,f),i.info(`CloudFront invalidation batch ${g.index+1}/${f.batches.length} completed.`,{invalidationId:g.invalidationId,pathCount:g.paths.length});}i.endMark("invalidate"),await i.flush();}function Ft(e){let t=new URL(e);return t.hash="",t.href}function ss(e,t,n){let r=new Set([...t].map(o=>Ft(o))),s=new Map,i=new Map,a=o=>{s.set(Ft(o),o);},c=o=>{if(!o)return;let l=Ft(o);s.has(l)||i.set(l,o);};for(let o of e.deleteUrls)a(o);for(let o of e.archiveFamilies)if(o.foundPosts===0)for(let l of o.pageUrls)r.has(Ft(l))||a(l);c(e.directRenderUrls[0]);for(let o of e.archiveFamilies)c(o.pageUrls[0]),c(o.pageUrls.at(-1));for(let o of n)c(o);return {expectedAvailable:[...i.values()],expectedMissing:[...s.values()]}}var os=["claimed","impact-planned","rendered","deployed","invalidated","verified","acknowledged"];function Rn(){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 Be(e,t){return os.indexOf(e)>=os.indexOf(t)}async function me(e,t,n,r,s={}){let i={timestamp:new Date().toISOString(),eventType:t,status:t.endsWith("failed")?"failed":"success",actorSource:"content-sync",jobId:n.id||"",command:"content-sync",message:r,details:s};await T.mkdir(e,{recursive:true}),await T.appendFile(S.join(e,"audit-events.jsonl"),`${JSON.stringify(i)}
|
|
14
|
-
`,"utf8");}function Oa(e){return Qe({postTypes:e.postTypes??[],listingPaths:e.listingPaths??[],includeSubsites:e.includeSubsites,includePostTypeArchives:e.includePostTypeArchives,includeTaxonomyArchives:e.includeTaxonomyArchives,includeAuthorArchives:e.includeAuthorArchives,includeDateArchives:e.includeDateArchives,includePostsPage:e.includePostsPage,includeSitemapChain:e.includeSitemapChain})}function Ua(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 xn(e,t){if(e.subscriptionType!=="PROFESSIONAL"&&e.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let n=Oa(t),r=Ne(e,t.deploymentProfile),s=r.name||"",i=kn(e.sourceOrigin,String(t.id||""),n),a=$n({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??{}}),c=En({siteId:e.wpsuite?.siteSettings?.siteId,accountId:e.wpsuite?.siteSettings?.accountId,sourceOrigin:e.sourceOrigin,ruleId:String(t.id||""),targetFingerprint:a}),o=`content-sync:${String(t.id||"")}:${ue({scopeFingerprint:i,targetFingerprint:a}).slice(0,32)}`,l=new at({sourceOrigin:e.sourceOrigin,runtimeToken:String(e.wpsuite?.runtimeToken||""),ignoreHttpsErrors:e.ignoreHttpsErrors}),u=await l.releaseFingerprint(n.includeSubsites),d=Tn({wordpressFingerprint:u,targetFingerprint:a,sourceOrigin:e.sourceOrigin,sitemapPaths:Ke(e.sitemapPaths),blockedPathPrefixes:e.blockedPathPrefixes,assetPathPrefixes:e.assetPathPrefixes,noJavaScriptRenderPathPrefixes:e.noJavaScriptRenderPathPrefixes,urlRewriteMode:e.urlRewriteMode});return {rule:t,scope:n,deployment:r,deploymentProfile:s,scopeFingerprint:i,targetFingerprint:a,consumerId:c,coalesceKey:o,client:l,releaseFingerprint:d}}async function La(e){let t=Rn(),n=ct(t),r=await se(),s=(r.scheduler?.rules??[]).filter(l=>l.command==="content-sync"&&l.enabled!==false);if(s.length===0)return 0;let i=await _t(n),a=await ut(n),c=await qt(n),o=0;for(let l of s){let u=await xn(r,l),d=c.entries[u.coalesceKey];if(!d||d.releaseJobId!==e||d.scopeFingerprint!==u.scopeFingerprint||d.targetFingerprint!==u.targetFingerprint||d.releaseFingerprint!==u.releaseFingerprint)throw new Error(`The normal release has no matching pre-crawl content-sync cutoff for rule ${String(l.id||"")}.`);let p=ue({releaseJobId:e,releaseFingerprint:u.releaseFingerprint,scopeFingerprint:u.scopeFingerprint,targetFingerprint:u.targetFingerprint,sequence:d.sequence}),f=await u.client.establishBaseline({consumerId:u.consumerId,scopeFingerprint:u.scopeFingerprint,baselineId:p,postTypes:u.scope.postTypes,includeSubsites:u.scope.includeSubsites,sequence:d.sequence}),g={schemaVersion:1,ruleId:String(l.id||""),consumerId:u.consumerId,coalesceKey:u.coalesceKey,scopeFingerprint:u.scopeFingerprint,targetFingerprint:u.targetFingerprint,releaseFingerprint:u.releaseFingerprint,baselineId:p,deploymentProfile:u.deploymentProfile,committedSequence:f.committedSequence,releaseJobId:e,verifiedAt:new Date().toISOString()};i.entries[u.coalesceKey]=g;let y=a.rules[u.coalesceKey];a.rules[u.coalesceKey]={ruleId:String(l.id||""),consumerId:u.consumerId,coalesceKey:u.coalesceKey,committedSequence:f.committedSequence,observedHeadSequence:f.headSequence,lag:Math.max(0,f.headSequence-f.committedSequence),lastSuccessfulJobId:y?.lastSuccessfulJobId||e,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:f.headSequence>f.committedSequence,retryAttempt:0,nextRetryAt:null,lastError:null,baselineStatus:"ready",baselineReason:null};let m=await Nn(n,u.coalesceKey);await me(t,"content-sync-baseline-established",{id:e},"A normal release established a verified content-sync baseline.",{ruleId:l.id,consumerId:u.consumerId,committedSequence:f.committedSequence,supersededCurrent:m}),o++;}return await Un(n,i),await lt(n,a),await T.rm(n.releaseCutoff,{force:true}),o}async function ja(e){let t=Rn(),n=ct(t),r=await se(),s=(r.scheduler?.rules??[]).filter(c=>c.command==="content-sync"&&c.enabled!==false);if(s.length===0)return 0;let i=await qt(n),a=0;for(let c of s){let o=await xn(r,c),l=Object.values(i.entries).find(p=>p.releaseJobId===e&&p.ruleId===String(c.id||""));if(l){if(l.coalesceKey===o.coalesceKey&&l.scopeFingerprint===o.scopeFingerprint&&l.targetFingerprint===o.targetFingerprint&&l.releaseFingerprint===o.releaseFingerprint){a++;continue}throw new Error(`The normal release scope changed after its journal cutoff was captured for rule ${String(c.id||"")}. Start a new normal publish instead of resuming this release.`)}let u=await o.client.unboundHead(o.scope.postTypes,o.scope.includeSubsites),d={schemaVersion:1,releaseJobId:e,ruleId:String(c.id||""),coalesceKey:o.coalesceKey,scopeFingerprint:o.scopeFingerprint,targetFingerprint:o.targetFingerprint,releaseFingerprint:o.releaseFingerprint,sequence:u.headSequence,capturedAt:new Date().toISOString()};i.entries[o.coalesceKey]=d,await me(t,"content-sync-release-cutoff-captured",{id:e},"A normal release captured its pre-crawl content-sync journal cutoff.",{ruleId:c.id,consumerId:o.consumerId,sequence:u.headSequence}),a++;}return await On(n,i),a}async function qa(e,t){let n=JSON.parse(await T.readFile(S.join(e,"current-run.json"),"utf8"));if(n.id!==t||n.command!=="content-sync"||!String(n.ruleId||"").trim())throw new Error("The active queue job is not the requested content-sync job.");return n}async function Cn(e,t,n=0){let r=e.protocol==="https:"?Fn:ws,s=e.protocol==="https:"?new Fn.Agent({rejectUnauthorized:!t}):void 0;return new Promise((i,a)=>{let c=r.get(e,{agent:s,timeout:3e4,headers:{"user-agent":"WP-Suite-Content-Sync/1"}},o=>{let l=o.statusCode??500,u=o.headers.location;if(l>=300&&l<400&&u&&n<5){o.resume(),Cn(new URL(u,e),t,n+1).then(i,a);return}let d=[],p=0;o.on("data",f=>{p+=f.byteLength,p<=1048576&&d.push(f);}),o.on("error",a),o.on("end",()=>i({status:l,body:Buffer.concat(d).toString("utf8")}));});c.on("timeout",()=>c.destroy(new Error(`Verification timed out: ${e}`))),c.on("error",a);})}async function _a(e,t,n,r){let s=t.deployment.config.targetOrigin;if(!/^https?:\/\//i.test(s))throw new Error("Content-sync verification requires an absolute HTTP(S) target origin.");let i=JSON.parse(await T.readFile(r,"utf8")),a=new Set;for(let[l,u]of Object.entries(i.pages??{}))a.add(l),typeof u.url=="string"&&a.add(u.url);let c=await Me(e);if(c?.schemaVersion!==2||c.impactHash!==n.impactHash)throw new Error("Content-sync verification requires the matching targeted deploy plan.");let o=ss(n,a,c.resolvedSitemapUrls);for(let l of o.expectedAvailable){let u=new URL(l),d=new URL(`${u.pathname}${u.search}`,s),p=await Cn(d,e.ignoreHttpsErrors);if(p.status<200||p.status>=400)throw new Error(`Content-sync verification failed (${p.status}): ${d}`)}for(let l of o.expectedMissing.slice(0,10)){let u=new URL(l),d=new URL(`${u.pathname}${u.search}`,s),p=await Cn(d,e.ignoreHttpsErrors);if(p.status>=200&&p.status<300)throw new Error(`Deleted content is still publicly available: ${d}`)}}async function Na(e){let t=await T.readFile(e.candidateManifest,"utf8");JSON.parse(t);let n=`${e.trustedManifest}.${process.pid}.tmp`;await T.writeFile(n,t,"utf8"),await T.rename(n,e.trustedManifest);}async function Ba(e,t){try{let n=JSON.parse(await T.readFile(e.candidateManifest,"utf8"));if([...Object.values(n.pages??{}),...Object.values(n.assets??{})].some(s=>s?.lastSeenRunId===t))return "resumed"}catch(n){if(n.code!=="ENOENT")throw new Error(`The content-sync candidate manifest is invalid: ${n instanceof Error?n.message:String(n)}`,{cause:n})}return await T.copyFile(e.trustedManifest,e.candidateManifest).catch(n=>{throw new Error(`A trusted crawl manifest is required before content-sync: ${n instanceof Error?n.message:String(n)}`,{cause:n})}),"initialized"}async function Ie(e,t,n,r,s={},i=0,a=async()=>{}){t.phase=n,await Ln(e,t),await _n(e,{schemaVersion:1,jobId:t.jobId,phase:n,completedItems:r,totalItems:r,attempt:i,updatedAt:new Date().toISOString(),details:s}),await me(S.dirname(e.state),"content-sync-checkpoint",{id:t.jobId},`Content-sync checkpoint completed: ${n}.`,{phase:n,completedItems:r,totalItems:r,attempt:i,...s}),await a(n,t);}async function Wa(e,t={}){let n={loadConfig:se,resolveRuleContext:xn,runCrawl:Jr,runDeploy:es,runInvalidate:rs,verifyDeployment:_a,promoteCandidateManifest:Na,clearDeployPlan:De,afterCheckpoint:async()=>{},...t},r=Rn(),s=ct(r),i=await qa(r,e),a=await n.loadConfig(),c=Ua(a,String(i.ruleId)),o=await n.resolveRuleContext(a,c);if(i.coalesceKey&&i.coalesceKey!==o.coalesceKey)throw new Error("Queued content-sync demand no longer matches the active rule scope.");let u=(await _t(s)).entries[o.coalesceKey];if(!u||u.scopeFingerprint!==o.scopeFingerprint||u.targetFingerprint!==o.targetFingerprint||u.releaseFingerprint!==o.releaseFingerprint)throw await me(r,"content-sync-baseline-rejected",i,"Content-sync requires a new verified full or incremental release baseline.",{ruleId:c.id,reason:u?"mismatch":"missing"}),new Error("Content-sync baseline is missing or stale. Run a successful normal publish first.");let d=await Nt(s),p=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:u.baselineId,postTypes:o.scope.postTypes,includeSubsites:o.scope.includeSubsites});if(d&&d.jobId!==i.id)throw new Error("Another immutable content-sync range is still active.");if(d||(d={schemaVersion:1,jobId:i.id,ruleId:String(c.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,scopeFingerprint:o.scopeFingerprint,targetFingerprint:o.targetFingerprint,baselineId:u.baselineId,fromSequence:p.committedSequence,toSequence:p.headSequence,phase:"claimed",impactHash:null,startedAt:new Date().toISOString(),updatedAt:new Date().toISOString()},await Ie(s,d,"claimed",0,{fromSequence:d.fromSequence,toSequence:d.toSequence},0,n.afterCheckpoint),await me(r,"content-sync-range-claimed",i,"Content-sync claimed a closed journal range.",{fromSequence:d.fromSequence,toSequence:d.toSequence})),d.fromSequence===d.toSequence){let h=await ut(s);h.rules[o.coalesceKey]={ruleId:String(c.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,committedSequence:d.toSequence,observedHeadSequence:p.headSequence,lag:Math.max(0,p.headSequence-d.toSequence),lastSuccessfulJobId:i.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:false,retryAttempt:0,nextRetryAt:null,lastError:null},await lt(s,h),await Bt(s);return}let f=await jn(s);if(!Be(d.phase,"impact-planned")){let h=await o.client.events({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:u.baselineId,postTypes:o.scope.postTypes,includeSubsites:o.scope.includeSubsites,afterSequence:d.fromSequence,throughSequence:d.toSequence}),w=jt({events:h,scope:o.scope,sourceOrigin:a.sourceOrigin}),v=await o.client.resolveImpactFamilies(w,o.scope.includeSubsites);f=Dn({jobId:i.id,ruleId:String(c.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,scopeFingerprint:o.scopeFingerprint,targetFingerprint:o.targetFingerprint,baselineId:u.baselineId,sourceOrigin:a.sourceOrigin,scope:o.scope,fromSequence:d.fromSequence,toSequence:d.toSequence,events:h,resolvedArchiveFamilies:v,sitemapUrls:Ke(a.sitemapPaths)}),await qn(s,f),d.impactHash=f.impactHash,await Ie(s,d,"impact-planned",h.length,{eventCount:h.length,foldedCount:f.foldedCount,impactHash:f.impactHash},0,n.afterCheckpoint),await me(r,"content-sync-impact-planned",i,"Content-sync persisted an immutable impact plan.",{impactHash:f.impactHash,eventCount:h.length});}if(!f||f.jobId!==i.id||d.impactHash!==f.impactHash)throw new Error("The immutable content-sync impact plan is missing or mismatched.");if(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH=s.candidateManifest,!Be(d.phase,"rendered")){let h=await Ba(s,i.id);await me(r,h==="resumed"?"content-sync-render-resumed":"content-sync-render-initialized",i,h==="resumed"?"Content-sync resumed its candidate crawl manifest.":"Content-sync initialized a candidate crawl manifest.",{impactHash:f.impactHash}),await n.runCrawl(["--content-sync-plan",s.impact]),await Ie(s,d,"rendered",f.directRenderUrls.length+f.archiveFamilyUrls.length,{impactHash:f.impactHash},i.attempt??0,n.afterCheckpoint);}let g=o.deploymentProfile?["--profile",o.deploymentProfile]:[];if(Be(d.phase,"deployed")||(await n.runDeploy([...g,"--content-sync"]),await Ie(s,d,"deployed",1,{impactHash:f.impactHash},0,n.afterCheckpoint),await me(r,"content-sync-deployed",i,"Content-sync targeted deployment completed.",{impactHash:f.impactHash})),Be(d.phase,"invalidated")?Be(d.phase,"verified")||await n.runInvalidate([...g,"--content-sync"]):(await n.runInvalidate([...g,"--content-sync"]),await Ie(s,d,"invalidated",1,{impactHash:f.impactHash},0,n.afterCheckpoint)),Be(d.phase,"verified")||(await n.verifyDeployment(a,o,f,s.candidateManifest),await n.promoteCandidateManifest(s),await Ie(s,d,"verified",1,{impactHash:f.impactHash},0,n.afterCheckpoint)),p=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:u.baselineId,postTypes:o.scope.postTypes,includeSubsites:o.scope.includeSubsites}),p.committedSequence===d.fromSequence)await o.client.acknowledge({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:u.baselineId,expectedSequence:d.fromSequence,sequence:d.toSequence,postTypes:o.scope.postTypes,includeSubsites:o.scope.includeSubsites});else if(p.committedSequence!==d.toSequence)throw new Error("Content-sync acknowledgement cursor is in an unexpected state.");await Ie(s,d,"acknowledged",1,{sequence:d.toSequence},0,n.afterCheckpoint),await me(r,"content-sync-cursor-acknowledged",i,"Content-sync committed its journal cursor after verification.",{sequence:d.toSequence});let y=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:u.baselineId,postTypes:o.scope.postTypes,includeSubsites:o.scope.includeSubsites}),m=await ut(s);m.rules[o.coalesceKey]={ruleId:String(c.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,committedSequence:d.toSequence,observedHeadSequence:y.headSequence,lag:Math.max(0,y.headSequence-d.toSequence),lastSuccessfulJobId:i.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:y.headSequence>d.toSequence,retryAttempt:0,nextRetryAt:null,lastError:null},await lt(s,m),await n.clearDeployPlan(a),await T.rm(S.join(r,"content-sync-invalidation.json"),{force:true}),await T.rm(s.candidateManifest,{force:true}),await Bt(s);}async function as(e=process.argv.slice(2)){let n=e.indexOf("--capture-baseline-cutoffs");if(n>=0){let a=String(e[n+1]||"").trim();if(!a)throw new Error("--capture-baseline-cutoffs requires a release job ID.");await ja(a);return}let r=e.indexOf("--establish-baselines");if(r>=0){let a=String(e[r+1]||"").trim();if(!a)throw new Error("--establish-baselines requires a release job ID.");await La(a);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 Wa(i);}as().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1);});
|
|
13
|
+
${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:a,tokenSource:"generated-404-response-hash",postId:null,dependencyPostIds:[],reason:null}}catch(s){return r.warn(`Generated 404 fallback token lookup failed for ${n}`,{url:n,error:String(s),requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),null}}async function Oi(e,t,n,r,s,i){let a=hn(e,s);if(!r.enabled)return {action:"render",changeToken:r.trackManifest?await Rt(e,t,r,s,i):null};let c=r.manifest.pages[s];if(!c)return {action:"render",changeToken:await Rt(e,t,r,s,i)};let o=await Rt(e,t,r,s,i);if(o?.supported&&o.token)return c.changeToken===o.token?a&&!await Ui(e,t,s,i)?{action:"render",changeToken:o}:{action:"reuse",changeToken:o}:{action:"render",changeToken:o};let d=tt(n.sitemapLastmodByPage[s]);return d&&c.sitemapLastmod&&c.sitemapLastmod===d?{action:"reuse",changeToken:o}:{action:"render",changeToken:o}}async function Ui(e,t,n,r){try{let i=(await t.get(n,{timeout:Math.min(e.navigationTimeoutMs,15e3),failOnStatusCode:!1})).status();return i===404?!0:(r.warn(`Generated 404 request path no longer returns 404 for ${n}`,{url:n,status:i,requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),!1)}catch(s){return r.warn(`Generated 404 status probe failed for ${n}`,{url:n,error:String(s),requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),false}}async function Li(e,t,n,r,s){let i=Ir(n.previousManifest,void 0,r,"previous-manifest"),a=0;for(let[p,f]of Object.entries(n.manifest.pages))if(!n.seenPages.has(p)){Rr(s,e,f.outputPath);try{await A.unlink(f.outputPath);}catch(g){(g.code||"")!=="ENOENT"&&r.warn(`Failed to remove stale incremental page output for ${p}`,{url:p,outputPath:f.outputPath,error:String(g)});}delete n.manifest.pages[p],a++;}let c=Ir(n.manifest,n.runId,r,"active-manifest"),o=new Set,d=new Set;for(let p of c){for(let y of nt(e,p))o.add(y);let f=n.manifest.assets[p]?.outputPath;f&&d.add(f);let g=je(e,t.assetMap,p);g&&d.add(g);}for(let p of Object.keys(n.manifest.assets)){if(c.has(p)){n.manifest.assets[p].unreferencedRuns=0;continue}let f=n.manifest.assets[p];if(yr(f.unreferencedRuns)){f.unreferencedRuns+=1,r.warn(`Deferred deletion of newly unreferenced incremental asset ${p}.`,{url:p,unreferencedRuns:f.unreferencedRuns,phase:"incremental-cleanup",source:"asset-deletion-grace"});continue}delete n.manifest.assets[p];}let l=0,u=0;for(let p of i){if(n.manifest.assets[p])continue;let f=new Set,g=n.previousManifest.assets[p]?.outputPath;g&&f.add(g);let y=je(e,t.assetMap,p);if(!c.has(p)&&y)f.add(y);else if(!c.has(p)){let h=eo(e,p,r,"incremental-cleanup");h&&(f.add(h.originalFilePath),h.hashedFilePath&&f.add(h.hashedFilePath));}for(let h of f)if(!d.has(h)){Rr(s,e,h);try{await A.unlink(h),l++;}catch(m){(m.code||"")!=="ENOENT"&&r.warn(`Failed to remove stale incremental asset output for ${p}`,{url:p,outputPath:h,error:String(m)});}}for(let h of nt(e,p))o.has(h)||Object.prototype.hasOwnProperty.call(t.assetMap,h)&&(delete t.assetMap[h],u++);}(a>0||l>0||u>0)&&r.info(`Incremental cleanup removed ${a} stale pages, ${l} stale assets, ${u} stale asset mappings`,{removedPages:a,removedAssets:l,removedAssetMappings:u,phase:"incremental-cleanup"});}function Ir(e,t,n,r){let s=new Set,i=a=>{let c=a.trim();if(c){if(n){let o=ve(c,n,"asset",r??"manifest");if(!o)return;s.add(o.toString());return}s.add(c);}};for(let a of Object.values(e.pages))for(let c of a.discoveredAssets||[])i(c);for(let[a,c]of Object.entries(e.assets||{}))t&&c.lastSeenRunId!==t||i(a);return s}function xr(e,t,n){for(let r of t)for(let s of nt(e,r))if(n.has(s))return true;return false}function ji(e,t,n,r,s){let i=new Set(n.rewriteTargets);for(let c of n.changedFiles)i.add(S.resolve(e.outputDir,c));for(let c of Object.values(t.manifest.pages))c.rewriteComplete||i.add(S.resolve(c.outputPath));for(let c of Object.values(t.manifest.assets))c.isText&&!c.rewriteComplete&&i.add(S.resolve(c.outputPath));let a=Ei(r,s);if(a.size===0)return [...i];for(let c of Object.values(t.manifest.pages))xr(e,c.discoveredAssets,a)&&i.add(S.resolve(c.outputPath));for(let[c,o]of Object.entries(t.manifest.assets)){o.isText&&xr(e,o.discoveredAssets,a)&&i.add(S.resolve(o.outputPath));for(let d of nt(e,c))if(a.has(d)){te(n,e,o.outputPath),o.isText&&i.add(S.resolve(o.outputPath));break}}return [...i]}function qi(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 _i(e,t,n){let r=new Set,s=i=>{if(!i)return;let a=Se(e.outputDir,i);a&&r.add(a);};for(let i of t.donePages)s(ge(e,i));for(let i of Object.values(n.manifest.pages))i.lastSeenRunId===n.runId&&s(i.outputPath);for(let i of t.doneAssets)s(je(e,t.assetMap,i));for(let i of Object.values(n.manifest.assets))i.lastSeenRunId===n.runId&&s(i.outputPath);return r}async function Ni(e,t,n,r,s){let i=[...r.deletedFiles].sort(),a=_i(e,t,n),c=0;for(let l of [...a].sort()){try{if((await A.stat(S.join(e.outputDir,l))).isFile())continue}catch{}c++,s.warn(`Active output is missing after crawl: ${l}`,{phase:"deploy-plan",file:l,outputPath:S.join(e.outputDir,l)});}if(c>0&&s.warn(`Detected ${c} active output file(s) missing before deploy plan save.`,{phase:"deploy-plan",missingActiveOutputs:c}),i.length===0)return [];let o=[],d=0;for(let l of i){if(!a.has(l)){o.push(l);continue}d++;let u=S.join(e.outputDir,l),p;try{p=(await A.stat(u)).isFile();}catch{p=false;}s.warn(`Deploy plan protected active output from deletion: ${l}`,{phase:"deploy-plan",file:l,outputPath:u,exists:p});}return d>0&&s.info(`Deploy plan skipped ${d} active output deletion(s).`,{phase:"deploy-plan",protectedDeletes:d,deletedFiles:o.length}),o}function nt(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 a of i)try{n.add(new URL(a).origin+r.pathname+r.search);}catch{}n.add(r.pathname+r.search),n.add(r.pathname);}catch{}return [...n]}function Bi(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 a of i)try{n.add(new URL(a).origin+r.pathname+r.search);}catch{}n.add(r.pathname+r.search);}catch{}return [...n]}function Nr(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,mn(r.pathname))}catch{return null}}function Wi(e,t,n){for(let r of Bi(e,n)){let s=t[r];if(!s)continue;let i=Nr(e,s);if(i)return {outputPath:i,publicUrl:s}}return null}function Hi(e,t,n){for(let r of nt(e,n)){let s=t[r];if(!s)continue;let i=Nr(e,s);if(i)return i}return null}function je(e,t,n){let r=Hi(e,t,n);if(r)return r;try{return Tt(e,n).originalFilePath}catch{return null}}function zi(){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 Ar(e){let t=zi();if(t)try{let n=await A.readFile(t,"utf8"),r=JSON.parse(n);if(!r||typeof r!="object")return;await A.writeFile(t,JSON.stringify({...r,checkedAt:new Date().toISOString(),status:"running",currentStep:"rewrite",message:e},null,2),"utf8");}catch{}}function Qi(e,t){let n=new Set;for(let r of t.donePages)n.add(S.resolve(ge(e,r)));for(let r of t.doneAssets){let s=je(e,t.assetMap,r);!s||!be(s)||n.add(S.resolve(s));}for(let r of t.doneSitemaps){let s=je(e,t.assetMap,r);!s||!be(s)||n.add(S.resolve(s));}return [...n]}var It="re:",vt=new Map;function Ji(e){if(!e.startsWith(It))return null;let t=vt.get(e);if(t!==void 0)return t||null;let n=e.slice(It.length).trim();if(!n)return vt.set(e,false),null;try{let r=new RegExp(n);return vt.set(e,r),r}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),vt.set(e,false),null}}function fn(e,t){let n=Ji(t);return n?n.test(e):t.startsWith(It)?false:e.startsWith(t)}function Vi(e,t){return t.find(n=>fn(e,n))}function Br(e,t){let n=Vi(t.pathname,e.blockedPathPrefixes);if(n)return n.startsWith(It)?`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 Ki(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 Gi(e,t){return Ki(e).has(t.hostname)}function Zi(e){let t=de(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function ln(e){let t=de(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function Yi(e){let t=de(e).replace(/\\\//g,"/").trim(),n=S.extname(t).toLowerCase();return Or.has(n)||Ur.has(n)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function qe(e){return Pi.some(t=>e.pathname.startsWith(t))}function J(e,t,n=e.sourceOrigin,r,s="url",i=false){let a=Zi(t);if(!a||a.startsWith("data:")||a.startsWith("blob:")||a.startsWith("mailto:")||a.startsWith("tel:")||a.startsWith("#"))return r?.ignore(s,t,"empty or unsupported scheme",n),null;if(ln(a))return r?.ignore(s,t,"looks like JavaScript/code fragment",n),null;if(Yi(a))return r?.ignore(s,t,"looks like JavaScript property access",n),null;try{let c=new URL(a,n);if(Wr(c))return r?.reject(s,t,"malformed URL encoding",n),null;if(!["http:","https:"].includes(c.protocol))return r?.ignore(s,t,"unsupported protocol: ",n),null;if(!Gi(e,c))return r?.ignore(s,c.toString(),"host not allowed",n),null;let o=Br(e,c);if(o&&!(i&&zt(c)))return r?.reject(s,c.toString(),o,n),null;let d=new URL(e.sourceOrigin);return c.protocol=d.protocol,c.host=d.host,c.hash="",c}catch{return r?.reject(s,t,"invalid URL",n),null}}function Wr(e){try{return decodeURIComponent(e.pathname),decodeURIComponent(e.search),decodeURIComponent(e.hash),!1}catch{return true}}function ve(e,t,n,r){try{let s=new URL(e);return Wr(s)?(t.reject(n,e,"malformed URL encoding",r),null):s.protocol!=="http:"&&s.protocol!=="https:"?(t.reject(n,e,`unsupported protocol: ${s.protocol}`,r),null):s}catch{return t.reject(n,e,"invalid URL",r),null}}function Hr(e){return Or.has(S.extname(e.pathname).toLowerCase())}function Ce(e){return qe(e)?false:Ur.has(S.extname(e.pathname).toLowerCase())}function _e(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function W(e,t){return !!(_e(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(n=>fn(t.pathname,n))||Hr(t)||!Ce(t)&&!qe(t))}function ge(e,t){let n=new URL(t),r=mn(n.pathname);return r.endsWith("/")?r+="index.html":S.extname(r)||(r+="/index.html"),S.join(e.outputDir,r)}function mn(e){try{return decodeURIComponent(e)}catch{return e}}function Xi(e){if(!e.generated404RequestPath)return null;try{let t=new URL(e.generated404RequestPath,e.sourceOrigin);return !t.pathname.endsWith("/")&&S.extname(t.pathname)===""&&(t.pathname+="/"),t.hash="",t.toString()}catch{return null}}function hn(e,t){let n=Xi(e);if(!n)return false;try{return new URL(t,e.sourceOrigin).toString()===n}catch{return false}}function Tt(e,t){let n=new URL(t),r=mn(n.pathname);r.endsWith("/")&&(r+="index.html");let s=!!n.search,i=r,a=S.join(e.outputDir,i),c=Xt(e.targetOrigin,i),o=`${c}${n.search}`;if(!s)return {originalPathname:i,originalFilePath:a,originalPublicUrl:c,originalPublicUrlWithSearch:o,preferQueryHashed:s};let d=S.extname(r),u=`${d?r.slice(0,-d.length):r}.${Ze(n.search)}${d||".bin"}`;return {originalPathname:i,originalFilePath:a,originalPublicUrl:c,originalPublicUrlWithSearch:o,preferQueryHashed:s,hashedPathname:u,hashedFilePath:S.join(e.outputDir,u),hashedPublicUrl:Xt(e.targetOrigin,u)}}function eo(e,t,n,r){let s=ve(t,n,"asset",r);return s?Tt(e,s.toString()):null}function to(e,t,n,r,s){t[n]=r;try{let i=new URL(n),c=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{c.push(new URL(e.targetOrigin).origin);}catch{}for(let o of c)try{let d=new URL(o);t[d.origin+i.pathname+i.search]=r;}catch{}try{let o=(()=>{let d=new URL(r,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin);return `${d.pathname}${d.search}`})();t[i.pathname+i.search]=o;}catch{}try{let o=new URL(r,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=o;}catch{}try{let o=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=o;}catch{}}catch{}}async function zr(e){try{return await A.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Le(e){try{return await A.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function no(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 Qr(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let n=Date.parse(t);return Number.isFinite(n)?n:null}function ro(e,t){let n=Qr(t),r=no(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 so(e,t){if(!t)return;let n=Qr(t);if(n===null)return;let r=await Le(e);if(!r)return;let s=new Date(n);await A.utimes(e,r.atime,s).catch(()=>{});}function Tr(e,t){let n=S.extname(e.pathname).toLowerCase(),r=t["content-type"]||"";return bi.has(n)||Si.some(s=>r.includes(s))&&!r.startsWith("image/")&&!r.includes("font")}function io(e){try{let t=S.extname(new URL(e).pathname).toLowerCase();return t===".js"||t===".mjs"}catch{return false}}function Ue(e,t){(e.doneAssets.size%25===0||e.doneAssets.size===1||e.doneAssets.size===e.stats.assetsQueued)&&t.progress(`Asset processing progress: processed ${e.doneAssets.size}, discovered ${e.stats.assetsQueued}.`,{doneAssets:e.doneAssets.size,assetsQueued:e.stats.assetsQueued,phase:"download-assets"});}function oo(e){return Ze(e.toString("base64"),40)}function ao(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 co(e,t,n){let r=e.assetVariantDigestsByOriginalPath.get(t);r||(r=new Set,e.assetVariantDigestsByOriginalPath.set(t,r)),r.add(n);}async function dn(e,t,n,r,s,i,a){let c=Tt(e,n),o=oo(r),d=c.originalFilePath,l=c.originalPublicUrlWithSearch;if(c.preferQueryHashed&&c.hashedFilePath&&c.hashedPublicUrl&&ao(s,c.originalFilePath,o)){let g=Wi(e,t,n);g?(d=g.outputPath,l=g.publicUrl):(d=c.hashedFilePath,l=c.hashedPublicUrl);}to(e,t,n,l,c.originalPublicUrl);let u=be(d)?Buffer.from(nn(r.toString("utf8"),e,t,d),"utf8"):r,p=await zr(d),f=false;return (p===null||!p.equals(u))&&(await Ye(d,u),f=true),i?.debug(`${f?"Saved":"Skipped unchanged"} asset output ${n}`,{phase:"download-assets",url:n,outputPath:d,bytes:u.length,wroteFile:f}),co(s,c.originalFilePath,o),await so(d,a),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:d,publicUrl:l,wroteFile:f}}function rt(e,t,n,r,s){let i=()=>{let u=String(s??"").trim();if(!u)return {discoveredFrom:"",discoveredFromType:"unknown"};if(u==="seed-path"||u==="cli"||u==="generated-404-request-path")return {discoveredFrom:u,discoveredFromType:u};if(/^https?:\/\//i.test(u))try{let p=new URL(u);return _e(p)?{discoveredFrom:u,discoveredFromType:"sitemap"}:W(e,p)?{discoveredFrom:u,discoveredFromType:"asset"}:Ce(p)&&!qe(p)?{discoveredFrom:u,discoveredFromType:"page"}:{discoveredFrom:u,discoveredFromType:"url"}}catch{return {discoveredFrom:u,discoveredFromType:"url"}}return {discoveredFrom:u,discoveredFromType:"url"}},a=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,c=J(e,n,a,r,"page");if(!c)return;if(!Ce(c)||Hr(c)){if(W(e,c)){r.info(`Seeded/non-page URL queued as asset: ${c.toString()}`,{url:c.toString(),source:s}),Q(e,t,c.toString(),r,s);return}r.reject("page",c.toString(),qe(c)?"asset/internal path cannot be page":"not page-like",s);return}let o=c.toString(),{discoveredFrom:d,discoveredFromType:l}=i();d&&!t.pageDiscoverySources.has(o)&&t.pageDiscoverySources.set(o,d),!t.donePages.has(o)&&!t.queuedPages.has(o)&&(t.queuedPages.add(o),t.pageQueue.push(o),t.stats.pagesQueued++,r.debug(`Queued discovered page ${o}`,{phase:"discovery",url:o,discoveredFrom:d,discoveredFromType:l,outputPath:ge(e,o)}),(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 Q(e,t,n,r,s){let i=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,a=J(e,n,i,r,"asset");if(!a)return;if(!W(e,a)){r.reject("asset",a.toString(),"not a safe asset path/prefix",s);return}let c=a.toString();!t.doneAssets.has(c)&&!t.queuedAssets.has(c)&&(t.queuedAssets.add(c),t.assetQueue.push(c),t.stats.assetsQueued++,(t.stats.assetsQueued%100===0||t.stats.assetsQueued===1)&&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 xt(e,t,n,r,s){let i=s&&/^https?:\/\//i.test(s)?s:e.sourceOrigin,a=J(e,n,i,r,"sitemap",zn(s));if(!a)return;if(!_e(a)){r.reject("sitemap",a.toString(),"not sitemap-like",s);return}let c=a.toString();!t.doneSitemaps.has(c)&&!t.queuedSitemaps.has(c)&&(t.queuedSitemaps.add(c),t.sitemapQueue.push(c),t.stats.sitemapsQueued++,(t.stats.sitemapsQueued%10===0||t.stats.sitemapsQueued===1)&&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 uo(e){let t=de(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:tt(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 lo(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function po(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 go(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function fo(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 on(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function Jr(e,t,n,r){let s=[];await A.mkdir(t,{recursive:true});let i=await A.readdir(e,{withFileTypes:true});for(let a of i){let c=S.join(e,a.name),o=S.join(t,a.name);if(a.isDirectory()){s.push(...await Jr(c,o,n,r));continue}await Vr(c,o,n,r)&&s.push(o);}return s}async function mo(e,t){try{let[n,r]=await Promise.all([A.stat(e),A.stat(t)]);if(n.size!==r.size)return !1;let[s,i]=await Promise.all([A.readFile(e),A.readFile(t)]);return s.equals(i)}catch{return false}}async function Vr(e,t,n,r){let s=S.resolve(t);return n.has(s)?(r.debug("Skipped post-crawl copy over crawled page output",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):await mo(e,t)?(r.debug("Skipped unchanged post-crawl copy target",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):(await A.mkdir(S.dirname(t),{recursive:true}),await A.copyFile(e,t),true)}async function ho(e,t,n){let r=Object.entries(e.postCrawlCopyMap||{}).map(([c,o])=>({sourcePath:c.trim(),prefix:String(o||"").trim()}));if(r.length===0)return [];let s=0,i=[],a=new Set([...t.donePages].map(c=>S.resolve(ge(e,c))));n.mark("copy-extra-paths");for(let c of r){let o=c.sourcePath,d=c.prefix;if(!o||!d){n.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:o,prefixPath:d});continue}let l=xi(o);if(!l.resolvedPath){n.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:o,alias:l.alias||"",requiredEnv:l.requiredEnv||"",prefixPath:d});continue}let u=l.resolvedPath,p=on(d);if(!p){n.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:o,prefixPath:d});continue}let f;try{f=await A.stat(u);}catch{n.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:o,sourceAbs:u,prefixPath:d});continue}let g=S.resolve(e.outputDir,p);if(f.isDirectory()){let w=await Jr(u,g,a,n);i.push(...w),s+=w.length,w.length>0&&n.progress(`Copied static directory to export: ${u} -> /${p}`,{phase:"copy-extra-paths",sourcePath:u,targetPath:`/${p}`,copiedItems:s,changedFiles:w.length});continue}let y=S.basename(u),h=d.endsWith("/")?S.join(g,y):g;await Vr(u,h,a,n)&&(i.push(h),s++,n.progress(`Copied static file to export: ${u} -> /${on(d.endsWith("/")?`${d}${y}`:d)}`,{phase:"copy-extra-paths",sourcePath:u,targetPath:`/${on(d.endsWith("/")?`${d}${y}`:d)}`,copiedItems:s}));}return n.endMark("copy-extra-paths",{mappedSources:r.length,copiedItems:s}),i}function st(e,t,n,r,s){let i=new Set,a=de(n).replace(/\\\//g,"/"),c=s==="page-html"?go(a):a,o=fo(t,s);if(o){for(let l of po(c)){let u=J(e,l,t,r,`${s}:css-url`);u&&W(e,u)&&i.add(u.toString());}for(let l of c.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let u=J(e,l[1],t,r,`${s}:css-import`);u&&W(e,u)&&i.add(u.toString());}}if(o||s==="page-html")for(let l of c.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let u=J(e,l[1],t,r,`${s}:xml-stylesheet`);u&&W(e,u)&&i.add(u.toString());}let d=new RegExp(`(?:https?:)?//[^\\s'"<>\\);]+\\.${rn}(?:\\?[^\\s'"<>\\);]*)?|(?<!\\.)/[^\\s'"<>\\);]+\\.${rn}(?:\\?[^\\s'"<>\\);]*)?`,"gi");if(s==="page-html")for(let l of a.matchAll(d)){let u=l[0].startsWith("//")?`${new URL(e.sourceOrigin).protocol}${l[0]}`:l[0];if(ln(u)){r.ignore(`${s}:serialized-url`,u,"looks like JavaScript/code fragment",t);continue}let p=J(e,u,t,r,`${s}:serialized-url`);p&&W(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"&&io(t))for(let l of mr(a)){if(ln(l)||!/\.(?:js|mjs)(?:[?#]|$)/i.test(l))continue;let u=J(e,l,t,r,`${s}:relative-asset`);u&&W(e,u)&&i.add(u.toString());}return [...i]}function wo(e,t,n,r){let s=new Set,i=de(n);for(let a of i.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let c=a[1],o=J(e,c,t,r,"page-link");o&&(Br(e,o)||Ce(o)&&!qe(o)&&!W(e,o)&&s.add(o.toString()));}return [...s]}async function kr(e,t,n,r,s,i,a=false,c=[]){let o=new Set(c),d=0,l=new Map,u=(p,f)=>{let g=[f],y=new Set;for(;g.length>0;){let h=g.pop();if(h===p)return true;y.has(h)||(y.add(h),g.push(...l.get(h)??[]));}return false};for(;n.sitemapQueue.length>0;){let p=n.sitemapQueue.shift();n.queuedSitemaps.delete(p);let f=ve(p,r,"sitemap","sitemap-queue");if(!f)continue;let g=f.toString();if(n.doneSitemaps.has(g))continue;n.doneSitemaps.add(g),r.sitemap(`Fetching sitemap ${g}`,{url:g});let y=true;try{let h=await t.get(g,{timeout:6e4});if(y=!1,!h.ok()){if(r.skip("sitemap",g,h.status()),a&&!o.has(g))throw new Error(`Required child content-sync sitemap returned HTTP ${h.status()}: ${g}`);continue}let m=await h.body(),w=h.url()||g,P=ve(w,r,"sitemap-response",g);if(!P)continue;let I=P.toString();n.successfulSitemaps.add(g),n.successfulSitemaps.add(I),o.has(g)&&(n.resolvedSitemapRoots.add(I),d+=1);let j=await dn(e,n.assetMap,I,m,n,r);te(s,e,j.outputPath),Ie(s,j.outputPath);let M=m.toString("utf8");/<sitemapindex(?:\s|>)/i.test(M)?n.sitemapIndexUrls.add(I):n.sitemapLeafUrls.add(I);let _=st(e,I,M,r,"sitemap");for(let $ of _)Q(e,n,$,r,I);let C=[];for(let $ of uo(M)){let R=J(e,$.loc,I,r,"sitemap-loc",!0);if(!R){if(a)throw new Error(`Content-sync sitemap contains an inadmissible location: ${$.loc}`);continue}if(_e(R)){if(u(I,R.toString()))throw new Error(`Sitemap index cycle detected: ${I} -> ${R.toString()}`);if(l.has(I)||l.set(I,new Set),l.get(I).add(R.toString()),C.push(R.toString()),a&&n.doneSitemaps.has(R.toString())&&!n.successfulSitemaps.has(R.toString()))throw new Error(`Required child content-sync sitemap was not resolved: ${R.toString()}`);xt(e,n,R.toString(),r,I);}else if(a){if(Ce(R)&&!W(e,R)){let D=i.requiredUrls.has(R.toString()),b=i.manifest.pages[R.toString()],T=!!b&&!!await Le(b.outputPath);if(!D&&!T)throw new Error(`Content-sync sitemap coverage is incomplete for ${R.toString()}.`)}r.ignore("sitemap-loc",R.toString(),"content-sync sitemap-only traversal does not enqueue urlset locations",I);}else W(e,R)?Q(e,n,R.toString(),r,I):Ce(R)?($.lastmod&&(n.sitemapLastmodByPage[R.toString()]=$.lastmod),rt(e,n,R.toString(),r,I)):r.reject("sitemap-loc",R.toString(),"not page/sitemap/asset-like",I);}i.trackManifest&&(i.manifest.assets[I]={url:I,outputPath:j.outputPath,isText:!0,contentType:h.headers()["content-type"]??"application/xml",changeToken:null,tokenSource:null,discoveredAssets:[...new Set([..._,...C])],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,unreferencedRuns:0,rewriteComplete:!1},await Pe(e,i));}catch(h){r.error(`Failed sitemap ${g}`,{url:g,error:String(h)});let m=a&&o.has(g)&&y;if(a&&!m)throw h}}if(a&&o.size>0&&d===0)throw new Error(`None of the configured content-sync sitemap roots could be resolved: ${[...o].join(", ")}`)}async function yo(e,t,n,r,s,i,a){let c=J(e,r,e.sourceOrigin,s,"asset-fetch");if(!c||!W(e,c))return;let o=c.toString();if(n.doneAssets.has(o))return;let d=i.enabled||i.strictTargeted?i.previousManifest.assets[o]:void 0,l=i.trackManifest?await Rt(e,t,i,o,s):null,u=l?.token??null,p=hr(d?.changeToken,l),f=i.strictTargeted&&(!l?.supported||!l.token)&&wr(e.sourceOrigin,o),g=i.strictTargeted?i.manifest.assets[o]:void 0;if(g?.lastSeenRunId===i.runId&&await Le(g.outputPath)){n.doneAssets.add(o);for(let h of g.discoveredAssets||[])Q(e,n,h,s,o);te(a,e,g.outputPath),g.isText&&Ie(a,g.outputPath),s.info(`Resumed completed content-sync asset ${o}`,{url:o,source:"content-sync-checkpoint"}),Ue(n,s);return}if(d&&(p||f)&&await Le(d.outputPath)){i.manifest.assets[o]={...d,changeToken:u,tokenSource:l?.tokenSource??d.tokenSource,discoveredAssets:[...d.discoveredAssets||[]],lastSeenRunId:i.runId,unreferencedRuns:0},delete i.manifest.pages[o],n.doneAssets.add(o);for(let h of d.discoveredAssets||[])Q(e,n,h,s,o);s.info(`Reused unchanged trusted asset ${o}.`,{url:o,tokenSource:l?.tokenSource??"unknown",phase:"download-assets",source:p?"asset-change-token-match":"content-sync-release-fingerprint"}),Ue(n,s);return}let y=(h,m={})=>{if(!d||i.strictTargeted)return false;i.manifest.assets[o]={...d,discoveredAssets:[...d.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,unreferencedRuns:0},delete i.manifest.pages[o],n.doneAssets.add(o);for(let w of d.discoveredAssets||[])Q(e,n,w,s,o);return s.warn(`Keeping previous incremental asset ${o} after fetch issue.`,{url:o,reason:h,preservedFromPreviousManifest:true,...m,phase:"download-assets"}),Ue(n,s),true};s.asset(`Fetching asset ${o}`,{url:o});try{let h=je(e,n.assetMap,o),m=h?await Le(h):null;if(h&&m)try{let D=await H(`fetch asset headers ${o}`,6e4,()=>t.head(o,{timeout:6e4})),b=D.headers();if(D.ok()&&ro(m,b)){let T=await zr(h);if(T!==null){let U=D.url()||o,q=ve(U,s,"asset-response",o);if(!q)return;let v=q.toString(),E=await dn(e,n.assetMap,v,T,n,s,b);E.wroteFile&&(te(a,e,E.outputPath),be(E.outputPath)&&Ie(a,E.outputPath)),n.doneAssets.add(o),s.info(`Reused existing asset ${o} based on response headers.`,{url:o,filePath:h,lastModified:b["last-modified"]||"",contentLength:b["content-length"]||"",phase:"download-assets"}),Ue(n,s);let F=Tr(c,b),z=d?.discoveredAssets?[...d.discoveredAssets]:[];if(F||d?.isText){let ee=T.toString("utf8"),O=st(e,v,ee,s,"asset:cached");(O.length>0||!d)&&(z=O);for(let Ae of z)Q(e,n,Ae,s,v);}if(i.trackManifest){let ee=F||!!d?.isText;i.manifest.assets[o]={url:o,outputPath:E.outputPath,isText:ee,contentType:cn(b)||d?.contentType||null,changeToken:l?.supported?l.token:null,tokenSource:l?.supported?l.tokenSource??null:null,discoveredAssets:z,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,unreferencedRuns:0,rewriteComplete:!ee},delete i.manifest.pages[o],(i.enabled||i.strictTargeted)&&ee&&await Pe(e,i);}return}}}catch{}let w=await H(`fetch asset ${o}`,6e4,()=>t.get(o,{timeout:6e4}));if(!w.ok()){if(y(`http-${w.status()}`,{status:w.status()}))return;if(i.strictTargeted)throw new Error(`Required content-sync asset returned HTTP ${w.status()}: ${o}`);s.skip("asset",o,w.status());return}let P=await H(`read asset response ${o}`,6e4,()=>w.body()),I=w.url()||o,j=ve(I,s,"asset-response",o);if(!j)return;let M=j.toString(),_=w.headers(),C=await dn(e,n.assetMap,M,P,n,s,_);C.wroteFile&&(te(a,e,C.outputPath),be(C.outputPath)&&Ie(a,C.outputPath)),n.doneAssets.add(o),Ue(n,s);let $=Tr(c,_),R=[];if($){let D=P.toString("utf8");R=st(e,M,D,s,`asset:${S.extname(c.pathname).toLowerCase()||_["content-type"]||"unknown"}`);for(let b of R)Q(e,n,b,s,M);}i.trackManifest&&(i.manifest.assets[o]={url:o,outputPath:C.outputPath,isText:$,contentType:cn(_),changeToken:l?.supported?l.token:null,tokenSource:l?.supported?l.tokenSource??null:null,discoveredAssets:R,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,unreferencedRuns:0,rewriteComplete:!$},delete i.manifest.pages[o],(i.enabled||i.strictTargeted)&&$&&await Pe(e,i));}catch(h){if(y("fetch-error",{error:String(h)}))return;if(s.error(`Failed asset ${o}`,{url:o,error:String(h)}),i.strictTargeted)throw h}finally{n.doneAssets.has(o)||(n.doneAssets.add(o),Ue(n,s));}}async function So(e,t,n,r,s,i){let a=Math.max(1,Number(e.assetDownloadConcurrency||e.concurrency||1)),c=Array.from({length:a},async()=>{for(;n.assetQueue.length>0;){let o=n.assetQueue.shift();o&&(n.queuedAssets.delete(o),await yo(e,t,n,o,r,s,i));}});await Promise.all(c);}function bo(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function pe(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function et(e){return Math.max(15e3,Math.min(6e4,pe(e)))}function Po(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function wn(e){return e.stats.pagesCompleted}function pn(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 an(e,t,n){let r=pn(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 H(e,t,n){let r;try{return await Promise.race([n(),new Promise((s,i)=>{r=globalThis.setTimeout(()=>{i(new it(e,t));},t);})])}finally{r!==void 0&&globalThis.clearTimeout(r);}}var it=class extends Error{constructor(n,r){super(`${n} timed out after ${bo(r)}.`);this.operation=n;this.timeoutMs=r;this.name="OperationTimeoutError";}operation;timeoutMs};async function vo(e,t){let n=Po(e);await t.evaluate(async r=>{await new Promise(s=>{let i=0,a=700,c=Date.now(),o=()=>{window.clearInterval(d),window.scrollTo(0,0),s();},d=window.setInterval(()=>{if(Date.now()-c>=r.maxDurationMs){o();return}window.scrollBy(0,a),i+=a;let l=document.body?.scrollHeight||0,u=document.documentElement?.scrollHeight||0,p=Math.max(l,u);i>=p+window.innerHeight&&o();},120);});},{maxDurationMs:n});}async function Co(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 vo(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function Ro(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 Io(e,t){return e.noJavaScriptRenderPathPrefixes.some(n=>fn(t,n))}async function xo(e,t,n,r,s=true){let i=new Set;if(s){let c=await t.evaluate(()=>{let o=new Set,d=["href","src","poster","data-src","data-lazy-src","data-original","data-bg","data-background","data-href"],l=new Set,u=["srcset","data-srcset","data-lazy-srcset"],p=f=>{f.querySelectorAll("*").forEach(g=>{for(let h of d){let m=g.getAttribute(h);m&&o.add(m);}for(let h of u){let m=g.getAttribute(h);m&&m.split(",").forEach(w=>{let P=w.trim().split(/\s+/)[0];P&&o.add(P);});}let y=g.getAttribute("style");y&&l.add(y),g.shadowRoot&&p(g.shadowRoot);});};return p(document),{attrs:[...o],styles:[...l]}});for(let o of c.attrs)for(let d of lo(o)){let l=J(e,d,n,r,"dom-attr");l&&W(e,l)&&i.add(l.toString());}for(let o of c.styles)for(let d of st(e,n,o,r,"dom-style"))i.add(d);}let a=await t.content();for(let c of st(e,n,a,r,"page-html"))i.add(c);return [...i]}async function $r(e,t,n,r,s){let i=ge(e,t);await Ye(i,n,"utf8");let a=await A.stat(i);s?.debug(`Saved page output ${t}`,{phase:"save-pages",url:t,outputPath:i,bytes:a.size}),r.stats.pagesSaved++;let c=Math.min(r.stats.pagesQueued,wn(r)+1);s&&(r.stats.pagesSaved%10===0||r.stats.pagesSaved===1)&&s.progress(`Page progress: processed ${c}, rendered ${r.stats.pagesRendered}, saved ${r.stats.pagesSaved}, discovered ${r.stats.pagesQueued}.`,{donePages:c,claimedPages:r.donePages.size,pagesRendered:r.stats.pagesRendered,pagesSaved:r.stats.pagesSaved,pagesQueued:r.stats.pagesQueued,pageQueue:r.pageQueue.length,phase:"save-pages"});}function Ao(e){let t=wn(e);return t%5===0||t===1||t===e.stats.pagesQueued}function To(e,t){let n=wn(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 ko(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 $o(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 ko(r),r}async function Eo(e,t,n,r,s,i,a,c){let o=await chromium.launch({headless:true}),d=pn(o);d.pid!==null&&n.debug(`Launched crawl worker browser PID ${d.pid}`,{browserPid:d.pid});try{for(;t.pageQueue.length>0;){o||(o=await chromium.launch({headless:!0}),d=pn(o),d.pid!==null&&n.debug(`Relaunched crawl worker browser PID ${d.pid}`,{browserPid:d.pid}));let l=o;if(e.maxPages>0&&t.donePages.size>=e.maxPages)break;let u=t.pageQueue.shift();if(!u)break;t.queuedPages.delete(u);let p=null,f=null,g=!1,y=[],h=new Set;try{let m=ve(u,n,"page","page-queue");if(!m)continue;let w=m.toString();if(u=w,t.queuedPages.delete(u),t.donePages.has(u))continue;t.donePages.add(u),i.enabled&&i.seenPages.add(u);let P=hn(e,u),I=Io(e,m.pathname);if(!Ce(m)||W(e,m)||qe(m)){if(W(e,m)){n.info(`Worker redirected non-page URL to asset queue: ${u}`,{url:u,source:"worker-guard"}),Q(e,t,u,n,"worker-guard");continue}n.reject("page",u,"guard rejected non-page URL before rendering","worker");continue}let j=i.strictTargeted?i.manifest.pages[u]:void 0;if(j?.lastSeenRunId===i.runId&&await Le(j.outputPath)){i.seenPages.add(u);for(let v of j.discoveredAssets||[])Q(e,t,v,n,u);te(a,e,j.outputPath),Ie(a,j.outputPath),n.info(`Resumed completed content-sync page ${u}`,{url:u,source:"content-sync-checkpoint"});continue}let M=await Oi(e,s,t,i,u,n);if(i.enabled&&r!=="single-url"&&r!=="content-sync"){let v=i.manifest.pages[u];if(M.action==="reuse"&&v){for(let E of v.discoveredAssets)Q(e,t,E,n,u);for(let E of v.discoveredPages)rt(e,t,E,n,u);v.lastSeenRunId=i.runId,v.sitemapLastmod=tt(t.sitemapLastmodByPage[u])??v.sitemapLastmod,M.changeToken?.supported&&(v.changeToken=M.changeToken.token,v.tokenSource=M.changeToken.tokenSource??v.tokenSource),n.info(`Incremental reuse skipped unchanged page ${u}`,{url:u,mode:"incremental",reason:M.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}p=await H(`create page context ${u}`,pe(e),()=>$o(l,e,I)),f=await H(`create page ${u}`,pe(e),()=>p.newPage()),y=await p.cookies();let _=!1,C=new Set;await f.route("**/*",async v=>{let E=v.request();try{let F=J(e,E.url(),e.sourceOrigin,n,"network-request");F&&W(e,F)&&(C.add(F.toString()),Q(e,t,F.toString(),n,u));}catch{}if(E.isNavigationRequest()&&E.frame()===f.mainFrame())try{let F=new URL(E.url()),z=new URL(w);if(F.hash="",z.hash="",F.href===z.href){if(_){n.warn(`Blocked same-page navigation/reload for ${u}`,{url:u,requestUrl:E.url()});try{await v.abort("aborted");}catch(ee){n.debug(`Ignored canceled route while blocking reload for ${u}`,{url:u,error:String(ee)});}return}_=!0;}}catch{}try{await v.continue();}catch(F){n.debug(`Ignored canceled network route for ${u}`,{url:u,requestUrl:E.url(),error:String(F)});}}),f.on("response",v=>{try{let F=J(e,v.url(),e.sourceOrigin,n,"network-response");F&&W(e,F)&&(C.add(F.toString()),Q(e,t,F.toString(),n,u));}catch{}let E=v.headerValues("set-cookie").then(F=>{for(let z of F)c.add(br(z,v.url()));}).catch(()=>{}).then(()=>{});h.add(E),E.finally(()=>h.delete(E));}),n.page(`Rendering ${u}`,{url:u});let $=null,R=null;try{if($=await f.goto(u,{waitUntil:"domcontentloaded",timeout:e.navigationTimeoutMs}),$&&$.ok())try{R=await H(`read response body ${u}`,pe(e),()=>$.text());}catch{R=null;}}catch(v){n.warn(`Navigation issue for ${u}; saving current DOM if available`,{url:u,error:String(v)});}if(r==="content-sync"&&$){let v=ve($.url(),n,"content-sync-final-response",u)?.toString();if(v&&v!==w){if(i.deleteOnMissingUrls.has(u)){await gn(e,i,a,u,i.deleteOnMissingUrls),n.info(`Removed stale content-sync archive route redirected to ${v}`,{url:u,finalResponseUrl:v,source:"content-sync-tombstone"});continue}throw new Error(`Required content-sync route redirected outside its planned URL: ${u} -> ${v}`)}}if(P){let v=$?.status()??null;if(v!==404){n.error(`Generated 404 request path returned unexpected status for ${u}`,{url:u,expectedStatus:404,status:v,requestPath:e.generated404RequestPath});continue}n.info(`Capturing rendered 404 page for ${u}`,{url:u,status:v,outputPath:ge(e,u)});}else if($&&!$.ok()){if(r==="content-sync"&&($.status()===404||$.status()===410)&&i.deleteOnMissingUrls.has(u)){await gn(e,i,a,u,i.deleteOnMissingUrls),n.info(`Removed stale content-sync archive page ${u}`,{url:u,status:$.status(),source:"content-sync-tombstone"}),await f.close();continue}if(r==="content-sync")throw new Error(`Required content-sync route returned HTTP ${$.status()}: ${u}`);n.skip("page",u,$.status(),t.pageDiscoverySources.get(u)),await f.close();continue}I?(n.info(`Rendering without JS execution for ${u}`,{url:u,mode:"no-js"}),await H(`wait for rendered page ${u}`,pe(e),()=>Ro(e,f))):await H(`wait for rendered page ${u}`,pe(e),()=>Co(e,f)),t.stats.pagesRendered++;let D=await H(`extract rendered assets ${u}`,pe(e),()=>xo(e,f,w,n,!I));for(let v of D)Q(e,t,v,n,u);let b=[...new Set([...D,...C])],T=R??await H(`capture rendered html ${u}`,pe(e),()=>f.content()),U=r!=="single-url"&&r!=="content-sync"&&!P?wo(e,u,T,n):[];if(r!=="single-url"&&r!=="content-sync"&&!P)for(let v of U)rt(e,t,v,n,u);await $r(e,u,T,t,n);let q=ge(e,u);if(te(a,e,q),Ie(a,q),i.trackManifest){let v=$?.headers();i.manifest.pages[u]={url:u,outputPath:q,contentType:cn(v),changeToken:M.changeToken?.supported?M.changeToken.token:null,tokenSource:M.changeToken?.supported?M.changeToken.tokenSource??null:null,sitemapLastmod:tt(t.sitemapLastmodByPage[u])??null,discoveredPages:U,discoveredAssets:b,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},(i.enabled||i.strictTargeted)&&await Pe(e,i);}}catch(m){if(g=m instanceof it,i.strictTargeted)throw n.error(`Failed required content-sync page ${u}`,{url:u,error:String(m)}),m;if(g)n.warn(`Skipped partial DOM for timed-out page ${u}`,{url:u,error:String(m),recovery:"recycle-worker-browser"});else try{let w=f?await H(`capture partial html ${u}`,pe(e),()=>f.content()):"";if(w&&w.trim()){await $r(e,u,w,t,n);let P=ge(e,u);if(te(a,e,P),Ie(a,P),i.trackManifest){let I=i.manifest.pages[u]??i.previousManifest.pages[u];i.manifest.pages[u]={url:u,outputPath:P,contentType:I?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:tt(t.sitemapLastmodByPage[u])??I?.sitemapLastmod??null,discoveredPages:I?.discoveredPages?[...I.discoveredPages]:[],discoveredAssets:I?.discoveredAssets?[...I.discoveredAssets]:[],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},(i.enabled||i.strictTargeted)&&await Pe(e,i);}n.warn(`Saved partial DOM for ${u}`,{url:u,error:String(m)});}}catch(w){w instanceof it&&(g=!0),n.error(`Could not save partial DOM for ${u}`,{url:u,error:String(w)});}n.error(`Failed page ${u}`,{url:u,error:String(m)});}finally{if(!g&&f&&await H(`drain network routes ${u}`,et(e),()=>f.unrouteAll({behavior:"wait"})).catch(m=>{g=!0,n.warn(`Could not drain network routes for ${u}`,{url:u,browserPid:d.pid,error:String(m),recovery:"recycle-worker-browser"});}),g&&(o=null,await an(l,n,`page operation timeout for ${u}`),await l.close().catch(()=>{})),h.size>0&&await Promise.allSettled([...h]),!g&&p)try{let m=await p.cookies();c.addAll(Pr(y,m));}catch{}t.stats.pagesCompleted++,Ao(t)&&To(t,n),!g&&f&&await H(`close page ${u}`,et(e),()=>f.close()).catch(m=>{g=!0,n.warn(`Timed out while closing page ${u}`,{url:u,browserPid:d.pid,error:String(m),recovery:"recycle-worker-browser"});}),!g&&p&&await H(`close page context ${u}`,et(e),()=>p.close()).catch(m=>{g=!0,n.warn(`Timed out while closing page context for ${u}`,{url:u,browserPid:d.pid,error:String(m),recovery:"recycle-worker-browser"});}),g&&o===l&&(o=null,await an(l,n,`page cleanup timeout for ${u}`),await l.close().catch(()=>{}));}}}finally{if(o){let l=o;await H("close worker browser",et(e),()=>l.close()).catch(u=>(n.warn("Timed out while closing crawl worker browser",{browserPid:d.pid,error:String(u)}),an(l,n,"browser.close timeout")));}}}async function Mo(e){try{let t=await A.readFile(e),r=(e.endsWith(".gz")?gunzipSync(t):t).toString("utf8").trim();if(!r)return [];try{let s=JSON.parse(r);if(Array.isArray(s))return s;if(s&&typeof s=="object")return [s]}catch{return r.split(/\r?\n/).map(s=>s.trim()).filter(Boolean).map(s=>{try{let i=JSON.parse(s);return i&&typeof i=="object"?i:null}catch{return null}}).filter(s=>s!==null)}return []}catch{return []}}function Er(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function Do(e){let t=String(e?.job?.command||"").trim(),n=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:n!=="incremental"}function Fo(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 Kr(e){try{let t=await A.readFile(e,"utf8"),n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function Mr(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function Oo(e,t){let n=Array.isArray(t?.artifacts)?t.artifacts.filter(r=>String(r?.role||"").trim()==="errors"&&String(r?.storedFileName||"").trim()!=="").sort((r,s)=>Mr(r)-Mr(s)).map(r=>S.join(e,String(r.storedFileName))):[];return [...new Set([...n,S.join(e,"errors.jsonl"),S.join(e,"errors.json"),S.join(e,"errors.jsonl.gz"),S.join(e,"errors.json.gz")])]}async function Dr(e){let t=await Kr(S.join(e,"job.json"));for(let n of Oo(e,t)){let r=await Mo(n);if(r.length>0)return r}return []}async function Uo(e){let t=S.join(e.logDir,"archive"),n;try{n=await A.readdir(t);}catch{return ""}let r="",s=0;for(let i of n){let a=S.join(t,i);if(!(await A.stat(a).catch(()=>null))?.isDirectory())continue;let o=await Kr(S.join(a,"job.json"));if(!Do(o))continue;let d=Fo(o);d>=s&&(s=d,r=a);}return r}async function Lo(e){let t=await Uo(e),n=t!==""?await Dr(t):await Dr(e.logDir),r=new Set;for(let s of n)if(Er(s.error)||Er(s.message)){let i=s.url;typeof i=="string"&&i&&r.add(i);}return [...r]}async function jo(e){let t=[];for(let n of e)if(n.startsWith("@")){let r=n.slice(1),s=await A.readFile(r,"utf8");t.push(...s.split(/\r?\n/).map(i=>i.trim()).filter(i=>i&&!i.startsWith("#")));}else t.push(n);return t}async function qo(e){if(!e)throw new Error("Content-sync crawl requires an immutable impact plan.");let t=JSON.parse(await A.readFile(e,"utf8"));return Je(t),t}function _o(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(/\/+$/,""),a=n.pathname.slice(i.length).replace(/^\/+/,""),c=String(r.paginationBase||"page").replace(/^\/+|\/+$/g,"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return n.pathname.startsWith(`${i}/`)&&new RegExp(`^${c}/\\d+/?$`).test(a)})}function Ct(e,t,n){let r=n==="page"?ge(e,t):Tt(e,t).originalFilePath;return Se(e.outputDir,r)}async function gn(e,t,n,r,s){let i=t.manifest.pages[r];if(!i)return;let a=Se(e.outputDir,i.outputPath);if(!a)throw new Error(`Manifest-owned page path escaped output root: ${r}`);let c=S.resolve(i.outputPath);Object.entries(t.manifest.pages).some(([d,l])=>d!==r&&!s.has(d)&&S.resolve(l.outputPath)===c)||(await A.rm(i.outputPath,{force:true}),n.deletedFiles.add(a)),delete t.manifest.pages[r];}function No(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 a of i?.discoveredAssets??[])try{_e(new URL(a))&&r.push(a);}catch{}}return n}async function Bo(e,t,n,r,s){let i=No(n.previousManifest,s);for(let a of i){if(t.successfulSitemaps.has(a))continue;let c=n.previousManifest.assets[a];if(!c)continue;let o=Se(e.outputDir,c.outputPath);if(!o)throw new Error(`Manifest-owned sitemap path escaped output root: ${a}`);await A.rm(c.outputPath,{force:true}),r.deletedFiles.add(o),delete n.manifest.assets[a];}await Pe(e,n);}async function Wo(e){try{let t=await A.readFile(S.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function Ho(e){let t=["crawl.log.jsonl","current-crawl-event.json","rejected.jsonl","ignored.jsonl","skipped-http.jsonl","errors.jsonl","timings.jsonl","rejected.json","ignored.json","skipped-http.json","errors.json","timings.json"];await A.mkdir(e,{recursive:true}),await Promise.all(t.map(async n=>{try{await A.unlink(S.join(e,n));}catch(r){if(r.code!=="ENOENT")throw r}}));}function Fr(e,t,n,r,s){let i=J(e,n,e.sourceOrigin,r,"manual-url");i&&(_e(i)?xt(e,t,i.toString(),r,s):W(e,i)?Q(e,t,i.toString(),r,s):Ce(i)?rt(e,t,i.toString(),r,s):r.reject("manual-url",i.toString(),"not page/sitemap/asset-like",s));}async function Gr(e=process.argv.slice(2)){let t=[],n=await ie(void 0,{onRemotePublisherConfigDiagnostic:b=>{t.push(b);}}),r=Ke(n.sitemapPaths),s=t.at(-1)??null,i=vi(e),a=i.mode==="content-sync"?await qo(i.contentSyncPlanPath):null;if(i.resumeRewrite&&i.mode!=="full")throw new Error("--resume-rewrite is only supported for full crawl/publish jobs.");let c=[];i.mode==="retry-timeouts"&&(c=await Lo(n)),i.mode==="single-url"&&(c=await jo(i.urls)),a&&(c=[...a.directRenderUrls,...a.archiveFamilyUrls]);let o=i.crawlMode==="incremental"&&i.mode==="full",d=o&&typeof n.subscriptionType=="string"&&n.subscriptionType.trim()!=="";if(a&&n.subscriptionType!=="PROFESSIONAL"&&n.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let l=(i.mode==="full"||i.mode==="single-url"||i.mode==="content-sync")&&!i.resumeRewrite,u=i.mode!=="full"||i.resumeRewrite||d,p=u?await Wo(n):{},f=d||i.mode==="single-url"||i.mode==="content-sync"?await ki(n):jr(),g=new Set(c),y=new Set;if(a){for(let b of a.archiveFamilies)if(b.foundPosts===0)for(let T of b.pageUrls)y.add(T);for(let b of Object.keys(f.pages))_o(b,a)&&!g.has(b)&&(c.push(b),y.add(b));}let h={enabled:d,trackManifest:l,manifest:un(f),previousManifest:un(f),runId:a?.jobId??`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve(),strictTargeted:!!a,requiredUrls:g,deleteOnMissingUrls:y};await Ho(n.logDir);let m=new yt(n.logDir,n.logLevel);if(s){let b={status:s.status,virtualAssetBaseUrl:s.virtualAssetBaseUrl,subscriptionType:s.subscriptionType??null,error:s.error,requests:s.requests,source:"remote-publisher-config"};s.status==="loaded"&&s.subscriptionType?m.info("Loaded remote WP Suite publisher configuration.",b):m.warn("Remote WP Suite publisher configuration is unavailable or has no active subscription type.",b);}if(o&&!d){let b="Incremental crawl requires an active remote publisher subscription; refusing to fall back to a destructive full crawl.";throw m.error(b,{requestedMode:i.crawlMode,subscriptionType:n.subscriptionType??null,source:"incremental-subscription-guard"}),await m.flush(),new Error(b)}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,successfulSitemaps:new Set,resolvedSitemapRoots:new Set,sitemapIndexUrls:new Set,sitemapLeafUrls:new Set,sitemapLastmodByPage:{},assetMap:{...p},assetVariantDigestsByOriginalPath:new Map,stats:{pagesQueued:0,pagesRendered:0,pagesCompleted:0,assetsQueued:0,sitemapsQueued:0,assetsSaved:0,pagesSaved:0}},P=Ti(),I=new bt,j=Ci();if(j&&!i.resumeRewrite&&await Pt(j,I.artifact()),await De(n),await er(n,{startedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir)}),u||await A.rm(n.outputDir,{recursive:true,force:true}),await A.mkdir(n.outputDir,{recursive:true}),a){let b=new Set([...a.deleteUrls,...h.deleteOnMissingUrls]);for(let T of a.deleteUrls)await gn(n,h,P,T,b);}if(i.resumeRewrite)m.info("Resuming final rewrite from existing output.",{phase:"rewrite-text",mode:i.mode,crawlMode:i.crawlMode});else {let b=await request.newContext({ignoreHTTPSErrors:n.ignoreHttpsErrors});try{if(m.mark("discovery"),i.mode==="full"?(r.forEach(U=>xt(n,w,U,m)),await kr(n,b,w,m,P,h),n.seedPaths.forEach(U=>Fr(n,w,U,m,"seed-path")),n.generated404RequestPath&&rt(n,w,n.generated404RequestPath,m,"generated-404-request-path")):(c.forEach(U=>Fr(n,w,U,m,"cli")),a?.sitemapUrls.forEach(U=>xt(n,w,U,m,"content-sync-impact")),await kr(n,b,w,m,P,h,i.mode==="content-sync",a?.sitemapUrls??[]),a&&await Bo(n,w,h,P,a.sitemapUrls)),m.endMark("discovery",{pages:w.pageQueue.length,assets:w.assetQueue.length,sitemaps:w.sitemapQueue.length}),m.summary(`Queued ${w.pageQueue.length} pages, ${w.assetQueue.length} assets, ${w.sitemapQueue.length} sitemaps.`,{mode:i.mode,crawlMode:i.crawlMode,queuedPages:w.pageQueue.length,queuedAssets:w.assetQueue.length,queuedSitemaps:w.sitemapQueue.length}),i.mode==="retry-timeouts"&&w.pageQueue.length===0&&w.assetQueue.length===0&&w.sitemapQueue.length===0){m.summary("No timed-out URLs were queued. Skipping retry crawl.",{mode:i.mode,crawlMode:i.crawlMode,queuedPages:0,queuedAssets:0,queuedSitemaps:0}),await m.flush(),j&&await Pt(j,I.artifact());return}m.mark("render-pages");let T=Array.from({length:Math.max(1,n.concurrency)},()=>Eo(n,w,m,i.mode,b,h,P,I));if(await Promise.all(T),j&&await Pt(j,I.artifact()),m.endMark("render-pages",{pages:w.stats.pagesCompleted}),m.mark("download-assets"),m.progress("Asset download phase started.",{phase:"download-assets",doneAssets:w.doneAssets.size,assetsQueued:w.stats.assetsQueued,assetQueue:w.assetQueue.length}),await Mi(n,b,h,[...w.assetQueue],m),await So(n,b,w,m,h,P),m.endMark("download-assets",{assets:w.doneAssets.size}),h.enabled&&n.maxPages===0&&await Li(n,w,h,m,P),i.mode==="full"){let U=await ho(n,w,m);for(let q of U)te(P,n,q);}}finally{await H("dispose crawl request context",et(n),()=>b.dispose()).catch(T=>{m.warn("Timed out while disposing crawl request context",{error:String(T)});});}}h.trackManifest&&await Pe(n,h),await A.writeFile(S.join(n.outputDir,"asset-map.json"),JSON.stringify(w.assetMap,null,2),"utf8"),JSON.stringify(p,null,2)!==JSON.stringify(w.assetMap,null,2)&&te(P,n,S.join(n.outputDir,"asset-map.json"));let M=i.mode==="single-url"||i.mode==="content-sync"?Qi(n,w):h.enabled&&!i.resumeRewrite?ji(n,h,P,p,w.assetMap):void 0;m.mark("rewrite-text");let _=i.mode==="single-url"||i.mode==="content-sync"?`Rewriting text files touched by URL crawl: 0/${M?.length??0}`:"Rewriting text files...";m.progress(_,{phase:"rewrite-text",index:0,totalFiles:M?.length,changedTextFiles:0}),await Ar(_);let C=Date.now(),$=await mt(n,w.assetMap,{files:M,previousAssetMap:p,onStart:({totalFiles:b,workerCount:T})=>{m.info(`Rewrite phase scanning ${b} text files.`,{phase:"rewrite-text",totalFiles:b,workerCount:T});},onProgress:async({index:b,totalFiles:T,changedTextFiles:U,file:q,changed:v})=>{v&&te(P,n,S.join(n.outputDir,q)),m.checkpoint(`Rewriting text file ${b}/${T}`,{phase:"rewrite-text",index:b,totalFiles:T,changedTextFiles:U,file:q}),m.debug(`${v?"Rewrote":"Checked unchanged"} text file ${b}/${T}: ${q}`,{phase:"rewrite-text",index:b,totalFiles:T,changedTextFiles:U,file:q,changed:v});let E=Date.now();if(!(b===1||b===T||b%50===0||E-C>=5e3))return;C=E;let z=`Rewriting text files: ${b}/${T}`;m.progress(z,{phase:"rewrite-text",index:b,totalFiles:T,changedTextFiles:U,file:q}),await Ar(z);}});h.trackManifest&&(qi(h,M),await Pe(n,h)),m.endMark("rewrite-text",{changedTextFiles:$});let R=a?[...P.deletedFiles].sort():h.enabled&&!i.resumeRewrite?await Ni(n,w,h,P,m):[],D=[...new Set((M||[]).map(b=>Se(n.outputDir,S.isAbsolute(b)?b:S.join(n.outputDir,b))).filter(b=>b!==null))].sort();if(a){let b=[...P.changedFiles].sort(),T=new Set(b),U=new Set(a.directRenderUrls.map(O=>Ct(n,O,"page")).filter(O=>!!O&&T.has(O))),q=new Set(a.archiveFamilyUrls.map(O=>Ct(n,O,"page")).filter(O=>!!O&&T.has(O))),v=new Set([...w.sitemapLeafUrls].map(O=>Ct(n,O,"asset")).filter(O=>!!O&&T.has(O))),E=new Set([...w.sitemapIndexUrls].map(O=>Ct(n,O,"asset")).filter(O=>!!O&&T.has(O))),F=new Set([...U,...q,...v,...E]),z=b.filter(O=>!F.has(O)),ee=[...new Set([...a.directRenderUrls,...a.archiveFamilyUrls,...w.resolvedSitemapRoots,...w.sitemapLeafUrls,...w.sitemapIndexUrls,...a.deleteUrls].map(O=>{let Ae=new URL(O);return `${Ae.pathname}${Ae.search}`}))].sort();await Yt(n,{schemaVersion:2,generatedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir),runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,changedFiles:b,deletedFiles:R,rewriteTargets:D,consumerId:a.consumerId,fromSequence:a.fromSequence,toSequence:a.toSequence,impactHash:a.impactHash,resolvedSitemapUrls:[...w.resolvedSitemapRoots],uploadGroups:{assets:z,content:[...U].sort(),listings:[...q].sort(),sitemapLeaves:[...v].sort(),sitemapIndexes:[...E].reverse()},invalidationPaths:ee});}else await Yt(n,{schemaVersion:1,generatedAt:new Date().toISOString(),outputDir:S.resolve(n.outputDir),runMode:i.mode,crawlMode:i.crawlMode,fullSyncRequired:!(h.enabled&&!i.resumeRewrite),changedFiles:h.enabled&&!i.resumeRewrite?[...P.changedFiles].sort():[],deletedFiles:h.enabled&&!i.resumeRewrite?R:[],rewriteTargets:h.enabled&&!i.resumeRewrite?D:[]});await nr(n),m.summary(i.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${$} text files.`:`Done. Rendered ${w.stats.pagesRendered} pages, processed ${w.doneSitemaps.size} sitemaps and ${w.doneAssets.size} assets.`,{mode:i.mode,crawlMode:i.crawlMode,resumeRewrite:i.resumeRewrite,...w.stats,pagesRendered:w.stats.pagesRendered,donePages:w.stats.pagesCompleted,claimedPages:w.donePages.size,doneSitemaps:w.doneSitemaps.size,doneAssets:w.doneAssets.size,changedTextFiles:$}),await m.flush();}function zo(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 ne(e,t,n){let r=new AbortController,s=globalThis.setTimeout(()=>{r.abort(new Error(`${e} timed out after ${zo(t)}.`));},t);try{return await n({abortController:r,httpOptions:{abortSignal:r.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(s);}}function Qo(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function kt(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 Jo(e,t){return {...e,...t??{}}}function Vo(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function Ne(e,t){let n=String(t??e.deploymentTargetOverride??"").trim();if(!Qo(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:Jo(e.s3,s.s3),cloudFront:Vo(e.cloudFront,s.cloudFront)}}}var es="wpsuite-sha256",ts="wpsuite-normalized-sha256",ra=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,Cn=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,sa=["SIGINT","SIGTERM"],Mt=new Set,$t=new Map,Zr=null;function ia(e){Mt.add(e);let t=false;return ()=>{t||(t=true,Mt.delete(e));}}async function oa(){let e=[...Mt];e.length!==0&&await Promise.allSettled(e.map(async t=>{Mt.delete(t),await A.rm(t,{recursive:true,force:true});}));}function aa(){if(!($t.size>0))for(let e of sa){let t=()=>{Zr||(Zr=oa().finally(()=>{for(let[n,r]of $t)process.off(n,r);$t.clear(),process.exit(1);}));};$t.set(e,t),process.on(e,t);}}aa();function ca(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 ns(e){return S.normalize(e).split(S.sep).join("/")}function Yr(e,t){let n=S.relative(S.resolve(e),S.resolve(t));return !n||n.startsWith("..")||S.isAbsolute(n)?null:ns(n)}async function ua(e,t,n){let r=ca(e.outputDir,t),s;try{s=await A.readFile(r,"utf8");}catch(l){return l.code==="ENOENT"?(n.warn("Deploy rewrite guard disabled because the crawl manifest is missing.",{manifestPath:r,source:"deploy-guard"}),null):(n.warn("Deploy rewrite guard disabled because the crawl manifest could not be read.",{manifestPath:r,error:l instanceof Error?l.message:String(l),source:"deploy-guard"}),null)}let i;try{i=JSON.parse(s);}catch(l){return n.warn("Deploy rewrite guard disabled because the crawl manifest is invalid JSON.",{manifestPath:r,error:l instanceof Error?l.message:String(l),source:"deploy-guard"}),null}let a=new Map,c=new Map,o=0,d=0;for(let[l,u]of Object.entries(i.pages||{})){let p=String(u?.outputPath||"").trim(),f=p?Yr(e.outputDir,p):null;if(f){let g=typeof u?.contentType=="string"&&u.contentType?u.contentType:null;g&&c.set(f,g);}!p||u?.rewriteComplete===true||f&&(o++,a.has(f)||a.set(f,{kind:"page",sourceUrl:l,outputPath:S.resolve(p),relativePath:f}));}for(let[l,u]of Object.entries(i.assets||{})){let p=String(u?.outputPath||"").trim(),f=u?.isText===true,g=p?Yr(e.outputDir,p):null;if(g){let y=typeof u?.contentType=="string"&&u.contentType?u.contentType:null;y&&c.set(g,y);}!p||!f||u?.rewriteComplete===true||g&&(d++,a.has(g)||a.set(g,{kind:"asset",sourceUrl:l,outputPath:S.resolve(p),relativePath:g}));}return {manifestPath:r,byRelativePath:a,contentTypeByRelativePath:c,pendingPages:o,pendingTextAssets:d}}function la(e){return e&&(Cn.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)?"__hex__":/^[0-9]{8,}$/.test(e)?"__num__":/^(?=.*[a-z])(?=.*\d)[a-z0-9]{8,}$/i.test(e)?"__alnum__":e)}function Sn(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,n)=>n%2===1?t:la(t)).join("")}function da(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,n)=>n%2===1?t:Cn.test(t)?"__uuid__":/^[0-9a-f]{6,}$/i.test(t)?"__hex__":/^[0-9]{6,}$/.test(t)?"__num__":/^[a-z0-9_-]{6,}$/i.test(t)?"__id__":t).join("")}function Dt(e,t){return Array.isArray(e)?e.map(n=>Dt(n,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Dt(r,n)])):typeof e!="string"?e:t&&ra.test(t)?da(e):Cn.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?Sn(e):e}function pa(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function ga(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(Dt(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),a=JSON.stringify(Dt(i));return Buffer.from(a,"utf8").toString("base64")}catch{}return t}function fa(e,t){let n=e.toLowerCase();return n==="class"?t.split(/(\s+)/).map((r,s)=>s%2===1?r:Sn(r)).join(""):n==="id"||n==="for"||n==="aria-controls"||n==="aria-labelledby"||n==="aria-describedby"||n==="aria-owns"||n==="aria-activedescendant"||n==="name"?Sn(t):n==="href"||n==="src"?pa(t):ga(n,t)}function ma(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,a,c,o)=>{let d=fa(a,o);return ` ${a}=${c}${d}${c}`});return `<${n}${s}>`})}function yn(e){let t=S.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(S.basename(e))}function Et(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function ha(e,t,n,r){let s=new Map,i,a=0;do{a++;let c=await ne(`S3 list objects page ${a} for s3://${t}/${n||""}`,3e5,({httpOptions:o})=>e.send(new ListObjectsV2Command({Bucket:t,Prefix:n||void 0,ContinuationToken:i}),o));for(let o of c.Contents||[]){if(!o.Key)continue;let d=(o.ETag||"").replace(/^"|"$/g,"").toLowerCase(),l=Number(o.Size??0);s.set(o.Key,{etag:d,size:l});}i=c.NextContinuationToken,r.debug(`Listed S3 keys page ${a}: ${s.size} keys so far`);}while(i);return s}async function wa(e,t,n,r){if(r.has(n))return r.get(n)??null;try{let s=await ne(`S3 head object ${n}`,3e5,({httpOptions:a})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),a)),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 ya(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 a=s.slice(i,i+1e3);if(a.length===0)continue;let c=await ne(`S3 delete objects batch ${Math.floor(i/1e3)+1}`,3e5,({httpOptions:o})=>e.send(new DeleteObjectsCommand({Bucket:t,Delete:{Objects:a.map(d=>({Key:d}))}}),o));if(c.Errors&&c.Errors.length>0){let o=c.Errors.map(d=>`${d.Key||"(unknown)"}: ${d.Code||"DeleteFailed"}`);throw new Error(`S3 reported ${o.length} object deletion error(s): ${o.join(", ")}`)}r.info(`Deleted batch of ${a.length} object(s).`);for(let o of a)r.debug(` deleted: ${o}`);}return s}function Sa(e){return createHash("md5").update(e).digest("hex")}function Xr(e){return createHash("sha256").update(e).digest("hex")}function bn(e){return createHash("sha256").update(ma(e.toString("utf8"))).digest("hex")}async function ba(e,t,n,r){if(r.has(n))return r.get(n)??null;try{let a=((await ne(`S3 head object metadata ${n}`,3e5,({httpOptions:c})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),c))).Metadata?.[es]||"").trim().toLowerCase()||null;return r.set(n,a),a}catch{return r.set(n,null),null}}async function Pa(e,t,n,r,s){if(r.has(n))return r.get(n)??null;try{let a=((await ne(`S3 head object normalized metadata ${n}`,3e5,({httpOptions:c})=>e.send(new HeadObjectCommand({Bucket:t,Key:n}),c))).Metadata?.[ts]||"").trim().toLowerCase();if(a)return r.set(n,a),a}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 a=await(await ne(`S3 get object ${n}`,3e5,({httpOptions:o})=>e.send(new GetObjectCommand({Bucket:t,Key:n}),o))).Body?.transformToByteArray(),c=a?bn(Buffer.from(a)):null;return s.set(n,c),r.set(n,c),c}catch{return s.set(n,null),r.set(n,null),null}}function va(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function Ca(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 Ra(e,t,n,r){let s=S.join(e,"asset-map.json"),i;try{i=await A.readFile(s,"utf8");}catch(o){if(o.code==="ENOENT")return;throw o}let a=JSON.parse(i);if(!a||typeof a!="object")return;let c=Object.fromEntries(Object.entries(a).map(([o,d])=>{let l=String(d??"");return t.urlRewriteMode==="absolute"&&t.targetOrigin&&n.targetOrigin&&t.targetOrigin!==n.targetOrigin&&(l=l.split(t.targetOrigin).join(n.targetOrigin)),l=Ca(l,r),[o,l]}));await A.writeFile(s,JSON.stringify(c,null,2),"utf8");}async function Ia(e,t,n,r,s,i){let a=e.targetOrigin!==t.targetOrigin,c=Object.keys(r).length>0;if(!n||!a&&!c)return {outputDir:e.outputDir,cleanup:async()=>{}};if(a&&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 o=S.join(S.dirname(e.outputDir),`.deploy-profile-${va(n)}-${Date.now()}`),d=ia(o);s.info(`Preparing deployment profile "${n}" from existing crawl output to ${o}...`);try{if(await A.rm(o,{recursive:!0,force:!0}),i){await A.mkdir(o,{recursive:!0});for(let f of i){let g=S.join(e.outputDir,f),y=S.join(o,f);await A.mkdir(S.dirname(y),{recursive:!0}),await A.copyFile(g,y);}}else await A.cp(e.outputDir,o,{recursive:!0});let l={...e,sourceOrigin:e.targetOrigin,targetOrigin:t.targetOrigin,extraReplacements:r,outputDir:o},u=1;s.info(`Rewriting text files for deployment profile "${n}"...`);let p=await mt(l,{},{files:i,onStart:({totalFiles:f,workerCount:g})=>{u=g,s.info(`Rewriting ${f} text file(s) for deployment profile "${n}" with ${g} worker(s).`);},onProgress:({index:f,totalFiles:g,changedTextFiles:y,file:h,changed:m})=>{let P=`Rewriting [${f}/${g}] ${h} (${m?"rewrote":"checked"}; ${y} changed so far)`;g<=200||f<=5||f%10===0||f===g?(s.progress(P,{file:h,index:f,totalFiles:g,changed:m,changedTextFiles:y,workerCount:u}),s.info(P)):s.debug(P);}});return await Ra(o,e,t,r),s.info(`Prepared deployment profile "${n}" in ${o} (${p} rewritten text file(s)).`),{outputDir:o,cleanup:async()=>{d(),await A.rm(o,{recursive:!0,force:!0});}}}catch(l){throw s.error(`Failed to prepare deployment profile "${n}" temporary output.`,{tempDir:o,outputDir:e.outputDir,error:l instanceof Error?l.message:String(l),...l instanceof Error&&l.stack?{stack:l.stack}:{}}),await A.rm(o,{recursive:true,force:true}).catch(()=>{}),d(),await s.flush().catch(()=>{}),l}}async function rs(e=process.argv.slice(2)){let t=await ie(),n=kt(e),r=Ne(t,n),s=S.resolve(r.config.logDir||"logs"),i=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",a=i?S.join(S.resolve(i),"deploy-diff.json"):"",c=new Oe(s,"deploy.log.jsonl",r.config.logLevel??"info"),o=r.profile?.extraReplacements??{},d=async()=>{};try{let l=await Me(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 tr(t);if(p)throw new Error(`Deployment blocked: the crawl started at ${p.startedAt} did not complete its final rewrite. Run a successful crawl or resume the rewrite before deploying.`);let f=await Ia(t,r.config,r.name,o,c,l?.schemaVersion===2?l.changedFiles:void 0);d=f.cleanup;let g={...r.config,outputDir:f.outputDir},y=g.s3SyncMode??"sdk-upload-delete";if(l?.schemaVersion===2&&l.deletedFiles.length>0&&y!=="sdk-upload-delete")throw new Error("Content-sync tombstones require the sdk-upload-delete S3 sync mode.");let h=l?.schemaVersion!==2&&f.outputDir!==t.outputDir&&(t.targetOrigin!==r.config.targetOrigin||Object.keys(o).length>0),m=!!l&&!l.fullSyncRequired&&!h;if(l?.schemaVersion===2&&!m)throw new Error("Content-sync deployment cannot widen into a full-output deployment.");r.name&&c.info(`Using deployment profile: ${r.name}`),c.info(`Starting deploy \u2014 s3://${g.s3.bucket}/${g.s3.prefix||""} (region: ${g.s3.region})`),c.info(`S3 sync mode: ${y}`),l&&l.fullSyncRequired?c.info("Deploy plan requests a full sync; scanning the whole output tree."):l&&h?c.info("Ignoring incremental deploy plan because deployment-profile rewrites require a full sync."):m&&c.info(`Using incremental deploy plan: ${l.changedFiles.length} changed file(s), ${l.deletedFiles.length} deleted file(s).`),c.mark("deploy");let w=new S3Client({region:g.s3.region}),P=f.outputDir===t.outputDir?await ua(t,i,c):null,I=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 k=[...new Set(I)],K=[...new Set(l.changedFiles)];if(k.length!==K.length||K.some(x=>!k.includes(x)))throw new Error("Content-sync deploy-plan upload groups do not cover the exact changed-file set.")}let j=m?(await Promise.all(I.map(async k=>{try{return (await A.stat(S.join(g.outputDir,k))).isFile()?k:null}catch{if(l?.schemaVersion===2)throw new Error(`Content-sync planned upload is missing: ${k}`);return null}}))).filter(k=>k!==null):await Hs(["**/*"],{cwd:g.outputDir,onlyFiles:!0,dot:!0}),M=[],_=[],C=j.filter(k=>{let K=P?.byRelativePath.get(ns(k));if(!K)return !0;let x=Et(g.s3.prefix,k);return M.push(k),_.push(x),c.reject(K.kind,K.sourceUrl||k,"rewrite not completed; deploy upload blocked","deploy-guard",{file:k,key:x,outputPath:K.outputPath,manifestPath:P?.manifestPath}),!1}),$=new Set((m?C:j).map(k=>Et(g.s3.prefix,k)));P&&(P.pendingPages>0||P.pendingTextAssets>0)&&c.info(`Deploy rewrite guard loaded ${P.pendingPages} pending page(s) and ${P.pendingTextAssets} pending text asset(s) from crawl manifest.`,{manifestPath:P.manifestPath,pendingPages:P.pendingPages,pendingTextAssets:P.pendingTextAssets,source:"deploy-guard"}),M.length>0&&c.warn(`Deploy rewrite guard blocked ${M.length} file(s) from upload because final crawl rewrite is incomplete.`,{rejected:M.length,manifestPath:P?.manifestPath,source:"deploy-guard"}),m?c.info(`Using ${C.length} eligible planned changed file(s) from deploy plan for upload${M.length>0?` (${M.length} blocked by deploy rewrite guard)`:""}.`):c.info(`Found ${j.length} file(s) in output directory "${g.outputDir}"${M.length>0?`; ${C.length} remain eligible for upload after deploy rewrite guard filtering`:""}.`),c.progress("Deploy preflight: comparing local output with remote S3 state.",{phase:"deploy",mode:y,totalFiles:C.length,scannedFiles:j.length,rejected:M.length,deploymentProfile:r.name||"",s3Bucket:g.s3.bucket,s3Prefix:g.s3.prefix||"",targetedPlan:m,deployGuardEnabled:f.outputDir===t.outputDir});let R=0,D=0,b=0,T=[],U=[],q=[],v=[],E=[],F=new Map,z=new Map,ee=new Map,O=new Map,Ae=new Map;m||(c.info("Listing existing S3 objects to detect unchanged files..."),F=await ha(w,g.s3.bucket,g.s3.prefix,c),c.info(`Found ${F.size} existing key(s) in S3.`));let ds=async k=>F.has(k)?F.get(k)??null:m?wa(w,g.s3.bucket,k,z):null;for(let k of C){let K=S.join(g.outputDir,k),x=Et(g.s3.prefix,k),re=P?.contentTypeByRelativePath.get(k),We=re&&re!=="application/octet-stream"?re:na.lookup(k)||re||"application/octet-stream",ps=yn(k)?g.s3.htmlCacheControl:g.s3.assetCacheControl,B=R+D+b+1;C.length<=200||B<=5||B%10===0||B===C.length?(c.progress(`Uploading [${B}/${C.length}] ${x} (${We})`,{file:k,key:x,index:B,totalFiles:C.length,contentType:We,mode:y}),c.info(`Uploading [${B}/${C.length}] ${x} (${We})`)):c.debug(`Uploading [${B}/${C.length}] ${x} (${We})`);try{let se=await A.readFile(K),He=await ds(x),ze=null,Te=null;if(He){let Ut=se.byteLength;if(He.size===Ut){let at=He.etag.includes("-");if(He.etag!==""&&!at){let gs=Sa(se);if(He.etag===gs){D++,C.length<=200||D<=5||D%25===0?(c.progress(`Skipped unchanged [${B}/${C.length}] ${x}`,{file:k,key:x,index:B,totalFiles:C.length,uploaded:R,skipped:D,failed:b,mode:y,reason:"etag-md5-match"}),c.info(`Skipped unchanged [${B}/${C.length}] ${x}`)):c.debug(`Skipped unchanged [${B}/${C.length}] ${x}`),U.push(x);continue}}ze=Xr(se);let kn=await ba(w,g.s3.bucket,x,ee);if(kn&&kn===ze){D++,C.length<=200||D<=5||D%25===0?(c.progress(`Skipped unchanged [${B}/${C.length}] ${x}`,{file:k,key:x,index:B,totalFiles:C.length,uploaded:R,skipped:D,failed:b,mode:y,reason:"metadata-sha256-match"}),c.info(`Skipped unchanged [${B}/${C.length}] ${x}`)):c.debug(`Skipped unchanged [${B}/${C.length}] ${x}`),U.push(x);continue}}if(yn(k)){Te=bn(se);let at=await Pa(w,g.s3.bucket,x,O,Ae);if(at&&at===Te){D++,C.length<=200||D<=5||D%25===0?(c.progress(`Skipped semantically unchanged [${B}/${C.length}] ${x}`,{file:k,key:x,index:B,totalFiles:C.length,uploaded:R,skipped:D,failed:b,mode:y,reason:"normalized-html-match"}),c.info(`Skipped semantically unchanged [${B}/${C.length}] ${x}`)):c.debug(`Skipped semantically unchanged [${B}/${C.length}] ${x}`),U.push(x);continue}}}ze=ze??Xr(se),Te=Te??(yn(k)?bn(se):null),await ne(`S3 upload ${x}`,9e5,({abortController:Ut})=>new Upload({client:w,abortController:Ut,params:{Bucket:g.s3.bucket,Key:x,Body:se,ContentType:We,CacheControl:ps,Metadata:{[es]:ze,...Te?{[ts]:Te}:{}}}}).done()),R++,T.push(x),(R%25===0||R===C.length)&&(c.progress(`Uploaded ${R}/${C.length} file(s)\u2026`,{uploaded:R,skipped:D,failed:b,totalFiles:C.length,mode:y}),c.info(`Uploaded ${R}/${C.length} file(s)\u2026`));}catch(se){b++,q.push(x),c.error(`Failed to upload ${x}: ${se.message}`,{key:x,error:String(se)});}}if(c.info(`Upload complete: ${R} uploaded, ${D} skipped unchanged, ${_.length} rejected by guard, ${b} failed.`),q.length>0||_.length>0)throw new Error(`Deployment stopped before deletion because ${q.length} upload(s) failed and ${_.length} upload(s) were rejected.`);if(y==="sdk-upload-delete"){let k=new Set((l?.deletedFiles??[]).map(x=>Et(g.s3.prefix,x))),K=[...k].filter(x=>!$.has(x));if(!m&&(E=[...F.keys()].filter(re=>!$.has(re)).filter(re=>!k.has(re)),E.length>0)){c.warn(`Protected ${E.length} remote-only S3 object(s) from deletion because the crawl did not provide explicit tombstones.`,{protected:E.length,source:"deploy-delete-guard"});for(let re of E)c.debug(` protected remote-only object: ${re}`);}v=await ya(w,g.s3.bucket,m?K:K.filter(x=>F.has(x)),c);}else c.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion.");a&&(await A.mkdir(S.dirname(a),{recursive:!0}),await A.writeFile(a,JSON.stringify({generatedAt:new Date().toISOString(),mode:y,summary:{totalFiles:j.length,eligibleFiles:C.length,uploaded:T.length,skipped:U.length,rejected:_.length,failed:q.length,deleted:v.length,protected:E.length,...r.name?{profile:r.name}:{}},uploadedKeys:T,skippedKeys:U,rejectedKeys:_,failedKeys:q,deletedKeys:v,protectedRemoteOnlyKeys:E},null,2),"utf8")),l?.schemaVersion!==2&&await De(t),c.endMark("deploy"),await c.flush();}finally{await d().catch(()=>{});}}function Aa(e){let t=e;return t.endsWith("/")?t+="index.html":S.posix.basename(t).includes(".")||(t+="/index.html"),t}function Ta(e,t){let n=t.trim().replace(/^\/+|\/+$/g,"");if(!n)return null;let r=`/${n}`;return e===r||e.startsWith(`${r}/`)?e:`${r}${e.startsWith("/")?e:`/${e}`}`}function ss(e,t){let n=new Set;for(let r of e){let s=new URL(r,"https://content-sync.invalid");if(s.origin!=="https://content-sync.invalid")continue;let i=`${s.pathname}${s.search}`,a=Aa(s.pathname);n.add(i),n.add(`${a}${s.search}`);let c=Ta(a,t);c&&n.add(`${c}${s.search}`);}return [...n].sort()}function Ma(){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 Rn(e,t){if(!e)return;await A.mkdir(S.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await A.writeFile(n,JSON.stringify({...t,updatedAt:new Date().toISOString()},null,2),"utf8"),await A.rename(n,e);}async function Da(e,t,n,r){if(!e)return null;try{let s=JSON.parse(await A.readFile(e,"utf8"));if(s.schemaVersion!==1||s.distributionId!==t||s.impactHash!==n||!Array.isArray(s.batches))throw new Error("Content-sync invalidation state does not match the deploy plan.");let i=s.batches.flatMap(a=>a.paths);return i.length!==r.length||i.some((a,c)=>a!==r[c])?null:s}catch(s){if(s.code==="ENOENT")return null;throw s}}function Fa(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 os(e=process.argv.slice(2)){let t=await ie(),n=kt(e),r=Ne(t,n),s=r.config,i=new Oe(s.logDir||"logs","invalidate.log.jsonl",s.logLevel??"info"),a=e.includes("--content-sync"),c=await Me(t);if(a&&c?.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 o=c?.schemaVersion===2?c.invalidationPaths:s.cloudFront.invalidationPaths.length>0?s.cloudFront.invalidationPaths:["/*"],d=c?.schemaVersion===2?ss(o,s.s3.prefix||""):o;if(c?.schemaVersion===2&&d.some(g=>g==="/*"))throw new Error("Content-sync cannot use a whole-distribution invalidation.");if(d.length===0){i.info("The targeted deploy plan has no CloudFront paths to invalidate."),await i.flush();return}let l=s.cloudFront.distributionId,u=new CloudFrontClient({region:"us-east-1",maxAttempts:5});if(i.mark("invalidate"),c?.schemaVersion!==2){let g=`smartcloud-static-publisher-${Date.now()}`;await ne(`CloudFront invalidation for distribution ${l}`,3e5,({httpOptions:y})=>u.send(new CreateInvalidationCommand({DistributionId:l,InvalidationBatch:{CallerReference:g,Paths:{Quantity:d.length,Items:d}}}),y)),i.endMark("invalidate"),await i.flush();return}let p=Ma(),f=await Da(p,l,c.impactHash,d);if(!f){let g=createHash("sha256").update(JSON.stringify(d)).digest("hex");f={schemaVersion:1,distributionId:l,impactHash:c.impactHash,updatedAt:new Date().toISOString(),batches:Fa(d).map((y,h)=>({index:h,callerReference:`wpsuite-content-sync-${c.impactHash.slice(0,24)}-${g.slice(0,24)}-${h}`,paths:y,invalidationId:null,status:"pending"}))},await Rn(p,f);}for(let g of f.batches){if(!g.invalidationId){let y=await ne(`CloudFront targeted invalidation batch ${g.index+1}`,3e5,({httpOptions:m})=>u.send(new CreateInvalidationCommand({DistributionId:l,InvalidationBatch:{CallerReference:g.callerReference,Paths:{Quantity:g.paths.length,Items:g.paths}}}),m)),h=String(y.Invalidation?.Id||"").trim();if(!h)throw new Error("CloudFront did not return an invalidation ID.");g.invalidationId=h,g.status="created",await Rn(p,f);}await waitUntilInvalidationCompleted({client:u,maxWaitTime:900,minDelay:2,maxDelay:15},{DistributionId:l,Id:g.invalidationId}),g.status="completed",await Rn(p,f),i.info(`CloudFront invalidation batch ${g.index+1}/${f.batches.length} completed.`,{invalidationId:g.invalidationId,pathCount:g.paths.length});}i.endMark("invalidate"),await i.flush();}function Ot(e){let t=new URL(e);return t.hash="",t.href}function as(e,t,n){let r=new Set([...t].map(o=>Ot(o))),s=new Map,i=new Map,a=o=>{s.set(Ot(o),o);},c=o=>{if(!o)return;let d=Ot(o);s.has(d)||i.set(d,o);};for(let o of e.deleteUrls)a(o);for(let o of e.archiveFamilies)if(o.foundPosts===0)for(let d of o.pageUrls)r.has(Ot(d))||a(d);c(e.directRenderUrls[0]);for(let o of e.archiveFamilies)c(o.pageUrls[0]),c(o.pageUrls.at(-1));for(let o of n)c(o);return {expectedAvailable:[...i.values()],expectedMissing:[...s.values()]}}var us=["claimed","impact-planned","rendered","deployed","invalidated","verified","acknowledged"];function An(){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 Be(e,t){return us.indexOf(e)>=us.indexOf(t)}async function me(e,t,n,r,s={}){let i={timestamp:new Date().toISOString(),eventType:t,status:t.endsWith("failed")?"failed":"success",actorSource:"content-sync",jobId:n.id||"",command:"content-sync",message:r,details:s};await A.mkdir(e,{recursive:true}),await A.appendFile(S.join(e,"audit-events.jsonl"),`${JSON.stringify(i)}
|
|
14
|
+
`,"utf8");}function Ua(e){return Qe({postTypes:e.postTypes??[],listingPaths:e.listingPaths??[],includeSubsites:e.includeSubsites,includePostTypeArchives:e.includePostTypeArchives,includeTaxonomyArchives:e.includeTaxonomyArchives,includeAuthorArchives:e.includeAuthorArchives,includeDateArchives:e.includeDateArchives,includePostsPage:e.includePostsPage,includeSitemapChain:e.includeSitemapChain})}function La(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 Tn(e,t){if(e.subscriptionType!=="PROFESSIONAL"&&e.subscriptionType!=="AGENCY")throw new Error("Content-sync requires an active Professional or Agency subscription.");let n=Ua(t),r=Ne(e,t.deploymentProfile),s=r.name||"",i=Mn(e.sourceOrigin,String(t.id||""),n),a=Dn({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??{}}),c=Fn({siteId:e.wpsuite?.siteSettings?.siteId,accountId:e.wpsuite?.siteSettings?.accountId,sourceOrigin:e.sourceOrigin,ruleId:String(t.id||""),targetFingerprint:a}),o=`content-sync:${String(t.id||"")}:${ue({scopeFingerprint:i,targetFingerprint:a}).slice(0,32)}`,d=new ut({sourceOrigin:e.sourceOrigin,runtimeToken:String(e.wpsuite?.runtimeToken||""),ignoreHttpsErrors:e.ignoreHttpsErrors}),l=await d.releaseFingerprint(n.includeSubsites),u=En({wordpressFingerprint:l,targetFingerprint:a,sourceOrigin:e.sourceOrigin,sitemapPaths:Ke(e.sitemapPaths),blockedPathPrefixes:e.blockedPathPrefixes,assetPathPrefixes:e.assetPathPrefixes,noJavaScriptRenderPathPrefixes:e.noJavaScriptRenderPathPrefixes,urlRewriteMode:e.urlRewriteMode});return {rule:t,scope:n,deployment:r,deploymentProfile:s,scopeFingerprint:i,targetFingerprint:a,consumerId:c,coalesceKey:o,client:d,releaseFingerprint:u}}async function ja(e){let t=An(),n=lt(t),r=await ie(),s=(r.scheduler?.rules??[]).filter(d=>d.command==="content-sync"&&d.enabled!==false);if(s.length===0)return 0;let i=await Nt(n),a=await dt(n),c=await _t(n),o=0;for(let d of s){let l=await Tn(r,d),u=c.entries[l.coalesceKey];if(!u||u.releaseJobId!==e||u.scopeFingerprint!==l.scopeFingerprint||u.targetFingerprint!==l.targetFingerprint||u.releaseFingerprint!==l.releaseFingerprint)throw new Error(`The normal release has no matching pre-crawl content-sync cutoff for rule ${String(d.id||"")}.`);let p=ue({releaseJobId:e,releaseFingerprint:l.releaseFingerprint,scopeFingerprint:l.scopeFingerprint,targetFingerprint:l.targetFingerprint,sequence:u.sequence}),f=await l.client.establishBaseline({consumerId:l.consumerId,scopeFingerprint:l.scopeFingerprint,baselineId:p,postTypes:l.scope.postTypes,includeSubsites:l.scope.includeSubsites,sequence:u.sequence}),g={schemaVersion:1,ruleId:String(d.id||""),consumerId:l.consumerId,coalesceKey:l.coalesceKey,scopeFingerprint:l.scopeFingerprint,targetFingerprint:l.targetFingerprint,releaseFingerprint:l.releaseFingerprint,baselineId:p,deploymentProfile:l.deploymentProfile,committedSequence:f.committedSequence,releaseJobId:e,verifiedAt:new Date().toISOString()};i.entries[l.coalesceKey]=g;let y=a.rules[l.coalesceKey];a.rules[l.coalesceKey]={ruleId:String(d.id||""),consumerId:l.consumerId,coalesceKey:l.coalesceKey,committedSequence:f.committedSequence,observedHeadSequence:f.headSequence,lag:Math.max(0,f.headSequence-f.committedSequence),lastSuccessfulJobId:y?.lastSuccessfulJobId||e,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:f.headSequence>f.committedSequence,retryAttempt:0,nextRetryAt:null,lastError:null,baselineStatus:"ready",baselineReason:null};let h=await Hn(n,l.coalesceKey);await me(t,"content-sync-baseline-established",{id:e},"A normal release established a verified content-sync baseline.",{ruleId:d.id,consumerId:l.consumerId,committedSequence:f.committedSequence,supersededCurrent:h}),o++;}return await qn(n,i),await pt(n,a),await A.rm(n.releaseCutoff,{force:true}),o}async function qa(e){let t=An(),n=lt(t),r=await ie(),s=(r.scheduler?.rules??[]).filter(c=>c.command==="content-sync"&&c.enabled!==false);if(s.length===0)return 0;let i=await _t(n),a=0;for(let c of s){let o=await Tn(r,c),d=Object.values(i.entries).find(p=>p.releaseJobId===e&&p.ruleId===String(c.id||""));if(d){if(d.coalesceKey===o.coalesceKey&&d.scopeFingerprint===o.scopeFingerprint&&d.targetFingerprint===o.targetFingerprint&&d.releaseFingerprint===o.releaseFingerprint){a++;continue}throw new Error(`The normal release scope changed after its journal cutoff was captured for rule ${String(c.id||"")}. Start a new normal publish instead of resuming this release.`)}let l=await o.client.unboundHead(o.scope.postTypes,o.scope.includeSubsites),u={schemaVersion:1,releaseJobId:e,ruleId:String(c.id||""),coalesceKey:o.coalesceKey,scopeFingerprint:o.scopeFingerprint,targetFingerprint:o.targetFingerprint,releaseFingerprint:o.releaseFingerprint,sequence:l.headSequence,capturedAt:new Date().toISOString()};i.entries[o.coalesceKey]=u,await me(t,"content-sync-release-cutoff-captured",{id:e},"A normal release captured its pre-crawl content-sync journal cutoff.",{ruleId:c.id,consumerId:o.consumerId,sequence:l.headSequence}),a++;}return await jn(n,i),a}async function _a(e,t){let n=JSON.parse(await A.readFile(S.join(e,"current-run.json"),"utf8"));if(n.id!==t||n.command!=="content-sync"||!String(n.ruleId||"").trim())throw new Error("The active queue job is not the requested content-sync job.");return n}async function xn(e,t,n=0){let r=e.protocol==="https:"?Ln:bs,s=e.protocol==="https:"?new Ln.Agent({rejectUnauthorized:!t}):void 0;return new Promise((i,a)=>{let c=r.get(e,{agent:s,timeout:3e4,headers:{"user-agent":"WP-Suite-Content-Sync/1"}},o=>{let d=o.statusCode??500,l=o.headers.location;if(d>=300&&d<400&&l&&n<5){o.resume(),xn(new URL(l,e),t,n+1).then(i,a);return}let u=[],p=0;o.on("data",f=>{p+=f.byteLength,p<=1048576&&u.push(f);}),o.on("error",a),o.on("end",()=>i({status:d,body:Buffer.concat(u).toString("utf8")}));});c.on("timeout",()=>c.destroy(new Error(`Verification timed out: ${e}`))),c.on("error",a);})}async function Na(e,t,n,r){let s=t.deployment.config.targetOrigin;if(!/^https?:\/\//i.test(s))throw new Error("Content-sync verification requires an absolute HTTP(S) target origin.");let i=JSON.parse(await A.readFile(r,"utf8")),a=new Set;for(let[d,l]of Object.entries(i.pages??{}))a.add(d),typeof l.url=="string"&&a.add(l.url);let c=await Me(e);if(c?.schemaVersion!==2||c.impactHash!==n.impactHash)throw new Error("Content-sync verification requires the matching targeted deploy plan.");let o=as(n,a,c.resolvedSitemapUrls);for(let d of o.expectedAvailable){let l=new URL(d),u=new URL(`${l.pathname}${l.search}`,s),p=await xn(u,e.ignoreHttpsErrors);if(p.status<200||p.status>=400)throw new Error(`Content-sync verification failed (${p.status}): ${u}`)}for(let d of o.expectedMissing.slice(0,10)){let l=new URL(d),u=new URL(`${l.pathname}${l.search}`,s),p=await xn(u,e.ignoreHttpsErrors);if(p.status>=200&&p.status<300)throw new Error(`Deleted content is still publicly available: ${u}`)}}async function Ba(e){let t=await A.readFile(e.candidateManifest,"utf8");JSON.parse(t);let n=`${e.trustedManifest}.${process.pid}.tmp`;await A.writeFile(n,t,"utf8"),await A.rename(n,e.trustedManifest);}async function Wa(e,t){try{let n=JSON.parse(await A.readFile(e.candidateManifest,"utf8"));if([...Object.values(n.pages??{}),...Object.values(n.assets??{})].some(s=>s?.lastSeenRunId===t))return "resumed"}catch(n){if(n.code!=="ENOENT")throw new Error(`The content-sync candidate manifest is invalid: ${n instanceof Error?n.message:String(n)}`,{cause:n})}return await A.copyFile(e.trustedManifest,e.candidateManifest).catch(n=>{throw new Error(`A trusted crawl manifest is required before content-sync: ${n instanceof Error?n.message:String(n)}`,{cause:n})}),"initialized"}async function xe(e,t,n,r,s={},i=0,a=async()=>{}){t.phase=n,await _n(e,t),await Wn(e,{schemaVersion:1,jobId:t.jobId,phase:n,completedItems:r,totalItems:r,attempt:i,updatedAt:new Date().toISOString(),details:s}),await me(S.dirname(e.state),"content-sync-checkpoint",{id:t.jobId},`Content-sync checkpoint completed: ${n}.`,{phase:n,completedItems:r,totalItems:r,attempt:i,...s}),await a(n,t);}async function Ha(e,t={}){let n={loadConfig:ie,resolveRuleContext:Tn,runCrawl:Gr,runDeploy:rs,runInvalidate:os,verifyDeployment:Na,promoteCandidateManifest:Ba,clearDeployPlan:De,afterCheckpoint:async()=>{},...t},r=An(),s=lt(r),i=await _a(r,e),a=await n.loadConfig(),c=La(a,String(i.ruleId)),o=await n.resolveRuleContext(a,c);if(i.coalesceKey&&i.coalesceKey!==o.coalesceKey)throw new Error("Queued content-sync demand no longer matches the active rule scope.");let l=(await Nt(s)).entries[o.coalesceKey];if(!l||l.scopeFingerprint!==o.scopeFingerprint||l.targetFingerprint!==o.targetFingerprint||l.releaseFingerprint!==o.releaseFingerprint)throw await me(r,"content-sync-baseline-rejected",i,"Content-sync requires a new verified full or incremental release baseline.",{ruleId:c.id,reason:l?"mismatch":"missing"}),new Error("Content-sync baseline is missing or stale. Run a successful normal publish first.");let u=await Bt(s),p=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:l.baselineId,postTypes:o.scope.postTypes,includeSubsites:o.scope.includeSubsites});if(u&&u.jobId!==i.id)throw new Error("Another immutable content-sync range is still active.");if(u||(u={schemaVersion:1,jobId:i.id,ruleId:String(c.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,scopeFingerprint:o.scopeFingerprint,targetFingerprint:o.targetFingerprint,baselineId:l.baselineId,fromSequence:p.committedSequence,toSequence:p.headSequence,phase:"claimed",impactHash:null,startedAt:new Date().toISOString(),updatedAt:new Date().toISOString()},await xe(s,u,"claimed",0,{fromSequence:u.fromSequence,toSequence:u.toSequence},0,n.afterCheckpoint),await me(r,"content-sync-range-claimed",i,"Content-sync claimed a closed journal range.",{fromSequence:u.fromSequence,toSequence:u.toSequence})),u.fromSequence===u.toSequence){let m=await dt(s);m.rules[o.coalesceKey]={ruleId:String(c.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,committedSequence:u.toSequence,observedHeadSequence:p.headSequence,lag:Math.max(0,p.headSequence-u.toSequence),lastSuccessfulJobId:i.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:false,retryAttempt:0,nextRetryAt:null,lastError:null},await pt(s,m),await Wt(s);return}let f=await Nn(s);if(!Be(u.phase,"impact-planned")){let m=await o.client.events({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:l.baselineId,postTypes:o.scope.postTypes,includeSubsites:o.scope.includeSubsites,afterSequence:u.fromSequence,throughSequence:u.toSequence}),w=qt({events:m,scope:o.scope,sourceOrigin:a.sourceOrigin}),P=await o.client.resolveImpactFamilies(w,o.scope.includeSubsites);f=Un({jobId:i.id,ruleId:String(c.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,scopeFingerprint:o.scopeFingerprint,targetFingerprint:o.targetFingerprint,baselineId:l.baselineId,sourceOrigin:a.sourceOrigin,scope:o.scope,fromSequence:u.fromSequence,toSequence:u.toSequence,events:m,resolvedArchiveFamilies:P,sitemapUrls:Ke(a.sitemapPaths)}),await Bn(s,f),u.impactHash=f.impactHash,await xe(s,u,"impact-planned",m.length,{eventCount:m.length,foldedCount:f.foldedCount,impactHash:f.impactHash},0,n.afterCheckpoint),await me(r,"content-sync-impact-planned",i,"Content-sync persisted an immutable impact plan.",{impactHash:f.impactHash,eventCount:m.length});}if(!f||f.jobId!==i.id||u.impactHash!==f.impactHash)throw new Error("The immutable content-sync impact plan is missing or mismatched.");if(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH=s.candidateManifest,!Be(u.phase,"rendered")){let m=await Wa(s,i.id);await me(r,m==="resumed"?"content-sync-render-resumed":"content-sync-render-initialized",i,m==="resumed"?"Content-sync resumed its candidate crawl manifest.":"Content-sync initialized a candidate crawl manifest.",{impactHash:f.impactHash}),await n.runCrawl(["--content-sync-plan",s.impact]),await xe(s,u,"rendered",f.directRenderUrls.length+f.archiveFamilyUrls.length,{impactHash:f.impactHash},i.attempt??0,n.afterCheckpoint);}let g=o.deploymentProfile?["--profile",o.deploymentProfile]:[];if(Be(u.phase,"deployed")||(await n.runDeploy([...g,"--content-sync"]),await xe(s,u,"deployed",1,{impactHash:f.impactHash},0,n.afterCheckpoint),await me(r,"content-sync-deployed",i,"Content-sync targeted deployment completed.",{impactHash:f.impactHash})),Be(u.phase,"invalidated")?Be(u.phase,"verified")||await n.runInvalidate([...g,"--content-sync"]):(await n.runInvalidate([...g,"--content-sync"]),await xe(s,u,"invalidated",1,{impactHash:f.impactHash},0,n.afterCheckpoint)),Be(u.phase,"verified")||(await n.verifyDeployment(a,o,f,s.candidateManifest),await n.promoteCandidateManifest(s),await xe(s,u,"verified",1,{impactHash:f.impactHash},0,n.afterCheckpoint)),p=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:l.baselineId,postTypes:o.scope.postTypes,includeSubsites:o.scope.includeSubsites}),p.committedSequence===u.fromSequence)await o.client.acknowledge({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:l.baselineId,expectedSequence:u.fromSequence,sequence:u.toSequence,postTypes:o.scope.postTypes,includeSubsites:o.scope.includeSubsites});else if(p.committedSequence!==u.toSequence)throw new Error("Content-sync acknowledgement cursor is in an unexpected state.");await xe(s,u,"acknowledged",1,{sequence:u.toSequence},0,n.afterCheckpoint),await me(r,"content-sync-cursor-acknowledged",i,"Content-sync committed its journal cursor after verification.",{sequence:u.toSequence});let y=await o.client.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:l.baselineId,postTypes:o.scope.postTypes,includeSubsites:o.scope.includeSubsites}),h=await dt(s);h.rules[o.coalesceKey]={ruleId:String(c.id||""),consumerId:o.consumerId,coalesceKey:o.coalesceKey,committedSequence:u.toSequence,observedHeadSequence:y.headSequence,lag:Math.max(0,y.headSequence-u.toSequence),lastSuccessfulJobId:i.id,lastSuccessfulAt:new Date().toISOString(),trailingWorkDetected:y.headSequence>u.toSequence,retryAttempt:0,nextRetryAt:null,lastError:null},await pt(s,h),await n.clearDeployPlan(a),await A.rm(S.join(r,"content-sync-invalidation.json"),{force:true}),await A.rm(s.candidateManifest,{force:true}),await Wt(s);}async function ls(e=process.argv.slice(2)){let n=e.indexOf("--capture-baseline-cutoffs");if(n>=0){let a=String(e[n+1]||"").trim();if(!a)throw new Error("--capture-baseline-cutoffs requires a release job ID.");await qa(a);return}let r=e.indexOf("--establish-baselines");if(r>=0){let a=String(e[r+1]||"").trim();if(!a)throw new Error("--establish-baselines requires a release job ID.");await ja(a);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 Ha(i);}ls().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1);});
|