@bobfrankston/gcards 0.1.35 → 0.1.36
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/.claude/settings.local.json +12 -1
- package/README.md +25 -6
- package/gcards.ts +14 -5
- package/package.json +3 -2
|
@@ -23,7 +23,18 @@
|
|
|
23
23
|
"WebFetch(domain:lh3.googleusercontent.com)",
|
|
24
24
|
"Bash(curl:*)",
|
|
25
25
|
"Bash(bun build:*)",
|
|
26
|
-
"Bash(xargs -I {} sh -c 'echo \"\"=== {} ===\"\" && head -20 {}')"
|
|
26
|
+
"Bash(xargs -I {} sh -c 'echo \"\"=== {} ===\"\" && head -20 {}')",
|
|
27
|
+
"Bash(del \"y:\\\\dev\\\\utils\\\\cardx\\\\gcards\\\\data\\\\bobfrankston\\\\token.json\" \"y:\\\\dev\\\\utils\\\\cardx\\\\gcards\\\\data\\\\bobfrankston\\\\token-write.json\")",
|
|
28
|
+
"Bash(echo:*)",
|
|
29
|
+
"Bash(npm whoami:*)",
|
|
30
|
+
"Bash(npm run build:*)",
|
|
31
|
+
"Bash(npm publish:*)",
|
|
32
|
+
"Bash(npm version:*)",
|
|
33
|
+
"Bash(npm link)",
|
|
34
|
+
"Bash(npm link:*)",
|
|
35
|
+
"Bash(cmd /c \"dir /AL\")",
|
|
36
|
+
"Bash(node gcards.ts:*)",
|
|
37
|
+
"Bash(npm run release:*)"
|
|
27
38
|
],
|
|
28
39
|
"deny": [],
|
|
29
40
|
"ask": []
|
package/README.md
CHANGED
|
@@ -261,12 +261,31 @@ After export, run `gcards push -u <target>` to upload.
|
|
|
261
261
|
|
|
262
262
|
## Setup
|
|
263
263
|
|
|
264
|
-
### Google API
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
264
|
+
### Google API Credentials (Required)
|
|
265
|
+
|
|
266
|
+
Each user must create their own Google Cloud credentials. This is a one-time setup:
|
|
267
|
+
|
|
268
|
+
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
269
|
+
2. Create a new project (e.g., "gcards")
|
|
270
|
+
3. Enable the **People API**:
|
|
271
|
+
- Go to APIs & Services > Library
|
|
272
|
+
- Search for "People API" and enable it
|
|
273
|
+
4. Configure OAuth consent screen:
|
|
274
|
+
- Go to APIs & Services > OAuth consent screen
|
|
275
|
+
- Choose "External" user type
|
|
276
|
+
- Fill in app name and email fields
|
|
277
|
+
- Add scope: `https://www.googleapis.com/auth/contacts`
|
|
278
|
+
5. Create OAuth credentials:
|
|
279
|
+
- Go to APIs & Services > Credentials
|
|
280
|
+
- Click "+ CREATE CREDENTIALS" > "OAuth client ID"
|
|
281
|
+
- Choose "Web application"
|
|
282
|
+
- Add redirect URI: `http://localhost:9326/oauth2callback`
|
|
283
|
+
- Click Create and download the JSON file
|
|
284
|
+
6. Save as `credentials.json` in the gcards install directory:
|
|
285
|
+
- Find install location: `npm list -g @bobfrankston/gcards`
|
|
286
|
+
- Or run gcards once to see the expected path in the error message
|
|
287
|
+
|
|
288
|
+
For detailed instructions, see: [SETUP-GOOGLE-OAUTH.md](https://github.com/BobFrankston/oauthsupport/blob/master/SETUP-GOOGLE-OAUTH.md)
|
|
270
289
|
|
|
271
290
|
### AI Error Explanations (Optional)
|
|
272
291
|
|
package/gcards.ts
CHANGED
|
@@ -10,7 +10,7 @@ import path from 'path';
|
|
|
10
10
|
import crypto from 'crypto';
|
|
11
11
|
import { parse as parseJsonc } from 'jsonc-parser';
|
|
12
12
|
import { parseArgs, showUsage, showHelp } from './glib/parsecli.ts';
|
|
13
|
-
import { authenticateOAuth } from '
|
|
13
|
+
import { authenticateOAuth } from '@bobfrankston/oauthsupport';
|
|
14
14
|
import type { GooglePerson, GoogleConnectionsResponse } from './glib/types.ts';
|
|
15
15
|
import { GCARDS_GUID_KEY, extractGuids } from './glib/gctypes.ts';
|
|
16
16
|
import type { ContactIndex, IndexEntry, DeletedEntry, DeleteQueue, DeleteQueueEntry, PushStatus, PendingChange, UserPaths } from './glib/gctypes.ts';
|
|
@@ -87,7 +87,15 @@ function cleanupEscapeHandler(): void {
|
|
|
87
87
|
|
|
88
88
|
async function getAccessToken(user: string, writeAccess = false, forceRefresh = false): Promise<string> {
|
|
89
89
|
if (!fs.existsSync(CREDENTIALS_FILE)) {
|
|
90
|
-
|
|
90
|
+
console.error(`\nCredentials file not found: ${CREDENTIALS_FILE}\n`);
|
|
91
|
+
console.error(`To use gcards, you need to create your own Google Cloud credentials:`);
|
|
92
|
+
console.error(` 1. Go to https://console.cloud.google.com/`);
|
|
93
|
+
console.error(` 2. Create a project and enable the People API`);
|
|
94
|
+
console.error(` 3. Create OAuth 2.0 credentials (Web application type)`);
|
|
95
|
+
console.error(` 4. Add redirect URI: http://localhost:9326/oauth2callback`);
|
|
96
|
+
console.error(` 5. Download credentials.json to: ${CREDENTIALS_FILE}\n`);
|
|
97
|
+
console.error(`See: https://github.com/BobFrankston/oauthsupport/blob/master/SETUP-GOOGLE-OAUTH.md`);
|
|
98
|
+
process.exit(1);
|
|
91
99
|
}
|
|
92
100
|
|
|
93
101
|
const paths = getUserPaths(user);
|
|
@@ -108,9 +116,10 @@ async function getAccessToken(user: string, writeAccess = false, forceRefresh =
|
|
|
108
116
|
tokenDirectory: paths.userDir,
|
|
109
117
|
tokenFileName,
|
|
110
118
|
credentialsKey: 'web',
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
119
|
+
signal: abortController?.signal
|
|
120
|
+
// includeOfflineAccess defaults to true - auto-requests refresh token
|
|
121
|
+
// prompt auto-detects when consent is needed for refresh token
|
|
122
|
+
// maxTokenLifetimeHours defaults to unlimited (uses refresh token indefinitely)
|
|
114
123
|
});
|
|
115
124
|
|
|
116
125
|
if (!token) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/gcards",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.36",
|
|
4
4
|
"description": "Google Contacts cleanup and management tool",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "gcards.ts",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"tsx": "^4.21.0"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@bobfrankston/miscassists": "
|
|
36
|
+
"@bobfrankston/miscassists": "^1.0.36",
|
|
37
|
+
"@bobfrankston/oauthsupport": "^1.0.1",
|
|
37
38
|
"jsonc-parser": "^3.3.1"
|
|
38
39
|
}
|
|
39
40
|
}
|