@marcfargas/go-easy 0.0.1 → 0.2.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.
- package/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/README.md +220 -0
- package/dist/auth.d.ts +41 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +91 -0
- package/dist/auth.js.map +1 -0
- package/dist/bin/calendar.d.ts +17 -0
- package/dist/bin/calendar.d.ts.map +1 -0
- package/dist/bin/calendar.js +162 -0
- package/dist/bin/calendar.js.map +1 -0
- package/dist/bin/drive.d.ts +18 -0
- package/dist/bin/drive.d.ts.map +1 -0
- package/dist/bin/drive.js +203 -0
- package/dist/bin/drive.js.map +1 -0
- package/dist/bin/gmail.d.ts +20 -0
- package/dist/bin/gmail.d.ts.map +1 -0
- package/dist/bin/gmail.js +171 -0
- package/dist/bin/gmail.js.map +1 -0
- package/dist/calendar/helpers.d.ts +23 -0
- package/dist/calendar/helpers.d.ts.map +1 -0
- package/dist/calendar/helpers.js +69 -0
- package/dist/calendar/helpers.js.map +1 -0
- package/dist/calendar/index.d.ts +64 -0
- package/dist/calendar/index.d.ts.map +1 -0
- package/dist/calendar/index.js +202 -0
- package/dist/calendar/index.js.map +1 -0
- package/dist/calendar/types.d.ts +107 -0
- package/dist/calendar/types.d.ts.map +1 -0
- package/dist/calendar/types.js +5 -0
- package/dist/calendar/types.js.map +1 -0
- package/dist/drive/helpers.d.ts +22 -0
- package/dist/drive/helpers.d.ts.map +1 -0
- package/dist/drive/helpers.js +85 -0
- package/dist/drive/helpers.js.map +1 -0
- package/dist/drive/index.d.ts +114 -0
- package/dist/drive/index.d.ts.map +1 -0
- package/dist/drive/index.js +418 -0
- package/dist/drive/index.js.map +1 -0
- package/dist/drive/types.d.ts +91 -0
- package/dist/drive/types.d.ts.map +1 -0
- package/dist/drive/types.js +5 -0
- package/dist/drive/types.js.map +1 -0
- package/dist/errors.d.ts +34 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +53 -0
- package/dist/errors.js.map +1 -0
- package/dist/gmail/helpers.d.ts +52 -0
- package/dist/gmail/helpers.d.ts.map +1 -0
- package/dist/gmail/helpers.js +282 -0
- package/dist/gmail/helpers.js.map +1 -0
- package/dist/gmail/index.d.ts +86 -0
- package/dist/gmail/index.d.ts.map +1 -0
- package/dist/gmail/index.js +395 -0
- package/dist/gmail/index.js.map +1 -0
- package/dist/gmail/types.d.ts +138 -0
- package/dist/gmail/types.d.ts.map +1 -0
- package/dist/gmail/types.js +5 -0
- package/dist/gmail/types.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/safety.d.ts +58 -0
- package/dist/safety.d.ts.map +1 -0
- package/dist/safety.js +61 -0
- package/dist/safety.js.map +1 -0
- package/package.json +48 -7
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# @marcfargas/go-easy
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`5f424e1`](https://github.com/marcfargas/go-easy/commit/5f424e16c3c9971c2be196725a5d9c1d7e88633b) Thanks [@marcfargas](https://github.com/marcfargas)! - Initial release — Gmail, Drive & Calendar APIs for AI agents and humans.
|
|
8
|
+
|
|
9
|
+
- Gmail: search, getMessage, getThread, send, reply, forward, createDraft, sendDraft, listDrafts, listLabels, batchModifyLabels, getAttachmentContent, getProfile
|
|
10
|
+
- Drive: listFiles, searchFiles, getFile, downloadFile, exportFile, uploadFile, createFolder, moveFile, renameFile, copyFile, trashFile, listPermissions, shareFile, unshareFile
|
|
11
|
+
- Calendar: listCalendars, listEvents, getEvent, createEvent, updateEvent, deleteEvent, queryFreeBusy
|
|
12
|
+
- Gateway CLIs: go-gmail, go-drive, go-calendar (JSON output, --confirm safety)
|
|
13
|
+
- Safety model: READ/WRITE/DESTRUCTIVE operation classification
|
|
14
|
+
- Auth: multi-account OAuth2 with per-service token stores
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Marc Fargas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# go-easy 🟢
|
|
2
|
+
|
|
3
|
+
> Google APIs made easy — Gmail, Drive & Calendar. For AI agents and humans.
|
|
4
|
+
|
|
5
|
+
Thin TypeScript wrappers over Google's individual `@googleapis/*` packages with:
|
|
6
|
+
- **Simple auth** — multi-account OAuth2 with token import from existing tools
|
|
7
|
+
- **Agent-friendly types** — structured `GmailMessage`, `DriveFile`, `CalendarEvent`
|
|
8
|
+
- **Safety guards** — destructive operations (send, share, delete) require explicit confirmation
|
|
9
|
+
- **JSON gateways** — CLI tools that always output structured JSON
|
|
10
|
+
- **Progressive skills** — designed for AI agent consumption (pi coding agent)
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# As a library
|
|
16
|
+
npm install @marcfargas/go-easy
|
|
17
|
+
|
|
18
|
+
# As CLI tools (no install needed)
|
|
19
|
+
npx go-gmail you@example.com search "is:unread"
|
|
20
|
+
npx go-drive you@example.com ls
|
|
21
|
+
npx go-calendar you@example.com events primary
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Requires **Node.js ≥ 20**.
|
|
25
|
+
|
|
26
|
+
## Auth Setup
|
|
27
|
+
|
|
28
|
+
go-easy uses OAuth2 tokens stored per-service. Each service reads from its own token store:
|
|
29
|
+
|
|
30
|
+
| Service | Token store |
|
|
31
|
+
|---|---|
|
|
32
|
+
| Gmail | `~/.gmcli/accounts.json` |
|
|
33
|
+
| Drive | `~/.gdcli/accounts.json` |
|
|
34
|
+
| Calendar | `~/.gccli/accounts.json` |
|
|
35
|
+
|
|
36
|
+
Each `accounts.json` file contains an array of accounts:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
[
|
|
40
|
+
{
|
|
41
|
+
"email": "you@example.com",
|
|
42
|
+
"oauth2": {
|
|
43
|
+
"clientId": "YOUR_CLIENT_ID.apps.googleusercontent.com",
|
|
44
|
+
"clientSecret": "YOUR_CLIENT_SECRET",
|
|
45
|
+
"refreshToken": "YOUR_REFRESH_TOKEN"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
To obtain credentials:
|
|
52
|
+
1. Create a project in [Google Cloud Console](https://console.cloud.google.com/)
|
|
53
|
+
2. Enable the Gmail, Drive, and/or Calendar APIs
|
|
54
|
+
3. Create OAuth2 credentials (Desktop application)
|
|
55
|
+
4. Use the OAuth2 playground or a local flow to obtain a refresh token
|
|
56
|
+
5. Place the token in the appropriate `accounts.json` file
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { getAuth } from '@marcfargas/go-easy/auth';
|
|
62
|
+
import { search, send } from '@marcfargas/go-easy/gmail';
|
|
63
|
+
|
|
64
|
+
const auth = await getAuth('gmail', 'you@example.com');
|
|
65
|
+
|
|
66
|
+
// Search (READ — no safety gate)
|
|
67
|
+
const results = await search(auth, { query: 'is:unread from:client' });
|
|
68
|
+
console.log(results.items);
|
|
69
|
+
|
|
70
|
+
// Send (DESTRUCTIVE — requires safety context)
|
|
71
|
+
import { setSafetyContext } from '@marcfargas/go-easy';
|
|
72
|
+
|
|
73
|
+
setSafetyContext({
|
|
74
|
+
confirm: async (op) => {
|
|
75
|
+
console.log(`⚠️ ${op.description}`);
|
|
76
|
+
return true; // or prompt the user
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
await send(auth, {
|
|
81
|
+
to: 'client@example.com',
|
|
82
|
+
subject: 'Invoice attached',
|
|
83
|
+
html: '<h1>Invoice</h1><p>Please find attached.</p>',
|
|
84
|
+
attachments: ['./invoice.pdf'],
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Gateway CLIs
|
|
89
|
+
|
|
90
|
+
All gateway CLIs output JSON to stdout and work via `npx`:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Gmail
|
|
94
|
+
npx go-gmail you@example.com search "is:unread" --max=10
|
|
95
|
+
npx go-gmail you@example.com get <messageId>
|
|
96
|
+
npx go-gmail you@example.com send --to=x@y.com --subject="Hi" --body="Hello" --confirm
|
|
97
|
+
|
|
98
|
+
# Drive
|
|
99
|
+
npx go-drive you@example.com ls
|
|
100
|
+
npx go-drive you@example.com search "quarterly report"
|
|
101
|
+
npx go-drive you@example.com upload ./file.pdf --folder=<folderId>
|
|
102
|
+
|
|
103
|
+
# Calendar
|
|
104
|
+
npx go-calendar you@example.com events primary --from=2026-02-01T00:00:00Z
|
|
105
|
+
npx go-calendar you@example.com create primary --summary="Meeting" --start=... --end=...
|
|
106
|
+
npx go-calendar you@example.com freebusy primary --from=... --to=...
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Destructive operations require `--confirm`. Without it, they show what *would* happen and exit with code 2.
|
|
110
|
+
|
|
111
|
+
## Services
|
|
112
|
+
|
|
113
|
+
| Service | Module | Gateway | Status |
|
|
114
|
+
|---------|--------|---------|--------|
|
|
115
|
+
| Gmail | `@marcfargas/go-easy/gmail` | `npx go-gmail` | ✅ Ready |
|
|
116
|
+
| Drive | `@marcfargas/go-easy/drive` | `npx go-drive` | ✅ Ready |
|
|
117
|
+
| Calendar | `@marcfargas/go-easy/calendar` | `npx go-calendar` | ✅ Ready |
|
|
118
|
+
|
|
119
|
+
### Gmail
|
|
120
|
+
|
|
121
|
+
| Function | Safety | Description |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| `search` | READ | Search messages by Gmail query |
|
|
124
|
+
| `getMessage` | READ | Get a single message with parsed fields |
|
|
125
|
+
| `getThread` | READ | Get a full conversation thread |
|
|
126
|
+
| `listLabels` | READ | List all labels |
|
|
127
|
+
| `getAttachmentContent` | READ | Download an attachment as Buffer |
|
|
128
|
+
| `getProfile` | READ | Get the authenticated email address |
|
|
129
|
+
| `createDraft` | WRITE | Create a draft (no send) |
|
|
130
|
+
| `listDrafts` | READ | List existing drafts |
|
|
131
|
+
| `batchModifyLabels` | WRITE | Add/remove labels on multiple messages |
|
|
132
|
+
| `send` | ⚠️ DESTRUCTIVE | Send a new email |
|
|
133
|
+
| `reply` | ⚠️ DESTRUCTIVE | Reply to a message (preserves thread) |
|
|
134
|
+
| `forward` | ⚠️ DESTRUCTIVE | Forward a message with attachments |
|
|
135
|
+
| `sendDraft` | ⚠️ DESTRUCTIVE | Send an existing draft |
|
|
136
|
+
|
|
137
|
+
### Drive
|
|
138
|
+
|
|
139
|
+
| Function | Safety | Description |
|
|
140
|
+
|---|---|---|
|
|
141
|
+
| `listFiles` | READ | List folder contents or query by metadata |
|
|
142
|
+
| `searchFiles` | READ | Full-text search inside file contents |
|
|
143
|
+
| `getFile` | READ | Get file metadata by ID |
|
|
144
|
+
| `downloadFile` | READ | Download binary files as Buffer |
|
|
145
|
+
| `exportFile` | READ | Export Workspace files (Docs → pdf/docx, Sheets → xlsx/csv, etc.) |
|
|
146
|
+
| `listPermissions` | READ | List sharing permissions on a file |
|
|
147
|
+
| `uploadFile` | WRITE | Upload a local file |
|
|
148
|
+
| `createFolder` | WRITE | Create a folder |
|
|
149
|
+
| `moveFile` | WRITE | Move a file to a different folder |
|
|
150
|
+
| `renameFile` | WRITE | Rename a file |
|
|
151
|
+
| `copyFile` | WRITE | Copy a file |
|
|
152
|
+
| `trashFile` | ⚠️ DESTRUCTIVE | Trash a file |
|
|
153
|
+
| `shareFile` | ⚠️ DESTRUCTIVE* | Share a file (*public sharing only; user/group is WRITE) |
|
|
154
|
+
| `unshareFile` | ⚠️ DESTRUCTIVE | Remove a sharing permission |
|
|
155
|
+
|
|
156
|
+
### Calendar
|
|
157
|
+
|
|
158
|
+
| Function | Safety | Description |
|
|
159
|
+
|---|---|---|
|
|
160
|
+
| `listCalendars` | READ | List all calendars for the account |
|
|
161
|
+
| `listEvents` | READ | List events with time range, search, pagination |
|
|
162
|
+
| `getEvent` | READ | Get a single event by ID |
|
|
163
|
+
| `queryFreeBusy` | READ | Check availability across calendars |
|
|
164
|
+
| `createEvent` | WRITE | Create an event (with attendees, all-day, location) |
|
|
165
|
+
| `updateEvent` | WRITE | Update an existing event |
|
|
166
|
+
| `deleteEvent` | ⚠️ DESTRUCTIVE | Delete an event (warns about attendee cancellation) |
|
|
167
|
+
|
|
168
|
+
## Safety Model
|
|
169
|
+
|
|
170
|
+
Operations are classified into three levels:
|
|
171
|
+
|
|
172
|
+
| Level | Gate | Examples |
|
|
173
|
+
|-------|------|----------|
|
|
174
|
+
| **READ** | None | search, getMessage, listLabels |
|
|
175
|
+
| **WRITE** | Logged | createDraft, batchModifyLabels, upload |
|
|
176
|
+
| **DESTRUCTIVE** | Blocked unless confirmed | send, reply, forward, share, delete |
|
|
177
|
+
|
|
178
|
+
Set up a `SafetyContext` at startup to handle confirmation prompts.
|
|
179
|
+
Without one, all destructive operations are blocked by default.
|
|
180
|
+
|
|
181
|
+
## Module Structure
|
|
182
|
+
|
|
183
|
+
go-easy uses **subpath exports** — import only what you need:
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
// Subpath imports (recommended)
|
|
187
|
+
import { getAuth } from '@marcfargas/go-easy/auth';
|
|
188
|
+
import { search, send } from '@marcfargas/go-easy/gmail';
|
|
189
|
+
import { listFiles, upload } from '@marcfargas/go-easy/drive';
|
|
190
|
+
import { listEvents, createEvent } from '@marcfargas/go-easy/calendar';
|
|
191
|
+
import { setSafetyContext } from '@marcfargas/go-easy'; // root: safety, errors, shared utils
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
| Import path | What's in it |
|
|
195
|
+
|---|---|
|
|
196
|
+
| `@marcfargas/go-easy` | Safety context, errors, plus `gmail`/`drive`/`calendar` as namespaces |
|
|
197
|
+
| `@marcfargas/go-easy/auth` | `getAuth`, `listAccounts`, `clearAuthCache` |
|
|
198
|
+
| `@marcfargas/go-easy/gmail` | All Gmail operations |
|
|
199
|
+
| `@marcfargas/go-easy/drive` | All Drive operations |
|
|
200
|
+
| `@marcfargas/go-easy/calendar` | All Calendar operations |
|
|
201
|
+
|
|
202
|
+
The root export also re-exports each service as a namespace, so `import { gmail } from '@marcfargas/go-easy'` works if you prefer a single import.
|
|
203
|
+
|
|
204
|
+
## Development
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
npm install # install deps
|
|
208
|
+
npm run build # compile TypeScript
|
|
209
|
+
npm test # run tests (vitest)
|
|
210
|
+
npm run lint # type-check without emitting
|
|
211
|
+
npm run dev # watch mode
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Contributing
|
|
215
|
+
|
|
216
|
+
Found a bug or have a feature request? [Open an issue](https://github.com/marcfargas/go-easy/issues).
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth module — OAuth2 client factory with multi-account support.
|
|
3
|
+
*
|
|
4
|
+
* Phase 1 (MVP): Import tokens from existing CLI stores:
|
|
5
|
+
* ~/.gmcli/accounts.json → Gmail tokens
|
|
6
|
+
* ~/.gdcli/accounts.json → Drive tokens
|
|
7
|
+
* ~/.gccli/accounts.json → Calendar tokens
|
|
8
|
+
*
|
|
9
|
+
* Phase 2 (post-migration): Unified token store at ~/.go-easy/
|
|
10
|
+
* with combined scopes per account (single OAuth consent).
|
|
11
|
+
*
|
|
12
|
+
* Each CLI token only works for its service's scopes. The library
|
|
13
|
+
* routes internally — callers specify account (email), and each
|
|
14
|
+
* service module gets the right OAuth2Client.
|
|
15
|
+
*/
|
|
16
|
+
import { OAuth2Client } from 'google-auth-library';
|
|
17
|
+
/** Services we can load tokens for */
|
|
18
|
+
export type GoogleService = 'gmail' | 'drive' | 'calendar';
|
|
19
|
+
/**
|
|
20
|
+
* Get an OAuth2Client for a specific service and account.
|
|
21
|
+
*
|
|
22
|
+
* @param service - Which Google service (determines which CLI token to use)
|
|
23
|
+
* @param account - Email address (defaults to first account in the store)
|
|
24
|
+
* @returns Configured OAuth2Client with refresh token set
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { getAuth } from 'go-easy/auth';
|
|
29
|
+
* const auth = await getAuth('gmail', 'marc@blegal.eu');
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function getAuth(service: GoogleService, account?: string): Promise<OAuth2Client>;
|
|
33
|
+
/**
|
|
34
|
+
* List available accounts for a service.
|
|
35
|
+
*/
|
|
36
|
+
export declare function listAccounts(service: GoogleService): Promise<string[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Clear the client cache. Useful for tests or token rotation.
|
|
39
|
+
*/
|
|
40
|
+
export declare function clearAuthCache(): void;
|
|
41
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,sCAAsC;AACtC,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;AAwC3D;;;;;;;;;;;;GAYG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CA+BvB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAG5E;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth module — OAuth2 client factory with multi-account support.
|
|
3
|
+
*
|
|
4
|
+
* Phase 1 (MVP): Import tokens from existing CLI stores:
|
|
5
|
+
* ~/.gmcli/accounts.json → Gmail tokens
|
|
6
|
+
* ~/.gdcli/accounts.json → Drive tokens
|
|
7
|
+
* ~/.gccli/accounts.json → Calendar tokens
|
|
8
|
+
*
|
|
9
|
+
* Phase 2 (post-migration): Unified token store at ~/.go-easy/
|
|
10
|
+
* with combined scopes per account (single OAuth consent).
|
|
11
|
+
*
|
|
12
|
+
* Each CLI token only works for its service's scopes. The library
|
|
13
|
+
* routes internally — callers specify account (email), and each
|
|
14
|
+
* service module gets the right OAuth2Client.
|
|
15
|
+
*/
|
|
16
|
+
import { readFile } from 'node:fs/promises';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import { OAuth2Client } from 'google-auth-library';
|
|
20
|
+
import { AuthError } from './errors.js';
|
|
21
|
+
/** Map service → CLI config directory name */
|
|
22
|
+
const CLI_DIRS = {
|
|
23
|
+
gmail: '.gmcli',
|
|
24
|
+
drive: '.gdcli',
|
|
25
|
+
calendar: '.gccli',
|
|
26
|
+
};
|
|
27
|
+
/** Cache: "service:email" → OAuth2Client */
|
|
28
|
+
const clientCache = new Map();
|
|
29
|
+
/**
|
|
30
|
+
* Load accounts from a CLI's accounts.json file.
|
|
31
|
+
*/
|
|
32
|
+
async function loadCliAccounts(service) {
|
|
33
|
+
const dir = CLI_DIRS[service];
|
|
34
|
+
const accountsPath = join(homedir(), dir, 'accounts.json');
|
|
35
|
+
try {
|
|
36
|
+
const raw = await readFile(accountsPath, 'utf-8');
|
|
37
|
+
return JSON.parse(raw);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
throw new AuthError(`Cannot read ${service} accounts from ${accountsPath}. Is the CLI configured?`, err);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get an OAuth2Client for a specific service and account.
|
|
45
|
+
*
|
|
46
|
+
* @param service - Which Google service (determines which CLI token to use)
|
|
47
|
+
* @param account - Email address (defaults to first account in the store)
|
|
48
|
+
* @returns Configured OAuth2Client with refresh token set
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { getAuth } from 'go-easy/auth';
|
|
53
|
+
* const auth = await getAuth('gmail', 'marc@blegal.eu');
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export async function getAuth(service, account) {
|
|
57
|
+
const accounts = await loadCliAccounts(service);
|
|
58
|
+
const entry = account
|
|
59
|
+
? accounts.find((a) => a.email === account)
|
|
60
|
+
: accounts[0];
|
|
61
|
+
if (!entry) {
|
|
62
|
+
const available = accounts.map((a) => a.email).join(', ');
|
|
63
|
+
throw new AuthError(account
|
|
64
|
+
? `Account "${account}" not found for ${service}. Available: ${available}`
|
|
65
|
+
: `No accounts configured for ${service}`);
|
|
66
|
+
}
|
|
67
|
+
const cacheKey = `${service}:${entry.email}`;
|
|
68
|
+
const cached = clientCache.get(cacheKey);
|
|
69
|
+
if (cached)
|
|
70
|
+
return cached;
|
|
71
|
+
const oauth2 = new OAuth2Client(entry.oauth2.clientId, entry.oauth2.clientSecret);
|
|
72
|
+
oauth2.setCredentials({
|
|
73
|
+
refresh_token: entry.oauth2.refreshToken,
|
|
74
|
+
});
|
|
75
|
+
clientCache.set(cacheKey, oauth2);
|
|
76
|
+
return oauth2;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* List available accounts for a service.
|
|
80
|
+
*/
|
|
81
|
+
export async function listAccounts(service) {
|
|
82
|
+
const accounts = await loadCliAccounts(service);
|
|
83
|
+
return accounts.map((a) => a.email);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Clear the client cache. Useful for tests or token rotation.
|
|
87
|
+
*/
|
|
88
|
+
export function clearAuthCache() {
|
|
89
|
+
clientCache.clear();
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* go-calendar — Gateway CLI for Google Calendar operations.
|
|
4
|
+
*
|
|
5
|
+
* Always outputs JSON. Designed for agent consumption.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* go-calendar <account> <command> [args...]
|
|
9
|
+
* go-calendar marc@blegal.eu calendars
|
|
10
|
+
* go-calendar marc@blegal.eu events primary --from=2026-02-01T00:00:00Z
|
|
11
|
+
* go-calendar marc@blegal.eu create primary --summary="Meeting" --start=... --end=...
|
|
12
|
+
*
|
|
13
|
+
* Safety:
|
|
14
|
+
* Destructive operations (delete) require --confirm flag.
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=calendar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../src/bin/calendar.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* go-calendar — Gateway CLI for Google Calendar operations.
|
|
4
|
+
*
|
|
5
|
+
* Always outputs JSON. Designed for agent consumption.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* go-calendar <account> <command> [args...]
|
|
9
|
+
* go-calendar marc@blegal.eu calendars
|
|
10
|
+
* go-calendar marc@blegal.eu events primary --from=2026-02-01T00:00:00Z
|
|
11
|
+
* go-calendar marc@blegal.eu create primary --summary="Meeting" --start=... --end=...
|
|
12
|
+
*
|
|
13
|
+
* Safety:
|
|
14
|
+
* Destructive operations (delete) require --confirm flag.
|
|
15
|
+
*/
|
|
16
|
+
import { getAuth } from '../auth.js';
|
|
17
|
+
import { setSafetyContext } from '../safety.js';
|
|
18
|
+
import * as calendar from '../calendar/index.js';
|
|
19
|
+
const args = process.argv.slice(2);
|
|
20
|
+
function usage() {
|
|
21
|
+
console.log(JSON.stringify({
|
|
22
|
+
error: 'USAGE',
|
|
23
|
+
message: 'go-calendar <account> <command> [args...]',
|
|
24
|
+
commands: {
|
|
25
|
+
calendars: 'go-calendar <account> calendars',
|
|
26
|
+
events: 'go-calendar <account> events <calendarId> [--from=<dt>] [--to=<dt>] [--max=N] [--query="..."]',
|
|
27
|
+
event: 'go-calendar <account> event <calendarId> <eventId>',
|
|
28
|
+
create: 'go-calendar <account> create <calendarId> --summary="..." --start=<dt> --end=<dt> [--description="..."] [--location="..."] [--attendees=a@b,c@d] [--all-day] [--tz=<tz>]',
|
|
29
|
+
update: 'go-calendar <account> update <calendarId> <eventId> --summary="..." --start=<dt> --end=<dt> [--description="..."] [--location="..."] [--attendees=a@b,c@d] [--all-day] [--tz=<tz>]',
|
|
30
|
+
delete: 'go-calendar <account> delete <calendarId> <eventId> [--confirm]',
|
|
31
|
+
freebusy: 'go-calendar <account> freebusy <calendarId1,calendarId2> --from=<dt> --to=<dt>',
|
|
32
|
+
},
|
|
33
|
+
}, null, 2));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
/** Parse --key=value flags from args */
|
|
37
|
+
function parseFlags(args) {
|
|
38
|
+
const flags = {};
|
|
39
|
+
for (const arg of args) {
|
|
40
|
+
const match = arg.match(/^--([^=]+)(?:=(.*))?$/);
|
|
41
|
+
if (match) {
|
|
42
|
+
flags[match[1]] = match[2] ?? 'true';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return flags;
|
|
46
|
+
}
|
|
47
|
+
/** Get positional args (non-flag) */
|
|
48
|
+
function positional(args) {
|
|
49
|
+
return args.filter((a) => !a.startsWith('--'));
|
|
50
|
+
}
|
|
51
|
+
async function main() {
|
|
52
|
+
if (args.length < 2)
|
|
53
|
+
usage();
|
|
54
|
+
const account = args[0];
|
|
55
|
+
const command = args[1];
|
|
56
|
+
const rest = args.slice(2);
|
|
57
|
+
const flags = parseFlags(rest);
|
|
58
|
+
const pos = positional(rest);
|
|
59
|
+
// Set up safety context: --confirm flag allows destructive ops
|
|
60
|
+
const hasConfirm = 'confirm' in flags;
|
|
61
|
+
setSafetyContext({
|
|
62
|
+
confirm: async (op) => {
|
|
63
|
+
if (!hasConfirm) {
|
|
64
|
+
console.log(JSON.stringify({
|
|
65
|
+
blocked: true,
|
|
66
|
+
operation: op.name,
|
|
67
|
+
description: op.description,
|
|
68
|
+
details: op.details,
|
|
69
|
+
hint: 'Add --confirm to execute this operation',
|
|
70
|
+
}, null, 2));
|
|
71
|
+
process.exit(2);
|
|
72
|
+
}
|
|
73
|
+
return true;
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
const auth = await getAuth('calendar', account);
|
|
77
|
+
try {
|
|
78
|
+
let result;
|
|
79
|
+
switch (command) {
|
|
80
|
+
case 'calendars':
|
|
81
|
+
result = await calendar.listCalendars(auth);
|
|
82
|
+
break;
|
|
83
|
+
case 'events':
|
|
84
|
+
if (!pos[0])
|
|
85
|
+
usage();
|
|
86
|
+
result = await calendar.listEvents(auth, pos[0], {
|
|
87
|
+
timeMin: flags.from,
|
|
88
|
+
timeMax: flags.to,
|
|
89
|
+
maxResults: flags.max ? parseInt(flags.max) : undefined,
|
|
90
|
+
query: flags.query,
|
|
91
|
+
});
|
|
92
|
+
break;
|
|
93
|
+
case 'event':
|
|
94
|
+
if (!pos[0] || !pos[1])
|
|
95
|
+
usage();
|
|
96
|
+
result = await calendar.getEvent(auth, pos[0], pos[1]);
|
|
97
|
+
break;
|
|
98
|
+
case 'create': {
|
|
99
|
+
if (!pos[0])
|
|
100
|
+
usage();
|
|
101
|
+
const createOpts = {
|
|
102
|
+
summary: flags.summary ?? '',
|
|
103
|
+
description: flags.description,
|
|
104
|
+
start: flags.start ?? '',
|
|
105
|
+
end: flags.end ?? '',
|
|
106
|
+
timeZone: flags.tz,
|
|
107
|
+
location: flags.location,
|
|
108
|
+
attendees: flags.attendees?.split(','),
|
|
109
|
+
allDay: 'all-day' in flags,
|
|
110
|
+
};
|
|
111
|
+
result = await calendar.createEvent(auth, pos[0], createOpts);
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
case 'update': {
|
|
115
|
+
if (!pos[0] || !pos[1])
|
|
116
|
+
usage();
|
|
117
|
+
const updateOpts = {
|
|
118
|
+
summary: flags.summary ?? '',
|
|
119
|
+
description: flags.description,
|
|
120
|
+
start: flags.start ?? '',
|
|
121
|
+
end: flags.end ?? '',
|
|
122
|
+
timeZone: flags.tz,
|
|
123
|
+
location: flags.location,
|
|
124
|
+
attendees: flags.attendees?.split(','),
|
|
125
|
+
allDay: 'all-day' in flags,
|
|
126
|
+
};
|
|
127
|
+
result = await calendar.updateEvent(auth, pos[0], pos[1], updateOpts);
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
case 'delete':
|
|
131
|
+
if (!pos[0] || !pos[1])
|
|
132
|
+
usage();
|
|
133
|
+
result = await calendar.deleteEvent(auth, pos[0], pos[1]);
|
|
134
|
+
break;
|
|
135
|
+
case 'freebusy': {
|
|
136
|
+
if (!pos[0] || !flags.from || !flags.to)
|
|
137
|
+
usage();
|
|
138
|
+
const calIds = pos[0].split(',');
|
|
139
|
+
result = await calendar.queryFreeBusy(auth, calIds, flags.from, flags.to);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
default:
|
|
143
|
+
usage();
|
|
144
|
+
}
|
|
145
|
+
console.log(JSON.stringify(result, null, 2));
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
const e = err;
|
|
149
|
+
if (typeof e.toJSON === 'function') {
|
|
150
|
+
console.error(JSON.stringify(e.toJSON(), null, 2));
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
console.error(JSON.stringify({
|
|
154
|
+
error: e.code ?? 'UNKNOWN',
|
|
155
|
+
message: e.message ?? String(err),
|
|
156
|
+
}, null, 2));
|
|
157
|
+
}
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
main();
|
|
162
|
+
//# sourceMappingURL=calendar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.js","sourceRoot":"","sources":["../../src/bin/calendar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* go-drive — Gateway CLI for Google Drive operations.
|
|
4
|
+
*
|
|
5
|
+
* Always outputs JSON. Designed for agent consumption.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* go-drive <account> <command> [args...]
|
|
9
|
+
* go-drive marc@blegal.eu ls
|
|
10
|
+
* go-drive marc@blegal.eu search "quarterly report"
|
|
11
|
+
* go-drive marc@blegal.eu download <fileId>
|
|
12
|
+
* go-drive marc@blegal.eu upload ./file.pdf --folder=<folderId>
|
|
13
|
+
*
|
|
14
|
+
* Safety:
|
|
15
|
+
* Destructive operations (trash, share --anyone, unshare) require --confirm flag.
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=drive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive.d.ts","sourceRoot":"","sources":["../../src/bin/drive.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG"}
|