gworkspace 0.2.1
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/README.md +184 -0
- package/bun.lock +220 -0
- package/dist/auth/index.impl.js +49 -0
- package/dist/auth/index.js +55 -0
- package/dist/auth/oauth.js +101 -0
- package/dist/auth/token.js +23 -0
- package/dist/cli.js +99 -0
- package/dist/commands/calendar.js +47 -0
- package/dist/commands/chat.js +82 -0
- package/dist/commands/drive.js +52 -0
- package/dist/commands/gmail.js +72 -0
- package/dist/commands/time.js +31 -0
- package/dist/config.js +23 -0
- package/dist/index.js +7 -0
- package/dist/lib/args.js +65 -0
- package/dist/lib/io.js +11 -0
- package/dist/lib/types.js +1 -0
- package/dist/usage.js +90 -0
- package/docs/auth.md +56 -0
- package/docs/commands.md +63 -0
- package/package.json +24 -0
- package/src/auth/index.ts +65 -0
- package/src/auth/oauth.ts +120 -0
- package/src/auth/token.ts +30 -0
- package/src/cli.ts +114 -0
- package/src/commands/calendar.ts +52 -0
- package/src/commands/chat.ts +89 -0
- package/src/commands/drive.ts +61 -0
- package/src/commands/gmail.ts +80 -0
- package/src/commands/time.ts +34 -0
- package/src/config.ts +32 -0
- package/src/index.ts +9 -0
- package/src/lib/args.ts +73 -0
- package/src/lib/io.ts +17 -0
- package/src/lib/types.ts +5 -0
- package/src/usage.ts +104 -0
- package/tsconfig.json +13 -0
package/README.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# gw
|
|
2
|
+
|
|
3
|
+
`gw` is a native Google Workspace CLI with direct Google API access.
|
|
4
|
+
It is built for direct execution: less ceremony, more signal.
|
|
5
|
+
|
|
6
|
+
## What it does
|
|
7
|
+
|
|
8
|
+
- Browser-based OAuth login (localhost callback)
|
|
9
|
+
- Calendar read access (event listing)
|
|
10
|
+
- Gmail read access (search + metadata fetch)
|
|
11
|
+
- Drive read access (search + recent + file metadata)
|
|
12
|
+
- Google Chat read access (spaces + messages)
|
|
13
|
+
- Time utilities for reliable local/UTC context
|
|
14
|
+
- Compatibility aliases for Workspace-style command names
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
1. Create a Google Cloud **Desktop OAuth client**.
|
|
19
|
+
2. Download the OAuth client JSON.
|
|
20
|
+
3. Save it to `~/.config/gworkspace/credentials.json` (or pass `--credentials`).
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
gw auth login
|
|
24
|
+
gw auth status
|
|
25
|
+
gw time now
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`auth login` opens your browser, waits for OAuth callback on localhost, then stores token at `~/.config/gworkspace/token.json`.
|
|
29
|
+
|
|
30
|
+
## Install and run
|
|
31
|
+
|
|
32
|
+
### Run from source
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bun install
|
|
36
|
+
bun run build
|
|
37
|
+
node dist/index.js --help
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Install globally (optional)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
bun install -g .
|
|
44
|
+
gw --help
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Help
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
gw --help
|
|
51
|
+
gw -h
|
|
52
|
+
gw help
|
|
53
|
+
gw help auth
|
|
54
|
+
gw auth --help
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Common workflows
|
|
58
|
+
|
|
59
|
+
### Morning context pull
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
gw time now
|
|
63
|
+
gw calendar list --from 2026-02-18T00:00:00Z --to 2026-02-18T23:59:59Z
|
|
64
|
+
gw gmail search --query "newer_than:1d" --max 20
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Project document scan
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
gw drive search --query "name contains 'spec' and trashed = false"
|
|
71
|
+
gw drive get --id <fileId>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Message triage
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
gw gmail search --query "is:unread newer_than:7d" --max 25
|
|
78
|
+
gw gmail get --id <messageId>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Command surface
|
|
82
|
+
|
|
83
|
+
### Auth
|
|
84
|
+
|
|
85
|
+
- `gw auth login [--credentials path/to/credentials.json] [--no-open]`
|
|
86
|
+
- `gw auth status`
|
|
87
|
+
- `gw auth logout`
|
|
88
|
+
|
|
89
|
+
### Calendar
|
|
90
|
+
|
|
91
|
+
- `gw calendar list --from <ISO> --to <ISO> [--calendarId primary] [--max 20]`
|
|
92
|
+
- `gw calendar list today [--calendarId primary] [--max 20]`
|
|
93
|
+
|
|
94
|
+
### Gmail
|
|
95
|
+
|
|
96
|
+
- `gw gmail search --query "<gmail query>" [--max 20] [--pageToken <token>]`
|
|
97
|
+
- `gw gmail list today [--max 20]`
|
|
98
|
+
- `gw gmail get --id <messageId>`
|
|
99
|
+
|
|
100
|
+
### Drive
|
|
101
|
+
|
|
102
|
+
- `gw drive search --query "<drive query>" [--max 20]`
|
|
103
|
+
- `gw drive recent [--max 20]`
|
|
104
|
+
- `gw drive get --id <fileId>`
|
|
105
|
+
|
|
106
|
+
### Time
|
|
107
|
+
|
|
108
|
+
- `gw time now`
|
|
109
|
+
- `gw time date`
|
|
110
|
+
- `gw time zone`
|
|
111
|
+
|
|
112
|
+
### Chat
|
|
113
|
+
|
|
114
|
+
- `gw chat spaces [--max 20] [--filter "spaceType = SPACE"] [--pageToken <token>]`
|
|
115
|
+
- `gw chat messages --space spaces/<spaceId> [--max 20] [--orderBy "createTime desc"] [--pageToken <token>]`
|
|
116
|
+
- `gw chat list today --space spaces/<spaceId> [--max 20]`
|
|
117
|
+
|
|
118
|
+
## Workspace-style aliases (compat)
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
gw calendar_getEvents --timeMin 2026-02-18T00:00:00Z --timeMax 2026-02-19T00:00:00Z
|
|
122
|
+
gw gmail_search --query "newer_than:7d" --max 20
|
|
123
|
+
gw drive_search --query "trashed = false" --max 20
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Security notes
|
|
127
|
+
|
|
128
|
+
- OAuth tokens are stored locally, not committed by default.
|
|
129
|
+
- Uses Desktop OAuth credentials JSON for browser login.
|
|
130
|
+
- Scopes are read-only:
|
|
131
|
+
- `calendar.readonly`
|
|
132
|
+
- `gmail.readonly`
|
|
133
|
+
- `drive.readonly`
|
|
134
|
+
- `chat.spaces.readonly`
|
|
135
|
+
- `chat.messages.readonly`
|
|
136
|
+
- If you rotate credentials, run `gw auth logout` then `gw auth login`.
|
|
137
|
+
|
|
138
|
+
## Troubleshooting
|
|
139
|
+
|
|
140
|
+
- `Credentials file not found`
|
|
141
|
+
- Create/download Desktop OAuth credentials and pass `--credentials /path/to/credentials.json`, or place it at `~/.config/gworkspace/credentials.json`.
|
|
142
|
+
- Browser did not open
|
|
143
|
+
- Run `gw auth login --no-open` and open the URL manually.
|
|
144
|
+
- Login timeout
|
|
145
|
+
- Re-run login and complete consent in the browser within the timeout window.
|
|
146
|
+
- `No token found`
|
|
147
|
+
- Run `gw auth login` first.
|
|
148
|
+
|
|
149
|
+
## Docs
|
|
150
|
+
|
|
151
|
+
- `docs/auth.md` - OAuth browser flow, token storage, and troubleshooting.
|
|
152
|
+
- `docs/commands.md` - full command reference and examples.
|
|
153
|
+
|
|
154
|
+
## Repo layout
|
|
155
|
+
|
|
156
|
+
```text
|
|
157
|
+
src/
|
|
158
|
+
index.ts # tiny entrypoint
|
|
159
|
+
cli.ts # command routing
|
|
160
|
+
usage.ts # help output
|
|
161
|
+
config.ts # paths + scopes
|
|
162
|
+
auth/
|
|
163
|
+
index.ts # auth commands + authorize()
|
|
164
|
+
oauth.ts # browser OAuth flow
|
|
165
|
+
token.ts # token read/write/delete
|
|
166
|
+
commands/
|
|
167
|
+
calendar.ts
|
|
168
|
+
gmail.ts
|
|
169
|
+
drive.ts
|
|
170
|
+
chat.ts
|
|
171
|
+
time.ts
|
|
172
|
+
lib/
|
|
173
|
+
args.ts # argv parsing helpers
|
|
174
|
+
io.ts # JSON output + fail handling
|
|
175
|
+
types.ts # shared types
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Development
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
bun run check
|
|
182
|
+
bun run build
|
|
183
|
+
node dist/index.js --help
|
|
184
|
+
```
|
package/bun.lock
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "gworkspace",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"googleapis": "^171.0.0",
|
|
9
|
+
"open": "^10.1.2",
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@types/node": "^24.3.0",
|
|
13
|
+
"typescript": "^5.9.3",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
"packages": {
|
|
18
|
+
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
|
|
19
|
+
|
|
20
|
+
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
|
|
21
|
+
|
|
22
|
+
"@types/node": ["@types/node@24.10.13", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg=="],
|
|
23
|
+
|
|
24
|
+
"agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
|
|
25
|
+
|
|
26
|
+
"ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
|
|
27
|
+
|
|
28
|
+
"ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
|
29
|
+
|
|
30
|
+
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
|
31
|
+
|
|
32
|
+
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
|
33
|
+
|
|
34
|
+
"bignumber.js": ["bignumber.js@9.3.1", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="],
|
|
35
|
+
|
|
36
|
+
"brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
|
37
|
+
|
|
38
|
+
"buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="],
|
|
39
|
+
|
|
40
|
+
"bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="],
|
|
41
|
+
|
|
42
|
+
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
|
43
|
+
|
|
44
|
+
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
|
|
45
|
+
|
|
46
|
+
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
|
47
|
+
|
|
48
|
+
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
|
49
|
+
|
|
50
|
+
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
|
51
|
+
|
|
52
|
+
"data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="],
|
|
53
|
+
|
|
54
|
+
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
|
55
|
+
|
|
56
|
+
"default-browser": ["default-browser@5.5.0", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw=="],
|
|
57
|
+
|
|
58
|
+
"default-browser-id": ["default-browser-id@5.0.1", "", {}, "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q=="],
|
|
59
|
+
|
|
60
|
+
"define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="],
|
|
61
|
+
|
|
62
|
+
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
|
63
|
+
|
|
64
|
+
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
|
|
65
|
+
|
|
66
|
+
"ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="],
|
|
67
|
+
|
|
68
|
+
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
|
69
|
+
|
|
70
|
+
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
|
71
|
+
|
|
72
|
+
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
|
73
|
+
|
|
74
|
+
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
|
|
75
|
+
|
|
76
|
+
"extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
|
|
77
|
+
|
|
78
|
+
"fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="],
|
|
79
|
+
|
|
80
|
+
"foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
|
|
81
|
+
|
|
82
|
+
"formdata-polyfill": ["formdata-polyfill@4.0.10", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="],
|
|
83
|
+
|
|
84
|
+
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
|
85
|
+
|
|
86
|
+
"gaxios": ["gaxios@7.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2", "rimraf": "^5.0.1" } }, "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ=="],
|
|
87
|
+
|
|
88
|
+
"gcp-metadata": ["gcp-metadata@8.1.2", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="],
|
|
89
|
+
|
|
90
|
+
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
|
91
|
+
|
|
92
|
+
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
|
|
93
|
+
|
|
94
|
+
"glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
|
|
95
|
+
|
|
96
|
+
"google-auth-library": ["google-auth-library@10.5.0", "", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^7.0.0", "gcp-metadata": "^8.0.0", "google-logging-utils": "^1.0.0", "gtoken": "^8.0.0", "jws": "^4.0.0" } }, "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w=="],
|
|
97
|
+
|
|
98
|
+
"google-logging-utils": ["google-logging-utils@1.1.3", "", {}, "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA=="],
|
|
99
|
+
|
|
100
|
+
"googleapis": ["googleapis@171.4.0", "", { "dependencies": { "google-auth-library": "^10.2.0", "googleapis-common": "^8.0.0" } }, "sha512-xybFL2SmmUgIifgsbsRQYRdNrSAYwxWZDmkZTGjUIaRnX5jPqR8el/cEvo6rCqh7iaZx6MfEPS/lrDgZ0bymkg=="],
|
|
101
|
+
|
|
102
|
+
"googleapis-common": ["googleapis-common@8.0.1", "", { "dependencies": { "extend": "^3.0.2", "gaxios": "^7.0.0-rc.4", "google-auth-library": "^10.1.0", "qs": "^6.7.0", "url-template": "^2.0.8" } }, "sha512-eCzNACUXPb1PW5l0ULTzMHaL/ltPRADoPgjBlT8jWsTbxkCp6siv+qKJ/1ldaybCthGwsYFYallF7u9AkU4L+A=="],
|
|
103
|
+
|
|
104
|
+
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
|
105
|
+
|
|
106
|
+
"gtoken": ["gtoken@8.0.0", "", { "dependencies": { "gaxios": "^7.0.0", "jws": "^4.0.0" } }, "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw=="],
|
|
107
|
+
|
|
108
|
+
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
|
|
109
|
+
|
|
110
|
+
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
|
111
|
+
|
|
112
|
+
"https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
|
113
|
+
|
|
114
|
+
"is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="],
|
|
115
|
+
|
|
116
|
+
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
|
|
117
|
+
|
|
118
|
+
"is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="],
|
|
119
|
+
|
|
120
|
+
"is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="],
|
|
121
|
+
|
|
122
|
+
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
|
123
|
+
|
|
124
|
+
"jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
|
|
125
|
+
|
|
126
|
+
"json-bigint": ["json-bigint@1.0.0", "", { "dependencies": { "bignumber.js": "^9.0.0" } }, "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ=="],
|
|
127
|
+
|
|
128
|
+
"jwa": ["jwa@2.0.1", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg=="],
|
|
129
|
+
|
|
130
|
+
"jws": ["jws@4.0.1", "", { "dependencies": { "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA=="],
|
|
131
|
+
|
|
132
|
+
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
|
133
|
+
|
|
134
|
+
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
|
135
|
+
|
|
136
|
+
"minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
|
137
|
+
|
|
138
|
+
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
|
139
|
+
|
|
140
|
+
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
|
141
|
+
|
|
142
|
+
"node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="],
|
|
143
|
+
|
|
144
|
+
"node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
|
|
145
|
+
|
|
146
|
+
"object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
|
|
147
|
+
|
|
148
|
+
"open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="],
|
|
149
|
+
|
|
150
|
+
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
|
|
151
|
+
|
|
152
|
+
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
|
153
|
+
|
|
154
|
+
"path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
|
|
155
|
+
|
|
156
|
+
"qs": ["qs@6.15.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ=="],
|
|
157
|
+
|
|
158
|
+
"rimraf": ["rimraf@5.0.10", "", { "dependencies": { "glob": "^10.3.7" }, "bin": { "rimraf": "dist/esm/bin.mjs" } }, "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ=="],
|
|
159
|
+
|
|
160
|
+
"run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="],
|
|
161
|
+
|
|
162
|
+
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
|
163
|
+
|
|
164
|
+
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
|
165
|
+
|
|
166
|
+
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
|
167
|
+
|
|
168
|
+
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
|
|
169
|
+
|
|
170
|
+
"side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
|
|
171
|
+
|
|
172
|
+
"side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
|
|
173
|
+
|
|
174
|
+
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
|
|
175
|
+
|
|
176
|
+
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
|
|
177
|
+
|
|
178
|
+
"string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
|
|
179
|
+
|
|
180
|
+
"string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
|
181
|
+
|
|
182
|
+
"strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
|
|
183
|
+
|
|
184
|
+
"strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
|
185
|
+
|
|
186
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
187
|
+
|
|
188
|
+
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
|
189
|
+
|
|
190
|
+
"url-template": ["url-template@2.0.8", "", {}, "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw=="],
|
|
191
|
+
|
|
192
|
+
"web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="],
|
|
193
|
+
|
|
194
|
+
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
|
195
|
+
|
|
196
|
+
"wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
|
|
197
|
+
|
|
198
|
+
"wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
|
199
|
+
|
|
200
|
+
"wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="],
|
|
201
|
+
|
|
202
|
+
"string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
|
203
|
+
|
|
204
|
+
"string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
|
205
|
+
|
|
206
|
+
"strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
|
207
|
+
|
|
208
|
+
"wrap-ansi-cjs/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
|
209
|
+
|
|
210
|
+
"wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
|
211
|
+
|
|
212
|
+
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
|
213
|
+
|
|
214
|
+
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
|
215
|
+
|
|
216
|
+
"wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
|
217
|
+
|
|
218
|
+
"wrap-ansi-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
|
219
|
+
}
|
|
220
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { SCOPES, TOKEN_PATH, resolveCredentialsPath } from '../config';
|
|
3
|
+
import { fail, output } from '../lib/io';
|
|
4
|
+
import { createOAuthClient, runBrowserOAuthFlow } from './oauth';
|
|
5
|
+
import { clearToken, loadSavedToken, saveToken } from './token';
|
|
6
|
+
export async function authorize(credentialsPath) {
|
|
7
|
+
const oauth = createOAuthClient(credentialsPath, 0);
|
|
8
|
+
const token = loadSavedToken();
|
|
9
|
+
if (token) {
|
|
10
|
+
oauth.setCredentials(token);
|
|
11
|
+
return oauth;
|
|
12
|
+
}
|
|
13
|
+
fail('No token found. Run `gworkspace auth login` first.', {
|
|
14
|
+
tokenPath: TOKEN_PATH,
|
|
15
|
+
credentialsPath,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export function commandAuthStatus() {
|
|
19
|
+
const token = loadSavedToken();
|
|
20
|
+
output({
|
|
21
|
+
ok: true,
|
|
22
|
+
action: 'auth.status',
|
|
23
|
+
authenticated: !!token,
|
|
24
|
+
tokenPath: TOKEN_PATH,
|
|
25
|
+
scopes: SCOPES,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export async function commandAuthLogin(options) {
|
|
29
|
+
const credentialsPath = resolveCredentialsPath(options);
|
|
30
|
+
if (!fs.existsSync(credentialsPath)) {
|
|
31
|
+
fail('Credentials file not found.', { credentialsPath });
|
|
32
|
+
}
|
|
33
|
+
const noOpen = options['no-open'] === true;
|
|
34
|
+
const result = await runBrowserOAuthFlow(credentialsPath, noOpen);
|
|
35
|
+
saveToken(result.credentials);
|
|
36
|
+
output({
|
|
37
|
+
ok: true,
|
|
38
|
+
action: 'auth.login',
|
|
39
|
+
credentialsPath,
|
|
40
|
+
tokenPath: TOKEN_PATH,
|
|
41
|
+
browserOpened: result.browserOpened,
|
|
42
|
+
callbackPort: result.callbackPort,
|
|
43
|
+
scopes: SCOPES,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
export function commandAuthLogout() {
|
|
47
|
+
clearToken();
|
|
48
|
+
output({ ok: true, action: 'auth.logout', tokenPath: TOKEN_PATH });
|
|
49
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { google } from 'googleapis';
|
|
3
|
+
import { SCOPES, TOKEN_PATH, resolveCredentialsPath } from '../config.js';
|
|
4
|
+
import { fail, output } from '../lib/io.js';
|
|
5
|
+
import { createOAuthClient, runBrowserOAuthFlow } from './oauth.js';
|
|
6
|
+
import { clearToken, loadSavedToken, saveToken } from './token.js';
|
|
7
|
+
export async function authorize(credentialsPath) {
|
|
8
|
+
const token = loadSavedToken();
|
|
9
|
+
if (token) {
|
|
10
|
+
const oauth = fs.existsSync(credentialsPath)
|
|
11
|
+
? createOAuthClient(credentialsPath, 0)
|
|
12
|
+
: new google.auth.OAuth2();
|
|
13
|
+
oauth.setCredentials(token);
|
|
14
|
+
return oauth;
|
|
15
|
+
}
|
|
16
|
+
if (!fs.existsSync(credentialsPath)) {
|
|
17
|
+
fail('Credentials file not found.', { credentialsPath });
|
|
18
|
+
}
|
|
19
|
+
fail('No token found. Run `gw auth login` first.', {
|
|
20
|
+
tokenPath: TOKEN_PATH,
|
|
21
|
+
credentialsPath,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
export function commandAuthStatus() {
|
|
25
|
+
const token = loadSavedToken();
|
|
26
|
+
output({
|
|
27
|
+
ok: true,
|
|
28
|
+
action: 'auth.status',
|
|
29
|
+
authenticated: !!token,
|
|
30
|
+
tokenPath: TOKEN_PATH,
|
|
31
|
+
scopes: SCOPES,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export async function commandAuthLogin(options) {
|
|
35
|
+
const credentialsPath = resolveCredentialsPath(options);
|
|
36
|
+
if (!fs.existsSync(credentialsPath)) {
|
|
37
|
+
fail('Credentials file not found.', { credentialsPath });
|
|
38
|
+
}
|
|
39
|
+
const noOpen = options['no-open'] === true;
|
|
40
|
+
const result = await runBrowserOAuthFlow(credentialsPath, noOpen);
|
|
41
|
+
saveToken(result.credentials);
|
|
42
|
+
output({
|
|
43
|
+
ok: true,
|
|
44
|
+
action: 'auth.login',
|
|
45
|
+
credentialsPath,
|
|
46
|
+
tokenPath: TOKEN_PATH,
|
|
47
|
+
browserOpened: result.browserOpened,
|
|
48
|
+
callbackPort: result.callbackPort,
|
|
49
|
+
scopes: SCOPES,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export function commandAuthLogout() {
|
|
53
|
+
clearToken();
|
|
54
|
+
output({ ok: true, action: 'auth.logout', tokenPath: TOKEN_PATH });
|
|
55
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import http from 'node:http';
|
|
3
|
+
import net from 'node:net';
|
|
4
|
+
import { URL } from 'node:url';
|
|
5
|
+
import { google } from 'googleapis';
|
|
6
|
+
import open from 'open';
|
|
7
|
+
import { SCOPES } from '../config.js';
|
|
8
|
+
import { fail } from '../lib/io.js';
|
|
9
|
+
export function createOAuthClient(credentialsPath, port) {
|
|
10
|
+
const credentials = JSON.parse(fs.readFileSync(credentialsPath, 'utf8'));
|
|
11
|
+
const payload = credentials.installed || credentials.web;
|
|
12
|
+
if (!payload?.client_id || !payload?.client_secret) {
|
|
13
|
+
fail('Invalid credentials file. Expected installed/web OAuth client JSON.');
|
|
14
|
+
}
|
|
15
|
+
const redirectUri = port > 0 ? `http://127.0.0.1:${port}/oauth2callback` : 'http://127.0.0.1';
|
|
16
|
+
return new google.auth.OAuth2(payload.client_id, payload.client_secret, redirectUri);
|
|
17
|
+
}
|
|
18
|
+
export function getAvailablePort() {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
const server = net.createServer();
|
|
21
|
+
server.listen(0, '127.0.0.1', () => {
|
|
22
|
+
const address = server.address();
|
|
23
|
+
if (!address || typeof address === 'string') {
|
|
24
|
+
server.close(() => reject(new Error('Could not allocate callback port.')));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const { port } = address;
|
|
28
|
+
server.close((err) => {
|
|
29
|
+
if (err)
|
|
30
|
+
reject(err);
|
|
31
|
+
else
|
|
32
|
+
resolve(port);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
server.on('error', reject);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export function waitForAuthCode(port, authUrl) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const timeout = setTimeout(() => {
|
|
41
|
+
reject(new Error(`Authentication timed out after 5 minutes. Open this URL manually: ${authUrl}`));
|
|
42
|
+
}, 5 * 60 * 1000);
|
|
43
|
+
const server = http.createServer((req, res) => {
|
|
44
|
+
try {
|
|
45
|
+
if (!req.url)
|
|
46
|
+
throw new Error('Missing callback URL.');
|
|
47
|
+
const parsed = new URL(req.url, `http://127.0.0.1:${port}`);
|
|
48
|
+
if (parsed.pathname !== '/oauth2callback') {
|
|
49
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
50
|
+
res.end('Not found');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const error = parsed.searchParams.get('error');
|
|
54
|
+
if (error) {
|
|
55
|
+
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
56
|
+
res.end(`OAuth error: ${error}`);
|
|
57
|
+
throw new Error(`OAuth error: ${error}`);
|
|
58
|
+
}
|
|
59
|
+
const code = parsed.searchParams.get('code');
|
|
60
|
+
if (!code) {
|
|
61
|
+
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
62
|
+
res.end('Missing code');
|
|
63
|
+
throw new Error('OAuth callback missing code parameter.');
|
|
64
|
+
}
|
|
65
|
+
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
66
|
+
res.end('Authentication successful. You can close this tab.');
|
|
67
|
+
clearTimeout(timeout);
|
|
68
|
+
server.close(() => resolve(code));
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
clearTimeout(timeout);
|
|
72
|
+
server.close(() => reject(err));
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
server.on('error', (err) => {
|
|
76
|
+
clearTimeout(timeout);
|
|
77
|
+
reject(err);
|
|
78
|
+
});
|
|
79
|
+
server.listen(port, '127.0.0.1');
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
export async function runBrowserOAuthFlow(credentialsPath, noOpen) {
|
|
83
|
+
const callbackPort = await getAvailablePort();
|
|
84
|
+
const oauth = createOAuthClient(credentialsPath, callbackPort);
|
|
85
|
+
const authUrl = oauth.generateAuthUrl({
|
|
86
|
+
access_type: 'offline',
|
|
87
|
+
scope: SCOPES,
|
|
88
|
+
prompt: 'consent',
|
|
89
|
+
});
|
|
90
|
+
if (!noOpen) {
|
|
91
|
+
await open(authUrl);
|
|
92
|
+
}
|
|
93
|
+
const code = await waitForAuthCode(callbackPort, authUrl);
|
|
94
|
+
const tokenResponse = await oauth.getToken(code);
|
|
95
|
+
oauth.setCredentials(tokenResponse.tokens);
|
|
96
|
+
return {
|
|
97
|
+
credentials: oauth.credentials,
|
|
98
|
+
callbackPort,
|
|
99
|
+
browserOpened: !noOpen,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { ensureConfigDir, TOKEN_PATH } from '../config.js';
|
|
3
|
+
export function loadSavedToken() {
|
|
4
|
+
if (!fs.existsSync(TOKEN_PATH))
|
|
5
|
+
return null;
|
|
6
|
+
const raw = JSON.parse(fs.readFileSync(TOKEN_PATH, 'utf8'));
|
|
7
|
+
if (raw &&
|
|
8
|
+
typeof raw === 'object' &&
|
|
9
|
+
'credentials' in raw &&
|
|
10
|
+
raw.credentials &&
|
|
11
|
+
typeof raw.credentials === 'object') {
|
|
12
|
+
return raw.credentials;
|
|
13
|
+
}
|
|
14
|
+
return raw;
|
|
15
|
+
}
|
|
16
|
+
export function saveToken(credentials) {
|
|
17
|
+
ensureConfigDir();
|
|
18
|
+
fs.writeFileSync(TOKEN_PATH, `${JSON.stringify(credentials, null, 2)}\n`, 'utf8');
|
|
19
|
+
}
|
|
20
|
+
export function clearToken() {
|
|
21
|
+
if (fs.existsSync(TOKEN_PATH))
|
|
22
|
+
fs.unlinkSync(TOKEN_PATH);
|
|
23
|
+
}
|