@theholocron/google-client 1.32.0 → 1.33.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/dist/index.d.mts +19 -0
- package/dist/index.mjs +144 -0
- package/package.json +2 -2
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { JWT, OAuth2Client } from "google-auth-library";
|
|
2
|
+
//#region ../../../../../src/types.d.ts
|
|
3
|
+
type Return<T> = [Error, null, number] | [null, T, number];
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region ../../../../../src/authentication.d.ts
|
|
6
|
+
declare const oauth: (scopes: string[]) => Promise<OAuth2Client | null>;
|
|
7
|
+
declare function googleAuth(scopes: string[]): Promise<JWT>;
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region ../../../../../src/index.d.ts
|
|
10
|
+
declare const google: {
|
|
11
|
+
documents: {
|
|
12
|
+
get: (id: string) => Promise<Return<import("googleapis").docs_v1.Schema$Document>>;
|
|
13
|
+
};
|
|
14
|
+
spreadsheets: {
|
|
15
|
+
get: (id: string) => Promise<Return<import("googleapis").sheets_v4.Schema$Spreadsheet>>;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { type Return, google, googleAuth, oauth };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { google as google$1 } from "googleapis";
|
|
2
|
+
import http from "node:http";
|
|
3
|
+
import url from "node:url";
|
|
4
|
+
import open from "open";
|
|
5
|
+
import destroyer from "server-destroy";
|
|
6
|
+
//#region ../../../../../src/key.ts
|
|
7
|
+
/**
|
|
8
|
+
* Load service account credentials from environment variables.
|
|
9
|
+
* Set GOOGLE_SERVICE_ACCOUNT_JSON to the full JSON key file content,
|
|
10
|
+
* or set individual GOOGLE_* variables for each field.
|
|
11
|
+
*/
|
|
12
|
+
function loadServiceAccountKey() {
|
|
13
|
+
const raw = process.env.GOOGLE_SERVICE_ACCOUNT_JSON;
|
|
14
|
+
if (raw) return JSON.parse(raw);
|
|
15
|
+
for (const key of [
|
|
16
|
+
"GOOGLE_TYPE",
|
|
17
|
+
"GOOGLE_PROJECT_ID",
|
|
18
|
+
"GOOGLE_PRIVATE_KEY_ID",
|
|
19
|
+
"GOOGLE_PRIVATE_KEY",
|
|
20
|
+
"GOOGLE_CLIENT_EMAIL",
|
|
21
|
+
"GOOGLE_CLIENT_ID"
|
|
22
|
+
]) if (!process.env[key]) throw new Error(`Missing required environment variable: ${key}`);
|
|
23
|
+
return {
|
|
24
|
+
type: process.env.GOOGLE_TYPE,
|
|
25
|
+
project_id: process.env.GOOGLE_PROJECT_ID,
|
|
26
|
+
private_key_id: process.env.GOOGLE_PRIVATE_KEY_ID,
|
|
27
|
+
private_key: process.env.GOOGLE_PRIVATE_KEY.replace(/\\n/g, "\n"),
|
|
28
|
+
client_email: process.env.GOOGLE_CLIENT_EMAIL,
|
|
29
|
+
client_id: process.env.GOOGLE_CLIENT_ID,
|
|
30
|
+
auth_uri: "https://accounts.google.com/o/oauth2/auth",
|
|
31
|
+
token_uri: "https://oauth2.googleapis.com/token",
|
|
32
|
+
auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs",
|
|
33
|
+
client_x509_cert_url: `https://www.googleapis.com/robot/v1/metadata/x509/${encodeURIComponent(process.env.GOOGLE_CLIENT_EMAIL)}`,
|
|
34
|
+
universe_domain: "googleapis.com"
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region ../../../../../src/authentication.ts
|
|
39
|
+
function buildOAuth2Client() {
|
|
40
|
+
const clientID = process.env.GOOGLE_CLIENT_ID;
|
|
41
|
+
const clientSecret = process.env.GOOGLE_CLIENT_SECRET;
|
|
42
|
+
const redirectURI = process.env.GOOGLE_REDIRECT_URI ?? "http://localhost:4000/oauth2callback";
|
|
43
|
+
if (!clientID || !clientSecret) throw new Error("GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET environment variables are required for OAuth");
|
|
44
|
+
return new google$1.auth.OAuth2(clientID, clientSecret, redirectURI);
|
|
45
|
+
}
|
|
46
|
+
const oauth = async (scopes) => {
|
|
47
|
+
const oauth2Client = buildOAuth2Client();
|
|
48
|
+
const port = parseInt(process.env.GOOGLE_REDIRECT_PORT ?? "4000", 10);
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const authorizeUrl = oauth2Client.generateAuthUrl({
|
|
51
|
+
access_type: "offline",
|
|
52
|
+
scope: scopes.join(" ")
|
|
53
|
+
});
|
|
54
|
+
const server = http.createServer(async (req, res) => {
|
|
55
|
+
try {
|
|
56
|
+
if (req.url && req.url.indexOf("/oauth2callback") > -1) {
|
|
57
|
+
const qs = new url.URL(req.url, `http://localhost:${port}`).searchParams;
|
|
58
|
+
res.end("Authentication successful! Please return to the console.");
|
|
59
|
+
server.destroy();
|
|
60
|
+
const { tokens } = await oauth2Client.getToken(qs.get("code") ?? "");
|
|
61
|
+
oauth2Client.credentials = tokens;
|
|
62
|
+
resolve(oauth2Client);
|
|
63
|
+
}
|
|
64
|
+
} catch (e) {
|
|
65
|
+
reject(e);
|
|
66
|
+
}
|
|
67
|
+
}).listen(port, () => {
|
|
68
|
+
open(authorizeUrl, { wait: false }).then((cp) => cp.unref());
|
|
69
|
+
});
|
|
70
|
+
destroyer(server);
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
async function googleAuth(scopes) {
|
|
74
|
+
return await new google$1.auth.GoogleAuth({
|
|
75
|
+
credentials: loadServiceAccountKey(),
|
|
76
|
+
scopes
|
|
77
|
+
}).getClient();
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region ../../../../../src/documents.ts
|
|
81
|
+
const docs = google$1.docs("v1");
|
|
82
|
+
async function getDocument(id) {
|
|
83
|
+
if (!id) return [
|
|
84
|
+
/* @__PURE__ */ new Error("No ID was provided!"),
|
|
85
|
+
null,
|
|
86
|
+
0
|
|
87
|
+
];
|
|
88
|
+
const start = performance.now();
|
|
89
|
+
const authClient = await googleAuth(["https://www.googleapis.com/auth/documents.readonly"]);
|
|
90
|
+
try {
|
|
91
|
+
return [
|
|
92
|
+
null,
|
|
93
|
+
(await docs.documents.get({
|
|
94
|
+
auth: authClient,
|
|
95
|
+
documentId: id
|
|
96
|
+
})).data,
|
|
97
|
+
performance.now() - start
|
|
98
|
+
];
|
|
99
|
+
} catch (error) {
|
|
100
|
+
return [
|
|
101
|
+
error,
|
|
102
|
+
null,
|
|
103
|
+
performance.now() - start
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const documents = { get: getDocument };
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region ../../../../../src/spreadsheets.ts
|
|
110
|
+
const sheets = google$1.sheets("v4");
|
|
111
|
+
async function getSpreadsheet(id) {
|
|
112
|
+
if (!id) return [
|
|
113
|
+
/* @__PURE__ */ new Error("No ID was provided!"),
|
|
114
|
+
null,
|
|
115
|
+
0
|
|
116
|
+
];
|
|
117
|
+
const start = performance.now();
|
|
118
|
+
const authClient = await googleAuth(["https://www.googleapis.com/auth/spreadsheets.readonly"]);
|
|
119
|
+
try {
|
|
120
|
+
return [
|
|
121
|
+
null,
|
|
122
|
+
(await sheets.spreadsheets.get({
|
|
123
|
+
auth: authClient,
|
|
124
|
+
spreadsheetId: id,
|
|
125
|
+
includeGridData: true
|
|
126
|
+
})).data,
|
|
127
|
+
performance.now() - start
|
|
128
|
+
];
|
|
129
|
+
} catch (error) {
|
|
130
|
+
return [
|
|
131
|
+
error,
|
|
132
|
+
null,
|
|
133
|
+
performance.now() - start
|
|
134
|
+
];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region ../../../../../src/index.ts
|
|
139
|
+
const google = {
|
|
140
|
+
documents,
|
|
141
|
+
spreadsheets: { get: getSpreadsheet }
|
|
142
|
+
};
|
|
143
|
+
//#endregion
|
|
144
|
+
export { google, googleAuth, oauth };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/google-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.33.0",
|
|
4
4
|
"description": "A TypeScript client for Google Workspace APIs (Docs, Sheets)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"google",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@theholocron/cli": "5.0.0-alpha.79",
|
|
42
42
|
"@theholocron/eslint-config": "^8.4.3",
|
|
43
43
|
"@theholocron/tsconfig": "^8.2.0",
|
|
44
|
-
"@theholocron/tsdown-config": "^8.
|
|
44
|
+
"@theholocron/tsdown-config": "^8.6.1",
|
|
45
45
|
"@theholocron/vitest-config": "^8.2.0",
|
|
46
46
|
"@types/node": "^26.4.1",
|
|
47
47
|
"@types/server-destroy": "^1.0.4",
|