cronli5 0.1.2 → 0.1.5

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/es.cjs CHANGED
@@ -40,6 +40,42 @@ function clockDigits(time, { sep, pad: padHour, lean }) {
40
40
  return head + sep + pad(time.minute) + (time.second ? sep + pad(time.second) : "");
41
41
  }
42
42
 
43
+ // src/core/specs.ts
44
+ var weekdayNumbers = {
45
+ SUN: 0,
46
+ MON: 1,
47
+ TUE: 2,
48
+ WED: 3,
49
+ THU: 4,
50
+ FRI: 5,
51
+ SAT: 6
52
+ };
53
+ var maxClockTimes = 6;
54
+
55
+ // src/core/util.ts
56
+ function isNonNegativeInteger(value) {
57
+ const digits = /^\d+$/;
58
+ return digits.test(value);
59
+ }
60
+ function arithmeticStep(values) {
61
+ if (values.length < 5) {
62
+ return null;
63
+ }
64
+ const interval = values[1] - values[0];
65
+ if (interval < 2) {
66
+ return null;
67
+ }
68
+ for (let i = 2; i < values.length; i += 1) {
69
+ if (values[i] - values[i - 1] !== interval) {
70
+ return null;
71
+ }
72
+ }
73
+ return { start: values[0], interval, last: values[values.length - 1] };
74
+ }
75
+ function toFieldNumber(token, numberMap) {
76
+ return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
77
+ }
78
+
43
79
  // src/lang/es/dialects.ts
44
80
  var es = {
45
81
  ampm: false,
@@ -111,29 +147,6 @@ var weekdayNames = [
111
147
  "viernes",
112
148
  "s\xE1bado"
113
149
  ];
114
- var monthTokens = {
115
- JAN: 1,
116
- FEB: 2,
117
- MAR: 3,
118
- APR: 4,
119
- MAY: 5,
120
- JUN: 6,
121
- JUL: 7,
122
- AUG: 8,
123
- SEP: 9,
124
- OCT: 10,
125
- NOV: 11,
126
- DEC: 12
127
- };
128
- var weekdayTokens = {
129
- SUN: 0,
130
- MON: 1,
131
- TUE: 2,
132
- WED: 3,
133
- THU: 4,
134
- FRI: 5,
135
- SAT: 6
136
- };
137
150
  var nthWeekdayNames = [null, "primer", "segundo", "tercer", "cuarto", "quinto"];
138
151
  function normalizeOptions(options) {
139
152
  options = options || {};
@@ -176,16 +189,31 @@ function renderSecondsWithinMinute(ir, plan, opts) {
176
189
  }
177
190
  return secondsLeadClause(ir, opts) + ", en el minuto " + minuteField + " de cada hora" + trailingQualifier(ir, opts);
178
191
  }
192
+ function secondsListAtClock(ir, rest, opts) {
193
+ const clockPhrases = rest.times.map(function clock(time) {
194
+ return atTime(timePhrase(time.hour, time.minute, null, opts));
195
+ });
196
+ const grouped = groupClockTimesByArticle(clockPhrases);
197
+ const clockList = grouped.startsWith("a ") ? grouped.slice(2) : grouped;
198
+ const stride = strideFromSegments(fieldSegments(ir, "second"), "segundo", "", opts);
199
+ const secondsPhrase = stride ?? "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second")));
200
+ const dayFrame = trailingQualifier(ir, opts);
201
+ return (dayFrame ? dayFrame.trimStart() + ", " : "") + secondsPhrase + " de " + clockList;
202
+ }
203
+ function composeHourCadence(ir, plan, opts) {
204
+ const clockRest = plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes";
205
+ return clockRest && ir.shapes.minute === "single" ? hourCadence(ir, +ir.pattern.minute, opts) : null;
206
+ }
179
207
  function renderComposeSeconds(ir, plan, opts) {
208
+ const hourCad = composeHourCadence(ir, plan, opts);
209
+ if (hourCad !== null) {
210
+ return hourCad;
211
+ }
212
+ if (plan.rest.kind === "clockTimes" && (ir.shapes.second === "wildcard" || ir.shapes.second === "step")) {
213
+ return pinnedMinuteSeconds(ir, plan.rest, opts);
214
+ }
180
215
  if (plan.rest.kind === "clockTimes" && ir.shapes.second === "list") {
181
- const clockPhrases = plan.rest.times.map(function clock(time) {
182
- return atTime(timePhrase(time.hour, time.minute, null, opts));
183
- });
184
- const grouped = groupClockTimesByArticle(clockPhrases);
185
- const clockList = grouped.startsWith("a ") ? grouped.slice(2) : grouped;
186
- const secondsPhrase = "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second")));
187
- const dayFrame = trailingQualifier(ir, opts);
188
- return (dayFrame ? dayFrame.trimStart() + ", " : "") + secondsPhrase + " de " + clockList;
216
+ return secondsListAtClock(ir, plan.rest, opts);
189
217
  }
190
218
  if (plan.rest.kind === "hourRange" && ir.shapes.second === "step" && ir.pattern.weekday !== "*") {
191
219
  const restNode = plan.rest;
@@ -194,9 +222,30 @@ function renderComposeSeconds(ir, plan, opts) {
194
222
  const cadence = "cada " + numero(stepSegment(ir.analyses.segments.second).interval, opts) + " segundos del minuto " + ir.pattern.minute;
195
223
  return dayFrame + ", " + window + ", " + cadence;
196
224
  }
225
+ if (isEveryOtherMinuteSeconds(ir, plan)) {
226
+ return secondsLeadClause(ir, opts) + " de " + render(ir, plan.rest, opts);
227
+ }
197
228
  return secondsLeadClause(ir, opts) + ", " + render(ir, plan.rest, opts);
198
229
  }
230
+ function isEveryOtherMinuteSeconds(ir, plan) {
231
+ if (plan.rest.kind !== "minuteFrequency" || ir.shapes.second !== "wildcard" || ir.shapes.hour !== "wildcard") {
232
+ return false;
233
+ }
234
+ const minuteStep = stepSegment(ir.analyses.segments.minute);
235
+ return minuteStep.startToken === "*" && minuteStep.interval === 2;
236
+ }
237
+ function pinnedMinuteSeconds(ir, rest, opts) {
238
+ const dayTrail = leadingQualifier(ir, opts).trimEnd();
239
+ const trail = dayTrail ? ", " + dayTrail : "";
240
+ if (+rest.times[0].minute === 0) {
241
+ return secondsLeadClause(ir, opts) + " durante un minuto " + durationHourList(rest.times, opts) + trail;
242
+ }
243
+ return secondsLeadClause(ir, opts) + " de " + explicitClockList(rest.times, opts) + trail;
244
+ }
199
245
  function secondsLeadClause(ir, opts) {
246
+ return secondsClause(ir, "minuto", opts);
247
+ }
248
+ function secondsClause(ir, anchor, opts) {
200
249
  const secondField = ir.pattern.second;
201
250
  const shape = ir.shapes.second;
202
251
  if (secondField === "*") {
@@ -206,18 +255,23 @@ function secondsLeadClause(ir, opts) {
206
255
  return stepCycle60(
207
256
  stepSegment(ir.analyses.segments.second),
208
257
  "segundo",
209
- "minuto",
258
+ anchor,
210
259
  opts
211
260
  );
212
261
  }
213
262
  if (shape === "range") {
214
263
  const bounds = secondField.split("-");
215
- return "cada segundo del " + bounds[0] + " al " + bounds[1] + " de cada minuto";
264
+ return "cada segundo del " + bounds[0] + " al " + bounds[1] + " de cada " + anchor;
216
265
  }
217
266
  if (shape === "single") {
218
- return "en el segundo " + secondField + " de cada minuto";
267
+ return "en el segundo " + secondField + " de cada " + anchor;
219
268
  }
220
- return "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second"))) + " de cada minuto";
269
+ return strideFromSegments(
270
+ fieldSegments(ir, "second"),
271
+ "segundo",
272
+ anchor,
273
+ opts
274
+ ) ?? "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second"))) + " de cada " + anchor;
221
275
  }
222
276
  function renderEveryMinute(ir, plan, opts) {
223
277
  return "cada minuto" + trailingQualifier(ir, opts);
@@ -229,10 +283,15 @@ function renderRangeOfMinutes(ir, plan, opts) {
229
283
  return minuteRangeLead(ir.pattern.minute) + " de cada hora" + trailingQualifier(ir, opts);
230
284
  }
231
285
  function renderMultipleMinutes(ir, plan, opts) {
232
- return minutesList(ir) + trailingQualifier(ir, opts);
286
+ return minutesList(ir, opts) + trailingQualifier(ir, opts);
233
287
  }
234
- function minutesList(ir) {
235
- return "en los minutos " + joinList(segmentWords(fieldSegments(ir, "minute"))) + " de cada hora";
288
+ function minutesList(ir, opts) {
289
+ return strideFromSegments(
290
+ fieldSegments(ir, "minute"),
291
+ "minuto",
292
+ "hora",
293
+ opts
294
+ ) ?? "en los minutos " + joinList(segmentWords(fieldSegments(ir, "minute"))) + " de cada hora";
236
295
  }
237
296
  function minuteRangeLead(minuteField) {
238
297
  const bounds = minuteField.split("-");
@@ -304,6 +363,9 @@ function renderMinuteFrequency(ir, plan, opts) {
304
363
  return phrase + trailingQualifier(ir, opts);
305
364
  }
306
365
  function renderMinuteSpanInHour(ir, plan, opts) {
366
+ if (ir.pattern.minute === "*") {
367
+ return "cada minuto de la hora " + fromTime(timePhrase(plan.hour, 0, null, opts)) + trailingQualifier(ir, opts);
368
+ }
307
369
  return "cada minuto " + timeRange(
308
370
  { hour: plan.hour, minute: plan.span[0] },
309
371
  { hour: plan.hour, minute: plan.span[1] },
@@ -317,7 +379,7 @@ function renderMinutesAcrossHours(ir, plan, opts) {
317
379
  }
318
380
  return "cada minuto " + hourSpanFromTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
319
381
  }
320
- const lead = plan.form === "range" ? minuteRangeLead(ir.pattern.minute) : minutesList(ir);
382
+ const lead = plan.form === "range" ? minuteRangeLead(ir.pattern.minute) : minutesList(ir, opts);
321
383
  return lead + ", " + atHourTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
322
384
  }
323
385
  function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
@@ -325,7 +387,8 @@ function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
325
387
  if (plan.form === "wildcard") {
326
388
  return "cada minuto, " + stepHourSpan(segment, opts) + trailingQualifier(ir, opts);
327
389
  }
328
- return minuteRangeLead(ir.pattern.minute) + ", " + stepHours(segment, opts) + trailingQualifier(ir, opts);
390
+ const lead = plan.form === "list" ? minutesList(ir, opts) : minuteRangeLead(ir.pattern.minute);
391
+ return lead + ", " + stepHours(segment, opts) + trailingQualifier(ir, opts);
329
392
  }
330
393
  function renderEveryHour(ir, plan, opts) {
331
394
  return "cada hora" + trailingQualifier(ir, opts);
@@ -341,7 +404,7 @@ function renderHourRange(ir, plan, opts) {
341
404
  if (ir.pattern.minute === "0") {
342
405
  return "cada hora " + window + trailingQualifier(ir, opts);
343
406
  }
344
- const lead = ir.shapes.minute === "single" ? "en el minuto " + ir.pattern.minute + " de cada hora" : minutesList(ir);
407
+ const lead = ir.shapes.minute === "single" ? "en el minuto " + ir.pattern.minute + " de cada hora" : minutesList(ir, opts);
345
408
  return lead + ", " + window + trailingQualifier(ir, opts);
346
409
  }
347
410
  function renderHourStep(ir, plan, opts) {
@@ -415,11 +478,56 @@ function unionYaseaSuffix(ir, opts) {
415
478
  return ", ya sea " + domArm(ir, opts) + " o " + dowArm(ir);
416
479
  }
417
480
  function renderClockTimes(ir, plan, opts) {
481
+ if (ir.shapes.minute === "single") {
482
+ const cadence = hourCadence(ir, +ir.pattern.minute, opts);
483
+ if (cadence !== null) {
484
+ return cadence;
485
+ }
486
+ }
418
487
  const phrases = plan.times.map(function clock(time) {
419
488
  return atTime(timePhrase(time.hour, time.minute, time.second, opts));
420
489
  });
421
490
  return leadingQualifier(ir, opts) + groupClockTimes(phrases);
422
491
  }
492
+ function explicitClockList(times, opts) {
493
+ const phrases = times.map(function clock(time) {
494
+ return atTime(explicitTimePhrase(time.hour, time.minute, opts));
495
+ });
496
+ const grouped = groupClockTimes(phrases);
497
+ return grouped.startsWith("a ") ? grouped.slice(2) : grouped;
498
+ }
499
+ function durationHourList(times, opts) {
500
+ const phrases = times.map(function clock(time) {
501
+ return atTime(bareHourPhrase(time.hour, opts));
502
+ });
503
+ return groupClockTimes(phrases);
504
+ }
505
+ function bareHourPhrase(hour, opts) {
506
+ if (opts.ampm) {
507
+ return timePhrase(hour, 0, null, opts);
508
+ }
509
+ if (+hour === 0) {
510
+ return "medianoche";
511
+ }
512
+ if (+hour === 12) {
513
+ return "mediod\xEDa";
514
+ }
515
+ return (+hour === 1 ? "la " : "las ") + hour;
516
+ }
517
+ function explicitTimePhrase(hour, minute, opts) {
518
+ if (!opts.ampm) {
519
+ const article = +hour === 1 ? "la " : "las ";
520
+ const suffix = opts.style.hSuffix ? " h" : "";
521
+ return article + clockDigits(
522
+ { hour, minute, second: 0 },
523
+ { pad: true, sep: opts.style.sep }
524
+ ) + suffix;
525
+ }
526
+ const display = hour % 12 || 12;
527
+ const time = (display === 1 ? "la " : "las ") + clockDigits({ hour: display, minute, second: 0 }, { sep: opts.style.sep });
528
+ const period = opts.style.meridiem === "english" ? meridiemMark(hour) : dayPeriod(hour, opts);
529
+ return time + " " + period;
530
+ }
423
531
  function groupClockTimes(phrases) {
424
532
  if (phrases.length < 2) {
425
533
  return joinList(phrases);
@@ -557,6 +665,10 @@ function groupClockTimesByArticle(phrases) {
557
665
  }
558
666
  function renderCompactClockTimes(ir, plan, opts) {
559
667
  if (plan.fold) {
668
+ const cadence = hourCadence(ir, plan.minute, opts);
669
+ if (cadence !== null) {
670
+ return cadence;
671
+ }
560
672
  const ranged = hourSegments(ir).some(function range(segment) {
561
673
  return segment.kind === "range";
562
674
  });
@@ -565,7 +677,7 @@ function renderCompactClockTimes(ir, plan, opts) {
565
677
  }
566
678
  return leadingQualifier(ir, opts) + hourSegmentTimes(ir, plan.minute, ir.analyses.clockSecond, opts);
567
679
  }
568
- const phrase = minutesList(ir) + ", " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
680
+ const phrase = minutesList(ir, opts) + ", " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
569
681
  return ir.analyses.clockSecond ? secondsLeadClause(ir, opts) + ", " + phrase : phrase;
570
682
  }
571
683
  var renderers = {
@@ -588,19 +700,50 @@ var renderers = {
588
700
  singleMinute: renderSingleMinute,
589
701
  standaloneSeconds: renderStandaloneSeconds
590
702
  };
703
+ function renderStride(stride, opts) {
704
+ const { interval, start, last, cycle, unit, anchor } = stride;
705
+ const cadence = "cada " + numero(interval, opts) + " " + unit + "s";
706
+ const tiles = cycle % interval === 0;
707
+ if (start === 0 && tiles) {
708
+ return cadence;
709
+ }
710
+ const tail = anchor ? " de cada " + anchor : "";
711
+ if (start < interval && tiles) {
712
+ return cadence + " a partir del " + unit + " " + start + tail;
713
+ }
714
+ return cadence + " del " + unit + " " + start + " al " + last + tail;
715
+ }
591
716
  function stepCycle60(segment, unit, anchor, opts) {
592
717
  if (segment.startToken.indexOf("-") !== -1) {
593
718
  return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
594
719
  }
595
720
  const start = segment.startToken === "*" ? 0 : +segment.startToken;
596
- const interval = segment.interval;
597
- if (start !== 0) {
598
- if (segment.fires.length <= 3) {
599
- return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
721
+ if (start !== 0 && segment.fires.length <= 3) {
722
+ return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
723
+ }
724
+ return renderStride({
725
+ interval: segment.interval,
726
+ start,
727
+ last: segment.fires[segment.fires.length - 1],
728
+ cycle: 60,
729
+ unit,
730
+ anchor
731
+ }, opts);
732
+ }
733
+ function strideFromSegments(segments, unit, anchor, opts) {
734
+ const values = singleValues(segments);
735
+ const step = values && arithmeticStep(values);
736
+ return step ? renderStride({ ...step, cycle: 60, unit, anchor }, opts) : null;
737
+ }
738
+ function singleValues(segments) {
739
+ const values = [];
740
+ for (const segment of segments) {
741
+ if (segment.kind !== "single") {
742
+ return null;
600
743
  }
601
- return "cada " + numero(interval, opts) + " " + unit + "s a partir del " + unit + " " + start + " de cada " + anchor;
744
+ values.push(+segment.value);
602
745
  }
603
- return "cada " + numero(interval, opts) + " " + unit + "s";
746
+ return values;
604
747
  }
605
748
  function stepHours(segment, opts) {
606
749
  if (segment.startToken.indexOf("-") !== -1) {
@@ -616,6 +759,68 @@ function stepHours(segment, opts) {
616
759
  }
617
760
  return "cada " + numero(interval, opts) + " horas a partir de " + timePhrase(start, 0, null, opts);
618
761
  }
762
+ function hourStrideCadence(stride, opts) {
763
+ const { start, interval, last } = stride;
764
+ const cadence = "cada " + numero(interval, opts) + " horas";
765
+ const tiles = 24 % interval === 0;
766
+ if (start === 0 && tiles) {
767
+ return cadence;
768
+ }
769
+ if (start < interval && tiles) {
770
+ return cadence + " a partir de " + timePhrase(start, 0, null, opts);
771
+ }
772
+ return cadence + " de " + timePhrase(start, 0, null, opts) + " a " + timePhrase(last, 0, null, opts);
773
+ }
774
+ function hourStride(ir) {
775
+ const segments = fieldSegments(ir, "hour");
776
+ if (segments.length === 1 && segments[0].kind === "step") {
777
+ const segment = segments[0];
778
+ const start = segment.startToken === "*" ? 0 : +segment.startToken.split("-")[0];
779
+ return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
780
+ }
781
+ const values = singleValues(segments);
782
+ const step = values && arithmeticStep(values);
783
+ return step || null;
784
+ }
785
+ function subMinuteSecond(ir) {
786
+ return ir.pattern.second === "*" || ir.shapes.second === "step";
787
+ }
788
+ function hourCadenceLead(ir, minute, opts) {
789
+ if (minute === 0) {
790
+ if (subMinuteSecond(ir)) {
791
+ return secondsClause(ir, "minuto", opts) + " durante un minuto";
792
+ }
793
+ return secondsClause(ir, "hora", opts);
794
+ }
795
+ const minutePhrase = "en el minuto " + minute;
796
+ if (ir.pattern.second === "0") {
797
+ return minutePhrase;
798
+ }
799
+ return secondsClause(ir, "minuto", opts) + ", " + minutePhrase;
800
+ }
801
+ function hourCadence(ir, minute, opts) {
802
+ const stride = hourStride(ir);
803
+ if (!stride) {
804
+ return null;
805
+ }
806
+ const fires = (stride.last - stride.start) / stride.interval + 1;
807
+ if (ir.pattern.second === "0" && fires <= maxClockTimes) {
808
+ return null;
809
+ }
810
+ const confinement = minute === 0 && subMinuteSecond(ir) && cleanStrideSegment(ir);
811
+ if (confinement) {
812
+ return secondsClause(ir, "minuto", opts) + " durante un minuto, " + stepHourSpan(confinement, opts) + trailingQualifier(ir, opts);
813
+ }
814
+ return hourCadenceLead(ir, minute, opts) + ", " + hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
815
+ }
816
+ function cleanStrideSegment(ir) {
817
+ const segments = fieldSegments(ir, "hour");
818
+ const segment = segments.length === 1 && segments[0];
819
+ if (!segment || segment.kind !== "step" || segment.startToken.indexOf("-") !== -1) {
820
+ return null;
821
+ }
822
+ return segment;
823
+ }
619
824
  function atTimes(hours, opts) {
620
825
  return hours.map(function each(hour) {
621
826
  return atTime(timePhrase(hour, 0, null, opts));
@@ -992,17 +1197,15 @@ function numero(n, opts) {
992
1197
  return numeral(n, numeros, opts);
993
1198
  }
994
1199
  function weekdayName(token) {
995
- if (token === "7" || token === 7) {
996
- return weekdayNames[0];
997
- }
998
- return weekdayNames[token] || weekdayNames[weekdayTokens[token]];
1200
+ const number = toFieldNumber("" + token, weekdayNumbers);
1201
+ return weekdayNames[number === 7 ? 0 : number];
999
1202
  }
1000
1203
  function pluralWeekday(token) {
1001
1204
  const name = weekdayName(token);
1002
1205
  return name.endsWith("s") ? name : name + "s";
1003
1206
  }
1004
1207
  function monthName(token) {
1005
- return monthNames[token] || monthNames[monthTokens[token]];
1208
+ return monthNames[+token];
1006
1209
  }
1007
1210
  function isOpenStep(field) {
1008
1211
  return field.indexOf("/") !== -1 && field.indexOf("-") === -1 && field.indexOf(",") === -1;
@@ -1012,7 +1215,9 @@ var es2 = {
1012
1215
  fallback: "un patr\xF3n cron irreconocible",
1013
1216
  options: normalizeOptions,
1014
1217
  reboot: "al arrancar el sistema",
1015
- sentence: (description) => "Se ejecuta " + description + "."
1218
+ // A description ending in a period already carries it, so closing the
1219
+ // sentence must not double it.
1220
+ sentence: (description) => "Se ejecuta " + description + (description.endsWith(".") ? "" : ".")
1016
1221
  };
1017
1222
  var index_default = es2;
1018
1223
  module.exports = module.exports.default;