@smart-cloud/publisher-exporter 1.1.65 → 1.1.67
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 +22 -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/queue-runner.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {pathToFileURL}from'url';import P from'fs/promises';import {existsSync,createReadStream,createWriteStream}from'fs';import h from'path';import {spawn}from'child_process';import {randomUUID,createHash}from'crypto';import Ge from'http';import Se from'https';import {pipeline}from'stream/promises';import {createGzip}from'zlib';function he(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))].sort()}function Y(e){return Array.isArray(e)?e.map(Y):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,Y(n)])):e}function _e(e){return JSON.stringify(Y(e))}function J(e){return createHash("sha256").update(_e(e)).digest("hex")}function fe(e){return J({schemaVersion:1,wordpressFingerprint:e.wordpressFingerprint,targetFingerprint:e.targetFingerprint,sourceOrigin:e.sourceOrigin,sitemapPaths:[...e.sitemapPaths].sort(),blockedPathPrefixes:[...e.blockedPathPrefixes].sort(),assetPathPrefixes:[...e.assetPathPrefixes].sort(),noJavaScriptRenderPathPrefixes:[...e.noJavaScriptRenderPathPrefixes].sort(),urlRewriteMode:e.urlRewriteMode})}function He(e){let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error(`Unsupported source origin protocol: ${t.protocol}`);return t.hash="",t.search="",t.pathname=t.pathname.replace(/\/+$/,""),t.toString().replace(/\/$/,"")}function Q(e){let t=he((e.postTypes??[]).map(i=>String(i).toLowerCase().replace(/[^a-z0-9_-]/g,"")));if(t.length===0)throw new Error("Content-sync requires at least one public post type.");let n=he((e.listingPaths??[]).map(i=>{let r=String(i).trim();if(!r)return "";let a=new URL(r,"https://content-sync.invalid/");if(a.origin!=="https://content-sync.invalid"&&/^https?:\/\//i.test(r))throw new Error("Content-sync listing routes must be same-site paths.");let o=`/${a.pathname.replace(/^\/+|\/+$/g,"")}`;return o==="/"?"/":`${o}/`}));return {postTypes:t,listingPaths:n,includeSubsites:e.includeSubsites===true,includePostTypeArchives:e.includePostTypeArchives!==false,includeTaxonomyArchives:e.includeTaxonomyArchives!==false,includeAuthorArchives:e.includeAuthorArchives===true,includeDateArchives:e.includeDateArchives===true,includePostsPage:e.includePostsPage!==false,includeSitemapChain:e.includeSitemapChain!==false}}function Z(e,t,n){return J({schemaVersion:1,sourceOrigin:He(e),ruleId:t.trim(),scope:Q(n)})}function X(e){return J({schemaVersion:1,...e})}function be(e){return e.replace(/((?:x-static-publisher-token|authorization|proxy-authorization|x-api-key|aws-access-key-id|aws-secret-access-key|aws-session-token)\s*:\s*)[^\r\n]+/gi,"$1[REDACTED]").replace(/\b(Basic|Bearer)\s+[^\s]+/gi,"$1 [REDACTED]").replace(/([?&](?:token|access_token|refresh_token|api_key|key|nonce)=)[^&\s]+/gi,"$1[REDACTED]").replace(/((?:"|')?(?:runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken)(?:"|')?\s*[:=]\s*(?:"|'))[^"']+/gi,"$1[REDACTED]")}var ye=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";ye?h.join(ye,"current-progress.json"):"";Promise.resolve();var Ye="wp-json/smartcloud-static-publisher/v1/content-sync/",Ze=25*1024*1024,T=class extends Error{status;code;constructor(t,n,i){super(i),this.name="ContentSyncApiError",this.status=t,this.code=n;}},L=class{options;constructor(t){if(!t.runtimeToken.trim())throw new Error("Content-sync requires a WordPress runtime token.");this.options={...t,timeoutMs:t.timeoutMs??6e4};}endpoint(t,n="content-sync"){let i=this.options.sourceOrigin.replace(/\/+$/,"")+"/",r=n==="content-sync"?Ye:`wp-json/smartcloud-static-publisher/v1/${n}/`;return new URL(`${r}${t}`,i)}async post(t,n,i="content-sync"){let r=this.endpoint(t,i),a=Buffer.from(JSON.stringify(n),"utf8"),o=r.protocol==="https:"?Se:Ge,s=r.protocol==="https:"?new Se.Agent({rejectUnauthorized:!this.options.ignoreHttpsErrors}):void 0;return new Promise((c,u)=>{let p=o.request(r,{method:"POST",agent:s,headers:{"content-type":"application/json","content-length":String(a.byteLength),"x-static-publisher-token":this.options.runtimeToken},timeout:this.options.timeoutMs},d=>{let m=[],f=0;d.on("data",b=>{if(f+=b.byteLength,f>Ze){d.destroy(new Error("Content-sync API response exceeded the size limit."));return}m.push(b);}),d.on("error",u),d.on("end",()=>{let b=Buffer.concat(m).toString("utf8"),l;try{l=b?JSON.parse(b):{};}catch{u(new T(d.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let g=d.statusCode??500;if(g<200||g>=300){u(new T(g,String(l.code??"request-failed"),String(l.message??`Content-sync API request failed (${g}).`)));return}c(l);});});p.on("timeout",()=>p.destroy(new Error(`Content-sync API request timed out: ${t}`))),p.on("error",u),p.end(a);})}async head(t){return this.post("head",t)}async unboundHead(t,n){return this.post("head",{postTypes:t,includeSubsites:n})}async events(t){let n=[],i=t.afterSequence,r=new Set(t.postTypes);for(;i<t.throughSequence;){let a=await this.post("events",{...t,afterSequence:i,limit:250});if(a.fromSequence!==i||a.throughSequence!==t.throughSequence||a.nextSequence<i||a.nextSequence>t.throughSequence)throw new Error("Content-sync API returned an inconsistent event page.");if(!Array.isArray(a.items))throw new Error("Content-sync API returned a malformed event page.");let o=i;for(let s of a.items){if(!Number.isSafeInteger(s.sequence)||s.sequence<=o||s.sequence>t.throughSequence||!Number.isSafeInteger(s.postId)||s.postId<=0||!Number.isSafeInteger(s.blogId)||s.blogId<=0||!r.has(s.postType)||typeof s.operation!="string"||!s.operation)throw new Error("Content-sync API returned an invalid or out-of-scope journal event.");o=s.sequence;}if(a.items.length>0&&a.nextSequence!==o)throw new Error("Content-sync API event cursor does not match the final returned event.");if(n.push(...a.items),!a.hasMore)break;if(a.nextSequence===i)throw new Error("Content-sync API event pagination did not advance.");i=a.nextSequence;}if(t.throughSequence>t.afterSequence&&n.at(-1)?.sequence!==t.throughSequence)throw new Error("Content-sync API omitted the claimed journal high-water event.");return n}async resolveImpactFamilies(t,n){let i=await this.post("impact",{families:t,includeSubsites:n});return Array.isArray(i.families)?i.families:[]}async releaseFingerprint(t=false){let n=await this.post("fingerprint",{includeSubsites:t}),i=String(n.fingerprint||"").trim();if(!/^[a-f0-9]{64}$/.test(i))throw new Error("WordPress returned an invalid release fingerprint.");return i}async establishBaseline(t){return this.post("baseline",t)}async acknowledge(t){return this.post("ack",t)}async importCookieObservations(t){return this.post("cookie-observations",t,"privacy")}};function Xe(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function et(e,t){return {...e,...t??{}}}function tt(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function ee(e,t){let n=String(t??e.deploymentTargetOverride??"").trim();if(!Xe(e)){if(n)throw new Error(`Deployment target "${n}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:e}}let i=String(n||e.defaultDeploymentProfile||"").trim();if(!i)return {name:null,profile:null,config:e};let r=e.deploymentProfiles?.[i];if(!r)throw new Error(`Unknown deployment profile "${i}". Check the linked WPSuite publisher configuration.`);return {name:i,profile:r,config:{...e,targetOrigin:r.targetOrigin??e.targetOrigin,s3:et(e.s3,r.s3),cloudFront:tt(e.cloudFront,r.cloudFront)}}}var te=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function we(e){let t=new Set;for(let n of [...e,...te]){let i=String(n||"").trim();i&&t.add(i);}return [...t]}function Pe(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function ot(e){let t=String(e??"").trim();if(!t)return "";let n=t;if(/^https?:\/\//i.test(n))try{n=new URL(n).pathname;}catch{return ""}if(n=n.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!n)return "";let i=n.endsWith("/"),r=n.replace(/^\/+/,"").split("/").map(o=>o.replace(/[^A-Za-z0-9._-]/g,"")).filter(o=>o.length>0&&o!=="."&&o!=="..");if(r.length===0)return "";let a=`/${r.join("/")}`;return i&&h.extname(a)===""&&(a+="/"),a==="/"?"":a}function ne(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t.trim(),String(n??"")]).filter(([t])=>t.length>0))}function st(e){if(!e||typeof e!="object")return {};let t={};for(let[n,i]of Object.entries(e)){let r=n.trim();if(!r||!i||typeof i!="object")continue;let a=i,o={};if(typeof a.targetOrigin=="string"){let c=Pe(a.targetOrigin);c&&(o.targetOrigin=c);}let s=ne(a.extraReplacements);if(Object.keys(s).length>0&&(o.extraReplacements=s),a.s3&&typeof a.s3=="object"){let c={},u=a.s3;typeof u.bucket=="string"&&(c.bucket=u.bucket.trim()),typeof u.prefix=="string"&&(c.prefix=u.prefix.trim()),typeof u.region=="string"&&(c.region=u.region.trim()),typeof u.htmlCacheControl=="string"&&(c.htmlCacheControl=u.htmlCacheControl.trim()),typeof u.assetCacheControl=="string"&&(c.assetCacheControl=u.assetCacheControl.trim()),Object.keys(c).length>0&&(o.s3=c);}if(a.cloudFront&&typeof a.cloudFront=="object"){let c={},u=a.cloudFront;typeof u.distributionId=="string"&&(c.distributionId=u.distributionId.trim()),Array.isArray(u.invalidationPaths)&&(c.invalidationPaths=u.invalidationPaths.map(p=>String(p??"").trim()).filter(p=>p.length>0)),Object.keys(c).length>0&&(o.cloudFront=c);}t[r]=o;}return t}function ie(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function at(e,t){if(!e||typeof e!="object")return null;let n=e,i=n.command;if(i!=="publish"&&i!=="crawl"&&i!=="deploy"&&i!=="invalidate"&&i!=="retry-timeouts"&&i!=="url"&&i!=="content-sync")return null;let r=Number.parseInt(String(n.intervalMinutes??"0"),10);if(!Number.isFinite(r)||r<1)return null;let a=String(n.id??`${i}-${t+1}`).trim();if(!a)return null;let o=String(n.deploymentProfile??"").trim(),s=String(n.url??"").trim(),c=Array.isArray(n.postTypes)?[...new Set(n.postTypes.map(p=>String(p??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],u=Array.isArray(n.listingPaths)?[...new Set(n.listingPaths.map(p=>String(p??"").trim()).filter(Boolean))]:[];return i==="content-sync"&&c.length===0?null:{id:a,enabled:n.enabled!==false,command:i,intervalMinutes:r,...i==="publish"||i==="crawl"?{crawlMode:n.crawlMode==="incremental"?"incremental":"full"}:{},...(i==="publish"||i==="deploy"||i==="invalidate"||i==="content-sync")&&o?{deploymentProfile:o}:{},...s?{url:s}:{},...c.length>0?{postTypes:c}:{},...u.length>0?{listingPaths:u}:{},...typeof n.includeSubsites=="boolean"?{includeSubsites:n.includeSubsites}:{},...typeof n.includePostTypeArchives=="boolean"?{includePostTypeArchives:n.includePostTypeArchives}:{},...typeof n.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:n.includeTaxonomyArchives}:{},...typeof n.includeAuthorArchives=="boolean"?{includeAuthorArchives:n.includeAuthorArchives}:{},...typeof n.includeDateArchives=="boolean"?{includeDateArchives:n.includeDateArchives}:{},...typeof n.includePostsPage=="boolean"?{includePostsPage:n.includePostsPage}:{},...typeof n.includeSitemapChain=="boolean"?{includeSitemapChain:n.includeSitemapChain}:{}}}function Ce(e){let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.rules)?t.rules.map((i,r)=>at(i,r)).filter(i=>!!i):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:n}}function ct(e){let t=e&&typeof e=="object"?e:{},n=t.render&&typeof t.render=="object"?t.render:{},i=Number(n.concurrency??0),r=Number(n.maxAttempts??0),a=t.rewrite&&typeof t.rewrite=="object"?t.rewrite:{},o=t.deploy&&typeof t.deploy=="object"?t.deploy:{},s=(c,u)=>({enabled:typeof c.enabled=="boolean"?c.enabled:n.enabled===true,concurrency:Math.min(100,Math.max(1,Number(c.concurrency||u.concurrency))),batchSize:Math.min(500,Math.max(1,Number(c.batchSize||u.batchSize))),maxAttempts:Math.min(5,Math.max(1,Number(c.maxAttempts||2)))});return {render:{enabled:n.enabled===true,...Number.isInteger(i)&&i>0?{concurrency:i}:{},...Number.isInteger(r)&&r>0?{maxAttempts:Math.min(5,r)}:{}},rewrite:s(a,{concurrency:8,batchSize:25}),deploy:s(o,{concurrency:8,batchSize:50})}}function ut(e){if(!e||typeof e!="object")return;let t=e,n={};for(let r of ["accountId","siteId"]){let a=t[r];typeof a=="string"&&a.trim()!==""&&(n[r]=a.trim());}let i=Number(t.lastUpdate??0);return Number.isFinite(i)&&i>0&&(n.lastUpdate=Math.floor(i)),t.subscriber===true&&(n.subscriber=true),Object.keys(n).length>0?n:void 0}function oe(e){let t=e&&typeof e=="object"?e:{},n=String(t.accountId??"").trim(),i=String(t.siteId??"").trim(),r=t.subscriber===true,a=ut(t.siteSettings),o={...a??{},...n?{accountId:a?.accountId??n}:{},...i?{siteId:a?.siteId??i}:{},...a?.subscriber===true||r?{subscriber:true}:{}},s={},c=String(t.apiBase??"").trim();c&&(s.apiBase=c);let u=String(t.runtimeToken??t.nonce??"").trim();u&&(s.runtimeToken=u);let p=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();p&&(s.virtualAssetBaseUrl=p),Object.keys(o).length>0&&(s.siteSettings=o);let d=ie(t.subscriptionType);return d&&(s.subscriptionType=d),s}function lt(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Ae(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function dt(e,t){let n=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[i,r]of new Headers(t.headers).entries())n.set(i,r);return n}async function Ie(e,t,n=5){let i=new URL(Ae(e)),r=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),a=i.protocol==="http:"?Ge:Se,o=dt(e,t);return await new Promise((s,c)=>{let u=a.request(i,{method:r,headers:Object.fromEntries(o.entries()),...i.protocol==="https:"?{rejectUnauthorized:false}:{}},p=>{let d=[];p.on("data",m=>{d.push(Buffer.isBuffer(m)?m:Buffer.from(m));}),p.on("error",c),p.on("end",()=>{let m=p.statusCode??0,f=p.headers.location;if(n>0&&f&&[301,302,303,307,308].includes(m)){s(Ie(new URL(f,i),{method:m===303?"GET":r},n-1));return}let b=new Headers;for(let[l,g]of Object.entries(p.headers))Array.isArray(g)?b.set(l,g.join(", ")):typeof g=="string"&&b.set(l,g);s(new Response(Buffer.concat(d),{status:m,statusText:p.statusMessage??"",headers:b}));});});u.on("error",c),u.end();})}function gt(e){let t=oe(e.wpsuite),n={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},i=String(n.accountId??"").trim(),r=String(n.siteId??"").trim(),a=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();if(e.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...a?{virtualAssetBaseUrl:a}:{},...Object.keys(n).length>0?{siteSettings:n}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!i||!r||!a)return false;lt(e.sourceOrigin);let o=globalThis,c={...o.WpSuite??{},siteSettings:n,uploadUrl:a};return t.apiBase&&(c.apiBase=t.apiBase),o.WpSuite=c,true}async function pt(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!gt(e)){let r=e.wpsuite?.siteSettings,a=[String(r?.accountId??"").trim()?"":"accountId",String(r?.siteId??"").trim()?"":"siteId",t?"":"virtualAssetBaseUrl"].filter(Boolean);return {remote:null,diagnostic:{status:"invalid-runtime",virtualAssetBaseUrl:t,subscriptionType:null,error:`Missing WP Suite runtime field(s): ${a.join(", ")}.`,requests:[]}}}let n=globalThis.fetch,i=[];try{typeof n=="function"&&/^https?:\/\//i.test(t)&&(globalThis.fetch=(async(c,u)=>{let p=Ae(c);if(p.startsWith(t)){let d=(()=>{try{return new URL(p).pathname}catch{return p}})();try{let m=e.ignoreHttpsErrors&&p.startsWith("https://")?await Ie(c,u):await n(c,u);return i.push({path:d,status:m.status,ok:m.ok,error:null}),m}catch(m){throw i.push({path:d,status:null,ok:!1,error:m instanceof Error?m.message:String(m)}),m}}return n(c,u)}));let{getConfig:r}=await import('@smart-cloud/wpsuite-core'),a=await r("publisher"),o=a&&typeof a=="object"?a:null,s=ie(o?.subscriptionType);return {remote:o,diagnostic:{status:o?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:s??null,error:o?null:"WP Suite publisher config loader returned no configuration.",requests:i}}}catch(r){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:t,subscriptionType:null,error:r instanceof Error?r.message:String(r),requests:i}}}finally{typeof n=="function"&&(globalThis.fetch=n);}}function mt(e,t){let n=st(t?.deploymentProfiles),i=String(t?.defaultDeploymentProfile??"").trim(),r=n[i]?i:"",a=ie(t?.subscriptionType),o=oe(e.wpsuite);return {...e,scheduler:Ce(t?.scheduler),deploymentProfiles:n,defaultDeploymentProfile:r,...a?{subscriptionType:a}:{},wpsuite:{...o,...o.siteSettings||a?{siteSettings:{...o.siteSettings??{},...o.siteSettings?.subscriber===true||a==="PROFESSIONAL"||a==="AGENCY"?{subscriber:true}:{}}}:{},...a?{subscriptionType:a}:{}}}}function re(e,t){let i=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!i)return t;let r=i.split("/").map(a=>a.trim()).filter(a=>a.length>0&&a!=="."&&a!=="..");return r.length>0?r.join("/"):t}function ht(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?h.resolve(e):""}function ve(e,t,n){let i=String(t||"").trim();return i&&h.isAbsolute(i)?h.resolve(i):h.resolve(e,re(i,n))}async function K(e,t={}){let n=String(e??"").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",i=await P.readFile(n,"utf8"),r=JSON.parse(i);r.sourceOrigin=r.sourceOrigin.replace(/\/$/,""),r.targetOrigin=Pe(r.targetOrigin),r.ignoreHttpsErrors??=false,r.outputDir=String(r.outputDir||"export").trim()||"export",r.urlRewriteMode||=r.targetOrigin==="."?"relative":"absolute",r.noJavaScriptRenderPathPrefixes||=[],r.seedPaths||=[],r.generated404RequestPath=ot(r.generated404RequestPath),r.sitemapPaths||=[...te],r.allowedAssetHosts||=[],r.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],r.blockedPathPrefixes||=[],r.blockedSearchFragments||=[];let a=Number(r.processingConcurrency)>0?Math.min(100,Math.max(1,Number(r.processingConcurrency))):null;r.concurrency=a??r.concurrency??1,r.maxPages||=0,r.extraReplacements=ne(r.extraReplacements),r.postCrawlCopyMap=ne(r.postCrawlCopyMap),r.logDir=String(r.logDir||"logs").trim()||"logs",r.verbose??=false,r.logLevel||=r.verbose?"debug":"info",r.s3SyncMode||="sdk-upload-delete",r.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},r.readiness.timeoutMs??=1500,r.readiness.fallbackWaitMs??=1500,r.viewport||={width:1440,height:1200},r.navigationTimeoutMs||=3e4,r.assetDownloadConcurrency=a??(Number(r.assetDownloadConcurrency)>0?Number(r.assetDownloadConcurrency):r.concurrency),r.rewriteConcurrency=a??(Number(r.rewriteConcurrency)>0?Number(r.rewriteConcurrency):r.assetDownloadConcurrency),r.wpsuite=oe(r.wpsuite),r.scheduler=Ce(void 0),r.remoteWorkers=ct(r.remoteWorkers),typeof r.lambdaDelegationEnabled=="boolean"&&(r.remoteWorkers.render??={},r.remoteWorkers.rewrite??={},r.remoteWorkers.deploy??={},r.remoteWorkers.render.enabled=r.lambdaDelegationEnabled,r.remoteWorkers.rewrite.enabled=r.lambdaDelegationEnabled,r.remoteWorkers.deploy.enabled=r.lambdaDelegationEnabled),a!==null&&(r.processingConcurrency=a,r.remoteWorkers.render??={},r.remoteWorkers.rewrite??={},r.remoteWorkers.deploy??={},r.remoteWorkers.render.concurrency=a,r.remoteWorkers.rewrite.concurrency=a,r.remoteWorkers.deploy.concurrency=a),r.deploymentProfiles={},r.defaultDeploymentProfile="",r.deploymentTargetOverride=String(r.deploymentTargetOverride??"").trim();let o=await pt(r);t.onRemotePublisherConfigDiagnostic?.(o.diagnostic);let s=mt(r,o.remote),c=ht(),u=c?h.resolve(c,".."):"";return u?(s.outputDir=ve(u,s.outputDir,"export"),s.logDir=ve(u,s.logDir,"logs")):(h.isAbsolute(s.outputDir)||(s.outputDir=re(s.outputDir,"export")),h.isAbsolute(s.logDir)||(s.logDir=re(s.logDir,"logs"))),s}function Re(e){let t=e.split(/\r?\n/).map(i=>i.trim()).filter(Boolean),n=[...t].reverse().find(i=>/^(?:Error|[A-Za-z][A-Za-z0-9]*Error):\s/.test(i));return n||(t.find(i=>!i.startsWith("at "))??"")}function se(e){let t=h.resolve(e);return {state:h.join(t,"content-sync-state.json"),current:h.join(t,"content-sync-current.json"),impact:h.join(t,"content-sync-impact-plan.json"),checkpoint:h.join(t,"content-sync-checkpoint.json"),baseline:h.join(t,"content-sync-baseline.json"),activeRules:h.join(t,"content-sync-active-rules.json"),releaseCutoff:h.join(t,"content-sync-release-cutoff.json"),candidateManifest:h.join(t,"content-sync-candidate-manifest.json"),trustedManifest:h.join(t,"crawl-manifest.json"),invalidation:h.join(t,"content-sync-invalidation.json"),deployPlan:h.join(t,"deploy-plan.json")}}async function M(e,t,n=[],i=[],r=false){await xe(e.activeRules,{contractVersion:1,evaluatedAt:new Date().toISOString(),discoveryReady:r,entries:t,targets:n,rules:i});}async function xe(e,t){await P.mkdir(h.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await P.writeFile(n,JSON.stringify(t,null,2),"utf8"),await P.rename(n,e);}async function ke(e){try{return JSON.parse(await P.readFile(e,"utf8"))}catch(t){if(t.code==="ENOENT")return null;throw new Error(`Invalid or unreadable content-sync state file ${e}: ${t instanceof Error?t.message:String(t)}`,{cause:t})}}async function ft(e){let t=await ke(e.current);if(t===null)return null;let n=t;if(n.schemaVersion!==1||typeof n.jobId!="string"||typeof n.phase!="string"||!Number.isSafeInteger(n.fromSequence)||!Number.isSafeInteger(n.toSequence))throw new Error("Invalid content-sync current-range state.");return n}async function qe(e){let t=await ke(e.state);if(t===null)return {schemaVersion:1,updatedAt:"",rules:{}};let n=t;if(n.schemaVersion!==1||typeof n.updatedAt!="string"||!n.rules||typeof n.rules!="object"||Array.isArray(n.rules))throw new Error("Invalid content-sync state store.");return n}async function De(e,t){await xe(e.state,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Te(e,t){let n=await ft(e);return !n||n.coalesceKey!==t?false:(await Promise.all([e.current,e.checkpoint,e.impact,e.candidateManifest,e.invalidation,e.deployPlan].map(async i=>{try{await P.unlink(i);}catch(r){if(r.code!=="ENOENT")throw r}})),true)}function Le(e){let t=String(e.command??"").trim();return (t==="publish"||t==="crawl")&&e.crawlMode==="incremental"||t==="content-sync"}var ae=new Map;async function Ee(e){let t=h.resolve(e),n=ae.get(t);if(n!==void 0)return n;try{let i=JSON.parse(await P.readFile(t,"utf8")),r=String(i.version??"").trim();return ae.set(t,r),r}catch{return ae.set(t,""),""}}var N=class extends Error{request;step;constructor(t,n){super(`Stop requested during ${n}.`),this.name="StopRequestedError",this.request=t,this.step=n;}},Pt="queue-mutation.lock",Ct=5e3,At=3e4;function It(e){let t=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",n=process.env.STATIC_PUBLISHER_EXPORTER_DIR||process.cwd(),i=process.env.PUBLISHER_CONFIG||"",r=1;for(let s=0;s<e.length;s++){let c=e[s];c==="--runtime-dir"?t=e[++s]||"":c.startsWith("--runtime-dir=")?t=c.slice(14):c==="--exporter-dir"?n=e[++s]||n:c.startsWith("--exporter-dir=")?n=c.slice(15):c==="--config"?i=e[++s]||"":c.startsWith("--config=")?i=c.slice(9):c==="--max-jobs"?r=Number.parseInt(e[++s]||"1",10):c.startsWith("--max-jobs=")&&(r=Number.parseInt(c.slice(11),10));}if(!t)throw new Error("Missing runtime dir. Use --runtime-dir or STATIC_PUBLISHER_RUNTIME_DIR.");let a=h.resolve(t),o=i?h.resolve(i):h.join(a,"config.json");return {runtimeDir:a,exporterDir:h.resolve(n),configPath:o,maxJobs:Number.isFinite(r)&&r>0?r:1}}async function w(e,t){try{let n=await P.readFile(e,"utf8");return JSON.parse(n)}catch(n){if((n&&typeof n=="object"&&"code"in n?String(n.code||""):"")!=="ENOENT"){let r=n instanceof Error?n.message:String(n);console.warn(`[queue-runner] failed to read JSON ${e}: ${r}`);}return t}}async function v(e,t){await P.mkdir(h.dirname(e),{recursive:true}),await P.writeFile(e,JSON.stringify(t,null,2),"utf8");}function Be(e){return h.join(e,Pt)}async function Rt(e){await new Promise(t=>setTimeout(t,e));}async function xt(e){let t=Be(e),n=Date.now()+Ct;for(;;)try{await P.mkdir(h.dirname(t),{recursive:!0}),await P.writeFile(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()},null,2),{encoding:"utf8",flag:"wx"});return}catch(i){if((i&&typeof i=="object"&&"code"in i?String(i.code||""):"")!=="EEXIST")throw i;let a=await P.stat(t).catch(()=>null);if(a&&Date.now()-a.mtimeMs>At){await P.unlink(t).catch(()=>{});continue}if(Date.now()>=n)throw new Error("Timed out acquiring queue mutation lock.",{cause:i});await Rt(50);}}async function kt(e){await P.unlink(Be(e)).catch(()=>{});}async function F(e,t){await xt(e);try{return await t()}finally{await kt(e);}}function Me(e){return h.join(e,"queue-runner-heartbeat.json")}function ge(e){return h.join(e,"current-progress.json")}function ce(e){return h.join(e,"scheduler-state.json")}function qt(e,t){let i=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!i)return t;let r=i.split("/").map(a=>a.trim()).filter(a=>a.length>0&&a!=="."&&a!=="..");return r.length>0?r.join("/"):t}async function Ue(e){let t=await w(e.configPath||"",null),n=h.resolve(e.runtimeDir,".."),r=(typeof t?.logDir=="string"?t.logDir:"").trim();return r&&h.isAbsolute(r)?h.resolve(r):h.resolve(n,qt(r,"logs"))}function ue(e,t){return String(e||"").trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||t}function Dt(e){let t=e?new Date(e):new Date;return (Number.isNaN(t.getTime())?new Date:t).toISOString().replace(/[-:]/g,"").replace(/\.\d{3}Z$/,"Z")}function Tt(e){return [Dt(e.endedAt||e.startedAt),ue(e.command||"job","job"),ue(e.id||"job","job"),ue(e.status||"finished","finished")].join("-")}function Et(e){return e.endsWith(".log.jsonl")||e.endsWith(".errors.jsonl")||e.endsWith(".rejected.jsonl")?true:["current-crawl-event.json","rejected.jsonl","ignored.jsonl","skipped-http.jsonl","errors.jsonl","timings.jsonl","rejected.json","ignored.json","skipped-http.json","errors.json","timings.json"].includes(e)}function Ft(e){return e==="errors.json"||e==="errors.jsonl"||e.endsWith(".errors.jsonl")?"errors":e==="ignored.json"||e==="ignored.jsonl"?"ignored":e==="rejected.json"||e==="rejected.jsonl"||e.endsWith(".rejected.jsonl")?"rejected":e==="skipped-http.json"||e==="skipped-http.jsonl"?"skipped-http":e==="timings.json"||e==="timings.jsonl"?"timings":e==="current-progress.json"?"current-progress":e==="current-crawl-event.json"?"current-crawl-event":e.endsWith(".log.jsonl")?e.replace(/\.log\.jsonl$/i,"-log"):e.replace(/\.[^.]+$/u,"")||"artifact"}function jt(e){return e.endsWith(".gz")?"application/gzip":e.endsWith(".jsonl")?"application/x-ndjson":e.endsWith(".json")?"application/json":"text/plain"}async function z(e,t,n){let i=`${n}.gz`,r=h.join(t,i);await pipeline(createReadStream(e),createGzip({level:9}),createWriteStream(r));let[a,o]=await Promise.all([P.stat(e),P.stat(r)]);return {role:Ft(n),originalFileName:n,storedFileName:i,compressed:true,compression:"gzip",contentType:jt(i),originalSize:a.size,storedSize:o.size}}async function _(e,t){let n=await Ue(t),i=new Date().toISOString(),r=Tt(e),a=h.join(n,"archive",r),o=[],s=[];await P.mkdir(a,{recursive:true});try{let d=await P.readdir(n,{withFileTypes:!0});for(let m of d){if(!m.isFile()||!Et(m.name))continue;let f=await z(h.join(n,m.name),a,m.name);s.push(f),o.push(f.storedFileName);}}catch(d){if((d&&typeof d=="object"&&"code"in d?String(d.code||""):"")!=="ENOENT")throw d}let c=ge(t.runtimeDir);if(existsSync(c)){let d=await z(c,a,"current-progress.json");s.push(d),o.push(d.storedFileName);}if(e.command==="content-sync")for(let d of ["content-sync-current.json","content-sync-impact-plan.json","content-sync-checkpoint.json","content-sync-state.json","content-sync-invalidation.json","deploy-plan.json"]){let m=h.join(t.runtimeDir,d);if(!existsSync(m))continue;let f=await z(m,a,d);s.push(f),o.push(f.storedFileName);}let u=h.join(t.runtimeDir,"privacy","cookie-observations.json");if(existsSync(u)){let d=await z(u,a,"cookie-observations.json");s.push(d),o.push(d.storedFileName);}let p=[...o,"job.json"];return await v(h.join(a,"job.json"),{manifestVersion:1,archivedAt:i,archiveKey:r,archiveDir:a,logDir:n,runtimeDir:t.runtimeDir,exporterDir:t.exporterDir,configPath:t.configPath||"",archivedFiles:p,artifacts:s,job:e}),{archiveKey:r,archiveDir:a,archiveCreatedAt:i,archivedFiles:p,artifacts:s}}function Ot(e){return h.join(e,"audit-events.jsonl")}function le(e){return h.join(e,"stop-request.json")}async function We(e){try{let t=await P.readFile(le(e),"utf8"),n=JSON.parse(t);return n&&typeof n=="object"?n:null}catch{return null}}async function Fe(e,t){let n=await We(e);if(!n)return null;let i=String(n.targetJobId||"").trim();return i&&i!==t?null:n}async function W(e,t){if(!t){await P.unlink(le(e)).catch(()=>{});return}let n=await We(e);if(!n)return;let i=String(n.targetJobId||"").trim();(!i||i===t)&&await P.unlink(le(e)).catch(()=>{});}async function R(e,t){try{let n={occurredAt:t.occurredAt||new Date().toISOString(),status:t.status||"info",actorSource:t.actorSource||"queue-runner",...t};await P.mkdir(e,{recursive:!0}),await P.appendFile(Ot(e),`${JSON.stringify(n)}
|
|
2
|
-
`,"utf8");}catch{}}async function C(e,t,n){let[i,r]=await Promise.all([Ee(h.join(e.exporterDir,"package.json")),Ee(h.join(e.exporterDir,"node_modules","@smart-cloud","wpsuite-core","package.json"))]),a={checkedAt:new Date().toISOString(),status:t,pid:process.pid,nodePath:process.execPath,nodeVersion:process.version,exporterVersion:i,wpsuiteCoreVersion:r,runtimeDir:e.runtimeDir,exporterDir:e.exporterDir,...n??{}};try{await v(Me(e.runtimeDir),a);}catch{}}async function E(e){try{await P.unlink(ge(e));}catch{}}function Jt(e,t){let n=e.command;if(n!=="publish"&&n!=="crawl"&&n!=="deploy"&&n!=="invalidate"&&n!=="retry-timeouts"&&n!=="url"&&n!=="content-sync")return null;let i=Number.parseInt(String(e.intervalMinutes??"0"),10);if(!Number.isFinite(i)||i<1)return null;let r=(e.id||`${n}-${t+1}`).trim();if(!r)return null;let a=e.enabled!==false,o=typeof e.url=="string"?e.url.trim():"",s=typeof e.deploymentProfile=="string"?e.deploymentProfile.trim():"",c=Array.isArray(e.postTypes)?[...new Set(e.postTypes.map(d=>String(d).trim()).filter(Boolean))]:[],u=Array.isArray(e.listingPaths)?[...new Set(e.listingPaths.map(d=>String(d).trim()).filter(Boolean))]:[],p=(n==="publish"||n==="crawl")&&e.crawlMode==="incremental"?"incremental":"full";return n==="url"&&!o||n==="content-sync"&&c.length===0?null:{id:r,enabled:a,command:n,intervalMinutes:i,...n==="publish"||n==="crawl"?{crawlMode:p}:{},...(n==="publish"||n==="deploy"||n==="invalidate"||n==="content-sync")&&s?{deploymentProfile:s}:{},...o?{url:o}:{},...c.length>0?{postTypes:c}:{},...u.length>0?{listingPaths:u}:{},...typeof e.includeSubsites=="boolean"?{includeSubsites:e.includeSubsites}:{},...typeof e.includePostTypeArchives=="boolean"?{includePostTypeArchives:e.includePostTypeArchives}:{},...typeof e.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:e.includeTaxonomyArchives}:{},...typeof e.includeAuthorArchives=="boolean"?{includeAuthorArchives:e.includeAuthorArchives}:{},...typeof e.includeDateArchives=="boolean"?{includeDateArchives:e.includeDateArchives}:{},...typeof e.includePostsPage=="boolean"?{includePostsPage:e.includePostsPage}:{},...typeof e.includeSitemapChain=="boolean"?{includeSitemapChain:e.includeSitemapChain}:{}}}async function Lt(e){let t=await K(e.configPath).catch(()=>null),n=t?.scheduler,i=Array.isArray(n?.rules)?n.rules.map((r,a)=>Jt(r,a)).filter(r=>!!r):[];return {enabled:!!n?.enabled,timezone:typeof n?.timezone=="string"&&n.timezone.trim()?n.timezone.trim():"UTC",rules:i,wpsuite:t?.wpsuite,publisherConfig:t}}function $(e,t){if(!t)throw new Error("Content-sync scheduler requires a valid publisher config.");let n=Q({postTypes:e.postTypes??[],listingPaths:e.listingPaths??[],includeSubsites:e.includeSubsites,includePostTypeArchives:e.includePostTypeArchives,includeTaxonomyArchives:e.includeTaxonomyArchives,includeAuthorArchives:e.includeAuthorArchives,includeDateArchives:e.includeDateArchives,includePostsPage:e.includePostsPage,includeSitemapChain:e.includeSitemapChain}),i=Z(t.sourceOrigin,e.id,n),r=ee(t,e.deploymentProfile),a=X({sourceOrigin:t.sourceOrigin,targetOrigin:r.config.targetOrigin,deploymentProfile:r.name||"",s3Bucket:r.config.s3.bucket,s3Prefix:r.config.s3.prefix,cloudFrontDistributionId:r.config.cloudFront.distributionId,urlRewriteMode:r.config.urlRewriteMode,extraReplacements:r.profile?.extraReplacements??{}});return `content-sync:${e.id}:${J({scopeFingerprint:i,targetFingerprint:a}).slice(0,32)}`}function Bt(e,t,n,i){let r=[n[t],i[t]].filter(o=>!!o).filter(o=>o.coalesceKey===t&&o.ruleId===e.id).map(o=>String(o.consumerId??"").trim()).filter(Boolean),a=[...new Set(r)];return a.length===1?a[0]:""}async function je(e,t){let n=se(e.runtimeDir);if(await M(n,[]),!t?.publisherConfig)return;let i=t.publisherConfig,r=i.deploymentProfiles??{},a=String(i.defaultDeploymentProfile??"").trim(),o=a?r[a]:void 0,s=[{target:"default",resolvedDeploymentProfile:o?a:"",targetOrigin:String(o?.targetOrigin??i.targetOrigin??"").trim()},...Object.keys(r).sort((g,S)=>g.localeCompare(S)).map(g=>({target:g,resolvedDeploymentProfile:g,targetOrigin:String(r[g]?.targetOrigin??i.targetOrigin??"").trim()}))],c=t.rules.filter(g=>g.command==="content-sync"),u=c.map(g=>({ruleId:g.id,coalesceKey:$(g,i),target:String(g.deploymentProfile??"").trim()||"default",effectiveTarget:String(g.deploymentProfile??i.defaultDeploymentProfile??"").trim()||"default",enabled:g.enabled,active:t.enabled&&g.enabled,intervalMinutes:g.intervalMinutes,postTypes:[...g.postTypes??[]],listingPaths:[...g.listingPaths??[]]}));if(!t.enabled){await M(n,[],s,u,true);return}let p=c.filter(g=>g.enabled);if(p.length===0){await M(n,[],s,u,true);return}let[d,m]=await Promise.all([w(n.state,{}),w(n.baseline,{})]),f=d.rules??{},b=m.entries??{},l=[];for(let g of p){let S=$(g,i),x=Bt(g,S,f,b);x&&l.push({ruleId:g.id,coalesceKey:S,consumerId:x});}await M(n,l,s,u,true);}async function Mt(e,t,n,i,r){let o=(await w(h.join(e.runtimeDir,"content-sync-baseline.json"),{})).entries?.[i];if(!o?.consumerId||!o.scopeFingerprint||!o.baselineId)return {status:"baseline-required",reason:"No verified normal-release baseline exists for this rule scope."};try{let s=t.publisherConfig;if(!s)throw new Error("Publisher configuration is unavailable.");let c=Q({postTypes:n.postTypes??[],listingPaths:n.listingPaths??[],includeSubsites:n.includeSubsites,includePostTypeArchives:n.includePostTypeArchives,includeTaxonomyArchives:n.includeTaxonomyArchives,includeAuthorArchives:n.includeAuthorArchives,includeDateArchives:n.includeDateArchives,includePostsPage:n.includePostsPage,includeSitemapChain:n.includeSitemapChain}),u=Z(s.sourceOrigin,n.id,c),p=ee(s,n.deploymentProfile),d=X({sourceOrigin:s.sourceOrigin,targetOrigin:p.config.targetOrigin,deploymentProfile:p.name||"",s3Bucket:p.config.s3.bucket,s3Prefix:p.config.s3.prefix,cloudFrontDistributionId:p.config.cloudFront.distributionId,urlRewriteMode:p.config.urlRewriteMode,extraReplacements:p.profile?.extraReplacements??{}});if(o.scopeFingerprint!==u||o.targetFingerprint!==d||!o.releaseFingerprint)return {status:"baseline-required",reason:"The verified content-sync baseline does not match the active scope or deployment target. Run a successful full or incremental publish to establish a new baseline."};let m=new L({sourceOrigin:s.sourceOrigin,runtimeToken:String(s.wpsuite?.runtimeToken||""),ignoreHttpsErrors:s.ignoreHttpsErrors}),f=await m.releaseFingerprint(c.includeSubsites),b=fe({wordpressFingerprint:f,targetFingerprint:d,sourceOrigin:s.sourceOrigin,sitemapPaths:we(s.sitemapPaths),blockedPathPrefixes:s.blockedPathPrefixes,assetPathPrefixes:s.assetPathPrefixes,noJavaScriptRenderPathPrefixes:s.noJavaScriptRenderPathPrefixes,urlRewriteMode:s.urlRewriteMode});if(o.releaseFingerprint!==b)return {status:"baseline-required",reason:"The installed WordPress release changed after the last verified content-sync baseline. Run a successful full or incremental publish to establish a new baseline."};let l=await m.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:o.baselineId,postTypes:c.postTypes,includeSubsites:c.includeSubsites}),g=l.committedSequence;if(r?.command==="content-sync"&&r.coalesceKey===i){let S=await w(h.join(e.runtimeDir,"content-sync-current.json"),null);S?.coalesceKey===i&&Number.isSafeInteger(S.toSequence)&&(g=Math.max(g,Number(S.toSequence)));}return {status:l.headSequence>g?"pending":"current",headSequence:l.headSequence,committedSequence:l.committedSequence}}catch(s){return s instanceof T&&s.code==="baseline-required"?{status:"baseline-required",reason:s.message}:{status:"unavailable",reason:s instanceof Error?s.message:String(s)}}}async function $e(e,t,n,i,r,a){let o=h.join(e.runtimeDir,"content-sync-state.json"),c=(await w(o,{})).rules??{},u=c[n]??{};c[n]={...u,ruleId:t,coalesceKey:n,...Number.isSafeInteger(r)?{observedHeadSequence:r}:{},...Number.isSafeInteger(a)?{committedSequence:a}:{},retryAttempt:0,nextRetryAt:null,lastError:i,baselineStatus:"required",baselineReason:i,trailingWorkDetected:Number.isSafeInteger(r)&&Number.isSafeInteger(a)?Number(r)>Number(a):!!u.trailingWorkDetected},await v(o,{schemaVersion:1,updatedAt:new Date().toISOString(),rules:c});}function de(e,t){let n=(t.url||"").trim(),i=t.crawlMode||"full",r=(t.deploymentProfile||"").trim(),a=(t.coalesceKey||"").trim();return e.some(o=>o.command===t.command&&(t.command!=="content-sync"||(o.coalesceKey||"").trim()===a)&&(o.url||"").trim()===n&&(o.crawlMode||"full")===i&&(o.deploymentProfile||"").trim()===r&&(o.status===void 0||o.status==="queued"||o.status==="retry-wait"||o.status==="running"))}async function Ut(e,t,n){if(!t.allowSchedulerAutoEnqueue)return await je(e,null),0;let i=await Lt(e);if(await je(e,i),!i.enabled||i.rules.length===0)return 0;if(t.assertActiveSubscriptionForIdentity)try{await t.assertActiveSubscriptionForIdentity(i.wpsuite??null);}catch(l){let g=l instanceof Error?l.message:String(l);return console.warn(`[queue-runner] scheduler auto-enqueue skipped: ${g}`),0}let r=h.join(e.runtimeDir,"queue.json"),a=h.join(e.runtimeDir,"current-run.json"),o=Date.now(),s=0,c=[],u=[],p=[],d=new Map,[m,f,b]=await Promise.all([w(r,[]),w(a,null),w(ce(e.runtimeDir),{lastEnqueuedBucketByRuleId:{},lastEvaluatedBucketByRuleId:{},lastCreatedBucketByRuleId:{},coalescedCountByRuleId:{}})]);for(let l of i.rules){if(!l.enabled||l.command!=="content-sync")continue;let g=Math.floor(o/(l.intervalMinutes*60*1e3)),S=b.lastEvaluatedBucketByRuleId?.[l.id]??b.lastEnqueuedBucketByRuleId?.[l.id]??-1;if(g<=S)continue;let x=$(l,i.publisherConfig);de(m,{command:l.command,deploymentProfile:l.deploymentProfile,coalesceKey:x})||d.set(l.id,await Mt(e,i,l,x,f));}await F(e.runtimeDir,async()=>{let l=await w(r,[]),g=await w(a,null),S=await w(ce(e.runtimeDir),{lastEnqueuedBucketByRuleId:{},lastEvaluatedBucketByRuleId:{},lastCreatedBucketByRuleId:{},coalescedCountByRuleId:{}});S.lastEnqueuedBucketByRuleId??={},S.lastEvaluatedBucketByRuleId??={...S.lastEnqueuedBucketByRuleId},S.lastCreatedBucketByRuleId??={...S.lastEnqueuedBucketByRuleId},S.coalescedCountByRuleId??={};let x=[...l];g&&g.status==="running"&&x.unshift(g);for(let y of i.rules){if(!y.enabled)continue;let A=y.intervalMinutes*60*1e3,q=Math.floor(o/A),j=S.lastEvaluatedBucketByRuleId[y.id]??S.lastEnqueuedBucketByRuleId[y.id]??-1;if(q<=j)continue;let O=y.command==="content-sync"?$(y,i.publisherConfig):"";S.lastEvaluatedBucketByRuleId[y.id]=q;let Ke=y.command==="content-sync"?l:x;if(de(Ke,{command:y.command,url:y.url,crawlMode:y.crawlMode,deploymentProfile:y.deploymentProfile,coalesceKey:O})){S.coalescedCountByRuleId[y.id]=(S.coalescedCountByRuleId[y.id]??0)+1,u.push(y);continue}if(y.command==="content-sync"){let G=d.get(y.id);if(!G||G.status!=="pending"){let me=G??{status:"unavailable",reason:"Content-sync demand was not checked."};me.status!=="current"&&p.push({rule:y,check:me});continue}}let V={id:randomUUID(),command:y.command,...y.command==="content-sync"?{ruleId:y.id,coalesceKey:O,attempt:0}:{},...(y.command==="publish"||y.command==="crawl")&&y.crawlMode?{crawlMode:y.crawlMode}:{},...(y.command==="publish"||y.command==="deploy"||y.command==="invalidate"||y.command==="content-sync")&&y.deploymentProfile?{deploymentProfile:y.deploymentProfile}:{},...y.url?{url:y.url}:{},enqueueSource:"scheduler",...i.wpsuite?{wpsuite:i.wpsuite}:{},status:"queued",createdAt:new Date().toISOString(),createdBy:0};l.push(V),x.push(V),c.push({job:V,rule:y}),S.lastEnqueuedBucketByRuleId[y.id]=q,S.lastCreatedBucketByRuleId[y.id]=q,s+=1;}s>0&&await v(r,l),await v(ce(e.runtimeDir),S);});for(let l of c){if(l.rule.command==="content-sync"){let g=d.get(l.rule.id);await R(e.runtimeDir,{eventType:"content-sync-demand-detected",status:"queued",actorSource:"queue-runner-scheduler",jobId:l.job.id,command:l.job.command,message:"Pending journal changes require a content-sync job.",details:{ruleId:l.rule.id,headSequence:g?.headSequence??0,committedSequence:g?.committedSequence??0}});}await R(e.runtimeDir,{eventType:"job-created",status:"queued",actorSource:"queue-runner-scheduler",jobId:l.job.id,command:l.job.command,message:"Scheduler auto-enqueued a job.",details:{ruleId:l.rule.id,intervalMinutes:l.rule.intervalMinutes,timezone:i.timezone,deploymentProfile:l.rule.deploymentProfile||"",url:l.rule.url||""}});}for(let l of u)await R(e.runtimeDir,{eventType:"content-sync-coalesced",status:"queued",actorSource:"queue-runner-scheduler",command:l.command,message:"Scheduler demand was coalesced into an existing content-sync job.",details:{ruleId:l.id}});for(let l of p){if(l.check.status==="baseline-required"){let g=$(l.rule,i.publisherConfig);await $e(e,l.rule.id,g,l.check.reason||"A successful full or incremental publish must establish a new content-sync baseline.",l.check.headSequence,l.check.committedSequence);}await R(e.runtimeDir,{eventType:l.check.status==="baseline-required"?"content-sync-baseline-required":"content-sync-demand-check-failed",status:l.check.status==="unavailable"?"failed":"info",actorSource:"queue-runner-scheduler",command:"content-sync",message:l.check.reason||"The content-sync consumer is already at the current journal head.",details:{ruleId:l.rule.id,headSequence:l.check.headSequence??0,committedSequence:l.check.committedSequence??0}});}return s}async function Wt(e){let t={pid:process.pid,startedAt:new Date().toISOString()};await P.writeFile(e,JSON.stringify(t,null,2),{encoding:"utf8",flag:"wx"});}async function $t(e){try{await P.unlink(e);}catch{}}function Nt(e,t){let n=[h.join(e,"dist",`${t}.js`),h.join(e,`${t}.js`)];for(let i of n)if(existsSync(i))return i;throw new Error(`Cannot find ${t}.js in ${h.join(e,"dist")} or ${e}`)}async function k(e,t,n,i,r,a,o){if(o){let u=await Fe(t,o);if(u)throw new N(u,n)}let s=Nt(e,n),c={...process.env,...a??{}};return c.STATIC_PUBLISHER_RUNTIME_DIR=t,r&&(c.PUBLISHER_CONFIG=r),await new Promise((u,p)=>{let d=null,m=null,f=null,b=null,l=false,g="",S=spawn(process.execPath,[s,...i],{cwd:e,env:c,stdio:["inherit","inherit","pipe"]});S.stderr?.on("data",A=>{g+=A.toString("utf8");});let x=()=>{m&&clearInterval(m),f&&clearInterval(f),b&&clearTimeout(b);},y=async()=>{if(!(!o||d||l)){l=true;try{let A=await Fe(t,o);if(!A)return;d=A,S.kill("SIGTERM"),b=setTimeout(()=>{S.kill("SIGKILL");},1e4);}finally{l=false;}}};o&&(m=setInterval(()=>{y();},1e3),f=setInterval(()=>{(async()=>{let A=Me(t),q=await w(A,{});await v(A,{...q,checkedAt:new Date().toISOString(),status:"running",currentJobId:o||q.currentJobId||"",currentStep:n});})().catch(()=>{});},15e3)),S.on("error",A=>{x(),p(A);}),S.on("close",(A,q)=>{x();let j=be(g).trim();if(j&&process.stderr.write(`${j}
|
|
3
|
-
`),d){p(new N(d,n));return}if(A===0)u();else {let O=Re(j);p(new Error(`${n} exited with code ${A??-1}${q?` (signal ${q})`:""}${O?`: ${O}`:""}`));}});}),0}function Qt(e){let t=e.awsTempCreds;if(!t)return {};let n={};return typeof t.accessKeyId=="string"&&t.accessKeyId.trim()!==""&&(n.AWS_ACCESS_KEY_ID=t.accessKeyId.trim()),typeof t.secretAccessKey=="string"&&t.secretAccessKey.trim()!==""&&(n.AWS_SECRET_ACCESS_KEY=t.secretAccessKey.trim()),typeof t.sessionToken=="string"&&t.sessionToken.trim()!==""&&(n.AWS_SESSION_TOKEN=t.sessionToken.trim()),n}async function Kt(e,t){let n=o=>{if(!o||typeof o!="object")return null;let s=o,c={...s.siteSettings??{},...String(s.accountId??"").trim()&&!s.siteSettings?.accountId?{accountId:String(s.accountId).trim()}:{},...String(s.siteId??"").trim()&&!s.siteSettings?.siteId?{siteId:String(s.siteId).trim()}:{},...s.siteSettings?.subscriber===true||s.subscriber===true?{subscriber:true}:{}},u={...String(s.apiBase??"").trim()?{apiBase:String(s.apiBase).trim()}:{},...String(s.runtimeToken??s.nonce??"").trim()?{runtimeToken:String(s.runtimeToken??s.nonce).trim()}:{},...String(s.virtualAssetBaseUrl??s.uploadUrl??"").trim()?{virtualAssetBaseUrl:String(s.virtualAssetBaseUrl??s.uploadUrl).trim()}:{},...Object.keys(c).length>0?{siteSettings:c}:{},...s.subscriptionType?{subscriptionType:s.subscriptionType}:{}};return Object.keys(u).length>0?u:null},i=await K(t.configPath).catch(()=>null),r=n(i?.wpsuite);if(r)return r;let a=n(e.wpsuite);return a||null}async function zt(e,t){return await Kt(e,t)}function pe(e){let t={...e,status:"queued"};return delete t.startedAt,delete t.endedAt,delete t.exitCode,delete t.error,delete t.stopRequestedAt,delete t.stopRequestedByUserId,delete t.stopRequestedByLogin,delete t.stopMode,delete t.stoppedStep,t}async function _t(e,t){let n=await w(ge(e.runtimeDir),null),i=n&&n.details&&typeof n.details.phase=="string"?n.details.phase.trim():"";if(i)return i;let r=n&&typeof n.currentStep=="string"?n.currentStep.trim():"";if(r)return r;let a=await Ue(e).catch(()=>"");if(a){let o=await w(h.join(a,"current-crawl-event.json"),null),s=o&&typeof o.currentStep=="string"?o.currentStep.trim():"";if(s)return s}return t}function Ht(e,t){if((e.command==="publish"||e.command==="crawl")&&t==="rewrite-text")return "rewrite-text"}async function Vt(e){let t=h.join(e.runtimeDir,"queue.json"),n=h.join(e.runtimeDir,"current-run.json"),i=await F(e.runtimeDir,async()=>{let r=await w(n,null);if(!r||r.status!=="running"&&r.status!=="queued")return null;let a=await w(t,[]),o=Array.isArray(a)?a.filter(c=>c?.id!==r.id):[],s=pe(r);return await v(t,[s,...o]),await v(n,null),s});i&&(await W(e.runtimeDir,i.id),await R(e.runtimeDir,{eventType:"job-recovered",status:"queued",actorSource:"queue-runner",jobId:i.id,command:i.command,message:"Recovered stale current-run entry back into queue."}));}async function U(e,t){if(e.resumeFromStep==="rewrite-text")return;let n=h.join(t.runtimeDir,"privacy","cookie-observations.json"),i;try{let s=await P.stat(n);if(!s.isFile()||s.size>5*1024*1024)throw new Error("Cookie observation artifact is missing or exceeds 5 MiB.");i=JSON.parse(await P.readFile(n,"utf8"));}catch(s){if((s&&typeof s=="object"&&"code"in s?String(s.code||""):"")==="ENOENT")return;throw s}let r=await K(t.configPath),a=String(r.wpsuite?.runtimeToken||"").trim();if(!a)return;await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"consent-cookie-observations"}),await new L({sourceOrigin:r.sourceOrigin,runtimeToken:a,ignoreHttpsErrors:!!r.ignoreHttpsErrors}).importCookieObservations(i);}async function Gt(e,t,n){try{if((n.shouldEnforceSubscriptionOnJobExecution?.(e)??n.enforceSubscriptionOnJobExecution)&&n.assertActiveSubscriptionForIdentity){let s=await zt(e,t);await n.assertActiveSubscriptionForIdentity(s);}let r=Qt(e),a=e.resumeFromStep==="rewrite-text"?["--resume-rewrite"]:e.crawlMode==="incremental"?["--crawl-mode","incremental"]:[],o=e.deploymentProfile?["--profile",e.deploymentProfile]:[];if(e.command==="publish")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"content-sync-release-cutoff"}),await k(t.exporterDir,t.runtimeDir,"content-sync",["--capture-baseline-cutoffs",e.id],t.configPath,r,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:e.resumeFromStep==="rewrite-text"?"rewrite-text":"crawl"}),await k(t.exporterDir,t.runtimeDir,"crawl",a,t.configPath,r,e.id),await U(e,t),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"deploy"}),await k(t.exporterDir,t.runtimeDir,"deploy",o,t.configPath,r,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"invalidate"}),await k(t.exporterDir,t.runtimeDir,"invalidate",o,t.configPath,r,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"content-sync-baseline"}),await k(t.exporterDir,t.runtimeDir,"content-sync",["--establish-baselines",e.id],t.configPath,r,e.id),{exitCode:0};if(e.command==="crawl")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:e.resumeFromStep==="rewrite-text"?"rewrite-text":"crawl"}),await k(t.exporterDir,t.runtimeDir,"crawl",a,t.configPath,r,e.id),await U(e,t),{exitCode:0};if(e.command==="deploy")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"deploy"}),await k(t.exporterDir,t.runtimeDir,"deploy",o,t.configPath,r,e.id),{exitCode:0};if(e.command==="invalidate")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"invalidate"}),await k(t.exporterDir,t.runtimeDir,"invalidate",o,t.configPath,r,e.id),{exitCode:0};if(e.command==="retry-timeouts")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"retry-timeouts"}),await k(t.exporterDir,t.runtimeDir,"crawl",["--retry-timeouts"],t.configPath,r,e.id),await U(e,t),{exitCode:0};if(e.command==="url"){let s=(e.url||"").trim();return s?(await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"url"}),await k(t.exporterDir,t.runtimeDir,"crawl",["--url",s],t.configPath,r,e.id),await U(e,t),{exitCode:0}):{exitCode:2,error:"Missing url for command 'url'"}}return e.command==="content-sync"?!e.ruleId||!e.coalesceKey?{exitCode:2,error:"Content-sync queue jobs require ruleId and coalesceKey."}:(await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"content-sync"}),await k(t.exporterDir,t.runtimeDir,"content-sync",["--job-id",e.id],t.configPath,r,e.id),await U(e,t),{exitCode:0}):{exitCode:2,error:`Unsupported command: ${e.command}`}}catch(i){return i instanceof N?{exitCode:130,error:"Job stop requested.",stopped:true,stopRequest:i.request,stoppedStep:i.step}:{exitCode:1,error:i instanceof Error?i.message:String(i)}}}function Ne(e){return async function(n=process.argv.slice(2)){let i=It(n),r=h.join(i.runtimeDir,"export.lock"),a=h.join(i.runtimeDir,"last-run.json");await E(i.runtimeDir),await C(i,"starting",{message:"queue-runner starting"});try{await Wt(r);}catch(o){if((o&&typeof o=="object"&&"code"in o?String(o.code||""):"")!=="EEXIST")throw o;console.log("[queue-runner] lock active, skipping"),await C(i,"lock-active",{message:"lock active, skipped this cron tick"});return}try{await Vt(i);let o=await Ut(i,e),s=0;for(let c=0;c<i.maxJobs;c++){let u=await en(i,e);if(u==="none"||(s+=1,u==="stopped"))break}if(s===0)await E(i.runtimeDir),await C(i,"idle",{processedJobs:s,schedulerEnqueued:o,message:"no queued jobs"});else {await E(i.runtimeDir);let c=await w(a,null),u=String(c?.status||"").trim();await C(i,u==="success"?"job-success":u==="stopped"?"job-stopped":"job-failed",{processedJobs:s,schedulerEnqueued:o,lastJobId:c?.id,lastJobCommand:c?.command,lastJobStatus:c?.status,lastJobExitCode:c?.exitCode,lastJobError:c?.error,...u==="stopped"?{currentStep:c?.stoppedStep,stopRequestedAt:c?.stopRequestedAt,stopRequestedByLogin:c?.stopRequestedByLogin,stopRequestedMode:c?.stopMode,lastStoppedStep:c?.stoppedStep,message:c?.stopMode==="requeue"?`Job stopped during ${c?.stoppedStep||c?.command||"active step"} and requeued.`:`Job stopped during ${c?.stoppedStep||c?.command||"active step"} and left out of queue.`}:{}});}}catch(o){let s=o instanceof Error?o.message:String(o);throw await C(i,"error",{message:s}),await R(i.runtimeDir,{eventType:"queue-runner-error",status:"failed",actorSource:"queue-runner",message:"Unhandled queue-runner error.",details:{error:s}}),o}finally{await $t(r);}}}async function Oe(e,t){if(t.command!=="content-sync"||!t.coalesceKey)return false;let n=se(e.runtimeDir),i=await Te(n,t.coalesceKey),r=await qe(n),a=r.rules[t.coalesceKey];return a&&(r.rules[t.coalesceKey]={...a,trailingWorkDetected:true,retryAttempt:0,nextRetryAt:null,lastError:null},await De(n,r)),i}async function Yt(e,t,n){let i=h.join(e.runtimeDir,"queue.json"),r=h.join(e.runtimeDir,"current-run.json");await F(e.runtimeDir,async()=>{let a=await w(i,[]),o=Array.isArray(a)?a.filter(u=>u?.id!==t.id):[],s=pe(t),c=Ht(t,n);c?s.resumeFromStep=c:delete s.resumeFromStep,await v(i,[s,...o]),await v(r,null);});}async function Zt(e,t,n){let i=Math.max(0,t.attempt??0)+1,r=Math.min(3600*1e3,6e4*2**(i-1)),a=Math.floor(r*.2*Math.random()),o=new Date(Date.now()+r+a).toISOString(),s={...pe(t),status:"retry-wait",attempt:i,nextAttemptAt:o,error:n};if(await F(e.runtimeDir,async()=>{let c=h.join(e.runtimeDir,"queue.json"),u=h.join(e.runtimeDir,"current-run.json"),d=(await w(c,[])).filter(m=>m.id!==t.id);await v(c,[s,...d]),await v(u,null);}),t.coalesceKey){let c=h.join(e.runtimeDir,"content-sync-state.json"),p=(await w(c,{})).rules??{};p[t.coalesceKey]={...p[t.coalesceKey]??{},ruleId:t.ruleId||"",coalesceKey:t.coalesceKey,retryAttempt:i,nextRetryAt:o,lastError:n,trailingWorkDetected:true},await v(c,{schemaVersion:1,updatedAt:new Date().toISOString(),rules:p});}return s}async function Xt(e,t){if(!t.coalesceKey||!t.ruleId||!(await w(h.join(e.runtimeDir,"content-sync-state.json"),null))?.rules?.[t.coalesceKey]?.trailingWorkDetected)return null;let i=null;await F(e.runtimeDir,async()=>{let a=h.join(e.runtimeDir,"queue.json"),o=await w(a,[]);de(o,{command:"content-sync",coalesceKey:t.coalesceKey,deploymentProfile:t.deploymentProfile})||(i={id:randomUUID(),command:"content-sync",ruleId:t.ruleId,coalesceKey:t.coalesceKey,deploymentProfile:t.deploymentProfile,enqueueSource:"scheduler",wpsuite:t.wpsuite,status:"queued",attempt:0,createdAt:new Date().toISOString(),createdBy:0},await v(a,[...o,i]));});let r=i;return r&&await R(e.runtimeDir,{eventType:"content-sync-trailing-job-created",status:"queued",actorSource:"queue-runner",jobId:r.id,command:r.command,message:"Content changes after the stable cutoff created one trailing job.",details:{predecessorJobId:t.id,ruleId:t.ruleId,coalesceKey:t.coalesceKey}}),r}async function en(e,t){let n=h.join(e.runtimeDir,"queue.json"),i=h.join(e.runtimeDir,"current-run.json"),r=h.join(e.runtimeDir,"last-run.json"),a=new Date().toISOString(),o=await F(e.runtimeDir,async()=>{let d=await w(n,[]);if(!Array.isArray(d)||d.length===0)return null;let m=Date.parse(String(d[0]?.nextAttemptAt||""));if(Number.isFinite(m)&&m>Date.now())return null;let f={...d[0],status:"running",startedAt:a};return delete f.nextAttemptAt,await v(n,d.slice(1)),await v(i,f),f});if(!o)return "none";await E(e.runtimeDir),await R(e.runtimeDir,{eventType:"job-run-started",status:"running",actorSource:"queue-runner",jobId:o.id,command:o.command,message:"Job execution started.",details:{createdAt:o.createdAt||"",startedAt:a,createdBy:o.createdBy??null,deploymentProfile:o.deploymentProfile||"",queuedWithTempAwsCreds:!!o.awsTempCreds}}),await C(e,"running",{currentJobId:o.id,currentJobCommand:o.command,currentStep:o.command});let s=await Gt(o,e,t),c=new Date().toISOString();if(s.stopped){let d=await _t(e,s.stoppedStep||o.command),m=s.stopRequest?.mode==="requeue"?"requeue":"stop",f={...o,status:"stopped",endedAt:c,exitCode:s.exitCode,...s.error?{error:s.error}:{},stopRequestedAt:s.stopRequest?.requestedAt||"",stopRequestedByUserId:typeof s.stopRequest?.requestedByUserId=="number"?s.stopRequest.requestedByUserId:null,stopRequestedByLogin:s.stopRequest?.requestedByLogin||"",stopMode:m,stoppedStep:d},b=false;m==="requeue"?await Yt(e,o,d):(await v(i,null),b=await Oe(e,o));try{let l=await _(f,e);f.logArchiveDir=l.archiveDir,f.logArchiveCreatedAt=l.archiveCreatedAt,f.logArchiveFileCount=l.archivedFiles.length;}catch(l){f.logArchiveError=l instanceof Error?l.message:String(l);}return await v(r,f),await W(e.runtimeDir,o.id),await E(e.runtimeDir),await R(e.runtimeDir,{eventType:"job-run-stopped",status:"stopped",actorSource:"queue-runner",jobId:o.id,command:o.command,message:m==="requeue"?"Job stop requested and requeued.":"Job stop requested and removed from active execution without requeue.",details:{startedAt:o.startedAt||"",endedAt:c,deploymentProfile:o.deploymentProfile||"",stopMode:m,stopRequestedAt:s.stopRequest?.requestedAt||"",stopRequestedByLogin:s.stopRequest?.requestedByLogin||"",stopRequestedByUserId:typeof s.stopRequest?.requestedByUserId=="number"?s.stopRequest.requestedByUserId:null,stoppedStep:d,logArchiveKey:f.logArchiveError||!f.logArchiveDir?"":h.basename(f.logArchiveDir),logArchiveDir:f.logArchiveDir||"",logArchiveCreatedAt:f.logArchiveCreatedAt||"",logArchiveFileCount:f.logArchiveFileCount??0,logArchiveError:f.logArchiveError||"",contentSyncAbandoned:b,journalCursorPreserved:b}}),"stopped"}if(o.command==="content-sync"&&s.exitCode!==0){if(/baseline (?:is missing or stale|required)|verified content-sync baseline|new baseline/i.test(s.error||"")){let b="The installed release no longer matches the verified content-sync baseline. Run a successful full or incremental publish to establish a new baseline.";o.ruleId&&o.coalesceKey&&await $e(e,o.ruleId,o.coalesceKey,b);let l={...o,status:"failed",endedAt:c,exitCode:s.exitCode,error:b};await v(i,null),await E(e.runtimeDir),await Oe(e,o);try{let g=await _(l,e);l.logArchiveDir=g.archiveDir,l.logArchiveCreatedAt=g.archiveCreatedAt,l.logArchiveFileCount=g.archivedFiles.length;}catch(g){l.logArchiveError=g instanceof Error?g.message:String(g);}return await v(r,l),await W(e.runtimeDir,o.id),await R(e.runtimeDir,{eventType:"content-sync-baseline-required",status:"failed",actorSource:"queue-runner",jobId:o.id,command:o.command,message:b,details:{ruleId:o.ruleId||"",retryScheduled:false}}),"processed"}await R(e.runtimeDir,{eventType:"content-sync-failed",status:"failed",actorSource:"queue-runner",jobId:o.id,command:o.command,message:"Content-sync execution failed before cursor acknowledgement.",details:{attempt:o.attempt??0,error:s.error||"Content-sync execution failed."}});let m=await Zt(e,o,s.error||"Content-sync execution failed."),f={...o,status:"retry-wait",endedAt:c,exitCode:s.exitCode,error:m.error,attempt:m.attempt,nextAttemptAt:m.nextAttemptAt};try{let b=await _(f,e);f.logArchiveDir=b.archiveDir,f.logArchiveCreatedAt=b.archiveCreatedAt,f.logArchiveFileCount=b.archivedFiles.length;}catch(b){f.logArchiveError=b instanceof Error?b.message:String(b);}return await v(r,f),await W(e.runtimeDir,o.id),await R(e.runtimeDir,{eventType:"content-sync-retry-scheduled",status:"retry-wait",actorSource:"queue-runner",jobId:o.id,command:o.command,message:"Content-sync retry was scheduled with bounded backoff.",details:{attempt:m.attempt??0,nextAttemptAt:m.nextAttemptAt||"",error:m.error||""}}),"processed"}let u={...o,status:s.exitCode===0?"success":"failed",endedAt:c,exitCode:s.exitCode,...s.error?{error:s.error}:{}};await v(i,null),u.status==="success"&&u.command==="content-sync"&&await Xt(e,u),await W(e.runtimeDir,o.id);try{let d=await _(u,e);u.logArchiveDir=d.archiveDir,u.logArchiveCreatedAt=d.archiveCreatedAt,u.logArchiveFileCount=d.archivedFiles.length;}catch(d){u.logArchiveError=d instanceof Error?d.message:String(d);}await v(r,u);let p=o.startedAt&&u.endedAt?Math.max(0,Math.round((new Date(u.endedAt).getTime()-new Date(o.startedAt).getTime())/1e3)):void 0;return await R(e.runtimeDir,{eventType:"job-run-finished",status:u.status==="success"?"success":"failed",actorSource:"queue-runner",jobId:u.id,command:u.command,message:u.status==="success"?"Job execution finished successfully.":"Job execution finished with failure.",details:{startedAt:o.startedAt||"",endedAt:u.endedAt||"",durationSec:p,deploymentProfile:u.deploymentProfile||"",exitCode:u.exitCode??null,error:u.error||"",logArchiveKey:u.logArchiveError||!u.logArchiveDir?"":h.basename(u.logArchiveDir),logArchiveDir:u.logArchiveDir||"",logArchiveCreatedAt:u.logArchiveCreatedAt||"",logArchiveFileCount:u.logArchiveFileCount??0,logArchiveError:u.logArchiveError||""}}),"processed"}async function nn(e){if(!e)throw new Error("Missing remote WPSuite publisher state. Refresh the runtime config before running subscription-gated jobs.");if(e.subscriptionType!=="PROFESSIONAL"&&e.subscriptionType!=="AGENCY")throw new Error("This job requires an active WPSuite publisher subscription in the remote site configuration.")}var rn={allowSchedulerAutoEnqueue:true,enforceSubscriptionOnJobExecution:false,shouldEnforceSubscriptionOnJobExecution:e=>Le(e)||e.enqueueSource==="scheduler"||e.createdBy===0,assertActiveSubscriptionForIdentity:nn},Qe=Ne(rn),on=Qe,Vn=Qe;process.argv[1]&&import.meta.url===pathToFileURL(process.argv[1]).href&&on().catch(e=>{console.error(e),process.exit(1);});export{Vn as default,on as main,Qe as runQueueRunner};
|
|
1
|
+
import {pathToFileURL}from'url';import P from'fs/promises';import {existsSync,createReadStream,createWriteStream}from'fs';import h from'path';import {spawn}from'child_process';import {randomUUID,createHash}from'crypto';import Ge from'http';import Se from'https';import {pipeline}from'stream/promises';import {createGzip}from'zlib';function he(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))].sort()}function Y(e){return Array.isArray(e)?e.map(Y):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,Y(n)])):e}function _e(e){return JSON.stringify(Y(e))}function J(e){return createHash("sha256").update(_e(e)).digest("hex")}function fe(e){return J({schemaVersion:1,wordpressFingerprint:e.wordpressFingerprint,targetFingerprint:e.targetFingerprint,sourceOrigin:e.sourceOrigin,sitemapPaths:[...e.sitemapPaths].sort(),blockedPathPrefixes:[...e.blockedPathPrefixes].sort(),assetPathPrefixes:[...e.assetPathPrefixes].sort(),noJavaScriptRenderPathPrefixes:[...e.noJavaScriptRenderPathPrefixes].sort(),urlRewriteMode:e.urlRewriteMode})}function He(e){let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error(`Unsupported source origin protocol: ${t.protocol}`);return t.hash="",t.search="",t.pathname=t.pathname.replace(/\/+$/,""),t.toString().replace(/\/$/,"")}function Q(e){let t=he((e.postTypes??[]).map(i=>String(i).toLowerCase().replace(/[^a-z0-9_-]/g,"")));if(t.length===0)throw new Error("Content-sync requires at least one public post type.");let n=he((e.listingPaths??[]).map(i=>{let r=String(i).trim();if(!r)return "";let a=new URL(r,"https://content-sync.invalid/");if(a.origin!=="https://content-sync.invalid"&&/^https?:\/\//i.test(r))throw new Error("Content-sync listing routes must be same-site paths.");let o=`/${a.pathname.replace(/^\/+|\/+$/g,"")}`;return o==="/"?"/":`${o}/`}));return {postTypes:t,listingPaths:n,includeSubsites:e.includeSubsites===true,includePostTypeArchives:e.includePostTypeArchives!==false,includeTaxonomyArchives:e.includeTaxonomyArchives!==false,includeAuthorArchives:e.includeAuthorArchives===true,includeDateArchives:e.includeDateArchives===true,includePostsPage:e.includePostsPage!==false,includeSitemapChain:e.includeSitemapChain!==false}}function Z(e,t,n){return J({schemaVersion:1,sourceOrigin:He(e),ruleId:t.trim(),scope:Q(n)})}function X(e){return J({schemaVersion:1,...e})}function be(e){return e.replace(/((?:x-static-publisher-token|authorization|proxy-authorization|x-api-key|aws-access-key-id|aws-secret-access-key|aws-session-token)\s*:\s*)[^\r\n]+/gi,"$1[REDACTED]").replace(/\b(Basic|Bearer)\s+[^\s]+/gi,"$1 [REDACTED]").replace(/([?&](?:token|access_token|refresh_token|api_key|key|nonce)=)[^&\s]+/gi,"$1[REDACTED]").replace(/((?:"|')?(?:runtimeToken|siteKey|nonce|accessToken|refreshToken|accessKeyId|secretAccessKey|sessionToken)(?:"|')?\s*[:=]\s*(?:"|'))[^"']+/gi,"$1[REDACTED]")}var ye=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";ye?h.join(ye,"current-progress.json"):"";Promise.resolve();var Ye="wp-json/smartcloud-static-publisher/v1/content-sync/",Ze=25*1024*1024,T=class extends Error{status;code;constructor(t,n,i){super(i),this.name="ContentSyncApiError",this.status=t,this.code=n;}},L=class{options;constructor(t){if(!t.runtimeToken.trim())throw new Error("Content-sync requires a WordPress runtime token.");this.options={...t,timeoutMs:t.timeoutMs??6e4};}endpoint(t,n="content-sync"){let i=this.options.sourceOrigin.replace(/\/+$/,"")+"/",r=n==="content-sync"?Ye:`wp-json/smartcloud-static-publisher/v1/${n}/`;return new URL(`${r}${t}`,i)}async post(t,n,i="content-sync"){let r=this.endpoint(t,i),a=Buffer.from(JSON.stringify(n),"utf8"),o=r.protocol==="https:"?Se:Ge,s=r.protocol==="https:"?new Se.Agent({rejectUnauthorized:!this.options.ignoreHttpsErrors}):void 0;return new Promise((c,u)=>{let g=o.request(r,{method:"POST",agent:s,headers:{"content-type":"application/json","content-length":String(a.byteLength),"x-static-publisher-token":this.options.runtimeToken},timeout:this.options.timeoutMs},d=>{let m=[],f=0;d.on("data",b=>{if(f+=b.byteLength,f>Ze){d.destroy(new Error("Content-sync API response exceeded the size limit."));return}m.push(b);}),d.on("error",u),d.on("end",()=>{let b=Buffer.concat(m).toString("utf8"),l;try{l=b?JSON.parse(b):{};}catch{u(new T(d.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let p=d.statusCode??500;if(p<200||p>=300){u(new T(p,String(l.code??"request-failed"),String(l.message??`Content-sync API request failed (${p}).`)));return}c(l);});});g.on("timeout",()=>g.destroy(new Error(`Content-sync API request timed out: ${t}`))),g.on("error",u),g.end(a);})}async head(t){return this.post("head",t)}async unboundHead(t,n){return this.post("head",{postTypes:t,includeSubsites:n})}async events(t){let n=[],i=t.afterSequence,r=new Set(t.postTypes);for(;i<t.throughSequence;){let a=await this.post("events",{...t,afterSequence:i,limit:250});if(a.fromSequence!==i||a.throughSequence!==t.throughSequence||a.nextSequence<i||a.nextSequence>t.throughSequence)throw new Error("Content-sync API returned an inconsistent event page.");if(!Array.isArray(a.items))throw new Error("Content-sync API returned a malformed event page.");let o=i;for(let s of a.items){if(!Number.isSafeInteger(s.sequence)||s.sequence<=o||s.sequence>t.throughSequence||!Number.isSafeInteger(s.postId)||s.postId<=0||!Number.isSafeInteger(s.blogId)||s.blogId<=0||!r.has(s.postType)||typeof s.operation!="string"||!s.operation)throw new Error("Content-sync API returned an invalid or out-of-scope journal event.");o=s.sequence;}if(a.items.length>0&&a.nextSequence!==o)throw new Error("Content-sync API event cursor does not match the final returned event.");if(n.push(...a.items),!a.hasMore)break;if(a.nextSequence===i)throw new Error("Content-sync API event pagination did not advance.");i=a.nextSequence;}if(t.throughSequence>t.afterSequence&&n.at(-1)?.sequence!==t.throughSequence)throw new Error("Content-sync API omitted the claimed journal high-water event.");return n}async resolveImpactFamilies(t,n){let i=await this.post("impact",{families:t,includeSubsites:n});return Array.isArray(i.families)?i.families:[]}async releaseFingerprint(t=false){let n=await this.post("fingerprint",{includeSubsites:t}),i=String(n.fingerprint||"").trim();if(!/^[a-f0-9]{64}$/.test(i))throw new Error("WordPress returned an invalid release fingerprint.");return i}async establishBaseline(t){return this.post("baseline",t)}async acknowledge(t){return this.post("ack",t)}async importCookieObservations(t){return this.post("cookie-observations",t,"privacy")}};function Xe(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function et(e,t){return {...e,...t??{}}}function tt(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function ee(e,t){let n=String(t??e.deploymentTargetOverride??"").trim();if(!Xe(e)){if(n)throw new Error(`Deployment target "${n}" requires an active WPSuite subscription and remote publisher config.`);return {name:null,profile:null,config:e}}let i=String(n||e.defaultDeploymentProfile||"").trim();if(!i)return {name:null,profile:null,config:e};let r=e.deploymentProfiles?.[i];if(!r)throw new Error(`Unknown deployment profile "${i}". Check the linked WPSuite publisher configuration.`);return {name:i,profile:r,config:{...e,targetOrigin:r.targetOrigin??e.targetOrigin,s3:et(e.s3,r.s3),cloudFront:tt(e.cloudFront,r.cloudFront)}}}var te=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function we(e){let t=new Set;for(let n of [...e,...te]){let i=String(n||"").trim();i&&t.add(i);}return [...t]}function Pe(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function ot(e){let t=String(e??"").trim();if(!t)return "";let n=t;if(/^https?:\/\//i.test(n))try{n=new URL(n).pathname;}catch{return ""}if(n=n.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!n)return "";let i=n.endsWith("/"),r=n.replace(/^\/+/,"").split("/").map(o=>o.replace(/[^A-Za-z0-9._-]/g,"")).filter(o=>o.length>0&&o!=="."&&o!=="..");if(r.length===0)return "";let a=`/${r.join("/")}`;return i&&h.extname(a)===""&&(a+="/"),a==="/"?"":a}function ne(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t.trim(),String(n??"")]).filter(([t])=>t.length>0))}function st(e){if(!e||typeof e!="object")return {};let t={};for(let[n,i]of Object.entries(e)){let r=n.trim();if(!r||!i||typeof i!="object")continue;let a=i,o={};if(typeof a.targetOrigin=="string"){let c=Pe(a.targetOrigin);c&&(o.targetOrigin=c);}let s=ne(a.extraReplacements);if(Object.keys(s).length>0&&(o.extraReplacements=s),a.s3&&typeof a.s3=="object"){let c={},u=a.s3;typeof u.bucket=="string"&&(c.bucket=u.bucket.trim()),typeof u.prefix=="string"&&(c.prefix=u.prefix.trim()),typeof u.region=="string"&&(c.region=u.region.trim()),typeof u.htmlCacheControl=="string"&&(c.htmlCacheControl=u.htmlCacheControl.trim()),typeof u.assetCacheControl=="string"&&(c.assetCacheControl=u.assetCacheControl.trim()),Object.keys(c).length>0&&(o.s3=c);}if(a.cloudFront&&typeof a.cloudFront=="object"){let c={},u=a.cloudFront;typeof u.distributionId=="string"&&(c.distributionId=u.distributionId.trim()),Array.isArray(u.invalidationPaths)&&(c.invalidationPaths=u.invalidationPaths.map(g=>String(g??"").trim()).filter(g=>g.length>0)),Object.keys(c).length>0&&(o.cloudFront=c);}t[r]=o;}return t}function ie(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function at(e,t){if(!e||typeof e!="object")return null;let n=e,i=n.command;if(i!=="publish"&&i!=="crawl"&&i!=="deploy"&&i!=="invalidate"&&i!=="retry-timeouts"&&i!=="url"&&i!=="content-sync")return null;let r=Number.parseInt(String(n.intervalMinutes??"0"),10);if(!Number.isFinite(r)||r<1)return null;let a=String(n.id??`${i}-${t+1}`).trim();if(!a)return null;let o=String(n.deploymentProfile??"").trim(),s=String(n.url??"").trim(),c=Array.isArray(n.postTypes)?[...new Set(n.postTypes.map(g=>String(g??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],u=Array.isArray(n.listingPaths)?[...new Set(n.listingPaths.map(g=>String(g??"").trim()).filter(Boolean))]:[];return i==="content-sync"&&c.length===0?null:{id:a,enabled:n.enabled!==false,command:i,intervalMinutes:r,...i==="publish"||i==="crawl"?{crawlMode:n.crawlMode==="incremental"?"incremental":"full"}:{},...(i==="publish"||i==="deploy"||i==="invalidate"||i==="content-sync")&&o?{deploymentProfile:o}:{},...s?{url:s}:{},...c.length>0?{postTypes:c}:{},...u.length>0?{listingPaths:u}:{},...typeof n.includeSubsites=="boolean"?{includeSubsites:n.includeSubsites}:{},...typeof n.includePostTypeArchives=="boolean"?{includePostTypeArchives:n.includePostTypeArchives}:{},...typeof n.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:n.includeTaxonomyArchives}:{},...typeof n.includeAuthorArchives=="boolean"?{includeAuthorArchives:n.includeAuthorArchives}:{},...typeof n.includeDateArchives=="boolean"?{includeDateArchives:n.includeDateArchives}:{},...typeof n.includePostsPage=="boolean"?{includePostsPage:n.includePostsPage}:{},...typeof n.includeSitemapChain=="boolean"?{includeSitemapChain:n.includeSitemapChain}:{}}}function Ce(e){let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.rules)?t.rules.map((i,r)=>at(i,r)).filter(i=>!!i):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:n}}function ct(e){let t=e&&typeof e=="object"?e:{},n=t.render&&typeof t.render=="object"?t.render:{},i=Number(n.concurrency??0),r=Number(n.batchSize??0),a=Number(n.maxAttempts??0),o=t.rewrite&&typeof t.rewrite=="object"?t.rewrite:{},s=t.deploy&&typeof t.deploy=="object"?t.deploy:{},c=(u,g)=>({enabled:typeof u.enabled=="boolean"?u.enabled:n.enabled===true,concurrency:Math.min(100,Math.max(1,Number(u.concurrency||g.concurrency))),batchSize:Math.min(500,Math.max(1,Number(u.batchSize||g.batchSize))),maxAttempts:Math.min(5,Math.max(1,Number(u.maxAttempts||2)))});return {render:{enabled:n.enabled===true,...Number.isInteger(i)&&i>0?{concurrency:i}:{},batchSize:Number.isInteger(r)&&r>0?Math.min(20,r):5,...Number.isInteger(a)&&a>0?{maxAttempts:Math.min(5,a)}:{}},rewrite:c(o,{concurrency:8,batchSize:25}),deploy:c(s,{concurrency:8,batchSize:50})}}function ut(e){if(!e||typeof e!="object")return;let t=e,n={};for(let r of ["accountId","siteId"]){let a=t[r];typeof a=="string"&&a.trim()!==""&&(n[r]=a.trim());}let i=Number(t.lastUpdate??0);return Number.isFinite(i)&&i>0&&(n.lastUpdate=Math.floor(i)),t.subscriber===true&&(n.subscriber=true),Object.keys(n).length>0?n:void 0}function oe(e){let t=e&&typeof e=="object"?e:{},n=String(t.accountId??"").trim(),i=String(t.siteId??"").trim(),r=t.subscriber===true,a=ut(t.siteSettings),o={...a??{},...n?{accountId:a?.accountId??n}:{},...i?{siteId:a?.siteId??i}:{},...a?.subscriber===true||r?{subscriber:true}:{}},s={},c=String(t.apiBase??"").trim();c&&(s.apiBase=c);let u=String(t.runtimeToken??t.nonce??"").trim();u&&(s.runtimeToken=u);let g=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();g&&(s.virtualAssetBaseUrl=g),Object.keys(o).length>0&&(s.siteSettings=o);let d=ie(t.subscriptionType);return d&&(s.subscriptionType=d),s}function lt(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Ae(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function dt(e,t){let n=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[i,r]of new Headers(t.headers).entries())n.set(i,r);return n}async function Ie(e,t,n=5){let i=new URL(Ae(e)),r=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),a=i.protocol==="http:"?Ge:Se,o=dt(e,t);return await new Promise((s,c)=>{let u=a.request(i,{method:r,headers:Object.fromEntries(o.entries()),...i.protocol==="https:"?{rejectUnauthorized:false}:{}},g=>{let d=[];g.on("data",m=>{d.push(Buffer.isBuffer(m)?m:Buffer.from(m));}),g.on("error",c),g.on("end",()=>{let m=g.statusCode??0,f=g.headers.location;if(n>0&&f&&[301,302,303,307,308].includes(m)){s(Ie(new URL(f,i),{method:m===303?"GET":r},n-1));return}let b=new Headers;for(let[l,p]of Object.entries(g.headers))Array.isArray(p)?b.set(l,p.join(", ")):typeof p=="string"&&b.set(l,p);s(new Response(Buffer.concat(d),{status:m,statusText:g.statusMessage??"",headers:b}));});});u.on("error",c),u.end();})}function gt(e){let t=oe(e.wpsuite),n={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},i=String(n.accountId??"").trim(),r=String(n.siteId??"").trim(),a=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();if(e.wpsuite={...t.apiBase?{apiBase:t.apiBase}:{},...t.runtimeToken?{runtimeToken:t.runtimeToken}:{},...a?{virtualAssetBaseUrl:a}:{},...Object.keys(n).length>0?{siteSettings:n}:{},...t.subscriptionType?{subscriptionType:t.subscriptionType}:{}},!i||!r||!a)return false;lt(e.sourceOrigin);let o=globalThis,c={...o.WpSuite??{},siteSettings:n,uploadUrl:a};return t.apiBase&&(c.apiBase=t.apiBase),o.WpSuite=c,true}async function pt(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!gt(e)){let r=e.wpsuite?.siteSettings,a=[String(r?.accountId??"").trim()?"":"accountId",String(r?.siteId??"").trim()?"":"siteId",t?"":"virtualAssetBaseUrl"].filter(Boolean);return {remote:null,diagnostic:{status:"invalid-runtime",virtualAssetBaseUrl:t,subscriptionType:null,error:`Missing WP Suite runtime field(s): ${a.join(", ")}.`,requests:[]}}}let n=globalThis.fetch,i=[];try{typeof n=="function"&&/^https?:\/\//i.test(t)&&(globalThis.fetch=(async(c,u)=>{let g=Ae(c);if(g.startsWith(t)){let d=(()=>{try{return new URL(g).pathname}catch{return g}})();try{let m=e.ignoreHttpsErrors&&g.startsWith("https://")?await Ie(c,u):await n(c,u);return i.push({path:d,status:m.status,ok:m.ok,error:null}),m}catch(m){throw i.push({path:d,status:null,ok:!1,error:m instanceof Error?m.message:String(m)}),m}}return n(c,u)}));let{getConfig:r}=await import('@smart-cloud/wpsuite-core'),a=await r("publisher"),o=a&&typeof a=="object"?a:null,s=ie(o?.subscriptionType);return {remote:o,diagnostic:{status:o?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:s??null,error:o?null:"WP Suite publisher config loader returned no configuration.",requests:i}}}catch(r){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:t,subscriptionType:null,error:r instanceof Error?r.message:String(r),requests:i}}}finally{typeof n=="function"&&(globalThis.fetch=n);}}function mt(e,t){let n=st(t?.deploymentProfiles),i=String(t?.defaultDeploymentProfile??"").trim(),r=n[i]?i:"",a=ie(t?.subscriptionType),o=oe(e.wpsuite);return {...e,scheduler:Ce(t?.scheduler),deploymentProfiles:n,defaultDeploymentProfile:r,...a?{subscriptionType:a}:{},wpsuite:{...o,...o.siteSettings||a?{siteSettings:{...o.siteSettings??{},...o.siteSettings?.subscriber===true||a==="PROFESSIONAL"||a==="AGENCY"?{subscriber:true}:{}}}:{},...a?{subscriptionType:a}:{}}}}function re(e,t){let i=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!i)return t;let r=i.split("/").map(a=>a.trim()).filter(a=>a.length>0&&a!=="."&&a!=="..");return r.length>0?r.join("/"):t}function ht(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?h.resolve(e):""}function ve(e,t,n){let i=String(t||"").trim();return i&&h.isAbsolute(i)?h.resolve(i):h.resolve(e,re(i,n))}async function z(e,t={}){let n=String(e??"").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",i=await P.readFile(n,"utf8"),r=JSON.parse(i);r.sourceOrigin=r.sourceOrigin.replace(/\/$/,""),r.targetOrigin=Pe(r.targetOrigin),r.ignoreHttpsErrors??=false,r.outputDir=String(r.outputDir||"export").trim()||"export",r.urlRewriteMode||=r.targetOrigin==="."?"relative":"absolute",r.noJavaScriptRenderPathPrefixes||=[],r.seedPaths||=[],r.generated404RequestPath=ot(r.generated404RequestPath),r.sitemapPaths||=[...te],r.allowedAssetHosts||=[],r.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],r.blockedPathPrefixes||=[],r.blockedSearchFragments||=[];let a=Number(r.processingConcurrency)>0?Math.min(100,Math.max(1,Number(r.processingConcurrency))):null;r.concurrency=a??r.concurrency??1,r.maxPages||=0,r.extraReplacements=ne(r.extraReplacements),r.postCrawlCopyMap=ne(r.postCrawlCopyMap),r.logDir=String(r.logDir||"logs").trim()||"logs",r.verbose??=false,r.logLevel||=r.verbose?"debug":"info",r.s3SyncMode||="sdk-upload-delete",r.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},r.readiness.timeoutMs??=1500,r.readiness.fallbackWaitMs??=1500,r.viewport||={width:1440,height:1200},r.navigationTimeoutMs||=3e4,r.assetDownloadConcurrency=a??(Number(r.assetDownloadConcurrency)>0?Number(r.assetDownloadConcurrency):r.concurrency),r.rewriteConcurrency=a??(Number(r.rewriteConcurrency)>0?Number(r.rewriteConcurrency):r.assetDownloadConcurrency),r.wpsuite=oe(r.wpsuite),r.scheduler=Ce(void 0),r.remoteWorkers=ct(r.remoteWorkers),typeof r.lambdaDelegationEnabled=="boolean"&&(r.remoteWorkers.render??={},r.remoteWorkers.rewrite??={},r.remoteWorkers.deploy??={},r.remoteWorkers.render.enabled=r.lambdaDelegationEnabled,r.remoteWorkers.rewrite.enabled=r.lambdaDelegationEnabled,r.remoteWorkers.deploy.enabled=r.lambdaDelegationEnabled),a!==null&&(r.processingConcurrency=a,r.remoteWorkers.render??={},r.remoteWorkers.rewrite??={},r.remoteWorkers.deploy??={},r.remoteWorkers.render.concurrency=a,r.remoteWorkers.rewrite.concurrency=a,r.remoteWorkers.deploy.concurrency=a),r.deploymentProfiles={},r.defaultDeploymentProfile="",r.deploymentTargetOverride=String(r.deploymentTargetOverride??"").trim();let o=await pt(r);t.onRemotePublisherConfigDiagnostic?.(o.diagnostic);let s=mt(r,o.remote),c=ht(),u=c?h.resolve(c,".."):"";return u?(s.outputDir=ve(u,s.outputDir,"export"),s.logDir=ve(u,s.logDir,"logs")):(h.isAbsolute(s.outputDir)||(s.outputDir=re(s.outputDir,"export")),h.isAbsolute(s.logDir)||(s.logDir=re(s.logDir,"logs"))),s}function Re(e){let t=e.split(/\r?\n/).map(i=>i.trim()).filter(Boolean),n=[...t].reverse().find(i=>/^(?:Error|[A-Za-z][A-Za-z0-9]*Error):\s/.test(i));return n||(t.find(i=>!i.startsWith("at "))??"")}function se(e){let t=h.resolve(e);return {state:h.join(t,"content-sync-state.json"),current:h.join(t,"content-sync-current.json"),impact:h.join(t,"content-sync-impact-plan.json"),checkpoint:h.join(t,"content-sync-checkpoint.json"),baseline:h.join(t,"content-sync-baseline.json"),activeRules:h.join(t,"content-sync-active-rules.json"),releaseCutoff:h.join(t,"content-sync-release-cutoff.json"),candidateManifest:h.join(t,"content-sync-candidate-manifest.json"),trustedManifest:h.join(t,"crawl-manifest.json"),invalidation:h.join(t,"content-sync-invalidation.json"),deployPlan:h.join(t,"deploy-plan.json")}}async function M(e,t,n=[],i=[],r=false){await xe(e.activeRules,{contractVersion:1,evaluatedAt:new Date().toISOString(),discoveryReady:r,entries:t,targets:n,rules:i});}async function xe(e,t){await P.mkdir(h.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${Date.now()}.tmp`;await P.writeFile(n,JSON.stringify(t,null,2),"utf8"),await P.rename(n,e);}async function ke(e){try{return JSON.parse(await P.readFile(e,"utf8"))}catch(t){if(t.code==="ENOENT")return null;throw new Error(`Invalid or unreadable content-sync state file ${e}: ${t instanceof Error?t.message:String(t)}`,{cause:t})}}async function ft(e){let t=await ke(e.current);if(t===null)return null;let n=t;if(n.schemaVersion!==1||typeof n.jobId!="string"||typeof n.phase!="string"||!Number.isSafeInteger(n.fromSequence)||!Number.isSafeInteger(n.toSequence))throw new Error("Invalid content-sync current-range state.");return n}async function qe(e){let t=await ke(e.state);if(t===null)return {schemaVersion:1,updatedAt:"",rules:{}};let n=t;if(n.schemaVersion!==1||typeof n.updatedAt!="string"||!n.rules||typeof n.rules!="object"||Array.isArray(n.rules))throw new Error("Invalid content-sync state store.");return n}async function De(e,t){await xe(e.state,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Te(e,t){let n=await ft(e);return !n||n.coalesceKey!==t?false:(await Promise.all([e.current,e.checkpoint,e.impact,e.candidateManifest,e.invalidation,e.deployPlan].map(async i=>{try{await P.unlink(i);}catch(r){if(r.code!=="ENOENT")throw r}})),true)}function Le(e){let t=String(e.command??"").trim();return (t==="publish"||t==="crawl")&&e.crawlMode==="incremental"||t==="content-sync"}var ae=new Map;async function Ee(e){let t=h.resolve(e),n=ae.get(t);if(n!==void 0)return n;try{let i=JSON.parse(await P.readFile(t,"utf8")),r=String(i.version??"").trim();return ae.set(t,r),r}catch{return ae.set(t,""),""}}var $=class extends Error{request;step;constructor(t,n){super(`Stop requested during ${n}.`),this.name="StopRequestedError",this.request=t,this.step=n;}},Pt="queue-mutation.lock",Ct=5e3,At=3e4;function It(e){let t=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",n=process.env.STATIC_PUBLISHER_EXPORTER_DIR||process.cwd(),i=process.env.PUBLISHER_CONFIG||"",r=1;for(let s=0;s<e.length;s++){let c=e[s];c==="--runtime-dir"?t=e[++s]||"":c.startsWith("--runtime-dir=")?t=c.slice(14):c==="--exporter-dir"?n=e[++s]||n:c.startsWith("--exporter-dir=")?n=c.slice(15):c==="--config"?i=e[++s]||"":c.startsWith("--config=")?i=c.slice(9):c==="--max-jobs"?r=Number.parseInt(e[++s]||"1",10):c.startsWith("--max-jobs=")&&(r=Number.parseInt(c.slice(11),10));}if(!t)throw new Error("Missing runtime dir. Use --runtime-dir or STATIC_PUBLISHER_RUNTIME_DIR.");let a=h.resolve(t),o=i?h.resolve(i):h.join(a,"config.json");return {runtimeDir:a,exporterDir:h.resolve(n),configPath:o,maxJobs:Number.isFinite(r)&&r>0?r:1}}async function w(e,t){try{let n=await P.readFile(e,"utf8");return JSON.parse(n)}catch(n){if((n&&typeof n=="object"&&"code"in n?String(n.code||""):"")!=="ENOENT"){let r=n instanceof Error?n.message:String(n);console.warn(`[queue-runner] failed to read JSON ${e}: ${r}`);}return t}}async function v(e,t){await P.mkdir(h.dirname(e),{recursive:true}),await P.writeFile(e,JSON.stringify(t,null,2),"utf8");}function Be(e){return h.join(e,Pt)}async function Rt(e){await new Promise(t=>setTimeout(t,e));}async function xt(e){let t=Be(e),n=Date.now()+Ct;for(;;)try{await P.mkdir(h.dirname(t),{recursive:!0}),await P.writeFile(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()},null,2),{encoding:"utf8",flag:"wx"});return}catch(i){if((i&&typeof i=="object"&&"code"in i?String(i.code||""):"")!=="EEXIST")throw i;let a=await P.stat(t).catch(()=>null);if(a&&Date.now()-a.mtimeMs>At){await P.unlink(t).catch(()=>{});continue}if(Date.now()>=n)throw new Error("Timed out acquiring queue mutation lock.",{cause:i});await Rt(50);}}async function kt(e){await P.unlink(Be(e)).catch(()=>{});}async function F(e,t){await xt(e);try{return await t()}finally{await kt(e);}}function Me(e){return h.join(e,"queue-runner-heartbeat.json")}function ge(e){return h.join(e,"current-progress.json")}function ce(e){return h.join(e,"scheduler-state.json")}function qt(e,t){let i=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!i)return t;let r=i.split("/").map(a=>a.trim()).filter(a=>a.length>0&&a!=="."&&a!=="..");return r.length>0?r.join("/"):t}async function Ue(e){let t=await w(e.configPath||"",null),n=h.resolve(e.runtimeDir,".."),r=(typeof t?.logDir=="string"?t.logDir:"").trim();return r&&h.isAbsolute(r)?h.resolve(r):h.resolve(n,qt(r,"logs"))}function ue(e,t){return String(e||"").trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||t}function Dt(e){let t=e?new Date(e):new Date;return (Number.isNaN(t.getTime())?new Date:t).toISOString().replace(/[-:]/g,"").replace(/\.\d{3}Z$/,"Z")}function Tt(e){return [Dt(e.endedAt||e.startedAt),ue(e.command||"job","job"),ue(e.id||"job","job"),ue(e.status||"finished","finished")].join("-")}function Et(e){return e.endsWith(".log.jsonl")||e.endsWith(".errors.jsonl")||e.endsWith(".rejected.jsonl")?true:["current-crawl-event.json","rejected.jsonl","ignored.jsonl","skipped-http.jsonl","errors.jsonl","timings.jsonl","rejected.json","ignored.json","skipped-http.json","errors.json","timings.json"].includes(e)}function Ft(e){return e==="errors.json"||e==="errors.jsonl"||e.endsWith(".errors.jsonl")?"errors":e==="ignored.json"||e==="ignored.jsonl"?"ignored":e==="rejected.json"||e==="rejected.jsonl"||e.endsWith(".rejected.jsonl")?"rejected":e==="skipped-http.json"||e==="skipped-http.jsonl"?"skipped-http":e==="timings.json"||e==="timings.jsonl"?"timings":e==="current-progress.json"?"current-progress":e==="current-crawl-event.json"?"current-crawl-event":e.endsWith(".log.jsonl")?e.replace(/\.log\.jsonl$/i,"-log"):e.replace(/\.[^.]+$/u,"")||"artifact"}function jt(e){return e.endsWith(".gz")?"application/gzip":e.endsWith(".jsonl")?"application/x-ndjson":e.endsWith(".json")?"application/json":"text/plain"}async function K(e,t,n){let i=`${n}.gz`,r=h.join(t,i);await pipeline(createReadStream(e),createGzip({level:9}),createWriteStream(r));let[a,o]=await Promise.all([P.stat(e),P.stat(r)]);return {role:Ft(n),originalFileName:n,storedFileName:i,compressed:true,compression:"gzip",contentType:jt(i),originalSize:a.size,storedSize:o.size}}async function _(e,t){let n=await Ue(t),i=new Date().toISOString(),r=Tt(e),a=h.join(n,"archive",r),o=[],s=[];await P.mkdir(a,{recursive:true});try{let d=await P.readdir(n,{withFileTypes:!0});for(let m of d){if(!m.isFile()||!Et(m.name))continue;let f=await K(h.join(n,m.name),a,m.name);s.push(f),o.push(f.storedFileName);}}catch(d){if((d&&typeof d=="object"&&"code"in d?String(d.code||""):"")!=="ENOENT")throw d}let c=ge(t.runtimeDir);if(existsSync(c)){let d=await K(c,a,"current-progress.json");s.push(d),o.push(d.storedFileName);}if(e.command==="content-sync")for(let d of ["content-sync-current.json","content-sync-impact-plan.json","content-sync-checkpoint.json","content-sync-state.json","content-sync-invalidation.json","deploy-plan.json"]){let m=h.join(t.runtimeDir,d);if(!existsSync(m))continue;let f=await K(m,a,d);s.push(f),o.push(f.storedFileName);}let u=h.join(t.runtimeDir,"privacy","cookie-observations.json");if(existsSync(u)){let d=await K(u,a,"cookie-observations.json");s.push(d),o.push(d.storedFileName);}let g=[...o,"job.json"];return await v(h.join(a,"job.json"),{manifestVersion:1,archivedAt:i,archiveKey:r,archiveDir:a,logDir:n,runtimeDir:t.runtimeDir,exporterDir:t.exporterDir,configPath:t.configPath||"",archivedFiles:g,artifacts:s,job:e}),{archiveKey:r,archiveDir:a,archiveCreatedAt:i,archivedFiles:g,artifacts:s}}function Ot(e){return h.join(e,"audit-events.jsonl")}function le(e){return h.join(e,"stop-request.json")}async function We(e){try{let t=await P.readFile(le(e),"utf8"),n=JSON.parse(t);return n&&typeof n=="object"?n:null}catch{return null}}async function Fe(e,t){let n=await We(e);if(!n)return null;let i=String(n.targetJobId||"").trim();return i&&i!==t?null:n}async function W(e,t){if(!t){await P.unlink(le(e)).catch(()=>{});return}let n=await We(e);if(!n)return;let i=String(n.targetJobId||"").trim();(!i||i===t)&&await P.unlink(le(e)).catch(()=>{});}async function R(e,t){try{let n={occurredAt:t.occurredAt||new Date().toISOString(),status:t.status||"info",actorSource:t.actorSource||"queue-runner",...t};await P.mkdir(e,{recursive:!0}),await P.appendFile(Ot(e),`${JSON.stringify(n)}
|
|
2
|
+
`,"utf8");}catch{}}async function C(e,t,n){let[i,r]=await Promise.all([Ee(h.join(e.exporterDir,"package.json")),Ee(h.join(e.exporterDir,"node_modules","@smart-cloud","wpsuite-core","package.json"))]),a={checkedAt:new Date().toISOString(),status:t,pid:process.pid,nodePath:process.execPath,nodeVersion:process.version,exporterVersion:i,wpsuiteCoreVersion:r,runtimeDir:e.runtimeDir,exporterDir:e.exporterDir,...n??{}};try{await v(Me(e.runtimeDir),a);}catch{}}async function E(e){try{await P.unlink(ge(e));}catch{}}function Jt(e,t){let n=e.command;if(n!=="publish"&&n!=="crawl"&&n!=="deploy"&&n!=="invalidate"&&n!=="retry-timeouts"&&n!=="url"&&n!=="content-sync")return null;let i=Number.parseInt(String(e.intervalMinutes??"0"),10);if(!Number.isFinite(i)||i<1)return null;let r=(e.id||`${n}-${t+1}`).trim();if(!r)return null;let a=e.enabled!==false,o=typeof e.url=="string"?e.url.trim():"",s=typeof e.deploymentProfile=="string"?e.deploymentProfile.trim():"",c=Array.isArray(e.postTypes)?[...new Set(e.postTypes.map(d=>String(d).trim()).filter(Boolean))]:[],u=Array.isArray(e.listingPaths)?[...new Set(e.listingPaths.map(d=>String(d).trim()).filter(Boolean))]:[],g=(n==="publish"||n==="crawl")&&e.crawlMode==="incremental"?"incremental":"full";return n==="url"&&!o||n==="content-sync"&&c.length===0?null:{id:r,enabled:a,command:n,intervalMinutes:i,...n==="publish"||n==="crawl"?{crawlMode:g}:{},...(n==="publish"||n==="deploy"||n==="invalidate"||n==="content-sync")&&s?{deploymentProfile:s}:{},...o?{url:o}:{},...c.length>0?{postTypes:c}:{},...u.length>0?{listingPaths:u}:{},...typeof e.includeSubsites=="boolean"?{includeSubsites:e.includeSubsites}:{},...typeof e.includePostTypeArchives=="boolean"?{includePostTypeArchives:e.includePostTypeArchives}:{},...typeof e.includeTaxonomyArchives=="boolean"?{includeTaxonomyArchives:e.includeTaxonomyArchives}:{},...typeof e.includeAuthorArchives=="boolean"?{includeAuthorArchives:e.includeAuthorArchives}:{},...typeof e.includeDateArchives=="boolean"?{includeDateArchives:e.includeDateArchives}:{},...typeof e.includePostsPage=="boolean"?{includePostsPage:e.includePostsPage}:{},...typeof e.includeSitemapChain=="boolean"?{includeSitemapChain:e.includeSitemapChain}:{}}}async function Lt(e){let t=await z(e.configPath).catch(()=>null),n=t?.scheduler,i=Array.isArray(n?.rules)?n.rules.map((r,a)=>Jt(r,a)).filter(r=>!!r):[];return {enabled:!!n?.enabled,timezone:typeof n?.timezone=="string"&&n.timezone.trim()?n.timezone.trim():"UTC",rules:i,wpsuite:t?.wpsuite,publisherConfig:t}}function N(e,t){if(!t)throw new Error("Content-sync scheduler requires a valid publisher config.");let n=Q({postTypes:e.postTypes??[],listingPaths:e.listingPaths??[],includeSubsites:e.includeSubsites,includePostTypeArchives:e.includePostTypeArchives,includeTaxonomyArchives:e.includeTaxonomyArchives,includeAuthorArchives:e.includeAuthorArchives,includeDateArchives:e.includeDateArchives,includePostsPage:e.includePostsPage,includeSitemapChain:e.includeSitemapChain}),i=Z(t.sourceOrigin,e.id,n),r=ee(t,e.deploymentProfile),a=X({sourceOrigin:t.sourceOrigin,targetOrigin:r.config.targetOrigin,deploymentProfile:r.name||"",s3Bucket:r.config.s3.bucket,s3Prefix:r.config.s3.prefix,cloudFrontDistributionId:r.config.cloudFront.distributionId,urlRewriteMode:r.config.urlRewriteMode,extraReplacements:r.profile?.extraReplacements??{}});return `content-sync:${e.id}:${J({scopeFingerprint:i,targetFingerprint:a}).slice(0,32)}`}function Bt(e,t,n,i){let r=[n[t],i[t]].filter(o=>!!o).filter(o=>o.coalesceKey===t&&o.ruleId===e.id).map(o=>String(o.consumerId??"").trim()).filter(Boolean),a=[...new Set(r)];return a.length===1?a[0]:""}async function je(e,t){let n=se(e.runtimeDir);if(await M(n,[]),!t?.publisherConfig)return;let i=t.publisherConfig,r=i.deploymentProfiles??{},a=String(i.defaultDeploymentProfile??"").trim(),o=a?r[a]:void 0,s=[{target:"default",resolvedDeploymentProfile:o?a:"",targetOrigin:String(o?.targetOrigin??i.targetOrigin??"").trim()},...Object.keys(r).sort((p,S)=>p.localeCompare(S)).map(p=>({target:p,resolvedDeploymentProfile:p,targetOrigin:String(r[p]?.targetOrigin??i.targetOrigin??"").trim()}))],c=t.rules.filter(p=>p.command==="content-sync"),u=c.map(p=>({ruleId:p.id,coalesceKey:N(p,i),target:String(p.deploymentProfile??"").trim()||"default",effectiveTarget:String(p.deploymentProfile??i.defaultDeploymentProfile??"").trim()||"default",enabled:p.enabled,active:t.enabled&&p.enabled,intervalMinutes:p.intervalMinutes,postTypes:[...p.postTypes??[]],listingPaths:[...p.listingPaths??[]]}));if(!t.enabled){await M(n,[],s,u,true);return}let g=c.filter(p=>p.enabled);if(g.length===0){await M(n,[],s,u,true);return}let[d,m]=await Promise.all([w(n.state,{}),w(n.baseline,{})]),f=d.rules??{},b=m.entries??{},l=[];for(let p of g){let S=N(p,i),x=Bt(p,S,f,b);x&&l.push({ruleId:p.id,coalesceKey:S,consumerId:x});}await M(n,l,s,u,true);}async function Mt(e,t,n,i,r){let o=(await w(h.join(e.runtimeDir,"content-sync-baseline.json"),{})).entries?.[i];if(!o?.consumerId||!o.scopeFingerprint||!o.baselineId)return {status:"baseline-required",reason:"No verified normal-release baseline exists for this rule scope."};try{let s=t.publisherConfig;if(!s)throw new Error("Publisher configuration is unavailable.");let c=Q({postTypes:n.postTypes??[],listingPaths:n.listingPaths??[],includeSubsites:n.includeSubsites,includePostTypeArchives:n.includePostTypeArchives,includeTaxonomyArchives:n.includeTaxonomyArchives,includeAuthorArchives:n.includeAuthorArchives,includeDateArchives:n.includeDateArchives,includePostsPage:n.includePostsPage,includeSitemapChain:n.includeSitemapChain}),u=Z(s.sourceOrigin,n.id,c),g=ee(s,n.deploymentProfile),d=X({sourceOrigin:s.sourceOrigin,targetOrigin:g.config.targetOrigin,deploymentProfile:g.name||"",s3Bucket:g.config.s3.bucket,s3Prefix:g.config.s3.prefix,cloudFrontDistributionId:g.config.cloudFront.distributionId,urlRewriteMode:g.config.urlRewriteMode,extraReplacements:g.profile?.extraReplacements??{}});if(o.scopeFingerprint!==u||o.targetFingerprint!==d||!o.releaseFingerprint)return {status:"baseline-required",reason:"The verified content-sync baseline does not match the active scope or deployment target. Run a successful full or incremental publish to establish a new baseline."};let m=new L({sourceOrigin:s.sourceOrigin,runtimeToken:String(s.wpsuite?.runtimeToken||""),ignoreHttpsErrors:s.ignoreHttpsErrors}),f=await m.releaseFingerprint(c.includeSubsites),b=fe({wordpressFingerprint:f,targetFingerprint:d,sourceOrigin:s.sourceOrigin,sitemapPaths:we(s.sitemapPaths),blockedPathPrefixes:s.blockedPathPrefixes,assetPathPrefixes:s.assetPathPrefixes,noJavaScriptRenderPathPrefixes:s.noJavaScriptRenderPathPrefixes,urlRewriteMode:s.urlRewriteMode});if(o.releaseFingerprint!==b)return {status:"baseline-required",reason:"The installed WordPress release changed after the last verified content-sync baseline. Run a successful full or incremental publish to establish a new baseline."};let l=await m.head({consumerId:o.consumerId,scopeFingerprint:o.scopeFingerprint,baselineId:o.baselineId,postTypes:c.postTypes,includeSubsites:c.includeSubsites}),p=l.committedSequence;if(r?.command==="content-sync"&&r.coalesceKey===i){let S=await w(h.join(e.runtimeDir,"content-sync-current.json"),null);S?.coalesceKey===i&&Number.isSafeInteger(S.toSequence)&&(p=Math.max(p,Number(S.toSequence)));}return {status:l.headSequence>p?"pending":"current",headSequence:l.headSequence,committedSequence:l.committedSequence}}catch(s){return s instanceof T&&s.code==="baseline-required"?{status:"baseline-required",reason:s.message}:{status:"unavailable",reason:s instanceof Error?s.message:String(s)}}}async function Ne(e,t,n,i,r,a){let o=h.join(e.runtimeDir,"content-sync-state.json"),c=(await w(o,{})).rules??{},u=c[n]??{};c[n]={...u,ruleId:t,coalesceKey:n,...Number.isSafeInteger(r)?{observedHeadSequence:r}:{},...Number.isSafeInteger(a)?{committedSequence:a}:{},retryAttempt:0,nextRetryAt:null,lastError:i,baselineStatus:"required",baselineReason:i,trailingWorkDetected:Number.isSafeInteger(r)&&Number.isSafeInteger(a)?Number(r)>Number(a):!!u.trailingWorkDetected},await v(o,{schemaVersion:1,updatedAt:new Date().toISOString(),rules:c});}function de(e,t){let n=(t.url||"").trim(),i=t.crawlMode||"full",r=(t.deploymentProfile||"").trim(),a=(t.coalesceKey||"").trim();return e.some(o=>o.command===t.command&&(t.command!=="content-sync"||(o.coalesceKey||"").trim()===a)&&(o.url||"").trim()===n&&(o.crawlMode||"full")===i&&(o.deploymentProfile||"").trim()===r&&(o.status===void 0||o.status==="queued"||o.status==="retry-wait"||o.status==="running"))}async function Ut(e,t,n){if(!t.allowSchedulerAutoEnqueue)return await je(e,null),0;let i=await Lt(e);if(await je(e,i),!i.enabled||i.rules.length===0)return 0;if(t.assertActiveSubscriptionForIdentity)try{await t.assertActiveSubscriptionForIdentity(i.wpsuite??null);}catch(l){let p=l instanceof Error?l.message:String(l);return console.warn(`[queue-runner] scheduler auto-enqueue skipped: ${p}`),0}let r=h.join(e.runtimeDir,"queue.json"),a=h.join(e.runtimeDir,"current-run.json"),o=Date.now(),s=0,c=[],u=[],g=[],d=new Map,[m,f,b]=await Promise.all([w(r,[]),w(a,null),w(ce(e.runtimeDir),{lastEnqueuedBucketByRuleId:{},lastEvaluatedBucketByRuleId:{},lastCreatedBucketByRuleId:{},coalescedCountByRuleId:{}})]);for(let l of i.rules){if(!l.enabled||l.command!=="content-sync")continue;let p=Math.floor(o/(l.intervalMinutes*60*1e3)),S=b.lastEvaluatedBucketByRuleId?.[l.id]??b.lastEnqueuedBucketByRuleId?.[l.id]??-1;if(p<=S)continue;let x=N(l,i.publisherConfig);de(m,{command:l.command,deploymentProfile:l.deploymentProfile,coalesceKey:x})||d.set(l.id,await Mt(e,i,l,x,f));}await F(e.runtimeDir,async()=>{let l=await w(r,[]),p=await w(a,null),S=await w(ce(e.runtimeDir),{lastEnqueuedBucketByRuleId:{},lastEvaluatedBucketByRuleId:{},lastCreatedBucketByRuleId:{},coalescedCountByRuleId:{}});S.lastEnqueuedBucketByRuleId??={},S.lastEvaluatedBucketByRuleId??={...S.lastEnqueuedBucketByRuleId},S.lastCreatedBucketByRuleId??={...S.lastEnqueuedBucketByRuleId},S.coalescedCountByRuleId??={};let x=[...l];p&&p.status==="running"&&x.unshift(p);for(let y of i.rules){if(!y.enabled)continue;let A=y.intervalMinutes*60*1e3,q=Math.floor(o/A),j=S.lastEvaluatedBucketByRuleId[y.id]??S.lastEnqueuedBucketByRuleId[y.id]??-1;if(q<=j)continue;let O=y.command==="content-sync"?N(y,i.publisherConfig):"";S.lastEvaluatedBucketByRuleId[y.id]=q;let ze=y.command==="content-sync"?l:x;if(de(ze,{command:y.command,url:y.url,crawlMode:y.crawlMode,deploymentProfile:y.deploymentProfile,coalesceKey:O})){S.coalescedCountByRuleId[y.id]=(S.coalescedCountByRuleId[y.id]??0)+1,u.push(y);continue}if(y.command==="content-sync"){let G=d.get(y.id);if(!G||G.status!=="pending"){let me=G??{status:"unavailable",reason:"Content-sync demand was not checked."};me.status!=="current"&&g.push({rule:y,check:me});continue}}let V={id:randomUUID(),command:y.command,...y.command==="content-sync"?{ruleId:y.id,coalesceKey:O,attempt:0}:{},...(y.command==="publish"||y.command==="crawl")&&y.crawlMode?{crawlMode:y.crawlMode}:{},...(y.command==="publish"||y.command==="deploy"||y.command==="invalidate"||y.command==="content-sync")&&y.deploymentProfile?{deploymentProfile:y.deploymentProfile}:{},...y.url?{url:y.url}:{},enqueueSource:"scheduler",...i.wpsuite?{wpsuite:i.wpsuite}:{},status:"queued",createdAt:new Date().toISOString(),createdBy:0};l.push(V),x.push(V),c.push({job:V,rule:y}),S.lastEnqueuedBucketByRuleId[y.id]=q,S.lastCreatedBucketByRuleId[y.id]=q,s+=1;}s>0&&await v(r,l),await v(ce(e.runtimeDir),S);});for(let l of c){if(l.rule.command==="content-sync"){let p=d.get(l.rule.id);await R(e.runtimeDir,{eventType:"content-sync-demand-detected",status:"queued",actorSource:"queue-runner-scheduler",jobId:l.job.id,command:l.job.command,message:"Pending journal changes require a content-sync job.",details:{ruleId:l.rule.id,headSequence:p?.headSequence??0,committedSequence:p?.committedSequence??0}});}await R(e.runtimeDir,{eventType:"job-created",status:"queued",actorSource:"queue-runner-scheduler",jobId:l.job.id,command:l.job.command,message:"Scheduler auto-enqueued a job.",details:{ruleId:l.rule.id,intervalMinutes:l.rule.intervalMinutes,timezone:i.timezone,deploymentProfile:l.rule.deploymentProfile||"",url:l.rule.url||""}});}for(let l of u)await R(e.runtimeDir,{eventType:"content-sync-coalesced",status:"queued",actorSource:"queue-runner-scheduler",command:l.command,message:"Scheduler demand was coalesced into an existing content-sync job.",details:{ruleId:l.id}});for(let l of g){if(l.check.status==="baseline-required"){let p=N(l.rule,i.publisherConfig);await Ne(e,l.rule.id,p,l.check.reason||"A successful full or incremental publish must establish a new content-sync baseline.",l.check.headSequence,l.check.committedSequence);}await R(e.runtimeDir,{eventType:l.check.status==="baseline-required"?"content-sync-baseline-required":"content-sync-demand-check-failed",status:l.check.status==="unavailable"?"failed":"info",actorSource:"queue-runner-scheduler",command:"content-sync",message:l.check.reason||"The content-sync consumer is already at the current journal head.",details:{ruleId:l.rule.id,headSequence:l.check.headSequence??0,committedSequence:l.check.committedSequence??0}});}return s}async function Wt(e){let t={pid:process.pid,startedAt:new Date().toISOString()};await P.writeFile(e,JSON.stringify(t,null,2),{encoding:"utf8",flag:"wx"});}async function Nt(e){try{await P.unlink(e);}catch{}}function $t(e,t){let n=[h.join(e,"dist",`${t}.js`),h.join(e,`${t}.js`)];for(let i of n)if(existsSync(i))return i;throw new Error(`Cannot find ${t}.js in ${h.join(e,"dist")} or ${e}`)}async function k(e,t,n,i,r,a,o){if(o){let u=await Fe(t,o);if(u)throw new $(u,n)}let s=$t(e,n),c={...process.env,...a??{}};return c.STATIC_PUBLISHER_RUNTIME_DIR=t,r&&(c.PUBLISHER_CONFIG=r),await new Promise((u,g)=>{let d=null,m=null,f=null,b=null,l=false,p="",S=spawn(process.execPath,[s,...i],{cwd:e,env:c,stdio:["inherit","inherit","pipe"]});S.stderr?.on("data",A=>{p+=A.toString("utf8");});let x=()=>{m&&clearInterval(m),f&&clearInterval(f),b&&clearTimeout(b);},y=async()=>{if(!(!o||d||l)){l=true;try{let A=await Fe(t,o);if(!A)return;d=A,S.kill("SIGTERM"),b=setTimeout(()=>{S.kill("SIGKILL");},1e4);}finally{l=false;}}};o&&(m=setInterval(()=>{y();},1e3),f=setInterval(()=>{(async()=>{let A=Me(t),q=await w(A,{});await v(A,{...q,checkedAt:new Date().toISOString(),status:"running",currentJobId:o||q.currentJobId||"",currentStep:n});})().catch(()=>{});},15e3)),S.on("error",A=>{x(),g(A);}),S.on("close",(A,q)=>{x();let j=be(p).trim();if(j&&process.stderr.write(`${j}
|
|
3
|
+
`),d){g(new $(d,n));return}if(A===0)u();else {let O=Re(j);g(new Error(`${n} exited with code ${A??-1}${q?` (signal ${q})`:""}${O?`: ${O}`:""}`));}});}),0}function Qt(e){let t=e.awsTempCreds;if(!t)return {};let n={};return typeof t.accessKeyId=="string"&&t.accessKeyId.trim()!==""&&(n.AWS_ACCESS_KEY_ID=t.accessKeyId.trim()),typeof t.secretAccessKey=="string"&&t.secretAccessKey.trim()!==""&&(n.AWS_SECRET_ACCESS_KEY=t.secretAccessKey.trim()),typeof t.sessionToken=="string"&&t.sessionToken.trim()!==""&&(n.AWS_SESSION_TOKEN=t.sessionToken.trim()),n}async function zt(e,t){let n=o=>{if(!o||typeof o!="object")return null;let s=o,c={...s.siteSettings??{},...String(s.accountId??"").trim()&&!s.siteSettings?.accountId?{accountId:String(s.accountId).trim()}:{},...String(s.siteId??"").trim()&&!s.siteSettings?.siteId?{siteId:String(s.siteId).trim()}:{},...s.siteSettings?.subscriber===true||s.subscriber===true?{subscriber:true}:{}},u={...String(s.apiBase??"").trim()?{apiBase:String(s.apiBase).trim()}:{},...String(s.runtimeToken??s.nonce??"").trim()?{runtimeToken:String(s.runtimeToken??s.nonce).trim()}:{},...String(s.virtualAssetBaseUrl??s.uploadUrl??"").trim()?{virtualAssetBaseUrl:String(s.virtualAssetBaseUrl??s.uploadUrl).trim()}:{},...Object.keys(c).length>0?{siteSettings:c}:{},...s.subscriptionType?{subscriptionType:s.subscriptionType}:{}};return Object.keys(u).length>0?u:null},i=await z(t.configPath).catch(()=>null),r=n(i?.wpsuite);if(r)return r;let a=n(e.wpsuite);return a||null}async function Kt(e,t){return await zt(e,t)}function pe(e){let t={...e,status:"queued"};return delete t.startedAt,delete t.endedAt,delete t.exitCode,delete t.error,delete t.stopRequestedAt,delete t.stopRequestedByUserId,delete t.stopRequestedByLogin,delete t.stopMode,delete t.stoppedStep,t}async function _t(e,t){let n=await w(ge(e.runtimeDir),null),i=n&&n.details&&typeof n.details.phase=="string"?n.details.phase.trim():"";if(i)return i;let r=n&&typeof n.currentStep=="string"?n.currentStep.trim():"";if(r)return r;let a=await Ue(e).catch(()=>"");if(a){let o=await w(h.join(a,"current-crawl-event.json"),null),s=o&&typeof o.currentStep=="string"?o.currentStep.trim():"";if(s)return s}return t}function Ht(e,t){if((e.command==="publish"||e.command==="crawl")&&t==="rewrite-text")return "rewrite-text"}async function Vt(e){let t=h.join(e.runtimeDir,"queue.json"),n=h.join(e.runtimeDir,"current-run.json"),i=await F(e.runtimeDir,async()=>{let r=await w(n,null);if(!r||r.status!=="running"&&r.status!=="queued")return null;let a=await w(t,[]),o=Array.isArray(a)?a.filter(c=>c?.id!==r.id):[],s=pe(r);return await v(t,[s,...o]),await v(n,null),s});i&&(await W(e.runtimeDir,i.id),await R(e.runtimeDir,{eventType:"job-recovered",status:"queued",actorSource:"queue-runner",jobId:i.id,command:i.command,message:"Recovered stale current-run entry back into queue."}));}async function U(e,t){if(e.resumeFromStep==="rewrite-text")return;let n=h.join(t.runtimeDir,"privacy","cookie-observations.json"),i;try{let s=await P.stat(n);if(!s.isFile()||s.size>5*1024*1024)throw new Error("Cookie observation artifact is missing or exceeds 5 MiB.");i=JSON.parse(await P.readFile(n,"utf8"));}catch(s){if((s&&typeof s=="object"&&"code"in s?String(s.code||""):"")==="ENOENT")return;throw s}let r=await z(t.configPath),a=String(r.wpsuite?.runtimeToken||"").trim();if(!a)return;await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"consent-cookie-observations"}),await new L({sourceOrigin:r.sourceOrigin,runtimeToken:a,ignoreHttpsErrors:!!r.ignoreHttpsErrors}).importCookieObservations(i);}async function Gt(e,t,n){try{if((n.shouldEnforceSubscriptionOnJobExecution?.(e)??n.enforceSubscriptionOnJobExecution)&&n.assertActiveSubscriptionForIdentity){let s=await Kt(e,t);await n.assertActiveSubscriptionForIdentity(s);}let r=Qt(e),a=e.resumeFromStep==="rewrite-text"?["--resume-rewrite"]:e.crawlMode==="incremental"?["--crawl-mode","incremental"]:[],o=e.deploymentProfile?["--profile",e.deploymentProfile]:[];if(e.command==="publish")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"content-sync-release-cutoff"}),await k(t.exporterDir,t.runtimeDir,"content-sync",["--capture-baseline-cutoffs",e.id],t.configPath,r,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:e.resumeFromStep==="rewrite-text"?"rewrite-text":"crawl"}),await k(t.exporterDir,t.runtimeDir,"crawl",a,t.configPath,r,e.id),await U(e,t),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"deploy"}),await k(t.exporterDir,t.runtimeDir,"deploy",o,t.configPath,r,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"invalidate"}),await k(t.exporterDir,t.runtimeDir,"invalidate",o,t.configPath,r,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"content-sync-baseline"}),await k(t.exporterDir,t.runtimeDir,"content-sync",["--establish-baselines",e.id],t.configPath,r,e.id),{exitCode:0};if(e.command==="crawl")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:e.resumeFromStep==="rewrite-text"?"rewrite-text":"crawl"}),await k(t.exporterDir,t.runtimeDir,"crawl",a,t.configPath,r,e.id),await U(e,t),{exitCode:0};if(e.command==="deploy")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"deploy"}),await k(t.exporterDir,t.runtimeDir,"deploy",o,t.configPath,r,e.id),{exitCode:0};if(e.command==="invalidate")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"invalidate"}),await k(t.exporterDir,t.runtimeDir,"invalidate",o,t.configPath,r,e.id),{exitCode:0};if(e.command==="retry-timeouts")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"retry-timeouts"}),await k(t.exporterDir,t.runtimeDir,"crawl",["--retry-timeouts"],t.configPath,r,e.id),await U(e,t),{exitCode:0};if(e.command==="url"){let s=(e.url||"").trim();return s?(await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"url"}),await k(t.exporterDir,t.runtimeDir,"crawl",["--url",s],t.configPath,r,e.id),await U(e,t),{exitCode:0}):{exitCode:2,error:"Missing url for command 'url'"}}return e.command==="content-sync"?!e.ruleId||!e.coalesceKey?{exitCode:2,error:"Content-sync queue jobs require ruleId and coalesceKey."}:(await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"content-sync"}),await k(t.exporterDir,t.runtimeDir,"content-sync",["--job-id",e.id],t.configPath,r,e.id),await U(e,t),{exitCode:0}):{exitCode:2,error:`Unsupported command: ${e.command}`}}catch(i){return i instanceof $?{exitCode:130,error:"Job stop requested.",stopped:true,stopRequest:i.request,stoppedStep:i.step}:{exitCode:1,error:i instanceof Error?i.message:String(i)}}}function $e(e){return async function(n=process.argv.slice(2)){let i=It(n),r=h.join(i.runtimeDir,"export.lock"),a=h.join(i.runtimeDir,"last-run.json");await E(i.runtimeDir),await C(i,"starting",{message:"queue-runner starting"});try{await Wt(r);}catch(o){if((o&&typeof o=="object"&&"code"in o?String(o.code||""):"")!=="EEXIST")throw o;console.log("[queue-runner] lock active, skipping"),await C(i,"lock-active",{message:"lock active, skipped this cron tick"});return}try{await Vt(i);let o=await Ut(i,e),s=0;for(let c=0;c<i.maxJobs;c++){let u=await en(i,e);if(u==="none"||(s+=1,u==="stopped"))break}if(s===0)await E(i.runtimeDir),await C(i,"idle",{processedJobs:s,schedulerEnqueued:o,message:"no queued jobs"});else {await E(i.runtimeDir);let c=await w(a,null),u=String(c?.status||"").trim();await C(i,u==="success"?"job-success":u==="stopped"?"job-stopped":"job-failed",{processedJobs:s,schedulerEnqueued:o,lastJobId:c?.id,lastJobCommand:c?.command,lastJobStatus:c?.status,lastJobExitCode:c?.exitCode,lastJobError:c?.error,...u==="stopped"?{currentStep:c?.stoppedStep,stopRequestedAt:c?.stopRequestedAt,stopRequestedByLogin:c?.stopRequestedByLogin,stopRequestedMode:c?.stopMode,lastStoppedStep:c?.stoppedStep,message:c?.stopMode==="requeue"?`Job stopped during ${c?.stoppedStep||c?.command||"active step"} and requeued.`:`Job stopped during ${c?.stoppedStep||c?.command||"active step"} and left out of queue.`}:{}});}}catch(o){let s=o instanceof Error?o.message:String(o);throw await C(i,"error",{message:s}),await R(i.runtimeDir,{eventType:"queue-runner-error",status:"failed",actorSource:"queue-runner",message:"Unhandled queue-runner error.",details:{error:s}}),o}finally{await Nt(r);}}}async function Oe(e,t){if(t.command!=="content-sync"||!t.coalesceKey)return false;let n=se(e.runtimeDir),i=await Te(n,t.coalesceKey),r=await qe(n),a=r.rules[t.coalesceKey];return a&&(r.rules[t.coalesceKey]={...a,trailingWorkDetected:true,retryAttempt:0,nextRetryAt:null,lastError:null},await De(n,r)),i}async function Yt(e,t,n){let i=h.join(e.runtimeDir,"queue.json"),r=h.join(e.runtimeDir,"current-run.json");await F(e.runtimeDir,async()=>{let a=await w(i,[]),o=Array.isArray(a)?a.filter(u=>u?.id!==t.id):[],s=pe(t),c=Ht(t,n);c?s.resumeFromStep=c:delete s.resumeFromStep,await v(i,[s,...o]),await v(r,null);});}async function Zt(e,t,n){let i=Math.max(0,t.attempt??0)+1,r=Math.min(3600*1e3,6e4*2**(i-1)),a=Math.floor(r*.2*Math.random()),o=new Date(Date.now()+r+a).toISOString(),s={...pe(t),status:"retry-wait",attempt:i,nextAttemptAt:o,error:n};if(await F(e.runtimeDir,async()=>{let c=h.join(e.runtimeDir,"queue.json"),u=h.join(e.runtimeDir,"current-run.json"),d=(await w(c,[])).filter(m=>m.id!==t.id);await v(c,[s,...d]),await v(u,null);}),t.coalesceKey){let c=h.join(e.runtimeDir,"content-sync-state.json"),g=(await w(c,{})).rules??{};g[t.coalesceKey]={...g[t.coalesceKey]??{},ruleId:t.ruleId||"",coalesceKey:t.coalesceKey,retryAttempt:i,nextRetryAt:o,lastError:n,trailingWorkDetected:true},await v(c,{schemaVersion:1,updatedAt:new Date().toISOString(),rules:g});}return s}async function Xt(e,t){if(!t.coalesceKey||!t.ruleId||!(await w(h.join(e.runtimeDir,"content-sync-state.json"),null))?.rules?.[t.coalesceKey]?.trailingWorkDetected)return null;let i=null;await F(e.runtimeDir,async()=>{let a=h.join(e.runtimeDir,"queue.json"),o=await w(a,[]);de(o,{command:"content-sync",coalesceKey:t.coalesceKey,deploymentProfile:t.deploymentProfile})||(i={id:randomUUID(),command:"content-sync",ruleId:t.ruleId,coalesceKey:t.coalesceKey,deploymentProfile:t.deploymentProfile,enqueueSource:"scheduler",wpsuite:t.wpsuite,status:"queued",attempt:0,createdAt:new Date().toISOString(),createdBy:0},await v(a,[...o,i]));});let r=i;return r&&await R(e.runtimeDir,{eventType:"content-sync-trailing-job-created",status:"queued",actorSource:"queue-runner",jobId:r.id,command:r.command,message:"Content changes after the stable cutoff created one trailing job.",details:{predecessorJobId:t.id,ruleId:t.ruleId,coalesceKey:t.coalesceKey}}),r}async function en(e,t){let n=h.join(e.runtimeDir,"queue.json"),i=h.join(e.runtimeDir,"current-run.json"),r=h.join(e.runtimeDir,"last-run.json"),a=new Date().toISOString(),o=await F(e.runtimeDir,async()=>{let d=await w(n,[]);if(!Array.isArray(d)||d.length===0)return null;let m=Date.parse(String(d[0]?.nextAttemptAt||""));if(Number.isFinite(m)&&m>Date.now())return null;let f={...d[0],status:"running",startedAt:a};return delete f.nextAttemptAt,await v(n,d.slice(1)),await v(i,f),f});if(!o)return "none";await E(e.runtimeDir),await R(e.runtimeDir,{eventType:"job-run-started",status:"running",actorSource:"queue-runner",jobId:o.id,command:o.command,message:"Job execution started.",details:{createdAt:o.createdAt||"",startedAt:a,createdBy:o.createdBy??null,deploymentProfile:o.deploymentProfile||"",queuedWithTempAwsCreds:!!o.awsTempCreds}}),await C(e,"running",{currentJobId:o.id,currentJobCommand:o.command,currentStep:o.command});let s=await Gt(o,e,t),c=new Date().toISOString();if(s.stopped){let d=await _t(e,s.stoppedStep||o.command),m=s.stopRequest?.mode==="requeue"?"requeue":"stop",f={...o,status:"stopped",endedAt:c,exitCode:s.exitCode,...s.error?{error:s.error}:{},stopRequestedAt:s.stopRequest?.requestedAt||"",stopRequestedByUserId:typeof s.stopRequest?.requestedByUserId=="number"?s.stopRequest.requestedByUserId:null,stopRequestedByLogin:s.stopRequest?.requestedByLogin||"",stopMode:m,stoppedStep:d},b=false;m==="requeue"?await Yt(e,o,d):(await v(i,null),b=await Oe(e,o));try{let l=await _(f,e);f.logArchiveDir=l.archiveDir,f.logArchiveCreatedAt=l.archiveCreatedAt,f.logArchiveFileCount=l.archivedFiles.length;}catch(l){f.logArchiveError=l instanceof Error?l.message:String(l);}return await v(r,f),await W(e.runtimeDir,o.id),await E(e.runtimeDir),await R(e.runtimeDir,{eventType:"job-run-stopped",status:"stopped",actorSource:"queue-runner",jobId:o.id,command:o.command,message:m==="requeue"?"Job stop requested and requeued.":"Job stop requested and removed from active execution without requeue.",details:{startedAt:o.startedAt||"",endedAt:c,deploymentProfile:o.deploymentProfile||"",stopMode:m,stopRequestedAt:s.stopRequest?.requestedAt||"",stopRequestedByLogin:s.stopRequest?.requestedByLogin||"",stopRequestedByUserId:typeof s.stopRequest?.requestedByUserId=="number"?s.stopRequest.requestedByUserId:null,stoppedStep:d,logArchiveKey:f.logArchiveError||!f.logArchiveDir?"":h.basename(f.logArchiveDir),logArchiveDir:f.logArchiveDir||"",logArchiveCreatedAt:f.logArchiveCreatedAt||"",logArchiveFileCount:f.logArchiveFileCount??0,logArchiveError:f.logArchiveError||"",contentSyncAbandoned:b,journalCursorPreserved:b}}),"stopped"}if(o.command==="content-sync"&&s.exitCode!==0){if(/baseline (?:is missing or stale|required)|verified content-sync baseline|new baseline/i.test(s.error||"")){let b="The installed release no longer matches the verified content-sync baseline. Run a successful full or incremental publish to establish a new baseline.";o.ruleId&&o.coalesceKey&&await Ne(e,o.ruleId,o.coalesceKey,b);let l={...o,status:"failed",endedAt:c,exitCode:s.exitCode,error:b};await v(i,null),await E(e.runtimeDir),await Oe(e,o);try{let p=await _(l,e);l.logArchiveDir=p.archiveDir,l.logArchiveCreatedAt=p.archiveCreatedAt,l.logArchiveFileCount=p.archivedFiles.length;}catch(p){l.logArchiveError=p instanceof Error?p.message:String(p);}return await v(r,l),await W(e.runtimeDir,o.id),await R(e.runtimeDir,{eventType:"content-sync-baseline-required",status:"failed",actorSource:"queue-runner",jobId:o.id,command:o.command,message:b,details:{ruleId:o.ruleId||"",retryScheduled:false}}),"processed"}await R(e.runtimeDir,{eventType:"content-sync-failed",status:"failed",actorSource:"queue-runner",jobId:o.id,command:o.command,message:"Content-sync execution failed before cursor acknowledgement.",details:{attempt:o.attempt??0,error:s.error||"Content-sync execution failed."}});let m=await Zt(e,o,s.error||"Content-sync execution failed."),f={...o,status:"retry-wait",endedAt:c,exitCode:s.exitCode,error:m.error,attempt:m.attempt,nextAttemptAt:m.nextAttemptAt};try{let b=await _(f,e);f.logArchiveDir=b.archiveDir,f.logArchiveCreatedAt=b.archiveCreatedAt,f.logArchiveFileCount=b.archivedFiles.length;}catch(b){f.logArchiveError=b instanceof Error?b.message:String(b);}return await v(r,f),await W(e.runtimeDir,o.id),await R(e.runtimeDir,{eventType:"content-sync-retry-scheduled",status:"retry-wait",actorSource:"queue-runner",jobId:o.id,command:o.command,message:"Content-sync retry was scheduled with bounded backoff.",details:{attempt:m.attempt??0,nextAttemptAt:m.nextAttemptAt||"",error:m.error||""}}),"processed"}let u={...o,status:s.exitCode===0?"success":"failed",endedAt:c,exitCode:s.exitCode,...s.error?{error:s.error}:{}};await v(i,null),u.status==="success"&&u.command==="content-sync"&&await Xt(e,u),await W(e.runtimeDir,o.id);try{let d=await _(u,e);u.logArchiveDir=d.archiveDir,u.logArchiveCreatedAt=d.archiveCreatedAt,u.logArchiveFileCount=d.archivedFiles.length;}catch(d){u.logArchiveError=d instanceof Error?d.message:String(d);}await v(r,u);let g=o.startedAt&&u.endedAt?Math.max(0,Math.round((new Date(u.endedAt).getTime()-new Date(o.startedAt).getTime())/1e3)):void 0;return await R(e.runtimeDir,{eventType:"job-run-finished",status:u.status==="success"?"success":"failed",actorSource:"queue-runner",jobId:u.id,command:u.command,message:u.status==="success"?"Job execution finished successfully.":"Job execution finished with failure.",details:{startedAt:o.startedAt||"",endedAt:u.endedAt||"",durationSec:g,deploymentProfile:u.deploymentProfile||"",exitCode:u.exitCode??null,error:u.error||"",logArchiveKey:u.logArchiveError||!u.logArchiveDir?"":h.basename(u.logArchiveDir),logArchiveDir:u.logArchiveDir||"",logArchiveCreatedAt:u.logArchiveCreatedAt||"",logArchiveFileCount:u.logArchiveFileCount??0,logArchiveError:u.logArchiveError||""}}),"processed"}async function nn(e){if(!e)throw new Error("Missing remote WPSuite publisher state. Refresh the runtime config before running subscription-gated jobs.");if(e.subscriptionType!=="PROFESSIONAL"&&e.subscriptionType!=="AGENCY")throw new Error("This job requires an active WPSuite publisher subscription in the remote site configuration.")}var rn={allowSchedulerAutoEnqueue:true,enforceSubscriptionOnJobExecution:false,shouldEnforceSubscriptionOnJobExecution:e=>Le(e)||e.enqueueSource==="scheduler"||e.createdBy===0,assertActiveSubscriptionForIdentity:nn},Qe=$e(rn),on=Qe,Vn=Qe;process.argv[1]&&import.meta.url===pathToFileURL(process.argv[1]).href&&on().catch(e=>{console.error(e),process.exit(1);});export{Vn as default,on as main,Qe as runQueueRunner};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import g from'path';import {readFile}from'fs/promises';import {LambdaClient,InvokeCommand}from'@aws-sdk/client-lambda';import {DynamoDBClient,GetItemCommand}from'@aws-sdk/client-dynamodb';import {S3Client,GetObjectCommand,PutObjectCommand,CopyObjectCommand}from'@aws-sdk/client-s3';import {fromTemporaryCredentials}from'@aws-sdk/credential-providers';import {createHash}from'crypto';var l=1;function b(n){let e=String(n??"").trim().replace(/^\/+|\/+$/g,"");if(!e)return "";let r=e.split("/").filter(Boolean);if(r.some(t=>t==="."||t===".."))throw new Error("S3 prefix contains an unsafe dot path segment.");return `${r.join("/")}/`}function m(n){return createHash("sha256").update(n).digest("hex")}function u(n,e){let r=String(n??"").replace(/^\/+/,""),t=b(e);if(!r||r.includes("\0"))throw new Error("S3 object key is empty or invalid.");if(t&&!r.startsWith(t))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 a(n,e,{optional:r=false}={}){if(!(r&&(n==null||n===""))){if(typeof n!="string"||!n.trim())throw new Error(`${e} must be a non-empty string.`);return n.trim()}}function T(n){if(!n||typeof n!="object")throw new Error("Remote worker config must be a JSON object.");let e=n;if(e.schemaVersion!==1)throw new Error(`Unsupported remote worker config version: ${String(e.schemaVersion)}.`);if(e.protocolVersion!==l)throw new Error(`Remote worker protocol mismatch: expected ${l}, received ${String(e.protocolVersion)}.`);let r=e.workspace,t=e.functions;if(!r||!t)throw new Error("Remote worker config requires workspace and functions objects.");return {schemaVersion:1,region:a(e.region,"region"),...a(e.roleArn,"roleArn",{optional:true})?{roleArn:a(e.roleArn,"roleArn")}:{},...a(e.roleSessionName,"roleSessionName",{optional:true})?{roleSessionName:a(e.roleSessionName,"roleSessionName")}:{},workspace:{bucket:a(r.bucket,"workspace.bucket"),prefix:String(r.prefix??"")},...e.status&&typeof e.status=="object"?{status:{tableName:a(e.status.tableName,"status.tableName")}}:{},functions:{render:a(t.render,"functions.render"),...a(t.asset,"functions.asset",{optional:true})?{asset:a(t.asset,"functions.asset")}:{},rewrite:a(t.rewrite,"functions.rewrite"),"deploy-copy":a(t["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:a(i.id,`targets[${s}].id`),bucketName:a(i.bucketName,`targets[${s}].bucketName`),prefix:String(i.prefix??""),region:a(i.region,`targets[${s}].region`)}}):[],protocolVersion:l}}async function w(n){let e=g.resolve(n);try{return T(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 d=class{config;lambda;s3;dynamodb;#e;constructor(e,r={},t={}){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=t;}async#t(e){if(!this.dynamodb||!this.config.status)return null;let t=(await this.dynamodb.send(new GetItemCommand({TableName:this.config.status.tableName,ConsistentRead:true,Key:{jobId:{S:e.jobId},taskId:{S:e.taskId}}}))).Item;if(!t)return null;let o=t.operation?.S,s=t.status?.S;return !o||!["render","asset","rewrite","deploy-copy"].includes(o)||!s||!["running","succeeded","partial","failed"].includes(s)?null:{jobId:t.jobId?.S??e.jobId,taskId:t.taskId?.S??e.taskId,operation:o,status:s,completedItems:Number(t.completedItems?.N??0),failedItems:Number(t.failedItems?.N??0),totalItems:Number(t.totalItems?.N??0),sequence:Number(t.sequence?.N??0),updatedAt:t.updatedAt?.S??new Date(0).toISOString(),requestId:t.requestId?.S??null}}async#r(e,r){let t=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 t;let o=false,s=t.finally(()=>{o=true;}),i=Math.max(500,Math.min(3e4,this.#e.progressPollIntervalMs??2e3)),p=-1;for(;!o;){await Promise.race([s.then(()=>{},()=>{}),new Promise(c=>setTimeout(c,i))]);try{let c=await this.#t(e);c&&c.sequence>p&&(p=c.sequence,await this.#e.onProgress(c));}catch(c){await this.#e.onProgressError?.(c instanceof Error?c:new Error(String(c)));}}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 t=await this.#r(e,r),o=t.Payload?JSON.parse(new TextDecoder().decode(t.Payload)):null;if(t.FunctionError)throw new Error(`Remote ${e.operation} worker failed (${t.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!==l||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=u(e.resultKey,this.config.workspace.prefix),t=await this.s3.send(new GetObjectCommand({Bucket:this.config.workspace.bucket,Key:r}));if(!t.Body)throw new Error(`Remote worker result has no body: ${r}`);return JSON.parse(await t.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=u(e.key,this.config.workspace.prefix),t=await this.s3.send(new GetObjectCommand({Bucket:this.config.workspace.bucket,Key:r,...e.versionId?{VersionId:e.versionId}:{}}));if(!t.Body)throw new Error(`Remote worker object has no body: ${r}`);let o=await t.Body.transformToByteArray();if(o.byteLength!==e.bytes)throw new Error(`Remote worker object length mismatch for ${r}: expected ${e.bytes}, received ${o.byteLength}.`);if(m(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 t=`${e}-${Date.now()}`,o=await this.lambda.send(new InvokeCommand({FunctionName:r,InvocationType:"RequestResponse",Payload:Buffer.from(JSON.stringify({schemaVersion:l,operation:"health",jobId:"health",taskId:t}),"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=u(e.key,this.config.workspace.prefix),t=typeof e.body=="string"?Buffer.from(e.body,"utf8"):e.body,o=m(t),s=await this.s3.send(new PutObjectCommand({Bucket:this.config.workspace.bucket,Key:r,Body:t,ContentType:e.contentType,...e.cacheControl?{CacheControl:e.cacheControl}:{},Metadata:{sha256:o,...e.metadata??{}}}));return {bucket:this.config.workspace.bucket,key:r,sha256:o,bytes:t.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 t=u(e.key,this.config.workspace.prefix),o=u(r,this.config.workspace.prefix),s=`${e.bucket}/${t.split("/").map(p=>encodeURIComponent(p)).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 f="remote-workers.json";function R(n={}){let e=String(n.explicitPath??"").trim();if(e)return g.resolve(e);let r=String(n.runtimeDir??process.env.STATIC_PUBLISHER_RUNTIME_DIR??process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR??"").trim();return r?g.join(g.resolve(r),f):""}function C(n){let e=n.findIndex(i=>i==="--config"||i==="-c"),r=n.find(i=>i.startsWith("--config=")),t=n.findIndex(i=>i==="--runtime-dir"),o=n.find(i=>i.startsWith("--runtime-dir=")),s=R({explicitPath:r?.slice(9)??(e>=0?n[e+1]:void 0),runtimeDir:o?.slice(14)??(t>=0?n[t+1]:void 0)});if(!s)throw new Error(`Pass --runtime-dir <path>; ${f} must be installed there. --config remains available for diagnostic overrides.`);return g.resolve(s)}async function j(){let n=await w(C(process.argv.slice(2))),e=new d(n),r=["render",...n.functions.asset?["asset"]:[],"rewrite","deploy-copy"],t=await Promise.all(r.map(async o=>({operation:o,response:await e.health(o)})));console.log(JSON.stringify({ok:true,results:t},null,2));}j().catch(n=>{console.error(n instanceof Error?n.message:String(n)),process.exit(1);});
|
package/dist/remote-worker.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {S3Client,HeadObjectCommand,CopyObjectCommand,DeleteObjectsCommand,PutObjectCommand,GetObjectCommand}from'@aws-sdk/client-s3';import {request,chromium}from'playwright';import {createHash}from'crypto';import {lookup}from'dns/promises';import {isIP}from'net';import j from'path';import'fast-glob';import'fs/promises';import'os';import'worker_threads';var b=1,ie=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function A(e,t){let r=String(e??"").trim();if(!ie.test(r))throw new Error(`${t} must match ${ie.source} and be at most 128 characters.`);return r}function C(e){let t=String(e??"").trim().replace(/^\/+|\/+$/g,"");if(!t)return "";let r=t.split("/").filter(Boolean);if(r.some(n=>n==="."||n===".."))throw new Error("S3 prefix contains an unsafe dot path segment.");return `${r.join("/")}/`}function x(e,...t){let r=C(e),n=t.map((s,o)=>{let i=String(s??"").replace(/^\/+|\/+$/g,"");if(!i||i.split("/").some(l=>l==="."||l===".."))throw new Error(`Unsafe S3 key segment at index ${o}.`);return i});return `${r}${n.join("/")}`}function L(e,t,r){return `${x(e,"jobs",A(t,"jobId"),"tasks",A(r,"taskId"))}/`}function W(e){return createHash("sha256").update(e).digest("hex")}function P(e,t){let r=String(e??"").replace(/^\/+/,""),n=C(t);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(s=>s===".."))throw new Error("S3 object key contains an unsafe parent segment.");return r}function S(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new Error(`${t} must be a JSON object.`);return e}function m(e,t){if(typeof e!="string"||!e.trim())throw new Error(`${t} must be a non-empty string.`);return e.trim()}function R(e,t,r,n){if(!Number.isInteger(e)||Number(e)<r||Number(e)>n)throw new Error(`${t} must be an integer between ${r} and ${n}.`);return Number(e)}function Ie(e){return e.hostname.replace(/^\[|\]$/g,"").replace(/\.$/,"").toLowerCase()}function _(e){let t=e.split(".");if(t.length!==4)return null;let r=t.map(n=>Number(n));return r.every((n,s)=>Number.isInteger(n)&&n>=0&&n<=255&&String(n)===t[s])?r:null}function Y(e){let t=e.toLowerCase();if(t.includes("%")||t.split("::").length>2)return null;let r=t,n=r.lastIndexOf(":");if(r.includes(".")&&n>=0){let u=_(r.slice(n+1));if(!u)return null;r=`${r.slice(0,n)}:${((u[0]??0)*256+(u[1]??0)).toString(16)}:${((u[2]??0)*256+(u[3]??0)).toString(16)}`;}let[s,o]=r.split("::"),i=s?s.split(":"):[],l=o?o.split(":"):[],c=r.includes("::"),a=8-i.length-l.length;return c&&a<1||!c&&a!==0||[...i,...l].some(u=>!/^[0-9a-f]{1,4}$/.test(u))?null:[...i.map(u=>Number.parseInt(u,16)),...Array.from({length:a},()=>0),...l.map(u=>Number.parseInt(u,16))]}function ae(e){let t=_(e);if(!t)return "an invalid IPv4 address";let[r=0,n=0,s=0,o=0]=t;return r===0?"the unspecified/current-network IPv4 range":r===10||r===172&&n>=16&&n<=31||r===192&&n===168?"an RFC1918 private IPv4 range":r===127?"the IPv4 loopback range":r===169&&n===254?"the IPv4 link-local/metadata range":r===100&&n===100&&s===100&&o===200?"a cloud instance metadata endpoint":r===100&&n>=64&&n<=127?"the shared carrier-grade NAT IPv4 range":r===198&&(n===18||n===19)?"the IPv4 benchmarking range":r>=224&&r<=239?"the IPv4 multicast range":r>=240?"the reserved IPv4 range":null}function $e(e){let t=Y(e);if(!t||t.length!==8)return "an invalid IPv6 address";if(t.every(s=>s===0))return "the unspecified IPv6 address";if(t.slice(0,7).every(s=>s===0)&&t[7]===1)return "the IPv6 loopback address";let r=t[0]??0;if((r&65024)===64512)return "an IPv6 unique-local range";if((r&65472)===65152)return "the IPv6 link-local range";if((r&65280)===65280)return "the IPv6 multicast range";if(t.slice(0,5).every(s=>s===0)&&t[5]===65535){let s=t[6]??0,o=t[7]??0;return ae(`${s>>8}.${s&255}.${o>>8}.${o&255}`)}return null}function Z(e){return _(e)?ae(e):Y(e)?$e(e):"an invalid IP address"}function T(e,t){let r=m(e,t),n;try{n=new URL(r);}catch{throw new Error(`${t} must be a valid URL.`)}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new Error(`${t} must use HTTP or HTTPS.`);if(n.username||n.password)throw new Error(`${t} must not contain URL credentials.`);let s=Ie(n);if(!s)throw new Error(`${t} must contain a hostname.`);if(s==="localhost"||s.endsWith(".localhost"))throw new Error(`${t} must not target localhost.`);if(s==="metadata.google.internal")throw new Error(`${t} must not target a cloud instance metadata endpoint.`);if(_(s)||Y(s)){let o=Z(s);if(o)throw new Error(`${t} must not target ${o}.`)}return n}function Oe(e){let t=T(e.sourceOrigin,"sourceOrigin").origin;if(!Array.isArray(e.urls)||e.urls.length<1||e.urls.length>20)throw new Error("Render tasks require between 1 and 20 URLs.");for(let[o,i]of e.urls.entries())if(T(i,`urls[${o}]`).origin!==t)throw new Error(`urls[${o}] is outside sourceOrigin.`);let r=S(e.options,"options");if(typeof r.ignoreHttpsErrors!="boolean")throw new Error("options.ignoreHttpsErrors must be a boolean.");if(typeof r.javaScriptEnabled!="boolean")throw new Error("options.javaScriptEnabled must be a boolean.");let n=S(r.viewport,"options.viewport");R(n.width,"options.viewport.width",320,7680),R(n.height,"options.viewport.height",240,7680),R(r.navigationTimeoutMs,"options.navigationTimeoutMs",1e3,6e5),R(r.autoScrollTimeoutMs,"options.autoScrollTimeoutMs",0,12e4);let s=S(r.readiness,"options.readiness");for(let o of ["waitForSelector","waitForFunction"])if(s[o]!==null&&typeof s[o]!="string")throw new Error(`options.readiness.${o} must be a string or null.`);R(s.timeoutMs,"options.readiness.timeoutMs",0,12e4),R(s.fallbackWaitMs,"options.readiness.fallbackWaitMs",0,12e4);}function ve(e){if(!Array.isArray(e.urls)||e.urls.length<1||e.urls.length>20)throw new Error("Asset tasks require between 1 and 20 URLs.");for(let[r,n]of e.urls.entries())T(n,`urls[${r}]`);let t=S(e.options,"options");if(typeof t.ignoreHttpsErrors!="boolean")throw new Error("options.ignoreHttpsErrors must be a boolean.");R(t.timeoutMs,"options.timeoutMs",1e3,12e4);}function Ae(e){if(m(e.configKey,"configKey"),m(e.assetMapKey,"assetMapKey"),e.previousAssetMapKey!==void 0&&m(e.previousAssetMapKey,"previousAssetMapKey"),!Array.isArray(e.items)||e.items.length<1||e.items.length>500)throw new Error("Rewrite tasks require between 1 and 500 objects.");for(let[t,r]of e.items.entries()){let n=S(r,`items[${t}]`);m(n.inputKey,`items[${t}].inputKey`),m(n.outputKey,`items[${t}].outputKey`),m(n.relativePath,`items[${t}].relativePath`);}}function Te(e){if(A(m(e.targetId,"targetId"),"targetId"),!Array.isArray(e.items)||e.items.length>1e3)throw new Error("Deploy copy tasks accept at most 1000 objects.");for(let[r,n]of e.items.entries()){let s=S(n,`items[${r}]`);m(s.sourceKey,`items[${r}].sourceKey`),m(s.targetRelativeKey,`items[${r}].targetRelativeKey`),m(s.sha256,`items[${r}].sha256`),s.normalizedSha256!==void 0&&m(s.normalizedSha256,`items[${r}].normalizedSha256`),R(s.bytes,`items[${r}].bytes`,0,Number.MAX_SAFE_INTEGER),m(s.contentType,`items[${r}].contentType`),m(s.cacheControl,`items[${r}].cacheControl`);}let t=e.deleteRelativeKeys??[];if(!Array.isArray(t)||t.length>1e3)throw new Error("Deploy copy tasks accept at most 1000 deletion keys.");for(let[r,n]of t.entries())m(n,`deleteRelativeKeys[${r}]`);if(e.items.length===0&&t.length===0)throw new Error("Deploy copy tasks require copy or deletion work.")}function le(e){if(!e||typeof e!="object")throw new Error("Worker event must be a JSON object.");let t=e;if(t.schemaVersion!==b)throw new Error(`Unsupported worker protocol version: ${String(t.schemaVersion)}.`);let r=t.operation;if(r!=="render"&&r!=="asset"&&r!=="rewrite"&&r!=="deploy-copy"&&r!=="health")throw new Error(`Unsupported worker operation: ${String(r)}.`);return A(String(t.jobId??""),"jobId"),A(String(t.taskId??""),"taskId"),r==="render"&&Oe(t),r==="asset"&&ve(t),r==="rewrite"&&Ae(t),r==="deploy-copy"&&Te(t),e}function je(e){return e.hostname.replace(/^\[|\]$/g,"").replace(/\.$/,"").toLowerCase()}async function Ve(e){return (await lookup(e,{all:true,verbatim:true})).map(t=>t.address)}async function Q(e,t,r=Ve){let n=T(e,t),s=je(n);if(isIP(s))return n;let o;try{o=await r(s);}catch{throw new Error(`${t} hostname could not be resolved safely.`)}if(o.length===0)throw new Error(`${t} hostname resolved to no addresses.`);for(let i of o){let l=Z(i);if(l)throw new Error(`${t} hostname resolves to ${l}.`)}return n}async function ce(e,t=Q){let r=null;return await e.route("**/*",async n=>{try{await t(n.request().url(),"render request");}catch(s){r??=s instanceof Error?s:new Error(String(s)),await n.abort("blockedbyclient").catch(()=>{});return}await n.continue();}),await e.routeWebSocket("**/*",async n=>{try{await t(n.url(),"render WebSocket request");}catch(s){r??=s instanceof Error?s:new Error(String(s)),await n.close({code:1008,reason:"Blocked by network policy"});return}await n.close({code:1008,reason:"Only HTTP(S) requests are allowed"}),r??=new Error("render WebSocket request must use HTTP or HTTPS.");}),{getViolation:()=>r}}function Ue(e){return e.replace(/&/gi,"&").replace(/"/gi,'"').replace(/'|'/gi,"'").replace(/</gi,"<").replace(/>/gi,">")}function Ke(e,t){let r=e.trim();if(!r||r.startsWith("data:")||r.startsWith("blob:")||r.startsWith("javascript:")||r.startsWith("#"))return null;try{let n=new URL(r,t);return n.protocol!=="http:"&&n.protocol!=="https:"||n.username||n.password?null:(n.hash="",n.toString())}catch{return null}}function I(e,t,r){let n=Ke(t,r);n&&e.add(n);}function Le(e,t,r){for(let n of t.split(",")){let s=n.trim().split(/\s+/,1)[0];s&&I(e,s,r);}}function ee(e,t,r=""){let n=new Set,s=Ue(t).replace(/\\\//g,"/");for(let l of s.matchAll(/\b(?:src|href|poster|data-src|data-href|data-resource-url)\s*=\s*["']([^"']+)["']/gi))I(n,l[1]??"",e);for(let l of s.matchAll(/\b(?:srcset|data-srcset)\s*=\s*["']([^"']+)["']/gi))Le(n,l[1]??"",e);for(let l of s.matchAll(/url\(\s*(?:"([^"]+)"|'([^']+)'|([^)]*?))\s*\)/gi))I(n,l[1]??l[2]??l[3]??"",e);for(let l of s.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;)]+)['"]?\s*\)?/gi))I(n,l[1]??"",e);for(let l of s.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi))I(n,l[1]??"",e);let o=(()=>{try{return j.extname(new URL(e).pathname).toLowerCase()}catch{return ""}})();if(o===".js"||o===".mjs"||/(?:java|ecma)script/i.test(r))for(let l of s.matchAll(/["']((?:\.\.?\/|\/)?[^"'\s]+\.(?:js|mjs)(?:[?#][^"']*)?)["']/gi))I(n,l[1]??"",e);return [...n].sort()}function pe(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function $(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function H(e){return e.replace(/\//g,"\\/")}function ue(e){return e.replace(/\//g,"\\\\/")}function _e(e){try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return null;let r=t.pathname==="/"&&!t.search&&!t.hash?"":`${t.pathname}${t.search}${t.hash}`;return `//${t.host}${r}`}catch{return null}}function de(e,t,r){if(!t)return;e[t]=r;let n=H(t),s=H(r);e[n]=s;let o=ue(t),i=ue(r);e[o]=i;let l=$(t),c=$(r);e[l]=c;let a=$(n),u=$(s);e[a]=u;let d=$(o),p=$(i);e[d]=p;}function N(e,t,r){de(e,t,r);let n=_e(t);n&&n!==t&&de(e,n,r);}function ge(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function me(e,t,r){if(!t)return r;let n=j.dirname(j.resolve(t)),s=j.resolve(e,r.replace(/^\/+/,"")),o=j.relative(n,s).replace(/\\/g,"/");return o?(o.startsWith(".")||(o=`./${o}`),o):"."}var Fe=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],He=new Set([".html",".htm"]),fe="WPSuite.io Static Publisher",Ne=fe.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function qe(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Be(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function De(e,t,r){return Be(t)?e.replace(new RegExp(`(?<!:)${qe(t)}`,"g"),r):e.split(t).join(r)}function ze(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let s=j.extname(r).toLowerCase();return He.has(s)?/<head\b|<html\b|<!doctype html/i.test(t):false}function Je(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Ne}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${fe}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let n=e.includes(`\r
|
|
1
|
+
import {S3Client,HeadObjectCommand,CopyObjectCommand,DeleteObjectsCommand,PutObjectCommand,GetObjectCommand}from'@aws-sdk/client-s3';import {request,chromium}from'playwright';import {createHash}from'crypto';import {lookup}from'dns/promises';import {isIP}from'net';import M from'path';import'fast-glob';import'fs/promises';import'os';import'worker_threads';import {DynamoDBClient,UpdateItemCommand}from'@aws-sdk/client-dynamodb';import xe from'mime-types';var k=1,de=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function W(e,t){let r=String(e??"").trim();if(!de.test(r))throw new Error(`${t} must match ${de.source} and be at most 128 characters.`);return r}function j(e){let t=String(e??"").trim().replace(/^\/+|\/+$/g,"");if(!t)return "";let r=t.split("/").filter(Boolean);if(r.some(o=>o==="."||o===".."))throw new Error("S3 prefix contains an unsafe dot path segment.");return `${r.join("/")}/`}function x(e,...t){let r=j(e),o=t.map((n,s)=>{let a=String(n??"").replace(/^\/+|\/+$/g,"");if(!a||a.split("/").some(i=>i==="."||i===".."))throw new Error(`Unsafe S3 key segment at index ${s}.`);return a});return `${r}${o.join("/")}`}function _(e,t,r){return `${x(e,"jobs",W(t,"jobId"),"tasks",W(r,"taskId"))}/`}function V(e){return createHash("sha256").update(e).digest("hex")}function T(e,t){let r=String(e??"").replace(/^\/+/,""),o=j(t);if(!r||r.includes("\0"))throw new Error("S3 object key is empty or invalid.");if(o&&!r.startsWith(o))throw new Error(`S3 object key is outside the configured workspace prefix: ${r}`);if(r.split("/").some(n=>n===".."))throw new Error("S3 object key contains an unsafe parent segment.");return r}function I(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new Error(`${t} must be a JSON object.`);return e}function h(e,t){if(typeof e!="string"||!e.trim())throw new Error(`${t} must be a non-empty string.`);return e.trim()}function E(e,t,r,o){if(!Number.isInteger(e)||Number(e)<r||Number(e)>o)throw new Error(`${t} must be an integer between ${r} and ${o}.`);return Number(e)}function je(e){return e.hostname.replace(/^\[|\]$/g,"").replace(/\.$/,"").toLowerCase()}function q(e){let t=e.split(".");if(t.length!==4)return null;let r=t.map(o=>Number(o));return r.every((o,n)=>Number.isInteger(o)&&o>=0&&o<=255&&String(o)===t[n])?r:null}function ee(e){let t=e.toLowerCase();if(t.includes("%")||t.split("::").length>2)return null;let r=t,o=r.lastIndexOf(":");if(r.includes(".")&&o>=0){let l=q(r.slice(o+1));if(!l)return null;r=`${r.slice(0,o)}:${((l[0]??0)*256+(l[1]??0)).toString(16)}:${((l[2]??0)*256+(l[3]??0)).toString(16)}`;}let[n,s]=r.split("::"),a=n?n.split(":"):[],i=s?s.split(":"):[],c=r.includes("::"),d=8-a.length-i.length;return c&&d<1||!c&&d!==0||[...a,...i].some(l=>!/^[0-9a-f]{1,4}$/.test(l))?null:[...a.map(l=>Number.parseInt(l,16)),...Array.from({length:d},()=>0),...i.map(l=>Number.parseInt(l,16))]}function pe(e){let t=q(e);if(!t)return "an invalid IPv4 address";let[r=0,o=0,n=0,s=0]=t;return r===0?"the unspecified/current-network IPv4 range":r===10||r===172&&o>=16&&o<=31||r===192&&o===168?"an RFC1918 private IPv4 range":r===127?"the IPv4 loopback range":r===169&&o===254?"the IPv4 link-local/metadata range":r===100&&o===100&&n===100&&s===200?"a cloud instance metadata endpoint":r===100&&o>=64&&o<=127?"the shared carrier-grade NAT IPv4 range":r===198&&(o===18||o===19)?"the IPv4 benchmarking range":r>=224&&r<=239?"the IPv4 multicast range":r>=240?"the reserved IPv4 range":null}function Ve(e){let t=ee(e);if(!t||t.length!==8)return "an invalid IPv6 address";if(t.every(n=>n===0))return "the unspecified IPv6 address";if(t.slice(0,7).every(n=>n===0)&&t[7]===1)return "the IPv6 loopback address";let r=t[0]??0;if((r&65024)===64512)return "an IPv6 unique-local range";if((r&65472)===65152)return "the IPv6 link-local range";if((r&65280)===65280)return "the IPv6 multicast range";if(t.slice(0,5).every(n=>n===0)&&t[5]===65535){let n=t[6]??0,s=t[7]??0;return pe(`${n>>8}.${n&255}.${s>>8}.${s&255}`)}return null}function te(e){return q(e)?pe(e):ee(e)?Ve(e):"an invalid IP address"}function C(e,t){let r=h(e,t),o;try{o=new URL(r);}catch{throw new Error(`${t} must be a valid URL.`)}if(o.protocol!=="http:"&&o.protocol!=="https:")throw new Error(`${t} must use HTTP or HTTPS.`);if(o.username||o.password)throw new Error(`${t} must not contain URL credentials.`);let n=je(o);if(!n)throw new Error(`${t} must contain a hostname.`);if(n==="localhost"||n.endsWith(".localhost"))throw new Error(`${t} must not target localhost.`);if(n==="metadata.google.internal")throw new Error(`${t} must not target a cloud instance metadata endpoint.`);if(q(n)||ee(n)){let s=te(n);if(s)throw new Error(`${t} must not target ${s}.`)}return o}function Me(e){let t=C(e.sourceOrigin,"sourceOrigin").origin;if(!Array.isArray(e.urls)||e.urls.length<1||e.urls.length>20)throw new Error("Render tasks require between 1 and 20 URLs.");for(let[s,a]of e.urls.entries())if(C(a,`urls[${s}]`).origin!==t)throw new Error(`urls[${s}] is outside sourceOrigin.`);let r=I(e.options,"options");if(typeof r.ignoreHttpsErrors!="boolean")throw new Error("options.ignoreHttpsErrors must be a boolean.");if(typeof r.javaScriptEnabled!="boolean")throw new Error("options.javaScriptEnabled must be a boolean.");let o=I(r.viewport,"options.viewport");E(o.width,"options.viewport.width",320,7680),E(o.height,"options.viewport.height",240,7680),E(r.navigationTimeoutMs,"options.navigationTimeoutMs",1e3,6e5),E(r.autoScrollTimeoutMs,"options.autoScrollTimeoutMs",0,12e4);let n=I(r.readiness,"options.readiness");for(let s of ["waitForSelector","waitForFunction"])if(n[s]!==null&&typeof n[s]!="string")throw new Error(`options.readiness.${s} must be a string or null.`);E(n.timeoutMs,"options.readiness.timeoutMs",0,12e4),E(n.fallbackWaitMs,"options.readiness.fallbackWaitMs",0,12e4);}function Ue(e){if(!Array.isArray(e.urls)||e.urls.length<1||e.urls.length>20)throw new Error("Asset tasks require between 1 and 20 URLs.");for(let[r,o]of e.urls.entries())C(o,`urls[${r}]`);let t=I(e.options,"options");if(typeof t.ignoreHttpsErrors!="boolean")throw new Error("options.ignoreHttpsErrors must be a boolean.");E(t.timeoutMs,"options.timeoutMs",1e3,12e4);}function Le(e){if(h(e.configKey,"configKey"),h(e.assetMapKey,"assetMapKey"),e.previousAssetMapKey!==void 0&&h(e.previousAssetMapKey,"previousAssetMapKey"),!Array.isArray(e.items)||e.items.length<1||e.items.length>500)throw new Error("Rewrite tasks require between 1 and 500 objects.");for(let[t,r]of e.items.entries()){let o=I(r,`items[${t}]`);h(o.inputKey,`items[${t}].inputKey`),h(o.outputKey,`items[${t}].outputKey`),h(o.relativePath,`items[${t}].relativePath`),o.contentType!==void 0&&o.contentType!==null&&h(o.contentType,`items[${t}].contentType`);}}function Ke(e){if(W(h(e.targetId,"targetId"),"targetId"),!Array.isArray(e.items)||e.items.length>1e3)throw new Error("Deploy copy tasks accept at most 1000 objects.");for(let[r,o]of e.items.entries()){let n=I(o,`items[${r}]`);h(n.sourceKey,`items[${r}].sourceKey`),h(n.targetRelativeKey,`items[${r}].targetRelativeKey`),h(n.sha256,`items[${r}].sha256`),n.normalizedSha256!==void 0&&h(n.normalizedSha256,`items[${r}].normalizedSha256`),E(n.bytes,`items[${r}].bytes`,0,Number.MAX_SAFE_INTEGER),h(n.contentType,`items[${r}].contentType`),h(n.cacheControl,`items[${r}].cacheControl`);}let t=e.deleteRelativeKeys??[];if(!Array.isArray(t)||t.length>1e3)throw new Error("Deploy copy tasks accept at most 1000 deletion keys.");for(let[r,o]of t.entries())h(o,`deleteRelativeKeys[${r}]`);if(e.items.length===0&&t.length===0)throw new Error("Deploy copy tasks require copy or deletion work.")}function me(e){if(!e||typeof e!="object")throw new Error("Worker event must be a JSON object.");let t=e;if(t.schemaVersion!==k)throw new Error(`Unsupported worker protocol version: ${String(t.schemaVersion)}.`);let r=t.operation;if(r!=="render"&&r!=="asset"&&r!=="rewrite"&&r!=="deploy-copy"&&r!=="health")throw new Error(`Unsupported worker operation: ${String(r)}.`);return W(String(t.jobId??""),"jobId"),W(String(t.taskId??""),"taskId"),r==="render"&&Me(t),r==="asset"&&Ue(t),r==="rewrite"&&Le(t),r==="deploy-copy"&&Ke(t),e}function Ne(e){return e.hostname.replace(/^\[|\]$/g,"").replace(/\.$/,"").toLowerCase()}async function Fe(e){return (await lookup(e,{all:true,verbatim:true})).map(t=>t.address)}async function re(e,t,r=Fe){let o=C(e,t),n=Ne(o);if(isIP(n))return o;let s;try{s=await r(n);}catch{throw new Error(`${t} hostname could not be resolved safely.`)}if(s.length===0)throw new Error(`${t} hostname resolved to no addresses.`);for(let a of s){let i=te(a);if(i)throw new Error(`${t} hostname resolves to ${i}.`)}return o}async function ge(e,t=re){let r=null;return await e.route("**/*",async o=>{try{await t(o.request().url(),"render request");}catch(n){r??=n instanceof Error?n:new Error(String(n)),await o.abort("blockedbyclient").catch(()=>{});return}await o.continue();}),await e.routeWebSocket("**/*",async o=>{try{await t(o.url(),"render WebSocket request");}catch(n){r??=n instanceof Error?n:new Error(String(n)),await o.close({code:1008,reason:"Blocked by network policy"});return}await o.close({code:1008,reason:"Only HTTP(S) requests are allowed"}),r??=new Error("render WebSocket request must use HTTP or HTTPS.");}),{getViolation:()=>r}}function Be(e){return e.replace(/&/gi,"&").replace(/"/gi,'"').replace(/'|'/gi,"'").replace(/</gi,"<").replace(/>/gi,">")}function De(e,t){let r=e.trim();if(!r||r.startsWith("data:")||r.startsWith("blob:")||r.startsWith("javascript:")||r.startsWith("#"))return null;try{let o=new URL(r,t);return o.protocol!=="http:"&&o.protocol!=="https:"||o.username||o.password?null:(o.hash="",o.toString())}catch{return null}}function $(e,t,r){let o=De(t,r);o&&e.add(o);}function ze(e,t,r){for(let o of t.split(",")){let n=o.trim().split(/\s+/,1)[0];n&&$(e,n,r);}}function ne(e,t,r=""){let o=new Set,n=Be(t).replace(/\\\//g,"/");for(let i of n.matchAll(/\b(?:src|href|poster|data-src|data-href|data-resource-url)\s*=\s*["']([^"']+)["']/gi))$(o,i[1]??"",e);for(let i of n.matchAll(/\b(?:srcset|data-srcset)\s*=\s*["']([^"']+)["']/gi))ze(o,i[1]??"",e);for(let i of n.matchAll(/url\(\s*(?:"([^"]+)"|'([^']+)'|([^)]*?))\s*\)/gi))$(o,i[1]??i[2]??i[3]??"",e);for(let i of n.matchAll(/@import\s+(?:url\()?\s*['"]?([^'"\s;)]+)['"]?\s*\)?/gi))$(o,i[1]??"",e);for(let i of n.matchAll(/<\?xml-stylesheet[^>]+href=["']([^"']+)["'][^>]*\?>/gi))$(o,i[1]??"",e);let s=(()=>{try{return M.extname(new URL(e).pathname).toLowerCase()}catch{return ""}})();if(s===".js"||s===".mjs"||/(?:java|ecma)script/i.test(r))for(let i of n.matchAll(/["']((?:\.\.?\/|\/)?[^"'\s]+\.(?:js|mjs)(?:[?#][^"']*)?)["']/gi))$(o,i[1]??"",e);return [...o].sort()}function we(e){return e.replace(/"/g,'"').replace(/"/g,'"').replace(/'/g,"'").replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function v(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function F(e){return e.replace(/\//g,"\\/")}function fe(e){return e.replace(/\//g,"\\\\/")}function Je(e){try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return null;let r=t.pathname==="/"&&!t.search&&!t.hash?"":`${t.pathname}${t.search}${t.hash}`;return `//${t.host}${r}`}catch{return null}}function he(e,t,r){if(!t)return;e[t]=r;let o=F(t),n=F(r);e[o]=n;let s=fe(t),a=fe(r);e[s]=a;let i=v(t),c=v(r);e[i]=c;let d=v(o),l=v(n);e[d]=l;let u=v(s),p=v(a);e[u]=p;}function H(e,t,r){he(e,t,r);let o=Je(t);o&&o!==t&&he(e,o,r);}function ye(e,t){try{return new URL(e,t==="."?"https://relative.invalid":t).pathname}catch{return e.startsWith("/")?e:`/${e.replace(/^\.\//,"")}`}}function Re(e,t,r){if(!t)return r;let o=M.dirname(M.resolve(t)),n=M.resolve(e,r.replace(/^\/+/,"")),s=M.relative(o,n).replace(/\\/g,"/");return s?(s.startsWith(".")||(s=`./${s}`),s):"."}var Ge=["wp-content/","wp-includes/","wp-admin/","wp-json/","_next/"],Xe=new Set([".html",".htm"]),be="WPSuite.io Static Publisher",Ze=be.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Ye(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Qe(e){return e.startsWith("//")||e.startsWith("\\/\\/")||e.startsWith("\\\\/\\\\/")}function et(e,t,r){return Qe(t)?e.replace(new RegExp(`(?<!:)${Ye(t)}`,"g"),r):e.split(t).join(r)}function tt(e,t,r){if(e.wpsuite?.siteSettings?.subscriber===true||e.wpsuite?.subscriptionType==="PROFESSIONAL"||e.wpsuite?.subscriptionType==="AGENCY"||!r)return false;let n=M.extname(r).toLowerCase();return Xe.has(n)?/<head\b|<html\b|<!doctype html/i.test(t):false}function rt(e){if(new RegExp(`<meta\\b(?=[^>]*\\bname=(["'])generator\\1)(?=[^>]*\\bcontent=(["'])${Ze}\\2)[^>]*\\/?>`,"i").test(e))return e;let t=`<meta name="generator" content="${be}" />`;if(e.match(/(\r?\n)([ \t]*)<\/head>/i))return e.replace(/(\r?\n)([ \t]*)<\/head>/i,`$1$2${t}$1$2</head>`);let o=e.includes(`\r
|
|
2
2
|
`)?`\r
|
|
3
3
|
`:`
|
|
4
|
-
`;return e.replace(/<head\b[^>]*>/i,
|
|
5
|
-
`,"application/json; charset=utf-8")}async function ft(e){try{let t=await D(e);return t.response??t}catch(t){if(t.name==="NoSuchKey"||t.$metadata?.httpStatusCode===404)return null;throw t}}function B(e){return [...new Set(e)].filter(t=>{try{let r=new URL(t);return (r.protocol==="http:"||r.protocol==="https:")&&!r.username&&!r.password}catch{return false}}).sort()}async function ht(e,t,r){let n=null,s=null,o,i=new Set;try{let l=await dt(e);n=l.context,s=l.page,o=l.networkPolicyViolation,s.on("request",g=>i.add(g.url()));let c=await s.goto(t,{waitUntil:"domcontentloaded",timeout:e.options.navigationTimeoutMs});e.options.readiness.waitForSelector&&await s.waitForSelector(e.options.readiness.waitForSelector,{timeout:e.options.readiness.timeoutMs}).catch(()=>{}),e.options.javaScriptEnabled&&e.options.readiness.waitForFunction&&await s.waitForFunction(e.options.readiness.waitForFunction,void 0,{timeout:e.options.readiness.timeoutMs}).catch(()=>{}),e.options.javaScriptEnabled?await gt(s,e.options.autoScrollTimeoutMs):await s.waitForLoadState("load",{timeout:e.options.readiness.timeoutMs}).catch(()=>{}),e.options.readiness.fallbackWaitMs>0&&await s.waitForTimeout(e.options.readiness.fallbackWaitMs);let a=o?.();if(a)throw a;let u=await s.evaluate(()=>{let g=(k,ke)=>{let G=[];for(let xe of document.querySelectorAll(k))for(let se of ke){let X=xe.getAttribute(se);if(X)if(se.includes("srcset"))for(let Se of X.split(",")){let oe=Se.trim().split(/\s+/,1)[0];oe&&G.push(oe);}else G.push(X);}return G},v=k=>{try{return new URL(k,document.baseURI).href}catch{return null}};return {links:g("a[href]",["href"]).map(v).filter(k=>k!==null),assets:g("img,script,link,source,video,audio,iframe,[data-src],[data-href],[data-resource-url]",["src","href","srcset","data-src","data-srcset","data-href","data-resource-url","poster"]).map(v).filter(k=>k!==null)}});await s.evaluate(()=>{document.querySelectorAll("#wpsuite-consent-root").forEach(g=>g.remove()),document.documentElement.classList.remove("wpsuite-consent-scroll-locked"),document.body.classList.remove("wpsuite-consent-scroll-locked");});let d=await s.content(),p=o();if(p)throw p;let f=new URL(t),E=B(u.links).filter(g=>{let v=new URL(g);return v.hash="",v.origin===f.origin}),J=x(L(w,e.jobId,e.taskId),"pages",`${String(r).padStart(4,"0")}-${W(t).slice(0,24)}.html`),U=await z(J,d,"text/html; charset=utf-8"),y=(await n.cookies()).map(g=>({name:g.name,domain:g.domain,path:g.path,expires:g.expires,httpOnly:g.httpOnly,secure:g.secure,sameSite:g.sameSite,..."partitionKey"in g?{partitioned:!0}:{}})),K=c?.status()??null;return {requestedUrl:t,finalUrl:s?.url()||null,outcome:K!==null&&K>=400?"http-error":"rendered",httpStatus:K,contentType:c?.headers()["content-type"]??null,html:U,discoveredPages:E,discoveredAssets:B([...u.assets,...ee(s.url()||t,d,c?.headers()["content-type"]??"text/html")]),networkUrls:B([...i]),cookies:y}}catch(l){return {requestedUrl:t,finalUrl:s?.url()||null,outcome:"failed",httpStatus:null,contentType:null,html:null,discoveredPages:[],discoveredAssets:[],networkUrls:B([...i]),cookies:[],error:l instanceof Error?l.message:String(l)}}finally{await n?.close().catch(()=>{});}}function wt(e,t){let r=t.toLowerCase();if(r.startsWith("text/")||r.includes("javascript")||r.includes("json")||r.includes("xml")||r.includes("svg"))return true;try{return /\.(?:css|js|mjs|json|xml|xsl|svg|txt|map|html?)$/i.test(new URL(e).pathname)}catch{return false}}async function yt(e,t,r){let n=t;for(let s=0;s<=5;s+=1){await Q(n,"asset request");let o=await e.get(n,{timeout:r,failOnStatusCode:false,maxRedirects:0}),i=o.status();if(i<300||i>=400)return o;let l=o.headers().location;if(!l)return o;if(s===5)throw await o.dispose(),new Error("Asset request exceeded five redirects.");n=new URL(l,n).toString(),await o.dispose();}throw new Error("Asset redirect handling failed.")}async function Rt(e,t){if(!Array.isArray(e.urls)||e.urls.length<1||e.urls.length>20)throw new Error("Asset tasks require between 1 and 20 URLs.");let r=await request.newContext({ignoreHTTPSErrors:e.options.ignoreHttpsErrors,userAgent:"WPSuiteStaticPublisher/remote-asset-worker-v1",...V?{proxy:{server:V}}:{}}),n=[];try{for(let o=0;o<e.urls.length;o+=1){let i=e.urls[o],l=t.getRemainingTimeInMillis?.();if(l!==void 0&&l<3e4){n.push({requestedUrl:i,finalUrl:null,outcome:"deferred",httpStatus:null,contentType:null,cacheControl:null,lastModified:null,object:null,discoveredAssets:[],error:"Worker stopped accepting assets because less than 30 seconds remained."});continue}let c=null;try{c=await yt(r,i,e.options.timeoutMs);let a=c.status(),u=c.headers(),d=c.url()||i;if(a<200||a>=300){n.push({requestedUrl:i,finalUrl:d,outcome:"http-error",httpStatus:a,contentType:u["content-type"]??null,cacheControl:u["cache-control"]??null,lastModified:u["last-modified"]??null,object:null,discoveredAssets:[],error:`Asset returned HTTP ${a}.`});continue}let p=await c.body(),f=u["content-type"]??"application/octet-stream",E=await z(x(L(w,e.jobId,e.taskId),"assets",`${String(o).padStart(4,"0")}-${W(i).slice(0,24)}.bin`),p,f);n.push({requestedUrl:i,finalUrl:d,outcome:"fetched",httpStatus:a,contentType:f,cacheControl:u["cache-control"]??null,lastModified:u["last-modified"]??null,object:E,discoveredAssets:wt(d,f)?ee(d,new TextDecoder("utf8").decode(p),f):[]});}catch(a){n.push({requestedUrl:i,finalUrl:c?.url()??null,outcome:"failed",httpStatus:c?.status()??null,contentType:c?.headers()["content-type"]??null,cacheControl:c?.headers()["cache-control"]??null,lastModified:c?.headers()["last-modified"]??null,object:null,discoveredAssets:[],error:a instanceof Error?a.message:String(a)});}finally{await c?.dispose().catch(()=>{});}}}finally{await r.dispose();}let s=n.filter(o=>o.outcome==="failed"||o.outcome==="deferred").length;return {response:{schemaVersion:b,operation:"asset",jobId:e.jobId,taskId:e.taskId,status:s>0?"partial":"succeeded",completedItems:n.length-s,failedItems:s,exporterVersion:M},detail:{assets:n}}}async function bt(e,t){if(!Array.isArray(e.urls)||e.urls.length<1||e.urls.length>20)throw new Error("Render tasks require between 1 and 20 URLs.");let r=new URL(e.sourceOrigin).origin,n=[];for(let o=0;o<e.urls.length;o+=1){let i=e.urls[o];if(!i)continue;let l=t.getRemainingTimeInMillis?.();if(l!==void 0&&l<6e4){n.push({requestedUrl:i,finalUrl:null,outcome:"deferred",httpStatus:null,contentType:null,html:null,discoveredPages:[],discoveredAssets:[],networkUrls:[],cookies:[],error:"Worker stopped accepting URLs because less than 60 seconds remained."});continue}let c=new URL(i);if(c.origin!==r)throw new Error(`Primary render URL is outside sourceOrigin: ${i}`);n.push(await ht(e,c.toString(),o));}let s=n.filter(o=>o.outcome==="failed"||o.outcome==="deferred").length;return {response:{schemaVersion:b,operation:"render",jobId:e.jobId,taskId:e.taskId,status:s>0?"partial":"succeeded",completedItems:n.length-s,failedItems:s,exporterVersion:M},detail:{pages:n}}}async function Et(e){if(!Array.isArray(e.items)||e.items.length<1||e.items.length>500)throw new Error("Rewrite tasks require between 1 and 500 objects.");let r={...await D(e.configKey),outputDir:"/workspace"},n=await D(e.assetMapKey),s=e.previousAssetMapKey?await D(e.previousAssetMapKey):{},o=[];for(let i of e.items){let l=P(i.inputKey,w),c=P(i.outputKey,w),a=await Ee(l),u=`/workspace/${i.relativePath.replace(/^\/+/,"")}`,d=he(a,r,n,u,s),p=await z(c,d,"text/plain; charset=utf-8");o.push({inputKey:l,outputKey:c,changed:d!==a,output:p});}return {response:{schemaVersion:b,operation:"rewrite",jobId:e.jobId,taskId:e.taskId,status:"succeeded",completedItems:o.length,failedItems:0,exporterVersion:M},detail:{objects:o}}}function kt(e,t){return `${e}/${t.split("/").map(r=>encodeURIComponent(r)).join("/")}`}async function xt(e){if(!Array.isArray(e.items)||e.items.length>1e3)throw new Error("Deploy copy tasks accept at most 1000 objects.");let t=at.find(a=>a.id===e.targetId);if(!t)throw new Error(`Unknown deployment target: ${e.targetId}`);let r=we.get(t.region);r||(r=new S3Client({region:t.region}),we.set(t.region,r));let n=[];for(let a of e.items){let u=P(a.sourceKey,w),d=x(t.prefix,a.targetRelativeKey);try{let p=await r.send(new HeadObjectCommand({Bucket:t.bucketName,Key:d})).catch(y=>{if((y&&typeof y=="object"&&"$metadata"in y?Number(y.$metadata?.httpStatusCode):0)===404||y?.name==="NotFound")return null;throw y}),f=String(p?.CacheControl??"").replace(/\s+/g,"")===a.cacheControl.replace(/\s+/g,""),E=p?.Metadata?.["wpsuite-sha256"]===a.sha256,J=!!a.normalizedSha256&&p?.Metadata?.["wpsuite-normalized-sha256"]===a.normalizedSha256;if(f&&(E||J)){n.push({sourceKey:u,targetKey:d,status:"skipped"});continue}let U=await r.send(new CopyObjectCommand({Bucket:t.bucketName,Key:d,CopySource:kt(O,u),MetadataDirective:"REPLACE",ContentType:a.contentType,CacheControl:a.cacheControl,Metadata:{"wpsuite-sha256":a.sha256,...a.normalizedSha256?{"wpsuite-normalized-sha256":a.normalizedSha256}:{}}}));n.push({sourceKey:u,targetKey:d,status:"copied",...U.CopyObjectResult?.ETag?{etag:U.CopyObjectResult.ETag}:{}});}catch(p){n.push({sourceKey:u,targetKey:d,status:"failed",error:p instanceof Error?p.message:String(p)});}}let o=(e.deleteRelativeKeys??[]).map(a=>x(t.prefix,a)),i=[],l=[];if(o.length>0){let a=await r.send(new DeleteObjectsCommand({Bucket:t.bucketName,Delete:{Objects:o.map(u=>({Key:u})),Quiet:false}}));i.push(...(a.Deleted??[]).flatMap(u=>u.Key?[u.Key]:[])),l.push(...(a.Errors??[]).map(u=>({key:u.Key??"",error:u.Message??u.Code??"S3 deletion failed"})));}let c=n.filter(a=>a.status==="failed").length+l.length;return {response:{schemaVersion:b,operation:"deploy-copy",jobId:e.jobId,taskId:e.taskId,status:c>0?"partial":"succeeded",completedItems:n.filter(a=>a.status!=="failed").length+i.length,failedItems:c,exporterVersion:M},detail:{objects:n,deletedKeys:i,deleteErrors:l,targetId:t.id}}}async function ye(e,t){if(e.operation==="health")return {response:{schemaVersion:b,operation:"health",jobId:e.jobId,taskId:e.taskId,status:"succeeded",completedItems:1,failedItems:0,exporterVersion:M},detail:{allowedOperation:q,workspaceBucket:O,workspacePrefix:w,proxyConfigured:!!V}};if(q&&q!==e.operation)throw new Error(`Function is configured for ${q}, not ${e.operation}.`);return e.operation==="render"?await bt(e,t):e.operation==="asset"?await Rt(e,t):e.operation==="rewrite"?await Et(e):await xt(e)}async function sr(e,t={}){let r=le(e);try{if(r.operation==="health")return (await ye(r,t)).response;ne();let n=x(L(w,r.jobId,r.taskId),"result.json"),s=await ft(n);if(s)return s;let o=await ye(r,t),i={...o.response,resultKey:n};return await mt(n,{schemaVersion:b,response:i,detail:o.detail,completedAt:new Date().toISOString(),requestId:t.awsRequestId??null}),i}finally{r.operation==="render"&&await ut();}}export{sr as handler};
|
|
4
|
+
`;return e.replace(/<head\b[^>]*>/i,n=>`${n}${o} ${t}`)}function nt(e){let t=we(e).trim();return t.startsWith("{")||t.startsWith("[")||t.includes("\\/")||/"@context"|"@type"/.test(t)}function ot(e,t){let r=[...new Set(t)].filter(s=>s.includes("/")&&!/\\+\//.test(s)).map(s=>[s,F(s)]).filter(([s,a])=>s!==a).sort((s,a)=>a[0].length-s[0].length);if(!r.length)return e;let o=s=>{let a=s;for(let[i,c]of r)a=a.split(i).join(c);return a},n=e.replace(/(<script\b[^>]*\btype=["']application\/(?:ld\+)?json["'][^>]*>)([\s\S]*?)(<\/script>)/gi,(s,a,i,c)=>`${a}${o(i)}${c}`);return n=n.replace(/(<meta\b[^>]*\bcontent=(['"]))([\s\S]*?)(\2[^>]*>)/gi,(s,a,i,c,d)=>nt(c)?`${a}${o(c)}${d}`:s),n}function st(e,t){if(!t)return null;let r=M.dirname(M.resolve(t)),o=M.resolve(e.outputDir),n=M.relative(r,o).replace(/\\/g,"/");return n?(n.startsWith(".")||(n=`./${n}`),n.endsWith("/")?n:`${n}/`):"./"}function it(e,t,r){let o=st(t,r);if(!o)return e;let n=e;for(let s of Ge){let a=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=new RegExp(`(?:\\.{1,}/)+${a}`,"g"),c=new RegExp(`(?<!\\.)/${a}`,"g");n=n.replace(i,`${o}${s}`).replace(c,`${o}${s}`);let d=s.replace(/\//g,"\\/"),l=o.replace(/\//g,"\\/"),u=d.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),p=new RegExp(`(?:\\.{1,}\\\\/)+${u}`,"g"),m=new RegExp(`(?:\\.{1,}(?:\\\\/|\\\\))+${u}`,"g"),w=new RegExp(`(?<![\\.\\\\])\\/${u}`,"g");n=n.replace(p,`${l}${d}`).replace(m,`${l}${d}`).replace(w,`${l}${d}`);}return n}function se(e,t,r){if(e.urlRewriteMode==="absolute")return t;let o=(()=>{try{return new URL(t,e.targetOrigin==="."?"https://relative.invalid":e.targetOrigin)}catch{return null}})(),n=o?o.pathname:ye(t,e.targetOrigin),s=o?`${o.search}${o.hash}`:"";return e.urlRewriteMode==="root-relative"?`${n}${s}`:`${Re(e.outputDir,r,n)}${s}`}function oe(e,t,r,o,n){H(e,r,se(t,o,n));}function at(e,t,r,o,n){if(!r||r===o)return;H(e,r,o);let s=se(t,r,n),a=se(t,o,n);H(e,s,a);}function Ee(e,t,r,o,n={}){let s=e,a={};oe(a,t,t.sourceOrigin,t.targetOrigin,o);for(let[c,d]of Object.entries(t.extraReplacements))oe(a,t,c,d,o);for(let[c,d]of Object.entries(r))oe(a,t,c,d,o);for(let[c,d]of Object.entries(n)){let l=r[c];!l||l===d||at(a,t,d,l,o);}let i=Object.entries(a).sort((c,d)=>d[0].length-c[0].length);for(let[c,d]of i)s=et(s,c,d);return t.urlRewriteMode!=="absolute"&&(s=it(s,t,o)),s=ot(s,i.map(([,c])=>c)),tt(t,s,o)&&(s=rt(s)),s}var ie=String(process.env.PUBLISHER_PROGRESS_TABLE??"").trim(),ke=Number(process.env.PUBLISHER_PROGRESS_RETENTION_SECONDS??604800),ut=Number.isFinite(ke)?Math.max(86400,ke):604800,Se=ie?new DynamoDBClient({}):null;function dt(e){return e.operation==="render"||e.operation==="asset"?e.urls.length:e.operation==="rewrite"?e.items.length:e.items.length+(e.deleteRelativeKeys?.length??0)}async function pt(e){if(!(!Se||!ie))try{let t=Math.floor(Date.now()/1e3)+ut;await Se.send(new UpdateItemCommand({TableName:ie,Key:{jobId:{S:e.jobId},taskId:{S:e.taskId}},UpdateExpression:"SET #operation = :operation, #status = :status, completedItems = :completedItems, failedItems = :failedItems, totalItems = :totalItems, #sequence = :sequence, updatedAt = :updatedAt, expiresAt = :expiresAt"+(e.requestId?", requestId = :requestId":""),ConditionExpression:"attribute_not_exists(#sequence) OR #sequence < :sequence",ExpressionAttributeNames:{"#operation":"operation","#status":"status","#sequence":"sequence"},ExpressionAttributeValues:{":operation":{S:e.operation},":status":{S:e.status},":completedItems":{N:String(e.completedItems)},":failedItems":{N:String(e.failedItems)},":totalItems":{N:String(e.totalItems)},":sequence":{N:String(e.sequence)},":updatedAt":{S:e.updatedAt},":expiresAt":{N:String(t)},...e.requestId?{":requestId":{S:e.requestId}}:{}}}));}catch(t){if(t.name==="ConditionalCheckFailedException")return;console.warn(JSON.stringify({message:"Remote worker progress status could not be written.",jobId:e.jobId,taskId:e.taskId,error:t instanceof Error?t.message:String(t)}));}}var B=class{#t;#o;#e;#s;#i;#a=-1;#l=0;#n=0;#c=0;constructor(t,r,o=pt){this.#t=t,this.#o=r??null,this.#e=dt(t),this.#s=Math.max(1,Math.ceil(this.#e/20)),this.#i=o;}async started(){await this.#r("running",0,0,0);}async updated(t,r){this.#n=t,this.#c=r;let o=t+r,n=Date.now();o<this.#e&&o-this.#a<this.#s&&n-this.#l<5e3||await this.#r("running",t,r,o+1);}async completed(t){await this.#r(t.status,t.completedItems,t.failedItems,this.#e+2);}async failed(){let t=Math.min(this.#e-this.#n,Math.max(1,this.#c));await this.#r("failed",this.#n,t,this.#e+3);}async#r(t,r,o,n){this.#a=r+o,this.#l=Date.now(),await this.#i({jobId:this.#t.jobId,taskId:this.#t.taskId,operation:this.#t.operation,status:t,completedItems:r,failedItems:o,totalItems:this.#e,sequence:n,updatedAt:new Date().toISOString(),requestId:this.#o});}};var mt=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+(?:\s*;.*)?$/u;function gt(e){try{return new URL(e).pathname}catch{return e}}function D(e,t,r){let o=String(e??"").trim();if(mt.test(o))return o;let n=xe.lookup(gt(t));return n?xe.contentType(n)||n:r}function ae(e){return String(e??"").split(";").map(t=>t.trim().toLowerCase()).filter(Boolean).join(";")}var O=String(process.env.PUBLISHER_WORKSPACE_BUCKET??"").trim(),b=j(process.env.PUBLISHER_WORKSPACE_PREFIX??""),z=String(process.env.PUBLISHER_ALLOWED_OPERATION??"").trim(),L=String(process.env.PUBLISHER_EXPORTER_VERSION??"unknown").trim(),U=String(process.env.PUBLISHER_PROXY_URL??"").trim(),kt=St(process.env.PUBLISHER_ALLOWED_TARGETS??"[]"),$e=new S3Client({}),Pe=new Map,R=null;function St(e){try{let t=JSON.parse(e);return Array.isArray(t)?t.filter(r=>{if(!r||typeof r!="object")return !1;let o=r;return ["id","bucketName","prefix","region"].every(n=>typeof o[n]=="string")}).map(r=>({...r,prefix:j(r.prefix)})):[]}catch{return []}}function le(){if(!O)throw new Error("PUBLISHER_WORKSPACE_BUCKET is required.")}async function xt(){if(R){let t=await R.catch(()=>null);if(t?.isConnected())return t}let e=chromium.launch({headless:true,args:["--no-sandbox","--disable-setuid-sandbox","--disable-dev-shm-usage","--no-zygote","--single-process","--disable-gpu"],...U?{proxy:{server:U}}:{}});R=e;try{let t=await e;return t.once("disconnected",()=>{R===e&&(R=null);}),t}catch(t){throw R===e&&(R=null),t}}async function Pt(){let e=R;if(R=null,!e)return;let t=await e.catch(()=>null);t&&await t.close().catch(()=>{});}async function It(e){let t;for(let r=1;r<=2;r+=1){let o=await xt(),n=null;try{n=await o.newContext({viewport:e.options.viewport,ignoreHTTPSErrors:e.options.ignoreHttpsErrors,javaScriptEnabled:e.options.javaScriptEnabled,serviceWorkers:"block",userAgent:"WPSuiteStaticPublisher/remote-worker-v1"}),e.options.javaScriptEnabled&&await Tt(n);let s=await ge(n);return {context:n,page:await n.newPage(),networkPolicyViolation:s.getViolation}}catch(s){t=s,await n?.close().catch(()=>{}),R=null,await o.close().catch(()=>{});}}throw t instanceof Error?t:new Error(`Unable to create a Chromium page: ${String(t)}`)}async function Tt(e){await e.addInitScript(()=>{Object.defineProperty(window,"__WPSUITE_STATIC_EXPORT__",{value:true,writable:false,configurable:true});let t=r=>{if(r==null||String(r)==="")return true;try{let o=new URL(String(r),window.location.href),n=new URL(window.location.href);return o.hash="",n.hash="",o.href===n.href}catch{return false}};try{let r=window.location.assign.bind(window.location),o=window.location.replace.bind(window.location);Object.defineProperty(window.location,"assign",{configurable:!0,value:n=>{if(!t(n))return r(n)}}),Object.defineProperty(window.location,"replace",{configurable:!0,value:n=>{if(!t(n))return o(n)}}),Object.defineProperty(window.location,"reload",{configurable:!0,value:()=>{}});}catch{}});}async function $t(e,t){await e.evaluate(async r=>{await new Promise(o=>{let n=0,s=700,a=Date.now(),i=()=>{window.clearInterval(c),window.scrollTo(0,0),o();},c=window.setInterval(()=>{if(Date.now()-a>=r){i();return}window.scrollBy(0,s),n+=s;let d=Math.max(document.body?.scrollHeight||0,document.documentElement?.scrollHeight||0);n>=d+window.innerHeight&&i();},120);});},t);}async function ve(e){le();let t=T(e,b),r=await $e.send(new GetObjectCommand({Bucket:O,Key:t}));if(!r.Body)throw new Error(`S3 object has no body: ${t}`);return {body:await r.Body.transformToString("utf8"),contentType:r.ContentType?.trim()||null}}async function vt(e){return (await ve(e)).body}async function G(e){return JSON.parse(await vt(e))}async function X(e,t,r){le();let o=T(e,b),n=typeof t=="string"?Buffer.from(t,"utf8"):t,s=await $e.send(new PutObjectCommand({Bucket:O,Key:o,Body:n,ContentType:r,Metadata:{sha256:V(n)}}));return {bucket:O,key:o,sha256:V(n),bytes:n.byteLength,contentType:r,...s.ETag?{etag:s.ETag}:{},...s.VersionId?{versionId:s.VersionId}:{}}}async function Ot(e,t){return await X(e,`${JSON.stringify(t,null,2)}
|
|
5
|
+
`,"application/json; charset=utf-8")}async function At(e){try{let t=await G(e);return t.response??t}catch(t){if(t.name==="NoSuchKey"||t.$metadata?.httpStatusCode===404)return null;throw t}}function J(e){return [...new Set(e)].filter(t=>{try{let r=new URL(t);return (r.protocol==="http:"||r.protocol==="https:")&&!r.username&&!r.password}catch{return false}}).sort()}async function Wt(e,t,r){let o=null,n=null,s,a=new Set;try{let i=await It(e);o=i.context,n=i.page,s=i.networkPolicyViolation,n.on("request",f=>a.add(f.url()));let c=await n.goto(t,{waitUntil:"domcontentloaded",timeout:e.options.navigationTimeoutMs});e.options.readiness.waitForSelector&&await n.waitForSelector(e.options.readiness.waitForSelector,{timeout:e.options.readiness.timeoutMs}).catch(()=>{}),e.options.javaScriptEnabled&&e.options.readiness.waitForFunction&&await n.waitForFunction(e.options.readiness.waitForFunction,void 0,{timeout:e.options.readiness.timeoutMs}).catch(()=>{}),e.options.javaScriptEnabled?await $t(n,e.options.autoScrollTimeoutMs):await n.waitForLoadState("load",{timeout:e.options.readiness.timeoutMs}).catch(()=>{}),e.options.readiness.fallbackWaitMs>0&&await n.waitForTimeout(e.options.readiness.fallbackWaitMs);let d=s?.();if(d)throw d;let l=await n.evaluate(()=>{let f=(S,Oe)=>{let Y=[];for(let Ae of document.querySelectorAll(S))for(let ce of Oe){let Q=Ae.getAttribute(ce);if(Q)if(ce.includes("srcset"))for(let We of Q.split(",")){let ue=We.trim().split(/\s+/,1)[0];ue&&Y.push(ue);}else Y.push(Q);}return Y},A=S=>{try{return new URL(S,document.baseURI).href}catch{return null}};return {links:f("a[href]",["href"]).map(A).filter(S=>S!==null),assets:f("img,script,link,source,video,audio,iframe,[data-src],[data-href],[data-resource-url]",["src","href","srcset","data-src","data-srcset","data-href","data-resource-url","poster"]).map(A).filter(S=>S!==null)}});await n.evaluate(()=>{document.querySelectorAll("#wpsuite-consent-root").forEach(f=>f.remove()),document.documentElement.classList.remove("wpsuite-consent-scroll-locked"),document.body.classList.remove("wpsuite-consent-scroll-locked");});let u=await n.content(),p=s();if(p)throw p;let m=new URL(t),w=J(l.links).filter(f=>{let A=new URL(f);return A.hash="",A.origin===m.origin}),y=x(_(b,e.jobId,e.taskId),"pages",`${String(r).padStart(4,"0")}-${V(t).slice(0,24)}.html`),P=D(c?.headers()["content-type"],n.url()||t,"text/html; charset=utf-8"),Z=await X(y,u,P),K=(await o.cookies()).map(f=>({name:f.name,domain:f.domain,path:f.path,expires:f.expires,httpOnly:f.httpOnly,secure:f.secure,sameSite:f.sameSite,..."partitionKey"in f?{partitioned:!0}:{}})),g=c?.status()??null;return {requestedUrl:t,finalUrl:n?.url()||null,outcome:g!==null&&g>=400?"http-error":"rendered",httpStatus:g,contentType:P,html:Z,discoveredPages:w,discoveredAssets:J([...l.assets,...ne(n.url()||t,u,c?.headers()["content-type"]??"text/html")]),networkUrls:J([...a]),cookies:K}}catch(i){return {requestedUrl:t,finalUrl:n?.url()||null,outcome:"failed",httpStatus:null,contentType:null,html:null,discoveredPages:[],discoveredAssets:[],networkUrls:J([...a]),cookies:[],error:i instanceof Error?i.message:String(i)}}finally{await o?.close().catch(()=>{});}}function Ct(e,t){let r=t.toLowerCase();if(r.startsWith("text/")||r.includes("javascript")||r.includes("json")||r.includes("xml")||r.includes("svg"))return true;try{return /\.(?:css|js|mjs|json|xml|xsl|svg|txt|map|html?)$/i.test(new URL(e).pathname)}catch{return false}}async function jt(e,t,r){let o=t;for(let n=0;n<=5;n+=1){await re(o,"asset request");let s=await e.get(o,{timeout:r,failOnStatusCode:false,maxRedirects:0}),a=s.status();if(a<300||a>=400)return s;let i=s.headers().location;if(!i)return s;if(n===5)throw await s.dispose(),new Error("Asset request exceeded five redirects.");o=new URL(i,o).toString(),await s.dispose();}throw new Error("Asset redirect handling failed.")}async function Vt(e,t,r){if(!Array.isArray(e.urls)||e.urls.length<1||e.urls.length>20)throw new Error("Asset tasks require between 1 and 20 URLs.");let o=await request.newContext({ignoreHTTPSErrors:e.options.ignoreHttpsErrors,userAgent:"WPSuiteStaticPublisher/remote-asset-worker-v1",...U?{proxy:{server:U}}:{}}),n=[],s=async i=>{n.push(i);let c=n.filter(d=>d.outcome==="failed"||d.outcome==="deferred").length;await r.updated(n.length-c,c);};try{for(let i=0;i<e.urls.length;i+=1){let c=e.urls[i],d=t.getRemainingTimeInMillis?.();if(d!==void 0&&d<3e4){await s({requestedUrl:c,finalUrl:null,outcome:"deferred",httpStatus:null,contentType:null,cacheControl:null,lastModified:null,object:null,discoveredAssets:[],error:"Worker stopped accepting assets because less than 30 seconds remained."});continue}let l=null;try{l=await jt(o,c,e.options.timeoutMs);let u=l.status(),p=l.headers(),m=l.url()||c;if(u<200||u>=300){await s({requestedUrl:c,finalUrl:m,outcome:"http-error",httpStatus:u,contentType:p["content-type"]??null,cacheControl:p["cache-control"]??null,lastModified:p["last-modified"]??null,object:null,discoveredAssets:[],error:`Asset returned HTTP ${u}.`});continue}let w=await l.body(),y=D(p["content-type"],m,"application/octet-stream"),P=await X(x(_(b,e.jobId,e.taskId),"assets",`${String(i).padStart(4,"0")}-${V(c).slice(0,24)}.bin`),w,y);await s({requestedUrl:c,finalUrl:m,outcome:"fetched",httpStatus:u,contentType:y,cacheControl:p["cache-control"]??null,lastModified:p["last-modified"]??null,object:P,discoveredAssets:Ct(m,y)?ne(m,new TextDecoder("utf8").decode(w),y):[]});}catch(u){await s({requestedUrl:c,finalUrl:l?.url()??null,outcome:"failed",httpStatus:l?.status()??null,contentType:l?.headers()["content-type"]??null,cacheControl:l?.headers()["cache-control"]??null,lastModified:l?.headers()["last-modified"]??null,object:null,discoveredAssets:[],error:u instanceof Error?u.message:String(u)});}finally{await l?.dispose().catch(()=>{});}}}finally{await o.dispose();}let a=n.filter(i=>i.outcome==="failed"||i.outcome==="deferred").length;return {response:{schemaVersion:k,operation:"asset",jobId:e.jobId,taskId:e.taskId,status:a>0?"partial":"succeeded",completedItems:n.length-a,failedItems:a,exporterVersion:L},detail:{assets:n}}}async function Mt(e,t,r){if(!Array.isArray(e.urls)||e.urls.length<1||e.urls.length>20)throw new Error("Render tasks require between 1 and 20 URLs.");let o=new URL(e.sourceOrigin).origin,n=[];for(let a=0;a<e.urls.length;a+=1){let i=e.urls[a];if(!i)continue;let c=t.getRemainingTimeInMillis?.();if(c!==void 0&&c<6e4){n.push({requestedUrl:i,finalUrl:null,outcome:"deferred",httpStatus:null,contentType:null,html:null,discoveredPages:[],discoveredAssets:[],networkUrls:[],cookies:[],error:"Worker stopped accepting URLs because less than 60 seconds remained."}),await r.updated(n.filter(u=>u.outcome!=="failed"&&u.outcome!=="deferred").length,n.filter(u=>u.outcome==="failed"||u.outcome==="deferred").length);continue}let d=new URL(i);if(d.origin!==o)throw new Error(`Primary render URL is outside sourceOrigin: ${i}`);n.push(await Wt(e,d.toString(),a));let l=n.filter(u=>u.outcome==="failed"||u.outcome==="deferred").length;await r.updated(n.length-l,l);}let s=n.filter(a=>a.outcome==="failed"||a.outcome==="deferred").length;return {response:{schemaVersion:k,operation:"render",jobId:e.jobId,taskId:e.taskId,status:s>0?"partial":"succeeded",completedItems:n.length-s,failedItems:s,exporterVersion:L},detail:{pages:n}}}async function Ut(e,t){if(!Array.isArray(e.items)||e.items.length<1||e.items.length>500)throw new Error("Rewrite tasks require between 1 and 500 objects.");let o={...await G(e.configKey),outputDir:"/workspace"},n=await G(e.assetMapKey),s=e.previousAssetMapKey?await G(e.previousAssetMapKey):{},a=[];for(let i of e.items){let c=T(i.inputKey,b),d=T(i.outputKey,b),l=await ve(c),u=l.body,p=`/workspace/${i.relativePath.replace(/^\/+/,"")}`,m=Ee(u,o,n,p,s),w=D(i.contentType||l.contentType,i.relativePath,"text/plain; charset=utf-8"),y=await X(d,m,w);a.push({inputKey:c,outputKey:d,changed:m!==u,output:y}),await t.updated(a.length,0);}return {response:{schemaVersion:k,operation:"rewrite",jobId:e.jobId,taskId:e.taskId,status:"succeeded",completedItems:a.length,failedItems:0,exporterVersion:L},detail:{objects:a}}}function Lt(e,t){return `${e}/${t.split("/").map(r=>encodeURIComponent(r)).join("/")}`}async function Kt(e,t){if(!Array.isArray(e.items)||e.items.length>1e3)throw new Error("Deploy copy tasks accept at most 1000 objects.");let r=kt.find(l=>l.id===e.targetId);if(!r)throw new Error(`Unknown deployment target: ${e.targetId}`);let o=Pe.get(r.region);o||(o=new S3Client({region:r.region}),Pe.set(r.region,o));let n=[];for(let l of e.items){let u=T(l.sourceKey,b),p=x(r.prefix,l.targetRelativeKey);try{let m=await o.send(new HeadObjectCommand({Bucket:r.bucketName,Key:p})).catch(g=>{if((g&&typeof g=="object"&&"$metadata"in g?Number(g.$metadata?.httpStatusCode):0)===404||g?.name==="NotFound")return null;throw g}),w=String(m?.CacheControl??"").replace(/\s+/g,"")===l.cacheControl.replace(/\s+/g,""),y=ae(m?.ContentType)===ae(l.contentType),P=m?.Metadata?.["wpsuite-sha256"]===l.sha256,Z=!!l.normalizedSha256&&m?.Metadata?.["wpsuite-normalized-sha256"]===l.normalizedSha256;if(w&&y&&(P||Z)){n.push({sourceKey:u,targetKey:p,status:"skipped"}),await t.updated(n.filter(g=>g.status!=="failed").length,n.filter(g=>g.status==="failed").length);continue}let K=await o.send(new CopyObjectCommand({Bucket:r.bucketName,Key:p,CopySource:Lt(O,u),MetadataDirective:"REPLACE",ContentType:l.contentType,CacheControl:l.cacheControl,Metadata:{"wpsuite-sha256":l.sha256,...l.normalizedSha256?{"wpsuite-normalized-sha256":l.normalizedSha256}:{}}}));n.push({sourceKey:u,targetKey:p,status:"copied",...K.CopyObjectResult?.ETag?{etag:K.CopyObjectResult.ETag}:{}}),await t.updated(n.filter(g=>g.status!=="failed").length,n.filter(g=>g.status==="failed").length);}catch(m){n.push({sourceKey:u,targetKey:p,status:"failed",error:m instanceof Error?m.message:String(m)}),await t.updated(n.filter(w=>w.status!=="failed").length,n.filter(w=>w.status==="failed").length);}}let a=(e.deleteRelativeKeys??[]).map(l=>x(r.prefix,l)),i=[],c=[];if(a.length>0){let l=await o.send(new DeleteObjectsCommand({Bucket:r.bucketName,Delete:{Objects:a.map(u=>({Key:u})),Quiet:false}}));i.push(...(l.Deleted??[]).flatMap(u=>u.Key?[u.Key]:[])),c.push(...(l.Errors??[]).map(u=>({key:u.Key??"",error:u.Message??u.Code??"S3 deletion failed"}))),await t.updated(n.filter(u=>u.status!=="failed").length+i.length,n.filter(u=>u.status==="failed").length+c.length);}let d=n.filter(l=>l.status==="failed").length+c.length;return {response:{schemaVersion:k,operation:"deploy-copy",jobId:e.jobId,taskId:e.taskId,status:d>0?"partial":"succeeded",completedItems:n.filter(l=>l.status!=="failed").length+i.length,failedItems:d,exporterVersion:L},detail:{objects:n,deletedKeys:i,deleteErrors:c,targetId:r.id}}}async function Ie(e,t,r){if(e.operation==="health")return {response:{schemaVersion:k,operation:"health",jobId:e.jobId,taskId:e.taskId,status:"succeeded",completedItems:1,failedItems:0,exporterVersion:L},detail:{allowedOperation:z,workspaceBucket:O,workspacePrefix:b,proxyConfigured:!!U}};if(z&&z!==e.operation)throw new Error(`Function is configured for ${z}, not ${e.operation}.`);if(!r)throw new Error("Remote worker progress reporter is required.");return e.operation==="render"?await Mt(e,t,r):e.operation==="asset"?await Vt(e,t,r):e.operation==="rewrite"?await Ut(e,r):await Kt(e,r)}async function Ir(e,t={}){let r=me(e);try{if(r.operation==="health")return (await Ie(r,t)).response;le();let o=x(_(b,r.jobId,r.taskId),"result.json"),n=await At(o),s=new B(r,t.awsRequestId);if(n)return await s.completed(n),n;await s.started();try{let a=await Ie(r,t,s),i={...a.response,resultKey:o};return await Ot(o,{schemaVersion:k,response:i,detail:a.detail,completedAt:new Date().toISOString(),requestId:t.awsRequestId??null}),await s.completed(i),i}catch(a){throw await s.failed(),a}}finally{r.operation==="render"&&await Pt();}}export{Ir as handler};
|