UNPKG

buddy-bot

Version:

Automated & optimized dependency updates for JavaScript & TypeScript projects. Like Renovate & Dependabot.

6 lines (4 loc) 4.49 kB
// @bun import{d as X,e as _}from"./chunk-tpe7vkbz.js";import"./chunk-r1rkcs0b.js";import"./chunk-j0phfedr.js";import"./chunk-ma13sjrm.js";import"./chunk-p0vny2x9.js";import"./chunk-1z74sgbm.js";import"./chunk-b5gyp8hn.js";import"./chunk-3j3vxazw.js";import"./chunk-f5bh0qas.js";import"./chunk-72vxav2c.js";import"./chunk-knkqp939.js";import"./chunk-jah7r3bb.js";import"./chunk-32dgq3f4.js";import"./chunk-8wk4nc61.js";import"./chunk-vd04qkw4.js";import"./chunk-pvk7bcsa.js";import V from"process";class ${jobs=new Map;timers=new Map;logger;isRunning=!1;constructor(q=!1){this.logger=q?X.verbose():X.quiet()}addJob(q){this.jobs.set(q.id,q),this.scheduleJob(q),this.logger.info(`Scheduled job '${q.name}' with cron: ${q.schedule.cron}`)}removeJob(q){let C=this.timers.get(q);if(C)clearTimeout(C),this.timers.delete(q);this.jobs.delete(q),this.logger.info(`Removed scheduled job: ${q}`)}start(){if(this.isRunning){this.logger.warn("Scheduler is already running");return}this.isRunning=!0,this.logger.info("\uD83D\uDD52 Buddy Scheduler started");for(let q of this.jobs.values())if(this.scheduleJob(q),q.schedule.runOnStartup)this.logger.info(`Running startup job: ${q.name}`),setImmediate(()=>this.runJob(q));V.on("SIGINT",()=>this.stop()),V.on("SIGTERM",()=>this.stop())}stop(){if(!this.isRunning)return;this.isRunning=!1,this.logger.info("\uD83D\uDED1 Stopping Buddy Scheduler...");for(let q of this.timers.values())clearTimeout(q);this.timers.clear(),this.logger.success("\u2705 Buddy Scheduler stopped"),V.exit(0)}getJobStatus(q){return this.jobs.get(q)}getAllJobs(){return Array.from(this.jobs.values())}scheduleJob(q){let C=this.timers.get(q.id);if(C)clearTimeout(C);let D=this.getNextRunTime(q.schedule.cron,q.schedule.timezone);if(q.nextRun=D||void 0,D){let G=D.getTime()-Date.now(),F=setTimeout(()=>{this.runJob(q),this.scheduleJob(q)},G);this.timers.set(q.id,F),this.logger.debug(`Job '${q.name}' scheduled for ${D.toISOString()}`)}}async runJob(q){if(q.status==="running"){this.logger.warn(`Job '${q.name}' is already running, skipping`);return}q.status="running",q.lastRun=new Date,this.logger.info(`\uD83D\uDE80 Running scheduled job: ${q.name}`);let C=Date.now(),D=q.schedule.maxRuntime||1800000;try{let G=new Promise((U,Q)=>{setTimeout(()=>Q(Error("Job timeout")),D)}),F=this.executeJob(q);await Promise.race([F,G]);let J=Date.now()-C;q.status="idle",this.logger.success(`\u2705 Job '${q.name}' completed in ${J}ms`)}catch(G){q.status="error",this.logger.error(`\u274C Job '${q.name}' failed:`,G)}}async executeJob(q){let C=new _(q.config),D=await C.scanForUpdates();if(D.updates.length===0){this.logger.info("No dependency updates found");return}if(this.logger.info(`Found ${D.updates.length} dependency updates`),q.config.repository&&q.config.pullRequest)await C.createPullRequests(D),this.logger.success(`Created pull requests for ${D.groups.length} update groups`);else this.logger.info("Repository not configured, skipping PR creation")}getNextRunTime(q,C){try{return this.parseCronExpression(q,C)}catch(D){return this.logger.error(`Invalid cron expression '${q}':`,D),null}}parseCronExpression(q,C){let D=q.trim().split(/\s+/);if(D.length!==5)throw Error("Cron expression must have 5 parts: minute hour day month dayOfWeek");let[G,F,J,U,Q]=D,K=new Date;if(C)this.logger.debug(`Using timezone: ${C}`);let N=new Date(K);N.setSeconds(0,0);let Y=this.parseCronField(F,0,23),Z=this.parseCronField(G,0,59);if(Y.length>0&&Z.length>0){if(N.setHours(Y[0],Z[0],0,0),N<=K)N.setDate(N.getDate()+1)}else N.setTime(K.getTime()+3600000);return N}parseCronField(q,C,D){if(q==="*")return Array.from({length:D-C+1},(F,J)=>C+J);if(q.includes(","))return q.split(",").map(Number).filter((F)=>F>=C&&F<=D);if(q.includes("-")){let[F,J]=q.split("-").map(Number);return Array.from({length:J-F+1},(U,Q)=>F+Q)}if(q.includes("/")){let[F,J]=q.split("/");return(F==="*"?Array.from({length:D-C+1},(Q,K)=>C+K):[Number(F)]).filter((Q,K)=>K%Number(J)===0)}let G=Number(q);return Number.isNaN(G)?[]:[G]}static createJobFromConfig(q,C="default"){let D={cron:q.schedule?.cron||"0 2 * * 1",timezone:q.schedule?.timezone,runOnStartup:!1,maxRuntime:1800000};return{id:C,name:`Buddy Dependency Updates (${C})`,schedule:D,status:"idle",config:q}}static PRESETS={DAILY:"0 2 * * *",WEEKLY:"0 2 * * 1",WEEKDAYS:"0 2 * * 1-5",TWICE_WEEKLY:"0 2 * * 1,4",MONTHLY:"0 2 1 * *",HOURLY:"0 * * * *",CUSTOM:(q,C,D="*")=>`${q} ${C} * * ${D}`}}export{$ as Scheduler}; export{$ as a}; //# debugId=2DC9C4AB3CC49D0064756E2164756E21