@bobfrankston/gcal 0.1.9 → 0.1.11

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.
Files changed (3) hide show
  1. package/gcal.ts +4 -52
  2. package/glib/gutils.ts +5 -16
  3. package/package.json +50 -46
package/gcal.ts CHANGED
@@ -90,8 +90,7 @@ async function listEvents(
90
90
  accessToken: string,
91
91
  calendarId = 'primary',
92
92
  maxResults = 10,
93
- timeMin?: string,
94
- timeMax?: string
93
+ timeMin?: string
95
94
  ): Promise<GoogleEvent[]> {
96
95
  const params = new URLSearchParams({
97
96
  maxResults: maxResults.toString(),
@@ -99,9 +98,6 @@ async function listEvents(
99
98
  orderBy: 'startTime',
100
99
  timeMin: timeMin || new Date().toISOString()
101
100
  });
102
- if (timeMax) {
103
- params.set('timeMax', timeMax);
104
- }
105
101
 
106
102
  const url = `${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events?${params}`;
107
103
  const res = await apiFetch(url, accessToken);
@@ -243,18 +239,14 @@ Options:
243
239
  -defaultUser <email> Set default user for future use
244
240
  -c, -calendar <id> Calendar ID (default: primary)
245
241
  -n <count> Number of events to list
246
- -after <when> List events after this date/time
247
- -before <when> List events before this date/time
248
242
  -v, -verbose Show event IDs and links
249
243
 
250
244
  Examples:
251
245
  gcal meeting.ics Import ICS file
252
246
  gcal list List next 10 events
253
- gcal list -after tomorrow -before "jan 30"
254
247
  gcal add "Dentist" "Friday 3pm" "1h"
255
248
  gcal add "Lunch" "1/14/2026 12:00" "1h"
256
- gcal add "Meeting" "tomorrow 10am"
257
- gcal add "Call" "3pm" "30m"
249
+ gcal add "Meeting" "tomorrow 10:00"
258
250
  gcal add "Appointment" "jan 15 2pm"
259
251
  gcal -defaultUser bob@gmail.com Set default user
260
252
 
@@ -274,8 +266,6 @@ interface ParsedArgs {
274
266
  help: boolean;
275
267
  verbose: boolean;
276
268
  icsFile: string; /** Direct .ics file path */
277
- after: string; /** Filter: events after this date/time */
278
- before: string; /** Filter: events before this date/time */
279
269
  }
280
270
 
281
271
  function parseArgs(argv: string[]): ParsedArgs {
@@ -288,9 +278,7 @@ function parseArgs(argv: string[]): ParsedArgs {
288
278
  count: 10,
289
279
  help: false,
290
280
  verbose: false,
291
- icsFile: '',
292
- after: '',
293
- before: ''
281
+ icsFile: ''
294
282
  };
295
283
 
296
284
  const unknown: string[] = [];
@@ -315,14 +303,6 @@ function parseArgs(argv: string[]): ParsedArgs {
315
303
  case '-n':
316
304
  result.count = parseInt(argv[++i]) || 10;
317
305
  break;
318
- case '-after':
319
- case '--after':
320
- result.after = argv[++i] || '';
321
- break;
322
- case '-before':
323
- case '--before':
324
- result.before = argv[++i] || '';
325
- break;
326
306
  case '-v':
327
307
  case '-verbose':
328
308
  case '--verbose':
@@ -448,9 +428,7 @@ async function main(): Promise<void> {
448
428
  case 'list': {
449
429
  const count = parsed.args[0] ? parseInt(parsed.args[0]) : parsed.count;
450
430
  const token = await getAccessToken(user, false);
451
- const timeMin = parsed.after ? parseDateTime(parsed.after).toISOString() : undefined;
452
- const timeMax = parsed.before ? parseDateTime(parsed.before).toISOString() : undefined;
453
- const events = await listEvents(token, parsed.calendar, count, timeMin, timeMax);
431
+ const events = await listEvents(token, parsed.calendar, count);
454
432
 
455
433
  if (events.length === 0) {
456
434
  console.log('No upcoming events found.');
@@ -506,32 +484,6 @@ async function main(): Promise<void> {
506
484
  const durationMins = parseDuration(duration);
507
485
  const endTime = new Date(startTime.getTime() + durationMins * 60 * 1000);
508
486
 
509
- // Check for suspicious dates (likely parsing errors)
510
- const now = new Date();
511
- const twoYearsFromNow = new Date(now);
512
- twoYearsFromNow.setFullYear(twoYearsFromNow.getFullYear() + 2);
513
-
514
- let warning = '';
515
- if (startTime < now) {
516
- warning = `Date is in the past: ${formatDateTime({ dateTime: startTime.toISOString() })}`;
517
- } else if (startTime > twoYearsFromNow) {
518
- warning = `Date is more than 2 years away: ${formatDateTime({ dateTime: startTime.toISOString() })}`;
519
- }
520
-
521
- if (warning) {
522
- console.log(`\nWarning: ${warning}`);
523
- console.log(`Input was: "${when}"`);
524
- const readline = await import('readline');
525
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
526
- const response = await new Promise<string>(resolve => {
527
- rl.question('Continue? (y/N) ', answer => { rl.close(); resolve(answer); });
528
- });
529
- if (response.toLowerCase() !== 'y') {
530
- console.log('Cancelled.');
531
- process.exit(0);
532
- }
533
- }
534
-
535
487
  const event: GoogleEvent = {
536
488
  summary: title,
537
489
  start: {
package/glib/gutils.ts CHANGED
@@ -307,29 +307,18 @@ export function parseDateTime(input: string): Date {
307
307
  return d;
308
308
  }
309
309
 
310
- // Handle time with am/pm: "10am", "3pm", "10:30am", "3:45pm" - assume today
311
- const timeAmPmMatch = lower.match(/^(\d{1,2})(?::(\d{2}))?\s*(am|pm)$/);
312
- if (timeAmPmMatch) {
313
- const [, hour, min, ampm] = timeAmPmMatch;
314
- const d = new Date(now);
310
+ // Handle time with am/pm (2pm, 10am, 2:30pm) - assume today
311
+ const ampmMatch = lower.match(/^(\d{1,2})(?::(\d{2}))?\s*(am|pm)$/);
312
+ if (ampmMatch) {
313
+ const [, hour, min, ampm] = ampmMatch;
315
314
  let h = parseInt(hour);
316
315
  if (ampm === 'pm' && h < 12) h += 12;
317
316
  if (ampm === 'am' && h === 12) h = 0;
317
+ const d = new Date(now);
318
318
  d.setHours(h, parseInt(min || '0'), 0, 0);
319
319
  return d;
320
320
  }
321
321
 
322
- // Handle bare hour: "10", "14" - interpret as today at that hour (not a month)
323
- const bareHourMatch = input.match(/^(\d{1,2})$/);
324
- if (bareHourMatch) {
325
- const hour = parseInt(bareHourMatch[1]);
326
- if (hour >= 0 && hour <= 23) {
327
- const d = new Date(now);
328
- d.setHours(hour, 0, 0, 0);
329
- return d;
330
- }
331
- }
332
-
333
322
  // Try native Date parsing
334
323
  const parsed = new Date(input);
335
324
  if (!isNaN(parsed.getTime())) {
package/package.json CHANGED
@@ -1,46 +1,50 @@
1
- {
2
- "name": "@bobfrankston/gcal",
3
- "version": "0.1.9",
4
- "description": "Google Calendar CLI tool with ICS import support",
5
- "type": "module",
6
- "main": "gcal.ts",
7
- "bin": {
8
- "gcal": "gcal.ts"
9
- },
10
- "files": [
11
- "gcal.ts",
12
- "glib/**/*.ts",
13
- "tsconfig.json",
14
- "README.md"
15
- ],
16
- "repository": {
17
- "type": "git",
18
- "url": "git+https://github.com/BobFrankston/gcal.git"
19
- },
20
- "scripts": {
21
- "check": "tsc --noEmit",
22
- "prerelease:local": "git add -A && (git diff-index --quiet HEAD || git commit -m \"Pre-release commit\")",
23
- "preversion": "npm run check && git add -A",
24
- "postversion": "git push && git push --tags",
25
- "release": "npm run prerelease:local && npm version patch && npm publish --access public",
26
- "release:local": "npm run prerelease:local && npm version patch && npm publish --access public --ignore-scripts",
27
- "installer": "npm run release && npm install -g ."
28
- },
29
- "keywords": [
30
- "google",
31
- "calendar",
32
- "ics",
33
- "ical",
34
- "oauth",
35
- "cli"
36
- ],
37
- "author": "Bob Frankston",
38
- "license": "MIT",
39
- "devDependencies": {
40
- "@types/node": "^25.0.3"
41
- },
42
- "dependencies": {
43
- "@bobfrankston/oauthsupport": "^1.0.1",
44
- "ical.js": "^2.1.0"
45
- }
46
- }
1
+ {
2
+ "name": "@bobfrankston/gcal",
3
+ "version": "0.1.11",
4
+ "description": "Google Calendar CLI tool with ICS import support",
5
+ "type": "module",
6
+ "main": "gcal.ts",
7
+ "bin": {
8
+ "gcal": "gcal.ts"
9
+ },
10
+ "files": [
11
+ "gcal.ts",
12
+ "glib/**/*.ts",
13
+ "tsconfig.json",
14
+ "README.md"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/BobFrankston/gcal.git"
19
+ },
20
+ "scripts": {
21
+ "check": "tsc --noEmit",
22
+ "prerelease:local": "git add -A && (git diff-index --quiet HEAD || git commit -m \"Pre-release commit\")",
23
+ "preversion": "npm run check && git add -A",
24
+ "postversion": "git push && git push --tags",
25
+ "release": "npm run prerelease:local && npm version patch && npm publish --access public",
26
+ "release:local": "npm run prerelease:local && npm version patch && npm publish --access public --ignore-scripts",
27
+ "installer": "npm run release && npm install -g ."
28
+ },
29
+ "keywords": [
30
+ "google",
31
+ "calendar",
32
+ "ics",
33
+ "ical",
34
+ "oauth",
35
+ "cli"
36
+ ],
37
+ "author": "Bob Frankston",
38
+ "license": "MIT",
39
+ "devDependencies": {
40
+ "@types/node": "^25.0.9"
41
+ },
42
+ "dependencies": {
43
+ "@bobfrankston/oauthsupport": "^1.0.5",
44
+ "ical.js": "^2.1.0"
45
+ },
46
+ ".dependencies": {
47
+ "@bobfrankston/oauthsupport": "file:../../../projects/OAuth/OauthSupport",
48
+ "ical.js": "^2.1.0"
49
+ }
50
+ }