@smart-cloud/publisher-exporter 1.1.32 → 1.1.34

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/README.md CHANGED
@@ -57,6 +57,7 @@ npx @smart-cloud/publisher-exporter queue-runner --runtime-dir /srv/site/runtime
57
57
 
58
58
  - `crawl` without extra flags performs a normal full crawl, asset download, and final text rewrite.
59
59
  - `crawl --crawl-mode incremental` reuses the existing crawl manifest when possible and rewrites only the files affected by re-crawled pages, text assets, or changed asset-map entries.
60
+ - An incremental crawl now fails closed when the remote WP Suite subscription configuration cannot be loaded. It never silently falls back to a full crawl that clears the existing output tree.
60
61
  - `crawl --resume-rewrite` skips discovery, rendering, and asset download, then reruns the final text rewrite over the existing output tree using the current rewrite rules.
61
62
  - `crawl --retry-timeouts` retries timed-out URLs from the latest archived full crawl or publish log snapshot.
62
63
 
@@ -162,6 +163,9 @@ Prune old archive directories with `publisher-exporter prune-logs --runtime-dir
162
163
  - If `--resume-rewrite` appears to stop after the initial resume message, check `runtime/current-progress.json` and `<logDir>/current-crawl-event.json` before assuming it is stuck. That phase can stay mostly quiet on stdout while it rewrites files.
163
164
  - If direct CLI execution seems to ignore the expected runtime state, verify that `PUBLISHER_CONFIG` and `STATIC_PUBLISHER_RUNTIME_DIR` both point at the same runtime tree. A mismatched config path and runtime dir can make the run look idle or incomplete.
164
165
  - Prefer incremental crawl when the existing manifest is trusted and you only need a fast recrawl of changed pages or assets. Prefer a full crawl when discovery rules changed, the manifest is missing or suspect, or you want a clean end-to-end rebuild.
166
+ - Text-asset discovery resolves quoted relative dependencies against the owning JavaScript, CSS, JSON, or other text asset. This includes stable lazy chunk names such as `custom-block-parser.js` that may not be requested before the browser readiness window closes.
167
+ - In `sdk-upload-delete` mode, remote-only S3 objects are protected unless the crawl deploy plan contains an explicit manifest-backed deletion tombstone. Protected keys are listed in `deploy-diff.json` and the deploy log. This intentionally favors availability over automatically removing an unverified remote-only object.
168
+ - `queue-runner-heartbeat.json` reports both the exporter package version and the installed `@smart-cloud/wpsuite-core` version. Crawl logs also report the runtime `virtualAssetBaseUrl`, remote config loader status, and resolved subscription type without logging the runtime token. Legacy runtime input using `uploadUrl` is accepted during migration but normalized to `virtualAssetBaseUrl`.
165
169
  - For generated 404 capture, set `generated404RequestPath` to a path that really returns HTTP 404 from the origin. The exporter validates that response before reusing it as the generated 404 page.
166
170
 
167
171
  ## WordPress Integration
@@ -177,4 +181,4 @@ Typical values:
177
181
 
178
182
  - Playwright browser binaries are separate from the npm package and may need reinstalling after Playwright version upgrades.
179
183
  - For internal/self-signed TLS origins, set `ignoreHttpsErrors` in `publisher.config.json` or through the WordPress admin UI.
180
- - The package expects Node.js 20 or newer.
184
+ - The package expects Node.js 20 or newer.
package/dist/crawl.js CHANGED
@@ -1,9 +1,9 @@
1
- import {request,chromium}from'playwright';import S from'fs/promises';import f from'path';import {gunzipSync}from'zlib';import Wt from'http';import _t from'https';import Xe from'crypto';import rr from'fast-glob';import {availableParallelism}from'os';import {Worker}from'worker_threads';var jt=".deploy-plan.json",Et="deploy-plan.json";function Ut(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?f.resolve(e):""}function _e(e){let t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,"").trim();return !t||t==="."||t.startsWith("../")||t===".."?null:t}function Se(e){return [...new Set(e.map(_e).filter(t=>t!==null))]}function qt(e,t){return {schemaVersion:1,generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:f.resolve(e.outputDir),runMode:t.runMode,crawlMode:t.crawlMode,fullSyncRequired:!!t.fullSyncRequired,changedFiles:Se(t.changedFiles||[]),deletedFiles:Se(t.deletedFiles||[]),rewriteTargets:Se(t.rewriteTargets||[])}}function Qt(e){let t=f.join(f.resolve(e.outputDir),jt),r=Ut();return r?[f.join(r,Et),t]:[t]}function ee(e,t){let r=f.resolve(e),s=f.resolve(t),n=f.relative(r,s).replace(/\\/g,"/");return _e(n)}async function Be(e,t){let r=qt(e,t);for(let s of Qt(e))await S.mkdir(f.dirname(s),{recursive:true}),await S.writeFile(s,JSON.stringify(r,null,2),"utf8");}function ze(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function Bt(e){let t=String(e??"").trim();if(!t)return "";let r=t;if(/^https?:\/\//i.test(r))try{r=new URL(r).pathname;}catch{return ""}if(r=r.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!r)return "";let s=r.endsWith("/"),n=r.replace(/^\/+/,"").split("/").map(u=>u.replace(/[^A-Za-z0-9._-]/g,"")).filter(u=>u.length>0&&u!=="."&&u!=="..");if(n.length===0)return "";let i=`/${n.join("/")}`;return s&&f.extname(i)===""&&(i+="/"),i==="/"?"":i}function be(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function Ht(e){if(!e||typeof e!="object")return {};let t={};for(let[r,s]of Object.entries(e)){let n=r.trim();if(!n||!s||typeof s!="object")continue;let i=s,u={};if(typeof i.targetOrigin=="string"){let a=ze(i.targetOrigin);a&&(u.targetOrigin=a);}let l=be(i.extraReplacements);if(Object.keys(l).length>0&&(u.extraReplacements=l),i.s3&&typeof i.s3=="object"){let a={},o=i.s3;typeof o.bucket=="string"&&(a.bucket=o.bucket.trim()),typeof o.prefix=="string"&&(a.prefix=o.prefix.trim()),typeof o.region=="string"&&(a.region=o.region.trim()),typeof o.htmlCacheControl=="string"&&(a.htmlCacheControl=o.htmlCacheControl.trim()),typeof o.assetCacheControl=="string"&&(a.assetCacheControl=o.assetCacheControl.trim()),Object.keys(a).length>0&&(u.s3=a);}if(i.cloudFront&&typeof i.cloudFront=="object"){let a={},o=i.cloudFront;typeof o.distributionId=="string"&&(a.distributionId=o.distributionId.trim()),Array.isArray(o.invalidationPaths)&&(a.invalidationPaths=o.invalidationPaths.map(d=>String(d??"").trim()).filter(d=>d.length>0)),Object.keys(a).length>0&&(u.cloudFront=a);}t[n]=u;}return t}function Je(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function zt(e,t){if(!e||typeof e!="object")return null;let r=e,s=r.command;if(s!=="publish"&&s!=="crawl"&&s!=="deploy"&&s!=="invalidate"&&s!=="retry-timeouts"&&s!=="url")return null;let n=Number.parseInt(String(r.intervalMinutes??"0"),10);if(!Number.isFinite(n)||n<1)return null;let i=String(r.id??`${s}-${t+1}`).trim();if(!i)return null;let u=String(r.deploymentProfile??"").trim(),l=String(r.url??"").trim();return {id:i,enabled:r.enabled!==false,command:s,intervalMinutes:n,...s==="publish"||s==="crawl"?{crawlMode:r.crawlMode==="incremental"?"incremental":"full"}:{},...(s==="publish"||s==="deploy"||s==="invalidate")&&u?{deploymentProfile:u}:{},...l?{url:l}:{}}}function Ge(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((s,n)=>zt(s,n)).filter(s=>!!s):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:r}}function Jt(e){if(!e||typeof e!="object")return;let t=e,r={};for(let n of ["accountId","siteId"]){let i=t[n];typeof i=="string"&&i.trim()!==""&&(r[n]=i.trim());}let s=Number(t.lastUpdate??0);return Number.isFinite(s)&&s>0&&(r.lastUpdate=Math.floor(s)),t.subscriber===true&&(r.subscriber=true),Object.keys(r).length>0?r:void 0}function ve(e){let t=e&&typeof e=="object"?e:{},r=String(t.accountId??"").trim(),s=String(t.siteId??"").trim(),n=t.subscriber===true,i=Jt(t.siteSettings),u={...i??{},...r?{accountId:i?.accountId??r}:{},...s?{siteId:i?.siteId??s}:{},...i?.subscriber===true||n?{subscriber:true}:{}},l={},a=String(t.apiBase??"").trim();a&&(l.apiBase=a);let o=String(t.runtimeToken??t.nonce??"").trim();o&&(l.runtimeToken=o);let d=String(t.uploadUrl??"").trim();d&&(l.uploadUrl=d),Object.keys(u).length>0&&(l.siteSettings=u);let p=Je(t.subscriptionType);return p&&(l.subscriptionType=p),l}function Gt(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Ve(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function Vt(e,t){let r=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[s,n]of new Headers(t.headers).entries())r.set(s,n);return r}async function Ke(e,t,r=5){let s=new URL(Ve(e)),n=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),i=s.protocol==="http:"?Wt:_t,u=Vt(e,t);return await new Promise((l,a)=>{let o=i.request(s,{method:n,headers:Object.fromEntries(u.entries()),...s.protocol==="https:"?{rejectUnauthorized:false}:{}},d=>{let p=[];d.on("data",c=>{p.push(Buffer.isBuffer(c)?c:Buffer.from(c));}),d.on("error",a),d.on("end",()=>{let c=d.statusCode??0,g=d.headers.location;if(r>0&&g&&[301,302,303,307,308].includes(c)){l(Ke(new URL(g,s),{method:c===303?"GET":n},r-1));return}let m=new Headers;for(let[w,h]of Object.entries(d.headers))Array.isArray(h)?m.set(w,h.join(", ")):typeof h=="string"&&m.set(w,h);l(new Response(Buffer.concat(p),{status:c,statusText:d.statusMessage??"",headers:m}));});});o.on("error",a),o.end();})}function Kt(e){let t=ve(e.wpsuite),r={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},s=String(r.accountId??"").trim(),n=String(r.siteId??"").trim(),i=String(t.uploadUrl??"").trim();if(e.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...i?{uploadUrl:i}:{},...Object.keys(r).length>0?{siteSettings:r}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!s||!n||!i)return false;Gt(e.sourceOrigin);let u=globalThis,a={...u.WpSuite??{},siteSettings:r,uploadUrl:i};return t.apiBase&&(a.apiBase=t.apiBase),u.WpSuite=a,true}async function Yt(e){if(!Kt(e))return null;let t=String(e.wpsuite?.uploadUrl??"").trim(),r=globalThis.fetch;try{e.ignoreHttpsErrors&&typeof r=="function"&&t.startsWith("https://")&&(globalThis.fetch=(async(i,u)=>Ve(i).startsWith(t)?Ke(i,u):r(i,u)));let{getConfig:s}=await import('@smart-cloud/wpsuite-core'),n=await s("publisher");return n&&typeof n=="object"?n:null}catch{return null}finally{typeof r=="function"&&(globalThis.fetch=r);}}function Zt(e,t){let r=Ht(t?.deploymentProfiles),s=String(t?.defaultDeploymentProfile??"").trim(),n=r[s]?s:"",i=Je(t?.subscriptionType),u=ve(e.wpsuite);return {...e,scheduler:Ge(t?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:n,...i?{subscriptionType:i}:{},wpsuite:{...u,...u.siteSettings||i?{siteSettings:{...u.siteSettings??{},...u.siteSettings?.subscriber===true||i==="PROFESSIONAL"||i==="AGENCY"?{subscriber:true}:{}}}:{},...i?{subscriptionType:i}:{}}}}function ye(e,t){let s=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!s)return t;let n=s.split("/").map(i=>i.trim()).filter(i=>i.length>0&&i!=="."&&i!=="..");return n.length>0?n.join("/"):t}function Xt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?f.resolve(e):""}function He(e,t,r){let s=String(t||"").trim();return s&&f.isAbsolute(s)?f.resolve(s):f.resolve(e,ye(s,r))}async function Re(e){let t=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",r=await S.readFile(t,"utf8"),s=JSON.parse(r);s.sourceOrigin=s.sourceOrigin.replace(/\/$/,""),s.targetOrigin=ze(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=Bt(s.generated404RequestPath),s.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],s.allowedAssetHosts||=[],s.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],s.blockedPathPrefixes||=[],s.blockedSearchFragments||=[],s.concurrency||=1,s.maxPages||=0,s.extraReplacements=be(s.extraReplacements),s.postCrawlCopyMap=be(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=ve(s.wpsuite),s.scheduler=Ge(void 0),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let n=Zt(s,await Yt(s)),i=Xt(),u=i?f.resolve(i,".."):"";return u?(n.outputDir=He(u,n.outputDir,"export"),n.logDir=He(u,n.logDir,"logs")):(f.isAbsolute(n.outputDir)||(n.outputDir=ye(n.outputDir,"export")),f.isAbsolute(n.logDir)||(n.logDir=ye(n.logDir,"logs"))),n}function re(e,t=10){return Xe.createHash("sha1").update(e).digest("hex").slice(0,t)}async function er(e){await S.mkdir(f.dirname(e),{recursive:true});}async function se(e,t,r){await er(e);let s=f.join(f.dirname(e),`.${f.basename(e)}.${process.pid}.${Date.now()}.${Xe.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await S.writeFile(s,t,r??"utf8"):await S.writeFile(s,t),await S.rename(s,e);}catch(n){throw await S.unlink(s).catch(()=>{}),n}}function z(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(f.extname(e).toLowerCase())}function E(e){return e.replace(/&quot;/g,'"').replace(/&#34;/g,'"').replace(/&apos;/g,"'").replace(/&#39;/g,"'").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">")}function V(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function pe(e){return e.replace(/\//g,"\\/")}function Ye(e){return e.replace(/\//g,"\\\\/")}function tr(e){try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return null;let r=t.pathname==="/"&&!t.search&&!t.hash?"":`${t.pathname}${t.search}${t.hash}`;return `//${t.host}${r}`}catch{return null}}function Ze(e,t,r){if(!t)return;e[t]=r;let s=pe(t),n=pe(r);e[s]=n;let i=Ye(t),u=Ye(r);e[i]=u;let l=V(t),a=V(r);e[l]=a;let o=V(s),d=V(n);e[o]=d;let p=V(i),c=V(u);e[p]=c;}function ge(e,t,r){Ze(e,t,r);let s=tr(t);s&&s!==t&&Ze(e,s,r);}function Ce(e,t){let r=t.startsWith("/")?t:`/${t}`,s=(e||"").replace(/\/$/,"");return !s||s==="."||s==="/"?r:`${s}${r}`}function et(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function tt(e,t,r){if(!t)return r;let s=f.dirname(f.resolve(t)),n=f.resolve(e,r.replace(/^\/+/,"")),i=f.relative(s,n).replace(/\\/g,"/");return i?(i.startsWith(".")||(i=`./${i}`),i):"."}var or=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],ar=new Set([".html",".htm"]),rt="WPSuite.io Static Publisher",ur=rt.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function lr(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function cr(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function dr(e,t,r){return cr(t)?e.replace(new RegExp(`(?<!:)${lr(t)}`,"g"),r):e.split(t).join(r)}function pr(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let n=f.extname(r).toLowerCase();return ar.has(n)?/<head\b|<html\b|<!doctype html/i.test(t):false}function gr(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${ur}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${rt}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let s=e.includes(`\r
1
+ import {request,chromium}from'playwright';import b from'fs/promises';import f from'path';import {gunzipSync}from'zlib';import _t from'http';import Ht from'https';import tt from'crypto';import nr from'fast-glob';import {availableParallelism}from'os';import {Worker}from'worker_threads';var Ut=".deploy-plan.json",qt="deploy-plan.json";function Qt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?f.resolve(e):""}function ze(e){let t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,"").trim();return !t||t==="."||t.startsWith("../")||t===".."?null:t}function Se(e){return [...new Set(e.map(ze).filter(t=>t!==null))]}function Wt(e,t){return {schemaVersion:1,generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:f.resolve(e.outputDir),runMode:t.runMode,crawlMode:t.crawlMode,fullSyncRequired:!!t.fullSyncRequired,changedFiles:Se(t.changedFiles||[]),deletedFiles:Se(t.deletedFiles||[]),rewriteTargets:Se(t.rewriteTargets||[])}}function Nt(e){let t=f.join(f.resolve(e.outputDir),Ut),r=Qt();return r?[f.join(r,qt),t]:[t]}function ee(e,t){let r=f.resolve(e),s=f.resolve(t),n=f.relative(r,s).replace(/\\/g,"/");return ze(n)}async function Je(e,t){let r=Wt(e,t);for(let s of Nt(e))await b.mkdir(f.dirname(s),{recursive:true}),await b.writeFile(s,JSON.stringify(r,null,2),"utf8");}function Ve(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function zt(e){let t=String(e??"").trim();if(!t)return "";let r=t;if(/^https?:\/\//i.test(r))try{r=new URL(r).pathname;}catch{return ""}if(r=r.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!r)return "";let s=r.endsWith("/"),n=r.replace(/^\/+/,"").split("/").map(u=>u.replace(/[^A-Za-z0-9._-]/g,"")).filter(u=>u.length>0&&u!=="."&&u!=="..");if(n.length===0)return "";let i=`/${n.join("/")}`;return s&&f.extname(i)===""&&(i+="/"),i==="/"?"":i}function ye(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function Jt(e){if(!e||typeof e!="object")return {};let t={};for(let[r,s]of Object.entries(e)){let n=r.trim();if(!n||!s||typeof s!="object")continue;let i=s,u={};if(typeof i.targetOrigin=="string"){let o=Ve(i.targetOrigin);o&&(u.targetOrigin=o);}let l=ye(i.extraReplacements);if(Object.keys(l).length>0&&(u.extraReplacements=l),i.s3&&typeof i.s3=="object"){let o={},a=i.s3;typeof a.bucket=="string"&&(o.bucket=a.bucket.trim()),typeof a.prefix=="string"&&(o.prefix=a.prefix.trim()),typeof a.region=="string"&&(o.region=a.region.trim()),typeof a.htmlCacheControl=="string"&&(o.htmlCacheControl=a.htmlCacheControl.trim()),typeof a.assetCacheControl=="string"&&(o.assetCacheControl=a.assetCacheControl.trim()),Object.keys(o).length>0&&(u.s3=o);}if(i.cloudFront&&typeof i.cloudFront=="object"){let o={},a=i.cloudFront;typeof a.distributionId=="string"&&(o.distributionId=a.distributionId.trim()),Array.isArray(a.invalidationPaths)&&(o.invalidationPaths=a.invalidationPaths.map(g=>String(g??"").trim()).filter(g=>g.length>0)),Object.keys(o).length>0&&(u.cloudFront=o);}t[n]=u;}return t}function Re(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function Gt(e,t){if(!e||typeof e!="object")return null;let r=e,s=r.command;if(s!=="publish"&&s!=="crawl"&&s!=="deploy"&&s!=="invalidate"&&s!=="retry-timeouts"&&s!=="url")return null;let n=Number.parseInt(String(r.intervalMinutes??"0"),10);if(!Number.isFinite(n)||n<1)return null;let i=String(r.id??`${s}-${t+1}`).trim();if(!i)return null;let u=String(r.deploymentProfile??"").trim(),l=String(r.url??"").trim();return {id:i,enabled:r.enabled!==false,command:s,intervalMinutes:n,...s==="publish"||s==="crawl"?{crawlMode:r.crawlMode==="incremental"?"incremental":"full"}:{},...(s==="publish"||s==="deploy"||s==="invalidate")&&u?{deploymentProfile:u}:{},...l?{url:l}:{}}}function Ye(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((s,n)=>Gt(s,n)).filter(s=>!!s):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:r}}function Vt(e){if(!e||typeof e!="object")return;let t=e,r={};for(let n of ["accountId","siteId"]){let i=t[n];typeof i=="string"&&i.trim()!==""&&(r[n]=i.trim());}let s=Number(t.lastUpdate??0);return Number.isFinite(s)&&s>0&&(r.lastUpdate=Math.floor(s)),t.subscriber===true&&(r.subscriber=true),Object.keys(r).length>0?r:void 0}function Ce(e){let t=e&&typeof e=="object"?e:{},r=String(t.accountId??"").trim(),s=String(t.siteId??"").trim(),n=t.subscriber===true,i=Vt(t.siteSettings),u={...i??{},...r?{accountId:i?.accountId??r}:{},...s?{siteId:i?.siteId??s}:{},...i?.subscriber===true||n?{subscriber:true}:{}},l={},o=String(t.apiBase??"").trim();o&&(l.apiBase=o);let a=String(t.runtimeToken??t.nonce??"").trim();a&&(l.runtimeToken=a);let g=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();g&&(l.virtualAssetBaseUrl=g),Object.keys(u).length>0&&(l.siteSettings=u);let d=Re(t.subscriptionType);return d&&(l.subscriptionType=d),l}function Yt(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Ze(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function Zt(e,t){let r=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[s,n]of new Headers(t.headers).entries())r.set(s,n);return r}async function Ke(e,t,r=5){let s=new URL(Ze(e)),n=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),i=s.protocol==="http:"?_t:Ht,u=Zt(e,t);return await new Promise((l,o)=>{let a=i.request(s,{method:n,headers:Object.fromEntries(u.entries()),...s.protocol==="https:"?{rejectUnauthorized:false}:{}},g=>{let d=[];g.on("data",c=>{d.push(Buffer.isBuffer(c)?c:Buffer.from(c));}),g.on("error",o),g.on("end",()=>{let c=g.statusCode??0,p=g.headers.location;if(r>0&&p&&[301,302,303,307,308].includes(c)){l(Ke(new URL(p,s),{method:c===303?"GET":n},r-1));return}let h=new Headers;for(let[m,w]of Object.entries(g.headers))Array.isArray(w)?h.set(m,w.join(", ")):typeof w=="string"&&h.set(m,w);l(new Response(Buffer.concat(d),{status:c,statusText:g.statusMessage??"",headers:h}));});});a.on("error",o),a.end();})}function Kt(e){let t=Ce(e.wpsuite),r={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},s=String(r.accountId??"").trim(),n=String(r.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(r).length>0?{siteSettings:r}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!s||!n||!i)return false;Yt(e.sourceOrigin);let u=globalThis,o={...u.WpSuite??{},siteSettings:r,uploadUrl:i};return t.apiBase&&(o.apiBase=t.apiBase),u.WpSuite=o,true}async function Xt(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!Kt(e)){let n=e.wpsuite?.siteSettings,i=[String(n?.accountId??"").trim()?"":"accountId",String(n?.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 r=globalThis.fetch,s=[];try{typeof r=="function"&&/^https?:\/\//i.test(t)&&(globalThis.fetch=(async(o,a)=>{let g=Ze(o);if(g.startsWith(t)){let d=(()=>{try{return new URL(g).pathname}catch{return g}})();try{let c=e.ignoreHttpsErrors&&g.startsWith("https://")?await Ke(o,a):await r(o,a);return s.push({path:d,status:c.status,ok:c.ok,error:null}),c}catch(c){throw s.push({path:d,status:null,ok:!1,error:c instanceof Error?c.message:String(c)}),c}}return r(o,a)}));let{getConfig:n}=await import('@smart-cloud/wpsuite-core'),i=await n("publisher"),u=i&&typeof i=="object"?i:null,l=Re(u?.subscriptionType);return {remote:u,diagnostic:{status:u?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:l??null,error:u?null:"WP Suite publisher config loader returned no configuration.",requests:s}}}catch(n){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:t,subscriptionType:null,error:n instanceof Error?n.message:String(n),requests:s}}}finally{typeof r=="function"&&(globalThis.fetch=r);}}function er(e,t){let r=Jt(t?.deploymentProfiles),s=String(t?.defaultDeploymentProfile??"").trim(),n=r[s]?s:"",i=Re(t?.subscriptionType),u=Ce(e.wpsuite);return {...e,scheduler:Ye(t?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:n,...i?{subscriptionType:i}:{},wpsuite:{...u,...u.siteSettings||i?{siteSettings:{...u.siteSettings??{},...u.siteSettings?.subscriber===true||i==="PROFESSIONAL"||i==="AGENCY"?{subscriber:true}:{}}}:{},...i?{subscriptionType:i}:{}}}}function ve(e,t){let s=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!s)return t;let n=s.split("/").map(i=>i.trim()).filter(i=>i.length>0&&i!=="."&&i!=="..");return n.length>0?n.join("/"):t}function tr(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?f.resolve(e):""}function Ge(e,t,r){let s=String(t||"").trim();return s&&f.isAbsolute(s)?f.resolve(s):f.resolve(e,ve(s,r))}async function xe(e,t={}){let r=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",s=await b.readFile(r,"utf8"),n=JSON.parse(s);n.sourceOrigin=n.sourceOrigin.replace(/\/$/,""),n.targetOrigin=Ve(n.targetOrigin),n.ignoreHttpsErrors??=false,n.outputDir=String(n.outputDir||"export").trim()||"export",n.urlRewriteMode||=n.targetOrigin==="."?"relative":"absolute",n.noJavaScriptRenderPathPrefixes||=[],n.seedPaths||=[],n.generated404RequestPath=zt(n.generated404RequestPath),n.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],n.allowedAssetHosts||=[],n.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],n.blockedPathPrefixes||=[],n.blockedSearchFragments||=[],n.concurrency||=1,n.maxPages||=0,n.extraReplacements=ye(n.extraReplacements),n.postCrawlCopyMap=ye(n.postCrawlCopyMap),n.logDir=String(n.logDir||"logs").trim()||"logs",n.verbose??=false,n.logLevel||=n.verbose?"debug":"info",n.s3SyncMode||="sdk-upload-delete",n.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},n.readiness.timeoutMs??=1500,n.readiness.fallbackWaitMs??=1500,n.viewport||={width:1440,height:1200},n.navigationTimeoutMs||=3e4,n.assetDownloadConcurrency=Number(n.assetDownloadConcurrency)>0?Number(n.assetDownloadConcurrency):n.concurrency,n.rewriteConcurrency=Number(n.rewriteConcurrency)>0?Number(n.rewriteConcurrency):n.assetDownloadConcurrency,n.wpsuite=Ce(n.wpsuite),n.scheduler=Ye(void 0),n.deploymentProfiles={},n.defaultDeploymentProfile="",n.deploymentTargetOverride=String(n.deploymentTargetOverride??"").trim();let i=await Xt(n);t.onRemotePublisherConfigDiagnostic?.(i.diagnostic);let u=er(n,i.remote),l=tr(),o=l?f.resolve(l,".."):"";return o?(u.outputDir=Ge(o,u.outputDir,"export"),u.logDir=Ge(o,u.logDir,"logs")):(f.isAbsolute(u.outputDir)||(u.outputDir=ve(u.outputDir,"export")),f.isAbsolute(u.logDir)||(u.logDir=ve(u.logDir,"logs"))),u}function re(e,t=10){return tt.createHash("sha1").update(e).digest("hex").slice(0,t)}async function rr(e){await b.mkdir(f.dirname(e),{recursive:true});}async function se(e,t,r){await rr(e);let s=f.join(f.dirname(e),`.${f.basename(e)}.${process.pid}.${Date.now()}.${tt.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await b.writeFile(s,t,r??"utf8"):await b.writeFile(s,t),await b.rename(s,e);}catch(n){throw await b.unlink(s).catch(()=>{}),n}}function z(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(f.extname(e).toLowerCase())}function U(e){return e.replace(/&quot;/g,'"').replace(/&#34;/g,'"').replace(/&apos;/g,"'").replace(/&#39;/g,"'").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">")}function V(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function pe(e){return e.replace(/\//g,"\\/")}function Xe(e){return e.replace(/\//g,"\\\\/")}function sr(e){try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return null;let r=t.pathname==="/"&&!t.search&&!t.hash?"":`${t.pathname}${t.search}${t.hash}`;return `//${t.host}${r}`}catch{return null}}function et(e,t,r){if(!t)return;e[t]=r;let s=pe(t),n=pe(r);e[s]=n;let i=Xe(t),u=Xe(r);e[i]=u;let l=V(t),o=V(r);e[l]=o;let a=V(s),g=V(n);e[a]=g;let d=V(i),c=V(u);e[d]=c;}function ge(e,t,r){et(e,t,r);let s=sr(t);s&&s!==t&&et(e,s,r);}function ke(e,t){let r=t.startsWith("/")?t:`/${t}`,s=(e||"").replace(/\/$/,"");return !s||s==="."||s==="/"?r:`${s}${r}`}function rt(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function st(e,t,r){if(!t)return r;let s=f.dirname(f.resolve(t)),n=f.resolve(e,r.replace(/^\/+/,"")),i=f.relative(s,n).replace(/\\/g,"/");return i?(i.startsWith(".")||(i=`./${i}`),i):"."}var ur=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],lr=new Set([".html",".htm"]),nt="WPSuite.io Static Publisher",cr=nt.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function dr(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function pr(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function gr(e,t,r){return pr(t)?e.replace(new RegExp(`(?<!:)${dr(t)}`,"g"),r):e.split(t).join(r)}function fr(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let n=f.extname(r).toLowerCase();return lr.has(n)?/<head\b|<html\b|<!doctype html/i.test(t):false}function hr(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${cr}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${nt}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let s=e.includes(`\r
2
2
  `)?`\r
3
3
  `:`
4
- `;return e.replace(/<head\b[^>]*>/i,n=>`${n}${s} ${t}`)}function fr(e){let t=E(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function hr(e,t){let r=[...new Set(t)].filter(i=>i.includes("/")&&!/\\+\//.test(i)).map(i=>[i,pe(i)]).filter(([i,u])=>i!==u).sort((i,u)=>u[0].length-i[0].length);if(!r.length)return e;let s=i=>{let u=i;for(let[l,a]of r)u=u.split(l).join(a);return u},n=e.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(i,u,l,a)=>`${u}${s(l)}${a}`);return n=n.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(i,u,l,a,o)=>fr(a)?`${u}${s(a)}${o}`:i),n}function mr(e,t){if(!t)return null;let r=f.dirname(f.resolve(t)),s=f.resolve(e.outputDir),n=f.relative(r,s).replace(/\\/g,"/");return n?(n.startsWith(".")||(n=`./${n}`),n.endsWith("/")?n:`${n}/`):"./"}function wr(e,t,r){let s=mr(t,r);if(!s)return e;let n=e;for(let i of or){let u=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),l=new RegExp(`(?:\\.{1,}/)+${u}`,"g"),a=new RegExp(`(?<!\\.)/${u}`,"g");n=n.replace(l,`${s}${i}`).replace(a,`${s}${i}`);let o=i.replace(/\//g,"\\/"),d=s.replace(/\//g,"\\/"),p=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=new RegExp(`(?:\\.{1,}\\\\/)+${p}`,"g"),g=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${p}`,"g"),m=new RegExp(`(?<![\\.\\\\])\\/${p}`,"g");n=n.replace(c,`${d}${o}`).replace(g,`${d}${o}`).replace(m,`${d}${o}`);}return n}function xe(e,t,r){if(e.urlRewriteMode==="absolute")return t;let s=(()=>{try{return new URL(t,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin)}catch{return null}})(),n=s?s.pathname:et(t,e.targetOrigin),i=s?`${s.search}${s.hash}`:"";return e.urlRewriteMode==="root-relative"?`${n}${i}`:`${tt(e.outputDir,r,n)}${i}`}function ke(e,t,r,s,n){ge(e,r,xe(t,s,n));}function Pr(e,t,r,s,n){if(!r||r===s)return;ge(e,r,s);let i=xe(t,r,n),u=xe(t,s,n);ge(e,i,u);}function Te(e,t,r,s,n={}){let i=e,u={};ke(u,t,t.sourceOrigin,t.targetOrigin,s);for(let[a,o]of Object.entries(t.extraReplacements))ke(u,t,a,o,s);for(let[a,o]of Object.entries(r))ke(u,t,a,o,s);for(let[a,o]of Object.entries(n)){let d=r[a];!d||d===o||Pr(u,t,o,d,s);}let l=Object.entries(u).sort((a,o)=>o[0].length-a[0].length);for(let[a,o]of l)i=dr(i,a,o);return t.urlRewriteMode!=="absolute"&&(i=wr(i,t,s)),i=hr(i,l.map(([,a])=>a)),pr(t,i,s)&&(i=gr(i)),i}async function Sr(e,t,r,s){let n=f.join(e.outputDir,s),i=f.extname(n).toLowerCase(),u;try{u=await S.readFile(n,"utf8");}catch(o){if(o.code!=="ENOENT")throw o;return {changed:false}}let a=Te(u,e,t,i===".js"||i===".mjs"?void 0:n,r);return a!==u?(await se(n,a,"utf8"),{changed:true}):{changed:false}}async function br(e,t){return await new Promise((r,s)=>{let n=a=>{if(l(),a?.error){s(new Error(a.error));return}r({changed:!!a?.changed});},i=a=>{l(),s(a);},u=a=>{l(),a!==0&&s(new Error(`Rewrite worker exited with code ${a}.`));},l=()=>{e.off("message",n),e.off("error",i),e.off("exit",u);};e.on("message",n),e.on("error",i),e.on("exit",u),e.postMessage({file:t});})}async function st(e,t,r={}){let n=(r.files?[...new Set(r.files)].map(c=>f.resolve(c)).filter(c=>c.startsWith(f.resolve(e.outputDir))).map(c=>f.relative(e.outputDir,c).replace(/\\/g,"/")).filter(c=>c.length>0):await rr(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(c=>c!=="asset-map.json"&&z(c)),i=0;if(n.length===0)return 0;let u=Math.max(1,Number(e.rewriteConcurrency||e.assetDownloadConcurrency||1)),l=Math.max(1,Math.min(u,n.length,availableParallelism()));await r.onStart?.({totalFiles:n.length,workerCount:l});let a=0,o=0,d=null;if(l===1){for(let c of n){let g=await Sr(e,t,r.previousAssetMap??{},c);g.changed&&(i+=1),o+=1,await r.onProgress?.({index:o,totalFiles:n.length,changedTextFiles:i,file:c,changed:g.changed});}return i}let p=Array.from({length:l},async()=>{let c=new Worker(new URL("./rewrite-worker.js",import.meta.url),{workerData:{config:e,assetMap:t,previousAssetMap:r.previousAssetMap??{}}});try{for(;!d;){let g=a;if(g>=n.length)return;a+=1;let m=n[g],w=await br(c,m);w.changed&&(i+=1),o+=1,await r.onProgress?.({index:o,totalFiles:n.length,changedTextFiles:i,file:m,changed:w.changed});}}catch(g){throw d=g instanceof Error?g:new Error(String(g)),d}finally{await c.terminate().catch(()=>{});}});return await Promise.all(p),i}var _={error:0,warn:1,info:2,debug:3},nt=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",fe=nt?f.join(nt,"current-progress.json"):"",it=Promise.resolve();function ot(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function yr(e,t){let r={...e},s=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","pageQueue","assetQueue","sitemapQueue"]);for(let[n,i]of Object.entries(t)){let u=r[n];if(typeof u=="number"&&typeof i=="number"&&s.has(n)){r[n]=Math.max(u,i);continue}r[n]=i;}return r}function vr(e,t,r){fe&&(it=it.then(async()=>{let s=new Date,n=s.toISOString();await S.mkdir(f.dirname(fe),{recursive:true});let i=await S.readFile(fe,"utf8").then(w=>JSON.parse(w)).catch(()=>null),u=i&&typeof i.details=="object"&&i.details?i.details:{},l=ot(e),a=i?.currentStep||ot(i?.source||""),o=i?.startedAt||n,d={...i?.stepDurationsSec??{}},p=i?.stepStartedAt||n;if(a&&a!==l&&i?.stepStartedAt){let w=Math.max(0,Math.round((s.getTime()-new Date(i.stepStartedAt).getTime())/1e3));d[a]=(d[a]??0)+w,p=n;}let c=Math.max(0,Math.round((s.getTime()-new Date(p).getTime())/1e3)),g=Math.max(0,Math.round((s.getTime()-new Date(o).getTime())/1e3)),m={checkedAt:n,source:e,message:t,details:yr(u,r??{}),startedAt:o,currentStep:l,stepStartedAt:p,stepElapsedSec:c,totalElapsedSec:g,stepDurationsSec:d};await S.writeFile(fe,JSON.stringify(m,null,2),"utf8");}).catch(()=>{}));}async function Rr(e,t){await S.mkdir(f.dirname(e),{recursive:true}),await S.appendFile(e,`${JSON.stringify(t)}
5
- `,"utf8");}function Cr(e,t){let r=typeof t?.phase=="string"?t.phase.trim():"";return r||(e==="page"?"render-pages":e==="asset"?"download-assets":e==="sitemap"?"discovery":e==="timing"&&typeof t?.name=="string"&&t.name.trim()||"crawl")}function kr(e,t,r){return {checkedAt:new Date().toISOString(),currentStep:Cr(e,r),level:e,message:t,details:r??{}}}var ne=class{constructor(t,r="info"){this.logDir=t;this.level=typeof r=="boolean"?r?"debug":"info":r,this.ensureLogFileReady();}logDir;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;level;get logPath(){return f.join(this.logDir,"crawl.log.jsonl")}get currentEventPath(){return f.join(this.logDir,"current-crawl-event.json")}get rejectedPath(){return f.join(this.logDir,"rejected.jsonl")}get ignoredPath(){return f.join(this.logDir,"ignored.jsonl")}get skippedPath(){return f.join(this.logDir,"skipped-http.jsonl")}get errorsPath(){return f.join(this.logDir,"errors.jsonl")}get timingsPath(){return f.join(this.logDir,"timings.jsonl")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await S.mkdir(this.logDir,{recursive:true}),await S.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(t){this.writeQueue=this.writeQueue.then(t).catch(r=>{this.writeError=r instanceof Error?r:new Error(String(r));});}enqueueLine(t){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await S.appendFile(this.logPath,`${t}
6
- `,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>Rr(t,r));}updateCurrentEvent(t,r,s){let n=kr(t,r,s);this.enqueueTask(async()=>{await S.mkdir(this.logDir,{recursive:true}),await S.writeFile(this.currentEventPath,JSON.stringify(n,null,2),"utf8");});}push(t,r,s){let n=JSON.stringify({time:new Date().toISOString(),level:t,message:r,...s||{}});this.enqueueLine(n),this.updateCurrentEvent(t,r,s),t==="error"?console.error(r,s||""):t==="warn"?console.warn(r,s||""):(_[this.level]>=_.debug||["summary","page","sitemap","asset","timing"].includes(t))&&console.log(r);}info(t,r){this.push("info",t,r);}debug(t,r){_[this.level]<_.debug||this.push("debug",t,r);}progress(t,r){vr("crawl.log.jsonl",t,r),this.updateCurrentEvent("progress",t,r);}checkpoint(t,r){this.updateCurrentEvent("checkpoint",t,r);}page(t,r){this.push("page",t,r);}sitemap(t,r){this.push("sitemap",t,r);}asset(t,r){this.push("asset",t,r);}warn(t,r){this.push("warn",t,r);}error(t,r){this.enqueueJsonLine(this.errorsPath,{message:t,...r||{}}),this.push("error",t,r);}summary(t,r){this.push("summary",t,r);}mark(t){this.marks.set(t,Date.now());}endMark(t,r){let s=this.marks.get(t);if(!s)return;let n=Date.now()-s,i={name:t,ms:n,seconds:Number((n/1e3).toFixed(2)),...r||{}};this.enqueueJsonLine(this.timingsPath,i),this.push("timing",`Timing ${t}: ${i.seconds}s`,i);}reject(t,r,s,n){let i={kind:t,url:r,reason:s,source:n};this.enqueueJsonLine(this.rejectedPath,i),_[this.level]>=_.debug&&this.push("reject",`Rejected ${t} ${r}: ${s}`,i);}ignore(t,r,s,n){let i={kind:t,url:r,reason:s,source:n};this.enqueueJsonLine(this.ignoredPath,i),_[this.level]>=_.debug&&this.push("ignore",`Ignored ${t} ${r}: ${s}`,i);}skip(t,r,s,n){let i={kind:t,url:r,status:s,source:n};this.enqueueJsonLine(this.skippedPath,i),this.push("warn",`Skipped ${t} ${r}: HTTP ${s}`,i);}async flush(){let t=Date.now()-this.startedAt,r={name:"total",ms:t,seconds:Number((t/1e3).toFixed(2))};if(this.enqueueJsonLine(this.timingsPath,r),await this.writeQueue,this.writeError)throw this.writeError}};var Mr=["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","application/octet-stream"],St=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"]),bt=new Set(["",".html",".htm"]),Lr=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),Ir=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function $r(e){let t=[],r="full",s="full",n=false,i=false;for(let u=0;u<e.length;u++){let l=e[u];if(l==="--retry-timeouts")r="retry-timeouts",n=true;else if(l==="--resume")n=true;else if(l==="--resume-rewrite")n=true,i=true;else if(l==="--crawl-mode"){let a=e[++u];if(!a)throw new Error("--crawl-mode requires a value");s=a==="incremental"?"incremental":"full",n||=s==="incremental";}else if(l.startsWith("--crawl-mode="))s=l.slice(13)==="incremental"?"incremental":"full",n||=s==="incremental";else if(l==="--incremental")s="incremental",n=true;else if(l==="--url"){let a=e[++u];if(!a)throw new Error("--url requires a value");r="single-url",n=true,t.push(a);}else if(l.startsWith("--url="))r="single-url",n=true,t.push(l.slice(6));else if(l==="--urls"){let a=e[++u];if(!a)throw new Error("--urls requires a file path");r="single-url",n=true,t.push(`@${a}`);}}return {mode:r,crawlMode:s,urls:t,preserveOutput:n,resumeRewrite:i}}function Oe(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?f.resolve(e):""}function Dr(){let e=Oe();return e?f.resolve(e,".."):""}function Or(){let e=process.env.STATIC_PUBLISHER_WP_ROOT||process.env.WPSUITE_STATIC_PUBLISHER_WP_ROOT||"";return e.trim()?f.resolve(e):""}function Fr(e){let t=e.trim(),r=[{alias:"@storage-root",root:Dr(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@runtime",root:Oe(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@wp-root",root:Or(),requiredEnv:"STATIC_PUBLISHER_WP_ROOT or WPSUITE_STATIC_PUBLISHER_WP_ROOT"}];for(let s of r){if(t!==s.alias&&!t.startsWith(`${s.alias}/`))continue;if(!s.root)return {resolvedPath:null,alias:s.alias,requiredEnv:s.requiredEnv};let n=t.slice(s.alias.length).replace(/^\/+/,"");return {resolvedPath:n?f.resolve(s.root,n):s.root,alias:s.alias}}return {resolvedPath:f.resolve(t)}}function yt(e){let t=Oe();return t?f.join(t,"crawl-manifest.json"):f.join(e.outputDir,".crawl-manifest.json")}function vt(){return {schemaVersion:3,updatedAt:"",pages:{},assets:{}}}function at(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 jr(e){let t=e.isText===true;return {url:String(e.url||""),outputPath:String(e.outputPath||""),isText:t,contentType:typeof e.contentType=="string"&&e.contentType?e.contentType:null,discoveredAssets:Array.isArray(e.discoveredAssets)?e.discoveredAssets.map(r=>String(r)):[],lastCrawledAt:String(e.lastCrawledAt||""),lastSeenRunId:String(e.lastSeenRunId||""),rewriteComplete:e.rewriteComplete===true||!t}}function Ie(e){let t=e?.["content-type"]?.trim();return t||null}function Er(){return {rewriteTargets:new Set,changedFiles:new Set,deletedFiles:new Set}}function q(e,t,r){let s=ee(t.outputDir,r);s&&(e.changedFiles.add(s),e.deletedFiles.delete(s));}function ut(e,t,r){let s=ee(t.outputDir,r);s&&(e.deletedFiles.add(s),e.changedFiles.delete(s));}function oe(e,t){e.rewriteTargets.add(f.resolve(t));}async function Ur(e){try{let t=await S.readFile(yt(e),"utf8"),r=JSON.parse(t);if(r&&typeof r=="object"&&r.pages&&typeof r.pages=="object"){if((r.schemaVersion===2||r.schemaVersion===3)&&r.assets&&typeof r.assets=="object")return {schemaVersion:3,updatedAt:String(r.updatedAt||""),pages:Object.fromEntries(Object.entries(r.pages).map(([s,n])=>[s,at(n)])),assets:Object.fromEntries(Object.entries(r.assets).map(([s,n])=>[s,jr(n)]))};if(r.schemaVersion===1)return {schemaVersion:3,updatedAt:String(r.updatedAt||""),pages:Object.fromEntries(Object.entries(r.pages).map(([s,n])=>[s,at(n)])),assets:{}}}}catch{}return vt()}function $e(e){return JSON.parse(JSON.stringify(e))}async function qr(e,t){let r=yt(e);await S.mkdir(f.dirname(r),{recursive:true}),await S.writeFile(r,JSON.stringify(t,null,2),"utf8");}async function K(e,t){if(!t.trackManifest)return;let r=async()=>{let s=$e(t.manifest);s.updatedAt=new Date().toISOString(),t.manifest.updatedAt=s.updatedAt,await qr(e,s);};t.manifestSaveChain=t.manifestSaveChain.then(r,r),await t.manifestSaveChain;}function ie(e){if(!e)return null;let t=e.trim();return t||null}function Qr(e,t){let r=new Set,s=new Set([...Object.keys(e),...Object.keys(t)]);for(let n of s){let i=e[n],u=t[n];!i||!u||i===u||r.add(n);}return r}async function Nr(e,t,r,s){let n=[...new Set(r.map(l=>l.trim()).filter(Boolean))],i=String(e.wpsuite?.runtimeToken||"").trim();if(n.length===0||!i)return new Map;let u=new URL("/wp-json/smartcloud-static-publisher/v1/change-tokens",e.sourceOrigin).toString();try{let l=await t.post(u,{timeout:3e4,failOnStatusCode:!1,headers:{"content-type":"application/json","x-static-publisher-token":i},data:JSON.stringify({urls:n})});if(!l.ok())return s.warn(`Change token lookup failed with HTTP ${l.status()}`,{endpoint:u,status:l.status()}),new Map;let a=await l.json().catch(()=>null);if(!a||!Array.isArray(a.items))return new Map;let o=new Map;for(let d of a.items)!d||typeof d.url!="string"||o.set(d.url,d);return o}catch(l){return s.warn("Change token lookup failed; falling back to sitemap metadata",{endpoint:u,error:String(l)}),new Map}}async function Ae(e,t,r,s,n){if(!r.enabled&&!r.trackManifest)return null;if(r.changeTokenCache.has(s))return r.changeTokenCache.get(s)??null;let u=(await Nr(e,t,[s],n)).get(s)??null;return Ee(e,s)&&(!u||u.supported!==true||!u.token)&&(u=await Br(e,t,s,n)),u=_r(e,u),r.changeTokenCache.set(s,u),u}function Wr(e){return `subscriber=${e.wpsuite?.siteSettings?.subscriber===true?"1":"0"}`}function _r(e,t){if(!t?.supported||!t.token)return t;let r=Wr(e);return {...t,token:re(`${t.token}
7
- ${r}`,40),tokenSource:t.tokenSource?`${t.tokenSource}+site-subscriber`:"site-subscriber"}}async function Br(e,t,r,s){try{let n=await t.get(r,{timeout:Math.min(e.navigationTimeoutMs,15e3),failOnStatusCode:!1});if(n.status()!==404)return s.warn(`Generated 404 fallback token skipped for ${r}`,{url:r,status:n.status(),requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),null;let i=await n.text().catch(()=>""),u=re(`${r}
4
+ `;return e.replace(/<head\b[^>]*>/i,n=>`${n}${s} ${t}`)}function mr(e){let t=U(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function wr(e,t){let r=[...new Set(t)].filter(i=>i.includes("/")&&!/\\+\//.test(i)).map(i=>[i,pe(i)]).filter(([i,u])=>i!==u).sort((i,u)=>u[0].length-i[0].length);if(!r.length)return e;let s=i=>{let u=i;for(let[l,o]of r)u=u.split(l).join(o);return u},n=e.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(i,u,l,o)=>`${u}${s(l)}${o}`);return n=n.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(i,u,l,o,a)=>mr(o)?`${u}${s(o)}${a}`:i),n}function Pr(e,t){if(!t)return null;let r=f.dirname(f.resolve(t)),s=f.resolve(e.outputDir),n=f.relative(r,s).replace(/\\/g,"/");return n?(n.startsWith(".")||(n=`./${n}`),n.endsWith("/")?n:`${n}/`):"./"}function br(e,t,r){let s=Pr(t,r);if(!s)return e;let n=e;for(let i of ur){let u=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),l=new RegExp(`(?:\\.{1,}/)+${u}`,"g"),o=new RegExp(`(?<!\\.)/${u}`,"g");n=n.replace(l,`${s}${i}`).replace(o,`${s}${i}`);let a=i.replace(/\//g,"\\/"),g=s.replace(/\//g,"\\/"),d=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=new RegExp(`(?:\\.{1,}\\\\/)+${d}`,"g"),p=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${d}`,"g"),h=new RegExp(`(?<![\\.\\\\])\\/${d}`,"g");n=n.replace(c,`${g}${a}`).replace(p,`${g}${a}`).replace(h,`${g}${a}`);}return n}function Ae(e,t,r){if(e.urlRewriteMode==="absolute")return t;let s=(()=>{try{return new URL(t,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin)}catch{return null}})(),n=s?s.pathname:rt(t,e.targetOrigin),i=s?`${s.search}${s.hash}`:"";return e.urlRewriteMode==="root-relative"?`${n}${i}`:`${st(e.outputDir,r,n)}${i}`}function Te(e,t,r,s,n){ge(e,r,Ae(t,s,n));}function Sr(e,t,r,s,n){if(!r||r===s)return;ge(e,r,s);let i=Ae(t,r,n),u=Ae(t,s,n);ge(e,i,u);}function Me(e,t,r,s,n={}){let i=e,u={};Te(u,t,t.sourceOrigin,t.targetOrigin,s);for(let[o,a]of Object.entries(t.extraReplacements))Te(u,t,o,a,s);for(let[o,a]of Object.entries(r))Te(u,t,o,a,s);for(let[o,a]of Object.entries(n)){let g=r[o];!g||g===a||Sr(u,t,a,g,s);}let l=Object.entries(u).sort((o,a)=>a[0].length-o[0].length);for(let[o,a]of l)i=gr(i,o,a);return t.urlRewriteMode!=="absolute"&&(i=br(i,t,s)),i=wr(i,l.map(([,o])=>o)),fr(t,i,s)&&(i=hr(i)),i}async function yr(e,t,r,s){let n=f.join(e.outputDir,s),i=f.extname(n).toLowerCase(),u;try{u=await b.readFile(n,"utf8");}catch(a){if(a.code!=="ENOENT")throw a;return {changed:false}}let o=Me(u,e,t,i===".js"||i===".mjs"?void 0:n,r);return o!==u?(await se(n,o,"utf8"),{changed:true}):{changed:false}}async function vr(e,t){return await new Promise((r,s)=>{let n=o=>{if(l(),o?.error){s(new Error(o.error));return}r({changed:!!o?.changed});},i=o=>{l(),s(o);},u=o=>{l(),o!==0&&s(new Error(`Rewrite worker exited with code ${o}.`));},l=()=>{e.off("message",n),e.off("error",i),e.off("exit",u);};e.on("message",n),e.on("error",i),e.on("exit",u),e.postMessage({file:t});})}async function it(e,t,r={}){let n=(r.files?[...new Set(r.files)].map(c=>f.resolve(c)).filter(c=>c.startsWith(f.resolve(e.outputDir))).map(c=>f.relative(e.outputDir,c).replace(/\\/g,"/")).filter(c=>c.length>0):await nr(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(c=>c!=="asset-map.json"&&z(c)),i=0;if(n.length===0)return 0;let u=Math.max(1,Number(e.rewriteConcurrency||e.assetDownloadConcurrency||1)),l=Math.max(1,Math.min(u,n.length,availableParallelism()));await r.onStart?.({totalFiles:n.length,workerCount:l});let o=0,a=0,g=null;if(l===1){for(let c of n){let p=await yr(e,t,r.previousAssetMap??{},c);p.changed&&(i+=1),a+=1,await r.onProgress?.({index:a,totalFiles:n.length,changedTextFiles:i,file:c,changed:p.changed});}return i}let d=Array.from({length:l},async()=>{let c=new Worker(new URL("./rewrite-worker.js",import.meta.url),{workerData:{config:e,assetMap:t,previousAssetMap:r.previousAssetMap??{}}});try{for(;!g;){let p=o;if(p>=n.length)return;o+=1;let h=n[p],m=await vr(c,h);m.changed&&(i+=1),a+=1,await r.onProgress?.({index:a,totalFiles:n.length,changedTextFiles:i,file:h,changed:m.changed});}}catch(p){throw g=p instanceof Error?p:new Error(String(p)),g}finally{await c.terminate().catch(()=>{});}});return await Promise.all(d),i}var _={error:0,warn:1,info:2,debug:3},ot=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",fe=ot?f.join(ot,"current-progress.json"):"",at=Promise.resolve();function ut(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function Rr(e,t){let r={...e},s=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","pageQueue","assetQueue","sitemapQueue"]);for(let[n,i]of Object.entries(t)){let u=r[n];if(typeof u=="number"&&typeof i=="number"&&s.has(n)){r[n]=Math.max(u,i);continue}r[n]=i;}return r}function Cr(e,t,r){fe&&(at=at.then(async()=>{let s=new Date,n=s.toISOString();await b.mkdir(f.dirname(fe),{recursive:true});let i=await b.readFile(fe,"utf8").then(m=>JSON.parse(m)).catch(()=>null),u=i&&typeof i.details=="object"&&i.details?i.details:{},l=ut(e),o=i?.currentStep||ut(i?.source||""),a=i?.startedAt||n,g={...i?.stepDurationsSec??{}},d=i?.stepStartedAt||n;if(o&&o!==l&&i?.stepStartedAt){let m=Math.max(0,Math.round((s.getTime()-new Date(i.stepStartedAt).getTime())/1e3));g[o]=(g[o]??0)+m,d=n;}let c=Math.max(0,Math.round((s.getTime()-new Date(d).getTime())/1e3)),p=Math.max(0,Math.round((s.getTime()-new Date(a).getTime())/1e3)),h={checkedAt:n,source:e,message:t,details:Rr(u,r??{}),startedAt:a,currentStep:l,stepStartedAt:d,stepElapsedSec:c,totalElapsedSec:p,stepDurationsSec:g};await b.writeFile(fe,JSON.stringify(h,null,2),"utf8");}).catch(()=>{}));}async function xr(e,t){await b.mkdir(f.dirname(e),{recursive:true}),await b.appendFile(e,`${JSON.stringify(t)}
5
+ `,"utf8");}function kr(e,t){let r=typeof t?.phase=="string"?t.phase.trim():"";return r||(e==="page"?"render-pages":e==="asset"?"download-assets":e==="sitemap"?"discovery":e==="timing"&&typeof t?.name=="string"&&t.name.trim()||"crawl")}function Tr(e,t,r){return {checkedAt:new Date().toISOString(),currentStep:kr(e,r),level:e,message:t,details:r??{}}}var ne=class{constructor(t,r="info"){this.logDir=t;this.level=typeof r=="boolean"?r?"debug":"info":r,this.ensureLogFileReady();}logDir;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;level;get logPath(){return f.join(this.logDir,"crawl.log.jsonl")}get currentEventPath(){return f.join(this.logDir,"current-crawl-event.json")}get rejectedPath(){return f.join(this.logDir,"rejected.jsonl")}get ignoredPath(){return f.join(this.logDir,"ignored.jsonl")}get skippedPath(){return f.join(this.logDir,"skipped-http.jsonl")}get errorsPath(){return f.join(this.logDir,"errors.jsonl")}get timingsPath(){return f.join(this.logDir,"timings.jsonl")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await b.mkdir(this.logDir,{recursive:true}),await b.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(t){this.writeQueue=this.writeQueue.then(t).catch(r=>{this.writeError=r instanceof Error?r:new Error(String(r));});}enqueueLine(t){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await b.appendFile(this.logPath,`${t}
6
+ `,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>xr(t,r));}updateCurrentEvent(t,r,s){let n=Tr(t,r,s);this.enqueueTask(async()=>{await b.mkdir(this.logDir,{recursive:true}),await b.writeFile(this.currentEventPath,JSON.stringify(n,null,2),"utf8");});}push(t,r,s){let n=JSON.stringify({time:new Date().toISOString(),level:t,message:r,...s||{}});this.enqueueLine(n),this.updateCurrentEvent(t,r,s),t==="error"?console.error(r,s||""):t==="warn"?console.warn(r,s||""):(_[this.level]>=_.debug||["summary","page","sitemap","asset","timing"].includes(t))&&console.log(r);}info(t,r){this.push("info",t,r);}debug(t,r){_[this.level]<_.debug||this.push("debug",t,r);}progress(t,r){Cr("crawl.log.jsonl",t,r),this.updateCurrentEvent("progress",t,r);}checkpoint(t,r){this.updateCurrentEvent("checkpoint",t,r);}page(t,r){this.push("page",t,r);}sitemap(t,r){this.push("sitemap",t,r);}asset(t,r){this.push("asset",t,r);}warn(t,r){this.push("warn",t,r);}error(t,r){this.enqueueJsonLine(this.errorsPath,{message:t,...r||{}}),this.push("error",t,r);}summary(t,r){this.push("summary",t,r);}mark(t){this.marks.set(t,Date.now());}endMark(t,r){let s=this.marks.get(t);if(!s)return;let n=Date.now()-s,i={name:t,ms:n,seconds:Number((n/1e3).toFixed(2)),...r||{}};this.enqueueJsonLine(this.timingsPath,i),this.push("timing",`Timing ${t}: ${i.seconds}s`,i);}reject(t,r,s,n){let i={kind:t,url:r,reason:s,source:n};this.enqueueJsonLine(this.rejectedPath,i),_[this.level]>=_.debug&&this.push("reject",`Rejected ${t} ${r}: ${s}`,i);}ignore(t,r,s,n){let i={kind:t,url:r,reason:s,source:n};this.enqueueJsonLine(this.ignoredPath,i),_[this.level]>=_.debug&&this.push("ignore",`Ignored ${t} ${r}: ${s}`,i);}skip(t,r,s,n){let i={kind:t,url:r,status:s,source:n};this.enqueueJsonLine(this.skippedPath,i),this.push("warn",`Skipped ${t} ${r}: HTTP ${s}`,i);}async flush(){let t=Date.now()-this.startedAt,r={name:"total",ms:t,seconds:Number((t/1e3).toFixed(2))};if(this.enqueueJsonLine(this.timingsPath,r),await this.writeQueue,this.writeError)throw this.writeError}};var he="(?: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 lt(e){let t=new Set,r=new RegExp(`["'\\x60]((?:\\.{1,2}/)?[a-z0-9@_][^"'\\x60\\s<>\\\\]*\\.${he}(?:\\?[^"'\\x60\\s<>\\\\]*)?)["'\\x60]`,"gi");for(let s of e.matchAll(r)){let n=s[1];!n||n.startsWith("/")||n.startsWith("//")||/^[a-z][a-z0-9+.-]*:/i.test(n)||t.add(n);}return [...t]}var Ir=["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","application/octet-stream"],vt=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"]),Rt=new Set(["",".html",".htm"]),$r=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),Dr=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function Or(e){let t=[],r="full",s="full",n=false,i=false;for(let u=0;u<e.length;u++){let l=e[u];if(l==="--retry-timeouts")r="retry-timeouts",n=true;else if(l==="--resume")n=true;else if(l==="--resume-rewrite")n=true,i=true;else if(l==="--crawl-mode"){let o=e[++u];if(!o)throw new Error("--crawl-mode requires a value");s=o==="incremental"?"incremental":"full",n||=s==="incremental";}else if(l.startsWith("--crawl-mode="))s=l.slice(13)==="incremental"?"incremental":"full",n||=s==="incremental";else if(l==="--incremental")s="incremental",n=true;else if(l==="--url"){let o=e[++u];if(!o)throw new Error("--url requires a value");r="single-url",n=true,t.push(o);}else if(l.startsWith("--url="))r="single-url",n=true,t.push(l.slice(6));else if(l==="--urls"){let o=e[++u];if(!o)throw new Error("--urls requires a file path");r="single-url",n=true,t.push(`@${o}`);}}return {mode:r,crawlMode:s,urls:t,preserveOutput:n,resumeRewrite:i}}function Ee(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?f.resolve(e):""}function Fr(){let e=Ee();return e?f.resolve(e,".."):""}function jr(){let e=process.env.STATIC_PUBLISHER_WP_ROOT||process.env.WPSUITE_STATIC_PUBLISHER_WP_ROOT||"";return e.trim()?f.resolve(e):""}function Er(e){let t=e.trim(),r=[{alias:"@storage-root",root:Fr(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@runtime",root:Ee(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@wp-root",root:jr(),requiredEnv:"STATIC_PUBLISHER_WP_ROOT or WPSUITE_STATIC_PUBLISHER_WP_ROOT"}];for(let s of r){if(t!==s.alias&&!t.startsWith(`${s.alias}/`))continue;if(!s.root)return {resolvedPath:null,alias:s.alias,requiredEnv:s.requiredEnv};let n=t.slice(s.alias.length).replace(/^\/+/,"");return {resolvedPath:n?f.resolve(s.root,n):s.root,alias:s.alias}}return {resolvedPath:f.resolve(t)}}function Ct(e){let t=Ee();return t?f.join(t,"crawl-manifest.json"):f.join(e.outputDir,".crawl-manifest.json")}function xt(){return {schemaVersion:3,updatedAt:"",pages:{},assets:{}}}function ct(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 Ur(e){let t=e.isText===true;return {url:String(e.url||""),outputPath:String(e.outputPath||""),isText:t,contentType:typeof e.contentType=="string"&&e.contentType?e.contentType:null,discoveredAssets:Array.isArray(e.discoveredAssets)?e.discoveredAssets.map(r=>String(r)):[],lastCrawledAt:String(e.lastCrawledAt||""),lastSeenRunId:String(e.lastSeenRunId||""),rewriteComplete:e.rewriteComplete===true||!t}}function De(e){let t=e?.["content-type"]?.trim();return t||null}function qr(){return {rewriteTargets:new Set,changedFiles:new Set,deletedFiles:new Set}}function Q(e,t,r){let s=ee(t.outputDir,r);s&&(e.changedFiles.add(s),e.deletedFiles.delete(s));}function dt(e,t,r){let s=ee(t.outputDir,r);s&&(e.deletedFiles.add(s),e.changedFiles.delete(s));}function oe(e,t){e.rewriteTargets.add(f.resolve(t));}async function Qr(e){try{let t=await b.readFile(Ct(e),"utf8"),r=JSON.parse(t);if(r&&typeof r=="object"&&r.pages&&typeof r.pages=="object"){if((r.schemaVersion===2||r.schemaVersion===3)&&r.assets&&typeof r.assets=="object")return {schemaVersion:3,updatedAt:String(r.updatedAt||""),pages:Object.fromEntries(Object.entries(r.pages).map(([s,n])=>[s,ct(n)])),assets:Object.fromEntries(Object.entries(r.assets).map(([s,n])=>[s,Ur(n)]))};if(r.schemaVersion===1)return {schemaVersion:3,updatedAt:String(r.updatedAt||""),pages:Object.fromEntries(Object.entries(r.pages).map(([s,n])=>[s,ct(n)])),assets:{}}}}catch{}return xt()}function Oe(e){return JSON.parse(JSON.stringify(e))}async function Wr(e,t){let r=Ct(e);await b.mkdir(f.dirname(r),{recursive:true}),await b.writeFile(r,JSON.stringify(t,null,2),"utf8");}async function Y(e,t){if(!t.trackManifest)return;let r=async()=>{let s=Oe(t.manifest);s.updatedAt=new Date().toISOString(),t.manifest.updatedAt=s.updatedAt,await Wr(e,s);};t.manifestSaveChain=t.manifestSaveChain.then(r,r),await t.manifestSaveChain;}function ie(e){if(!e)return null;let t=e.trim();return t||null}function Nr(e,t){let r=new Set,s=new Set([...Object.keys(e),...Object.keys(t)]);for(let n of s){let i=e[n],u=t[n];!i||!u||i===u||r.add(n);}return r}async function Br(e,t,r,s){let n=[...new Set(r.map(l=>l.trim()).filter(Boolean))],i=String(e.wpsuite?.runtimeToken||"").trim();if(n.length===0||!i)return new Map;let u=new URL("/wp-json/smartcloud-static-publisher/v1/change-tokens",e.sourceOrigin).toString();try{let l=await t.post(u,{timeout:3e4,failOnStatusCode:!1,headers:{"content-type":"application/json","x-static-publisher-token":i},data:JSON.stringify({urls:n})});if(!l.ok())return s.warn(`Change token lookup failed with HTTP ${l.status()}`,{endpoint:u,status:l.status()}),new Map;let o=await l.json().catch(()=>null);if(!o||!Array.isArray(o.items))return new Map;let a=new Map;for(let g of o.items)!g||typeof g.url!="string"||a.set(g.url,g);return a}catch(l){return s.warn("Change token lookup failed; falling back to sitemap metadata",{endpoint:u,error:String(l)}),new Map}}async function Le(e,t,r,s,n){if(!r.enabled&&!r.trackManifest)return null;if(r.changeTokenCache.has(s))return r.changeTokenCache.get(s)??null;let u=(await Br(e,t,[s],n)).get(s)??null;return Qe(e,s)&&(!u||u.supported!==true||!u.token)&&(u=await zr(e,t,s,n)),u=Hr(e,u),r.changeTokenCache.set(s,u),u}function _r(e){return `subscriber=${e.wpsuite?.siteSettings?.subscriber===true?"1":"0"}`}function Hr(e,t){if(!t?.supported||!t.token)return t;let r=_r(e);return {...t,token:re(`${t.token}
7
+ ${r}`,40),tokenSource:t.tokenSource?`${t.tokenSource}+site-subscriber`:"site-subscriber"}}async function zr(e,t,r,s){try{let n=await t.get(r,{timeout:Math.min(e.navigationTimeoutMs,15e3),failOnStatusCode:!1});if(n.status()!==404)return s.warn(`Generated 404 fallback token skipped for ${r}`,{url:r,status:n.status(),requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),null;let i=await n.text().catch(()=>""),u=re(`${r}
8
8
  404
9
- ${i}`,40);return s.info(`Using generated 404 fallback change token for ${r}`,{url:r,requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),{url:r,supported:!0,token:u,tokenSource:"generated-404-response-hash",postId:null,dependencyPostIds:[],reason:null}}catch(n){return s.warn(`Generated 404 fallback token lookup failed for ${r}`,{url:r,error:String(n),requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),null}}async function Hr(e,t,r,s,n,i){let u=Ee(e,n);if(!s.enabled)return {action:"render",changeToken:s.trackManifest?await Ae(e,t,s,n,i):null};let l=s.manifest.pages[n];if(!l)return {action:"render",changeToken:await Ae(e,t,s,n,i)};let a=await Ae(e,t,s,n,i);if(a?.supported&&a.token)return l.changeToken===a.token?u&&!await zr(e,t,n,i)?{action:"render",changeToken:a}:{action:"reuse",changeToken:a}:{action:"render",changeToken:a};let o=ie(r.sitemapLastmodByPage[n]);return o&&l.sitemapLastmod&&l.sitemapLastmod===o?{action:"reuse",changeToken:a}:{action:"render",changeToken:a}}async function zr(e,t,r,s){try{let i=(await t.get(r,{timeout:Math.min(e.navigationTimeoutMs,15e3),failOnStatusCode:!1})).status();return i===404?!0:(s.warn(`Generated 404 request path no longer returns 404 for ${r}`,{url:r,status:i,requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),!1)}catch(n){return s.warn(`Generated 404 status probe failed for ${r}`,{url:r,error:String(n),requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),false}}async function Jr(e,t,r,s,n){let i=lt(r.previousManifest,void 0,s,"previous-manifest"),u=0;for(let[c,g]of Object.entries(r.manifest.pages))if(!r.seenPages.has(c)){ut(n,e,g.outputPath);try{await S.unlink(g.outputPath);}catch(m){(m.code||"")!=="ENOENT"&&s.warn(`Failed to remove stale incremental page output for ${c}`,{url:c,outputPath:g.outputPath,error:String(m)});}delete r.manifest.pages[c],u++;}let l=lt(r.manifest,r.runId,s,"active-manifest"),a=new Set,o=new Set;for(let c of l){for(let w of ae(e,c))a.add(w);let g=r.manifest.assets[c]?.outputPath;g&&o.add(g);let m=ue(e,t.assetMap,c);m&&o.add(m);}for(let c of Object.keys(r.manifest.assets))l.has(c)||delete r.manifest.assets[c];let d=0,p=0;for(let c of i){let g=new Set,m=r.previousManifest.assets[c]?.outputPath;m&&g.add(m);let w=ue(e,t.assetMap,c);if(!l.has(c)&&w)g.add(w);else if(!l.has(c)){let h=cs(e,c,s,"incremental-cleanup");h&&(g.add(h.originalFilePath),h.hashedFilePath&&g.add(h.hashedFilePath));}for(let h of g)if(!o.has(h)){ut(n,e,h);try{await S.unlink(h),d++;}catch(C){(C.code||"")!=="ENOENT"&&s.warn(`Failed to remove stale incremental asset output for ${c}`,{url:c,outputPath:h,error:String(C)});}}for(let h of ae(e,c))a.has(h)||Object.prototype.hasOwnProperty.call(t.assetMap,h)&&(delete t.assetMap[h],p++);}(u>0||d>0||p>0)&&s.info(`Incremental cleanup removed ${u} stale pages, ${d} stale assets, ${p} stale asset mappings`,{removedPages:u,removedAssets:d,removedAssetMappings:p,phase:"incremental-cleanup"});}function lt(e,t,r,s){let n=new Set,i=u=>{let l=u.trim();if(l){if(r){let a=J(l,r,"asset",s??"manifest");if(!a)return;n.add(a.toString());return}n.add(l);}};for(let u of Object.values(e.pages))for(let l of u.discoveredAssets||[])i(l);for(let[u,l]of Object.entries(e.assets||{}))t&&l.lastSeenRunId!==t||i(u);return n}function ct(e,t,r){for(let s of t)for(let n of ae(e,s))if(r.has(n))return true;return false}function Gr(e,t,r,s,n){let i=new Set(r.rewriteTargets);for(let l of Object.values(t.manifest.pages))l.rewriteComplete||i.add(f.resolve(l.outputPath));for(let l of Object.values(t.manifest.assets))l.isText&&!l.rewriteComplete&&i.add(f.resolve(l.outputPath));let u=Qr(s,n);if(u.size===0)return [...i];for(let l of Object.values(t.manifest.pages))ct(e,l.discoveredAssets,u)&&i.add(f.resolve(l.outputPath));for(let[l,a]of Object.entries(t.manifest.assets)){a.isText&&ct(e,a.discoveredAssets,u)&&i.add(f.resolve(a.outputPath));for(let o of ae(e,l))if(u.has(o)){q(r,e,a.outputPath),a.isText&&i.add(f.resolve(a.outputPath));break}}return [...i]}function Vr(e,t){let r=t?new Set(Array.from(t,n=>f.resolve(n))):null,s=n=>r===null||r.has(f.resolve(n));for(let n of Object.values(e.manifest.pages))s(n.outputPath)&&(n.rewriteComplete=true);for(let n of Object.values(e.manifest.assets)){if(!n.isText){n.rewriteComplete=true;continue}s(n.outputPath)&&(n.rewriteComplete=true);}}function Kr(e,t,r){let s=new Set,n=i=>{if(!i)return;let u=ee(e.outputDir,i);u&&s.add(u);};for(let i of t.donePages)n(B(e,i));for(let i of Object.values(r.manifest.pages))i.lastSeenRunId===r.runId&&n(i.outputPath);for(let i of t.doneAssets)n(ue(e,t.assetMap,i));for(let i of Object.values(r.manifest.assets))i.lastSeenRunId===r.runId&&n(i.outputPath);return s}async function Yr(e,t,r,s,n){let i=[...s.deletedFiles].sort(),u=Kr(e,t,r),l=0;for(let d of [...u].sort()){try{if((await S.stat(f.join(e.outputDir,d))).isFile())continue}catch{}l++,n.warn(`Active output is missing after crawl: ${d}`,{phase:"deploy-plan",file:d,outputPath:f.join(e.outputDir,d)});}if(l>0&&n.warn(`Detected ${l} active output file(s) missing before deploy plan save.`,{phase:"deploy-plan",missingActiveOutputs:l}),i.length===0)return [];let a=[],o=0;for(let d of i){if(!u.has(d)){a.push(d);continue}o++;let p=f.join(e.outputDir,d),c;try{c=(await S.stat(p)).isFile();}catch{c=false;}n.warn(`Deploy plan protected active output from deletion: ${d}`,{phase:"deploy-plan",file:d,outputPath:p,exists:c});}return o>0&&n.info(`Deploy plan skipped ${o} active output deletion(s).`,{phase:"deploy-plan",protectedDeletes:o,deletedFiles:a.length}),a}function ae(e,t){let r=new Set([t]);try{let s=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 u of i)try{r.add(new URL(u).origin+s.pathname+s.search);}catch{}r.add(s.pathname+s.search),r.add(s.pathname);}catch{}return [...r]}function Zr(e,t){let r=new Set([t]);try{let s=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 u of i)try{r.add(new URL(u).origin+s.pathname+s.search);}catch{}r.add(s.pathname+s.search);}catch{}return [...r]}function Rt(e,t){let r=e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/"?e.targetOrigin:"https://relative.invalid/";try{let s=new URL(t,r);return f.join(e.outputDir,je(s.pathname))}catch{return null}}function Xr(e,t,r){for(let s of Zr(e,r)){let n=t[s];if(!n)continue;let i=Rt(e,n);if(i)return {outputPath:i,publicUrl:n}}return null}function es(e,t,r){for(let s of ae(e,r)){let n=t[s];if(!n)continue;let i=Rt(e,n);if(i)return i}return null}function ue(e,t,r){let s=es(e,t,r);if(s)return s;try{return Ue(e,r).originalFilePath}catch{return null}}function ts(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?f.join(f.resolve(e),"queue-runner-heartbeat.json"):""}async function dt(e){let t=ts();if(t)try{let r=await S.readFile(t,"utf8"),s=JSON.parse(r);if(!s||typeof s!="object")return;await S.writeFile(t,JSON.stringify({...s,checkedAt:new Date().toISOString(),status:"running",currentStep:"rewrite",message:e},null,2),"utf8");}catch{}}function rs(e,t){let r=new Set;for(let s of t.donePages)r.add(f.resolve(B(e,s)));for(let s of t.doneAssets){let n=ue(e,t.assetMap,s);!n||!z(n)||r.add(f.resolve(n));}return [...r]}var we="re:",he=new Map;function ss(e){if(!e.startsWith(we))return null;let t=he.get(e);if(t!==void 0)return t||null;let r=e.slice(we.length).trim();if(!r)return he.set(e,false),null;try{let s=new RegExp(r);return he.set(e,s),s}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),he.set(e,false),null}}function Fe(e,t){let r=ss(t);return r?r.test(e):t.startsWith(we)?false:e.startsWith(t)}function ns(e,t){return t.find(r=>Fe(e,r))}function Ct(e,t){let r=ns(t.pathname,e.blockedPathPrefixes);if(r)return r.startsWith(we)?`blocked path regex: ${r}`:`blocked path prefix: ${r}`;let s=e.blockedSearchFragments.find(n=>t.search.includes(n));return s?`blocked search fragment: ${s}`:null}function is(e){let t=new URL(e.sourceOrigin),r=new Set([t.hostname,...e.allowedAssetHosts]);if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{r.add(new URL(e.targetOrigin).hostname);}catch{}for(let s of Object.keys(e.extraReplacements||{}))try{r.add(new URL(s).hostname);}catch{}return r}function os(e,t){return is(e).has(t.hostname)}function as(e){let t=E(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function kt(e){let t=E(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function us(e){let t=E(e).replace(/\\\//g,"/").trim(),r=f.extname(t).toLowerCase();return St.has(r)||bt.has(r)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function Y(e){return Ir.some(t=>e.pathname.startsWith(t))}function A(e,t,r=e.sourceOrigin,s,n="url"){let i=as(t);if(!i||i.startsWith("data:")||i.startsWith("blob:")||i.startsWith("mailto:")||i.startsWith("tel:")||i.startsWith("#"))return s?.ignore(n,t,"empty or unsupported scheme",r),null;if(kt(i))return s?.ignore(n,t,"looks like JavaScript/code fragment",r),null;if(us(i))return s?.ignore(n,t,"looks like JavaScript property access",r),null;try{let u=new URL(i,r);if(xt(u))return s?.reject(n,t,"malformed URL encoding",r),null;if(!["http:","https:"].includes(u.protocol))return s?.ignore(n,t,"unsupported protocol: ",r),null;if(!os(e,u))return s?.ignore(n,u.toString(),"host not allowed",r),null;let l=Ct(e,u);if(l)return s?.reject(n,u.toString(),l,r),null;let a=new URL(e.sourceOrigin);return u.protocol=a.protocol,u.host=a.host,u.hash="",u}catch{return s?.reject(n,t,"invalid URL",r),null}}function xt(e){try{return decodeURIComponent(e.pathname),decodeURIComponent(e.search),decodeURIComponent(e.hash),!1}catch{return true}}function J(e,t,r,s){try{let n=new URL(e);return xt(n)?(t.reject(r,e,"malformed URL encoding",s),null):n.protocol!=="http:"&&n.protocol!=="https:"?(t.reject(r,e,`unsupported protocol: ${n.protocol}`,s),null):n}catch{return t.reject(r,e,"invalid URL",s),null}}function Tt(e){return St.has(f.extname(e.pathname).toLowerCase())}function G(e){return Y(e)?false:bt.has(f.extname(e.pathname).toLowerCase())}function de(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function k(e,t){return !!(de(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(r=>Fe(t.pathname,r))||Tt(t)||!G(t)&&!Y(t))}function B(e,t){let r=new URL(t),s=je(r.pathname);return s.endsWith("/")?s+="index.html":f.extname(s)||(s+="/index.html"),f.join(e.outputDir,s)}function je(e){try{return decodeURIComponent(e)}catch{return e}}function ls(e){if(!e.generated404RequestPath)return null;try{let t=new URL(e.generated404RequestPath,e.sourceOrigin);return !t.pathname.endsWith("/")&&f.extname(t.pathname)===""&&(t.pathname+="/"),t.hash="",t.toString()}catch{return null}}function Ee(e,t){let r=ls(e);if(!r)return false;try{return new URL(t,e.sourceOrigin).toString()===r}catch{return false}}function Ue(e,t){let r=new URL(t),s=je(r.pathname);s.endsWith("/")&&(s+="index.html");let n=!!r.search,i=s,u=f.join(e.outputDir,i),l=Ce(e.targetOrigin,i),a=`${l}${r.search}`;if(!n)return {originalPathname:i,originalFilePath:u,originalPublicUrl:l,originalPublicUrlWithSearch:a,preferQueryHashed:n};let o=f.extname(s),p=`${o?s.slice(0,-o.length):s}.${re(r.search)}${o||".bin"}`;return {originalPathname:i,originalFilePath:u,originalPublicUrl:l,originalPublicUrlWithSearch:a,preferQueryHashed:n,hashedPathname:p,hashedFilePath:f.join(e.outputDir,p),hashedPublicUrl:Ce(e.targetOrigin,p)}}function cs(e,t,r,s){let n=J(t,r,"asset",s);return n?Ue(e,n.toString()):null}function ds(e,t,r,s,n){t[r]=s;try{let i=new URL(r),l=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{l.push(new URL(e.targetOrigin).origin);}catch{}for(let a of l)try{let o=new URL(a);t[o.origin+i.pathname+i.search]=s;}catch{}try{let a=(()=>{let o=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin);return `${o.pathname}${o.search}`})();t[i.pathname+i.search]=a;}catch{}try{let a=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=a;}catch{}try{let a=new URL(n,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=a;}catch{}}catch{}}async function At(e){try{return await S.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Mt(e){try{return await S.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function ps(e){let t=String(e["content-length"]||"").trim();if(!t)return null;let r=Number.parseInt(t,10);return Number.isFinite(r)&&r>=0?r:null}function Lt(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let r=Date.parse(t);return Number.isFinite(r)?r:null}function gs(e,t){let r=Lt(t),s=ps(t),n=e?.mtime.getTime();return r!==null&&Math.abs((n??0)-r)>=1e3||s!==null&&e?.size!==s?false:r!==null||s!==null}async function fs(e,t){if(!t)return;let r=Lt(t);if(r===null)return;let s=await Mt(e);if(!s)return;let n=new Date(r);await S.utimes(e,s.atime,n).catch(()=>{});}function pt(e,t){let r=f.extname(e.pathname).toLowerCase(),s=t["content-type"]||"";return Lr.has(r)||Mr.some(n=>s.includes(n))&&!s.startsWith("image/")&&!s.includes("font")}function Me(e,t){(e.doneAssets.size%25===0||e.doneAssets.size===1||e.doneAssets.size===e.stats.assetsQueued)&&t.progress(`Asset download progress: downloaded ${e.doneAssets.size}, discovered ${e.stats.assetsQueued}.`,{doneAssets:e.doneAssets.size,assetsQueued:e.stats.assetsQueued,phase:"download-assets"});}function hs(e){return re(e.toString("base64"),40)}function ms(e,t,r){let s=e.assetVariantDigestsByOriginalPath.get(t);if(!s||s.size===0)return false;for(let n of s)if(n!==r)return true;return false}function ws(e,t,r){let s=e.assetVariantDigestsByOriginalPath.get(t);s||(s=new Set,e.assetVariantDigestsByOriginalPath.set(t,s)),s.add(r);}async function De(e,t,r,s,n,i,u){let l=Ue(e,r),a=hs(s),o=l.originalFilePath,d=l.originalPublicUrlWithSearch;if(l.preferQueryHashed&&l.hashedFilePath&&l.hashedPublicUrl&&ms(n,l.originalFilePath,a)){let m=Xr(e,t,r);m?(o=m.outputPath,d=m.publicUrl):(o=l.hashedFilePath,d=l.hashedPublicUrl);}ds(e,t,r,d,l.originalPublicUrl);let p=z(o)?Buffer.from(Te(s.toString("utf8"),e,t,o),"utf8"):s,c=await At(o),g=false;return (c===null||!c.equals(p))&&(await se(o,p),g=true),i?.debug(`${g?"Saved":"Skipped unchanged"} asset output ${r}`,{phase:"download-assets",url:r,outputPath:o,bytes:p.length,wroteFile:g}),ws(n,l.originalFilePath,a),await fs(o,u),n.stats.assetsSaved++,i&&(n.stats.assetsSaved%50===0||n.stats.assetsSaved===1)&&i.progress(`Asset progress: saved ${n.stats.assetsSaved}, discovered ${n.stats.assetsQueued}, pending ${n.assetQueue.length}.`,{assetsSaved:n.stats.assetsSaved,assetsQueued:n.stats.assetsQueued,assetQueue:n.assetQueue.length,phase:"download-assets"}),{outputPath:o,publicUrl:d,wroteFile:g}}function le(e,t,r,s,n){let i=()=>{let p=String(n??"").trim();if(!p)return {discoveredFrom:"",discoveredFromType:"unknown"};if(p==="seed-path"||p==="cli"||p==="generated-404-request-path")return {discoveredFrom:p,discoveredFromType:p};if(/^https?:\/\//i.test(p))try{let c=new URL(p);return de(c)?{discoveredFrom:p,discoveredFromType:"sitemap"}:k(e,c)?{discoveredFrom:p,discoveredFromType:"asset"}:G(c)&&!Y(c)?{discoveredFrom:p,discoveredFromType:"page"}:{discoveredFrom:p,discoveredFromType:"url"}}catch{return {discoveredFrom:p,discoveredFromType:"url"}}return {discoveredFrom:p,discoveredFromType:"url"}},u=n&&/^https?:\/\//i.test(n)?n:e.sourceOrigin,l=A(e,r,u,s,"page");if(!l)return;if(!G(l)||Tt(l)){if(k(e,l)){s.info(`Seeded/non-page URL queued as asset: ${l.toString()}`,{url:l.toString(),source:n}),I(e,t,l.toString(),s,n);return}s.reject("page",l.toString(),Y(l)?"asset/internal path cannot be page":"not page-like",n);return}let a=l.toString(),{discoveredFrom:o,discoveredFromType:d}=i();o&&!t.pageDiscoverySources.has(a)&&t.pageDiscoverySources.set(a,o),!t.donePages.has(a)&&!t.queuedPages.has(a)&&(t.queuedPages.add(a),t.pageQueue.push(a),t.stats.pagesQueued++,s.debug(`Queued discovered page ${a}`,{phase:"discovery",url:a,discoveredFrom:o,discoveredFromType:d,outputPath:B(e,a)}),(t.stats.pagesQueued%25===0||t.stats.pagesQueued===1)&&s.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 I(e,t,r,s,n){let i=n&&/^https?:\/\//i.test(n)?n:e.sourceOrigin,u=A(e,r,i,s,"asset");if(!u)return;if(!k(e,u)){s.reject("asset",u.toString(),"not a safe asset path/prefix",n);return}let l=u.toString();!t.doneAssets.has(l)&&!t.queuedAssets.has(l)&&(t.queuedAssets.add(l),t.assetQueue.push(l),t.stats.assetsQueued++,(t.stats.assetsQueued%100===0||t.stats.assetsQueued===1)&&s.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 qe(e,t,r,s,n){let i=n&&/^https?:\/\//i.test(n)?n:e.sourceOrigin,u=A(e,r,i,s,"sitemap");if(!u)return;if(!de(u)){s.reject("sitemap",u.toString(),"not sitemap-like",n);return}let l=u.toString();!t.doneSitemaps.has(l)&&!t.queuedSitemaps.has(l)&&(t.queuedSitemaps.add(l),t.sitemapQueue.push(l),t.stats.sitemapsQueued++,(t.stats.sitemapsQueued%10===0||t.stats.sitemapsQueued===1)&&s.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 Ps(e){let t=E(e),r=[...t.matchAll(/<url>\s*([\s\S]*?)\s*<\/url>/gi)].map(s=>s[1]);return r.length>0?r.map(s=>{let n=s.match(/<loc>\s*([^<]+?)\s*<\/loc>/i);if(!n?.[1])return null;let i=s.match(/<lastmod>\s*([^<]+?)\s*<\/lastmod>/i);return {loc:n[1].trim(),lastmod:ie(i?.[1]??null)}}).filter(s=>!!s):[...t.matchAll(/<loc>\s*([^<]+?)\s*<\/loc>/gi)].map(s=>({loc:s[1].trim(),lastmod:null})).filter(s=>s.loc)}function Ss(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function bs(e){let t=[],r=/url\(\s*(?:"([^"]+)"|'([^']+)'|([^)]*?))\s*\)/gi;for(let s of e.matchAll(r)){let n=e.slice(Math.max(0,s.index-8),s.index);if(/\bnew\s+$/i.test(n))continue;let i=(s[1]||s[2]||s[3]||"").trim();i&&t.push(i);}return t}function ys(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function vs(e,t){if(t==="dom-style")return true;let r=(()=>{try{return f.extname(new URL(e).pathname).toLowerCase()}catch{return ""}})();return !(r===".js"||r===".mjs"||r===".map"||t.includes("javascript"))}function Le(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function It(e,t,r,s){let n=[];await S.mkdir(t,{recursive:true});let i=await S.readdir(e,{withFileTypes:true});for(let u of i){let l=f.join(e,u.name),a=f.join(t,u.name);if(u.isDirectory()){n.push(...await It(l,a,r,s));continue}await $t(l,a,r,s)&&n.push(a);}return n}async function Rs(e,t){try{let[r,s]=await Promise.all([S.stat(e),S.stat(t)]);if(r.size!==s.size)return !1;let[n,i]=await Promise.all([S.readFile(e),S.readFile(t)]);return n.equals(i)}catch{return false}}async function $t(e,t,r,s){let n=f.resolve(t);return r.has(n)?(s.debug("Skipped post-crawl copy over crawled page output",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):await Rs(e,t)?(s.debug("Skipped unchanged post-crawl copy target",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):(await S.mkdir(f.dirname(t),{recursive:true}),await S.copyFile(e,t),true)}async function Cs(e,t,r){let s=Object.entries(e.postCrawlCopyMap||{}).map(([l,a])=>({sourcePath:l.trim(),prefix:String(a||"").trim()}));if(s.length===0)return [];let n=0,i=[],u=new Set([...t.donePages].map(l=>f.resolve(B(e,l))));r.mark("copy-extra-paths");for(let l of s){let a=l.sourcePath,o=l.prefix;if(!a||!o){r.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:a,prefixPath:o});continue}let d=Fr(a);if(!d.resolvedPath){r.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:a,alias:d.alias||"",requiredEnv:d.requiredEnv||"",prefixPath:o});continue}let p=d.resolvedPath,c=Le(o);if(!c){r.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:a,prefixPath:o});continue}let g;try{g=await S.stat(p);}catch{r.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:a,sourceAbs:p,prefixPath:o});continue}let m=f.resolve(e.outputDir,c);if(g.isDirectory()){let P=await It(p,m,u,r);i.push(...P),n+=P.length,P.length>0&&r.progress(`Copied static directory to export: ${p} -> /${c}`,{phase:"copy-extra-paths",sourcePath:p,targetPath:`/${c}`,copiedItems:n,changedFiles:P.length});continue}let w=f.basename(p),h=o.endsWith("/")?f.join(m,w):m;await $t(p,h,u,r)&&(i.push(h),n++,r.progress(`Copied static file to export: ${p} -> /${Le(o.endsWith("/")?`${o}${w}`:o)}`,{phase:"copy-extra-paths",sourcePath:p,targetPath:`/${Le(o.endsWith("/")?`${o}${w}`:o)}`,copiedItems:n}));}return r.endMark("copy-extra-paths",{mappedSources:s.length,copiedItems:n}),i}function ce(e,t,r,s,n){let i=new Set,u=E(r).replace(/\\\//g,"/"),l=n==="page-html"?ys(u):u,a=vs(t,n);if(a){for(let p of bs(l)){let c=A(e,p,t,s,`${n}:css-url`);c&&k(e,c)&&i.add(c.toString());}for(let p of l.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let c=A(e,p[1],t,s,`${n}:css-import`);c&&k(e,c)&&i.add(c.toString());}}if(a||n==="page-html")for(let p of l.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let c=A(e,p[1],t,s,`${n}:xml-stylesheet`);c&&k(e,c)&&i.add(c.toString());}let o="(?: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)",d=new RegExp(`(?:https?:)?//[^\\s'"<>\\);]+\\.${o}(?:\\?[^\\s'"<>\\);]*)?|(?<!\\.)/[^\\s'"<>\\);]+\\.${o}(?:\\?[^\\s'"<>\\);]*)?`,"gi");for(let p of u.matchAll(d)){let c=p[0].startsWith("//")?`${new URL(e.sourceOrigin).protocol}${p[0]}`:p[0];if(kt(c)){s.ignore(`${n}:serialized-url`,c,"looks like JavaScript/code fragment",t);continue}let g=A(e,c,t,s,`${n}:serialized-url`);g&&k(e,g)?i.add(g.toString()):g&&s.ignore("asset",g.toString(),"serialized URL did not pass safe asset path filter",t);}return [...i]}function ks(e,t,r,s){let n=new Set,i=E(r);for(let u of i.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let l=u[1],a=A(e,l,t,s,"page-link");a&&(Ct(e,a)||G(a)&&!Y(a)&&!k(e,a)&&n.add(a.toString()));}return [...n]}async function gt(e,t,r,s,n){for(;r.sitemapQueue.length>0;){let i=r.sitemapQueue.shift();r.queuedSitemaps.delete(i);let u=J(i,s,"sitemap","sitemap-queue");if(!u)continue;let l=u.toString();if(!r.doneSitemaps.has(l)){r.doneSitemaps.add(l),s.sitemap(`Fetching sitemap ${l}`,{url:l});try{let a=await t.get(l,{timeout:6e4});if(!a.ok()){s.skip("sitemap",l,a.status());continue}let o=await a.body(),d=a.url()||l,p=J(d,s,"sitemap-response",l);if(!p)continue;let c=p.toString(),g=await De(e,r.assetMap,c,o,r,s);q(n,e,g.outputPath),oe(n,g.outputPath);let m=o.toString("utf8");for(let w of ce(e,c,m,s,"sitemap"))I(e,r,w,s,c);for(let w of Ps(m)){let h=A(e,w.loc,c,s,"sitemap-loc");h&&(de(h)?qe(e,r,h.toString(),s,c):k(e,h)?I(e,r,h.toString(),s,c):G(h)?(w.lastmod&&(r.sitemapLastmodByPage[h.toString()]=w.lastmod),le(e,r,h.toString(),s,c)):s.reject("sitemap-loc",h.toString(),"not page/sitemap/asset-like",c));}}catch(a){s.error(`Failed sitemap ${l}`,{url:l,error:String(a)});}}}}async function xs(e,t,r,s,n,i,u){let l=A(e,s,e.sourceOrigin,n,"asset-fetch");if(!l||!k(e,l))return;let a=l.toString();if(r.doneAssets.has(a))return;let o=i.enabled?i.previousManifest.assets[a]:void 0,d=(p,c={})=>{if(!o)return false;i.manifest.assets[a]={...o,discoveredAssets:[...o.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId},delete i.manifest.pages[a],r.doneAssets.add(a);for(let g of o.discoveredAssets||[])I(e,r,g,n,a);return n.warn(`Keeping previous incremental asset ${a} after fetch issue.`,{url:a,reason:p,preservedFromPreviousManifest:true,...c,phase:"download-assets"}),Me(r,n),true};n.asset(`Fetching asset ${a}`,{url:a});try{let p=ue(e,r.assetMap,a),c=p?await Mt(p):null;if(p&&c)try{let L=await t.head(a,{timeout:6e4}),T=L.headers();if(L.ok()&&gs(c,T)){let H=await At(p);if(H!==null){let Q=L.url()||a,b=J(Q,n,"asset-response",a);if(!b)return;let R=b.toString(),N=await De(e,r.assetMap,R,H,r,n,T);N.wroteFile&&(q(u,e,N.outputPath),z(N.outputPath)&&oe(u,N.outputPath)),r.doneAssets.add(a),n.info(`Reused existing asset ${a} based on response headers.`,{url:a,filePath:p,lastModified:T["last-modified"]||"",contentLength:T["content-length"]||"",phase:"download-assets"}),Me(r,n);let Z=pt(l,T),Pe=o?.discoveredAssets?[...o.discoveredAssets]:[];if(Z||o?.isText){let X=H.toString("utf8"),Ne=ce(e,R,X,n,"asset:cached");(Ne.length>0||!o)&&(Pe=Ne);for(let Ft of Pe)I(e,r,Ft,n,R);}if(i.trackManifest){let X=Z||!!o?.isText;i.manifest.assets[a]={url:a,outputPath:N.outputPath,isText:X,contentType:Ie(T)||o?.contentType||null,discoveredAssets:Pe,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!X},delete i.manifest.pages[a],i.enabled&&X&&await K(e,i);}return}}}catch{}let g=await t.get(a,{timeout:6e4});if(!g.ok()){if(d(`http-${g.status()}`,{status:g.status()}))return;n.skip("asset",a,g.status());return}let m=await g.body(),w=g.url()||a,h=J(w,n,"asset-response",a);if(!h)return;let C=h.toString(),P=g.headers(),y=await De(e,r.assetMap,C,m,r,n,P);y.wroteFile&&(q(u,e,y.outputPath),z(y.outputPath)&&oe(u,y.outputPath)),r.doneAssets.add(a),Me(r,n);let v=pt(l,P),x=[];if(v){let L=m.toString("utf8");x=ce(e,C,L,n,`asset:${f.extname(l.pathname).toLowerCase()||P["content-type"]||"unknown"}`);for(let T of x)I(e,r,T,n,C);}i.trackManifest&&(i.manifest.assets[a]={url:a,outputPath:y.outputPath,isText:v,contentType:Ie(P),discoveredAssets:x,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!v},delete i.manifest.pages[a],i.enabled&&v&&await K(e,i));}catch(p){if(d("fetch-error",{error:String(p)}))return;n.error(`Failed asset ${a}`,{url:a,error:String(p)});}}async function Ts(e,t,r,s,n,i){let u=Math.max(1,Number(e.assetDownloadConcurrency||e.concurrency||1)),l=Array.from({length:u},async()=>{for(;r.assetQueue.length>0;){let a=r.assetQueue.shift();a&&(r.queuedAssets.delete(a),await xs(e,t,r,a,s,n,i));}});await Promise.all(l);}function As(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function U(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function me(e){return Math.max(15e3,Math.min(6e4,U(e)))}function Ms(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function Qe(e){return e.stats.pagesCompleted}function Dt(e){let r=e.options?.browserProcess;return {pid:typeof r?.process?.pid=="number"?r.process.pid:null,kill:typeof r?.kill=="function"?r.kill.bind(r):null}}async function Ls(e,t,r){let s=Dt(e);try{if(s.kill){await s.kill(),t.warn(`Force-killed crawl worker browser after ${r}`,{browserPid:s.pid,reason:r});return}if(s.pid!==null){process.kill(s.pid,"SIGKILL"),t.warn(`Sent SIGKILL to crawl worker browser after ${r}`,{browserPid:s.pid,reason:r});return}t.warn(`Could not resolve crawl worker browser PID after ${r}`,{reason:r});}catch(n){t.error(`Failed to force-kill crawl worker browser after ${r}`,{browserPid:s.pid,reason:r,error:String(n)});}}async function M(e,t,r){let s;try{return await Promise.race([r(),new Promise((n,i)=>{s=globalThis.setTimeout(()=>{i(new Error(`${e} timed out after ${As(t)}.`));},t);})])}finally{s!==void 0&&globalThis.clearTimeout(s);}}async function Is(e,t){let r=Ms(e);await t.evaluate(async s=>{await new Promise(n=>{let i=0,u=700,l=Date.now(),a=()=>{window.clearInterval(o),window.scrollTo(0,0),n();},o=window.setInterval(()=>{if(Date.now()-l>=s.maxDurationMs){a();return}window.scrollBy(0,u),i+=u;let d=document.body?.scrollHeight||0,p=document.documentElement?.scrollHeight||0,c=Math.max(d,p);i>=c+window.innerHeight&&a();},120);});},{maxDurationMs:r});}async function $s(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 Is(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function Ds(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 Os(e,t){return e.noJavaScriptRenderPathPrefixes.some(r=>Fe(t,r))}async function Fs(e,t,r,s,n=true){let i=new Set;if(n){let l=await t.evaluate(()=>{let a=new Set,o=["href","src","poster","data-src","data-lazy-src","data-original","data-bg","data-background","data-href"],d=new Set,p=["srcset","data-srcset","data-lazy-srcset"];return document.querySelectorAll("*").forEach(c=>{for(let m of o){let w=c.getAttribute(m);w&&a.add(w);}for(let m of p){let w=c.getAttribute(m);w&&w.split(",").forEach(h=>{let C=h.trim().split(/\s+/)[0];C&&a.add(C);});}let g=c.getAttribute("style");g&&d.add(g);}),{attrs:[...a],styles:[...d]}});for(let a of l.attrs)for(let o of Ss(a)){let d=A(e,o,r,s,"dom-attr");d&&k(e,d)&&i.add(d.toString());}for(let a of l.styles)for(let o of ce(e,r,a,s,"dom-style"))i.add(o);}let u=await t.content();for(let l of ce(e,r,u,s,"page-html"))i.add(l);return [...i]}async function ft(e,t,r,s,n){let i=B(e,t);await se(i,r,"utf8");let u=await S.stat(i);n?.debug(`Saved page output ${t}`,{phase:"save-pages",url:t,outputPath:i,bytes:u.size}),s.stats.pagesSaved++;let l=Math.min(s.stats.pagesQueued,Qe(s)+1);n&&(s.stats.pagesSaved%10===0||s.stats.pagesSaved===1)&&n.progress(`Page progress: processed ${l}, rendered ${s.stats.pagesRendered}, saved ${s.stats.pagesSaved}, discovered ${s.stats.pagesQueued}.`,{donePages:l,claimedPages:s.donePages.size,pagesRendered:s.stats.pagesRendered,pagesSaved:s.stats.pagesSaved,pagesQueued:s.stats.pagesQueued,pageQueue:s.pageQueue.length,phase:"save-pages"});}function js(e){let t=Qe(e);return t%5===0||t===1||t===e.stats.pagesQueued}function Es(e,t){let r=Qe(e);t.progress(`Render progress: processed ${r}, rendered ${e.stats.pagesRendered}, saved ${e.stats.pagesSaved}, discovered ${e.stats.pagesQueued}.`,{donePages:r,claimedPages:e.donePages.size,pagesRendered:e.stats.pagesRendered,pagesSaved:e.stats.pagesSaved,pagesQueued:e.stats.pagesQueued,phase:"render-pages"});}async function Us(e){await e.addInitScript(()=>{Object.defineProperty(window,"__WPSUITE_STATIC_EXPORT__",{value:true,writable:false,configurable:true});let t=r=>{if(r==null||String(r)==="")return true;try{let s=new URL(String(r),window.location.href),n=new URL(window.location.href);return s.hash="",n.hash="",s.href===n.href}catch{return false}};try{let r=window.location.assign.bind(window.location),s=window.location.replace.bind(window.location),n=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 r(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 s(i)}}),Object.defineProperty(window.location,"reload",{configurable:!0,value:()=>{console.warn("[smartcloud-static-publisher] blocked location.reload");}});}catch{}});}async function qs(e,t,r){let s=await e.newContext({viewport:t.viewport,userAgent:"WPSuiteStaticPublisher/0.8 Playwright SitemapOnly",ignoreHTTPSErrors:t.ignoreHttpsErrors,...r?{javaScriptEnabled:false}:{}});return r||await Us(s),s}async function Qs(e,t,r,s,n,i,u){let l=await chromium.launch({headless:true}),a=Dt(l);a.pid!==null&&r.debug(`Launched crawl worker browser PID ${a.pid}`,{browserPid:a.pid});try{for(;t.pageQueue.length>0&&!(e.maxPages>0&&t.donePages.size>=e.maxPages);){let o=t.pageQueue.shift();if(!o)break;t.queuedPages.delete(o);let d=null,p=null;try{let c=J(o,r,"page","page-queue");if(!c)continue;let g=c.toString();if(o=g,t.queuedPages.delete(o),t.donePages.has(o))continue;t.donePages.add(o),i.enabled&&i.seenPages.add(o);let m=Ee(e,o),w=Os(e,c.pathname);if(!G(c)||k(e,c)||Y(c)){if(k(e,c)){r.info(`Worker redirected non-page URL to asset queue: ${o}`,{url:o,source:"worker-guard"}),I(e,t,o,r,"worker-guard");continue}r.reject("page",o,"guard rejected non-page URL before rendering","worker");continue}let h=await Hr(e,n,t,i,o,r);if(i.enabled&&s!=="single-url"){let b=i.manifest.pages[o];if(h.action==="reuse"&&b){for(let R of b.discoveredAssets)I(e,t,R,r,o);for(let R of b.discoveredPages)le(e,t,R,r,o);b.lastSeenRunId=i.runId,b.sitemapLastmod=ie(t.sitemapLastmodByPage[o])??b.sitemapLastmod,h.changeToken?.supported&&(b.changeToken=h.changeToken.token,b.tokenSource=h.changeToken.tokenSource??b.tokenSource),r.info(`Incremental reuse skipped unchanged page ${o}`,{url:o,mode:"incremental",reason:h.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}d=await M(`create page context ${o}`,U(e),()=>qs(l,e,w)),p=await M(`create page ${o}`,U(e),()=>d.newPage());let C=!1,P=new Set;await p.route("**/*",async b=>{let R=b.request();if(R.isNavigationRequest()&&R.frame()===p.mainFrame())try{let N=new URL(R.url()),Z=new URL(g);if(N.hash="",Z.hash="",N.href===Z.href){if(C){r.warn(`Blocked same-page navigation/reload for ${o}`,{url:o,requestUrl:R.url()}),await b.abort("aborted");return}C=!0;}}catch{}await b.continue();}),p.on("response",b=>{try{let R=A(e,b.url(),e.sourceOrigin,r,"network-response");R&&k(e,R)&&(P.add(R.toString()),I(e,t,R.toString(),r,o));}catch{}}),r.page(`Rendering ${o}`,{url:o});let y=null,v=null;try{if(y=await p.goto(o,{waitUntil:"domcontentloaded",timeout:e.navigationTimeoutMs}),y&&y.ok())try{v=await M(`read response body ${o}`,U(e),()=>y.text());}catch{v=null;}}catch(b){r.warn(`Navigation issue for ${o}; saving current DOM if available`,{url:o,error:String(b)});}if(m){let b=y?.status()??null;if(b!==404){r.error(`Generated 404 request path returned unexpected status for ${o}`,{url:o,expectedStatus:404,status:b,requestPath:e.generated404RequestPath});continue}r.info(`Capturing rendered 404 page for ${o}`,{url:o,status:b,outputPath:B(e,o)});}else if(y&&!y.ok()){r.skip("page",o,y.status(),t.pageDiscoverySources.get(o)),await p.close();continue}w?(r.info(`Rendering without JS execution for ${o}`,{url:o,mode:"no-js"}),await M(`wait for rendered page ${o}`,U(e),()=>Ds(e,p))):await M(`wait for rendered page ${o}`,U(e),()=>$s(e,p)),t.stats.pagesRendered++;let x=await M(`extract rendered assets ${o}`,U(e),()=>Fs(e,p,g,r,!w));for(let b of x)I(e,t,b,r,o);let L=[...new Set([...x,...P])],T=v??await M(`capture rendered html ${o}`,U(e),()=>p.content()),H=s!=="single-url"&&!m?ks(e,o,T,r):[];if(s!=="single-url"&&!m)for(let b of H)le(e,t,b,r,o);await ft(e,o,T,t,r);let Q=B(e,o);if(q(u,e,Q),oe(u,Q),i.trackManifest){let b=y?.headers();i.manifest.pages[o]={url:o,outputPath:Q,contentType:Ie(b),changeToken:h.changeToken?.supported?h.changeToken.token:null,tokenSource:h.changeToken?.supported?h.changeToken.tokenSource??null:null,sitemapLastmod:ie(t.sitemapLastmodByPage[o])??null,discoveredPages:H,discoveredAssets:L,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},i.enabled&&await K(e,i);}}catch(c){try{let g=p?await M(`capture partial html ${o}`,U(e),()=>p.content()):"";if(g&&g.trim()){await ft(e,o,g,t,r);let m=B(e,o);if(q(u,e,m),oe(u,m),i.trackManifest){let w=i.manifest.pages[o]??i.previousManifest.pages[o];i.manifest.pages[o]={url:o,outputPath:m,contentType:w?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:ie(t.sitemapLastmodByPage[o])??w?.sitemapLastmod??null,discoveredPages:w?.discoveredPages?[...w.discoveredPages]:[],discoveredAssets:w?.discoveredAssets?[...w.discoveredAssets]:[],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},i.enabled&&await K(e,i);}r.warn(`Saved partial DOM for ${o}`,{url:o,error:String(c)});}}catch(g){r.error(`Could not save partial DOM for ${o}`,{url:o,error:String(g)});}r.error(`Failed page ${o}`,{url:o,error:String(c)});}finally{t.stats.pagesCompleted++,js(t)&&Es(t,r),p&&await M(`close page ${o}`,me(e),()=>p.close()).catch(c=>{r.warn(`Timed out while closing page ${o}`,{url:o,browserPid:a.pid,error:String(c)});}),d&&await M(`close page context ${o}`,me(e),()=>d.close()).catch(c=>{r.warn(`Timed out while closing page context for ${o}`,{url:o,browserPid:a.pid,error:String(c)});});}}}finally{await M("close worker browser",me(e),()=>l.close()).catch(o=>(r.warn("Timed out while closing crawl worker browser",{browserPid:a.pid,error:String(o)}),Ls(l,r,"browser.close timeout")));}}async function Ns(e){try{let t=await S.readFile(e),s=(e.endsWith(".gz")?gunzipSync(t):t).toString("utf8").trim();if(!s)return [];try{let n=JSON.parse(s);if(Array.isArray(n))return n;if(n&&typeof n=="object")return [n]}catch{return s.split(/\r?\n/).map(n=>n.trim()).filter(Boolean).map(n=>{try{let i=JSON.parse(n);return i&&typeof i=="object"?i:null}catch{return null}}).filter(n=>n!==null)}return []}catch{return []}}function ht(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function Ws(e){let t=String(e?.job?.command||"").trim(),r=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:r!=="incremental"}function _s(e){let t=[e?.archivedAt,e?.job?.endedAt,e?.job?.startedAt];for(let r of t){let s=Date.parse(String(r||""));if(Number.isFinite(s))return s}return 0}async function Ot(e){try{let t=await S.readFile(e,"utf8"),r=JSON.parse(t);return r&&typeof r=="object"&&!Array.isArray(r)?r:null}catch{return null}}function mt(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function Bs(e,t){let r=Array.isArray(t?.artifacts)?t.artifacts.filter(s=>String(s?.role||"").trim()==="errors"&&String(s?.storedFileName||"").trim()!=="").sort((s,n)=>mt(s)-mt(n)).map(s=>f.join(e,String(s.storedFileName))):[];return [...new Set([...r,f.join(e,"errors.jsonl"),f.join(e,"errors.json"),f.join(e,"errors.jsonl.gz"),f.join(e,"errors.json.gz")])]}async function wt(e){let t=await Ot(f.join(e,"job.json"));for(let r of Bs(e,t)){let s=await Ns(r);if(s.length>0)return s}return []}async function Hs(e){let t=f.join(e.logDir,"archive"),r;try{r=await S.readdir(t);}catch{return ""}let s="",n=0;for(let i of r){let u=f.join(t,i);if(!(await S.stat(u).catch(()=>null))?.isDirectory())continue;let a=await Ot(f.join(u,"job.json"));if(!Ws(a))continue;let o=_s(a);o>=n&&(n=o,s=u);}return s}async function zs(e){let t=await Hs(e),r=t!==""?await wt(t):await wt(e.logDir),s=new Set;for(let n of r)if(ht(n.error)||ht(n.message)){let i=n.url;typeof i=="string"&&i&&s.add(i);}return [...s]}async function Js(e){let t=[];for(let r of e)if(r.startsWith("@")){let s=r.slice(1),n=await S.readFile(s,"utf8");t.push(...n.split(/\r?\n/).map(i=>i.trim()).filter(i=>i&&!i.startsWith("#")));}else t.push(r);return t}async function Gs(e){try{let t=await S.readFile(f.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function Vs(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 S.mkdir(e,{recursive:true}),await Promise.all(t.map(async r=>{try{await S.unlink(f.join(e,r));}catch(s){if(s.code!=="ENOENT")throw s}}));}function Pt(e,t,r,s,n){let i=A(e,r,e.sourceOrigin,s,"manual-url");i&&(de(i)?qe(e,t,i.toString(),s,n):k(e,i)?I(e,t,i.toString(),s,n):G(i)?le(e,t,i.toString(),s,n):s.reject("manual-url",i.toString(),"not page/sitemap/asset-like",n));}async function Ks(){let e=await Re(),t=$r(process.argv.slice(2));if(t.resumeRewrite&&t.mode!=="full")throw new Error("--resume-rewrite is only supported for full crawl/publish jobs.");let r=[];t.mode==="retry-timeouts"&&(r=await zs(e)),t.mode==="single-url"&&(r=await Js(t.urls));let s=t.crawlMode==="incremental"&&t.mode==="full",n=s&&typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!=="",i=(t.mode==="full"||t.mode==="single-url")&&!t.resumeRewrite,u=t.mode!=="full"||t.resumeRewrite||n,l=u?await Gs(e):{},a=n||t.mode==="single-url"?await Ur(e):vt(),o={enabled:n,trackManifest:i,manifest:$e(a),previousManifest:$e(a),runId:`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve()};await Vs(e.logDir);let d={pageQueue:[],queuedPages:new Set,donePages:new Set,pageDiscoverySources:new Map,assetQueue:[],queuedAssets:new Set,doneAssets:new Set,sitemapQueue:[],queuedSitemaps:new Set,doneSitemaps:new Set,sitemapLastmodByPage:{},assetMap:{...l},assetVariantDigestsByOriginalPath:new Map,stats:{pagesQueued:0,pagesRendered:0,pagesCompleted:0,assetsQueued:0,sitemapsQueued:0,assetsSaved:0,pagesSaved:0}},p=Er();u||await S.rm(e.outputDir,{recursive:true,force:true}),await S.mkdir(e.outputDir,{recursive:true});let c=new ne(e.logDir,e.logLevel);if(s&&!n&&c.warn("Incremental crawl requested without active remote publisher subscription. Falling back to full crawl.",{requestedMode:t.crawlMode,subscriptionType:e.subscriptionType??null}),t.resumeRewrite)c.info("Resuming final rewrite from existing output.",{phase:"rewrite-text",mode:t.mode,crawlMode:t.crawlMode});else {let P=await request.newContext({ignoreHTTPSErrors:e.ignoreHttpsErrors});try{if(c.mark("discovery"),t.mode==="full"?(e.sitemapPaths.forEach(v=>qe(e,d,v,c)),await gt(e,P,d,c,p),e.seedPaths.forEach(v=>Pt(e,d,v,c,"seed-path")),e.generated404RequestPath&&le(e,d,e.generated404RequestPath,c,"generated-404-request-path")):(r.forEach(v=>Pt(e,d,v,c,"cli")),await gt(e,P,d,c,p)),c.endMark("discovery",{pages:d.pageQueue.length,assets:d.assetQueue.length,sitemaps:d.sitemapQueue.length}),c.summary(`Queued ${d.pageQueue.length} pages, ${d.assetQueue.length} assets, ${d.sitemapQueue.length} sitemaps.`,{mode:t.mode,crawlMode:t.crawlMode,queuedPages:d.pageQueue.length,queuedAssets:d.assetQueue.length,queuedSitemaps:d.sitemapQueue.length}),t.mode==="retry-timeouts"&&d.pageQueue.length===0&&d.assetQueue.length===0&&d.sitemapQueue.length===0){c.summary("No timed-out URLs were queued. Skipping retry crawl.",{mode:t.mode,crawlMode:t.crawlMode,queuedPages:0,queuedAssets:0,queuedSitemaps:0}),await c.flush();return}c.mark("render-pages");let y=Array.from({length:Math.max(1,e.concurrency)},()=>Qs(e,d,c,t.mode,P,o,p));if(await Promise.all(y),c.endMark("render-pages",{pages:d.stats.pagesCompleted}),c.mark("download-assets"),c.progress("Asset download phase started.",{phase:"download-assets",doneAssets:d.doneAssets.size,assetsQueued:d.stats.assetsQueued,assetQueue:d.assetQueue.length}),await Ts(e,P,d,c,o,p),c.endMark("download-assets",{assets:d.doneAssets.size}),o.enabled&&e.maxPages===0&&await Jr(e,d,o,c,p),t.mode==="full"){let v=await Cs(e,d,c);for(let x of v)q(p,e,x);}}finally{await M("dispose crawl request context",me(e),()=>P.dispose()).catch(y=>{c.warn("Timed out while disposing crawl request context",{error:String(y)});});}}o.trackManifest&&await K(e,o),await S.writeFile(f.join(e.outputDir,"asset-map.json"),JSON.stringify(d.assetMap,null,2),"utf8"),JSON.stringify(l,null,2)!==JSON.stringify(d.assetMap,null,2)&&q(p,e,f.join(e.outputDir,"asset-map.json"));let g=t.mode==="single-url"?rs(e,d):o.enabled&&!t.resumeRewrite?Gr(e,o,p,l,d.assetMap):void 0;c.mark("rewrite-text");let m=t.mode==="single-url"?`Rewriting text files touched by URL crawl: 0/${g?.length??0}`:"Rewriting text files...";c.progress(m,{phase:"rewrite-text",index:0,totalFiles:g?.length,changedTextFiles:0}),await dt(m);let w=Date.now(),h=await st(e,d.assetMap,{files:g,previousAssetMap:l,onStart:({totalFiles:P,workerCount:y})=>{c.info(`Rewrite phase scanning ${P} text files.`,{phase:"rewrite-text",totalFiles:P,workerCount:y});},onProgress:async({index:P,totalFiles:y,changedTextFiles:v,file:x,changed:L})=>{L&&q(p,e,f.join(e.outputDir,x)),c.checkpoint(`Rewriting text file ${P}/${y}`,{phase:"rewrite-text",index:P,totalFiles:y,changedTextFiles:v,file:x}),c.debug(`${L?"Rewrote":"Checked unchanged"} text file ${P}/${y}: ${x}`,{phase:"rewrite-text",index:P,totalFiles:y,changedTextFiles:v,file:x,changed:L});let T=Date.now();if(!(P===1||P===y||P%50===0||T-w>=5e3))return;w=T;let Q=`Rewriting text files: ${P}/${y}`;c.progress(Q,{phase:"rewrite-text",index:P,totalFiles:y,changedTextFiles:v,file:x}),await dt(Q);}});o.trackManifest&&(Vr(o,g),await K(e,o)),c.endMark("rewrite-text",{changedTextFiles:h});let C=o.enabled&&!t.resumeRewrite?await Yr(e,d,o,p,c):[];await Be(e,{generatedAt:new Date().toISOString(),outputDir:f.resolve(e.outputDir),runMode:t.mode,crawlMode:t.crawlMode,fullSyncRequired:!(o.enabled&&!t.resumeRewrite),changedFiles:o.enabled&&!t.resumeRewrite?[...p.changedFiles].sort():[],deletedFiles:o.enabled&&!t.resumeRewrite?C:[],rewriteTargets:o.enabled&&!t.resumeRewrite?[...new Set((g||[]).map(P=>ee(e.outputDir,f.isAbsolute(P)?P:f.join(e.outputDir,P))).filter(P=>P!==null))].sort():[]}),c.summary(t.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${h} text files.`:`Done. Rendered ${d.stats.pagesRendered} pages, processed ${d.doneSitemaps.size} sitemaps, downloaded ${d.doneAssets.size} assets.`,{mode:t.mode,crawlMode:t.crawlMode,resumeRewrite:t.resumeRewrite,...d.stats,pagesRendered:d.stats.pagesRendered,donePages:d.stats.pagesCompleted,claimedPages:d.donePages.size,doneSitemaps:d.doneSitemaps.size,doneAssets:d.doneAssets.size,changedTextFiles:h}),await c.flush();}Ks().catch(async e=>{console.error(e);try{let r=(await Re().catch(()=>null))?.logDir??"logs",s=new ne(r,"debug");s.error(`Unhandled error: ${e instanceof Error?e.message:String(e)}`,e instanceof Error?{stack:e.stack}:void 0),await s.flush();}catch{}process.exit(1);});
9
+ ${i}`,40);return s.info(`Using generated 404 fallback change token for ${r}`,{url:r,requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),{url:r,supported:!0,token:u,tokenSource:"generated-404-response-hash",postId:null,dependencyPostIds:[],reason:null}}catch(n){return s.warn(`Generated 404 fallback token lookup failed for ${r}`,{url:r,error:String(n),requestPath:e.generated404RequestPath,source:"generated-404-change-token-fallback"}),null}}async function Jr(e,t,r,s,n,i){let u=Qe(e,n);if(!s.enabled)return {action:"render",changeToken:s.trackManifest?await Le(e,t,s,n,i):null};let l=s.manifest.pages[n];if(!l)return {action:"render",changeToken:await Le(e,t,s,n,i)};let o=await Le(e,t,s,n,i);if(o?.supported&&o.token)return l.changeToken===o.token?u&&!await Gr(e,t,n,i)?{action:"render",changeToken:o}:{action:"reuse",changeToken:o}:{action:"render",changeToken:o};let a=ie(r.sitemapLastmodByPage[n]);return a&&l.sitemapLastmod&&l.sitemapLastmod===a?{action:"reuse",changeToken:o}:{action:"render",changeToken:o}}async function Gr(e,t,r,s){try{let i=(await t.get(r,{timeout:Math.min(e.navigationTimeoutMs,15e3),failOnStatusCode:!1})).status();return i===404?!0:(s.warn(`Generated 404 request path no longer returns 404 for ${r}`,{url:r,status:i,requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),!1)}catch(n){return s.warn(`Generated 404 status probe failed for ${r}`,{url:r,error:String(n),requestPath:e.generated404RequestPath,source:"generated-404-status-probe"}),false}}async function Vr(e,t,r,s,n){let i=pt(r.previousManifest,void 0,s,"previous-manifest"),u=0;for(let[c,p]of Object.entries(r.manifest.pages))if(!r.seenPages.has(c)){dt(n,e,p.outputPath);try{await b.unlink(p.outputPath);}catch(h){(h.code||"")!=="ENOENT"&&s.warn(`Failed to remove stale incremental page output for ${c}`,{url:c,outputPath:p.outputPath,error:String(h)});}delete r.manifest.pages[c],u++;}let l=pt(r.manifest,r.runId,s,"active-manifest"),o=new Set,a=new Set;for(let c of l){for(let m of ae(e,c))o.add(m);let p=r.manifest.assets[c]?.outputPath;p&&a.add(p);let h=ue(e,t.assetMap,c);h&&a.add(h);}for(let c of Object.keys(r.manifest.assets))l.has(c)||delete r.manifest.assets[c];let g=0,d=0;for(let c of i){let p=new Set,h=r.previousManifest.assets[c]?.outputPath;h&&p.add(h);let m=ue(e,t.assetMap,c);if(!l.has(c)&&m)p.add(m);else if(!l.has(c)){let w=ps(e,c,s,"incremental-cleanup");w&&(p.add(w.originalFilePath),w.hashedFilePath&&p.add(w.hashedFilePath));}for(let w of p)if(!a.has(w)){dt(n,e,w);try{await b.unlink(w),g++;}catch(T){(T.code||"")!=="ENOENT"&&s.warn(`Failed to remove stale incremental asset output for ${c}`,{url:c,outputPath:w,error:String(T)});}}for(let w of ae(e,c))o.has(w)||Object.prototype.hasOwnProperty.call(t.assetMap,w)&&(delete t.assetMap[w],d++);}(u>0||g>0||d>0)&&s.info(`Incremental cleanup removed ${u} stale pages, ${g} stale assets, ${d} stale asset mappings`,{removedPages:u,removedAssets:g,removedAssetMappings:d,phase:"incremental-cleanup"});}function pt(e,t,r,s){let n=new Set,i=u=>{let l=u.trim();if(l){if(r){let o=J(l,r,"asset",s??"manifest");if(!o)return;n.add(o.toString());return}n.add(l);}};for(let u of Object.values(e.pages))for(let l of u.discoveredAssets||[])i(l);for(let[u,l]of Object.entries(e.assets||{}))t&&l.lastSeenRunId!==t||i(u);return n}function gt(e,t,r){for(let s of t)for(let n of ae(e,s))if(r.has(n))return true;return false}function Yr(e,t,r,s,n){let i=new Set(r.rewriteTargets);for(let l of Object.values(t.manifest.pages))l.rewriteComplete||i.add(f.resolve(l.outputPath));for(let l of Object.values(t.manifest.assets))l.isText&&!l.rewriteComplete&&i.add(f.resolve(l.outputPath));let u=Nr(s,n);if(u.size===0)return [...i];for(let l of Object.values(t.manifest.pages))gt(e,l.discoveredAssets,u)&&i.add(f.resolve(l.outputPath));for(let[l,o]of Object.entries(t.manifest.assets)){o.isText&&gt(e,o.discoveredAssets,u)&&i.add(f.resolve(o.outputPath));for(let a of ae(e,l))if(u.has(a)){Q(r,e,o.outputPath),o.isText&&i.add(f.resolve(o.outputPath));break}}return [...i]}function Zr(e,t){let r=t?new Set(Array.from(t,n=>f.resolve(n))):null,s=n=>r===null||r.has(f.resolve(n));for(let n of Object.values(e.manifest.pages))s(n.outputPath)&&(n.rewriteComplete=true);for(let n of Object.values(e.manifest.assets)){if(!n.isText){n.rewriteComplete=true;continue}s(n.outputPath)&&(n.rewriteComplete=true);}}function Kr(e,t,r){let s=new Set,n=i=>{if(!i)return;let u=ee(e.outputDir,i);u&&s.add(u);};for(let i of t.donePages)n(H(e,i));for(let i of Object.values(r.manifest.pages))i.lastSeenRunId===r.runId&&n(i.outputPath);for(let i of t.doneAssets)n(ue(e,t.assetMap,i));for(let i of Object.values(r.manifest.assets))i.lastSeenRunId===r.runId&&n(i.outputPath);return s}async function Xr(e,t,r,s,n){let i=[...s.deletedFiles].sort(),u=Kr(e,t,r),l=0;for(let g of [...u].sort()){try{if((await b.stat(f.join(e.outputDir,g))).isFile())continue}catch{}l++,n.warn(`Active output is missing after crawl: ${g}`,{phase:"deploy-plan",file:g,outputPath:f.join(e.outputDir,g)});}if(l>0&&n.warn(`Detected ${l} active output file(s) missing before deploy plan save.`,{phase:"deploy-plan",missingActiveOutputs:l}),i.length===0)return [];let o=[],a=0;for(let g of i){if(!u.has(g)){o.push(g);continue}a++;let d=f.join(e.outputDir,g),c;try{c=(await b.stat(d)).isFile();}catch{c=false;}n.warn(`Deploy plan protected active output from deletion: ${g}`,{phase:"deploy-plan",file:g,outputPath:d,exists:c});}return a>0&&n.info(`Deploy plan skipped ${a} active output deletion(s).`,{phase:"deploy-plan",protectedDeletes:a,deletedFiles:o.length}),o}function ae(e,t){let r=new Set([t]);try{let s=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 u of i)try{r.add(new URL(u).origin+s.pathname+s.search);}catch{}r.add(s.pathname+s.search),r.add(s.pathname);}catch{}return [...r]}function es(e,t){let r=new Set([t]);try{let s=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 u of i)try{r.add(new URL(u).origin+s.pathname+s.search);}catch{}r.add(s.pathname+s.search);}catch{}return [...r]}function kt(e,t){let r=e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/"?e.targetOrigin:"https://relative.invalid/";try{let s=new URL(t,r);return f.join(e.outputDir,qe(s.pathname))}catch{return null}}function ts(e,t,r){for(let s of es(e,r)){let n=t[s];if(!n)continue;let i=kt(e,n);if(i)return {outputPath:i,publicUrl:n}}return null}function rs(e,t,r){for(let s of ae(e,r)){let n=t[s];if(!n)continue;let i=kt(e,n);if(i)return i}return null}function ue(e,t,r){let s=rs(e,t,r);if(s)return s;try{return We(e,r).originalFilePath}catch{return null}}function ss(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?f.join(f.resolve(e),"queue-runner-heartbeat.json"):""}async function ft(e){let t=ss();if(t)try{let r=await b.readFile(t,"utf8"),s=JSON.parse(r);if(!s||typeof s!="object")return;await b.writeFile(t,JSON.stringify({...s,checkedAt:new Date().toISOString(),status:"running",currentStep:"rewrite",message:e},null,2),"utf8");}catch{}}function ns(e,t){let r=new Set;for(let s of t.donePages)r.add(f.resolve(H(e,s)));for(let s of t.doneAssets){let n=ue(e,t.assetMap,s);!n||!z(n)||r.add(f.resolve(n));}return [...r]}var Pe="re:",me=new Map;function is(e){if(!e.startsWith(Pe))return null;let t=me.get(e);if(t!==void 0)return t||null;let r=e.slice(Pe.length).trim();if(!r)return me.set(e,false),null;try{let s=new RegExp(r);return me.set(e,s),s}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),me.set(e,false),null}}function Ue(e,t){let r=is(t);return r?r.test(e):t.startsWith(Pe)?false:e.startsWith(t)}function os(e,t){return t.find(r=>Ue(e,r))}function Tt(e,t){let r=os(t.pathname,e.blockedPathPrefixes);if(r)return r.startsWith(Pe)?`blocked path regex: ${r}`:`blocked path prefix: ${r}`;let s=e.blockedSearchFragments.find(n=>t.search.includes(n));return s?`blocked search fragment: ${s}`:null}function as(e){let t=new URL(e.sourceOrigin),r=new Set([t.hostname,...e.allowedAssetHosts]);if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{r.add(new URL(e.targetOrigin).hostname);}catch{}for(let s of Object.keys(e.extraReplacements||{}))try{r.add(new URL(s).hostname);}catch{}return r}function us(e,t){return as(e).has(t.hostname)}function ls(e){let t=U(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function Fe(e){let t=U(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function cs(e){let t=U(e).replace(/\\\//g,"/").trim(),r=f.extname(t).toLowerCase();return vt.has(r)||Rt.has(r)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function Z(e){return Dr.some(t=>e.pathname.startsWith(t))}function M(e,t,r=e.sourceOrigin,s,n="url"){let i=ls(t);if(!i||i.startsWith("data:")||i.startsWith("blob:")||i.startsWith("mailto:")||i.startsWith("tel:")||i.startsWith("#"))return s?.ignore(n,t,"empty or unsupported scheme",r),null;if(Fe(i))return s?.ignore(n,t,"looks like JavaScript/code fragment",r),null;if(cs(i))return s?.ignore(n,t,"looks like JavaScript property access",r),null;try{let u=new URL(i,r);if(At(u))return s?.reject(n,t,"malformed URL encoding",r),null;if(!["http:","https:"].includes(u.protocol))return s?.ignore(n,t,"unsupported protocol: ",r),null;if(!us(e,u))return s?.ignore(n,u.toString(),"host not allowed",r),null;let l=Tt(e,u);if(l)return s?.reject(n,u.toString(),l,r),null;let o=new URL(e.sourceOrigin);return u.protocol=o.protocol,u.host=o.host,u.hash="",u}catch{return s?.reject(n,t,"invalid URL",r),null}}function At(e){try{return decodeURIComponent(e.pathname),decodeURIComponent(e.search),decodeURIComponent(e.hash),!1}catch{return true}}function J(e,t,r,s){try{let n=new URL(e);return At(n)?(t.reject(r,e,"malformed URL encoding",s),null):n.protocol!=="http:"&&n.protocol!=="https:"?(t.reject(r,e,`unsupported protocol: ${n.protocol}`,s),null):n}catch{return t.reject(r,e,"invalid URL",s),null}}function Mt(e){return vt.has(f.extname(e.pathname).toLowerCase())}function G(e){return Z(e)?false:Rt.has(f.extname(e.pathname).toLowerCase())}function de(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function A(e,t){return !!(de(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(r=>Ue(t.pathname,r))||Mt(t)||!G(t)&&!Z(t))}function H(e,t){let r=new URL(t),s=qe(r.pathname);return s.endsWith("/")?s+="index.html":f.extname(s)||(s+="/index.html"),f.join(e.outputDir,s)}function qe(e){try{return decodeURIComponent(e)}catch{return e}}function ds(e){if(!e.generated404RequestPath)return null;try{let t=new URL(e.generated404RequestPath,e.sourceOrigin);return !t.pathname.endsWith("/")&&f.extname(t.pathname)===""&&(t.pathname+="/"),t.hash="",t.toString()}catch{return null}}function Qe(e,t){let r=ds(e);if(!r)return false;try{return new URL(t,e.sourceOrigin).toString()===r}catch{return false}}function We(e,t){let r=new URL(t),s=qe(r.pathname);s.endsWith("/")&&(s+="index.html");let n=!!r.search,i=s,u=f.join(e.outputDir,i),l=ke(e.targetOrigin,i),o=`${l}${r.search}`;if(!n)return {originalPathname:i,originalFilePath:u,originalPublicUrl:l,originalPublicUrlWithSearch:o,preferQueryHashed:n};let a=f.extname(s),d=`${a?s.slice(0,-a.length):s}.${re(r.search)}${a||".bin"}`;return {originalPathname:i,originalFilePath:u,originalPublicUrl:l,originalPublicUrlWithSearch:o,preferQueryHashed:n,hashedPathname:d,hashedFilePath:f.join(e.outputDir,d),hashedPublicUrl:ke(e.targetOrigin,d)}}function ps(e,t,r,s){let n=J(t,r,"asset",s);return n?We(e,n.toString()):null}function gs(e,t,r,s,n){t[r]=s;try{let i=new URL(r),l=[new URL(e.sourceOrigin).origin,...Object.keys(e.extraReplacements||{})];if(e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/")try{l.push(new URL(e.targetOrigin).origin);}catch{}for(let o of l)try{let a=new URL(o);t[a.origin+i.pathname+i.search]=s;}catch{}try{let o=(()=>{let a=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin);return `${a.pathname}${a.search}`})();t[i.pathname+i.search]=o;}catch{}try{let o=new URL(s,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=o;}catch{}try{let o=new URL(n,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin).pathname;t[i.pathname]=o;}catch{}}catch{}}async function Lt(e){try{return await b.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function It(e){try{return await b.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function fs(e){let t=String(e["content-length"]||"").trim();if(!t)return null;let r=Number.parseInt(t,10);return Number.isFinite(r)&&r>=0?r:null}function $t(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let r=Date.parse(t);return Number.isFinite(r)?r:null}function hs(e,t){let r=$t(t),s=fs(t),n=e?.mtime.getTime();return r!==null&&Math.abs((n??0)-r)>=1e3||s!==null&&e?.size!==s?false:r!==null||s!==null}async function ms(e,t){if(!t)return;let r=$t(t);if(r===null)return;let s=await It(e);if(!s)return;let n=new Date(r);await b.utimes(e,s.atime,n).catch(()=>{});}function ht(e,t){let r=f.extname(e.pathname).toLowerCase(),s=t["content-type"]||"";return $r.has(r)||Ir.some(n=>s.includes(n))&&!s.startsWith("image/")&&!s.includes("font")}function Ie(e,t){(e.doneAssets.size%25===0||e.doneAssets.size===1||e.doneAssets.size===e.stats.assetsQueued)&&t.progress(`Asset download progress: downloaded ${e.doneAssets.size}, discovered ${e.stats.assetsQueued}.`,{doneAssets:e.doneAssets.size,assetsQueued:e.stats.assetsQueued,phase:"download-assets"});}function ws(e){return re(e.toString("base64"),40)}function Ps(e,t,r){let s=e.assetVariantDigestsByOriginalPath.get(t);if(!s||s.size===0)return false;for(let n of s)if(n!==r)return true;return false}function bs(e,t,r){let s=e.assetVariantDigestsByOriginalPath.get(t);s||(s=new Set,e.assetVariantDigestsByOriginalPath.set(t,s)),s.add(r);}async function je(e,t,r,s,n,i,u){let l=We(e,r),o=ws(s),a=l.originalFilePath,g=l.originalPublicUrlWithSearch;if(l.preferQueryHashed&&l.hashedFilePath&&l.hashedPublicUrl&&Ps(n,l.originalFilePath,o)){let h=ts(e,t,r);h?(a=h.outputPath,g=h.publicUrl):(a=l.hashedFilePath,g=l.hashedPublicUrl);}gs(e,t,r,g,l.originalPublicUrl);let d=z(a)?Buffer.from(Me(s.toString("utf8"),e,t,a),"utf8"):s,c=await Lt(a),p=false;return (c===null||!c.equals(d))&&(await se(a,d),p=true),i?.debug(`${p?"Saved":"Skipped unchanged"} asset output ${r}`,{phase:"download-assets",url:r,outputPath:a,bytes:d.length,wroteFile:p}),bs(n,l.originalFilePath,o),await ms(a,u),n.stats.assetsSaved++,i&&(n.stats.assetsSaved%50===0||n.stats.assetsSaved===1)&&i.progress(`Asset progress: saved ${n.stats.assetsSaved}, discovered ${n.stats.assetsQueued}, pending ${n.assetQueue.length}.`,{assetsSaved:n.stats.assetsSaved,assetsQueued:n.stats.assetsQueued,assetQueue:n.assetQueue.length,phase:"download-assets"}),{outputPath:a,publicUrl:g,wroteFile:p}}function le(e,t,r,s,n){let i=()=>{let d=String(n??"").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 c=new URL(d);return de(c)?{discoveredFrom:d,discoveredFromType:"sitemap"}:A(e,c)?{discoveredFrom:d,discoveredFromType:"asset"}:G(c)&&!Z(c)?{discoveredFrom:d,discoveredFromType:"page"}:{discoveredFrom:d,discoveredFromType:"url"}}catch{return {discoveredFrom:d,discoveredFromType:"url"}}return {discoveredFrom:d,discoveredFromType:"url"}},u=n&&/^https?:\/\//i.test(n)?n:e.sourceOrigin,l=M(e,r,u,s,"page");if(!l)return;if(!G(l)||Mt(l)){if(A(e,l)){s.info(`Seeded/non-page URL queued as asset: ${l.toString()}`,{url:l.toString(),source:n}),I(e,t,l.toString(),s,n);return}s.reject("page",l.toString(),Z(l)?"asset/internal path cannot be page":"not page-like",n);return}let o=l.toString(),{discoveredFrom:a,discoveredFromType:g}=i();a&&!t.pageDiscoverySources.has(o)&&t.pageDiscoverySources.set(o,a),!t.donePages.has(o)&&!t.queuedPages.has(o)&&(t.queuedPages.add(o),t.pageQueue.push(o),t.stats.pagesQueued++,s.debug(`Queued discovered page ${o}`,{phase:"discovery",url:o,discoveredFrom:a,discoveredFromType:g,outputPath:H(e,o)}),(t.stats.pagesQueued%25===0||t.stats.pagesQueued===1)&&s.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 I(e,t,r,s,n){let i=n&&/^https?:\/\//i.test(n)?n:e.sourceOrigin,u=M(e,r,i,s,"asset");if(!u)return;if(!A(e,u)){s.reject("asset",u.toString(),"not a safe asset path/prefix",n);return}let l=u.toString();!t.doneAssets.has(l)&&!t.queuedAssets.has(l)&&(t.queuedAssets.add(l),t.assetQueue.push(l),t.stats.assetsQueued++,(t.stats.assetsQueued%100===0||t.stats.assetsQueued===1)&&s.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 Ne(e,t,r,s,n){let i=n&&/^https?:\/\//i.test(n)?n:e.sourceOrigin,u=M(e,r,i,s,"sitemap");if(!u)return;if(!de(u)){s.reject("sitemap",u.toString(),"not sitemap-like",n);return}let l=u.toString();!t.doneSitemaps.has(l)&&!t.queuedSitemaps.has(l)&&(t.queuedSitemaps.add(l),t.sitemapQueue.push(l),t.stats.sitemapsQueued++,(t.stats.sitemapsQueued%10===0||t.stats.sitemapsQueued===1)&&s.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 Ss(e){let t=U(e),r=[...t.matchAll(/<url>\s*([\s\S]*?)\s*<\/url>/gi)].map(s=>s[1]);return r.length>0?r.map(s=>{let n=s.match(/<loc>\s*([^<]+?)\s*<\/loc>/i);if(!n?.[1])return null;let i=s.match(/<lastmod>\s*([^<]+?)\s*<\/lastmod>/i);return {loc:n[1].trim(),lastmod:ie(i?.[1]??null)}}).filter(s=>!!s):[...t.matchAll(/<loc>\s*([^<]+?)\s*<\/loc>/gi)].map(s=>({loc:s[1].trim(),lastmod:null})).filter(s=>s.loc)}function ys(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function vs(e){let t=[],r=/url\(\s*(?:"([^"]+)"|'([^']+)'|([^)]*?))\s*\)/gi;for(let s of e.matchAll(r)){let n=e.slice(Math.max(0,s.index-8),s.index);if(/\bnew\s+$/i.test(n))continue;let i=(s[1]||s[2]||s[3]||"").trim();i&&t.push(i);}return t}function Rs(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function Cs(e,t){if(t==="dom-style")return true;let r=(()=>{try{return f.extname(new URL(e).pathname).toLowerCase()}catch{return ""}})();return !(r===".js"||r===".mjs"||r===".map"||t.includes("javascript"))}function $e(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function Dt(e,t,r,s){let n=[];await b.mkdir(t,{recursive:true});let i=await b.readdir(e,{withFileTypes:true});for(let u of i){let l=f.join(e,u.name),o=f.join(t,u.name);if(u.isDirectory()){n.push(...await Dt(l,o,r,s));continue}await Ot(l,o,r,s)&&n.push(o);}return n}async function xs(e,t){try{let[r,s]=await Promise.all([b.stat(e),b.stat(t)]);if(r.size!==s.size)return !1;let[n,i]=await Promise.all([b.readFile(e),b.readFile(t)]);return n.equals(i)}catch{return false}}async function Ot(e,t,r,s){let n=f.resolve(t);return r.has(n)?(s.debug("Skipped post-crawl copy over crawled page output",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):await xs(e,t)?(s.debug("Skipped unchanged post-crawl copy target",{phase:"copy-extra-paths",sourcePath:e,targetPath:t}),false):(await b.mkdir(f.dirname(t),{recursive:true}),await b.copyFile(e,t),true)}async function ks(e,t,r){let s=Object.entries(e.postCrawlCopyMap||{}).map(([l,o])=>({sourcePath:l.trim(),prefix:String(o||"").trim()}));if(s.length===0)return [];let n=0,i=[],u=new Set([...t.donePages].map(l=>f.resolve(H(e,l))));r.mark("copy-extra-paths");for(let l of s){let o=l.sourcePath,a=l.prefix;if(!o||!a){r.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:o,prefixPath:a});continue}let g=Er(o);if(!g.resolvedPath){r.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:o,alias:g.alias||"",requiredEnv:g.requiredEnv||"",prefixPath:a});continue}let d=g.resolvedPath,c=$e(a);if(!c){r.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:o,prefixPath:a});continue}let p;try{p=await b.stat(d);}catch{r.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:o,sourceAbs:d,prefixPath:a});continue}let h=f.resolve(e.outputDir,c);if(p.isDirectory()){let x=await Dt(d,h,u,r);i.push(...x),n+=x.length,x.length>0&&r.progress(`Copied static directory to export: ${d} -> /${c}`,{phase:"copy-extra-paths",sourcePath:d,targetPath:`/${c}`,copiedItems:n,changedFiles:x.length});continue}let m=f.basename(d),w=a.endsWith("/")?f.join(h,m):h;await Ot(d,w,u,r)&&(i.push(w),n++,r.progress(`Copied static file to export: ${d} -> /${$e(a.endsWith("/")?`${a}${m}`:a)}`,{phase:"copy-extra-paths",sourcePath:d,targetPath:`/${$e(a.endsWith("/")?`${a}${m}`:a)}`,copiedItems:n}));}return r.endMark("copy-extra-paths",{mappedSources:s.length,copiedItems:n}),i}function ce(e,t,r,s,n){let i=new Set,u=U(r).replace(/\\\//g,"/"),l=n==="page-html"?Rs(u):u,o=Cs(t,n);if(o){for(let g of vs(l)){let d=M(e,g,t,s,`${n}:css-url`);d&&A(e,d)&&i.add(d.toString());}for(let g of l.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let d=M(e,g[1],t,s,`${n}:css-import`);d&&A(e,d)&&i.add(d.toString());}}if(o||n==="page-html")for(let g of l.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let d=M(e,g[1],t,s,`${n}:xml-stylesheet`);d&&A(e,d)&&i.add(d.toString());}let a=new RegExp(`(?:https?:)?//[^\\s'"<>\\);]+\\.${he}(?:\\?[^\\s'"<>\\);]*)?|(?<!\\.)/[^\\s'"<>\\);]+\\.${he}(?:\\?[^\\s'"<>\\);]*)?`,"gi");for(let g of u.matchAll(a)){let d=g[0].startsWith("//")?`${new URL(e.sourceOrigin).protocol}${g[0]}`:g[0];if(Fe(d)){s.ignore(`${n}:serialized-url`,d,"looks like JavaScript/code fragment",t);continue}let c=M(e,d,t,s,`${n}:serialized-url`);c&&A(e,c)?i.add(c.toString()):c&&s.ignore("asset",c.toString(),"serialized URL did not pass safe asset path filter",t);}if(n!=="page-html")for(let g of lt(u)){if(Fe(g))continue;let d=M(e,g,t,s,`${n}:relative-asset`);d&&A(e,d)&&i.add(d.toString());}return [...i]}function Ts(e,t,r,s){let n=new Set,i=U(r);for(let u of i.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let l=u[1],o=M(e,l,t,s,"page-link");o&&(Tt(e,o)||G(o)&&!Z(o)&&!A(e,o)&&n.add(o.toString()));}return [...n]}async function mt(e,t,r,s,n){for(;r.sitemapQueue.length>0;){let i=r.sitemapQueue.shift();r.queuedSitemaps.delete(i);let u=J(i,s,"sitemap","sitemap-queue");if(!u)continue;let l=u.toString();if(!r.doneSitemaps.has(l)){r.doneSitemaps.add(l),s.sitemap(`Fetching sitemap ${l}`,{url:l});try{let o=await t.get(l,{timeout:6e4});if(!o.ok()){s.skip("sitemap",l,o.status());continue}let a=await o.body(),g=o.url()||l,d=J(g,s,"sitemap-response",l);if(!d)continue;let c=d.toString(),p=await je(e,r.assetMap,c,a,r,s);Q(n,e,p.outputPath),oe(n,p.outputPath);let h=a.toString("utf8");for(let m of ce(e,c,h,s,"sitemap"))I(e,r,m,s,c);for(let m of Ss(h)){let w=M(e,m.loc,c,s,"sitemap-loc");w&&(de(w)?Ne(e,r,w.toString(),s,c):A(e,w)?I(e,r,w.toString(),s,c):G(w)?(m.lastmod&&(r.sitemapLastmodByPage[w.toString()]=m.lastmod),le(e,r,w.toString(),s,c)):s.reject("sitemap-loc",w.toString(),"not page/sitemap/asset-like",c));}}catch(o){s.error(`Failed sitemap ${l}`,{url:l,error:String(o)});}}}}async function As(e,t,r,s,n,i,u){let l=M(e,s,e.sourceOrigin,n,"asset-fetch");if(!l||!A(e,l))return;let o=l.toString();if(r.doneAssets.has(o))return;let a=i.enabled?i.previousManifest.assets[o]:void 0,g=(d,c={})=>{if(!a)return false;i.manifest.assets[o]={...a,discoveredAssets:[...a.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId},delete i.manifest.pages[o],r.doneAssets.add(o);for(let p of a.discoveredAssets||[])I(e,r,p,n,o);return n.warn(`Keeping previous incremental asset ${o} after fetch issue.`,{url:o,reason:d,preservedFromPreviousManifest:true,...c,phase:"download-assets"}),Ie(r,n),true};n.asset(`Fetching asset ${o}`,{url:o});try{let d=ue(e,r.assetMap,o),c=d?await It(d):null;if(d&&c)try{let R=await t.head(o,{timeout:6e4}),C=R.headers();if(R.ok()&&hs(c,C)){let $=await Lt(d);if($!==null){let W=R.url()||o,S=J(W,n,"asset-response",o);if(!S)return;let v=S.toString(),N=await je(e,r.assetMap,v,$,r,n,C);N.wroteFile&&(Q(u,e,N.outputPath),z(N.outputPath)&&oe(u,N.outputPath)),r.doneAssets.add(o),n.info(`Reused existing asset ${o} based on response headers.`,{url:o,filePath:d,lastModified:C["last-modified"]||"",contentLength:C["content-length"]||"",phase:"download-assets"}),Ie(r,n);let K=ht(l,C),be=a?.discoveredAssets?[...a.discoveredAssets]:[];if(K||a?.isText){let X=$.toString("utf8"),_e=ce(e,v,X,n,"asset:cached");(_e.length>0||!a)&&(be=_e);for(let Et of be)I(e,r,Et,n,v);}if(i.trackManifest){let X=K||!!a?.isText;i.manifest.assets[o]={url:o,outputPath:N.outputPath,isText:X,contentType:De(C)||a?.contentType||null,discoveredAssets:be,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!X},delete i.manifest.pages[o],i.enabled&&X&&await Y(e,i);}return}}}catch{}let p=await t.get(o,{timeout:6e4});if(!p.ok()){if(g(`http-${p.status()}`,{status:p.status()}))return;n.skip("asset",o,p.status());return}let h=await p.body(),m=p.url()||o,w=J(m,n,"asset-response",o);if(!w)return;let T=w.toString(),x=p.headers(),k=await je(e,r.assetMap,T,h,r,n,x);k.wroteFile&&(Q(u,e,k.outputPath),z(k.outputPath)&&oe(u,k.outputPath)),r.doneAssets.add(o),Ie(r,n);let P=ht(l,x),y=[];if(P){let R=h.toString("utf8");y=ce(e,T,R,n,`asset:${f.extname(l.pathname).toLowerCase()||x["content-type"]||"unknown"}`);for(let C of y)I(e,r,C,n,T);}i.trackManifest&&(i.manifest.assets[o]={url:o,outputPath:k.outputPath,isText:P,contentType:De(x),discoveredAssets:y,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!P},delete i.manifest.pages[o],i.enabled&&P&&await Y(e,i));}catch(d){if(g("fetch-error",{error:String(d)}))return;n.error(`Failed asset ${o}`,{url:o,error:String(d)});}}async function Ms(e,t,r,s,n,i){let u=Math.max(1,Number(e.assetDownloadConcurrency||e.concurrency||1)),l=Array.from({length:u},async()=>{for(;r.assetQueue.length>0;){let o=r.assetQueue.shift();o&&(r.queuedAssets.delete(o),await As(e,t,r,o,s,n,i));}});await Promise.all(l);}function Ls(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function q(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function we(e){return Math.max(15e3,Math.min(6e4,q(e)))}function Is(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function Be(e){return e.stats.pagesCompleted}function Ft(e){let r=e.options?.browserProcess;return {pid:typeof r?.process?.pid=="number"?r.process.pid:null,kill:typeof r?.kill=="function"?r.kill.bind(r):null}}async function $s(e,t,r){let s=Ft(e);try{if(s.kill){await s.kill(),t.warn(`Force-killed crawl worker browser after ${r}`,{browserPid:s.pid,reason:r});return}if(s.pid!==null){process.kill(s.pid,"SIGKILL"),t.warn(`Sent SIGKILL to crawl worker browser after ${r}`,{browserPid:s.pid,reason:r});return}t.warn(`Could not resolve crawl worker browser PID after ${r}`,{reason:r});}catch(n){t.error(`Failed to force-kill crawl worker browser after ${r}`,{browserPid:s.pid,reason:r,error:String(n)});}}async function L(e,t,r){let s;try{return await Promise.race([r(),new Promise((n,i)=>{s=globalThis.setTimeout(()=>{i(new Error(`${e} timed out after ${Ls(t)}.`));},t);})])}finally{s!==void 0&&globalThis.clearTimeout(s);}}async function Ds(e,t){let r=Is(e);await t.evaluate(async s=>{await new Promise(n=>{let i=0,u=700,l=Date.now(),o=()=>{window.clearInterval(a),window.scrollTo(0,0),n();},a=window.setInterval(()=>{if(Date.now()-l>=s.maxDurationMs){o();return}window.scrollBy(0,u),i+=u;let g=document.body?.scrollHeight||0,d=document.documentElement?.scrollHeight||0,c=Math.max(g,d);i>=c+window.innerHeight&&o();},120);});},{maxDurationMs:r});}async function Os(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 Ds(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function Fs(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 js(e,t){return e.noJavaScriptRenderPathPrefixes.some(r=>Ue(t,r))}async function Es(e,t,r,s,n=true){let i=new Set;if(n){let l=await t.evaluate(()=>{let o=new Set,a=["href","src","poster","data-src","data-lazy-src","data-original","data-bg","data-background","data-href"],g=new Set,d=["srcset","data-srcset","data-lazy-srcset"];return document.querySelectorAll("*").forEach(c=>{for(let h of a){let m=c.getAttribute(h);m&&o.add(m);}for(let h of d){let m=c.getAttribute(h);m&&m.split(",").forEach(w=>{let T=w.trim().split(/\s+/)[0];T&&o.add(T);});}let p=c.getAttribute("style");p&&g.add(p);}),{attrs:[...o],styles:[...g]}});for(let o of l.attrs)for(let a of ys(o)){let g=M(e,a,r,s,"dom-attr");g&&A(e,g)&&i.add(g.toString());}for(let o of l.styles)for(let a of ce(e,r,o,s,"dom-style"))i.add(a);}let u=await t.content();for(let l of ce(e,r,u,s,"page-html"))i.add(l);return [...i]}async function wt(e,t,r,s,n){let i=H(e,t);await se(i,r,"utf8");let u=await b.stat(i);n?.debug(`Saved page output ${t}`,{phase:"save-pages",url:t,outputPath:i,bytes:u.size}),s.stats.pagesSaved++;let l=Math.min(s.stats.pagesQueued,Be(s)+1);n&&(s.stats.pagesSaved%10===0||s.stats.pagesSaved===1)&&n.progress(`Page progress: processed ${l}, rendered ${s.stats.pagesRendered}, saved ${s.stats.pagesSaved}, discovered ${s.stats.pagesQueued}.`,{donePages:l,claimedPages:s.donePages.size,pagesRendered:s.stats.pagesRendered,pagesSaved:s.stats.pagesSaved,pagesQueued:s.stats.pagesQueued,pageQueue:s.pageQueue.length,phase:"save-pages"});}function Us(e){let t=Be(e);return t%5===0||t===1||t===e.stats.pagesQueued}function qs(e,t){let r=Be(e);t.progress(`Render progress: processed ${r}, rendered ${e.stats.pagesRendered}, saved ${e.stats.pagesSaved}, discovered ${e.stats.pagesQueued}.`,{donePages:r,claimedPages:e.donePages.size,pagesRendered:e.stats.pagesRendered,pagesSaved:e.stats.pagesSaved,pagesQueued:e.stats.pagesQueued,phase:"render-pages"});}async function Qs(e){await e.addInitScript(()=>{Object.defineProperty(window,"__WPSUITE_STATIC_EXPORT__",{value:true,writable:false,configurable:true});let t=r=>{if(r==null||String(r)==="")return true;try{let s=new URL(String(r),window.location.href),n=new URL(window.location.href);return s.hash="",n.hash="",s.href===n.href}catch{return false}};try{let r=window.location.assign.bind(window.location),s=window.location.replace.bind(window.location),n=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 r(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 s(i)}}),Object.defineProperty(window.location,"reload",{configurable:!0,value:()=>{console.warn("[smartcloud-static-publisher] blocked location.reload");}});}catch{}});}async function Ws(e,t,r){let s=await e.newContext({viewport:t.viewport,userAgent:"WPSuiteStaticPublisher/0.8 Playwright SitemapOnly",ignoreHTTPSErrors:t.ignoreHttpsErrors,...r?{javaScriptEnabled:false}:{}});return r||await Qs(s),s}async function Ns(e,t,r,s,n,i,u){let l=await chromium.launch({headless:true}),o=Ft(l);o.pid!==null&&r.debug(`Launched crawl worker browser PID ${o.pid}`,{browserPid:o.pid});try{for(;t.pageQueue.length>0&&!(e.maxPages>0&&t.donePages.size>=e.maxPages);){let a=t.pageQueue.shift();if(!a)break;t.queuedPages.delete(a);let g=null,d=null;try{let c=J(a,r,"page","page-queue");if(!c)continue;let p=c.toString();if(a=p,t.queuedPages.delete(a),t.donePages.has(a))continue;t.donePages.add(a),i.enabled&&i.seenPages.add(a);let h=Qe(e,a),m=js(e,c.pathname);if(!G(c)||A(e,c)||Z(c)){if(A(e,c)){r.info(`Worker redirected non-page URL to asset queue: ${a}`,{url:a,source:"worker-guard"}),I(e,t,a,r,"worker-guard");continue}r.reject("page",a,"guard rejected non-page URL before rendering","worker");continue}let w=await Jr(e,n,t,i,a,r);if(i.enabled&&s!=="single-url"){let S=i.manifest.pages[a];if(w.action==="reuse"&&S){for(let v of S.discoveredAssets)I(e,t,v,r,a);for(let v of S.discoveredPages)le(e,t,v,r,a);S.lastSeenRunId=i.runId,S.sitemapLastmod=ie(t.sitemapLastmodByPage[a])??S.sitemapLastmod,w.changeToken?.supported&&(S.changeToken=w.changeToken.token,S.tokenSource=w.changeToken.tokenSource??S.tokenSource),r.info(`Incremental reuse skipped unchanged page ${a}`,{url:a,mode:"incremental",reason:w.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}g=await L(`create page context ${a}`,q(e),()=>Ws(l,e,m)),d=await L(`create page ${a}`,q(e),()=>g.newPage());let T=!1,x=new Set;await d.route("**/*",async S=>{let v=S.request();if(v.isNavigationRequest()&&v.frame()===d.mainFrame())try{let N=new URL(v.url()),K=new URL(p);if(N.hash="",K.hash="",N.href===K.href){if(T){r.warn(`Blocked same-page navigation/reload for ${a}`,{url:a,requestUrl:v.url()}),await S.abort("aborted");return}T=!0;}}catch{}await S.continue();}),d.on("response",S=>{try{let v=M(e,S.url(),e.sourceOrigin,r,"network-response");v&&A(e,v)&&(x.add(v.toString()),I(e,t,v.toString(),r,a));}catch{}}),r.page(`Rendering ${a}`,{url:a});let k=null,P=null;try{if(k=await d.goto(a,{waitUntil:"domcontentloaded",timeout:e.navigationTimeoutMs}),k&&k.ok())try{P=await L(`read response body ${a}`,q(e),()=>k.text());}catch{P=null;}}catch(S){r.warn(`Navigation issue for ${a}; saving current DOM if available`,{url:a,error:String(S)});}if(h){let S=k?.status()??null;if(S!==404){r.error(`Generated 404 request path returned unexpected status for ${a}`,{url:a,expectedStatus:404,status:S,requestPath:e.generated404RequestPath});continue}r.info(`Capturing rendered 404 page for ${a}`,{url:a,status:S,outputPath:H(e,a)});}else if(k&&!k.ok()){r.skip("page",a,k.status(),t.pageDiscoverySources.get(a)),await d.close();continue}m?(r.info(`Rendering without JS execution for ${a}`,{url:a,mode:"no-js"}),await L(`wait for rendered page ${a}`,q(e),()=>Fs(e,d))):await L(`wait for rendered page ${a}`,q(e),()=>Os(e,d)),t.stats.pagesRendered++;let y=await L(`extract rendered assets ${a}`,q(e),()=>Es(e,d,p,r,!m));for(let S of y)I(e,t,S,r,a);let R=[...new Set([...y,...x])],C=P??await L(`capture rendered html ${a}`,q(e),()=>d.content()),$=s!=="single-url"&&!h?Ts(e,a,C,r):[];if(s!=="single-url"&&!h)for(let S of $)le(e,t,S,r,a);await wt(e,a,C,t,r);let W=H(e,a);if(Q(u,e,W),oe(u,W),i.trackManifest){let S=k?.headers();i.manifest.pages[a]={url:a,outputPath:W,contentType:De(S),changeToken:w.changeToken?.supported?w.changeToken.token:null,tokenSource:w.changeToken?.supported?w.changeToken.tokenSource??null:null,sitemapLastmod:ie(t.sitemapLastmodByPage[a])??null,discoveredPages:$,discoveredAssets:R,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},i.enabled&&await Y(e,i);}}catch(c){try{let p=d?await L(`capture partial html ${a}`,q(e),()=>d.content()):"";if(p&&p.trim()){await wt(e,a,p,t,r);let h=H(e,a);if(Q(u,e,h),oe(u,h),i.trackManifest){let m=i.manifest.pages[a]??i.previousManifest.pages[a];i.manifest.pages[a]={url:a,outputPath:h,contentType:m?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:ie(t.sitemapLastmodByPage[a])??m?.sitemapLastmod??null,discoveredPages:m?.discoveredPages?[...m.discoveredPages]:[],discoveredAssets:m?.discoveredAssets?[...m.discoveredAssets]:[],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},i.enabled&&await Y(e,i);}r.warn(`Saved partial DOM for ${a}`,{url:a,error:String(c)});}}catch(p){r.error(`Could not save partial DOM for ${a}`,{url:a,error:String(p)});}r.error(`Failed page ${a}`,{url:a,error:String(c)});}finally{t.stats.pagesCompleted++,Us(t)&&qs(t,r),d&&await L(`close page ${a}`,we(e),()=>d.close()).catch(c=>{r.warn(`Timed out while closing page ${a}`,{url:a,browserPid:o.pid,error:String(c)});}),g&&await L(`close page context ${a}`,we(e),()=>g.close()).catch(c=>{r.warn(`Timed out while closing page context for ${a}`,{url:a,browserPid:o.pid,error:String(c)});});}}}finally{await L("close worker browser",we(e),()=>l.close()).catch(a=>(r.warn("Timed out while closing crawl worker browser",{browserPid:o.pid,error:String(a)}),$s(l,r,"browser.close timeout")));}}async function Bs(e){try{let t=await b.readFile(e),s=(e.endsWith(".gz")?gunzipSync(t):t).toString("utf8").trim();if(!s)return [];try{let n=JSON.parse(s);if(Array.isArray(n))return n;if(n&&typeof n=="object")return [n]}catch{return s.split(/\r?\n/).map(n=>n.trim()).filter(Boolean).map(n=>{try{let i=JSON.parse(n);return i&&typeof i=="object"?i:null}catch{return null}}).filter(n=>n!==null)}return []}catch{return []}}function Pt(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function _s(e){let t=String(e?.job?.command||"").trim(),r=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:r!=="incremental"}function Hs(e){let t=[e?.archivedAt,e?.job?.endedAt,e?.job?.startedAt];for(let r of t){let s=Date.parse(String(r||""));if(Number.isFinite(s))return s}return 0}async function jt(e){try{let t=await b.readFile(e,"utf8"),r=JSON.parse(t);return r&&typeof r=="object"&&!Array.isArray(r)?r:null}catch{return null}}function bt(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function zs(e,t){let r=Array.isArray(t?.artifacts)?t.artifacts.filter(s=>String(s?.role||"").trim()==="errors"&&String(s?.storedFileName||"").trim()!=="").sort((s,n)=>bt(s)-bt(n)).map(s=>f.join(e,String(s.storedFileName))):[];return [...new Set([...r,f.join(e,"errors.jsonl"),f.join(e,"errors.json"),f.join(e,"errors.jsonl.gz"),f.join(e,"errors.json.gz")])]}async function St(e){let t=await jt(f.join(e,"job.json"));for(let r of zs(e,t)){let s=await Bs(r);if(s.length>0)return s}return []}async function Js(e){let t=f.join(e.logDir,"archive"),r;try{r=await b.readdir(t);}catch{return ""}let s="",n=0;for(let i of r){let u=f.join(t,i);if(!(await b.stat(u).catch(()=>null))?.isDirectory())continue;let o=await jt(f.join(u,"job.json"));if(!_s(o))continue;let a=Hs(o);a>=n&&(n=a,s=u);}return s}async function Gs(e){let t=await Js(e),r=t!==""?await St(t):await St(e.logDir),s=new Set;for(let n of r)if(Pt(n.error)||Pt(n.message)){let i=n.url;typeof i=="string"&&i&&s.add(i);}return [...s]}async function Vs(e){let t=[];for(let r of e)if(r.startsWith("@")){let s=r.slice(1),n=await b.readFile(s,"utf8");t.push(...n.split(/\r?\n/).map(i=>i.trim()).filter(i=>i&&!i.startsWith("#")));}else t.push(r);return t}async function Ys(e){try{let t=await b.readFile(f.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function Zs(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 b.mkdir(e,{recursive:true}),await Promise.all(t.map(async r=>{try{await b.unlink(f.join(e,r));}catch(s){if(s.code!=="ENOENT")throw s}}));}function yt(e,t,r,s,n){let i=M(e,r,e.sourceOrigin,s,"manual-url");i&&(de(i)?Ne(e,t,i.toString(),s,n):A(e,i)?I(e,t,i.toString(),s,n):G(i)?le(e,t,i.toString(),s,n):s.reject("manual-url",i.toString(),"not page/sitemap/asset-like",n));}async function Ks(){let e=[],t=await xe(void 0,{onRemotePublisherConfigDiagnostic:P=>{e.push(P);}}),r=e.at(-1)??null,s=Or(process.argv.slice(2));if(s.resumeRewrite&&s.mode!=="full")throw new Error("--resume-rewrite is only supported for full crawl/publish jobs.");let n=[];s.mode==="retry-timeouts"&&(n=await Gs(t)),s.mode==="single-url"&&(n=await Vs(s.urls));let i=s.crawlMode==="incremental"&&s.mode==="full",u=i&&typeof t.subscriptionType=="string"&&t.subscriptionType.trim()!=="",l=(s.mode==="full"||s.mode==="single-url")&&!s.resumeRewrite,o=s.mode!=="full"||s.resumeRewrite||u,a=o?await Ys(t):{},g=u||s.mode==="single-url"?await Qr(t):xt(),d={enabled:u,trackManifest:l,manifest:Oe(g),previousManifest:Oe(g),runId:`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve()};await Zs(t.logDir);let c=new ne(t.logDir,t.logLevel);if(r){let P={status:r.status,virtualAssetBaseUrl:r.virtualAssetBaseUrl,subscriptionType:r.subscriptionType??null,error:r.error,requests:r.requests,source:"remote-publisher-config"};r.status==="loaded"&&r.subscriptionType?c.info("Loaded remote WP Suite publisher configuration.",P):c.warn("Remote WP Suite publisher configuration is unavailable or has no active subscription type.",P);}if(i&&!u){let P="Incremental crawl requires an active remote publisher subscription; refusing to fall back to a destructive full crawl.";throw c.error(P,{requestedMode:s.crawlMode,subscriptionType:t.subscriptionType??null,source:"incremental-subscription-guard"}),await c.flush(),new Error(P)}let p={pageQueue:[],queuedPages:new Set,donePages:new Set,pageDiscoverySources:new Map,assetQueue:[],queuedAssets:new Set,doneAssets:new Set,sitemapQueue:[],queuedSitemaps:new Set,doneSitemaps:new Set,sitemapLastmodByPage:{},assetMap:{...a},assetVariantDigestsByOriginalPath:new Map,stats:{pagesQueued:0,pagesRendered:0,pagesCompleted:0,assetsQueued:0,sitemapsQueued:0,assetsSaved:0,pagesSaved:0}},h=qr();if(o||await b.rm(t.outputDir,{recursive:true,force:true}),await b.mkdir(t.outputDir,{recursive:true}),s.resumeRewrite)c.info("Resuming final rewrite from existing output.",{phase:"rewrite-text",mode:s.mode,crawlMode:s.crawlMode});else {let P=await request.newContext({ignoreHTTPSErrors:t.ignoreHttpsErrors});try{if(c.mark("discovery"),s.mode==="full"?(t.sitemapPaths.forEach(R=>Ne(t,p,R,c)),await mt(t,P,p,c,h),t.seedPaths.forEach(R=>yt(t,p,R,c,"seed-path")),t.generated404RequestPath&&le(t,p,t.generated404RequestPath,c,"generated-404-request-path")):(n.forEach(R=>yt(t,p,R,c,"cli")),await mt(t,P,p,c,h)),c.endMark("discovery",{pages:p.pageQueue.length,assets:p.assetQueue.length,sitemaps:p.sitemapQueue.length}),c.summary(`Queued ${p.pageQueue.length} pages, ${p.assetQueue.length} assets, ${p.sitemapQueue.length} sitemaps.`,{mode:s.mode,crawlMode:s.crawlMode,queuedPages:p.pageQueue.length,queuedAssets:p.assetQueue.length,queuedSitemaps:p.sitemapQueue.length}),s.mode==="retry-timeouts"&&p.pageQueue.length===0&&p.assetQueue.length===0&&p.sitemapQueue.length===0){c.summary("No timed-out URLs were queued. Skipping retry crawl.",{mode:s.mode,crawlMode:s.crawlMode,queuedPages:0,queuedAssets:0,queuedSitemaps:0}),await c.flush();return}c.mark("render-pages");let y=Array.from({length:Math.max(1,t.concurrency)},()=>Ns(t,p,c,s.mode,P,d,h));if(await Promise.all(y),c.endMark("render-pages",{pages:p.stats.pagesCompleted}),c.mark("download-assets"),c.progress("Asset download phase started.",{phase:"download-assets",doneAssets:p.doneAssets.size,assetsQueued:p.stats.assetsQueued,assetQueue:p.assetQueue.length}),await Ms(t,P,p,c,d,h),c.endMark("download-assets",{assets:p.doneAssets.size}),d.enabled&&t.maxPages===0&&await Vr(t,p,d,c,h),s.mode==="full"){let R=await ks(t,p,c);for(let C of R)Q(h,t,C);}}finally{await L("dispose crawl request context",we(t),()=>P.dispose()).catch(y=>{c.warn("Timed out while disposing crawl request context",{error:String(y)});});}}d.trackManifest&&await Y(t,d),await b.writeFile(f.join(t.outputDir,"asset-map.json"),JSON.stringify(p.assetMap,null,2),"utf8"),JSON.stringify(a,null,2)!==JSON.stringify(p.assetMap,null,2)&&Q(h,t,f.join(t.outputDir,"asset-map.json"));let m=s.mode==="single-url"?ns(t,p):d.enabled&&!s.resumeRewrite?Yr(t,d,h,a,p.assetMap):void 0;c.mark("rewrite-text");let w=s.mode==="single-url"?`Rewriting text files touched by URL crawl: 0/${m?.length??0}`:"Rewriting text files...";c.progress(w,{phase:"rewrite-text",index:0,totalFiles:m?.length,changedTextFiles:0}),await ft(w);let T=Date.now(),x=await it(t,p.assetMap,{files:m,previousAssetMap:a,onStart:({totalFiles:P,workerCount:y})=>{c.info(`Rewrite phase scanning ${P} text files.`,{phase:"rewrite-text",totalFiles:P,workerCount:y});},onProgress:async({index:P,totalFiles:y,changedTextFiles:R,file:C,changed:$})=>{$&&Q(h,t,f.join(t.outputDir,C)),c.checkpoint(`Rewriting text file ${P}/${y}`,{phase:"rewrite-text",index:P,totalFiles:y,changedTextFiles:R,file:C}),c.debug(`${$?"Rewrote":"Checked unchanged"} text file ${P}/${y}: ${C}`,{phase:"rewrite-text",index:P,totalFiles:y,changedTextFiles:R,file:C,changed:$});let W=Date.now();if(!(P===1||P===y||P%50===0||W-T>=5e3))return;T=W;let v=`Rewriting text files: ${P}/${y}`;c.progress(v,{phase:"rewrite-text",index:P,totalFiles:y,changedTextFiles:R,file:C}),await ft(v);}});d.trackManifest&&(Zr(d,m),await Y(t,d)),c.endMark("rewrite-text",{changedTextFiles:x});let k=d.enabled&&!s.resumeRewrite?await Xr(t,p,d,h,c):[];await Je(t,{generatedAt:new Date().toISOString(),outputDir:f.resolve(t.outputDir),runMode:s.mode,crawlMode:s.crawlMode,fullSyncRequired:!(d.enabled&&!s.resumeRewrite),changedFiles:d.enabled&&!s.resumeRewrite?[...h.changedFiles].sort():[],deletedFiles:d.enabled&&!s.resumeRewrite?k:[],rewriteTargets:d.enabled&&!s.resumeRewrite?[...new Set((m||[]).map(P=>ee(t.outputDir,f.isAbsolute(P)?P:f.join(t.outputDir,P))).filter(P=>P!==null))].sort():[]}),c.summary(s.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${x} text files.`:`Done. Rendered ${p.stats.pagesRendered} pages, processed ${p.doneSitemaps.size} sitemaps, downloaded ${p.doneAssets.size} assets.`,{mode:s.mode,crawlMode:s.crawlMode,resumeRewrite:s.resumeRewrite,...p.stats,pagesRendered:p.stats.pagesRendered,donePages:p.stats.pagesCompleted,claimedPages:p.donePages.size,doneSitemaps:p.doneSitemaps.size,doneAssets:p.doneAssets.size,changedTextFiles:x}),await c.flush();}Ks().catch(async e=>{console.error(e);try{let r=(await xe().catch(()=>null))?.logDir??"logs",s=new ne(r,"debug");s.error(`Unhandled error: ${e instanceof Error?e.message:String(e)}`,e instanceof Error?{stack:e.stack}:void 0),await s.flush();}catch{}process.exit(1);});
package/dist/deploy.js CHANGED
@@ -1,6 +1,6 @@
1
- import {S3Client,HeadObjectCommand,GetObjectCommand,DeleteObjectsCommand,ListObjectsV2Command}from'@aws-sdk/client-s3';import {Upload}from'@aws-sdk/lib-storage';import It,{createHash}from'crypto';import Ft from'fast-glob';import $ from'fs/promises';import b from'path';import ur from'mime-types';import lt from'http';import ut from'https';import {availableParallelism}from'os';import {Worker}from'worker_threads';function ve(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function ct(e){let t=String(e??"").trim();if(!t)return "";let r=t;if(/^https?:\/\//i.test(r))try{r=new URL(r).pathname;}catch{return ""}if(r=r.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!r)return "";let n=r.endsWith("/"),i=r.replace(/^\/+/,"").split("/").map(o=>o.replace(/[^A-Za-z0-9._-]/g,"")).filter(o=>o.length>0&&o!=="."&&o!=="..");if(i.length===0)return "";let s=`/${i.join("/")}`;return n&&b.extname(s)===""&&(s+="/"),s==="/"?"":s}function ae(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function gt(e){if(!e||typeof e!="object")return {};let t={};for(let[r,n]of Object.entries(e)){let i=r.trim();if(!i||!n||typeof n!="object")continue;let s=n,o={};if(typeof s.targetOrigin=="string"){let a=ve(s.targetOrigin);a&&(o.targetOrigin=a);}let u=ae(s.extraReplacements);if(Object.keys(u).length>0&&(o.extraReplacements=u),s.s3&&typeof s.s3=="object"){let a={},c=s.s3;typeof c.bucket=="string"&&(a.bucket=c.bucket.trim()),typeof c.prefix=="string"&&(a.prefix=c.prefix.trim()),typeof c.region=="string"&&(a.region=c.region.trim()),typeof c.htmlCacheControl=="string"&&(a.htmlCacheControl=c.htmlCacheControl.trim()),typeof c.assetCacheControl=="string"&&(a.assetCacheControl=c.assetCacheControl.trim()),Object.keys(a).length>0&&(o.s3=a);}if(s.cloudFront&&typeof s.cloudFront=="object"){let a={},c=s.cloudFront;typeof c.distributionId=="string"&&(a.distributionId=c.distributionId.trim()),Array.isArray(c.invalidationPaths)&&(a.invalidationPaths=c.invalidationPaths.map(l=>String(l??"").trim()).filter(l=>l.length>0)),Object.keys(a).length>0&&(o.cloudFront=a);}t[i]=o;}return t}function Re(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function pt(e,t){if(!e||typeof e!="object")return null;let r=e,n=r.command;if(n!=="publish"&&n!=="crawl"&&n!=="deploy"&&n!=="invalidate"&&n!=="retry-timeouts"&&n!=="url")return null;let i=Number.parseInt(String(r.intervalMinutes??"0"),10);if(!Number.isFinite(i)||i<1)return null;let s=String(r.id??`${n}-${t+1}`).trim();if(!s)return null;let o=String(r.deploymentProfile??"").trim(),u=String(r.url??"").trim();return {id:s,enabled:r.enabled!==false,command:n,intervalMinutes:i,...n==="publish"||n==="crawl"?{crawlMode:r.crawlMode==="incremental"?"incremental":"full"}:{},...(n==="publish"||n==="deploy"||n==="invalidate")&&o?{deploymentProfile:o}:{},...u?{url:u}:{}}}function $e(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((n,i)=>pt(n,i)).filter(n=>!!n):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:r}}function dt(e){if(!e||typeof e!="object")return;let t=e,r={};for(let i of ["accountId","siteId"]){let s=t[i];typeof s=="string"&&s.trim()!==""&&(r[i]=s.trim());}let n=Number(t.lastUpdate??0);return Number.isFinite(n)&&n>0&&(r.lastUpdate=Math.floor(n)),t.subscriber===true&&(r.subscriber=true),Object.keys(r).length>0?r:void 0}function ue(e){let t=e&&typeof e=="object"?e:{},r=String(t.accountId??"").trim(),n=String(t.siteId??"").trim(),i=t.subscriber===true,s=dt(t.siteSettings),o={...s??{},...r?{accountId:s?.accountId??r}:{},...n?{siteId:s?.siteId??n}:{},...s?.subscriber===true||i?{subscriber:true}:{}},u={},a=String(t.apiBase??"").trim();a&&(u.apiBase=a);let c=String(t.runtimeToken??t.nonce??"").trim();c&&(u.runtimeToken=c);let l=String(t.uploadUrl??"").trim();l&&(u.uploadUrl=l),Object.keys(o).length>0&&(u.siteSettings=o);let p=Re(t.subscriptionType);return p&&(u.subscriptionType=p),u}function ft(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function xe(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function ht(e,t){let r=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[n,i]of new Headers(t.headers).entries())r.set(n,i);return r}async function De(e,t,r=5){let n=new URL(xe(e)),i=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),s=n.protocol==="http:"?lt:ut,o=ht(e,t);return await new Promise((u,a)=>{let c=s.request(n,{method:i,headers:Object.fromEntries(o.entries()),...n.protocol==="https:"?{rejectUnauthorized:false}:{}},l=>{let p=[];l.on("data",g=>{p.push(Buffer.isBuffer(g)?g:Buffer.from(g));}),l.on("error",a),l.on("end",()=>{let g=l.statusCode??0,d=l.headers.location;if(r>0&&d&&[301,302,303,307,308].includes(g)){u(De(new URL(d,n),{method:g===303?"GET":i},r-1));return}let f=new Headers;for(let[y,P]of Object.entries(l.headers))Array.isArray(P)?f.set(y,P.join(", ")):typeof P=="string"&&f.set(y,P);u(new Response(Buffer.concat(p),{status:g,statusText:l.statusMessage??"",headers:f}));});});c.on("error",a),c.end();})}function mt(e){let t=ue(e.wpsuite),r={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},n=String(r.accountId??"").trim(),i=String(r.siteId??"").trim(),s=String(t.uploadUrl??"").trim();if(e.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...s?{uploadUrl:s}:{},...Object.keys(r).length>0?{siteSettings:r}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!n||!i||!s)return false;ft(e.sourceOrigin);let o=globalThis,a={...o.WpSuite??{},siteSettings:r,uploadUrl:s};return t.apiBase&&(a.apiBase=t.apiBase),o.WpSuite=a,true}async function wt(e){if(!mt(e))return null;let t=String(e.wpsuite?.uploadUrl??"").trim(),r=globalThis.fetch;try{e.ignoreHttpsErrors&&typeof r=="function"&&t.startsWith("https://")&&(globalThis.fetch=(async(s,o)=>xe(s).startsWith(t)?De(s,o):r(s,o)));let{getConfig:n}=await import('@smart-cloud/wpsuite-core'),i=await n("publisher");return i&&typeof i=="object"?i:null}catch{return null}finally{typeof r=="function"&&(globalThis.fetch=r);}}function yt(e,t){let r=gt(t?.deploymentProfiles),n=String(t?.defaultDeploymentProfile??"").trim(),i=r[n]?n:"",s=Re(t?.subscriptionType),o=ue(e.wpsuite);return {...e,scheduler:$e(t?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:i,...s?{subscriptionType:s}:{},wpsuite:{...o,...o.siteSettings||s?{siteSettings:{...o.siteSettings??{},...o.siteSettings?.subscriber===true||s==="PROFESSIONAL"||s==="AGENCY"?{subscriber:true}:{}}}:{},...s?{subscriptionType:s}:{}}}}function le(e,t){let n=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!n)return t;let i=n.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return i.length>0?i.join("/"):t}function bt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?b.resolve(e):""}function Se(e,t,r){let n=String(t||"").trim();return n&&b.isAbsolute(n)?b.resolve(n):b.resolve(e,le(n,r))}async function ce(e){let t=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",r=await $.readFile(t,"utf8"),n=JSON.parse(r);n.sourceOrigin=n.sourceOrigin.replace(/\/$/,""),n.targetOrigin=ve(n.targetOrigin),n.ignoreHttpsErrors??=false,n.outputDir=String(n.outputDir||"export").trim()||"export",n.urlRewriteMode||=n.targetOrigin==="."?"relative":"absolute",n.noJavaScriptRenderPathPrefixes||=[],n.seedPaths||=[],n.generated404RequestPath=ct(n.generated404RequestPath),n.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],n.allowedAssetHosts||=[],n.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],n.blockedPathPrefixes||=[],n.blockedSearchFragments||=[],n.concurrency||=1,n.maxPages||=0,n.extraReplacements=ae(n.extraReplacements),n.postCrawlCopyMap=ae(n.postCrawlCopyMap),n.logDir=String(n.logDir||"logs").trim()||"logs",n.verbose??=false,n.logLevel||=n.verbose?"debug":"info",n.s3SyncMode||="sdk-upload-delete",n.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},n.readiness.timeoutMs??=1500,n.readiness.fallbackWaitMs??=1500,n.viewport||={width:1440,height:1200},n.navigationTimeoutMs||=3e4,n.assetDownloadConcurrency=Number(n.assetDownloadConcurrency)>0?Number(n.assetDownloadConcurrency):n.concurrency,n.rewriteConcurrency=Number(n.rewriteConcurrency)>0?Number(n.rewriteConcurrency):n.assetDownloadConcurrency,n.wpsuite=ue(n.wpsuite),n.scheduler=$e(void 0),n.deploymentProfiles={},n.defaultDeploymentProfile="",n.deploymentTargetOverride=String(n.deploymentTargetOverride??"").trim();let i=yt(n,await wt(n)),s=bt(),o=s?b.resolve(s,".."):"";return o?(i.outputDir=Se(o,i.outputDir,"export"),i.logDir=Se(o,i.logDir,"logs")):(b.isAbsolute(i.outputDir)||(i.outputDir=le(i.outputDir,"export")),b.isAbsolute(i.logDir)||(i.logDir=le(i.logDir,"logs"))),i}function Pt(e){let t=e/6e4;if(Number.isInteger(t)&&t>=1)return `${t} minute${t===1?"":"s"}`;let r=Math.ceil(e/1e3);return `${r} second${r===1?"":"s"}`}async function M(e,t,r){let n=new AbortController,i=globalThis.setTimeout(()=>{n.abort(new Error(`${e} timed out after ${Pt(t)}.`));},t);try{return await r({abortController:n,httpOptions:{abortSignal:n.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(i);}}var St=".deploy-plan.json",vt="deploy-plan.json";function Rt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?b.resolve(e):""}function $t(e){let t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,"").trim();return !t||t==="."||t.startsWith("../")||t===".."?null:t}function ge(e){return [...new Set(e.map($t).filter(t=>t!==null))]}function xt(e,t){return {schemaVersion:1,generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:b.resolve(e.outputDir),runMode:t.runMode,crawlMode:t.crawlMode,fullSyncRequired:!!t.fullSyncRequired,changedFiles:ge(t.changedFiles||[]),deletedFiles:ge(t.deletedFiles||[]),rewriteTargets:ge(t.rewriteTargets||[])}}function Dt(e){if(!e||typeof e!="object")return false;let t=e;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 Ce(e){let t=b.join(b.resolve(e.outputDir),St),r=Rt();return r?[b.join(r,vt),t]:[t]}async function Ee(e){let t=b.resolve(e.outputDir);for(let r of Ce(e))try{let n=await $.readFile(r,"utf8"),i=JSON.parse(n);if(!Dt(i)||b.resolve(i.outputDir)!==t)continue;return xt(e,i)}catch{}return null}async function Me(e){for(let t of Ce(e))try{await $.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}function Tt(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function ke(e){let t="";for(let n=0;n<e.length;n++){let i=e[n];if(i==="--profile"){let s=(e[n+1]||"").trim();if(!s)throw new Error("Missing value for --profile.");t=s,n+=1;}else if(i.startsWith("--profile=")){let s=i.slice(10).trim();if(!s)throw new Error("Missing value for --profile.");t=s;}}let r=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return t||r||null}function Ct(e,t){return {...e,...t??{}}}function Et(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function Le(e,t){let r=String(t??e.deploymentTargetOverride??"").trim();if(!Tt(e)){if(r)throw new Error(`Deployment target "${r}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:e}}let n=String(r||e.defaultDeploymentProfile||"").trim();if(!n)return {name:null,profile:null,config:e};let i=e.deploymentProfiles?.[n];if(!i)throw new Error(`Unknown deployment profile "${n}". Check the linked WPSuite publisher configuration.`);return {name:n,profile:i,config:{...e,targetOrigin:i.targetOrigin??e.targetOrigin,s3:Ct(e.s3,i.s3),cloudFront:Et(e.cloudFront,i.cloudFront)}}}var Ie={error:0,warn:1,info:2,debug:3},Oe=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",Y=Oe?b.join(Oe,"current-progress.json"):"",je=Promise.resolve();function Fe(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function Mt(e,t){let r={...e},n=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","pageQueue","assetQueue","sitemapQueue"]);for(let[i,s]of Object.entries(t)){let o=r[i];if(typeof o=="number"&&typeof s=="number"&&n.has(i)){r[i]=Math.max(o,s);continue}r[i]=s;}return r}function kt(e,t,r){Y&&(je=je.then(async()=>{let n=new Date,i=n.toISOString();await $.mkdir(b.dirname(Y),{recursive:true});let s=await $.readFile(Y,"utf8").then(y=>JSON.parse(y)).catch(()=>null),o=s&&typeof s.details=="object"&&s.details?s.details:{},u=Fe(e),a=s?.currentStep||Fe(s?.source||""),c=s?.startedAt||i,l={...s?.stepDurationsSec??{}},p=s?.stepStartedAt||i;if(a&&a!==u&&s?.stepStartedAt){let y=Math.max(0,Math.round((n.getTime()-new Date(s.stepStartedAt).getTime())/1e3));l[a]=(l[a]??0)+y,p=i;}let g=Math.max(0,Math.round((n.getTime()-new Date(p).getTime())/1e3)),d=Math.max(0,Math.round((n.getTime()-new Date(c).getTime())/1e3)),f={checkedAt:i,source:e,message:t,details:Mt(o,r??{}),startedAt:c,currentStep:u,stepStartedAt:p,stepElapsedSec:g,totalElapsedSec:d,stepDurationsSec:l};await $.writeFile(Y,JSON.stringify(f,null,2),"utf8");}).catch(()=>{}));}async function Lt(e,t){await $.mkdir(b.dirname(e),{recursive:true}),await $.appendFile(e,`${JSON.stringify(t)}
2
- `,"utf8");}var H=class{constructor(t,r,n="info"){this.logDir=t;this.logFile=r;this.level=n;this.ensureLogFileReady();}logDir;logFile;level;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;get logPath(){return b.join(this.logDir,this.logFile)}artifactPath(t){return this.logFile.endsWith(".log.jsonl")?b.join(this.logDir,this.logFile.replace(/\.log\.jsonl$/u,`${t}.jsonl`)):b.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 $.mkdir(this.logDir,{recursive:true}),await $.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(t){this.writeQueue=this.writeQueue.then(t).catch(r=>{this.writeError=r instanceof Error?r:new Error(String(r));});}enqueueLine(t){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await $.appendFile(this.logPath,`${t}
3
- `,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>Lt(t,r));}accepts(t){return Ie[t]<=Ie[this.level]}push(t,r,n){if(!this.accepts(t))return;let i=JSON.stringify({time:new Date().toISOString(),level:t,message:r,...n||{}});this.enqueueLine(i),t==="error"?console.error(`[ERROR] ${r}`,n?JSON.stringify(n):""):t==="warn"?console.warn(`[WARN] ${r}`,n?JSON.stringify(n):""):console.log(`[${t.toUpperCase().padEnd(5)}] ${r}`);}info(t,r){this.push("info",t,r);}progress(t,r){kt(this.logFile,t,r);}debug(t,r){this.push("debug",t,r);}warn(t,r){this.push("warn",t,r);}reject(t,r,n,i,s){let o={kind:t,url:r,reason:n,...i?{source:i}:{},...s||{}};this.enqueueJsonLine(this.rejectedPath,o),this.accepts("debug")&&this.push("debug",`Rejected ${t} ${r}: ${n}`,o);}error(t,r){this.enqueueJsonLine(this.errorsPath,{message:t,...r||{}}),this.push("error",t,r);}mark(t){this.marks.set(t,Date.now());}endMark(t,r){let n=this.marks.get(t);if(!n)return;let i=Date.now()-n,s=Number((i/1e3).toFixed(2));this.push("info",`Timing ${t}: ${s}s`,{name:t,ms:i,seconds:s,...r||{}});}async flush(){let t=Date.now()-this.startedAt,r=Number((t/1e3).toFixed(2));if(this.push("info",`Total time: ${r}s`,{name:"total",ms:t,seconds:r}),await this.writeQueue,this.writeError)throw this.writeError}};async function Ot(e){await $.mkdir(b.dirname(e),{recursive:true});}async function Ue(e,t,r){await Ot(e);let n=b.join(b.dirname(e),`.${b.basename(e)}.${process.pid}.${Date.now()}.${It.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await $.writeFile(n,t,r??"utf8"):await $.writeFile(n,t),await $.rename(n,e);}catch(i){throw await $.unlink(n).catch(()=>{}),i}}function Ne(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(b.extname(e).toLowerCase())}function We(e){return e.replace(/&quot;/g,'"').replace(/&#34;/g,'"').replace(/&apos;/g,"'").replace(/&#39;/g,"'").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">")}function _(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Z(e){return e.replace(/\//g,"\\/")}function Ae(e){return e.replace(/\//g,"\\\\/")}function jt(e){try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return null;let r=t.pathname==="/"&&!t.search&&!t.hash?"":`${t.pathname}${t.search}${t.hash}`;return `//${t.host}${r}`}catch{return null}}function _e(e,t,r){if(!t)return;e[t]=r;let n=Z(t),i=Z(r);e[n]=i;let s=Ae(t),o=Ae(r);e[s]=o;let u=_(t),a=_(r);e[u]=a;let c=_(n),l=_(i);e[c]=l;let p=_(s),g=_(o);e[p]=g;}function X(e,t,r){_e(e,t,r);let n=jt(t);n&&n!==t&&_e(e,n,r);}function ze(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function Be(e,t,r){if(!t)return r;let n=b.dirname(b.resolve(t)),i=b.resolve(e,r.replace(/^\/+/,"")),s=b.relative(n,i).replace(/\\/g,"/");return s?(s.startsWith(".")||(s=`./${s}`),s):"."}var Nt=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Wt=new Set([".html",".htm"]),qe="WPSuite.io Static Publisher",zt=qe.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Bt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function qt(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function Ht(e,t,r){return qt(t)?e.replace(new RegExp(`(?<!:)${Bt(t)}`,"g"),r):e.split(t).join(r)}function Jt(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let i=b.extname(r).toLowerCase();return Wt.has(i)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Kt(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${zt}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${qe}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let n=e.includes(`\r
1
+ import {S3Client,HeadObjectCommand,GetObjectCommand,DeleteObjectsCommand,ListObjectsV2Command}from'@aws-sdk/client-s3';import {Upload}from'@aws-sdk/lib-storage';import It,{createHash}from'crypto';import Ft from'fast-glob';import $ from'fs/promises';import w from'path';import ur from'mime-types';import lt from'http';import ut from'https';import {availableParallelism}from'os';import {Worker}from'worker_threads';function xe(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function ct(e){let t=String(e??"").trim();if(!t)return "";let r=t;if(/^https?:\/\//i.test(r))try{r=new URL(r).pathname;}catch{return ""}if(r=r.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!r)return "";let i=r.endsWith("/"),n=r.replace(/^\/+/,"").split("/").map(o=>o.replace(/[^A-Za-z0-9._-]/g,"")).filter(o=>o.length>0&&o!=="."&&o!=="..");if(n.length===0)return "";let s=`/${n.join("/")}`;return i&&w.extname(s)===""&&(s+="/"),s==="/"?"":s}function le(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function gt(e){if(!e||typeof e!="object")return {};let t={};for(let[r,i]of Object.entries(e)){let n=r.trim();if(!n||!i||typeof i!="object")continue;let s=i,o={};if(typeof s.targetOrigin=="string"){let a=xe(s.targetOrigin);a&&(o.targetOrigin=a);}let u=le(s.extraReplacements);if(Object.keys(u).length>0&&(o.extraReplacements=u),s.s3&&typeof s.s3=="object"){let a={},c=s.s3;typeof c.bucket=="string"&&(a.bucket=c.bucket.trim()),typeof c.prefix=="string"&&(a.prefix=c.prefix.trim()),typeof c.region=="string"&&(a.region=c.region.trim()),typeof c.htmlCacheControl=="string"&&(a.htmlCacheControl=c.htmlCacheControl.trim()),typeof c.assetCacheControl=="string"&&(a.assetCacheControl=c.assetCacheControl.trim()),Object.keys(a).length>0&&(o.s3=a);}if(s.cloudFront&&typeof s.cloudFront=="object"){let a={},c=s.cloudFront;typeof c.distributionId=="string"&&(a.distributionId=c.distributionId.trim()),Array.isArray(c.invalidationPaths)&&(a.invalidationPaths=c.invalidationPaths.map(l=>String(l??"").trim()).filter(l=>l.length>0)),Object.keys(a).length>0&&(o.cloudFront=a);}t[n]=o;}return t}function ce(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function pt(e,t){if(!e||typeof e!="object")return null;let r=e,i=r.command;if(i!=="publish"&&i!=="crawl"&&i!=="deploy"&&i!=="invalidate"&&i!=="retry-timeouts"&&i!=="url")return null;let n=Number.parseInt(String(r.intervalMinutes??"0"),10);if(!Number.isFinite(n)||n<1)return null;let s=String(r.id??`${i}-${t+1}`).trim();if(!s)return null;let o=String(r.deploymentProfile??"").trim(),u=String(r.url??"").trim();return {id:s,enabled:r.enabled!==false,command:i,intervalMinutes:n,...i==="publish"||i==="crawl"?{crawlMode:r.crawlMode==="incremental"?"incremental":"full"}:{},...(i==="publish"||i==="deploy"||i==="invalidate")&&o?{deploymentProfile:o}:{},...u?{url:u}:{}}}function De(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((i,n)=>pt(i,n)).filter(i=>!!i):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:r}}function dt(e){if(!e||typeof e!="object")return;let t=e,r={};for(let n of ["accountId","siteId"]){let s=t[n];typeof s=="string"&&s.trim()!==""&&(r[n]=s.trim());}let i=Number(t.lastUpdate??0);return Number.isFinite(i)&&i>0&&(r.lastUpdate=Math.floor(i)),t.subscriber===true&&(r.subscriber=true),Object.keys(r).length>0?r:void 0}function ge(e){let t=e&&typeof e=="object"?e:{},r=String(t.accountId??"").trim(),i=String(t.siteId??"").trim(),n=t.subscriber===true,s=dt(t.siteSettings),o={...s??{},...r?{accountId:s?.accountId??r}:{},...i?{siteId:s?.siteId??i}:{},...s?.subscriber===true||n?{subscriber:true}:{}},u={},a=String(t.apiBase??"").trim();a&&(u.apiBase=a);let c=String(t.runtimeToken??t.nonce??"").trim();c&&(u.runtimeToken=c);let l=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();l&&(u.virtualAssetBaseUrl=l),Object.keys(o).length>0&&(u.siteSettings=o);let p=ce(t.subscriptionType);return p&&(u.subscriptionType=p),u}function ft(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Te(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function mt(e,t){let r=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[i,n]of new Headers(t.headers).entries())r.set(i,n);return r}async function Ce(e,t,r=5){let i=new URL(Te(e)),n=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),s=i.protocol==="http:"?lt:ut,o=mt(e,t);return await new Promise((u,a)=>{let c=s.request(i,{method:n,headers:Object.fromEntries(o.entries()),...i.protocol==="https:"?{rejectUnauthorized:false}:{}},l=>{let p=[];l.on("data",g=>{p.push(Buffer.isBuffer(g)?g:Buffer.from(g));}),l.on("error",a),l.on("end",()=>{let g=l.statusCode??0,f=l.headers.location;if(r>0&&f&&[301,302,303,307,308].includes(g)){u(Ce(new URL(f,i),{method:g===303?"GET":n},r-1));return}let m=new Headers;for(let[b,P]of Object.entries(l.headers))Array.isArray(P)?m.set(b,P.join(", ")):typeof P=="string"&&m.set(b,P);u(new Response(Buffer.concat(p),{status:g,statusText:l.statusMessage??"",headers:m}));});});c.on("error",a),c.end();})}function ht(e){let t=ge(e.wpsuite),r={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},i=String(r.accountId??"").trim(),n=String(r.siteId??"").trim(),s=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();if(e.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...s?{virtualAssetBaseUrl:s}:{},...Object.keys(r).length>0?{siteSettings:r}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!i||!n||!s)return false;ft(e.sourceOrigin);let o=globalThis,a={...o.WpSuite??{},siteSettings:r,uploadUrl:s};return t.apiBase&&(a.apiBase=t.apiBase),o.WpSuite=a,true}async function yt(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!ht(e)){let n=e.wpsuite?.siteSettings,s=[String(n?.accountId??"").trim()?"":"accountId",String(n?.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): ${s.join(", ")}.`,requests:[]}}}let r=globalThis.fetch,i=[];try{typeof r=="function"&&/^https?:\/\//i.test(t)&&(globalThis.fetch=(async(a,c)=>{let l=Te(a);if(l.startsWith(t)){let p=(()=>{try{return new URL(l).pathname}catch{return l}})();try{let g=e.ignoreHttpsErrors&&l.startsWith("https://")?await Ce(a,c):await r(a,c);return i.push({path:p,status:g.status,ok:g.ok,error:null}),g}catch(g){throw i.push({path:p,status:null,ok:!1,error:g instanceof Error?g.message:String(g)}),g}}return r(a,c)}));let{getConfig:n}=await import('@smart-cloud/wpsuite-core'),s=await n("publisher"),o=s&&typeof s=="object"?s:null,u=ce(o?.subscriptionType);return {remote:o,diagnostic:{status:o?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:u??null,error:o?null:"WP Suite publisher config loader returned no configuration.",requests:i}}}catch(n){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:t,subscriptionType:null,error:n instanceof Error?n.message:String(n),requests:i}}}finally{typeof r=="function"&&(globalThis.fetch=r);}}function wt(e,t){let r=gt(t?.deploymentProfiles),i=String(t?.defaultDeploymentProfile??"").trim(),n=r[i]?i:"",s=ce(t?.subscriptionType),o=ge(e.wpsuite);return {...e,scheduler:De(t?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:n,...s?{subscriptionType:s}:{},wpsuite:{...o,...o.siteSettings||s?{siteSettings:{...o.siteSettings??{},...o.siteSettings?.subscriber===true||s==="PROFESSIONAL"||s==="AGENCY"?{subscriber:true}:{}}}:{},...s?{subscriptionType:s}:{}}}}function ue(e,t){let i=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!i)return t;let n=i.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return n.length>0?n.join("/"):t}function bt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?w.resolve(e):""}function $e(e,t,r){let i=String(t||"").trim();return i&&w.isAbsolute(i)?w.resolve(i):w.resolve(e,ue(i,r))}async function pe(e,t={}){let r=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",i=await $.readFile(r,"utf8"),n=JSON.parse(i);n.sourceOrigin=n.sourceOrigin.replace(/\/$/,""),n.targetOrigin=xe(n.targetOrigin),n.ignoreHttpsErrors??=false,n.outputDir=String(n.outputDir||"export").trim()||"export",n.urlRewriteMode||=n.targetOrigin==="."?"relative":"absolute",n.noJavaScriptRenderPathPrefixes||=[],n.seedPaths||=[],n.generated404RequestPath=ct(n.generated404RequestPath),n.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],n.allowedAssetHosts||=[],n.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],n.blockedPathPrefixes||=[],n.blockedSearchFragments||=[],n.concurrency||=1,n.maxPages||=0,n.extraReplacements=le(n.extraReplacements),n.postCrawlCopyMap=le(n.postCrawlCopyMap),n.logDir=String(n.logDir||"logs").trim()||"logs",n.verbose??=false,n.logLevel||=n.verbose?"debug":"info",n.s3SyncMode||="sdk-upload-delete",n.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},n.readiness.timeoutMs??=1500,n.readiness.fallbackWaitMs??=1500,n.viewport||={width:1440,height:1200},n.navigationTimeoutMs||=3e4,n.assetDownloadConcurrency=Number(n.assetDownloadConcurrency)>0?Number(n.assetDownloadConcurrency):n.concurrency,n.rewriteConcurrency=Number(n.rewriteConcurrency)>0?Number(n.rewriteConcurrency):n.assetDownloadConcurrency,n.wpsuite=ge(n.wpsuite),n.scheduler=De(void 0),n.deploymentProfiles={},n.defaultDeploymentProfile="",n.deploymentTargetOverride=String(n.deploymentTargetOverride??"").trim();let s=await yt(n);t.onRemotePublisherConfigDiagnostic?.(s.diagnostic);let o=wt(n,s.remote),u=bt(),a=u?w.resolve(u,".."):"";return a?(o.outputDir=$e(a,o.outputDir,"export"),o.logDir=$e(a,o.logDir,"logs")):(w.isAbsolute(o.outputDir)||(o.outputDir=ue(o.outputDir,"export")),w.isAbsolute(o.logDir)||(o.logDir=ue(o.logDir,"logs"))),o}function Pt(e){let t=e/6e4;if(Number.isInteger(t)&&t>=1)return `${t} minute${t===1?"":"s"}`;let r=Math.ceil(e/1e3);return `${r} second${r===1?"":"s"}`}async function L(e,t,r){let i=new AbortController,n=globalThis.setTimeout(()=>{i.abort(new Error(`${e} timed out after ${Pt(t)}.`));},t);try{return await r({abortController:i,httpOptions:{abortSignal:i.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(n);}}var St=".deploy-plan.json",vt="deploy-plan.json";function Rt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?w.resolve(e):""}function $t(e){let t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,"").trim();return !t||t==="."||t.startsWith("../")||t===".."?null:t}function de(e){return [...new Set(e.map($t).filter(t=>t!==null))]}function xt(e,t){return {schemaVersion:1,generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:w.resolve(e.outputDir),runMode:t.runMode,crawlMode:t.crawlMode,fullSyncRequired:!!t.fullSyncRequired,changedFiles:de(t.changedFiles||[]),deletedFiles:de(t.deletedFiles||[]),rewriteTargets:de(t.rewriteTargets||[])}}function Dt(e){if(!e||typeof e!="object")return false;let t=e;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 Me(e){let t=w.join(w.resolve(e.outputDir),St),r=Rt();return r?[w.join(r,vt),t]:[t]}async function ke(e){let t=w.resolve(e.outputDir);for(let r of Me(e))try{let i=await $.readFile(r,"utf8"),n=JSON.parse(i);if(!Dt(n)||w.resolve(n.outputDir)!==t)continue;return xt(e,n)}catch{}return null}async function Le(e){for(let t of Me(e))try{await $.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}function Tt(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function Ie(e){let t="";for(let i=0;i<e.length;i++){let n=e[i];if(n==="--profile"){let s=(e[i+1]||"").trim();if(!s)throw new Error("Missing value for --profile.");t=s,i+=1;}else if(n.startsWith("--profile=")){let s=n.slice(10).trim();if(!s)throw new Error("Missing value for --profile.");t=s;}}let r=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return t||r||null}function Ct(e,t){return {...e,...t??{}}}function Et(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function Oe(e,t){let r=String(t??e.deploymentTargetOverride??"").trim();if(!Tt(e)){if(r)throw new Error(`Deployment target "${r}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:e}}let i=String(r||e.defaultDeploymentProfile||"").trim();if(!i)return {name:null,profile:null,config:e};let n=e.deploymentProfiles?.[i];if(!n)throw new Error(`Unknown deployment profile "${i}". Check the linked WPSuite publisher configuration.`);return {name:i,profile:n,config:{...e,targetOrigin:n.targetOrigin??e.targetOrigin,s3:Ct(e.s3,n.s3),cloudFront:Et(e.cloudFront,n.cloudFront)}}}var je={error:0,warn:1,info:2,debug:3},Fe=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",Y=Fe?w.join(Fe,"current-progress.json"):"",Ae=Promise.resolve();function _e(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function Mt(e,t){let r={...e},i=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","pageQueue","assetQueue","sitemapQueue"]);for(let[n,s]of Object.entries(t)){let o=r[n];if(typeof o=="number"&&typeof s=="number"&&i.has(n)){r[n]=Math.max(o,s);continue}r[n]=s;}return r}function kt(e,t,r){Y&&(Ae=Ae.then(async()=>{let i=new Date,n=i.toISOString();await $.mkdir(w.dirname(Y),{recursive:true});let s=await $.readFile(Y,"utf8").then(b=>JSON.parse(b)).catch(()=>null),o=s&&typeof s.details=="object"&&s.details?s.details:{},u=_e(e),a=s?.currentStep||_e(s?.source||""),c=s?.startedAt||n,l={...s?.stepDurationsSec??{}},p=s?.stepStartedAt||n;if(a&&a!==u&&s?.stepStartedAt){let b=Math.max(0,Math.round((i.getTime()-new Date(s.stepStartedAt).getTime())/1e3));l[a]=(l[a]??0)+b,p=n;}let g=Math.max(0,Math.round((i.getTime()-new Date(p).getTime())/1e3)),f=Math.max(0,Math.round((i.getTime()-new Date(c).getTime())/1e3)),m={checkedAt:n,source:e,message:t,details:Mt(o,r??{}),startedAt:c,currentStep:u,stepStartedAt:p,stepElapsedSec:g,totalElapsedSec:f,stepDurationsSec:l};await $.writeFile(Y,JSON.stringify(m,null,2),"utf8");}).catch(()=>{}));}async function Lt(e,t){await $.mkdir(w.dirname(e),{recursive:true}),await $.appendFile(e,`${JSON.stringify(t)}
2
+ `,"utf8");}var K=class{constructor(t,r,i="info"){this.logDir=t;this.logFile=r;this.level=i;this.ensureLogFileReady();}logDir;logFile;level;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;get logPath(){return w.join(this.logDir,this.logFile)}artifactPath(t){return this.logFile.endsWith(".log.jsonl")?w.join(this.logDir,this.logFile.replace(/\.log\.jsonl$/u,`${t}.jsonl`)):w.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 $.mkdir(this.logDir,{recursive:true}),await $.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(t){this.writeQueue=this.writeQueue.then(t).catch(r=>{this.writeError=r instanceof Error?r:new Error(String(r));});}enqueueLine(t){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await $.appendFile(this.logPath,`${t}
3
+ `,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>Lt(t,r));}accepts(t){return je[t]<=je[this.level]}push(t,r,i){if(!this.accepts(t))return;let n=JSON.stringify({time:new Date().toISOString(),level:t,message:r,...i||{}});this.enqueueLine(n),t==="error"?console.error(`[ERROR] ${r}`,i?JSON.stringify(i):""):t==="warn"?console.warn(`[WARN] ${r}`,i?JSON.stringify(i):""):console.log(`[${t.toUpperCase().padEnd(5)}] ${r}`);}info(t,r){this.push("info",t,r);}progress(t,r){kt(this.logFile,t,r);}debug(t,r){this.push("debug",t,r);}warn(t,r){this.push("warn",t,r);}reject(t,r,i,n,s){let o={kind:t,url:r,reason:i,...n?{source:n}:{},...s||{}};this.enqueueJsonLine(this.rejectedPath,o),this.accepts("debug")&&this.push("debug",`Rejected ${t} ${r}: ${i}`,o);}error(t,r){this.enqueueJsonLine(this.errorsPath,{message:t,...r||{}}),this.push("error",t,r);}mark(t){this.marks.set(t,Date.now());}endMark(t,r){let i=this.marks.get(t);if(!i)return;let n=Date.now()-i,s=Number((n/1e3).toFixed(2));this.push("info",`Timing ${t}: ${s}s`,{name:t,ms:n,seconds:s,...r||{}});}async flush(){let t=Date.now()-this.startedAt,r=Number((t/1e3).toFixed(2));if(this.push("info",`Total time: ${r}s`,{name:"total",ms:t,seconds:r}),await this.writeQueue,this.writeError)throw this.writeError}};async function Ot(e){await $.mkdir(w.dirname(e),{recursive:true});}async function We(e,t,r){await Ot(e);let i=w.join(w.dirname(e),`.${w.basename(e)}.${process.pid}.${Date.now()}.${It.randomBytes(6).toString("hex")}.tmp`);try{typeof t=="string"?await $.writeFile(i,t,r??"utf8"):await $.writeFile(i,t),await $.rename(i,e);}catch(n){throw await $.unlink(i).catch(()=>{}),n}}function ze(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(w.extname(e).toLowerCase())}function Be(e){return e.replace(/&quot;/g,'"').replace(/&#34;/g,'"').replace(/&apos;/g,"'").replace(/&#39;/g,"'").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">")}function W(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Z(e){return e.replace(/\//g,"\\/")}function Ue(e){return e.replace(/\//g,"\\\\/")}function jt(e){try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return null;let r=t.pathname==="/"&&!t.search&&!t.hash?"":`${t.pathname}${t.search}${t.hash}`;return `//${t.host}${r}`}catch{return null}}function Ne(e,t,r){if(!t)return;e[t]=r;let i=Z(t),n=Z(r);e[i]=n;let s=Ue(t),o=Ue(r);e[s]=o;let u=W(t),a=W(r);e[u]=a;let c=W(i),l=W(n);e[c]=l;let p=W(s),g=W(o);e[p]=g;}function X(e,t,r){Ne(e,t,r);let i=jt(t);i&&i!==t&&Ne(e,i,r);}function qe(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function He(e,t,r){if(!t)return r;let i=w.dirname(w.resolve(t)),n=w.resolve(e,r.replace(/^\/+/,"")),s=w.relative(i,n).replace(/\\/g,"/");return s?(s.startsWith(".")||(s=`./${s}`),s):"."}var Nt=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Wt=new Set([".html",".htm"]),Je="WPSuite.io Static Publisher",zt=Je.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Bt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function qt(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function Ht(e,t,r){return qt(t)?e.replace(new RegExp(`(?<!:)${Bt(t)}`,"g"),r):e.split(t).join(r)}function Jt(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let n=w.extname(r).toLowerCase();return Wt.has(n)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Kt(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${zt}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${Je}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let i=e.includes(`\r
4
4
  `)?`\r
5
5
  `:`
6
- `;return e.replace(/<head\b[^>]*>/i,i=>`${i}${n} ${t}`)}function Gt(e){let t=We(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function Qt(e,t){let r=[...new Set(t)].filter(s=>s.includes("/")&&!/\\+\//.test(s)).map(s=>[s,Z(s)]).filter(([s,o])=>s!==o).sort((s,o)=>o[0].length-s[0].length);if(!r.length)return e;let n=s=>{let o=s;for(let[u,a]of r)o=o.split(u).join(a);return o},i=e.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(s,o,u,a)=>`${o}${n(u)}${a}`);return i=i.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(s,o,u,a,c)=>Gt(a)?`${o}${n(a)}${c}`:s),i}function Vt(e,t){if(!t)return null;let r=b.dirname(b.resolve(t)),n=b.resolve(e.outputDir),i=b.relative(r,n).replace(/\\/g,"/");return i?(i.startsWith(".")||(i=`./${i}`),i.endsWith("/")?i:`${i}/`):"./"}function Yt(e,t,r){let n=Vt(t,r);if(!n)return e;let i=e;for(let s of Nt){let o=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),u=new RegExp(`(?:\\.{1,}/)+${o}`,"g"),a=new RegExp(`(?<!\\.)/${o}`,"g");i=i.replace(u,`${n}${s}`).replace(a,`${n}${s}`);let c=s.replace(/\//g,"\\/"),l=n.replace(/\//g,"\\/"),p=c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),g=new RegExp(`(?:\\.{1,}\\\\/)+${p}`,"g"),d=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${p}`,"g"),f=new RegExp(`(?<![\\.\\\\])\\/${p}`,"g");i=i.replace(g,`${l}${c}`).replace(d,`${l}${c}`).replace(f,`${l}${c}`);}return i}function de(e,t,r){if(e.urlRewriteMode==="absolute")return t;let n=(()=>{try{return new URL(t,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin)}catch{return null}})(),i=n?n.pathname:ze(t,e.targetOrigin),s=n?`${n.search}${n.hash}`:"";return e.urlRewriteMode==="root-relative"?`${i}${s}`:`${Be(e.outputDir,r,i)}${s}`}function pe(e,t,r,n,i){X(e,r,de(t,n,i));}function Zt(e,t,r,n,i){if(!r||r===n)return;X(e,r,n);let s=de(t,r,i),o=de(t,n,i);X(e,s,o);}function Xt(e,t,r,n,i={}){let s=e,o={};pe(o,t,t.sourceOrigin,t.targetOrigin,n);for(let[a,c]of Object.entries(t.extraReplacements))pe(o,t,a,c,n);for(let[a,c]of Object.entries(r))pe(o,t,a,c,n);for(let[a,c]of Object.entries(i)){let l=r[a];!l||l===c||Zt(o,t,c,l,n);}let u=Object.entries(o).sort((a,c)=>c[0].length-a[0].length);for(let[a,c]of u)s=Ht(s,a,c);return t.urlRewriteMode!=="absolute"&&(s=Yt(s,t,n)),s=Qt(s,u.map(([,a])=>a)),Jt(t,s,n)&&(s=Kt(s)),s}async function er(e,t,r,n){let i=b.join(e.outputDir,n),s=b.extname(i).toLowerCase(),o;try{o=await $.readFile(i,"utf8");}catch(c){if(c.code!=="ENOENT")throw c;return {changed:false}}let a=Xt(o,e,t,s===".js"||s===".mjs"?void 0:i,r);return a!==o?(await Ue(i,a,"utf8"),{changed:true}):{changed:false}}async function tr(e,t){return await new Promise((r,n)=>{let i=a=>{if(u(),a?.error){n(new Error(a.error));return}r({changed:!!a?.changed});},s=a=>{u(),n(a);},o=a=>{u(),a!==0&&n(new Error(`Rewrite worker exited with code ${a}.`));},u=()=>{e.off("message",i),e.off("error",s),e.off("exit",o);};e.on("message",i),e.on("error",s),e.on("exit",o),e.postMessage({file:t});})}async function He(e,t,r={}){let i=(r.files?[...new Set(r.files)].map(g=>b.resolve(g)).filter(g=>g.startsWith(b.resolve(e.outputDir))).map(g=>b.relative(e.outputDir,g).replace(/\\/g,"/")).filter(g=>g.length>0):await Ft(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(g=>g!=="asset-map.json"&&Ne(g)),s=0;if(i.length===0)return 0;let o=Math.max(1,Number(e.rewriteConcurrency||e.assetDownloadConcurrency||1)),u=Math.max(1,Math.min(o,i.length,availableParallelism()));await r.onStart?.({totalFiles:i.length,workerCount:u});let a=0,c=0,l=null;if(u===1){for(let g of i){let d=await er(e,t,r.previousAssetMap??{},g);d.changed&&(s+=1),c+=1,await r.onProgress?.({index:c,totalFiles:i.length,changedTextFiles:s,file:g,changed:d.changed});}return s}let p=Array.from({length:u},async()=>{let g=new Worker(new URL("./rewrite-worker.js",import.meta.url),{workerData:{config:e,assetMap:t,previousAssetMap:r.previousAssetMap??{}}});try{for(;!l;){let d=a;if(d>=i.length)return;a+=1;let f=i[d],y=await tr(g,f);y.changed&&(s+=1),c+=1,await r.onProgress?.({index:c,totalFiles:i.length,changedTextFiles:s,file:f,changed:y.changed});}}catch(d){throw l=d instanceof Error?d:new Error(String(d)),l}finally{await g.terminate().catch(()=>{});}});return await Promise.all(p),s}var Qe="wpsuite-sha256",Ve="wpsuite-normalized-sha256",cr=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,be=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,gr=["SIGINT","SIGTERM"],re=new Set,ee=new Map,Je=null;function pr(e){re.add(e);let t=false;return ()=>{t||(t=true,re.delete(e));}}async function dr(){let e=[...re];e.length!==0&&await Promise.allSettled(e.map(async t=>{re.delete(t),await $.rm(t,{recursive:true,force:true});}));}function fr(){if(!(ee.size>0))for(let e of gr){let t=()=>{Je||(Je=dr().finally(()=>{for(let[r,n]of ee)process.off(r,n);ee.clear(),process.exit(1);}));};ee.set(e,t),process.on(e,t);}}fr();function hr(e,t){let r=t.trim();return r?b.join(b.resolve(r),"crawl-manifest.json"):b.join(b.resolve(e),".crawl-manifest.json")}function Ye(e){return b.normalize(e).split(b.sep).join("/")}function Ke(e,t){let r=b.relative(b.resolve(e),b.resolve(t));return !r||r.startsWith("..")||b.isAbsolute(r)?null:Ye(r)}async function mr(e,t,r){let n=hr(e.outputDir,t),i;try{i=await $.readFile(n,"utf8");}catch(l){return l.code==="ENOENT"?(r.warn("Deploy rewrite guard disabled because the crawl manifest is missing.",{manifestPath:n,source:"deploy-guard"}),null):(r.warn("Deploy rewrite guard disabled because the crawl manifest could not be read.",{manifestPath:n,error:l instanceof Error?l.message:String(l),source:"deploy-guard"}),null)}let s;try{s=JSON.parse(i);}catch(l){return r.warn("Deploy rewrite guard disabled because the crawl manifest is invalid JSON.",{manifestPath:n,error:l instanceof Error?l.message:String(l),source:"deploy-guard"}),null}let o=new Map,u=new Map,a=0,c=0;for(let[l,p]of Object.entries(s.pages||{})){let g=String(p?.outputPath||"").trim(),d=g?Ke(e.outputDir,g):null;if(d){let f=typeof p?.contentType=="string"&&p.contentType?p.contentType:null;f&&u.set(d,f);}!g||p?.rewriteComplete===true||d&&(a++,o.has(d)||o.set(d,{kind:"page",sourceUrl:l,outputPath:b.resolve(g),relativePath:d}));}for(let[l,p]of Object.entries(s.assets||{})){let g=String(p?.outputPath||"").trim(),d=p?.isText===true,f=g?Ke(e.outputDir,g):null;if(f){let y=typeof p?.contentType=="string"&&p.contentType?p.contentType:null;y&&u.set(f,y);}!g||!d||p?.rewriteComplete===true||f&&(c++,o.has(f)||o.set(f,{kind:"asset",sourceUrl:l,outputPath:b.resolve(g),relativePath:f}));}return {manifestPath:n,byRelativePath:o,contentTypeByRelativePath:u,pendingPages:a,pendingTextAssets:c}}function wr(e){return e&&(be.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 he(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,r)=>r%2===1?t:wr(t)).join("")}function yr(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,r)=>r%2===1?t:be.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 ne(e,t){return Array.isArray(e)?e.map(r=>ne(r,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([r,n])=>[r,ne(n,r)])):typeof e!="string"?e:t&&cr.test(t)?yr(e):be.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?he(e):e}function br(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function Pr(e,t){let r=t.trim();if((r.startsWith("{")||r.startsWith("[")||r.startsWith('"'))&&e.startsWith("data-"))try{let i=JSON.parse(r);return JSON.stringify(ne(i))}catch{}if(e.startsWith("data-")&&/^[A-Za-z0-9+/=]+$/.test(r))try{let i=Buffer.from(r,"base64").toString("utf8"),s=JSON.parse(i),o=JSON.stringify(ne(s));return Buffer.from(o,"utf8").toString("base64")}catch{}return t}function Sr(e,t){let r=e.toLowerCase();return r==="class"?t.split(/(\s+)/).map((n,i)=>i%2===1?n:he(n)).join(""):r==="id"||r==="for"||r==="aria-controls"||r==="aria-labelledby"||r==="aria-describedby"||r==="aria-owns"||r==="aria-activedescendant"||r==="name"?he(t):r==="href"||r==="src"?br(t):Pr(r,t)}function vr(e){return e.replace(/<([a-z][^\s/>]*)([^<>]*?)>/gi,(t,r,n)=>{if(r.startsWith("/"))return t;let i=n.replace(/\s([:@a-zA-Z_][-:.a-zA-Z0-9_]*?)=(['"])([\s\S]*?)\2/g,(s,o,u,a)=>{let c=Sr(o,a);return ` ${o}=${u}${c}${u}`});return `<${r}${i}>`})}function fe(e){let t=b.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(b.basename(e))}function te(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function Rr(e,t,r,n){let i=new Map,s,o=0;do{o++;let u=await M(`S3 list objects page ${o} for s3://${t}/${r||""}`,3e5,({httpOptions:a})=>e.send(new ListObjectsV2Command({Bucket:t,Prefix:r||void 0,ContinuationToken:s}),a));for(let a of u.Contents||[]){if(!a.Key)continue;let c=(a.ETag||"").replace(/^"|"$/g,"").toLowerCase(),l=Number(a.Size??0);i.set(a.Key,{etag:c,size:l});}s=u.NextContinuationToken,n.debug(`Listed S3 keys page ${o}: ${i.size} keys so far`);}while(s);return i}async function $r(e,t,r,n){if(n.has(r))return n.get(r)??null;try{let i=await M(`S3 head object ${r}`,3e5,({httpOptions:o})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),o)),s={etag:(i.ETag||"").replace(/^"|"$/g,"").toLowerCase(),size:Number(i.ContentLength??0)};return n.set(r,s),s}catch{return n.set(r,null),null}}async function Ze(e,t,r,n){let i=[...new Set(Array.from(r).filter(Boolean))];if(i.length===0)return n.info("No stale S3 objects to delete."),[];n.info(`Deleting ${i.length} stale S3 object(s)\u2026`);for(let s=0;s<i.length;s+=1e3){let o=i.slice(s,s+1e3);if(o.length!==0){await M(`S3 delete objects batch ${Math.floor(s/1e3)+1}`,3e5,({httpOptions:u})=>e.send(new DeleteObjectsCommand({Bucket:t,Delete:{Objects:o.map(a=>({Key:a}))}}),u)),n.info(`Deleted batch of ${o.length} object(s).`);for(let u of o)n.debug(` deleted: ${u}`);}}return i}async function xr(e,t,r,n,i){return Ze(e,t,Array.from(r).filter(s=>!n.has(s)),i)}function Dr(e){return createHash("md5").update(e).digest("hex")}function Ge(e){return createHash("sha256").update(e).digest("hex")}function me(e){return createHash("sha256").update(vr(e.toString("utf8"))).digest("hex")}async function Tr(e,t,r,n){if(n.has(r))return n.get(r)??null;try{let o=((await M(`S3 head object metadata ${r}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),u))).Metadata?.[Qe]||"").trim().toLowerCase()||null;return n.set(r,o),o}catch{return n.set(r,null),null}}async function Cr(e,t,r,n,i){if(n.has(r))return n.get(r)??null;try{let o=((await M(`S3 head object normalized metadata ${r}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),u))).Metadata?.[Ve]||"").trim().toLowerCase();if(o)return n.set(r,o),o}catch{return n.set(r,null),null}if(i.has(r)){let s=i.get(r)??null;return n.set(r,s),s}try{let o=await(await M(`S3 get object ${r}`,3e5,({httpOptions:a})=>e.send(new GetObjectCommand({Bucket:t,Key:r}),a))).Body?.transformToByteArray(),u=o?me(Buffer.from(o)):null;return i.set(r,u),n.set(r,u),u}catch{return i.set(r,null),n.set(r,null),null}}function Er(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function Mr(e,t){let r=e,n=Object.entries(t).sort((i,s)=>s[0].length-i[0].length);for(let[i,s]of n)i&&(r=r.split(i).join(s));return r}async function kr(e,t,r,n){let i=b.join(e,"asset-map.json"),s;try{s=await $.readFile(i,"utf8");}catch(a){if(a.code==="ENOENT")return;throw a}let o=JSON.parse(s);if(!o||typeof o!="object")return;let u=Object.fromEntries(Object.entries(o).map(([a,c])=>{let l=String(c??"");return t.urlRewriteMode==="absolute"&&t.targetOrigin&&r.targetOrigin&&t.targetOrigin!==r.targetOrigin&&(l=l.split(t.targetOrigin).join(r.targetOrigin)),l=Mr(l,n),[a,l]}));await $.writeFile(i,JSON.stringify(u,null,2),"utf8");}async function Lr(e,t,r,n,i){let s=e.targetOrigin!==t.targetOrigin,o=Object.keys(n).length>0;if(!r||!s&&!o)return {outputDir:e.outputDir,cleanup:async()=>{}};if(s&&e.urlRewriteMode!=="absolute")throw new Error(`Deployment profile "${r}" changes targetOrigin, but the base crawl output must use urlRewriteMode "absolute" for multi-target redeploys.`);let u=b.join(b.dirname(e.outputDir),`.deploy-profile-${Er(r)}-${Date.now()}`),a=pr(u);i.info(`Preparing deployment profile "${r}" from existing crawl output to ${u}...`);try{await $.rm(u,{recursive:!0,force:!0}),await $.cp(e.outputDir,u,{recursive:!0});let c={...e,sourceOrigin:e.targetOrigin,targetOrigin:t.targetOrigin,extraReplacements:n,outputDir:u},l=1;i.info(`Rewriting text files for deployment profile "${r}"...`);let p=await He(c,{},{onStart:({totalFiles:g,workerCount:d})=>{l=d,i.info(`Rewriting ${g} text file(s) for deployment profile "${r}" with ${d} worker(s).`);},onProgress:({index:g,totalFiles:d,changedTextFiles:f,file:y,changed:P})=>{let R=`Rewriting [${g}/${d}] ${y} (${P?"rewrote":"checked"}; ${f} changed so far)`;d<=200||g<=5||g%10===0||g===d?(i.progress(R,{file:y,index:g,totalFiles:d,changed:P,changedTextFiles:f,workerCount:l}),i.info(R)):i.debug(R);}});return await kr(u,e,t,n),i.info(`Prepared deployment profile "${r}" in ${u} (${p} rewritten text file(s)).`),{outputDir:u,cleanup:async()=>{a(),await $.rm(u,{recursive:!0,force:!0});}}}catch(c){throw i.error(`Failed to prepare deployment profile "${r}" temporary output.`,{tempDir:u,outputDir:e.outputDir,error:c instanceof Error?c.message:String(c),...c instanceof Error&&c.stack?{stack:c.stack}:{}}),await $.rm(u,{recursive:true,force:true}).catch(()=>{}),a(),await i.flush().catch(()=>{}),c}}async function Ir(){let e=await ce(),t=ke(process.argv.slice(2)),r=Le(e,t),n=b.resolve(r.config.logDir||"logs"),i=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",s=i?b.join(b.resolve(i),"deploy-diff.json"):"",o=new H(n,"deploy.log.jsonl",r.config.logLevel??"info"),u=r.profile?.extraReplacements??{},a=async()=>{};try{let c=await Lr(e,r.config,r.name,u,o);a=c.cleanup;let l={...r.config,outputDir:c.outputDir},p=l.s3SyncMode??"sdk-upload-delete",g=await Ee(e),d=c.outputDir!==e.outputDir&&(e.targetOrigin!==r.config.targetOrigin||Object.keys(u).length>0),f=!!g&&!g.fullSyncRequired&&!d;r.name&&o.info(`Using deployment profile: ${r.name}`),o.info(`Starting deploy \u2014 s3://${l.s3.bucket}/${l.s3.prefix||""} (region: ${l.s3.region})`),o.info(`S3 sync mode: ${p}`),g&&g.fullSyncRequired?o.info("Deploy plan requests a full sync; scanning the whole output tree."):g&&d?o.info("Ignoring incremental deploy plan because deployment-profile rewrites require a full sync."):f&&o.info(`Using incremental deploy plan: ${g.changedFiles.length} changed file(s), ${g.deletedFiles.length} deleted file(s).`),o.mark("deploy");let y=new S3Client({region:l.s3.region}),P=c.outputDir===e.outputDir?await mr(e,i,o):null,j=f?(await Promise.all(g.changedFiles.map(async w=>{try{return (await $.stat(b.join(l.outputDir,w))).isFile()?w:null}catch{return null}}))).filter(w=>w!==null):await Ft(["**/*"],{cwd:l.outputDir,onlyFiles:!0,dot:!0}),R=[],K=[],m=j.filter(w=>{let I=P?.byRelativePath.get(Ye(w));if(!I)return !0;let h=te(l.s3.prefix,w);return R.push(w),K.push(h),o.reject(I.kind,I.sourceUrl||w,"rewrite not completed; deploy upload blocked","deploy-guard",{file:w,key:h,outputPath:I.outputPath,manifestPath:P?.manifestPath}),!1}),Xe=f?new Set:new Set(j.map(w=>te(l.s3.prefix,w)));P&&(P.pendingPages>0||P.pendingTextAssets>0)&&o.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"}),R.length>0&&o.warn(`Deploy rewrite guard blocked ${R.length} file(s) from upload because final crawl rewrite is incomplete.`,{rejected:R.length,manifestPath:P?.manifestPath,source:"deploy-guard"}),f?o.info(`Using ${m.length} eligible planned changed file(s) from deploy plan for upload${R.length>0?` (${R.length} blocked by deploy rewrite guard)`:""}.`):o.info(`Found ${j.length} file(s) in output directory "${l.outputDir}"${R.length>0?`; ${m.length} remain eligible for upload after deploy rewrite guard filtering`:""}.`),o.progress("Deploy preflight: comparing local output with remote S3 state.",{phase:"deploy",mode:p,totalFiles:m.length,scannedFiles:j.length,rejected:R.length,deploymentProfile:r.name||"",s3Bucket:l.s3.bucket,s3Prefix:l.s3.prefix||"",targetedPlan:f,deployGuardEnabled:c.outputDir===e.outputDir});let x=0,v=0,L=0,ie=[],N=[],se=[],G=[],W=new Map,et=new Map,tt=new Map,rt=new Map,nt=new Map;f||(o.info("Listing existing S3 objects to detect unchanged files..."),W=await Rr(y,l.s3.bucket,l.s3.prefix,o),o.info(`Found ${W.size} existing key(s) in S3.`));let it=async w=>W.has(w)?W.get(w)??null:f?$r(y,l.s3.bucket,w,et):null;for(let w of m){let I=b.join(l.outputDir,w),h=te(l.s3.prefix,w),Q=P?.contentTypeByRelativePath.get(w),z=Q&&Q!=="application/octet-stream"?Q:ur.lookup(w)||Q||"application/octet-stream",st=fe(w)?l.s3.htmlCacheControl:l.s3.assetCacheControl,S=x+v+L+1;m.length<=200||S<=5||S%10===0||S===m.length?(o.progress(`Uploading [${S}/${m.length}] ${h} (${z})`,{file:w,key:h,index:S,totalFiles:m.length,contentType:z,mode:p}),o.info(`Uploading [${S}/${m.length}] ${h} (${z})`)):o.debug(`Uploading [${S}/${m.length}] ${h} (${z})`);try{let D=await $.readFile(I),B=await it(h),q=null,F=null;if(B){let oe=D.byteLength;if(B.size===oe){let V=B.etag.includes("-");if(B.etag!==""&&!V){let ot=Dr(D);if(B.etag===ot){v++,m.length<=200||v<=5||v%25===0?(o.progress(`Skipped unchanged [${S}/${m.length}] ${h}`,{file:w,key:h,index:S,totalFiles:m.length,uploaded:x,skipped:v,failed:L,mode:p,reason:"etag-md5-match"}),o.info(`Skipped unchanged [${S}/${m.length}] ${h}`)):o.debug(`Skipped unchanged [${S}/${m.length}] ${h}`),N.push(h);continue}}q=Ge(D);let Pe=await Tr(y,l.s3.bucket,h,tt);if(Pe&&Pe===q){v++,m.length<=200||v<=5||v%25===0?(o.progress(`Skipped unchanged [${S}/${m.length}] ${h}`,{file:w,key:h,index:S,totalFiles:m.length,uploaded:x,skipped:v,failed:L,mode:p,reason:"metadata-sha256-match"}),o.info(`Skipped unchanged [${S}/${m.length}] ${h}`)):o.debug(`Skipped unchanged [${S}/${m.length}] ${h}`),N.push(h);continue}}if(fe(w)){F=me(D);let V=await Cr(y,l.s3.bucket,h,rt,nt);if(V&&V===F){v++,m.length<=200||v<=5||v%25===0?(o.progress(`Skipped semantically unchanged [${S}/${m.length}] ${h}`,{file:w,key:h,index:S,totalFiles:m.length,uploaded:x,skipped:v,failed:L,mode:p,reason:"normalized-html-match"}),o.info(`Skipped semantically unchanged [${S}/${m.length}] ${h}`)):o.debug(`Skipped semantically unchanged [${S}/${m.length}] ${h}`),N.push(h);continue}}}q=q??Ge(D),F=F??(fe(w)?me(D):null),await M(`S3 upload ${h}`,9e5,({abortController:oe})=>new Upload({client:y,abortController:oe,params:{Bucket:l.s3.bucket,Key:h,Body:D,ContentType:z,CacheControl:st,Metadata:{[Qe]:q,...F?{[Ve]:F}:{}}}}).done()),x++,ie.push(h),(x%25===0||x===m.length)&&(o.progress(`Uploaded ${x}/${m.length} file(s)\u2026`,{uploaded:x,skipped:v,failed:L,totalFiles:m.length,mode:p}),o.info(`Uploaded ${x}/${m.length} file(s)\u2026`));}catch(D){L++,se.push(h),o.error(`Failed to upload ${h}: ${D.message}`,{key:h,error:String(D)});}}o.info(`Upload complete: ${x} uploaded, ${v} skipped unchanged, ${K.length} rejected by guard, ${L} failed.`),p==="sdk-upload-delete"?f?G=await Ze(y,l.s3.bucket,g.deletedFiles.map(w=>te(l.s3.prefix,w)),o):G=await xr(y,l.s3.bucket,W.keys(),Xe,o):o.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion."),s&&(await $.mkdir(b.dirname(s),{recursive:!0}),await $.writeFile(s,JSON.stringify({generatedAt:new Date().toISOString(),mode:p,summary:{totalFiles:j.length,eligibleFiles:m.length,uploaded:ie.length,skipped:N.length,rejected:K.length,failed:se.length,deleted:G.length,...r.name?{profile:r.name}:{}},uploadedKeys:ie,skippedKeys:N,rejectedKeys:K,failedKeys:se,deletedKeys:G},null,2),"utf8")),await Me(e),o.endMark("deploy"),await o.flush();}finally{await a().catch(()=>{});}}Ir().catch(async e=>{console.error(e);try{let r=(await ce().catch(()=>null))?.logDir??"logs",n=new H(r,"deploy.log.jsonl","debug");n.error(`Unhandled error: ${e instanceof Error?e.message:String(e)}`,e instanceof Error?{stack:e.stack}:void 0),await n.flush();}catch{}process.exit(1);});
6
+ `;return e.replace(/<head\b[^>]*>/i,n=>`${n}${i} ${t}`)}function Gt(e){let t=Be(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function Qt(e,t){let r=[...new Set(t)].filter(s=>s.includes("/")&&!/\\+\//.test(s)).map(s=>[s,Z(s)]).filter(([s,o])=>s!==o).sort((s,o)=>o[0].length-s[0].length);if(!r.length)return e;let i=s=>{let o=s;for(let[u,a]of r)o=o.split(u).join(a);return o},n=e.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(s,o,u,a)=>`${o}${i(u)}${a}`);return n=n.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(s,o,u,a,c)=>Gt(a)?`${o}${i(a)}${c}`:s),n}function Vt(e,t){if(!t)return null;let r=w.dirname(w.resolve(t)),i=w.resolve(e.outputDir),n=w.relative(r,i).replace(/\\/g,"/");return n?(n.startsWith(".")||(n=`./${n}`),n.endsWith("/")?n:`${n}/`):"./"}function Yt(e,t,r){let i=Vt(t,r);if(!i)return e;let n=e;for(let s of Nt){let o=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),u=new RegExp(`(?:\\.{1,}/)+${o}`,"g"),a=new RegExp(`(?<!\\.)/${o}`,"g");n=n.replace(u,`${i}${s}`).replace(a,`${i}${s}`);let c=s.replace(/\//g,"\\/"),l=i.replace(/\//g,"\\/"),p=c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),g=new RegExp(`(?:\\.{1,}\\\\/)+${p}`,"g"),f=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${p}`,"g"),m=new RegExp(`(?<![\\.\\\\])\\/${p}`,"g");n=n.replace(g,`${l}${c}`).replace(f,`${l}${c}`).replace(m,`${l}${c}`);}return n}function me(e,t,r){if(e.urlRewriteMode==="absolute")return t;let i=(()=>{try{return new URL(t,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin)}catch{return null}})(),n=i?i.pathname:qe(t,e.targetOrigin),s=i?`${i.search}${i.hash}`:"";return e.urlRewriteMode==="root-relative"?`${n}${s}`:`${He(e.outputDir,r,n)}${s}`}function fe(e,t,r,i,n){X(e,r,me(t,i,n));}function Zt(e,t,r,i,n){if(!r||r===i)return;X(e,r,i);let s=me(t,r,n),o=me(t,i,n);X(e,s,o);}function Xt(e,t,r,i,n={}){let s=e,o={};fe(o,t,t.sourceOrigin,t.targetOrigin,i);for(let[a,c]of Object.entries(t.extraReplacements))fe(o,t,a,c,i);for(let[a,c]of Object.entries(r))fe(o,t,a,c,i);for(let[a,c]of Object.entries(n)){let l=r[a];!l||l===c||Zt(o,t,c,l,i);}let u=Object.entries(o).sort((a,c)=>c[0].length-a[0].length);for(let[a,c]of u)s=Ht(s,a,c);return t.urlRewriteMode!=="absolute"&&(s=Yt(s,t,i)),s=Qt(s,u.map(([,a])=>a)),Jt(t,s,i)&&(s=Kt(s)),s}async function er(e,t,r,i){let n=w.join(e.outputDir,i),s=w.extname(n).toLowerCase(),o;try{o=await $.readFile(n,"utf8");}catch(c){if(c.code!=="ENOENT")throw c;return {changed:false}}let a=Xt(o,e,t,s===".js"||s===".mjs"?void 0:n,r);return a!==o?(await We(n,a,"utf8"),{changed:true}):{changed:false}}async function tr(e,t){return await new Promise((r,i)=>{let n=a=>{if(u(),a?.error){i(new Error(a.error));return}r({changed:!!a?.changed});},s=a=>{u(),i(a);},o=a=>{u(),a!==0&&i(new Error(`Rewrite worker exited with code ${a}.`));},u=()=>{e.off("message",n),e.off("error",s),e.off("exit",o);};e.on("message",n),e.on("error",s),e.on("exit",o),e.postMessage({file:t});})}async function Ke(e,t,r={}){let n=(r.files?[...new Set(r.files)].map(g=>w.resolve(g)).filter(g=>g.startsWith(w.resolve(e.outputDir))).map(g=>w.relative(e.outputDir,g).replace(/\\/g,"/")).filter(g=>g.length>0):await Ft(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(g=>g!=="asset-map.json"&&ze(g)),s=0;if(n.length===0)return 0;let o=Math.max(1,Number(e.rewriteConcurrency||e.assetDownloadConcurrency||1)),u=Math.max(1,Math.min(o,n.length,availableParallelism()));await r.onStart?.({totalFiles:n.length,workerCount:u});let a=0,c=0,l=null;if(u===1){for(let g of n){let f=await er(e,t,r.previousAssetMap??{},g);f.changed&&(s+=1),c+=1,await r.onProgress?.({index:c,totalFiles:n.length,changedTextFiles:s,file:g,changed:f.changed});}return s}let p=Array.from({length:u},async()=>{let g=new Worker(new URL("./rewrite-worker.js",import.meta.url),{workerData:{config:e,assetMap:t,previousAssetMap:r.previousAssetMap??{}}});try{for(;!l;){let f=a;if(f>=n.length)return;a+=1;let m=n[f],b=await tr(g,m);b.changed&&(s+=1),c+=1,await r.onProgress?.({index:c,totalFiles:n.length,changedTextFiles:s,file:m,changed:b.changed});}}catch(f){throw l=f instanceof Error?f:new Error(String(f)),l}finally{await g.terminate().catch(()=>{});}});return await Promise.all(p),s}var Ye="wpsuite-sha256",Ze="wpsuite-normalized-sha256",cr=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,Se=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,gr=["SIGINT","SIGTERM"],re=new Set,ee=new Map,Ge=null;function pr(e){re.add(e);let t=false;return ()=>{t||(t=true,re.delete(e));}}async function dr(){let e=[...re];e.length!==0&&await Promise.allSettled(e.map(async t=>{re.delete(t),await $.rm(t,{recursive:true,force:true});}));}function fr(){if(!(ee.size>0))for(let e of gr){let t=()=>{Ge||(Ge=dr().finally(()=>{for(let[r,i]of ee)process.off(r,i);ee.clear(),process.exit(1);}));};ee.set(e,t),process.on(e,t);}}fr();function mr(e,t){let r=t.trim();return r?w.join(w.resolve(r),"crawl-manifest.json"):w.join(w.resolve(e),".crawl-manifest.json")}function Xe(e){return w.normalize(e).split(w.sep).join("/")}function Qe(e,t){let r=w.relative(w.resolve(e),w.resolve(t));return !r||r.startsWith("..")||w.isAbsolute(r)?null:Xe(r)}async function hr(e,t,r){let i=mr(e.outputDir,t),n;try{n=await $.readFile(i,"utf8");}catch(l){return l.code==="ENOENT"?(r.warn("Deploy rewrite guard disabled because the crawl manifest is missing.",{manifestPath:i,source:"deploy-guard"}),null):(r.warn("Deploy rewrite guard disabled because the crawl manifest could not be read.",{manifestPath:i,error:l instanceof Error?l.message:String(l),source:"deploy-guard"}),null)}let s;try{s=JSON.parse(n);}catch(l){return r.warn("Deploy rewrite guard disabled because the crawl manifest is invalid JSON.",{manifestPath:i,error:l instanceof Error?l.message:String(l),source:"deploy-guard"}),null}let o=new Map,u=new Map,a=0,c=0;for(let[l,p]of Object.entries(s.pages||{})){let g=String(p?.outputPath||"").trim(),f=g?Qe(e.outputDir,g):null;if(f){let m=typeof p?.contentType=="string"&&p.contentType?p.contentType:null;m&&u.set(f,m);}!g||p?.rewriteComplete===true||f&&(a++,o.has(f)||o.set(f,{kind:"page",sourceUrl:l,outputPath:w.resolve(g),relativePath:f}));}for(let[l,p]of Object.entries(s.assets||{})){let g=String(p?.outputPath||"").trim(),f=p?.isText===true,m=g?Qe(e.outputDir,g):null;if(m){let b=typeof p?.contentType=="string"&&p.contentType?p.contentType:null;b&&u.set(m,b);}!g||!f||p?.rewriteComplete===true||m&&(c++,o.has(m)||o.set(m,{kind:"asset",sourceUrl:l,outputPath:w.resolve(g),relativePath:m}));}return {manifestPath:i,byRelativePath:o,contentTypeByRelativePath:u,pendingPages:a,pendingTextAssets:c}}function yr(e){return e&&(Se.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 ye(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,r)=>r%2===1?t:yr(t)).join("")}function wr(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,r)=>r%2===1?t:Se.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 ne(e,t){return Array.isArray(e)?e.map(r=>ne(r,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([r,i])=>[r,ne(i,r)])):typeof e!="string"?e:t&&cr.test(t)?wr(e):Se.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?ye(e):e}function br(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function Pr(e,t){let r=t.trim();if((r.startsWith("{")||r.startsWith("[")||r.startsWith('"'))&&e.startsWith("data-"))try{let n=JSON.parse(r);return JSON.stringify(ne(n))}catch{}if(e.startsWith("data-")&&/^[A-Za-z0-9+/=]+$/.test(r))try{let n=Buffer.from(r,"base64").toString("utf8"),s=JSON.parse(n),o=JSON.stringify(ne(s));return Buffer.from(o,"utf8").toString("base64")}catch{}return t}function Sr(e,t){let r=e.toLowerCase();return r==="class"?t.split(/(\s+)/).map((i,n)=>n%2===1?i:ye(i)).join(""):r==="id"||r==="for"||r==="aria-controls"||r==="aria-labelledby"||r==="aria-describedby"||r==="aria-owns"||r==="aria-activedescendant"||r==="name"?ye(t):r==="href"||r==="src"?br(t):Pr(r,t)}function vr(e){return e.replace(/<([a-z][^\s/>]*)([^<>]*?)>/gi,(t,r,i)=>{if(r.startsWith("/"))return t;let n=i.replace(/\s([:@a-zA-Z_][-:.a-zA-Z0-9_]*?)=(['"])([\s\S]*?)\2/g,(s,o,u,a)=>{let c=Sr(o,a);return ` ${o}=${u}${c}${u}`});return `<${r}${n}>`})}function he(e){let t=w.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(w.basename(e))}function te(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function Rr(e,t,r,i){let n=new Map,s,o=0;do{o++;let u=await L(`S3 list objects page ${o} for s3://${t}/${r||""}`,3e5,({httpOptions:a})=>e.send(new ListObjectsV2Command({Bucket:t,Prefix:r||void 0,ContinuationToken:s}),a));for(let a of u.Contents||[]){if(!a.Key)continue;let c=(a.ETag||"").replace(/^"|"$/g,"").toLowerCase(),l=Number(a.Size??0);n.set(a.Key,{etag:c,size:l});}s=u.NextContinuationToken,i.debug(`Listed S3 keys page ${o}: ${n.size} keys so far`);}while(s);return n}async function $r(e,t,r,i){if(i.has(r))return i.get(r)??null;try{let n=await L(`S3 head object ${r}`,3e5,({httpOptions:o})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),o)),s={etag:(n.ETag||"").replace(/^"|"$/g,"").toLowerCase(),size:Number(n.ContentLength??0)};return i.set(r,s),s}catch{return i.set(r,null),null}}async function xr(e,t,r,i){let n=[...new Set(Array.from(r).filter(Boolean))];if(n.length===0)return i.info("No explicitly tombstoned S3 objects to delete."),[];i.info(`Deleting ${n.length} explicitly tombstoned S3 object(s)\u2026`);for(let s=0;s<n.length;s+=1e3){let o=n.slice(s,s+1e3);if(o.length!==0){await L(`S3 delete objects batch ${Math.floor(s/1e3)+1}`,3e5,({httpOptions:u})=>e.send(new DeleteObjectsCommand({Bucket:t,Delete:{Objects:o.map(a=>({Key:a}))}}),u)),i.info(`Deleted batch of ${o.length} object(s).`);for(let u of o)i.debug(` deleted: ${u}`);}}return n}function Dr(e){return createHash("md5").update(e).digest("hex")}function Ve(e){return createHash("sha256").update(e).digest("hex")}function we(e){return createHash("sha256").update(vr(e.toString("utf8"))).digest("hex")}async function Tr(e,t,r,i){if(i.has(r))return i.get(r)??null;try{let o=((await L(`S3 head object metadata ${r}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),u))).Metadata?.[Ye]||"").trim().toLowerCase()||null;return i.set(r,o),o}catch{return i.set(r,null),null}}async function Cr(e,t,r,i,n){if(i.has(r))return i.get(r)??null;try{let o=((await L(`S3 head object normalized metadata ${r}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),u))).Metadata?.[Ze]||"").trim().toLowerCase();if(o)return i.set(r,o),o}catch{return i.set(r,null),null}if(n.has(r)){let s=n.get(r)??null;return i.set(r,s),s}try{let o=await(await L(`S3 get object ${r}`,3e5,({httpOptions:a})=>e.send(new GetObjectCommand({Bucket:t,Key:r}),a))).Body?.transformToByteArray(),u=o?we(Buffer.from(o)):null;return n.set(r,u),i.set(r,u),u}catch{return n.set(r,null),i.set(r,null),null}}function Er(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function Mr(e,t){let r=e,i=Object.entries(t).sort((n,s)=>s[0].length-n[0].length);for(let[n,s]of i)n&&(r=r.split(n).join(s));return r}async function kr(e,t,r,i){let n=w.join(e,"asset-map.json"),s;try{s=await $.readFile(n,"utf8");}catch(a){if(a.code==="ENOENT")return;throw a}let o=JSON.parse(s);if(!o||typeof o!="object")return;let u=Object.fromEntries(Object.entries(o).map(([a,c])=>{let l=String(c??"");return t.urlRewriteMode==="absolute"&&t.targetOrigin&&r.targetOrigin&&t.targetOrigin!==r.targetOrigin&&(l=l.split(t.targetOrigin).join(r.targetOrigin)),l=Mr(l,i),[a,l]}));await $.writeFile(n,JSON.stringify(u,null,2),"utf8");}async function Lr(e,t,r,i,n){let s=e.targetOrigin!==t.targetOrigin,o=Object.keys(i).length>0;if(!r||!s&&!o)return {outputDir:e.outputDir,cleanup:async()=>{}};if(s&&e.urlRewriteMode!=="absolute")throw new Error(`Deployment profile "${r}" changes targetOrigin, but the base crawl output must use urlRewriteMode "absolute" for multi-target redeploys.`);let u=w.join(w.dirname(e.outputDir),`.deploy-profile-${Er(r)}-${Date.now()}`),a=pr(u);n.info(`Preparing deployment profile "${r}" from existing crawl output to ${u}...`);try{await $.rm(u,{recursive:!0,force:!0}),await $.cp(e.outputDir,u,{recursive:!0});let c={...e,sourceOrigin:e.targetOrigin,targetOrigin:t.targetOrigin,extraReplacements:i,outputDir:u},l=1;n.info(`Rewriting text files for deployment profile "${r}"...`);let p=await Ke(c,{},{onStart:({totalFiles:g,workerCount:f})=>{l=f,n.info(`Rewriting ${g} text file(s) for deployment profile "${r}" with ${f} worker(s).`);},onProgress:({index:g,totalFiles:f,changedTextFiles:m,file:b,changed:P})=>{let R=`Rewriting [${g}/${f}] ${b} (${P?"rewrote":"checked"}; ${m} changed so far)`;f<=200||g<=5||g%10===0||g===f?(n.progress(R,{file:b,index:g,totalFiles:f,changed:P,changedTextFiles:m,workerCount:l}),n.info(R)):n.debug(R);}});return await kr(u,e,t,i),n.info(`Prepared deployment profile "${r}" in ${u} (${p} rewritten text file(s)).`),{outputDir:u,cleanup:async()=>{a(),await $.rm(u,{recursive:!0,force:!0});}}}catch(c){throw n.error(`Failed to prepare deployment profile "${r}" temporary output.`,{tempDir:u,outputDir:e.outputDir,error:c instanceof Error?c.message:String(c),...c instanceof Error&&c.stack?{stack:c.stack}:{}}),await $.rm(u,{recursive:true,force:true}).catch(()=>{}),a(),await n.flush().catch(()=>{}),c}}async function Ir(){let e=await pe(),t=Ie(process.argv.slice(2)),r=Oe(e,t),i=w.resolve(r.config.logDir||"logs"),n=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",s=n?w.join(w.resolve(n),"deploy-diff.json"):"",o=new K(i,"deploy.log.jsonl",r.config.logLevel??"info"),u=r.profile?.extraReplacements??{},a=async()=>{};try{let c=await Lr(e,r.config,r.name,u,o);a=c.cleanup;let l={...r.config,outputDir:c.outputDir},p=l.s3SyncMode??"sdk-upload-delete",g=await ke(e),f=c.outputDir!==e.outputDir&&(e.targetOrigin!==r.config.targetOrigin||Object.keys(u).length>0),m=!!g&&!g.fullSyncRequired&&!f;r.name&&o.info(`Using deployment profile: ${r.name}`),o.info(`Starting deploy \u2014 s3://${l.s3.bucket}/${l.s3.prefix||""} (region: ${l.s3.region})`),o.info(`S3 sync mode: ${p}`),g&&g.fullSyncRequired?o.info("Deploy plan requests a full sync; scanning the whole output tree."):g&&f?o.info("Ignoring incremental deploy plan because deployment-profile rewrites require a full sync."):m&&o.info(`Using incremental deploy plan: ${g.changedFiles.length} changed file(s), ${g.deletedFiles.length} deleted file(s).`),o.mark("deploy");let b=new S3Client({region:l.s3.region}),P=c.outputDir===e.outputDir?await hr(e,n,o):null,A=m?(await Promise.all(g.changedFiles.map(async y=>{try{return (await $.stat(w.join(l.outputDir,y))).isFile()?y:null}catch{return null}}))).filter(y=>y!==null):await Ft(["**/*"],{cwd:l.outputDir,onlyFiles:!0,dot:!0}),R=[],Q=[],h=A.filter(y=>{let D=P?.byRelativePath.get(Xe(y));if(!D)return !0;let d=te(l.s3.prefix,y);return R.push(y),Q.push(d),o.reject(D.kind,D.sourceUrl||y,"rewrite not completed; deploy upload blocked","deploy-guard",{file:y,key:d,outputPath:D.outputPath,manifestPath:P?.manifestPath}),!1}),ve=new Set((m?h:A).map(y=>te(l.s3.prefix,y)));P&&(P.pendingPages>0||P.pendingTextAssets>0)&&o.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"}),R.length>0&&o.warn(`Deploy rewrite guard blocked ${R.length} file(s) from upload because final crawl rewrite is incomplete.`,{rejected:R.length,manifestPath:P?.manifestPath,source:"deploy-guard"}),m?o.info(`Using ${h.length} eligible planned changed file(s) from deploy plan for upload${R.length>0?` (${R.length} blocked by deploy rewrite guard)`:""}.`):o.info(`Found ${A.length} file(s) in output directory "${l.outputDir}"${R.length>0?`; ${h.length} remain eligible for upload after deploy rewrite guard filtering`:""}.`),o.progress("Deploy preflight: comparing local output with remote S3 state.",{phase:"deploy",mode:p,totalFiles:h.length,scannedFiles:A.length,rejected:R.length,deploymentProfile:r.name||"",s3Bucket:l.s3.bucket,s3Prefix:l.s3.prefix||"",targetedPlan:m,deployGuardEnabled:c.outputDir===e.outputDir});let x=0,v=0,O=0,ie=[],B=[],se=[],oe=[],j=[],_=new Map,et=new Map,tt=new Map,rt=new Map,nt=new Map;m||(o.info("Listing existing S3 objects to detect unchanged files..."),_=await Rr(b,l.s3.bucket,l.s3.prefix,o),o.info(`Found ${_.size} existing key(s) in S3.`));let it=async y=>_.has(y)?_.get(y)??null:m?$r(b,l.s3.bucket,y,et):null;for(let y of h){let D=w.join(l.outputDir,y),d=te(l.s3.prefix,y),T=P?.contentTypeByRelativePath.get(y),q=T&&T!=="application/octet-stream"?T:ur.lookup(y)||T||"application/octet-stream",st=he(y)?l.s3.htmlCacheControl:l.s3.assetCacheControl,S=x+v+O+1;h.length<=200||S<=5||S%10===0||S===h.length?(o.progress(`Uploading [${S}/${h.length}] ${d} (${q})`,{file:y,key:d,index:S,totalFiles:h.length,contentType:q,mode:p}),o.info(`Uploading [${S}/${h.length}] ${d} (${q})`)):o.debug(`Uploading [${S}/${h.length}] ${d} (${q})`);try{let C=await $.readFile(D),H=await it(d),J=null,U=null;if(H){let ae=C.byteLength;if(H.size===ae){let V=H.etag.includes("-");if(H.etag!==""&&!V){let ot=Dr(C);if(H.etag===ot){v++,h.length<=200||v<=5||v%25===0?(o.progress(`Skipped unchanged [${S}/${h.length}] ${d}`,{file:y,key:d,index:S,totalFiles:h.length,uploaded:x,skipped:v,failed:O,mode:p,reason:"etag-md5-match"}),o.info(`Skipped unchanged [${S}/${h.length}] ${d}`)):o.debug(`Skipped unchanged [${S}/${h.length}] ${d}`),B.push(d);continue}}J=Ve(C);let Re=await Tr(b,l.s3.bucket,d,tt);if(Re&&Re===J){v++,h.length<=200||v<=5||v%25===0?(o.progress(`Skipped unchanged [${S}/${h.length}] ${d}`,{file:y,key:d,index:S,totalFiles:h.length,uploaded:x,skipped:v,failed:O,mode:p,reason:"metadata-sha256-match"}),o.info(`Skipped unchanged [${S}/${h.length}] ${d}`)):o.debug(`Skipped unchanged [${S}/${h.length}] ${d}`),B.push(d);continue}}if(he(y)){U=we(C);let V=await Cr(b,l.s3.bucket,d,rt,nt);if(V&&V===U){v++,h.length<=200||v<=5||v%25===0?(o.progress(`Skipped semantically unchanged [${S}/${h.length}] ${d}`,{file:y,key:d,index:S,totalFiles:h.length,uploaded:x,skipped:v,failed:O,mode:p,reason:"normalized-html-match"}),o.info(`Skipped semantically unchanged [${S}/${h.length}] ${d}`)):o.debug(`Skipped semantically unchanged [${S}/${h.length}] ${d}`),B.push(d);continue}}}J=J??Ve(C),U=U??(he(y)?we(C):null),await L(`S3 upload ${d}`,9e5,({abortController:ae})=>new Upload({client:b,abortController:ae,params:{Bucket:l.s3.bucket,Key:d,Body:C,ContentType:q,CacheControl:st,Metadata:{[Ye]:J,...U?{[Ze]:U}:{}}}}).done()),x++,ie.push(d),(x%25===0||x===h.length)&&(o.progress(`Uploaded ${x}/${h.length} file(s)\u2026`,{uploaded:x,skipped:v,failed:O,totalFiles:h.length,mode:p}),o.info(`Uploaded ${x}/${h.length} file(s)\u2026`));}catch(C){O++,se.push(d),o.error(`Failed to upload ${d}: ${C.message}`,{key:d,error:String(C)});}}if(o.info(`Upload complete: ${x} uploaded, ${v} skipped unchanged, ${Q.length} rejected by guard, ${O} failed.`),p==="sdk-upload-delete"){let y=new Set((g?.deletedFiles??[]).map(d=>te(l.s3.prefix,d))),D=[...y].filter(d=>!ve.has(d));if(!m&&(j=[..._.keys()].filter(T=>!ve.has(T)).filter(T=>!y.has(T)),j.length>0)){o.warn(`Protected ${j.length} remote-only S3 object(s) from deletion because the crawl did not provide explicit tombstones.`,{protected:j.length,source:"deploy-delete-guard"});for(let T of j)o.debug(` protected remote-only object: ${T}`);}oe=await xr(b,l.s3.bucket,m?D:D.filter(d=>_.has(d)),o);}else o.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion.");s&&(await $.mkdir(w.dirname(s),{recursive:!0}),await $.writeFile(s,JSON.stringify({generatedAt:new Date().toISOString(),mode:p,summary:{totalFiles:A.length,eligibleFiles:h.length,uploaded:ie.length,skipped:B.length,rejected:Q.length,failed:se.length,deleted:oe.length,protected:j.length,...r.name?{profile:r.name}:{}},uploadedKeys:ie,skippedKeys:B,rejectedKeys:Q,failedKeys:se,deletedKeys:oe,protectedRemoteOnlyKeys:j},null,2),"utf8")),await Le(e),o.endMark("deploy"),await o.flush();}finally{await a().catch(()=>{});}}Ir().catch(async e=>{console.error(e);try{let r=(await pe().catch(()=>null))?.logDir??"logs",i=new K(r,"deploy.log.jsonl","debug");i.error(`Unhandled error: ${e instanceof Error?e.message:String(e)}`,e instanceof Error?{stack:e.stack}:void 0),await i.flush();}catch{}process.exit(1);});
@@ -1,3 +1,3 @@
1
- import {CloudFrontClient,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';import h from'fs/promises';import W from'http';import _ from'https';import d from'path';function N(i){let t=i/6e4;if(Number.isInteger(t)&&t>=1)return `${t} minute${"s"}`;let r=Math.ceil(i/1e3);return `${r} second${r===1?"":"s"}`}async function L(i,t,r){let e=new AbortController,o=globalThis.setTimeout(()=>{e.abort(new Error(`${i} timed out after ${N(t)}.`));},t);try{return await r({abortController:e,httpOptions:{abortSignal:e.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(o);}}function D(i){let t=i.trim();return t==="."?".":t.replace(/\/$/,"")}function B(i){let t=String(i??"").trim();if(!t)return "";let r=t;if(/^https?:\/\//i.test(r))try{r=new URL(r).pathname;}catch{return ""}if(r=r.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!r)return "";let e=r.endsWith("/"),o=r.replace(/^\/+/,"").split("/").map(s=>s.replace(/[^A-Za-z0-9._-]/g,"")).filter(s=>s.length>0&&s!=="."&&s!=="..");if(o.length===0)return "";let n=`/${o.join("/")}`;return e&&d.extname(n)===""&&(n+="/"),n==="/"?"":n}function v(i){return !i||typeof i!="object"?{}:Object.fromEntries(Object.entries(i).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function J(i){if(!i||typeof i!="object")return {};let t={};for(let[r,e]of Object.entries(i)){let o=r.trim();if(!o||!e||typeof e!="object")continue;let n=e,s={};if(typeof n.targetOrigin=="string"){let a=D(n.targetOrigin);a&&(s.targetOrigin=a);}let l=v(n.extraReplacements);if(Object.keys(l).length>0&&(s.extraReplacements=l),n.s3&&typeof n.s3=="object"){let a={},u=n.s3;typeof u.bucket=="string"&&(a.bucket=u.bucket.trim()),typeof u.prefix=="string"&&(a.prefix=u.prefix.trim()),typeof u.region=="string"&&(a.region=u.region.trim()),typeof u.htmlCacheControl=="string"&&(a.htmlCacheControl=u.htmlCacheControl.trim()),typeof u.assetCacheControl=="string"&&(a.assetCacheControl=u.assetCacheControl.trim()),Object.keys(a).length>0&&(s.s3=a);}if(n.cloudFront&&typeof n.cloudFront=="object"){let a={},u=n.cloudFront;typeof u.distributionId=="string"&&(a.distributionId=u.distributionId.trim()),Array.isArray(u.invalidationPaths)&&(a.invalidationPaths=u.invalidationPaths.map(c=>String(c??"").trim()).filter(c=>c.length>0)),Object.keys(a).length>0&&(s.cloudFront=a);}t[o]=s;}return t}function k(i){return i==="PROFESSIONAL"||i==="AGENCY"?i:void 0}function H(i,t){if(!i||typeof i!="object")return null;let r=i,e=r.command;if(e!=="publish"&&e!=="crawl"&&e!=="deploy"&&e!=="invalidate"&&e!=="retry-timeouts"&&e!=="url")return null;let o=Number.parseInt(String(r.intervalMinutes??"0"),10);if(!Number.isFinite(o)||o<1)return null;let n=String(r.id??`${e}-${t+1}`).trim();if(!n)return null;let s=String(r.deploymentProfile??"").trim(),l=String(r.url??"").trim();return {id:n,enabled:r.enabled!==false,command:e,intervalMinutes:o,...e==="publish"||e==="crawl"?{crawlMode:r.crawlMode==="incremental"?"incremental":"full"}:{},...(e==="publish"||e==="deploy"||e==="invalidate")&&s?{deploymentProfile:s}:{},...l?{url:l}:{}}}function E(i){let t=i&&typeof i=="object"?i:{},r=Array.isArray(t.rules)?t.rules.map((e,o)=>H(e,o)).filter(e=>!!e):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:r}}function z(i){if(!i||typeof i!="object")return;let t=i,r={};for(let o of ["accountId","siteId"]){let n=t[o];typeof n=="string"&&n.trim()!==""&&(r[o]=n.trim());}let e=Number(t.lastUpdate??0);return Number.isFinite(e)&&e>0&&(r.lastUpdate=Math.floor(e)),t.subscriber===true&&(r.subscriber=true),Object.keys(r).length>0?r:void 0}function I(i){let t=i&&typeof i=="object"?i:{},r=String(t.accountId??"").trim(),e=String(t.siteId??"").trim(),o=t.subscriber===true,n=z(t.siteSettings),s={...n??{},...r?{accountId:n?.accountId??r}:{},...e?{siteId:n?.siteId??e}:{},...n?.subscriber===true||o?{subscriber:true}:{}},l={},a=String(t.apiBase??"").trim();a&&(l.apiBase=a);let u=String(t.runtimeToken??t.nonce??"").trim();u&&(l.runtimeToken=u);let c=String(t.uploadUrl??"").trim();c&&(l.uploadUrl=c),Object.keys(s).length>0&&(l.siteSettings=s);let g=k(t.subscriptionType);return g&&(l.subscriptionType=g),l}function Q(i){try{let t=new URL(i);globalThis.location=t;}catch{}}function F(i){return typeof i=="string"?i:i instanceof URL?i.toString():i.url}function G(i,t){let r=new Headers(i instanceof Request?i.headers:void 0);if(t?.headers)for(let[e,o]of new Headers(t.headers).entries())r.set(e,o);return r}async function x(i,t,r=5){let e=new URL(F(i)),o=String(t?.method??(i instanceof Request?i.method:"GET")).toUpperCase(),n=e.protocol==="http:"?W:_,s=G(i,t);return await new Promise((l,a)=>{let u=n.request(e,{method:o,headers:Object.fromEntries(s.entries()),...e.protocol==="https:"?{rejectUnauthorized:false}:{}},c=>{let g=[];c.on("data",p=>{g.push(Buffer.isBuffer(p)?p:Buffer.from(p));}),c.on("error",a),c.on("end",()=>{let p=c.statusCode??0,S=c.headers.location;if(r>0&&S&&[301,302,303,307,308].includes(p)){l(x(new URL(S,e),{method:p===303?"GET":o},r-1));return}let b=new Headers;for(let[m,w]of Object.entries(c.headers))Array.isArray(w)?b.set(m,w.join(", ")):typeof w=="string"&&b.set(m,w);l(new Response(Buffer.concat(g),{status:p,statusText:c.statusMessage??"",headers:b}));});});u.on("error",a),u.end();})}function Y(i){let t=I(i.wpsuite),r={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},e=String(r.accountId??"").trim(),o=String(r.siteId??"").trim(),n=String(t.uploadUrl??"").trim();if(i.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...n?{uploadUrl:n}:{},...Object.keys(r).length>0?{siteSettings:r}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!e||!o||!n)return false;Q(i.sourceOrigin);let s=globalThis,a={...s.WpSuite??{},siteSettings:r,uploadUrl:n};return t.apiBase&&(a.apiBase=t.apiBase),s.WpSuite=a,true}async function K(i){if(!Y(i))return null;let t=String(i.wpsuite?.uploadUrl??"").trim(),r=globalThis.fetch;try{i.ignoreHttpsErrors&&typeof r=="function"&&t.startsWith("https://")&&(globalThis.fetch=(async(n,s)=>F(n).startsWith(t)?x(n,s):r(n,s)));let{getConfig:e}=await import('@smart-cloud/wpsuite-core'),o=await e("publisher");return o&&typeof o=="object"?o:null}catch{return null}finally{typeof r=="function"&&(globalThis.fetch=r);}}function V(i,t){let r=J(t?.deploymentProfiles),e=String(t?.defaultDeploymentProfile??"").trim(),o=r[e]?e:"",n=k(t?.subscriptionType),s=I(i.wpsuite);return {...i,scheduler:E(t?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:o,...n?{subscriptionType:n}:{},wpsuite:{...s,...s.siteSettings||n?{siteSettings:{...s.siteSettings??{},...s.siteSettings?.subscriber===true||n==="PROFESSIONAL"||n==="AGENCY"?{subscriber:true}:{}}}:{},...n?{subscriptionType:n}:{}}}}function C(i,t){let e=String(i||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!e)return t;let o=e.split("/").map(n=>n.trim()).filter(n=>n.length>0&&n!=="."&&n!=="..");return o.length>0?o.join("/"):t}function Z(){let i=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return i.trim()?d.resolve(i):""}function T(i,t,r){let e=String(t||"").trim();return e&&d.isAbsolute(e)?d.resolve(e):d.resolve(i,C(e,r))}async function R(i){let t=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",r=await h.readFile(t,"utf8"),e=JSON.parse(r);e.sourceOrigin=e.sourceOrigin.replace(/\/$/,""),e.targetOrigin=D(e.targetOrigin),e.ignoreHttpsErrors??=false,e.outputDir=String(e.outputDir||"export").trim()||"export",e.urlRewriteMode||=e.targetOrigin==="."?"relative":"absolute",e.noJavaScriptRenderPathPrefixes||=[],e.seedPaths||=[],e.generated404RequestPath=B(e.generated404RequestPath),e.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],e.allowedAssetHosts||=[],e.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],e.blockedPathPrefixes||=[],e.blockedSearchFragments||=[],e.concurrency||=1,e.maxPages||=0,e.extraReplacements=v(e.extraReplacements),e.postCrawlCopyMap=v(e.postCrawlCopyMap),e.logDir=String(e.logDir||"logs").trim()||"logs",e.verbose??=false,e.logLevel||=e.verbose?"debug":"info",e.s3SyncMode||="sdk-upload-delete",e.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},e.readiness.timeoutMs??=1500,e.readiness.fallbackWaitMs??=1500,e.viewport||={width:1440,height:1200},e.navigationTimeoutMs||=3e4,e.assetDownloadConcurrency=Number(e.assetDownloadConcurrency)>0?Number(e.assetDownloadConcurrency):e.concurrency,e.rewriteConcurrency=Number(e.rewriteConcurrency)>0?Number(e.rewriteConcurrency):e.assetDownloadConcurrency,e.wpsuite=I(e.wpsuite),e.scheduler=E(void 0),e.deploymentProfiles={},e.defaultDeploymentProfile="",e.deploymentTargetOverride=String(e.deploymentTargetOverride??"").trim();let o=V(e,await K(e)),n=Z(),s=n?d.resolve(n,".."):"";return s?(o.outputDir=T(s,o.outputDir,"export"),o.logDir=T(s,o.logDir,"logs")):(d.isAbsolute(o.outputDir)||(o.outputDir=C(o.outputDir,"export")),d.isAbsolute(o.logDir)||(o.logDir=C(o.logDir,"logs"))),o}function X(i){return typeof i.subscriptionType=="string"&&i.subscriptionType.trim()!==""}function O(i){let t="";for(let e=0;e<i.length;e++){let o=i[e];if(o==="--profile"){let n=(i[e+1]||"").trim();if(!n)throw new Error("Missing value for --profile.");t=n,e+=1;}else if(o.startsWith("--profile=")){let n=o.slice(10).trim();if(!n)throw new Error("Missing value for --profile.");t=n;}}let r=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return t||r||null}function ee(i,t){return {...i,...t??{}}}function te(i,t){return {...i,...t??{},invalidationPaths:[...(t?.invalidationPaths??i.invalidationPaths)||[]]}}function j(i,t){let r=String(t??i.deploymentTargetOverride??"").trim();if(!X(i)){if(r)throw new Error(`Deployment target "${r}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:i}}let e=String(r||i.defaultDeploymentProfile||"").trim();if(!e)return {name:null,profile:null,config:i};let o=i.deploymentProfiles?.[e];if(!o)throw new Error(`Unknown deployment profile "${e}". Check the linked WPSuite publisher configuration.`);return {name:e,profile:o,config:{...i,targetOrigin:o.targetOrigin??i.targetOrigin,s3:ee(i.s3,o.s3),cloudFront:te(i.cloudFront,o.cloudFront)}}}var M={error:0,warn:1,info:2,debug:3},A=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",y=A?d.join(A,"current-progress.json"):"",U=Promise.resolve();function $(i){return i.includes("crawl")?"crawl":i.includes("deploy")?"deploy":i.includes("invalidate")?"invalidate":i}function ie(i,t){let r={...i},e=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","pageQueue","assetQueue","sitemapQueue"]);for(let[o,n]of Object.entries(t)){let s=r[o];if(typeof s=="number"&&typeof n=="number"&&e.has(o)){r[o]=Math.max(s,n);continue}r[o]=n;}return r}function re(i,t,r){y&&(U=U.then(async()=>{let e=new Date,o=e.toISOString();await h.mkdir(d.dirname(y),{recursive:true});let n=await h.readFile(y,"utf8").then(m=>JSON.parse(m)).catch(()=>null),s=n&&typeof n.details=="object"&&n.details?n.details:{},l=$(i),a=n?.currentStep||$(n?.source||""),u=n?.startedAt||o,c={...n?.stepDurationsSec??{}},g=n?.stepStartedAt||o;if(a&&a!==l&&n?.stepStartedAt){let m=Math.max(0,Math.round((e.getTime()-new Date(n.stepStartedAt).getTime())/1e3));c[a]=(c[a]??0)+m,g=o;}let p=Math.max(0,Math.round((e.getTime()-new Date(g).getTime())/1e3)),S=Math.max(0,Math.round((e.getTime()-new Date(u).getTime())/1e3)),b={checkedAt:o,source:i,message:t,details:ie(s,r??{}),startedAt:u,currentStep:l,stepStartedAt:g,stepElapsedSec:p,totalElapsedSec:S,stepDurationsSec:c};await h.writeFile(y,JSON.stringify(b,null,2),"utf8");}).catch(()=>{}));}async function ne(i,t){await h.mkdir(d.dirname(i),{recursive:true}),await h.appendFile(i,`${JSON.stringify(t)}
2
- `,"utf8");}var P=class{constructor(t,r,e="info"){this.logDir=t;this.logFile=r;this.level=e;this.ensureLogFileReady();}logDir;logFile;level;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;get logPath(){return d.join(this.logDir,this.logFile)}artifactPath(t){return this.logFile.endsWith(".log.jsonl")?d.join(this.logDir,this.logFile.replace(/\.log\.jsonl$/u,`${t}.jsonl`)):d.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 h.mkdir(this.logDir,{recursive:true}),await h.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(t){this.writeQueue=this.writeQueue.then(t).catch(r=>{this.writeError=r instanceof Error?r:new Error(String(r));});}enqueueLine(t){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await h.appendFile(this.logPath,`${t}
3
- `,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>ne(t,r));}accepts(t){return M[t]<=M[this.level]}push(t,r,e){if(!this.accepts(t))return;let o=JSON.stringify({time:new Date().toISOString(),level:t,message:r,...e||{}});this.enqueueLine(o),t==="error"?console.error(`[ERROR] ${r}`,e?JSON.stringify(e):""):t==="warn"?console.warn(`[WARN] ${r}`,e?JSON.stringify(e):""):console.log(`[${t.toUpperCase().padEnd(5)}] ${r}`);}info(t,r){this.push("info",t,r);}progress(t,r){re(this.logFile,t,r);}debug(t,r){this.push("debug",t,r);}warn(t,r){this.push("warn",t,r);}reject(t,r,e,o,n){let s={kind:t,url:r,reason:e,...o?{source:o}:{},...n||{}};this.enqueueJsonLine(this.rejectedPath,s),this.accepts("debug")&&this.push("debug",`Rejected ${t} ${r}: ${e}`,s);}error(t,r){this.enqueueJsonLine(this.errorsPath,{message:t,...r||{}}),this.push("error",t,r);}mark(t){this.marks.set(t,Date.now());}endMark(t,r){let e=this.marks.get(t);if(!e)return;let o=Date.now()-e,n=Number((o/1e3).toFixed(2));this.push("info",`Timing ${t}: ${n}s`,{name:t,ms:o,seconds:n,...r||{}});}async flush(){let t=Date.now()-this.startedAt,r=Number((t/1e3).toFixed(2));if(this.push("info",`Total time: ${r}s`,{name:"total",ms:t,seconds:r}),await this.writeQueue,this.writeError)throw this.writeError}};async function ue(){let i=await R(),t=O(process.argv.slice(2)),r=j(i,t),e=r.config,o=e.logDir||"logs",n=new P(o,"invalidate.log.jsonl",e.logLevel??"info");if(r.name&&n.info(`Using deployment profile: ${r.name}`),!e.cloudFront.distributionId){n.info("No CloudFront distributionId configured; skipping invalidation."),await n.flush();return}let s=e.cloudFront.invalidationPaths.length>0?e.cloudFront.invalidationPaths:["/*"];n.info(`Starting CloudFront invalidation for distribution ${e.cloudFront.distributionId}`),n.info(`Invalidation paths (${s.length}): ${s.join(", ")}`),n.mark("invalidate"),n.progress("CloudFront invalidation request queued.",{phase:"invalidate",distributionId:e.cloudFront.distributionId,pathCount:s.length});let l=new CloudFrontClient({region:"us-east-1"}),a=`smartcloud-static-publisher-${Date.now()}`;n.debug(`CallerReference: ${a}`);let u=await L(`CloudFront invalidation for distribution ${e.cloudFront.distributionId}`,3e5,({httpOptions:p})=>l.send(new CreateInvalidationCommand({DistributionId:e.cloudFront.distributionId,InvalidationBatch:{CallerReference:a,Paths:{Quantity:s.length,Items:s}}}),p)),c=u.Invalidation?.Id??"(unknown)",g=u.Invalidation?.Status??"(unknown)";n.info(`CloudFront invalidation created. ID: ${c} Status: ${g}`),n.debug(`Full invalidation response: ${JSON.stringify(u.Invalidation)}`),n.endMark("invalidate"),await n.flush();}ue().catch(async i=>{console.error(i);try{let r=(await R().catch(()=>null))?.logDir??"logs",e=new P(r,"invalidate.log.jsonl","debug");e.error(`Unhandled error: ${i instanceof Error?i.message:String(i)}`,i instanceof Error?{stack:i.stack}:void 0),await e.flush();}catch{}process.exit(1);});
1
+ import {CloudFrontClient,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';import h from'fs/promises';import W from'http';import _ from'https';import d from'path';function q(i){let e=i/6e4;if(Number.isInteger(e)&&e>=1)return `${e} minute${"s"}`;let r=Math.ceil(i/1e3);return `${r} second${r===1?"":"s"}`}async function L(i,e,r){let n=new AbortController,t=globalThis.setTimeout(()=>{n.abort(new Error(`${i} timed out after ${q(e)}.`));},e);try{return await r({abortController:n,httpOptions:{abortSignal:n.signal,requestTimeout:e}})}finally{globalThis.clearTimeout(t);}}function k(i){let e=i.trim();return e==="."?".":e.replace(/\/$/,"")}function B(i){let e=String(i??"").trim();if(!e)return "";let r=e;if(/^https?:\/\//i.test(r))try{r=new URL(r).pathname;}catch{return ""}if(r=r.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!r)return "";let n=r.endsWith("/"),t=r.replace(/^\/+/,"").split("/").map(o=>o.replace(/[^A-Za-z0-9._-]/g,"")).filter(o=>o.length>0&&o!=="."&&o!=="..");if(t.length===0)return "";let s=`/${t.join("/")}`;return n&&d.extname(s)===""&&(s+="/"),s==="/"?"":s}function w(i){return !i||typeof i!="object"?{}:Object.fromEntries(Object.entries(i).map(([e,r])=>[e.trim(),String(r??"")]).filter(([e])=>e.length>0))}function J(i){if(!i||typeof i!="object")return {};let e={};for(let[r,n]of Object.entries(i)){let t=r.trim();if(!t||!n||typeof n!="object")continue;let s=n,o={};if(typeof s.targetOrigin=="string"){let a=k(s.targetOrigin);a&&(o.targetOrigin=a);}let l=w(s.extraReplacements);if(Object.keys(l).length>0&&(o.extraReplacements=l),s.s3&&typeof s.s3=="object"){let a={},u=s.s3;typeof u.bucket=="string"&&(a.bucket=u.bucket.trim()),typeof u.prefix=="string"&&(a.prefix=u.prefix.trim()),typeof u.region=="string"&&(a.region=u.region.trim()),typeof u.htmlCacheControl=="string"&&(a.htmlCacheControl=u.htmlCacheControl.trim()),typeof u.assetCacheControl=="string"&&(a.assetCacheControl=u.assetCacheControl.trim()),Object.keys(a).length>0&&(o.s3=a);}if(s.cloudFront&&typeof s.cloudFront=="object"){let a={},u=s.cloudFront;typeof u.distributionId=="string"&&(a.distributionId=u.distributionId.trim()),Array.isArray(u.invalidationPaths)&&(a.invalidationPaths=u.invalidationPaths.map(c=>String(c??"").trim()).filter(c=>c.length>0)),Object.keys(a).length>0&&(o.cloudFront=a);}e[t]=o;}return e}function I(i){return i==="PROFESSIONAL"||i==="AGENCY"?i:void 0}function H(i,e){if(!i||typeof i!="object")return null;let r=i,n=r.command;if(n!=="publish"&&n!=="crawl"&&n!=="deploy"&&n!=="invalidate"&&n!=="retry-timeouts"&&n!=="url")return null;let t=Number.parseInt(String(r.intervalMinutes??"0"),10);if(!Number.isFinite(t)||t<1)return null;let s=String(r.id??`${n}-${e+1}`).trim();if(!s)return null;let o=String(r.deploymentProfile??"").trim(),l=String(r.url??"").trim();return {id:s,enabled:r.enabled!==false,command:n,intervalMinutes:t,...n==="publish"||n==="crawl"?{crawlMode:r.crawlMode==="incremental"?"incremental":"full"}:{},...(n==="publish"||n==="deploy"||n==="invalidate")&&o?{deploymentProfile:o}:{},...l?{url:l}:{}}}function E(i){let e=i&&typeof i=="object"?i:{},r=Array.isArray(e.rules)?e.rules.map((n,t)=>H(n,t)).filter(n=>!!n):[];return {enabled:e.enabled===true,timezone:typeof e.timezone=="string"&&e.timezone.trim()!==""?e.timezone.trim():"UTC",rules:r}}function z(i){if(!i||typeof i!="object")return;let e=i,r={};for(let t of ["accountId","siteId"]){let s=e[t];typeof s=="string"&&s.trim()!==""&&(r[t]=s.trim());}let n=Number(e.lastUpdate??0);return Number.isFinite(n)&&n>0&&(r.lastUpdate=Math.floor(n)),e.subscriber===true&&(r.subscriber=true),Object.keys(r).length>0?r:void 0}function R(i){let e=i&&typeof i=="object"?i:{},r=String(e.accountId??"").trim(),n=String(e.siteId??"").trim(),t=e.subscriber===true,s=z(e.siteSettings),o={...s??{},...r?{accountId:s?.accountId??r}:{},...n?{siteId:s?.siteId??n}:{},...s?.subscriber===true||t?{subscriber:true}:{}},l={},a=String(e.apiBase??"").trim();a&&(l.apiBase=a);let u=String(e.runtimeToken??e.nonce??"").trim();u&&(l.runtimeToken=u);let c=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();c&&(l.virtualAssetBaseUrl=c),Object.keys(o).length>0&&(l.siteSettings=o);let p=I(e.subscriptionType);return p&&(l.subscriptionType=p),l}function Q(i){try{let e=new URL(i);globalThis.location=e;}catch{}}function F(i){return typeof i=="string"?i:i instanceof URL?i.toString():i.url}function G(i,e){let r=new Headers(i instanceof Request?i.headers:void 0);if(e?.headers)for(let[n,t]of new Headers(e.headers).entries())r.set(n,t);return r}async function x(i,e,r=5){let n=new URL(F(i)),t=String(e?.method??(i instanceof Request?i.method:"GET")).toUpperCase(),s=n.protocol==="http:"?W:_,o=G(i,e);return await new Promise((l,a)=>{let u=s.request(n,{method:t,headers:Object.fromEntries(o.entries()),...n.protocol==="https:"?{rejectUnauthorized:false}:{}},c=>{let p=[];c.on("data",g=>{p.push(Buffer.isBuffer(g)?g:Buffer.from(g));}),c.on("error",a),c.on("end",()=>{let g=c.statusCode??0,S=c.headers.location;if(r>0&&S&&[301,302,303,307,308].includes(g)){l(x(new URL(S,n),{method:g===303?"GET":t},r-1));return}let b=new Headers;for(let[m,v]of Object.entries(c.headers))Array.isArray(v)?b.set(m,v.join(", ")):typeof v=="string"&&b.set(m,v);l(new Response(Buffer.concat(p),{status:g,statusText:c.statusMessage??"",headers:b}));});});u.on("error",a),u.end();})}function Y(i){let e=R(i.wpsuite),r={...e.siteSettings??{},...e.siteSettings?.subscriber===true||e.subscriptionType==="PROFESSIONAL"||e.subscriptionType==="AGENCY"?{subscriber:true}:{}},n=String(r.accountId??"").trim(),t=String(r.siteId??"").trim(),s=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();if(i.wpsuite={...e.apiBase?{apiBase:e.apiBase}:{},...e.runtimeToken?{runtimeToken:e.runtimeToken}:{},...s?{virtualAssetBaseUrl:s}:{},...Object.keys(r).length>0?{siteSettings:r}:{},...e.subscriptionType?{subscriptionType:e.subscriptionType}:{}},!n||!t||!s)return false;Q(i.sourceOrigin);let o=globalThis,a={...o.WpSuite??{},siteSettings:r,uploadUrl:s};return e.apiBase&&(a.apiBase=e.apiBase),o.WpSuite=a,true}async function K(i){let e=String(i.wpsuite?.virtualAssetBaseUrl??i.wpsuite?.uploadUrl??"").trim();if(!Y(i)){let t=i.wpsuite?.siteSettings,s=[String(t?.accountId??"").trim()?"":"accountId",String(t?.siteId??"").trim()?"":"siteId",e?"":"virtualAssetBaseUrl"].filter(Boolean);return {remote:null,diagnostic:{status:"invalid-runtime",virtualAssetBaseUrl:e,subscriptionType:null,error:`Missing WP Suite runtime field(s): ${s.join(", ")}.`,requests:[]}}}let r=globalThis.fetch,n=[];try{typeof r=="function"&&/^https?:\/\//i.test(e)&&(globalThis.fetch=(async(a,u)=>{let c=F(a);if(c.startsWith(e)){let p=(()=>{try{return new URL(c).pathname}catch{return c}})();try{let g=i.ignoreHttpsErrors&&c.startsWith("https://")?await x(a,u):await r(a,u);return n.push({path:p,status:g.status,ok:g.ok,error:null}),g}catch(g){throw n.push({path:p,status:null,ok:!1,error:g instanceof Error?g.message:String(g)}),g}}return r(a,u)}));let{getConfig:t}=await import('@smart-cloud/wpsuite-core'),s=await t("publisher"),o=s&&typeof s=="object"?s:null,l=I(o?.subscriptionType);return {remote:o,diagnostic:{status:o?"loaded":"unavailable",virtualAssetBaseUrl:e,subscriptionType:l??null,error:o?null:"WP Suite publisher config loader returned no configuration.",requests:n}}}catch(t){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:e,subscriptionType:null,error:t instanceof Error?t.message:String(t),requests:n}}}finally{typeof r=="function"&&(globalThis.fetch=r);}}function V(i,e){let r=J(e?.deploymentProfiles),n=String(e?.defaultDeploymentProfile??"").trim(),t=r[n]?n:"",s=I(e?.subscriptionType),o=R(i.wpsuite);return {...i,scheduler:E(e?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:t,...s?{subscriptionType:s}:{},wpsuite:{...o,...o.siteSettings||s?{siteSettings:{...o.siteSettings??{},...o.siteSettings?.subscriber===true||s==="PROFESSIONAL"||s==="AGENCY"?{subscriber:true}:{}}}:{},...s?{subscriptionType:s}:{}}}}function C(i,e){let n=String(i||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!n)return e;let t=n.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return t.length>0?t.join("/"):e}function Z(){let i=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return i.trim()?d.resolve(i):""}function D(i,e,r){let n=String(e||"").trim();return n&&d.isAbsolute(n)?d.resolve(n):d.resolve(i,C(n,r))}async function T(i,e={}){let r=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",n=await h.readFile(r,"utf8"),t=JSON.parse(n);t.sourceOrigin=t.sourceOrigin.replace(/\/$/,""),t.targetOrigin=k(t.targetOrigin),t.ignoreHttpsErrors??=false,t.outputDir=String(t.outputDir||"export").trim()||"export",t.urlRewriteMode||=t.targetOrigin==="."?"relative":"absolute",t.noJavaScriptRenderPathPrefixes||=[],t.seedPaths||=[],t.generated404RequestPath=B(t.generated404RequestPath),t.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],t.allowedAssetHosts||=[],t.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],t.blockedPathPrefixes||=[],t.blockedSearchFragments||=[],t.concurrency||=1,t.maxPages||=0,t.extraReplacements=w(t.extraReplacements),t.postCrawlCopyMap=w(t.postCrawlCopyMap),t.logDir=String(t.logDir||"logs").trim()||"logs",t.verbose??=false,t.logLevel||=t.verbose?"debug":"info",t.s3SyncMode||="sdk-upload-delete",t.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},t.readiness.timeoutMs??=1500,t.readiness.fallbackWaitMs??=1500,t.viewport||={width:1440,height:1200},t.navigationTimeoutMs||=3e4,t.assetDownloadConcurrency=Number(t.assetDownloadConcurrency)>0?Number(t.assetDownloadConcurrency):t.concurrency,t.rewriteConcurrency=Number(t.rewriteConcurrency)>0?Number(t.rewriteConcurrency):t.assetDownloadConcurrency,t.wpsuite=R(t.wpsuite),t.scheduler=E(void 0),t.deploymentProfiles={},t.defaultDeploymentProfile="",t.deploymentTargetOverride=String(t.deploymentTargetOverride??"").trim();let s=await K(t);e.onRemotePublisherConfigDiagnostic?.(s.diagnostic);let o=V(t,s.remote),l=Z(),a=l?d.resolve(l,".."):"";return a?(o.outputDir=D(a,o.outputDir,"export"),o.logDir=D(a,o.logDir,"logs")):(d.isAbsolute(o.outputDir)||(o.outputDir=C(o.outputDir,"export")),d.isAbsolute(o.logDir)||(o.logDir=C(o.logDir,"logs"))),o}function X(i){return typeof i.subscriptionType=="string"&&i.subscriptionType.trim()!==""}function O(i){let e="";for(let n=0;n<i.length;n++){let t=i[n];if(t==="--profile"){let s=(i[n+1]||"").trim();if(!s)throw new Error("Missing value for --profile.");e=s,n+=1;}else if(t.startsWith("--profile=")){let s=t.slice(10).trim();if(!s)throw new Error("Missing value for --profile.");e=s;}}let r=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return e||r||null}function ee(i,e){return {...i,...e??{}}}function te(i,e){return {...i,...e??{},invalidationPaths:[...(e?.invalidationPaths??i.invalidationPaths)||[]]}}function A(i,e){let r=String(e??i.deploymentTargetOverride??"").trim();if(!X(i)){if(r)throw new Error(`Deployment target "${r}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:i}}let n=String(r||i.defaultDeploymentProfile||"").trim();if(!n)return {name:null,profile:null,config:i};let t=i.deploymentProfiles?.[n];if(!t)throw new Error(`Unknown deployment profile "${n}". Check the linked WPSuite publisher configuration.`);return {name:n,profile:t,config:{...i,targetOrigin:t.targetOrigin??i.targetOrigin,s3:ee(i.s3,t.s3),cloudFront:te(i.cloudFront,t.cloudFront)}}}var j={error:0,warn:1,info:2,debug:3},M=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",y=M?d.join(M,"current-progress.json"):"",U=Promise.resolve();function $(i){return i.includes("crawl")?"crawl":i.includes("deploy")?"deploy":i.includes("invalidate")?"invalidate":i}function ie(i,e){let r={...i},n=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","pageQueue","assetQueue","sitemapQueue"]);for(let[t,s]of Object.entries(e)){let o=r[t];if(typeof o=="number"&&typeof s=="number"&&n.has(t)){r[t]=Math.max(o,s);continue}r[t]=s;}return r}function re(i,e,r){y&&(U=U.then(async()=>{let n=new Date,t=n.toISOString();await h.mkdir(d.dirname(y),{recursive:true});let s=await h.readFile(y,"utf8").then(m=>JSON.parse(m)).catch(()=>null),o=s&&typeof s.details=="object"&&s.details?s.details:{},l=$(i),a=s?.currentStep||$(s?.source||""),u=s?.startedAt||t,c={...s?.stepDurationsSec??{}},p=s?.stepStartedAt||t;if(a&&a!==l&&s?.stepStartedAt){let m=Math.max(0,Math.round((n.getTime()-new Date(s.stepStartedAt).getTime())/1e3));c[a]=(c[a]??0)+m,p=t;}let g=Math.max(0,Math.round((n.getTime()-new Date(p).getTime())/1e3)),S=Math.max(0,Math.round((n.getTime()-new Date(u).getTime())/1e3)),b={checkedAt:t,source:i,message:e,details:ie(o,r??{}),startedAt:u,currentStep:l,stepStartedAt:p,stepElapsedSec:g,totalElapsedSec:S,stepDurationsSec:c};await h.writeFile(y,JSON.stringify(b,null,2),"utf8");}).catch(()=>{}));}async function ne(i,e){await h.mkdir(d.dirname(i),{recursive:true}),await h.appendFile(i,`${JSON.stringify(e)}
2
+ `,"utf8");}var P=class{constructor(e,r,n="info"){this.logDir=e;this.logFile=r;this.level=n;this.ensureLogFileReady();}logDir;logFile;level;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;get logPath(){return d.join(this.logDir,this.logFile)}artifactPath(e){return this.logFile.endsWith(".log.jsonl")?d.join(this.logDir,this.logFile.replace(/\.log\.jsonl$/u,`${e}.jsonl`)):d.join(this.logDir,`${this.logFile}${e}.jsonl`)}get errorsPath(){return this.artifactPath(".errors")}get rejectedPath(){return this.artifactPath(".rejected")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await h.mkdir(this.logDir,{recursive:true}),await h.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(e){this.writeQueue=this.writeQueue.then(e).catch(r=>{this.writeError=r instanceof Error?r:new Error(String(r));});}enqueueLine(e){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await h.appendFile(this.logPath,`${e}
3
+ `,"utf8");});}enqueueJsonLine(e,r){this.enqueueTask(()=>ne(e,r));}accepts(e){return j[e]<=j[this.level]}push(e,r,n){if(!this.accepts(e))return;let t=JSON.stringify({time:new Date().toISOString(),level:e,message:r,...n||{}});this.enqueueLine(t),e==="error"?console.error(`[ERROR] ${r}`,n?JSON.stringify(n):""):e==="warn"?console.warn(`[WARN] ${r}`,n?JSON.stringify(n):""):console.log(`[${e.toUpperCase().padEnd(5)}] ${r}`);}info(e,r){this.push("info",e,r);}progress(e,r){re(this.logFile,e,r);}debug(e,r){this.push("debug",e,r);}warn(e,r){this.push("warn",e,r);}reject(e,r,n,t,s){let o={kind:e,url:r,reason:n,...t?{source:t}:{},...s||{}};this.enqueueJsonLine(this.rejectedPath,o),this.accepts("debug")&&this.push("debug",`Rejected ${e} ${r}: ${n}`,o);}error(e,r){this.enqueueJsonLine(this.errorsPath,{message:e,...r||{}}),this.push("error",e,r);}mark(e){this.marks.set(e,Date.now());}endMark(e,r){let n=this.marks.get(e);if(!n)return;let t=Date.now()-n,s=Number((t/1e3).toFixed(2));this.push("info",`Timing ${e}: ${s}s`,{name:e,ms:t,seconds:s,...r||{}});}async flush(){let e=Date.now()-this.startedAt,r=Number((e/1e3).toFixed(2));if(this.push("info",`Total time: ${r}s`,{name:"total",ms:e,seconds:r}),await this.writeQueue,this.writeError)throw this.writeError}};async function ue(){let i=await T(),e=O(process.argv.slice(2)),r=A(i,e),n=r.config,t=n.logDir||"logs",s=new P(t,"invalidate.log.jsonl",n.logLevel??"info");if(r.name&&s.info(`Using deployment profile: ${r.name}`),!n.cloudFront.distributionId){s.info("No CloudFront distributionId configured; skipping invalidation."),await s.flush();return}let o=n.cloudFront.invalidationPaths.length>0?n.cloudFront.invalidationPaths:["/*"];s.info(`Starting CloudFront invalidation for distribution ${n.cloudFront.distributionId}`),s.info(`Invalidation paths (${o.length}): ${o.join(", ")}`),s.mark("invalidate"),s.progress("CloudFront invalidation request queued.",{phase:"invalidate",distributionId:n.cloudFront.distributionId,pathCount:o.length});let l=new CloudFrontClient({region:"us-east-1"}),a=`smartcloud-static-publisher-${Date.now()}`;s.debug(`CallerReference: ${a}`);let u=await L(`CloudFront invalidation for distribution ${n.cloudFront.distributionId}`,3e5,({httpOptions:g})=>l.send(new CreateInvalidationCommand({DistributionId:n.cloudFront.distributionId,InvalidationBatch:{CallerReference:a,Paths:{Quantity:o.length,Items:o}}}),g)),c=u.Invalidation?.Id??"(unknown)",p=u.Invalidation?.Status??"(unknown)";s.info(`CloudFront invalidation created. ID: ${c} Status: ${p}`),s.debug(`Full invalidation response: ${JSON.stringify(u.Invalidation)}`),s.endMark("invalidate"),await s.flush();}ue().catch(async i=>{console.error(i);try{let r=(await T().catch(()=>null))?.logDir??"logs",n=new P(r,"invalidate.log.jsonl","debug");n.error(`Unhandled error: ${i instanceof Error?i.message:String(i)}`,i instanceof Error?{stack:i.stack}:void 0),await n.flush();}catch{}process.exit(1);});
@@ -1,2 +1,2 @@
1
- import {pathToFileURL}from'url';import f from'fs/promises';import {existsSync,createReadStream,createWriteStream}from'fs';import p from'path';import {spawn}from'child_process';import {randomUUID}from'crypto';import {pipeline}from'stream/promises';import {createGzip}from'zlib';import ne from'http';import ie from'https';function U(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function oe(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("/"),o=n.replace(/^\/+/,"").split("/").map(i=>i.replace(/[^A-Za-z0-9._-]/g,"")).filter(i=>i.length>0&&i!=="."&&i!=="..");if(o.length===0)return "";let s=`/${o.join("/")}`;return r&&p.extname(s)===""&&(s+="/"),s==="/"?"":s}function x(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t.trim(),String(n??"")]).filter(([t])=>t.length>0))}function se(e){if(!e||typeof e!="object")return {};let t={};for(let[n,r]of Object.entries(e)){let o=n.trim();if(!o||!r||typeof r!="object")continue;let s=r,i={};if(typeof s.targetOrigin=="string"){let a=U(s.targetOrigin);a&&(i.targetOrigin=a);}let u=x(s.extraReplacements);if(Object.keys(u).length>0&&(i.extraReplacements=u),s.s3&&typeof s.s3=="object"){let a={},c=s.s3;typeof c.bucket=="string"&&(a.bucket=c.bucket.trim()),typeof c.prefix=="string"&&(a.prefix=c.prefix.trim()),typeof c.region=="string"&&(a.region=c.region.trim()),typeof c.htmlCacheControl=="string"&&(a.htmlCacheControl=c.htmlCacheControl.trim()),typeof c.assetCacheControl=="string"&&(a.assetCacheControl=c.assetCacheControl.trim()),Object.keys(a).length>0&&(i.s3=a);}if(s.cloudFront&&typeof s.cloudFront=="object"){let a={},c=s.cloudFront;typeof c.distributionId=="string"&&(a.distributionId=c.distributionId.trim()),Array.isArray(c.invalidationPaths)&&(a.invalidationPaths=c.invalidationPaths.map(g=>String(g??"").trim()).filter(g=>g.length>0)),Object.keys(a).length>0&&(i.cloudFront=a);}t[o]=i;}return t}function W(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function ue(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")return null;let o=Number.parseInt(String(n.intervalMinutes??"0"),10);if(!Number.isFinite(o)||o<1)return null;let s=String(n.id??`${r}-${t+1}`).trim();if(!s)return null;let i=String(n.deploymentProfile??"").trim(),u=String(n.url??"").trim();return {id:s,enabled:n.enabled!==false,command:r,intervalMinutes:o,...r==="publish"||r==="crawl"?{crawlMode:n.crawlMode==="incremental"?"incremental":"full"}:{},...(r==="publish"||r==="deploy"||r==="invalidate")&&i?{deploymentProfile:i}:{},...u?{url:u}:{}}}function B(e){let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.rules)?t.rules.map((r,o)=>ue(r,o)).filter(r=>!!r):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:n}}function ae(e){if(!e||typeof e!="object")return;let t=e,n={};for(let o of ["accountId","siteId"]){let s=t[o];typeof s=="string"&&s.trim()!==""&&(n[o]=s.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 T(e){let t=e&&typeof e=="object"?e:{},n=String(t.accountId??"").trim(),r=String(t.siteId??"").trim(),o=t.subscriber===true,s=ae(t.siteSettings),i={...s??{},...n?{accountId:s?.accountId??n}:{},...r?{siteId:s?.siteId??r}:{},...s?.subscriber===true||o?{subscriber:true}:{}},u={},a=String(t.apiBase??"").trim();a&&(u.apiBase=a);let c=String(t.runtimeToken??t.nonce??"").trim();c&&(u.runtimeToken=c);let g=String(t.uploadUrl??"").trim();g&&(u.uploadUrl=g),Object.keys(i).length>0&&(u.siteSettings=i);let d=W(t.subscriptionType);return d&&(u.subscriptionType=d),u}function ce(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Q(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function le(e,t){let n=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[r,o]of new Headers(t.headers).entries())n.set(r,o);return n}async function z(e,t,n=5){let r=new URL(Q(e)),o=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),s=r.protocol==="http:"?ne:ie,i=le(e,t);return await new Promise((u,a)=>{let c=s.request(r,{method:o,headers:Object.fromEntries(i.entries()),...r.protocol==="https:"?{rejectUnauthorized:false}:{}},g=>{let d=[];g.on("data",l=>{d.push(Buffer.isBuffer(l)?l:Buffer.from(l));}),g.on("error",a),g.on("end",()=>{let l=g.statusCode??0,m=g.headers.location;if(n>0&&m&&[301,302,303,307,308].includes(l)){u(z(new URL(m,r),{method:l===303?"GET":o},n-1));return}let h=new Headers;for(let[P,y]of Object.entries(g.headers))Array.isArray(y)?h.set(P,y.join(", ")):typeof y=="string"&&h.set(P,y);u(new Response(Buffer.concat(d),{status:l,statusText:g.statusMessage??"",headers:h}));});});c.on("error",a),c.end();})}function de(e){let t=T(e.wpsuite),n={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},r=String(n.accountId??"").trim(),o=String(n.siteId??"").trim(),s=String(t.uploadUrl??"").trim();if(e.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...s?{uploadUrl:s}:{},...Object.keys(n).length>0?{siteSettings:n}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!r||!o||!s)return false;ce(e.sourceOrigin);let i=globalThis,a={...i.WpSuite??{},siteSettings:n,uploadUrl:s};return t.apiBase&&(a.apiBase=t.apiBase),i.WpSuite=a,true}async function pe(e){if(!de(e))return null;let t=String(e.wpsuite?.uploadUrl??"").trim(),n=globalThis.fetch;try{e.ignoreHttpsErrors&&typeof n=="function"&&t.startsWith("https://")&&(globalThis.fetch=(async(s,i)=>Q(s).startsWith(t)?z(s,i):n(s,i)));let{getConfig:r}=await import('@smart-cloud/wpsuite-core'),o=await r("publisher");return o&&typeof o=="object"?o:null}catch{return null}finally{typeof n=="function"&&(globalThis.fetch=n);}}function ge(e,t){let n=se(t?.deploymentProfiles),r=String(t?.defaultDeploymentProfile??"").trim(),o=n[r]?r:"",s=W(t?.subscriptionType),i=T(e.wpsuite);return {...e,scheduler:B(t?.scheduler),deploymentProfiles:n,defaultDeploymentProfile:o,...s?{subscriptionType:s}:{},wpsuite:{...i,...i.siteSettings||s?{siteSettings:{...i.siteSettings??{},...i.siteSettings?.subscriber===true||s==="PROFESSIONAL"||s==="AGENCY"?{subscriber:true}:{}}}:{},...s?{subscriptionType:s}:{}}}}function J(e,t){let r=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!r)return t;let o=r.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return o.length>0?o.join("/"):t}function me(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?p.resolve(e):""}function L(e,t,n){let r=String(t||"").trim();return r&&p.isAbsolute(r)?p.resolve(r):p.resolve(e,J(r,n))}async function k(e){let t=String(e??"").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",n=await f.readFile(t,"utf8"),r=JSON.parse(n);r.sourceOrigin=r.sourceOrigin.replace(/\/$/,""),r.targetOrigin=U(r.targetOrigin),r.ignoreHttpsErrors??=false,r.outputDir=String(r.outputDir||"export").trim()||"export",r.urlRewriteMode||=r.targetOrigin==="."?"relative":"absolute",r.noJavaScriptRenderPathPrefixes||=[],r.seedPaths||=[],r.generated404RequestPath=oe(r.generated404RequestPath),r.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],r.allowedAssetHosts||=[],r.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],r.blockedPathPrefixes||=[],r.blockedSearchFragments||=[],r.concurrency||=1,r.maxPages||=0,r.extraReplacements=x(r.extraReplacements),r.postCrawlCopyMap=x(r.postCrawlCopyMap),r.logDir=String(r.logDir||"logs").trim()||"logs",r.verbose??=false,r.logLevel||=r.verbose?"debug":"info",r.s3SyncMode||="sdk-upload-delete",r.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},r.readiness.timeoutMs??=1500,r.readiness.fallbackWaitMs??=1500,r.viewport||={width:1440,height:1200},r.navigationTimeoutMs||=3e4,r.assetDownloadConcurrency=Number(r.assetDownloadConcurrency)>0?Number(r.assetDownloadConcurrency):r.concurrency,r.rewriteConcurrency=Number(r.rewriteConcurrency)>0?Number(r.rewriteConcurrency):r.assetDownloadConcurrency,r.wpsuite=T(r.wpsuite),r.scheduler=B(void 0),r.deploymentProfiles={},r.defaultDeploymentProfile="",r.deploymentTargetOverride=String(r.deploymentTargetOverride??"").trim();let o=ge(r,await pe(r)),s=me(),i=s?p.resolve(s,".."):"";return i?(o.outputDir=L(i,o.outputDir,"export"),o.logDir=L(i,o.logDir,"logs")):(p.isAbsolute(o.outputDir)||(o.outputDir=J(o.outputDir,"export")),p.isAbsolute(o.logDir)||(o.logDir=J(o.logDir,"logs"))),o}var I=class extends Error{request;step;constructor(t,n){super(`Stop requested during ${n}.`),this.name="StopRequestedError",this.request=t,this.step=n;}},Pe="queue-mutation.lock",ve=5e3,Ce=3e4;function Re(e){let t=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",n=process.env.STATIC_PUBLISHER_EXPORTER_DIR||process.cwd(),r=process.env.PUBLISHER_CONFIG||"",o=1;for(let u=0;u<e.length;u++){let a=e[u];a==="--runtime-dir"?t=e[++u]||"":a.startsWith("--runtime-dir=")?t=a.slice(14):a==="--exporter-dir"?n=e[++u]||n:a.startsWith("--exporter-dir=")?n=a.slice(15):a==="--config"?r=e[++u]||"":a.startsWith("--config=")?r=a.slice(9):a==="--max-jobs"?o=Number.parseInt(e[++u]||"1",10):a.startsWith("--max-jobs=")&&(o=Number.parseInt(a.slice(11),10));}if(!t)throw new Error("Missing runtime dir. Use --runtime-dir or STATIC_PUBLISHER_RUNTIME_DIR.");let s=p.resolve(t),i=r?p.resolve(r):p.join(s,"config.json");return {runtimeDir:s,exporterDir:p.resolve(n),configPath:i,maxJobs:Number.isFinite(o)&&o>0?o:1}}async function w(e,t){try{let n=await f.readFile(e,"utf8");return JSON.parse(n)}catch(n){if((n&&typeof n=="object"&&"code"in n?String(n.code||""):"")!=="ENOENT"){let o=n instanceof Error?n.message:String(n);console.warn(`[queue-runner] failed to read JSON ${e}: ${o}`);}return t}}async function S(e,t){await f.mkdir(p.dirname(e),{recursive:true}),await f.writeFile(e,JSON.stringify(t,null,2),"utf8");}function G(e){return p.join(e,Pe)}async function Ae(e){await new Promise(t=>setTimeout(t,e));}async function qe(e){let t=G(e),n=Date.now()+ve;for(;;)try{await f.mkdir(p.dirname(t),{recursive:!0}),await f.writeFile(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()},null,2),{encoding:"utf8",flag:"wx"});return}catch(r){if((r&&typeof r=="object"&&"code"in r?String(r.code||""):"")!=="EEXIST")throw r;let s=await f.stat(t).catch(()=>null);if(s&&Date.now()-s.mtimeMs>Ce){await f.unlink(t).catch(()=>{});continue}if(Date.now()>=n)throw new Error("Timed out acquiring queue mutation lock.",{cause:r});await Ae(50);}}async function Ie(e){await f.unlink(G(e)).catch(()=>{});}async function D(e,t){await qe(e);try{return await t()}finally{await Ie(e);}}function De(e){return p.join(e,"queue-runner-heartbeat.json")}function F(e){return p.join(e,"current-progress.json")}function N(e){return p.join(e,"scheduler-state.json")}function xe(e,t){let r=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!r)return t;let o=r.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return o.length>0?o.join("/"):t}async function Y(e){let t=await w(e.configPath||"",null),n=p.resolve(e.runtimeDir,".."),o=(typeof t?.logDir=="string"?t.logDir:"").trim();return o&&p.isAbsolute(o)?p.resolve(o):p.resolve(n,xe(o,"logs"))}function E(e,t){return String(e||"").trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||t}function Je(e){let t=e?new Date(e):new Date;return (Number.isNaN(t.getTime())?new Date:t).toISOString().replace(/[-:]/g,"").replace(/\.\d{3}Z$/,"Z")}function Te(e){return [Je(e.endedAt||e.startedAt),E(e.command||"job","job"),E(e.id||"job","job"),E(e.status||"finished","finished")].join("-")}function ke(e){return e.endsWith(".log.jsonl")||e.endsWith(".errors.jsonl")||e.endsWith(".rejected.jsonl")?true:["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"].includes(e)}function Ee(e){return e==="errors.json"||e==="errors.jsonl"||e.endsWith(".errors.jsonl")?"errors":e==="ignored.json"||e==="ignored.jsonl"?"ignored":e==="rejected.json"||e==="rejected.jsonl"||e.endsWith(".rejected.jsonl")?"rejected":e==="skipped-http.json"||e==="skipped-http.jsonl"?"skipped-http":e==="timings.json"||e==="timings.jsonl"?"timings":e==="current-progress.json"?"current-progress":e==="current-crawl-event.json"?"current-crawl-event":e.endsWith(".log.jsonl")?e.replace(/\.log\.jsonl$/i,"-log"):e.replace(/\.[^.]+$/u,"")||"artifact"}function je(e){return e.endsWith(".gz")?"application/gzip":e.endsWith(".jsonl")?"application/x-ndjson":e.endsWith(".json")?"application/json":"text/plain"}async function _(e,t,n){let r=`${n}.gz`,o=p.join(t,r);await pipeline(createReadStream(e),createGzip({level:9}),createWriteStream(o));let[s,i]=await Promise.all([f.stat(e),f.stat(o)]);return {role:Ee(n),originalFileName:n,storedFileName:r,compressed:true,compression:"gzip",contentType:je(r),originalSize:s.size,storedSize:i.size}}async function H(e,t){let n=await Y(t),r=new Date().toISOString(),o=Te(e),s=p.join(n,"archive",o),i=[],u=[];await f.mkdir(s,{recursive:true});try{let g=await f.readdir(n,{withFileTypes:!0});for(let d of g){if(!d.isFile()||!ke(d.name))continue;let l=await _(p.join(n,d.name),s,d.name);u.push(l),i.push(l.storedFileName);}}catch(g){if((g&&typeof g=="object"&&"code"in g?String(g.code||""):"")!=="ENOENT")throw g}let a=F(t.runtimeDir);if(existsSync(a)){let g=await _(a,s,"current-progress.json");u.push(g),i.push(g.storedFileName);}let c=[...i,"job.json"];return await S(p.join(s,"job.json"),{manifestVersion:1,archivedAt:r,archiveKey:o,archiveDir:s,logDir:n,runtimeDir:t.runtimeDir,exporterDir:t.exporterDir,configPath:t.configPath||"",archivedFiles:c,artifacts:u,job:e}),{archiveKey:o,archiveDir:s,archiveCreatedAt:r,archivedFiles:c,artifacts:u}}function Oe(e){return p.join(e,"audit-events.jsonl")}function j(e){return p.join(e,"stop-request.json")}async function Z(e){try{let t=await f.readFile(j(e),"utf8"),n=JSON.parse(t);return n&&typeof n=="object"?n:null}catch{return null}}async function $(e,t){let n=await Z(e);if(!n)return null;let r=String(n.targetJobId||"").trim();return r&&r!==t?null:n}async function O(e,t){if(!t){await f.unlink(j(e)).catch(()=>{});return}let n=await Z(e);if(!n)return;let r=String(n.targetJobId||"").trim();(!r||r===t)&&await f.unlink(j(e)).catch(()=>{});}async function A(e,t){try{let n={occurredAt:t.occurredAt||new Date().toISOString(),status:t.status||"info",actorSource:t.actorSource||"queue-runner",...t};await f.mkdir(e,{recursive:!0}),await f.appendFile(Oe(e),`${JSON.stringify(n)}
2
- `,"utf8");}catch{}}async function b(e,t,n){let r={checkedAt:new Date().toISOString(),status:t,pid:process.pid,nodePath:process.execPath,nodeVersion:process.version,runtimeDir:e.runtimeDir,exporterDir:e.exporterDir,...n??{}};try{await S(De(e.runtimeDir),r);}catch{}}async function q(e){try{await f.unlink(F(e));}catch{}}function Fe(e,t){let n=e.command;if(n!=="publish"&&n!=="crawl"&&n!=="deploy"&&n!=="invalidate"&&n!=="retry-timeouts"&&n!=="url")return null;let r=Number.parseInt(String(e.intervalMinutes??"0"),10);if(!Number.isFinite(r)||r<1)return null;let o=(e.id||`${n}-${t+1}`).trim();if(!o)return null;let s=e.enabled!==false,i=typeof e.url=="string"?e.url.trim():"",u=typeof e.deploymentProfile=="string"?e.deploymentProfile.trim():"",a=(n==="publish"||n==="crawl")&&e.crawlMode==="incremental"?"incremental":"full";return n==="url"&&!i?null:{id:o,enabled:s,command:n,intervalMinutes:r,...n==="publish"||n==="crawl"?{crawlMode:a}:{},...(n==="publish"||n==="deploy"||n==="invalidate")&&u?{deploymentProfile:u}:{},...i?{url:i}:{}}}async function Me(e){let t=await k(e.configPath).catch(()=>null),n=t?.scheduler,r=Array.isArray(n?.rules)?n.rules.map((o,s)=>Fe(o,s)).filter(o=>!!o):[];return {enabled:!!n?.enabled,timezone:typeof n?.timezone=="string"&&n.timezone.trim()?n.timezone.trim():"UTC",rules:r,wpsuite:t?.wpsuite}}function Le(e,t){let n=(t.url||"").trim(),r=t.crawlMode||"full",o=(t.deploymentProfile||"").trim();return e.some(s=>s.command===t.command&&(s.url||"").trim()===n&&(s.crawlMode||"full")===r&&(s.deploymentProfile||"").trim()===o&&(s.status===void 0||s.status==="queued"||s.status==="running"))}async function Ue(e,t){if(!t.allowSchedulerAutoEnqueue)return 0;let n=await Me(e);if(!n.enabled||n.rules.length===0)return 0;if(t.assertActiveSubscriptionForIdentity)try{await t.assertActiveSubscriptionForIdentity(n.wpsuite??null);}catch(a){let c=a instanceof Error?a.message:String(a);return console.warn(`[queue-runner] scheduler auto-enqueue skipped: ${c}`),0}let r=p.join(e.runtimeDir,"queue.json"),o=p.join(e.runtimeDir,"current-run.json"),s=Date.now(),i=0,u=[];await D(e.runtimeDir,async()=>{let a=await w(r,[]),c=await w(o,null),g=await w(N(e.runtimeDir),{lastEnqueuedBucketByRuleId:{}}),d=[...a];c&&c.status==="running"&&d.unshift(c);for(let l of n.rules){if(!l.enabled)continue;let m=l.intervalMinutes*60*1e3,h=Math.floor(s/m),P=g.lastEnqueuedBucketByRuleId[l.id]??-1;if(h<=P||Le(d,{command:l.command,url:l.url,crawlMode:l.crawlMode,deploymentProfile:l.deploymentProfile}))continue;let y={id:randomUUID(),command:l.command,...(l.command==="publish"||l.command==="crawl")&&l.crawlMode?{crawlMode:l.crawlMode}:{},...(l.command==="publish"||l.command==="deploy"||l.command==="invalidate")&&l.deploymentProfile?{deploymentProfile:l.deploymentProfile}:{},...l.url?{url:l.url}:{},enqueueSource:"scheduler",...n.wpsuite?{wpsuite:n.wpsuite}:{},status:"queued",createdAt:new Date().toISOString(),createdBy:0};a.push(y),d.push(y),u.push({job:y,rule:l}),g.lastEnqueuedBucketByRuleId[l.id]=h,i+=1;}i>0&&(await S(r,a),await S(N(e.runtimeDir),g));});for(let a of u)await A(e.runtimeDir,{eventType:"job-created",status:"queued",actorSource:"queue-runner-scheduler",jobId:a.job.id,command:a.job.command,message:"Scheduler auto-enqueued a job.",details:{ruleId:a.rule.id,intervalMinutes:a.rule.intervalMinutes,timezone:n.timezone,deploymentProfile:a.rule.deploymentProfile||"",url:a.rule.url||""}});return i}async function We(e){let t={pid:process.pid,startedAt:new Date().toISOString()};await f.writeFile(e,JSON.stringify(t,null,2),{encoding:"utf8",flag:"wx"});}async function Be(e){try{await f.unlink(e);}catch{}}function Qe(e,t){let n=[p.join(e,"dist",`${t}.js`),p.join(e,`${t}.js`)];for(let r of n)if(existsSync(r))return r;throw new Error(`Cannot find ${t}.js in ${p.join(e,"dist")} or ${e}`)}async function C(e,t,n,r,o,s,i){if(i){let c=await $(t,i);if(c)throw new I(c,n)}let u=Qe(e,n),a={...process.env,...s??{}};return a.STATIC_PUBLISHER_RUNTIME_DIR=t,o&&(a.PUBLISHER_CONFIG=o),await new Promise((c,g)=>{let d=null,l=null,m=null,h=false,P=spawn(process.execPath,[u,...r],{cwd:e,env:a,stdio:"inherit"}),y=()=>{l&&clearInterval(l),m&&clearTimeout(m);},te=async()=>{if(!(!i||d||h)){h=true;try{let R=await $(t,i);if(!R)return;d=R,P.kill("SIGTERM"),m=setTimeout(()=>{P.kill("SIGKILL");},1e4);}finally{h=false;}}};i&&(l=setInterval(()=>{te();},1e3)),P.on("error",R=>{y(),g(R);}),P.on("close",(R,M)=>{if(y(),d){g(new I(d,n));return}R===0?c():g(new Error(`${n} exited with code ${R??-1}${M?` (signal ${M})`:""}`));});}),0}function ze(e){let t=e.awsTempCreds;if(!t)return {};let n={};return typeof t.accessKeyId=="string"&&t.accessKeyId.trim()!==""&&(n.AWS_ACCESS_KEY_ID=t.accessKeyId.trim()),typeof t.secretAccessKey=="string"&&t.secretAccessKey.trim()!==""&&(n.AWS_SECRET_ACCESS_KEY=t.secretAccessKey.trim()),typeof t.sessionToken=="string"&&t.sessionToken.trim()!==""&&(n.AWS_SESSION_TOKEN=t.sessionToken.trim()),n}async function Ne(e,t){let n=i=>{if(!i||typeof i!="object")return null;let u=i,a={...u.siteSettings??{},...String(u.accountId??"").trim()&&!u.siteSettings?.accountId?{accountId:String(u.accountId).trim()}:{},...String(u.siteId??"").trim()&&!u.siteSettings?.siteId?{siteId:String(u.siteId).trim()}:{},...u.siteSettings?.subscriber===true||u.subscriber===true?{subscriber:true}:{}},c={...String(u.apiBase??"").trim()?{apiBase:String(u.apiBase).trim()}:{},...String(u.runtimeToken??u.nonce??"").trim()?{runtimeToken:String(u.runtimeToken??u.nonce).trim()}:{},...String(u.uploadUrl??"").trim()?{uploadUrl:String(u.uploadUrl).trim()}:{},...Object.keys(a).length>0?{siteSettings:a}:{},...u.subscriptionType?{subscriptionType:u.subscriptionType}:{}};return Object.keys(c).length>0?c:null},r=await k(t.configPath).catch(()=>null),o=n(r?.wpsuite);if(o)return o;let s=n(e.wpsuite);return s||null}async function _e(e,t){return await Ne(e,t)}function V(e){let t={...e,status:"queued"};return delete t.startedAt,delete t.endedAt,delete t.exitCode,delete t.error,delete t.stopRequestedAt,delete t.stopRequestedByUserId,delete t.stopRequestedByLogin,delete t.stopMode,delete t.stoppedStep,t}async function He(e,t){let n=await w(F(e.runtimeDir),null),r=n&&n.details&&typeof n.details.phase=="string"?n.details.phase.trim():"";if(r)return r;let o=n&&typeof n.currentStep=="string"?n.currentStep.trim():"";if(o)return o;let s=await Y(e).catch(()=>"");if(s){let i=await w(p.join(s,"current-crawl-event.json"),null),u=i&&typeof i.currentStep=="string"?i.currentStep.trim():"";if(u)return u}return t}function $e(e,t){if((e.command==="publish"||e.command==="crawl")&&t==="rewrite-text")return "rewrite-text"}async function Ke(e){let t=p.join(e.runtimeDir,"queue.json"),n=p.join(e.runtimeDir,"current-run.json"),r=await D(e.runtimeDir,async()=>{let o=await w(n,null);if(!o||o.status!=="running"&&o.status!=="queued")return null;let s=await w(t,[]),i=Array.isArray(s)?s.filter(a=>a?.id!==o.id):[],u=V(o);return await S(t,[u,...i]),await S(n,null),u});r&&(await O(e.runtimeDir,r.id),await A(e.runtimeDir,{eventType:"job-recovered",status:"queued",actorSource:"queue-runner",jobId:r.id,command:r.command,message:"Recovered stale current-run entry back into queue."}));}async function Ge(e,t,n){try{if((n.shouldEnforceSubscriptionOnJobExecution?.(e)??n.enforceSubscriptionOnJobExecution)&&n.assertActiveSubscriptionForIdentity){let u=await _e(e,t);await n.assertActiveSubscriptionForIdentity(u);}let o=ze(e),s=e.resumeFromStep==="rewrite-text"?["--resume-rewrite"]:e.crawlMode==="incremental"?["--crawl-mode","incremental"]:[],i=e.deploymentProfile?["--profile",e.deploymentProfile]:[];if(e.command==="publish")return await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:e.resumeFromStep==="rewrite-text"?"rewrite-text":"crawl"}),await C(t.exporterDir,t.runtimeDir,"crawl",s,t.configPath,o,e.id),await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"deploy"}),await C(t.exporterDir,t.runtimeDir,"deploy",i,t.configPath,o,e.id),await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"invalidate"}),await C(t.exporterDir,t.runtimeDir,"invalidate",i,t.configPath,o,e.id),{exitCode:0};if(e.command==="crawl")return await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:e.resumeFromStep==="rewrite-text"?"rewrite-text":"crawl"}),await C(t.exporterDir,t.runtimeDir,"crawl",s,t.configPath,o,e.id),{exitCode:0};if(e.command==="deploy")return await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"deploy"}),await C(t.exporterDir,t.runtimeDir,"deploy",i,t.configPath,o,e.id),{exitCode:0};if(e.command==="invalidate")return await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"invalidate"}),await C(t.exporterDir,t.runtimeDir,"invalidate",i,t.configPath,o,e.id),{exitCode:0};if(e.command==="retry-timeouts")return await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"retry-timeouts"}),await C(t.exporterDir,t.runtimeDir,"crawl",["--retry-timeouts"],t.configPath,o,e.id),{exitCode:0};if(e.command==="url"){let u=(e.url||"").trim();return u?(await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"url"}),await C(t.exporterDir,t.runtimeDir,"crawl",["--url",u],t.configPath,o,e.id),{exitCode:0}):{exitCode:2,error:"Missing url for command 'url'"}}return {exitCode:2,error:`Unsupported command: ${e.command}`}}catch(r){return r instanceof I?{exitCode:130,error:"Job stop requested.",stopped:true,stopRequest:r.request,stoppedStep:r.step}:{exitCode:1,error:r instanceof Error?r.message:String(r)}}}function X(e){return async function(n=process.argv.slice(2)){let r=Re(n),o=p.join(r.runtimeDir,"export.lock"),s=p.join(r.runtimeDir,"last-run.json");await q(r.runtimeDir),await b(r,"starting",{message:"queue-runner starting"});try{await We(o);}catch(i){if((i&&typeof i=="object"&&"code"in i?String(i.code||""):"")!=="EEXIST")throw i;console.log("[queue-runner] lock active, skipping"),await b(r,"lock-active",{message:"lock active, skipped this cron tick"});return}try{await Ke(r);let i=await Ue(r,e),u=0;for(let a=0;a<r.maxJobs;a++){let c=await Ze(r,e);if(c==="none"||(u+=1,c==="stopped"))break}if(u===0)await q(r.runtimeDir),await b(r,"idle",{processedJobs:u,schedulerEnqueued:i,message:"no queued jobs"});else {await q(r.runtimeDir);let a=await w(s,null),c=String(a?.status||"").trim();await b(r,c==="success"?"job-success":c==="stopped"?"job-stopped":"job-failed",{processedJobs:u,schedulerEnqueued:i,lastJobId:a?.id,lastJobCommand:a?.command,lastJobStatus:a?.status,lastJobExitCode:a?.exitCode,lastJobError:a?.error,...c==="stopped"?{currentStep:a?.stoppedStep,stopRequestedAt:a?.stopRequestedAt,stopRequestedByLogin:a?.stopRequestedByLogin,stopRequestedMode:a?.stopMode,lastStoppedStep:a?.stoppedStep,message:a?.stopMode==="requeue"?`Job stopped during ${a?.stoppedStep||a?.command||"active step"} and requeued.`:`Job stopped during ${a?.stoppedStep||a?.command||"active step"} and left out of queue.`}:{}});}}catch(i){let u=i instanceof Error?i.message:String(i);throw await b(r,"error",{message:u}),await A(r.runtimeDir,{eventType:"queue-runner-error",status:"failed",actorSource:"queue-runner",message:"Unhandled queue-runner error.",details:{error:u}}),i}finally{await Be(o);}}}async function Ye(e,t,n){let r=p.join(e.runtimeDir,"queue.json"),o=p.join(e.runtimeDir,"current-run.json");await D(e.runtimeDir,async()=>{let s=await w(r,[]),i=Array.isArray(s)?s.filter(c=>c?.id!==t.id):[],u=V(t),a=$e(t,n);a?u.resumeFromStep=a:delete u.resumeFromStep,await S(r,[u,...i]),await S(o,null);});}async function Ze(e,t){let n=p.join(e.runtimeDir,"queue.json"),r=p.join(e.runtimeDir,"current-run.json"),o=p.join(e.runtimeDir,"last-run.json"),s=new Date().toISOString(),i=await D(e.runtimeDir,async()=>{let d=await w(n,[]);if(!Array.isArray(d)||d.length===0)return null;let l={...d[0],status:"running",startedAt:s};return await S(n,d.slice(1)),await S(r,l),l});if(!i)return "none";await q(e.runtimeDir),await A(e.runtimeDir,{eventType:"job-run-started",status:"running",actorSource:"queue-runner",jobId:i.id,command:i.command,message:"Job execution started.",details:{createdAt:i.createdAt||"",startedAt:s,createdBy:i.createdBy??null,deploymentProfile:i.deploymentProfile||"",queuedWithTempAwsCreds:!!i.awsTempCreds}}),await b(e,"running",{currentJobId:i.id,currentJobCommand:i.command,currentStep:i.command});let u=await Ge(i,e,t),a=new Date().toISOString();if(u.stopped){let d=await He(e,u.stoppedStep||i.command),l=u.stopRequest?.mode==="requeue"?"requeue":"stop",m={...i,status:"stopped",endedAt:a,exitCode:u.exitCode,...u.error?{error:u.error}:{},stopRequestedAt:u.stopRequest?.requestedAt||"",stopRequestedByUserId:typeof u.stopRequest?.requestedByUserId=="number"?u.stopRequest.requestedByUserId:null,stopRequestedByLogin:u.stopRequest?.requestedByLogin||"",stopMode:l,stoppedStep:d};l==="requeue"?await Ye(e,i,d):await S(r,null);try{let h=await H(m,e);m.logArchiveDir=h.archiveDir,m.logArchiveCreatedAt=h.archiveCreatedAt,m.logArchiveFileCount=h.archivedFiles.length;}catch(h){m.logArchiveError=h instanceof Error?h.message:String(h);}return await S(o,m),await O(e.runtimeDir,i.id),await q(e.runtimeDir),await A(e.runtimeDir,{eventType:"job-run-stopped",status:"stopped",actorSource:"queue-runner",jobId:i.id,command:i.command,message:l==="requeue"?"Job stop requested and requeued.":"Job stop requested and removed from active execution without requeue.",details:{startedAt:i.startedAt||"",endedAt:a,deploymentProfile:i.deploymentProfile||"",stopMode:l,stopRequestedAt:u.stopRequest?.requestedAt||"",stopRequestedByLogin:u.stopRequest?.requestedByLogin||"",stopRequestedByUserId:typeof u.stopRequest?.requestedByUserId=="number"?u.stopRequest.requestedByUserId:null,stoppedStep:d,logArchiveKey:m.logArchiveError||!m.logArchiveDir?"":p.basename(m.logArchiveDir),logArchiveDir:m.logArchiveDir||"",logArchiveCreatedAt:m.logArchiveCreatedAt||"",logArchiveFileCount:m.logArchiveFileCount??0,logArchiveError:m.logArchiveError||""}}),"stopped"}let c={...i,status:u.exitCode===0?"success":"failed",endedAt:a,exitCode:u.exitCode,...u.error?{error:u.error}:{}};await S(r,null),await O(e.runtimeDir,i.id);try{let d=await H(c,e);c.logArchiveDir=d.archiveDir,c.logArchiveCreatedAt=d.archiveCreatedAt,c.logArchiveFileCount=d.archivedFiles.length;}catch(d){c.logArchiveError=d instanceof Error?d.message:String(d);}await S(o,c);let g=i.startedAt&&c.endedAt?Math.max(0,Math.round((new Date(c.endedAt).getTime()-new Date(i.startedAt).getTime())/1e3)):void 0;return await A(e.runtimeDir,{eventType:"job-run-finished",status:c.status==="success"?"success":"failed",actorSource:"queue-runner",jobId:c.id,command:c.command,message:c.status==="success"?"Job execution finished successfully.":"Job execution finished with failure.",details:{startedAt:i.startedAt||"",endedAt:c.endedAt||"",durationSec:g,deploymentProfile:c.deploymentProfile||"",exitCode:c.exitCode??null,error:c.error||"",logArchiveKey:c.logArchiveError||!c.logArchiveDir?"":p.basename(c.logArchiveDir),logArchiveDir:c.logArchiveDir||"",logArchiveCreatedAt:c.logArchiveCreatedAt||"",logArchiveFileCount:c.logArchiveFileCount??0,logArchiveError:c.logArchiveError||""}}),"processed"}async function Xe(e){if(!e)throw new Error("Missing remote WPSuite publisher state. Refresh the runtime config before running subscription-gated jobs.");if(e.subscriptionType!=="PROFESSIONAL"&&e.subscriptionType!=="AGENCY")throw new Error("This job requires an active WPSuite publisher subscription in the remote site configuration.")}var et={allowSchedulerAutoEnqueue:true,enforceSubscriptionOnJobExecution:false,shouldEnforceSubscriptionOnJobExecution:e=>e.enqueueSource==="scheduler"||e.createdBy===0,assertActiveSubscriptionForIdentity:Xe},ee=X(et),tt=ee,St=ee;process.argv[1]&&import.meta.url===pathToFileURL(process.argv[1]).href&&tt().catch(e=>{console.error(e),process.exit(1);});export{St as default,tt as main,ee as runQueueRunner};
1
+ import {pathToFileURL}from'url';import f from'fs/promises';import {existsSync,createReadStream,createWriteStream}from'fs';import p from'path';import {spawn}from'child_process';import {randomUUID}from'crypto';import {pipeline}from'stream/promises';import {createGzip}from'zlib';import oe from'http';import se from'https';function W(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function ue(e){let t=String(e??"").trim();if(!t)return "";let r=t;if(/^https?:\/\//i.test(r))try{r=new URL(r).pathname;}catch{return ""}if(r=r.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!r)return "";let i=r.endsWith("/"),n=r.replace(/^\/+/,"").split("/").map(o=>o.replace(/[^A-Za-z0-9._-]/g,"")).filter(o=>o.length>0&&o!=="."&&o!=="..");if(n.length===0)return "";let s=`/${n.join("/")}`;return i&&p.extname(s)===""&&(s+="/"),s==="/"?"":s}function x(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function ae(e){if(!e||typeof e!="object")return {};let t={};for(let[r,i]of Object.entries(e)){let n=r.trim();if(!n||!i||typeof i!="object")continue;let s=i,o={};if(typeof s.targetOrigin=="string"){let a=W(s.targetOrigin);a&&(o.targetOrigin=a);}let u=x(s.extraReplacements);if(Object.keys(u).length>0&&(o.extraReplacements=u),s.s3&&typeof s.s3=="object"){let a={},c=s.s3;typeof c.bucket=="string"&&(a.bucket=c.bucket.trim()),typeof c.prefix=="string"&&(a.prefix=c.prefix.trim()),typeof c.region=="string"&&(a.region=c.region.trim()),typeof c.htmlCacheControl=="string"&&(a.htmlCacheControl=c.htmlCacheControl.trim()),typeof c.assetCacheControl=="string"&&(a.assetCacheControl=c.assetCacheControl.trim()),Object.keys(a).length>0&&(o.s3=a);}if(s.cloudFront&&typeof s.cloudFront=="object"){let a={},c=s.cloudFront;typeof c.distributionId=="string"&&(a.distributionId=c.distributionId.trim()),Array.isArray(c.invalidationPaths)&&(a.invalidationPaths=c.invalidationPaths.map(d=>String(d??"").trim()).filter(d=>d.length>0)),Object.keys(a).length>0&&(o.cloudFront=a);}t[n]=o;}return t}function T(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function ce(e,t){if(!e||typeof e!="object")return null;let r=e,i=r.command;if(i!=="publish"&&i!=="crawl"&&i!=="deploy"&&i!=="invalidate"&&i!=="retry-timeouts"&&i!=="url")return null;let n=Number.parseInt(String(r.intervalMinutes??"0"),10);if(!Number.isFinite(n)||n<1)return null;let s=String(r.id??`${i}-${t+1}`).trim();if(!s)return null;let o=String(r.deploymentProfile??"").trim(),u=String(r.url??"").trim();return {id:s,enabled:r.enabled!==false,command:i,intervalMinutes:n,...i==="publish"||i==="crawl"?{crawlMode:r.crawlMode==="incremental"?"incremental":"full"}:{},...(i==="publish"||i==="deploy"||i==="invalidate")&&o?{deploymentProfile:o}:{},...u?{url:u}:{}}}function Q(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((i,n)=>ce(i,n)).filter(i=>!!i):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:r}}function le(e){if(!e||typeof e!="object")return;let t=e,r={};for(let n of ["accountId","siteId"]){let s=t[n];typeof s=="string"&&s.trim()!==""&&(r[n]=s.trim());}let i=Number(t.lastUpdate??0);return Number.isFinite(i)&&i>0&&(r.lastUpdate=Math.floor(i)),t.subscriber===true&&(r.subscriber=true),Object.keys(r).length>0?r:void 0}function J(e){let t=e&&typeof e=="object"?e:{},r=String(t.accountId??"").trim(),i=String(t.siteId??"").trim(),n=t.subscriber===true,s=le(t.siteSettings),o={...s??{},...r?{accountId:s?.accountId??r}:{},...i?{siteId:s?.siteId??i}:{},...s?.subscriber===true||n?{subscriber:true}:{}},u={},a=String(t.apiBase??"").trim();a&&(u.apiBase=a);let c=String(t.runtimeToken??t.nonce??"").trim();c&&(u.runtimeToken=c);let d=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();d&&(u.virtualAssetBaseUrl=d),Object.keys(o).length>0&&(u.siteSettings=o);let g=T(t.subscriptionType);return g&&(u.subscriptionType=g),u}function de(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function z(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function ge(e,t){let r=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[i,n]of new Headers(t.headers).entries())r.set(i,n);return r}async function N(e,t,r=5){let i=new URL(z(e)),n=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),s=i.protocol==="http:"?oe:se,o=ge(e,t);return await new Promise((u,a)=>{let c=s.request(i,{method:n,headers:Object.fromEntries(o.entries()),...i.protocol==="https:"?{rejectUnauthorized:false}:{}},d=>{let g=[];d.on("data",l=>{g.push(Buffer.isBuffer(l)?l:Buffer.from(l));}),d.on("error",a),d.on("end",()=>{let l=d.statusCode??0,m=d.headers.location;if(r>0&&m&&[301,302,303,307,308].includes(l)){u(N(new URL(m,i),{method:l===303?"GET":n},r-1));return}let h=new Headers;for(let[P,y]of Object.entries(d.headers))Array.isArray(y)?h.set(P,y.join(", ")):typeof y=="string"&&h.set(P,y);u(new Response(Buffer.concat(g),{status:l,statusText:d.statusMessage??"",headers:h}));});});c.on("error",a),c.end();})}function pe(e){let t=J(e.wpsuite),r={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},i=String(r.accountId??"").trim(),n=String(r.siteId??"").trim(),s=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();if(e.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...s?{virtualAssetBaseUrl:s}:{},...Object.keys(r).length>0?{siteSettings:r}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!i||!n||!s)return false;de(e.sourceOrigin);let o=globalThis,a={...o.WpSuite??{},siteSettings:r,uploadUrl:s};return t.apiBase&&(a.apiBase=t.apiBase),o.WpSuite=a,true}async function me(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!pe(e)){let n=e.wpsuite?.siteSettings,s=[String(n?.accountId??"").trim()?"":"accountId",String(n?.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): ${s.join(", ")}.`,requests:[]}}}let r=globalThis.fetch,i=[];try{typeof r=="function"&&/^https?:\/\//i.test(t)&&(globalThis.fetch=(async(a,c)=>{let d=z(a);if(d.startsWith(t)){let g=(()=>{try{return new URL(d).pathname}catch{return d}})();try{let l=e.ignoreHttpsErrors&&d.startsWith("https://")?await N(a,c):await r(a,c);return i.push({path:g,status:l.status,ok:l.ok,error:null}),l}catch(l){throw i.push({path:g,status:null,ok:!1,error:l instanceof Error?l.message:String(l)}),l}}return r(a,c)}));let{getConfig:n}=await import('@smart-cloud/wpsuite-core'),s=await n("publisher"),o=s&&typeof s=="object"?s:null,u=T(o?.subscriptionType);return {remote:o,diagnostic:{status:o?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:u??null,error:o?null:"WP Suite publisher config loader returned no configuration.",requests:i}}}catch(n){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:t,subscriptionType:null,error:n instanceof Error?n.message:String(n),requests:i}}}finally{typeof r=="function"&&(globalThis.fetch=r);}}function fe(e,t){let r=ae(t?.deploymentProfiles),i=String(t?.defaultDeploymentProfile??"").trim(),n=r[i]?i:"",s=T(t?.subscriptionType),o=J(e.wpsuite);return {...e,scheduler:Q(t?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:n,...s?{subscriptionType:s}:{},wpsuite:{...o,...o.siteSettings||s?{siteSettings:{...o.siteSettings??{},...o.siteSettings?.subscriber===true||s==="PROFESSIONAL"||s==="AGENCY"?{subscriber:true}:{}}}:{},...s?{subscriptionType:s}:{}}}}function k(e,t){let i=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!i)return t;let n=i.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return n.length>0?n.join("/"):t}function he(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?p.resolve(e):""}function L(e,t,r){let i=String(t||"").trim();return i&&p.isAbsolute(i)?p.resolve(i):p.resolve(e,k(i,r))}async function j(e,t={}){let r=String(e??"").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",i=await f.readFile(r,"utf8"),n=JSON.parse(i);n.sourceOrigin=n.sourceOrigin.replace(/\/$/,""),n.targetOrigin=W(n.targetOrigin),n.ignoreHttpsErrors??=false,n.outputDir=String(n.outputDir||"export").trim()||"export",n.urlRewriteMode||=n.targetOrigin==="."?"relative":"absolute",n.noJavaScriptRenderPathPrefixes||=[],n.seedPaths||=[],n.generated404RequestPath=ue(n.generated404RequestPath),n.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],n.allowedAssetHosts||=[],n.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],n.blockedPathPrefixes||=[],n.blockedSearchFragments||=[],n.concurrency||=1,n.maxPages||=0,n.extraReplacements=x(n.extraReplacements),n.postCrawlCopyMap=x(n.postCrawlCopyMap),n.logDir=String(n.logDir||"logs").trim()||"logs",n.verbose??=false,n.logLevel||=n.verbose?"debug":"info",n.s3SyncMode||="sdk-upload-delete",n.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},n.readiness.timeoutMs??=1500,n.readiness.fallbackWaitMs??=1500,n.viewport||={width:1440,height:1200},n.navigationTimeoutMs||=3e4,n.assetDownloadConcurrency=Number(n.assetDownloadConcurrency)>0?Number(n.assetDownloadConcurrency):n.concurrency,n.rewriteConcurrency=Number(n.rewriteConcurrency)>0?Number(n.rewriteConcurrency):n.assetDownloadConcurrency,n.wpsuite=J(n.wpsuite),n.scheduler=Q(void 0),n.deploymentProfiles={},n.defaultDeploymentProfile="",n.deploymentTargetOverride=String(n.deploymentTargetOverride??"").trim();let s=await me(n);t.onRemotePublisherConfigDiagnostic?.(s.diagnostic);let o=fe(n,s.remote),u=he(),a=u?p.resolve(u,".."):"";return a?(o.outputDir=L(a,o.outputDir,"export"),o.logDir=L(a,o.logDir,"logs")):(p.isAbsolute(o.outputDir)||(o.outputDir=k(o.outputDir,"export")),p.isAbsolute(o.logDir)||(o.logDir=k(o.logDir,"logs"))),o}var E=new Map;async function _(e){let t=p.resolve(e),r=E.get(t);if(r!==void 0)return r;try{let i=JSON.parse(await f.readFile(t,"utf8")),n=String(i.version??"").trim();return E.set(t,n),n}catch{return E.set(t,""),""}}var D=class extends Error{request;step;constructor(t,r){super(`Stop requested during ${r}.`),this.name="StopRequestedError",this.request=t,this.step=r;}},Ce="queue-mutation.lock",Re=5e3,Ae=3e4;function qe(e){let t=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",r=process.env.STATIC_PUBLISHER_EXPORTER_DIR||process.cwd(),i=process.env.PUBLISHER_CONFIG||"",n=1;for(let u=0;u<e.length;u++){let a=e[u];a==="--runtime-dir"?t=e[++u]||"":a.startsWith("--runtime-dir=")?t=a.slice(14):a==="--exporter-dir"?r=e[++u]||r:a.startsWith("--exporter-dir=")?r=a.slice(15):a==="--config"?i=e[++u]||"":a.startsWith("--config=")?i=a.slice(9):a==="--max-jobs"?n=Number.parseInt(e[++u]||"1",10):a.startsWith("--max-jobs=")&&(n=Number.parseInt(a.slice(11),10));}if(!t)throw new Error("Missing runtime dir. Use --runtime-dir or STATIC_PUBLISHER_RUNTIME_DIR.");let s=p.resolve(t),o=i?p.resolve(i):p.join(s,"config.json");return {runtimeDir:s,exporterDir:p.resolve(r),configPath:o,maxJobs:Number.isFinite(n)&&n>0?n:1}}async function w(e,t){try{let r=await f.readFile(e,"utf8");return JSON.parse(r)}catch(r){if((r&&typeof r=="object"&&"code"in r?String(r.code||""):"")!=="ENOENT"){let n=r instanceof Error?r.message:String(r);console.warn(`[queue-runner] failed to read JSON ${e}: ${n}`);}return t}}async function S(e,t){await f.mkdir(p.dirname(e),{recursive:true}),await f.writeFile(e,JSON.stringify(t,null,2),"utf8");}function Y(e){return p.join(e,Ce)}async function De(e){await new Promise(t=>setTimeout(t,e));}async function Ie(e){let t=Y(e),r=Date.now()+Re;for(;;)try{await f.mkdir(p.dirname(t),{recursive:!0}),await f.writeFile(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()},null,2),{encoding:"utf8",flag:"wx"});return}catch(i){if((i&&typeof i=="object"&&"code"in i?String(i.code||""):"")!=="EEXIST")throw i;let s=await f.stat(t).catch(()=>null);if(s&&Date.now()-s.mtimeMs>Ae){await f.unlink(t).catch(()=>{});continue}if(Date.now()>=r)throw new Error("Timed out acquiring queue mutation lock.",{cause:i});await De(50);}}async function xe(e){await f.unlink(Y(e)).catch(()=>{});}async function I(e,t){await Ie(e);try{return await t()}finally{await xe(e);}}function ke(e){return p.join(e,"queue-runner-heartbeat.json")}function U(e){return p.join(e,"current-progress.json")}function $(e){return p.join(e,"scheduler-state.json")}function Te(e,t){let i=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!i)return t;let n=i.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return n.length>0?n.join("/"):t}async function Z(e){let t=await w(e.configPath||"",null),r=p.resolve(e.runtimeDir,".."),n=(typeof t?.logDir=="string"?t.logDir:"").trim();return n&&p.isAbsolute(n)?p.resolve(n):p.resolve(r,Te(n,"logs"))}function O(e,t){return String(e||"").trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||t}function Je(e){let t=e?new Date(e):new Date;return (Number.isNaN(t.getTime())?new Date:t).toISOString().replace(/[-:]/g,"").replace(/\.\d{3}Z$/,"Z")}function je(e){return [Je(e.endedAt||e.startedAt),O(e.command||"job","job"),O(e.id||"job","job"),O(e.status||"finished","finished")].join("-")}function Ee(e){return e.endsWith(".log.jsonl")||e.endsWith(".errors.jsonl")||e.endsWith(".rejected.jsonl")?true:["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"].includes(e)}function Oe(e){return e==="errors.json"||e==="errors.jsonl"||e.endsWith(".errors.jsonl")?"errors":e==="ignored.json"||e==="ignored.jsonl"?"ignored":e==="rejected.json"||e==="rejected.jsonl"||e.endsWith(".rejected.jsonl")?"rejected":e==="skipped-http.json"||e==="skipped-http.jsonl"?"skipped-http":e==="timings.json"||e==="timings.jsonl"?"timings":e==="current-progress.json"?"current-progress":e==="current-crawl-event.json"?"current-crawl-event":e.endsWith(".log.jsonl")?e.replace(/\.log\.jsonl$/i,"-log"):e.replace(/\.[^.]+$/u,"")||"artifact"}function Fe(e){return e.endsWith(".gz")?"application/gzip":e.endsWith(".jsonl")?"application/x-ndjson":e.endsWith(".json")?"application/json":"text/plain"}async function H(e,t,r){let i=`${r}.gz`,n=p.join(t,i);await pipeline(createReadStream(e),createGzip({level:9}),createWriteStream(n));let[s,o]=await Promise.all([f.stat(e),f.stat(n)]);return {role:Oe(r),originalFileName:r,storedFileName:i,compressed:true,compression:"gzip",contentType:Fe(i),originalSize:s.size,storedSize:o.size}}async function K(e,t){let r=await Z(t),i=new Date().toISOString(),n=je(e),s=p.join(r,"archive",n),o=[],u=[];await f.mkdir(s,{recursive:true});try{let d=await f.readdir(r,{withFileTypes:!0});for(let g of d){if(!g.isFile()||!Ee(g.name))continue;let l=await H(p.join(r,g.name),s,g.name);u.push(l),o.push(l.storedFileName);}}catch(d){if((d&&typeof d=="object"&&"code"in d?String(d.code||""):"")!=="ENOENT")throw d}let a=U(t.runtimeDir);if(existsSync(a)){let d=await H(a,s,"current-progress.json");u.push(d),o.push(d.storedFileName);}let c=[...o,"job.json"];return await S(p.join(s,"job.json"),{manifestVersion:1,archivedAt:i,archiveKey:n,archiveDir:s,logDir:r,runtimeDir:t.runtimeDir,exporterDir:t.exporterDir,configPath:t.configPath||"",archivedFiles:c,artifacts:u,job:e}),{archiveKey:n,archiveDir:s,archiveCreatedAt:i,archivedFiles:c,artifacts:u}}function Me(e){return p.join(e,"audit-events.jsonl")}function F(e){return p.join(e,"stop-request.json")}async function X(e){try{let t=await f.readFile(F(e),"utf8"),r=JSON.parse(t);return r&&typeof r=="object"?r:null}catch{return null}}async function G(e,t){let r=await X(e);if(!r)return null;let i=String(r.targetJobId||"").trim();return i&&i!==t?null:r}async function M(e,t){if(!t){await f.unlink(F(e)).catch(()=>{});return}let r=await X(e);if(!r)return;let i=String(r.targetJobId||"").trim();(!i||i===t)&&await f.unlink(F(e)).catch(()=>{});}async function A(e,t){try{let r={occurredAt:t.occurredAt||new Date().toISOString(),status:t.status||"info",actorSource:t.actorSource||"queue-runner",...t};await f.mkdir(e,{recursive:!0}),await f.appendFile(Me(e),`${JSON.stringify(r)}
2
+ `,"utf8");}catch{}}async function b(e,t,r){let[i,n]=await Promise.all([_(p.join(e.exporterDir,"package.json")),_(p.join(e.exporterDir,"node_modules","@smart-cloud","wpsuite-core","package.json"))]),s={checkedAt:new Date().toISOString(),status:t,pid:process.pid,nodePath:process.execPath,nodeVersion:process.version,exporterVersion:i,wpsuiteCoreVersion:n,runtimeDir:e.runtimeDir,exporterDir:e.exporterDir,...r??{}};try{await S(ke(e.runtimeDir),s);}catch{}}async function q(e){try{await f.unlink(U(e));}catch{}}function Ue(e,t){let r=e.command;if(r!=="publish"&&r!=="crawl"&&r!=="deploy"&&r!=="invalidate"&&r!=="retry-timeouts"&&r!=="url")return null;let i=Number.parseInt(String(e.intervalMinutes??"0"),10);if(!Number.isFinite(i)||i<1)return null;let n=(e.id||`${r}-${t+1}`).trim();if(!n)return null;let s=e.enabled!==false,o=typeof e.url=="string"?e.url.trim():"",u=typeof e.deploymentProfile=="string"?e.deploymentProfile.trim():"",a=(r==="publish"||r==="crawl")&&e.crawlMode==="incremental"?"incremental":"full";return r==="url"&&!o?null:{id:n,enabled:s,command:r,intervalMinutes:i,...r==="publish"||r==="crawl"?{crawlMode:a}:{},...(r==="publish"||r==="deploy"||r==="invalidate")&&u?{deploymentProfile:u}:{},...o?{url:o}:{}}}async function Be(e){let t=await j(e.configPath).catch(()=>null),r=t?.scheduler,i=Array.isArray(r?.rules)?r.rules.map((n,s)=>Ue(n,s)).filter(n=>!!n):[];return {enabled:!!r?.enabled,timezone:typeof r?.timezone=="string"&&r.timezone.trim()?r.timezone.trim():"UTC",rules:i,wpsuite:t?.wpsuite}}function Le(e,t){let r=(t.url||"").trim(),i=t.crawlMode||"full",n=(t.deploymentProfile||"").trim();return e.some(s=>s.command===t.command&&(s.url||"").trim()===r&&(s.crawlMode||"full")===i&&(s.deploymentProfile||"").trim()===n&&(s.status===void 0||s.status==="queued"||s.status==="running"))}async function We(e,t){if(!t.allowSchedulerAutoEnqueue)return 0;let r=await Be(e);if(!r.enabled||r.rules.length===0)return 0;if(t.assertActiveSubscriptionForIdentity)try{await t.assertActiveSubscriptionForIdentity(r.wpsuite??null);}catch(a){let c=a instanceof Error?a.message:String(a);return console.warn(`[queue-runner] scheduler auto-enqueue skipped: ${c}`),0}let i=p.join(e.runtimeDir,"queue.json"),n=p.join(e.runtimeDir,"current-run.json"),s=Date.now(),o=0,u=[];await I(e.runtimeDir,async()=>{let a=await w(i,[]),c=await w(n,null),d=await w($(e.runtimeDir),{lastEnqueuedBucketByRuleId:{}}),g=[...a];c&&c.status==="running"&&g.unshift(c);for(let l of r.rules){if(!l.enabled)continue;let m=l.intervalMinutes*60*1e3,h=Math.floor(s/m),P=d.lastEnqueuedBucketByRuleId[l.id]??-1;if(h<=P||Le(g,{command:l.command,url:l.url,crawlMode:l.crawlMode,deploymentProfile:l.deploymentProfile}))continue;let y={id:randomUUID(),command:l.command,...(l.command==="publish"||l.command==="crawl")&&l.crawlMode?{crawlMode:l.crawlMode}:{},...(l.command==="publish"||l.command==="deploy"||l.command==="invalidate")&&l.deploymentProfile?{deploymentProfile:l.deploymentProfile}:{},...l.url?{url:l.url}:{},enqueueSource:"scheduler",...r.wpsuite?{wpsuite:r.wpsuite}:{},status:"queued",createdAt:new Date().toISOString(),createdBy:0};a.push(y),g.push(y),u.push({job:y,rule:l}),d.lastEnqueuedBucketByRuleId[l.id]=h,o+=1;}o>0&&(await S(i,a),await S($(e.runtimeDir),d));});for(let a of u)await A(e.runtimeDir,{eventType:"job-created",status:"queued",actorSource:"queue-runner-scheduler",jobId:a.job.id,command:a.job.command,message:"Scheduler auto-enqueued a job.",details:{ruleId:a.rule.id,intervalMinutes:a.rule.intervalMinutes,timezone:r.timezone,deploymentProfile:a.rule.deploymentProfile||"",url:a.rule.url||""}});return o}async function Qe(e){let t={pid:process.pid,startedAt:new Date().toISOString()};await f.writeFile(e,JSON.stringify(t,null,2),{encoding:"utf8",flag:"wx"});}async function ze(e){try{await f.unlink(e);}catch{}}function Ne(e,t){let r=[p.join(e,"dist",`${t}.js`),p.join(e,`${t}.js`)];for(let i of r)if(existsSync(i))return i;throw new Error(`Cannot find ${t}.js in ${p.join(e,"dist")} or ${e}`)}async function C(e,t,r,i,n,s,o){if(o){let c=await G(t,o);if(c)throw new D(c,r)}let u=Ne(e,r),a={...process.env,...s??{}};return a.STATIC_PUBLISHER_RUNTIME_DIR=t,n&&(a.PUBLISHER_CONFIG=n),await new Promise((c,d)=>{let g=null,l=null,m=null,h=false,P=spawn(process.execPath,[u,...i],{cwd:e,env:a,stdio:"inherit"}),y=()=>{l&&clearInterval(l),m&&clearTimeout(m);},ne=async()=>{if(!(!o||g||h)){h=true;try{let R=await G(t,o);if(!R)return;g=R,P.kill("SIGTERM"),m=setTimeout(()=>{P.kill("SIGKILL");},1e4);}finally{h=false;}}};o&&(l=setInterval(()=>{ne();},1e3)),P.on("error",R=>{y(),d(R);}),P.on("close",(R,B)=>{if(y(),g){d(new D(g,r));return}R===0?c():d(new Error(`${r} exited with code ${R??-1}${B?` (signal ${B})`:""}`));});}),0}function _e(e){let t=e.awsTempCreds;if(!t)return {};let r={};return typeof t.accessKeyId=="string"&&t.accessKeyId.trim()!==""&&(r.AWS_ACCESS_KEY_ID=t.accessKeyId.trim()),typeof t.secretAccessKey=="string"&&t.secretAccessKey.trim()!==""&&(r.AWS_SECRET_ACCESS_KEY=t.secretAccessKey.trim()),typeof t.sessionToken=="string"&&t.sessionToken.trim()!==""&&(r.AWS_SESSION_TOKEN=t.sessionToken.trim()),r}async function $e(e,t){let r=o=>{if(!o||typeof o!="object")return null;let u=o,a={...u.siteSettings??{},...String(u.accountId??"").trim()&&!u.siteSettings?.accountId?{accountId:String(u.accountId).trim()}:{},...String(u.siteId??"").trim()&&!u.siteSettings?.siteId?{siteId:String(u.siteId).trim()}:{},...u.siteSettings?.subscriber===true||u.subscriber===true?{subscriber:true}:{}},c={...String(u.apiBase??"").trim()?{apiBase:String(u.apiBase).trim()}:{},...String(u.runtimeToken??u.nonce??"").trim()?{runtimeToken:String(u.runtimeToken??u.nonce).trim()}:{},...String(u.virtualAssetBaseUrl??u.uploadUrl??"").trim()?{virtualAssetBaseUrl:String(u.virtualAssetBaseUrl??u.uploadUrl).trim()}:{},...Object.keys(a).length>0?{siteSettings:a}:{},...u.subscriptionType?{subscriptionType:u.subscriptionType}:{}};return Object.keys(c).length>0?c:null},i=await j(t.configPath).catch(()=>null),n=r(i?.wpsuite);if(n)return n;let s=r(e.wpsuite);return s||null}async function He(e,t){return await $e(e,t)}function ee(e){let t={...e,status:"queued"};return delete t.startedAt,delete t.endedAt,delete t.exitCode,delete t.error,delete t.stopRequestedAt,delete t.stopRequestedByUserId,delete t.stopRequestedByLogin,delete t.stopMode,delete t.stoppedStep,t}async function Ke(e,t){let r=await w(U(e.runtimeDir),null),i=r&&r.details&&typeof r.details.phase=="string"?r.details.phase.trim():"";if(i)return i;let n=r&&typeof r.currentStep=="string"?r.currentStep.trim():"";if(n)return n;let s=await Z(e).catch(()=>"");if(s){let o=await w(p.join(s,"current-crawl-event.json"),null),u=o&&typeof o.currentStep=="string"?o.currentStep.trim():"";if(u)return u}return t}function Ge(e,t){if((e.command==="publish"||e.command==="crawl")&&t==="rewrite-text")return "rewrite-text"}async function Ve(e){let t=p.join(e.runtimeDir,"queue.json"),r=p.join(e.runtimeDir,"current-run.json"),i=await I(e.runtimeDir,async()=>{let n=await w(r,null);if(!n||n.status!=="running"&&n.status!=="queued")return null;let s=await w(t,[]),o=Array.isArray(s)?s.filter(a=>a?.id!==n.id):[],u=ee(n);return await S(t,[u,...o]),await S(r,null),u});i&&(await M(e.runtimeDir,i.id),await A(e.runtimeDir,{eventType:"job-recovered",status:"queued",actorSource:"queue-runner",jobId:i.id,command:i.command,message:"Recovered stale current-run entry back into queue."}));}async function Ye(e,t,r){try{if((r.shouldEnforceSubscriptionOnJobExecution?.(e)??r.enforceSubscriptionOnJobExecution)&&r.assertActiveSubscriptionForIdentity){let u=await He(e,t);await r.assertActiveSubscriptionForIdentity(u);}let n=_e(e),s=e.resumeFromStep==="rewrite-text"?["--resume-rewrite"]:e.crawlMode==="incremental"?["--crawl-mode","incremental"]:[],o=e.deploymentProfile?["--profile",e.deploymentProfile]:[];if(e.command==="publish")return await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:e.resumeFromStep==="rewrite-text"?"rewrite-text":"crawl"}),await C(t.exporterDir,t.runtimeDir,"crawl",s,t.configPath,n,e.id),await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"deploy"}),await C(t.exporterDir,t.runtimeDir,"deploy",o,t.configPath,n,e.id),await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"invalidate"}),await C(t.exporterDir,t.runtimeDir,"invalidate",o,t.configPath,n,e.id),{exitCode:0};if(e.command==="crawl")return await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:e.resumeFromStep==="rewrite-text"?"rewrite-text":"crawl"}),await C(t.exporterDir,t.runtimeDir,"crawl",s,t.configPath,n,e.id),{exitCode:0};if(e.command==="deploy")return await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"deploy"}),await C(t.exporterDir,t.runtimeDir,"deploy",o,t.configPath,n,e.id),{exitCode:0};if(e.command==="invalidate")return await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"invalidate"}),await C(t.exporterDir,t.runtimeDir,"invalidate",o,t.configPath,n,e.id),{exitCode:0};if(e.command==="retry-timeouts")return await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"retry-timeouts"}),await C(t.exporterDir,t.runtimeDir,"crawl",["--retry-timeouts"],t.configPath,n,e.id),{exitCode:0};if(e.command==="url"){let u=(e.url||"").trim();return u?(await b(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"url"}),await C(t.exporterDir,t.runtimeDir,"crawl",["--url",u],t.configPath,n,e.id),{exitCode:0}):{exitCode:2,error:"Missing url for command 'url'"}}return {exitCode:2,error:`Unsupported command: ${e.command}`}}catch(i){return i instanceof D?{exitCode:130,error:"Job stop requested.",stopped:true,stopRequest:i.request,stoppedStep:i.step}:{exitCode:1,error:i instanceof Error?i.message:String(i)}}}function te(e){return async function(r=process.argv.slice(2)){let i=qe(r),n=p.join(i.runtimeDir,"export.lock"),s=p.join(i.runtimeDir,"last-run.json");await q(i.runtimeDir),await b(i,"starting",{message:"queue-runner starting"});try{await Qe(n);}catch(o){if((o&&typeof o=="object"&&"code"in o?String(o.code||""):"")!=="EEXIST")throw o;console.log("[queue-runner] lock active, skipping"),await b(i,"lock-active",{message:"lock active, skipped this cron tick"});return}try{await Ve(i);let o=await We(i,e),u=0;for(let a=0;a<i.maxJobs;a++){let c=await Xe(i,e);if(c==="none"||(u+=1,c==="stopped"))break}if(u===0)await q(i.runtimeDir),await b(i,"idle",{processedJobs:u,schedulerEnqueued:o,message:"no queued jobs"});else {await q(i.runtimeDir);let a=await w(s,null),c=String(a?.status||"").trim();await b(i,c==="success"?"job-success":c==="stopped"?"job-stopped":"job-failed",{processedJobs:u,schedulerEnqueued:o,lastJobId:a?.id,lastJobCommand:a?.command,lastJobStatus:a?.status,lastJobExitCode:a?.exitCode,lastJobError:a?.error,...c==="stopped"?{currentStep:a?.stoppedStep,stopRequestedAt:a?.stopRequestedAt,stopRequestedByLogin:a?.stopRequestedByLogin,stopRequestedMode:a?.stopMode,lastStoppedStep:a?.stoppedStep,message:a?.stopMode==="requeue"?`Job stopped during ${a?.stoppedStep||a?.command||"active step"} and requeued.`:`Job stopped during ${a?.stoppedStep||a?.command||"active step"} and left out of queue.`}:{}});}}catch(o){let u=o instanceof Error?o.message:String(o);throw await b(i,"error",{message:u}),await A(i.runtimeDir,{eventType:"queue-runner-error",status:"failed",actorSource:"queue-runner",message:"Unhandled queue-runner error.",details:{error:u}}),o}finally{await ze(n);}}}async function Ze(e,t,r){let i=p.join(e.runtimeDir,"queue.json"),n=p.join(e.runtimeDir,"current-run.json");await I(e.runtimeDir,async()=>{let s=await w(i,[]),o=Array.isArray(s)?s.filter(c=>c?.id!==t.id):[],u=ee(t),a=Ge(t,r);a?u.resumeFromStep=a:delete u.resumeFromStep,await S(i,[u,...o]),await S(n,null);});}async function Xe(e,t){let r=p.join(e.runtimeDir,"queue.json"),i=p.join(e.runtimeDir,"current-run.json"),n=p.join(e.runtimeDir,"last-run.json"),s=new Date().toISOString(),o=await I(e.runtimeDir,async()=>{let g=await w(r,[]);if(!Array.isArray(g)||g.length===0)return null;let l={...g[0],status:"running",startedAt:s};return await S(r,g.slice(1)),await S(i,l),l});if(!o)return "none";await q(e.runtimeDir),await A(e.runtimeDir,{eventType:"job-run-started",status:"running",actorSource:"queue-runner",jobId:o.id,command:o.command,message:"Job execution started.",details:{createdAt:o.createdAt||"",startedAt:s,createdBy:o.createdBy??null,deploymentProfile:o.deploymentProfile||"",queuedWithTempAwsCreds:!!o.awsTempCreds}}),await b(e,"running",{currentJobId:o.id,currentJobCommand:o.command,currentStep:o.command});let u=await Ye(o,e,t),a=new Date().toISOString();if(u.stopped){let g=await Ke(e,u.stoppedStep||o.command),l=u.stopRequest?.mode==="requeue"?"requeue":"stop",m={...o,status:"stopped",endedAt:a,exitCode:u.exitCode,...u.error?{error:u.error}:{},stopRequestedAt:u.stopRequest?.requestedAt||"",stopRequestedByUserId:typeof u.stopRequest?.requestedByUserId=="number"?u.stopRequest.requestedByUserId:null,stopRequestedByLogin:u.stopRequest?.requestedByLogin||"",stopMode:l,stoppedStep:g};l==="requeue"?await Ze(e,o,g):await S(i,null);try{let h=await K(m,e);m.logArchiveDir=h.archiveDir,m.logArchiveCreatedAt=h.archiveCreatedAt,m.logArchiveFileCount=h.archivedFiles.length;}catch(h){m.logArchiveError=h instanceof Error?h.message:String(h);}return await S(n,m),await M(e.runtimeDir,o.id),await q(e.runtimeDir),await A(e.runtimeDir,{eventType:"job-run-stopped",status:"stopped",actorSource:"queue-runner",jobId:o.id,command:o.command,message:l==="requeue"?"Job stop requested and requeued.":"Job stop requested and removed from active execution without requeue.",details:{startedAt:o.startedAt||"",endedAt:a,deploymentProfile:o.deploymentProfile||"",stopMode:l,stopRequestedAt:u.stopRequest?.requestedAt||"",stopRequestedByLogin:u.stopRequest?.requestedByLogin||"",stopRequestedByUserId:typeof u.stopRequest?.requestedByUserId=="number"?u.stopRequest.requestedByUserId:null,stoppedStep:g,logArchiveKey:m.logArchiveError||!m.logArchiveDir?"":p.basename(m.logArchiveDir),logArchiveDir:m.logArchiveDir||"",logArchiveCreatedAt:m.logArchiveCreatedAt||"",logArchiveFileCount:m.logArchiveFileCount??0,logArchiveError:m.logArchiveError||""}}),"stopped"}let c={...o,status:u.exitCode===0?"success":"failed",endedAt:a,exitCode:u.exitCode,...u.error?{error:u.error}:{}};await S(i,null),await M(e.runtimeDir,o.id);try{let g=await K(c,e);c.logArchiveDir=g.archiveDir,c.logArchiveCreatedAt=g.archiveCreatedAt,c.logArchiveFileCount=g.archivedFiles.length;}catch(g){c.logArchiveError=g instanceof Error?g.message:String(g);}await S(n,c);let d=o.startedAt&&c.endedAt?Math.max(0,Math.round((new Date(c.endedAt).getTime()-new Date(o.startedAt).getTime())/1e3)):void 0;return await A(e.runtimeDir,{eventType:"job-run-finished",status:c.status==="success"?"success":"failed",actorSource:"queue-runner",jobId:c.id,command:c.command,message:c.status==="success"?"Job execution finished successfully.":"Job execution finished with failure.",details:{startedAt:o.startedAt||"",endedAt:c.endedAt||"",durationSec:d,deploymentProfile:c.deploymentProfile||"",exitCode:c.exitCode??null,error:c.error||"",logArchiveKey:c.logArchiveError||!c.logArchiveDir?"":p.basename(c.logArchiveDir),logArchiveDir:c.logArchiveDir||"",logArchiveCreatedAt:c.logArchiveCreatedAt||"",logArchiveFileCount:c.logArchiveFileCount??0,logArchiveError:c.logArchiveError||""}}),"processed"}var tt={allowSchedulerAutoEnqueue:false,enforceSubscriptionOnJobExecution:false},re=te(tt),rt=re,yt=re;process.argv[1]&&import.meta.url===pathToFileURL(process.argv[1]).href&&rt().catch(e=>{console.error(e),process.exit(1);});export{yt as default,rt as main,re as runQueueRunner};
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@smart-cloud/publisher-exporter",
3
- "version": "1.1.32",
3
+ "version": "1.1.34",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Headless Playwright static publisher for WordPress/Elementor sites with sitemap-only page discovery, strict asset capture, escaped URL rewrite, structured logs, and targeted retry modes.",
7
7
  "bin": {
8
- "publisher-exporter": "./dist/cli.js"
8
+ "publisher-exporter": "dist/cli.js"
9
9
  },
10
10
  "files": [
11
11
  "dist",
@@ -25,6 +25,7 @@
25
25
  "build": "tsup --config tsup.config.ts",
26
26
  "check": "tsc -p tsconfig.json --noEmit",
27
27
  "lint": "eslint 'src/**/*.ts' --report-unused-disable-directives --max-warnings 0",
28
+ "test": "node --test tests/*.test.mjs",
28
29
  "crawl": "node dist/crawl.js",
29
30
  "crawl:retry-timeouts": "node dist/crawl.js --retry-timeouts",
30
31
  "crawl:url": "node dist/crawl.js --url",
@@ -36,29 +37,38 @@
36
37
  "queue:drain": "node dist/queue-runner.js --max-jobs=100",
37
38
  "publish:site": "npm run build && npm run crawl && npm run deploy && npm run invalidate",
38
39
  "install:browsers": "playwright install chromium",
39
- "release:npm": "WPSUITE_PREMIUM=true npm run build && npm publish --access=public"
40
+ "release:npm": "WPSUITE_PREMIUM=true npm run lint && npm run check && npm run build && npm publish --access=public --registry=https://registry.npmjs.org/"
40
41
  },
41
42
  "dependencies": {
42
- "@aws-sdk/client-cloudfront": "^3.1057.0",
43
- "@aws-sdk/client-s3": "^3.1057.0",
44
- "@aws-sdk/lib-storage": "^3.1057.0",
45
- "@smart-cloud/publisher-core": "^1.1.3",
46
- "@smart-cloud/wpsuite-core": "^2.3.1",
43
+ "@aws-sdk/client-cloudfront": "^3.1100.0",
44
+ "@aws-sdk/client-s3": "^3.1100.0",
45
+ "@aws-sdk/lib-storage": "^3.1100.0",
46
+ "@smart-cloud/publisher-core": "^1.1.5",
47
+ "@smart-cloud/wpsuite-core": "^2.3.2",
47
48
  "fast-glob": "^3.3.3",
49
+ "jose": "^6.2.8",
48
50
  "mime-types": "^3.0.2",
49
- "playwright": "^1.60.0"
51
+ "playwright": "^1.62.1"
50
52
  },
51
53
  "devDependencies": {
52
54
  "@eslint/js": "^10.0.1",
53
55
  "@types/mime-types": "^3.0.1",
54
- "@types/node": "^25.9.1",
55
- "@typescript-eslint/eslint-plugin": "^8.60.0",
56
- "@typescript-eslint/parser": "^8.60.0",
57
- "esbuild": "^0.28.0",
58
- "eslint": "^10.4.1",
59
- "globals": "^17.6.0",
56
+ "@types/node": "^26.1.2",
57
+ "@typescript-eslint/eslint-plugin": "^8.65.0",
58
+ "@typescript-eslint/parser": "^8.65.0",
59
+ "esbuild": "^0.28.1",
60
+ "eslint": "^10.8.0",
61
+ "globals": "^17.8.0",
60
62
  "tsup": "^8.5.1",
61
63
  "typescript": "^6.0.3",
62
- "typescript-eslint": "^8.60.0"
64
+ "typescript-eslint": "^8.65.0"
65
+ },
66
+ "overrides": {
67
+ "brace-expansion": "^5.0.8",
68
+ "esbuild": "^0.28.1"
69
+ },
70
+ "resolutions": {
71
+ "brace-expansion": "^5.0.8",
72
+ "esbuild": "^0.28.1"
63
73
  }
64
74
  }