cronli5 0.7.2 → 0.8.2

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/dist/cronli5.js CHANGED
@@ -26,10 +26,10 @@ var fieldSpecs = {
26
26
  second: { cyclic: true, max: 59, min: 0, top: 59 },
27
27
  minute: { cyclic: true, max: 59, min: 0, top: 59 },
28
28
  hour: { cyclic: true, max: 23, min: 0, top: 23 },
29
- date: { aliases: { "?": "*" }, cyclic: true, max: 31, min: 1, top: 31 },
29
+ date: { cyclic: true, max: 31, min: 1, top: 31 },
30
30
  month: { cyclic: true, max: 12, min: 1, numbers: monthNumbers, top: 12 },
31
31
  weekday: {
32
- aliases: { "?": "*", L: "6" },
32
+ aliases: { L: "6" },
33
33
  cyclic: true,
34
34
  max: 7,
35
35
  min: 0,
@@ -326,6 +326,53 @@ function firstFire(segment, spec) {
326
326
  return start === "*" ? spec.min : toFieldNumber(start, spec.numbers);
327
327
  }
328
328
 
329
+ // src/core/quartz.ts
330
+ var quartzTokenMessage = "`?` is a Quartz token \u2014 pass { quartz: true } to enable Quartz semantics.";
331
+ function applyQuartz(cronPattern, quartz) {
332
+ if (!quartz) {
333
+ rejectQuartzToken(cronPattern.date);
334
+ rejectQuartzToken(cronPattern.weekday);
335
+ return;
336
+ }
337
+ if ("" + cronPattern.date === "?") {
338
+ cronPattern.date = "*";
339
+ }
340
+ if ("" + cronPattern.weekday === "?") {
341
+ cronPattern.weekday = "*";
342
+ return;
343
+ }
344
+ cronPattern.weekday = reindexWeekday("" + cronPattern.weekday);
345
+ }
346
+ function rejectQuartzToken(value) {
347
+ if ("" + value === "?") {
348
+ throw new Error(quartzTokenMessage);
349
+ }
350
+ }
351
+ function reindexWeekday(value) {
352
+ if (value === "*") {
353
+ return value;
354
+ }
355
+ return value.split(",").map(reindexSegment).join(",");
356
+ }
357
+ function reindexSegment(segment) {
358
+ const operator = /(#\d+|L)$/.exec(segment);
359
+ const suffix = operator ? operator[0] : "";
360
+ const core = suffix ? segment.slice(0, -suffix.length) : segment;
361
+ const step = core.split("/");
362
+ const range = step[0].split("-").map(reindexNumber).join("-");
363
+ const head = step.length === 2 ? range + "/" + step[1] : range;
364
+ return head + suffix;
365
+ }
366
+ function reindexNumber(token) {
367
+ if (!isNonNegativeInteger(token)) {
368
+ return token;
369
+ }
370
+ if (token === "0") {
371
+ throw new Error('`cronli5` was passed an invalid Quartz day-of-week value "0"; Quartz numbers weekdays 1 (Sunday) through 7 (Saturday).');
372
+ }
373
+ return "" + (+token - 1);
374
+ }
375
+
329
376
  // src/core/parse.ts
330
377
  function parseCronPattern(cronPattern, opts) {
331
378
  const isArray = cronPattern instanceof Array;
@@ -866,6 +913,7 @@ function hourTimesPlan(hourField) {
866
913
  // src/core/index.ts
867
914
  function prepare(cronPattern, opts) {
868
915
  const pattern = parseCronPattern(cronPattern, opts);
916
+ applyQuartz(pattern, opts.quartz);
869
917
  applyQuartzAliases(pattern);
870
918
  validateCronPattern(pattern);
871
919
  return normalizeCronPattern(pattern);
@@ -994,6 +1042,7 @@ function normalizeOptions(options) {
994
1042
  return {
995
1043
  ampm: typeof options.ampm === "boolean" ? options.ampm : true,
996
1044
  lenient: !!options.lenient,
1045
+ quartz: !!options.quartz,
997
1046
  seconds: !!options.seconds,
998
1047
  short: !!options.short,
999
1048
  style: resolveDialect(options.dialect),
@@ -1211,7 +1260,8 @@ function renderMinuteFrequency(schedule, plan, opts) {
1211
1260
  to: plan.hours.to
1212
1261
  }, opts);
1213
1262
  } else if (plan.hours.kind === "step") {
1214
- phrase += " " + everyNthHour(stepSegment(schedule, "hour"), opts);
1263
+ const bound = withoutHourAnchor(phrase);
1264
+ phrase = bound + (bound === phrase ? " " : ", ") + everyNthHour(stepSegment(schedule, "hour"), opts);
1215
1265
  }
1216
1266
  return phrase + trailingQualifier(schedule, opts);
1217
1267
  }
@@ -1274,7 +1324,7 @@ function renderMinuteSpanAcrossHourStep(schedule, plan, opts) {
1274
1324
  if (plan.form === "wildcard") {
1275
1325
  return "every minute " + everyNthHour(segment, opts) + trailingQualifier(schedule, opts);
1276
1326
  }
1277
- const lead = plan.form === "list" ? strideFromSegments(
1327
+ const lead = withoutHourAnchor(plan.form === "list" ? strideFromSegments(
1278
1328
  segmentsOf(schedule, "minute"),
1279
1329
  "minute",
1280
1330
  "hour",
@@ -1284,7 +1334,7 @@ function renderMinuteSpanAcrossHourStep(schedule, plan, opts) {
1284
1334
  "minute",
1285
1335
  "hour",
1286
1336
  opts
1287
- ) : minuteRangeLead(schedule.pattern.minute, opts);
1337
+ ) : minuteRangeLead(schedule.pattern.minute, opts));
1288
1338
  const cadence = unevenHourCadence(schedule, opts);
1289
1339
  return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(schedule, opts);
1290
1340
  }
@@ -1403,7 +1453,7 @@ function renderCompactClockTimes(schedule, plan, opts) {
1403
1453
  )
1404
1454
  );
1405
1455
  const cadence = unevenHourCadence(schedule, opts);
1406
- const phrase = cadence ? minuteLead + ", " + cadence + trailingQualifier(schedule, opts) : minuteLead + ", at " + hourSegmentTimes(schedule, { minute: 0, second: null }, true, opts) + trailingQualifier(schedule, opts);
1456
+ const phrase = cadence ? withoutHourAnchor(minuteLead) + ", " + cadence + trailingQualifier(schedule, opts) : minuteLead + ", at " + hourSegmentTimes(schedule, { minute: 0, second: null }, true, opts) + trailingQualifier(schedule, opts);
1407
1457
  return schedule.analyses.clockSecond ? secondsLeadClause(schedule, opts) + ", " + phrase : phrase;
1408
1458
  }
1409
1459
  function foldedHourWindows(schedule, plan, opts) {
@@ -1777,6 +1827,9 @@ function segmentWords(segments, opts) {
1777
1827
  function listPastThe(words, unit, anchor, opts) {
1778
1828
  return "at " + joinList(words, opts) + " " + unit + "s past the " + anchor;
1779
1829
  }
1830
+ function withoutHourAnchor(lead) {
1831
+ return lead.replace(/ past the hour$/, "");
1832
+ }
1780
1833
  function wordTime(hour, minute, second) {
1781
1834
  return (+hour === 0 || +hour === 12) && +minute === 0 && !(typeof second === "number" && second > 0);
1782
1835
  }
@@ -2296,7 +2349,14 @@ function interpretCronPattern(cronPattern, lang, opts) {
2296
2349
  const plan = lang.plan ? lang.plan(schedule, schedule.plan) : schedule.plan;
2297
2350
  return lang.describe({ ...schedule, plan }, opts);
2298
2351
  }
2299
- var cronli5_default = cronli5;
2352
+ function sentence(cronPattern, options) {
2353
+ return cronli5(cronPattern, { ...options, sentence: true });
2354
+ }
2355
+ function fragment(cronPattern, options) {
2356
+ return cronli5(cronPattern, { ...options, sentence: false });
2357
+ }
2358
+ var callable = Object.assign(cronli5, { sentence, fragment });
2359
+ var cronli5_default = callable;
2300
2360
  export {
2301
2361
  cronli5_default as default
2302
2362
  };
package/dist/lang/de.cjs CHANGED
@@ -563,7 +563,7 @@ function renderComposeSeconds(schedule, plan, opts) {
563
563
  return cadence;
564
564
  }
565
565
  }
566
- if (composeMinuteZero(schedule, plan)) {
566
+ if (composeSingleMinute(schedule, plan)) {
567
567
  return secondsLead(schedule) + " " + clockMinuteGenitive(plan.rest.times, opts.style.sep);
568
568
  }
569
569
  if (isEveryOtherMinuteSeconds(schedule, plan)) {
@@ -573,8 +573,8 @@ function renderComposeSeconds(schedule, plan, opts) {
573
573
  const lead = restOwnsLead ? "" : secondsLead(schedule) + ", ";
574
574
  return lead + render(schedule, plan.rest, opts);
575
575
  }
576
- function composeMinuteZero(schedule, plan) {
577
- return plan.rest.kind === "clockTimes" && plan.rest.times.every((time) => +time.minute === 0);
576
+ function composeSingleMinute(schedule, plan) {
577
+ return plan.rest.kind === "clockTimes" && schedule.shapes.minute === "single";
578
578
  }
579
579
  function clockMinuteGenitive(times, sep) {
580
580
  const clocks = times.map(function clock(time) {
@@ -645,10 +645,10 @@ function renderMinuteFrequency(schedule, plan, opts) {
645
645
  const base = stepClause(segment, UNITS.minute, "jeder Stunde");
646
646
  if (plan.hours.kind === "during") {
647
647
  const cadence = unevenHourCadence(schedule);
648
- return cadence ? base + ", " + cadence : base + " " + duringHours(schedule, plan.hours.times, sep);
648
+ return cadence ? stepClause(segment, UNITS.minute, "") + ", " + cadence : base + " " + duringHours(schedule, plan.hours.times, sep);
649
649
  }
650
650
  if (plan.hours.kind === "step") {
651
- return base + " " + everyNthHour(stepSegment(schedule, "hour"));
651
+ return stepClause(segment, UNITS.minute, "") + " " + everyNthHour(stepSegment(schedule, "hour"));
652
652
  }
653
653
  return base;
654
654
  }
@@ -859,16 +859,16 @@ function qualifier(schedule, months2) {
859
859
  }
860
860
  var LEADING_PLANS = /* @__PURE__ */ new Set(["clockTimes"]);
861
861
  function leadsQualifier(schedule) {
862
- return LEADING_PLANS.has(schedule.plan.kind) || isComposeMinuteZero(schedule);
862
+ return LEADING_PLANS.has(schedule.plan.kind) || isComposeSingleMinute(schedule);
863
863
  }
864
- function isComposeMinuteZero(schedule) {
865
- return schedule.plan.kind === "composeSeconds" && composeMinuteZero(schedule, schedule.plan);
864
+ function isComposeSingleMinute(schedule) {
865
+ return schedule.plan.kind === "composeSeconds" && composeSingleMinute(schedule, schedule.plan);
866
866
  }
867
867
  function needsDailyFrame(schedule) {
868
868
  if (hourCadenceApplies(schedule)) {
869
869
  return false;
870
870
  }
871
- if (schedule.plan.kind === "clockTimes" || isComposeMinuteZero(schedule)) {
871
+ if (schedule.plan.kind === "clockTimes" || isComposeSingleMinute(schedule)) {
872
872
  return true;
873
873
  }
874
874
  if (schedule.plan.kind !== "hourStep") {
@@ -890,6 +890,7 @@ function normalizeOptions(options) {
890
890
  return {
891
891
  ampm: typeof options.ampm === "boolean" ? options.ampm : false,
892
892
  lenient: !!options.lenient,
893
+ quartz: !!options.quartz,
893
894
  seconds: !!options.seconds,
894
895
  short: !!options.short,
895
896
  style,
package/dist/lang/de.js CHANGED
@@ -537,7 +537,7 @@ function renderComposeSeconds(schedule, plan, opts) {
537
537
  return cadence;
538
538
  }
539
539
  }
540
- if (composeMinuteZero(schedule, plan)) {
540
+ if (composeSingleMinute(schedule, plan)) {
541
541
  return secondsLead(schedule) + " " + clockMinuteGenitive(plan.rest.times, opts.style.sep);
542
542
  }
543
543
  if (isEveryOtherMinuteSeconds(schedule, plan)) {
@@ -547,8 +547,8 @@ function renderComposeSeconds(schedule, plan, opts) {
547
547
  const lead = restOwnsLead ? "" : secondsLead(schedule) + ", ";
548
548
  return lead + render(schedule, plan.rest, opts);
549
549
  }
550
- function composeMinuteZero(schedule, plan) {
551
- return plan.rest.kind === "clockTimes" && plan.rest.times.every((time) => +time.minute === 0);
550
+ function composeSingleMinute(schedule, plan) {
551
+ return plan.rest.kind === "clockTimes" && schedule.shapes.minute === "single";
552
552
  }
553
553
  function clockMinuteGenitive(times, sep) {
554
554
  const clocks = times.map(function clock(time) {
@@ -619,10 +619,10 @@ function renderMinuteFrequency(schedule, plan, opts) {
619
619
  const base = stepClause(segment, UNITS.minute, "jeder Stunde");
620
620
  if (plan.hours.kind === "during") {
621
621
  const cadence = unevenHourCadence(schedule);
622
- return cadence ? base + ", " + cadence : base + " " + duringHours(schedule, plan.hours.times, sep);
622
+ return cadence ? stepClause(segment, UNITS.minute, "") + ", " + cadence : base + " " + duringHours(schedule, plan.hours.times, sep);
623
623
  }
624
624
  if (plan.hours.kind === "step") {
625
- return base + " " + everyNthHour(stepSegment(schedule, "hour"));
625
+ return stepClause(segment, UNITS.minute, "") + " " + everyNthHour(stepSegment(schedule, "hour"));
626
626
  }
627
627
  return base;
628
628
  }
@@ -833,16 +833,16 @@ function qualifier(schedule, months2) {
833
833
  }
834
834
  var LEADING_PLANS = /* @__PURE__ */ new Set(["clockTimes"]);
835
835
  function leadsQualifier(schedule) {
836
- return LEADING_PLANS.has(schedule.plan.kind) || isComposeMinuteZero(schedule);
836
+ return LEADING_PLANS.has(schedule.plan.kind) || isComposeSingleMinute(schedule);
837
837
  }
838
- function isComposeMinuteZero(schedule) {
839
- return schedule.plan.kind === "composeSeconds" && composeMinuteZero(schedule, schedule.plan);
838
+ function isComposeSingleMinute(schedule) {
839
+ return schedule.plan.kind === "composeSeconds" && composeSingleMinute(schedule, schedule.plan);
840
840
  }
841
841
  function needsDailyFrame(schedule) {
842
842
  if (hourCadenceApplies(schedule)) {
843
843
  return false;
844
844
  }
845
- if (schedule.plan.kind === "clockTimes" || isComposeMinuteZero(schedule)) {
845
+ if (schedule.plan.kind === "clockTimes" || isComposeSingleMinute(schedule)) {
846
846
  return true;
847
847
  }
848
848
  if (schedule.plan.kind !== "hourStep") {
@@ -864,6 +864,7 @@ function normalizeOptions(options) {
864
864
  return {
865
865
  ampm: typeof options.ampm === "boolean" ? options.ampm : false,
866
866
  lenient: !!options.lenient,
867
+ quartz: !!options.quartz,
867
868
  seconds: !!options.seconds,
868
869
  short: !!options.short,
869
870
  style,
package/dist/lang/en.cjs CHANGED
@@ -249,6 +249,7 @@ function normalizeOptions(options) {
249
249
  return {
250
250
  ampm: typeof options.ampm === "boolean" ? options.ampm : true,
251
251
  lenient: !!options.lenient,
252
+ quartz: !!options.quartz,
252
253
  seconds: !!options.seconds,
253
254
  short: !!options.short,
254
255
  style: resolveDialect(options.dialect),
@@ -466,7 +467,8 @@ function renderMinuteFrequency(schedule, plan, opts) {
466
467
  to: plan.hours.to
467
468
  }, opts);
468
469
  } else if (plan.hours.kind === "step") {
469
- phrase += " " + everyNthHour(stepSegment(schedule, "hour"), opts);
470
+ const bound = withoutHourAnchor(phrase);
471
+ phrase = bound + (bound === phrase ? " " : ", ") + everyNthHour(stepSegment(schedule, "hour"), opts);
470
472
  }
471
473
  return phrase + trailingQualifier(schedule, opts);
472
474
  }
@@ -529,7 +531,7 @@ function renderMinuteSpanAcrossHourStep(schedule, plan, opts) {
529
531
  if (plan.form === "wildcard") {
530
532
  return "every minute " + everyNthHour(segment, opts) + trailingQualifier(schedule, opts);
531
533
  }
532
- const lead = plan.form === "list" ? strideFromSegments(
534
+ const lead = withoutHourAnchor(plan.form === "list" ? strideFromSegments(
533
535
  segmentsOf(schedule, "minute"),
534
536
  "minute",
535
537
  "hour",
@@ -539,7 +541,7 @@ function renderMinuteSpanAcrossHourStep(schedule, plan, opts) {
539
541
  "minute",
540
542
  "hour",
541
543
  opts
542
- ) : minuteRangeLead(schedule.pattern.minute, opts);
544
+ ) : minuteRangeLead(schedule.pattern.minute, opts));
543
545
  const cadence = unevenHourCadence(schedule, opts);
544
546
  return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(schedule, opts);
545
547
  }
@@ -658,7 +660,7 @@ function renderCompactClockTimes(schedule, plan, opts) {
658
660
  )
659
661
  );
660
662
  const cadence = unevenHourCadence(schedule, opts);
661
- const phrase = cadence ? minuteLead + ", " + cadence + trailingQualifier(schedule, opts) : minuteLead + ", at " + hourSegmentTimes(schedule, { minute: 0, second: null }, true, opts) + trailingQualifier(schedule, opts);
663
+ const phrase = cadence ? withoutHourAnchor(minuteLead) + ", " + cadence + trailingQualifier(schedule, opts) : minuteLead + ", at " + hourSegmentTimes(schedule, { minute: 0, second: null }, true, opts) + trailingQualifier(schedule, opts);
662
664
  return schedule.analyses.clockSecond ? secondsLeadClause(schedule, opts) + ", " + phrase : phrase;
663
665
  }
664
666
  function foldedHourWindows(schedule, plan, opts) {
@@ -1032,6 +1034,9 @@ function segmentWords(segments, opts) {
1032
1034
  function listPastThe(words, unit, anchor, opts) {
1033
1035
  return "at " + joinList(words, opts) + " " + unit + "s past the " + anchor;
1034
1036
  }
1037
+ function withoutHourAnchor(lead) {
1038
+ return lead.replace(/ past the hour$/, "");
1039
+ }
1035
1040
  function wordTime(hour, minute, second) {
1036
1041
  return (+hour === 0 || +hour === 12) && +minute === 0 && !(typeof second === "number" && second > 0);
1037
1042
  }
package/dist/lang/en.js CHANGED
@@ -223,6 +223,7 @@ function normalizeOptions(options) {
223
223
  return {
224
224
  ampm: typeof options.ampm === "boolean" ? options.ampm : true,
225
225
  lenient: !!options.lenient,
226
+ quartz: !!options.quartz,
226
227
  seconds: !!options.seconds,
227
228
  short: !!options.short,
228
229
  style: resolveDialect(options.dialect),
@@ -440,7 +441,8 @@ function renderMinuteFrequency(schedule, plan, opts) {
440
441
  to: plan.hours.to
441
442
  }, opts);
442
443
  } else if (plan.hours.kind === "step") {
443
- phrase += " " + everyNthHour(stepSegment(schedule, "hour"), opts);
444
+ const bound = withoutHourAnchor(phrase);
445
+ phrase = bound + (bound === phrase ? " " : ", ") + everyNthHour(stepSegment(schedule, "hour"), opts);
444
446
  }
445
447
  return phrase + trailingQualifier(schedule, opts);
446
448
  }
@@ -503,7 +505,7 @@ function renderMinuteSpanAcrossHourStep(schedule, plan, opts) {
503
505
  if (plan.form === "wildcard") {
504
506
  return "every minute " + everyNthHour(segment, opts) + trailingQualifier(schedule, opts);
505
507
  }
506
- const lead = plan.form === "list" ? strideFromSegments(
508
+ const lead = withoutHourAnchor(plan.form === "list" ? strideFromSegments(
507
509
  segmentsOf(schedule, "minute"),
508
510
  "minute",
509
511
  "hour",
@@ -513,7 +515,7 @@ function renderMinuteSpanAcrossHourStep(schedule, plan, opts) {
513
515
  "minute",
514
516
  "hour",
515
517
  opts
516
- ) : minuteRangeLead(schedule.pattern.minute, opts);
518
+ ) : minuteRangeLead(schedule.pattern.minute, opts));
517
519
  const cadence = unevenHourCadence(schedule, opts);
518
520
  return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(schedule, opts);
519
521
  }
@@ -632,7 +634,7 @@ function renderCompactClockTimes(schedule, plan, opts) {
632
634
  )
633
635
  );
634
636
  const cadence = unevenHourCadence(schedule, opts);
635
- const phrase = cadence ? minuteLead + ", " + cadence + trailingQualifier(schedule, opts) : minuteLead + ", at " + hourSegmentTimes(schedule, { minute: 0, second: null }, true, opts) + trailingQualifier(schedule, opts);
637
+ const phrase = cadence ? withoutHourAnchor(minuteLead) + ", " + cadence + trailingQualifier(schedule, opts) : minuteLead + ", at " + hourSegmentTimes(schedule, { minute: 0, second: null }, true, opts) + trailingQualifier(schedule, opts);
636
638
  return schedule.analyses.clockSecond ? secondsLeadClause(schedule, opts) + ", " + phrase : phrase;
637
639
  }
638
640
  function foldedHourWindows(schedule, plan, opts) {
@@ -1006,6 +1008,9 @@ function segmentWords(segments, opts) {
1006
1008
  function listPastThe(words, unit, anchor, opts) {
1007
1009
  return "at " + joinList(words, opts) + " " + unit + "s past the " + anchor;
1008
1010
  }
1011
+ function withoutHourAnchor(lead) {
1012
+ return lead.replace(/ past the hour$/, "");
1013
+ }
1009
1014
  function wordTime(hour, minute, second) {
1010
1015
  return (+hour === 0 || +hour === 12) && +minute === 0 && !(typeof second === "number" && second > 0);
1011
1016
  }
package/dist/lang/es.cjs CHANGED
@@ -231,6 +231,7 @@ function normalizeOptions(options) {
231
231
  // 12-hour for Mexico/US); an explicit `{ampm}` option overrides it.
232
232
  ampm: typeof options.ampm === "boolean" ? options.ampm : style.ampm,
233
233
  lenient: !!options.lenient,
234
+ quartz: !!options.quartz,
234
235
  seconds: !!options.seconds,
235
236
  short: !!options.short,
236
237
  style,
@@ -377,6 +378,9 @@ function minutesList(schedule, opts) {
377
378
  opts
378
379
  ) ?? "en los minutos " + joinList(segmentWords(segmentsOf(schedule, "minute"))) + " de cada hora";
379
380
  }
381
+ function withoutHourAnchor(lead) {
382
+ return lead.replace(/ de cada hora$/, "");
383
+ }
380
384
  function minuteRangeLead(minuteField) {
381
385
  const bounds = minuteField.split("-");
382
386
  return "cada minuto del " + bounds[0] + " al " + bounds[1];
@@ -447,7 +451,7 @@ function renderMinuteFrequency(schedule, plan, opts) {
447
451
  } else if (plan.hours.kind === "window") {
448
452
  phrase += " " + hourWindow(plan.hours, opts);
449
453
  } else if (plan.hours.kind === "step") {
450
- phrase += ", " + stepHourSpan(stepSegment(schedule, "hour"), opts);
454
+ phrase = withoutHourAnchor(phrase) + ", " + stepHourSpan(stepSegment(schedule, "hour"), opts);
451
455
  }
452
456
  return phrase + trailingQualifier(schedule, opts);
453
457
  }
@@ -484,7 +488,7 @@ function renderMinuteSpanAcrossHourStep(schedule, plan, opts) {
484
488
  if (plan.form === "wildcard") {
485
489
  return "cada minuto, " + stepHourSpan(segment, opts) + trailingQualifier(schedule, opts);
486
490
  }
487
- const lead = plan.form === "list" ? minutesList(schedule, opts) : minuteRangeLead(schedule.pattern.minute);
491
+ const lead = withoutHourAnchor(plan.form === "list" ? minutesList(schedule, opts) : minuteRangeLead(schedule.pattern.minute));
488
492
  return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(schedule, opts);
489
493
  }
490
494
  function renderEveryHour(schedule, plan, opts) {
@@ -795,7 +799,7 @@ function renderCompactClockTimes(schedule, plan, opts) {
795
799
  );
796
800
  }
797
801
  const cadence = unevenHourCadence(schedule, opts);
798
- const phrase = cadence ? minutesList(schedule, opts) + ", " + cadence + trailingQualifier(schedule, opts) : minutesList(schedule, opts) + ", " + hourContextTimes(schedule, opts) + trailingQualifier(schedule, opts);
802
+ const phrase = cadence ? withoutHourAnchor(minutesList(schedule, opts)) + ", " + cadence + trailingQualifier(schedule, opts) : minutesList(schedule, opts) + ", " + hourContextTimes(schedule, opts) + trailingQualifier(schedule, opts);
799
803
  return schedule.analyses.clockSecond ? secondsLeadClause(schedule, opts) + ", " + phrase : phrase;
800
804
  }
801
805
  var renderers = {
package/dist/lang/es.js CHANGED
@@ -205,6 +205,7 @@ function normalizeOptions(options) {
205
205
  // 12-hour for Mexico/US); an explicit `{ampm}` option overrides it.
206
206
  ampm: typeof options.ampm === "boolean" ? options.ampm : style.ampm,
207
207
  lenient: !!options.lenient,
208
+ quartz: !!options.quartz,
208
209
  seconds: !!options.seconds,
209
210
  short: !!options.short,
210
211
  style,
@@ -351,6 +352,9 @@ function minutesList(schedule, opts) {
351
352
  opts
352
353
  ) ?? "en los minutos " + joinList(segmentWords(segmentsOf(schedule, "minute"))) + " de cada hora";
353
354
  }
355
+ function withoutHourAnchor(lead) {
356
+ return lead.replace(/ de cada hora$/, "");
357
+ }
354
358
  function minuteRangeLead(minuteField) {
355
359
  const bounds = minuteField.split("-");
356
360
  return "cada minuto del " + bounds[0] + " al " + bounds[1];
@@ -421,7 +425,7 @@ function renderMinuteFrequency(schedule, plan, opts) {
421
425
  } else if (plan.hours.kind === "window") {
422
426
  phrase += " " + hourWindow(plan.hours, opts);
423
427
  } else if (plan.hours.kind === "step") {
424
- phrase += ", " + stepHourSpan(stepSegment(schedule, "hour"), opts);
428
+ phrase = withoutHourAnchor(phrase) + ", " + stepHourSpan(stepSegment(schedule, "hour"), opts);
425
429
  }
426
430
  return phrase + trailingQualifier(schedule, opts);
427
431
  }
@@ -458,7 +462,7 @@ function renderMinuteSpanAcrossHourStep(schedule, plan, opts) {
458
462
  if (plan.form === "wildcard") {
459
463
  return "cada minuto, " + stepHourSpan(segment, opts) + trailingQualifier(schedule, opts);
460
464
  }
461
- const lead = plan.form === "list" ? minutesList(schedule, opts) : minuteRangeLead(schedule.pattern.minute);
465
+ const lead = withoutHourAnchor(plan.form === "list" ? minutesList(schedule, opts) : minuteRangeLead(schedule.pattern.minute));
462
466
  return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(schedule, opts);
463
467
  }
464
468
  function renderEveryHour(schedule, plan, opts) {
@@ -769,7 +773,7 @@ function renderCompactClockTimes(schedule, plan, opts) {
769
773
  );
770
774
  }
771
775
  const cadence = unevenHourCadence(schedule, opts);
772
- const phrase = cadence ? minutesList(schedule, opts) + ", " + cadence + trailingQualifier(schedule, opts) : minutesList(schedule, opts) + ", " + hourContextTimes(schedule, opts) + trailingQualifier(schedule, opts);
776
+ const phrase = cadence ? withoutHourAnchor(minutesList(schedule, opts)) + ", " + cadence + trailingQualifier(schedule, opts) : minutesList(schedule, opts) + ", " + hourContextTimes(schedule, opts) + trailingQualifier(schedule, opts);
773
777
  return schedule.analyses.clockSecond ? secondsLeadClause(schedule, opts) + ", " + phrase : phrase;
774
778
  }
775
779
  var renderers = {
package/dist/lang/fi.cjs CHANGED
@@ -308,6 +308,7 @@ function normalizeOptions(options) {
308
308
  return {
309
309
  ampm: false,
310
310
  lenient: !!options.lenient,
311
+ quartz: !!options.quartz,
311
312
  seconds: !!options.seconds,
312
313
  short: !!options.short,
313
314
  style: resolveDialect(options.dialect),
@@ -398,8 +399,8 @@ function renderComposeSeconds(schedule, plan, opts) {
398
399
  if (plan.rest.kind === "minuteFrequency" && schedule.pattern.second !== "*") {
399
400
  return composeSecondsOverMinuteStep(schedule, plan.rest, opts);
400
401
  }
401
- if (plan.rest.kind === "clockTimes" && plan.rest.times.every((time) => +time.minute === 0)) {
402
- return composeMinuteZero(schedule, plan.rest, opts);
402
+ if (plan.rest.kind === "clockTimes" && schedule.shapes.minute === "single") {
403
+ return composeSingleMinute(schedule, plan.rest, opts);
403
404
  }
404
405
  if (isEveryOtherMinuteSeconds(schedule, plan)) {
405
406
  return secondsLeadClause(schedule, opts) + " joka toisena minuuttina";
@@ -415,7 +416,7 @@ function isEveryOtherMinuteSeconds(schedule, plan) {
415
416
  const seg = stepSegment(schedule, "minute");
416
417
  return seg.startToken === "*" && seg.interval === 2;
417
418
  }
418
- function composeMinuteZero(schedule, rest, opts) {
419
+ function composeSingleMinute(schedule, rest, opts) {
419
420
  const clocks = rest.times.map(function clock(time) {
420
421
  return clockDigits(
421
422
  { hour: time.hour, minute: time.minute },
@@ -539,7 +540,7 @@ function renderMinuteFrequency(schedule, plan, opts) {
539
540
  if (plan.hours.kind === "during") {
540
541
  const cadence = unevenHourCadence(schedule, opts);
541
542
  if (cadence !== null) {
542
- return stepCycle60(seg, units.minute, opts) + ", " + cadence + trailingQualifier(schedule, opts);
543
+ return withoutHourAnchor(stepCycle60(seg, units.minute, opts)) + ", " + cadence + trailingQualifier(schedule, opts);
543
544
  }
544
545
  if (minuteStepIsAnchored(seg)) {
545
546
  const bareHours = kloFromTimes(schedule, plan.hours.times, opts);
@@ -547,11 +548,12 @@ function renderMinuteFrequency(schedule, plan, opts) {
547
548
  }
548
549
  return stepCycle60(seg, units.minute, opts) + " " + hourWindowsFromTimes(schedule, plan.hours.times, opts) + trailingQualifier(schedule, opts);
549
550
  }
550
- let phrase = stepCycle60(seg, units.minute, opts);
551
+ const phraseBase = stepCycle60(seg, units.minute, opts);
552
+ let phrase = phraseBase;
551
553
  if (plan.hours.kind === "window") {
552
554
  phrase += " " + hourWindow(plan.hours, opts);
553
555
  } else if (plan.hours.kind === "step") {
554
- phrase += " " + everyNthHour(stepSegment(schedule, "hour"), opts);
556
+ phrase = withoutHourAnchor(phraseBase) + " " + everyNthHour(stepSegment(schedule, "hour"), opts);
555
557
  }
556
558
  return phrase + trailingQualifier(schedule, opts);
557
559
  }
@@ -784,6 +786,9 @@ function stepCycle60(segment, unit, opts) {
784
786
  unit
785
787
  }, opts);
786
788
  }
789
+ function withoutHourAnchor(lead) {
790
+ return lead.replace(" " + units.minute.anchor + " ", " ");
791
+ }
787
792
  function stepHours(segment, opts) {
788
793
  if (segment.startToken.indexOf("-") !== -1) {
789
794
  return kloList(segment.fires, opts);
package/dist/lang/fi.js CHANGED
@@ -282,6 +282,7 @@ function normalizeOptions(options) {
282
282
  return {
283
283
  ampm: false,
284
284
  lenient: !!options.lenient,
285
+ quartz: !!options.quartz,
285
286
  seconds: !!options.seconds,
286
287
  short: !!options.short,
287
288
  style: resolveDialect(options.dialect),
@@ -372,8 +373,8 @@ function renderComposeSeconds(schedule, plan, opts) {
372
373
  if (plan.rest.kind === "minuteFrequency" && schedule.pattern.second !== "*") {
373
374
  return composeSecondsOverMinuteStep(schedule, plan.rest, opts);
374
375
  }
375
- if (plan.rest.kind === "clockTimes" && plan.rest.times.every((time) => +time.minute === 0)) {
376
- return composeMinuteZero(schedule, plan.rest, opts);
376
+ if (plan.rest.kind === "clockTimes" && schedule.shapes.minute === "single") {
377
+ return composeSingleMinute(schedule, plan.rest, opts);
377
378
  }
378
379
  if (isEveryOtherMinuteSeconds(schedule, plan)) {
379
380
  return secondsLeadClause(schedule, opts) + " joka toisena minuuttina";
@@ -389,7 +390,7 @@ function isEveryOtherMinuteSeconds(schedule, plan) {
389
390
  const seg = stepSegment(schedule, "minute");
390
391
  return seg.startToken === "*" && seg.interval === 2;
391
392
  }
392
- function composeMinuteZero(schedule, rest, opts) {
393
+ function composeSingleMinute(schedule, rest, opts) {
393
394
  const clocks = rest.times.map(function clock(time) {
394
395
  return clockDigits(
395
396
  { hour: time.hour, minute: time.minute },
@@ -513,7 +514,7 @@ function renderMinuteFrequency(schedule, plan, opts) {
513
514
  if (plan.hours.kind === "during") {
514
515
  const cadence = unevenHourCadence(schedule, opts);
515
516
  if (cadence !== null) {
516
- return stepCycle60(seg, units.minute, opts) + ", " + cadence + trailingQualifier(schedule, opts);
517
+ return withoutHourAnchor(stepCycle60(seg, units.minute, opts)) + ", " + cadence + trailingQualifier(schedule, opts);
517
518
  }
518
519
  if (minuteStepIsAnchored(seg)) {
519
520
  const bareHours = kloFromTimes(schedule, plan.hours.times, opts);
@@ -521,11 +522,12 @@ function renderMinuteFrequency(schedule, plan, opts) {
521
522
  }
522
523
  return stepCycle60(seg, units.minute, opts) + " " + hourWindowsFromTimes(schedule, plan.hours.times, opts) + trailingQualifier(schedule, opts);
523
524
  }
524
- let phrase = stepCycle60(seg, units.minute, opts);
525
+ const phraseBase = stepCycle60(seg, units.minute, opts);
526
+ let phrase = phraseBase;
525
527
  if (plan.hours.kind === "window") {
526
528
  phrase += " " + hourWindow(plan.hours, opts);
527
529
  } else if (plan.hours.kind === "step") {
528
- phrase += " " + everyNthHour(stepSegment(schedule, "hour"), opts);
530
+ phrase = withoutHourAnchor(phraseBase) + " " + everyNthHour(stepSegment(schedule, "hour"), opts);
529
531
  }
530
532
  return phrase + trailingQualifier(schedule, opts);
531
533
  }
@@ -758,6 +760,9 @@ function stepCycle60(segment, unit, opts) {
758
760
  unit
759
761
  }, opts);
760
762
  }
763
+ function withoutHourAnchor(lead) {
764
+ return lead.replace(" " + units.minute.anchor + " ", " ");
765
+ }
761
766
  function stepHours(segment, opts) {
762
767
  if (segment.startToken.indexOf("-") !== -1) {
763
768
  return kloList(segment.fires, opts);
package/dist/lang/fr.cjs CHANGED
@@ -219,6 +219,7 @@ function normalizeOptions(options) {
219
219
  // satisfied without the 12-hour machinery the es donor carried.
220
220
  ampm: false,
221
221
  lenient: !!options.lenient,
222
+ quartz: !!options.quartz,
222
223
  seconds: !!options.seconds,
223
224
  short: !!options.short,
224
225
  style,
@@ -364,6 +365,9 @@ function minutesList(schedule, opts) {
364
365
  opts
365
366
  ) ?? "aux minutes " + joinList(segmentWords(segmentsOf(schedule, "minute"))) + " de chaque heure";
366
367
  }
368
+ function withoutHourAnchor(lead) {
369
+ return lead.replace(/ de chaque heure$/, "");
370
+ }
367
371
  function minuteRangeLead(minuteField) {
368
372
  const bounds = minuteField.split("-");
369
373
  return "chaque minute de " + bounds[0] + " \xE0 " + bounds[1];
@@ -401,7 +405,7 @@ function renderMinuteFrequency(schedule, plan, opts) {
401
405
  } else if (plan.hours.kind === "window") {
402
406
  phrase += " " + hourWindow(plan.hours, opts);
403
407
  } else if (plan.hours.kind === "step") {
404
- phrase += ", " + stepHourSpan(stepSegment(schedule, "hour"), opts);
408
+ phrase = withoutHourAnchor(phrase) + ", " + stepHourSpan(stepSegment(schedule, "hour"), opts);
405
409
  }
406
410
  return phrase + trailingQualifier(schedule, opts);
407
411
  }
@@ -438,7 +442,7 @@ function renderMinuteSpanAcrossHourStep(schedule, plan, opts) {
438
442
  if (plan.form === "wildcard") {
439
443
  return "chaque minute, " + stepHourSpan(segment, opts) + trailingQualifier(schedule, opts);
440
444
  }
441
- const lead = plan.form === "list" ? minutesList(schedule, opts) : minuteRangeLead(schedule.pattern.minute);
445
+ const lead = withoutHourAnchor(plan.form === "list" ? minutesList(schedule, opts) : minuteRangeLead(schedule.pattern.minute));
442
446
  return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(schedule, opts);
443
447
  }
444
448
  function renderEveryHour(schedule, plan, opts) {
@@ -611,7 +615,7 @@ function renderCompactClockTimes(schedule, plan, opts) {
611
615
  );
612
616
  }
613
617
  const cadence = unevenHourCadence(schedule, opts);
614
- const phrase = cadence ? minutesList(schedule, opts) + ", " + cadence + trailingQualifier(schedule, opts) : minutesList(schedule, opts) + ", " + hourContextTimes(schedule, opts) + trailingQualifier(schedule, opts);
618
+ const phrase = cadence ? withoutHourAnchor(minutesList(schedule, opts)) + ", " + cadence + trailingQualifier(schedule, opts) : minutesList(schedule, opts) + ", " + hourContextTimes(schedule, opts) + trailingQualifier(schedule, opts);
615
619
  return schedule.analyses.clockSecond ? secondsLeadClause(schedule, opts) + ", " + phrase : phrase;
616
620
  }
617
621
  var renderers = {