@ncukondo/gcal-cli 0.1.0 → 0.1.3
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/index.js +130 -6
- package/package.json +5 -1
package/dist/index.js
CHANGED
|
@@ -587628,6 +587628,28 @@ function formatEventListText(events) {
|
|
|
587628
587628
|
return lines.join(`
|
|
587629
587629
|
`);
|
|
587630
587630
|
}
|
|
587631
|
+
function formatSearchEventLine(event) {
|
|
587632
|
+
const date3 = getDateKey(event);
|
|
587633
|
+
const time3 = formatTimeRange(event).padEnd(11);
|
|
587634
|
+
if (event.all_day) {
|
|
587635
|
+
return `${date3} ${time3} ${event.title} (${event.calendar_name})`;
|
|
587636
|
+
}
|
|
587637
|
+
const tag = transparencyTag(event);
|
|
587638
|
+
return `${date3} ${time3} ${event.title} (${event.calendar_name}) ${tag}`;
|
|
587639
|
+
}
|
|
587640
|
+
function formatSearchResultText(query, events) {
|
|
587641
|
+
const count = events.length;
|
|
587642
|
+
const plural = count === 1 ? "event" : "events";
|
|
587643
|
+
if (count === 0)
|
|
587644
|
+
return `Found 0 events matching "${query}".`;
|
|
587645
|
+
const header = `Found ${count} ${plural} matching "${query}":`;
|
|
587646
|
+
const lines = [header, ""];
|
|
587647
|
+
for (const event of events) {
|
|
587648
|
+
lines.push(formatSearchEventLine(event));
|
|
587649
|
+
}
|
|
587650
|
+
return lines.join(`
|
|
587651
|
+
`);
|
|
587652
|
+
}
|
|
587631
587653
|
var CALENDAR_ID_MAX = 15;
|
|
587632
587654
|
var CALENDAR_ID_COL = 18;
|
|
587633
587655
|
function truncateId(id) {
|
|
@@ -588140,9 +588162,16 @@ async function listEvents(api2, calendarId, calendarName, options) {
|
|
|
588140
588162
|
mapApiError(error);
|
|
588141
588163
|
}
|
|
588142
588164
|
}
|
|
588143
|
-
async function getEvent(api2, calendarId, calendarName, eventId) {
|
|
588165
|
+
async function getEvent(api2, calendarId, calendarName, eventId, timeZone) {
|
|
588144
588166
|
try {
|
|
588145
|
-
const
|
|
588167
|
+
const params = {
|
|
588168
|
+
calendarId,
|
|
588169
|
+
eventId
|
|
588170
|
+
};
|
|
588171
|
+
if (timeZone) {
|
|
588172
|
+
params.timeZone = timeZone;
|
|
588173
|
+
}
|
|
588174
|
+
const response = await api2.events.get(params);
|
|
588146
588175
|
return normalizeEvent(response.data, calendarId, calendarName);
|
|
588147
588176
|
} catch (error) {
|
|
588148
588177
|
mapApiError(error);
|
|
@@ -588216,7 +588245,7 @@ function isGoogleApiError(error) {
|
|
|
588216
588245
|
return error instanceof Error && "code" in error && typeof error.code === "number";
|
|
588217
588246
|
}
|
|
588218
588247
|
function isAuthRequiredError(error) {
|
|
588219
|
-
return error instanceof ApiError && error.code === "AUTH_REQUIRED";
|
|
588248
|
+
return (error instanceof ApiError || error instanceof AuthError) && (error.code === "AUTH_REQUIRED" || error.code === "AUTH_EXPIRED");
|
|
588220
588249
|
}
|
|
588221
588250
|
function mapApiError(error) {
|
|
588222
588251
|
if (isGoogleApiError(error)) {
|
|
@@ -590427,6 +590456,65 @@ function parseDateTimeInZone(dateStr, timezone) {
|
|
|
590427
590456
|
}
|
|
590428
590457
|
|
|
590429
590458
|
// src/commands/search.ts
|
|
590459
|
+
var DEFAULT_SEARCH_DAYS = 30;
|
|
590460
|
+
async function handleSearch(opts) {
|
|
590461
|
+
const { api: api2, query, format: format3, calendars, timezone, write } = opts;
|
|
590462
|
+
const writeErr = opts.writeErr ?? (() => {});
|
|
590463
|
+
const now = new Date;
|
|
590464
|
+
const days = opts.days ?? DEFAULT_SEARCH_DAYS;
|
|
590465
|
+
const isNegativeDays = days < 0;
|
|
590466
|
+
let timeMin;
|
|
590467
|
+
let timeMax;
|
|
590468
|
+
if (opts.from && opts.to) {
|
|
590469
|
+
timeMin = formatDateTimeInZone(parseDateTimeInZone(opts.from, timezone), timezone);
|
|
590470
|
+
timeMax = formatDateTimeInZone(parseDateTimeInZone(opts.to + "T23:59:59", timezone), timezone);
|
|
590471
|
+
} else if (opts.from) {
|
|
590472
|
+
const startDate = parseDateTimeInZone(opts.from, timezone);
|
|
590473
|
+
timeMin = formatDateTimeInZone(startDate, timezone);
|
|
590474
|
+
const endDate = new Date(startDate.getTime());
|
|
590475
|
+
endDate.setDate(endDate.getDate() + days);
|
|
590476
|
+
timeMax = formatDateTimeInZone(endDate, timezone);
|
|
590477
|
+
} else if (opts.to) {
|
|
590478
|
+
timeMax = formatDateTimeInZone(parseDateTimeInZone(opts.to + "T23:59:59", timezone), timezone);
|
|
590479
|
+
timeMin = formatDateTimeInZone(now, timezone);
|
|
590480
|
+
} else if (isNegativeDays) {
|
|
590481
|
+
const pastDate = new Date(now.getTime());
|
|
590482
|
+
pastDate.setDate(pastDate.getDate() + days);
|
|
590483
|
+
timeMin = formatDateTimeInZone(pastDate, timezone);
|
|
590484
|
+
timeMax = formatDateTimeInZone(now, timezone);
|
|
590485
|
+
} else {
|
|
590486
|
+
timeMin = formatDateTimeInZone(now, timezone);
|
|
590487
|
+
const endDate = new Date(now.getTime());
|
|
590488
|
+
endDate.setDate(endDate.getDate() + days);
|
|
590489
|
+
timeMax = formatDateTimeInZone(endDate, timezone);
|
|
590490
|
+
}
|
|
590491
|
+
const displayFrom = timeMin.slice(0, 10);
|
|
590492
|
+
const displayTo = timeMax.slice(0, 10);
|
|
590493
|
+
writeErr(`Searching: ${displayFrom} to ${displayTo}`);
|
|
590494
|
+
const hasExplicitRange = opts.days !== undefined || opts.from !== undefined || opts.to !== undefined;
|
|
590495
|
+
if (!hasExplicitRange) {
|
|
590496
|
+
writeErr("Tip: Use --days <n> or --from/--to to change the search range.");
|
|
590497
|
+
}
|
|
590498
|
+
const results = await Promise.all(calendars.map((cal) => listEvents(api2, cal.id, cal.name, { timeMin, timeMax, q: query })));
|
|
590499
|
+
const allEvents = results.flat();
|
|
590500
|
+
const transparency = opts.busy ? "busy" : opts.free ? "free" : undefined;
|
|
590501
|
+
const filterOpts = { transparency };
|
|
590502
|
+
if (opts.confirmed !== undefined)
|
|
590503
|
+
filterOpts.confirmed = opts.confirmed;
|
|
590504
|
+
if (opts.includeTentative !== undefined)
|
|
590505
|
+
filterOpts.includeTentative = opts.includeTentative;
|
|
590506
|
+
const filtered = applyFilters(allEvents, filterOpts);
|
|
590507
|
+
if (format3 === "json") {
|
|
590508
|
+
write(formatJsonSuccess({
|
|
590509
|
+
query,
|
|
590510
|
+
events: filtered,
|
|
590511
|
+
count: filtered.length
|
|
590512
|
+
}));
|
|
590513
|
+
} else {
|
|
590514
|
+
write(formatSearchResultText(query, filtered));
|
|
590515
|
+
}
|
|
590516
|
+
return { exitCode: ExitCode.SUCCESS };
|
|
590517
|
+
}
|
|
590430
590518
|
function createSearchCommand() {
|
|
590431
590519
|
const cmd = new Command("search").description("Search events by keyword").argument("<query>", "Search query string");
|
|
590432
590520
|
cmd.option("--from <date>", "Start date for search range");
|
|
@@ -590447,9 +590535,9 @@ function createSearchCommand() {
|
|
|
590447
590535
|
|
|
590448
590536
|
// src/commands/show.ts
|
|
590449
590537
|
async function handleShow(opts) {
|
|
590450
|
-
const { api: api2, eventId, calendarId, calendarName, format: format3, write } = opts;
|
|
590538
|
+
const { api: api2, eventId, calendarId, calendarName, format: format3, timezone, write } = opts;
|
|
590451
590539
|
try {
|
|
590452
|
-
const event = await getEvent(api2, calendarId, calendarName, eventId);
|
|
590540
|
+
const event = await getEvent(api2, calendarId, calendarName, eventId, timezone);
|
|
590453
590541
|
if (format3 === "json") {
|
|
590454
590542
|
write(formatJsonSuccess({ event }));
|
|
590455
590543
|
} else {
|
|
@@ -592127,7 +592215,41 @@ ${url}`);
|
|
|
592127
592215
|
}
|
|
592128
592216
|
});
|
|
592129
592217
|
program2.addCommand(listCmd);
|
|
592130
|
-
|
|
592218
|
+
const searchCmd = createSearchCommand();
|
|
592219
|
+
searchCmd.action(async (query) => {
|
|
592220
|
+
const globalOpts = resolveGlobalOptions2(program2);
|
|
592221
|
+
const searchOpts = searchCmd.opts();
|
|
592222
|
+
try {
|
|
592223
|
+
const config2 = loadConfig(fsAdapter);
|
|
592224
|
+
const auth = await getAuthenticatedClient(fsAdapter);
|
|
592225
|
+
const calendarApi = import_googleapis2.google.calendar({ version: "v3", auth });
|
|
592226
|
+
const api2 = createGoogleCalendarApi(calendarApi);
|
|
592227
|
+
const timezone = resolveTimezone(globalOpts.timezone, config2.timezone);
|
|
592228
|
+
const calendars = selectCalendars(globalOpts.calendar, config2);
|
|
592229
|
+
const result = await handleSearch({
|
|
592230
|
+
api: api2,
|
|
592231
|
+
query,
|
|
592232
|
+
format: globalOpts.format,
|
|
592233
|
+
calendars,
|
|
592234
|
+
timezone,
|
|
592235
|
+
days: searchOpts.days,
|
|
592236
|
+
from: searchOpts.from,
|
|
592237
|
+
to: searchOpts.to,
|
|
592238
|
+
busy: searchOpts.busy,
|
|
592239
|
+
free: searchOpts.free,
|
|
592240
|
+
confirmed: searchOpts.confirmed,
|
|
592241
|
+
includeTentative: searchOpts.includeTentative,
|
|
592242
|
+
write: (msg) => process.stdout.write(msg + `
|
|
592243
|
+
`),
|
|
592244
|
+
writeErr: (msg) => process.stderr.write(msg + `
|
|
592245
|
+
`)
|
|
592246
|
+
});
|
|
592247
|
+
process.exit(result.exitCode);
|
|
592248
|
+
} catch (error) {
|
|
592249
|
+
handleError2(error, globalOpts.format);
|
|
592250
|
+
}
|
|
592251
|
+
});
|
|
592252
|
+
program2.addCommand(searchCmd);
|
|
592131
592253
|
const showCmd = createShowCommand();
|
|
592132
592254
|
showCmd.action(async () => {
|
|
592133
592255
|
const globalOpts = resolveGlobalOptions2(program2);
|
|
@@ -592146,12 +592268,14 @@ ${url}`);
|
|
|
592146
592268
|
const enabled = config2.calendars.filter((c) => c.enabled);
|
|
592147
592269
|
cal = enabled[0] ?? { id: "primary", name: "Primary" };
|
|
592148
592270
|
}
|
|
592271
|
+
const timezone = resolveTimezone(globalOpts.timezone, config2.timezone);
|
|
592149
592272
|
const result = await handleShow({
|
|
592150
592273
|
api: api2,
|
|
592151
592274
|
eventId: showCmd.args[0],
|
|
592152
592275
|
calendarId: cal.id,
|
|
592153
592276
|
calendarName: cal.name,
|
|
592154
592277
|
format: globalOpts.format,
|
|
592278
|
+
timezone,
|
|
592155
592279
|
write: (msg) => process.stdout.write(msg + `
|
|
592156
592280
|
`)
|
|
592157
592281
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ncukondo/gcal-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dist/index.js"
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"dist"
|
|
13
13
|
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/ncukondo/gcal-cli"
|
|
17
|
+
},
|
|
14
18
|
"publishConfig": {
|
|
15
19
|
"access": "public"
|
|
16
20
|
},
|