@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.
- package/gcal.ts +4 -52
- package/glib/gutils.ts +5 -16
- 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
|
|
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
|
|
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
|
|
311
|
-
const
|
|
312
|
-
if (
|
|
313
|
-
const [, hour, min, ampm] =
|
|
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.
|
|
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.
|
|
41
|
-
},
|
|
42
|
-
"dependencies": {
|
|
43
|
-
"@bobfrankston/oauthsupport": "^1.0.
|
|
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
|
+
}
|