@stacksjs/cron 0.70.23 → 0.70.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,62 +38,62 @@ Drivers are configured with the following environment variables:
38
38
  #### Twilio
39
39
 
40
40
  ```bash
41
- TWILIO_ACCOUNT_SID=ACtest
42
- TWILIO_AUTH_TOKEN=testtoken
43
- TWILIO_FROM_NUMBER=+112345
44
- TWILIO_TO_NUMBER=+145678
41
+ TWILIO*ACCOUNT*SID=ACtest
42
+ TWILIO*AUTH*TOKEN=testtoken
43
+ TWILIO*FROM*NUMBER=+112345
44
+ TWILIO*TO*NUMBER=+145678
45
45
  ```
46
46
 
47
47
  #### Nexmo
48
48
 
49
49
  ```bash
50
- VONAGE_API_KEY=VN123
51
- VONAGE_API_SECRET=testkey
52
- VONAGE_FROM_NUMBER=+112345
50
+ VONAGE*API*KEY=VN123
51
+ VONAGE*API*SECRET=testkey
52
+ VONAGE*FROM*NUMBER=+112345
53
53
  ```
54
54
 
55
55
  #### Gupshup
56
56
 
57
57
  ```bash
58
- GUPSHUP_USER_ID=GU123
59
- GUPSHUP_PASSWORD=password
58
+ GUPSHUP*USER*ID=GU123
59
+ GUPSHUP*PASSWORD=password
60
60
  ```
61
61
 
62
62
  #### Plivo
63
63
 
64
64
  ```bash
65
- PLIVO_ACCOUNT_ID=PA123
66
- PLIVO_AUTH_TOKEN=testtoken
67
- PLIVO_FROM_NUMBER=+112345
65
+ PLIVO*ACCOUNT*ID=PA123
66
+ PLIVO*AUTH*TOKEN=testtoken
67
+ PLIVO*FROM*NUMBER=+112345
68
68
  ```
69
69
 
70
70
  #### SMS77
71
71
 
72
72
  ```bash
73
- SMS77_API_KEY=SA123
74
- SMS77_FROM=from@example.com
73
+ SMS77*API*KEY=SA123
74
+ SMS77*FROM=from@example.com
75
75
  ```
76
76
 
77
77
  #### SNS
78
78
 
79
79
  ```bash
80
- SMS77_API_KEY=SA123
81
- SMS77_FROM=from@example.com
80
+ SMS77*API*KEY=SA123
81
+ SMS77*FROM=from@example.com
82
82
  ```
83
83
 
84
84
  #### Telnyx
85
85
 
86
86
  ```bash
87
- TELNYX_API_KEY=TA123
88
- TELNYX_MESSAGE_PROFILE_ID=testprofileid
89
- TELNYX_FROM=from@example.com
87
+ TELNYX*API*KEY=TA123
88
+ TELNYX*MESSAGE*PROFILE*ID=testprofileid
89
+ TELNYX*FROM=from@example.com
90
90
  ```
91
91
 
92
92
  #### Termii
93
93
 
94
94
  ```bash
95
- TERMII_API_KEY=TermA123
96
- TERMII_SENDER=from@example.com
95
+ TERMII*API*KEY=TermA123
96
+ TERMII*SENDER=from@example.com
97
97
  ```
98
98
 
99
99
  Learn more in the docs.
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- function l(t,e,i,r,s,n,o,a){return l.fromTZ(l.tp(t,e,i,r,s,n,o),a)}l.fromTZISO=(t,e,i)=>l.fromTZ(_(t,e),i);l.fromTZ=function(t,e){let i=new Date(Date.UTC(t.y,t.m-1,t.d,t.h,t.i,t.s)),r=T(t.tz,i),s=new Date(i.getTime()-r),n=T(t.tz,s);if(n-r===0)return s;{let o=new Date(i.getTime()-n),a=T(t.tz,o);if(a-n===0)return o;if(!e&&a-n>0)return o;if(e)throw new Error("Invalid date passed to fromTZ()");return s}};l.toTZ=function(t,e){let i=t.toLocaleString("en-US",{timeZone:e}).replace(/[\u202f]/," "),r=new Date(i);return{y:r.getFullYear(),m:r.getMonth()+1,d:r.getDate(),h:r.getHours(),i:r.getMinutes(),s:r.getSeconds(),tz:e}};l.tp=(t,e,i,r,s,n,o)=>({y:t,m:e,d:i,h:r,i:s,s:n,tz:o});function T(t,e=new Date){let i=e.toLocaleString("en-US",{timeZone:t,timeZoneName:"shortOffset"}).split(" ").slice(-1)[0],r=e.toLocaleString("en-US").replace(/[\u202f]/," ");return Date.parse(`${r} GMT`)-Date.parse(`${r} ${i}`)}function _(t,e){let i=new Date(Date.parse(t));if(isNaN(i))throw new Error("minitz: Invalid ISO8601 passed to parser.");let r=t.substring(9);return t.includes("Z")||r.includes("-")||r.includes("+")?l.tp(i.getUTCFullYear(),i.getUTCMonth()+1,i.getUTCDate(),i.getUTCHours(),i.getUTCMinutes(),i.getUTCSeconds(),"Etc/UTC"):l.tp(i.getFullYear(),i.getMonth()+1,i.getDate(),i.getHours(),i.getMinutes(),i.getSeconds(),e)}l.minitz=l;var v=32,m=31|v,x=[1,2,4,8,16],C=class{pattern;timezone;second;minute;hour;day;month;dayOfWeek;lastDayOfMonth;starDOM;starDOW;constructor(t,e){this.pattern=t,this.timezone=e,this.second=Array(60).fill(0),this.minute=Array(60).fill(0),this.hour=Array(24).fill(0),this.day=Array(31).fill(0),this.month=Array(12).fill(0),this.dayOfWeek=Array(7).fill(0),this.lastDayOfMonth=!1,this.starDOM=!1,this.starDOW=!1,this.parse()}parse(){if(!(typeof this.pattern=="string"||this.pattern instanceof String))throw new TypeError("CronPattern: Pattern has to be of type string.");this.pattern.indexOf("@")>=0&&(this.pattern=this.handleNicknames(this.pattern).trim());let t=this.pattern.replace(/\s+/g," ").split(" ");if(t.length<5||t.length>6)throw new TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exactly five or six space separated parts are required.");if(t.length===5&&t.unshift("0"),t[3].indexOf("L")>=0&&(t[3]=t[3].replace("L",""),this.lastDayOfMonth=!0),t[3]=="*"&&(this.starDOM=!0),t[4].length>=3&&(t[4]=this.replaceAlphaMonths(t[4])),t[5].length>=3&&(t[5]=this.replaceAlphaDays(t[5])),t[5]=="*"&&(this.starDOW=!0),this.pattern.indexOf("?")>=0){let e=new u(new Date,this.timezone).getDate(!0);t[0]=t[0].replace("?",e.getSeconds().toString()),t[1]=t[1].replace("?",e.getMinutes().toString()),t[2]=t[2].replace("?",e.getHours().toString()),this.starDOM||(t[3]=t[3].replace("?",e.getDate().toString())),t[4]=t[4].replace("?",(e.getMonth()+1).toString()),this.starDOW||(t[5]=t[5].replace("?",e.getDay().toString()))}this.throwAtIllegalCharacters(t),this.partToArray("second",t[0],0,1),this.partToArray("minute",t[1],0,1),this.partToArray("hour",t[2],0,1),this.partToArray("day",t[3],-1,1),this.partToArray("month",t[4],-1,1),this.partToArray("dayOfWeek",t[5],0,m),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(t,e,i,r){let s=this[t],n=t==="day"&&this.lastDayOfMonth;if(e===""&&!n)throw new TypeError("CronPattern: configuration entry "+t+" ("+e+") is empty, check for trailing spaces.");if(e==="*")return s.fill(r);let o=e.split(",");if(o.length>1)for(let a=0;a<o.length;a++)this.partToArray(t,o[a],i,r);else e.indexOf("-")!==-1&&e.indexOf("/")!==-1?this.handleRangeWithStepping(e,t,i,r):e.indexOf("-")!==-1?this.handleRange(e,t,i,r):e.indexOf("/")!==-1?this.handleStepping(e,t,i,r):e!==""&&this.handleNumber(e,t,i,r)}throwAtIllegalCharacters(t){for(let e=0;e<t.length;e++)if((e===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(t[e]))throw new TypeError("CronPattern: configuration entry "+e+" ("+t[e]+") contains illegal characters.")}handleNumber(t,e,i,r){let s=this.extractNth(t,e),n=parseInt(s[0],10)+i;if(isNaN(n))throw new TypeError("CronPattern: "+e+" is not a number: '"+t+"'");this.setPart(e,n,s[1]||r)}setPart(t,e,i){if(!Object.prototype.hasOwnProperty.call(this,t))throw new TypeError("CronPattern: Invalid part specified: "+t);if(t==="dayOfWeek"){if(e===7&&(e=0),e<0||e>6)throw new RangeError("CronPattern: Invalid value for dayOfWeek: "+e);this.setNthWeekdayOfMonth(e,i);return}if(t==="second"||t==="minute"){if(e<0||e>=60)throw new RangeError("CronPattern: Invalid value for "+t+": "+e)}else if(t==="hour"){if(e<0||e>=24)throw new RangeError("CronPattern: Invalid value for "+t+": "+e)}else if(t==="day"){if(e<0||e>=31)throw new RangeError("CronPattern: Invalid value for "+t+": "+e)}else if(t==="month"&&(e<0||e>=12))throw new RangeError("CronPattern: Invalid value for "+t+": "+e);this[t][e]=i}handleRangeWithStepping(t,e,i,r){let s=this.extractNth(t,e),n=s[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(n===null)throw new TypeError("CronPattern: Syntax error, illegal range with stepping: '"+t+"'");let[,o,a,h]=n,p=parseInt(o,10)+i,f=parseInt(a,10)+i,y=parseInt(h,10);if(isNaN(p))throw new TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(f))throw new TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(y))throw new TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(y===0)throw new TypeError("CronPattern: Syntax error, illegal stepping: 0");if(y>this[e].length)throw new TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[e].length+")");if(p>f)throw new TypeError("CronPattern: From value is larger than to value: '"+t+"'");for(let w=p;w<=f;w+=y)this.setPart(e,w,s[1]||r)}extractNth(t,e){let i=t,r;if(i.includes("#")){if(e!=="dayOfWeek")throw new Error("CronPattern: nth (#) only allowed in day-of-week field");r=i.split("#")[1],i=i.split("#")[0]}return[i,r]}handleRange(t,e,i,r){let s=this.extractNth(t,e),n=s[0].split("-");if(n.length!==2)throw new TypeError("CronPattern: Syntax error, illegal range: '"+t+"'");let o=parseInt(n[0],10)+i,a=parseInt(n[1],10)+i;if(isNaN(o))throw new TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(a))throw new TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(o>a)throw new TypeError("CronPattern: From value is larger than to value: '"+t+"'");for(let h=o;h<=a;h++)this.setPart(e,h,s[1]||r)}handleStepping(t,e,i,r){let s=this.extractNth(t,e),n=s[0].split("/");if(n.length!==2)throw new TypeError("CronPattern: Syntax error, illegal stepping: '"+t+"'");n[0]===""&&(n[0]="*");let o=0;n[0]!=="*"&&(o=parseInt(n[0],10)+i);let a=parseInt(n[1],10);if(isNaN(a))throw new TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(a===0)throw new TypeError("CronPattern: Syntax error, illegal stepping: 0");if(a>this[e].length)throw new TypeError("CronPattern: Syntax error, max steps for part is ("+this[e].length+")");for(let h=o;h<this[e].length;h+=a)this.setPart(e,h,s[1]||r)}replaceAlphaDays(t){return t.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(t){return t.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(t){let e=t.trim().toLowerCase();return e==="@yearly"||e==="@annually"?"0 0 1 1 *":e==="@monthly"?"0 0 1 * *":e==="@weekly"?"0 0 * * 0":e==="@daily"?"0 0 * * *":e==="@hourly"?"0 * * * *":t}setNthWeekdayOfMonth(t,e){if(typeof e!="number"&&e==="L")this.dayOfWeek[t]=this.dayOfWeek[t]|v;else if(e===m)this.dayOfWeek[t]=m;else if(e<6&&e>0)this.dayOfWeek[t]=this.dayOfWeek[t]|x[e-1];else throw new TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${e}, Type: ${typeof e}`)}},D=[31,28,31,30,31,30,31,31,30,31,30,31],c=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],u=class t{tz;ms;second;minute;hour;day;month;year;constructor(e,i){if(this.tz=i,e&&e instanceof Date)if(!isNaN(e))this.fromDate(e);else throw new TypeError("CronDate: Invalid date passed to CronDate constructor");else if(e===void 0)this.fromDate(new Date);else if(e&&typeof e=="string")this.fromString(e);else if(e instanceof t)this.fromCronDate(e);else throw new TypeError("CronDate: Invalid type ("+typeof e+") passed to CronDate constructor")}isNthWeekdayOfMonth(e,i,r,s){let n=new Date(Date.UTC(e,i,r)).getUTCDay(),o=0;for(let a=1;a<=r;a++)new Date(Date.UTC(e,i,a)).getUTCDay()===n&&o++;if(s&m&&x[o-1]&s)return!0;if(s&v){let a=new Date(Date.UTC(e,i+1,0)).getUTCDate();for(let h=r+1;h<=a;h++)if(new Date(Date.UTC(e,i,h)).getUTCDay()===n)return!1;return!0}return!1}fromDate(e){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=e.getUTCMilliseconds(),this.second=e.getUTCSeconds(),this.minute=e.getUTCMinutes()+this.tz,this.hour=e.getUTCHours(),this.day=e.getUTCDate(),this.month=e.getUTCMonth(),this.year=e.getUTCFullYear(),this.apply();else{let i=l.toTZ(e,this.tz);this.ms=e.getMilliseconds(),this.second=i.s,this.minute=i.i,this.hour=i.h,this.day=i.d,this.month=i.m-1,this.year=i.y}else this.ms=e.getMilliseconds(),this.second=e.getSeconds(),this.minute=e.getMinutes(),this.hour=e.getHours(),this.day=e.getDate(),this.month=e.getMonth(),this.year=e.getFullYear()}fromCronDate(e){this.tz=e.tz,this.year=e.year,this.month=e.month,this.day=e.day,this.hour=e.hour,this.minute=e.minute,this.second=e.second,this.ms=e.ms}apply(){if(this.month>11||this.day>D[this.month]||this.hour>59||this.minute>59||this.second>59||this.hour<0||this.minute<0||this.second<0){let e=new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms));return this.ms=e.getUTCMilliseconds(),this.second=e.getUTCSeconds(),this.minute=e.getUTCMinutes(),this.hour=e.getUTCHours(),this.day=e.getUTCDate(),this.month=e.getUTCMonth(),this.year=e.getUTCFullYear(),!0}else return!1}fromString(e){if(typeof this.tz=="number"){let i=l.fromTZISO(e);this.ms=i.getUTCMilliseconds(),this.second=i.getUTCSeconds(),this.minute=i.getUTCMinutes(),this.hour=i.getUTCHours(),this.day=i.getUTCDate(),this.month=i.getUTCMonth(),this.year=i.getUTCFullYear(),this.apply()}else return this.fromDate(l.fromTZISO(e,this.tz))}findNext(e,i,r,s){let n=this[i],o;r.lastDayOfMonth&&(this.month!==1?o=D[this.month]:o=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let a=!r.starDOW&&i=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let h=this[i]+s;h<r[i].length;h++){let p=r[i][h];if(i==="day"&&r.lastDayOfMonth&&h-s==o&&(p=1),i==="day"&&!r.starDOW){let f=r.dayOfWeek[(a+(h-s-1))%7];if(f&&f&m)f=this.isNthWeekdayOfMonth(this.year,this.month,h-s,f)?1:0;else if(f)throw new Error(`CronDate: Invalid value for dayOfWeek encountered. ${f}`);e.legacyMode&&!r.starDOM?p=p||f:p=p&&f}if(p)return this[i]=h-s,n!==this[i]?2:1}return 3}recurse(e,i,r){let s=this.findNext(i,c[r][0],e,c[r][2]);if(s>1){let n=r+1;for(;n<c.length;)this[c[n][0]]=-c[n][2],n++;if(s===3)return this[c[r][1]]++,this[c[r][0]]=-c[r][2],this.apply(),this.recurse(e,i,0);if(this.apply())return this.recurse(e,i,r-1)}return r+=1,r>=c.length?this:this.year>=3000?null:this.recurse(e,i,r)}increment(e,i,r){return this.second+=i.interval!==void 0&&i.interval>1&&r?i.interval:1,this.ms=0,this.apply(),this.recurse(e,i,0)}getDate(e){return e||this.tz===void 0?new Date(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms):typeof this.tz=="number"?new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute-this.tz,this.second,this.ms)):l.fromTZ(l.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function N(t){if(t===void 0&&(t={}),delete t.name,t.legacyMode=t.legacyMode===void 0?!0:t.legacyMode,t.paused=t.paused===void 0?!1:t.paused,t.maxRuns=t.maxRuns===void 0?1/0:t.maxRuns,t.catch=t.catch===void 0?!1:t.catch,t.interval=t.interval===void 0?0:parseInt(t.interval.toString(),10),t.utcOffset=t.utcOffset===void 0?void 0:parseInt(t.utcOffset.toString(),10),t.unref=t.unref===void 0?!1:t.unref,t.startAt&&(t.startAt=new u(t.startAt,t.timezone)),t.stopAt&&(t.stopAt=new u(t.stopAt,t.timezone)),t.interval!==null){if(isNaN(t.interval))throw new Error("CronOptions: Supplied value for interval is not a number");if(t.interval<0)throw new Error("CronOptions: Supplied value for interval can not be negative")}if(t.utcOffset!==void 0){if(isNaN(t.utcOffset))throw new Error("CronOptions: Invalid value passed for utcOffset, should be number representing minutes offset from UTC.");if(t.utcOffset<-870||t.utcOffset>870)throw new Error("CronOptions: utcOffset out of bounds.");if(t.utcOffset!==void 0&&t.timezone)throw new Error("CronOptions: Combining 'utcOffset' with 'timezone' is not allowed.")}if(t.unref!==!0&&t.unref!==!1)throw new Error("CronOptions: Unref should be either true, false or undefined(false).");return t}function g(t){return Object.prototype.toString.call(t)==="[object Function]"||typeof t=="function"||t instanceof Function}function S(t){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(t):t&&typeof t.unref<"u"&&t.unref()}var O=30000,d=[],M=class{name;options;_states;fn;constructor(t,e,i){let r,s;if(g(e))s=e;else if(typeof e=="object")r=e;else if(e!==void 0)throw new Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");if(g(i))s=i;else if(typeof i=="object")r=i;else if(i!==void 0)throw new Error("Cron: Invalid argument passed for funcIn. Should be one of function, or object (options).");if(this.name=r?.name,this.options=N(r),this._states={kill:!1,blocking:!1,previousRun:void 0,currentRun:void 0,once:void 0,currentTimeout:void 0,maxRuns:r?r.maxRuns:void 0,paused:r?r.paused:!1,pattern:new C("* * * * *")},t&&(t instanceof Date||typeof t=="string"&&t.indexOf(":")>0)?this._states.once=new u(t,this.options.timezone||this.options.utcOffset):this._states.pattern=new C(t,this.options.timezone),this.name){if(d.find((n)=>n.name===this.name))throw new Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");d.push(this)}return s!==void 0&&g(s)&&(this.fn=s,this.schedule()),this}nextRun(t){let e=this._next(t);return e?e.getDate(!1):null}nextRuns(t,e){this._states.maxRuns!==void 0&&t>this._states.maxRuns&&(t=this._states.maxRuns);let i=[],r=e||this._states.currentRun||void 0;for(;t--&&(r=this.nextRun(r));)i.push(r);return i}getPattern(){return this._states.pattern?this._states.pattern.pattern:void 0}isRunning(){let t=this.nextRun(this._states.currentRun),e=!this._states.paused,i=this.fn!==void 0,r=!this._states.kill;return e&&i&&r&&t!==null}isStopped(){return this._states.kill}isBusy(){return this._states.blocking}currentRun(){return this._states.currentRun?this._states.currentRun.getDate():null}previousRun(){return this._states.previousRun?this._states.previousRun.getDate():null}msToNext(t){t=t||new Date;let e=this._next(t);return e?t instanceof u||t instanceof Date?e.getTime()-t.getTime():e.getTime()-new u(t).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let t=d.indexOf(this);t>=0&&d.splice(t,1)}pause(){return this._states.paused=!0,!this._states.kill}resume(){return this._states.paused=!1,!this._states.kill}schedule(t){if(t&&this.fn)throw new Error("Cron: It is not allowed to schedule two functions using the same Croner instance.");t&&(this.fn=t);let e=this.msToNext(),i=this.nextRun(this._states.currentRun);return e==null||isNaN(e)||i===null?this:(e>O&&(e=O),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(i),e),this._states.currentTimeout&&this.options.unref&&S(this._states.currentTimeout),this)}async _trigger(t){if(this._states.blocking=!0,this._states.currentRun=new u(void 0,this.options.timezone||this.options.utcOffset),this.options.catch)try{this.fn!==void 0&&await this.fn(this,this.options.context)}catch(e){g(this.options.catch)&&this.options.catch(e,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new u(t,this.options.timezone||this.options.utcOffset),this._states.blocking=!1}async trigger(){await this._trigger()}runsLeft(){return this._states.maxRuns}_checkTrigger(t){let e=new Date,i=!this._states.paused&&e.getTime()>=t.getTime(),r=this._states.blocking&&this.options.protect;i&&!r?(this._states.maxRuns!==void 0&&this._states.maxRuns--,this._trigger()):i&&r&&g(this.options.protect)&&setTimeout(()=>this.options.protect(this),0),this.schedule()}_next(t){let e=!!(t||this._states.currentRun),i=!1;!t&&this.options.startAt&&this.options.interval&&([t,e]=this._calculatePreviousRun(t,e),i=!t),t=new u(t,this.options.timezone||this.options.utcOffset),this.options.startAt&&t&&t.getTime()<this.options.startAt.getTime()&&(t=this.options.startAt);let r=this._states.once||new u(t,this.options.timezone||this.options.utcOffset);return!i&&r!==this._states.once&&(r=r.increment(this._states.pattern,this.options,e)),this._states.once&&this._states.once.getTime()<=t.getTime()||r===null||this._states.maxRuns!==void 0&&this._states.maxRuns<=0||this._states.kill||this.options.stopAt&&r.getTime()>=this.options.stopAt.getTime()?null:r}_calculatePreviousRun(t,e){let i=new u(void 0,this.options.timezone||this.options.utcOffset),r=t;if(this.options.startAt.getTime()<=i.getTime()){r=this.options.startAt;let s=r.getTime()+this.options.interval*1000;for(;s<=i.getTime();)r=new u(r,this.options.timezone||this.options.utcOffset).increment(this._states.pattern,this.options,!0),s=r.getTime()+this.options.interval*1000;e=!0}return r===null&&(r=void 0),[r,e]}};export{d as scheduledJobs,C as CronPattern,u as CronDate,M as Cron};
2
+ var A={"@yearly":"0 0 1 1 *","@annually":"0 0 1 1 *","@monthly":"0 0 1 * *","@weekly":"0 0 * * 0","@daily":"0 0 * * *","@midnight":"0 0 * * *","@hourly":"0 * * * *"},S={jan:1,feb:2,mar:3,apr:4,may:5,jun:6,jul:7,aug:8,sep:9,oct:10,nov:11,dec:12,january:1,february:2,march:3,april:4,june:6,july:7,august:8,september:9,october:10,november:11,december:12},w={sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6,sunday:0,monday:1,tuesday:2,wednesday:3,thursday:4,friday:5,saturday:6};function N(P,C){return P.replace(/[a-z]+/gi,(q)=>{let J=C[q.toLowerCase()];if(J===void 0)throw Error(`Invalid cron value: ${q}`);return String(J)})}function Z(P,C,q,J){let R=J?N(P,J):P,L=new Set;for(let $ of R.split(",")){let Q=$.match(/^(.+)\/(\d+)$/),B,G=1;if(Q){if(B=Q[1]??"",G=Number.parseInt(Q[2]??"",10),G<=0)throw Error(`Invalid step: ${G}`)}else B=$;if(B==="*")for(let z=C;z<=q;z+=G)L.add(z);else if(B.includes("-")){let[z,H]=B.split("-"),U=Number.parseInt(z??"",10),V=Number.parseInt(H??"",10);if(Number.isNaN(U)||Number.isNaN(V))throw Error(`Invalid range: ${B}`);if(U<C||V>q)throw Error(`Range out of bounds: ${B} (${C}-${q})`);for(let I=U;I<=V;I+=G)L.add(I)}else{let z=Number.parseInt(B,10);if(Number.isNaN(z))throw Error(`Invalid cron value: ${B}`);if(z<C||z>q)throw Error(`Value out of range: ${z} (${C}-${q})`);L.add(z)}}return L}function Y(P,C){let q=P.trim(),R=(A[q.toLowerCase()]??q).split(/\s+/).filter(Boolean);if(R.length!==5)throw Error(`Invalid cron expression: expected 5 fields, got ${R.length}`);let[L,$,Q,B,G]=R,z=Z(L,0,59),H=Z($,0,23),U=Z(Q,1,31),V=Z(B,1,12,S),I=Z(G,0,7,w);if(I.has(7))I.add(0),I.delete(7);let _=Q==="*",j=G==="*",K=C instanceof Date?C.getTime():typeof C==="number"?C:Date.now();if(Number.isNaN(K)||!Number.isFinite(K))throw Error("Invalid date");let b=new Date(K);b.setUTCSeconds(0,0),b.setUTCMinutes(b.getUTCMinutes()+1);let T=b.getTime()+126230400000;while(b.getTime()<T){if(!V.has(b.getUTCMonth()+1)){b.setUTCMonth(b.getUTCMonth()+1,1),b.setUTCHours(0,0,0,0);continue}let k=U.has(b.getUTCDate()),E=I.has(b.getUTCDay()),X;if(_&&j)X=!0;else if(_)X=E;else if(j)X=k;else X=k||E;if(!X){b.setUTCDate(b.getUTCDate()+1),b.setUTCHours(0,0,0,0);continue}if(!H.has(b.getUTCHours())){b.setUTCHours(b.getUTCHours()+1,0,0,0);continue}if(!z.has(b.getUTCMinutes())){b.setUTCMinutes(b.getUTCMinutes()+1,0,0);continue}return new Date(b.getTime())}return null}function W(P,C){if(typeof Bun<"u"&&Bun.cron?.parse)return Bun.cron.parse(P,C);return Y(P,C)}async function g(P,C,q){if(typeof Bun>"u"||!Bun.cron)throw Error("Bun.cron is not available. OS-level cron requires a Bun version with native cron support.");await Bun.cron(P,C,q)}async function y(P){if(typeof Bun>"u"||!Bun.cron?.remove)throw Error("Bun.cron is not available. OS-level cron requires a Bun version with native cron support.");await Bun.cron.remove(P)}export{y as remove,g as register,Y as parseCron,W as parse};
@@ -0,0 +1,41 @@
1
+ /// <reference path="./bun-cron.d.ts" />
2
+ import { parseCron } from './parser';
3
+ // Parse a cron expression and return the next matching Date.
4
+ // Uses Bun's native cron parser when available, otherwise falls back
5
+ // to our own 5-field parser with identical behavior.
6
+ //
7
+ // Examples:
8
+ // parse('0 0 * * *') → next midnight UTC
9
+ // parse('@hourly') → next hour
10
+ // parse('0,15,30,45 * * * *') → next 15-min mark
11
+ export declare function parse(expression: string, relativeDate?: Date | number): Date | null;
12
+ /**
13
+ * Register an OS-level cron job that persists across process restarts.
14
+ *
15
+ * Requires Bun's native cron support (crontab on Linux, launchd on macOS,
16
+ * schtasks on Windows).
17
+ *
18
+ * The target script must export a `scheduled(controller)` handler:
19
+ * ```ts
20
+ * export default {
21
+ * async scheduled(controller) {
22
+ * // controller.cron, controller.scheduledTime
23
+ * await doWork()
24
+ * }
25
+ * }
26
+ * ```
27
+ *
28
+ * @param path - Path to the script to run
29
+ * @param schedule - Cron expression or nickname (@daily, @hourly, etc.)
30
+ * @param title - Unique job identifier (alphanumeric, hyphens, underscores)
31
+ */
32
+ export declare function register(path: string, schedule: string, title: string): Promise<void>;
33
+ /**
34
+ * Remove a previously registered OS-level cron job.
35
+ *
36
+ * @param title - The title of the cron job to remove
37
+ */
38
+ export declare function remove(title: string): Promise<void>;
39
+ /// <reference path="./bun-cron.d.ts" />
40
+ export * from './types';
41
+ export { parseCron } from './parser';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Parse a cron expression and return the next matching UTC Date.
3
+ *
4
+ * @param expression - A 5-field cron expression or nickname (@daily, etc.)
5
+ * @param relativeDate - Starting point for the search (defaults to Date.now())
6
+ * @returns The next Date matching the expression (UTC), or null if no match within ~4 years
7
+ */
8
+ export declare function parseCron(expression: string, relativeDate?: Date | number): Date | null;
@@ -0,0 +1,5 @@
1
+ export type CatchCallbackFn = (_error: Error) => void;
2
+ export type ProtectCallbackFn = () => void;
3
+ export type IntRange<Min extends number, Max extends number> = number extends Min | Max
4
+ ? never
5
+ : number | [Min | number, Max | number];
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "@stacksjs/cron",
3
3
  "type": "module",
4
- "version": "0.70.23",
4
+ "version": "0.70.26",
5
5
  "description": "The Stacks cron.",
6
6
  "author": "Chris Breuer",
7
- "contributors": ["Chris Breuer <chris@stacksjs.org>"],
7
+ "contributors": [
8
+ "Chris Breuer <chris@stacksjs.com>"
9
+ ],
8
10
  "license": "MIT",
9
11
  "funding": "https://github.com/sponsors/chrisbbreuer",
10
12
  "homepage": "https://github.com/stacksjs/stacks/tree/main/storage/framework/core/cron#readme",
@@ -16,25 +18,36 @@
16
18
  "bugs": {
17
19
  "url": "https://github.com/stacksjs/stacks/issues"
18
20
  },
19
- "keywords": ["cron", "croner", "jobs", "bun", "stacks"],
21
+ "keywords": [
22
+ "cron",
23
+ "bun-cron",
24
+ "jobs",
25
+ "bun",
26
+ "stacks"
27
+ ],
20
28
  "exports": {
21
29
  ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "bun": "./src/index.ts",
22
32
  "import": "./dist/index.js"
23
33
  },
24
34
  "./*": {
35
+ "bun": "./src/*",
25
36
  "import": "./dist/*"
26
37
  }
27
38
  },
28
39
  "module": "dist/index.js",
29
40
  "types": "dist/index.d.ts",
30
- "files": ["README.md", "dist"],
41
+ "files": [
42
+ "README.md",
43
+ "dist"
44
+ ],
31
45
  "scripts": {
32
46
  "build": "bun build.ts",
33
47
  "typecheck": "bun tsc --noEmit",
34
48
  "prepublishOnly": "bun run build"
35
49
  },
36
50
  "devDependencies": {
37
- "@stacksjs/development": "0.70.22",
38
- "croner": "^9.0.0"
51
+ "better-dx": "^0.2.12"
39
52
  }
40
53
  }
package/dist/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export { Cron, CronDate, CronPattern, scheduledJobs } from 'croner'
2
-
3
- export * from './types'
package/dist/types.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export type {
2
- export declare type IntRange<Min extends number, Max extends number> = number extends Min | Max
3
- ? never
4
- : number | [Min | number, Max | number]