Skip to content

Commit 395b489

Browse files
authored
fix: treat ? (Quartz no-value) like * in toHuman (#9)
A ? field was rendered as a literal value, producing nonsense such as "on day ?" or "on undefined". ? means "no constraint on this field" (Quartz / AWS use it in day-of-month or day-of-week), so it is now normalized to *. "0 0 9 ? * MON" now reads as "at 9am on monday".
1 parent 2522f5d commit 395b489

2 files changed

Lines changed: 14 additions & 3 deletions

File tree

src/to-human.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,9 @@ export function toHuman(expression: string): string {
154154
if (parts.length !== 5 && parts.length !== 6) {
155155
throw new CronTranslateError(`Expected a 5- or 6-field cron expression, got ${parts.length} fields.`);
156156
}
157-
const [sec, min, hour, dom, monthRaw, dowRaw] = parts.length === 6
158-
? parts
159-
: ['0', ...parts];
157+
// `?` (Quartz "no specific value") means no constraint on the field, same as `*`.
158+
const fields = (parts.length === 6 ? parts : ['0', ...parts]).map((f) => (f === '?' ? '*' : f));
159+
const [sec, min, hour, dom, monthRaw, dowRaw] = fields;
160160
const month = mapNames(monthRaw, MONTH_NUMS);
161161
const dow = mapNames(dowRaw, DOW_NUMS);
162162

test/to-human.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ describe('toHuman — accepts month/weekday names in input', () => {
6969
});
7070
});
7171

72+
describe('toHuman — treats ? (Quartz no-value) like *', () => {
73+
const cases: [string, string][] = [
74+
['0 0 9 ? * MON', 'at 9am on monday'],
75+
['0 0 9 15 * ?', 'at 9am on day 15'],
76+
['0 0 0 ? * 1-5', 'on monday to friday'],
77+
];
78+
it.each(cases)('%s => %s', (cron, expected) => {
79+
expect(toHuman(cron)).toBe(expected);
80+
});
81+
});
82+
7283
describe('toHuman — rejects malformed input', () => {
7384
it.each(['', 'a b c', '1 2 3 4 5 6 7'])('rejects %j', (bad) => {
7485
expect(() => toHuman(bad)).toThrow();

0 commit comments

Comments
 (0)