Skip to content

Commit

Permalink
Option to disable last day of month in arrayToString
Browse files Browse the repository at this point in the history
  • Loading branch information
roccivic committed Sep 28, 2024
1 parent 34c1090 commit 2bddfdb
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 28 deletions.
16 changes: 9 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ import { units } from "./units.js";
export { Schedule } from "./schedule.js";
export { Unit, Options } from "./types.js";

const defaultParseOptions: ParseOptions = {
enableLastDayOfMonth: true,
};

const defaultOptions: Options = {
...defaultParseOptions,
outputHashes: false,
outputMonthNames: false,
outputWeekdayNames: false,
};


const defaultParseOptions: ParseOptions = {
enableLastDayOfMonth: true
};

/**
* Parses a cron string
*
Expand All @@ -32,9 +32,11 @@ export function stringToArray(str: string, options?: Partial<ParseOptions>) {
if (parts.length !== 5) {
throw new Error("Invalid cron string format");
} else {
return parts.map((str, idx) => stringToArrayPart(str, units[idx], { ...defaultParseOptions, ...options }));
return parts.map((str, idx) =>
stringToArrayPart(str, units[idx], { ...defaultParseOptions, ...options })
);
}
};
}

/**
* Parses a 2-dimentional array of integers and serializes it to a string
Expand Down
32 changes: 21 additions & 11 deletions src/part.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const arrayToStringPart = (
dedup(
fixSunday(
arr.map((value) => {
const parsedValue = parseNumber(unit, value, {enableLastDayOfMonth: false});
const parsedValue = parseNumber(unit, value, options);
if (parsedValue === undefined) {
throw getError(`Invalid value "${value}"`, unit);
}
Expand All @@ -31,7 +31,7 @@ export const arrayToStringPart = (
if (!values.length) {
throw getError("Empty interval value", unit);
}
assertInRange(values, unit);
assertInRange(values, unit, options);
return toString(values, unit, options);
};

Expand All @@ -40,10 +40,14 @@ export const arrayToStringPart = (
*
* @param str The part of a cron string to convert
* @param unit The unit for the part
* @param options Parse options
* @param options The parse options
* @return An array of numbers
*/
export const stringToArrayPart = (str: string, unit: Unit, options: ParseOptions) => {
export const stringToArrayPart = (
str: string,
unit: Unit,
options: ParseOptions
) => {
const values = sort(
dedup(
fixSunday(
Expand Down Expand Up @@ -71,7 +75,7 @@ export const stringToArrayPart = (str: string, unit: Unit, options: ParseOptions
)
)
);
assertInRange(values, unit);
assertInRange(values, unit, options);
return values;
};

Expand Down Expand Up @@ -105,7 +109,7 @@ const toRanges = (values: number[]) => {
*
* @param values An array of numbers
* @param unit The unit for the part
* @param options The formatting options to use
* @param options The options to use
* @return The part of a cron string
*/
const toString = (values: number[], unit: Unit, options: Options) => {
Expand All @@ -116,8 +120,8 @@ const toString = (values: number[], unit: Unit, options: Options) => {
} else {
retval = "*";
}
} else if (unit.name === 'day' && values.length === 1 && values[0] === -1) {
retval = 'L';
} else if (unit.name === "day" && values.length === 1 && values[0] === -1) {
retval = "L";
} else {
const step = getStep(values);
if (step && isInterval(values, step)) {
Expand Down Expand Up @@ -199,7 +203,12 @@ const getError = (error: string, unit: Unit) =>
* @param options Parse options
* @return The resulting array
*/
const parseRange = (rangeString: string, context: string, unit: Unit, options: ParseOptions) => {
const parseRange = (
rangeString: string,
context: string,
unit: Unit,
options: ParseOptions
) => {
const subparts = rangeString.split("-");
if (subparts.length === 1) {
const value = parseNumber(unit, subparts[0], options);
Expand Down Expand Up @@ -302,11 +311,12 @@ const replaceAlternatives = (str: string, unit: Unit) => {
*
* @param values The values to test
* @param unit The unit for the part
* @param options The parse options
*/
const assertInRange = (values: number[], unit: Unit) => {
const assertInRange = (values: number[], unit: Unit, options: ParseOptions) => {
let first = values[0];
let last = values[values.length - 1];
if (unit.name === 'day' && first === -1 && last === -1) {
if (options.enableLastDayOfMonth && unit.name === "day" && first === -1 && last === -1) {
first = Math.abs(first);
last = Math.abs(last);
}
Expand Down
14 changes: 7 additions & 7 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ export type Unit = {
min: number;
max: number;
alt?: ReadonlyArray<string>;
}
};

export type Options = {
export type ParseOptions = {
enableLastDayOfMonth: boolean;
};

export type Options = ParseOptions & {
outputHashes: boolean;
outputWeekdayNames: boolean;
outputMonthNames: boolean;
}

export type ParseOptions = {
enableLastDayOfMonth: boolean;
}
};
19 changes: 17 additions & 2 deletions test/cron.invalid.array.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { expect } from "chai";
import { arrayToString } from "../src/index.js";

const invalidCron = [
type Test = {
array: number[][];
error: string;
enableLastDayOfMonth?: boolean;
};

const invalidCron: Test[] = [
{
array: [],
error: "Invalid cron array",
Expand Down Expand Up @@ -38,12 +44,21 @@ const invalidCron = [
array: [[1], [1], [-2], [1], [1]],
error: 'Value "-2" out of range for day',
},
{
array: [[1], [1], [-1], [1], [1]],
error: 'Value "-1" out of range for day',
enableLastDayOfMonth: false,
},
];

describe("Should throw on invalid cron array", function () {
invalidCron.forEach(function (invalid) {
it(invalid.array.toString(), function () {
expect(() => arrayToString(invalid.array)).to.throw(invalid.error);
expect(() =>
arrayToString(invalid.array, {
enableLastDayOfMonth: invalid.enableLastDayOfMonth,
})
).to.throw(invalid.error);
});
});
});
8 changes: 7 additions & 1 deletion test/cron.invalid.string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,18 @@ const invalidCron = [
string: "5/ * * * *",
error: 'Invalid interval step value "" for minute',
},
{
string: "* * L * *",
error: 'Invalid value "L" for day',
},
];

describe("Should throw on invalid cron string", function () {
invalidCron.forEach(function (invalid) {
it(`${invalid.string}`, function () {
expect(() => stringToArray(invalid.string)).to.throw(invalid.error);
expect(() =>
stringToArray(invalid.string, { enableLastDayOfMonth: false })
).to.throw(invalid.error);
});
});
});
1 change: 1 addition & 0 deletions test/range.valid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ describe("Should parse valid string", function () {
it(validRange.input + " as string", function () {
expect(
arrayToStringPart(range, validRange.unit, {
enableLastDayOfMonth: true,
outputHashes: false,
outputMonthNames: false,
outputWeekdayNames: false,
Expand Down

0 comments on commit 2bddfdb

Please sign in to comment.