cronli5 0.2.0 → 0.2.1

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/lang/en.js CHANGED
@@ -34,6 +34,48 @@ function orderWeekdaysForDisplay(segments) {
34
34
  return pair[0];
35
35
  });
36
36
  }
37
+ function segmentsOf(ir, field) {
38
+ return ir.analyses.segments[field] ?? [];
39
+ }
40
+ function stepSegment(ir, field) {
41
+ return segmentsOf(ir, field)[0];
42
+ }
43
+ function singleValues(segments) {
44
+ const values = [];
45
+ for (const segment of segments) {
46
+ if (segment.kind !== "single") {
47
+ return null;
48
+ }
49
+ values.push(+segment.value);
50
+ }
51
+ return values;
52
+ }
53
+ function offsetCleanStride(stride) {
54
+ return stride.start < stride.interval && 24 % stride.interval === 0;
55
+ }
56
+ function hourListStride(values) {
57
+ if (values.length < 2) {
58
+ return null;
59
+ }
60
+ const interval = values[1] - values[0];
61
+ if (interval < 2) {
62
+ return null;
63
+ }
64
+ for (let i = 2; i < values.length; i += 1) {
65
+ if (values[i] - values[i - 1] !== interval) {
66
+ return null;
67
+ }
68
+ }
69
+ if (values[0] !== 0 && values.length < 5) {
70
+ return null;
71
+ }
72
+ return { interval, last: values[values.length - 1], start: values[0] };
73
+ }
74
+
75
+ // src/core/shapes.ts
76
+ function isOpenStep(field) {
77
+ return field.indexOf("/") !== -1 && field.indexOf("-") === -1 && field.indexOf(",") === -1;
78
+ }
37
79
 
38
80
  // src/core/specs.ts
39
81
  var maxClockTimes = 6;
@@ -255,7 +297,7 @@ function secondsClause(ir, anchor, opts) {
255
297
  }
256
298
  if (shape === "step") {
257
299
  return stepCycle60(
258
- ir.analyses.segments.second[0],
300
+ stepSegment(ir, "second"),
259
301
  "second",
260
302
  anchor,
261
303
  opts
@@ -270,12 +312,12 @@ function secondsClause(ir, anchor, opts) {
270
312
  return "at " + getNumber(secondField, opts) + " " + pluralize(secondField, "second") + " past the " + anchor;
271
313
  }
272
314
  return strideFromSegments(
273
- ir.analyses.segments.second,
315
+ segmentsOf(ir, "second"),
274
316
  "second",
275
317
  anchor,
276
318
  opts
277
319
  ) ?? listPastThe(
278
- segmentWords(ir.analyses.segments.second, opts),
320
+ segmentWords(segmentsOf(ir, "second"), opts),
279
321
  "second",
280
322
  anchor,
281
323
  opts
@@ -292,15 +334,15 @@ function renderRangeOfMinutes(ir, plan, opts) {
292
334
  return minuteRangeLead(ir.pattern.minute, opts) + trailingQualifier(ir, opts);
293
335
  }
294
336
  function renderMultipleMinutes(ir, plan, opts) {
295
- const stride = strideFromSegments(ir.analyses.segments.minute, "minute", "hour", opts);
337
+ const stride = strideFromSegments(segmentsOf(ir, "minute"), "minute", "hour", opts);
296
338
  return (stride ?? listPastThe(segmentWords(
297
- ir.analyses.segments.minute,
339
+ segmentsOf(ir, "minute"),
298
340
  opts
299
341
  ), "minute", "hour", opts)) + trailingQualifier(ir, opts);
300
342
  }
301
343
  function renderMinuteFrequency(ir, plan, opts) {
302
344
  let phrase = stepCycle60(
303
- ir.analyses.segments.minute[0],
345
+ stepSegment(ir, "minute"),
304
346
  "minute",
305
347
  "hour",
306
348
  opts
@@ -309,9 +351,14 @@ function renderMinuteFrequency(ir, plan, opts) {
309
351
  const cadence = unevenHourCadence(ir, opts);
310
352
  phrase += cadence ? ", " + cadence : " during the " + hourTimesFromPlan(ir, plan.hours.times, false, opts) + " hours";
311
353
  } else if (plan.hours.kind === "window") {
312
- phrase += " " + hourWindow(plan.hours, opts);
354
+ phrase += " " + rangeWindow({
355
+ continuous: false,
356
+ from: plan.hours.from,
357
+ throughMinute: plan.hours.last,
358
+ to: plan.hours.to
359
+ }, opts);
313
360
  } else if (plan.hours.kind === "step") {
314
- phrase += " " + everyNthHour(ir.analyses.segments.hour[0], opts);
361
+ phrase += " " + everyNthHour(stepSegment(ir, "hour"), opts);
315
362
  }
316
363
  return phrase + trailingQualifier(ir, opts);
317
364
  }
@@ -339,8 +386,8 @@ function renderMinutesAcrossHours(ir, plan, opts) {
339
386
  }
340
387
  return lead2 + " during the " + hourTimesFromPlan(ir, plan.times, false, opts) + " hours" + trailingQualifier(ir, opts);
341
388
  }
342
- const lead = strideFromSegments(ir.analyses.segments.minute, "minute", "hour", opts) ?? listPastThe(
343
- segmentWords(ir.analyses.segments.minute, opts),
389
+ const lead = strideFromSegments(segmentsOf(ir, "minute"), "minute", "hour", opts) ?? listPastThe(
390
+ segmentWords(segmentsOf(ir, "minute"), opts),
344
391
  "minute",
345
392
  "hour",
346
393
  opts
@@ -365,12 +412,12 @@ function everyNthHour(segment, opts) {
365
412
  return start === 0 ? base : base + " starting at " + getTime({ hour: start, minute: 0 }, opts);
366
413
  }
367
414
  function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
368
- const segment = ir.analyses.segments.hour[0];
415
+ const segment = stepSegment(ir, "hour");
369
416
  if (plan.form === "wildcard") {
370
417
  return "every minute " + everyNthHour(segment, opts) + trailingQualifier(ir, opts);
371
418
  }
372
- const lead = plan.form === "list" ? strideFromSegments(ir.analyses.segments.minute, "minute", "hour", opts) ?? listPastThe(
373
- segmentWords(ir.analyses.segments.minute, opts),
419
+ const lead = plan.form === "list" ? strideFromSegments(segmentsOf(ir, "minute"), "minute", "hour", opts) ?? listPastThe(
420
+ segmentWords(segmentsOf(ir, "minute"), opts),
374
421
  "minute",
375
422
  "hour",
376
423
  opts
@@ -401,12 +448,12 @@ function rangeMinuteLead(ir, opts) {
401
448
  return "every hour";
402
449
  }
403
450
  return strideFromSegments(
404
- ir.analyses.segments.minute,
451
+ segmentsOf(ir, "minute"),
405
452
  "minute",
406
453
  "hour",
407
454
  opts
408
455
  ) ?? listPastThe(
409
- segmentWords(ir.analyses.segments.minute, opts),
456
+ segmentWords(segmentsOf(ir, "minute"), opts),
410
457
  "minute",
411
458
  "hour",
412
459
  opts
@@ -417,21 +464,28 @@ function renderHourStep(ir, plan, opts) {
417
464
  if (cadence !== null) {
418
465
  return cadence + trailingQualifier(ir, opts);
419
466
  }
420
- return stepHours(ir.analyses.segments.hour[0], opts) + trailingQualifier(ir, opts);
467
+ return stepHours(stepSegment(ir, "hour"), opts) + trailingQualifier(ir, opts);
421
468
  }
422
469
  function boundedWindow(plan) {
423
- const last = plan.minuteForm === "wildcard" ? plan.boundMinute ?? 0 : 0;
424
- return { from: plan.from, last, to: plan.to };
470
+ const continuous = plan.minuteForm === "wildcard";
471
+ const closeMinute = continuous ? plan.boundMinute ?? 0 : 0;
472
+ return { from: plan.from, closeMinute, to: plan.to, continuous };
425
473
  }
426
- function rangeWindow(from, to, throughMinute, opts) {
474
+ function rangeWindow(window, opts) {
475
+ const { from, to, throughMinute, continuous } = window;
427
476
  const open = "from " + getTime({ hour: from, minute: 0 }, opts);
428
477
  if (opts.style.untilWindow && !opts.short && from !== to) {
429
- return open + " until " + getTime({ hour: (to + 1) % 24, minute: 0 }, opts);
478
+ return continuous ? open + " until " + getTime({ hour: (to + 1) % 24, minute: 0 }, opts) : open + through(opts) + getTime({ hour: to, minute: 0 }, opts);
430
479
  }
431
480
  return open + through(opts) + getTime({ hour: to, minute: throughMinute }, opts);
432
481
  }
433
482
  function hourWindow(window, opts) {
434
- return rangeWindow(window.from, window.to, window.last, opts);
483
+ return rangeWindow({
484
+ continuous: window.continuous,
485
+ from: window.from,
486
+ throughMinute: window.closeMinute,
487
+ to: window.to
488
+ }, opts);
435
489
  }
436
490
  function renderClockTimes(ir, plan, opts) {
437
491
  if (ir.shapes.minute === "single") {
@@ -461,7 +515,7 @@ function renderCompactClockTimes(ir, plan, opts) {
461
515
  if (cadence2 !== null) {
462
516
  return cadence2;
463
517
  }
464
- const hasRange = ir.analyses.segments.hour.some(function range(segment) {
518
+ const hasRange = segmentsOf(ir, "hour").some(function range(segment) {
465
519
  return segment.kind === "range";
466
520
  });
467
521
  if (hasRange && !ir.analyses.clockSecond) {
@@ -473,8 +527,8 @@ function renderCompactClockTimes(ir, plan, opts) {
473
527
  const minuteLead = (
474
528
  // The non-fold branch is a minute list, which has segments. An
475
529
  // offset/uneven step enumerated to that list reads as a stride.
476
- strideFromSegments(ir.analyses.segments.minute, "minute", "hour", opts) ?? listPastThe(
477
- segmentWords(ir.analyses.segments.minute, opts),
530
+ strideFromSegments(segmentsOf(ir, "minute"), "minute", "hour", opts) ?? listPastThe(
531
+ segmentWords(segmentsOf(ir, "minute"), opts),
478
532
  "minute",
479
533
  "hour",
480
534
  opts
@@ -487,42 +541,38 @@ function renderCompactClockTimes(ir, plan, opts) {
487
541
  function foldedHourWindows(ir, plan, opts) {
488
542
  const minute = plan.minute;
489
543
  const windows = [];
490
- const outliers = collectHourOutliers(ir);
491
- const times = outliers.hours.map(function time(hour) {
544
+ const times = collectHourOutliers(ir).map(function time(hour) {
492
545
  return getTime({ hour, minute }, opts);
493
546
  });
494
- ir.analyses.segments.hour.forEach(function classify(segment) {
547
+ segmentsOf(ir, "hour").forEach(function classify(segment) {
495
548
  if (segment.kind === "range") {
496
- windows.push(rangeWindow(
497
- +segment.bounds[0],
498
- +segment.bounds[1],
499
- minute,
500
- opts
501
- ));
549
+ windows.push(rangeWindow({
550
+ continuous: false,
551
+ from: +segment.bounds[0],
552
+ throughMinute: minute,
553
+ to: +segment.bounds[1]
554
+ }, opts));
502
555
  }
503
556
  });
504
557
  const phrase = rangeMinuteLead(ir, opts) + " " + joinList(windows, opts);
505
- return phrase + outlierTail(times, outliers.pureStrays, opts);
558
+ return phrase + outlierTail(times, opts);
506
559
  }
507
560
  function collectHourOutliers(ir) {
508
561
  const hours = [];
509
- let pureStrays = true;
510
- ir.analyses.segments.hour.forEach(function classify(segment) {
562
+ segmentsOf(ir, "hour").forEach(function classify(segment) {
511
563
  if (segment.kind === "step") {
512
564
  hours.push(...segment.fires);
513
- pureStrays = false;
514
565
  } else if (segment.kind !== "range") {
515
566
  hours.push(+segment.value);
516
567
  }
517
568
  });
518
- return { hours, pureStrays };
569
+ return hours;
519
570
  }
520
- function outlierTail(times, pureStrays, opts) {
571
+ function outlierTail(times, opts) {
521
572
  if (!times.length) {
522
573
  return "";
523
574
  }
524
- const connector = pureStrays && opts.style.untilWindow && !opts.short ? " plus " : " and at ";
525
- return connector + joinList(times, opts);
575
+ return " and at " + joinList(times, opts);
526
576
  }
527
577
  function isCadenceField(token) {
528
578
  return token === "*" || token.startsWith("*/") && token.indexOf("-") === -1;
@@ -536,7 +586,7 @@ function leadingCadence(ir, opts) {
536
586
  const text = minute === "*" ? "every minute" : (
537
587
  // A clean minute step's first segment is a step segment.
538
588
  stepCycle60(
539
- ir.analyses.segments.minute[0],
589
+ stepSegment(ir, "minute"),
540
590
  "minute",
541
591
  "hour",
542
592
  opts
@@ -554,7 +604,7 @@ function minuteConfinement(ir, opts) {
554
604
  if (isCadenceField(minute)) {
555
605
  return " of every other minute";
556
606
  }
557
- const segments = ir.analyses.segments.minute;
607
+ const segments = segmentsOf(ir, "minute");
558
608
  if (ir.shapes.minute === "single") {
559
609
  return " during minute :" + pad(minute);
560
610
  }
@@ -588,7 +638,12 @@ function hourConfinement(ir, opts) {
588
638
  }
589
639
  if (ir.shapes.hour === "range") {
590
640
  const bounds = hour.split("-");
591
- return " " + rangeWindow(+bounds[0], +bounds[1], 0, opts);
641
+ return " " + rangeWindow({
642
+ continuous: ir.pattern.minute === "*",
643
+ from: +bounds[0],
644
+ throughMinute: 0,
645
+ to: +bounds[1]
646
+ }, opts);
592
647
  }
593
648
  return " during the " + hourSegmentTimes(ir, { minute: 0, second: null }, false, opts) + " hours";
594
649
  }
@@ -599,14 +654,14 @@ function confinableHour(ir) {
599
654
  if (ir.shapes.hour !== "step") {
600
655
  return true;
601
656
  }
602
- const segment = ir.analyses.segments.hour[0];
657
+ const segment = stepSegment(ir, "hour");
603
658
  return ir.pattern.hour === "*/2" || segment.startToken.indexOf("-") !== -1;
604
659
  }
605
660
  function isMinuteStride(ir) {
606
661
  if (ir.shapes.minute !== "list") {
607
662
  return false;
608
663
  }
609
- const values = singleValues(ir.analyses.segments.minute);
664
+ const values = singleValues(segmentsOf(ir, "minute"));
610
665
  return values !== null && arithmeticStep(values) !== null;
611
666
  }
612
667
  function confinementEligible(ir, lead) {
@@ -676,16 +731,6 @@ function renderStride(stride, opts) {
676
731
  const num = seriesNumber();
677
732
  return cadence + " from " + num(start) + through(opts) + num(last) + " " + pluralize(last, unit) + " past the " + anchor;
678
733
  }
679
- function singleValues(segments) {
680
- const values = [];
681
- for (const segment of segments) {
682
- if (segment.kind !== "single") {
683
- return null;
684
- }
685
- values.push(+segment.value);
686
- }
687
- return values;
688
- }
689
734
  function strideFromSegments(segments, unit, anchor, opts) {
690
735
  const values = singleValues(segments);
691
736
  const step = values && arithmeticStep(values);
@@ -734,9 +779,6 @@ function hourStrideCadence(stride, opts) {
734
779
  }
735
780
  return cadence + " from " + getTime({ hour: start, minute: 0 }, opts) + through(opts) + getTime({ hour: last, minute: 0 }, opts);
736
781
  }
737
- function offsetCleanStride(stride) {
738
- return stride.start < stride.interval && 24 % stride.interval === 0;
739
- }
740
782
  function unevenHourCadence(ir, opts) {
741
783
  const stride = hourStride(ir);
742
784
  if (!stride || offsetCleanStride(stride)) {
@@ -744,26 +786,8 @@ function unevenHourCadence(ir, opts) {
744
786
  }
745
787
  return hourStrideCadence(stride, opts);
746
788
  }
747
- function hourListStride(values) {
748
- if (values.length < 2) {
749
- return null;
750
- }
751
- const interval = values[1] - values[0];
752
- if (interval < 2) {
753
- return null;
754
- }
755
- for (let i = 2; i < values.length; i += 1) {
756
- if (values[i] - values[i - 1] !== interval) {
757
- return null;
758
- }
759
- }
760
- if (values[0] !== 0 && values.length < 5) {
761
- return null;
762
- }
763
- return { interval, last: values[values.length - 1], start: values[0] };
764
- }
765
789
  function hourStride(ir) {
766
- const segments = ir.analyses.segments.hour;
790
+ const segments = segmentsOf(ir, "hour");
767
791
  if (segments.length === 1 && segments[0].kind === "step") {
768
792
  const segment = segments[0];
769
793
  if (segment.fires.length < 2) {
@@ -810,7 +834,7 @@ function hourCadence(ir, minute, opts) {
810
834
  return hourCadenceLead(ir, minute, opts) + ", " + hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
811
835
  }
812
836
  function cleanStrideSegment(ir) {
813
- const segments = ir.analyses.segments.hour;
837
+ const segments = segmentsOf(ir, "hour");
814
838
  const segment = segments.length === 1 && segments[0];
815
839
  if (!segment || segment.kind !== "step" || segment.startToken.indexOf("-") !== -1 || !(segment.interval in stepOrdinals)) {
816
840
  return null;
@@ -818,28 +842,28 @@ function cleanStrideSegment(ir) {
818
842
  return segment;
819
843
  }
820
844
  function hasHourWindow(ir) {
821
- return ir.analyses.segments.hour.some(function range(segment) {
845
+ return segmentsOf(ir, "hour").some(function range(segment) {
822
846
  return segment.kind === "range";
823
847
  });
824
848
  }
825
849
  function hourRangeWindowTail(ir, opts) {
826
850
  const windows = [];
827
- const outliers = collectHourOutliers(ir);
828
- ir.analyses.segments.hour.forEach(function classify(segment) {
851
+ const outlierHours = collectHourOutliers(ir);
852
+ segmentsOf(ir, "hour").forEach(function classify(segment) {
829
853
  if (segment.kind === "range") {
830
- windows.push(rangeWindow(
831
- +segment.bounds[0],
832
- +segment.bounds[1],
833
- 0,
834
- opts
835
- ));
854
+ windows.push(rangeWindow({
855
+ continuous: false,
856
+ from: +segment.bounds[0],
857
+ throughMinute: 0,
858
+ to: +segment.bounds[1]
859
+ }, opts));
836
860
  }
837
861
  });
838
862
  const phrase = "every hour " + joinList(windows, opts);
839
- const times = outliers.hours.map(function time(hour) {
863
+ const times = outlierHours.map(function time(hour) {
840
864
  return getTime({ hour, minute: 0 }, opts);
841
865
  });
842
- return phrase + outlierTail(times, outliers.pureStrays, opts);
866
+ return phrase + outlierTail(times, opts);
843
867
  }
844
868
  function hourRangeCadence(ir, minute, opts) {
845
869
  if (minute !== 0 || !hasHourWindow(ir)) {
@@ -924,7 +948,7 @@ function segmentHours(segment) {
924
948
  }
925
949
  function hourSegmentTimes(ir, fold, atContext, opts) {
926
950
  const { minute, second } = fold;
927
- const segments = ir.analyses.segments.hour;
951
+ const segments = segmentsOf(ir, "hour");
928
952
  const plain = mixedTwelve(segments.flatMap(function entries(segment) {
929
953
  return segmentHours(segment).map(function entry(hour) {
930
954
  return { hour: +hour, minute, second };
@@ -1044,7 +1068,7 @@ function datePhrase(ir, words, opts) {
1044
1068
  }
1045
1069
  function monthFoldsIntoDate(ir) {
1046
1070
  return !oddEvenMonth(ir.pattern.month) && // Reached only with a restricted month, which has segments.
1047
- ir.analyses.segments.month.every(function flat(segment) {
1071
+ segmentsOf(ir, "month").every(function flat(segment) {
1048
1072
  return segment.kind !== "range";
1049
1073
  });
1050
1074
  }
@@ -1075,7 +1099,7 @@ function dayUnionDatePieces(ir, opts) {
1075
1099
  return [oddEven];
1076
1100
  }
1077
1101
  const pieces = [];
1078
- ir.analyses.segments.date.forEach(function expand(segment) {
1102
+ segmentsOf(ir, "date").forEach(function expand(segment) {
1079
1103
  if (segment.kind === "range") {
1080
1104
  pieces.push("from the " + getOrdinal(segment.bounds[0]) + through(opts) + "the " + getOrdinal(segment.bounds[1]));
1081
1105
  } else if (segment.kind === "step") {
@@ -1095,7 +1119,7 @@ function dayUnionWeekdayPieces(ir, opts) {
1095
1119
  return [quartz.replace(/^on /, "")];
1096
1120
  }
1097
1121
  const pieces = [];
1098
- ir.analyses.segments.weekday.forEach(function expand(segment) {
1122
+ segmentsOf(ir, "weekday").forEach(function expand(segment) {
1099
1123
  if (segment.kind === "range" && segment.bounds[0] === "1" && segment.bounds[1] === "5") {
1100
1124
  pieces.push("a weekday");
1101
1125
  } else if (segment.kind === "range") {
@@ -1176,7 +1200,7 @@ function quartzWeekdayPhrase(weekdayField, opts) {
1176
1200
  function monthDatePhrase(ir, opts) {
1177
1201
  const month = monthName(ir, opts);
1178
1202
  const days = renderSegments(
1179
- ir.analyses.segments.date,
1203
+ segmentsOf(ir, "date"),
1180
1204
  opts.style.ordinals ? getOrdinal : cardinalDay,
1181
1205
  opts
1182
1206
  );
@@ -1219,14 +1243,14 @@ function stepDates(dateField) {
1219
1243
  return phrase;
1220
1244
  }
1221
1245
  function dateOrdinals(ir, opts) {
1222
- return renderSegments(ir.analyses.segments.date, getOrdinal, opts);
1246
+ return renderSegments(segmentsOf(ir, "date"), getOrdinal, opts);
1223
1247
  }
1224
1248
  function monthName(ir, opts) {
1225
1249
  const oddEven = oddEvenMonth(ir.pattern.month);
1226
1250
  if (oddEven) {
1227
1251
  return oddEven;
1228
1252
  }
1229
- return renderSegments(ir.analyses.segments.month, function name(value) {
1253
+ return renderSegments(segmentsOf(ir, "month"), function name(value) {
1230
1254
  return getMonth(value, opts);
1231
1255
  }, opts);
1232
1256
  }
@@ -1244,7 +1268,7 @@ function oddEvenMonth(monthField) {
1244
1268
  return start === "2" ? "every even-numbered month" : null;
1245
1269
  }
1246
1270
  function weekdayPhrase(ir, recurring, opts) {
1247
- const segments = orderWeekdaysForDisplay(ir.analyses.segments.weekday);
1271
+ const segments = orderWeekdaysForDisplay(segmentsOf(ir, "weekday"));
1248
1272
  const hasRange = segments.some(function range(segment) {
1249
1273
  return segment.kind === "range";
1250
1274
  });
@@ -1272,9 +1296,6 @@ function renderSegments(segments, word, opts) {
1272
1296
  });
1273
1297
  return joinList(pieces, opts);
1274
1298
  }
1275
- function isOpenStep(field) {
1276
- return field.indexOf("/") !== -1 && field.indexOf("-") === -1 && field.indexOf(",") === -1;
1277
- }
1278
1299
  function applyYear(description, ir, opts) {
1279
1300
  const yearField = ir.pattern.year;
1280
1301
  if (yearField === "*") {