@smart-cloud/publisher-exporter 1.1.49 → 1.1.52

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.
@@ -1,3 +1,3 @@
1
- import {pathToFileURL}from'url';import P from'fs/promises';import {existsSync,createReadStream,createWriteStream}from'fs';import m from'path';import {spawn}from'child_process';import {randomUUID,createHash}from'crypto';import Qe from'http';import fe from'https';import {pipeline}from'stream/promises';import {createGzip}from'zlib';function ge(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))].sort()}function _(e){return Array.isArray(e)?e.map(_):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,_(n)])):e}function Ue(e){return JSON.stringify(_(e))}function L(e){return createHash("sha256").update(Ue(e)).digest("hex")}function pe(e){return L({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 $e(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 $(e){let t=ge((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=ge((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 s=`/${a.pathname.replace(/^\/+|\/+$/g,"")}`;return s==="/"?"/":`${s}/`}));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 L({schemaVersion:1,sourceOrigin:$e(e),ruleId:t.trim(),scope:$(n)})}function H(e){return L({schemaVersion:1,...e})}function he(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 me=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";me?m.join(me,"current-progress.json"):"";Promise.resolve();var We="wp-json/smartcloud-static-publisher/v1/content-sync/",Ke=25*1024*1024,E=class extends Error{status;code;constructor(t,n,i){super(i),this.name="ContentSyncApiError",this.status=t,this.code=n;}},N=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){let n=this.options.sourceOrigin.replace(/\/+$/,"")+"/";return new URL(`${We}${t}`,n)}async post(t,n){let i=this.endpoint(t),r=Buffer.from(JSON.stringify(n),"utf8"),a=i.protocol==="https:"?fe:Qe,s=i.protocol==="https:"?new fe.Agent({rejectUnauthorized:!this.options.ignoreHttpsErrors}):void 0;return new Promise((o,c)=>{let u=a.request(i,{method:"POST",agent:s,headers:{"content-type":"application/json","content-length":String(r.byteLength),"x-static-publisher-token":this.options.runtimeToken},timeout:this.options.timeoutMs},d=>{let g=[],p=0;d.on("data",h=>{if(p+=h.byteLength,p>Ke){d.destroy(new Error("Content-sync API response exceeded the size limit."));return}g.push(h);}),d.on("error",c),d.on("end",()=>{let h=Buffer.concat(g).toString("utf8"),y;try{y=h?JSON.parse(h):{};}catch{c(new E(d.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let l=d.statusCode??500;if(l<200||l>=300){c(new E(l,String(y.code??"request-failed"),String(y.message??`Content-sync API request failed (${l}).`)));return}o(y);});});u.on("timeout",()=>u.destroy(new Error(`Content-sync API request timed out: ${t}`))),u.on("error",c),u.end(r);})}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 s=i;for(let o of a.items){if(!Number.isSafeInteger(o.sequence)||o.sequence<=s||o.sequence>t.throughSequence||!Number.isSafeInteger(o.postId)||o.postId<=0||!Number.isSafeInteger(o.blogId)||o.blogId<=0||!r.has(o.postType)||typeof o.operation!="string"||!o.operation)throw new Error("Content-sync API returned an invalid or out-of-scope journal event.");s=o.sequence;}if(a.items.length>0&&a.nextSequence!==s)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)}};function _e(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function ze(e,t){return {...e,...t??{}}}function He(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function V(e,t){let n=String(t??e.deploymentTargetOverride??"").trim();if(!_e(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:ze(e.s3,r.s3),cloudFront:He(e.cloudFront,r.cloudFront)}}}function Se(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function Ze(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(s=>s.replace(/[^A-Za-z0-9._-]/g,"")).filter(s=>s.length>0&&s!=="."&&s!=="..");if(r.length===0)return "";let a=`/${r.join("/")}`;return i&&m.extname(a)===""&&(a+="/"),a==="/"?"":a}function G(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t.trim(),String(n??"")]).filter(([t])=>t.length>0))}function Xe(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,s={};if(typeof a.targetOrigin=="string"){let c=Se(a.targetOrigin);c&&(s.targetOrigin=c);}let o=G(a.extraReplacements);if(Object.keys(o).length>0&&(s.extraReplacements=o),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&&(s.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(d=>String(d??"").trim()).filter(d=>d.length>0)),Object.keys(c).length>0&&(s.cloudFront=c);}t[r]=s;}return t}function Z(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function et(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 s=String(n.deploymentProfile??"").trim(),o=String(n.url??"").trim(),c=Array.isArray(n.postTypes)?[...new Set(n.postTypes.map(d=>String(d??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],u=Array.isArray(n.listingPaths)?[...new Set(n.listingPaths.map(d=>String(d??"").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")&&s?{deploymentProfile:s}:{},...o?{url:o}:{},...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 be(e){let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.rules)?t.rules.map((i,r)=>et(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 tt(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 X(e){let t=e&&typeof e=="object"?e:{},n=String(t.accountId??"").trim(),i=String(t.siteId??"").trim(),r=t.subscriber===true,a=tt(t.siteSettings),s={...a??{},...n?{accountId:a?.accountId??n}:{},...i?{siteId:a?.siteId??i}:{},...a?.subscriber===true||r?{subscriber:true}:{}},o={},c=String(t.apiBase??"").trim();c&&(o.apiBase=c);let u=String(t.runtimeToken??t.nonce??"").trim();u&&(o.runtimeToken=u);let d=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();d&&(o.virtualAssetBaseUrl=d),Object.keys(s).length>0&&(o.siteSettings=s);let g=Z(t.subscriptionType);return g&&(o.subscriptionType=g),o}function nt(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function we(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function rt(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 ve(e,t,n=5){let i=new URL(we(e)),r=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),a=i.protocol==="http:"?Qe:fe,s=rt(e,t);return await new Promise((o,c)=>{let u=a.request(i,{method:r,headers:Object.fromEntries(s.entries()),...i.protocol==="https:"?{rejectUnauthorized:false}:{}},d=>{let g=[];d.on("data",p=>{g.push(Buffer.isBuffer(p)?p:Buffer.from(p));}),d.on("error",c),d.on("end",()=>{let p=d.statusCode??0,h=d.headers.location;if(n>0&&h&&[301,302,303,307,308].includes(p)){o(ve(new URL(h,i),{method:p===303?"GET":r},n-1));return}let y=new Headers;for(let[l,S]of Object.entries(d.headers))Array.isArray(S)?y.set(l,S.join(", ")):typeof S=="string"&&y.set(l,S);o(new Response(Buffer.concat(g),{status:p,statusText:d.statusMessage??"",headers:y}));});});u.on("error",c),u.end();})}function it(e){let t=X(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;nt(e.sourceOrigin);let s=globalThis,c={...s.WpSuite??{},siteSettings:n,uploadUrl:a};return t.apiBase&&(c.apiBase=t.apiBase),s.WpSuite=c,true}async function st(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!it(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 d=we(c);if(d.startsWith(t)){let g=(()=>{try{return new URL(d).pathname}catch{return d}})();try{let p=e.ignoreHttpsErrors&&d.startsWith("https://")?await ve(c,u):await n(c,u);return i.push({path:g,status:p.status,ok:p.ok,error:null}),p}catch(p){throw i.push({path:g,status:null,ok:!1,error:p instanceof Error?p.message:String(p)}),p}}return n(c,u)}));let{getConfig:r}=await import('@smart-cloud/wpsuite-core'),a=await r("publisher"),s=a&&typeof a=="object"?a:null,o=Z(s?.subscriptionType);return {remote:s,diagnostic:{status:s?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:o??null,error:s?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 ot(e,t){let n=Xe(t?.deploymentProfiles),i=String(t?.defaultDeploymentProfile??"").trim(),r=n[i]?i:"",a=Z(t?.subscriptionType),s=X(e.wpsuite);return {...e,scheduler:be(t?.scheduler),deploymentProfiles:n,defaultDeploymentProfile:r,...a?{subscriptionType:a}:{},wpsuite:{...s,...s.siteSettings||a?{siteSettings:{...s.siteSettings??{},...s.siteSettings?.subscriber===true||a==="PROFESSIONAL"||a==="AGENCY"?{subscriber:true}:{}}}:{},...a?{subscriptionType:a}:{}}}}function Y(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 at(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?m.resolve(e):""}function ye(e,t,n){let i=String(t||"").trim();return i&&m.isAbsolute(i)?m.resolve(i):m.resolve(e,Y(i,n))}async function ee(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=Se(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=Ze(r.generated404RequestPath),r.sitemapPaths||=["/sitemap_index.xml","/sitemap.xml"],r.allowedAssetHosts||=[],r.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],r.blockedPathPrefixes||=[],r.blockedSearchFragments||=[],r.concurrency||=1,r.maxPages||=0,r.extraReplacements=G(r.extraReplacements),r.postCrawlCopyMap=G(r.postCrawlCopyMap),r.logDir=String(r.logDir||"logs").trim()||"logs",r.verbose??=false,r.logLevel||=r.verbose?"debug":"info",r.s3SyncMode||="sdk-upload-delete",r.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},r.readiness.timeoutMs??=1500,r.readiness.fallbackWaitMs??=1500,r.viewport||={width:1440,height:1200},r.navigationTimeoutMs||=3e4,r.assetDownloadConcurrency=Number(r.assetDownloadConcurrency)>0?Number(r.assetDownloadConcurrency):r.concurrency,r.rewriteConcurrency=Number(r.rewriteConcurrency)>0?Number(r.rewriteConcurrency):r.assetDownloadConcurrency,r.wpsuite=X(r.wpsuite),r.scheduler=be(void 0),r.deploymentProfiles={},r.defaultDeploymentProfile="",r.deploymentTargetOverride=String(r.deploymentTargetOverride??"").trim();let a=await st(r);t.onRemotePublisherConfigDiagnostic?.(a.diagnostic);let s=ot(r,a.remote),o=at(),c=o?m.resolve(o,".."):"";return c?(s.outputDir=ye(c,s.outputDir,"export"),s.logDir=ye(c,s.logDir,"logs")):(m.isAbsolute(s.outputDir)||(s.outputDir=Y(s.outputDir,"export")),m.isAbsolute(s.logDir)||(s.logDir=Y(s.logDir,"logs"))),s}function Pe(e){let t=m.resolve(e);return {state:m.join(t,"content-sync-state.json"),current:m.join(t,"content-sync-current.json"),impact:m.join(t,"content-sync-impact-plan.json"),checkpoint:m.join(t,"content-sync-checkpoint.json"),baseline:m.join(t,"content-sync-baseline.json"),releaseCutoff:m.join(t,"content-sync-release-cutoff.json"),candidateManifest:m.join(t,"content-sync-candidate-manifest.json"),trustedManifest:m.join(t,"crawl-manifest.json"),invalidation:m.join(t,"content-sync-invalidation.json"),deployPlan:m.join(t,"deploy-plan.json")}}async function ct(e,t){await P.mkdir(m.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 Ce(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 ut(e){let t=await Ce(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 Ie(e){let t=await Ce(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 Ae(e,t){await ct(e.state,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function Re(e,t){let n=await ut(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 Te(e){let t=String(e.command??"").trim();return (t==="publish"||t==="crawl")&&e.crawlMode==="incremental"||t==="content-sync"}var te=new Map;async function qe(e){let t=m.resolve(e),n=te.get(t);if(n!==void 0)return n;try{let i=JSON.parse(await P.readFile(t,"utf8")),r=String(i.version??"").trim();return te.set(t,r),r}catch{return te.set(t,""),""}}var U=class extends Error{request;step;constructor(t,n){super(`Stop requested during ${n}.`),this.name="StopRequestedError",this.request=t,this.step=n;}},ht="queue-mutation.lock",ft=5e3,yt=3e4;function St(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 o=0;o<e.length;o++){let c=e[o];c==="--runtime-dir"?t=e[++o]||"":c.startsWith("--runtime-dir=")?t=c.slice(14):c==="--exporter-dir"?n=e[++o]||n:c.startsWith("--exporter-dir=")?n=c.slice(15):c==="--config"?i=e[++o]||"":c.startsWith("--config=")?i=c.slice(9):c==="--max-jobs"?r=Number.parseInt(e[++o]||"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=m.resolve(t),s=i?m.resolve(i):m.join(a,"config.json");return {runtimeDir:a,exporterDir:m.resolve(n),configPath:s,maxJobs:Number.isFinite(r)&&r>0?r:1}}async function v(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 w(e,t){await P.mkdir(m.dirname(e),{recursive:true}),await P.writeFile(e,JSON.stringify(t,null,2),"utf8");}function Ee(e){return m.join(e,ht)}async function bt(e){await new Promise(t=>setTimeout(t,e));}async function wt(e){let t=Ee(e),n=Date.now()+ft;for(;;)try{await P.mkdir(m.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>yt){await P.unlink(t).catch(()=>{});continue}if(Date.now()>=n)throw new Error("Timed out acquiring queue mutation lock.",{cause:i});await bt(50);}}async function vt(e){await P.unlink(Ee(e)).catch(()=>{});}async function j(e,t){await wt(e);try{return await t()}finally{await vt(e);}}function Fe(e){return m.join(e,"queue-runner-heartbeat.json")}function ue(e){return m.join(e,"current-progress.json")}function ne(e){return m.join(e,"scheduler-state.json")}function Pt(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 je(e){let t=await v(e.configPath||"",null),n=m.resolve(e.runtimeDir,".."),r=(typeof t?.logDir=="string"?t.logDir:"").trim();return r&&m.isAbsolute(r)?m.resolve(r):m.resolve(n,Pt(r,"logs"))}function re(e,t){return String(e||"").trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||t}function Ct(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 It(e){return [Ct(e.endedAt||e.startedAt),re(e.command||"job","job"),re(e.id||"job","job"),re(e.status||"finished","finished")].join("-")}function At(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 Rt(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 qt(e){return e.endsWith(".gz")?"application/gzip":e.endsWith(".jsonl")?"application/x-ndjson":e.endsWith(".json")?"application/json":"text/plain"}async function ie(e,t,n){let i=`${n}.gz`,r=m.join(t,i);await pipeline(createReadStream(e),createGzip({level:9}),createWriteStream(r));let[a,s]=await Promise.all([P.stat(e),P.stat(r)]);return {role:Rt(n),originalFileName:n,storedFileName:i,compressed:true,compression:"gzip",contentType:qt(i),originalSize:a.size,storedSize:s.size}}async function Q(e,t){let n=await je(t),i=new Date().toISOString(),r=It(e),a=m.join(n,"archive",r),s=[],o=[];await P.mkdir(a,{recursive:true});try{let d=await P.readdir(n,{withFileTypes:!0});for(let g of d){if(!g.isFile()||!At(g.name))continue;let p=await ie(m.join(n,g.name),a,g.name);o.push(p),s.push(p.storedFileName);}}catch(d){if((d&&typeof d=="object"&&"code"in d?String(d.code||""):"")!=="ENOENT")throw d}let c=ue(t.runtimeDir);if(existsSync(c)){let d=await ie(c,a,"current-progress.json");o.push(d),s.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 g=m.join(t.runtimeDir,d);if(!existsSync(g))continue;let p=await ie(g,a,d);o.push(p),s.push(p.storedFileName);}let u=[...s,"job.json"];return await w(m.join(a,"job.json"),{manifestVersion:1,archivedAt:i,archiveKey:r,archiveDir:a,logDir:n,runtimeDir:t.runtimeDir,exporterDir:t.exporterDir,configPath:t.configPath||"",archivedFiles:u,artifacts:o,job:e}),{archiveKey:r,archiveDir:a,archiveCreatedAt:i,archivedFiles:u,artifacts:o}}function xt(e){return m.join(e,"audit-events.jsonl")}function ae(e){return m.join(e,"stop-request.json")}async function Je(e){try{let t=await P.readFile(ae(e),"utf8"),n=JSON.parse(t);return n&&typeof n=="object"?n:null}catch{return null}}async function xe(e,t){let n=await Je(e);if(!n)return null;let i=String(n.targetJobId||"").trim();return i&&i!==t?null:n}async function M(e,t){if(!t){await P.unlink(ae(e)).catch(()=>{});return}let n=await Je(e);if(!n)return;let i=String(n.targetJobId||"").trim();(!i||i===t)&&await P.unlink(ae(e)).catch(()=>{});}async function A(e,t){try{let n={occurredAt:t.occurredAt||new Date().toISOString(),status:t.status||"info",actorSource:t.actorSource||"queue-runner",...t};await P.mkdir(e,{recursive:!0}),await P.appendFile(xt(e),`${JSON.stringify(n)}
2
- `,"utf8");}catch{}}async function C(e,t,n){let[i,r]=await Promise.all([qe(m.join(e.exporterDir,"package.json")),qe(m.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 w(Fe(e.runtimeDir),a);}catch{}}async function F(e){try{await P.unlink(ue(e));}catch{}}function Dt(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,s=typeof e.url=="string"?e.url.trim():"",o=typeof e.deploymentProfile=="string"?e.deploymentProfile.trim():"",c=Array.isArray(e.postTypes)?[...new Set(e.postTypes.map(g=>String(g).trim()).filter(Boolean))]:[],u=Array.isArray(e.listingPaths)?[...new Set(e.listingPaths.map(g=>String(g).trim()).filter(Boolean))]:[],d=(n==="publish"||n==="crawl")&&e.crawlMode==="incremental"?"incremental":"full";return n==="url"&&!s||n==="content-sync"&&c.length===0?null:{id:r,enabled:a,command:n,intervalMinutes:i,...n==="publish"||n==="crawl"?{crawlMode:d}:{},...(n==="publish"||n==="deploy"||n==="invalidate"||n==="content-sync")&&o?{deploymentProfile:o}:{},...s?{url:s}:{},...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 kt(e){let t=await ee(e.configPath).catch(()=>null),n=t?.scheduler,i=Array.isArray(n?.rules)?n.rules.map((r,a)=>Dt(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 se(e,t){if(!t)throw new Error("Content-sync scheduler requires a valid publisher config.");let n=$({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=V(t,e.deploymentProfile),a=H({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}:${L({scopeFingerprint:i,targetFingerprint:a}).slice(0,32)}`}async function Tt(e,t,n,i,r){let s=(await v(m.join(e.runtimeDir,"content-sync-baseline.json"),{})).entries?.[i];if(!s?.consumerId||!s.scopeFingerprint||!s.baselineId)return {status:"baseline-required",reason:"No verified normal-release baseline exists for this rule scope."};try{let o=t.publisherConfig;if(!o)throw new Error("Publisher configuration is unavailable.");let c=$({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(o.sourceOrigin,n.id,c),d=V(o,n.deploymentProfile),g=H({sourceOrigin:o.sourceOrigin,targetOrigin:d.config.targetOrigin,deploymentProfile:d.name||"",s3Bucket:d.config.s3.bucket,s3Prefix:d.config.s3.prefix,cloudFrontDistributionId:d.config.cloudFront.distributionId,urlRewriteMode:d.config.urlRewriteMode,extraReplacements:d.profile?.extraReplacements??{}});if(s.scopeFingerprint!==u||s.targetFingerprint!==g||!s.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 p=new N({sourceOrigin:o.sourceOrigin,runtimeToken:String(o.wpsuite?.runtimeToken||""),ignoreHttpsErrors:o.ignoreHttpsErrors}),h=await p.releaseFingerprint(c.includeSubsites),y=pe({wordpressFingerprint:h,targetFingerprint:g,sourceOrigin:o.sourceOrigin,sitemapPaths:o.sitemapPaths,blockedPathPrefixes:o.blockedPathPrefixes,assetPathPrefixes:o.assetPathPrefixes,noJavaScriptRenderPathPrefixes:o.noJavaScriptRenderPathPrefixes,urlRewriteMode:o.urlRewriteMode});if(s.releaseFingerprint!==y)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 p.head({consumerId:s.consumerId,scopeFingerprint:s.scopeFingerprint,baselineId:s.baselineId,postTypes:c.postTypes,includeSubsites:c.includeSubsites}),S=l.committedSequence;if(r?.command==="content-sync"&&r.coalesceKey===i){let b=await v(m.join(e.runtimeDir,"content-sync-current.json"),null);b?.coalesceKey===i&&Number.isSafeInteger(b.toSequence)&&(S=Math.max(S,Number(b.toSequence)));}return {status:l.headSequence>S?"pending":"current",headSequence:l.headSequence,committedSequence:l.committedSequence}}catch(o){return o instanceof E&&o.code==="baseline-required"?{status:"baseline-required",reason:o.message}:{status:"unavailable",reason:o instanceof Error?o.message:String(o)}}}async function Oe(e,t,n,i,r,a){let s=m.join(e.runtimeDir,"content-sync-state.json"),c=(await v(s,{})).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 w(s,{schemaVersion:1,updatedAt:new Date().toISOString(),rules:c});}function ce(e,t){let n=(t.url||"").trim(),i=t.crawlMode||"full",r=(t.deploymentProfile||"").trim(),a=(t.coalesceKey||"").trim();return e.some(s=>s.command===t.command&&(t.command!=="content-sync"||(s.coalesceKey||"").trim()===a)&&(s.url||"").trim()===n&&(s.crawlMode||"full")===i&&(s.deploymentProfile||"").trim()===r&&(s.status===void 0||s.status==="queued"||s.status==="retry-wait"||s.status==="running"))}async function Et(e,t,n){if(!t.allowSchedulerAutoEnqueue)return 0;let i=await kt(e);if(!i.enabled||i.rules.length===0)return 0;if(t.assertActiveSubscriptionForIdentity)try{await t.assertActiveSubscriptionForIdentity(i.wpsuite??null);}catch(l){let S=l instanceof Error?l.message:String(l);return console.warn(`[queue-runner] scheduler auto-enqueue skipped: ${S}`),0}let r=m.join(e.runtimeDir,"queue.json"),a=m.join(e.runtimeDir,"current-run.json"),s=Date.now(),o=0,c=[],u=[],d=[],g=new Map,[p,h,y]=await Promise.all([v(r,[]),v(a,null),v(ne(e.runtimeDir),{lastEnqueuedBucketByRuleId:{},lastEvaluatedBucketByRuleId:{},lastCreatedBucketByRuleId:{},coalescedCountByRuleId:{}})]);for(let l of i.rules){if(!l.enabled||l.command!=="content-sync")continue;let S=Math.floor(s/(l.intervalMinutes*60*1e3)),b=y.lastEvaluatedBucketByRuleId?.[l.id]??y.lastEnqueuedBucketByRuleId?.[l.id]??-1;if(S<=b)continue;let D=se(l,i.publisherConfig);ce(p,{command:l.command,deploymentProfile:l.deploymentProfile,coalesceKey:D})||g.set(l.id,await Tt(e,i,l,D,h));}await j(e.runtimeDir,async()=>{let l=await v(r,[]),S=await v(a,null),b=await v(ne(e.runtimeDir),{lastEnqueuedBucketByRuleId:{},lastEvaluatedBucketByRuleId:{},lastCreatedBucketByRuleId:{},coalescedCountByRuleId:{}});b.lastEnqueuedBucketByRuleId??={},b.lastEvaluatedBucketByRuleId??={...b.lastEnqueuedBucketByRuleId},b.lastCreatedBucketByRuleId??={...b.lastEnqueuedBucketByRuleId},b.coalescedCountByRuleId??={};let D=[...l];S&&S.status==="running"&&D.unshift(S);for(let f of i.rules){if(!f.enabled)continue;let I=f.intervalMinutes*60*1e3,x=Math.floor(s/I),J=b.lastEvaluatedBucketByRuleId[f.id]??b.lastEnqueuedBucketByRuleId[f.id]??-1;if(x<=J)continue;let O=f.command==="content-sync"?se(f,i.publisherConfig):"";b.lastEvaluatedBucketByRuleId[f.id]=x;let T=f.command==="content-sync"?l:D;if(ce(T,{command:f.command,url:f.url,crawlMode:f.crawlMode,deploymentProfile:f.deploymentProfile,coalesceKey:O})){b.coalescedCountByRuleId[f.id]=(b.coalescedCountByRuleId[f.id]??0)+1,u.push(f);continue}if(f.command==="content-sync"){let K=g.get(f.id);if(!K||K.status!=="pending"){let de=K??{status:"unavailable",reason:"Content-sync demand was not checked."};de.status!=="current"&&d.push({rule:f,check:de});continue}}let W={id:randomUUID(),command:f.command,...f.command==="content-sync"?{ruleId:f.id,coalesceKey:O,attempt:0}:{},...(f.command==="publish"||f.command==="crawl")&&f.crawlMode?{crawlMode:f.crawlMode}:{},...(f.command==="publish"||f.command==="deploy"||f.command==="invalidate"||f.command==="content-sync")&&f.deploymentProfile?{deploymentProfile:f.deploymentProfile}:{},...f.url?{url:f.url}:{},enqueueSource:"scheduler",...i.wpsuite?{wpsuite:i.wpsuite}:{},status:"queued",createdAt:new Date().toISOString(),createdBy:0};l.push(W),D.push(W),c.push({job:W,rule:f}),b.lastEnqueuedBucketByRuleId[f.id]=x,b.lastCreatedBucketByRuleId[f.id]=x,o+=1;}o>0&&await w(r,l),await w(ne(e.runtimeDir),b);});for(let l of c){if(l.rule.command==="content-sync"){let S=g.get(l.rule.id);await A(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:S?.headSequence??0,committedSequence:S?.committedSequence??0}});}await A(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 A(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 d){if(l.check.status==="baseline-required"){let S=se(l.rule,i.publisherConfig);await Oe(e,l.rule.id,S,l.check.reason||"A successful full or incremental publish must establish a new content-sync baseline.",l.check.headSequence,l.check.committedSequence);}await A(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 o}async function Ft(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 jt(e){try{await P.unlink(e);}catch{}}function Jt(e,t){let n=[m.join(e,"dist",`${t}.js`),m.join(e,`${t}.js`)];for(let i of n)if(existsSync(i))return i;throw new Error(`Cannot find ${t}.js in ${m.join(e,"dist")} or ${e}`)}async function q(e,t,n,i,r,a,s){if(s){let u=await xe(t,s);if(u)throw new U(u,n)}let o=Jt(e,n),c={...process.env,...a??{}};return c.STATIC_PUBLISHER_RUNTIME_DIR=t,r&&(c.PUBLISHER_CONFIG=r),await new Promise((u,d)=>{let g=null,p=null,h=null,y=null,l=false,S="",b=spawn(process.execPath,[o,...i],{cwd:e,env:c,stdio:["inherit","inherit","pipe"]});b.stderr?.on("data",I=>{S+=I.toString("utf8");});let D=()=>{p&&clearInterval(p),h&&clearInterval(h),y&&clearTimeout(y);},f=async()=>{if(!(!s||g||l)){l=true;try{let I=await xe(t,s);if(!I)return;g=I,b.kill("SIGTERM"),y=setTimeout(()=>{b.kill("SIGKILL");},1e4);}finally{l=false;}}};s&&(p=setInterval(()=>{f();},1e3),h=setInterval(()=>{(async()=>{let I=Fe(t),x=await v(I,{});await w(I,{...x,checkedAt:new Date().toISOString(),status:"running",currentJobId:s||x.currentJobId||"",currentStep:n});})().catch(()=>{});},15e3)),b.on("error",I=>{D(),d(I);}),b.on("close",(I,x)=>{D();let J=he(S).trim();if(J&&process.stderr.write(`${J}
3
- `),g){d(new U(g,n));return}if(I===0)u();else {let O=J.split(/\r?\n/).map(T=>T.trim()).find(T=>T&&!T.startsWith("at "));d(new Error(`${n} exited with code ${I??-1}${x?` (signal ${x})`:""}${O?`: ${O}`:""}`));}});}),0}function Ot(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 Lt(e,t){let n=s=>{if(!s||typeof s!="object")return null;let o=s,c={...o.siteSettings??{},...String(o.accountId??"").trim()&&!o.siteSettings?.accountId?{accountId:String(o.accountId).trim()}:{},...String(o.siteId??"").trim()&&!o.siteSettings?.siteId?{siteId:String(o.siteId).trim()}:{},...o.siteSettings?.subscriber===true||o.subscriber===true?{subscriber:true}:{}},u={...String(o.apiBase??"").trim()?{apiBase:String(o.apiBase).trim()}:{},...String(o.runtimeToken??o.nonce??"").trim()?{runtimeToken:String(o.runtimeToken??o.nonce).trim()}:{},...String(o.virtualAssetBaseUrl??o.uploadUrl??"").trim()?{virtualAssetBaseUrl:String(o.virtualAssetBaseUrl??o.uploadUrl).trim()}:{},...Object.keys(c).length>0?{siteSettings:c}:{},...o.subscriptionType?{subscriptionType:o.subscriptionType}:{}};return Object.keys(u).length>0?u:null},i=await ee(t.configPath).catch(()=>null),r=n(i?.wpsuite);if(r)return r;let a=n(e.wpsuite);return a||null}async function Bt(e,t){return await Lt(e,t)}function le(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 Mt(e,t){let n=await v(ue(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 je(e).catch(()=>"");if(a){let s=await v(m.join(a,"current-crawl-event.json"),null),o=s&&typeof s.currentStep=="string"?s.currentStep.trim():"";if(o)return o}return t}function Ut(e,t){if((e.command==="publish"||e.command==="crawl")&&t==="rewrite-text")return "rewrite-text"}async function $t(e){let t=m.join(e.runtimeDir,"queue.json"),n=m.join(e.runtimeDir,"current-run.json"),i=await j(e.runtimeDir,async()=>{let r=await v(n,null);if(!r||r.status!=="running"&&r.status!=="queued")return null;let a=await v(t,[]),s=Array.isArray(a)?a.filter(c=>c?.id!==r.id):[],o=le(r);return await w(t,[o,...s]),await w(n,null),o});i&&(await M(e.runtimeDir,i.id),await A(e.runtimeDir,{eventType:"job-recovered",status:"queued",actorSource:"queue-runner",jobId:i.id,command:i.command,message:"Recovered stale current-run entry back into queue."}));}async function Nt(e,t,n){try{if((n.shouldEnforceSubscriptionOnJobExecution?.(e)??n.enforceSubscriptionOnJobExecution)&&n.assertActiveSubscriptionForIdentity){let o=await Bt(e,t);await n.assertActiveSubscriptionForIdentity(o);}let r=Ot(e),a=e.resumeFromStep==="rewrite-text"?["--resume-rewrite"]:e.crawlMode==="incremental"?["--crawl-mode","incremental"]:[],s=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 q(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 q(t.exporterDir,t.runtimeDir,"crawl",a,t.configPath,r,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"deploy"}),await q(t.exporterDir,t.runtimeDir,"deploy",s,t.configPath,r,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"invalidate"}),await q(t.exporterDir,t.runtimeDir,"invalidate",s,t.configPath,r,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"content-sync-baseline"}),await q(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 q(t.exporterDir,t.runtimeDir,"crawl",a,t.configPath,r,e.id),{exitCode:0};if(e.command==="deploy")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"deploy"}),await q(t.exporterDir,t.runtimeDir,"deploy",s,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 q(t.exporterDir,t.runtimeDir,"invalidate",s,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 q(t.exporterDir,t.runtimeDir,"crawl",["--retry-timeouts"],t.configPath,r,e.id),{exitCode:0};if(e.command==="url"){let o=(e.url||"").trim();return o?(await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"url"}),await q(t.exporterDir,t.runtimeDir,"crawl",["--url",o],t.configPath,r,e.id),{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 q(t.exporterDir,t.runtimeDir,"content-sync",["--job-id",e.id],t.configPath,r,e.id),{exitCode:0}):{exitCode:2,error:`Unsupported command: ${e.command}`}}catch(i){return i instanceof U?{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 Le(e){return async function(n=process.argv.slice(2)){let i=St(n),r=m.join(i.runtimeDir,"export.lock"),a=m.join(i.runtimeDir,"last-run.json");await F(i.runtimeDir),await C(i,"starting",{message:"queue-runner starting"});try{await Ft(r);}catch(s){if((s&&typeof s=="object"&&"code"in s?String(s.code||""):"")!=="EEXIST")throw s;console.log("[queue-runner] lock active, skipping"),await C(i,"lock-active",{message:"lock active, skipped this cron tick"});return}try{await $t(i);let s=await Et(i,e),o=0;for(let c=0;c<i.maxJobs;c++){let u=await _t(i,e);if(u==="none"||(o+=1,u==="stopped"))break}if(o===0)await F(i.runtimeDir),await C(i,"idle",{processedJobs:o,schedulerEnqueued:s,message:"no queued jobs"});else {await F(i.runtimeDir);let c=await v(a,null),u=String(c?.status||"").trim();await C(i,u==="success"?"job-success":u==="stopped"?"job-stopped":"job-failed",{processedJobs:o,schedulerEnqueued:s,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(s){let o=s instanceof Error?s.message:String(s);throw await C(i,"error",{message:o}),await A(i.runtimeDir,{eventType:"queue-runner-error",status:"failed",actorSource:"queue-runner",message:"Unhandled queue-runner error.",details:{error:o}}),s}finally{await jt(r);}}}async function De(e,t){if(t.command!=="content-sync"||!t.coalesceKey)return false;let n=Pe(e.runtimeDir),i=await Re(n,t.coalesceKey),r=await Ie(n),a=r.rules[t.coalesceKey];return a&&(r.rules[t.coalesceKey]={...a,trailingWorkDetected:true,retryAttempt:0,nextRetryAt:null,lastError:null},await Ae(n,r)),i}async function Qt(e,t,n){let i=m.join(e.runtimeDir,"queue.json"),r=m.join(e.runtimeDir,"current-run.json");await j(e.runtimeDir,async()=>{let a=await v(i,[]),s=Array.isArray(a)?a.filter(u=>u?.id!==t.id):[],o=le(t),c=Ut(t,n);c?o.resumeFromStep=c:delete o.resumeFromStep,await w(i,[o,...s]),await w(r,null);});}async function Wt(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()),s=new Date(Date.now()+r+a).toISOString(),o={...le(t),status:"retry-wait",attempt:i,nextAttemptAt:s,error:n};if(await j(e.runtimeDir,async()=>{let c=m.join(e.runtimeDir,"queue.json"),u=m.join(e.runtimeDir,"current-run.json"),g=(await v(c,[])).filter(p=>p.id!==t.id);await w(c,[o,...g]),await w(u,null);}),t.coalesceKey){let c=m.join(e.runtimeDir,"content-sync-state.json"),d=(await v(c,{})).rules??{};d[t.coalesceKey]={...d[t.coalesceKey]??{},ruleId:t.ruleId||"",coalesceKey:t.coalesceKey,retryAttempt:i,nextRetryAt:s,lastError:n,trailingWorkDetected:true},await w(c,{schemaVersion:1,updatedAt:new Date().toISOString(),rules:d});}return o}async function Kt(e,t){if(!t.coalesceKey||!t.ruleId||!(await v(m.join(e.runtimeDir,"content-sync-state.json"),null))?.rules?.[t.coalesceKey]?.trailingWorkDetected)return null;let i=null;await j(e.runtimeDir,async()=>{let a=m.join(e.runtimeDir,"queue.json"),s=await v(a,[]);ce(s,{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 w(a,[...s,i]));});let r=i;return r&&await A(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 _t(e,t){let n=m.join(e.runtimeDir,"queue.json"),i=m.join(e.runtimeDir,"current-run.json"),r=m.join(e.runtimeDir,"last-run.json"),a=new Date().toISOString(),s=await j(e.runtimeDir,async()=>{let g=await v(n,[]);if(!Array.isArray(g)||g.length===0)return null;let p=Date.parse(String(g[0]?.nextAttemptAt||""));if(Number.isFinite(p)&&p>Date.now())return null;let h={...g[0],status:"running",startedAt:a};return delete h.nextAttemptAt,await w(n,g.slice(1)),await w(i,h),h});if(!s)return "none";await F(e.runtimeDir),await A(e.runtimeDir,{eventType:"job-run-started",status:"running",actorSource:"queue-runner",jobId:s.id,command:s.command,message:"Job execution started.",details:{createdAt:s.createdAt||"",startedAt:a,createdBy:s.createdBy??null,deploymentProfile:s.deploymentProfile||"",queuedWithTempAwsCreds:!!s.awsTempCreds}}),await C(e,"running",{currentJobId:s.id,currentJobCommand:s.command,currentStep:s.command});let o=await Nt(s,e,t),c=new Date().toISOString();if(o.stopped){let g=await Mt(e,o.stoppedStep||s.command),p=o.stopRequest?.mode==="requeue"?"requeue":"stop",h={...s,status:"stopped",endedAt:c,exitCode:o.exitCode,...o.error?{error:o.error}:{},stopRequestedAt:o.stopRequest?.requestedAt||"",stopRequestedByUserId:typeof o.stopRequest?.requestedByUserId=="number"?o.stopRequest.requestedByUserId:null,stopRequestedByLogin:o.stopRequest?.requestedByLogin||"",stopMode:p,stoppedStep:g},y=false;p==="requeue"?await Qt(e,s,g):(await w(i,null),y=await De(e,s));try{let l=await Q(h,e);h.logArchiveDir=l.archiveDir,h.logArchiveCreatedAt=l.archiveCreatedAt,h.logArchiveFileCount=l.archivedFiles.length;}catch(l){h.logArchiveError=l instanceof Error?l.message:String(l);}return await w(r,h),await M(e.runtimeDir,s.id),await F(e.runtimeDir),await A(e.runtimeDir,{eventType:"job-run-stopped",status:"stopped",actorSource:"queue-runner",jobId:s.id,command:s.command,message:p==="requeue"?"Job stop requested and requeued.":"Job stop requested and removed from active execution without requeue.",details:{startedAt:s.startedAt||"",endedAt:c,deploymentProfile:s.deploymentProfile||"",stopMode:p,stopRequestedAt:o.stopRequest?.requestedAt||"",stopRequestedByLogin:o.stopRequest?.requestedByLogin||"",stopRequestedByUserId:typeof o.stopRequest?.requestedByUserId=="number"?o.stopRequest.requestedByUserId:null,stoppedStep:g,logArchiveKey:h.logArchiveError||!h.logArchiveDir?"":m.basename(h.logArchiveDir),logArchiveDir:h.logArchiveDir||"",logArchiveCreatedAt:h.logArchiveCreatedAt||"",logArchiveFileCount:h.logArchiveFileCount??0,logArchiveError:h.logArchiveError||"",contentSyncAbandoned:y,journalCursorPreserved:y}}),"stopped"}if(s.command==="content-sync"&&o.exitCode!==0){if(/baseline (?:is missing or stale|required)|verified content-sync baseline|new baseline/i.test(o.error||"")){let y="The installed release no longer matches the verified content-sync baseline. Run a successful full or incremental publish to establish a new baseline.";s.ruleId&&s.coalesceKey&&await Oe(e,s.ruleId,s.coalesceKey,y);let l={...s,status:"failed",endedAt:c,exitCode:o.exitCode,error:y};await w(i,null),await F(e.runtimeDir),await De(e,s);try{let S=await Q(l,e);l.logArchiveDir=S.archiveDir,l.logArchiveCreatedAt=S.archiveCreatedAt,l.logArchiveFileCount=S.archivedFiles.length;}catch(S){l.logArchiveError=S instanceof Error?S.message:String(S);}return await w(r,l),await M(e.runtimeDir,s.id),await A(e.runtimeDir,{eventType:"content-sync-baseline-required",status:"failed",actorSource:"queue-runner",jobId:s.id,command:s.command,message:y,details:{ruleId:s.ruleId||"",retryScheduled:false}}),"processed"}await A(e.runtimeDir,{eventType:"content-sync-failed",status:"failed",actorSource:"queue-runner",jobId:s.id,command:s.command,message:"Content-sync execution failed before cursor acknowledgement.",details:{attempt:s.attempt??0,error:o.error||"Content-sync execution failed."}});let p=await Wt(e,s,o.error||"Content-sync execution failed."),h={...s,status:"retry-wait",endedAt:c,exitCode:o.exitCode,error:p.error,attempt:p.attempt,nextAttemptAt:p.nextAttemptAt};try{let y=await Q(h,e);h.logArchiveDir=y.archiveDir,h.logArchiveCreatedAt=y.archiveCreatedAt,h.logArchiveFileCount=y.archivedFiles.length;}catch(y){h.logArchiveError=y instanceof Error?y.message:String(y);}return await w(r,h),await M(e.runtimeDir,s.id),await A(e.runtimeDir,{eventType:"content-sync-retry-scheduled",status:"retry-wait",actorSource:"queue-runner",jobId:s.id,command:s.command,message:"Content-sync retry was scheduled with bounded backoff.",details:{attempt:p.attempt??0,nextAttemptAt:p.nextAttemptAt||"",error:p.error||""}}),"processed"}let u={...s,status:o.exitCode===0?"success":"failed",endedAt:c,exitCode:o.exitCode,...o.error?{error:o.error}:{}};await w(i,null),u.status==="success"&&u.command==="content-sync"&&await Kt(e,u),await M(e.runtimeDir,s.id);try{let g=await Q(u,e);u.logArchiveDir=g.archiveDir,u.logArchiveCreatedAt=g.archiveCreatedAt,u.logArchiveFileCount=g.archivedFiles.length;}catch(g){u.logArchiveError=g instanceof Error?g.message:String(g);}await w(r,u);let d=s.startedAt&&u.endedAt?Math.max(0,Math.round((new Date(u.endedAt).getTime()-new Date(s.startedAt).getTime())/1e3)):void 0;return await A(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:s.startedAt||"",endedAt:u.endedAt||"",durationSec:d,deploymentProfile:u.deploymentProfile||"",exitCode:u.exitCode??null,error:u.error||"",logArchiveKey:u.logArchiveError||!u.logArchiveDir?"":m.basename(u.logArchiveDir),logArchiveDir:u.logArchiveDir||"",logArchiveCreatedAt:u.logArchiveCreatedAt||"",logArchiveFileCount:u.logArchiveFileCount??0,logArchiveError:u.logArchiveError||""}}),"processed"}async function Ht(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 Vt={allowSchedulerAutoEnqueue:true,enforceSubscriptionOnJobExecution:false,shouldEnforceSubscriptionOnJobExecution:e=>Te(e)||e.enqueueSource==="scheduler"||e.createdBy===0,assertActiveSubscriptionForIdentity:Ht},Be=Le(Vt),Gt=Be,On=Be;process.argv[1]&&import.meta.url===pathToFileURL(process.argv[1]).href&&Gt().catch(e=>{console.error(e),process.exit(1);});export{On as default,Gt as main,Be as runQueueRunner};
1
+ import {pathToFileURL}from'url';import P from'fs/promises';import {existsSync,createReadStream,createWriteStream}from'fs';import m from'path';import {spawn}from'child_process';import {randomUUID,createHash}from'crypto';import Ke from'http';import ye from'https';import {pipeline}from'stream/promises';import {createGzip}from'zlib';function pe(e){return [...new Set(e.map(t=>t.trim()).filter(Boolean))].sort()}function _(e){return Array.isArray(e)?e.map(_):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,_(n)])):e}function Ne(e){return JSON.stringify(_(e))}function L(e){return createHash("sha256").update(Ne(e)).digest("hex")}function me(e){return L({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 Qe(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 $(e){let t=pe((e.postTypes??[]).map(r=>String(r).toLowerCase().replace(/[^a-z0-9_-]/g,"")));if(t.length===0)throw new Error("Content-sync requires at least one public post type.");let n=pe((e.listingPaths??[]).map(r=>{let i=String(r).trim();if(!i)return "";let a=new URL(i,"https://content-sync.invalid/");if(a.origin!=="https://content-sync.invalid"&&/^https?:\/\//i.test(i))throw new Error("Content-sync listing routes must be same-site paths.");let s=`/${a.pathname.replace(/^\/+|\/+$/g,"")}`;return s==="/"?"/":`${s}/`}));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 L({schemaVersion:1,sourceOrigin:Qe(e),ruleId:t.trim(),scope:$(n)})}function H(e){return L({schemaVersion:1,...e})}function fe(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 he=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";he?m.join(he,"current-progress.json"):"";Promise.resolve();var _e="wp-json/smartcloud-static-publisher/v1/content-sync/",ze=25*1024*1024,E=class extends Error{status;code;constructor(t,n,r){super(r),this.name="ContentSyncApiError",this.status=t,this.code=n;}},N=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){let n=this.options.sourceOrigin.replace(/\/+$/,"")+"/";return new URL(`${_e}${t}`,n)}async post(t,n){let r=this.endpoint(t),i=Buffer.from(JSON.stringify(n),"utf8"),a=r.protocol==="https:"?ye:Ke,s=r.protocol==="https:"?new ye.Agent({rejectUnauthorized:!this.options.ignoreHttpsErrors}):void 0;return new Promise((o,c)=>{let u=a.request(r,{method:"POST",agent:s,headers:{"content-type":"application/json","content-length":String(i.byteLength),"x-static-publisher-token":this.options.runtimeToken},timeout:this.options.timeoutMs},d=>{let g=[],p=0;d.on("data",h=>{if(p+=h.byteLength,p>ze){d.destroy(new Error("Content-sync API response exceeded the size limit."));return}g.push(h);}),d.on("error",c),d.on("end",()=>{let h=Buffer.concat(g).toString("utf8"),y;try{y=h?JSON.parse(h):{};}catch{c(new E(d.statusCode??500,"invalid-json","Content-sync API returned invalid JSON."));return}let l=d.statusCode??500;if(l<200||l>=300){c(new E(l,String(y.code??"request-failed"),String(y.message??`Content-sync API request failed (${l}).`)));return}o(y);});});u.on("timeout",()=>u.destroy(new Error(`Content-sync API request timed out: ${t}`))),u.on("error",c),u.end(i);})}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=[],r=t.afterSequence,i=new Set(t.postTypes);for(;r<t.throughSequence;){let a=await this.post("events",{...t,afterSequence:r,limit:250});if(a.fromSequence!==r||a.throughSequence!==t.throughSequence||a.nextSequence<r||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 s=r;for(let o of a.items){if(!Number.isSafeInteger(o.sequence)||o.sequence<=s||o.sequence>t.throughSequence||!Number.isSafeInteger(o.postId)||o.postId<=0||!Number.isSafeInteger(o.blogId)||o.blogId<=0||!i.has(o.postType)||typeof o.operation!="string"||!o.operation)throw new Error("Content-sync API returned an invalid or out-of-scope journal event.");s=o.sequence;}if(a.items.length>0&&a.nextSequence!==s)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===r)throw new Error("Content-sync API event pagination did not advance.");r=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 r=await this.post("impact",{families:t,includeSubsites:n});return Array.isArray(r.families)?r.families:[]}async releaseFingerprint(t=false){let n=await this.post("fingerprint",{includeSubsites:t}),r=String(n.fingerprint||"").trim();if(!/^[a-f0-9]{64}$/.test(r))throw new Error("WordPress returned an invalid release fingerprint.");return r}async establishBaseline(t){return this.post("baseline",t)}async acknowledge(t){return this.post("ack",t)}};function He(e){return typeof e.subscriptionType=="string"&&e.subscriptionType.trim()!==""}function Ve(e,t){return {...e,...t??{}}}function Ge(e,t){return {...e,...t??{},invalidationPaths:[...(t?.invalidationPaths??e.invalidationPaths)||[]]}}function V(e,t){let n=String(t??e.deploymentTargetOverride??"").trim();if(!He(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 r=String(n||e.defaultDeploymentProfile||"").trim();if(!r)return {name:null,profile:null,config:e};let i=e.deploymentProfiles?.[r];if(!i)throw new Error(`Unknown deployment profile "${r}". Check the linked WPSuite publisher configuration.`);return {name:r,profile:i,config:{...e,targetOrigin:i.targetOrigin??e.targetOrigin,s3:Ve(e.s3,i.s3),cloudFront:Ge(e.cloudFront,i.cloudFront)}}}var G=["/sitemap_index.xml","/wp-sitemap.xml","/sitemap.xml"];function Se(e){let t=new Set;for(let n of [...e,...G]){let r=String(n||"").trim();r&&t.add(r);}return [...t]}function we(e){let t=e.trim();return t==="."?".":t.replace(/\/$/,"")}function et(e){let t=String(e??"").trim();if(!t)return "";let n=t;if(/^https?:\/\//i.test(n))try{n=new URL(n).pathname;}catch{return ""}if(n=n.split(/[?#]/,1)[0]?.replace(/\\/g,"/").trim()??"",!n)return "";let r=n.endsWith("/"),i=n.replace(/^\/+/,"").split("/").map(s=>s.replace(/[^A-Za-z0-9._-]/g,"")).filter(s=>s.length>0&&s!=="."&&s!=="..");if(i.length===0)return "";let a=`/${i.join("/")}`;return r&&m.extname(a)===""&&(a+="/"),a==="/"?"":a}function Y(e){return !e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t.trim(),String(n??"")]).filter(([t])=>t.length>0))}function tt(e){if(!e||typeof e!="object")return {};let t={};for(let[n,r]of Object.entries(e)){let i=n.trim();if(!i||!r||typeof r!="object")continue;let a=r,s={};if(typeof a.targetOrigin=="string"){let c=we(a.targetOrigin);c&&(s.targetOrigin=c);}let o=Y(a.extraReplacements);if(Object.keys(o).length>0&&(s.extraReplacements=o),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&&(s.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(d=>String(d??"").trim()).filter(d=>d.length>0)),Object.keys(c).length>0&&(s.cloudFront=c);}t[i]=s;}return t}function X(e){return e==="PROFESSIONAL"||e==="AGENCY"?e:void 0}function nt(e,t){if(!e||typeof e!="object")return null;let n=e,r=n.command;if(r!=="publish"&&r!=="crawl"&&r!=="deploy"&&r!=="invalidate"&&r!=="retry-timeouts"&&r!=="url"&&r!=="content-sync")return null;let i=Number.parseInt(String(n.intervalMinutes??"0"),10);if(!Number.isFinite(i)||i<1)return null;let a=String(n.id??`${r}-${t+1}`).trim();if(!a)return null;let s=String(n.deploymentProfile??"").trim(),o=String(n.url??"").trim(),c=Array.isArray(n.postTypes)?[...new Set(n.postTypes.map(d=>String(d??"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"")).filter(Boolean))]:[],u=Array.isArray(n.listingPaths)?[...new Set(n.listingPaths.map(d=>String(d??"").trim()).filter(Boolean))]:[];return r==="content-sync"&&c.length===0?null:{id:a,enabled:n.enabled!==false,command:r,intervalMinutes:i,...r==="publish"||r==="crawl"?{crawlMode:n.crawlMode==="incremental"?"incremental":"full"}:{},...(r==="publish"||r==="deploy"||r==="invalidate"||r==="content-sync")&&s?{deploymentProfile:s}:{},...o?{url:o}:{},...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 ve(e){let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.rules)?t.rules.map((r,i)=>nt(r,i)).filter(r=>!!r):[];return {enabled:t.enabled===true,timezone:typeof t.timezone=="string"&&t.timezone.trim()!==""?t.timezone.trim():"UTC",rules:n}}function rt(e){if(!e||typeof e!="object")return;let t=e,n={};for(let i of ["accountId","siteId"]){let a=t[i];typeof a=="string"&&a.trim()!==""&&(n[i]=a.trim());}let r=Number(t.lastUpdate??0);return Number.isFinite(r)&&r>0&&(n.lastUpdate=Math.floor(r)),t.subscriber===true&&(n.subscriber=true),Object.keys(n).length>0?n:void 0}function ee(e){let t=e&&typeof e=="object"?e:{},n=String(t.accountId??"").trim(),r=String(t.siteId??"").trim(),i=t.subscriber===true,a=rt(t.siteSettings),s={...a??{},...n?{accountId:a?.accountId??n}:{},...r?{siteId:a?.siteId??r}:{},...a?.subscriber===true||i?{subscriber:true}:{}},o={},c=String(t.apiBase??"").trim();c&&(o.apiBase=c);let u=String(t.runtimeToken??t.nonce??"").trim();u&&(o.runtimeToken=u);let d=String(t.virtualAssetBaseUrl??t.uploadUrl??"").trim();d&&(o.virtualAssetBaseUrl=d),Object.keys(s).length>0&&(o.siteSettings=s);let g=X(t.subscriptionType);return g&&(o.subscriptionType=g),o}function it(e){try{let t=new URL(e);globalThis.location=t;}catch{}}function Pe(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function st(e,t){let n=new Headers(e instanceof Request?e.headers:void 0);if(t?.headers)for(let[r,i]of new Headers(t.headers).entries())n.set(r,i);return n}async function Ce(e,t,n=5){let r=new URL(Pe(e)),i=String(t?.method??(e instanceof Request?e.method:"GET")).toUpperCase(),a=r.protocol==="http:"?Ke:ye,s=st(e,t);return await new Promise((o,c)=>{let u=a.request(r,{method:i,headers:Object.fromEntries(s.entries()),...r.protocol==="https:"?{rejectUnauthorized:false}:{}},d=>{let g=[];d.on("data",p=>{g.push(Buffer.isBuffer(p)?p:Buffer.from(p));}),d.on("error",c),d.on("end",()=>{let p=d.statusCode??0,h=d.headers.location;if(n>0&&h&&[301,302,303,307,308].includes(p)){o(Ce(new URL(h,r),{method:p===303?"GET":i},n-1));return}let y=new Headers;for(let[l,S]of Object.entries(d.headers))Array.isArray(S)?y.set(l,S.join(", ")):typeof S=="string"&&y.set(l,S);o(new Response(Buffer.concat(g),{status:p,statusText:d.statusMessage??"",headers:y}));});});u.on("error",c),u.end();})}function ot(e){let t=ee(e.wpsuite),n={...t.siteSettings??{},...t.siteSettings?.subscriber===true||t.subscriptionType==="PROFESSIONAL"||t.subscriptionType==="AGENCY"?{subscriber:true}:{}},r=String(n.accountId??"").trim(),i=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}:{}},!r||!i||!a)return false;it(e.sourceOrigin);let s=globalThis,c={...s.WpSuite??{},siteSettings:n,uploadUrl:a};return t.apiBase&&(c.apiBase=t.apiBase),s.WpSuite=c,true}async function at(e){let t=String(e.wpsuite?.virtualAssetBaseUrl??e.wpsuite?.uploadUrl??"").trim();if(!ot(e)){let i=e.wpsuite?.siteSettings,a=[String(i?.accountId??"").trim()?"":"accountId",String(i?.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,r=[];try{typeof n=="function"&&/^https?:\/\//i.test(t)&&(globalThis.fetch=(async(c,u)=>{let d=Pe(c);if(d.startsWith(t)){let g=(()=>{try{return new URL(d).pathname}catch{return d}})();try{let p=e.ignoreHttpsErrors&&d.startsWith("https://")?await Ce(c,u):await n(c,u);return r.push({path:g,status:p.status,ok:p.ok,error:null}),p}catch(p){throw r.push({path:g,status:null,ok:!1,error:p instanceof Error?p.message:String(p)}),p}}return n(c,u)}));let{getConfig:i}=await import('@smart-cloud/wpsuite-core'),a=await i("publisher"),s=a&&typeof a=="object"?a:null,o=X(s?.subscriptionType);return {remote:s,diagnostic:{status:s?"loaded":"unavailable",virtualAssetBaseUrl:t,subscriptionType:o??null,error:s?null:"WP Suite publisher config loader returned no configuration.",requests:r}}}catch(i){return {remote:null,diagnostic:{status:"unavailable",virtualAssetBaseUrl:t,subscriptionType:null,error:i instanceof Error?i.message:String(i),requests:r}}}finally{typeof n=="function"&&(globalThis.fetch=n);}}function ct(e,t){let n=tt(t?.deploymentProfiles),r=String(t?.defaultDeploymentProfile??"").trim(),i=n[r]?r:"",a=X(t?.subscriptionType),s=ee(e.wpsuite);return {...e,scheduler:ve(t?.scheduler),deploymentProfiles:n,defaultDeploymentProfile:i,...a?{subscriptionType:a}:{},wpsuite:{...s,...s.siteSettings||a?{siteSettings:{...s.siteSettings??{},...s.siteSettings?.subscriber===true||a==="PROFESSIONAL"||a==="AGENCY"?{subscriber:true}:{}}}:{},...a?{subscriptionType:a}:{}}}}function Z(e,t){let r=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!r)return t;let i=r.split("/").map(a=>a.trim()).filter(a=>a.length>0&&a!=="."&&a!=="..");return i.length>0?i.join("/"):t}function ut(){let e=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"";return e.trim()?m.resolve(e):""}function be(e,t,n){let r=String(t||"").trim();return r&&m.isAbsolute(r)?m.resolve(r):m.resolve(e,Z(r,n))}async function te(e,t={}){let n=String(e??"").trim()||process.env.PUBLISHER_CONFIG||"publisher.config.json",r=await P.readFile(n,"utf8"),i=JSON.parse(r);i.sourceOrigin=i.sourceOrigin.replace(/\/$/,""),i.targetOrigin=we(i.targetOrigin),i.ignoreHttpsErrors??=false,i.outputDir=String(i.outputDir||"export").trim()||"export",i.urlRewriteMode||=i.targetOrigin==="."?"relative":"absolute",i.noJavaScriptRenderPathPrefixes||=[],i.seedPaths||=[],i.generated404RequestPath=et(i.generated404RequestPath),i.sitemapPaths||=[...G],i.allowedAssetHosts||=[],i.assetPathPrefixes||=["/wp-content/","/wp-includes/","/static/","/assets/","/build/","/_next/","/docs/","/sitemap","/robots.txt","/llms.txt"],i.blockedPathPrefixes||=[],i.blockedSearchFragments||=[],i.concurrency||=1,i.maxPages||=0,i.extraReplacements=Y(i.extraReplacements),i.postCrawlCopyMap=Y(i.postCrawlCopyMap),i.logDir=String(i.logDir||"logs").trim()||"logs",i.verbose??=false,i.logLevel||=i.verbose?"debug":"info",i.s3SyncMode||="sdk-upload-delete",i.readiness||={waitForSelector:null,waitForFunction:null,timeoutMs:1500,fallbackWaitMs:1500},i.readiness.timeoutMs??=1500,i.readiness.fallbackWaitMs??=1500,i.viewport||={width:1440,height:1200},i.navigationTimeoutMs||=3e4,i.assetDownloadConcurrency=Number(i.assetDownloadConcurrency)>0?Number(i.assetDownloadConcurrency):i.concurrency,i.rewriteConcurrency=Number(i.rewriteConcurrency)>0?Number(i.rewriteConcurrency):i.assetDownloadConcurrency,i.wpsuite=ee(i.wpsuite),i.scheduler=ve(void 0),i.deploymentProfiles={},i.defaultDeploymentProfile="",i.deploymentTargetOverride=String(i.deploymentTargetOverride??"").trim();let a=await at(i);t.onRemotePublisherConfigDiagnostic?.(a.diagnostic);let s=ct(i,a.remote),o=ut(),c=o?m.resolve(o,".."):"";return c?(s.outputDir=be(c,s.outputDir,"export"),s.logDir=be(c,s.logDir,"logs")):(m.isAbsolute(s.outputDir)||(s.outputDir=Z(s.outputDir,"export")),m.isAbsolute(s.logDir)||(s.logDir=Z(s.logDir,"logs"))),s}function Ae(e){let t=m.resolve(e);return {state:m.join(t,"content-sync-state.json"),current:m.join(t,"content-sync-current.json"),impact:m.join(t,"content-sync-impact-plan.json"),checkpoint:m.join(t,"content-sync-checkpoint.json"),baseline:m.join(t,"content-sync-baseline.json"),releaseCutoff:m.join(t,"content-sync-release-cutoff.json"),candidateManifest:m.join(t,"content-sync-candidate-manifest.json"),trustedManifest:m.join(t,"crawl-manifest.json"),invalidation:m.join(t,"content-sync-invalidation.json"),deployPlan:m.join(t,"deploy-plan.json")}}async function lt(e,t){await P.mkdir(m.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 Ie(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 dt(e){let t=await Ie(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 Re(e){let t=await Ie(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 qe(e,t){await lt(e.state,{...t,schemaVersion:1,updatedAt:new Date().toISOString()});}async function xe(e,t){let n=await dt(e);return !n||n.coalesceKey!==t?false:(await Promise.all([e.current,e.checkpoint,e.impact,e.candidateManifest,e.invalidation,e.deployPlan].map(async r=>{try{await P.unlink(r);}catch(i){if(i.code!=="ENOENT")throw i}})),true)}function Fe(e){let t=String(e.command??"").trim();return (t==="publish"||t==="crawl")&&e.crawlMode==="incremental"||t==="content-sync"}var ne=new Map;async function De(e){let t=m.resolve(e),n=ne.get(t);if(n!==void 0)return n;try{let r=JSON.parse(await P.readFile(t,"utf8")),i=String(r.version??"").trim();return ne.set(t,i),i}catch{return ne.set(t,""),""}}var U=class extends Error{request;step;constructor(t,n){super(`Stop requested during ${n}.`),this.name="StopRequestedError",this.request=t,this.step=n;}},yt="queue-mutation.lock",St=5e3,bt=3e4;function wt(e){let t=process.env.STATIC_PUBLISHER_RUNTIME_DIR||process.env.WPSUITE_STATIC_PUBLISHER_RUNTIME_DIR||"",n=process.env.STATIC_PUBLISHER_EXPORTER_DIR||process.cwd(),r=process.env.PUBLISHER_CONFIG||"",i=1;for(let o=0;o<e.length;o++){let c=e[o];c==="--runtime-dir"?t=e[++o]||"":c.startsWith("--runtime-dir=")?t=c.slice(14):c==="--exporter-dir"?n=e[++o]||n:c.startsWith("--exporter-dir=")?n=c.slice(15):c==="--config"?r=e[++o]||"":c.startsWith("--config=")?r=c.slice(9):c==="--max-jobs"?i=Number.parseInt(e[++o]||"1",10):c.startsWith("--max-jobs=")&&(i=Number.parseInt(c.slice(11),10));}if(!t)throw new Error("Missing runtime dir. Use --runtime-dir or STATIC_PUBLISHER_RUNTIME_DIR.");let a=m.resolve(t),s=r?m.resolve(r):m.join(a,"config.json");return {runtimeDir:a,exporterDir:m.resolve(n),configPath:s,maxJobs:Number.isFinite(i)&&i>0?i:1}}async function v(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 i=n instanceof Error?n.message:String(n);console.warn(`[queue-runner] failed to read JSON ${e}: ${i}`);}return t}}async function w(e,t){await P.mkdir(m.dirname(e),{recursive:true}),await P.writeFile(e,JSON.stringify(t,null,2),"utf8");}function je(e){return m.join(e,yt)}async function vt(e){await new Promise(t=>setTimeout(t,e));}async function Pt(e){let t=je(e),n=Date.now()+St;for(;;)try{await P.mkdir(m.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(r){if((r&&typeof r=="object"&&"code"in r?String(r.code||""):"")!=="EEXIST")throw r;let a=await P.stat(t).catch(()=>null);if(a&&Date.now()-a.mtimeMs>bt){await P.unlink(t).catch(()=>{});continue}if(Date.now()>=n)throw new Error("Timed out acquiring queue mutation lock.",{cause:r});await vt(50);}}async function Ct(e){await P.unlink(je(e)).catch(()=>{});}async function j(e,t){await Pt(e);try{return await t()}finally{await Ct(e);}}function Je(e){return m.join(e,"queue-runner-heartbeat.json")}function le(e){return m.join(e,"current-progress.json")}function re(e){return m.join(e,"scheduler-state.json")}function At(e,t){let r=String(e||"").replace(/\\/g,"/").trim().replace(/^\/+|\/+$/g,"");if(!r)return t;let i=r.split("/").map(a=>a.trim()).filter(a=>a.length>0&&a!=="."&&a!=="..");return i.length>0?i.join("/"):t}async function Oe(e){let t=await v(e.configPath||"",null),n=m.resolve(e.runtimeDir,".."),i=(typeof t?.logDir=="string"?t.logDir:"").trim();return i&&m.isAbsolute(i)?m.resolve(i):m.resolve(n,At(i,"logs"))}function ie(e,t){return String(e||"").trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||t}function It(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 Rt(e){return [It(e.endedAt||e.startedAt),ie(e.command||"job","job"),ie(e.id||"job","job"),ie(e.status||"finished","finished")].join("-")}function qt(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 xt(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 Dt(e){return e.endsWith(".gz")?"application/gzip":e.endsWith(".jsonl")?"application/x-ndjson":e.endsWith(".json")?"application/json":"text/plain"}async function se(e,t,n){let r=`${n}.gz`,i=m.join(t,r);await pipeline(createReadStream(e),createGzip({level:9}),createWriteStream(i));let[a,s]=await Promise.all([P.stat(e),P.stat(i)]);return {role:xt(n),originalFileName:n,storedFileName:r,compressed:true,compression:"gzip",contentType:Dt(r),originalSize:a.size,storedSize:s.size}}async function Q(e,t){let n=await Oe(t),r=new Date().toISOString(),i=Rt(e),a=m.join(n,"archive",i),s=[],o=[];await P.mkdir(a,{recursive:true});try{let d=await P.readdir(n,{withFileTypes:!0});for(let g of d){if(!g.isFile()||!qt(g.name))continue;let p=await se(m.join(n,g.name),a,g.name);o.push(p),s.push(p.storedFileName);}}catch(d){if((d&&typeof d=="object"&&"code"in d?String(d.code||""):"")!=="ENOENT")throw d}let c=le(t.runtimeDir);if(existsSync(c)){let d=await se(c,a,"current-progress.json");o.push(d),s.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 g=m.join(t.runtimeDir,d);if(!existsSync(g))continue;let p=await se(g,a,d);o.push(p),s.push(p.storedFileName);}let u=[...s,"job.json"];return await w(m.join(a,"job.json"),{manifestVersion:1,archivedAt:r,archiveKey:i,archiveDir:a,logDir:n,runtimeDir:t.runtimeDir,exporterDir:t.exporterDir,configPath:t.configPath||"",archivedFiles:u,artifacts:o,job:e}),{archiveKey:i,archiveDir:a,archiveCreatedAt:r,archivedFiles:u,artifacts:o}}function kt(e){return m.join(e,"audit-events.jsonl")}function ce(e){return m.join(e,"stop-request.json")}async function Le(e){try{let t=await P.readFile(ce(e),"utf8"),n=JSON.parse(t);return n&&typeof n=="object"?n:null}catch{return null}}async function ke(e,t){let n=await Le(e);if(!n)return null;let r=String(n.targetJobId||"").trim();return r&&r!==t?null:n}async function M(e,t){if(!t){await P.unlink(ce(e)).catch(()=>{});return}let n=await Le(e);if(!n)return;let r=String(n.targetJobId||"").trim();(!r||r===t)&&await P.unlink(ce(e)).catch(()=>{});}async function I(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(kt(e),`${JSON.stringify(n)}
2
+ `,"utf8");}catch{}}async function C(e,t,n){let[r,i]=await Promise.all([De(m.join(e.exporterDir,"package.json")),De(m.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:r,wpsuiteCoreVersion:i,runtimeDir:e.runtimeDir,exporterDir:e.exporterDir,...n??{}};try{await w(Je(e.runtimeDir),a);}catch{}}async function F(e){try{await P.unlink(le(e));}catch{}}function Tt(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 r=Number.parseInt(String(e.intervalMinutes??"0"),10);if(!Number.isFinite(r)||r<1)return null;let i=(e.id||`${n}-${t+1}`).trim();if(!i)return null;let a=e.enabled!==false,s=typeof e.url=="string"?e.url.trim():"",o=typeof e.deploymentProfile=="string"?e.deploymentProfile.trim():"",c=Array.isArray(e.postTypes)?[...new Set(e.postTypes.map(g=>String(g).trim()).filter(Boolean))]:[],u=Array.isArray(e.listingPaths)?[...new Set(e.listingPaths.map(g=>String(g).trim()).filter(Boolean))]:[],d=(n==="publish"||n==="crawl")&&e.crawlMode==="incremental"?"incremental":"full";return n==="url"&&!s||n==="content-sync"&&c.length===0?null:{id:i,enabled:a,command:n,intervalMinutes:r,...n==="publish"||n==="crawl"?{crawlMode:d}:{},...(n==="publish"||n==="deploy"||n==="invalidate"||n==="content-sync")&&o?{deploymentProfile:o}:{},...s?{url:s}:{},...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 Et(e){let t=await te(e.configPath).catch(()=>null),n=t?.scheduler,r=Array.isArray(n?.rules)?n.rules.map((i,a)=>Tt(i,a)).filter(i=>!!i):[];return {enabled:!!n?.enabled,timezone:typeof n?.timezone=="string"&&n.timezone.trim()?n.timezone.trim():"UTC",rules:r,wpsuite:t?.wpsuite,publisherConfig:t}}function oe(e,t){if(!t)throw new Error("Content-sync scheduler requires a valid publisher config.");let n=$({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}),r=z(t.sourceOrigin,e.id,n),i=V(t,e.deploymentProfile),a=H({sourceOrigin:t.sourceOrigin,targetOrigin:i.config.targetOrigin,deploymentProfile:i.name||"",s3Bucket:i.config.s3.bucket,s3Prefix:i.config.s3.prefix,cloudFrontDistributionId:i.config.cloudFront.distributionId,urlRewriteMode:i.config.urlRewriteMode,extraReplacements:i.profile?.extraReplacements??{}});return `content-sync:${e.id}:${L({scopeFingerprint:r,targetFingerprint:a}).slice(0,32)}`}async function Ft(e,t,n,r,i){let s=(await v(m.join(e.runtimeDir,"content-sync-baseline.json"),{})).entries?.[r];if(!s?.consumerId||!s.scopeFingerprint||!s.baselineId)return {status:"baseline-required",reason:"No verified normal-release baseline exists for this rule scope."};try{let o=t.publisherConfig;if(!o)throw new Error("Publisher configuration is unavailable.");let c=$({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(o.sourceOrigin,n.id,c),d=V(o,n.deploymentProfile),g=H({sourceOrigin:o.sourceOrigin,targetOrigin:d.config.targetOrigin,deploymentProfile:d.name||"",s3Bucket:d.config.s3.bucket,s3Prefix:d.config.s3.prefix,cloudFrontDistributionId:d.config.cloudFront.distributionId,urlRewriteMode:d.config.urlRewriteMode,extraReplacements:d.profile?.extraReplacements??{}});if(s.scopeFingerprint!==u||s.targetFingerprint!==g||!s.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 p=new N({sourceOrigin:o.sourceOrigin,runtimeToken:String(o.wpsuite?.runtimeToken||""),ignoreHttpsErrors:o.ignoreHttpsErrors}),h=await p.releaseFingerprint(c.includeSubsites),y=me({wordpressFingerprint:h,targetFingerprint:g,sourceOrigin:o.sourceOrigin,sitemapPaths:Se(o.sitemapPaths),blockedPathPrefixes:o.blockedPathPrefixes,assetPathPrefixes:o.assetPathPrefixes,noJavaScriptRenderPathPrefixes:o.noJavaScriptRenderPathPrefixes,urlRewriteMode:o.urlRewriteMode});if(s.releaseFingerprint!==y)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 p.head({consumerId:s.consumerId,scopeFingerprint:s.scopeFingerprint,baselineId:s.baselineId,postTypes:c.postTypes,includeSubsites:c.includeSubsites}),S=l.committedSequence;if(i?.command==="content-sync"&&i.coalesceKey===r){let b=await v(m.join(e.runtimeDir,"content-sync-current.json"),null);b?.coalesceKey===r&&Number.isSafeInteger(b.toSequence)&&(S=Math.max(S,Number(b.toSequence)));}return {status:l.headSequence>S?"pending":"current",headSequence:l.headSequence,committedSequence:l.committedSequence}}catch(o){return o instanceof E&&o.code==="baseline-required"?{status:"baseline-required",reason:o.message}:{status:"unavailable",reason:o instanceof Error?o.message:String(o)}}}async function Be(e,t,n,r,i,a){let s=m.join(e.runtimeDir,"content-sync-state.json"),c=(await v(s,{})).rules??{},u=c[n]??{};c[n]={...u,ruleId:t,coalesceKey:n,...Number.isSafeInteger(i)?{observedHeadSequence:i}:{},...Number.isSafeInteger(a)?{committedSequence:a}:{},retryAttempt:0,nextRetryAt:null,lastError:r,baselineStatus:"required",baselineReason:r,trailingWorkDetected:Number.isSafeInteger(i)&&Number.isSafeInteger(a)?Number(i)>Number(a):!!u.trailingWorkDetected},await w(s,{schemaVersion:1,updatedAt:new Date().toISOString(),rules:c});}function ue(e,t){let n=(t.url||"").trim(),r=t.crawlMode||"full",i=(t.deploymentProfile||"").trim(),a=(t.coalesceKey||"").trim();return e.some(s=>s.command===t.command&&(t.command!=="content-sync"||(s.coalesceKey||"").trim()===a)&&(s.url||"").trim()===n&&(s.crawlMode||"full")===r&&(s.deploymentProfile||"").trim()===i&&(s.status===void 0||s.status==="queued"||s.status==="retry-wait"||s.status==="running"))}async function jt(e,t,n){if(!t.allowSchedulerAutoEnqueue)return 0;let r=await Et(e);if(!r.enabled||r.rules.length===0)return 0;if(t.assertActiveSubscriptionForIdentity)try{await t.assertActiveSubscriptionForIdentity(r.wpsuite??null);}catch(l){let S=l instanceof Error?l.message:String(l);return console.warn(`[queue-runner] scheduler auto-enqueue skipped: ${S}`),0}let i=m.join(e.runtimeDir,"queue.json"),a=m.join(e.runtimeDir,"current-run.json"),s=Date.now(),o=0,c=[],u=[],d=[],g=new Map,[p,h,y]=await Promise.all([v(i,[]),v(a,null),v(re(e.runtimeDir),{lastEnqueuedBucketByRuleId:{},lastEvaluatedBucketByRuleId:{},lastCreatedBucketByRuleId:{},coalescedCountByRuleId:{}})]);for(let l of r.rules){if(!l.enabled||l.command!=="content-sync")continue;let S=Math.floor(s/(l.intervalMinutes*60*1e3)),b=y.lastEvaluatedBucketByRuleId?.[l.id]??y.lastEnqueuedBucketByRuleId?.[l.id]??-1;if(S<=b)continue;let D=oe(l,r.publisherConfig);ue(p,{command:l.command,deploymentProfile:l.deploymentProfile,coalesceKey:D})||g.set(l.id,await Ft(e,r,l,D,h));}await j(e.runtimeDir,async()=>{let l=await v(i,[]),S=await v(a,null),b=await v(re(e.runtimeDir),{lastEnqueuedBucketByRuleId:{},lastEvaluatedBucketByRuleId:{},lastCreatedBucketByRuleId:{},coalescedCountByRuleId:{}});b.lastEnqueuedBucketByRuleId??={},b.lastEvaluatedBucketByRuleId??={...b.lastEnqueuedBucketByRuleId},b.lastCreatedBucketByRuleId??={...b.lastEnqueuedBucketByRuleId},b.coalescedCountByRuleId??={};let D=[...l];S&&S.status==="running"&&D.unshift(S);for(let f of r.rules){if(!f.enabled)continue;let A=f.intervalMinutes*60*1e3,x=Math.floor(s/A),J=b.lastEvaluatedBucketByRuleId[f.id]??b.lastEnqueuedBucketByRuleId[f.id]??-1;if(x<=J)continue;let O=f.command==="content-sync"?oe(f,r.publisherConfig):"";b.lastEvaluatedBucketByRuleId[f.id]=x;let T=f.command==="content-sync"?l:D;if(ue(T,{command:f.command,url:f.url,crawlMode:f.crawlMode,deploymentProfile:f.deploymentProfile,coalesceKey:O})){b.coalescedCountByRuleId[f.id]=(b.coalescedCountByRuleId[f.id]??0)+1,u.push(f);continue}if(f.command==="content-sync"){let K=g.get(f.id);if(!K||K.status!=="pending"){let ge=K??{status:"unavailable",reason:"Content-sync demand was not checked."};ge.status!=="current"&&d.push({rule:f,check:ge});continue}}let W={id:randomUUID(),command:f.command,...f.command==="content-sync"?{ruleId:f.id,coalesceKey:O,attempt:0}:{},...(f.command==="publish"||f.command==="crawl")&&f.crawlMode?{crawlMode:f.crawlMode}:{},...(f.command==="publish"||f.command==="deploy"||f.command==="invalidate"||f.command==="content-sync")&&f.deploymentProfile?{deploymentProfile:f.deploymentProfile}:{},...f.url?{url:f.url}:{},enqueueSource:"scheduler",...r.wpsuite?{wpsuite:r.wpsuite}:{},status:"queued",createdAt:new Date().toISOString(),createdBy:0};l.push(W),D.push(W),c.push({job:W,rule:f}),b.lastEnqueuedBucketByRuleId[f.id]=x,b.lastCreatedBucketByRuleId[f.id]=x,o+=1;}o>0&&await w(i,l),await w(re(e.runtimeDir),b);});for(let l of c){if(l.rule.command==="content-sync"){let S=g.get(l.rule.id);await I(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:S?.headSequence??0,committedSequence:S?.committedSequence??0}});}await I(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:r.timezone,deploymentProfile:l.rule.deploymentProfile||"",url:l.rule.url||""}});}for(let l of u)await I(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 d){if(l.check.status==="baseline-required"){let S=oe(l.rule,r.publisherConfig);await Be(e,l.rule.id,S,l.check.reason||"A successful full or incremental publish must establish a new content-sync baseline.",l.check.headSequence,l.check.committedSequence);}await I(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 o}async function Jt(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 Ot(e){try{await P.unlink(e);}catch{}}function Lt(e,t){let n=[m.join(e,"dist",`${t}.js`),m.join(e,`${t}.js`)];for(let r of n)if(existsSync(r))return r;throw new Error(`Cannot find ${t}.js in ${m.join(e,"dist")} or ${e}`)}async function q(e,t,n,r,i,a,s){if(s){let u=await ke(t,s);if(u)throw new U(u,n)}let o=Lt(e,n),c={...process.env,...a??{}};return c.STATIC_PUBLISHER_RUNTIME_DIR=t,i&&(c.PUBLISHER_CONFIG=i),await new Promise((u,d)=>{let g=null,p=null,h=null,y=null,l=false,S="",b=spawn(process.execPath,[o,...r],{cwd:e,env:c,stdio:["inherit","inherit","pipe"]});b.stderr?.on("data",A=>{S+=A.toString("utf8");});let D=()=>{p&&clearInterval(p),h&&clearInterval(h),y&&clearTimeout(y);},f=async()=>{if(!(!s||g||l)){l=true;try{let A=await ke(t,s);if(!A)return;g=A,b.kill("SIGTERM"),y=setTimeout(()=>{b.kill("SIGKILL");},1e4);}finally{l=false;}}};s&&(p=setInterval(()=>{f();},1e3),h=setInterval(()=>{(async()=>{let A=Je(t),x=await v(A,{});await w(A,{...x,checkedAt:new Date().toISOString(),status:"running",currentJobId:s||x.currentJobId||"",currentStep:n});})().catch(()=>{});},15e3)),b.on("error",A=>{D(),d(A);}),b.on("close",(A,x)=>{D();let J=fe(S).trim();if(J&&process.stderr.write(`${J}
3
+ `),g){d(new U(g,n));return}if(A===0)u();else {let O=J.split(/\r?\n/).map(T=>T.trim()).find(T=>T&&!T.startsWith("at "));d(new Error(`${n} exited with code ${A??-1}${x?` (signal ${x})`:""}${O?`: ${O}`:""}`));}});}),0}function Bt(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 Mt(e,t){let n=s=>{if(!s||typeof s!="object")return null;let o=s,c={...o.siteSettings??{},...String(o.accountId??"").trim()&&!o.siteSettings?.accountId?{accountId:String(o.accountId).trim()}:{},...String(o.siteId??"").trim()&&!o.siteSettings?.siteId?{siteId:String(o.siteId).trim()}:{},...o.siteSettings?.subscriber===true||o.subscriber===true?{subscriber:true}:{}},u={...String(o.apiBase??"").trim()?{apiBase:String(o.apiBase).trim()}:{},...String(o.runtimeToken??o.nonce??"").trim()?{runtimeToken:String(o.runtimeToken??o.nonce).trim()}:{},...String(o.virtualAssetBaseUrl??o.uploadUrl??"").trim()?{virtualAssetBaseUrl:String(o.virtualAssetBaseUrl??o.uploadUrl).trim()}:{},...Object.keys(c).length>0?{siteSettings:c}:{},...o.subscriptionType?{subscriptionType:o.subscriptionType}:{}};return Object.keys(u).length>0?u:null},r=await te(t.configPath).catch(()=>null),i=n(r?.wpsuite);if(i)return i;let a=n(e.wpsuite);return a||null}async function Ut(e,t){return await Mt(e,t)}function de(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 v(le(e.runtimeDir),null),r=n&&n.details&&typeof n.details.phase=="string"?n.details.phase.trim():"";if(r)return r;let i=n&&typeof n.currentStep=="string"?n.currentStep.trim():"";if(i)return i;let a=await Oe(e).catch(()=>"");if(a){let s=await v(m.join(a,"current-crawl-event.json"),null),o=s&&typeof s.currentStep=="string"?s.currentStep.trim():"";if(o)return o}return t}function Nt(e,t){if((e.command==="publish"||e.command==="crawl")&&t==="rewrite-text")return "rewrite-text"}async function Qt(e){let t=m.join(e.runtimeDir,"queue.json"),n=m.join(e.runtimeDir,"current-run.json"),r=await j(e.runtimeDir,async()=>{let i=await v(n,null);if(!i||i.status!=="running"&&i.status!=="queued")return null;let a=await v(t,[]),s=Array.isArray(a)?a.filter(c=>c?.id!==i.id):[],o=de(i);return await w(t,[o,...s]),await w(n,null),o});r&&(await M(e.runtimeDir,r.id),await I(e.runtimeDir,{eventType:"job-recovered",status:"queued",actorSource:"queue-runner",jobId:r.id,command:r.command,message:"Recovered stale current-run entry back into queue."}));}async function Wt(e,t,n){try{if((n.shouldEnforceSubscriptionOnJobExecution?.(e)??n.enforceSubscriptionOnJobExecution)&&n.assertActiveSubscriptionForIdentity){let o=await Ut(e,t);await n.assertActiveSubscriptionForIdentity(o);}let i=Bt(e),a=e.resumeFromStep==="rewrite-text"?["--resume-rewrite"]:e.crawlMode==="incremental"?["--crawl-mode","incremental"]:[],s=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 q(t.exporterDir,t.runtimeDir,"content-sync",["--capture-baseline-cutoffs",e.id],t.configPath,i,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:e.resumeFromStep==="rewrite-text"?"rewrite-text":"crawl"}),await q(t.exporterDir,t.runtimeDir,"crawl",a,t.configPath,i,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"deploy"}),await q(t.exporterDir,t.runtimeDir,"deploy",s,t.configPath,i,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"invalidate"}),await q(t.exporterDir,t.runtimeDir,"invalidate",s,t.configPath,i,e.id),await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"content-sync-baseline"}),await q(t.exporterDir,t.runtimeDir,"content-sync",["--establish-baselines",e.id],t.configPath,i,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 q(t.exporterDir,t.runtimeDir,"crawl",a,t.configPath,i,e.id),{exitCode:0};if(e.command==="deploy")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"deploy"}),await q(t.exporterDir,t.runtimeDir,"deploy",s,t.configPath,i,e.id),{exitCode:0};if(e.command==="invalidate")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"invalidate"}),await q(t.exporterDir,t.runtimeDir,"invalidate",s,t.configPath,i,e.id),{exitCode:0};if(e.command==="retry-timeouts")return await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"retry-timeouts"}),await q(t.exporterDir,t.runtimeDir,"crawl",["--retry-timeouts"],t.configPath,i,e.id),{exitCode:0};if(e.command==="url"){let o=(e.url||"").trim();return o?(await C(t,"running",{currentJobId:e.id,currentJobCommand:e.command,currentStep:"url"}),await q(t.exporterDir,t.runtimeDir,"crawl",["--url",o],t.configPath,i,e.id),{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 q(t.exporterDir,t.runtimeDir,"content-sync",["--job-id",e.id],t.configPath,i,e.id),{exitCode:0}):{exitCode:2,error:`Unsupported command: ${e.command}`}}catch(r){return r instanceof U?{exitCode:130,error:"Job stop requested.",stopped:true,stopRequest:r.request,stoppedStep:r.step}:{exitCode:1,error:r instanceof Error?r.message:String(r)}}}function Me(e){return async function(n=process.argv.slice(2)){let r=wt(n),i=m.join(r.runtimeDir,"export.lock"),a=m.join(r.runtimeDir,"last-run.json");await F(r.runtimeDir),await C(r,"starting",{message:"queue-runner starting"});try{await Jt(i);}catch(s){if((s&&typeof s=="object"&&"code"in s?String(s.code||""):"")!=="EEXIST")throw s;console.log("[queue-runner] lock active, skipping"),await C(r,"lock-active",{message:"lock active, skipped this cron tick"});return}try{await Qt(r);let s=await jt(r,e),o=0;for(let c=0;c<r.maxJobs;c++){let u=await Ht(r,e);if(u==="none"||(o+=1,u==="stopped"))break}if(o===0)await F(r.runtimeDir),await C(r,"idle",{processedJobs:o,schedulerEnqueued:s,message:"no queued jobs"});else {await F(r.runtimeDir);let c=await v(a,null),u=String(c?.status||"").trim();await C(r,u==="success"?"job-success":u==="stopped"?"job-stopped":"job-failed",{processedJobs:o,schedulerEnqueued:s,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(s){let o=s instanceof Error?s.message:String(s);throw await C(r,"error",{message:o}),await I(r.runtimeDir,{eventType:"queue-runner-error",status:"failed",actorSource:"queue-runner",message:"Unhandled queue-runner error.",details:{error:o}}),s}finally{await Ot(i);}}}async function Te(e,t){if(t.command!=="content-sync"||!t.coalesceKey)return false;let n=Ae(e.runtimeDir),r=await xe(n,t.coalesceKey),i=await Re(n),a=i.rules[t.coalesceKey];return a&&(i.rules[t.coalesceKey]={...a,trailingWorkDetected:true,retryAttempt:0,nextRetryAt:null,lastError:null},await qe(n,i)),r}async function Kt(e,t,n){let r=m.join(e.runtimeDir,"queue.json"),i=m.join(e.runtimeDir,"current-run.json");await j(e.runtimeDir,async()=>{let a=await v(r,[]),s=Array.isArray(a)?a.filter(u=>u?.id!==t.id):[],o=de(t),c=Nt(t,n);c?o.resumeFromStep=c:delete o.resumeFromStep,await w(r,[o,...s]),await w(i,null);});}async function _t(e,t,n){let r=Math.max(0,t.attempt??0)+1,i=Math.min(3600*1e3,6e4*2**(r-1)),a=Math.floor(i*.2*Math.random()),s=new Date(Date.now()+i+a).toISOString(),o={...de(t),status:"retry-wait",attempt:r,nextAttemptAt:s,error:n};if(await j(e.runtimeDir,async()=>{let c=m.join(e.runtimeDir,"queue.json"),u=m.join(e.runtimeDir,"current-run.json"),g=(await v(c,[])).filter(p=>p.id!==t.id);await w(c,[o,...g]),await w(u,null);}),t.coalesceKey){let c=m.join(e.runtimeDir,"content-sync-state.json"),d=(await v(c,{})).rules??{};d[t.coalesceKey]={...d[t.coalesceKey]??{},ruleId:t.ruleId||"",coalesceKey:t.coalesceKey,retryAttempt:r,nextRetryAt:s,lastError:n,trailingWorkDetected:true},await w(c,{schemaVersion:1,updatedAt:new Date().toISOString(),rules:d});}return o}async function zt(e,t){if(!t.coalesceKey||!t.ruleId||!(await v(m.join(e.runtimeDir,"content-sync-state.json"),null))?.rules?.[t.coalesceKey]?.trailingWorkDetected)return null;let r=null;await j(e.runtimeDir,async()=>{let a=m.join(e.runtimeDir,"queue.json"),s=await v(a,[]);ue(s,{command:"content-sync",coalesceKey:t.coalesceKey,deploymentProfile:t.deploymentProfile})||(r={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 w(a,[...s,r]));});let i=r;return i&&await I(e.runtimeDir,{eventType:"content-sync-trailing-job-created",status:"queued",actorSource:"queue-runner",jobId:i.id,command:i.command,message:"Content changes after the stable cutoff created one trailing job.",details:{predecessorJobId:t.id,ruleId:t.ruleId,coalesceKey:t.coalesceKey}}),i}async function Ht(e,t){let n=m.join(e.runtimeDir,"queue.json"),r=m.join(e.runtimeDir,"current-run.json"),i=m.join(e.runtimeDir,"last-run.json"),a=new Date().toISOString(),s=await j(e.runtimeDir,async()=>{let g=await v(n,[]);if(!Array.isArray(g)||g.length===0)return null;let p=Date.parse(String(g[0]?.nextAttemptAt||""));if(Number.isFinite(p)&&p>Date.now())return null;let h={...g[0],status:"running",startedAt:a};return delete h.nextAttemptAt,await w(n,g.slice(1)),await w(r,h),h});if(!s)return "none";await F(e.runtimeDir),await I(e.runtimeDir,{eventType:"job-run-started",status:"running",actorSource:"queue-runner",jobId:s.id,command:s.command,message:"Job execution started.",details:{createdAt:s.createdAt||"",startedAt:a,createdBy:s.createdBy??null,deploymentProfile:s.deploymentProfile||"",queuedWithTempAwsCreds:!!s.awsTempCreds}}),await C(e,"running",{currentJobId:s.id,currentJobCommand:s.command,currentStep:s.command});let o=await Wt(s,e,t),c=new Date().toISOString();if(o.stopped){let g=await $t(e,o.stoppedStep||s.command),p=o.stopRequest?.mode==="requeue"?"requeue":"stop",h={...s,status:"stopped",endedAt:c,exitCode:o.exitCode,...o.error?{error:o.error}:{},stopRequestedAt:o.stopRequest?.requestedAt||"",stopRequestedByUserId:typeof o.stopRequest?.requestedByUserId=="number"?o.stopRequest.requestedByUserId:null,stopRequestedByLogin:o.stopRequest?.requestedByLogin||"",stopMode:p,stoppedStep:g},y=false;p==="requeue"?await Kt(e,s,g):(await w(r,null),y=await Te(e,s));try{let l=await Q(h,e);h.logArchiveDir=l.archiveDir,h.logArchiveCreatedAt=l.archiveCreatedAt,h.logArchiveFileCount=l.archivedFiles.length;}catch(l){h.logArchiveError=l instanceof Error?l.message:String(l);}return await w(i,h),await M(e.runtimeDir,s.id),await F(e.runtimeDir),await I(e.runtimeDir,{eventType:"job-run-stopped",status:"stopped",actorSource:"queue-runner",jobId:s.id,command:s.command,message:p==="requeue"?"Job stop requested and requeued.":"Job stop requested and removed from active execution without requeue.",details:{startedAt:s.startedAt||"",endedAt:c,deploymentProfile:s.deploymentProfile||"",stopMode:p,stopRequestedAt:o.stopRequest?.requestedAt||"",stopRequestedByLogin:o.stopRequest?.requestedByLogin||"",stopRequestedByUserId:typeof o.stopRequest?.requestedByUserId=="number"?o.stopRequest.requestedByUserId:null,stoppedStep:g,logArchiveKey:h.logArchiveError||!h.logArchiveDir?"":m.basename(h.logArchiveDir),logArchiveDir:h.logArchiveDir||"",logArchiveCreatedAt:h.logArchiveCreatedAt||"",logArchiveFileCount:h.logArchiveFileCount??0,logArchiveError:h.logArchiveError||"",contentSyncAbandoned:y,journalCursorPreserved:y}}),"stopped"}if(s.command==="content-sync"&&o.exitCode!==0){if(/baseline (?:is missing or stale|required)|verified content-sync baseline|new baseline/i.test(o.error||"")){let y="The installed release no longer matches the verified content-sync baseline. Run a successful full or incremental publish to establish a new baseline.";s.ruleId&&s.coalesceKey&&await Be(e,s.ruleId,s.coalesceKey,y);let l={...s,status:"failed",endedAt:c,exitCode:o.exitCode,error:y};await w(r,null),await F(e.runtimeDir),await Te(e,s);try{let S=await Q(l,e);l.logArchiveDir=S.archiveDir,l.logArchiveCreatedAt=S.archiveCreatedAt,l.logArchiveFileCount=S.archivedFiles.length;}catch(S){l.logArchiveError=S instanceof Error?S.message:String(S);}return await w(i,l),await M(e.runtimeDir,s.id),await I(e.runtimeDir,{eventType:"content-sync-baseline-required",status:"failed",actorSource:"queue-runner",jobId:s.id,command:s.command,message:y,details:{ruleId:s.ruleId||"",retryScheduled:false}}),"processed"}await I(e.runtimeDir,{eventType:"content-sync-failed",status:"failed",actorSource:"queue-runner",jobId:s.id,command:s.command,message:"Content-sync execution failed before cursor acknowledgement.",details:{attempt:s.attempt??0,error:o.error||"Content-sync execution failed."}});let p=await _t(e,s,o.error||"Content-sync execution failed."),h={...s,status:"retry-wait",endedAt:c,exitCode:o.exitCode,error:p.error,attempt:p.attempt,nextAttemptAt:p.nextAttemptAt};try{let y=await Q(h,e);h.logArchiveDir=y.archiveDir,h.logArchiveCreatedAt=y.archiveCreatedAt,h.logArchiveFileCount=y.archivedFiles.length;}catch(y){h.logArchiveError=y instanceof Error?y.message:String(y);}return await w(i,h),await M(e.runtimeDir,s.id),await I(e.runtimeDir,{eventType:"content-sync-retry-scheduled",status:"retry-wait",actorSource:"queue-runner",jobId:s.id,command:s.command,message:"Content-sync retry was scheduled with bounded backoff.",details:{attempt:p.attempt??0,nextAttemptAt:p.nextAttemptAt||"",error:p.error||""}}),"processed"}let u={...s,status:o.exitCode===0?"success":"failed",endedAt:c,exitCode:o.exitCode,...o.error?{error:o.error}:{}};await w(r,null),u.status==="success"&&u.command==="content-sync"&&await zt(e,u),await M(e.runtimeDir,s.id);try{let g=await Q(u,e);u.logArchiveDir=g.archiveDir,u.logArchiveCreatedAt=g.archiveCreatedAt,u.logArchiveFileCount=g.archivedFiles.length;}catch(g){u.logArchiveError=g instanceof Error?g.message:String(g);}await w(i,u);let d=s.startedAt&&u.endedAt?Math.max(0,Math.round((new Date(u.endedAt).getTime()-new Date(s.startedAt).getTime())/1e3)):void 0;return await I(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:s.startedAt||"",endedAt:u.endedAt||"",durationSec:d,deploymentProfile:u.deploymentProfile||"",exitCode:u.exitCode??null,error:u.error||"",logArchiveKey:u.logArchiveError||!u.logArchiveDir?"":m.basename(u.logArchiveDir),logArchiveDir:u.logArchiveDir||"",logArchiveCreatedAt:u.logArchiveCreatedAt||"",logArchiveFileCount:u.logArchiveFileCount??0,logArchiveError:u.logArchiveError||""}}),"processed"}async function Gt(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 Yt={allowSchedulerAutoEnqueue:true,enforceSubscriptionOnJobExecution:false,shouldEnforceSubscriptionOnJobExecution:e=>Fe(e)||e.enqueueSource==="scheduler"||e.createdBy===0,assertActiveSubscriptionForIdentity:Gt},Ue=Me(Yt),Zt=Ue,$n=Ue;process.argv[1]&&import.meta.url===pathToFileURL(process.argv[1]).href&&Zt().catch(e=>{console.error(e),process.exit(1);});export{$n as default,Zt as main,Ue as runQueueRunner};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smart-cloud/publisher-exporter",
3
- "version": "1.1.49",
3
+ "version": "1.1.52",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Headless Playwright static publisher for WordPress/Elementor sites with sitemap-only page discovery, strict asset capture, escaped URL rewrite, structured logs, and targeted retry modes.",
@@ -46,8 +46,8 @@
46
46
  "@aws-sdk/client-cloudfront": "^3.1127.0",
47
47
  "@aws-sdk/client-s3": "^3.1127.0",
48
48
  "@aws-sdk/lib-storage": "^3.1127.0",
49
- "@smart-cloud/publisher-core": "^1.1.9",
50
- "@smart-cloud/wpsuite-core": "^2.4.0",
49
+ "@smart-cloud/publisher-core": "^1.1.10",
50
+ "@smart-cloud/wpsuite-core": "^2.4.1",
51
51
  "@wordpress/data": "^10.54.0",
52
52
  "baseline-browser-mapping": "^2.11.21",
53
53
  "caniuse-lite": "^1.0.30001810",