@smart-cloud/publisher-exporter 1.1.18 → 1.1.19
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/dist/rewrite-worker.js +2 -2
- 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 Mt from'http';import Lt from'https';import Nt from'crypto';import _t from'fast-glob';import {availableParallelism}from'os';import {Worker}from'worker_threads';var Rt=".deploy-plan.json",Ct="deploy-plan.json";function kt(){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 xt(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 Tt(e){let t=h.join(h.resolve(e.outputDir),Rt),r=kt();return r?[h.join(r,Ct),t]:[t]}function se(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=xt(e,t);for(let s of Tt(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 It(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 Ot(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(c=>String(c??"").trim()).filter(c=>c.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 Dt(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)=>Dt(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 Ft(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=Ft(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 c=String(t.uploadUrl??"").trim();c&&(l.uploadUrl=c),Object.keys(u).length>0&&(l.siteSettings=u);let p=qe(t.subscriptionType);return p&&(l.subscriptionType=p),l}function Et(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 jt(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:"?Mt:Lt,u=jt(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}:{}},c=>{let p=[];c.on("data",d=>{p.push(Buffer.isBuffer(d)?d:Buffer.from(d));}),c.on("error",a),c.on("end",()=>{let d=c.statusCode??0,g=c.headers.location;if(r>0&&g&&[301,302,303,307,308].includes(d)){l(We(new URL(g,s),{method:d===303?"GET":n},r-1));return}let f=new Headers;for(let[m,P]of Object.entries(c.headers))Array.isArray(P)?f.set(m,P.join(", ")):typeof P=="string"&&f.set(m,P);l(new Response(Buffer.concat(p),{status:d,statusText:c.statusMessage??"",headers:f}));});});o.on("error",a),o.end();})}function $t(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;Et(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 Ut(e){if(!$t(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 qt(e,t){let r=Ot(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 Qt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?h.resolve(e):""}function $e(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=It(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=qt(s,await Ut(s)),i=Qt(),u=i?h.resolve(i,".."):"";return u?(n.outputDir=$e(u,n.outputDir,"export"),n.logDir=$e(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 ie(e,t=10){return Nt.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 q(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function B(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function ne(e){return e.replace(/\//g,"\\/")}function _e(e){return e.replace(/\//g,"\\\\/")}function oe(e,t,r){if(!t)return;e[t]=r;let s=ne(t),n=ne(r);e[s]=n;let i=_e(t),u=_e(r);e[i]=u;let l=B(t),a=B(r);e[l]=a;let o=B(s),c=B(n);e[o]=c;let p=B(i),d=B(u);e[p]=d;}function Se(e,t){let r=t.startsWith("/")?t:`/${t}`,s=(e||"").replace(/\/$/,"");return !s||s==="."||s==="/"?r:`${s}${r}`}function Be(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function He(e,t,r){if(!t)return r;let 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 zt=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Jt=new Set([".html",".htm"]),Je="WPSuite.io Static Publisher",Gt=Je.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Vt(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 Jt.has(n)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Kt(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Gt}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${Je}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let s=e.includes(`\r
|
|
1
|
+
import {request,chromium}from'playwright';import S from'fs/promises';import h from'path';import {gunzipSync}from'zlib';import Lt from'http';import It from'https';import Wt from'crypto';import Ht from'fast-glob';import {availableParallelism}from'os';import {Worker}from'worker_threads';var Ct=".deploy-plan.json",kt="deploy-plan.json";function xt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?h.resolve(e):""}function $e(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($e).filter(t=>t!==null))]}function Tt(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 At(e){let t=h.join(h.resolve(e.outputDir),Ct),r=xt();return r?[h.join(r,kt),t]:[t]}function se(e,t){let r=h.resolve(e),s=h.resolve(t),n=h.relative(r,s).replace(/\\/g,"/");return $e(n)}async function Ee(e,t){let r=Tt(e,t);for(let s of At(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 Ot(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 Dt(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(c=>String(c??"").trim()).filter(c=>c.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 Ft(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)=>Ft(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 $t(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=$t(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 c=String(t.uploadUrl??"").trim();c&&(l.uploadUrl=c),Object.keys(u).length>0&&(l.siteSettings=u);let p=qe(t.subscriptionType);return p&&(l.subscriptionType=p),l}function Et(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 jt(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:"?Lt:It,u=jt(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}:{}},c=>{let p=[];c.on("data",d=>{p.push(Buffer.isBuffer(d)?d:Buffer.from(d));}),c.on("error",a),c.on("end",()=>{let d=c.statusCode??0,g=c.headers.location;if(r>0&&g&&[301,302,303,307,308].includes(d)){l(We(new URL(g,s),{method:d===303?"GET":n},r-1));return}let f=new Headers;for(let[m,P]of Object.entries(c.headers))Array.isArray(P)?f.set(m,P.join(", ")):typeof P=="string"&&f.set(m,P);l(new Response(Buffer.concat(p),{status:d,statusText:c.statusMessage??"",headers:f}));});});o.on("error",a),o.end();})}function Ut(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;Et(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 qt(e){if(!Ut(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 Qt(e,t){let r=Dt(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 Nt(){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=Ot(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=Qt(s,await qt(s)),i=Nt(),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 ie(e,t=10){return Wt.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 q(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function B(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function ne(e){return e.replace(/\//g,"\\/")}function _e(e){return e.replace(/\//g,"\\\\/")}function Bt(e){try{let t=new URL(e);return t.protocol!=="http:"&&t.protocol!=="https:"?null:`//${t.host}${t.pathname}${t.search}${t.hash}`}catch{return null}}function Be(e,t,r){if(!t)return;e[t]=r;let s=ne(t),n=ne(r);e[s]=n;let i=_e(t),u=_e(r);e[i]=u;let l=B(t),a=B(r);e[l]=a;let o=B(s),c=B(n);e[o]=c;let p=B(i),d=B(u);e[p]=d;}function oe(e,t,r){Be(e,t,r);let s=Bt(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 Gt=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Vt=new Set([".html",".htm"]),Ge="WPSuite.io Static Publisher",Kt=Ge.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Yt(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 Vt.has(n)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Xt(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Kt}\\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
|
|
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 Zt(e){let t=q(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function er(e,t){let r=[...new Set(t)].filter(i=>i.includes("/")&&!/\\+\//.test(i)).map(i=>[i,ne(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)=>Zt(a)?`${u}${s(a)}${o}`:i),n}function tr(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 rr(e,t,r){let s=tr(t,r);if(!s)return e;let n=e;for(let i of Gt){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,"\\/"),c=s.replace(/\//g,"\\/"),p=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),d=new RegExp(`(?:\\.{1,}\\\\/)+${p}`,"g"),g=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${p}`,"g"),f=new RegExp(`(?<![\\.\\\\])\\/${p}`,"g");n=n.replace(d,`${c}${o}`).replace(g,`${c}${o}`).replace(f,`${c}${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:He(t,e.targetOrigin),i=s?`${s.search}${s.hash}`:"";return e.urlRewriteMode==="root-relative"?`${n}${i}`:`${ze(e.outputDir,r,n)}${i}`}function be(e,t,r,s,n){oe(e,r,ye(t,s,n));}function sr(e,t,r,s,n){if(!r||r===s)return;oe(e,r,s);let i=ye(t,r,n),u=ye(t,s,n);oe(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 c=r[a];!c||c===o||sr(u,t,o,c,s);}let l=Object.entries(u).sort((a,o)=>o[0].length-a[0].length);for(let[a,o]of l)i=i.split(a).join(o);return t.urlRewriteMode!=="absolute"&&(i=rr(i,t,s)),i=er(i,l.map(([,a])=>a)),Yt(t,i,s)&&(i=Xt(i)),i}async function nr(e,t,r,s){let n=h.join(e.outputDir,s),i=h.extname(n).toLowerCase(),u;try{u=await S.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 S.writeFile(n,a,"utf8"),{changed:true}):{changed:false}}async function ir(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 Ve(e,t,r={}){let n=(r.files?[...new Set(r.files)].map(d=>h.resolve(d)).filter(d=>d.startsWith(h.resolve(e.outputDir))).map(d=>h.relative(e.outputDir,d).replace(/\\/g,"/")).filter(d=>d.length>0):await Ht(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(d=>d!=="asset-map.json"&&_(d)),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,c=null;if(l===1){for(let d of n){let g=await nr(e,t,r.previousAssetMap??{},d);g.changed&&(i+=1),o+=1,await r.onProgress?.({index:o,totalFiles:n.length,changedTextFiles:i,file:d,changed:g.changed});}return i}let p=Array.from({length:l},async()=>{let d=new Worker(new URL("./rewrite-worker.js",import.meta.url),{workerData:{config:e,assetMap:t,previousAssetMap:r.previousAssetMap??{}}});try{for(;!c;){let g=a;if(g>=n.length)return;a+=1;let f=n[g],m=await ir(d,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 c=g instanceof Error?g:new Error(String(g)),c}finally{await d.terminate().catch(()=>{});}});return await Promise.all(p),i}var Q={error:0,warn:1,info:2,debug:3},Ke=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",ae=Ke?h.join(Ke,"current-progress.json"):"",Ye=Promise.resolve();function Xe(e){return e.includes("crawl")?"crawl":e.includes("deploy")?"deploy":e.includes("invalidate")?"invalidate":e}function or(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 ar(e,t,r){ae&&(Ye=Ye.then(async()=>{let s=new Date,n=s.toISOString();await S.mkdir(h.dirname(ae),{recursive:true});let i=await S.readFile(ae,"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,c={...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));c[a]=(c[a]??0)+m,p=n;}let d=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:or(u,r??{}),startedAt:o,currentStep:l,stepStartedAt:p,stepElapsedSec:d,totalElapsedSec:g,stepDurationsSec:c};await S.writeFile(ae,JSON.stringify(f,null,2),"utf8");}).catch(()=>{}));}async function ur(e,t){await S.mkdir(h.dirname(e),{recursive:true}),await S.appendFile(e,`${JSON.stringify(t)}
|
|
5
|
+
`,"utf8");}function lr(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 cr(e,t,r){return {checkedAt:new Date().toISOString(),currentStep:lr(e,r),level:e,message:t,details:r??{}}}var K=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 S.mkdir(this.logDir,{recursive:true}),await S.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(t){this.writeQueue=this.writeQueue.then(t).catch(r=>{this.writeError=r instanceof Error?r:new Error(String(r));});}enqueueLine(t){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await S.appendFile(this.logPath,`${t}
|
|
6
|
+
`,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>ur(t,r));}updateCurrentEvent(t,r,s){let n=cr(t,r,s);this.enqueueTask(async()=>{await S.mkdir(this.logDir,{recursive:true}),await S.writeFile(this.currentEventPath,JSON.stringify(n,null,2),"utf8");});}push(t,r,s){let n=JSON.stringify({time:new Date().toISOString(),level:t,message:r,...s||{}});this.enqueueLine(n),this.updateCurrentEvent(t,r,s),t==="error"?console.error(r,s||""):t==="warn"?console.warn(r,s||""):(Q[this.level]>=Q.debug||["summary","page","sitemap","asset","timing"].includes(t))&&console.log(r);}info(t,r){this.push("info",t,r);}debug(t,r){Q[this.level]<Q.debug||this.push("debug",t,r);}progress(t,r){ar("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),Q[this.level]>=Q.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),Q[this.level]>=Q.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 hr=["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"],fr=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"]),mr=new Set(["",".html",".htm"]),wr=new Set([".css",".xml",".xsl",".svg",".json",".html",".htm",".txt",".enc",".jws"]),Pr=["/wp-content/","/wp-includes/","/wp-admin/","/static/","/assets/","/build/","/_next/"];function Sr(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 Ae(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?h.resolve(e):""}function br(){let e=Ae();return e?h.resolve(e,".."):""}function yr(){let e=process.env.STATIC_PUBLISHER_WP_ROOT||process.env.WPSUITE_STATIC_PUBLISHER_WP_ROOT||"";return e.trim()?h.resolve(e):""}function vr(e){let t=e.trim(),r=[{alias:"@storage-root",root:br(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@runtime",root:Ae(),requiredEnv:"STATIC_PUBLISHER_RUNTIME_DIR or WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR"},{alias:"@wp-root",root:yr(),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 dt(e){let t=Ae();return t?h.join(t,"crawl-manifest.json"):h.join(e.outputDir,".crawl-manifest.json")}function pt(){return {schemaVersion:3,updatedAt:"",pages:{},assets:{}}}function Ze(e){return {url:String(e.url||""),outputPath:String(e.outputPath||""),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 Rr(e){let t=e.isText===true;return {url:String(e.url||""),outputPath:String(e.outputPath||""),isText:t,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 Cr(){return {rewriteTargets:new Set,changedFiles:new Set,deletedFiles:new Set}}function N(e,t,r){let s=se(t.outputDir,r);s&&(e.changedFiles.add(s),e.deletedFiles.delete(s));}function et(e,t,r){let s=se(t.outputDir,r);s&&(e.deletedFiles.add(s),e.changedFiles.delete(s));}function ce(e,t){e.rewriteTargets.add(h.resolve(t));}async function kr(e){try{let t=await S.readFile(dt(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,Ze(n)])),assets:Object.fromEntries(Object.entries(r.assets).map(([s,n])=>[s,Rr(n)]))};if(r.schemaVersion===1)return {schemaVersion:3,updatedAt:String(r.updatedAt||""),pages:Object.fromEntries(Object.entries(r.pages).map(([s,n])=>[s,Ze(n)])),assets:{}}}}catch{}return pt()}function xe(e){return JSON.parse(JSON.stringify(e))}async function xr(e,t){let r=dt(e);await S.mkdir(h.dirname(r),{recursive:true}),await S.writeFile(r,JSON.stringify(t,null,2),"utf8");}async function J(e,t){if(!t.trackManifest)return;let r=async()=>{let s=xe(t.manifest);s.updatedAt=new Date().toISOString(),t.manifest.updatedAt=s.updatedAt,await xr(e,s);};t.manifestSaveChain=t.manifestSaveChain.then(r,r),await t.manifestSaveChain;}function Y(e){if(!e)return null;let t=e.trim();return t||null}function Tr(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 Ar(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 c of a.items)!c||typeof c.url!="string"||o.set(c.url,c);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 Ar(e,t,[s],n)).get(s)??null;return Le(e,s)&&(!u||u.supported!==true||!u.token)&&(u=await Mr(e,t,s,n)),r.changeTokenCache.set(s,u),u}async function Mr(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=ie(`${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 Ar(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 Mr(e,t,n,i)?{action:"render",changeToken:a}:{action:"reuse",changeToken:a}:{action:"render",changeToken:a};let o=Y(r.sitemapLastmodByPage[n]);return o&&l.sitemapLastmod&&l.sitemapLastmod===o?{action:"reuse",changeToken:a}:{action:"render",changeToken:a}}async function Mr(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 Lr(e,t,r,s,n){let i=et(r.previousManifest),u=0;for(let[d,g]of Object.entries(r.manifest.pages))if(!r.seenPages.has(d)){Ze(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 ${d}`,{url:d,outputPath:g.outputPath,error:String(f)});}delete r.manifest.pages[d],u++;}let l=et(r.manifest,r.runId),a=new Set,o=new Set;for(let d of l){for(let m of X(e,d))a.add(m);let g=r.manifest.assets[d]?.outputPath;g&&o.add(g);let f=de(e,t.assetMap,d);f&&o.add(f);}for(let d of Object.keys(r.manifest.assets))l.has(d)||delete r.manifest.assets[d];let c=0,p=0;for(let d of i){let g=new Set,f=r.previousManifest.assets[d]?.outputPath;f&&g.add(f);let m=de(e,t.assetMap,d);if(!l.has(d)&&m)g.add(m);else if(!l.has(d)){let P=Ie(e,d);g.add(P.originalFilePath),P.hashedFilePath&&g.add(P.hashedFilePath);}for(let P of g)if(!o.has(P)){Ze(n,e,P);try{await S.unlink(P),c++;}catch(w){(w.code||"")!=="ENOENT"&&s.warn(`Failed to remove stale incremental asset output for ${d}`,{url:d,outputPath:P,error:String(w)});}}for(let P of X(e,d))a.has(P)||Object.prototype.hasOwnProperty.call(t.assetMap,P)&&(delete t.assetMap[P],p++);}(u>0||c>0||p>0)&&s.info(`Incremental cleanup removed ${u} stale pages, ${c} stale assets, ${p} stale asset mappings`,{removedPages:u,removedAssets:c,removedAssetMappings:p,phase:"incremental-cleanup"});}function et(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 tt(e,t,r){for(let s of t)for(let n of X(e,s))if(r.has(n))return true;return false}function Ir(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=kr(s,n);if(u.size===0)return [...i];for(let l of Object.values(t.manifest.pages))tt(e,l.discoveredAssets,u)&&i.add(h.resolve(l.outputPath));for(let[l,a]of Object.entries(t.manifest.assets)){a.isText&&tt(e,a.discoveredAssets,u)&&i.add(h.resolve(a.outputPath));for(let o of X(e,l))if(u.has(o)){N(r,e,a.outputPath),a.isText&&i.add(h.resolve(a.outputPath));break}}return [...i]}function Or(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 X(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 Dr(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 pt(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 Fr(e,t,r){for(let s of Dr(e,r)){let n=t[s];if(!n)continue;let i=pt(e,n);if(i)return {outputPath:i,publicUrl:n}}return null}function Er(e,t,r){for(let s of X(e,r)){let n=t[s];if(!n)continue;let i=pt(e,n);if(i)return i}return null}function de(e,t,r){let s=Er(e,t,r);return s||Ie(e,r).originalFilePath}function jr(){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 rt(e){let t=jr();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 $r(e,t){let r=new Set;for(let s of t.donePages)r.add(h.resolve(z(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:",ue=new Map;function Ur(e){if(!e.startsWith(pe))return null;let t=ue.get(e);if(t!==void 0)return t||null;let r=e.slice(pe.length).trim();if(!r)return ue.set(e,false),null;try{let s=new RegExp(r);return ue.set(e,s),s}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),ue.set(e,false),null}}function Me(e,t){let r=Ur(t);return r?r.test(e):t.startsWith(pe)?false:e.startsWith(t)}function qr(e,t){return t.find(r=>Me(e,r))}function gt(e,t){let r=qr(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 Qr(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 Nr(e,t){return Qr(e).has(t.hostname)}function Wr(e){let t=q(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function ht(e){let t=q(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)}function Z(e){return mr.some(t=>e.pathname.startsWith(t))}function T(e,t,r=e.sourceOrigin,s,n="url"){let i=Wr(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(ht(i))return s?.ignore(n,t,"looks like JavaScript/code fragment",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(!Nr(e,u))return s?.ignore(n,u.toString(),"host not allowed",r),null;let l=gt(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 ft(e){return gr.has(h.extname(e.pathname).toLowerCase())}function G(e){return Z(e)?false:hr.has(h.extname(e.pathname).toLowerCase())}function re(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function C(e,t){return re(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")?true:ft(t)?e.assetPathPrefixes.length===0?true:e.assetPathPrefixes.some(r=>Me(t.pathname,r)):false}function z(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 _r(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=_r(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}.${ie(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 Br(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 mt(e){try{return await S.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function wt(e){try{return await S.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function Hr(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 Pt(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=Pt(t),s=Hr(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 Jr(e,t){if(!t)return;let r=Pt(t);if(r===null)return;let s=await wt(e);if(!s)return;let n=new Date(r);await S.utimes(e,s.atime,n).catch(()=>{});}function st(e,t){let r=h.extname(e.pathname).toLowerCase(),s=t["content-type"]||"";return fr.has(r)||pr.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 Gr(e){return ie(e.toString("base64"),40)}function Vr(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 Kr(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=Gr(s),o=l.originalFilePath,c=l.originalPublicUrlWithSearch;if(l.preferQueryHashed&&l.hashedFilePath&&l.hashedPublicUrl&&Vr(n,l.originalFilePath,a)){let f=Fr(e,t,r);f?(o=f.outputPath,c=f.publicUrl):(o=l.hashedFilePath,c=l.hashedPublicUrl);}Br(e,t,r,c,l.originalPublicUrl);let p=_(o)?Buffer.from(ve(s.toString("utf8"),e,t,o),"utf8"):s,d=await mt(o),g=false;return (d===null||!d.equals(p))&&(await Pe(o),await S.writeFile(o,p),g=true),Kr(n,l.originalFilePath,a),await Jr(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:c,wroteFile:g}}function ee(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 d=new URL(p);return re(d)?{discoveredFrom:p,discoveredFromType:"sitemap"}:C(e,d)?{discoveredFrom:p,discoveredFromType:"asset"}:G(d)&&!Z(d)?{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(!G(l)||ft(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(),Z(l)?"asset/internal path cannot be page":"not page-like",n);return}let a=l.toString(),{discoveredFrom:o,discoveredFromType:c}=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:c,outputPath:z(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(!re(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 Yr(e){let t=q(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:Y(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 Xr(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function Zr(e){let t=[],r=/url\(\s*(?:"([^"]+)"|'([^']+)'|([^)]*?))\s*\)/gi;for(let s of e.matchAll(r)){let n=(s[1]||s[2]||s[3]||"").trim();n&&t.push(n);}return t}function ke(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function St(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 St(i,u));continue}await S.copyFile(i,u),r.push(u);}return r}async function es(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=br(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,c=ke(l);if(!c){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 d=h.resolve(e.outputDir,c);if(p.isDirectory()){n.push(...await St(o,d)),s++,t.progress(`Copied static directory to export: ${o} -> /${c}`,{phase:"copy-extra-paths",sourcePath:o,targetPath:`/${c}`,copiedItems:s});continue}let g=h.basename(o),f=l.endsWith("/")?h.join(d,g):d;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} -> /${ke(l.endsWith("/")?`${l}${g}`:l)}`,{phase:"copy-extra-paths",sourcePath:o,targetPath:`/${ke(l.endsWith("/")?`${l}${g}`:l)}`,copiedItems:s});}return t.endMark("copy-extra-paths",{mappedSources:r.length,copiedItems:s}),n}function te(e,t,r,s,n){let i=new Set,u=q(r).replace(/\\\//g,"/");for(let o of Zr(u)){let c=T(e,o,t,s,`${n}:css-url`);c&&C(e,c)&&i.add(c.toString());}for(let o of u.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let c=T(e,o[1],t,s,`${n}:css-import`);c&&C(e,c)&&i.add(c.toString());}for(let o of u.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let c=T(e,o[1],t,s,`${n}:xml-stylesheet`);c&&C(e,c)&&i.add(c.toString());}let l="(?: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)",a=new RegExp(`(?:https?:)?//[^\\s'"<>\\);]+\\.${l}(?:\\?[^\\s'"<>\\);]*)?|(?<!\\.)/[^\\s'"<>\\);]+\\.${l}(?:\\?[^\\s'"<>\\);]*)?`,"gi");for(let o of u.matchAll(a)){let c=o[0].startsWith("//")?`${new URL(e.sourceOrigin).protocol}${o[0]}`:o[0];if(ht(c)){s.ignore(`${n}:serialized-url`,c,"looks like JavaScript/code fragment",t);continue}let p=T(e,c,t,s,`${n}:serialized-url`);p&&C(e,p)?i.add(p.toString()):p&&s.ignore("asset",p.toString(),"serialized URL did not pass safe asset path filter",t);}return [...i]}function ts(e,t,r,s){let n=new Set,i=q(r);for(let u of i.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let l=u[1],a=T(e,l,t,s,"page-link");a&&(gt(e,a)||G(a)&&!Z(a)&&!C(e,a)&&n.add(a.toString()));}return [...n]}async function nt(e,t,r,s){for(;r.sitemapQueue.length>0;){let n=r.sitemapQueue.shift();if(r.queuedSitemaps.delete(n),!r.doneSitemaps.has(n)){r.doneSitemaps.add(n),s.sitemap(`Fetching sitemap ${n}`,{url:n});try{let i=await t.get(n,{timeout:6e4});if(!i.ok()){s.skip("sitemap",n,i.status());continue}let u=await i.body(),l=i.url()||n;await Te(e,r.assetMap,l,u,r,s);let a=u.toString("utf8");for(let o of te(e,l,a,s,"sitemap"))L(e,r,o,s,l);for(let o of Yr(a)){let c=T(e,o.loc,l,s,"sitemap-loc");c&&(re(c)?Oe(e,r,c.toString(),s,l):C(e,c)?L(e,r,c.toString(),s,l):G(c)?(o.lastmod&&(r.sitemapLastmodByPage[c.toString()]=o.lastmod),ee(e,r,c.toString(),s,l)):s.reject("sitemap-loc",c.toString(),"not page/sitemap/asset-like",l));}}catch(i){s.error(`Failed sitemap ${n}`,{url:n,error:String(i)});}}}}async function rs(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,c=(p,d={})=>{if(!o)return false;i.manifest.assets[a]={...o,discoveredAssets:[...o.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId},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,...d,phase:"download-assets"}),Ce(r,n),true};n.asset(`Fetching asset ${a}`,{url:a});try{let p=de(e,r.assetMap,a),d=p?await wt(p):null;if(p&&d)try{let k=await t.head(a,{timeout:6e4}),M=k.headers();if(k.ok()&&zr(d,M)){let E=await mt(p);if(E!==null){let W=k.url()||a,A=await Te(e,r.assetMap,W,E,r,n,M);A.wroteFile&&(N(u,e,A.outputPath),_(A.outputPath)&&ce(u,A.outputPath)),r.doneAssets.add(a),n.info(`Reused existing asset ${a} based on response headers.`,{url:a,filePath:p,lastModified:M["last-modified"]||"",contentLength:M["content-length"]||"",phase:"download-assets"}),Ce(r,n);let b=st(l,M),R=o?.discoveredAssets?[...o.discoveredAssets]:[];if(b||o?.isText){let $=E.toString("utf8"),V=te(e,W,$,n,"asset:cached");(V.length>0||!o)&&(R=V);for(let vt of R)L(e,r,vt,n,W);}if(i.trackManifest){let $=b||!!o?.isText;i.manifest.assets[a]={url:a,outputPath:A.outputPath,isText:$,discoveredAssets:R,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!$},i.enabled&&$&&await J(e,i);}return}}}catch{}let g=await t.get(a,{timeout:6e4});if(!g.ok()){if(c(`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&&(N(u,e,w.outputPath),_(w.outputPath)&&ce(u,w.outputPath)),r.doneAssets.add(a),Ce(r,n);let y=st(l,P),v=[];if(y){let k=f.toString("utf8");v=te(e,m,k,n,`asset:${h.extname(l.pathname).toLowerCase()||P["content-type"]||"unknown"}`);for(let M of v)L(e,r,M,n,m);}i.trackManifest&&(i.manifest.assets[a]={url:a,outputPath:w.outputPath,isText:y,discoveredAssets:v,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!y},i.enabled&&y&&await J(e,i));}catch(p){if(c("fetch-error",{error:String(p)}))return;n.error(`Failed asset ${a}`,{url:a,error:String(p)});}}async function ss(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 rs(e,t,r,a,s,n,i));}});await Promise.all(l);}function ns(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function F(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function le(e){return Math.max(15e3,Math.min(6e4,F(e)))}function is(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function De(e){return e.stats.pagesCompleted}function bt(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 os(e,t,r){let s=bt(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 x(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 ${ns(t)}.`));},t);})])}finally{s!==void 0&&globalThis.clearTimeout(s);}}async function as(e,t){let r=is(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 c=document.body?.scrollHeight||0,p=document.documentElement?.scrollHeight||0,d=Math.max(c,p);i>=d+window.innerHeight&&a();},120);});},{maxDurationMs:r});}async function us(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 as(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function ls(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 cs(e,t){return e.noJavaScriptRenderPathPrefixes.some(r=>Me(t,r))}async function ds(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"],c=new Set,p=["srcset","data-srcset","data-lazy-srcset"];return document.querySelectorAll("*").forEach(d=>{for(let f of o){let m=d.getAttribute(f);m&&a.add(m);}for(let f of p){let m=d.getAttribute(f);m&&m.split(",").forEach(P=>{let w=P.trim().split(/\s+/)[0];w&&a.add(w);});}let g=d.getAttribute("style");g&&c.add(g);}),{attrs:[...a],styles:[...c]}});for(let a of l.attrs)for(let o of Xr(a)){let c=T(e,o,r,s,"dom-attr");c&&C(e,c)&&i.add(c.toString());}for(let a of l.styles)for(let o of te(e,r,a,s,"dom-style"))i.add(o);}let u=await t.content();for(let l of te(e,r,u,s,"page-html"))i.add(l);return [...i]}async function it(e,t,r,s,n){let i=z(e,t);await x(`save page ${t}`,F(e),async()=>{await Pe(i),await S.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 ps(e){let t=De(e);return t%5===0||t===1||t===e.stats.pagesQueued}function gs(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 hs(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 fs(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 hs(s),s}async function ms(e,t,r,s,n,i,u){let l=await chromium.launch({headless:true}),a=bt(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 c=null,p=null;try{let d=new URL(o),g=Le(e,o),f=cs(e,d.pathname);if(!G(d)||C(e,d)||Z(d)){if(C(e,d)){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 Ar(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)ee(e,t,R,r,o);b.lastSeenRunId=i.runId,b.sitemapLastmod=Y(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}}c=await x(`create page context ${o}`,F(e),()=>fs(l,e,f)),p=await x(`create page ${o}`,F(e),()=>c.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 $=new URL(R.url()),V=new URL(o);if($.hash="",V.hash="",$.href===V.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 x(`read response body ${o}`,F(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:z(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 x(`wait for rendered page ${o}`,F(e),()=>ls(e,p))):await x(`wait for rendered page ${o}`,F(e),()=>us(e,p)),t.stats.pagesRendered++;let k=await x(`extract rendered assets ${o}`,F(e),()=>ds(e,p,o,r,!f));for(let b of k)L(e,t,b,r,o);let M=[...new Set([...k,...w])],E=v??await x(`capture rendered html ${o}`,F(e),()=>p.content()),W=s!=="single-url"&&!g?ts(e,o,E,r):[];if(s!=="single-url"&&!g)for(let b of W)ee(e,t,b,r,o);await it(e,o,E,t,r);let A=z(e,o);N(u,e,A),ce(u,A),i.trackManifest&&(i.manifest.pages[o]={url:o,outputPath:A,changeToken:m.changeToken?.supported?m.changeToken.token:null,tokenSource:m.changeToken?.supported?m.changeToken.tokenSource??null:null,sitemapLastmod:Y(t.sitemapLastmodByPage[o])??null,discoveredPages:W,discoveredAssets:M,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},i.enabled&&await J(e,i));}catch(d){try{let g=p?await x(`capture partial html ${o}`,F(e),()=>p.content()):"";if(g&&g.trim()){await it(e,o,g,t,r);let f=z(e,o);if(N(u,e,f),ce(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:Y(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 J(e,i);}r.warn(`Saved partial DOM for ${o}`,{url:o,error:String(d)});}}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(d)});}finally{t.stats.pagesCompleted++,ps(t)&&gs(t,r),p&&await x(`close page ${o}`,le(e),()=>p.close()).catch(d=>{r.warn(`Timed out while closing page ${o}`,{url:o,browserPid:a.pid,error:String(d)});}),c&&await x(`close page context ${o}`,le(e),()=>c.close()).catch(d=>{r.warn(`Timed out while closing page context for ${o}`,{url:o,browserPid:a.pid,error:String(d)});});}}}finally{await x("close worker browser",le(e),()=>l.close()).catch(o=>(r.warn("Timed out while closing crawl worker browser",{browserPid:a.pid,error:String(o)}),os(l,r,"browser.close timeout")));}}async function ws(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 ot(e){let t=String(e||"").toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("navigation timeout")}function Ps(e){let t=String(e?.job?.command||"").trim(),r=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:r!=="incremental"}function Ss(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 yt(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 at(e){let t=String(e.originalFileName||"").toLowerCase();return t.endsWith("errors.jsonl")?0:t.endsWith("errors.json")?1:2}function bs(e,t){let r=Array.isArray(t?.artifacts)?t.artifacts.filter(s=>String(s?.role||"").trim()==="errors"&&String(s?.storedFileName||"").trim()!=="").sort((s,n)=>at(s)-at(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 ut(e){let t=await yt(h.join(e,"job.json"));for(let r of bs(e,t)){let s=await ws(r);if(s.length>0)return s}return []}async function ys(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 yt(h.join(u,"job.json"));if(!Ps(a))continue;let o=Ss(a);o>=n&&(n=o,s=u);}return s}async function vs(e){let t=await ys(e),r=t!==""?await ut(t):await ut(e.logDir),s=new Set;for(let n of r)if(ot(n.error)||ot(n.message)){let i=n.url;typeof i=="string"&&i&&s.add(i);}return [...s]}async function Rs(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 Cs(e){try{let t=await S.readFile(h.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function ks(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 lt(e,t,r,s,n){let i=T(e,r,e.sourceOrigin,s,"manual-url");i&&(re(i)?Oe(e,t,i.toString(),s,n):C(e,i)?L(e,t,i.toString(),s,n):G(i)?ee(e,t,i.toString(),s,n):s.reject("manual-url",i.toString(),"not page/sitemap/asset-like",n));}async function xs(){let e=await we(),t=wr(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 vs(e)),t.mode==="single-url"&&(r=await Rs(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 Cs(e):{},a=n?await Rr(e):dt(),o={enabled:n,trackManifest:i,manifest:xe(a),previousManifest:xe(a),runId:`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve()};await ks(e.logDir);let c={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=vr();u||await S.rm(e.outputDir,{recursive:true,force:true}),await S.mkdir(e.outputDir,{recursive:true});let d=new K(e.logDir,e.logLevel);if(s&&!n&&d.warn("Incremental crawl requested without active remote publisher subscription. Falling back to full crawl.",{requestedMode:t.crawlMode,subscriptionType:e.subscriptionType??null}),t.resumeRewrite)d.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(d.mark("discovery"),t.mode==="full"?(e.sitemapPaths.forEach(v=>Oe(e,c,v,d)),await nt(e,w,c,d),e.seedPaths.forEach(v=>lt(e,c,v,d,"seed-path")),e.generated404RequestPath&&ee(e,c,e.generated404RequestPath,d,"generated-404-request-path")):(r.forEach(v=>lt(e,c,v,d,"cli")),await nt(e,w,c,d)),d.endMark("discovery",{pages:c.pageQueue.length,assets:c.assetQueue.length,sitemaps:c.sitemapQueue.length}),d.summary(`Queued ${c.pageQueue.length} pages, ${c.assetQueue.length} assets, ${c.sitemapQueue.length} sitemaps.`,{mode:t.mode,crawlMode:t.crawlMode,queuedPages:c.pageQueue.length,queuedAssets:c.assetQueue.length,queuedSitemaps:c.sitemapQueue.length}),t.mode==="retry-timeouts"&&c.pageQueue.length===0&&c.assetQueue.length===0&&c.sitemapQueue.length===0){d.summary("No timed-out URLs were queued. Skipping retry crawl.",{mode:t.mode,crawlMode:t.crawlMode,queuedPages:0,queuedAssets:0,queuedSitemaps:0}),await d.flush();return}d.mark("render-pages");let y=Array.from({length:Math.max(1,e.concurrency)},()=>ms(e,c,d,t.mode,w,o,p));if(await Promise.all(y),d.endMark("render-pages",{pages:c.stats.pagesCompleted}),d.mark("download-assets"),d.progress("Asset download phase started.",{phase:"download-assets",doneAssets:c.doneAssets.size,assetsQueued:c.stats.assetsQueued,assetQueue:c.assetQueue.length}),await ss(e,w,c,d,o,p),d.endMark("download-assets",{assets:c.doneAssets.size}),o.enabled&&e.maxPages===0&&await Lr(e,c,o,d,p),t.mode==="full"){let v=await es(e,d);for(let k of v)N(p,e,k);}}finally{await x("dispose crawl request context",le(e),()=>w.dispose()).catch(y=>{d.warn("Timed out while disposing crawl request context",{error:String(y)});});}}o.trackManifest&&await J(e,o),await S.writeFile(h.join(e.outputDir,"asset-map.json"),JSON.stringify(c.assetMap,null,2),"utf8"),JSON.stringify(l,null,2)!==JSON.stringify(c.assetMap,null,2)&&N(p,e,h.join(e.outputDir,"asset-map.json"));let g=t.mode==="single-url"?$r(e,c):o.enabled&&!t.resumeRewrite?Ir(e,o,p,l,c.assetMap):void 0;d.mark("rewrite-text");let f=t.mode==="single-url"?`Rewriting text files touched by URL crawl: 0/${g?.length??0}`:"Rewriting text files...";d.progress(f,{phase:"rewrite-text",index:0,totalFiles:g?.length,changedTextFiles:0}),await rt(f);let m=Date.now(),P=await Ge(e,c.assetMap,{files:g,previousAssetMap:l,onProgress:async({index:w,totalFiles:y,changedTextFiles:v,file:k,changed:M})=>{M&&N(p,e,h.join(e.outputDir,k)),d.checkpoint(`Rewriting text file ${w}/${y}`,{phase:"rewrite-text",index:w,totalFiles:y,changedTextFiles:v,file:k});let E=Date.now();if(!(w===1||w===y||E-m>=5e3))return;m=E;let A=`Rewriting text files: ${w}/${y}`;d.progress(A,{phase:"rewrite-text",index:w,totalFiles:y,changedTextFiles:v,file:k}),await rt(A);}});o.trackManifest&&(Or(o,g),await J(e,o)),d.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=>se(e.outputDir,h.isAbsolute(w)?w:h.join(e.outputDir,w))).filter(w=>w!==null))].sort():[]}),d.summary(t.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${P} text files.`:`Done. Rendered ${c.stats.pagesRendered} pages, processed ${c.doneSitemaps.size} sitemaps, downloaded ${c.doneAssets.size} assets.`,{mode:t.mode,crawlMode:t.crawlMode,resumeRewrite:t.resumeRewrite,...c.stats,pagesRendered:c.stats.pagesRendered,donePages:c.stats.pagesCompleted,claimedPages:c.donePages.size,doneSitemaps:c.doneSitemaps.size,doneAssets:c.doneAssets.size,changedTextFiles:P}),await d.flush();}xs().catch(async e=>{console.error(e);try{let r=(await we().catch(()=>null))?.logDir??"logs",s=new K(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 Lr(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 Ir(e,t,n,i)?{action:"render",changeToken:a}:{action:"reuse",changeToken:a}:{action:"render",changeToken:a};let o=Y(r.sitemapLastmodByPage[n]);return o&&l.sitemapLastmod&&l.sitemapLastmod===o?{action:"reuse",changeToken:a}:{action:"render",changeToken:a}}async function Ir(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 Or(e,t,r,s,n){let i=tt(r.previousManifest),u=0;for(let[d,g]of Object.entries(r.manifest.pages))if(!r.seenPages.has(d)){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 ${d}`,{url:d,outputPath:g.outputPath,error:String(f)});}delete r.manifest.pages[d],u++;}let l=tt(r.manifest,r.runId),a=new Set,o=new Set;for(let d of l){for(let m of X(e,d))a.add(m);let g=r.manifest.assets[d]?.outputPath;g&&o.add(g);let f=de(e,t.assetMap,d);f&&o.add(f);}for(let d of Object.keys(r.manifest.assets))l.has(d)||delete r.manifest.assets[d];let c=0,p=0;for(let d of i){let g=new Set,f=r.previousManifest.assets[d]?.outputPath;f&&g.add(f);let m=de(e,t.assetMap,d);if(!l.has(d)&&m)g.add(m);else if(!l.has(d)){let P=Ie(e,d);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),c++;}catch(w){(w.code||"")!=="ENOENT"&&s.warn(`Failed to remove stale incremental asset output for ${d}`,{url:d,outputPath:P,error:String(w)});}}for(let P of X(e,d))a.has(P)||Object.prototype.hasOwnProperty.call(t.assetMap,P)&&(delete t.assetMap[P],p++);}(u>0||c>0||p>0)&&s.info(`Incremental cleanup removed ${u} stale pages, ${c} stale assets, ${p} stale asset mappings`,{removedPages:u,removedAssets:c,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 X(e,s))if(r.has(n))return true;return false}function Dr(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=Tr(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 X(e,l))if(u.has(o)){N(r,e,a.outputPath),a.isText&&i.add(h.resolve(a.outputPath));break}}return [...i]}function Fr(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 X(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 $r(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 gt(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 Er(e,t,r){for(let s of $r(e,r)){let n=t[s];if(!n)continue;let i=gt(e,n);if(i)return {outputPath:i,publicUrl:n}}return null}function jr(e,t,r){for(let s of X(e,r)){let n=t[s];if(!n)continue;let i=gt(e,n);if(i)return i}return null}function de(e,t,r){let s=jr(e,t,r);return s||Ie(e,r).originalFilePath}function Ur(){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=Ur();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 qr(e,t){let r=new Set;for(let s of t.donePages)r.add(h.resolve(z(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:",ue=new Map;function Qr(e){if(!e.startsWith(pe))return null;let t=ue.get(e);if(t!==void 0)return t||null;let r=e.slice(pe.length).trim();if(!r)return ue.set(e,false),null;try{let s=new RegExp(r);return ue.set(e,s),s}catch{return console.warn(`[crawl] Ignoring invalid path matcher regex: ${e}`),ue.set(e,false),null}}function Me(e,t){let r=Qr(t);return r?r.test(e):t.startsWith(pe)?false:e.startsWith(t)}function Nr(e,t){return t.find(r=>Me(e,r))}function ht(e,t){let r=Nr(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 Wr(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 _r(e,t){return Wr(e).has(t.hostname)}function Br(e){let t=q(e.trim()).replace(/\\\//g,"/").replace(/^['"]|['"]$/g,"").trim();return t=t.replace(/[)]+$/g,"").trim(),t=t.replace(/;.*$/g,"").trim(),t}function ft(e){let t=q(e).replace(/\\\//g,"/");return /[{}]|\bwindow\.|\blocation\.|\bincludes\(|\?\?null|\+|%7B|%7D|%22|<|>|\s/.test(t)}function Z(e){return Pr.some(t=>e.pathname.startsWith(t))}function T(e,t,r=e.sourceOrigin,s,n="url"){let i=Br(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(ft(i))return s?.ignore(n,t,"looks like JavaScript/code fragment",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(!_r(e,u))return s?.ignore(n,u.toString(),"host not allowed",r),null;let l=ht(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 mt(e){return fr.has(h.extname(e.pathname).toLowerCase())}function G(e){return Z(e)?false:mr.has(h.extname(e.pathname).toLowerCase())}function re(e){let t=e.pathname.toLowerCase();return t.endsWith(".xml")&&(t.includes("sitemap")||t.endsWith("/sitemap.xml"))}function C(e,t){return re(t)||t.pathname==="/robots.txt"||t.pathname==="/llms.txt"||t.pathname.toLowerCase().endsWith(".xsl")?true:mt(t)?e.assetPathPrefixes.length===0?true:e.assetPathPrefixes.some(r=>Me(t.pathname,r)):false}function z(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 Hr(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=Hr(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}.${ie(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 zr(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 wt(e){try{return await S.readFile(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Pt(e){try{return await S.stat(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}function Jr(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 St(e){let t=String(e["last-modified"]||"").trim();if(!t)return null;let r=Date.parse(t);return Number.isFinite(r)?r:null}function Gr(e,t){let r=St(t),s=Jr(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 Vr(e,t){if(!t)return;let r=St(t);if(r===null)return;let s=await Pt(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 wr.has(r)||hr.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 Kr(e){return ie(e.toString("base64"),40)}function Yr(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 Xr(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=Kr(s),o=l.originalFilePath,c=l.originalPublicUrlWithSearch;if(l.preferQueryHashed&&l.hashedFilePath&&l.hashedPublicUrl&&Yr(n,l.originalFilePath,a)){let f=Er(e,t,r);f?(o=f.outputPath,c=f.publicUrl):(o=l.hashedFilePath,c=l.hashedPublicUrl);}zr(e,t,r,c,l.originalPublicUrl);let p=_(o)?Buffer.from(ve(s.toString("utf8"),e,t,o),"utf8"):s,d=await wt(o),g=false;return (d===null||!d.equals(p))&&(await Pe(o),await S.writeFile(o,p),g=true),Xr(n,l.originalFilePath,a),await Vr(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:c,wroteFile:g}}function ee(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 d=new URL(p);return re(d)?{discoveredFrom:p,discoveredFromType:"sitemap"}:C(e,d)?{discoveredFrom:p,discoveredFromType:"asset"}:G(d)&&!Z(d)?{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(!G(l)||mt(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(),Z(l)?"asset/internal path cannot be page":"not page-like",n);return}let a=l.toString(),{discoveredFrom:o,discoveredFromType:c}=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:c,outputPath:z(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(!re(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 Zr(e){let t=q(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:Y(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 es(e){return e.split(",").map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function ts(e){let t=[],r=/url\(\s*(?:"([^"]+)"|'([^']+)'|([^)]*?))\s*\)/gi;for(let s of e.matchAll(r)){let n=(s[1]||s[2]||s[3]||"").trim();n&&t.push(n);}return t}function ke(e){return e.trim().replace(/\\/g,"/").replace(/^https?:\/\/[^/]+/i,"").replace(/^\/+/,"")}async function bt(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 bt(i,u));continue}await S.copyFile(i,u),r.push(u);}return r}async function rs(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=vr(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,c=ke(l);if(!c){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 d=h.resolve(e.outputDir,c);if(p.isDirectory()){n.push(...await bt(o,d)),s++,t.progress(`Copied static directory to export: ${o} -> /${c}`,{phase:"copy-extra-paths",sourcePath:o,targetPath:`/${c}`,copiedItems:s});continue}let g=h.basename(o),f=l.endsWith("/")?h.join(d,g):d;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} -> /${ke(l.endsWith("/")?`${l}${g}`:l)}`,{phase:"copy-extra-paths",sourcePath:o,targetPath:`/${ke(l.endsWith("/")?`${l}${g}`:l)}`,copiedItems:s});}return t.endMark("copy-extra-paths",{mappedSources:r.length,copiedItems:s}),n}function te(e,t,r,s,n){let i=new Set,u=q(r).replace(/\\\//g,"/");for(let o of ts(u)){let c=T(e,o,t,s,`${n}:css-url`);c&&C(e,c)&&i.add(c.toString());}for(let o of u.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;]+)['"]?\s*\)?/gi)){let c=T(e,o[1],t,s,`${n}:css-import`);c&&C(e,c)&&i.add(c.toString());}for(let o of u.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi)){let c=T(e,o[1],t,s,`${n}:xml-stylesheet`);c&&C(e,c)&&i.add(c.toString());}let l="(?: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)",a=new RegExp(`(?:https?:)?//[^\\s'"<>\\);]+\\.${l}(?:\\?[^\\s'"<>\\);]*)?|(?<!\\.)/[^\\s'"<>\\);]+\\.${l}(?:\\?[^\\s'"<>\\);]*)?`,"gi");for(let o of u.matchAll(a)){let c=o[0].startsWith("//")?`${new URL(e.sourceOrigin).protocol}${o[0]}`:o[0];if(ft(c)){s.ignore(`${n}:serialized-url`,c,"looks like JavaScript/code fragment",t);continue}let p=T(e,c,t,s,`${n}:serialized-url`);p&&C(e,p)?i.add(p.toString()):p&&s.ignore("asset",p.toString(),"serialized URL did not pass safe asset path filter",t);}return [...i]}function ss(e,t,r,s){let n=new Set,i=q(r);for(let u of i.matchAll(/href=["']([^"'#\s][^"']*?)["']/gi)){let l=u[1],a=T(e,l,t,s,"page-link");a&&(ht(e,a)||G(a)&&!Z(a)&&!C(e,a)&&n.add(a.toString()));}return [...n]}async function it(e,t,r,s){for(;r.sitemapQueue.length>0;){let n=r.sitemapQueue.shift();if(r.queuedSitemaps.delete(n),!r.doneSitemaps.has(n)){r.doneSitemaps.add(n),s.sitemap(`Fetching sitemap ${n}`,{url:n});try{let i=await t.get(n,{timeout:6e4});if(!i.ok()){s.skip("sitemap",n,i.status());continue}let u=await i.body(),l=i.url()||n;await Te(e,r.assetMap,l,u,r,s);let a=u.toString("utf8");for(let o of te(e,l,a,s,"sitemap"))L(e,r,o,s,l);for(let o of Zr(a)){let c=T(e,o.loc,l,s,"sitemap-loc");c&&(re(c)?Oe(e,r,c.toString(),s,l):C(e,c)?L(e,r,c.toString(),s,l):G(c)?(o.lastmod&&(r.sitemapLastmodByPage[c.toString()]=o.lastmod),ee(e,r,c.toString(),s,l)):s.reject("sitemap-loc",c.toString(),"not page/sitemap/asset-like",l));}}catch(i){s.error(`Failed sitemap ${n}`,{url:n,error:String(i)});}}}}async function ns(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,c=(p,d={})=>{if(!o)return false;i.manifest.assets[a]={...o,discoveredAssets:[...o.discoveredAssets||[]],lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId},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,...d,phase:"download-assets"}),Ce(r,n),true};n.asset(`Fetching asset ${a}`,{url:a});try{let p=de(e,r.assetMap,a),d=p?await Pt(p):null;if(p&&d)try{let k=await t.head(a,{timeout:6e4}),M=k.headers();if(k.ok()&&Gr(d,M)){let $=await wt(p);if($!==null){let W=k.url()||a,A=await Te(e,r.assetMap,W,$,r,n,M);A.wroteFile&&(N(u,e,A.outputPath),_(A.outputPath)&&ce(u,A.outputPath)),r.doneAssets.add(a),n.info(`Reused existing asset ${a} based on response headers.`,{url:a,filePath:p,lastModified:M["last-modified"]||"",contentLength:M["content-length"]||"",phase:"download-assets"}),Ce(r,n);let b=nt(l,M),R=o?.discoveredAssets?[...o.discoveredAssets]:[];if(b||o?.isText){let j=$.toString("utf8"),V=te(e,W,j,n,"asset:cached");(V.length>0||!o)&&(R=V);for(let Rt of R)L(e,r,Rt,n,W);}if(i.trackManifest){let j=b||!!o?.isText;i.manifest.assets[a]={url:a,outputPath:A.outputPath,isText:j,discoveredAssets:R,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!j},i.enabled&&j&&await J(e,i);}return}}}catch{}let g=await t.get(a,{timeout:6e4});if(!g.ok()){if(c(`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&&(N(u,e,w.outputPath),_(w.outputPath)&&ce(u,w.outputPath)),r.doneAssets.add(a),Ce(r,n);let y=nt(l,P),v=[];if(y){let k=f.toString("utf8");v=te(e,m,k,n,`asset:${h.extname(l.pathname).toLowerCase()||P["content-type"]||"unknown"}`);for(let M of v)L(e,r,M,n,m);}i.trackManifest&&(i.manifest.assets[a]={url:a,outputPath:w.outputPath,isText:y,discoveredAssets:v,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!y},i.enabled&&y&&await J(e,i));}catch(p){if(c("fetch-error",{error:String(p)}))return;n.error(`Failed asset ${a}`,{url:a,error:String(p)});}}async function is(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 ns(e,t,r,a,s,n,i));}});await Promise.all(l);}function os(e){let t=Math.ceil(e/1e3);return `${t} second${t===1?"":"s"}`}function F(e){return Math.max(6e4,e.navigationTimeoutMs*2,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+15e3)}function le(e){return Math.max(15e3,Math.min(6e4,F(e)))}function as(e){return Math.max(15e3,e.readiness.timeoutMs+e.readiness.fallbackWaitMs+1e4)}function De(e){return e.stats.pagesCompleted}function yt(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 us(e,t,r){let s=yt(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 x(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 ${os(t)}.`));},t);})])}finally{s!==void 0&&globalThis.clearTimeout(s);}}async function ls(e,t){let r=as(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 c=document.body?.scrollHeight||0,p=document.documentElement?.scrollHeight||0,d=Math.max(c,p);i>=d+window.innerHeight&&a();},120);});},{maxDurationMs:r});}async function cs(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 ls(e,t),await t.waitForTimeout(e.readiness.fallbackWaitMs);}async function ds(e,t){await t.waitForLoadState("domcontentloaded",{timeout:e.readiness.timeoutMs}).catch(()=>{}),await t.waitForLoadState("load",{timeout:e.readiness.timeoutMs}).catch(()=>{}),e.readiness.waitForSelector&&await t.waitForSelector(e.readiness.waitForSelector,{timeout:e.readiness.timeoutMs}).catch(()=>{}),await t.waitForTimeout(e.readiness.fallbackWaitMs);}function ps(e,t){return e.noJavaScriptRenderPathPrefixes.some(r=>Me(t,r))}async function gs(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"],c=new Set,p=["srcset","data-srcset","data-lazy-srcset"];return document.querySelectorAll("*").forEach(d=>{for(let f of o){let m=d.getAttribute(f);m&&a.add(m);}for(let f of p){let m=d.getAttribute(f);m&&m.split(",").forEach(P=>{let w=P.trim().split(/\s+/)[0];w&&a.add(w);});}let g=d.getAttribute("style");g&&c.add(g);}),{attrs:[...a],styles:[...c]}});for(let a of l.attrs)for(let o of es(a)){let c=T(e,o,r,s,"dom-attr");c&&C(e,c)&&i.add(c.toString());}for(let a of l.styles)for(let o of te(e,r,a,s,"dom-style"))i.add(o);}let u=await t.content();for(let l of te(e,r,u,s,"page-html"))i.add(l);return [...i]}async function ot(e,t,r,s,n){let i=z(e,t);await x(`save page ${t}`,F(e),async()=>{await Pe(i),await S.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 hs(e){let t=De(e);return t%5===0||t===1||t===e.stats.pagesQueued}function fs(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 ms(e){await e.addInitScript(()=>{Object.defineProperty(window,"__WPSUITE_STATIC_EXPORT__",{value:true,writable:false,configurable:true});let t=r=>{if(r==null||String(r)==="")return true;try{let s=new URL(String(r),window.location.href),n=new URL(window.location.href);return s.hash="",n.hash="",s.href===n.href}catch{return false}};try{let r=window.location.assign.bind(window.location),s=window.location.replace.bind(window.location),n=window.location.reload.bind(window.location);Object.defineProperty(window.location,"assign",{configurable:!0,value:i=>{if(t(i)){console.warn("[smartcloud-static-publisher] blocked same-page location.assign",i??"");return}return r(i)}}),Object.defineProperty(window.location,"replace",{configurable:!0,value:i=>{if(t(i)){console.warn("[smartcloud-static-publisher] blocked same-page location.replace",i??"");return}return s(i)}}),Object.defineProperty(window.location,"reload",{configurable:!0,value:()=>{console.warn("[smartcloud-static-publisher] blocked location.reload");}});}catch{}});}async function ws(e,t,r){let s=await e.newContext({viewport:t.viewport,userAgent:"WPSuiteStaticPublisher/0.8 Playwright SitemapOnly",ignoreHTTPSErrors:t.ignoreHttpsErrors,...r?{javaScriptEnabled:false}:{}});return r||await ms(s),s}async function Ps(e,t,r,s,n,i,u){let l=await chromium.launch({headless:true}),a=yt(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 c=null,p=null;try{let d=new URL(o),g=Le(e,o),f=ps(e,d.pathname);if(!G(d)||C(e,d)||Z(d)){if(C(e,d)){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 Lr(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)ee(e,t,R,r,o);b.lastSeenRunId=i.runId,b.sitemapLastmod=Y(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}}c=await x(`create page context ${o}`,F(e),()=>ws(l,e,f)),p=await x(`create page ${o}`,F(e),()=>c.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 j=new URL(R.url()),V=new URL(o);if(j.hash="",V.hash="",j.href===V.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 x(`read response body ${o}`,F(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:z(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 x(`wait for rendered page ${o}`,F(e),()=>ds(e,p))):await x(`wait for rendered page ${o}`,F(e),()=>cs(e,p)),t.stats.pagesRendered++;let k=await x(`extract rendered assets ${o}`,F(e),()=>gs(e,p,o,r,!f));for(let b of k)L(e,t,b,r,o);let M=[...new Set([...k,...w])],$=v??await x(`capture rendered html ${o}`,F(e),()=>p.content()),W=s!=="single-url"&&!g?ss(e,o,$,r):[];if(s!=="single-url"&&!g)for(let b of W)ee(e,t,b,r,o);await ot(e,o,$,t,r);let A=z(e,o);N(u,e,A),ce(u,A),i.trackManifest&&(i.manifest.pages[o]={url:o,outputPath:A,changeToken:m.changeToken?.supported?m.changeToken.token:null,tokenSource:m.changeToken?.supported?m.changeToken.tokenSource??null:null,sitemapLastmod:Y(t.sitemapLastmodByPage[o])??null,discoveredPages:W,discoveredAssets:M,lastCrawledAt:new Date().toISOString(),lastSeenRunId:i.runId,rewriteComplete:!1},i.enabled&&await J(e,i));}catch(d){try{let g=p?await x(`capture partial html ${o}`,F(e),()=>p.content()):"";if(g&&g.trim()){await ot(e,o,g,t,r);let f=z(e,o);if(N(u,e,f),ce(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:Y(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 J(e,i);}r.warn(`Saved partial DOM for ${o}`,{url:o,error:String(d)});}}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(d)});}finally{t.stats.pagesCompleted++,hs(t)&&fs(t,r),p&&await x(`close page ${o}`,le(e),()=>p.close()).catch(d=>{r.warn(`Timed out while closing page ${o}`,{url:o,browserPid:a.pid,error:String(d)});}),c&&await x(`close page context ${o}`,le(e),()=>c.close()).catch(d=>{r.warn(`Timed out while closing page context for ${o}`,{url:o,browserPid:a.pid,error:String(d)});});}}}finally{await x("close worker browser",le(e),()=>l.close()).catch(o=>(r.warn("Timed out while closing crawl worker browser",{browserPid:a.pid,error:String(o)}),us(l,r,"browser.close timeout")));}}async function Ss(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 bs(e){let t=String(e?.job?.command||"").trim(),r=String(e?.job?.crawlMode||"full").trim();return t!=="publish"&&t!=="crawl"?false:r!=="incremental"}function ys(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 vt(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 vs(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 vt(h.join(e,"job.json"));for(let r of vs(e,t)){let s=await Ss(r);if(s.length>0)return s}return []}async function Rs(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 vt(h.join(u,"job.json"));if(!bs(a))continue;let o=ys(a);o>=n&&(n=o,s=u);}return s}async function Cs(e){let t=await Rs(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 ks(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 xs(e){try{let t=await S.readFile(h.join(e.outputDir,"asset-map.json"),"utf8");return JSON.parse(t)}catch{return {}}}async function Ts(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&&(re(i)?Oe(e,t,i.toString(),s,n):C(e,i)?L(e,t,i.toString(),s,n):G(i)?ee(e,t,i.toString(),s,n):s.reject("manual-url",i.toString(),"not page/sitemap/asset-like",n));}async function As(){let e=await we(),t=Sr(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 Cs(e)),t.mode==="single-url"&&(r=await ks(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 xs(e):{},a=n?await kr(e):pt(),o={enabled:n,trackManifest:i,manifest:xe(a),previousManifest:xe(a),runId:`${Date.now()}`,seenPages:new Set,changeTokenCache:new Map,manifestSaveChain:Promise.resolve()};await Ts(e.logDir);let c={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=Cr();u||await S.rm(e.outputDir,{recursive:true,force:true}),await S.mkdir(e.outputDir,{recursive:true});let d=new K(e.logDir,e.logLevel);if(s&&!n&&d.warn("Incremental crawl requested without active remote publisher subscription. Falling back to full crawl.",{requestedMode:t.crawlMode,subscriptionType:e.subscriptionType??null}),t.resumeRewrite)d.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(d.mark("discovery"),t.mode==="full"?(e.sitemapPaths.forEach(v=>Oe(e,c,v,d)),await it(e,w,c,d),e.seedPaths.forEach(v=>ct(e,c,v,d,"seed-path")),e.generated404RequestPath&&ee(e,c,e.generated404RequestPath,d,"generated-404-request-path")):(r.forEach(v=>ct(e,c,v,d,"cli")),await it(e,w,c,d)),d.endMark("discovery",{pages:c.pageQueue.length,assets:c.assetQueue.length,sitemaps:c.sitemapQueue.length}),d.summary(`Queued ${c.pageQueue.length} pages, ${c.assetQueue.length} assets, ${c.sitemapQueue.length} sitemaps.`,{mode:t.mode,crawlMode:t.crawlMode,queuedPages:c.pageQueue.length,queuedAssets:c.assetQueue.length,queuedSitemaps:c.sitemapQueue.length}),t.mode==="retry-timeouts"&&c.pageQueue.length===0&&c.assetQueue.length===0&&c.sitemapQueue.length===0){d.summary("No timed-out URLs were queued. Skipping retry crawl.",{mode:t.mode,crawlMode:t.crawlMode,queuedPages:0,queuedAssets:0,queuedSitemaps:0}),await d.flush();return}d.mark("render-pages");let y=Array.from({length:Math.max(1,e.concurrency)},()=>Ps(e,c,d,t.mode,w,o,p));if(await Promise.all(y),d.endMark("render-pages",{pages:c.stats.pagesCompleted}),d.mark("download-assets"),d.progress("Asset download phase started.",{phase:"download-assets",doneAssets:c.doneAssets.size,assetsQueued:c.stats.assetsQueued,assetQueue:c.assetQueue.length}),await is(e,w,c,d,o,p),d.endMark("download-assets",{assets:c.doneAssets.size}),o.enabled&&e.maxPages===0&&await Or(e,c,o,d,p),t.mode==="full"){let v=await rs(e,d);for(let k of v)N(p,e,k);}}finally{await x("dispose crawl request context",le(e),()=>w.dispose()).catch(y=>{d.warn("Timed out while disposing crawl request context",{error:String(y)});});}}o.trackManifest&&await J(e,o),await S.writeFile(h.join(e.outputDir,"asset-map.json"),JSON.stringify(c.assetMap,null,2),"utf8"),JSON.stringify(l,null,2)!==JSON.stringify(c.assetMap,null,2)&&N(p,e,h.join(e.outputDir,"asset-map.json"));let g=t.mode==="single-url"?qr(e,c):o.enabled&&!t.resumeRewrite?Dr(e,o,p,l,c.assetMap):void 0;d.mark("rewrite-text");let f=t.mode==="single-url"?`Rewriting text files touched by URL crawl: 0/${g?.length??0}`:"Rewriting text files...";d.progress(f,{phase:"rewrite-text",index:0,totalFiles:g?.length,changedTextFiles:0}),await st(f);let m=Date.now(),P=await Ve(e,c.assetMap,{files:g,previousAssetMap:l,onProgress:async({index:w,totalFiles:y,changedTextFiles:v,file:k,changed:M})=>{M&&N(p,e,h.join(e.outputDir,k)),d.checkpoint(`Rewriting text file ${w}/${y}`,{phase:"rewrite-text",index:w,totalFiles:y,changedTextFiles:v,file:k});let $=Date.now();if(!(w===1||w===y||$-m>=5e3))return;m=$;let A=`Rewriting text files: ${w}/${y}`;d.progress(A,{phase:"rewrite-text",index:w,totalFiles:y,changedTextFiles:v,file:k}),await st(A);}});o.trackManifest&&(Fr(o,g),await J(e,o)),d.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=>se(e.outputDir,h.isAbsolute(w)?w:h.join(e.outputDir,w))).filter(w=>w!==null))].sort():[]}),d.summary(t.resumeRewrite?`Done. Resumed final rewrite over existing output and changed ${P} text files.`:`Done. Rendered ${c.stats.pagesRendered} pages, processed ${c.doneSitemaps.size} sitemaps, downloaded ${c.doneAssets.size} assets.`,{mode:t.mode,crawlMode:t.crawlMode,resumeRewrite:t.resumeRewrite,...c.stats,pagesRendered:c.stats.pagesRendered,donePages:c.stats.pagesCompleted,claimedPages:c.donePages.size,doneSitemaps:c.doneSitemaps.size,doneAssets:c.doneAssets.size,changedTextFiles:P}),await d.flush();}As().catch(async e=>{console.error(e);try{let r=(await we().catch(()=>null))?.logDir??"logs",s=new K(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 Mt from'fast-glob';import $ from'fs/promises';import w from'path';import Xt from'mime-types';import st from'http';import ot from'https';import {availableParallelism}from'os';import {Worker}from'worker_threads';function Pe(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function at(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&&w.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 lt(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={},l=s.s3;typeof l.bucket=="string"&&(a.bucket=l.bucket.trim()),typeof l.prefix=="string"&&(a.prefix=l.prefix.trim()),typeof l.region=="string"&&(a.region=l.region.trim()),typeof l.htmlCacheControl=="string"&&(a.htmlCacheControl=l.htmlCacheControl.trim()),typeof l.assetCacheControl=="string"&&(a.assetCacheControl=l.assetCacheControl.trim()),Object.keys(a).length>0&&(o.s3=a);}if(s.cloudFront&&typeof s.cloudFront=="object"){let a={},l=s.cloudFront;typeof l.distributionId=="string"&&(a.distributionId=l.distributionId.trim()),Array.isArray(l.invalidationPaths)&&(a.invalidationPaths=l.invalidationPaths.map(c=>String(c??"").trim()).filter(c=>c.length>0)),Object.keys(a).length>0&&(o.cloudFront=a);}t[i]=o;}return t}function Se(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function ut(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)=>ut(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 ct(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=ct(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 l=String(t.runtimeToken??t.nonce??"").trim();l&&(u.runtimeToken=l);let c=String(t.uploadUrl??"").trim();c&&(u.uploadUrl=c),Object.keys(o).length>0&&(u.siteSettings=o);let p=Se(t.subscriptionType);return p&&(u.subscriptionType=p),u}function gt(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 pt(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:"?st:ot,o=pt(e,t);return await new Promise((u,a)=>{let l=s.request(n,{method:i,headers:Object.fromEntries(o.entries()),...n.protocol==="https:"?{rejectUnauthorized:false}:{}},c=>{let p=[];c.on("data",g=>{p.push(Buffer.isBuffer(g)?g:Buffer.from(g));}),c.on("error",a),c.on("end",()=>{let g=c.statusCode??0,d=c.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 y=new Headers;for(let[b,P]of Object.entries(c.headers))Array.isArray(P)?y.set(b,P.join(", ")):typeof P=="string"&&y.set(b,P);u(new Response(Buffer.concat(p),{status:g,statusText:c.statusMessage??"",headers:y}));});});l.on("error",a),l.end();})}function dt(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;gt(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 ft(e){if(!dt(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=lt(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 ht(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?w.resolve(e):""}function be(e,t,r){let n=String(t||"").trim();return n&&w.isAbsolute(n)?w.resolve(n):w.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=at(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 ft(n)),s=ht(),o=s?w.resolve(s,".."):"";return o?(i.outputDir=be(o,i.outputDir,"export"),i.logDir=be(o,i.logDir,"logs")):(w.isAbsolute(i.outputDir)||(i.outputDir=oe(i.outputDir,"export")),w.isAbsolute(i.logDir)||(i.logDir=oe(i.logDir,"logs"))),i}function wt(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 ${wt(t)}.`));},t);try{return await r({abortController:n,httpOptions:{abortSignal:n.signal,requestTimeout:t}})}finally{globalThis.clearTimeout(i);}}var yt=".deploy-plan.json",bt="deploy-plan.json";function Pt(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?w.resolve(e):""}function St(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(St).filter(t=>t!==null))]}function vt(e,t){return {schemaVersion:1,generatedAt:String(t.generatedAt||new Date().toISOString()),outputDir:w.resolve(e.outputDir),runMode:t.runMode,crawlMode:t.crawlMode,fullSyncRequired:!!t.fullSyncRequired,changedFiles:ue(t.changedFiles||[]),deletedFiles:ue(t.deletedFiles||[]),rewriteTargets:ue(t.rewriteTargets||[])}}function Rt(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=w.join(w.resolve(e.outputDir),yt),r=Pt();return r?[w.join(r,bt),t]:[t]}async function Te(e){let t=w.resolve(e.outputDir);for(let r of De(e))try{let n=await $.readFile(r,"utf8"),i=JSON.parse(n);if(!Rt(i)||w.resolve(i.outputDir)!==t)continue;return vt(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 $t(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 xt(e,t){return {...e,...t??{}}}function Dt(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function Me(e,t){let r=String(t??e.deploymentTargetOverride??"").trim();if(!$t(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:xt(e.s3,i.s3),cloudFront:Dt(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?w.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 Tt(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 Ct(e,t,r){Q&&(Ie=Ie.then(async()=>{let n=new Date,i=n.toISOString();await $.mkdir(w.dirname(Q),{recursive:true});let s=await $.readFile(Q,"utf8").then(b=>JSON.parse(b)).catch(()=>null),o=s&&typeof s.details=="object"&&s.details?s.details:{},u=Oe(e),a=s?.currentStep||Oe(s?.source||""),l=s?.startedAt||i,c={...s?.stepDurationsSec??{}},p=s?.stepStartedAt||i;if(a&&a!==u&&s?.stepStartedAt){let b=Math.max(0,Math.round((n.getTime()-new Date(s.stepStartedAt).getTime())/1e3));c[a]=(c[a]??0)+b,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(l).getTime())/1e3)),y={checkedAt:i,source:e,message:t,details:Tt(o,r??{}),startedAt:l,currentStep:u,stepStartedAt:p,stepElapsedSec:g,totalElapsedSec:d,stepDurationsSec:c};await $.writeFile(Q,JSON.stringify(y,null,2),"utf8");}).catch(()=>{}));}async function Et(e,t){await $.mkdir(w.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 Lt from'fast-glob';import $ from'fs/promises';import w from'path';import tr 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&&w.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={},l=s.s3;typeof l.bucket=="string"&&(a.bucket=l.bucket.trim()),typeof l.prefix=="string"&&(a.prefix=l.prefix.trim()),typeof l.region=="string"&&(a.region=l.region.trim()),typeof l.htmlCacheControl=="string"&&(a.htmlCacheControl=l.htmlCacheControl.trim()),typeof l.assetCacheControl=="string"&&(a.assetCacheControl=l.assetCacheControl.trim()),Object.keys(a).length>0&&(o.s3=a);}if(s.cloudFront&&typeof s.cloudFront=="object"){let a={},l=s.cloudFront;typeof l.distributionId=="string"&&(a.distributionId=l.distributionId.trim()),Array.isArray(l.invalidationPaths)&&(a.invalidationPaths=l.invalidationPaths.map(c=>String(c??"").trim()).filter(c=>c.length>0)),Object.keys(a).length>0&&(o.cloudFront=a);}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 l=String(t.runtimeToken??t.nonce??"").trim();l&&(u.runtimeToken=l);let c=String(t.uploadUrl??"").trim();c&&(u.uploadUrl=c),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 l=s.request(n,{method:i,headers:Object.fromEntries(o.entries()),...n.protocol==="https:"?{rejectUnauthorized:false}:{}},c=>{let p=[];c.on("data",g=>{p.push(Buffer.isBuffer(g)?g:Buffer.from(g));}),c.on("error",a),c.on("end",()=>{let g=c.statusCode??0,d=c.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 y=new Headers;for(let[b,P]of Object.entries(c.headers))Array.isArray(P)?y.set(b,P.join(", ")):typeof P=="string"&&y.set(b,P);u(new Response(Buffer.concat(p),{status:g,statusText:c.statusMessage??"",headers:y}));});});l.on("error",a),l.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()?w.resolve(e):""}function be(e,t,r){let n=String(t||"").trim();return n&&w.isAbsolute(n)?w.resolve(n):w.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?w.resolve(s,".."):"";return o?(i.outputDir=be(o,i.outputDir,"export"),i.logDir=be(o,i.logDir,"logs")):(w.isAbsolute(i.outputDir)||(i.outputDir=oe(i.outputDir,"export")),w.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()?w.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:w.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=w.join(w.resolve(e.outputDir),bt),r=St();return r?[w.join(r,Pt),t]:[t]}async function Te(e){let t=w.resolve(e.outputDir);for(let r of De(e))try{let n=await $.readFile(r,"utf8"),i=JSON.parse(n);if(!$t(i)||w.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?w.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(w.dirname(Q),{recursive:true});let s=await $.readFile(Q,"utf8").then(b=>JSON.parse(b)).catch(()=>null),o=s&&typeof s.details=="object"&&s.details?s.details:{},u=Oe(e),a=s?.currentStep||Oe(s?.source||""),l=s?.startedAt||i,c={...s?.stepDurationsSec??{}},p=s?.stepStartedAt||i;if(a&&a!==u&&s?.stepStartedAt){let b=Math.max(0,Math.round((n.getTime()-new Date(s.stepStartedAt).getTime())/1e3));c[a]=(c[a]??0)+b,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(l).getTime())/1e3)),y={checkedAt:i,source:e,message:t,details:Ct(o,r??{}),startedAt:l,currentStep:u,stepStartedAt:p,stepElapsedSec:g,totalElapsedSec:d,stepDurationsSec:c};await $.writeFile(Q,JSON.stringify(y,null,2),"utf8");}).catch(()=>{}));}async function Mt(e,t){await $.mkdir(w.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 w.join(this.logDir,this.logFile)}artifactPath(t){return this.logFile.endsWith(".log.jsonl")?w.join(this.logDir,this.logFile.replace(/\.log\.jsonl$/u,`${t}.jsonl`)):w.join(this.logDir,`${this.logFile}${t}.jsonl`)}get errorsPath(){return this.artifactPath(".errors")}get rejectedPath(){return this.artifactPath(".rejected")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await $.mkdir(this.logDir,{recursive:true}),await $.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(t){this.writeQueue=this.writeQueue.then(t).catch(r=>{this.writeError=r instanceof Error?r:new Error(String(r));});}enqueueLine(t){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await $.appendFile(this.logPath,`${t}
|
|
3
|
-
`,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>
|
|
3
|
+
`,"utf8");});}enqueueJsonLine(t,r){this.enqueueTask(()=>Mt(t,r));}accepts(t){return ke[t]<=ke[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){Et(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 Ae(e){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(w.extname(e).toLowerCase())}function _e(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 V(e){return e.replace(/\//g,"\\/")}function je(e){return e.replace(/\//g,"\\\\/")}function kt(e){try{let t=new URL(e);return t.protocol!=="http:"&&t.protocol!=="https:"?null:`//${t.host}${t.pathname}${t.search}${t.hash}`}catch{return null}}function Fe(e,t,r){if(!t)return;e[t]=r;let n=V(t),i=V(r);e[n]=i;let s=je(t),o=je(r);e[s]=o;let u=A(t),a=A(r);e[u]=a;let l=A(n),c=A(i);e[l]=c;let p=A(s),g=A(o);e[p]=g;}function Y(e,t,r){Fe(e,t,r);let n=kt(t);n&&n!==t&&Fe(e,n,r);}function Ue(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function Ne(e,t,r){if(!t)return r;let n=w.dirname(w.resolve(t)),i=w.resolve(e,r.replace(/^\/+/,"")),s=w.relative(n,i).replace(/\\/g,"/");return s?(s.startsWith(".")||(s=`./${s}`),s):"."}var jt=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Ft=new Set([".html",".htm"]),We="WPSuite.io Static Publisher",At=We.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function _t(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let i=w.extname(r).toLowerCase();return Ft.has(i)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Ut(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${At}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${We}" />`;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 _t(e){let t=Ae(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function Ut(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,l)=>_t(a)?`${o}${n(a)}${l}`:s),i}function Nt(e,t){if(!t)return null;let r=w.dirname(w.resolve(t)),n=w.resolve(e.outputDir),i=w.relative(r,n).replace(/\\/g,"/");return i?(i.startsWith(".")||(i=`./${i}`),i.endsWith("/")?i:`${i}/`):"./"}function zt(e,t,r){let n=Nt(t,r);if(!n)return e;let i=e;for(let s of It){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 l=s.replace(/\//g,"\\/"),c=n.replace(/\//g,"\\/"),p=l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),g=new RegExp(`(?:\\.{1,}\\\\/)+${p}`,"g"),d=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${p}`,"g"),y=new RegExp(`(?<![\\.\\\\])\\/${p}`,"g");i=i.replace(g,`${c}${l}`).replace(d,`${c}${l}`).replace(y,`${c}${l}`);}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:_e(t,e.targetOrigin),s=n?`${n.search}${n.hash}`:"";return e.urlRewriteMode==="root-relative"?`${i}${s}`:`${Ue(e.outputDir,r,i)}${s}`}function ce(e,t,r,n,i){Y(e,r,ge(t,n,i));}function Wt(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 qt(e,t,r,n,i={}){let s=e,o={};ce(o,t,t.sourceOrigin,t.targetOrigin,n);for(let[a,l]of Object.entries(t.extraReplacements))ce(o,t,a,l,n);for(let[a,l]of Object.entries(r))ce(o,t,a,l,n);for(let[a,l]of Object.entries(i)){let c=r[a];!c||c===l||Wt(o,t,l,c,n);}let u=Object.entries(o).sort((a,l)=>l[0].length-a[0].length);for(let[a,l]of u)s=s.split(a).join(l);return t.urlRewriteMode!=="absolute"&&(s=zt(s,t,n)),s=Ut(s,u.map(([,a])=>a)),Ft(t,s,n)&&(s=At(s)),s}async function Bt(e,t,r,n){let i=w.join(e.outputDir,n),s=w.extname(i).toLowerCase(),o;try{o=await $.readFile(i,"utf8");}catch(l){if(l.code!=="ENOENT")throw l;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 Ht(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 We(e,t,r={}){let i=(r.files?[...new Set(r.files)].map(g=>w.resolve(g)).filter(g=>g.startsWith(w.resolve(e.outputDir))).map(g=>w.relative(e.outputDir,g).replace(/\\/g,"/")).filter(g=>g.length>0):await Mt(["**/*"],{cwd:e.outputDir,onlyFiles:true,dot:true})).filter(g=>g!=="asset-map.json"&&Fe(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,l=0,c=null;if(u===1){for(let g of i){let d=await Bt(e,t,r.previousAssetMap??{},g);d.changed&&(s+=1),l+=1,await r.onProgress?.({index:l,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(;!c;){let d=a;if(d>=i.length)return;a+=1;let y=i[d],b=await Ht(g,y);b.changed&&(s+=1),l+=1,await r.onProgress?.({index:l,totalFiles:i.length,changedTextFiles:s,file:y,changed:b.changed});}}catch(d){throw c=d instanceof Error?d:new Error(String(d)),c}finally{await g.terminate().catch(()=>{});}});return await Promise.all(p),s}var Je="wpsuite-sha256",Ke="wpsuite-normalized-sha256",er=/(?:^|[-_:.])(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,tr=["SIGINT","SIGTERM"],ee=new Set,Z=new Map,qe=null;function rr(e){ee.add(e);let t=false;return ()=>{t||(t=true,ee.delete(e));}}async function nr(){let e=[...ee];e.length!==0&&await Promise.allSettled(e.map(async t=>{ee.delete(t),await $.rm(t,{recursive:true,force:true});}));}function ir(){if(!(Z.size>0))for(let e of tr){let t=()=>{qe||(qe=nr().finally(()=>{for(let[r,n]of Z)process.off(r,n);Z.clear(),process.exit(1);}));};Z.set(e,t),process.on(e,t);}}ir();function sr(e,t){let r=t.trim();return r?w.join(w.resolve(r),"crawl-manifest.json"):w.join(w.resolve(e),".crawl-manifest.json")}function Ge(e){return w.normalize(e).split(w.sep).join("/")}function Be(e,t){let r=w.relative(w.resolve(e),w.resolve(t));return !r||r.startsWith("..")||w.isAbsolute(r)?null:Ge(r)}async function or(e,t,r){let n=sr(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=0,a=0;for(let[l,c]of Object.entries(s.pages||{})){let p=String(c?.outputPath||"").trim();if(!p||c?.rewriteComplete===true)continue;let g=Be(e.outputDir,p);g&&(u++,o.has(g)||o.set(g,{kind:"page",sourceUrl:l,outputPath:w.resolve(p),relativePath:g}));}for(let[l,c]of Object.entries(s.assets||{})){let p=String(c?.outputPath||"").trim(),g=c?.isText===true;if(!p||!g||c?.rewriteComplete===true)continue;let d=Be(e.outputDir,p);d&&(a++,o.has(d)||o.set(d,{kind:"asset",sourceUrl:l,outputPath:w.resolve(p),relativePath:d}));}return {manifestPath:n,byRelativePath:o,pendingPages:u,pendingTextAssets:a}}function ar(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:ar(t)).join("")}function lr(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&&er.test(t)?lr(e):we.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?de(e):e}function ur(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function cr(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 gr(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"?ur(t):cr(r,t)}function pr(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 l=gr(o,a);return ` ${o}=${u}${l}${u}`});return `<${r}${i}>`})}function pe(e){let t=w.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(w.basename(e))}function X(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function dr(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 l=(a.ETag||"").replace(/^"|"$/g,"").toLowerCase(),c=Number(a.Size??0);i.set(a.Key,{etag:l,size:c});}s=u.NextContinuationToken,n.debug(`Listed S3 keys page ${o}: ${i.size} keys so far`);}while(s);return i}async function fr(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 Qe(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 mr(e,t,r,n,i){return Qe(e,t,Array.from(r).filter(s=>!n.has(s)),i)}function hr(e){return createHash("md5").update(e).digest("hex")}function He(e){return createHash("sha256").update(e).digest("hex")}function fe(e){return createHash("sha256").update(pr(e.toString("utf8"))).digest("hex")}async function wr(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?.[Je]||"").trim().toLowerCase()||null;return n.set(r,o),o}catch{return n.set(r,null),null}}async function yr(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?.[Ke]||"").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 br(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function Pr(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 Sr(e,t,r,n){let i=w.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,l])=>{let c=String(l??"");return t.urlRewriteMode==="absolute"&&t.targetOrigin&&r.targetOrigin&&t.targetOrigin!==r.targetOrigin&&(c=c.split(t.targetOrigin).join(r.targetOrigin)),c=Pr(c,n),[a,c]}));await $.writeFile(i,JSON.stringify(u,null,2),"utf8");}async function vr(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=w.join(w.dirname(e.outputDir),`.deploy-profile-${br(r)}-${Date.now()}`),a=rr(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 l={...e,sourceOrigin:e.targetOrigin,targetOrigin:t.targetOrigin,extraReplacements:n,outputDir:u},c=1;i.info(`Rewriting text files for deployment profile "${r}"...`);let p=await We(l,{},{onStart:({totalFiles:g,workerCount:d})=>{c=d,i.info(`Rewriting ${g} text file(s) for deployment profile "${r}" with ${d} worker(s).`);},onProgress:({index:g,totalFiles:d,changedTextFiles:y,file:b,changed:P})=>{let R=`Rewriting [${g}/${d}] ${b} (${P?"rewrote":"checked"}; ${y} changed so far)`;d<=200||g<=5||g%10===0||g===d?(i.progress(R,{file:b,index:g,totalFiles:d,changed:P,changedTextFiles:y,workerCount:c}),i.info(R)):i.debug(R);}});return await Sr(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(l){throw i.error(`Failed to prepare deployment profile "${r}" temporary output.`,{tempDir:u,outputDir:e.outputDir,error:l instanceof Error?l.message:String(l),...l instanceof Error&&l.stack?{stack:l.stack}:{}}),await $.rm(u,{recursive:true,force:true}).catch(()=>{}),a(),await i.flush().catch(()=>{}),l}}async function Rr(){let e=await le(),t=Ee(process.argv.slice(2)),r=Me(e,t),n=w.resolve(r.config.logDir||"logs"),i=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",s=i?w.join(w.resolve(i),"deploy-diff.json"):"",o=new B(n,"deploy.log.jsonl",r.config.logLevel??"info"),u=r.profile?.extraReplacements??{},a=async()=>{};try{let l=await vr(e,r.config,r.name,u,o);a=l.cleanup;let c={...r.config,outputDir:l.outputDir},p=c.s3SyncMode??"sdk-upload-delete",g=await Te(e),d=l.outputDir!==e.outputDir&&(e.targetOrigin!==r.config.targetOrigin||Object.keys(u).length>0),y=!!g&&!g.fullSyncRequired&&!d;r.name&&o.info(`Using deployment profile: ${r.name}`),o.info(`Starting deploy \u2014 s3://${c.s3.bucket}/${c.s3.prefix||""} (region: ${c.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."):y&&o.info(`Using incremental deploy plan: ${g.changedFiles.length} changed file(s), ${g.deletedFiles.length} deleted file(s).`),o.mark("deploy");let b=new S3Client({region:c.s3.region}),P=l.outputDir===e.outputDir?await or(e,i,o):null,O=y?(await Promise.all(g.changedFiles.map(async h=>{try{return (await $.stat(w.join(c.outputDir,h))).isFile()?h:null}catch{return null}}))).filter(h=>h!==null):await Mt(["**/*"],{cwd:c.outputDir,onlyFiles:!0,dot:!0}),R=[],J=[],m=O.filter(h=>{let L=P?.byRelativePath.get(Ge(h));if(!L)return !0;let f=X(c.s3.prefix,h);return R.push(h),J.push(f),o.reject(L.kind,L.sourceUrl||h,"rewrite not completed; deploy upload blocked","deploy-guard",{file:h,key:f,outputPath:L.outputPath,manifestPath:P?.manifestPath}),!1}),Ve=y?new Set:new Set(O.map(h=>X(c.s3.prefix,h)));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"}),y?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 "${c.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:c.s3.bucket,s3Prefix:c.s3.prefix||"",targetedPlan:y,deployGuardEnabled:l.outputDir===e.outputDir});let x=0,v=0,k=0,re=[],U=[],ne=[],K=[],N=new Map,Ye=new Map,Ze=new Map,Xe=new Map,et=new Map;y||(o.info("Listing existing S3 objects to detect unchanged files..."),N=await dr(b,c.s3.bucket,c.s3.prefix,o),o.info(`Found ${N.size} existing key(s) in S3.`));let tt=async h=>N.has(h)?N.get(h)??null:y?fr(b,c.s3.bucket,h,Ye):null;for(let h of m){let L=w.join(c.outputDir,h),f=X(c.s3.prefix,h),z=Xt.lookup(h)||"application/octet-stream",rt=pe(h)?c.s3.htmlCacheControl:c.s3.assetCacheControl,S=x+v+k+1;m.length<=200||S<=5||S%10===0||S===m.length?(o.progress(`Uploading [${S}/${m.length}] ${f} (${z})`,{file:h,key:f,index:S,totalFiles:m.length,contentType:z,mode:p}),o.info(`Uploading [${S}/${m.length}] ${f} (${z})`)):o.debug(`Uploading [${S}/${m.length}] ${f} (${z})`);try{let D=await $.readFile(L),W=await tt(f),q=null,j=null;if(W){let ie=D.byteLength;if(W.size===ie){let G=W.etag.includes("-");if(W.etag!==""&&!G){let nt=hr(D);if(W.etag===nt){v++,m.length<=200||v<=5||v%25===0?(o.progress(`Skipped unchanged [${S}/${m.length}] ${f}`,{file:h,key:f,index:S,totalFiles:m.length,uploaded:x,skipped:v,failed:k,mode:p,reason:"etag-md5-match"}),o.info(`Skipped unchanged [${S}/${m.length}] ${f}`)):o.debug(`Skipped unchanged [${S}/${m.length}] ${f}`),U.push(f);continue}}q=He(D);let ye=await wr(b,c.s3.bucket,f,Ze);if(ye&&ye===q){v++,m.length<=200||v<=5||v%25===0?(o.progress(`Skipped unchanged [${S}/${m.length}] ${f}`,{file:h,key:f,index:S,totalFiles:m.length,uploaded:x,skipped:v,failed:k,mode:p,reason:"metadata-sha256-match"}),o.info(`Skipped unchanged [${S}/${m.length}] ${f}`)):o.debug(`Skipped unchanged [${S}/${m.length}] ${f}`),U.push(f);continue}}if(pe(h)){j=fe(D);let G=await yr(b,c.s3.bucket,f,Xe,et);if(G&&G===j){v++,m.length<=200||v<=5||v%25===0?(o.progress(`Skipped semantically unchanged [${S}/${m.length}] ${f}`,{file:h,key:f,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}] ${f}`)):o.debug(`Skipped semantically unchanged [${S}/${m.length}] ${f}`),U.push(f);continue}}}q=q??He(D),j=j??(pe(h)?fe(D):null),await E(`S3 upload ${f}`,9e5,({abortController:ie})=>new Upload({client:b,abortController:ie,params:{Bucket:c.s3.bucket,Key:f,Body:D,ContentType:z,CacheControl:rt,Metadata:{[Je]:q,...j?{[Ke]:j}:{}}}}).done()),x++,re.push(f),(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++,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"?y?K=await Qe(b,c.s3.bucket,g.deletedFiles.map(h=>X(c.s3.prefix,h)),o):K=await mr(b,c.s3.bucket,N.keys(),Ve,o):o.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion."),s&&(await $.mkdir(w.dirname(s),{recursive:!0}),await $.writeFile(s,JSON.stringify({generatedAt:new Date().toISOString(),mode:p,summary:{totalFiles:O.length,eligibleFiles:m.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(()=>{});}}Rr().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 Nt(e){let t=_e(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function zt(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,l)=>Nt(a)?`${o}${n(a)}${l}`:s),i}function Wt(e,t){if(!t)return null;let r=w.dirname(w.resolve(t)),n=w.resolve(e.outputDir),i=w.relative(r,n).replace(/\\/g,"/");return i?(i.startsWith(".")||(i=`./${i}`),i.endsWith("/")?i:`${i}/`):"./"}function qt(e,t,r){let n=Wt(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 l=s.replace(/\//g,"\\/"),c=n.replace(/\//g,"\\/"),p=l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),g=new RegExp(`(?:\\.{1,}\\\\/)+${p}`,"g"),d=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${p}`,"g"),y=new RegExp(`(?<![\\.\\\\])\\/${p}`,"g");i=i.replace(g,`${c}${l}`).replace(d,`${c}${l}`).replace(y,`${c}${l}`);}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 Bt(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 Ht(e,t,r,n,i={}){let s=e,o={};ce(o,t,t.sourceOrigin,t.targetOrigin,n);for(let[a,l]of Object.entries(t.extraReplacements))ce(o,t,a,l,n);for(let[a,l]of Object.entries(r))ce(o,t,a,l,n);for(let[a,l]of Object.entries(i)){let c=r[a];!c||c===l||Bt(o,t,l,c,n);}let u=Object.entries(o).sort((a,l)=>l[0].length-a[0].length);for(let[a,l]of u)s=s.split(a).join(l);return t.urlRewriteMode!=="absolute"&&(s=qt(s,t,n)),s=zt(s,u.map(([,a])=>a)),_t(t,s,n)&&(s=Ut(s)),s}async function Jt(e,t,r,n){let i=w.join(e.outputDir,n),s=w.extname(i).toLowerCase(),o;try{o=await $.readFile(i,"utf8");}catch(l){if(l.code!=="ENOENT")throw l;return {changed:false}}let a=Ht(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 Kt(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=>w.resolve(g)).filter(g=>g.startsWith(w.resolve(e.outputDir))).map(g=>w.relative(e.outputDir,g).replace(/\\/g,"/")).filter(g=>g.length>0):await 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,l=0,c=null;if(u===1){for(let g of i){let d=await Jt(e,t,r.previousAssetMap??{},g);d.changed&&(s+=1),l+=1,await r.onProgress?.({index:l,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(;!c;){let d=a;if(d>=i.length)return;a+=1;let y=i[d],b=await Kt(g,y);b.changed&&(s+=1),l+=1,await r.onProgress?.({index:l,totalFiles:i.length,changedTextFiles:s,file:y,changed:b.changed});}}catch(d){throw c=d instanceof Error?d:new Error(String(d)),c}finally{await g.terminate().catch(()=>{});}});return await Promise.all(p),s}var Ke="wpsuite-sha256",Ge="wpsuite-normalized-sha256",rr=/(?:^|[-_:.])(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,nr=["SIGINT","SIGTERM"],ee=new Set,Z=new Map,Be=null;function ir(e){ee.add(e);let t=false;return ()=>{t||(t=true,ee.delete(e));}}async function sr(){let e=[...ee];e.length!==0&&await Promise.allSettled(e.map(async t=>{ee.delete(t),await $.rm(t,{recursive:true,force:true});}));}function or(){if(!(Z.size>0))for(let e of nr){let t=()=>{Be||(Be=sr().finally(()=>{for(let[r,n]of Z)process.off(r,n);Z.clear(),process.exit(1);}));};Z.set(e,t),process.on(e,t);}}or();function ar(e,t){let r=t.trim();return r?w.join(w.resolve(r),"crawl-manifest.json"):w.join(w.resolve(e),".crawl-manifest.json")}function Qe(e){return w.normalize(e).split(w.sep).join("/")}function He(e,t){let r=w.relative(w.resolve(e),w.resolve(t));return !r||r.startsWith("..")||w.isAbsolute(r)?null:Qe(r)}async function lr(e,t,r){let n=ar(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=0,a=0;for(let[l,c]of Object.entries(s.pages||{})){let p=String(c?.outputPath||"").trim();if(!p||c?.rewriteComplete===true)continue;let g=He(e.outputDir,p);g&&(u++,o.has(g)||o.set(g,{kind:"page",sourceUrl:l,outputPath:w.resolve(p),relativePath:g}));}for(let[l,c]of Object.entries(s.assets||{})){let p=String(c?.outputPath||"").trim(),g=c?.isText===true;if(!p||!g||c?.rewriteComplete===true)continue;let d=He(e.outputDir,p);d&&(a++,o.has(d)||o.set(d,{kind:"asset",sourceUrl:l,outputPath:w.resolve(p),relativePath:d}));}return {manifestPath:n,byRelativePath:o,pendingPages:u,pendingTextAssets:a}}function ur(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:ur(t)).join("")}function cr(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&&rr.test(t)?cr(e):we.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)||/^[0-9]{8,}$/.test(e)?de(e):e}function gr(e){return e.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function pr(e,t){let r=t.trim();if((r.startsWith("{")||r.startsWith("[")||r.startsWith('"'))&&e.startsWith("data-"))try{let i=JSON.parse(r);return JSON.stringify(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 dr(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"?gr(t):pr(r,t)}function fr(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 l=dr(o,a);return ` ${o}=${u}${l}${u}`});return `<${r}${i}>`})}function pe(e){let t=w.extname(e).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(t)||["robots.txt","sitemap.xml"].includes(w.basename(e))}function X(e,t){return [e.replace(/^\/+|\/+$/g,""),t.replace(/^\/+/,"")].filter(Boolean).join("/")}async function hr(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 l=(a.ETag||"").replace(/^"|"$/g,"").toLowerCase(),c=Number(a.Size??0);i.set(a.Key,{etag:l,size:c});}s=u.NextContinuationToken,n.debug(`Listed S3 keys page ${o}: ${i.size} keys so far`);}while(s);return i}async function mr(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 wr(e,t,r,n,i){return Ve(e,t,Array.from(r).filter(s=>!n.has(s)),i)}function yr(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(fr(e.toString("utf8"))).digest("hex")}async function br(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 Pr(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 Sr(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function vr(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 Rr(e,t,r,n){let i=w.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,l])=>{let c=String(l??"");return t.urlRewriteMode==="absolute"&&t.targetOrigin&&r.targetOrigin&&t.targetOrigin!==r.targetOrigin&&(c=c.split(t.targetOrigin).join(r.targetOrigin)),c=vr(c,n),[a,c]}));await $.writeFile(i,JSON.stringify(u,null,2),"utf8");}async function $r(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=w.join(w.dirname(e.outputDir),`.deploy-profile-${Sr(r)}-${Date.now()}`),a=ir(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 l={...e,sourceOrigin:e.targetOrigin,targetOrigin:t.targetOrigin,extraReplacements:n,outputDir:u},c=1;i.info(`Rewriting text files for deployment profile "${r}"...`);let p=await qe(l,{},{onStart:({totalFiles:g,workerCount:d})=>{c=d,i.info(`Rewriting ${g} text file(s) for deployment profile "${r}" with ${d} worker(s).`);},onProgress:({index:g,totalFiles:d,changedTextFiles:y,file:b,changed:P})=>{let R=`Rewriting [${g}/${d}] ${b} (${P?"rewrote":"checked"}; ${y} changed so far)`;d<=200||g<=5||g%10===0||g===d?(i.progress(R,{file:b,index:g,totalFiles:d,changed:P,changedTextFiles:y,workerCount:c}),i.info(R)):i.debug(R);}});return await Rr(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(l){throw i.error(`Failed to prepare deployment profile "${r}" temporary output.`,{tempDir:u,outputDir:e.outputDir,error:l instanceof Error?l.message:String(l),...l instanceof Error&&l.stack?{stack:l.stack}:{}}),await $.rm(u,{recursive:true,force:true}).catch(()=>{}),a(),await i.flush().catch(()=>{}),l}}async function xr(){let e=await le(),t=Ee(process.argv.slice(2)),r=Me(e,t),n=w.resolve(r.config.logDir||"logs"),i=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",s=i?w.join(w.resolve(i),"deploy-diff.json"):"",o=new B(n,"deploy.log.jsonl",r.config.logLevel??"info"),u=r.profile?.extraReplacements??{},a=async()=>{};try{let l=await $r(e,r.config,r.name,u,o);a=l.cleanup;let c={...r.config,outputDir:l.outputDir},p=c.s3SyncMode??"sdk-upload-delete",g=await Te(e),d=l.outputDir!==e.outputDir&&(e.targetOrigin!==r.config.targetOrigin||Object.keys(u).length>0),y=!!g&&!g.fullSyncRequired&&!d;r.name&&o.info(`Using deployment profile: ${r.name}`),o.info(`Starting deploy \u2014 s3://${c.s3.bucket}/${c.s3.prefix||""} (region: ${c.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."):y&&o.info(`Using incremental deploy plan: ${g.changedFiles.length} changed file(s), ${g.deletedFiles.length} deleted file(s).`),o.mark("deploy");let b=new S3Client({region:c.s3.region}),P=l.outputDir===e.outputDir?await lr(e,i,o):null,O=y?(await Promise.all(g.changedFiles.map(async m=>{try{return (await $.stat(w.join(c.outputDir,m))).isFile()?m:null}catch{return null}}))).filter(m=>m!==null):await Lt(["**/*"],{cwd:c.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(c.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=y?new Set:new Set(O.map(m=>X(c.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"}),y?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 "${c.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:c.s3.bucket,s3Prefix:c.s3.prefix||"",targetedPlan:y,deployGuardEnabled:l.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;y||(o.info("Listing existing S3 objects to detect unchanged files..."),N=await hr(b,c.s3.bucket,c.s3.prefix,o),o.info(`Found ${N.size} existing key(s) in S3.`));let rt=async m=>N.has(m)?N.get(m)??null:y?mr(b,c.s3.bucket,m,Ze):null;for(let m of h){let L=w.join(c.outputDir,m),f=X(c.s3.prefix,m),z=tr.lookup(m)||"application/octet-stream",nt=pe(m)?c.s3.htmlCacheControl:c.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} (${z})`,{file:m,key:f,index:S,totalFiles:h.length,contentType:z,mode:p}),o.info(`Uploading [${S}/${h.length}] ${f} (${z})`)):o.debug(`Uploading [${S}/${h.length}] ${f} (${z})`);try{let D=await $.readFile(L),W=await rt(f),q=null,j=null;if(W){let ie=D.byteLength;if(W.size===ie){let G=W.etag.includes("-");if(W.etag!==""&&!G){let it=yr(D);if(W.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 br(b,c.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 Pr(b,c.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:b,abortController:ie,params:{Bucket:c.s3.bucket,Key:f,Body:D,ContentType:z,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"?y?K=await Ve(b,c.s3.bucket,g.deletedFiles.map(m=>X(c.s3.prefix,m)),o):K=await wr(b,c.s3.bucket,N.keys(),Ye,o):o.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion."),s&&(await $.mkdir(w.dirname(s),{recursive:!0}),await $.writeFile(s,JSON.stringify({generatedAt:new Date().toISOString(),mode:p,summary:{totalFiles: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(()=>{});}}xr().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);});
|
package/dist/rewrite-worker.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import F from'fs/promises';import f from'path';import {workerData,parentPort}from'worker_threads';import'fast-glob';import'os';import'crypto';function y(t){return t.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function p(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function d(t){return t.replace(/\//g,"\\/")}function $(t){return t.replace(/\//g,"\\\\/")}function A(t){try{let e=new URL(t);return e.protocol!=="http:"&&e.protocol!=="https:"?null:`//${e.host}${e.pathname}${e.search}${e.hash}`}catch{return null}}function P(t,e,i){if(!e)return;t[e]=i;let n=d(e),s=d(i);t[n]=s;let r=$(e),o=$(i);t[r]=o;let c=p(e),a=p(i);t[c]=a;let l=p(n),u=p(s);t[l]=u;let g=p(r),x=p(o);t[g]=x;}function m(t,e,i){P(t,e,i);let n=A(e);n&&n!==e&&P(t,n,i);}function E(t,e){try{return new URL(t,e==="."?"https://relative.invalid":e).pathname}catch{return t.startsWith("/")?t:`/${t.replace(/^\.\//,"")}`}}function S(t,e,i){if(!e)return i;let n=f.dirname(f.resolve(e)),s=f.resolve(t,i.replace(/^\/+/,"")),r=f.relative(n,s).replace(/\\/g,"/");return r?(r.startsWith(".")||(r=`./${r}`),r):"."}var D=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],k=new Set([".html",".htm"]),v="WPSuite.io Static Publisher",O=v.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function H(t,e,i){if(t.wpsuite?.siteSettings?.subscriber===true||t.wpsuite?.subscriptionType==="PROFESSIONAL"||t.wpsuite?.subscriptionType==="AGENCY"||!i)return false;let s=f.extname(i).toLowerCase();return k.has(s)?/<head\b|<html\b|<!doctype html/i.test(e):false}function L(t){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${O}\\2)[^>]*\\/?>`,"i").test(t))return t;let e=`<meta name="generator" content="${v}" />`;if(t.match(/(\r?\n)([ \t]*)<\/head>/i))return t.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${e}$1$2</head>`);let n=t.includes(`\r
|
|
2
2
|
`)?`\r
|
|
3
3
|
`:`
|
|
4
|
-
`;return
|
|
4
|
+
`;return t.replace(/<head\b[^>]*>/i,s=>`${s}${n} ${e}`)}function U(t){let e=y(t).trim();return e.startsWith("{")||e.startsWith("[")||e.includes("\\/")||/"@context"|"@type"/.test(e)}function N(t,e){let i=[...new Set(e)].filter(r=>r.includes("/")&&!/\\+\//.test(r)).map(r=>[r,d(r)]).filter(([r,o])=>r!==o).sort((r,o)=>o[0].length-r[0].length);if(!i.length)return t;let n=r=>{let o=r;for(let[c,a]of i)o=o.split(c).join(a);return o},s=t.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(r,o,c,a)=>`${o}${n(c)}${a}`);return s=s.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(r,o,c,a,l)=>U(a)?`${o}${n(a)}${l}`:r),s}function I(t,e){if(!e)return null;let i=f.dirname(f.resolve(e)),n=f.resolve(t.outputDir),s=f.relative(i,n).replace(/\\/g,"/");return s?(s.startsWith(".")||(s=`./${s}`),s.endsWith("/")?s:`${s}/`):"./"}function q(t,e,i){let n=I(e,i);if(!n)return t;let s=t;for(let r of D){let o=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=new RegExp(`(?:\\.{1,}/)+${o}`,"g"),a=new RegExp(`(?<!\\.)/${o}`,"g");s=s.replace(c,`${n}${r}`).replace(a,`${n}${r}`);let l=r.replace(/\//g,"\\/"),u=n.replace(/\//g,"\\/"),g=l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),x=new RegExp(`(?:\\.{1,}\\\\/)+${g}`,"g"),W=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${g}`,"g"),j=new RegExp(`(?<![\\.\\\\])\\/${g}`,"g");s=s.replace(x,`${u}${l}`).replace(W,`${u}${l}`).replace(j,`${u}${l}`);}return s}function R(t,e,i){if(t.urlRewriteMode==="absolute")return e;let n=(()=>{try{return new URL(e,t.targetOrigin==="."?"https://relative.invalid":t.targetOrigin)}catch{return null}})(),s=n?n.pathname:E(e,t.targetOrigin),r=n?`${n.search}${n.hash}`:"";return t.urlRewriteMode==="root-relative"?`${s}${r}`:`${S(t.outputDir,i,s)}${r}`}function b(t,e,i,n,s){m(t,i,R(e,n,s));}function V(t,e,i,n,s){if(!i||i===n)return;m(t,i,n);let r=R(e,i,s),o=R(e,n,s);m(t,r,o);}function M(t,e,i,n,s={}){let r=t,o={};b(o,e,e.sourceOrigin,e.targetOrigin,n);for(let[a,l]of Object.entries(e.extraReplacements))b(o,e,a,l,n);for(let[a,l]of Object.entries(i))b(o,e,a,l,n);for(let[a,l]of Object.entries(s)){let u=i[a];!u||u===l||V(o,e,l,u,n);}let c=Object.entries(o).sort((a,l)=>l[0].length-a[0].length);for(let[a,l]of c)r=r.split(a).join(l);return e.urlRewriteMode!=="absolute"&&(r=q(r,e,n)),r=N(r,c.map(([,a])=>a)),H(e,r,n)&&(r=L(r)),r}var{config:T,assetMap:J,previousAssetMap:B}=workerData;async function z(t){let e=f.join(T.outputDir,t),i=f.extname(e).toLowerCase(),n;try{n=await F.readFile(e,"utf8");}catch(o){if(o.code==="ENOENT")return false;throw o}let r=M(n,T,J,i===".js"||i===".mjs"?void 0:e,B);return r===n?false:(await F.writeFile(e,r,"utf8"),true)}if(!parentPort)throw new Error("rewrite worker requires a parent port");parentPort.on("message",async t=>{try{let e=await z(t.file);parentPort?.postMessage({changed:e});}catch(e){parentPort?.postMessage({changed:false,error:e instanceof Error?e.message:String(e)});}});
|
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.19",
|
|
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.",
|