@smart-cloud/publisher-exporter 1.1.26 → 1.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/crawl.js +5 -5
- package/dist/deploy.js +3 -3
- package/package.json +1 -1
package/dist/crawl.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {request,chromium}from'playwright';import S from'fs/promises';import h from'path';import {gunzipSync}from'zlib';import $t from'http';import Ot from'https';import Bt from'crypto';import Jt from'fast-glob';import {availableParallelism}from'os';import {Worker}from'worker_threads';var kt=".deploy-plan.json",Tt="deploy-plan.json";function At(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?h.resolve(e):""}function Fe(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(Fe).filter(t=>t!==null))]}function Mt(e,t){return {schemaVersion:1,generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:h.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 Lt(e){let t=h.join(h.resolve(e.outputDir),kt),r=At();return r?[h.join(r,Tt),t]:[t]}function ne(e,t){let r=h.resolve(e),s=h.resolve(t),n=h.relative(r,s).replace(/\\/g,"/");return Fe(n)}async function Ee(e,t){let r=Mt(e,t);for(let s of Lt(e))await S.mkdir(h.dirname(s),{recursive:true}),await S.writeFile(s,JSON.stringify(r,null,2),"utf8");}function Ue(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function Dt(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&&h.extname(i)===""&&(i+="/"),i==="/"?"":i}function he(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function Ft(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=Ue(i.targetOrigin);a&&(u.targetOrigin=a);}let l=he(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 qe(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function Et(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 Qe(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((s,n)=>Et(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 me(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=qe(t.subscriptionType);return p&&(l.subscriptionType=p),l}function Ut(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Ne(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function qt(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 We(e,t,r=5){let s=new URL(Ne(e)),n=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),i=s.protocol==="http:"?$t:Ot,u=qt(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(We(new URL(g,s),{method:c===303?"GET":n},r-1));return}let f=new Headers;for(let[m,P]of Object.entries(d.headers))Array.isArray(P)?f.set(m,P.join(", ")):typeof P=="string"&&f.set(m,P);l(new Response(Buffer.concat(p),{status:c,statusText:d.statusMessage??"",headers:f}));});});o.on("error",a),o.end();})}function Qt(e){let t=me(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;Ut(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 Nt(e){if(!Qt(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)=>Ne(i).startsWith(t)?We(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 Wt(e,t){let r=Ft(t?.deploymentProfiles),s=String(t?.defaultDeploymentProfile??"").trim(),n=r[s]?s:"",i=qe(t?.subscriptionType),u=me(e.wpsuite);return {...e,scheduler:Qe(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 fe(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 _t(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?h.resolve(e):""}function je(e,t,r){let s=String(t||"").trim();return s&&h.isAbsolute(s)?h.resolve(s):h.resolve(e,fe(s,r))}async function we(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=Ue(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=Dt(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=he(s.extraReplacements),s.postCrawlCopyMap=he(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=me(s.wpsuite),s.scheduler=Qe(void 0),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let n=Wt(s,await Nt(s)),i=_t(),u=i?h.resolve(i,".."):"";return u?(n.outputDir=je(u,n.outputDir,"export"),n.logDir=je(u,n.logDir,"logs")):(h.isAbsolute(n.outputDir)||(n.outputDir=fe(n.outputDir,"export")),h.isAbsolute(n.logDir)||(n.logDir=fe(n.logDir,"logs"))),n}function oe(e,t=10){return Bt.createHash("sha1").update(e).digest("hex").slice(0,t)}async function Pe(e){await S.mkdir(h.dirname(e),{recursive:true});}function _(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(h.extname(e).toLowerCase())}function j(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function H(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function ie(e){return e.replace(/\//g,"\\/")}function _e(e){return e.replace(/\//g,"\\\\/")}function zt(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 Be(e,t,r){if(!t)return;e[t]=r;let s=ie(t),n=ie(r);e[s]=n;let i=_e(t),u=_e(r);e[i]=u;let l=H(t),a=H(r);e[l]=a;let o=H(s),d=H(n);e[o]=d;let p=H(i),c=H(u);e[p]=c;}function ae(e,t,r){Be(e,t,r);let s=zt(t);s&&s!==t&&Be(e,s,r);}function Se(e,t){let r=t.startsWith("/")?t:`/${t}`,s=(e||"").replace(/\/$/,"");return !s||s==="."||s==="/"?r:`${s}${r}`}function He(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function ze(e,t,r){if(!t)return r;let s=h.dirname(h.resolve(t)),n=h.resolve(e,r.replace(/^\/+/,"")),i=h.relative(s,n).replace(/\\/g,"/");return i?(i.startsWith(".")||(i=`./${i}`),i):"."}var Kt=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Yt=new Set([".html",".htm"]),Ge="WPSuite.io Static Publisher",Zt=Ge.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Xt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function er(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function tr(e,t,r){return er(t)?e.replace(new RegExp(`(?<!:)${Xt(t)}`,"g"),r):e.split(t).join(r)}function rr(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let n=h.extname(r).toLowerCase();return Yt.has(n)?/<head\b|<html\b|<!doctype html/i.test(t):false}function sr(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Zt}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${Ge}" />`;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 h from'path';import {gunzipSync}from'zlib';import Ot from'http';import Dt from'https';import Ht from'crypto';import Gt from'fast-glob';import {availableParallelism}from'os';import {Worker}from'worker_threads';var Tt=".deploy-plan.json",At="deploy-plan.json";function Mt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?h.resolve(e):""}function Ee(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(Ee).filter(t=>t!==null))]}function Lt(e,t){return {schemaVersion:1,generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:h.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 It(e){let t=h.join(h.resolve(e.outputDir),Tt),r=Mt();return r?[h.join(r,At),t]:[t]}function ne(e,t){let r=h.resolve(e),s=h.resolve(t),n=h.relative(r,s).replace(/\\/g,"/");return Ee(n)}async function je(e,t){let r=Lt(e,t);for(let s of It(e))await b.mkdir(h.dirname(s),{recursive:true}),await b.writeFile(s,JSON.stringify(r,null,2),"utf8");}function qe(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function Ft(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&&h.extname(i)===""&&(i+="/"),i==="/"?"":i}function he(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function Et(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=qe(i.targetOrigin);a&&(u.targetOrigin=a);}let l=he(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 Qe(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function jt(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 Ne(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((s,n)=>jt(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 Ut(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 me(e){let t=e&&typeof e=="object"?e:{},r=String(t.accountId??"").trim(),s=String(t.siteId??"").trim(),n=t.subscriber===true,i=Ut(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=Qe(t.subscriptionType);return p&&(l.subscriptionType=p),l}function qt(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function We(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function Qt(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 _e(e,t,r=5){let s=new URL(We(e)),n=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),i=s.protocol==="http:"?Ot:Dt,u=Qt(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(_e(new URL(g,s),{method:c===303?"GET":n},r-1));return}let f=new Headers;for(let[m,P]of Object.entries(d.headers))Array.isArray(P)?f.set(m,P.join(", ")):typeof P=="string"&&f.set(m,P);l(new Response(Buffer.concat(p),{status:c,statusText:d.statusMessage??"",headers:f}));});});o.on("error",a),o.end();})}function Nt(e){let t=me(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;qt(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 Wt(e){if(!Nt(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)=>We(i).startsWith(t)?_e(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 _t(e,t){let r=Et(t?.deploymentProfiles),s=String(t?.defaultDeploymentProfile??"").trim(),n=r[s]?s:"",i=Qe(t?.subscriptionType),u=me(e.wpsuite);return {...e,scheduler:Ne(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 fe(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 Bt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?h.resolve(e):""}function Ue(e,t,r){let s=String(t||"").trim();return s&&h.isAbsolute(s)?h.resolve(s):h.resolve(e,fe(s,r))}async function we(e){let t=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",r=await b.readFile(t,"utf8"),s=JSON.parse(r);s.sourceOrigin=s.sourceOrigin.replace(/\/$/,""),s.targetOrigin=qe(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=Ft(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=he(s.extraReplacements),s.postCrawlCopyMap=he(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=me(s.wpsuite),s.scheduler=Ne(void 0),s.deploymentProfiles={},s.defaultDeploymentProfile="",s.deploymentTargetOverride=String(s.deploymentTargetOverride??"").trim();let n=_t(s,await Wt(s)),i=Bt(),u=i?h.resolve(i,".."):"";return u?(n.outputDir=Ue(u,n.outputDir,"export"),n.logDir=Ue(u,n.logDir,"logs")):(h.isAbsolute(n.outputDir)||(n.outputDir=fe(n.outputDir,"export")),h.isAbsolute(n.logDir)||(n.logDir=fe(n.logDir,"logs"))),n}function oe(e,t=10){return Ht.createHash("sha1").update(e).digest("hex").slice(0,t)}async function Pe(e){await b.mkdir(h.dirname(e),{recursive:true});}function _(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(h.extname(e).toLowerCase())}function j(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function H(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function ie(e){return e.replace(/\//g,"\\/")}function Be(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 He(e,t,r){if(!t)return;e[t]=r;let s=ie(t),n=ie(r);e[s]=n;let i=Be(t),u=Be(r);e[i]=u;let l=H(t),a=H(r);e[l]=a;let o=H(s),d=H(n);e[o]=d;let p=H(i),c=H(u);e[p]=c;}function ae(e,t,r){He(e,t,r);let s=Jt(t);s&&s!==t&&He(e,s,r);}function Se(e,t){let r=t.startsWith("/")?t:`/${t}`,s=(e||"").replace(/\/$/,"");return !s||s==="."||s==="/"?r:`${s}${r}`}function ze(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function Je(e,t,r){if(!t)return r;let s=h.dirname(h.resolve(t)),n=h.resolve(e,r.replace(/^\/+/,"")),i=h.relative(s,n).replace(/\\/g,"/");return i?(i.startsWith(".")||(i=`./${i}`),i):"."}var Yt=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Zt=new Set([".html",".htm"]),Ve="WPSuite.io Static Publisher",Xt=Ve.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function er(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function tr(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function rr(e,t,r){return tr(t)?e.replace(new RegExp(`(?<!:)${er(t)}`,"g"),r):e.split(t).join(r)}function sr(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let n=h.extname(r).toLowerCase();return Zt.has(n)?/<head\b|<html\b|<!doctype html/i.test(t):false}function nr(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Xt}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${Ve}" />`;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
|
|
5
|
-
`,"utf8");}function
|
|
6
|
-
`,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>
|
|
4
|
+
`;return e.replace(/<head\b[^>]*>/i,n=>`${n}${s} ${t}`)}function ir(e){let t=j(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function or(e,t){let r=[...new Set(t)].filter(i=>i.includes("/")&&!/\\+\//.test(i)).map(i=>[i,ie(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)=>ir(a)?`${u}${s(a)}${o}`:i),n}function ar(e,t){if(!t)return null;let r=h.dirname(h.resolve(t)),s=h.resolve(e.outputDir),n=h.relative(r,s).replace(/\\/g,"/");return n?(n.startsWith(".")||(n=`./${n}`),n.endsWith("/")?n:`${n}/`):"./"}function ur(e,t,r){let s=ar(t,r);if(!s)return e;let n=e;for(let i of Yt){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"),f=new RegExp(`(?<![\\.\\\\])\\/${p}`,"g");n=n.replace(c,`${d}${o}`).replace(g,`${d}${o}`).replace(f,`${d}${o}`);}return n}function ye(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:ze(t,e.targetOrigin),i=s?`${s.search}${s.hash}`:"";return e.urlRewriteMode==="root-relative"?`${n}${i}`:`${Je(e.outputDir,r,n)}${i}`}function be(e,t,r,s,n){ae(e,r,ye(t,s,n));}function lr(e,t,r,s,n){if(!r||r===s)return;ae(e,r,s);let i=ye(t,r,n),u=ye(t,s,n);ae(e,i,u);}function ve(e,t,r,s,n={}){let i=e,u={};be(u,t,t.sourceOrigin,t.targetOrigin,s);for(let[a,o]of Object.entries(t.extraReplacements))be(u,t,a,o,s);for(let[a,o]of Object.entries(r))be(u,t,a,o,s);for(let[a,o]of Object.entries(n)){let d=r[a];!d||d===o||lr(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=rr(i,a,o);return t.urlRewriteMode!=="absolute"&&(i=ur(i,t,s)),i=or(i,l.map(([,a])=>a)),sr(t,i,s)&&(i=nr(i)),i}async function cr(e,t,r,s){let n=h.join(e.outputDir,s),i=h.extname(n).toLowerCase(),u;try{u=await b.readFile(n,"utf8");}catch(o){if(o.code!=="ENOENT")throw o;return {changed:false}}let a=ve(u,e,t,i===".js"||i===".mjs"?void 0:n,r);return a!==u?(await b.writeFile(n,a,"utf8"),{changed:true}):{changed:false}}async function dr(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 Ke(e,t,r={}){let n=(r.files?[...new Set(r.files)].map(c=>h.resolve(c)).filter(c=>c.startsWith(h.resolve(e.outputDir))).map(c=>h.relative(e.outputDir,c).replace(/\\/g,"/")).filter(c=>c.length>0):await Gt(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(c=>c!=="asset-map.json"&&_(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 cr(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 f=n[g],m=await dr(c,f);m.changed&&(i+=1),o+=1,await r.onProgress?.({index:o,totalFiles:n.length,changedTextFiles:i,file:f,changed:m.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 N={error:0,warn:1,info:2,debug:3},Ye=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",ue=Ye?h.join(Ye,"current-progress.json"):"",Ze=Promise.resolve();function Xe(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function pr(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 gr(e,t,r){ue&&(Ze=Ze.then(async()=>{let s=new Date,n=s.toISOString();await b.mkdir(h.dirname(ue),{recursive:true});let i=await b.readFile(ue,"utf8").then(m=>JSON.parse(m)).catch(()=>null),u=i&&typeof i.details=="object"&&i.details?i.details:{},l=Xe(e),a=i?.currentStep||Xe(i?.source||""),o=i?.startedAt||n,d={...i?.stepDurationsSec??{}},p=i?.stepStartedAt||n;if(a&&a!==l&&i?.stepStartedAt){let m=Math.max(0,Math.round((s.getTime()-new Date(i.stepStartedAt).getTime())/1e3));d[a]=(d[a]??0)+m,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)),f={checkedAt:n,source:e,message:t,details:pr(u,r??{}),startedAt:o,currentStep:l,stepStartedAt:p,stepElapsedSec:c,totalElapsedSec:g,stepDurationsSec:d};await b.writeFile(ue,JSON.stringify(f,null,2),"utf8");}).catch(()=>{}));}async function hr(e,t){await b.mkdir(h.dirname(e),{recursive:true}),await b.appendFile(e,`${JSON.stringify(t)}
|
|
5
|
+
`,"utf8");}function fr(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 mr(e,t,r){return {checkedAt:new Date().toISOString(),currentStep:fr(e,r),level:e,message:t,details:r??{}}}var Y=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 h.join(this.logDir,"crawl.log.jsonl")}get currentEventPath(){return h.join(this.logDir,"current-crawl-event.json")}get rejectedPath(){return h.join(this.logDir,"rejected.jsonl")}get ignoredPath(){return h.join(this.logDir,"ignored.jsonl")}get skippedPath(){return h.join(this.logDir,"skipped-http.jsonl")}get errorsPath(){return h.join(this.logDir,"errors.jsonl")}get timingsPath(){return h.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(()=>hr(t,r));}updateCurrentEvent(t,r,s){let n=mr(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||""):(N[this.level]>=N.debug||["summary","page","sitemap","asset","timing"].includes(t))&&console.log(r);}info(t,r){this.push("info",t,r);}debug(t,r){N[this.level]<N.debug||this.push("debug",t,r);}progress(t,r){gr("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),N[this.level]>=N.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),N[this.level]>=N.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 br=["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"],pt=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"]),gt=new Set(["",".html",".htm"]),yr=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),vr=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function Rr(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 Me(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?h.resolve(e):""}function Cr(){let e=Me();return e?h.resolve(e,".."):""}function xr(){let e=process.env.STATIC_PUBLISHER_WP_ROOT||process.env.WPSUITE_STATIC_PUBLISHER_WP_ROOT||"";return e.trim()?h.resolve(e):""}function kr(e){let t=e.trim(),r=[{alias:"@storage-root",root:Cr(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@runtime",root:Me(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@wp-root",root:xr(),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?h.resolve(s.root,n):s.root,alias:s.alias}}return {resolvedPath:h.resolve(t)}}function ht(e){let t=Me();return t?h.join(t,"crawl-manifest.json"):h.join(e.outputDir,".crawl-manifest.json")}function ft(){return {schemaVersion:3,updatedAt:"",pages:{},assets:{}}}function et(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 Tr(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 ke(e){let t=e?.["content-type"]?.trim();return t||null}function Ar(){return {rewriteTargets:new Set,changedFiles:new Set,deletedFiles:new Set}}function U(e,t,r){let s=ne(t.outputDir,r);s&&(e.changedFiles.add(s),e.deletedFiles.delete(s));}function tt(e,t,r){let s=ne(t.outputDir,r);s&&(e.deletedFiles.add(s),e.changedFiles.delete(s));}function X(e,t){e.rewriteTargets.add(h.resolve(t));}async function Mr(e){try{let t=await b.readFile(ht(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,et(n)])),assets:Object.fromEntries(Object.entries(r.assets).map(([s,n])=>[s,Tr(n)]))};if(r.schemaVersion===1)return {schemaVersion:3,updatedAt:String(r.updatedAt||""),pages:Object.fromEntries(Object.entries(r.pages).map(([s,n])=>[s,et(n)])),assets:{}}}}catch{}return ft()}function Te(e){return JSON.parse(JSON.stringify(e))}async function Lr(e,t){let r=ht(e);await b.mkdir(h.dirname(r),{recursive:true}),await b.writeFile(r,JSON.stringify(t,null,2),"utf8");}async function G(e,t){if(!t.trackManifest)return;let r=async()=>{let s=Te(t.manifest);s.updatedAt=new Date().toISOString(),t.manifest.updatedAt=s.updatedAt,await Lr(e,s);};t.manifestSaveChain=t.manifestSaveChain.then(r,r),await t.manifestSaveChain;}function Z(e){if(!e)return null;let t=e.trim();return t||null}function Ir(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 $r(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 Re(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 $r(e,t,[s],n)).get(s)??null;return Ie(e,s)&&(!u||u.supported!==true||!u.token)&&(u=await Or(e,t,s,n)),r.changeTokenCache.set(s,u),u}async function Or(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=oe(`${r}
|
|
7
7
|
404
|
|
8
|
-
${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 Or(e,t,r,s,n,i){let u=Le(e,n);if(!s.enabled)return {action:"render",changeToken:s.trackManifest?await Re(e,t,s,n,i):null};let l=s.manifest.pages[n];if(!l)return {action:"render",changeToken:await Re(e,t,s,n,i)};let a=await Re(e,t,s,n,i);if(a?.supported&&a.token)return l.changeToken===a.token?u&&!await Dr(e,t,n,i)?{action:"render",changeToken:a}:{action:"reuse",changeToken:a}:{action:"render",changeToken:a};let o=Z(r.sitemapLastmodByPage[n]);return o&&l.sitemapLastmod&&l.sitemapLastmod===o?{action:"reuse",changeToken:a}:{action:"render",changeToken:a}}async function Dr(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 Fr(e,t,r,s,n){let i=tt(r.previousManifest),u=0;for(let[c,g]of Object.entries(r.manifest.pages))if(!r.seenPages.has(c)){et(n,e,g.outputPath);try{await S.unlink(g.outputPath);}catch(f){(f.code||"")!=="ENOENT"&&s.warn(`Failed to remove stale incremental page output for ${c}`,{url:c,outputPath:g.outputPath,error:String(f)});}delete r.manifest.pages[c],u++;}let l=tt(r.manifest,r.runId),a=new Set,o=new Set;for(let c of l){for(let m of ee(e,c))a.add(m);let g=r.manifest.assets[c]?.outputPath;g&&o.add(g);let f=de(e,t.assetMap,c);f&&o.add(f);}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,f=r.previousManifest.assets[c]?.outputPath;f&&g.add(f);let m=de(e,t.assetMap,c);if(!l.has(c)&&m)g.add(m);else if(!l.has(c)){let P=Ie(e,c);g.add(P.originalFilePath),P.hashedFilePath&&g.add(P.hashedFilePath);}for(let P of g)if(!o.has(P)){et(n,e,P);try{await S.unlink(P),d++;}catch(w){(w.code||"")!=="ENOENT"&&s.warn(`Failed to remove stale incremental asset output for ${c}`,{url:c,outputPath:P,error:String(w)});}}for(let P of ee(e,c))a.has(P)||Object.prototype.hasOwnProperty.call(t.assetMap,P)&&(delete t.assetMap[P],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 tt(e,t){let r=new Set;for(let s of Object.values(e.pages))for(let n of s.discoveredAssets||[]){let i=n.trim();i&&r.add(i);}for(let[s,n]of Object.entries(e.assets||{})){if(t&&n.lastSeenRunId!==t)continue;let i=s.trim();i&&r.add(i);}return r}function rt(e,t,r){for(let s of t)for(let n of ee(e,s))if(r.has(n))return true;return false}function Er(e,t,r,s,n){let i=new Set(r.rewriteTargets);for(let l of Object.values(t.manifest.pages))l.rewriteComplete||i.add(h.resolve(l.outputPath));for(let l of Object.values(t.manifest.assets))l.isText&&!l.rewriteComplete&&i.add(h.resolve(l.outputPath));let u=Lr(s,n);if(u.size===0)return [...i];for(let l of Object.values(t.manifest.pages))rt(e,l.discoveredAssets,u)&&i.add(h.resolve(l.outputPath));for(let[l,a]of Object.entries(t.manifest.assets)){a.isText&&rt(e,a.discoveredAssets,u)&&i.add(h.resolve(a.outputPath));for(let o of ee(e,l))if(u.has(o)){U(r,e,a.outputPath),a.isText&&i.add(h.resolve(a.outputPath));break}}return [...i]}function jr(e,t){let r=t?new Set(Array.from(t,n=>h.resolve(n))):null,s=n=>r===null||r.has(h.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 ee(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 Ur(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 ft(e,t){let r=e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/"?e.targetOrigin:"https://relative.invalid/";try{let s=new URL(t,r);return h.join(e.outputDir,decodeURIComponent(s.pathname))}catch{return null}}function qr(e,t,r){for(let s of Ur(e,r)){let n=t[s];if(!n)continue;let i=ft(e,n);if(i)return {outputPath:i,publicUrl:n}}return null}function Qr(e,t,r){for(let s of ee(e,r)){let n=t[s];if(!n)continue;let i=ft(e,n);if(i)return i}return null}function de(e,t,r){let s=Qr(e,t,r);return s||Ie(e,r).originalFilePath}function Nr(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?h.join(h.resolve(e),"queue-runner-heartbeat.json"):""}async function st(e){let t=Nr();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 Wr(e,t){let r=new Set;for(let s of t.donePages)r.add(h.resolve(J(e,s)));for(let s of t.doneAssets){let n=de(e,t.assetMap,s);!n||!_(n)||r.add(h.resolve(n));}return [...r]}var pe="re:",le=new Map;function _r(e){if(!e.startsWith(pe))return null;let t=le.get(e);if(t!==void 0)return t||null;let r=e.slice(pe.length).trim();if(!r)return le.set(e,false),null;try{let s=new RegExp(r);return le.set(e,s),s}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),le.set(e,false),null}}function Me(e,t){let r=_r(t);return r?r.test(e):t.startsWith(pe)?false:e.startsWith(t)}function Br(e,t){return t.find(r=>Me(e,r))}function mt(e,t){let r=Br(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 Hr(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 zr(e,t){return Hr(e).has(t.hostname)}function Jr(e){let t=j(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function wt(e){let t=j(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function Gr(e){let t=j(e).replace(/\\\//g,"/").trim(),r=h.extname(t).toLowerCase();return dt.has(r)||pt.has(r)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function V(e){return yr.some(t=>e.pathname.startsWith(t))}function T(e,t,r=e.sourceOrigin,s,n="url"){let i=Jr(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(wt(i))return s?.ignore(n,t,"looks like JavaScript/code fragment",r),null;if(Gr(i))return s?.ignore(n,t,"looks like JavaScript property access",r),null;try{let u=new URL(i,r);if(!["http:","https:"].includes(u.protocol))return s?.ignore(n,t,"unsupported protocol: ",r),null;if(!zr(e,u))return s?.ignore(n,u.toString(),"host not allowed",r),null;let l=mt(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 Pt(e){return dt.has(h.extname(e.pathname).toLowerCase())}function B(e){return V(e)?false:pt.has(h.extname(e.pathname).toLowerCase())}function se(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function C(e,t){return !!(se(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(r=>Me(t.pathname,r))||Pt(t)||!B(t)&&!V(t))}function J(e,t){let r=new URL(t),s=decodeURIComponent(r.pathname);return s.endsWith("/")?s+="index.html":h.extname(s)||(s+="/index.html"),h.join(e.outputDir,s)}function Vr(e){if(!e.generated404RequestPath)return null;try{let t=new URL(e.generated404RequestPath,e.sourceOrigin);return !t.pathname.endsWith("/")&&h.extname(t.pathname)===""&&(t.pathname+="/"),t.hash="",t.toString()}catch{return null}}function Le(e,t){let r=Vr(e);if(!r)return false;try{return new URL(t,e.sourceOrigin).toString()===r}catch{return false}}function Ie(e,t){let r=new URL(t),s=decodeURIComponent(r.pathname);s.endsWith("/")&&(s+="index.html");let n=!!r.search,i=s,u=h.join(e.outputDir,i),l=Se(e.targetOrigin,i),a=`${l}${r.search}`;if(!n)return {originalPathname:i,originalFilePath:u,originalPublicUrl:l,originalPublicUrlWithSearch:a,preferQueryHashed:n};let o=h.extname(s),p=`${o?s.slice(0,-o.length):s}.${oe(r.search)}${o||".bin"}`;return {originalPathname:i,originalFilePath:u,originalPublicUrl:l,originalPublicUrlWithSearch:a,preferQueryHashed:n,hashedPathname:p,hashedFilePath:h.join(e.outputDir,p),hashedPublicUrl:Se(e.targetOrigin,p)}}function Kr(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 St(e){try{return await S.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function bt(e){try{return await S.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function Yr(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 yt(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let r=Date.parse(t);return Number.isFinite(r)?r:null}function Zr(e,t){let r=yt(t),s=Yr(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 Xr(e,t){if(!t)return;let r=yt(t);if(r===null)return;let s=await bt(e);if(!s)return;let n=new Date(r);await S.utimes(e,s.atime,n).catch(()=>{});}function nt(e,t){let r=h.extname(e.pathname).toLowerCase(),s=t["content-type"]||"";return br.has(r)||Sr.some(n=>s.includes(n))&&!s.startsWith("image/")&&!s.includes("font")}function Ce(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 es(e){return oe(e.toString("base64"),40)}function ts(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 rs(e,t,r){let s=e.assetVariantDigestsByOriginalPath.get(t);s||(s=new Set,e.assetVariantDigestsByOriginalPath.set(t,s)),s.add(r);}async function Te(e,t,r,s,n,i,u){let l=Ie(e,r),a=es(s),o=l.originalFilePath,d=l.originalPublicUrlWithSearch;if(l.preferQueryHashed&&l.hashedFilePath&&l.hashedPublicUrl&&ts(n,l.originalFilePath,a)){let f=qr(e,t,r);f?(o=f.outputPath,d=f.publicUrl):(o=l.hashedFilePath,d=l.hashedPublicUrl);}Kr(e,t,r,d,l.originalPublicUrl);let p=_(o)?Buffer.from(ve(s.toString("utf8"),e,t,o),"utf8"):s,c=await St(o),g=false;return (c===null||!c.equals(p))&&(await Pe(o),await S.writeFile(o,p),g=true),rs(n,l.originalFilePath,a),await Xr(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 te(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 se(c)?{discoveredFrom:p,discoveredFromType:"sitemap"}:C(e,c)?{discoveredFrom:p,discoveredFromType:"asset"}:B(c)&&!V(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=T(e,r,u,s,"page");if(!l)return;if(!B(l)||Pt(l)){if(C(e,l)){s.info(`Seeded/non-page URL queued as asset: ${l.toString()}`,{url:l.toString(),source:n}),L(e,t,l.toString(),s,n);return}s.reject("page",l.toString(),V(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:J(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 L(e,t,r,s,n){let i=n&&/^https?:\/\//i.test(n)?n:e.sourceOrigin,u=T(e,r,i,s,"asset");if(!u)return;if(!C(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 $e(e,t,r,s,n){let i=n&&/^https?:\/\//i.test(n)?n:e.sourceOrigin,u=T(e,r,i,s,"sitemap");if(!u)return;if(!se(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=j(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:Z(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 ns(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function is(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 os(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function as(e,t){if(t==="dom-style")return true;let r=(()=>{try{return h.extname(new URL(e).pathname).toLowerCase()}catch{return ""}})();return !(r===".js"||r===".mjs"||r===".map"||t.includes("javascript"))}function xe(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function vt(e,t){let r=[];await S.mkdir(t,{recursive:true});let s=await S.readdir(e,{withFileTypes:true});for(let n of s){let i=h.join(e,n.name),u=h.join(t,n.name);if(n.isDirectory()){r.push(...await vt(i,u));continue}await S.copyFile(i,u),r.push(u);}return r}async function us(e,t){let r=Object.entries(e.postCrawlCopyMap||{}).map(([i,u])=>({sourcePath:i.trim(),prefix:String(u||"").trim()}));if(r.length===0)return [];let s=0,n=[];t.mark("copy-extra-paths");for(let i of r){let u=i.sourcePath,l=i.prefix;if(!u||!l){t.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:u,prefixPath:l});continue}let a=xr(u);if(!a.resolvedPath){t.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:u,alias:a.alias||"",requiredEnv:a.requiredEnv||"",prefixPath:l});continue}let o=a.resolvedPath,d=xe(l);if(!d){t.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:u,prefixPath:l});continue}let p;try{p=await S.stat(o);}catch{t.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:u,sourceAbs:o,prefixPath:l});continue}let c=h.resolve(e.outputDir,d);if(p.isDirectory()){n.push(...await vt(o,c)),s++,t.progress(`Copied static directory to export: ${o} -> /${d}`,{phase:"copy-extra-paths",sourcePath:o,targetPath:`/${d}`,copiedItems:s});continue}let g=h.basename(o),f=l.endsWith("/")?h.join(c,g):c;await S.mkdir(h.dirname(f),{recursive:true}),await S.copyFile(o,f),n.push(f),s++,t.progress(`Copied static file to export: ${o} -> /${xe(l.endsWith("/")?`${l}${g}`:l)}`,{phase:"copy-extra-paths",sourcePath:o,targetPath:`/${xe(l.endsWith("/")?`${l}${g}`:l)}`,copiedItems:s});}return t.endMark("copy-extra-paths",{mappedSources:r.length,copiedItems:s}),n}function re(e,t,r,s,n){let i=new Set,u=j(r).replace(/\\\//g,"/"),l=n==="page-html"?os(u):u,a=as(t,n);if(a){for(let p of is(l)){let c=T(e,p,t,s,`${n}:css-url`);c&&C(e,c)&&i.add(c.toString());}for(let p of l.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let c=T(e,p[1],t,s,`${n}:css-import`);c&&C(e,c)&&i.add(c.toString());}}if(a||n==="page-html")for(let p of l.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let c=T(e,p[1],t,s,`${n}:xml-stylesheet`);c&&C(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(wt(c)){s.ignore(`${n}:serialized-url`,c,"looks like JavaScript/code fragment",t);continue}let g=T(e,c,t,s,`${n}:serialized-url`);g&&C(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 ls(e,t,r,s){let n=new Set,i=j(r);for(let u of i.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let l=u[1],a=T(e,l,t,s,"page-link");a&&(mt(e,a)||B(a)&&!V(a)&&!C(e,a)&&n.add(a.toString()));}return [...n]}async function it(e,t,r,s,n){for(;r.sitemapQueue.length>0;){let i=r.sitemapQueue.shift();if(r.queuedSitemaps.delete(i),!r.doneSitemaps.has(i)){r.doneSitemaps.add(i),s.sitemap(`Fetching sitemap ${i}`,{url:i});try{let u=await t.get(i,{timeout:6e4});if(!u.ok()){s.skip("sitemap",i,u.status());continue}let l=await u.body(),a=u.url()||i,o=await Te(e,r.assetMap,a,l,r,s);U(n,e,o.outputPath),X(n,o.outputPath);let d=l.toString("utf8");for(let p of re(e,a,d,s,"sitemap"))L(e,r,p,s,a);for(let p of ss(d)){let c=T(e,p.loc,a,s,"sitemap-loc");c&&(se(c)?$e(e,r,c.toString(),s,a):C(e,c)?L(e,r,c.toString(),s,a):B(c)?(p.lastmod&&(r.sitemapLastmodByPage[c.toString()]=p.lastmod),te(e,r,c.toString(),s,a)):s.reject("sitemap-loc",c.toString(),"not page/sitemap/asset-like",a));}}catch(u){s.error(`Failed sitemap ${i}`,{url:i,error:String(u)});}}}}async function cs(e,t,r,s,n,i,u){let l=T(e,s,e.sourceOrigin,n,"asset-fetch");if(!l||!C(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||[])L(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"}),Ce(r,n),true};n.asset(`Fetching asset ${a}`,{url:a});try{let p=de(e,r.assetMap,a),c=p?await bt(p):null;if(p&&c)try{let x=await t.head(a,{timeout:6e4}),A=x.headers();if(x.ok()&&Zr(c,A)){let F=await St(p);if(F!==null){let W=x.url()||a,M=await Te(e,r.assetMap,W,F,r,n,A);M.wroteFile&&(U(u,e,M.outputPath),_(M.outputPath)&&X(u,M.outputPath)),r.doneAssets.add(a),n.info(`Reused existing asset ${a} based on response headers.`,{url:a,filePath:p,lastModified:A["last-modified"]||"",contentLength:A["content-length"]||"",phase:"download-assets"}),Ce(r,n);let b=nt(l,A),R=o?.discoveredAssets?[...o.discoveredAssets]:[];if(b||o?.isText){let q=F.toString("utf8"),K=re(e,W,q,n,"asset:cached");(K.length>0||!o)&&(R=K);for(let xt of R)L(e,r,xt,n,W);}if(i.trackManifest){let q=b||!!o?.isText;i.manifest.assets[a]={url:a,outputPath:M.outputPath,isText:q,contentType:A["content-type"]?.split(";")[0].trim()||o?.contentType||null,discoveredAssets:R,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!q},delete i.manifest.pages[a],i.enabled&&q&&await G(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 f=await g.body(),m=g.url()||a,P=g.headers(),w=await Te(e,r.assetMap,m,f,r,n,P);w.wroteFile&&(U(u,e,w.outputPath),_(w.outputPath)&&X(u,w.outputPath)),r.doneAssets.add(a),Ce(r,n);let y=nt(l,P),v=[];if(y){let x=f.toString("utf8");v=re(e,m,x,n,`asset:${h.extname(l.pathname).toLowerCase()||P["content-type"]||"unknown"}`);for(let A of v)L(e,r,A,n,m);}i.trackManifest&&(i.manifest.assets[a]={url:a,outputPath:w.outputPath,isText:y,contentType:P["content-type"]?.split(";")[0].trim()||null,discoveredAssets:v,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!y},delete i.manifest.pages[a],i.enabled&&y&&await G(e,i));}catch(p){if(d("fetch-error",{error:String(p)}))return;n.error(`Failed asset ${a}`,{url:a,error:String(p)});}}async function ds(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 cs(e,t,r,a,s,n,i));}});await Promise.all(l);}function ps(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function D(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function ce(e){return Math.max(15e3,Math.min(6e4,D(e)))}function gs(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function Oe(e){return e.stats.pagesCompleted}function Rt(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 hs(e,t,r){let s=Rt(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 k(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 ${ps(t)}.`));},t);})])}finally{s!==void 0&&globalThis.clearTimeout(s);}}async function fs(e,t){let r=gs(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 ms(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 fs(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function ws(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 Ps(e,t){return e.noJavaScriptRenderPathPrefixes.some(r=>Me(t,r))}async function Ss(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 f of o){let m=c.getAttribute(f);m&&a.add(m);}for(let f of p){let m=c.getAttribute(f);m&&m.split(",").forEach(P=>{let w=P.trim().split(/\s+/)[0];w&&a.add(w);});}let g=c.getAttribute("style");g&&d.add(g);}),{attrs:[...a],styles:[...d]}});for(let a of l.attrs)for(let o of ns(a)){let d=T(e,o,r,s,"dom-attr");d&&C(e,d)&&i.add(d.toString());}for(let a of l.styles)for(let o of re(e,r,a,s,"dom-style"))i.add(o);}let u=await t.content();for(let l of re(e,r,u,s,"page-html"))i.add(l);return [...i]}async function ot(e,t,r,s,n){let i=J(e,t);await k(`save page ${t}`,D(e),async()=>{await Pe(i),await S.writeFile(i,r,"utf8");}),s.stats.pagesSaved++;let u=Math.min(s.stats.pagesQueued,Oe(s)+1);n&&(s.stats.pagesSaved%10===0||s.stats.pagesSaved===1)&&n.progress(`Page progress: processed ${u}, rendered ${s.stats.pagesRendered}, saved ${s.stats.pagesSaved}, discovered ${s.stats.pagesQueued}.`,{donePages:u,claimedPages:s.donePages.size,pagesRendered:s.stats.pagesRendered,pagesSaved:s.stats.pagesSaved,pagesQueued:s.stats.pagesQueued,pageQueue:s.pageQueue.length,phase:"save-pages"});}function bs(e){let t=Oe(e);return t%5===0||t===1||t===e.stats.pagesQueued}function ys(e,t){let r=Oe(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 vs(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 Rs(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 vs(s),s}async function Cs(e,t,r,s,n,i,u){let l=await chromium.launch({headless:true}),a=Rt(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;if(t.queuedPages.delete(o),t.donePages.has(o))continue;t.donePages.add(o),i.enabled&&i.seenPages.add(o);let d=null,p=null;try{let c=new URL(o),g=Le(e,o),f=Ps(e,c.pathname);if(!B(c)||C(e,c)||V(c)){if(C(e,c)){r.info(`Worker redirected non-page URL to asset queue: ${o}`,{url:o,source:"worker-guard"}),L(e,t,o,r,"worker-guard");continue}r.reject("page",o,"guard rejected non-page URL before rendering","worker");continue}let m=await Or(e,n,t,i,o,r);if(i.enabled&&s!=="single-url"){let b=i.manifest.pages[o];if(m.action==="reuse"&&b){for(let R of b.discoveredAssets)L(e,t,R,r,o);for(let R of b.discoveredPages)te(e,t,R,r,o);b.lastSeenRunId=i.runId,b.sitemapLastmod=Z(t.sitemapLastmodByPage[o])??b.sitemapLastmod,m.changeToken?.supported&&(b.changeToken=m.changeToken.token,b.tokenSource=m.changeToken.tokenSource??b.tokenSource),r.info(`Incremental reuse skipped unchanged page ${o}`,{url:o,mode:"incremental",reason:m.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}d=await k(`create page context ${o}`,D(e),()=>Rs(l,e,f)),p=await k(`create page ${o}`,D(e),()=>d.newPage());let P=!1,w=new Set;await p.route("**/*",async b=>{let R=b.request();if(R.isNavigationRequest()&&R.frame()===p.mainFrame())try{let q=new URL(R.url()),K=new URL(o);if(q.hash="",K.hash="",q.href===K.href){if(P){r.warn(`Blocked same-page navigation/reload for ${o}`,{url:o,requestUrl:R.url()}),await b.abort("aborted");return}P=!0;}}catch{}await b.continue();}),p.on("response",b=>{try{let R=T(e,b.url(),e.sourceOrigin,void 0,"network-response");R&&C(e,R)&&(w.add(R.toString()),L(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 k(`read response body ${o}`,D(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(g){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:J(e,o)});}else if(y&&!y.ok()){r.skip("page",o,y.status(),t.pageDiscoverySources.get(o)),await p.close();continue}f?(r.info(`Rendering without JS execution for ${o}`,{url:o,mode:"no-js"}),await k(`wait for rendered page ${o}`,D(e),()=>ws(e,p))):await k(`wait for rendered page ${o}`,D(e),()=>ms(e,p)),t.stats.pagesRendered++;let x=await k(`extract rendered assets ${o}`,D(e),()=>Ss(e,p,o,r,!f));for(let b of x)L(e,t,b,r,o);let A=[...new Set([...x,...w])],F=v??await k(`capture rendered html ${o}`,D(e),()=>p.content()),W=s!=="single-url"&&!g?ls(e,o,F,r):[];if(s!=="single-url"&&!g)for(let b of W)te(e,t,b,r,o);await ot(e,o,F,t,r);let M=J(e,o);U(u,e,M),X(u,M),i.trackManifest&&(i.manifest.pages[o]={url:o,outputPath:M,changeToken:m.changeToken?.supported?m.changeToken.token:null,tokenSource:m.changeToken?.supported?m.changeToken.tokenSource??null:null,sitemapLastmod:Z(t.sitemapLastmodByPage[o])??null,discoveredPages:W,discoveredAssets:A,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},i.enabled&&await G(e,i));}catch(c){try{let g=p?await k(`capture partial html ${o}`,D(e),()=>p.content()):"";if(g&&g.trim()){await ot(e,o,g,t,r);let f=J(e,o);if(U(u,e,f),X(u,f),i.trackManifest){let m=i.manifest.pages[o]??i.previousManifest.pages[o];i.manifest.pages[o]={url:o,outputPath:f,changeToken:null,tokenSource:null,sitemapLastmod:Z(t.sitemapLastmodByPage[o])??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 G(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++,bs(t)&&ys(t,r),p&&await k(`close page ${o}`,ce(e),()=>p.close()).catch(c=>{r.warn(`Timed out while closing page ${o}`,{url:o,browserPid:a.pid,error:String(c)});}),d&&await k(`close page context ${o}`,ce(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 k("close worker browser",ce(e),()=>l.close()).catch(o=>(r.warn("Timed out while closing crawl worker browser",{browserPid:a.pid,error:String(o)}),hs(l,r,"browser.close timeout")));}}async function xs(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 at(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function ks(e){let t=String(e?.job?.command||"").trim(),r=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:r!=="incremental"}function Ts(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 Ct(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 ut(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function As(e,t){let r=Array.isArray(t?.artifacts)?t.artifacts.filter(s=>String(s?.role||"").trim()==="errors"&&String(s?.storedFileName||"").trim()!=="").sort((s,n)=>ut(s)-ut(n)).map(s=>h.join(e,String(s.storedFileName))):[];return [...new Set([...r,h.join(e,"errors.jsonl"),h.join(e,"errors.json"),h.join(e,"errors.jsonl.gz"),h.join(e,"errors.json.gz")])]}async function lt(e){let t=await Ct(h.join(e,"job.json"));for(let r of As(e,t)){let s=await xs(r);if(s.length>0)return s}return []}async function Ms(e){let t=h.join(e.logDir,"archive"),r;try{r=await S.readdir(t);}catch{return ""}let s="",n=0;for(let i of r){let u=h.join(t,i);if(!(await S.stat(u).catch(()=>null))?.isDirectory())continue;let a=await Ct(h.join(u,"job.json"));if(!ks(a))continue;let o=Ts(a);o>=n&&(n=o,s=u);}return s}async function Ls(e){let t=await Ms(e),r=t!==""?await lt(t):await lt(e.logDir),s=new Set;for(let n of r)if(at(n.error)||at(n.message)){let i=n.url;typeof i=="string"&&i&&s.add(i);}return [...s]}async function Is(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 $s(e){try{let t=await S.readFile(h.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function Os(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(h.join(e,r));}catch(s){if(s.code!=="ENOENT")throw s}}));}function ct(e,t,r,s,n){let i=T(e,r,e.sourceOrigin,s,"manual-url");i&&(se(i)?$e(e,t,i.toString(),s,n):C(e,i)?L(e,t,i.toString(),s,n):B(i)?te(e,t,i.toString(),s,n):s.reject("manual-url",i.toString(),"not page/sitemap/asset-like",n));}async function Ds(){let e=await we(),t=vr(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 Ls(e)),t.mode==="single-url"&&(r=await Is(t.urls));let s=t.crawlMode==="incremental"&&t.mode==="full",n=s&&typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!=="",i=t.mode==="full"&&!t.resumeRewrite,u=t.mode!=="full"||t.resumeRewrite||n,l=u?await $s(e):{},a=n?await Ar(e):ht(),o={enabled:n,trackManifest:i,manifest:ke(a),previousManifest:ke(a),runId:`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve()};await Os(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=Tr();u||await S.rm(e.outputDir,{recursive:true,force:true}),await S.mkdir(e.outputDir,{recursive:true});let c=new Y(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 w=await request.newContext({ignoreHTTPSErrors:e.ignoreHttpsErrors});try{if(c.mark("discovery"),t.mode==="full"?(e.sitemapPaths.forEach(v=>$e(e,d,v,c)),await it(e,w,d,c,p),e.seedPaths.forEach(v=>ct(e,d,v,c,"seed-path")),e.generated404RequestPath&&te(e,d,e.generated404RequestPath,c,"generated-404-request-path")):(r.forEach(v=>ct(e,d,v,c,"cli")),await it(e,w,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)},()=>Cs(e,d,c,t.mode,w,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 ds(e,w,d,c,o,p),c.endMark("download-assets",{assets:d.doneAssets.size}),o.enabled&&e.maxPages===0&&await Fr(e,d,o,c,p),t.mode==="full"){let v=await us(e,c);for(let x of v)U(p,e,x);}}finally{await k("dispose crawl request context",ce(e),()=>w.dispose()).catch(y=>{c.warn("Timed out while disposing crawl request context",{error:String(y)});});}}o.trackManifest&&await G(e,o),await S.writeFile(h.join(e.outputDir,"asset-map.json"),JSON.stringify(d.assetMap,null,2),"utf8"),JSON.stringify(l,null,2)!==JSON.stringify(d.assetMap,null,2)&&U(p,e,h.join(e.outputDir,"asset-map.json"));let g=t.mode==="single-url"?Wr(e,d):o.enabled&&!t.resumeRewrite?Er(e,o,p,l,d.assetMap):void 0;c.mark("rewrite-text");let f=t.mode==="single-url"?`Rewriting text files touched by URL crawl: 0/${g?.length??0}`:"Rewriting text files...";c.progress(f,{phase:"rewrite-text",index:0,totalFiles:g?.length,changedTextFiles:0}),await st(f);let m=Date.now(),P=await Ve(e,d.assetMap,{files:g,previousAssetMap:l,onProgress:async({index:w,totalFiles:y,changedTextFiles:v,file:x,changed:A})=>{A&&U(p,e,h.join(e.outputDir,x)),c.checkpoint(`Rewriting text file ${w}/${y}`,{phase:"rewrite-text",index:w,totalFiles:y,changedTextFiles:v,file:x});let F=Date.now();if(!(w===1||w===y||F-m>=5e3))return;m=F;let M=`Rewriting text files: ${w}/${y}`;c.progress(M,{phase:"rewrite-text",index:w,totalFiles:y,changedTextFiles:v,file:x}),await st(M);}});o.trackManifest&&(jr(o,g),await G(e,o)),c.endMark("rewrite-text",{changedTextFiles:P}),await Ee(e,{generatedAt:new Date().toISOString(),outputDir:h.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?[...p.deletedFiles].sort():[],rewriteTargets:o.enabled&&!t.resumeRewrite?[...new Set((g||[]).map(w=>ne(e.outputDir,h.isAbsolute(w)?w:h.join(e.outputDir,w))).filter(w=>w!==null))].sort():[]}),c.summary(t.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${P} 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:P}),await c.flush();}Ds().catch(async e=>{console.error(e);try{let r=(await we().catch(()=>null))?.logDir??"logs",s=new Y(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);});
|
|
8
|
+
${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 Dr(e,t,r,s,n,i){let u=Ie(e,n);if(!s.enabled)return {action:"render",changeToken:s.trackManifest?await Re(e,t,s,n,i):null};let l=s.manifest.pages[n];if(!l)return {action:"render",changeToken:await Re(e,t,s,n,i)};let a=await Re(e,t,s,n,i);if(a?.supported&&a.token)return l.changeToken===a.token?u&&!await Fr(e,t,n,i)?{action:"render",changeToken:a}:{action:"reuse",changeToken:a}:{action:"render",changeToken:a};let o=Z(r.sitemapLastmodByPage[n]);return o&&l.sitemapLastmod&&l.sitemapLastmod===o?{action:"reuse",changeToken:a}:{action:"render",changeToken:a}}async function Fr(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 Er(e,t,r,s,n){let i=rt(r.previousManifest),u=0;for(let[c,g]of Object.entries(r.manifest.pages))if(!r.seenPages.has(c)){tt(n,e,g.outputPath);try{await b.unlink(g.outputPath);}catch(f){(f.code||"")!=="ENOENT"&&s.warn(`Failed to remove stale incremental page output for ${c}`,{url:c,outputPath:g.outputPath,error:String(f)});}delete r.manifest.pages[c],u++;}let l=rt(r.manifest,r.runId),a=new Set,o=new Set;for(let c of l){for(let m of ee(e,c))a.add(m);let g=r.manifest.assets[c]?.outputPath;g&&o.add(g);let f=de(e,t.assetMap,c);f&&o.add(f);}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,f=r.previousManifest.assets[c]?.outputPath;f&&g.add(f);let m=de(e,t.assetMap,c);if(!l.has(c)&&m)g.add(m);else if(!l.has(c)){let P=$e(e,c);g.add(P.originalFilePath),P.hashedFilePath&&g.add(P.hashedFilePath);}for(let P of g)if(!o.has(P)){tt(n,e,P);try{await b.unlink(P),d++;}catch(w){(w.code||"")!=="ENOENT"&&s.warn(`Failed to remove stale incremental asset output for ${c}`,{url:c,outputPath:P,error:String(w)});}}for(let P of ee(e,c))a.has(P)||Object.prototype.hasOwnProperty.call(t.assetMap,P)&&(delete t.assetMap[P],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 rt(e,t){let r=new Set;for(let s of Object.values(e.pages))for(let n of s.discoveredAssets||[]){let i=n.trim();i&&r.add(i);}for(let[s,n]of Object.entries(e.assets||{})){if(t&&n.lastSeenRunId!==t)continue;let i=s.trim();i&&r.add(i);}return r}function st(e,t,r){for(let s of t)for(let n of ee(e,s))if(r.has(n))return true;return false}function jr(e,t,r,s,n){let i=new Set(r.rewriteTargets);for(let l of Object.values(t.manifest.pages))l.rewriteComplete||i.add(h.resolve(l.outputPath));for(let l of Object.values(t.manifest.assets))l.isText&&!l.rewriteComplete&&i.add(h.resolve(l.outputPath));let u=Ir(s,n);if(u.size===0)return [...i];for(let l of Object.values(t.manifest.pages))st(e,l.discoveredAssets,u)&&i.add(h.resolve(l.outputPath));for(let[l,a]of Object.entries(t.manifest.assets)){a.isText&&st(e,a.discoveredAssets,u)&&i.add(h.resolve(a.outputPath));for(let o of ee(e,l))if(u.has(o)){U(r,e,a.outputPath),a.isText&&i.add(h.resolve(a.outputPath));break}}return [...i]}function Ur(e,t){let r=t?new Set(Array.from(t,n=>h.resolve(n))):null,s=n=>r===null||r.has(h.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 ee(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 qr(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 mt(e,t){let r=e.targetOrigin&&e.targetOrigin!=="."&&e.targetOrigin!=="/"?e.targetOrigin:"https://relative.invalid/";try{let s=new URL(t,r);return h.join(e.outputDir,decodeURIComponent(s.pathname))}catch{return null}}function Qr(e,t,r){for(let s of qr(e,r)){let n=t[s];if(!n)continue;let i=mt(e,n);if(i)return {outputPath:i,publicUrl:n}}return null}function Nr(e,t,r){for(let s of ee(e,r)){let n=t[s];if(!n)continue;let i=mt(e,n);if(i)return i}return null}function de(e,t,r){let s=Nr(e,t,r);return s||$e(e,r).originalFilePath}function Wr(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?h.join(h.resolve(e),"queue-runner-heartbeat.json"):""}async function nt(e){let t=Wr();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 _r(e,t){let r=new Set;for(let s of t.donePages)r.add(h.resolve(J(e,s)));for(let s of t.doneAssets){let n=de(e,t.assetMap,s);!n||!_(n)||r.add(h.resolve(n));}return [...r]}var pe="re:",le=new Map;function Br(e){if(!e.startsWith(pe))return null;let t=le.get(e);if(t!==void 0)return t||null;let r=e.slice(pe.length).trim();if(!r)return le.set(e,false),null;try{let s=new RegExp(r);return le.set(e,s),s}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),le.set(e,false),null}}function Le(e,t){let r=Br(t);return r?r.test(e):t.startsWith(pe)?false:e.startsWith(t)}function Hr(e,t){return t.find(r=>Le(e,r))}function wt(e,t){let r=Hr(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 zr(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 Jr(e,t){return zr(e).has(t.hostname)}function Gr(e){let t=j(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function Pt(e){let t=j(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)||/[()[\]'"]/.test(t)}function Vr(e){let t=j(e).replace(/\\\//g,"/").trim(),r=h.extname(t).toLowerCase();return pt.has(r)||gt.has(r)?false:/^(?:this|[A-Za-z_$][\w$]*)\.[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(t)}function V(e){return vr.some(t=>e.pathname.startsWith(t))}function T(e,t,r=e.sourceOrigin,s,n="url"){let i=Gr(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(Pt(i))return s?.ignore(n,t,"looks like JavaScript/code fragment",r),null;if(Vr(i))return s?.ignore(n,t,"looks like JavaScript property access",r),null;try{let u=new URL(i,r);if(!["http:","https:"].includes(u.protocol))return s?.ignore(n,t,"unsupported protocol: ",r),null;if(!Jr(e,u))return s?.ignore(n,u.toString(),"host not allowed",r),null;let l=wt(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 St(e){return pt.has(h.extname(e.pathname).toLowerCase())}function B(e){return V(e)?false:gt.has(h.extname(e.pathname).toLowerCase())}function se(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function C(e,t){return !!(se(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")||e.assetPathPrefixes.length>0&&e.assetPathPrefixes.some(r=>Le(t.pathname,r))||St(t)||!B(t)&&!V(t))}function J(e,t){let r=new URL(t),s=decodeURIComponent(r.pathname);return s.endsWith("/")?s+="index.html":h.extname(s)||(s+="/index.html"),h.join(e.outputDir,s)}function Kr(e){if(!e.generated404RequestPath)return null;try{let t=new URL(e.generated404RequestPath,e.sourceOrigin);return !t.pathname.endsWith("/")&&h.extname(t.pathname)===""&&(t.pathname+="/"),t.hash="",t.toString()}catch{return null}}function Ie(e,t){let r=Kr(e);if(!r)return false;try{return new URL(t,e.sourceOrigin).toString()===r}catch{return false}}function $e(e,t){let r=new URL(t),s=decodeURIComponent(r.pathname);s.endsWith("/")&&(s+="index.html");let n=!!r.search,i=s,u=h.join(e.outputDir,i),l=Se(e.targetOrigin,i),a=`${l}${r.search}`;if(!n)return {originalPathname:i,originalFilePath:u,originalPublicUrl:l,originalPublicUrlWithSearch:a,preferQueryHashed:n};let o=h.extname(s),p=`${o?s.slice(0,-o.length):s}.${oe(r.search)}${o||".bin"}`;return {originalPathname:i,originalFilePath:u,originalPublicUrl:l,originalPublicUrlWithSearch:a,preferQueryHashed:n,hashedPathname:p,hashedFilePath:h.join(e.outputDir,p),hashedPublicUrl:Se(e.targetOrigin,p)}}function Yr(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 bt(e){try{return await b.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function yt(e){try{return await b.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function Zr(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 vt(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let r=Date.parse(t);return Number.isFinite(r)?r:null}function Xr(e,t){let r=vt(t),s=Zr(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 es(e,t){if(!t)return;let r=vt(t);if(r===null)return;let s=await yt(e);if(!s)return;let n=new Date(r);await b.utimes(e,s.atime,n).catch(()=>{});}function it(e,t){let r=h.extname(e.pathname).toLowerCase(),s=t["content-type"]||"";return yr.has(r)||br.some(n=>s.includes(n))&&!s.startsWith("image/")&&!s.includes("font")}function Ce(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 ts(e){return oe(e.toString("base64"),40)}function rs(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 ss(e,t,r){let s=e.assetVariantDigestsByOriginalPath.get(t);s||(s=new Set,e.assetVariantDigestsByOriginalPath.set(t,s)),s.add(r);}async function Ae(e,t,r,s,n,i,u){let l=$e(e,r),a=ts(s),o=l.originalFilePath,d=l.originalPublicUrlWithSearch;if(l.preferQueryHashed&&l.hashedFilePath&&l.hashedPublicUrl&&rs(n,l.originalFilePath,a)){let f=Qr(e,t,r);f?(o=f.outputPath,d=f.publicUrl):(o=l.hashedFilePath,d=l.hashedPublicUrl);}Yr(e,t,r,d,l.originalPublicUrl);let p=_(o)?Buffer.from(ve(s.toString("utf8"),e,t,o),"utf8"):s,c=await bt(o),g=false;return (c===null||!c.equals(p))&&(await Pe(o),await b.writeFile(o,p),g=true),ss(n,l.originalFilePath,a),await es(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 te(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 se(c)?{discoveredFrom:p,discoveredFromType:"sitemap"}:C(e,c)?{discoveredFrom:p,discoveredFromType:"asset"}:B(c)&&!V(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=T(e,r,u,s,"page");if(!l)return;if(!B(l)||St(l)){if(C(e,l)){s.info(`Seeded/non-page URL queued as asset: ${l.toString()}`,{url:l.toString(),source:n}),L(e,t,l.toString(),s,n);return}s.reject("page",l.toString(),V(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:J(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 L(e,t,r,s,n){let i=n&&/^https?:\/\//i.test(n)?n:e.sourceOrigin,u=T(e,r,i,s,"asset");if(!u)return;if(!C(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 Oe(e,t,r,s,n){let i=n&&/^https?:\/\//i.test(n)?n:e.sourceOrigin,u=T(e,r,i,s,"sitemap");if(!u)return;if(!se(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 ns(e){let t=j(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:Z(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 is(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function os(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 as(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,"")}function us(e,t){if(t==="dom-style")return true;let r=(()=>{try{return h.extname(new URL(e).pathname).toLowerCase()}catch{return ""}})();return !(r===".js"||r===".mjs"||r===".map"||t.includes("javascript"))}function xe(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function Rt(e,t){let r=[];await b.mkdir(t,{recursive:true});let s=await b.readdir(e,{withFileTypes:true});for(let n of s){let i=h.join(e,n.name),u=h.join(t,n.name);if(n.isDirectory()){r.push(...await Rt(i,u));continue}await b.copyFile(i,u),r.push(u);}return r}async function ls(e,t){let r=Object.entries(e.postCrawlCopyMap||{}).map(([i,u])=>({sourcePath:i.trim(),prefix:String(u||"").trim()}));if(r.length===0)return [];let s=0,n=[];t.mark("copy-extra-paths");for(let i of r){let u=i.sourcePath,l=i.prefix;if(!u||!l){t.warn("Skipped post-crawl copy mapping with empty key/value",{sourcePath:u,prefixPath:l});continue}let a=kr(u);if(!a.resolvedPath){t.warn("Skipped post-crawl copy source because alias root is not configured",{sourcePath:u,alias:a.alias||"",requiredEnv:a.requiredEnv||"",prefixPath:l});continue}let o=a.resolvedPath,d=xe(l);if(!d){t.warn("Skipped post-crawl copy mapping with invalid export prefix",{sourcePath:u,prefixPath:l});continue}let p;try{p=await b.stat(o);}catch{t.warn("Skipped post-crawl copy source because it does not exist",{sourcePath:u,sourceAbs:o,prefixPath:l});continue}let c=h.resolve(e.outputDir,d);if(p.isDirectory()){n.push(...await Rt(o,c)),s++,t.progress(`Copied static directory to export: ${o} -> /${d}`,{phase:"copy-extra-paths",sourcePath:o,targetPath:`/${d}`,copiedItems:s});continue}let g=h.basename(o),f=l.endsWith("/")?h.join(c,g):c;await b.mkdir(h.dirname(f),{recursive:true}),await b.copyFile(o,f),n.push(f),s++,t.progress(`Copied static file to export: ${o} -> /${xe(l.endsWith("/")?`${l}${g}`:l)}`,{phase:"copy-extra-paths",sourcePath:o,targetPath:`/${xe(l.endsWith("/")?`${l}${g}`:l)}`,copiedItems:s});}return t.endMark("copy-extra-paths",{mappedSources:r.length,copiedItems:s}),n}function re(e,t,r,s,n){let i=new Set,u=j(r).replace(/\\\//g,"/"),l=n==="page-html"?as(u):u,a=us(t,n);if(a){for(let p of os(l)){let c=T(e,p,t,s,`${n}:css-url`);c&&C(e,c)&&i.add(c.toString());}for(let p of l.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let c=T(e,p[1],t,s,`${n}:css-import`);c&&C(e,c)&&i.add(c.toString());}}if(a||n==="page-html")for(let p of l.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let c=T(e,p[1],t,s,`${n}:xml-stylesheet`);c&&C(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(Pt(c)){s.ignore(`${n}:serialized-url`,c,"looks like JavaScript/code fragment",t);continue}let g=T(e,c,t,s,`${n}:serialized-url`);g&&C(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 cs(e,t,r,s){let n=new Set,i=j(r);for(let u of i.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let l=u[1],a=T(e,l,t,s,"page-link");a&&(wt(e,a)||B(a)&&!V(a)&&!C(e,a)&&n.add(a.toString()));}return [...n]}async function ot(e,t,r,s,n){for(;r.sitemapQueue.length>0;){let i=r.sitemapQueue.shift();if(r.queuedSitemaps.delete(i),!r.doneSitemaps.has(i)){r.doneSitemaps.add(i),s.sitemap(`Fetching sitemap ${i}`,{url:i});try{let u=await t.get(i,{timeout:6e4});if(!u.ok()){s.skip("sitemap",i,u.status());continue}let l=await u.body(),a=u.url()||i,o=await Ae(e,r.assetMap,a,l,r,s);U(n,e,o.outputPath),X(n,o.outputPath);let d=l.toString("utf8");for(let p of re(e,a,d,s,"sitemap"))L(e,r,p,s,a);for(let p of ns(d)){let c=T(e,p.loc,a,s,"sitemap-loc");c&&(se(c)?Oe(e,r,c.toString(),s,a):C(e,c)?L(e,r,c.toString(),s,a):B(c)?(p.lastmod&&(r.sitemapLastmodByPage[c.toString()]=p.lastmod),te(e,r,c.toString(),s,a)):s.reject("sitemap-loc",c.toString(),"not page/sitemap/asset-like",a));}}catch(u){s.error(`Failed sitemap ${i}`,{url:i,error:String(u)});}}}}async function ds(e,t,r,s,n,i,u){let l=T(e,s,e.sourceOrigin,n,"asset-fetch");if(!l||!C(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||[])L(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"}),Ce(r,n),true};n.asset(`Fetching asset ${a}`,{url:a});try{let p=de(e,r.assetMap,a),c=p?await yt(p):null;if(p&&c)try{let x=await t.head(a,{timeout:6e4}),A=x.headers();if(x.ok()&&Xr(c,A)){let F=await bt(p);if(F!==null){let W=x.url()||a,M=await Ae(e,r.assetMap,W,F,r,n,A);M.wroteFile&&(U(u,e,M.outputPath),_(M.outputPath)&&X(u,M.outputPath)),r.doneAssets.add(a),n.info(`Reused existing asset ${a} based on response headers.`,{url:a,filePath:p,lastModified:A["last-modified"]||"",contentLength:A["content-length"]||"",phase:"download-assets"}),Ce(r,n);let S=it(l,A),R=o?.discoveredAssets?[...o.discoveredAssets]:[];if(S||o?.isText){let q=F.toString("utf8"),K=re(e,W,q,n,"asset:cached");(K.length>0||!o)&&(R=K);for(let kt of R)L(e,r,kt,n,W);}if(i.trackManifest){let q=S||!!o?.isText;i.manifest.assets[a]={url:a,outputPath:M.outputPath,isText:q,contentType:ke(A)||o?.contentType||null,discoveredAssets:R,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!q},delete i.manifest.pages[a],i.enabled&&q&&await G(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 f=await g.body(),m=g.url()||a,P=g.headers(),w=await Ae(e,r.assetMap,m,f,r,n,P);w.wroteFile&&(U(u,e,w.outputPath),_(w.outputPath)&&X(u,w.outputPath)),r.doneAssets.add(a),Ce(r,n);let y=it(l,P),v=[];if(y){let x=f.toString("utf8");v=re(e,m,x,n,`asset:${h.extname(l.pathname).toLowerCase()||P["content-type"]||"unknown"}`);for(let A of v)L(e,r,A,n,m);}i.trackManifest&&(i.manifest.assets[a]={url:a,outputPath:w.outputPath,isText:y,contentType:ke(P),discoveredAssets:v,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!y},delete i.manifest.pages[a],i.enabled&&y&&await G(e,i));}catch(p){if(d("fetch-error",{error:String(p)}))return;n.error(`Failed asset ${a}`,{url:a,error:String(p)});}}async function ps(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 ds(e,t,r,a,s,n,i));}});await Promise.all(l);}function gs(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function D(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function ce(e){return Math.max(15e3,Math.min(6e4,D(e)))}function hs(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function De(e){return e.stats.pagesCompleted}function Ct(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 fs(e,t,r){let s=Ct(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 k(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 ${gs(t)}.`));},t);})])}finally{s!==void 0&&globalThis.clearTimeout(s);}}async function ms(e,t){let r=hs(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 ws(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 ms(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function Ps(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 Ss(e,t){return e.noJavaScriptRenderPathPrefixes.some(r=>Le(t,r))}async function bs(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 f of o){let m=c.getAttribute(f);m&&a.add(m);}for(let f of p){let m=c.getAttribute(f);m&&m.split(",").forEach(P=>{let w=P.trim().split(/\s+/)[0];w&&a.add(w);});}let g=c.getAttribute("style");g&&d.add(g);}),{attrs:[...a],styles:[...d]}});for(let a of l.attrs)for(let o of is(a)){let d=T(e,o,r,s,"dom-attr");d&&C(e,d)&&i.add(d.toString());}for(let a of l.styles)for(let o of re(e,r,a,s,"dom-style"))i.add(o);}let u=await t.content();for(let l of re(e,r,u,s,"page-html"))i.add(l);return [...i]}async function at(e,t,r,s,n){let i=J(e,t);await k(`save page ${t}`,D(e),async()=>{await Pe(i),await b.writeFile(i,r,"utf8");}),s.stats.pagesSaved++;let u=Math.min(s.stats.pagesQueued,De(s)+1);n&&(s.stats.pagesSaved%10===0||s.stats.pagesSaved===1)&&n.progress(`Page progress: processed ${u}, rendered ${s.stats.pagesRendered}, saved ${s.stats.pagesSaved}, discovered ${s.stats.pagesQueued}.`,{donePages:u,claimedPages:s.donePages.size,pagesRendered:s.stats.pagesRendered,pagesSaved:s.stats.pagesSaved,pagesQueued:s.stats.pagesQueued,pageQueue:s.pageQueue.length,phase:"save-pages"});}function ys(e){let t=De(e);return t%5===0||t===1||t===e.stats.pagesQueued}function vs(e,t){let r=De(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 Rs(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 Cs(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 Rs(s),s}async function xs(e,t,r,s,n,i,u){let l=await chromium.launch({headless:true}),a=Ct(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;if(t.queuedPages.delete(o),t.donePages.has(o))continue;t.donePages.add(o),i.enabled&&i.seenPages.add(o);let d=null,p=null;try{let c=new URL(o),g=Ie(e,o),f=Ss(e,c.pathname);if(!B(c)||C(e,c)||V(c)){if(C(e,c)){r.info(`Worker redirected non-page URL to asset queue: ${o}`,{url:o,source:"worker-guard"}),L(e,t,o,r,"worker-guard");continue}r.reject("page",o,"guard rejected non-page URL before rendering","worker");continue}let m=await Dr(e,n,t,i,o,r);if(i.enabled&&s!=="single-url"){let S=i.manifest.pages[o];if(m.action==="reuse"&&S){for(let R of S.discoveredAssets)L(e,t,R,r,o);for(let R of S.discoveredPages)te(e,t,R,r,o);S.lastSeenRunId=i.runId,S.sitemapLastmod=Z(t.sitemapLastmodByPage[o])??S.sitemapLastmod,m.changeToken?.supported&&(S.changeToken=m.changeToken.token,S.tokenSource=m.changeToken.tokenSource??S.tokenSource),r.info(`Incremental reuse skipped unchanged page ${o}`,{url:o,mode:"incremental",reason:m.changeToken?.supported===!0?"change-token-match":"sitemap-lastmod-match"});continue}}d=await k(`create page context ${o}`,D(e),()=>Cs(l,e,f)),p=await k(`create page ${o}`,D(e),()=>d.newPage());let P=!1,w=new Set;await p.route("**/*",async S=>{let R=S.request();if(R.isNavigationRequest()&&R.frame()===p.mainFrame())try{let q=new URL(R.url()),K=new URL(o);if(q.hash="",K.hash="",q.href===K.href){if(P){r.warn(`Blocked same-page navigation/reload for ${o}`,{url:o,requestUrl:R.url()}),await S.abort("aborted");return}P=!0;}}catch{}await S.continue();}),p.on("response",S=>{try{let R=T(e,S.url(),e.sourceOrigin,void 0,"network-response");R&&C(e,R)&&(w.add(R.toString()),L(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 k(`read response body ${o}`,D(e),()=>y.text());}catch{v=null;}}catch(S){r.warn(`Navigation issue for ${o}; saving current DOM if available`,{url:o,error:String(S)});}if(g){let S=y?.status()??null;if(S!==404){r.error(`Generated 404 request path returned unexpected status for ${o}`,{url:o,expectedStatus:404,status:S,requestPath:e.generated404RequestPath});continue}r.info(`Capturing rendered 404 page for ${o}`,{url:o,status:S,outputPath:J(e,o)});}else if(y&&!y.ok()){r.skip("page",o,y.status(),t.pageDiscoverySources.get(o)),await p.close();continue}f?(r.info(`Rendering without JS execution for ${o}`,{url:o,mode:"no-js"}),await k(`wait for rendered page ${o}`,D(e),()=>Ps(e,p))):await k(`wait for rendered page ${o}`,D(e),()=>ws(e,p)),t.stats.pagesRendered++;let x=await k(`extract rendered assets ${o}`,D(e),()=>bs(e,p,o,r,!f));for(let S of x)L(e,t,S,r,o);let A=[...new Set([...x,...w])],F=v??await k(`capture rendered html ${o}`,D(e),()=>p.content()),W=s!=="single-url"&&!g?cs(e,o,F,r):[];if(s!=="single-url"&&!g)for(let S of W)te(e,t,S,r,o);await at(e,o,F,t,r);let M=J(e,o);if(U(u,e,M),X(u,M),i.trackManifest){let S=y?.headers();i.manifest.pages[o]={url:o,outputPath:M,contentType:ke(S),changeToken:m.changeToken?.supported?m.changeToken.token:null,tokenSource:m.changeToken?.supported?m.changeToken.tokenSource??null:null,sitemapLastmod:Z(t.sitemapLastmodByPage[o])??null,discoveredPages:W,discoveredAssets:A,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},i.enabled&&await G(e,i);}}catch(c){try{let g=p?await k(`capture partial html ${o}`,D(e),()=>p.content()):"";if(g&&g.trim()){await at(e,o,g,t,r);let f=J(e,o);if(U(u,e,f),X(u,f),i.trackManifest){let m=i.manifest.pages[o]??i.previousManifest.pages[o];i.manifest.pages[o]={url:o,outputPath:f,contentType:m?.contentType??null,changeToken:null,tokenSource:null,sitemapLastmod:Z(t.sitemapLastmodByPage[o])??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 G(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++,ys(t)&&vs(t,r),p&&await k(`close page ${o}`,ce(e),()=>p.close()).catch(c=>{r.warn(`Timed out while closing page ${o}`,{url:o,browserPid:a.pid,error:String(c)});}),d&&await k(`close page context ${o}`,ce(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 k("close worker browser",ce(e),()=>l.close()).catch(o=>(r.warn("Timed out while closing crawl worker browser",{browserPid:a.pid,error:String(o)}),fs(l,r,"browser.close timeout")));}}async function ks(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 ut(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function Ts(e){let t=String(e?.job?.command||"").trim(),r=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:r!=="incremental"}function As(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 xt(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 lt(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function Ms(e,t){let r=Array.isArray(t?.artifacts)?t.artifacts.filter(s=>String(s?.role||"").trim()==="errors"&&String(s?.storedFileName||"").trim()!=="").sort((s,n)=>lt(s)-lt(n)).map(s=>h.join(e,String(s.storedFileName))):[];return [...new Set([...r,h.join(e,"errors.jsonl"),h.join(e,"errors.json"),h.join(e,"errors.jsonl.gz"),h.join(e,"errors.json.gz")])]}async function ct(e){let t=await xt(h.join(e,"job.json"));for(let r of Ms(e,t)){let s=await ks(r);if(s.length>0)return s}return []}async function Ls(e){let t=h.join(e.logDir,"archive"),r;try{r=await b.readdir(t);}catch{return ""}let s="",n=0;for(let i of r){let u=h.join(t,i);if(!(await b.stat(u).catch(()=>null))?.isDirectory())continue;let a=await xt(h.join(u,"job.json"));if(!Ts(a))continue;let o=As(a);o>=n&&(n=o,s=u);}return s}async function Is(e){let t=await Ls(e),r=t!==""?await ct(t):await ct(e.logDir),s=new Set;for(let n of r)if(ut(n.error)||ut(n.message)){let i=n.url;typeof i=="string"&&i&&s.add(i);}return [...s]}async function $s(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 Os(e){try{let t=await b.readFile(h.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function Ds(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(h.join(e,r));}catch(s){if(s.code!=="ENOENT")throw s}}));}function dt(e,t,r,s,n){let i=T(e,r,e.sourceOrigin,s,"manual-url");i&&(se(i)?Oe(e,t,i.toString(),s,n):C(e,i)?L(e,t,i.toString(),s,n):B(i)?te(e,t,i.toString(),s,n):s.reject("manual-url",i.toString(),"not page/sitemap/asset-like",n));}async function Fs(){let e=await we(),t=Rr(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 Is(e)),t.mode==="single-url"&&(r=await $s(t.urls));let s=t.crawlMode==="incremental"&&t.mode==="full",n=s&&typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!=="",i=t.mode==="full"&&!t.resumeRewrite,u=t.mode!=="full"||t.resumeRewrite||n,l=u?await Os(e):{},a=n?await Mr(e):ft(),o={enabled:n,trackManifest:i,manifest:Te(a),previousManifest:Te(a),runId:`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve()};await Ds(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=Ar();u||await b.rm(e.outputDir,{recursive:true,force:true}),await b.mkdir(e.outputDir,{recursive:true});let c=new Y(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 w=await request.newContext({ignoreHTTPSErrors:e.ignoreHttpsErrors});try{if(c.mark("discovery"),t.mode==="full"?(e.sitemapPaths.forEach(v=>Oe(e,d,v,c)),await ot(e,w,d,c,p),e.seedPaths.forEach(v=>dt(e,d,v,c,"seed-path")),e.generated404RequestPath&&te(e,d,e.generated404RequestPath,c,"generated-404-request-path")):(r.forEach(v=>dt(e,d,v,c,"cli")),await ot(e,w,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)},()=>xs(e,d,c,t.mode,w,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 ps(e,w,d,c,o,p),c.endMark("download-assets",{assets:d.doneAssets.size}),o.enabled&&e.maxPages===0&&await Er(e,d,o,c,p),t.mode==="full"){let v=await ls(e,c);for(let x of v)U(p,e,x);}}finally{await k("dispose crawl request context",ce(e),()=>w.dispose()).catch(y=>{c.warn("Timed out while disposing crawl request context",{error:String(y)});});}}o.trackManifest&&await G(e,o),await b.writeFile(h.join(e.outputDir,"asset-map.json"),JSON.stringify(d.assetMap,null,2),"utf8"),JSON.stringify(l,null,2)!==JSON.stringify(d.assetMap,null,2)&&U(p,e,h.join(e.outputDir,"asset-map.json"));let g=t.mode==="single-url"?_r(e,d):o.enabled&&!t.resumeRewrite?jr(e,o,p,l,d.assetMap):void 0;c.mark("rewrite-text");let f=t.mode==="single-url"?`Rewriting text files touched by URL crawl: 0/${g?.length??0}`:"Rewriting text files...";c.progress(f,{phase:"rewrite-text",index:0,totalFiles:g?.length,changedTextFiles:0}),await nt(f);let m=Date.now(),P=await Ke(e,d.assetMap,{files:g,previousAssetMap:l,onProgress:async({index:w,totalFiles:y,changedTextFiles:v,file:x,changed:A})=>{A&&U(p,e,h.join(e.outputDir,x)),c.checkpoint(`Rewriting text file ${w}/${y}`,{phase:"rewrite-text",index:w,totalFiles:y,changedTextFiles:v,file:x});let F=Date.now();if(!(w===1||w===y||F-m>=5e3))return;m=F;let M=`Rewriting text files: ${w}/${y}`;c.progress(M,{phase:"rewrite-text",index:w,totalFiles:y,changedTextFiles:v,file:x}),await nt(M);}});o.trackManifest&&(Ur(o,g),await G(e,o)),c.endMark("rewrite-text",{changedTextFiles:P}),await je(e,{generatedAt:new Date().toISOString(),outputDir:h.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?[...p.deletedFiles].sort():[],rewriteTargets:o.enabled&&!t.resumeRewrite?[...new Set((g||[]).map(w=>ne(e.outputDir,h.isAbsolute(w)?w:h.join(e.outputDir,w))).filter(w=>w!==null))].sort():[]}),c.summary(t.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${P} 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:P}),await c.flush();}Fs().catch(async e=>{console.error(e);try{let r=(await we().catch(()=>null))?.logDir??"logs",s=new Y(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 {createHash}from'crypto';import Lt from'fast-glob';import $ from'fs/promises';import b from'path';import ir from'mime-types';import ot from'http';import at from'https';import {availableParallelism}from'os';import {Worker}from'worker_threads';function Pe(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function lt(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 se(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function ut(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=Pe(s.targetOrigin);a&&(o.targetOrigin=a);}let u=se(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 Se(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function ct(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 ve(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((n,i)=>ct(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 gt(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 ae(e){let t=e&&typeof e=="object"?e:{},r=String(t.accountId??"").trim(),n=String(t.siteId??"").trim(),i=t.subscriber===true,s=gt(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=Se(t.subscriptionType);return p&&(u.subscriptionType=p),u}function pt(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Re(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function dt(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 $e(e,t,r=5){let n=new URL(Re(e)),i=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),s=n.protocol==="http:"?ot:at,o=dt(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($e(new URL(d,n),{method:g===303?"GET":i},r-1));return}let w=new Headers;for(let[y,P]of Object.entries(l.headers))Array.isArray(P)?w.set(y,P.join(", ")):typeof P=="string"&&w.set(y,P);u(new Response(Buffer.concat(p),{status:g,statusText:l.statusMessage??"",headers:w}));});});c.on("error",a),c.end();})}function ft(e){let t=ae(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;pt(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 ht(e){if(!ft(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)=>Re(s).startsWith(t)?$e(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 mt(e,t){let r=ut(t?.deploymentProfiles),n=String(t?.defaultDeploymentProfile??"").trim(),i=r[n]?n:"",s=Se(t?.subscriptionType),o=ae(e.wpsuite);return {...e,scheduler:ve(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 oe(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 wt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?b.resolve(e):""}function be(e,t,r){let n=String(t||"").trim();return n&&b.isAbsolute(n)?b.resolve(n):b.resolve(e,oe(n,r))}async function le(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=Pe(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=lt(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=se(n.extraReplacements),n.postCrawlCopyMap=se(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=ae(n.wpsuite),n.scheduler=ve(void 0),n.deploymentProfiles={},n.defaultDeploymentProfile="",n.deploymentTargetOverride=String(n.deploymentTargetOverride??"").trim();let i=mt(n,await ht(n)),s=wt(),o=s?b.resolve(s,".."):"";return o?(i.outputDir=be(o,i.outputDir,"export"),i.logDir=be(o,i.logDir,"logs")):(b.isAbsolute(i.outputDir)||(i.outputDir=oe(i.outputDir,"export")),b.isAbsolute(i.logDir)||(i.logDir=oe(i.logDir,"logs"))),i}function yt(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 E(e,t,r){let n=new AbortController,i=globalThis.setTimeout(()=>{n.abort(new Error(`${e} timed out after ${yt(t)}.`));},t);try{return await r({abortController:n,httpOptions:{abortSignal:n.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(i);}}var bt=".deploy-plan.json",Pt="deploy-plan.json";function St(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?b.resolve(e):""}function vt(e){let t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,"").trim();return !t||t==="."||t.startsWith("../")||t===".."?null:t}function ue(e){return [...new Set(e.map(vt).filter(t=>t!==null))]}function Rt(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:ue(t.changedFiles||[]),deletedFiles:ue(t.deletedFiles||[]),rewriteTargets:ue(t.rewriteTargets||[])}}function $t(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 De(e){let t=b.join(b.resolve(e.outputDir),bt),r=St();return r?[b.join(r,Pt),t]:[t]}async function Te(e){let t=b.resolve(e.outputDir);for(let r of De(e))try{let n=await $.readFile(r,"utf8"),i=JSON.parse(n);if(!$t(i)||b.resolve(i.outputDir)!==t)continue;return Rt(e,i)}catch{}return null}async function Ce(e){for(let t of De(e))try{await $.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}function xt(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function Ee(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 Dt(e,t){return {...e,...t??{}}}function Tt(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function Me(e,t){let r=String(t??e.deploymentTargetOverride??"").trim();if(!xt(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:Dt(e.s3,i.s3),cloudFront:Tt(e.cloudFront,i.cloudFront)}}}var ke={error:0,warn:1,info:2,debug:3},Le=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",Q=Le?b.join(Le,"current-progress.json"):"",Ie=Promise.resolve();function Oe(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function Ct(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 Et(e,t,r){Q&&(Ie=Ie.then(async()=>{let n=new Date,i=n.toISOString();await $.mkdir(b.dirname(Q),{recursive:true});let s=await $.readFile(Q,"utf8").then(y=>JSON.parse(y)).catch(()=>null),o=s&&typeof s.details=="object"&&s.details?s.details:{},u=Oe(e),a=s?.currentStep||Oe(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)),w={checkedAt:i,source:e,message:t,details:Ct(o,r??{}),startedAt:c,currentStep:u,stepStartedAt:p,stepElapsedSec:g,totalElapsedSec:d,stepDurationsSec:l};await $.writeFile(Q,JSON.stringify(w,null,2),"utf8");}).catch(()=>{}));}async function Mt(e,t){await $.mkdir(b.dirname(e),{recursive:true}),await $.appendFile(e,`${JSON.stringify(t)}
|
|
1
|
+
import {S3Client,HeadObjectCommand,GetObjectCommand,DeleteObjectsCommand,ListObjectsV2Command}from'@aws-sdk/client-s3';import {Upload}from'@aws-sdk/lib-storage';import {createHash}from'crypto';import It from'fast-glob';import $ from'fs/promises';import b from'path';import sr from'mime-types';import at from'http';import lt from'https';import {availableParallelism}from'os';import {Worker}from'worker_threads';function Se(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function ut(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 oe(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t.trim(),String(r??"")]).filter(([t])=>t.length>0))}function ct(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=Se(s.targetOrigin);a&&(o.targetOrigin=a);}let u=oe(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 ve(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function gt(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 Re(e){let t=e&&typeof e=="object"?e:{},r=Array.isArray(t.rules)?t.rules.map((n,i)=>gt(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 pt(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 le(e){let t=e&&typeof e=="object"?e:{},r=String(t.accountId??"").trim(),n=String(t.siteId??"").trim(),i=t.subscriber===true,s=pt(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=ve(t.subscriptionType);return p&&(u.subscriptionType=p),u}function dt(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function $e(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function ft(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 xe(e,t,r=5){let n=new URL($e(e)),i=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),s=n.protocol==="http:"?at:lt,o=ft(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(xe(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 ht(e){let t=le(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;dt(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 mt(e){if(!ht(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)=>$e(s).startsWith(t)?xe(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 wt(e,t){let r=ct(t?.deploymentProfiles),n=String(t?.defaultDeploymentProfile??"").trim(),i=r[n]?n:"",s=ve(t?.subscriptionType),o=le(e.wpsuite);return {...e,scheduler:Re(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 ae(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 yt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?b.resolve(e):""}function Pe(e,t,r){let n=String(t||"").trim();return n&&b.isAbsolute(n)?b.resolve(n):b.resolve(e,ae(n,r))}async function ue(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=Se(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=ut(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=oe(n.extraReplacements),n.postCrawlCopyMap=oe(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=le(n.wpsuite),n.scheduler=Re(void 0),n.deploymentProfiles={},n.defaultDeploymentProfile="",n.deploymentTargetOverride=String(n.deploymentTargetOverride??"").trim();let i=wt(n,await mt(n)),s=yt(),o=s?b.resolve(s,".."):"";return o?(i.outputDir=Pe(o,i.outputDir,"export"),i.logDir=Pe(o,i.logDir,"logs")):(b.isAbsolute(i.outputDir)||(i.outputDir=ae(i.outputDir,"export")),b.isAbsolute(i.logDir)||(i.logDir=ae(i.logDir,"logs"))),i}function bt(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 E(e,t,r){let n=new AbortController,i=globalThis.setTimeout(()=>{n.abort(new Error(`${e} timed out after ${bt(t)}.`));},t);try{return await r({abortController:n,httpOptions:{abortSignal:n.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(i);}}var Pt=".deploy-plan.json",St="deploy-plan.json";function vt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?b.resolve(e):""}function Rt(e){let t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,"").trim();return !t||t==="."||t.startsWith("../")||t===".."?null:t}function ce(e){return [...new Set(e.map(Rt).filter(t=>t!==null))]}function $t(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:ce(t.changedFiles||[]),deletedFiles:ce(t.deletedFiles||[]),rewriteTargets:ce(t.rewriteTargets||[])}}function xt(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 Te(e){let t=b.join(b.resolve(e.outputDir),Pt),r=vt();return r?[b.join(r,St),t]:[t]}async function Ce(e){let t=b.resolve(e.outputDir);for(let r of Te(e))try{let n=await $.readFile(r,"utf8"),i=JSON.parse(n);if(!xt(i)||b.resolve(i.outputDir)!==t)continue;return $t(e,i)}catch{}return null}async function Ee(e){for(let t of Te(e))try{await $.unlink(t);}catch(r){if(r.code!=="ENOENT")throw r}}function Dt(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function Me(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 Tt(e,t){return {...e,...t??{}}}function Ct(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function ke(e,t){let r=String(t??e.deploymentTargetOverride??"").trim();if(!Dt(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:Tt(e.s3,i.s3),cloudFront:Ct(e.cloudFront,i.cloudFront)}}}var Le={error:0,warn:1,info:2,debug:3},Ie=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",V=Ie?b.join(Ie,"current-progress.json"):"",Oe=Promise.resolve();function je(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function Et(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 Mt(e,t,r){V&&(Oe=Oe.then(async()=>{let n=new Date,i=n.toISOString();await $.mkdir(b.dirname(V),{recursive:true});let s=await $.readFile(V,"utf8").then(y=>JSON.parse(y)).catch(()=>null),o=s&&typeof s.details=="object"&&s.details?s.details:{},u=je(e),a=s?.currentStep||je(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:Et(o,r??{}),startedAt:c,currentStep:u,stepStartedAt:p,stepElapsedSec:g,totalElapsedSec:d,stepDurationsSec:l};await $.writeFile(V,JSON.stringify(f,null,2),"utf8");}).catch(()=>{}));}async function kt(e,t){await $.mkdir(b.dirname(e),{recursive:true}),await $.appendFile(e,`${JSON.stringify(t)}
|
|
2
2
|
`,"utf8");}var B=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(()=>
|
|
3
|
+
`,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>kt(t,r));}accepts(t){return Le[t]<=Le[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){Mt(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}};function _e(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(b.extname(e).toLowerCase())}function Ue(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function A(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function Y(e){return e.replace(/\//g,"\\/")}function Fe(e){return e.replace(/\//g,"\\\\/")}function Lt(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 Ae(e,t,r){if(!t)return;e[t]=r;let n=Y(t),i=Y(r);e[n]=i;let s=Fe(t),o=Fe(r);e[s]=o;let u=A(t),a=A(r);e[u]=a;let c=A(n),l=A(i);e[c]=l;let p=A(s),g=A(o);e[p]=g;}function Z(e,t,r){Ae(e,t,r);let n=Lt(t);n&&n!==t&&Ae(e,n,r);}function Ne(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function We(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 Ft=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],At=new Set([".html",".htm"]),qe="WPSuite.io Static Publisher",_t=qe.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Ut(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Nt(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function Wt(e,t,r){return Nt(t)?e.replace(new RegExp(`(?<!:)${Ut(t)}`,"g"),r):e.split(t).join(r)}function zt(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 At.has(i)?/<head\b|<html\b|<!doctype html/i.test(t):false}function qt(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${_t}\\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
|
|
4
4
|
`)?`\r
|
|
5
5
|
`:`
|
|
6
|
-
`;return e.replace(/<head\b[^>]*>/i,i=>`${i}${n} ${t}`)}function qt(e){let t=_e(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function Bt(e,t){let r=[...new Set(t)].filter(s=>s.includes("/")&&!/\\+\//.test(s)).map(s=>[s,V(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)=>qt(a)?`${o}${n(a)}${c}`:s),i}function Ht(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 Jt(e,t,r){let n=Ht(t,r);if(!n)return e;let i=e;for(let s of jt){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"),w=new RegExp(`(?<![\\.\\\\])\\/${p}`,"g");i=i.replace(g,`${l}${c}`).replace(d,`${l}${c}`).replace(w,`${l}${c}`);}return i}function ge(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:Ue(t,e.targetOrigin),s=n?`${n.search}${n.hash}`:"";return e.urlRewriteMode==="root-relative"?`${i}${s}`:`${Ne(e.outputDir,r,i)}${s}`}function ce(e,t,r,n,i){Y(e,r,ge(t,n,i));}function Kt(e,t,r,n,i){if(!r||r===n)return;Y(e,r,n);let s=ge(t,r,i),o=ge(t,n,i);Y(e,s,o);}function Gt(e,t,r,n,i={}){let s=e,o={};ce(o,t,t.sourceOrigin,t.targetOrigin,n);for(let[a,c]of Object.entries(t.extraReplacements))ce(o,t,a,c,n);for(let[a,c]of Object.entries(r))ce(o,t,a,c,n);for(let[a,c]of Object.entries(i)){let l=r[a];!l||l===c||Kt(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=Nt(s,a,c);return t.urlRewriteMode!=="absolute"&&(s=Jt(s,t,n)),s=Bt(s,u.map(([,a])=>a)),Wt(t,s,n)&&(s=zt(s)),s}async function Qt(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=Gt(o,e,t,s===".js"||s===".mjs"?void 0:i,r);return a!==o?(await $.writeFile(i,a,"utf8"),{changed:true}):{changed:false}}async function Vt(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 qe(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 Lt(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(g=>g!=="asset-map.json"&&Ae(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 Qt(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 w=i[d],y=await Vt(g,w);y.changed&&(s+=1),c+=1,await r.onProgress?.({index:c,totalFiles:i.length,changedTextFiles:s,file:w,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 Ke="wpsuite-sha256",Ge="wpsuite-normalized-sha256",sr=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,we=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,or=["SIGINT","SIGTERM"],ee=new Set,Z=new Map,Be=null;function ar(e){ee.add(e);let t=false;return ()=>{t||(t=true,ee.delete(e));}}async function lr(){let e=[...ee];e.length!==0&&await Promise.allSettled(e.map(async t=>{ee.delete(t),await $.rm(t,{recursive:true,force:true});}));}function ur(){if(!(Z.size>0))for(let e of or){let t=()=>{Be||(Be=lr().finally(()=>{for(let[r,n]of Z)process.off(r,n);Z.clear(),process.exit(1);}));};Z.set(e,t),process.on(e,t);}}ur();function cr(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 Qe(e){return b.normalize(e).split(b.sep).join("/")}function He(e,t){let r=b.relative(b.resolve(e),b.resolve(t));return !r||r.startsWith("..")||b.isAbsolute(r)?null:Qe(r)}async function gr(e,t,r){let n=cr(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();if(!g||p?.rewriteComplete===true)continue;let d=He(e.outputDir,g);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,w=g?He(e.outputDir,g):null;if(w){let y=typeof p?.contentType=="string"&&p.contentType?p.contentType:null;y&&u.set(w,y);}!g||!d||p?.rewriteComplete===true||w&&(c++,o.has(w)||o.set(w,{kind:"asset",sourceUrl:l,outputPath:b.resolve(g),relativePath:w}));}return {manifestPath:n,byRelativePath:o,contentTypeByRelativePath:u,pendingPages:a,pendingTextAssets:c}}function pr(e){return e&&(we.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 de(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,r)=>r%2===1?t:pr(t)).join("")}function dr(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,r)=>r%2===1?t:we.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 te(e,t){return Array.isArray(e)?e.map(r=>te(r,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([r,n])=>[r,te(n,r)])):typeof e!="string"?e:t&&sr.test(t)?dr(e):we.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?de(e):e}function fr(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function hr(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(te(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(te(s));return Buffer.from(o,"utf8").toString("base64")}catch{}return t}function mr(e,t){let r=e.toLowerCase();return r==="class"?t.split(/(\s+)/).map((n,i)=>i%2===1?n:de(n)).join(""):r==="id"||r==="for"||r==="aria-controls"||r==="aria-labelledby"||r==="aria-describedby"||r==="aria-owns"||r==="aria-activedescendant"||r==="name"?de(t):r==="href"||r==="src"?fr(t):hr(r,t)}function wr(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=mr(o,a);return ` ${o}=${u}${c}${u}`});return `<${r}${i}>`})}function pe(e){let t=b.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(b.basename(e))}function X(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function yr(e,t,r,n){let i=new Map,s,o=0;do{o++;let u=await E(`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 br(e,t,r,n){if(n.has(r))return n.get(r)??null;try{let i=await E(`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 Ve(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 E(`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 Pr(e,t,r,n,i){return Ve(e,t,Array.from(r).filter(s=>!n.has(s)),i)}function Sr(e){return createHash("md5").update(e).digest("hex")}function Je(e){return createHash("sha256").update(e).digest("hex")}function fe(e){return createHash("sha256").update(wr(e.toString("utf8"))).digest("hex")}async function vr(e,t,r,n){if(n.has(r))return n.get(r)??null;try{let o=((await E(`S3 head object metadata ${r}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),u))).Metadata?.[Ke]||"").trim().toLowerCase()||null;return n.set(r,o),o}catch{return n.set(r,null),null}}async function Rr(e,t,r,n,i){if(n.has(r))return n.get(r)??null;try{let o=((await E(`S3 head object normalized metadata ${r}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),u))).Metadata?.[Ge]||"").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 E(`S3 get object ${r}`,3e5,({httpOptions:a})=>e.send(new GetObjectCommand({Bucket:t,Key:r}),a))).Body?.transformToByteArray(),u=o?fe(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 $r(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function xr(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 Dr(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=xr(l,n),[a,l]}));await $.writeFile(i,JSON.stringify(u,null,2),"utf8");}async function Tr(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-${$r(r)}-${Date.now()}`),a=ar(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 qe(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:w,file:y,changed:P})=>{let R=`Rewriting [${g}/${d}] ${y} (${P?"rewrote":"checked"}; ${w} changed so far)`;d<=200||g<=5||g%10===0||g===d?(i.progress(R,{file:y,index:g,totalFiles:d,changed:P,changedTextFiles:w,workerCount:l}),i.info(R)):i.debug(R);}});return await Dr(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 Cr(){let e=await le(),t=Ee(process.argv.slice(2)),r=Me(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 B(n,"deploy.log.jsonl",r.config.logLevel??"info"),u=r.profile?.extraReplacements??{},a=async()=>{};try{let c=await Tr(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 Te(e),d=c.outputDir!==e.outputDir&&(e.targetOrigin!==r.config.targetOrigin||Object.keys(u).length>0),w=!!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."):w&&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 gr(e,i,o):null,O=w?(await Promise.all(g.changedFiles.map(async m=>{try{return (await $.stat(b.join(l.outputDir,m))).isFile()?m:null}catch{return null}}))).filter(m=>m!==null):await Lt(["**/*"],{cwd:l.outputDir,onlyFiles:!0,dot:!0}),R=[],J=[],h=O.filter(m=>{let L=P?.byRelativePath.get(Qe(m));if(!L)return !0;let f=X(l.s3.prefix,m);return R.push(m),J.push(f),o.reject(L.kind,L.sourceUrl||m,"rewrite not completed; deploy upload blocked","deploy-guard",{file:m,key:f,outputPath:L.outputPath,manifestPath:P?.manifestPath}),!1}),Ye=w?new Set:new Set(O.map(m=>X(l.s3.prefix,m)));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"}),w?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 ${O.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:O.length,rejected:R.length,deploymentProfile:r.name||"",s3Bucket:l.s3.bucket,s3Prefix:l.s3.prefix||"",targetedPlan:w,deployGuardEnabled:c.outputDir===e.outputDir});let x=0,v=0,k=0,re=[],U=[],ne=[],K=[],N=new Map,Ze=new Map,Xe=new Map,et=new Map,tt=new Map;w||(o.info("Listing existing S3 objects to detect unchanged files..."),N=await yr(y,l.s3.bucket,l.s3.prefix,o),o.info(`Found ${N.size} existing key(s) in S3.`));let rt=async m=>N.has(m)?N.get(m)??null:w?br(y,l.s3.bucket,m,Ze):null;for(let m of h){let L=b.join(l.outputDir,m),f=X(l.s3.prefix,m),W=ir.lookup(m)||P?.contentTypeByRelativePath.get(m)||"application/octet-stream",nt=pe(m)?l.s3.htmlCacheControl:l.s3.assetCacheControl,S=x+v+k+1;h.length<=200||S<=5||S%10===0||S===h.length?(o.progress(`Uploading [${S}/${h.length}] ${f} (${W})`,{file:m,key:f,index:S,totalFiles:h.length,contentType:W,mode:p}),o.info(`Uploading [${S}/${h.length}] ${f} (${W})`)):o.debug(`Uploading [${S}/${h.length}] ${f} (${W})`);try{let D=await $.readFile(L),z=await rt(f),q=null,j=null;if(z){let ie=D.byteLength;if(z.size===ie){let G=z.etag.includes("-");if(z.etag!==""&&!G){let it=Sr(D);if(z.etag===it){v++,h.length<=200||v<=5||v%25===0?(o.progress(`Skipped unchanged [${S}/${h.length}] ${f}`,{file:m,key:f,index:S,totalFiles:h.length,uploaded:x,skipped:v,failed:k,mode:p,reason:"etag-md5-match"}),o.info(`Skipped unchanged [${S}/${h.length}] ${f}`)):o.debug(`Skipped unchanged [${S}/${h.length}] ${f}`),U.push(f);continue}}q=Je(D);let ye=await vr(y,l.s3.bucket,f,Xe);if(ye&&ye===q){v++,h.length<=200||v<=5||v%25===0?(o.progress(`Skipped unchanged [${S}/${h.length}] ${f}`,{file:m,key:f,index:S,totalFiles:h.length,uploaded:x,skipped:v,failed:k,mode:p,reason:"metadata-sha256-match"}),o.info(`Skipped unchanged [${S}/${h.length}] ${f}`)):o.debug(`Skipped unchanged [${S}/${h.length}] ${f}`),U.push(f);continue}}if(pe(m)){j=fe(D);let G=await Rr(y,l.s3.bucket,f,et,tt);if(G&&G===j){v++,h.length<=200||v<=5||v%25===0?(o.progress(`Skipped semantically unchanged [${S}/${h.length}] ${f}`,{file:m,key:f,index:S,totalFiles:h.length,uploaded:x,skipped:v,failed:k,mode:p,reason:"normalized-html-match"}),o.info(`Skipped semantically unchanged [${S}/${h.length}] ${f}`)):o.debug(`Skipped semantically unchanged [${S}/${h.length}] ${f}`),U.push(f);continue}}}q=q??Je(D),j=j??(pe(m)?fe(D):null),await E(`S3 upload ${f}`,9e5,({abortController:ie})=>new Upload({client:y,abortController:ie,params:{Bucket:l.s3.bucket,Key:f,Body:D,ContentType:W,CacheControl:nt,Metadata:{[Ke]:q,...j?{[Ge]:j}:{}}}}).done()),x++,re.push(f),(x%25===0||x===h.length)&&(o.progress(`Uploaded ${x}/${h.length} file(s)\u2026`,{uploaded:x,skipped:v,failed:k,totalFiles:h.length,mode:p}),o.info(`Uploaded ${x}/${h.length} file(s)\u2026`));}catch(D){k++,ne.push(f),o.error(`Failed to upload ${f}: ${D.message}`,{key:f,error:String(D)});}}o.info(`Upload complete: ${x} uploaded, ${v} skipped unchanged, ${J.length} rejected by guard, ${k} failed.`),p==="sdk-upload-delete"?w?K=await Ve(y,l.s3.bucket,g.deletedFiles.map(m=>X(l.s3.prefix,m)),o):K=await Pr(y,l.s3.bucket,N.keys(),Ye,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:O.length,eligibleFiles:h.length,uploaded:re.length,skipped:U.length,rejected:J.length,failed:ne.length,deleted:K.length,...r.name?{profile:r.name}:{}},uploadedKeys:re,skippedKeys:U,rejectedKeys:J,failedKeys:ne,deletedKeys:K},null,2),"utf8")),await Ce(e),o.endMark("deploy"),await o.flush();}finally{await a().catch(()=>{});}}Cr().catch(async e=>{console.error(e);try{let r=(await le().catch(()=>null))?.logDir??"logs",n=new B(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,i=>`${i}${n} ${t}`)}function Bt(e){let t=Ue(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function Ht(e,t){let r=[...new Set(t)].filter(s=>s.includes("/")&&!/\\+\//.test(s)).map(s=>[s,Y(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)=>Bt(a)?`${o}${n(a)}${c}`:s),i}function Jt(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 Kt(e,t,r){let n=Jt(t,r);if(!n)return e;let i=e;for(let s of Ft){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 pe(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:Ne(t,e.targetOrigin),s=n?`${n.search}${n.hash}`:"";return e.urlRewriteMode==="root-relative"?`${i}${s}`:`${We(e.outputDir,r,i)}${s}`}function ge(e,t,r,n,i){Z(e,r,pe(t,n,i));}function Gt(e,t,r,n,i){if(!r||r===n)return;Z(e,r,n);let s=pe(t,r,i),o=pe(t,n,i);Z(e,s,o);}function Qt(e,t,r,n,i={}){let s=e,o={};ge(o,t,t.sourceOrigin,t.targetOrigin,n);for(let[a,c]of Object.entries(t.extraReplacements))ge(o,t,a,c,n);for(let[a,c]of Object.entries(r))ge(o,t,a,c,n);for(let[a,c]of Object.entries(i)){let l=r[a];!l||l===c||Gt(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=Wt(s,a,c);return t.urlRewriteMode!=="absolute"&&(s=Kt(s,t,n)),s=Ht(s,u.map(([,a])=>a)),zt(t,s,n)&&(s=qt(s)),s}async function Vt(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=Qt(o,e,t,s===".js"||s===".mjs"?void 0:i,r);return a!==o?(await $.writeFile(i,a,"utf8"),{changed:true}):{changed:false}}async function Yt(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 Be(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 It(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(g=>g!=="asset-map.json"&&_e(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 Vt(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 Yt(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 Ge="wpsuite-sha256",Qe="wpsuite-normalized-sha256",or=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,ye=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,ar=["SIGINT","SIGTERM"],te=new Set,X=new Map,He=null;function lr(e){te.add(e);let t=false;return ()=>{t||(t=true,te.delete(e));}}async function ur(){let e=[...te];e.length!==0&&await Promise.allSettled(e.map(async t=>{te.delete(t),await $.rm(t,{recursive:true,force:true});}));}function cr(){if(!(X.size>0))for(let e of ar){let t=()=>{He||(He=ur().finally(()=>{for(let[r,n]of X)process.off(r,n);X.clear(),process.exit(1);}));};X.set(e,t),process.on(e,t);}}cr();function gr(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 Ve(e){return b.normalize(e).split(b.sep).join("/")}function Je(e,t){let r=b.relative(b.resolve(e),b.resolve(t));return !r||r.startsWith("..")||b.isAbsolute(r)?null:Ve(r)}async function pr(e,t,r){let n=gr(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?Je(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?Je(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 dr(e){return e&&(ye.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 fe(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,r)=>r%2===1?t:dr(t)).join("")}function fr(e){return e.split(/([_:.\-/=?&#]+)/g).map((t,r)=>r%2===1?t:ye.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 re(e,t){return Array.isArray(e)?e.map(r=>re(r,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([r,n])=>[r,re(n,r)])):typeof e!="string"?e:t&&or.test(t)?fr(e):ye.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?fe(e):e}function hr(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function mr(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(re(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(re(s));return Buffer.from(o,"utf8").toString("base64")}catch{}return t}function wr(e,t){let r=e.toLowerCase();return r==="class"?t.split(/(\s+)/).map((n,i)=>i%2===1?n:fe(n)).join(""):r==="id"||r==="for"||r==="aria-controls"||r==="aria-labelledby"||r==="aria-describedby"||r==="aria-owns"||r==="aria-activedescendant"||r==="name"?fe(t):r==="href"||r==="src"?hr(t):mr(r,t)}function yr(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=wr(o,a);return ` ${o}=${u}${c}${u}`});return `<${r}${i}>`})}function de(e){let t=b.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(b.basename(e))}function ee(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function br(e,t,r,n){let i=new Map,s,o=0;do{o++;let u=await E(`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 Pr(e,t,r,n){if(n.has(r))return n.get(r)??null;try{let i=await E(`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 Ye(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 E(`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 Sr(e,t,r,n,i){return Ye(e,t,Array.from(r).filter(s=>!n.has(s)),i)}function vr(e){return createHash("md5").update(e).digest("hex")}function Ke(e){return createHash("sha256").update(e).digest("hex")}function he(e){return createHash("sha256").update(yr(e.toString("utf8"))).digest("hex")}async function Rr(e,t,r,n){if(n.has(r))return n.get(r)??null;try{let o=((await E(`S3 head object metadata ${r}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),u))).Metadata?.[Ge]||"").trim().toLowerCase()||null;return n.set(r,o),o}catch{return n.set(r,null),null}}async function $r(e,t,r,n,i){if(n.has(r))return n.get(r)??null;try{let o=((await E(`S3 head object normalized metadata ${r}`,3e5,({httpOptions:u})=>e.send(new HeadObjectCommand({Bucket:t,Key:r}),u))).Metadata?.[Qe]||"").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 E(`S3 get object ${r}`,3e5,({httpOptions:a})=>e.send(new GetObjectCommand({Bucket:t,Key:r}),a))).Body?.transformToByteArray(),u=o?he(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 xr(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function Dr(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 Tr(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=Dr(l,n),[a,l]}));await $.writeFile(i,JSON.stringify(u,null,2),"utf8");}async function Cr(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-${xr(r)}-${Date.now()}`),a=lr(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 Be(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 Tr(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 Er(){let e=await ue(),t=Me(process.argv.slice(2)),r=ke(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 B(n,"deploy.log.jsonl",r.config.logLevel??"info"),u=r.profile?.extraReplacements??{},a=async()=>{};try{let c=await Cr(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 Ce(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 pr(e,i,o):null,O=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 It(["**/*"],{cwd:l.outputDir,onlyFiles:!0,dot:!0}),R=[],J=[],m=O.filter(w=>{let L=P?.byRelativePath.get(Ve(w));if(!L)return !0;let h=ee(l.s3.prefix,w);return R.push(w),J.push(h),o.reject(L.kind,L.sourceUrl||w,"rewrite not completed; deploy upload blocked","deploy-guard",{file:w,key:h,outputPath:L.outputPath,manifestPath:P?.manifestPath}),!1}),Ze=f?new Set:new Set(O.map(w=>ee(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 ${O.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:O.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,k=0,ne=[],U=[],ie=[],K=[],N=new Map,Xe=new Map,et=new Map,tt=new Map,rt=new Map;f||(o.info("Listing existing S3 objects to detect unchanged files..."),N=await br(y,l.s3.bucket,l.s3.prefix,o),o.info(`Found ${N.size} existing key(s) in S3.`));let nt=async w=>N.has(w)?N.get(w)??null:f?Pr(y,l.s3.bucket,w,Xe):null;for(let w of m){let L=b.join(l.outputDir,w),h=ee(l.s3.prefix,w),G=P?.contentTypeByRelativePath.get(w),W=G&&G!=="application/octet-stream"?G:sr.lookup(w)||G||"application/octet-stream",it=de(w)?l.s3.htmlCacheControl:l.s3.assetCacheControl,S=x+v+k+1;m.length<=200||S<=5||S%10===0||S===m.length?(o.progress(`Uploading [${S}/${m.length}] ${h} (${W})`,{file:w,key:h,index:S,totalFiles:m.length,contentType:W,mode:p}),o.info(`Uploading [${S}/${m.length}] ${h} (${W})`)):o.debug(`Uploading [${S}/${m.length}] ${h} (${W})`);try{let D=await $.readFile(L),z=await nt(h),q=null,j=null;if(z){let se=D.byteLength;if(z.size===se){let Q=z.etag.includes("-");if(z.etag!==""&&!Q){let st=vr(D);if(z.etag===st){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:k,mode:p,reason:"etag-md5-match"}),o.info(`Skipped unchanged [${S}/${m.length}] ${h}`)):o.debug(`Skipped unchanged [${S}/${m.length}] ${h}`),U.push(h);continue}}q=Ke(D);let be=await Rr(y,l.s3.bucket,h,et);if(be&&be===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:k,mode:p,reason:"metadata-sha256-match"}),o.info(`Skipped unchanged [${S}/${m.length}] ${h}`)):o.debug(`Skipped unchanged [${S}/${m.length}] ${h}`),U.push(h);continue}}if(de(w)){j=he(D);let Q=await $r(y,l.s3.bucket,h,tt,rt);if(Q&&Q===j){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:k,mode:p,reason:"normalized-html-match"}),o.info(`Skipped semantically unchanged [${S}/${m.length}] ${h}`)):o.debug(`Skipped semantically unchanged [${S}/${m.length}] ${h}`),U.push(h);continue}}}q=q??Ke(D),j=j??(de(w)?he(D):null),await E(`S3 upload ${h}`,9e5,({abortController:se})=>new Upload({client:y,abortController:se,params:{Bucket:l.s3.bucket,Key:h,Body:D,ContentType:W,CacheControl:it,Metadata:{[Ge]:q,...j?{[Qe]:j}:{}}}}).done()),x++,ne.push(h),(x%25===0||x===m.length)&&(o.progress(`Uploaded ${x}/${m.length} file(s)\u2026`,{uploaded:x,skipped:v,failed:k,totalFiles:m.length,mode:p}),o.info(`Uploaded ${x}/${m.length} file(s)\u2026`));}catch(D){k++,ie.push(h),o.error(`Failed to upload ${h}: ${D.message}`,{key:h,error:String(D)});}}o.info(`Upload complete: ${x} uploaded, ${v} skipped unchanged, ${J.length} rejected by guard, ${k} failed.`),p==="sdk-upload-delete"?f?K=await Ye(y,l.s3.bucket,g.deletedFiles.map(w=>ee(l.s3.prefix,w)),o):K=await Sr(y,l.s3.bucket,N.keys(),Ze,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:O.length,eligibleFiles:m.length,uploaded:ne.length,skipped:U.length,rejected:J.length,failed:ie.length,deleted:K.length,...r.name?{profile:r.name}:{}},uploadedKeys:ne,skippedKeys:U,rejectedKeys:J,failedKeys:ie,deletedKeys:K},null,2),"utf8")),await Ee(e),o.endMark("deploy"),await o.flush();}finally{await a().catch(()=>{});}}Er().catch(async e=>{console.error(e);try{let r=(await ue().catch(()=>null))?.logDir??"logs",n=new B(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);});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smart-cloud/publisher-exporter",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.28",
|
|
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.",
|