@smart-cloud/publisher-exporter 1.1.65 → 1.1.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -8
- package/dist/content-sync.js +15 -14
- package/dist/crawl.js +13 -12
- package/dist/deploy.js +6 -6
- package/dist/invalidate.js +2 -2
- package/dist/queue-runner.js +3 -3
- package/dist/remote-worker-health.js +1 -1
- package/dist/remote-worker.js +3 -3
- package/package.json +2 -1
- package/remote-workers.example.json +3 -0
package/dist/deploy.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import O,{readFile}from'fs/promises';import er from'http';import tr from'https';import v from'path';import {S3Client,GetObjectCommand,PutObjectCommand,CopyObjectCommand,HeadObjectCommand,DeleteObjectsCommand,ListObjectsV2Command}from'@aws-sdk/client-s3';import {Upload}from'@aws-sdk/lib-storage';import Tr,{createHash}from'crypto';import Ar from'fast-glob';import Kt from'mime-types';import {availableParallelism}from'os';import {Worker}from'worker_threads';import {LambdaClient,InvokeCommand}from'@aws-sdk/client-lambda';import {fromTemporaryCredentials}from'@aws-sdk/credential-providers';var tt=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function nt(t){let e=t.trim();return e==="."?".":e.replace(/\/$/,"")}function rr(t){let e=String(t??"").trim();if(!e)return "";let r=e;if(/^https?:\/\//i.test(r))try{r=new URL(r).pathname;}catch{return ""}if(r=r.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!r)return "";let n=r.endsWith("/"),o=r.replace(/^\/+/,"").split("/").map(i=>i.replace(/[^A-Za-z0-9._-]/g,"")).filter(i=>i.length>0&&i!=="."&&i!=="..");if(o.length===0)return "";let s=`/${o.join("/")}`;return n&&v.extname(s)===""&&(s+="/"),s==="/"?"":s}function _e(t){return !t||typeof t!="object"?{}:Object.fromEntries(Object.entries(t).map(([e,r])=>[e.trim(),String(r??"")]).filter(([e])=>e.length>0))}function nr(t){if(!t||typeof t!="object")return {};let e={};for(let[r,n]of Object.entries(t)){let o=r.trim();if(!o||!n||typeof n!="object")continue;let s=n,i={};if(typeof s.targetOrigin=="string"){let l=nt(s.targetOrigin);l&&(i.targetOrigin=l);}let a=_e(s.extraReplacements);if(Object.keys(a).length>0&&(i.extraReplacements=a),s.s3&&typeof s.s3=="object"){let l={},u=s.s3;typeof u.bucket=="string"&&(l.bucket=u.bucket.trim()),typeof u.prefix=="string"&&(l.prefix=u.prefix.trim()),typeof u.region=="string"&&(l.region=u.region.trim()),typeof u.htmlCacheControl=="string"&&(l.htmlCacheControl=u.htmlCacheControl.trim()),typeof u.assetCacheControl=="string"&&(l.assetCacheControl=u.assetCacheControl.trim()),Object.keys(l).length>0&&(i.s3=l);}if(s.cloudFront&&typeof s.cloudFront=="object"){let l={},u=s.cloudFront;typeof u.distributionId=="string"&&(l.distributionId=u.distributionId.trim()),Array.isArray(u.invalidationPaths)&&(l.invalidationPaths=u.invalidationPaths.map(c=>String(c??"").trim()).filter(c=>c.length>0)),Object.keys(l).length>0&&(i.cloudFront=l);}e[o]=i;}return e}function Ke(t){return t==="PROFESSIONAL"||t==="AGENCY"?t:void 0}function or(t,e){if(!t||typeof t!="object")return null;let r=t,n=r.command;if(n!=="publish"&&n!=="crawl"&&n!=="deploy"&&n!=="invalidate"&&n!=="retry-timeouts"&&n!=="url"&&n!=="content-sync")return null;let o=Number.parseInt(String(r.intervalMinutes??"0"),10);if(!Number.isFinite(o)||o<1)return null;let s=String(r.id??`${n}-${e+1}`).trim();if(!s)return null;let i=String(r.deploymentProfile??"").trim(),a=String(r.url??"").trim(),l=Array.isArray(r.postTypes)?[...new Set(r.postTypes.map(c=>String(c??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],u=Array.isArray(r.listingPaths)?[...new Set(r.listingPaths.map(c=>String(c??"").trim()).filter(Boolean))]:[];return n==="content-sync"&&l.length===0?null:{id:s,enabled:r.enabled!==false,command:n,intervalMinutes:o,...n==="publish"||n==="crawl"?{crawlMode:r.crawlMode==="incremental"?"incremental":"full"}:{},...(n==="publish"||n==="deploy"||n==="invalidate"||n==="content-sync")&&i?{deploymentProfile:i}:{},...a?{url:a}:{},...l.length>0?{postTypes:l}:{},...u.length>0?{listingPaths:u}:{},...typeof r.includeSubsites=="boolean"?{includeSubsites:r.includeSubsites}:{},...typeof r.includePostTypeArchives=="boolean"?{includePostTypeArchives:r.includePostTypeArchives}:{},...typeof r.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:r.includeTaxonomyArchives}:{},...typeof r.includeAuthorArchives=="boolean"?{includeAuthorArchives:r.includeAuthorArchives}:{},...typeof r.includeDateArchives=="boolean"?{includeDateArchives:r.includeDateArchives}:{},...typeof r.includePostsPage=="boolean"?{includePostsPage:r.includePostsPage}:{},...typeof r.includeSitemapChain=="boolean"?{includeSitemapChain:r.includeSitemapChain}:{}}}function ot(t){let e=t&&typeof t=="object"?t:{},r=Array.isArray(e.rules)?e.rules.map((n,o)=>or(n,o)).filter(n=>!!n):[];return {enabled:e.enabled===true,timezone:typeof e.timezone=="string"&&e.timezone.trim()!==""?e.timezone.trim():"UTC",rules:r}}function sr(t){let e=t&&typeof t=="object"?t:{},r=e.render&&typeof e.render=="object"?e.render:{},n=Number(r.concurrency??0),o=Number(r.maxAttempts??0),s=e.rewrite&&typeof e.rewrite=="object"?e.rewrite:{},i=e.deploy&&typeof e.deploy=="object"?e.deploy:{},a=(l,u)=>({enabled:typeof l.enabled=="boolean"?l.enabled:r.enabled===true,concurrency:Math.min(100,Math.max(1,Number(l.concurrency||u.concurrency))),batchSize:Math.min(500,Math.max(1,Number(l.batchSize||u.batchSize))),maxAttempts:Math.min(5,Math.max(1,Number(l.maxAttempts||2)))});return {render:{enabled:r.enabled===true,...Number.isInteger(n)&&n>0?{concurrency:n}:{},...Number.isInteger(o)&&o>0?{maxAttempts:Math.min(5,o)}:{}},rewrite:a(s,{concurrency:8,batchSize:25}),deploy:a(i,{concurrency:8,batchSize:50})}}function ir(t){if(!t||typeof t!="object")return;let e=t,r={};for(let o of ["accountId","siteId"]){let s=e[o];typeof s=="string"&&s.trim()!==""&&(r[o]=s.trim());}let n=Number(e.lastUpdate??0);return Number.isFinite(n)&&n>0&&(r.lastUpdate=Math.floor(n)),e.subscriber===true&&(r.subscriber=true),Object.keys(r).length>0?r:void 0}function Ue(t){let e=t&&typeof t=="object"?t:{},r=String(e.accountId??"").trim(),n=String(e.siteId??"").trim(),o=e.subscriber===true,s=ir(e.siteSettings),i={...s??{},...r?{accountId:s?.accountId??r}:{},...n?{siteId:s?.siteId??n}:{},...s?.subscriber===true||o?{subscriber:true}:{}},a={},l=String(e.apiBase??"").trim();l&&(a.apiBase=l);let u=String(e.runtimeToken??e.nonce??"").trim();u&&(a.runtimeToken=u);let c=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();c&&(a.virtualAssetBaseUrl=c),Object.keys(i).length>0&&(a.siteSettings=i);let p=Ke(e.subscriptionType);return p&&(a.subscriptionType=p),a}function ar(t){try{let e=new URL(t);globalThis.location=e;}catch{}}function st(t){return typeof t=="string"?t:t instanceof URL?t.toString():t.url}function lr(t,e){let r=new Headers(t instanceof Request?t.headers:void 0);if(e?.headers)for(let[n,o]of new Headers(e.headers).entries())r.set(n,o);return r}async function it(t,e,r=5){let n=new URL(st(t)),o=String(e?.method??(t instanceof Request?t.method:"GET")).toUpperCase(),s=n.protocol==="http:"?er:tr,i=lr(t,e);return await new Promise((a,l)=>{let u=s.request(n,{method:o,headers:Object.fromEntries(i.entries()),...n.protocol==="https:"?{rejectUnauthorized:false}:{}},c=>{let p=[];c.on("data",d=>{p.push(Buffer.isBuffer(d)?d:Buffer.from(d));}),c.on("error",l),c.on("end",()=>{let d=c.statusCode??0,g=c.headers.location;if(r>0&&g&&[301,302,303,307,308].includes(d)){a(it(new URL(g,n),{method:d===303?"GET":o},r-1));return}let R=new Headers;for(let[y,h]of Object.entries(c.headers))Array.isArray(h)?R.set(y,h.join(", ")):typeof h=="string"&&R.set(y,h);a(new Response(Buffer.concat(p),{status:d,statusText:c.statusMessage??"",headers:R}));});});u.on("error",l),u.end();})}function cr(t){let e=Ue(t.wpsuite),r={...e.siteSettings??{},...e.siteSettings?.subscriber===true||e.subscriptionType==="PROFESSIONAL"||e.subscriptionType==="AGENCY"?{subscriber:true}:{}},n=String(r.accountId??"").trim(),o=String(r.siteId??"").trim(),s=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();if(t.wpsuite={...e.apiBase?{apiBase:e.apiBase}:{},...e.runtimeToken?{runtimeToken:e.runtimeToken}:{},...s?{virtualAssetBaseUrl:s}:{},...Object.keys(r).length>0?{siteSettings:r}:{},...e.subscriptionType?{subscriptionType:e.subscriptionType}:{}},!n||!o||!s)return false;ar(t.sourceOrigin);let i=globalThis,l={...i.WpSuite??{},siteSettings:r,uploadUrl:s};return e.apiBase&&(l.apiBase=e.apiBase),i.WpSuite=l,true}async function ur(t){let e=String(t.wpsuite?.virtualAssetBaseUrl??t.wpsuite?.uploadUrl??"").trim();if(!cr(t)){let o=t.wpsuite?.siteSettings,s=[String(o?.accountId??"").trim()?"":"accountId",String(o?.siteId??"").trim()?"":"siteId",e?"":"virtualAssetBaseUrl"].filter(Boolean);return {remote:null,diagnostic:{status:"invalid-runtime",virtualAssetBaseUrl:e,subscriptionType:null,error:`Missing WP Suite runtime field(s): ${s.join(", ")}.`,requests:[]}}}let r=globalThis.fetch,n=[];try{typeof r=="function"&&/^https?:\/\//i.test(e)&&(globalThis.fetch=(async(l,u)=>{let c=st(l);if(c.startsWith(e)){let p=(()=>{try{return new URL(c).pathname}catch{return c}})();try{let d=t.ignoreHttpsErrors&&c.startsWith("https://")?await it(l,u):await r(l,u);return n.push({path:p,status:d.status,ok:d.ok,error:null}),d}catch(d){throw n.push({path:p,status:null,ok:!1,error:d instanceof Error?d.message:String(d)}),d}}return r(l,u)}));let{getConfig:o}=await import('@smart-cloud/wpsuite-core'),s=await o("publisher"),i=s&&typeof s=="object"?s:null,a=Ke(i?.subscriptionType);return {remote:i,diagnostic:{status:i?"loaded":"unavailable",virtualAssetBaseUrl:e,subscriptionType:a??null,error:i?null:"WP Suite publisher config loader returned no configuration.",requests:n}}}catch(o){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:e,subscriptionType:null,error:o instanceof Error?o.message:String(o),requests:n}}}finally{typeof r=="function"&&(globalThis.fetch=r);}}function pr(t,e){let r=nr(e?.deploymentProfiles),n=String(e?.defaultDeploymentProfile??"").trim(),o=r[n]?n:"",s=Ke(e?.subscriptionType),i=Ue(t.wpsuite);return {...t,scheduler:ot(e?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:o,...s?{subscriptionType:s}:{},wpsuite:{...i,...i.siteSettings||s?{siteSettings:{...i.siteSettings??{},...i.siteSettings?.subscriber===true||s==="PROFESSIONAL"||s==="AGENCY"?{subscriber:true}:{}}}:{},...s?{subscriptionType:s}:{}}}}function Ne(t,e){let n=String(t||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!n)return e;let o=n.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return o.length>0?o.join("/"):e}function dr(){let t=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return t.trim()?v.resolve(t):""}function rt(t,e,r){let n=String(e||"").trim();return n&&v.isAbsolute(n)?v.resolve(n):v.resolve(t,Ne(n,r))}async function ve(t,e={}){let r=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",n=await O.readFile(r,"utf8"),o=JSON.parse(n);o.sourceOrigin=o.sourceOrigin.replace(/\/$/,""),o.targetOrigin=nt(o.targetOrigin),o.ignoreHttpsErrors??=false,o.outputDir=String(o.outputDir||"export").trim()||"export",o.urlRewriteMode||=o.targetOrigin==="."?"relative":"absolute",o.noJavaScriptRenderPathPrefixes||=[],o.seedPaths||=[],o.generated404RequestPath=rr(o.generated404RequestPath),o.sitemapPaths||=[...tt],o.allowedAssetHosts||=[],o.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],o.blockedPathPrefixes||=[],o.blockedSearchFragments||=[];let s=Number(o.processingConcurrency)>0?Math.min(100,Math.max(1,Number(o.processingConcurrency))):null;o.concurrency=s??o.concurrency??1,o.maxPages||=0,o.extraReplacements=_e(o.extraReplacements),o.postCrawlCopyMap=_e(o.postCrawlCopyMap),o.logDir=String(o.logDir||"logs").trim()||"logs",o.verbose??=false,o.logLevel||=o.verbose?"debug":"info",o.s3SyncMode||="sdk-upload-delete",o.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},o.readiness.timeoutMs??=1500,o.readiness.fallbackWaitMs??=1500,o.viewport||={width:1440,height:1200},o.navigationTimeoutMs||=3e4,o.assetDownloadConcurrency=s??(Number(o.assetDownloadConcurrency)>0?Number(o.assetDownloadConcurrency):o.concurrency),o.rewriteConcurrency=s??(Number(o.rewriteConcurrency)>0?Number(o.rewriteConcurrency):o.assetDownloadConcurrency),o.wpsuite=Ue(o.wpsuite),o.scheduler=ot(void 0),o.remoteWorkers=sr(o.remoteWorkers),typeof o.lambdaDelegationEnabled=="boolean"&&(o.remoteWorkers.render??={},o.remoteWorkers.rewrite??={},o.remoteWorkers.deploy??={},o.remoteWorkers.render.enabled=o.lambdaDelegationEnabled,o.remoteWorkers.rewrite.enabled=o.lambdaDelegationEnabled,o.remoteWorkers.deploy.enabled=o.lambdaDelegationEnabled),s!==null&&(o.processingConcurrency=s,o.remoteWorkers.render??={},o.remoteWorkers.rewrite??={},o.remoteWorkers.deploy??={},o.remoteWorkers.render.concurrency=s,o.remoteWorkers.rewrite.concurrency=s,o.remoteWorkers.deploy.concurrency=s),o.deploymentProfiles={},o.defaultDeploymentProfile="",o.deploymentTargetOverride=String(o.deploymentTargetOverride??"").trim();let i=await ur(o);e.onRemotePublisherConfigDiagnostic?.(i.diagnostic);let a=pr(o,i.remote),l=dr(),u=l?v.resolve(l,".."):"";return u?(a.outputDir=rt(u,a.outputDir,"export"),a.logDir=rt(u,a.logDir,"logs")):(v.isAbsolute(a.outputDir)||(a.outputDir=Ne(a.outputDir,"export")),v.isAbsolute(a.logDir)||(a.logDir=Ne(a.logDir,"logs"))),a}function gr(t){let e=t/6e4;if(Number.isInteger(e)&&e>=1)return `${e} minute${e===1?"":"s"}`;let r=Math.ceil(t/1e3);return `${r} second${r===1?"":"s"}`}async function Y(t,e,r){let n=new AbortController,o=globalThis.setTimeout(()=>{n.abort(new Error(`${t} timed out after ${gr(e)}.`));},e);try{return await r({abortController:n,httpOptions:{abortSignal:n.signal,requestTimeout:e}})}finally{globalThis.clearTimeout(o);}}var mr=".deploy-plan.json",fr="deploy-plan.json",hr=".crawl-incomplete.json",yr="crawl-incomplete.json";function at(){let t=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return t.trim()?v.resolve(t):""}function wr(t){let e=String(t||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),r=v.posix.normalize(e);return !e||!r||r==="."||/^[a-zA-Z]:/.test(r)||r.startsWith("../")||r===".."?null:r}function br(t){let e=String(t||"").trim();if(!e.startsWith("/")||e.startsWith("//")||e.includes("*")||e.includes("#"))return null;try{let r=new URL(e,"https://content-sync.invalid");return r.origin!=="https://content-sync.invalid"?null:`${v.posix.normalize(r.pathname)}${r.search}`}catch{return null}}function q(t){return [...new Set(t.map(wr).filter(e=>e!==null))]}function Rr(t,e){let r={generatedAt:String(e.generatedAt||new Date().toISOString()),outputDir:v.resolve(t.outputDir),runMode:e.runMode,crawlMode:e.crawlMode,fullSyncRequired:!!e.fullSyncRequired,changedFiles:q(e.changedFiles||[]),deletedFiles:q(e.deletedFiles||[]),rewriteTargets:q(e.rewriteTargets||[]),revalidateFiles:q(e.revalidateFiles||[])};return e.schemaVersion===2?{...r,schemaVersion:2,runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,consumerId:String(e.consumerId||"").trim(),fromSequence:Math.max(0,Number(e.fromSequence)||0),toSequence:Math.max(0,Number(e.toSequence)||0),impactHash:String(e.impactHash||"").trim(),resolvedSitemapUrls:[...new Set((e.resolvedSitemapUrls||[]).map(n=>String(n||"").trim()).filter(n=>{try{let o=new URL(n);return o.protocol==="http:"||o.protocol==="https:"}catch{return false}}))],uploadGroups:{assets:q(e.uploadGroups?.assets||[]),content:q(e.uploadGroups?.content||[]),listings:q(e.uploadGroups?.listings||[]),resources:q(e.uploadGroups?.resources||[]),sitemapLeaves:q(e.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:q(e.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((e.invalidationPaths||[]).map(br).filter(n=>n!==null))].sort()}:{schemaVersion:1,...r,runMode:e.runMode}}function Sr(t){if(!t||typeof t!="object")return false;let e=t;if(e.schemaVersion===2){let r=e;return r.runMode==="content-sync"&&r.crawlMode==="incremental"&&r.fullSyncRequired===false&&typeof r.generatedAt=="string"&&typeof r.outputDir=="string"&&typeof r.consumerId=="string"&&r.consumerId.trim()!==""&&Number.isSafeInteger(r.fromSequence)&&Number.isSafeInteger(r.toSequence)&&Number(r.toSequence)>=Number(r.fromSequence)&&typeof r.impactHash=="string"&&/^[a-f0-9]{64}$/.test(r.impactHash)&&Array.isArray(r.resolvedSitemapUrls)&&Array.isArray(r.changedFiles)&&Array.isArray(r.deletedFiles)&&Array.isArray(r.rewriteTargets)&&(r.revalidateFiles===void 0||Array.isArray(r.revalidateFiles))&&!!r.uploadGroups&&Array.isArray(r.uploadGroups.assets)&&Array.isArray(r.uploadGroups.content)&&Array.isArray(r.uploadGroups.listings)&&Array.isArray(r.uploadGroups.resources)&&Array.isArray(r.uploadGroups.sitemapLeaves)&&Array.isArray(r.uploadGroups.sitemapIndexes)&&Array.isArray(r.invalidationPaths)}return e.schemaVersion===1&&typeof e.generatedAt=="string"&&typeof e.outputDir=="string"&&(e.runMode==="full"||e.runMode==="retry-timeouts"||e.runMode==="single-url")&&(e.crawlMode==="full"||e.crawlMode==="incremental")&&typeof e.fullSyncRequired=="boolean"&&Array.isArray(e.changedFiles)&&Array.isArray(e.deletedFiles)&&Array.isArray(e.rewriteTargets)&&(e.revalidateFiles===void 0||Array.isArray(e.revalidateFiles))}function lt(t){let e=v.join(v.resolve(t.outputDir),mr),r=at();return r?[v.join(r,fr),e]:[e]}function Pr(t){let e=v.join(v.resolve(t.outputDir),hr),r=at();return r?[v.join(r,yr),e]:[e]}async function ct(t){let e=v.resolve(t.outputDir);for(let r of lt(t))try{let n=await O.readFile(r,"utf8"),o=JSON.parse(n);if(!Sr(o)||v.resolve(o.outputDir)!==e)continue;return Rr(t,o)}catch{}return null}async function Ee(t){for(let e of lt(t))try{await O.unlink(e);}catch(r){if(r.code!=="ENOENT")throw r}}async function ut(t){let e=v.resolve(t.outputDir);for(let r of Pr(t)){let n;try{n=await O.readFile(r,"utf8");}catch(s){if(s.code==="ENOENT")continue;throw s}let o;try{o=JSON.parse(n);}catch{throw new Error(`Invalid incomplete crawl marker: ${r}`)}if(o.schemaVersion!==1||typeof o.startedAt!="string"||typeof o.outputDir!="string"||v.resolve(o.outputDir)!==e)throw new Error(`Invalid incomplete crawl marker: ${r}`);return {schemaVersion:1,startedAt:o.startedAt,outputDir:e}}return null}function kr(t){return typeof t.subscriptionType=="string"&&t.subscriptionType.trim()!==""}function pt(t){let e="";for(let n=0;n<t.length;n++){let o=t[n];if(o==="--profile"){let s=(t[n+1]||"").trim();if(!s)throw new Error("Missing value for --profile.");e=s,n+=1;}else if(o.startsWith("--profile=")){let s=o.slice(10).trim();if(!s)throw new Error("Missing value for --profile.");e=s;}}let r=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return e||r||null}function xr(t,e){return {...t,...e??{}}}function vr(t,e){return {...t,...e??{},invalidationPaths:[...(e?.invalidationPaths??t.invalidationPaths)||[]]}}function dt(t,e){let r=String(e??t.deploymentTargetOverride??"").trim();if(!kr(t)){if(r)throw new Error(`Deployment target "${r}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:t}}let n=String(r||t.defaultDeploymentProfile||"").trim();if(!n)return {name:null,profile:null,config:t};let o=t.deploymentProfiles?.[n];if(!o)throw new Error(`Unknown deployment profile "${n}". Check the linked WPSuite publisher configuration.`);return {name:n,profile:o,config:{...t,targetOrigin:o.targetOrigin??t.targetOrigin,s3:xr(t.s3,o.s3),cloudFront:vr(t.cloudFront,o.cloudFront)}}}var gt={error:0,warn:1,info:2,debug:3},Er=/^(?:authorization|proxyAuthorization|runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken|xStaticPublisherToken|xApiKey)$/i;function Se(t){return t.replace(/((?:x-static-publisher-token|authorization|proxy-authorization|x-api-key|aws-access-key-id|aws-secret-access-key|aws-session-token)\s*:\s*)[^\r\n]+/gi,"$1[REDACTED]").replace(/\b(Basic|Bearer)\s+[^\s]+/gi,"$1 [REDACTED]").replace(/([?&](?:token|access_token|refresh_token|api_key|key|nonce)=)[^&\s]+/gi,"$1[REDACTED]").replace(/((?:"|')?(?:runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken)(?:"|')?\s*[:=]\s*(?:"|'))[^"']+/gi,"$1[REDACTED]")}function Ce(t){return typeof t=="string"?Se(t):Array.isArray(t)?t.map(e=>Ce(e)):t instanceof Error?{name:t.name,message:Se(t.message),...t.stack?{stack:Se(t.stack)}:{}}:t&&typeof t=="object"?Object.fromEntries(Object.entries(t).map(([e,r])=>[e,Er.test(e)?"[REDACTED]":Ce(r)])):t}function yt(t){return t?Ce(t):void 0}var mt=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",$e=mt?v.join(mt,"current-progress.json"):"",ft=Promise.resolve();function ht(t){return t.includes("crawl")?"crawl":t.includes("deploy")?"deploy":t.includes("invalidate")?"invalidate":t}function $r(t,e){let r={...t},n=typeof t.phase=="string"?t.phase.trim():"",o=typeof e.phase=="string"?e.phase.trim():"";if(o!==""&&(o==="deploy"||o.startsWith("deploy-"))&&n!==o)for(let a of ["index","totalFiles","staged","uploaded","skipped","failed","deleted","workerCount","completedBatches","totalBatches"])delete r[a];let i=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","completedBatches","totalBatches","pageQueue","assetQueue","sitemapQueue"]);for(let[a,l]of Object.entries(e)){let u=r[a];if(typeof u=="number"&&typeof l=="number"&&i.has(a)){r[a]=Math.max(u,l);continue}r[a]=l;}return r}function Cr(t,e,r){$e&&(ft=ft.then(async()=>{let n=new Date,o=n.toISOString();await O.mkdir(v.dirname($e),{recursive:true});let s=await O.readFile($e,"utf8").then(k=>JSON.parse(k)).catch(()=>null),i=s&&typeof s.details=="object"&&s.details?s.details:{},a=ht(t),l=s?.currentStep||ht(s?.source||""),u=s?.startedAt||o,c={...s?.stepDurationsSec??{}},p=s?.stepStartedAt||o;if(l&&l!==a&&s?.stepStartedAt){let k=Math.max(0,Math.round((n.getTime()-new Date(s.stepStartedAt).getTime())/1e3));c[l]=(c[l]??0)+k,p=o;}let d=Math.max(0,Math.round((n.getTime()-new Date(p).getTime())/1e3)),g=Math.max(0,Math.round((n.getTime()-new Date(u).getTime())/1e3)),R=Se(e),y=yt(r)??{},h={checkedAt:o,source:t,message:R,details:$r(i,y),startedAt:u,currentStep:a,stepStartedAt:p,stepElapsedSec:d,totalElapsedSec:g,stepDurationsSec:c};await O.writeFile($e,JSON.stringify(h,null,2),"utf8");}).catch(()=>{}));}async function Ir(t,e){await O.mkdir(v.dirname(t),{recursive:true}),await O.appendFile(t,`${JSON.stringify(Ce(e))}
|
|
2
|
-
`,"utf8");}var ye=class{constructor(e,r,n="info"){this.logDir=e;this.logFile=r;this.level=n;this.ensureLogFileReady();}logDir;logFile;level;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;get logPath(){return v.join(this.logDir,this.logFile)}artifactPath(e){return this.logFile.endsWith(".log.jsonl")?v.join(this.logDir,this.logFile.replace(/\.log\.jsonl$/u,`${e}.jsonl`)):v.join(this.logDir,`${this.logFile}${e}.jsonl`)}get errorsPath(){return this.artifactPath(".errors")}get rejectedPath(){return this.artifactPath(".rejected")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await
|
|
3
|
-
`,"utf8");});}enqueueJsonLine(e,r){this.enqueueTask(()=>
|
|
1
|
+
import A,{readFile}from'fs/promises';import tr from'http';import rr from'https';import v from'path';import {S3Client,GetObjectCommand,PutObjectCommand,CopyObjectCommand,HeadObjectCommand,DeleteObjectsCommand,ListObjectsV2Command}from'@aws-sdk/client-s3';import {Upload}from'@aws-sdk/lib-storage';import jr,{createHash}from'crypto';import Mr from'fast-glob';import Ct from'mime-types';import {availableParallelism}from'os';import {Worker}from'worker_threads';import {LambdaClient,InvokeCommand}from'@aws-sdk/client-lambda';import {DynamoDBClient,GetItemCommand}from'@aws-sdk/client-dynamodb';import {fromTemporaryCredentials}from'@aws-sdk/credential-providers';var tt=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function nt(t){let e=t.trim();return e==="."?".":e.replace(/\/$/,"")}function nr(t){let e=String(t??"").trim();if(!e)return "";let r=e;if(/^https?:\/\//i.test(r))try{r=new URL(r).pathname;}catch{return ""}if(r=r.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!r)return "";let n=r.endsWith("/"),o=r.replace(/^\/+/,"").split("/").map(a=>a.replace(/[^A-Za-z0-9._-]/g,"")).filter(a=>a.length>0&&a!=="."&&a!=="..");if(o.length===0)return "";let s=`/${o.join("/")}`;return n&&v.extname(s)===""&&(s+="/"),s==="/"?"":s}function _e(t){return !t||typeof t!="object"?{}:Object.fromEntries(Object.entries(t).map(([e,r])=>[e.trim(),String(r??"")]).filter(([e])=>e.length>0))}function or(t){if(!t||typeof t!="object")return {};let e={};for(let[r,n]of Object.entries(t)){let o=r.trim();if(!o||!n||typeof n!="object")continue;let s=n,a={};if(typeof s.targetOrigin=="string"){let l=nt(s.targetOrigin);l&&(a.targetOrigin=l);}let i=_e(s.extraReplacements);if(Object.keys(i).length>0&&(a.extraReplacements=i),s.s3&&typeof s.s3=="object"){let l={},u=s.s3;typeof u.bucket=="string"&&(l.bucket=u.bucket.trim()),typeof u.prefix=="string"&&(l.prefix=u.prefix.trim()),typeof u.region=="string"&&(l.region=u.region.trim()),typeof u.htmlCacheControl=="string"&&(l.htmlCacheControl=u.htmlCacheControl.trim()),typeof u.assetCacheControl=="string"&&(l.assetCacheControl=u.assetCacheControl.trim()),Object.keys(l).length>0&&(a.s3=l);}if(s.cloudFront&&typeof s.cloudFront=="object"){let l={},u=s.cloudFront;typeof u.distributionId=="string"&&(l.distributionId=u.distributionId.trim()),Array.isArray(u.invalidationPaths)&&(l.invalidationPaths=u.invalidationPaths.map(c=>String(c??"").trim()).filter(c=>c.length>0)),Object.keys(l).length>0&&(a.cloudFront=l);}e[o]=a;}return e}function Ke(t){return t==="PROFESSIONAL"||t==="AGENCY"?t:void 0}function sr(t,e){if(!t||typeof t!="object")return null;let r=t,n=r.command;if(n!=="publish"&&n!=="crawl"&&n!=="deploy"&&n!=="invalidate"&&n!=="retry-timeouts"&&n!=="url"&&n!=="content-sync")return null;let o=Number.parseInt(String(r.intervalMinutes??"0"),10);if(!Number.isFinite(o)||o<1)return null;let s=String(r.id??`${n}-${e+1}`).trim();if(!s)return null;let a=String(r.deploymentProfile??"").trim(),i=String(r.url??"").trim(),l=Array.isArray(r.postTypes)?[...new Set(r.postTypes.map(c=>String(c??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],u=Array.isArray(r.listingPaths)?[...new Set(r.listingPaths.map(c=>String(c??"").trim()).filter(Boolean))]:[];return n==="content-sync"&&l.length===0?null:{id:s,enabled:r.enabled!==false,command:n,intervalMinutes:o,...n==="publish"||n==="crawl"?{crawlMode:r.crawlMode==="incremental"?"incremental":"full"}:{},...(n==="publish"||n==="deploy"||n==="invalidate"||n==="content-sync")&&a?{deploymentProfile:a}:{},...i?{url:i}:{},...l.length>0?{postTypes:l}:{},...u.length>0?{listingPaths:u}:{},...typeof r.includeSubsites=="boolean"?{includeSubsites:r.includeSubsites}:{},...typeof r.includePostTypeArchives=="boolean"?{includePostTypeArchives:r.includePostTypeArchives}:{},...typeof r.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:r.includeTaxonomyArchives}:{},...typeof r.includeAuthorArchives=="boolean"?{includeAuthorArchives:r.includeAuthorArchives}:{},...typeof r.includeDateArchives=="boolean"?{includeDateArchives:r.includeDateArchives}:{},...typeof r.includePostsPage=="boolean"?{includePostsPage:r.includePostsPage}:{},...typeof r.includeSitemapChain=="boolean"?{includeSitemapChain:r.includeSitemapChain}:{}}}function ot(t){let e=t&&typeof t=="object"?t:{},r=Array.isArray(e.rules)?e.rules.map((n,o)=>sr(n,o)).filter(n=>!!n):[];return {enabled:e.enabled===true,timezone:typeof e.timezone=="string"&&e.timezone.trim()!==""?e.timezone.trim():"UTC",rules:r}}function ir(t){let e=t&&typeof t=="object"?t:{},r=e.render&&typeof e.render=="object"?e.render:{},n=Number(r.concurrency??0),o=Number(r.batchSize??0),s=Number(r.maxAttempts??0),a=e.rewrite&&typeof e.rewrite=="object"?e.rewrite:{},i=e.deploy&&typeof e.deploy=="object"?e.deploy:{},l=(u,c)=>({enabled:typeof u.enabled=="boolean"?u.enabled:r.enabled===true,concurrency:Math.min(100,Math.max(1,Number(u.concurrency||c.concurrency))),batchSize:Math.min(500,Math.max(1,Number(u.batchSize||c.batchSize))),maxAttempts:Math.min(5,Math.max(1,Number(u.maxAttempts||2)))});return {render:{enabled:r.enabled===true,...Number.isInteger(n)&&n>0?{concurrency:n}:{},batchSize:Number.isInteger(o)&&o>0?Math.min(20,o):5,...Number.isInteger(s)&&s>0?{maxAttempts:Math.min(5,s)}:{}},rewrite:l(a,{concurrency:8,batchSize:25}),deploy:l(i,{concurrency:8,batchSize:50})}}function ar(t){if(!t||typeof t!="object")return;let e=t,r={};for(let o of ["accountId","siteId"]){let s=e[o];typeof s=="string"&&s.trim()!==""&&(r[o]=s.trim());}let n=Number(e.lastUpdate??0);return Number.isFinite(n)&&n>0&&(r.lastUpdate=Math.floor(n)),e.subscriber===true&&(r.subscriber=true),Object.keys(r).length>0?r:void 0}function Ue(t){let e=t&&typeof t=="object"?t:{},r=String(e.accountId??"").trim(),n=String(e.siteId??"").trim(),o=e.subscriber===true,s=ar(e.siteSettings),a={...s??{},...r?{accountId:s?.accountId??r}:{},...n?{siteId:s?.siteId??n}:{},...s?.subscriber===true||o?{subscriber:true}:{}},i={},l=String(e.apiBase??"").trim();l&&(i.apiBase=l);let u=String(e.runtimeToken??e.nonce??"").trim();u&&(i.runtimeToken=u);let c=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();c&&(i.virtualAssetBaseUrl=c),Object.keys(a).length>0&&(i.siteSettings=a);let p=Ke(e.subscriptionType);return p&&(i.subscriptionType=p),i}function lr(t){try{let e=new URL(t);globalThis.location=e;}catch{}}function st(t){return typeof t=="string"?t:t instanceof URL?t.toString():t.url}function cr(t,e){let r=new Headers(t instanceof Request?t.headers:void 0);if(e?.headers)for(let[n,o]of new Headers(e.headers).entries())r.set(n,o);return r}async function it(t,e,r=5){let n=new URL(st(t)),o=String(e?.method??(t instanceof Request?t.method:"GET")).toUpperCase(),s=n.protocol==="http:"?tr:rr,a=cr(t,e);return await new Promise((i,l)=>{let u=s.request(n,{method:o,headers:Object.fromEntries(a.entries()),...n.protocol==="https:"?{rejectUnauthorized:false}:{}},c=>{let p=[];c.on("data",d=>{p.push(Buffer.isBuffer(d)?d:Buffer.from(d));}),c.on("error",l),c.on("end",()=>{let d=c.statusCode??0,m=c.headers.location;if(r>0&&m&&[301,302,303,307,308].includes(d)){i(it(new URL(m,n),{method:d===303?"GET":o},r-1));return}let R=new Headers;for(let[w,y]of Object.entries(c.headers))Array.isArray(y)?R.set(w,y.join(", ")):typeof y=="string"&&R.set(w,y);i(new Response(Buffer.concat(p),{status:d,statusText:c.statusMessage??"",headers:R}));});});u.on("error",l),u.end();})}function ur(t){let e=Ue(t.wpsuite),r={...e.siteSettings??{},...e.siteSettings?.subscriber===true||e.subscriptionType==="PROFESSIONAL"||e.subscriptionType==="AGENCY"?{subscriber:true}:{}},n=String(r.accountId??"").trim(),o=String(r.siteId??"").trim(),s=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();if(t.wpsuite={...e.apiBase?{apiBase:e.apiBase}:{},...e.runtimeToken?{runtimeToken:e.runtimeToken}:{},...s?{virtualAssetBaseUrl:s}:{},...Object.keys(r).length>0?{siteSettings:r}:{},...e.subscriptionType?{subscriptionType:e.subscriptionType}:{}},!n||!o||!s)return false;lr(t.sourceOrigin);let a=globalThis,l={...a.WpSuite??{},siteSettings:r,uploadUrl:s};return e.apiBase&&(l.apiBase=e.apiBase),a.WpSuite=l,true}async function pr(t){let e=String(t.wpsuite?.virtualAssetBaseUrl??t.wpsuite?.uploadUrl??"").trim();if(!ur(t)){let o=t.wpsuite?.siteSettings,s=[String(o?.accountId??"").trim()?"":"accountId",String(o?.siteId??"").trim()?"":"siteId",e?"":"virtualAssetBaseUrl"].filter(Boolean);return {remote:null,diagnostic:{status:"invalid-runtime",virtualAssetBaseUrl:e,subscriptionType:null,error:`Missing WP Suite runtime field(s): ${s.join(", ")}.`,requests:[]}}}let r=globalThis.fetch,n=[];try{typeof r=="function"&&/^https?:\/\//i.test(e)&&(globalThis.fetch=(async(l,u)=>{let c=st(l);if(c.startsWith(e)){let p=(()=>{try{return new URL(c).pathname}catch{return c}})();try{let d=t.ignoreHttpsErrors&&c.startsWith("https://")?await it(l,u):await r(l,u);return n.push({path:p,status:d.status,ok:d.ok,error:null}),d}catch(d){throw n.push({path:p,status:null,ok:!1,error:d instanceof Error?d.message:String(d)}),d}}return r(l,u)}));let{getConfig:o}=await import('@smart-cloud/wpsuite-core'),s=await o("publisher"),a=s&&typeof s=="object"?s:null,i=Ke(a?.subscriptionType);return {remote:a,diagnostic:{status:a?"loaded":"unavailable",virtualAssetBaseUrl:e,subscriptionType:i??null,error:a?null:"WP Suite publisher config loader returned no configuration.",requests:n}}}catch(o){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:e,subscriptionType:null,error:o instanceof Error?o.message:String(o),requests:n}}}finally{typeof r=="function"&&(globalThis.fetch=r);}}function dr(t,e){let r=or(e?.deploymentProfiles),n=String(e?.defaultDeploymentProfile??"").trim(),o=r[n]?n:"",s=Ke(e?.subscriptionType),a=Ue(t.wpsuite);return {...t,scheduler:ot(e?.scheduler),deploymentProfiles:r,defaultDeploymentProfile:o,...s?{subscriptionType:s}:{},wpsuite:{...a,...a.siteSettings||s?{siteSettings:{...a.siteSettings??{},...a.siteSettings?.subscriber===true||s==="PROFESSIONAL"||s==="AGENCY"?{subscriber:true}:{}}}:{},...s?{subscriptionType:s}:{}}}}function Ne(t,e){let n=String(t||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!n)return e;let o=n.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return o.length>0?o.join("/"):e}function gr(){let t=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return t.trim()?v.resolve(t):""}function rt(t,e,r){let n=String(e||"").trim();return n&&v.isAbsolute(n)?v.resolve(n):v.resolve(t,Ne(n,r))}async function ve(t,e={}){let r=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",n=await A.readFile(r,"utf8"),o=JSON.parse(n);o.sourceOrigin=o.sourceOrigin.replace(/\/$/,""),o.targetOrigin=nt(o.targetOrigin),o.ignoreHttpsErrors??=false,o.outputDir=String(o.outputDir||"export").trim()||"export",o.urlRewriteMode||=o.targetOrigin==="."?"relative":"absolute",o.noJavaScriptRenderPathPrefixes||=[],o.seedPaths||=[],o.generated404RequestPath=nr(o.generated404RequestPath),o.sitemapPaths||=[...tt],o.allowedAssetHosts||=[],o.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],o.blockedPathPrefixes||=[],o.blockedSearchFragments||=[];let s=Number(o.processingConcurrency)>0?Math.min(100,Math.max(1,Number(o.processingConcurrency))):null;o.concurrency=s??o.concurrency??1,o.maxPages||=0,o.extraReplacements=_e(o.extraReplacements),o.postCrawlCopyMap=_e(o.postCrawlCopyMap),o.logDir=String(o.logDir||"logs").trim()||"logs",o.verbose??=false,o.logLevel||=o.verbose?"debug":"info",o.s3SyncMode||="sdk-upload-delete",o.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},o.readiness.timeoutMs??=1500,o.readiness.fallbackWaitMs??=1500,o.viewport||={width:1440,height:1200},o.navigationTimeoutMs||=3e4,o.assetDownloadConcurrency=s??(Number(o.assetDownloadConcurrency)>0?Number(o.assetDownloadConcurrency):o.concurrency),o.rewriteConcurrency=s??(Number(o.rewriteConcurrency)>0?Number(o.rewriteConcurrency):o.assetDownloadConcurrency),o.wpsuite=Ue(o.wpsuite),o.scheduler=ot(void 0),o.remoteWorkers=ir(o.remoteWorkers),typeof o.lambdaDelegationEnabled=="boolean"&&(o.remoteWorkers.render??={},o.remoteWorkers.rewrite??={},o.remoteWorkers.deploy??={},o.remoteWorkers.render.enabled=o.lambdaDelegationEnabled,o.remoteWorkers.rewrite.enabled=o.lambdaDelegationEnabled,o.remoteWorkers.deploy.enabled=o.lambdaDelegationEnabled),s!==null&&(o.processingConcurrency=s,o.remoteWorkers.render??={},o.remoteWorkers.rewrite??={},o.remoteWorkers.deploy??={},o.remoteWorkers.render.concurrency=s,o.remoteWorkers.rewrite.concurrency=s,o.remoteWorkers.deploy.concurrency=s),o.deploymentProfiles={},o.defaultDeploymentProfile="",o.deploymentTargetOverride=String(o.deploymentTargetOverride??"").trim();let a=await pr(o);e.onRemotePublisherConfigDiagnostic?.(a.diagnostic);let i=dr(o,a.remote),l=gr(),u=l?v.resolve(l,".."):"";return u?(i.outputDir=rt(u,i.outputDir,"export"),i.logDir=rt(u,i.logDir,"logs")):(v.isAbsolute(i.outputDir)||(i.outputDir=Ne(i.outputDir,"export")),v.isAbsolute(i.logDir)||(i.logDir=Ne(i.logDir,"logs"))),i}function mr(t){let e=t/6e4;if(Number.isInteger(e)&&e>=1)return `${e} minute${e===1?"":"s"}`;let r=Math.ceil(t/1e3);return `${r} second${r===1?"":"s"}`}async function Y(t,e,r){let n=new AbortController,o=globalThis.setTimeout(()=>{n.abort(new Error(`${t} timed out after ${mr(e)}.`));},e);try{return await r({abortController:n,httpOptions:{abortSignal:n.signal,requestTimeout:e}})}finally{globalThis.clearTimeout(o);}}var fr=".deploy-plan.json",hr="deploy-plan.json",yr=".crawl-incomplete.json",wr="crawl-incomplete.json";function at(){let t=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return t.trim()?v.resolve(t):""}function br(t){let e=String(t||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),r=v.posix.normalize(e);return !e||!r||r==="."||/^[a-zA-Z]:/.test(r)||r.startsWith("../")||r===".."?null:r}function Rr(t){let e=String(t||"").trim();if(!e.startsWith("/")||e.startsWith("//")||e.includes("*")||e.includes("#"))return null;try{let r=new URL(e,"https://content-sync.invalid");return r.origin!=="https://content-sync.invalid"?null:`${v.posix.normalize(r.pathname)}${r.search}`}catch{return null}}function q(t){return [...new Set(t.map(br).filter(e=>e!==null))]}function kr(t,e){let r={generatedAt:String(e.generatedAt||new Date().toISOString()),outputDir:v.resolve(t.outputDir),runMode:e.runMode,crawlMode:e.crawlMode,fullSyncRequired:!!e.fullSyncRequired,changedFiles:q(e.changedFiles||[]),deletedFiles:q(e.deletedFiles||[]),rewriteTargets:q(e.rewriteTargets||[]),revalidateFiles:q(e.revalidateFiles||[])};return e.schemaVersion===2?{...r,schemaVersion:2,runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,consumerId:String(e.consumerId||"").trim(),fromSequence:Math.max(0,Number(e.fromSequence)||0),toSequence:Math.max(0,Number(e.toSequence)||0),impactHash:String(e.impactHash||"").trim(),resolvedSitemapUrls:[...new Set((e.resolvedSitemapUrls||[]).map(n=>String(n||"").trim()).filter(n=>{try{let o=new URL(n);return o.protocol==="http:"||o.protocol==="https:"}catch{return false}}))],uploadGroups:{assets:q(e.uploadGroups?.assets||[]),content:q(e.uploadGroups?.content||[]),listings:q(e.uploadGroups?.listings||[]),resources:q(e.uploadGroups?.resources||[]),sitemapLeaves:q(e.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:q(e.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((e.invalidationPaths||[]).map(Rr).filter(n=>n!==null))].sort()}:{schemaVersion:1,...r,runMode:e.runMode}}function Pr(t){if(!t||typeof t!="object")return false;let e=t;if(e.schemaVersion===2){let r=e;return r.runMode==="content-sync"&&r.crawlMode==="incremental"&&r.fullSyncRequired===false&&typeof r.generatedAt=="string"&&typeof r.outputDir=="string"&&typeof r.consumerId=="string"&&r.consumerId.trim()!==""&&Number.isSafeInteger(r.fromSequence)&&Number.isSafeInteger(r.toSequence)&&Number(r.toSequence)>=Number(r.fromSequence)&&typeof r.impactHash=="string"&&/^[a-f0-9]{64}$/.test(r.impactHash)&&Array.isArray(r.resolvedSitemapUrls)&&Array.isArray(r.changedFiles)&&Array.isArray(r.deletedFiles)&&Array.isArray(r.rewriteTargets)&&(r.revalidateFiles===void 0||Array.isArray(r.revalidateFiles))&&!!r.uploadGroups&&Array.isArray(r.uploadGroups.assets)&&Array.isArray(r.uploadGroups.content)&&Array.isArray(r.uploadGroups.listings)&&Array.isArray(r.uploadGroups.resources)&&Array.isArray(r.uploadGroups.sitemapLeaves)&&Array.isArray(r.uploadGroups.sitemapIndexes)&&Array.isArray(r.invalidationPaths)}return e.schemaVersion===1&&typeof e.generatedAt=="string"&&typeof e.outputDir=="string"&&(e.runMode==="full"||e.runMode==="retry-timeouts"||e.runMode==="single-url")&&(e.crawlMode==="full"||e.crawlMode==="incremental")&&typeof e.fullSyncRequired=="boolean"&&Array.isArray(e.changedFiles)&&Array.isArray(e.deletedFiles)&&Array.isArray(e.rewriteTargets)&&(e.revalidateFiles===void 0||Array.isArray(e.revalidateFiles))}function lt(t){let e=v.join(v.resolve(t.outputDir),fr),r=at();return r?[v.join(r,hr),e]:[e]}function Sr(t){let e=v.join(v.resolve(t.outputDir),yr),r=at();return r?[v.join(r,wr),e]:[e]}async function ct(t){let e=v.resolve(t.outputDir);for(let r of lt(t))try{let n=await A.readFile(r,"utf8"),o=JSON.parse(n);if(!Pr(o)||v.resolve(o.outputDir)!==e)continue;return kr(t,o)}catch{}return null}async function Ee(t){for(let e of lt(t))try{await A.unlink(e);}catch(r){if(r.code!=="ENOENT")throw r}}async function ut(t){let e=v.resolve(t.outputDir);for(let r of Sr(t)){let n;try{n=await A.readFile(r,"utf8");}catch(s){if(s.code==="ENOENT")continue;throw s}let o;try{o=JSON.parse(n);}catch{throw new Error(`Invalid incomplete crawl marker: ${r}`)}if(o.schemaVersion!==1||typeof o.startedAt!="string"||typeof o.outputDir!="string"||v.resolve(o.outputDir)!==e)throw new Error(`Invalid incomplete crawl marker: ${r}`);return {schemaVersion:1,startedAt:o.startedAt,outputDir:e}}return null}function xr(t){return typeof t.subscriptionType=="string"&&t.subscriptionType.trim()!==""}function pt(t){let e="";for(let n=0;n<t.length;n++){let o=t[n];if(o==="--profile"){let s=(t[n+1]||"").trim();if(!s)throw new Error("Missing value for --profile.");e=s,n+=1;}else if(o.startsWith("--profile=")){let s=o.slice(10).trim();if(!s)throw new Error("Missing value for --profile.");e=s;}}let r=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return e||r||null}function vr(t,e){return {...t,...e??{}}}function Er(t,e){return {...t,...e??{},invalidationPaths:[...(e?.invalidationPaths??t.invalidationPaths)||[]]}}function dt(t,e){let r=String(e??t.deploymentTargetOverride??"").trim();if(!xr(t)){if(r)throw new Error(`Deployment target "${r}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:t}}let n=String(r||t.defaultDeploymentProfile||"").trim();if(!n)return {name:null,profile:null,config:t};let o=t.deploymentProfiles?.[n];if(!o)throw new Error(`Unknown deployment profile "${n}". Check the linked WPSuite publisher configuration.`);return {name:n,profile:o,config:{...t,targetOrigin:o.targetOrigin??t.targetOrigin,s3:vr(t.s3,o.s3),cloudFront:Er(t.cloudFront,o.cloudFront)}}}var gt={error:0,warn:1,info:2,debug:3},Ir=/^(?:authorization|proxyAuthorization|runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken|xStaticPublisherToken|xApiKey)$/i;function ke(t){return t.replace(/((?:x-static-publisher-token|authorization|proxy-authorization|x-api-key|aws-access-key-id|aws-secret-access-key|aws-session-token)\s*:\s*)[^\r\n]+/gi,"$1[REDACTED]").replace(/\b(Basic|Bearer)\s+[^\s]+/gi,"$1 [REDACTED]").replace(/([?&](?:token|access_token|refresh_token|api_key|key|nonce)=)[^&\s]+/gi,"$1[REDACTED]").replace(/((?:"|')?(?:runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken)(?:"|')?\s*[:=]\s*(?:"|'))[^"']+/gi,"$1[REDACTED]")}function Ce(t){return typeof t=="string"?ke(t):Array.isArray(t)?t.map(e=>Ce(e)):t instanceof Error?{name:t.name,message:ke(t.message),...t.stack?{stack:ke(t.stack)}:{}}:t&&typeof t=="object"?Object.fromEntries(Object.entries(t).map(([e,r])=>[e,Ir.test(e)?"[REDACTED]":Ce(r)])):t}function yt(t){return t?Ce(t):void 0}var mt=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",Ie=mt?v.join(mt,"current-progress.json"):"",ft=Promise.resolve();function ht(t){return t.includes("crawl")?"crawl":t.includes("deploy")?"deploy":t.includes("invalidate")?"invalidate":t}function Cr(t,e){let r={...t},n=typeof t.phase=="string"?t.phase.trim():"",o=typeof e.phase=="string"?e.phase.trim():"";if(o!==""&&(o==="deploy"||o.startsWith("deploy-"))&&n!==o)for(let i of ["index","totalFiles","staged","uploaded","skipped","failed","deleted","workerCount","completedBatches","totalBatches"])delete r[i];let a=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","completedBatches","totalBatches","pageQueue","assetQueue","sitemapQueue"]);for(let[i,l]of Object.entries(e)){let u=r[i];if(typeof u=="number"&&typeof l=="number"&&a.has(i)){r[i]=Math.max(u,l);continue}r[i]=l;}return r}function $r(t,e,r){Ie&&(ft=ft.then(async()=>{let n=new Date,o=n.toISOString();await A.mkdir(v.dirname(Ie),{recursive:true});let s=await A.readFile(Ie,"utf8").then(S=>JSON.parse(S)).catch(()=>null),a=s&&typeof s.details=="object"&&s.details?s.details:{},i=ht(t),l=s?.currentStep||ht(s?.source||""),u=s?.startedAt||o,c={...s?.stepDurationsSec??{}},p=s?.stepStartedAt||o;if(l&&l!==i&&s?.stepStartedAt){let S=Math.max(0,Math.round((n.getTime()-new Date(s.stepStartedAt).getTime())/1e3));c[l]=(c[l]??0)+S,p=o;}let d=Math.max(0,Math.round((n.getTime()-new Date(p).getTime())/1e3)),m=Math.max(0,Math.round((n.getTime()-new Date(u).getTime())/1e3)),R=ke(e),w=yt(r)??{},y={checkedAt:o,source:t,message:R,details:Cr(a,w),startedAt:u,currentStep:i,stepStartedAt:p,stepElapsedSec:d,totalElapsedSec:m,stepDurationsSec:c};await A.writeFile(Ie,JSON.stringify(y,null,2),"utf8");}).catch(()=>{}));}async function Tr(t,e){await A.mkdir(v.dirname(t),{recursive:true}),await A.appendFile(t,`${JSON.stringify(Ce(e))}
|
|
2
|
+
`,"utf8");}var ye=class{constructor(e,r,n="info"){this.logDir=e;this.logFile=r;this.level=n;this.ensureLogFileReady();}logDir;logFile;level;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;get logPath(){return v.join(this.logDir,this.logFile)}artifactPath(e){return this.logFile.endsWith(".log.jsonl")?v.join(this.logDir,this.logFile.replace(/\.log\.jsonl$/u,`${e}.jsonl`)):v.join(this.logDir,`${this.logFile}${e}.jsonl`)}get errorsPath(){return this.artifactPath(".errors")}get rejectedPath(){return this.artifactPath(".rejected")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await A.mkdir(this.logDir,{recursive:true}),await A.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(e){this.writeQueue=this.writeQueue.then(e).catch(r=>{this.writeError=r instanceof Error?r:new Error(String(r));});}enqueueLine(e){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await A.appendFile(this.logPath,`${e}
|
|
3
|
+
`,"utf8");});}enqueueJsonLine(e,r){this.enqueueTask(()=>Tr(e,r));}accepts(e){return gt[e]<=gt[this.level]}push(e,r,n){if(!this.accepts(e))return;let o=ke(r),s=yt(n),a=JSON.stringify({time:new Date().toISOString(),level:e,message:o,...s||{}});this.enqueueLine(a),e==="error"?console.error(`[ERROR] ${o}`,s?JSON.stringify(s):""):e==="warn"?console.warn(`[WARN] ${o}`,s?JSON.stringify(s):""):console.log(`[${e.toUpperCase().padEnd(5)}] ${o}`);}info(e,r){this.push("info",e,r);}progress(e,r){$r(this.logFile,e,r);}debug(e,r){this.push("debug",e,r);}warn(e,r){this.push("warn",e,r);}reject(e,r,n,o,s){let a={kind:e,url:r,reason:n,...o?{source:o}:{},...s||{}};this.enqueueJsonLine(this.rejectedPath,a),this.accepts("debug")&&this.push("debug",`Rejected ${e} ${r}: ${n}`,a);}error(e,r){this.enqueueJsonLine(this.errorsPath,{message:e,...r||{}}),this.push("error",e,r);}mark(e){this.marks.set(e,Date.now());}endMark(e,r){let n=this.marks.get(e);if(!n)return;let o=Date.now()-n,s=Number((o/1e3).toFixed(2));this.push("info",`Timing ${e}: ${s}s`,{name:e,ms:o,seconds:s,...r||{}});}async flush(){let e=Date.now()-this.startedAt,r=Number((e/1e3).toFixed(2));if(this.push("info",`Total time: ${r}s`,{name:"total",ms:e,seconds:r}),await this.writeQueue,this.writeError)throw this.writeError}};async function Or(t){await A.mkdir(v.dirname(t),{recursive:true});}async function Se(t,e,r){await Or(t);let n=v.join(v.dirname(t),`.${v.basename(t)}.${process.pid}.${Date.now()}.${jr.randomBytes(6).toString("hex")}.tmp`);try{typeof e=="string"?await A.writeFile(n,e,r??"utf8"):await A.writeFile(n,e),await A.rename(n,t);}catch(o){throw await A.unlink(n).catch(()=>{}),o}}function Rt(t){return [".html",".htm",".css",".js",".mjs",".json",".xml",".xsl",".txt",".svg",".map",".enc",".jws"].includes(v.extname(t).toLowerCase())}function kt(t){return t.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function we(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function $e(t){return t.replace(/\//g,"\\/")}function wt(t){return t.replace(/\//g,"\\\\/")}function Ar(t){try{let e=new URL(t);if(e.protocol!=="http:"&&e.protocol!=="https:")return null;let r=e.pathname==="/"&&!e.search&&!e.hash?"":`${e.pathname}${e.search}${e.hash}`;return `//${e.host}${r}`}catch{return null}}function bt(t,e,r){if(!e)return;t[e]=r;let n=$e(e),o=$e(r);t[n]=o;let s=wt(e),a=wt(r);t[s]=a;let i=we(e),l=we(r);t[i]=l;let u=we(n),c=we(o);t[u]=c;let p=we(s),d=we(a);t[p]=d;}function Te(t,e,r){bt(t,e,r);let n=Ar(e);n&&n!==e&&bt(t,n,r);}function Pt(t,e){try{return new URL(t,e==="."?"https://relative.invalid":e).pathname}catch{return t.startsWith("/")?t:`/${t.replace(/^\.\//,"")}`}}function St(t,e,r){if(!e)return r;let n=v.dirname(v.resolve(e)),o=v.resolve(t,r.replace(/^\/+/,"")),s=v.relative(n,o).replace(/\\/g,"/");return s?(s.startsWith(".")||(s=`./${s}`),s):"."}async function qe(t,e){return (e?[...new Set(e)].map(n=>v.resolve(n)).filter(n=>n.startsWith(v.resolve(t.outputDir))).map(n=>v.relative(t.outputDir,n).replace(/\\/g,"/")).filter(n=>n.length>0):await Mr(["**/*"],{cwd:t.outputDir,onlyFiles:true,dot:true})).filter(n=>n!=="asset-map.json"&&Rt(n))}var Fr=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],_r=new Set([".html",".htm"]),xt="WPSuite.io Static Publisher",Nr=xt.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Kr(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ur(t){return t.startsWith("//")||t.startsWith("\\/\\/")||t.startsWith("\\\\/\\\\/")}function Vr(t,e,r){return Ur(e)?t.replace(new RegExp(`(?<!:)${Kr(e)}`,"g"),r):t.split(e).join(r)}function zr(t,e,r){if(t.wpsuite?.siteSettings?.subscriber===true||t.wpsuite?.subscriptionType==="PROFESSIONAL"||t.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let o=v.extname(r).toLowerCase();return _r.has(o)?/<head\b|<html\b|<!doctype html/i.test(e):false}function Br(t){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Nr}\\2)[^>]*\\/?>`,"i").test(t))return t;let e=`<meta name="generator" content="${xt}" />`;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
|
|
4
4
|
`)?`\r
|
|
5
5
|
`:`
|
|
6
|
-
`;return t.replace(/<head\b[^>]*>/i,o=>`${o}${n} ${e}`)}function
|
|
7
|
-
`)).slice(0,16)}`,"taskId"),U={schemaVersion:K,operation:"rewrite",jobId:s,taskId:
|
|
8
|
-
`)).slice(0,16)}`,"taskId");try{let P=await n.client.invoke({schemaVersion:K,operation:"rewrite",jobId:i,taskId:E,configKey:l,assetMapKey:u,items:k.map(C=>({inputKey:C.object.key,outputKey:C.object.key,relativePath:C.relativePath}))});S=Tt(await n.client.readResult(P),P);break}catch(P){m=P;}}if(!S)throw new Error(`Remote object rewrite batch ${h+1}/${p.length} failed: ${m instanceof Error?m.message:String(m)}`,{cause:m});for(let b of k){let E=S.detail.objects.find(P=>P.outputKey===b.object.key);if(!E)throw new Error(`Remote rewrite result omitted ${b.relativePath}.`);b.object=E.output,E.changed&&(y+=1),R+=1,await n.onProgress?.({index:R,totalFiles:s.length,changedTextFiles:y,file:b.relativePath,changed:E.changed});}}})),e.assetMap={...r},e.generatedAt=new Date().toISOString(),y}function _(t,e,{optional:r=false}={}){if(!(r&&(t==null||t===""))){if(typeof t!="string"||!t.trim())throw new Error(`${e} must be a non-empty string.`);return t.trim()}}function un(t){if(!t||typeof t!="object")throw new Error("Remote worker config must be a JSON object.");let e=t;if(e.schemaVersion!==1)throw new Error(`Unsupported remote worker config version: ${String(e.schemaVersion)}.`);if(e.protocolVersion!==K)throw new Error(`Remote worker protocol mismatch: expected ${K}, received ${String(e.protocolVersion)}.`);let r=e.workspace,n=e.functions;if(!r||!n)throw new Error("Remote worker config requires workspace and functions objects.");return {schemaVersion:1,region:_(e.region,"region"),..._(e.roleArn,"roleArn",{optional:true})?{roleArn:_(e.roleArn,"roleArn")}:{},..._(e.roleSessionName,"roleSessionName",{optional:true})?{roleSessionName:_(e.roleSessionName,"roleSessionName")}:{},workspace:{bucket:_(r.bucket,"workspace.bucket"),prefix:String(r.prefix??"")},functions:{render:_(n.render,"functions.render"),..._(n.asset,"functions.asset",{optional:true})?{asset:_(n.asset,"functions.asset")}:{},rewrite:_(n.rewrite,"functions.rewrite"),"deploy-copy":_(n["deploy-copy"],"functions.deploy-copy")},targets:Array.isArray(e.targets)?e.targets.map((o,s)=>{if(!o||typeof o!="object")throw new Error(`targets[${s}] must be an object.`);let i=o;return {id:_(i.id,`targets[${s}].id`),bucketName:_(i.bucketName,`targets[${s}].bucketName`),prefix:String(i.prefix??""),region:_(i.region,`targets[${s}].region`)}}):[],protocolVersion:K}}async function Dt(t){let e=v.resolve(t);try{return un(JSON.parse(await readFile(e,"utf8")))}catch(r){throw new Error(`Unable to load remote worker config ${e}: ${r instanceof Error?r.message:String(r)}`,{cause:r})}}var je=class{config;lambda;s3;constructor(e,r={}){this.config=e;let n=e.roleArn?fromTemporaryCredentials({params:{RoleArn:e.roleArn,RoleSessionName:e.roleSessionName??"publisher-exporter-remote-worker"},clientConfig:{region:e.region}}):void 0;this.lambda=new LambdaClient({region:e.region,...n?{credentials:n}:{},...r}),this.s3=new S3Client({region:e.region,...n?{credentials:n}:{}});}async invoke(e){let r=e.operation==="health"?this.config.functions.render:this.config.functions[e.operation];if(!r)throw new Error(`Remote worker configuration does not provide a ${e.operation} function. Redeploy the Lambda workers and reinstall remote-workers.json.`);let n=await this.lambda.send(new InvokeCommand({FunctionName:r,InvocationType:"RequestResponse",Payload:Buffer.from(JSON.stringify(e),"utf8")})),o=n.Payload?JSON.parse(new TextDecoder().decode(n.Payload)):null;if(n.FunctionError)throw new Error(`Remote ${e.operation} worker failed (${n.FunctionError}): ${JSON.stringify(o)}`);if(!o||typeof o!="object")throw new Error(`Remote ${e.operation} worker returned no JSON response.`);let s=o;if(s.schemaVersion!==K||s.operation!==e.operation||s.jobId!==e.jobId||s.taskId!==e.taskId)throw new Error(`Remote ${e.operation} worker returned a mismatched response.`);return s}async readResult(e){if(!e.resultKey)throw new Error(`Remote ${e.operation} response does not contain a resultKey.`);let r=oe(e.resultKey,this.config.workspace.prefix),n=await this.s3.send(new GetObjectCommand({Bucket:this.config.workspace.bucket,Key:r}));if(!n.Body)throw new Error(`Remote worker result has no body: ${r}`);return JSON.parse(await n.Body.transformToString("utf8"))}async readObject(e){if(e.bucket!==this.config.workspace.bucket)throw new Error(`Remote worker object bucket mismatch: ${e.bucket}.`);let r=oe(e.key,this.config.workspace.prefix),n=await this.s3.send(new GetObjectCommand({Bucket:this.config.workspace.bucket,Key:r,...e.versionId?{VersionId:e.versionId}:{}}));if(!n.Body)throw new Error(`Remote worker object has no body: ${r}`);let o=await n.Body.transformToByteArray();if(o.byteLength!==e.bytes)throw new Error(`Remote worker object length mismatch for ${r}: expected ${e.bytes}, received ${o.byteLength}.`);if(pe(o)!==e.sha256)throw new Error(`Remote worker object checksum mismatch for ${r}.`);return o}async readObjectText(e){return new TextDecoder("utf8",{fatal:true}).decode(await this.readObject(e))}async health(e){let r=this.config.functions[e];if(!r)throw new Error(`Remote worker configuration does not provide a ${e} function.`);let n=`${e}-${Date.now()}`,o=await this.lambda.send(new InvokeCommand({FunctionName:r,InvocationType:"RequestResponse",Payload:Buffer.from(JSON.stringify({schemaVersion:K,operation:"health",jobId:"health",taskId:n}),"utf8")})),s=o.Payload?JSON.parse(new TextDecoder().decode(o.Payload)):null;if(o.FunctionError||!s||typeof s!="object")throw new Error(`Remote ${e} health check failed: ${JSON.stringify(s)}`);return s}async writeWorkspaceObject(e){let r=oe(e.key,this.config.workspace.prefix),n=typeof e.body=="string"?Buffer.from(e.body,"utf8"):e.body,o=pe(n),s=await this.s3.send(new PutObjectCommand({Bucket:this.config.workspace.bucket,Key:r,Body:n,ContentType:e.contentType,...e.cacheControl?{CacheControl:e.cacheControl}:{},Metadata:{sha256:o,...e.metadata??{}}}));return {bucket:this.config.workspace.bucket,key:r,sha256:o,bytes:n.byteLength,contentType:e.contentType,...s.ETag?{etag:s.ETag}:{},...s.VersionId?{versionId:s.VersionId}:{}}}async copyWorkspaceObject(e,r){if(e.bucket!==this.config.workspace.bucket)throw new Error(`Remote worker object bucket mismatch: ${e.bucket}.`);let n=oe(e.key,this.config.workspace.prefix),o=oe(r,this.config.workspace.prefix),s=`${e.bucket}/${n.split("/").map(a=>encodeURIComponent(a)).join("/")}`,i=await this.s3.send(new CopyObjectCommand({Bucket:e.bucket,Key:o,CopySource:s,MetadataDirective:"COPY"}));return {...e,key:o,...i.CopyObjectResult?.ETag?{etag:i.CopyObjectResult.ETag}:{},...i.VersionId?{versionId:i.VersionId}:{}}}};var pn="remote-workers.json";function Lt(t={}){let e=String(t.explicitPath??"").trim();if(e)return v.resolve(e);let r=String(t.runtimeDir??process.env.STATIC_PUBLISHER_RUNTIME_DIR??process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR??"").trim();return r?v.join(v.resolve(r),pn):""}function gn(){let t=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return t.trim()?v.resolve(t):""}function mn(t){let e=String(process.env.STATIC_PUBLISHER_REMOTE_EXPORT_MANIFEST_PATH||"").trim();if(e)return v.resolve(e);let r=gn();if(r)return v.join(r,"remote-export-manifest.json");let n=v.resolve(t.outputDir);return v.join(v.dirname(n),`.${v.basename(n)}-remote-export-manifest.json`)}function fn(t){let e=v.posix.normalize(String(t||"").replace(/\\/g,"/").replace(/^\/+/,""));if(!e||e==="."||e===".."||e.startsWith("../")||/^[A-Za-z]:/.test(e))throw new Error(`Invalid remote export relative path: ${t}`);return e}async function Ft(t){try{let e=JSON.parse(await O.readFile(mn(t),"utf8"));if(e.schemaVersion!==1||typeof e.jobId!="string"||!e.workspace||typeof e.workspace.bucket!="string"||typeof e.workspace.prefix!="string"||!e.objects||typeof e.objects!="object"||!e.assetMap||typeof e.assetMap!="object")return null;let r=e;for(let[n,o]of Object.entries(r.objects)){if(fn(n),!o||o.relativePath!==n||o.object?.bucket!==r.workspace.bucket)return null;oe(o.object.key,r.workspace.prefix);}return r}catch{return null}}var Ut="wpsuite-sha256",Vt="wpsuite-normalized-sha256",Qe="public, max-age=0, must-revalidate",kn=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,Ye=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,xn=["SIGINT","SIGTERM"],Me=new Set,Oe=new Map,Wt=null;function vn(t){Me.add(t);let e=false;return ()=>{e||(e=true,Me.delete(t));}}async function En(){let t=[...Me];t.length!==0&&await Promise.allSettled(t.map(async e=>{Me.delete(e),await O.rm(e,{recursive:true,force:true});}));}function $n(){if(!(Oe.size>0))for(let t of xn){let e=()=>{Wt||(Wt=En().finally(()=>{for(let[r,n]of Oe)process.off(r,n);Oe.clear(),process.exit(1);}));};Oe.set(t,e),process.on(t,e);}}$n();function Cn(t,e){let r=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(r)return v.resolve(r);let n=e.trim();return n?v.join(v.resolve(n),"crawl-manifest.json"):v.join(v.resolve(t),".crawl-manifest.json")}function ie(t){return v.normalize(t).split(v.sep).join("/")}function _t(t,e){let r=v.relative(v.resolve(t),v.resolve(e));return !r||r.startsWith("..")||v.isAbsolute(r)?null:ie(r)}async function In(t,e,r){let n=Cn(t.outputDir,e),o;try{o=await O.readFile(n,"utf8");}catch(c){return c.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:c instanceof Error?c.message:String(c),source:"deploy-guard"}),null)}let s;try{s=JSON.parse(o);}catch(c){return r.warn("Deploy rewrite guard disabled because the crawl manifest is invalid JSON.",{manifestPath:n,error:c instanceof Error?c.message:String(c),source:"deploy-guard"}),null}let i=new Map,a=new Map,l=0,u=0;for(let[c,p]of Object.entries(s.pages||{})){let d=String(p?.outputPath||"").trim(),g=d?_t(t.outputDir,d):null;if(g){let R=typeof p?.contentType=="string"&&p.contentType?p.contentType:null;R&&a.set(g,R);}!d||p?.rewriteComplete===true||g&&(l++,i.has(g)||i.set(g,{kind:"page",sourceUrl:c,outputPath:v.resolve(d),relativePath:g}));}for(let[c,p]of Object.entries(s.assets||{})){let d=String(p?.outputPath||"").trim(),g=p?.isText===true,R=d?_t(t.outputDir,d):null;if(R){let y=typeof p?.contentType=="string"&&p.contentType?p.contentType:null;y&&a.set(R,y);}!d||!g||p?.rewriteComplete===true||R&&(u++,i.has(R)||i.set(R,{kind:"asset",sourceUrl:c,outputPath:v.resolve(d),relativePath:R}));}return {manifestPath:n,byRelativePath:i,contentTypeByRelativePath:a,pendingPages:l,pendingTextAssets:u}}function Tn(t){return t&&(Ye.test(t)?"__uuid__":/^[0-9a-f]{6,}$/i.test(t)?"__hex__":/^[0-9]{8,}$/.test(t)?"__num__":/^(?=.*[a-z])(?=.*\d)[a-z0-9]{8,}$/i.test(t)?"__alnum__":t)}function Je(t){return t.split(/([_:.\-/=?&#]+)/g).map((e,r)=>r%2===1?e:Tn(e)).join("")}function jn(t){return t.split(/([_:.\-/=?&#]+)/g).map((e,r)=>r%2===1?e:Ye.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)?"__hex__":/^[0-9]{6,}$/.test(e)?"__num__":/^[a-z0-9_-]{6,}$/i.test(e)?"__id__":e).join("")}function De(t,e){return Array.isArray(t)?t.map(r=>De(r,e)):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).map(([r,n])=>[r,De(n,r)])):typeof t!="string"?t:e&&kn.test(e)?jn(t):Ye.test(t)?"__uuid__":/^[0-9a-f]{6,}$/i.test(t)||/^[0-9]{8,}$/.test(t)?Je(t):t}function On(t){return t.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function An(t,e){let r=e.trim();if((r.startsWith("{")||r.startsWith("[")||r.startsWith('"'))&&t.startsWith("data-"))try{let o=JSON.parse(r);return JSON.stringify(De(o))}catch{}if(t.startsWith("data-")&&/^[A-Za-z0-9+/=]+$/.test(r))try{let o=Buffer.from(r,"base64").toString("utf8"),s=JSON.parse(o),i=JSON.stringify(De(s));return Buffer.from(i,"utf8").toString("base64")}catch{}return e}function Mn(t,e){let r=t.toLowerCase();return r==="class"?e.split(/(\s+)/).map((n,o)=>o%2===1?n:Je(n)).join(""):r==="id"||r==="for"||r==="aria-controls"||r==="aria-labelledby"||r==="aria-describedby"||r==="aria-owns"||r==="aria-activedescendant"||r==="name"?Je(e):r==="href"||r==="src"?On(e):An(r,e)}function Dn(t){return t.replace(/<([a-z][^\s/>]*)([^<>]*?)>/gi,(e,r,n)=>{if(r.startsWith("/"))return e;let o=n.replace(/\s([:@a-zA-Z_][-:.a-zA-Z0-9_]*?)=(['"])([\s\S]*?)\2/g,(s,i,a,l)=>{let u=Mn(i,l);return ` ${i}=${a}${u}${a}`});return `<${r}${o}>`})}function Re(t){let e=v.extname(t).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(e)||["robots.txt","sitemap.xml"].includes(v.basename(t))}function Ae(t,e){return [t.replace(/^\/+|\/+$/g,""),e.replace(/^\/+/,"")].filter(Boolean).join("/")}async function Ln(t,e,r,n){let o=new Map,s,i=0;do{i++;let a=await Y(`S3 list objects page ${i} for s3://${e}/${r||""}`,3e5,({httpOptions:l})=>t.send(new ListObjectsV2Command({Bucket:e,Prefix:r||void 0,ContinuationToken:s}),l));for(let l of a.Contents||[]){if(!l.Key)continue;let u=(l.ETag||"").replace(/^"|"$/g,"").toLowerCase(),c=Number(l.Size??0);o.set(l.Key,{etag:u,size:c,cacheControl:void 0});}s=a.NextContinuationToken,n.debug(`Listed S3 keys page ${i}: ${o.size} keys so far`);}while(s);return o}async function Fn(t,e,r,n){if(n.has(r))return n.get(r)??null;try{let o=await Y(`S3 head object ${r}`,3e5,({httpOptions:i})=>t.send(new HeadObjectCommand({Bucket:e,Key:r}),i)),s={etag:(o.ETag||"").replace(/^"|"$/g,"").toLowerCase(),size:Number(o.ContentLength??0),cacheControl:o.CacheControl?.trim()||null};return n.set(r,s),s}catch{return n.set(r,null),null}}async function Wn(t,e,r,n){if(n.cacheControl!==void 0)return n.cacheControl;try{let o=await Y(`S3 head cache metadata ${r}`,3e5,({httpOptions:s})=>t.send(new HeadObjectCommand({Bucket:e,Key:r}),s));n.cacheControl=o.CacheControl?.trim()||null;}catch{n.cacheControl=null;}return n.cacheControl}function Nt(t){return String(t||"").split(",").map(e=>e.trim().toLowerCase()).filter(Boolean).sort().join(",")}async function _n(t,e,r,n){let o=[...new Set(Array.from(r).filter(Boolean))];if(o.length===0)return n.info("No explicitly tombstoned S3 objects to delete."),[];n.info(`Deleting ${o.length} explicitly tombstoned S3 object(s)\u2026`);for(let s=0;s<o.length;s+=1e3){let i=o.slice(s,s+1e3);if(i.length===0)continue;let a=await Y(`S3 delete objects batch ${Math.floor(s/1e3)+1}`,3e5,({httpOptions:l})=>t.send(new DeleteObjectsCommand({Bucket:e,Delete:{Objects:i.map(u=>({Key:u}))}}),l));if(a.Errors&&a.Errors.length>0){let l=a.Errors.map(u=>`${u.Key||"(unknown)"}: ${u.Code||"DeleteFailed"}`);throw new Error(`S3 reported ${l.length} object deletion error(s): ${l.join(", ")}`)}n.info(`Deleted batch of ${i.length} object(s).`);for(let l of i)n.debug(` deleted: ${l}`);}return o}function Nn(t){return createHash("md5").update(t).digest("hex")}function ae(t){return createHash("sha256").update(t).digest("hex")}function Le(t){return createHash("sha256").update(Dn(t.toString("utf8"))).digest("hex")}async function Kn(t,e,r,n){if(n.has(r))return n.get(r)??null;try{let i=((await Y(`S3 head object metadata ${r}`,3e5,({httpOptions:a})=>t.send(new HeadObjectCommand({Bucket:e,Key:r}),a))).Metadata?.[Ut]||"").trim().toLowerCase()||null;return n.set(r,i),i}catch{return n.set(r,null),null}}async function Un(t,e,r,n,o){if(n.has(r))return n.get(r)??null;try{let i=((await Y(`S3 head object normalized metadata ${r}`,3e5,({httpOptions:a})=>t.send(new HeadObjectCommand({Bucket:e,Key:r}),a))).Metadata?.[Vt]||"").trim().toLowerCase();if(i)return n.set(r,i),i}catch{return n.set(r,null),null}if(o.has(r)){let s=o.get(r)??null;return n.set(r,s),s}try{let i=await(await Y(`S3 get object ${r}`,3e5,({httpOptions:l})=>t.send(new GetObjectCommand({Bucket:e,Key:r}),l))).Body?.transformToByteArray(),a=i?Le(Buffer.from(i)):null;return o.set(r,a),n.set(r,a),a}catch{return o.set(r,null),n.set(r,null),null}}function Vn(t){return t.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function zn(t,e){let r=t,n=Object.entries(e).sort((o,s)=>s[0].length-o[0].length);for(let[o,s]of n)o&&(r=r.split(o).join(s));return r}async function Bn(t,e,r,n){let o=v.join(t,"asset-map.json"),s;try{s=await O.readFile(o,"utf8");}catch(l){if(l.code==="ENOENT")return;throw l}let i=JSON.parse(s);if(!i||typeof i!="object")return;let a=Object.fromEntries(Object.entries(i).map(([l,u])=>{let c=String(u??"");return e.urlRewriteMode==="absolute"&&e.targetOrigin&&r.targetOrigin&&e.targetOrigin!==r.targetOrigin&&(c=c.split(e.targetOrigin).join(r.targetOrigin)),c=zn(c,n),[l,c]}));await O.writeFile(o,JSON.stringify(a,null,2),"utf8");}async function qn(t,e,r,n,o,s,i){let a=t.targetOrigin!==e.targetOrigin,l=Object.keys(n).length>0;if(!r||!a&&!l)return {outputDir:t.outputDir,cleanup:async()=>{}};if(a&&t.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=v.join(v.dirname(t.outputDir),`.deploy-profile-${Vn(r)}-${Date.now()}`),c=vn(u);o.info(`Preparing deployment profile "${r}" from existing crawl output to ${u}...`);try{if(await O.rm(u,{recursive:!0,force:!0}),s){await O.mkdir(u,{recursive:!0});for(let y of s){let h=v.join(t.outputDir,y),k=v.join(u,y);await O.mkdir(v.dirname(k),{recursive:!0}),await O.copyFile(h,k);}}else await O.cp(t.outputDir,u,{recursive:!0});let p={...t,sourceOrigin:t.targetOrigin,targetOrigin:e.targetOrigin,extraReplacements:n,outputDir:u},d=1;o.info(`Rewriting text files for deployment profile "${r}"...`);let g={files:s,onStart:({totalFiles:y,workerCount:h})=>{d=h,o.info(`Rewriting ${y} text file(s) for deployment profile "${r}" with ${h} worker(s).`);},onProgress:({index:y,totalFiles:h,changedTextFiles:k,file:S,changed:m})=>{let E=`Rewriting [${y}/${h}] ${S} (${m?"rewrote":"checked"}; ${k} changed so far)`;h<=200||y<=5||y%10===0||y===h?(o.progress(E,{file:S,index:y,totalFiles:h,changed:m,changedTextFiles:k,workerCount:d}),o.info(E)):o.debug(E);}},R=i?await jt(p,{},{...i,options:g}):await vt(p,{},g);return await Bn(u,t,e,n),o.info(`Prepared deployment profile "${r}" in ${u} (${R} rewritten text file(s)).`),{outputDir:u,cleanup:async()=>{c(),await O.rm(u,{recursive:!0,force:!0});}}}catch(p){throw o.error(`Failed to prepare deployment profile "${r}" temporary output.`,{tempDir:u,outputDir:t.outputDir,error:p instanceof Error?p.message:String(p),...p instanceof Error&&p.stack?{stack:p.stack}:{}}),await O.rm(u,{recursive:true,force:true}).catch(()=>{}),c(),await o.flush().catch(()=>{}),p}}function zt(t,e){let r=o=>o.replace(/^\/+|\/+$/g,""),n=t.targets.find(o=>o.bucketName===e.s3.bucket&&r(o.prefix)===r(e.s3.prefix)&&o.region===e.s3.region);if(!n)throw new Error(`No CDK Lambda deployment target matches s3://${e.s3.bucket}/${e.s3.prefix||""} in ${e.s3.region}. Redeploy the CDK with this target and reinstall remote-workers.json.`);return n}function Hn(t,e){if(!t||typeof t!="object")throw new Error("Remote deploy result must be a JSON object.");let r=t;if(r.schemaVersion!==K||r.response?.operation!=="deploy-copy"||r.response.jobId!==e.jobId||r.response.taskId!==e.taskId||!r.detail||!Array.isArray(r.detail.objects)||!Array.isArray(r.detail.deletedKeys)||!Array.isArray(r.detail.deleteErrors))throw new Error("Remote deploy result has an invalid envelope.");return r}async function Fe(t){let e=null;for(let r=1;r<=Math.max(1,Math.min(5,t.maxAttempts));r+=1){let n=J(`deploy-${t.batchIndex}-a${r}-${Date.now()}`,"taskId");try{let o=await t.client.invoke({schemaVersion:K,operation:"deploy-copy",jobId:t.jobId,taskId:n,targetId:t.targetId,items:t.items,...t.deleteRelativeKeys?{deleteRelativeKeys:t.deleteRelativeKeys}:{}}),s=Hn(await t.client.readResult(o),o);if(s.response.status==="partial")throw new Error(`Worker reported ${s.response.failedItems} failed item(s).`);return s}catch(o){e=o;}}throw new Error(`Remote deploy task failed after ${t.maxAttempts} attempt(s): ${e instanceof Error?e.message:String(e)}`,{cause:e})}async function Jn(t){let e=zt(t.remoteConfig,t.config),r=J(`deploy-${Date.now()}-${ae(Buffer.from(`${e.id}:${t.config.outputDir}`)).slice(0,12)}`,"jobId"),n=be(t.remoteConfig.workspace.prefix,"jobs",r,"deploy-inputs");t.log.progress(`Staging export for Lambda deploy: 0/${t.files.length}`,{phase:"deploy-stage",index:0,totalFiles:t.files.length,uploaded:0,skipped:0,failed:0,mode:"lambda-s3-copy"});let o=0,s=[],i=Math.max(1,Math.min(16,t.concurrency*2)),a=0;await Promise.all(Array.from({length:Math.min(i,t.files.length)},async()=>{for(;;){let S=a;if(S>=t.files.length)return;a+=1;let m=t.files[S],b=await O.readFile(v.join(t.config.outputDir,m)),E=t.contentTypeByRelativePath?.get(m)||Kt.lookup(m)||"application/octet-stream",P=t.revalidateFiles.has(ie(m))?Qe:Re(m)?t.config.s3.htmlCacheControl:t.config.s3.assetCacheControl,C=ae(b),$=Re(m)?Le(b):void 0,I=`${n}/files/${ae(Buffer.from(m))}-${v.basename(m)}`.replace(/\/+/g,"/");await t.client.writeWorkspaceObject({key:I,body:b,contentType:String(E),cacheControl:P,metadata:{"wpsuite-sha256":C,...$?{"wpsuite-normalized-sha256":$}:{}}}),s[S]={sourceKey:I,targetRelativeKey:m,sha256:C,...$?{normalizedSha256:$}:{},bytes:b.byteLength,contentType:String(E),cacheControl:P},o+=1,(o===t.files.length||o<=5||o%25===0)&&t.log.progress(`Staging export for Lambda deploy: ${o}/${t.files.length}`,{phase:"deploy-stage",index:o,totalFiles:t.files.length,staged:o,mode:"lambda-s3-copy"});}}));let l=[],u=Math.max(1,Math.min(500,t.batchSize));for(let S=0;S<s.length;S+=u)l.push(s.slice(S,S+u));let c=[],p=[],d=[],g=0,R=0,y=0,h=Math.max(1,Math.min(Math.max(1,t.concurrency),l.length));if(t.log.progress(`Lambda deploy: 0/${t.files.length}`,{phase:"deploy-copy",index:0,totalFiles:t.files.length,uploaded:0,skipped:0,failed:0,mode:"lambda-s3-copy",workerCount:h,completedBatches:0,totalBatches:l.length}),await Promise.all(Array.from({length:h},async()=>{for(;;){let S=y;if(S>=l.length)return;y+=1;let m=Date.now(),b=await Fe({client:t.client,jobId:r,targetId:e.id,batchIndex:S+1,items:l[S],maxAttempts:t.maxAttempts}),E=0,P=0,C=0;for(let I of b.detail.objects)g+=1,I.status==="copied"?(c.push(I.targetKey),E+=1):I.status==="skipped"?(p.push(I.targetKey),P+=1):(d.push(I.targetKey),C+=1),t.log.debug(`Lambda deploy ${I.status}: ${I.targetKey}`,{phase:"deploy-copy",batch:S+1,sourceKey:I.sourceKey,targetKey:I.targetKey,status:I.status,...I.error?{error:I.error}:{}});R+=1;let $=Date.now()-m;t.log.info(`Lambda deploy batch ${S+1}/${l.length} completed: ${E} copied, ${P} skipped unchanged, ${C} failed.`,{phase:"deploy-copy",batch:S+1,totalBatches:l.length,items:b.detail.objects.length,copied:E,skipped:P,failed:C,elapsedMs:$,elapsedSeconds:Math.round($/10)/100,workerExporterVersion:b.response.exporterVersion,...b.requestId?{lambdaRequestId:b.requestId}:{},...b.completedAt?{workerCompletedAt:b.completedAt}:{}}),t.log.progress(`Lambda deploy: ${g}/${t.files.length}`,{phase:"deploy-copy",index:g,totalFiles:t.files.length,uploaded:c.length,skipped:p.length,failed:d.length,mode:"lambda-s3-copy",workerCount:h,completedBatches:R,totalBatches:l.length});}})),d.length>0)throw new Error(`Remote deployment failed for ${d.length} object(s).`);let k=[];for(let S=0;S<t.deletedFiles.length;S+=1e3){let m=t.deletedFiles.slice(S,S+1e3);if(m.length===0)continue;let b=await Fe({client:t.client,jobId:r,targetId:e.id,batchIndex:l.length+Math.floor(S/1e3)+1,items:[],deleteRelativeKeys:m,maxAttempts:t.maxAttempts});k.push(...b.detail.deletedKeys),t.log.progress(`Lambda deploy deletions: ${k.length}/${t.deletedFiles.length}`,{phase:"deploy-delete",index:k.length,totalFiles:t.deletedFiles.length,deleted:k.length,mode:"lambda-s3-copy"});}return {uploadedKeys:c,skippedKeys:p,failedKeys:d,deletedKeys:k}}async function Gn(t){let e=zt(t.remoteConfig,t.config),r=J(`deploy-manifest-${Date.now()}-${ae(Buffer.from(e.id)).slice(0,12)}`,"jobId"),n=t.objects.map(g=>({sourceKey:g.object.key,targetRelativeKey:g.relativePath,sha256:g.object.sha256,bytes:g.object.bytes,contentType:g.contentType||"application/octet-stream",cacheControl:t.revalidateFiles.has(ie(g.relativePath))?Qe:Re(g.relativePath)?t.config.s3.htmlCacheControl:t.config.s3.assetCacheControl})),o=[],s=Math.max(1,Math.min(500,t.batchSize));for(let g=0;g<n.length;g+=s)o.push(n.slice(g,g+s));let i=[],a=[],l=[],u=0,c=0,p=Math.max(1,Math.min(Math.max(1,t.concurrency),Math.max(1,o.length)));if(t.log.progress(`Lambda deploy: 0/${n.length}`,{phase:"deploy-copy",index:0,totalFiles:n.length,mode:"lambda-s3-native",workerCount:p}),await Promise.all(Array.from({length:o.length===0?0:p},async()=>{for(;;){let g=u;if(g>=o.length)return;u+=1;let R=await Fe({client:t.client,jobId:r,targetId:e.id,batchIndex:g+1,items:o[g],maxAttempts:t.maxAttempts});for(let y of R.detail.objects)c+=1,y.status==="copied"?i.push(y.targetKey):y.status==="skipped"?a.push(y.targetKey):l.push(y.targetKey);t.log.progress(`Lambda deploy: ${c}/${n.length}`,{phase:"deploy-copy",index:c,totalFiles:n.length,uploaded:i.length,skipped:a.length,failed:l.length,mode:"lambda-s3-native",workerCount:p});}})),l.length>0)throw new Error(`Remote deployment failed for ${l.length} object(s).`);let d=[];for(let g=0;g<t.deletedFiles.length;g+=1e3){let R=t.deletedFiles.slice(g,g+1e3);if(R.length===0)continue;let y=await Fe({client:t.client,jobId:r,targetId:e.id,batchIndex:o.length+Math.floor(g/1e3)+1,items:[],deleteRelativeKeys:R,maxAttempts:t.maxAttempts});d.push(...y.detail.deletedKeys);}return {uploadedKeys:i,skippedKeys:a,failedKeys:l,deletedKeys:d}}async function Qn(t,e,r,n,o){let s={...e,jobId:J(`profile-${ae(Buffer.from(n)).slice(0,16)}-${Date.now()}`,"jobId"),objects:{},assetMap:{...e.assetMap},generatedAt:new Date().toISOString()},i=0,a=Math.max(1,Math.min(Math.max(1,o),Math.max(1,r.length)));return await Promise.all(Array.from({length:r.length===0?0:a},async()=>{for(;;){let l=i;if(l>=r.length)return;i+=1;let u=r[l],c=be(t.config.workspace.prefix,"jobs",s.jobId,"profile",ae(Buffer.from(u.relativePath)),v.basename(u.relativePath));s.objects[u.relativePath]={...u,object:await t.copyWorkspaceObject(u.object,c)};}})),s}async function Bt(t=process.argv.slice(2)){let e=await ve(),r=pt(t),n=dt(e,r),o=v.resolve(n.config.logDir||"logs"),s=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",i=s?v.join(v.resolve(s),"deploy-diff.json"):"",a=new ye(o,"deploy.log.jsonl",n.config.logLevel??"info"),l=n.profile?.extraReplacements??{},u=async()=>{};try{let c=await ct(e);if(t.includes("--content-sync")&&c?.schemaVersion!==2)throw new Error("Content-sync deployment requires a valid schema-2 targeted deploy plan.");let d=await ut(e);if(d)throw new Error(`Deployment blocked: the crawl started at ${d.startedAt} did not complete its final rewrite. Run a successful crawl or resume the rewrite before deploying.`);let g=e.remoteWorkers?.rewrite?.enabled===!0,R=e.remoteWorkers?.deploy?.enabled===!0,y=null,h=null;if(g||R){let f=Lt({runtimeDir:s});if(!f)throw new Error("Remote Lambda workers are enabled, but the runtime directory is unknown.");y=await Dt(f),h=new je(y);}let k=R&&g&&e.remoteWorkers?.render?.enabled===!0&&h&&y?.functions.asset?await Ft(e):null;if(k&&h&&y){if(k.workspace.bucket!==y.workspace.bucket||k.workspace.prefix!==y.workspace.prefix)throw new Error("Remote export manifest workspace does not match remote-workers.json.");let f=n.config,j=f.s3SyncMode??"sdk-upload-delete";if(c?.schemaVersion===2&&c.deletedFiles.length>0&&j!=="sdk-upload-delete")throw new Error("Content-sync tombstones require the sdk-upload-delete S3 sync mode.");let w=c?.schemaVersion===2?[...c.uploadGroups.assets,...c.uploadGroups.content,...c.uploadGroups.listings,...c.uploadGroups.resources,...c.uploadGroups.sitemapLeaves,...c.uploadGroups.sitemapIndexes]:c?.changedFiles??[];if(c?.schemaVersion===2){let F=[...new Set(w)],Q=[...new Set(c.changedFiles)];if(F.length!==Q.length||Q.some(ue=>!F.includes(ue)))throw new Error("Content-sync deploy-plan upload groups do not cover the exact changed-file set.")}let G=!!c&&!c.fullSyncRequired?[...new Set(w.map(ie))]:Object.keys(k.objects).sort(),fe=G.filter(F=>!k.objects[F]);if(fe.length>0)throw new Error(`Remote export manifest is missing ${fe.length} planned object(s): ${fe.slice(0,10).join(", ")}`);let te=k,T=G.map(F=>k.objects[F]);n.name&&(e.targetOrigin!==f.targetOrigin||Object.keys(l).length>0)&&(te=await Qn(h,k,T,n.name||"default",e.concurrency),await Ot(f,te,te.assetMap,{client:h,jobId:te.jobId,concurrency:e.concurrency,batchSize:25,maxAttempts:2}),T=G.map(F=>te.objects[F])),n.name&&a.info(`Using deployment profile: ${n.name}`),a.info(`Starting S3-native Lambda deploy - s3://${f.s3.bucket}/${f.s3.prefix||""} (${f.s3.region}).`),a.mark("deploy");let D=await Gn({client:h,remoteConfig:y,config:f,objects:T,deletedFiles:j==="sdk-upload-delete"?c?.deletedFiles??[]:[],revalidateFiles:new Set((c?.revalidateFiles??[]).map(ie)),concurrency:e.concurrency,batchSize:50,maxAttempts:2,log:a});i&&(await O.mkdir(v.dirname(i),{recursive:!0}),await O.writeFile(i,JSON.stringify({generatedAt:new Date().toISOString(),mode:"lambda-s3-native",summary:{totalFiles:T.length,eligibleFiles:T.length,uploaded:D.uploadedKeys.length,skipped:D.skippedKeys.length,rejected:0,failed:D.failedKeys.length,deleted:D.deletedKeys.length,protected:0,...n.name?{profile:n.name}:{}},uploadedKeys:D.uploadedKeys,skippedKeys:D.skippedKeys,rejectedKeys:[],failedKeys:D.failedKeys,deletedKeys:D.deletedKeys,protectedRemoteOnlyKeys:[]},null,2),"utf8")),c?.schemaVersion!==2&&await Ee(e),a.endMark("deploy"),await a.flush();return}let S=await qn(e,n.config,n.name,l,a,c?.schemaVersion===2?c.changedFiles:void 0,g&&h?{client:h,jobId:`profile-${Date.now()}`,concurrency:e.remoteWorkers?.rewrite?.concurrency??e.rewriteConcurrency,batchSize:e.remoteWorkers?.rewrite?.batchSize??25,maxAttempts:e.remoteWorkers?.rewrite?.maxAttempts??2,onStageProgress:({index:f,totalFiles:j,file:w})=>{(f===1||f===j||f%25===0)&&a.progress(`Staging deployment-profile rewrite: ${f}/${j}`,{phase:"rewrite-stage",index:f,totalFiles:j,file:w,execution:"lambda"});}}:void 0);u=S.cleanup;let m={...n.config,outputDir:S.outputDir},b=m.s3SyncMode??"sdk-upload-delete";if(c?.schemaVersion===2&&c.deletedFiles.length>0&&b!=="sdk-upload-delete")throw new Error("Content-sync tombstones require the sdk-upload-delete S3 sync mode.");let E=c?.schemaVersion!==2&&S.outputDir!==e.outputDir&&(e.targetOrigin!==n.config.targetOrigin||Object.keys(l).length>0),P=!!c&&!c.fullSyncRequired&&!E;if(c?.schemaVersion===2&&!P)throw new Error("Content-sync deployment cannot widen into a full-output deployment.");n.name&&a.info(`Using deployment profile: ${n.name}`),a.info(`Starting deploy \u2014 s3://${m.s3.bucket}/${m.s3.prefix||""} (region: ${m.s3.region})`),a.info(`S3 sync mode: ${b}`),c&&c.fullSyncRequired?a.info("Deploy plan requests a full sync; scanning the whole output tree."):c&&E?a.info("Ignoring incremental deploy plan because deployment-profile rewrites require a full sync."):P&&a.info(`Using incremental deploy plan: ${c.changedFiles.length} changed file(s), ${c.deletedFiles.length} deleted file(s).`),a.mark("deploy");let C=new S3Client({region:m.s3.region}),$=S.outputDir===e.outputDir?await In(e,s,a):null,I=c?.schemaVersion===2?[...c.uploadGroups.assets,...c.uploadGroups.content,...c.uploadGroups.listings,...c.uploadGroups.resources,...c.uploadGroups.sitemapLeaves,...c.uploadGroups.sitemapIndexes]:c?.changedFiles??[];if(c?.schemaVersion===2){let f=[...new Set(I)],j=[...new Set(c.changedFiles)];if(f.length!==j.length||j.some(w=>!f.includes(w)))throw new Error("Content-sync deploy-plan upload groups do not cover the exact changed-file set.")}let N=P?(await Promise.all(I.map(async f=>{try{return (await O.stat(v.join(m.outputDir,f))).isFile()?f:null}catch{if(c?.schemaVersion===2)throw new Error(`Content-sync planned upload is missing: ${f}`);return null}}))).filter(f=>f!==null):await Ar(["**/*"],{cwd:m.outputDir,onlyFiles:!0,dot:!0}),U=[],A=[],x=N.filter(f=>{let j=$?.byRelativePath.get(ie(f));if(!j)return !0;let w=Ae(m.s3.prefix,f);return U.push(f),A.push(w),a.reject(j.kind,j.sourceUrl||f,"rewrite not completed; deploy upload blocked","deploy-guard",{file:f,key:w,outputPath:j.outputPath,manifestPath:$?.manifestPath}),!1}),Ze=new Set((c?.revalidateFiles||[]).map(ie)),Xe=new Set((P?x:N).map(f=>Ae(m.s3.prefix,f)));$&&($.pendingPages>0||$.pendingTextAssets>0)&&a.info(`Deploy rewrite guard loaded ${$.pendingPages} pending page(s) and ${$.pendingTextAssets} pending text asset(s) from crawl manifest.`,{manifestPath:$.manifestPath,pendingPages:$.pendingPages,pendingTextAssets:$.pendingTextAssets,source:"deploy-guard"}),U.length>0&&a.warn(`Deploy rewrite guard blocked ${U.length} file(s) from upload because final crawl rewrite is incomplete.`,{rejected:U.length,manifestPath:$?.manifestPath,source:"deploy-guard"}),P?a.info(`Using ${x.length} eligible planned changed file(s) from deploy plan for upload${U.length>0?` (${U.length} blocked by deploy rewrite guard)`:""}.`):a.info(`Found ${N.length} file(s) in output directory "${m.outputDir}"${U.length>0?`; ${x.length} remain eligible for upload after deploy rewrite guard filtering`:""}.`),a.progress("Deploy preflight: comparing local output with remote S3 state.",{phase:"deploy",mode:b,totalFiles:x.length,scannedFiles:N.length,rejected:U.length,deploymentProfile:n.name||"",s3Bucket:m.s3.bucket,s3Prefix:m.s3.prefix||"",targetedPlan:P,deployGuardEnabled:S.outputDir===e.outputDir});let L=0,M=0,B=0,ge=[],X=[],ee=[],le=[],ce=[],me=new Map,qt=new Map,Ht=new Map,Jt=new Map,Gt=new Map;if(R){if(!h||!y)throw new Error("Remote deploy worker client was not initialized.");if(b!=="sdk-upload-delete"&&b!=="sdk-upload-only")throw new Error(`Unsupported remote deploy mode: ${b}`);let f=await Jn({client:h,remoteConfig:y,config:m,files:x,deletedFiles:b==="sdk-upload-delete"?c?.deletedFiles??[]:[],revalidateFiles:Ze,contentTypeByRelativePath:$?.contentTypeByRelativePath,concurrency:m.remoteWorkers?.deploy?.concurrency??m.assetDownloadConcurrency,batchSize:m.remoteWorkers?.deploy?.batchSize??50,maxAttempts:m.remoteWorkers?.deploy?.maxAttempts??2,log:a});ge.push(...f.uploadedKeys),X.push(...f.skippedKeys),ee.push(...f.failedKeys),le=f.deletedKeys,L=ge.length,M=X.length,B=ee.length,a.info(`Lambda deploy complete: ${L} copied, ${M} skipped unchanged, ${le.length} deleted, ${B} failed.`),i&&(await O.mkdir(v.dirname(i),{recursive:!0}),await O.writeFile(i,JSON.stringify({generatedAt:new Date().toISOString(),mode:"lambda-s3-copy",summary:{totalFiles:N.length,eligibleFiles:x.length,uploaded:L,skipped:M,rejected:A.length,failed:B,deleted:le.length,protected:0,...n.name?{profile:n.name}:{}},uploadedKeys:ge,skippedKeys:X,rejectedKeys:A,failedKeys:ee,deletedKeys:le,protectedRemoteOnlyKeys:[]},null,2),"utf8")),c?.schemaVersion!==2&&await Ee(e),a.endMark("deploy"),await a.flush();return}P||(a.info("Listing existing S3 objects to detect unchanged files..."),me=await Ln(C,m.s3.bucket,m.s3.prefix,a),a.info(`Found ${me.size} existing key(s) in S3.`));let Qt=async f=>me.has(f)?me.get(f)??null:P?Fn(C,m.s3.bucket,f,qt):null;for(let f of x){let j=v.join(m.outputDir,f),w=Ae(m.s3.prefix,f),V=$?.contentTypeByRelativePath.get(f),G=V&&V!=="application/octet-stream"?V:Kt.lookup(f)||V||"application/octet-stream",fe=Ze.has(ie(f)),te=fe?Qe:Re(f)?m.s3.htmlCacheControl:m.s3.assetCacheControl,T=L+M+B+1;x.length<=200||T<=5||T%10===0||T===x.length?(a.progress(`Uploading [${T}/${x.length}] ${w} (${G})`,{file:f,key:w,index:T,totalFiles:x.length,contentType:G,mode:b}),a.info(`Uploading [${T}/${x.length}] ${w} (${G})`)):a.debug(`Uploading [${T}/${x.length}] ${w} (${G})`);try{let z=await O.readFile(j),D=await Qt(w),F=null,Q=null;if(D){let ue=!fe||Nt(await Wn(C,m.s3.bucket,w,D))===Nt(te),Yt=z.byteLength;if(D.size===Yt){let xe=D.etag.includes("-");if(D.etag!==""&&!xe){let Zt=Nn(z);if(D.etag===Zt&&ue){M++,x.length<=200||M<=5||M%25===0?(a.progress(`Skipped unchanged [${T}/${x.length}] ${w}`,{file:f,key:w,index:T,totalFiles:x.length,uploaded:L,skipped:M,failed:B,mode:b,reason:"etag-md5-match"}),a.info(`Skipped unchanged [${T}/${x.length}] ${w}`)):a.debug(`Skipped unchanged [${T}/${x.length}] ${w}`),X.push(w);continue}}F=ae(z);let et=await Kn(C,m.s3.bucket,w,Ht);if(et&&et===F&&ue){M++,x.length<=200||M<=5||M%25===0?(a.progress(`Skipped unchanged [${T}/${x.length}] ${w}`,{file:f,key:w,index:T,totalFiles:x.length,uploaded:L,skipped:M,failed:B,mode:b,reason:"metadata-sha256-match"}),a.info(`Skipped unchanged [${T}/${x.length}] ${w}`)):a.debug(`Skipped unchanged [${T}/${x.length}] ${w}`),X.push(w);continue}}if(Re(f)){Q=Le(z);let xe=await Un(C,m.s3.bucket,w,Jt,Gt);if(xe&&xe===Q&&ue){M++,x.length<=200||M<=5||M%25===0?(a.progress(`Skipped semantically unchanged [${T}/${x.length}] ${w}`,{file:f,key:w,index:T,totalFiles:x.length,uploaded:L,skipped:M,failed:B,mode:b,reason:"normalized-html-match"}),a.info(`Skipped semantically unchanged [${T}/${x.length}] ${w}`)):a.debug(`Skipped semantically unchanged [${T}/${x.length}] ${w}`),X.push(w);continue}}}F=F??ae(z),Q=Q??(Re(f)?Le(z):null),await Y(`S3 upload ${w}`,9e5,({abortController:ue})=>new Upload({client:C,abortController:ue,params:{Bucket:m.s3.bucket,Key:w,Body:z,ContentType:G,CacheControl:te,Metadata:{[Ut]:F,...Q?{[Vt]:Q}:{}}}}).done()),L++,ge.push(w),(L%25===0||L===x.length)&&(a.progress(`Uploaded ${L}/${x.length} file(s)\u2026`,{uploaded:L,skipped:M,failed:B,totalFiles:x.length,mode:b}),a.info(`Uploaded ${L}/${x.length} file(s)\u2026`));}catch(z){B++,ee.push(w),a.error(`Failed to upload ${w}: ${z.message}`,{key:w,error:String(z)});}}if(a.info(`Upload complete: ${L} uploaded, ${M} skipped unchanged, ${A.length} rejected by guard, ${B} failed.`),ee.length>0||A.length>0)throw new Error(`Deployment stopped before deletion because ${ee.length} upload(s) failed and ${A.length} upload(s) were rejected.`);if(b==="sdk-upload-delete"){let f=new Set((c?.deletedFiles??[]).map(w=>Ae(m.s3.prefix,w))),j=[...f].filter(w=>!Xe.has(w));if(!P&&(ce=[...me.keys()].filter(V=>!Xe.has(V)).filter(V=>!f.has(V)),ce.length>0)){a.warn(`Protected ${ce.length} remote-only S3 object(s) from deletion because the crawl did not provide explicit tombstones.`,{protected:ce.length,source:"deploy-delete-guard"});for(let V of ce)a.debug(` protected remote-only object: ${V}`);}le=await _n(C,m.s3.bucket,P?j:j.filter(w=>me.has(w)),a);}else a.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion.");i&&(await O.mkdir(v.dirname(i),{recursive:!0}),await O.writeFile(i,JSON.stringify({generatedAt:new Date().toISOString(),mode:b,summary:{totalFiles:N.length,eligibleFiles:x.length,uploaded:ge.length,skipped:X.length,rejected:A.length,failed:ee.length,deleted:le.length,protected:ce.length,...n.name?{profile:n.name}:{}},uploadedKeys:ge,skippedKeys:X,rejectedKeys:A,failedKeys:ee,deletedKeys:le,protectedRemoteOnlyKeys:ce},null,2),"utf8")),c?.schemaVersion!==2&&await Ee(e),a.endMark("deploy"),await a.flush();}finally{await u().catch(()=>{});}}Bt().catch(async t=>{console.error(t);try{let r=(await ve().catch(()=>null))?.logDir??"logs",n=new ye(r,"deploy.log.jsonl","debug");n.error(`Unhandled error: ${t instanceof Error?t.message:String(t)}`,t instanceof Error?{stack:t.stack}:void 0),await n.flush();}catch{}process.exit(1);});
|
|
6
|
+
`;return t.replace(/<head\b[^>]*>/i,o=>`${o}${n} ${e}`)}function qr(t){let e=kt(t).trim();return e.startsWith("{")||e.startsWith("[")||e.includes("\\/")||/"@context"|"@type"/.test(e)}function Hr(t,e){let r=[...new Set(e)].filter(s=>s.includes("/")&&!/\\+\//.test(s)).map(s=>[s,$e(s)]).filter(([s,a])=>s!==a).sort((s,a)=>a[0].length-s[0].length);if(!r.length)return t;let n=s=>{let a=s;for(let[i,l]of r)a=a.split(i).join(l);return a},o=t.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(s,a,i,l)=>`${a}${n(i)}${l}`);return o=o.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(s,a,i,l,u)=>qr(l)?`${a}${n(l)}${u}`:s),o}function Jr(t,e){if(!e)return null;let r=v.dirname(v.resolve(e)),n=v.resolve(t.outputDir),o=v.relative(r,n).replace(/\\/g,"/");return o?(o.startsWith(".")||(o=`./${o}`),o.endsWith("/")?o:`${o}/`):"./"}function Gr(t,e,r){let n=Jr(e,r);if(!n)return t;let o=t;for(let s of Fr){let a=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=new RegExp(`(?:\\.{1,}/)+${a}`,"g"),l=new RegExp(`(?<!\\.)/${a}`,"g");o=o.replace(i,`${n}${s}`).replace(l,`${n}${s}`);let u=s.replace(/\//g,"\\/"),c=n.replace(/\//g,"\\/"),p=u.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),d=new RegExp(`(?:\\.{1,}\\\\/)+${p}`,"g"),m=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${p}`,"g"),R=new RegExp(`(?<![\\.\\\\])\\/${p}`,"g");o=o.replace(d,`${c}${u}`).replace(m,`${c}${u}`).replace(R,`${c}${u}`);}return o}function Be(t,e,r){if(t.urlRewriteMode==="absolute")return e;let n=(()=>{try{return new URL(e,t.targetOrigin==="."?"https://relative.invalid":t.targetOrigin)}catch{return null}})(),o=n?n.pathname:Pt(e,t.targetOrigin),s=n?`${n.search}${n.hash}`:"";return t.urlRewriteMode==="root-relative"?`${o}${s}`:`${St(t.outputDir,r,o)}${s}`}function ze(t,e,r,n,o){Te(t,r,Be(e,n,o));}function Qr(t,e,r,n,o){if(!r||r===n)return;Te(t,r,n);let s=Be(e,r,o),a=Be(e,n,o);Te(t,s,a);}function Yr(t,e,r,n,o={}){let s=t,a={};ze(a,e,e.sourceOrigin,e.targetOrigin,n);for(let[l,u]of Object.entries(e.extraReplacements))ze(a,e,l,u,n);for(let[l,u]of Object.entries(r))ze(a,e,l,u,n);for(let[l,u]of Object.entries(o)){let c=r[l];!c||c===u||Qr(a,e,u,c,n);}let i=Object.entries(a).sort((l,u)=>u[0].length-l[0].length);for(let[l,u]of i)s=Vr(s,l,u);return e.urlRewriteMode!=="absolute"&&(s=Gr(s,e,n)),s=Hr(s,i.map(([,l])=>l)),zr(e,s,n)&&(s=Br(s)),s}async function Zr(t,e,r,n){let o=v.join(t.outputDir,n),s=v.extname(o).toLowerCase(),a;try{a=await A.readFile(o,"utf8");}catch(u){if(u.code!=="ENOENT")throw u;return {changed:false}}let l=Yr(a,t,e,s===".js"||s===".mjs"?void 0:o,r);return l!==a?(await Se(o,l,"utf8"),{changed:true}):{changed:false}}async function Xr(t,e){return await new Promise((r,n)=>{let o=l=>{if(i(),l?.error){n(new Error(l.error));return}r({changed:!!l?.changed});},s=l=>{i(),n(l);},a=l=>{i(),l!==0&&n(new Error(`Rewrite worker exited with code ${l}.`));},i=()=>{t.off("message",o),t.off("error",s),t.off("exit",a);};t.on("message",o),t.on("error",s),t.on("exit",a),t.postMessage({file:e});})}async function vt(t,e,r={}){let n=await qe(t,r.files),o=0;if(n.length===0)return 0;let s=Math.max(1,Number(t.rewriteConcurrency||t.assetDownloadConcurrency||1)),a=Math.max(1,Math.min(s,n.length,availableParallelism()));await r.onStart?.({totalFiles:n.length,workerCount:a});let i=0,l=0,u=null;if(a===1){for(let p of n){let d=await Zr(t,e,r.previousAssetMap??{},p);d.changed&&(o+=1),l+=1,await r.onProgress?.({index:l,totalFiles:n.length,changedTextFiles:o,file:p,changed:d.changed});}return o}let c=Array.from({length:a},async()=>{let p=new Worker(new URL("./rewrite-worker.js",import.meta.url),{workerData:{config:t,assetMap:e,previousAssetMap:r.previousAssetMap??{}}});try{for(;!u;){let d=i;if(d>=n.length)return;i+=1;let m=n[d],R=await Xr(p,m);R.changed&&(o+=1),l+=1,await r.onProgress?.({index:l,totalFiles:n.length,changedTextFiles:o,file:m,changed:R.changed});}}catch(d){throw u=d instanceof Error?d:new Error(String(d)),u}finally{await p.terminate().catch(()=>{});}});return await Promise.all(c),o}var K=1,Et=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function J(t,e){let r=String(t??"").trim();if(!Et.test(r))throw new Error(`${e} must match ${Et.source} and be at most 128 characters.`);return r}function It(t){let e=String(t??"").trim().replace(/^\/+|\/+$/g,"");if(!e)return "";let r=e.split("/").filter(Boolean);if(r.some(n=>n==="."||n===".."))throw new Error("S3 prefix contains an unsafe dot path segment.");return `${r.join("/")}/`}function be(t,...e){let r=It(t),n=e.map((o,s)=>{let a=String(o??"").replace(/^\/+|\/+$/g,"");if(!a||a.split("/").some(i=>i==="."||i===".."))throw new Error(`Unsafe S3 key segment at index ${s}.`);return a});return `${r}${n.join("/")}`}function pe(t){return createHash("sha256").update(t).digest("hex")}function oe(t,e){let r=String(t??"").replace(/^\/+/,""),n=It(e);if(!r||r.includes("\0"))throw new Error("S3 object key is empty or invalid.");if(n&&!r.startsWith(n))throw new Error(`S3 object key is outside the configured workspace prefix: ${r}`);if(r.split("/").some(o=>o===".."))throw new Error("S3 object key contains an unsafe parent segment.");return r}function $t(t,e){let r=[];for(let n=0;n<t.length;n+=e)r.push(t.slice(n,n+e));return r}function Tt(t){return {sourceOrigin:t.sourceOrigin,targetOrigin:t.targetOrigin,urlRewriteMode:t.urlRewriteMode,outputDir:"/workspace",extraReplacements:t.extraReplacements,wpsuite:{...t.wpsuite?.subscriptionType?{subscriptionType:t.wpsuite.subscriptionType}:{},...t.wpsuite?.siteSettings?{siteSettings:{subscriber:t.wpsuite.siteSettings.subscriber===true}}:{}}}}function jt(t,e){if(!t||typeof t!="object")throw new Error("Remote rewrite result must be a JSON object.");let r=t;if(r.schemaVersion!==K||r.response?.operation!=="rewrite"||r.response.jobId!==e.jobId||r.response.taskId!==e.taskId||!r.detail||!Array.isArray(r.detail.objects))throw new Error("Remote rewrite result has an invalid envelope.");return r}async function Ot(t,e,r){let n=r.options??{},o=await qe(t,n.files);if(o.length===0)return 0;let s=J(r.jobId,"jobId"),a=be(r.client.config.workspace.prefix,"jobs",s,"rewrite-inputs"),i=`${a}/config.json`.replace(/\/+/g,"/"),l=`${a}/asset-map.json`.replace(/\/+/g,"/"),u=`${a}/previous-asset-map.json`.replace(/\/+/g,"/");await Promise.all([r.client.writeWorkspaceObject({key:i,body:JSON.stringify(Tt(t)),contentType:"application/json; charset=utf-8"}),r.client.writeWorkspaceObject({key:l,body:JSON.stringify(e),contentType:"application/json; charset=utf-8"}),r.client.writeWorkspaceObject({key:u,body:JSON.stringify(n.previousAssetMap??{}),contentType:"application/json; charset=utf-8"})]);let c=Math.max(1,Math.min(500,r.batchSize)),p=Math.ceil(o.length/c),d=Math.max(1,Math.min(Math.max(1,r.concurrency),p));await n.onStart?.({totalFiles:o.length,workerCount:d});let m=[],R=0,w=0;await Promise.all(Array.from({length:Math.min(16,o.length)},async()=>{for(;;){let I=R;if(I>=o.length)return;R+=1;let P=o[I],C=v.join(t.outputDir,P),$=Ct.lookup(P),E=$?Ct.contentType($)||$:"text/plain; charset=utf-8",D=`${a}/files/${pe(P)}.txt`.replace(/\/+/g,"/");await r.client.writeWorkspaceObject({key:D,body:await A.readFile(C),contentType:E}),m[I]={relativePath:P,key:D,fullPath:C,contentType:E},w+=1,await r.onStageProgress?.({index:w,totalFiles:o.length,file:P});}}));let y=$t(m,c),S=0,k=0,f=0,b=Array.from({length:d},async()=>{for(;;){let I=S;if(I>=y.length)return;S+=1;let P=y[I],C=null,$=null;for(let E=1;E<=Math.max(1,Math.min(5,r.maxAttempts));E+=1){let D=J(`rewrite-${I+1}-a${E}-${pe(P.map(O=>O.relativePath).join(`
|
|
7
|
+
`)).slice(0,16)}`,"taskId"),U={schemaVersion:K,operation:"rewrite",jobId:s,taskId:D,configKey:i,assetMapKey:l,previousAssetMapKey:u,items:P.map(O=>({inputKey:O.key,outputKey:O.key,relativePath:O.relativePath,contentType:O.contentType}))};try{let O=await r.client.invoke(U);$=jt(await r.client.readResult(O),O);break}catch(O){C=O;}}if(!$)throw new Error(`Remote rewrite batch ${I+1}/${y.length} failed: ${C instanceof Error?C.message:String(C)}`,{cause:C});for(let E of P){let D=$.detail.objects.find(U=>U.outputKey===E.key);if(!D)throw new Error(`Remote rewrite result omitted ${E.relativePath}.`);await Se(E.fullPath,Buffer.from(await r.client.readObject(D.output))),D.changed&&(f+=1),k+=1,await n.onProgress?.({index:k,totalFiles:o.length,changedTextFiles:f,file:E.relativePath,changed:D.changed});}}});return await Promise.all(b),f}async function At(t,e,r,n){let o=n.relativePaths?new Set([...n.relativePaths].map(y=>y.replace(/\\/g,"/"))):null,s=Object.values(e.objects).filter(y=>y.isText&&(!o||o.has(y.relativePath))).sort((y,S)=>y.relativePath.localeCompare(S.relativePath));if(s.length===0)return 0;let a=J(n.jobId,"jobId"),i=be(n.client.config.workspace.prefix,"jobs",a,"rewrite-config"),l=`${i}/config.json`.replace(/\/+/g,"/"),u=`${i}/asset-map.json`.replace(/\/+/g,"/");await Promise.all([n.client.writeWorkspaceObject({key:l,body:JSON.stringify(Tt(t)),contentType:"application/json; charset=utf-8"}),n.client.writeWorkspaceObject({key:u,body:JSON.stringify(r),contentType:"application/json; charset=utf-8"})]);let c=Math.max(1,Math.min(500,n.batchSize)),p=$t(s,c),d=Math.max(1,Math.min(Math.max(1,n.concurrency),p.length)),m=0,R=0,w=0;return await Promise.all(Array.from({length:d},async()=>{for(;;){let y=m;if(y>=p.length)return;m+=1;let S=p[y],k=null,f=null;for(let b=1;b<=Math.max(1,Math.min(5,n.maxAttempts));b+=1){let I=J(`rewrite-object-${y+1}-a${b}-${pe(S.map(P=>P.relativePath).join(`
|
|
8
|
+
`)).slice(0,16)}`,"taskId");try{let P=await n.client.invoke({schemaVersion:K,operation:"rewrite",jobId:a,taskId:I,configKey:l,assetMapKey:u,items:S.map(C=>({inputKey:C.object.key,outputKey:C.object.key,relativePath:C.relativePath,contentType:C.contentType||C.object.contentType}))});k=jt(await n.client.readResult(P),P);break}catch(P){f=P;}}if(!k)throw new Error(`Remote object rewrite batch ${y+1}/${p.length} failed: ${f instanceof Error?f.message:String(f)}`,{cause:f});for(let b of S){let I=k.detail.objects.find(P=>P.outputKey===b.object.key);if(!I)throw new Error(`Remote rewrite result omitted ${b.relativePath}.`);b.object=I.output,I.changed&&(w+=1),R+=1,await n.onProgress?.({index:R,totalFiles:s.length,changedTextFiles:w,file:b.relativePath,changed:I.changed});}}})),e.assetMap={...r},e.generatedAt=new Date().toISOString(),w}function W(t,e,{optional:r=false}={}){if(!(r&&(t==null||t===""))){if(typeof t!="string"||!t.trim())throw new Error(`${e} must be a non-empty string.`);return t.trim()}}function gn(t){if(!t||typeof t!="object")throw new Error("Remote worker config must be a JSON object.");let e=t;if(e.schemaVersion!==1)throw new Error(`Unsupported remote worker config version: ${String(e.schemaVersion)}.`);if(e.protocolVersion!==K)throw new Error(`Remote worker protocol mismatch: expected ${K}, received ${String(e.protocolVersion)}.`);let r=e.workspace,n=e.functions;if(!r||!n)throw new Error("Remote worker config requires workspace and functions objects.");return {schemaVersion:1,region:W(e.region,"region"),...W(e.roleArn,"roleArn",{optional:true})?{roleArn:W(e.roleArn,"roleArn")}:{},...W(e.roleSessionName,"roleSessionName",{optional:true})?{roleSessionName:W(e.roleSessionName,"roleSessionName")}:{},workspace:{bucket:W(r.bucket,"workspace.bucket"),prefix:String(r.prefix??"")},...e.status&&typeof e.status=="object"?{status:{tableName:W(e.status.tableName,"status.tableName")}}:{},functions:{render:W(n.render,"functions.render"),...W(n.asset,"functions.asset",{optional:true})?{asset:W(n.asset,"functions.asset")}:{},rewrite:W(n.rewrite,"functions.rewrite"),"deploy-copy":W(n["deploy-copy"],"functions.deploy-copy")},targets:Array.isArray(e.targets)?e.targets.map((o,s)=>{if(!o||typeof o!="object")throw new Error(`targets[${s}] must be an object.`);let a=o;return {id:W(a.id,`targets[${s}].id`),bucketName:W(a.bucketName,`targets[${s}].bucketName`),prefix:String(a.prefix??""),region:W(a.region,`targets[${s}].region`)}}):[],protocolVersion:K}}async function Lt(t){let e=v.resolve(t);try{return gn(JSON.parse(await readFile(e,"utf8")))}catch(r){throw new Error(`Unable to load remote worker config ${e}: ${r instanceof Error?r.message:String(r)}`,{cause:r})}}var je=class{config;lambda;s3;dynamodb;#e;constructor(e,r={},n={}){this.config=e;let o=e.roleArn?fromTemporaryCredentials({params:{RoleArn:e.roleArn,RoleSessionName:e.roleSessionName??"publisher-exporter-remote-worker"},clientConfig:{region:e.region}}):void 0;this.lambda=new LambdaClient({region:e.region,...o?{credentials:o}:{},...r}),this.s3=new S3Client({region:e.region,...o?{credentials:o}:{}}),this.dynamodb=e.status?new DynamoDBClient({region:e.region,...o?{credentials:o}:{}}):null,this.#e=n;}async#t(e){if(!this.dynamodb||!this.config.status)return null;let n=(await this.dynamodb.send(new GetItemCommand({TableName:this.config.status.tableName,ConsistentRead:true,Key:{jobId:{S:e.jobId},taskId:{S:e.taskId}}}))).Item;if(!n)return null;let o=n.operation?.S,s=n.status?.S;return !o||!["render","asset","rewrite","deploy-copy"].includes(o)||!s||!["running","succeeded","partial","failed"].includes(s)?null:{jobId:n.jobId?.S??e.jobId,taskId:n.taskId?.S??e.taskId,operation:o,status:s,completedItems:Number(n.completedItems?.N??0),failedItems:Number(n.failedItems?.N??0),totalItems:Number(n.totalItems?.N??0),sequence:Number(n.sequence?.N??0),updatedAt:n.updatedAt?.S??new Date(0).toISOString(),requestId:n.requestId?.S??null}}async#r(e,r){let n=this.lambda.send(new InvokeCommand({FunctionName:r,InvocationType:"RequestResponse",Payload:Buffer.from(JSON.stringify(e),"utf8")}));if(e.operation==="health"||!this.dynamodb||!this.#e.onProgress)return await n;let o=false,s=n.finally(()=>{o=true;}),a=Math.max(500,Math.min(3e4,this.#e.progressPollIntervalMs??2e3)),i=-1;for(;!o;){await Promise.race([s.then(()=>{},()=>{}),new Promise(l=>setTimeout(l,a))]);try{let l=await this.#t(e);l&&l.sequence>i&&(i=l.sequence,await this.#e.onProgress(l));}catch(l){await this.#e.onProgressError?.(l instanceof Error?l:new Error(String(l)));}}return await s}async invoke(e){let r=e.operation==="health"?this.config.functions.render:this.config.functions[e.operation];if(!r)throw new Error(`Remote worker configuration does not provide a ${e.operation} function. Redeploy the Lambda workers and reinstall remote-workers.json.`);let n=await this.#r(e,r),o=n.Payload?JSON.parse(new TextDecoder().decode(n.Payload)):null;if(n.FunctionError)throw new Error(`Remote ${e.operation} worker failed (${n.FunctionError}): ${JSON.stringify(o)}`);if(!o||typeof o!="object")throw new Error(`Remote ${e.operation} worker returned no JSON response.`);let s=o;if(s.schemaVersion!==K||s.operation!==e.operation||s.jobId!==e.jobId||s.taskId!==e.taskId)throw new Error(`Remote ${e.operation} worker returned a mismatched response.`);return s}async readResult(e){if(!e.resultKey)throw new Error(`Remote ${e.operation} response does not contain a resultKey.`);let r=oe(e.resultKey,this.config.workspace.prefix),n=await this.s3.send(new GetObjectCommand({Bucket:this.config.workspace.bucket,Key:r}));if(!n.Body)throw new Error(`Remote worker result has no body: ${r}`);return JSON.parse(await n.Body.transformToString("utf8"))}async readObject(e){if(e.bucket!==this.config.workspace.bucket)throw new Error(`Remote worker object bucket mismatch: ${e.bucket}.`);let r=oe(e.key,this.config.workspace.prefix),n=await this.s3.send(new GetObjectCommand({Bucket:this.config.workspace.bucket,Key:r,...e.versionId?{VersionId:e.versionId}:{}}));if(!n.Body)throw new Error(`Remote worker object has no body: ${r}`);let o=await n.Body.transformToByteArray();if(o.byteLength!==e.bytes)throw new Error(`Remote worker object length mismatch for ${r}: expected ${e.bytes}, received ${o.byteLength}.`);if(pe(o)!==e.sha256)throw new Error(`Remote worker object checksum mismatch for ${r}.`);return o}async readObjectText(e){return new TextDecoder("utf8",{fatal:true}).decode(await this.readObject(e))}async health(e){let r=this.config.functions[e];if(!r)throw new Error(`Remote worker configuration does not provide a ${e} function.`);let n=`${e}-${Date.now()}`,o=await this.lambda.send(new InvokeCommand({FunctionName:r,InvocationType:"RequestResponse",Payload:Buffer.from(JSON.stringify({schemaVersion:K,operation:"health",jobId:"health",taskId:n}),"utf8")})),s=o.Payload?JSON.parse(new TextDecoder().decode(o.Payload)):null;if(o.FunctionError||!s||typeof s!="object")throw new Error(`Remote ${e} health check failed: ${JSON.stringify(s)}`);return s}async writeWorkspaceObject(e){let r=oe(e.key,this.config.workspace.prefix),n=typeof e.body=="string"?Buffer.from(e.body,"utf8"):e.body,o=pe(n),s=await this.s3.send(new PutObjectCommand({Bucket:this.config.workspace.bucket,Key:r,Body:n,ContentType:e.contentType,...e.cacheControl?{CacheControl:e.cacheControl}:{},Metadata:{sha256:o,...e.metadata??{}}}));return {bucket:this.config.workspace.bucket,key:r,sha256:o,bytes:n.byteLength,contentType:e.contentType,...s.ETag?{etag:s.ETag}:{},...s.VersionId?{versionId:s.VersionId}:{}}}async copyWorkspaceObject(e,r){if(e.bucket!==this.config.workspace.bucket)throw new Error(`Remote worker object bucket mismatch: ${e.bucket}.`);let n=oe(e.key,this.config.workspace.prefix),o=oe(r,this.config.workspace.prefix),s=`${e.bucket}/${n.split("/").map(i=>encodeURIComponent(i)).join("/")}`,a=await this.s3.send(new CopyObjectCommand({Bucket:e.bucket,Key:o,CopySource:s,MetadataDirective:"COPY"}));return {...e,key:o,...a.CopyObjectResult?.ETag?{etag:a.CopyObjectResult.ETag}:{},...a.VersionId?{versionId:a.VersionId}:{}}}};var mn="remote-workers.json";function Wt(t={}){let e=String(t.explicitPath??"").trim();if(e)return v.resolve(e);let r=String(t.runtimeDir??process.env.STATIC_PUBLISHER_RUNTIME_DIR??process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR??"").trim();return r?v.join(v.resolve(r),mn):""}function hn(){let t=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return t.trim()?v.resolve(t):""}function yn(t){let e=String(process.env.STATIC_PUBLISHER_REMOTE_EXPORT_MANIFEST_PATH||"").trim();if(e)return v.resolve(e);let r=hn();if(r)return v.join(r,"remote-export-manifest.json");let n=v.resolve(t.outputDir);return v.join(v.dirname(n),`.${v.basename(n)}-remote-export-manifest.json`)}function wn(t){let e=v.posix.normalize(String(t||"").replace(/\\/g,"/").replace(/^\/+/,""));if(!e||e==="."||e===".."||e.startsWith("../")||/^[A-Za-z]:/.test(e))throw new Error(`Invalid remote export relative path: ${t}`);return e}async function Ft(t){try{let e=JSON.parse(await A.readFile(yn(t),"utf8"));if(e.schemaVersion!==1||typeof e.jobId!="string"||!e.workspace||typeof e.workspace.bucket!="string"||typeof e.workspace.prefix!="string"||!e.objects||typeof e.objects!="object"||!e.assetMap||typeof e.assetMap!="object")return null;let r=e;for(let[n,o]of Object.entries(r.objects)){if(wn(n),!o||o.relativePath!==n||o.object?.bucket!==r.workspace.bucket)return null;oe(o.object.key,r.workspace.prefix);}return r}catch{return null}}var Vt="wpsuite-sha256",zt="wpsuite-normalized-sha256",Qe="public, max-age=0, must-revalidate",En=/(?:^|[-_:.])(id|uid|nonce|token|hash|instance)(?:$|[-_:.])/i,Ye=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,In=["SIGINT","SIGTERM"],Me=new Set,Oe=new Map,_t=null;function Cn(t){Me.add(t);let e=false;return ()=>{e||(e=true,Me.delete(t));}}async function $n(){let t=[...Me];t.length!==0&&await Promise.allSettled(t.map(async e=>{Me.delete(e),await A.rm(e,{recursive:true,force:true});}));}function Tn(){if(!(Oe.size>0))for(let t of In){let e=()=>{_t||(_t=$n().finally(()=>{for(let[r,n]of Oe)process.off(r,n);Oe.clear(),process.exit(1);}));};Oe.set(t,e),process.on(t,e);}}Tn();function jn(t,e){let r=String(process.env.STATIC_PUBLISHER_CRAWL_MANIFEST_PATH||"").trim();if(r)return v.resolve(r);let n=e.trim();return n?v.join(v.resolve(n),"crawl-manifest.json"):v.join(v.resolve(t),".crawl-manifest.json")}function ie(t){return v.normalize(t).split(v.sep).join("/")}function Nt(t,e){let r=v.relative(v.resolve(t),v.resolve(e));return !r||r.startsWith("..")||v.isAbsolute(r)?null:ie(r)}async function On(t,e,r){let n=jn(t.outputDir,e),o;try{o=await A.readFile(n,"utf8");}catch(c){return c.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:c instanceof Error?c.message:String(c),source:"deploy-guard"}),null)}let s;try{s=JSON.parse(o);}catch(c){return r.warn("Deploy rewrite guard disabled because the crawl manifest is invalid JSON.",{manifestPath:n,error:c instanceof Error?c.message:String(c),source:"deploy-guard"}),null}let a=new Map,i=new Map,l=0,u=0;for(let[c,p]of Object.entries(s.pages||{})){let d=String(p?.outputPath||"").trim(),m=d?Nt(t.outputDir,d):null;if(m){let R=typeof p?.contentType=="string"&&p.contentType?p.contentType:null;R&&i.set(m,R);}!d||p?.rewriteComplete===true||m&&(l++,a.has(m)||a.set(m,{kind:"page",sourceUrl:c,outputPath:v.resolve(d),relativePath:m}));}for(let[c,p]of Object.entries(s.assets||{})){let d=String(p?.outputPath||"").trim(),m=p?.isText===true,R=d?Nt(t.outputDir,d):null;if(R){let w=typeof p?.contentType=="string"&&p.contentType?p.contentType:null;w&&i.set(R,w);}!d||!m||p?.rewriteComplete===true||R&&(u++,a.has(R)||a.set(R,{kind:"asset",sourceUrl:c,outputPath:v.resolve(d),relativePath:R}));}return {manifestPath:n,byRelativePath:a,contentTypeByRelativePath:i,pendingPages:l,pendingTextAssets:u}}function An(t){return t&&(Ye.test(t)?"__uuid__":/^[0-9a-f]{6,}$/i.test(t)?"__hex__":/^[0-9]{8,}$/.test(t)?"__num__":/^(?=.*[a-z])(?=.*\d)[a-z0-9]{8,}$/i.test(t)?"__alnum__":t)}function Je(t){return t.split(/([_:.\-/=?&#]+)/g).map((e,r)=>r%2===1?e:An(e)).join("")}function Mn(t){return t.split(/([_:.\-/=?&#]+)/g).map((e,r)=>r%2===1?e:Ye.test(e)?"__uuid__":/^[0-9a-f]{6,}$/i.test(e)?"__hex__":/^[0-9]{6,}$/.test(e)?"__num__":/^[a-z0-9_-]{6,}$/i.test(e)?"__id__":e).join("")}function De(t,e){return Array.isArray(t)?t.map(r=>De(r,e)):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).map(([r,n])=>[r,De(n,r)])):typeof t!="string"?t:e&&En.test(e)?Mn(t):Ye.test(t)?"__uuid__":/^[0-9a-f]{6,}$/i.test(t)||/^[0-9]{8,}$/.test(t)?Je(t):t}function Dn(t){return t.replace(/((?:https?:\/\/[^"'\s>]+|\/)(?:wp-content|wp-includes)\/[^"'\s>?]+)\?ver=[A-Za-z0-9._-]+(?=$|[#"'])/gi,"$1")}function Ln(t,e){let r=e.trim();if((r.startsWith("{")||r.startsWith("[")||r.startsWith('"'))&&t.startsWith("data-"))try{let o=JSON.parse(r);return JSON.stringify(De(o))}catch{}if(t.startsWith("data-")&&/^[A-Za-z0-9+/=]+$/.test(r))try{let o=Buffer.from(r,"base64").toString("utf8"),s=JSON.parse(o),a=JSON.stringify(De(s));return Buffer.from(a,"utf8").toString("base64")}catch{}return e}function Wn(t,e){let r=t.toLowerCase();return r==="class"?e.split(/(\s+)/).map((n,o)=>o%2===1?n:Je(n)).join(""):r==="id"||r==="for"||r==="aria-controls"||r==="aria-labelledby"||r==="aria-describedby"||r==="aria-owns"||r==="aria-activedescendant"||r==="name"?Je(e):r==="href"||r==="src"?Dn(e):Ln(r,e)}function Fn(t){return t.replace(/<([a-z][^\s/>]*)([^<>]*?)>/gi,(e,r,n)=>{if(r.startsWith("/"))return e;let o=n.replace(/\s([:@a-zA-Z_][-:.a-zA-Z0-9_]*?)=(['"])([\s\S]*?)\2/g,(s,a,i,l)=>{let u=Wn(a,l);return ` ${a}=${i}${u}${i}`});return `<${r}${o}>`})}function Re(t){let e=v.extname(t).toLowerCase();return [".html",".htm",".xml",".xsl",".txt"].includes(e)||["robots.txt","sitemap.xml"].includes(v.basename(t))}function Ae(t,e){return [t.replace(/^\/+|\/+$/g,""),e.replace(/^\/+/,"")].filter(Boolean).join("/")}async function _n(t,e,r,n){let o=new Map,s,a=0;do{a++;let i=await Y(`S3 list objects page ${a} for s3://${e}/${r||""}`,3e5,({httpOptions:l})=>t.send(new ListObjectsV2Command({Bucket:e,Prefix:r||void 0,ContinuationToken:s}),l));for(let l of i.Contents||[]){if(!l.Key)continue;let u=(l.ETag||"").replace(/^"|"$/g,"").toLowerCase(),c=Number(l.Size??0);o.set(l.Key,{etag:u,size:c,cacheControl:void 0});}s=i.NextContinuationToken,n.debug(`Listed S3 keys page ${a}: ${o.size} keys so far`);}while(s);return o}async function Nn(t,e,r,n){if(n.has(r))return n.get(r)??null;try{let o=await Y(`S3 head object ${r}`,3e5,({httpOptions:a})=>t.send(new HeadObjectCommand({Bucket:e,Key:r}),a)),s={etag:(o.ETag||"").replace(/^"|"$/g,"").toLowerCase(),size:Number(o.ContentLength??0),cacheControl:o.CacheControl?.trim()||null};return n.set(r,s),s}catch{return n.set(r,null),null}}async function Kn(t,e,r,n){if(n.cacheControl!==void 0)return n.cacheControl;try{let o=await Y(`S3 head cache metadata ${r}`,3e5,({httpOptions:s})=>t.send(new HeadObjectCommand({Bucket:e,Key:r}),s));n.cacheControl=o.CacheControl?.trim()||null;}catch{n.cacheControl=null;}return n.cacheControl}function Kt(t){return String(t||"").split(",").map(e=>e.trim().toLowerCase()).filter(Boolean).sort().join(",")}async function Un(t,e,r,n){let o=[...new Set(Array.from(r).filter(Boolean))];if(o.length===0)return n.info("No explicitly tombstoned S3 objects to delete."),[];n.info(`Deleting ${o.length} explicitly tombstoned S3 object(s)\u2026`);for(let s=0;s<o.length;s+=1e3){let a=o.slice(s,s+1e3);if(a.length===0)continue;let i=await Y(`S3 delete objects batch ${Math.floor(s/1e3)+1}`,3e5,({httpOptions:l})=>t.send(new DeleteObjectsCommand({Bucket:e,Delete:{Objects:a.map(u=>({Key:u}))}}),l));if(i.Errors&&i.Errors.length>0){let l=i.Errors.map(u=>`${u.Key||"(unknown)"}: ${u.Code||"DeleteFailed"}`);throw new Error(`S3 reported ${l.length} object deletion error(s): ${l.join(", ")}`)}n.info(`Deleted batch of ${a.length} object(s).`);for(let l of a)n.debug(` deleted: ${l}`);}return o}function Vn(t){return createHash("md5").update(t).digest("hex")}function ae(t){return createHash("sha256").update(t).digest("hex")}function Le(t){return createHash("sha256").update(Fn(t.toString("utf8"))).digest("hex")}async function zn(t,e,r,n){if(n.has(r))return n.get(r)??null;try{let a=((await Y(`S3 head object metadata ${r}`,3e5,({httpOptions:i})=>t.send(new HeadObjectCommand({Bucket:e,Key:r}),i))).Metadata?.[Vt]||"").trim().toLowerCase()||null;return n.set(r,a),a}catch{return n.set(r,null),null}}async function Bn(t,e,r,n,o){if(n.has(r))return n.get(r)??null;try{let a=((await Y(`S3 head object normalized metadata ${r}`,3e5,({httpOptions:i})=>t.send(new HeadObjectCommand({Bucket:e,Key:r}),i))).Metadata?.[zt]||"").trim().toLowerCase();if(a)return n.set(r,a),a}catch{return n.set(r,null),null}if(o.has(r)){let s=o.get(r)??null;return n.set(r,s),s}try{let a=await(await Y(`S3 get object ${r}`,3e5,({httpOptions:l})=>t.send(new GetObjectCommand({Bucket:e,Key:r}),l))).Body?.transformToByteArray(),i=a?Le(Buffer.from(a)):null;return o.set(r,i),n.set(r,i),i}catch{return o.set(r,null),n.set(r,null),null}}function qn(t){return t.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"profile"}function Hn(t,e){let r=t,n=Object.entries(e).sort((o,s)=>s[0].length-o[0].length);for(let[o,s]of n)o&&(r=r.split(o).join(s));return r}async function Jn(t,e,r,n){let o=v.join(t,"asset-map.json"),s;try{s=await A.readFile(o,"utf8");}catch(l){if(l.code==="ENOENT")return;throw l}let a=JSON.parse(s);if(!a||typeof a!="object")return;let i=Object.fromEntries(Object.entries(a).map(([l,u])=>{let c=String(u??"");return e.urlRewriteMode==="absolute"&&e.targetOrigin&&r.targetOrigin&&e.targetOrigin!==r.targetOrigin&&(c=c.split(e.targetOrigin).join(r.targetOrigin)),c=Hn(c,n),[l,c]}));await A.writeFile(o,JSON.stringify(i,null,2),"utf8");}async function Gn(t,e,r,n,o,s,a){let i=t.targetOrigin!==e.targetOrigin,l=Object.keys(n).length>0;if(!r||!i&&!l)return {outputDir:t.outputDir,cleanup:async()=>{}};if(i&&t.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=v.join(v.dirname(t.outputDir),`.deploy-profile-${qn(r)}-${Date.now()}`),c=Cn(u);o.info(`Preparing deployment profile "${r}" from existing crawl output to ${u}...`);try{if(await A.rm(u,{recursive:!0,force:!0}),s){await A.mkdir(u,{recursive:!0});for(let w of s){let y=v.join(t.outputDir,w),S=v.join(u,w);await A.mkdir(v.dirname(S),{recursive:!0}),await A.copyFile(y,S);}}else await A.cp(t.outputDir,u,{recursive:!0});let p={...t,sourceOrigin:t.targetOrigin,targetOrigin:e.targetOrigin,extraReplacements:n,outputDir:u},d=1;o.info(`Rewriting text files for deployment profile "${r}"...`);let m={files:s,onStart:({totalFiles:w,workerCount:y})=>{d=y,o.info(`Rewriting ${w} text file(s) for deployment profile "${r}" with ${y} worker(s).`);},onProgress:({index:w,totalFiles:y,changedTextFiles:S,file:k,changed:f})=>{let I=`Rewriting [${w}/${y}] ${k} (${f?"rewrote":"checked"}; ${S} changed so far)`;y<=200||w<=5||w%10===0||w===y?(o.progress(I,{file:k,index:w,totalFiles:y,changed:f,changedTextFiles:S,workerCount:d}),o.info(I)):o.debug(I);}},R=a?await Ot(p,{},{...a,options:m}):await vt(p,{},m);return await Jn(u,t,e,n),o.info(`Prepared deployment profile "${r}" in ${u} (${R} rewritten text file(s)).`),{outputDir:u,cleanup:async()=>{c(),await A.rm(u,{recursive:!0,force:!0});}}}catch(p){throw o.error(`Failed to prepare deployment profile "${r}" temporary output.`,{tempDir:u,outputDir:t.outputDir,error:p instanceof Error?p.message:String(p),...p instanceof Error&&p.stack?{stack:p.stack}:{}}),await A.rm(u,{recursive:true,force:true}).catch(()=>{}),c(),await o.flush().catch(()=>{}),p}}function Bt(t,e){let r=o=>o.replace(/^\/+|\/+$/g,""),n=t.targets.find(o=>o.bucketName===e.s3.bucket&&r(o.prefix)===r(e.s3.prefix)&&o.region===e.s3.region);if(!n)throw new Error(`No CDK Lambda deployment target matches s3://${e.s3.bucket}/${e.s3.prefix||""} in ${e.s3.region}. Redeploy the CDK with this target and reinstall remote-workers.json.`);return n}function Qn(t,e){if(!t||typeof t!="object")throw new Error("Remote deploy result must be a JSON object.");let r=t;if(r.schemaVersion!==K||r.response?.operation!=="deploy-copy"||r.response.jobId!==e.jobId||r.response.taskId!==e.taskId||!r.detail||!Array.isArray(r.detail.objects)||!Array.isArray(r.detail.deletedKeys)||!Array.isArray(r.detail.deleteErrors))throw new Error("Remote deploy result has an invalid envelope.");return r}async function We(t){let e=null;for(let r=1;r<=Math.max(1,Math.min(5,t.maxAttempts));r+=1){let n=J(`deploy-${t.batchIndex}-a${r}-${Date.now()}`,"taskId");try{let o=await t.client.invoke({schemaVersion:K,operation:"deploy-copy",jobId:t.jobId,taskId:n,targetId:t.targetId,items:t.items,...t.deleteRelativeKeys?{deleteRelativeKeys:t.deleteRelativeKeys}:{}}),s=Qn(await t.client.readResult(o),o);if(s.response.status==="partial")throw new Error(`Worker reported ${s.response.failedItems} failed item(s).`);return s}catch(o){e=o;}}throw new Error(`Remote deploy task failed after ${t.maxAttempts} attempt(s): ${e instanceof Error?e.message:String(e)}`,{cause:e})}async function Yn(t){let e=Bt(t.remoteConfig,t.config),r=J(`deploy-${Date.now()}-${ae(Buffer.from(`${e.id}:${t.config.outputDir}`)).slice(0,12)}`,"jobId"),n=be(t.remoteConfig.workspace.prefix,"jobs",r,"deploy-inputs");t.log.progress(`Staging export for Lambda deploy: 0/${t.files.length}`,{phase:"deploy-stage",index:0,totalFiles:t.files.length,uploaded:0,skipped:0,failed:0,mode:"lambda-s3-copy"});let o=0,s=[],a=Math.max(1,Math.min(16,t.concurrency*2)),i=0;await Promise.all(Array.from({length:Math.min(a,t.files.length)},async()=>{for(;;){let k=i;if(k>=t.files.length)return;i+=1;let f=t.files[k],b=await A.readFile(v.join(t.config.outputDir,f)),I=t.contentTypeByRelativePath?.get(f)||Ct.lookup(f)||"application/octet-stream",P=t.revalidateFiles.has(ie(f))?Qe:Re(f)?t.config.s3.htmlCacheControl:t.config.s3.assetCacheControl,C=ae(b),$=Re(f)?Le(b):void 0,E=`${n}/files/${ae(Buffer.from(f))}-${v.basename(f)}`.replace(/\/+/g,"/");await t.client.writeWorkspaceObject({key:E,body:b,contentType:String(I),cacheControl:P,metadata:{"wpsuite-sha256":C,...$?{"wpsuite-normalized-sha256":$}:{}}}),s[k]={sourceKey:E,targetRelativeKey:f,sha256:C,...$?{normalizedSha256:$}:{},bytes:b.byteLength,contentType:String(I),cacheControl:P},o+=1,(o===t.files.length||o<=5||o%25===0)&&t.log.progress(`Staging export for Lambda deploy: ${o}/${t.files.length}`,{phase:"deploy-stage",index:o,totalFiles:t.files.length,staged:o,mode:"lambda-s3-copy"});}}));let l=[],u=Math.max(1,Math.min(500,t.batchSize));for(let k=0;k<s.length;k+=u)l.push(s.slice(k,k+u));let c=[],p=[],d=[],m=0,R=0,w=0,y=Math.max(1,Math.min(Math.max(1,t.concurrency),l.length));if(t.log.progress(`Lambda deploy: 0/${t.files.length}`,{phase:"deploy-copy",index:0,totalFiles:t.files.length,uploaded:0,skipped:0,failed:0,mode:"lambda-s3-copy",workerCount:y,completedBatches:0,totalBatches:l.length}),await Promise.all(Array.from({length:y},async()=>{for(;;){let k=w;if(k>=l.length)return;w+=1;let f=Date.now(),b=await We({client:t.client,jobId:r,targetId:e.id,batchIndex:k+1,items:l[k],maxAttempts:t.maxAttempts}),I=0,P=0,C=0;for(let E of b.detail.objects)m+=1,E.status==="copied"?(c.push(E.targetKey),I+=1):E.status==="skipped"?(p.push(E.targetKey),P+=1):(d.push(E.targetKey),C+=1),t.log.debug(`Lambda deploy ${E.status}: ${E.targetKey}`,{phase:"deploy-copy",batch:k+1,sourceKey:E.sourceKey,targetKey:E.targetKey,status:E.status,...E.error?{error:E.error}:{}});R+=1;let $=Date.now()-f;t.log.info(`Lambda deploy batch ${k+1}/${l.length} completed: ${I} copied, ${P} skipped unchanged, ${C} failed.`,{phase:"deploy-copy",batch:k+1,totalBatches:l.length,items:b.detail.objects.length,copied:I,skipped:P,failed:C,elapsedMs:$,elapsedSeconds:Math.round($/10)/100,workerExporterVersion:b.response.exporterVersion,...b.requestId?{lambdaRequestId:b.requestId}:{},...b.completedAt?{workerCompletedAt:b.completedAt}:{}}),t.log.progress(`Lambda deploy: ${m}/${t.files.length}`,{phase:"deploy-copy",index:m,totalFiles:t.files.length,uploaded:c.length,skipped:p.length,failed:d.length,mode:"lambda-s3-copy",workerCount:y,completedBatches:R,totalBatches:l.length});}})),d.length>0)throw new Error(`Remote deployment failed for ${d.length} object(s).`);let S=[];for(let k=0;k<t.deletedFiles.length;k+=1e3){let f=t.deletedFiles.slice(k,k+1e3);if(f.length===0)continue;let b=await We({client:t.client,jobId:r,targetId:e.id,batchIndex:l.length+Math.floor(k/1e3)+1,items:[],deleteRelativeKeys:f,maxAttempts:t.maxAttempts});S.push(...b.detail.deletedKeys),t.log.progress(`Lambda deploy deletions: ${S.length}/${t.deletedFiles.length}`,{phase:"deploy-delete",index:S.length,totalFiles:t.deletedFiles.length,deleted:S.length,mode:"lambda-s3-copy"});}return {uploadedKeys:c,skippedKeys:p,failedKeys:d,deletedKeys:S}}async function Zn(t){let e=Bt(t.remoteConfig,t.config),r=J(`deploy-manifest-${Date.now()}-${ae(Buffer.from(e.id)).slice(0,12)}`,"jobId"),n=t.objects.map(m=>({sourceKey:m.object.key,targetRelativeKey:m.relativePath,sha256:m.object.sha256,bytes:m.object.bytes,contentType:m.contentType||"application/octet-stream",cacheControl:t.revalidateFiles.has(ie(m.relativePath))?Qe:Re(m.relativePath)?t.config.s3.htmlCacheControl:t.config.s3.assetCacheControl})),o=[],s=Math.max(1,Math.min(500,t.batchSize));for(let m=0;m<n.length;m+=s)o.push(n.slice(m,m+s));let a=[],i=[],l=[],u=0,c=0,p=Math.max(1,Math.min(Math.max(1,t.concurrency),Math.max(1,o.length)));if(t.log.progress(`Lambda deploy: 0/${n.length}`,{phase:"deploy-copy",index:0,totalFiles:n.length,mode:"lambda-s3-native",workerCount:p}),await Promise.all(Array.from({length:o.length===0?0:p},async()=>{for(;;){let m=u;if(m>=o.length)return;u+=1;let R=await We({client:t.client,jobId:r,targetId:e.id,batchIndex:m+1,items:o[m],maxAttempts:t.maxAttempts});for(let w of R.detail.objects)c+=1,w.status==="copied"?a.push(w.targetKey):w.status==="skipped"?i.push(w.targetKey):l.push(w.targetKey);t.log.progress(`Lambda deploy: ${c}/${n.length}`,{phase:"deploy-copy",index:c,totalFiles:n.length,uploaded:a.length,skipped:i.length,failed:l.length,mode:"lambda-s3-native",workerCount:p});}})),l.length>0)throw new Error(`Remote deployment failed for ${l.length} object(s).`);let d=[];for(let m=0;m<t.deletedFiles.length;m+=1e3){let R=t.deletedFiles.slice(m,m+1e3);if(R.length===0)continue;let w=await We({client:t.client,jobId:r,targetId:e.id,batchIndex:o.length+Math.floor(m/1e3)+1,items:[],deleteRelativeKeys:R,maxAttempts:t.maxAttempts});d.push(...w.detail.deletedKeys);}return {uploadedKeys:a,skippedKeys:i,failedKeys:l,deletedKeys:d}}async function Xn(t,e,r,n,o){let s={...e,jobId:J(`profile-${ae(Buffer.from(n)).slice(0,16)}-${Date.now()}`,"jobId"),objects:{},assetMap:{...e.assetMap},generatedAt:new Date().toISOString()},a=0,i=Math.max(1,Math.min(Math.max(1,o),Math.max(1,r.length)));return await Promise.all(Array.from({length:r.length===0?0:i},async()=>{for(;;){let l=a;if(l>=r.length)return;a+=1;let u=r[l],c=be(t.config.workspace.prefix,"jobs",s.jobId,"profile",ae(Buffer.from(u.relativePath)),v.basename(u.relativePath));s.objects[u.relativePath]={...u,object:await t.copyWorkspaceObject(u.object,c)};}})),s}async function qt(t=process.argv.slice(2)){let e=await ve(),r=pt(t),n=dt(e,r),o=v.resolve(n.config.logDir||"logs"),s=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",a=s?v.join(v.resolve(s),"deploy-diff.json"):"",i=new ye(o,"deploy.log.jsonl",n.config.logLevel??"info"),l=n.profile?.extraReplacements??{},u=async()=>{};try{let c=await ct(e);if(t.includes("--content-sync")&&c?.schemaVersion!==2)throw new Error("Content-sync deployment requires a valid schema-2 targeted deploy plan.");let d=await ut(e);if(d)throw new Error(`Deployment blocked: the crawl started at ${d.startedAt} did not complete its final rewrite. Run a successful crawl or resume the rewrite before deploying.`);let m=e.remoteWorkers?.rewrite?.enabled===!0,R=e.remoteWorkers?.deploy?.enabled===!0,w=null,y=null;if(m||R){let h=Wt({runtimeDir:s});if(!h)throw new Error("Remote Lambda workers are enabled, but the runtime directory is unknown.");w=await Lt(h);let j=!1;y=new je(w,{},{onProgress:g=>{i.progress(`Lambda ${g.operation} batch: ${g.completedItems+g.failedItems}/${g.totalItems}`,{remoteWorkerOperation:g.operation,remoteWorkerTaskId:g.taskId,remoteWorkerStatus:g.status,remoteWorkerCompletedItems:g.completedItems,remoteWorkerFailedItems:g.failedItems,remoteWorkerTotalItems:g.totalItems,remoteWorkerUpdatedAt:g.updatedAt});},onProgressError:g=>{j||(j=!0,i.warn("Lambda progress status could not be read; task execution continues.",{error:g.message}));}});}let S=R&&m&&e.remoteWorkers?.render?.enabled===!0&&y&&w?.functions.asset?await Ft(e):null;if(S&&y&&w){if(S.workspace.bucket!==w.workspace.bucket||S.workspace.prefix!==w.workspace.prefix)throw new Error("Remote export manifest workspace does not match remote-workers.json.");let h=n.config,j=h.s3SyncMode??"sdk-upload-delete";if(c?.schemaVersion===2&&c.deletedFiles.length>0&&j!=="sdk-upload-delete")throw new Error("Content-sync tombstones require the sdk-upload-delete S3 sync mode.");let g=c?.schemaVersion===2?[...c.uploadGroups.assets,...c.uploadGroups.content,...c.uploadGroups.listings,...c.uploadGroups.resources,...c.uploadGroups.sitemapLeaves,...c.uploadGroups.sitemapIndexes]:c?.changedFiles??[];if(c?.schemaVersion===2){let _=[...new Set(g)],Q=[...new Set(c.changedFiles)];if(_.length!==Q.length||Q.some(ue=>!_.includes(ue)))throw new Error("Content-sync deploy-plan upload groups do not cover the exact changed-file set.")}let G=!!c&&!c.fullSyncRequired?[...new Set(g.map(ie))]:Object.keys(S.objects).sort(),fe=G.filter(_=>!S.objects[_]);if(fe.length>0)throw new Error(`Remote export manifest is missing ${fe.length} planned object(s): ${fe.slice(0,10).join(", ")}`);let te=S,T=G.map(_=>S.objects[_]);n.name&&(e.targetOrigin!==h.targetOrigin||Object.keys(l).length>0)&&(te=await Xn(y,S,T,n.name||"default",e.concurrency),await At(h,te,te.assetMap,{client:y,jobId:te.jobId,concurrency:e.concurrency,batchSize:25,maxAttempts:2}),T=G.map(_=>te.objects[_])),n.name&&i.info(`Using deployment profile: ${n.name}`),i.info(`Starting S3-native Lambda deploy - s3://${h.s3.bucket}/${h.s3.prefix||""} (${h.s3.region}).`),i.mark("deploy");let L=await Zn({client:y,remoteConfig:w,config:h,objects:T,deletedFiles:j==="sdk-upload-delete"?c?.deletedFiles??[]:[],revalidateFiles:new Set((c?.revalidateFiles??[]).map(ie)),concurrency:e.concurrency,batchSize:50,maxAttempts:2,log:i});a&&(await A.mkdir(v.dirname(a),{recursive:!0}),await A.writeFile(a,JSON.stringify({generatedAt:new Date().toISOString(),mode:"lambda-s3-native",summary:{totalFiles:T.length,eligibleFiles:T.length,uploaded:L.uploadedKeys.length,skipped:L.skippedKeys.length,rejected:0,failed:L.failedKeys.length,deleted:L.deletedKeys.length,protected:0,...n.name?{profile:n.name}:{}},uploadedKeys:L.uploadedKeys,skippedKeys:L.skippedKeys,rejectedKeys:[],failedKeys:L.failedKeys,deletedKeys:L.deletedKeys,protectedRemoteOnlyKeys:[]},null,2),"utf8")),c?.schemaVersion!==2&&await Ee(e),i.endMark("deploy"),await i.flush();return}let k=await Gn(e,n.config,n.name,l,i,c?.schemaVersion===2?c.changedFiles:void 0,m&&y?{client:y,jobId:`profile-${Date.now()}`,concurrency:e.remoteWorkers?.rewrite?.concurrency??e.rewriteConcurrency,batchSize:e.remoteWorkers?.rewrite?.batchSize??25,maxAttempts:e.remoteWorkers?.rewrite?.maxAttempts??2,onStageProgress:({index:h,totalFiles:j,file:g})=>{(h===1||h===j||h%25===0)&&i.progress(`Staging deployment-profile rewrite: ${h}/${j}`,{phase:"rewrite-stage",index:h,totalFiles:j,file:g,execution:"lambda"});}}:void 0);u=k.cleanup;let f={...n.config,outputDir:k.outputDir},b=f.s3SyncMode??"sdk-upload-delete";if(c?.schemaVersion===2&&c.deletedFiles.length>0&&b!=="sdk-upload-delete")throw new Error("Content-sync tombstones require the sdk-upload-delete S3 sync mode.");let I=c?.schemaVersion!==2&&k.outputDir!==e.outputDir&&(e.targetOrigin!==n.config.targetOrigin||Object.keys(l).length>0),P=!!c&&!c.fullSyncRequired&&!I;if(c?.schemaVersion===2&&!P)throw new Error("Content-sync deployment cannot widen into a full-output deployment.");n.name&&i.info(`Using deployment profile: ${n.name}`),i.info(`Starting deploy \u2014 s3://${f.s3.bucket}/${f.s3.prefix||""} (region: ${f.s3.region})`),i.info(`S3 sync mode: ${b}`),c&&c.fullSyncRequired?i.info("Deploy plan requests a full sync; scanning the whole output tree."):c&&I?i.info("Ignoring incremental deploy plan because deployment-profile rewrites require a full sync."):P&&i.info(`Using incremental deploy plan: ${c.changedFiles.length} changed file(s), ${c.deletedFiles.length} deleted file(s).`),i.mark("deploy");let C=new S3Client({region:f.s3.region}),$=k.outputDir===e.outputDir?await On(e,s,i):null,E=c?.schemaVersion===2?[...c.uploadGroups.assets,...c.uploadGroups.content,...c.uploadGroups.listings,...c.uploadGroups.resources,...c.uploadGroups.sitemapLeaves,...c.uploadGroups.sitemapIndexes]:c?.changedFiles??[];if(c?.schemaVersion===2){let h=[...new Set(E)],j=[...new Set(c.changedFiles)];if(h.length!==j.length||j.some(g=>!h.includes(g)))throw new Error("Content-sync deploy-plan upload groups do not cover the exact changed-file set.")}let D=P?(await Promise.all(E.map(async h=>{try{return (await A.stat(v.join(f.outputDir,h))).isFile()?h:null}catch{if(c?.schemaVersion===2)throw new Error(`Content-sync planned upload is missing: ${h}`);return null}}))).filter(h=>h!==null):await Mr(["**/*"],{cwd:f.outputDir,onlyFiles:!0,dot:!0}),U=[],O=[],x=D.filter(h=>{let j=$?.byRelativePath.get(ie(h));if(!j)return !0;let g=Ae(f.s3.prefix,h);return U.push(h),O.push(g),i.reject(j.kind,j.sourceUrl||h,"rewrite not completed; deploy upload blocked","deploy-guard",{file:h,key:g,outputPath:j.outputPath,manifestPath:$?.manifestPath}),!1}),Ze=new Set((c?.revalidateFiles||[]).map(ie)),Xe=new Set((P?x:D).map(h=>Ae(f.s3.prefix,h)));$&&($.pendingPages>0||$.pendingTextAssets>0)&&i.info(`Deploy rewrite guard loaded ${$.pendingPages} pending page(s) and ${$.pendingTextAssets} pending text asset(s) from crawl manifest.`,{manifestPath:$.manifestPath,pendingPages:$.pendingPages,pendingTextAssets:$.pendingTextAssets,source:"deploy-guard"}),U.length>0&&i.warn(`Deploy rewrite guard blocked ${U.length} file(s) from upload because final crawl rewrite is incomplete.`,{rejected:U.length,manifestPath:$?.manifestPath,source:"deploy-guard"}),P?i.info(`Using ${x.length} eligible planned changed file(s) from deploy plan for upload${U.length>0?` (${U.length} blocked by deploy rewrite guard)`:""}.`):i.info(`Found ${D.length} file(s) in output directory "${f.outputDir}"${U.length>0?`; ${x.length} remain eligible for upload after deploy rewrite guard filtering`:""}.`),i.progress("Deploy preflight: comparing local output with remote S3 state.",{phase:"deploy",mode:b,totalFiles:x.length,scannedFiles:D.length,rejected:U.length,deploymentProfile:n.name||"",s3Bucket:f.s3.bucket,s3Prefix:f.s3.prefix||"",targetedPlan:P,deployGuardEnabled:k.outputDir===e.outputDir});let F=0,M=0,B=0,ge=[],X=[],ee=[],le=[],ce=[],me=new Map,Ht=new Map,Jt=new Map,Gt=new Map,Qt=new Map;if(R){if(!y||!w)throw new Error("Remote deploy worker client was not initialized.");if(b!=="sdk-upload-delete"&&b!=="sdk-upload-only")throw new Error(`Unsupported remote deploy mode: ${b}`);let h=await Yn({client:y,remoteConfig:w,config:f,files:x,deletedFiles:b==="sdk-upload-delete"?c?.deletedFiles??[]:[],revalidateFiles:Ze,contentTypeByRelativePath:$?.contentTypeByRelativePath,concurrency:f.remoteWorkers?.deploy?.concurrency??f.assetDownloadConcurrency,batchSize:f.remoteWorkers?.deploy?.batchSize??50,maxAttempts:f.remoteWorkers?.deploy?.maxAttempts??2,log:i});ge.push(...h.uploadedKeys),X.push(...h.skippedKeys),ee.push(...h.failedKeys),le=h.deletedKeys,F=ge.length,M=X.length,B=ee.length,i.info(`Lambda deploy complete: ${F} copied, ${M} skipped unchanged, ${le.length} deleted, ${B} failed.`),a&&(await A.mkdir(v.dirname(a),{recursive:!0}),await A.writeFile(a,JSON.stringify({generatedAt:new Date().toISOString(),mode:"lambda-s3-copy",summary:{totalFiles:D.length,eligibleFiles:x.length,uploaded:F,skipped:M,rejected:O.length,failed:B,deleted:le.length,protected:0,...n.name?{profile:n.name}:{}},uploadedKeys:ge,skippedKeys:X,rejectedKeys:O,failedKeys:ee,deletedKeys:le,protectedRemoteOnlyKeys:[]},null,2),"utf8")),c?.schemaVersion!==2&&await Ee(e),i.endMark("deploy"),await i.flush();return}P||(i.info("Listing existing S3 objects to detect unchanged files..."),me=await _n(C,f.s3.bucket,f.s3.prefix,i),i.info(`Found ${me.size} existing key(s) in S3.`));let Yt=async h=>me.has(h)?me.get(h)??null:P?Nn(C,f.s3.bucket,h,Ht):null;for(let h of x){let j=v.join(f.outputDir,h),g=Ae(f.s3.prefix,h),V=$?.contentTypeByRelativePath.get(h),G=V&&V!=="application/octet-stream"?V:Ct.lookup(h)||V||"application/octet-stream",fe=Ze.has(ie(h)),te=fe?Qe:Re(h)?f.s3.htmlCacheControl:f.s3.assetCacheControl,T=F+M+B+1;x.length<=200||T<=5||T%10===0||T===x.length?(i.progress(`Uploading [${T}/${x.length}] ${g} (${G})`,{file:h,key:g,index:T,totalFiles:x.length,contentType:G,mode:b}),i.info(`Uploading [${T}/${x.length}] ${g} (${G})`)):i.debug(`Uploading [${T}/${x.length}] ${g} (${G})`);try{let z=await A.readFile(j),L=await Yt(g),_=null,Q=null;if(L){let ue=!fe||Kt(await Kn(C,f.s3.bucket,g,L))===Kt(te),Zt=z.byteLength;if(L.size===Zt){let xe=L.etag.includes("-");if(L.etag!==""&&!xe){let Xt=Vn(z);if(L.etag===Xt&&ue){M++,x.length<=200||M<=5||M%25===0?(i.progress(`Skipped unchanged [${T}/${x.length}] ${g}`,{file:h,key:g,index:T,totalFiles:x.length,uploaded:F,skipped:M,failed:B,mode:b,reason:"etag-md5-match"}),i.info(`Skipped unchanged [${T}/${x.length}] ${g}`)):i.debug(`Skipped unchanged [${T}/${x.length}] ${g}`),X.push(g);continue}}_=ae(z);let et=await zn(C,f.s3.bucket,g,Jt);if(et&&et===_&&ue){M++,x.length<=200||M<=5||M%25===0?(i.progress(`Skipped unchanged [${T}/${x.length}] ${g}`,{file:h,key:g,index:T,totalFiles:x.length,uploaded:F,skipped:M,failed:B,mode:b,reason:"metadata-sha256-match"}),i.info(`Skipped unchanged [${T}/${x.length}] ${g}`)):i.debug(`Skipped unchanged [${T}/${x.length}] ${g}`),X.push(g);continue}}if(Re(h)){Q=Le(z);let xe=await Bn(C,f.s3.bucket,g,Gt,Qt);if(xe&&xe===Q&&ue){M++,x.length<=200||M<=5||M%25===0?(i.progress(`Skipped semantically unchanged [${T}/${x.length}] ${g}`,{file:h,key:g,index:T,totalFiles:x.length,uploaded:F,skipped:M,failed:B,mode:b,reason:"normalized-html-match"}),i.info(`Skipped semantically unchanged [${T}/${x.length}] ${g}`)):i.debug(`Skipped semantically unchanged [${T}/${x.length}] ${g}`),X.push(g);continue}}}_=_??ae(z),Q=Q??(Re(h)?Le(z):null),await Y(`S3 upload ${g}`,9e5,({abortController:ue})=>new Upload({client:C,abortController:ue,params:{Bucket:f.s3.bucket,Key:g,Body:z,ContentType:G,CacheControl:te,Metadata:{[Vt]:_,...Q?{[zt]:Q}:{}}}}).done()),F++,ge.push(g),(F%25===0||F===x.length)&&(i.progress(`Uploaded ${F}/${x.length} file(s)\u2026`,{uploaded:F,skipped:M,failed:B,totalFiles:x.length,mode:b}),i.info(`Uploaded ${F}/${x.length} file(s)\u2026`));}catch(z){B++,ee.push(g),i.error(`Failed to upload ${g}: ${z.message}`,{key:g,error:String(z)});}}if(i.info(`Upload complete: ${F} uploaded, ${M} skipped unchanged, ${O.length} rejected by guard, ${B} failed.`),ee.length>0||O.length>0)throw new Error(`Deployment stopped before deletion because ${ee.length} upload(s) failed and ${O.length} upload(s) were rejected.`);if(b==="sdk-upload-delete"){let h=new Set((c?.deletedFiles??[]).map(g=>Ae(f.s3.prefix,g))),j=[...h].filter(g=>!Xe.has(g));if(!P&&(ce=[...me.keys()].filter(V=>!Xe.has(V)).filter(V=>!h.has(V)),ce.length>0)){i.warn(`Protected ${ce.length} remote-only S3 object(s) from deletion because the crawl did not provide explicit tombstones.`,{protected:ce.length,source:"deploy-delete-guard"});for(let V of ce)i.debug(` protected remote-only object: ${V}`);}le=await Un(C,f.s3.bucket,P?j:j.filter(g=>me.has(g)),i);}else i.info("Sync mode is sdk-upload-only \u2014 skipping stale object deletion.");a&&(await A.mkdir(v.dirname(a),{recursive:!0}),await A.writeFile(a,JSON.stringify({generatedAt:new Date().toISOString(),mode:b,summary:{totalFiles:D.length,eligibleFiles:x.length,uploaded:ge.length,skipped:X.length,rejected:O.length,failed:ee.length,deleted:le.length,protected:ce.length,...n.name?{profile:n.name}:{}},uploadedKeys:ge,skippedKeys:X,rejectedKeys:O,failedKeys:ee,deletedKeys:le,protectedRemoteOnlyKeys:ce},null,2),"utf8")),c?.schemaVersion!==2&&await Ee(e),i.endMark("deploy"),await i.flush();}finally{await u().catch(()=>{});}}qt().catch(async t=>{console.error(t);try{let r=(await ve().catch(()=>null))?.logDir??"logs",n=new ye(r,"deploy.log.jsonl","debug");n.error(`Unhandled error: ${t instanceof Error?t.message:String(t)}`,t instanceof Error?{stack:t.stack}:void 0),await n.flush();}catch{}process.exit(1);});
|
package/dist/invalidate.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import w from'fs/promises';import te from'http';import re from'https';import b from'path';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';import {createHash}from'crypto';var N=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function j(r){let e=r.trim();return e==="."?".":e.replace(/\/$/,"")}function ne(r){let e=String(r??"").trim();if(!e)return "";let t=e;if(/^https?:\/\//i.test(t))try{t=new URL(t).pathname;}catch{return ""}if(t=t.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!t)return "";let i=t.endsWith("/"),n=t.replace(/^\/+/,"").split("/").map(a=>a.replace(/[^A-Za-z0-9._-]/g,"")).filter(a=>a.length>0&&a!=="."&&a!=="..");if(n.length===0)return "";let s=`/${n.join("/")}`;return i&&b.extname(s)===""&&(s+="/"),s==="/"?"":s}function k(r){return !r||typeof r!="object"?{}:Object.fromEntries(Object.entries(r).map(([e,t])=>[e.trim(),String(t??"")]).filter(([e])=>e.length>0))}function ie(r){if(!r||typeof r!="object")return {};let e={};for(let[t,i]of Object.entries(r)){let n=t.trim();if(!n||!i||typeof i!="object")continue;let s=i,a={};if(typeof s.targetOrigin=="string"){let l=j(s.targetOrigin);l&&(a.targetOrigin=l);}let o=k(s.extraReplacements);if(Object.keys(o).length>0&&(a.extraReplacements=o),s.s3&&typeof s.s3=="object"){let l={},u=s.s3;typeof u.bucket=="string"&&(l.bucket=u.bucket.trim()),typeof u.prefix=="string"&&(l.prefix=u.prefix.trim()),typeof u.region=="string"&&(l.region=u.region.trim()),typeof u.htmlCacheControl=="string"&&(l.htmlCacheControl=u.htmlCacheControl.trim()),typeof u.assetCacheControl=="string"&&(l.assetCacheControl=u.assetCacheControl.trim()),Object.keys(l).length>0&&(a.s3=l);}if(s.cloudFront&&typeof s.cloudFront=="object"){let l={},u=s.cloudFront;typeof u.distributionId=="string"&&(l.distributionId=u.distributionId.trim()),Array.isArray(u.invalidationPaths)&&(l.invalidationPaths=u.invalidationPaths.map(c=>String(c??"").trim()).filter(c=>c.length>0)),Object.keys(l).length>0&&(a.cloudFront=l);}e[n]=a;}return e}function x(r){return r==="PROFESSIONAL"||r==="AGENCY"?r:void 0}function se(r,e){if(!r||typeof r!="object")return null;let t=r,i=t.command;if(i!=="publish"&&i!=="crawl"&&i!=="deploy"&&i!=="invalidate"&&i!=="retry-timeouts"&&i!=="url"&&i!=="content-sync")return null;let n=Number.parseInt(String(t.intervalMinutes??"0"),10);if(!Number.isFinite(n)||n<1)return null;let s=String(t.id??`${i}-${e+1}`).trim();if(!s)return null;let a=String(t.deploymentProfile??"").trim(),o=String(t.url??"").trim(),l=Array.isArray(t.postTypes)?[...new Set(t.postTypes.map(c=>String(c??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],u=Array.isArray(t.listingPaths)?[...new Set(t.listingPaths.map(c=>String(c??"").trim()).filter(Boolean))]:[];return i==="content-sync"&&l.length===0?null:{id:s,enabled:t.enabled!==false,command:i,intervalMinutes:n,...i==="publish"||i==="crawl"?{crawlMode:t.crawlMode==="incremental"?"incremental":"full"}:{},...(i==="publish"||i==="deploy"||i==="invalidate"||i==="content-sync")&&a?{deploymentProfile:a}:{},...o?{url:o}:{},...l.length>0?{postTypes:l}:{},...u.length>0?{listingPaths:u}:{},...typeof t.includeSubsites=="boolean"?{includeSubsites:t.includeSubsites}:{},...typeof t.includePostTypeArchives=="boolean"?{includePostTypeArchives:t.includePostTypeArchives}:{},...typeof t.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:t.includeTaxonomyArchives}:{},...typeof t.includeAuthorArchives=="boolean"?{includeAuthorArchives:t.includeAuthorArchives}:{},...typeof t.includeDateArchives=="boolean"?{includeDateArchives:t.includeDateArchives}:{},...typeof t.includePostsPage=="boolean"?{includePostsPage:t.includePostsPage}:{},...typeof t.includeSitemapChain=="boolean"?{includeSitemapChain:t.includeSitemapChain}:{}}}function $(r){let e=r&&typeof r=="object"?r:{},t=Array.isArray(e.rules)?e.rules.map((i,n)=>se(i,n)).filter(i=>!!i):[];return {enabled:e.enabled===true,timezone:typeof e.timezone=="string"&&e.timezone.trim()!==""?e.timezone.trim():"UTC",rules:t}}function oe(r){let e=r&&typeof r=="object"?r:{},t=e.render&&typeof e.render=="object"?e.render:{},i=Number(t.concurrency??0),n=Number(t.maxAttempts??0),s=e.rewrite&&typeof e.rewrite=="object"?e.rewrite:{},a=e.deploy&&typeof e.deploy=="object"?e.deploy:{},o=(l,u)=>({enabled:typeof l.enabled=="boolean"?l.enabled:t.enabled===true,concurrency:Math.min(100,Math.max(1,Number(l.concurrency||u.concurrency))),batchSize:Math.min(500,Math.max(1,Number(l.batchSize||u.batchSize))),maxAttempts:Math.min(5,Math.max(1,Number(l.maxAttempts||2)))});return {render:{enabled:t.enabled===true,...Number.isInteger(i)&&i>0?{concurrency:i}:{},...Number.isInteger(n)&&n>0?{maxAttempts:Math.min(5,n)}:{}},rewrite:o(s,{concurrency:8,batchSize:25}),deploy:o(a,{concurrency:8,batchSize:50})}}function ae(r){if(!r||typeof r!="object")return;let e=r,t={};for(let n of ["accountId","siteId"]){let s=e[n];typeof s=="string"&&s.trim()!==""&&(t[n]=s.trim());}let i=Number(e.lastUpdate??0);return Number.isFinite(i)&&i>0&&(t.lastUpdate=Math.floor(i)),e.subscriber===true&&(t.subscriber=true),Object.keys(t).length>0?t:void 0}function L(r){let e=r&&typeof r=="object"?r:{},t=String(e.accountId??"").trim(),i=String(e.siteId??"").trim(),n=e.subscriber===true,s=ae(e.siteSettings),a={...s??{},...t?{accountId:s?.accountId??t}:{},...i?{siteId:s?.siteId??i}:{},...s?.subscriber===true||n?{subscriber:true}:{}},o={},l=String(e.apiBase??"").trim();l&&(o.apiBase=l);let u=String(e.runtimeToken??e.nonce??"").trim();u&&(o.runtimeToken=u);let c=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();c&&(o.virtualAssetBaseUrl=c),Object.keys(a).length>0&&(o.siteSettings=a);let g=x(e.subscriptionType);return g&&(o.subscriptionType=g),o}function le(r){try{let e=new URL(r);globalThis.location=e;}catch{}}function _(r){return typeof r=="string"?r:r instanceof URL?r.toString():r.url}function ue(r,e){let t=new Headers(r instanceof Request?r.headers:void 0);if(e?.headers)for(let[i,n]of new Headers(e.headers).entries())t.set(i,n);return t}async function W(r,e,t=5){let i=new URL(_(r)),n=String(e?.method??(r instanceof Request?r.method:"GET")).toUpperCase(),s=i.protocol==="http:"?te:re,a=ue(r,e);return await new Promise((o,l)=>{let u=s.request(i,{method:n,headers:Object.fromEntries(a.entries()),...i.protocol==="https:"?{rejectUnauthorized:false}:{}},c=>{let g=[];c.on("data",p=>{g.push(Buffer.isBuffer(p)?p:Buffer.from(p));}),c.on("error",l),c.on("end",()=>{let p=c.statusCode??0,m=c.headers.location;if(t>0&&m&&[301,302,303,307,308].includes(p)){o(W(new URL(m,i),{method:p===303?"GET":n},t-1));return}let d=new Headers;for(let[f,h]of Object.entries(c.headers))Array.isArray(h)?d.set(f,h.join(", ")):typeof h=="string"&&d.set(f,h);o(new Response(Buffer.concat(g),{status:p,statusText:c.statusMessage??"",headers:d}));});});u.on("error",l),u.end();})}function ce(r){let e=L(r.wpsuite),t={...e.siteSettings??{},...e.siteSettings?.subscriber===true||e.subscriptionType==="PROFESSIONAL"||e.subscriptionType==="AGENCY"?{subscriber:true}:{}},i=String(t.accountId??"").trim(),n=String(t.siteId??"").trim(),s=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();if(r.wpsuite={...e.apiBase?{apiBase:e.apiBase}:{},...e.runtimeToken?{runtimeToken:e.runtimeToken}:{},...s?{virtualAssetBaseUrl:s}:{},...Object.keys(t).length>0?{siteSettings:t}:{},...e.subscriptionType?{subscriptionType:e.subscriptionType}:{}},!i||!n||!s)return false;le(r.sourceOrigin);let a=globalThis,l={...a.WpSuite??{},siteSettings:t,uploadUrl:s};return e.apiBase&&(l.apiBase=e.apiBase),a.WpSuite=l,true}async function de(r){let e=String(r.wpsuite?.virtualAssetBaseUrl??r.wpsuite?.uploadUrl??"").trim();if(!ce(r)){let n=r.wpsuite?.siteSettings,s=[String(n?.accountId??"").trim()?"":"accountId",String(n?.siteId??"").trim()?"":"siteId",e?"":"virtualAssetBaseUrl"].filter(Boolean);return {remote:null,diagnostic:{status:"invalid-runtime",virtualAssetBaseUrl:e,subscriptionType:null,error:`Missing WP Suite runtime field(s): ${s.join(", ")}.`,requests:[]}}}let t=globalThis.fetch,i=[];try{typeof t=="function"&&/^https?:\/\//i.test(e)&&(globalThis.fetch=(async(l,u)=>{let c=_(l);if(c.startsWith(e)){let g=(()=>{try{return new URL(c).pathname}catch{return c}})();try{let p=r.ignoreHttpsErrors&&c.startsWith("https://")?await W(l,u):await t(l,u);return i.push({path:g,status:p.status,ok:p.ok,error:null}),p}catch(p){throw i.push({path:g,status:null,ok:!1,error:p instanceof Error?p.message:String(p)}),p}}return t(l,u)}));let{getConfig:n}=await import('@smart-cloud/wpsuite-core'),s=await n("publisher"),a=s&&typeof s=="object"?s:null,o=x(a?.subscriptionType);return {remote:a,diagnostic:{status:a?"loaded":"unavailable",virtualAssetBaseUrl:e,subscriptionType:o??null,error:a?null:"WP Suite publisher config loader returned no configuration.",requests:i}}}catch(n){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:e,subscriptionType:null,error:n instanceof Error?n.message:String(n),requests:i}}}finally{typeof t=="function"&&(globalThis.fetch=t);}}function pe(r,e){let t=ie(e?.deploymentProfiles),i=String(e?.defaultDeploymentProfile??"").trim(),n=t[i]?i:"",s=x(e?.subscriptionType),a=L(r.wpsuite);return {...r,scheduler:$(e?.scheduler),deploymentProfiles:t,defaultDeploymentProfile:n,...s?{subscriptionType:s}:{},wpsuite:{...a,...a.siteSettings||s?{siteSettings:{...a.siteSettings??{},...a.siteSettings?.subscriber===true||s==="PROFESSIONAL"||s==="AGENCY"?{subscriber:true}:{}}}:{},...s?{subscriptionType:s}:{}}}}function E(r,e){let i=String(r||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!i)return e;let n=i.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return n.length>0?n.join("/"):e}function ge(){let r=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return r.trim()?b.resolve(r):""}function U(r,e,t){let i=String(e||"").trim();return i&&b.isAbsolute(i)?b.resolve(i):b.resolve(r,E(i,t))}async function D(r,e={}){let t=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",i=await w.readFile(t,"utf8"),n=JSON.parse(i);n.sourceOrigin=n.sourceOrigin.replace(/\/$/,""),n.targetOrigin=j(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=ne(n.generated404RequestPath),n.sitemapPaths||=[...N],n.allowedAssetHosts||=[],n.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],n.blockedPathPrefixes||=[],n.blockedSearchFragments||=[];let s=Number(n.processingConcurrency)>0?Math.min(100,Math.max(1,Number(n.processingConcurrency))):null;n.concurrency=s??n.concurrency??1,n.maxPages||=0,n.extraReplacements=k(n.extraReplacements),n.postCrawlCopyMap=k(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=s??(Number(n.assetDownloadConcurrency)>0?Number(n.assetDownloadConcurrency):n.concurrency),n.rewriteConcurrency=s??(Number(n.rewriteConcurrency)>0?Number(n.rewriteConcurrency):n.assetDownloadConcurrency),n.wpsuite=L(n.wpsuite),n.scheduler=$(void 0),n.remoteWorkers=oe(n.remoteWorkers),typeof n.lambdaDelegationEnabled=="boolean"&&(n.remoteWorkers.render??={},n.remoteWorkers.rewrite??={},n.remoteWorkers.deploy??={},n.remoteWorkers.render.enabled=n.lambdaDelegationEnabled,n.remoteWorkers.rewrite.enabled=n.lambdaDelegationEnabled,n.remoteWorkers.deploy.enabled=n.lambdaDelegationEnabled),s!==null&&(n.processingConcurrency=s,n.remoteWorkers.render??={},n.remoteWorkers.rewrite??={},n.remoteWorkers.deploy??={},n.remoteWorkers.render.concurrency=s,n.remoteWorkers.rewrite.concurrency=s,n.remoteWorkers.deploy.concurrency=s),n.deploymentProfiles={},n.defaultDeploymentProfile="",n.deploymentTargetOverride=String(n.deploymentTargetOverride??"").trim();let a=await de(n);e.onRemotePublisherConfigDiagnostic?.(a.diagnostic);let o=pe(n,a.remote),l=ge(),u=l?b.resolve(l,".."):"";return u?(o.outputDir=U(u,o.outputDir,"export"),o.logDir=U(u,o.logDir,"logs")):(b.isAbsolute(o.outputDir)||(o.outputDir=E(o.outputDir,"export")),b.isAbsolute(o.logDir)||(o.logDir=E(o.logDir,"logs"))),o}function me(r){let e=r/6e4;if(Number.isInteger(e)&&e>=1)return `${e} minute${"s"}`;let t=Math.ceil(r/1e3);return `${t} second${t===1?"":"s"}`}async function M(r,e,t){let i=new AbortController,n=globalThis.setTimeout(()=>{i.abort(new Error(`${r} timed out after ${me(e)}.`));},e);try{return await t({abortController:i,httpOptions:{abortSignal:i.signal,requestTimeout:e}})}finally{globalThis.clearTimeout(n);}}function fe(r){let e=r;return e.endsWith("/")?e+="index.html":b.posix.basename(e).includes(".")||(e+="/index.html"),e}function ye(r,e){let t=e.trim().replace(/^\/+|\/+$/g,"");if(!t)return null;let i=`/${t}`;return r===i||r.startsWith(`${i}/`)?r:`${i}${r.startsWith("/")?r:`/${r}`}`}function q(r,e){let t=new Set;for(let i of r){let n=new URL(i,"https://content-sync.invalid");if(n.origin!=="https://content-sync.invalid")continue;let s=`${n.pathname}${n.search}`,a=fe(n.pathname);t.add(s),t.add(`${a}${n.search}`);let o=ye(a,e);o&&t.add(`${o}${n.search}`);}return [...t].sort()}var Pe=".deploy-plan.json",we="deploy-plan.json";function Se(){let r=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return r.trim()?b.resolve(r):""}function ve(r){let e=String(r||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),t=b.posix.normalize(e);return !e||!t||t==="."||/^[a-zA-Z]:/.test(t)||t.startsWith("../")||t===".."?null:t}function Ie(r){let e=String(r||"").trim();if(!e.startsWith("/")||e.startsWith("//")||e.includes("*")||e.includes("#"))return null;try{let t=new URL(e,"https://content-sync.invalid");return t.origin!=="https://content-sync.invalid"?null:`${b.posix.normalize(t.pathname)}${t.search}`}catch{return null}}function y(r){return [...new Set(r.map(ve).filter(e=>e!==null))]}function Ce(r,e){let t={generatedAt:String(e.generatedAt||new Date().toISOString()),outputDir:b.resolve(r.outputDir),runMode:e.runMode,crawlMode:e.crawlMode,fullSyncRequired:!!e.fullSyncRequired,changedFiles:y(e.changedFiles||[]),deletedFiles:y(e.deletedFiles||[]),rewriteTargets:y(e.rewriteTargets||[]),revalidateFiles:y(e.revalidateFiles||[])};return e.schemaVersion===2?{...t,schemaVersion:2,runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,consumerId:String(e.consumerId||"").trim(),fromSequence:Math.max(0,Number(e.fromSequence)||0),toSequence:Math.max(0,Number(e.toSequence)||0),impactHash:String(e.impactHash||"").trim(),resolvedSitemapUrls:[...new Set((e.resolvedSitemapUrls||[]).map(i=>String(i||"").trim()).filter(i=>{try{let n=new URL(i);return n.protocol==="http:"||n.protocol==="https:"}catch{return false}}))],uploadGroups:{assets:y(e.uploadGroups?.assets||[]),content:y(e.uploadGroups?.content||[]),listings:y(e.uploadGroups?.listings||[]),resources:y(e.uploadGroups?.resources||[]),sitemapLeaves:y(e.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:y(e.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((e.invalidationPaths||[]).map(Ie).filter(i=>i!==null))].sort()}:{schemaVersion:1,...t,runMode:e.runMode}}function De(r){if(!r||typeof r!="object")return false;let e=r;if(e.schemaVersion===2){let t=e;return t.runMode==="content-sync"&&t.crawlMode==="incremental"&&t.fullSyncRequired===false&&typeof t.generatedAt=="string"&&typeof t.outputDir=="string"&&typeof t.consumerId=="string"&&t.consumerId.trim()!==""&&Number.isSafeInteger(t.fromSequence)&&Number.isSafeInteger(t.toSequence)&&Number(t.toSequence)>=Number(t.fromSequence)&&typeof t.impactHash=="string"&&/^[a-f0-9]{64}$/.test(t.impactHash)&&Array.isArray(t.resolvedSitemapUrls)&&Array.isArray(t.changedFiles)&&Array.isArray(t.deletedFiles)&&Array.isArray(t.rewriteTargets)&&(t.revalidateFiles===void 0||Array.isArray(t.revalidateFiles))&&!!t.uploadGroups&&Array.isArray(t.uploadGroups.assets)&&Array.isArray(t.uploadGroups.content)&&Array.isArray(t.uploadGroups.listings)&&Array.isArray(t.uploadGroups.resources)&&Array.isArray(t.uploadGroups.sitemapLeaves)&&Array.isArray(t.uploadGroups.sitemapIndexes)&&Array.isArray(t.invalidationPaths)}return e.schemaVersion===1&&typeof e.generatedAt=="string"&&typeof e.outputDir=="string"&&(e.runMode==="full"||e.runMode==="retry-timeouts"||e.runMode==="single-url")&&(e.crawlMode==="full"||e.crawlMode==="incremental")&&typeof e.fullSyncRequired=="boolean"&&Array.isArray(e.changedFiles)&&Array.isArray(e.deletedFiles)&&Array.isArray(e.rewriteTargets)&&(e.revalidateFiles===void 0||Array.isArray(e.revalidateFiles))}function Te(r){let e=b.join(b.resolve(r.outputDir),Pe),t=Se();return t?[b.join(t,we),e]:[e]}async function B(r){let e=b.resolve(r.outputDir);for(let t of Te(r))try{let i=await w.readFile(t,"utf8"),n=JSON.parse(i);if(!De(n)||b.resolve(n.outputDir)!==e)continue;return Ce(r,n)}catch{}return null}function Re(r){return typeof r.subscriptionType=="string"&&r.subscriptionType.trim()!==""}function z(r){let e="";for(let i=0;i<r.length;i++){let n=r[i];if(n==="--profile"){let s=(r[i+1]||"").trim();if(!s)throw new Error("Missing value for --profile.");e=s,i+=1;}else if(n.startsWith("--profile=")){let s=n.slice(10).trim();if(!s)throw new Error("Missing value for --profile.");e=s;}}let t=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return e||t||null}function Ae(r,e){return {...r,...e??{}}}function ke(r,e){return {...r,...e??{},invalidationPaths:[...(e?.invalidationPaths??r.invalidationPaths)||[]]}}function H(r,e){let t=String(e??r.deploymentTargetOverride??"").trim();if(!Re(r)){if(t)throw new Error(`Deployment target "${t}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:r}}let i=String(t||r.defaultDeploymentProfile||"").trim();if(!i)return {name:null,profile:null,config:r};let n=r.deploymentProfiles?.[i];if(!n)throw new Error(`Unknown deployment profile "${i}". Check the linked WPSuite publisher configuration.`);return {name:i,profile:n,config:{...r,targetOrigin:n.targetOrigin??r.targetOrigin,s3:Ae(r.s3,n.s3),cloudFront:ke(r.cloudFront,n.cloudFront)}}}var J={error:0,warn:1,info:2,debug:3},Ee=/^(?:authorization|proxyAuthorization|runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken|xStaticPublisherToken|xApiKey)$/i;function C(r){return r.replace(/((?:x-static-publisher-token|authorization|proxy-authorization|x-api-key|aws-access-key-id|aws-secret-access-key|aws-session-token)\s*:\s*)[^\r\n]+/gi,"$1[REDACTED]").replace(/\b(Basic|Bearer)\s+[^\s]+/gi,"$1 [REDACTED]").replace(/([?&](?:token|access_token|refresh_token|api_key|key|nonce)=)[^&\s]+/gi,"$1[REDACTED]").replace(/((?:"|')?(?:runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken)(?:"|')?\s*[:=]\s*(?:"|'))[^"']+/gi,"$1[REDACTED]")}function R(r){return typeof r=="string"?C(r):Array.isArray(r)?r.map(e=>R(e)):r instanceof Error?{name:r.name,message:C(r.message),...r.stack?{stack:C(r.stack)}:{}}:r&&typeof r=="object"?Object.fromEntries(Object.entries(r).map(([e,t])=>[e,Ee.test(e)?"[REDACTED]":R(t)])):r}function K(r){return r?R(r):void 0}var G=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",T=G?b.join(G,"current-progress.json"):"",V=Promise.resolve();function Q(r){return r.includes("crawl")?"crawl":r.includes("deploy")?"deploy":r.includes("invalidate")?"invalidate":r}function xe(r,e){let t={...r},i=typeof r.phase=="string"?r.phase.trim():"",n=typeof e.phase=="string"?e.phase.trim():"";if(n!==""&&(n==="deploy"||n.startsWith("deploy-"))&&i!==n)for(let o of ["index","totalFiles","staged","uploaded","skipped","failed","deleted","workerCount","completedBatches","totalBatches"])delete t[o];let a=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","completedBatches","totalBatches","pageQueue","assetQueue","sitemapQueue"]);for(let[o,l]of Object.entries(e)){let u=t[o];if(typeof u=="number"&&typeof l=="number"&&a.has(o)){t[o]=Math.max(u,l);continue}t[o]=l;}return t}function Le(r,e,t){T&&(V=V.then(async()=>{let i=new Date,n=i.toISOString();await w.mkdir(b.dirname(T),{recursive:true});let s=await w.readFile(T,"utf8").then(I=>JSON.parse(I)).catch(()=>null),a=s&&typeof s.details=="object"&&s.details?s.details:{},o=Q(r),l=s?.currentStep||Q(s?.source||""),u=s?.startedAt||n,c={...s?.stepDurationsSec??{}},g=s?.stepStartedAt||n;if(l&&l!==o&&s?.stepStartedAt){let I=Math.max(0,Math.round((i.getTime()-new Date(s.stepStartedAt).getTime())/1e3));c[l]=(c[l]??0)+I,g=n;}let p=Math.max(0,Math.round((i.getTime()-new Date(g).getTime())/1e3)),m=Math.max(0,Math.round((i.getTime()-new Date(u).getTime())/1e3)),d=C(e),f=K(t)??{},h={checkedAt:n,source:r,message:d,details:xe(a,f),startedAt:u,currentStep:o,stepStartedAt:g,stepElapsedSec:p,totalElapsedSec:m,stepDurationsSec:c};await w.writeFile(T,JSON.stringify(h,null,2),"utf8");}).catch(()=>{}));}async function Me(r,e){await w.mkdir(b.dirname(r),{recursive:true}),await w.appendFile(r,`${JSON.stringify(R(e))}
|
|
1
|
+
import w from'fs/promises';import te from'http';import re from'https';import b from'path';import {CloudFrontClient,waitUntilInvalidationCompleted,CreateInvalidationCommand}from'@aws-sdk/client-cloudfront';import {createHash}from'crypto';var N=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function j(r){let e=r.trim();return e==="."?".":e.replace(/\/$/,"")}function ne(r){let e=String(r??"").trim();if(!e)return "";let t=e;if(/^https?:\/\//i.test(t))try{t=new URL(t).pathname;}catch{return ""}if(t=t.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!t)return "";let i=t.endsWith("/"),n=t.replace(/^\/+/,"").split("/").map(a=>a.replace(/[^A-Za-z0-9._-]/g,"")).filter(a=>a.length>0&&a!=="."&&a!=="..");if(n.length===0)return "";let s=`/${n.join("/")}`;return i&&b.extname(s)===""&&(s+="/"),s==="/"?"":s}function k(r){return !r||typeof r!="object"?{}:Object.fromEntries(Object.entries(r).map(([e,t])=>[e.trim(),String(t??"")]).filter(([e])=>e.length>0))}function ie(r){if(!r||typeof r!="object")return {};let e={};for(let[t,i]of Object.entries(r)){let n=t.trim();if(!n||!i||typeof i!="object")continue;let s=i,a={};if(typeof s.targetOrigin=="string"){let u=j(s.targetOrigin);u&&(a.targetOrigin=u);}let o=k(s.extraReplacements);if(Object.keys(o).length>0&&(a.extraReplacements=o),s.s3&&typeof s.s3=="object"){let u={},l=s.s3;typeof l.bucket=="string"&&(u.bucket=l.bucket.trim()),typeof l.prefix=="string"&&(u.prefix=l.prefix.trim()),typeof l.region=="string"&&(u.region=l.region.trim()),typeof l.htmlCacheControl=="string"&&(u.htmlCacheControl=l.htmlCacheControl.trim()),typeof l.assetCacheControl=="string"&&(u.assetCacheControl=l.assetCacheControl.trim()),Object.keys(u).length>0&&(a.s3=u);}if(s.cloudFront&&typeof s.cloudFront=="object"){let u={},l=s.cloudFront;typeof l.distributionId=="string"&&(u.distributionId=l.distributionId.trim()),Array.isArray(l.invalidationPaths)&&(u.invalidationPaths=l.invalidationPaths.map(c=>String(c??"").trim()).filter(c=>c.length>0)),Object.keys(u).length>0&&(a.cloudFront=u);}e[n]=a;}return e}function x(r){return r==="PROFESSIONAL"||r==="AGENCY"?r:void 0}function se(r,e){if(!r||typeof r!="object")return null;let t=r,i=t.command;if(i!=="publish"&&i!=="crawl"&&i!=="deploy"&&i!=="invalidate"&&i!=="retry-timeouts"&&i!=="url"&&i!=="content-sync")return null;let n=Number.parseInt(String(t.intervalMinutes??"0"),10);if(!Number.isFinite(n)||n<1)return null;let s=String(t.id??`${i}-${e+1}`).trim();if(!s)return null;let a=String(t.deploymentProfile??"").trim(),o=String(t.url??"").trim(),u=Array.isArray(t.postTypes)?[...new Set(t.postTypes.map(c=>String(c??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],l=Array.isArray(t.listingPaths)?[...new Set(t.listingPaths.map(c=>String(c??"").trim()).filter(Boolean))]:[];return i==="content-sync"&&u.length===0?null:{id:s,enabled:t.enabled!==false,command:i,intervalMinutes:n,...i==="publish"||i==="crawl"?{crawlMode:t.crawlMode==="incremental"?"incremental":"full"}:{},...(i==="publish"||i==="deploy"||i==="invalidate"||i==="content-sync")&&a?{deploymentProfile:a}:{},...o?{url:o}:{},...u.length>0?{postTypes:u}:{},...l.length>0?{listingPaths:l}:{},...typeof t.includeSubsites=="boolean"?{includeSubsites:t.includeSubsites}:{},...typeof t.includePostTypeArchives=="boolean"?{includePostTypeArchives:t.includePostTypeArchives}:{},...typeof t.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:t.includeTaxonomyArchives}:{},...typeof t.includeAuthorArchives=="boolean"?{includeAuthorArchives:t.includeAuthorArchives}:{},...typeof t.includeDateArchives=="boolean"?{includeDateArchives:t.includeDateArchives}:{},...typeof t.includePostsPage=="boolean"?{includePostsPage:t.includePostsPage}:{},...typeof t.includeSitemapChain=="boolean"?{includeSitemapChain:t.includeSitemapChain}:{}}}function $(r){let e=r&&typeof r=="object"?r:{},t=Array.isArray(e.rules)?e.rules.map((i,n)=>se(i,n)).filter(i=>!!i):[];return {enabled:e.enabled===true,timezone:typeof e.timezone=="string"&&e.timezone.trim()!==""?e.timezone.trim():"UTC",rules:t}}function oe(r){let e=r&&typeof r=="object"?r:{},t=e.render&&typeof e.render=="object"?e.render:{},i=Number(t.concurrency??0),n=Number(t.batchSize??0),s=Number(t.maxAttempts??0),a=e.rewrite&&typeof e.rewrite=="object"?e.rewrite:{},o=e.deploy&&typeof e.deploy=="object"?e.deploy:{},u=(l,c)=>({enabled:typeof l.enabled=="boolean"?l.enabled:t.enabled===true,concurrency:Math.min(100,Math.max(1,Number(l.concurrency||c.concurrency))),batchSize:Math.min(500,Math.max(1,Number(l.batchSize||c.batchSize))),maxAttempts:Math.min(5,Math.max(1,Number(l.maxAttempts||2)))});return {render:{enabled:t.enabled===true,...Number.isInteger(i)&&i>0?{concurrency:i}:{},batchSize:Number.isInteger(n)&&n>0?Math.min(20,n):5,...Number.isInteger(s)&&s>0?{maxAttempts:Math.min(5,s)}:{}},rewrite:u(a,{concurrency:8,batchSize:25}),deploy:u(o,{concurrency:8,batchSize:50})}}function ae(r){if(!r||typeof r!="object")return;let e=r,t={};for(let n of ["accountId","siteId"]){let s=e[n];typeof s=="string"&&s.trim()!==""&&(t[n]=s.trim());}let i=Number(e.lastUpdate??0);return Number.isFinite(i)&&i>0&&(t.lastUpdate=Math.floor(i)),e.subscriber===true&&(t.subscriber=true),Object.keys(t).length>0?t:void 0}function L(r){let e=r&&typeof r=="object"?r:{},t=String(e.accountId??"").trim(),i=String(e.siteId??"").trim(),n=e.subscriber===true,s=ae(e.siteSettings),a={...s??{},...t?{accountId:s?.accountId??t}:{},...i?{siteId:s?.siteId??i}:{},...s?.subscriber===true||n?{subscriber:true}:{}},o={},u=String(e.apiBase??"").trim();u&&(o.apiBase=u);let l=String(e.runtimeToken??e.nonce??"").trim();l&&(o.runtimeToken=l);let c=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();c&&(o.virtualAssetBaseUrl=c),Object.keys(a).length>0&&(o.siteSettings=a);let g=x(e.subscriptionType);return g&&(o.subscriptionType=g),o}function le(r){try{let e=new URL(r);globalThis.location=e;}catch{}}function _(r){return typeof r=="string"?r:r instanceof URL?r.toString():r.url}function ue(r,e){let t=new Headers(r instanceof Request?r.headers:void 0);if(e?.headers)for(let[i,n]of new Headers(e.headers).entries())t.set(i,n);return t}async function W(r,e,t=5){let i=new URL(_(r)),n=String(e?.method??(r instanceof Request?r.method:"GET")).toUpperCase(),s=i.protocol==="http:"?te:re,a=ue(r,e);return await new Promise((o,u)=>{let l=s.request(i,{method:n,headers:Object.fromEntries(a.entries()),...i.protocol==="https:"?{rejectUnauthorized:false}:{}},c=>{let g=[];c.on("data",p=>{g.push(Buffer.isBuffer(p)?p:Buffer.from(p));}),c.on("error",u),c.on("end",()=>{let p=c.statusCode??0,m=c.headers.location;if(t>0&&m&&[301,302,303,307,308].includes(p)){o(W(new URL(m,i),{method:p===303?"GET":n},t-1));return}let d=new Headers;for(let[f,h]of Object.entries(c.headers))Array.isArray(h)?d.set(f,h.join(", ")):typeof h=="string"&&d.set(f,h);o(new Response(Buffer.concat(g),{status:p,statusText:c.statusMessage??"",headers:d}));});});l.on("error",u),l.end();})}function ce(r){let e=L(r.wpsuite),t={...e.siteSettings??{},...e.siteSettings?.subscriber===true||e.subscriptionType==="PROFESSIONAL"||e.subscriptionType==="AGENCY"?{subscriber:true}:{}},i=String(t.accountId??"").trim(),n=String(t.siteId??"").trim(),s=String(e.virtualAssetBaseUrl??e.uploadUrl??"").trim();if(r.wpsuite={...e.apiBase?{apiBase:e.apiBase}:{},...e.runtimeToken?{runtimeToken:e.runtimeToken}:{},...s?{virtualAssetBaseUrl:s}:{},...Object.keys(t).length>0?{siteSettings:t}:{},...e.subscriptionType?{subscriptionType:e.subscriptionType}:{}},!i||!n||!s)return false;le(r.sourceOrigin);let a=globalThis,u={...a.WpSuite??{},siteSettings:t,uploadUrl:s};return e.apiBase&&(u.apiBase=e.apiBase),a.WpSuite=u,true}async function de(r){let e=String(r.wpsuite?.virtualAssetBaseUrl??r.wpsuite?.uploadUrl??"").trim();if(!ce(r)){let n=r.wpsuite?.siteSettings,s=[String(n?.accountId??"").trim()?"":"accountId",String(n?.siteId??"").trim()?"":"siteId",e?"":"virtualAssetBaseUrl"].filter(Boolean);return {remote:null,diagnostic:{status:"invalid-runtime",virtualAssetBaseUrl:e,subscriptionType:null,error:`Missing WP Suite runtime field(s): ${s.join(", ")}.`,requests:[]}}}let t=globalThis.fetch,i=[];try{typeof t=="function"&&/^https?:\/\//i.test(e)&&(globalThis.fetch=(async(u,l)=>{let c=_(u);if(c.startsWith(e)){let g=(()=>{try{return new URL(c).pathname}catch{return c}})();try{let p=r.ignoreHttpsErrors&&c.startsWith("https://")?await W(u,l):await t(u,l);return i.push({path:g,status:p.status,ok:p.ok,error:null}),p}catch(p){throw i.push({path:g,status:null,ok:!1,error:p instanceof Error?p.message:String(p)}),p}}return t(u,l)}));let{getConfig:n}=await import('@smart-cloud/wpsuite-core'),s=await n("publisher"),a=s&&typeof s=="object"?s:null,o=x(a?.subscriptionType);return {remote:a,diagnostic:{status:a?"loaded":"unavailable",virtualAssetBaseUrl:e,subscriptionType:o??null,error:a?null:"WP Suite publisher config loader returned no configuration.",requests:i}}}catch(n){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:e,subscriptionType:null,error:n instanceof Error?n.message:String(n),requests:i}}}finally{typeof t=="function"&&(globalThis.fetch=t);}}function pe(r,e){let t=ie(e?.deploymentProfiles),i=String(e?.defaultDeploymentProfile??"").trim(),n=t[i]?i:"",s=x(e?.subscriptionType),a=L(r.wpsuite);return {...r,scheduler:$(e?.scheduler),deploymentProfiles:t,defaultDeploymentProfile:n,...s?{subscriptionType:s}:{},wpsuite:{...a,...a.siteSettings||s?{siteSettings:{...a.siteSettings??{},...a.siteSettings?.subscriber===true||s==="PROFESSIONAL"||s==="AGENCY"?{subscriber:true}:{}}}:{},...s?{subscriptionType:s}:{}}}}function E(r,e){let i=String(r||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!i)return e;let n=i.split("/").map(s=>s.trim()).filter(s=>s.length>0&&s!=="."&&s!=="..");return n.length>0?n.join("/"):e}function ge(){let r=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return r.trim()?b.resolve(r):""}function U(r,e,t){let i=String(e||"").trim();return i&&b.isAbsolute(i)?b.resolve(i):b.resolve(r,E(i,t))}async function D(r,e={}){let t=String("").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",i=await w.readFile(t,"utf8"),n=JSON.parse(i);n.sourceOrigin=n.sourceOrigin.replace(/\/$/,""),n.targetOrigin=j(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=ne(n.generated404RequestPath),n.sitemapPaths||=[...N],n.allowedAssetHosts||=[],n.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],n.blockedPathPrefixes||=[],n.blockedSearchFragments||=[];let s=Number(n.processingConcurrency)>0?Math.min(100,Math.max(1,Number(n.processingConcurrency))):null;n.concurrency=s??n.concurrency??1,n.maxPages||=0,n.extraReplacements=k(n.extraReplacements),n.postCrawlCopyMap=k(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=s??(Number(n.assetDownloadConcurrency)>0?Number(n.assetDownloadConcurrency):n.concurrency),n.rewriteConcurrency=s??(Number(n.rewriteConcurrency)>0?Number(n.rewriteConcurrency):n.assetDownloadConcurrency),n.wpsuite=L(n.wpsuite),n.scheduler=$(void 0),n.remoteWorkers=oe(n.remoteWorkers),typeof n.lambdaDelegationEnabled=="boolean"&&(n.remoteWorkers.render??={},n.remoteWorkers.rewrite??={},n.remoteWorkers.deploy??={},n.remoteWorkers.render.enabled=n.lambdaDelegationEnabled,n.remoteWorkers.rewrite.enabled=n.lambdaDelegationEnabled,n.remoteWorkers.deploy.enabled=n.lambdaDelegationEnabled),s!==null&&(n.processingConcurrency=s,n.remoteWorkers.render??={},n.remoteWorkers.rewrite??={},n.remoteWorkers.deploy??={},n.remoteWorkers.render.concurrency=s,n.remoteWorkers.rewrite.concurrency=s,n.remoteWorkers.deploy.concurrency=s),n.deploymentProfiles={},n.defaultDeploymentProfile="",n.deploymentTargetOverride=String(n.deploymentTargetOverride??"").trim();let a=await de(n);e.onRemotePublisherConfigDiagnostic?.(a.diagnostic);let o=pe(n,a.remote),u=ge(),l=u?b.resolve(u,".."):"";return l?(o.outputDir=U(l,o.outputDir,"export"),o.logDir=U(l,o.logDir,"logs")):(b.isAbsolute(o.outputDir)||(o.outputDir=E(o.outputDir,"export")),b.isAbsolute(o.logDir)||(o.logDir=E(o.logDir,"logs"))),o}function me(r){let e=r/6e4;if(Number.isInteger(e)&&e>=1)return `${e} minute${"s"}`;let t=Math.ceil(r/1e3);return `${t} second${t===1?"":"s"}`}async function M(r,e,t){let i=new AbortController,n=globalThis.setTimeout(()=>{i.abort(new Error(`${r} timed out after ${me(e)}.`));},e);try{return await t({abortController:i,httpOptions:{abortSignal:i.signal,requestTimeout:e}})}finally{globalThis.clearTimeout(n);}}function fe(r){let e=r;return e.endsWith("/")?e+="index.html":b.posix.basename(e).includes(".")||(e+="/index.html"),e}function ye(r,e){let t=e.trim().replace(/^\/+|\/+$/g,"");if(!t)return null;let i=`/${t}`;return r===i||r.startsWith(`${i}/`)?r:`${i}${r.startsWith("/")?r:`/${r}`}`}function q(r,e){let t=new Set;for(let i of r){let n=new URL(i,"https://content-sync.invalid");if(n.origin!=="https://content-sync.invalid")continue;let s=`${n.pathname}${n.search}`,a=fe(n.pathname);t.add(s),t.add(`${a}${n.search}`);let o=ye(a,e);o&&t.add(`${o}${n.search}`);}return [...t].sort()}var Pe=".deploy-plan.json",we="deploy-plan.json";function Se(){let r=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return r.trim()?b.resolve(r):""}function ve(r){let e=String(r||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),t=b.posix.normalize(e);return !e||!t||t==="."||/^[a-zA-Z]:/.test(t)||t.startsWith("../")||t===".."?null:t}function Ie(r){let e=String(r||"").trim();if(!e.startsWith("/")||e.startsWith("//")||e.includes("*")||e.includes("#"))return null;try{let t=new URL(e,"https://content-sync.invalid");return t.origin!=="https://content-sync.invalid"?null:`${b.posix.normalize(t.pathname)}${t.search}`}catch{return null}}function y(r){return [...new Set(r.map(ve).filter(e=>e!==null))]}function Ce(r,e){let t={generatedAt:String(e.generatedAt||new Date().toISOString()),outputDir:b.resolve(r.outputDir),runMode:e.runMode,crawlMode:e.crawlMode,fullSyncRequired:!!e.fullSyncRequired,changedFiles:y(e.changedFiles||[]),deletedFiles:y(e.deletedFiles||[]),rewriteTargets:y(e.rewriteTargets||[]),revalidateFiles:y(e.revalidateFiles||[])};return e.schemaVersion===2?{...t,schemaVersion:2,runMode:"content-sync",crawlMode:"incremental",fullSyncRequired:false,consumerId:String(e.consumerId||"").trim(),fromSequence:Math.max(0,Number(e.fromSequence)||0),toSequence:Math.max(0,Number(e.toSequence)||0),impactHash:String(e.impactHash||"").trim(),resolvedSitemapUrls:[...new Set((e.resolvedSitemapUrls||[]).map(i=>String(i||"").trim()).filter(i=>{try{let n=new URL(i);return n.protocol==="http:"||n.protocol==="https:"}catch{return false}}))],uploadGroups:{assets:y(e.uploadGroups?.assets||[]),content:y(e.uploadGroups?.content||[]),listings:y(e.uploadGroups?.listings||[]),resources:y(e.uploadGroups?.resources||[]),sitemapLeaves:y(e.uploadGroups?.sitemapLeaves||[]),sitemapIndexes:y(e.uploadGroups?.sitemapIndexes||[])},invalidationPaths:[...new Set((e.invalidationPaths||[]).map(Ie).filter(i=>i!==null))].sort()}:{schemaVersion:1,...t,runMode:e.runMode}}function De(r){if(!r||typeof r!="object")return false;let e=r;if(e.schemaVersion===2){let t=e;return t.runMode==="content-sync"&&t.crawlMode==="incremental"&&t.fullSyncRequired===false&&typeof t.generatedAt=="string"&&typeof t.outputDir=="string"&&typeof t.consumerId=="string"&&t.consumerId.trim()!==""&&Number.isSafeInteger(t.fromSequence)&&Number.isSafeInteger(t.toSequence)&&Number(t.toSequence)>=Number(t.fromSequence)&&typeof t.impactHash=="string"&&/^[a-f0-9]{64}$/.test(t.impactHash)&&Array.isArray(t.resolvedSitemapUrls)&&Array.isArray(t.changedFiles)&&Array.isArray(t.deletedFiles)&&Array.isArray(t.rewriteTargets)&&(t.revalidateFiles===void 0||Array.isArray(t.revalidateFiles))&&!!t.uploadGroups&&Array.isArray(t.uploadGroups.assets)&&Array.isArray(t.uploadGroups.content)&&Array.isArray(t.uploadGroups.listings)&&Array.isArray(t.uploadGroups.resources)&&Array.isArray(t.uploadGroups.sitemapLeaves)&&Array.isArray(t.uploadGroups.sitemapIndexes)&&Array.isArray(t.invalidationPaths)}return e.schemaVersion===1&&typeof e.generatedAt=="string"&&typeof e.outputDir=="string"&&(e.runMode==="full"||e.runMode==="retry-timeouts"||e.runMode==="single-url")&&(e.crawlMode==="full"||e.crawlMode==="incremental")&&typeof e.fullSyncRequired=="boolean"&&Array.isArray(e.changedFiles)&&Array.isArray(e.deletedFiles)&&Array.isArray(e.rewriteTargets)&&(e.revalidateFiles===void 0||Array.isArray(e.revalidateFiles))}function Te(r){let e=b.join(b.resolve(r.outputDir),Pe),t=Se();return t?[b.join(t,we),e]:[e]}async function B(r){let e=b.resolve(r.outputDir);for(let t of Te(r))try{let i=await w.readFile(t,"utf8"),n=JSON.parse(i);if(!De(n)||b.resolve(n.outputDir)!==e)continue;return Ce(r,n)}catch{}return null}function Re(r){return typeof r.subscriptionType=="string"&&r.subscriptionType.trim()!==""}function z(r){let e="";for(let i=0;i<r.length;i++){let n=r[i];if(n==="--profile"){let s=(r[i+1]||"").trim();if(!s)throw new Error("Missing value for --profile.");e=s,i+=1;}else if(n.startsWith("--profile=")){let s=n.slice(10).trim();if(!s)throw new Error("Missing value for --profile.");e=s;}}let t=String(process.env.PUBLISHER_DEPLOY_PROFILE||process.env.PUBLISHER_DEPLOYMENT_PROFILE||"").trim();return e||t||null}function Ae(r,e){return {...r,...e??{}}}function ke(r,e){return {...r,...e??{},invalidationPaths:[...(e?.invalidationPaths??r.invalidationPaths)||[]]}}function H(r,e){let t=String(e??r.deploymentTargetOverride??"").trim();if(!Re(r)){if(t)throw new Error(`Deployment target "${t}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:r}}let i=String(t||r.defaultDeploymentProfile||"").trim();if(!i)return {name:null,profile:null,config:r};let n=r.deploymentProfiles?.[i];if(!n)throw new Error(`Unknown deployment profile "${i}". Check the linked WPSuite publisher configuration.`);return {name:i,profile:n,config:{...r,targetOrigin:n.targetOrigin??r.targetOrigin,s3:Ae(r.s3,n.s3),cloudFront:ke(r.cloudFront,n.cloudFront)}}}var J={error:0,warn:1,info:2,debug:3},Ee=/^(?:authorization|proxyAuthorization|runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken|xStaticPublisherToken|xApiKey)$/i;function C(r){return r.replace(/((?:x-static-publisher-token|authorization|proxy-authorization|x-api-key|aws-access-key-id|aws-secret-access-key|aws-session-token)\s*:\s*)[^\r\n]+/gi,"$1[REDACTED]").replace(/\b(Basic|Bearer)\s+[^\s]+/gi,"$1 [REDACTED]").replace(/([?&](?:token|access_token|refresh_token|api_key|key|nonce)=)[^&\s]+/gi,"$1[REDACTED]").replace(/((?:"|')?(?:runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken)(?:"|')?\s*[:=]\s*(?:"|'))[^"']+/gi,"$1[REDACTED]")}function R(r){return typeof r=="string"?C(r):Array.isArray(r)?r.map(e=>R(e)):r instanceof Error?{name:r.name,message:C(r.message),...r.stack?{stack:C(r.stack)}:{}}:r&&typeof r=="object"?Object.fromEntries(Object.entries(r).map(([e,t])=>[e,Ee.test(e)?"[REDACTED]":R(t)])):r}function K(r){return r?R(r):void 0}var G=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",T=G?b.join(G,"current-progress.json"):"",V=Promise.resolve();function Q(r){return r.includes("crawl")?"crawl":r.includes("deploy")?"deploy":r.includes("invalidate")?"invalidate":r}function xe(r,e){let t={...r},i=typeof r.phase=="string"?r.phase.trim():"",n=typeof e.phase=="string"?e.phase.trim():"";if(n!==""&&(n==="deploy"||n.startsWith("deploy-"))&&i!==n)for(let o of ["index","totalFiles","staged","uploaded","skipped","failed","deleted","workerCount","completedBatches","totalBatches"])delete t[o];let a=new Set(["pagesQueued","pagesRendered","assetsQueued","sitemapsQueued","pagesDiscovered","assetsDiscovered","sitemapsDiscovered","pagesSaved","assetsSaved","donePages","doneAssets","doneSitemaps","changedTextFiles","uploaded","failed","index","totalFiles","completedBatches","totalBatches","pageQueue","assetQueue","sitemapQueue"]);for(let[o,u]of Object.entries(e)){let l=t[o];if(typeof l=="number"&&typeof u=="number"&&a.has(o)){t[o]=Math.max(l,u);continue}t[o]=u;}return t}function Le(r,e,t){T&&(V=V.then(async()=>{let i=new Date,n=i.toISOString();await w.mkdir(b.dirname(T),{recursive:true});let s=await w.readFile(T,"utf8").then(I=>JSON.parse(I)).catch(()=>null),a=s&&typeof s.details=="object"&&s.details?s.details:{},o=Q(r),u=s?.currentStep||Q(s?.source||""),l=s?.startedAt||n,c={...s?.stepDurationsSec??{}},g=s?.stepStartedAt||n;if(u&&u!==o&&s?.stepStartedAt){let I=Math.max(0,Math.round((i.getTime()-new Date(s.stepStartedAt).getTime())/1e3));c[u]=(c[u]??0)+I,g=n;}let p=Math.max(0,Math.round((i.getTime()-new Date(g).getTime())/1e3)),m=Math.max(0,Math.round((i.getTime()-new Date(l).getTime())/1e3)),d=C(e),f=K(t)??{},h={checkedAt:n,source:r,message:d,details:xe(a,f),startedAt:l,currentStep:o,stepStartedAt:g,stepElapsedSec:p,totalElapsedSec:m,stepDurationsSec:c};await w.writeFile(T,JSON.stringify(h,null,2),"utf8");}).catch(()=>{}));}async function Me(r,e){await w.mkdir(b.dirname(r),{recursive:true}),await w.appendFile(r,`${JSON.stringify(R(e))}
|
|
2
2
|
`,"utf8");}var v=class{constructor(e,t,i="info"){this.logDir=e;this.logFile=t;this.level=i;this.ensureLogFileReady();}logDir;logFile;level;startedAt=Date.now();marks=new Map;initPromise=null;writeQueue=Promise.resolve();writeError=null;get logPath(){return b.join(this.logDir,this.logFile)}artifactPath(e){return this.logFile.endsWith(".log.jsonl")?b.join(this.logDir,this.logFile.replace(/\.log\.jsonl$/u,`${e}.jsonl`)):b.join(this.logDir,`${this.logFile}${e}.jsonl`)}get errorsPath(){return this.artifactPath(".errors")}get rejectedPath(){return this.artifactPath(".rejected")}ensureLogFileReady(){return this.initPromise||(this.initPromise=(async()=>{await w.mkdir(this.logDir,{recursive:true}),await w.writeFile(this.logPath,"","utf8");})()),this.initPromise}enqueueTask(e){this.writeQueue=this.writeQueue.then(e).catch(t=>{this.writeError=t instanceof Error?t:new Error(String(t));});}enqueueLine(e){this.enqueueTask(async()=>{await this.ensureLogFileReady(),await w.appendFile(this.logPath,`${e}
|
|
3
|
-
`,"utf8");});}enqueueJsonLine(e,t){this.enqueueTask(()=>Me(e,t));}accepts(e){return J[e]<=J[this.level]}push(e,t,i){if(!this.accepts(e))return;let n=C(t),s=K(i),a=JSON.stringify({time:new Date().toISOString(),level:e,message:n,...s||{}});this.enqueueLine(a),e==="error"?console.error(`[ERROR] ${n}`,s?JSON.stringify(s):""):e==="warn"?console.warn(`[WARN] ${n}`,s?JSON.stringify(s):""):console.log(`[${e.toUpperCase().padEnd(5)}] ${n}`);}info(e,t){this.push("info",e,t);}progress(e,t){Le(this.logFile,e,t);}debug(e,t){this.push("debug",e,t);}warn(e,t){this.push("warn",e,t);}reject(e,t,i,n,s){let a={kind:e,url:t,reason:i,...n?{source:n}:{},...s||{}};this.enqueueJsonLine(this.rejectedPath,a),this.accepts("debug")&&this.push("debug",`Rejected ${e} ${t}: ${i}`,a);}error(e,t){this.enqueueJsonLine(this.errorsPath,{message:e,...t||{}}),this.push("error",e,t);}mark(e){this.marks.set(e,Date.now());}endMark(e,t){let i=this.marks.get(e);if(!i)return;let n=Date.now()-i,s=Number((n/1e3).toFixed(2));this.push("info",`Timing ${e}: ${s}s`,{name:e,ms:n,seconds:s,...t||{}});}async flush(){let e=Date.now()-this.startedAt,t=Number((e/1e3).toFixed(2));if(this.push("info",`Total time: ${t}s`,{name:"total",ms:e,seconds:t}),await this.writeQueue,this.writeError)throw this.writeError}};function Ue(){let r=String(process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"").trim();return r?b.join(b.resolve(r),"content-sync-invalidation.json"):""}async function F(r,e){if(!r)return;await w.mkdir(b.dirname(r),{recursive:true});let t=`${r}.${process.pid}.${Date.now()}.tmp`;await w.writeFile(t,JSON.stringify({...e,updatedAt:new Date().toISOString()},null,2),"utf8"),await w.rename(t,r);}async function je(r,e,t,i){if(!r)return null;try{let n=JSON.parse(await w.readFile(r,"utf8"));if(n.schemaVersion!==1||n.distributionId!==e||n.impactHash!==t||!Array.isArray(n.batches))throw new Error("Content-sync invalidation state does not match the deploy plan.");let s=n.batches.flatMap(a=>a.paths);return s.length!==i.length||s.some((a,o)=>a!==i[o])?null:n}catch(n){if(n.code==="ENOENT")return null;throw n}}function $e(r,e=3e3){let t=[];for(let i=0;i<r.length;i+=e)t.push(r.slice(i,i+e));return t}async function X(r=process.argv.slice(2)){let e=await D(),t=z(r),i=H(e,t),n=i.config,s=new v(n.logDir||"logs","invalidate.log.jsonl",n.logLevel??"info"),a=r.includes("--content-sync"),o=await B(e);if(a&&o?.schemaVersion!==2)throw new Error("Content-sync invalidation requires a valid schema-2 targeted deploy plan.");if(i.name&&s.info(`Using deployment profile: ${i.name}`),!n.cloudFront.distributionId){s.info("No CloudFront distributionId configured; skipping invalidation."),await s.flush();return}let
|
|
3
|
+
`,"utf8");});}enqueueJsonLine(e,t){this.enqueueTask(()=>Me(e,t));}accepts(e){return J[e]<=J[this.level]}push(e,t,i){if(!this.accepts(e))return;let n=C(t),s=K(i),a=JSON.stringify({time:new Date().toISOString(),level:e,message:n,...s||{}});this.enqueueLine(a),e==="error"?console.error(`[ERROR] ${n}`,s?JSON.stringify(s):""):e==="warn"?console.warn(`[WARN] ${n}`,s?JSON.stringify(s):""):console.log(`[${e.toUpperCase().padEnd(5)}] ${n}`);}info(e,t){this.push("info",e,t);}progress(e,t){Le(this.logFile,e,t);}debug(e,t){this.push("debug",e,t);}warn(e,t){this.push("warn",e,t);}reject(e,t,i,n,s){let a={kind:e,url:t,reason:i,...n?{source:n}:{},...s||{}};this.enqueueJsonLine(this.rejectedPath,a),this.accepts("debug")&&this.push("debug",`Rejected ${e} ${t}: ${i}`,a);}error(e,t){this.enqueueJsonLine(this.errorsPath,{message:e,...t||{}}),this.push("error",e,t);}mark(e){this.marks.set(e,Date.now());}endMark(e,t){let i=this.marks.get(e);if(!i)return;let n=Date.now()-i,s=Number((n/1e3).toFixed(2));this.push("info",`Timing ${e}: ${s}s`,{name:e,ms:n,seconds:s,...t||{}});}async flush(){let e=Date.now()-this.startedAt,t=Number((e/1e3).toFixed(2));if(this.push("info",`Total time: ${t}s`,{name:"total",ms:e,seconds:t}),await this.writeQueue,this.writeError)throw this.writeError}};function Ue(){let r=String(process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"").trim();return r?b.join(b.resolve(r),"content-sync-invalidation.json"):""}async function F(r,e){if(!r)return;await w.mkdir(b.dirname(r),{recursive:true});let t=`${r}.${process.pid}.${Date.now()}.tmp`;await w.writeFile(t,JSON.stringify({...e,updatedAt:new Date().toISOString()},null,2),"utf8"),await w.rename(t,r);}async function je(r,e,t,i){if(!r)return null;try{let n=JSON.parse(await w.readFile(r,"utf8"));if(n.schemaVersion!==1||n.distributionId!==e||n.impactHash!==t||!Array.isArray(n.batches))throw new Error("Content-sync invalidation state does not match the deploy plan.");let s=n.batches.flatMap(a=>a.paths);return s.length!==i.length||s.some((a,o)=>a!==i[o])?null:n}catch(n){if(n.code==="ENOENT")return null;throw n}}function $e(r,e=3e3){let t=[];for(let i=0;i<r.length;i+=e)t.push(r.slice(i,i+e));return t}async function X(r=process.argv.slice(2)){let e=await D(),t=z(r),i=H(e,t),n=i.config,s=new v(n.logDir||"logs","invalidate.log.jsonl",n.logLevel??"info"),a=r.includes("--content-sync"),o=await B(e);if(a&&o?.schemaVersion!==2)throw new Error("Content-sync invalidation requires a valid schema-2 targeted deploy plan.");if(i.name&&s.info(`Using deployment profile: ${i.name}`),!n.cloudFront.distributionId){s.info("No CloudFront distributionId configured; skipping invalidation."),await s.flush();return}let u=o?.schemaVersion===2?o.invalidationPaths:n.cloudFront.invalidationPaths.length>0?n.cloudFront.invalidationPaths:["/*"],l=o?.schemaVersion===2?q(u,n.s3.prefix||""):u;if(o?.schemaVersion===2&&l.some(d=>d==="/*"))throw new Error("Content-sync cannot use a whole-distribution invalidation.");if(l.length===0){s.info("The targeted deploy plan has no CloudFront paths to invalidate."),await s.flush();return}let c=n.cloudFront.distributionId,g=new CloudFrontClient({region:"us-east-1",maxAttempts:5});if(s.mark("invalidate"),o?.schemaVersion!==2){let d=`smartcloud-static-publisher-${Date.now()}`;await M(`CloudFront invalidation for distribution ${c}`,3e5,({httpOptions:f})=>g.send(new CreateInvalidationCommand({DistributionId:c,InvalidationBatch:{CallerReference:d,Paths:{Quantity:l.length,Items:l}}}),f)),s.endMark("invalidate"),await s.flush();return}let p=Ue(),m=await je(p,c,o.impactHash,l);if(!m){let d=createHash("sha256").update(JSON.stringify(l)).digest("hex");m={schemaVersion:1,distributionId:c,impactHash:o.impactHash,updatedAt:new Date().toISOString(),batches:$e(l).map((f,h)=>({index:h,callerReference:`wpsuite-content-sync-${o.impactHash.slice(0,24)}-${d.slice(0,24)}-${h}`,paths:f,invalidationId:null,status:"pending"}))},await F(p,m);}for(let d of m.batches){if(!d.invalidationId){let f=await M(`CloudFront targeted invalidation batch ${d.index+1}`,3e5,({httpOptions:I})=>g.send(new CreateInvalidationCommand({DistributionId:c,InvalidationBatch:{CallerReference:d.callerReference,Paths:{Quantity:d.paths.length,Items:d.paths}}}),I)),h=String(f.Invalidation?.Id||"").trim();if(!h)throw new Error("CloudFront did not return an invalidation ID.");d.invalidationId=h,d.status="created",await F(p,m);}await waitUntilInvalidationCompleted({client:g,maxWaitTime:900,minDelay:2,maxDelay:15},{DistributionId:c,Id:d.invalidationId}),d.status="completed",await F(p,m),s.info(`CloudFront invalidation batch ${d.index+1}/${m.batches.length} completed.`,{invalidationId:d.invalidationId,pathCount:d.paths.length});}s.endMark("invalidate"),await s.flush();}X().catch(async r=>{console.error(r);try{let e=await D().catch(()=>null),t=new v(e?.logDir??"logs","invalidate.log.jsonl","debug");t.error(`Unhandled error: ${r instanceof Error?r.message:String(r)}`,r instanceof Error?{stack:r.stack}:void 0),await t.flush();}catch{}process.exit(1);});
|