@sprucelabs/spruce-calendar-components 22.11.0 → 22.12.0

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.
@@ -0,0 +1,7 @@
1
+ export default class DateParser {
2
+ private now;
3
+ private parsers;
4
+ private constructor();
5
+ static Parser(now: () => number): DateParser;
6
+ parse(str: string): number;
7
+ }
@@ -0,0 +1,230 @@
1
+ import { dateUtil } from '@sprucelabs/calendar-utils';
2
+ import { assertOptions } from '@sprucelabs/schema';
3
+ export default class DateParser {
4
+ constructor(now) {
5
+ this.parsers = [];
6
+ this.now = now;
7
+ const parsers = ParserFactory.Factory(now);
8
+ this.parsers = [
9
+ parsers.Parser('Year'),
10
+ parsers.Parser('Month'),
11
+ parsers.Parser('Dow'),
12
+ parsers.Parser('Time'),
13
+ ];
14
+ }
15
+ static Parser(now) {
16
+ assertOptions({ now }, ['now']);
17
+ return new this(now);
18
+ }
19
+ parse(str) {
20
+ const now = this.now();
21
+ const date = dateUtil.splitDate(now);
22
+ let parsed = str.toLocaleLowerCase().replace(/[^a-z0-9: ]/g, '');
23
+ const context = {
24
+ hasYear: false,
25
+ };
26
+ if (str !== 'now') {
27
+ for (const parser of this.parsers) {
28
+ parsed = parser.parse(parsed, date, context);
29
+ }
30
+ }
31
+ let normalized = dateUtil.date(Object.assign(Object.assign({}, date), { milliseconds: 0, second: 0 }));
32
+ return normalized;
33
+ }
34
+ }
35
+ class ParserFactory {
36
+ constructor(now) {
37
+ this.strategies = {
38
+ Year: () => new YearParser(this.now),
39
+ Month: () => new MonthParser(this.now),
40
+ Dow: () => new DowParser(this.now),
41
+ Time: () => new TimeParser(this.now),
42
+ };
43
+ this.now = now;
44
+ }
45
+ static Factory(now) {
46
+ return new this(now);
47
+ }
48
+ Parser(parserType) {
49
+ return this.strategies[parserType]();
50
+ }
51
+ }
52
+ class AbstractParser {
53
+ constructor(now) {
54
+ this.now = now;
55
+ }
56
+ }
57
+ class TimeParser extends AbstractParser {
58
+ parse(str, date, context) {
59
+ var _a;
60
+ const match = (_a = str.match(/(\d{1,2})(:(\d{2}))? ?(am|pm)?/)) === null || _a === void 0 ? void 0 : _a[0];
61
+ if (!match) {
62
+ return str;
63
+ }
64
+ if (match) {
65
+ date.hour = parseInt(match, 10);
66
+ date.minute = 0;
67
+ }
68
+ if (str.includes(':')) {
69
+ date.minute = parseInt(str.split(':')[1], 10);
70
+ }
71
+ if (str.includes('pm')) {
72
+ date.hour += 12;
73
+ }
74
+ else if (date.hour === 12 && str.includes('am')) {
75
+ date.hour = 0;
76
+ }
77
+ if (!context.hasYear && dateUtil.date(date) < this.now() && str !== 'now') {
78
+ date.hour += 12;
79
+ }
80
+ return str;
81
+ }
82
+ }
83
+ class DowParser extends AbstractParser {
84
+ parse(str, date) {
85
+ var _a;
86
+ if (str.includes('tomorrow')) {
87
+ date.day += 1;
88
+ str = str.replace('tomorrow', '');
89
+ }
90
+ const dows = [
91
+ {
92
+ abbr: 'sun',
93
+ full: 'sunday',
94
+ },
95
+ {
96
+ abbr: 'mon',
97
+ full: 'monday',
98
+ },
99
+ {
100
+ abbr: 'tue',
101
+ full: 'tuesday',
102
+ },
103
+ {
104
+ abbr: 'wed',
105
+ full: 'wednesday',
106
+ },
107
+ {
108
+ abbr: 'thu',
109
+ full: 'thursday',
110
+ },
111
+ {
112
+ abbr: 'fri',
113
+ full: 'friday',
114
+ },
115
+ {
116
+ abbr: 'sat',
117
+ full: 'saturday',
118
+ },
119
+ ];
120
+ for (const dow of dows) {
121
+ const re = new RegExp(`(^|\\W)${dow.abbr}(\\W|$)`, 'gi');
122
+ str = str.replace(re, `$1${dow.full}$2`);
123
+ }
124
+ const match = (_a = str.match(/(monday|tuesday|wednesday|thursday|friday|saturday|sunday)/)) === null || _a === void 0 ? void 0 : _a[0];
125
+ if (match) {
126
+ while (dateUtil.format(dateUtil.date(date), 'EEEE').toLocaleLowerCase() !==
127
+ match) {
128
+ date.day += 1;
129
+ str = str.replace(match, '');
130
+ }
131
+ }
132
+ return str;
133
+ }
134
+ }
135
+ class YearParser extends AbstractParser {
136
+ parse(str, date, context) {
137
+ const matches = str.match(/\d{4}/);
138
+ if (matches) {
139
+ date.year = parseInt(matches[0], 10);
140
+ str = str.replace(matches[0], '');
141
+ context.hasYear = true;
142
+ }
143
+ return str;
144
+ }
145
+ }
146
+ class MonthParser extends AbstractParser {
147
+ parse(str, date) {
148
+ let normalized = str;
149
+ normalized = this.normalizeMonths(normalized);
150
+ const matches = normalized.match(/(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) ?(\d+)(?:nd|rd|th|st)?/i);
151
+ if (matches) {
152
+ date.month = [
153
+ 'jan',
154
+ 'feb',
155
+ 'mar',
156
+ 'apr',
157
+ 'may',
158
+ 'jun',
159
+ 'jul',
160
+ 'aug',
161
+ 'sep',
162
+ 'oct',
163
+ 'nov',
164
+ 'dec',
165
+ ].indexOf(matches[1]);
166
+ date.day = parseInt(matches[2], 10);
167
+ normalized = normalized.replace(matches[0], '');
168
+ return normalized;
169
+ }
170
+ return str;
171
+ }
172
+ normalizeMonths(normalized) {
173
+ const months = [
174
+ {
175
+ desired: 'jan',
176
+ possible: ['january'],
177
+ },
178
+ {
179
+ desired: 'feb',
180
+ possible: ['february'],
181
+ },
182
+ {
183
+ desired: 'mar',
184
+ possible: ['march'],
185
+ },
186
+ {
187
+ desired: 'apr',
188
+ possible: ['april'],
189
+ },
190
+ {
191
+ desired: 'may',
192
+ possible: ['may'],
193
+ },
194
+ {
195
+ desired: 'jun',
196
+ possible: ['june'],
197
+ },
198
+ {
199
+ desired: 'jul',
200
+ possible: ['july'],
201
+ },
202
+ {
203
+ desired: 'aug',
204
+ possible: ['august'],
205
+ },
206
+ {
207
+ desired: 'sep',
208
+ possible: ['september'],
209
+ },
210
+ {
211
+ desired: 'oct',
212
+ possible: ['october'],
213
+ },
214
+ {
215
+ desired: 'nov',
216
+ possible: ['november'],
217
+ },
218
+ {
219
+ desired: 'dec',
220
+ possible: ['december'],
221
+ },
222
+ ];
223
+ for (const month of months) {
224
+ for (const possible of month.possible) {
225
+ normalized = normalized.replace(possible, month.desired);
226
+ }
227
+ }
228
+ return normalized;
229
+ }
230
+ }
@@ -0,0 +1,7 @@
1
+ export default class DateParser {
2
+ private now;
3
+ private parsers;
4
+ private constructor();
5
+ static Parser(now: () => number): DateParser;
6
+ parse(str: string): number;
7
+ }
@@ -0,0 +1,233 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const calendar_utils_1 = require("@sprucelabs/calendar-utils");
4
+ const schema_1 = require("@sprucelabs/schema");
5
+ class DateParser {
6
+ constructor(now) {
7
+ this.parsers = [];
8
+ this.now = now;
9
+ const parsers = ParserFactory.Factory(now);
10
+ this.parsers = [
11
+ parsers.Parser('Year'),
12
+ parsers.Parser('Month'),
13
+ parsers.Parser('Dow'),
14
+ parsers.Parser('Time'),
15
+ ];
16
+ }
17
+ static Parser(now) {
18
+ (0, schema_1.assertOptions)({ now }, ['now']);
19
+ return new this(now);
20
+ }
21
+ parse(str) {
22
+ const now = this.now();
23
+ const date = calendar_utils_1.dateUtil.splitDate(now);
24
+ let parsed = str.toLocaleLowerCase().replace(/[^a-z0-9: ]/g, '');
25
+ const context = {
26
+ hasYear: false,
27
+ };
28
+ if (str !== 'now') {
29
+ for (const parser of this.parsers) {
30
+ parsed = parser.parse(parsed, date, context);
31
+ }
32
+ }
33
+ let normalized = calendar_utils_1.dateUtil.date(Object.assign(Object.assign({}, date), { milliseconds: 0, second: 0 }));
34
+ return normalized;
35
+ }
36
+ }
37
+ exports.default = DateParser;
38
+ class ParserFactory {
39
+ constructor(now) {
40
+ this.strategies = {
41
+ Year: () => new YearParser(this.now),
42
+ Month: () => new MonthParser(this.now),
43
+ Dow: () => new DowParser(this.now),
44
+ Time: () => new TimeParser(this.now),
45
+ };
46
+ this.now = now;
47
+ }
48
+ static Factory(now) {
49
+ return new this(now);
50
+ }
51
+ Parser(parserType) {
52
+ return this.strategies[parserType]();
53
+ }
54
+ }
55
+ class AbstractParser {
56
+ constructor(now) {
57
+ this.now = now;
58
+ }
59
+ }
60
+ class TimeParser extends AbstractParser {
61
+ parse(str, date, context) {
62
+ var _a;
63
+ const match = (_a = str.match(/(\d{1,2})(:(\d{2}))? ?(am|pm)?/)) === null || _a === void 0 ? void 0 : _a[0];
64
+ if (!match) {
65
+ return str;
66
+ }
67
+ if (match) {
68
+ date.hour = parseInt(match, 10);
69
+ date.minute = 0;
70
+ }
71
+ if (str.includes(':')) {
72
+ date.minute = parseInt(str.split(':')[1], 10);
73
+ }
74
+ if (str.includes('pm')) {
75
+ date.hour += 12;
76
+ }
77
+ else if (date.hour === 12 && str.includes('am')) {
78
+ date.hour = 0;
79
+ }
80
+ if (!context.hasYear && calendar_utils_1.dateUtil.date(date) < this.now() && str !== 'now') {
81
+ date.hour += 12;
82
+ }
83
+ return str;
84
+ }
85
+ }
86
+ class DowParser extends AbstractParser {
87
+ parse(str, date) {
88
+ var _a;
89
+ if (str.includes('tomorrow')) {
90
+ date.day += 1;
91
+ str = str.replace('tomorrow', '');
92
+ }
93
+ const dows = [
94
+ {
95
+ abbr: 'sun',
96
+ full: 'sunday',
97
+ },
98
+ {
99
+ abbr: 'mon',
100
+ full: 'monday',
101
+ },
102
+ {
103
+ abbr: 'tue',
104
+ full: 'tuesday',
105
+ },
106
+ {
107
+ abbr: 'wed',
108
+ full: 'wednesday',
109
+ },
110
+ {
111
+ abbr: 'thu',
112
+ full: 'thursday',
113
+ },
114
+ {
115
+ abbr: 'fri',
116
+ full: 'friday',
117
+ },
118
+ {
119
+ abbr: 'sat',
120
+ full: 'saturday',
121
+ },
122
+ ];
123
+ for (const dow of dows) {
124
+ const re = new RegExp(`(^|\\W)${dow.abbr}(\\W|$)`, 'gi');
125
+ str = str.replace(re, `$1${dow.full}$2`);
126
+ }
127
+ const match = (_a = str.match(/(monday|tuesday|wednesday|thursday|friday|saturday|sunday)/)) === null || _a === void 0 ? void 0 : _a[0];
128
+ if (match) {
129
+ while (calendar_utils_1.dateUtil.format(calendar_utils_1.dateUtil.date(date), 'EEEE').toLocaleLowerCase() !==
130
+ match) {
131
+ date.day += 1;
132
+ str = str.replace(match, '');
133
+ }
134
+ }
135
+ return str;
136
+ }
137
+ }
138
+ class YearParser extends AbstractParser {
139
+ parse(str, date, context) {
140
+ const matches = str.match(/\d{4}/);
141
+ if (matches) {
142
+ date.year = parseInt(matches[0], 10);
143
+ str = str.replace(matches[0], '');
144
+ context.hasYear = true;
145
+ }
146
+ return str;
147
+ }
148
+ }
149
+ class MonthParser extends AbstractParser {
150
+ parse(str, date) {
151
+ let normalized = str;
152
+ normalized = this.normalizeMonths(normalized);
153
+ const matches = normalized.match(/(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) ?(\d+)(?:nd|rd|th|st)?/i);
154
+ if (matches) {
155
+ date.month = [
156
+ 'jan',
157
+ 'feb',
158
+ 'mar',
159
+ 'apr',
160
+ 'may',
161
+ 'jun',
162
+ 'jul',
163
+ 'aug',
164
+ 'sep',
165
+ 'oct',
166
+ 'nov',
167
+ 'dec',
168
+ ].indexOf(matches[1]);
169
+ date.day = parseInt(matches[2], 10);
170
+ normalized = normalized.replace(matches[0], '');
171
+ return normalized;
172
+ }
173
+ return str;
174
+ }
175
+ normalizeMonths(normalized) {
176
+ const months = [
177
+ {
178
+ desired: 'jan',
179
+ possible: ['january'],
180
+ },
181
+ {
182
+ desired: 'feb',
183
+ possible: ['february'],
184
+ },
185
+ {
186
+ desired: 'mar',
187
+ possible: ['march'],
188
+ },
189
+ {
190
+ desired: 'apr',
191
+ possible: ['april'],
192
+ },
193
+ {
194
+ desired: 'may',
195
+ possible: ['may'],
196
+ },
197
+ {
198
+ desired: 'jun',
199
+ possible: ['june'],
200
+ },
201
+ {
202
+ desired: 'jul',
203
+ possible: ['july'],
204
+ },
205
+ {
206
+ desired: 'aug',
207
+ possible: ['august'],
208
+ },
209
+ {
210
+ desired: 'sep',
211
+ possible: ['september'],
212
+ },
213
+ {
214
+ desired: 'oct',
215
+ possible: ['october'],
216
+ },
217
+ {
218
+ desired: 'nov',
219
+ possible: ['november'],
220
+ },
221
+ {
222
+ desired: 'dec',
223
+ possible: ['december'],
224
+ },
225
+ ];
226
+ for (const month of months) {
227
+ for (const possible of month.possible) {
228
+ normalized = normalized.replace(possible, month.desired);
229
+ }
230
+ }
231
+ return normalized;
232
+ }
233
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sprucelabs/spruce-calendar-components",
3
3
  "description": "Calendar components for working with calendars and Sprucebot.",
4
- "version": "22.11.0",
4
+ "version": "22.12.0",
5
5
  "skill": {
6
6
  "namespace": "calendar"
7
7
  },
@@ -169,7 +169,11 @@
169
169
  "build/noSchedules/peopleToPeopleWithoutSchedules.js",
170
170
  "build/noSchedules/peopleToPeopleWithoutSchedules.d.ts",
171
171
  "build/esm/noSchedules/peopleToPeopleWithoutSchedules.js",
172
- "build/esm/noSchedules/peopleToPeopleWithoutSchedules.d.ts"
172
+ "build/esm/noSchedules/peopleToPeopleWithoutSchedules.d.ts",
173
+ "build/parsing/DateParser.js",
174
+ "build/parsing/DateParser.d.ts",
175
+ "build/esm/parsing/DateParser.js",
176
+ "build/esm/parsing/DateParser.d.ts"
173
177
  ],
174
178
  "keywords": [],
175
179
  "scripts": {
@@ -191,4 +195,4 @@
191
195
  "engines": {
192
196
  "yarn": "1.x"
193
197
  }
194
- }
198
+ }