@divizend/scratch-core 1.0.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/basic/demo.ts +11 -0
- package/basic/index.ts +490 -0
- package/core/Auth.ts +63 -0
- package/core/Currency.ts +16 -0
- package/core/Env.ts +186 -0
- package/core/Fragment.ts +43 -0
- package/core/FragmentServingMode.ts +37 -0
- package/core/JsonSchemaValidator.ts +173 -0
- package/core/ProjectRoot.ts +76 -0
- package/core/Scratch.ts +44 -0
- package/core/URI.ts +203 -0
- package/core/Universe.ts +406 -0
- package/core/index.ts +27 -0
- package/gsuite/core/GSuite.ts +237 -0
- package/gsuite/core/GSuiteAdmin.ts +81 -0
- package/gsuite/core/GSuiteOrgConfig.ts +47 -0
- package/gsuite/core/GSuiteUser.ts +115 -0
- package/gsuite/core/index.ts +21 -0
- package/gsuite/documents/Document.ts +173 -0
- package/gsuite/documents/Documents.ts +52 -0
- package/gsuite/documents/index.ts +19 -0
- package/gsuite/drive/Drive.ts +118 -0
- package/gsuite/drive/DriveFile.ts +147 -0
- package/gsuite/drive/index.ts +19 -0
- package/gsuite/gmail/Gmail.ts +430 -0
- package/gsuite/gmail/GmailLabel.ts +55 -0
- package/gsuite/gmail/GmailMessage.ts +428 -0
- package/gsuite/gmail/GmailMessagePart.ts +298 -0
- package/gsuite/gmail/GmailThread.ts +97 -0
- package/gsuite/gmail/index.ts +5 -0
- package/gsuite/gmail/utils.ts +184 -0
- package/gsuite/index.ts +28 -0
- package/gsuite/spreadsheets/CellValue.ts +71 -0
- package/gsuite/spreadsheets/Sheet.ts +128 -0
- package/gsuite/spreadsheets/SheetValues.ts +12 -0
- package/gsuite/spreadsheets/Spreadsheet.ts +76 -0
- package/gsuite/spreadsheets/Spreadsheets.ts +52 -0
- package/gsuite/spreadsheets/index.ts +25 -0
- package/gsuite/spreadsheets/utils.ts +52 -0
- package/gsuite/utils.ts +104 -0
- package/http-server/HttpServer.ts +110 -0
- package/http-server/NativeHttpServer.ts +1084 -0
- package/http-server/index.ts +3 -0
- package/http-server/middlewares/01-cors.ts +33 -0
- package/http-server/middlewares/02-static.ts +67 -0
- package/http-server/middlewares/03-request-logger.ts +159 -0
- package/http-server/middlewares/04-body-parser.ts +54 -0
- package/http-server/middlewares/05-no-cache.ts +23 -0
- package/http-server/middlewares/06-response-handler.ts +39 -0
- package/http-server/middlewares/handler-wrapper.ts +250 -0
- package/http-server/middlewares/index.ts +37 -0
- package/http-server/middlewares/types.ts +27 -0
- package/index.ts +24 -0
- package/package.json +37 -0
- package/queue/EmailQueue.ts +228 -0
- package/queue/RateLimiter.ts +54 -0
- package/queue/index.ts +2 -0
- package/resend/Resend.ts +190 -0
- package/resend/index.ts +11 -0
- package/s2/S2.ts +335 -0
- package/s2/index.ts +11 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSuite - Google Workspace Integration Manager
|
|
3
|
+
*
|
|
4
|
+
* The GSuite class manages integration with Google Workspace (formerly G Suite)
|
|
5
|
+
* services including Gmail, Google Drive, Google Sheets, and Google Docs.
|
|
6
|
+
*
|
|
7
|
+
* This class handles:
|
|
8
|
+
* - Multi-organization Google Workspace setup
|
|
9
|
+
* - Service account authentication and JWT management
|
|
10
|
+
* - User directory management and domain validation
|
|
11
|
+
* - Centralized access to all Google Workspace APIs
|
|
12
|
+
*
|
|
13
|
+
* The system supports multiple organizations, each with their own service account
|
|
14
|
+
* credentials, enabling enterprise-scale deployments with proper isolation.
|
|
15
|
+
*
|
|
16
|
+
* @class GSuite
|
|
17
|
+
* @version 1.0.0
|
|
18
|
+
* @author Divizend GmbH
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { JWT } from "google-auth-library";
|
|
22
|
+
import { admin_directory_v1 } from "googleapis";
|
|
23
|
+
import { GSuiteOrgConfig, GSuiteUser, Universe } from "../..";
|
|
24
|
+
import { parseEnvGroup } from "../../core/Env";
|
|
25
|
+
|
|
26
|
+
export class GSuite {
|
|
27
|
+
/**
|
|
28
|
+
* Creates a new GSuite instance
|
|
29
|
+
*
|
|
30
|
+
* @param universe - Reference to the central Universe instance
|
|
31
|
+
* @param orgConfigs - Configuration for each organization
|
|
32
|
+
* @param usersDirectory - Cached user directory data for performance
|
|
33
|
+
*/
|
|
34
|
+
constructor(
|
|
35
|
+
private readonly universe: Universe,
|
|
36
|
+
private readonly orgConfigs: { [org: string]: GSuiteOrgConfig },
|
|
37
|
+
private readonly usersDirectory: {
|
|
38
|
+
[email: string]: admin_directory_v1.Schema$User;
|
|
39
|
+
}
|
|
40
|
+
) {}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Constructs and initializes a GSuite instance
|
|
44
|
+
*
|
|
45
|
+
* This factory method performs the following initialization steps:
|
|
46
|
+
* 1. Parses environment variables for GCP credentials
|
|
47
|
+
* 2. Creates JWT authentication functions for each organization
|
|
48
|
+
* 3. Fetches domain and user information for each organization
|
|
49
|
+
* 4. Builds the user directory cache for efficient lookups
|
|
50
|
+
*
|
|
51
|
+
* Environment Variables Required:
|
|
52
|
+
* - GCP_CLIENT_EMAIL_<identifier>: Service account email
|
|
53
|
+
* - GCP_PRIVATE_KEY_<identifier>: Service account private key
|
|
54
|
+
* - GCP_ADMIN_USER_<identifier>: Admin user email for the organization
|
|
55
|
+
*
|
|
56
|
+
* @param universe - Reference to the central Universe instance
|
|
57
|
+
* @returns Promise<GSuite> - Fully initialized GSuite instance
|
|
58
|
+
* @throws Error if required credentials are missing or invalid
|
|
59
|
+
*/
|
|
60
|
+
static async construct(universe: Universe) {
|
|
61
|
+
// Parse environment variables grouped by organization identifier
|
|
62
|
+
const gcpCreds = parseEnvGroup<
|
|
63
|
+
{
|
|
64
|
+
clientEmail: string;
|
|
65
|
+
privateKey: string;
|
|
66
|
+
adminUser: string;
|
|
67
|
+
}
|
|
68
|
+
>(
|
|
69
|
+
["GCP_CLIENT_EMAIL_", "GCP_PRIVATE_KEY_", "GCP_ADMIN_USER_"],
|
|
70
|
+
{
|
|
71
|
+
propertyMap: {
|
|
72
|
+
"GCP_CLIENT_EMAIL_": "clientEmail",
|
|
73
|
+
"GCP_PRIVATE_KEY_": "privateKey",
|
|
74
|
+
"GCP_ADMIN_USER_": "adminUser",
|
|
75
|
+
},
|
|
76
|
+
identifierExtractor: (key: string) => {
|
|
77
|
+
// For "GCP_CLIENT_EMAIL_ORG1", split by "_" gives ["GCP", "CLIENT", "EMAIL", "ORG1"]
|
|
78
|
+
// We want the 4th segment (index 3), lowercased
|
|
79
|
+
const parts = key.split("_");
|
|
80
|
+
return parts[3]?.toLowerCase() || "";
|
|
81
|
+
},
|
|
82
|
+
errorMessage:
|
|
83
|
+
"No GCP credentials found. Please set GCP_CLIENT_EMAIL_<identifier>, GCP_PRIVATE_KEY_<identifier> and GCP_ADMIN_USER_<identifier> environment variables.",
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const orgConfigs: {
|
|
88
|
+
[org: string]: GSuiteOrgConfig;
|
|
89
|
+
} = {};
|
|
90
|
+
|
|
91
|
+
const rawAuths: { [org: string]: (subject: string) => JWT } = {};
|
|
92
|
+
|
|
93
|
+
// Create JWT authentication functions for each organization
|
|
94
|
+
for (const [identifier, creds] of Object.entries(gcpCreds)) {
|
|
95
|
+
if (!creds.clientEmail || !creds.privateKey || !creds.adminUser) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`Missing GCP credentials for ${identifier}. Please set GCP_CLIENT_EMAIL_${identifier}, GCP_PRIVATE_KEY_${identifier} and GCP_ADMIN_USER_${identifier} environment variables.`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Create JWT authentication with required scopes
|
|
102
|
+
rawAuths[identifier] = (subject: string) =>
|
|
103
|
+
new JWT({
|
|
104
|
+
email: creds.clientEmail!,
|
|
105
|
+
key: creds.privateKey!,
|
|
106
|
+
scopes: [
|
|
107
|
+
"https://www.googleapis.com/auth/gmail.readonly",
|
|
108
|
+
"https://www.googleapis.com/auth/gmail.send",
|
|
109
|
+
"https://www.googleapis.com/auth/gmail.modify",
|
|
110
|
+
"https://www.googleapis.com/auth/gmail.settings.sharing",
|
|
111
|
+
"https://www.googleapis.com/auth/admin.directory.user.readonly",
|
|
112
|
+
"https://www.googleapis.com/auth/admin.directory.domain.readonly",
|
|
113
|
+
"https://www.googleapis.com/auth/spreadsheets",
|
|
114
|
+
"https://www.googleapis.com/auth/drive",
|
|
115
|
+
"https://www.googleapis.com/auth/documents",
|
|
116
|
+
],
|
|
117
|
+
subject,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Initialize organization configurations and user directory
|
|
122
|
+
const usersDirectory: { [email: string]: admin_directory_v1.Schema$User } =
|
|
123
|
+
{};
|
|
124
|
+
|
|
125
|
+
for (const [identifier, rawAuth] of Object.entries(rawAuths)) {
|
|
126
|
+
const adminUser = gcpCreds[identifier]!.adminUser!;
|
|
127
|
+
|
|
128
|
+
// Create admin user instance and fetch organization data
|
|
129
|
+
const admin = new GSuiteUser(
|
|
130
|
+
universe,
|
|
131
|
+
rawAuth(adminUser),
|
|
132
|
+
usersDirectory[adminUser]!
|
|
133
|
+
).admin();
|
|
134
|
+
|
|
135
|
+
// Fetch domains for the organization
|
|
136
|
+
const domains = await admin.getDomains();
|
|
137
|
+
orgConfigs[identifier] = new GSuiteOrgConfig(rawAuth, domains, adminUser);
|
|
138
|
+
|
|
139
|
+
console.warn(
|
|
140
|
+
`${identifier} has ${orgConfigs[identifier].domains.length} domains`
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
// Fetch and cache user directory information
|
|
144
|
+
const users = await admin.getUsers();
|
|
145
|
+
for (const user of users) {
|
|
146
|
+
usersDirectory[user.primaryEmail!] = user;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
console.warn(`${identifier} has ${users.length} users`);
|
|
150
|
+
for (const user of users) {
|
|
151
|
+
console.log(user.primaryEmail);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return new GSuite(universe, orgConfigs, usersDirectory);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Creates a GSuiteUser instance for the specified email address
|
|
160
|
+
*
|
|
161
|
+
* This method:
|
|
162
|
+
* 1. Determines which organization the user belongs to based on email domain
|
|
163
|
+
* 2. Retrieves the appropriate authentication configuration
|
|
164
|
+
* 3. Fetches user directory data for the specified user
|
|
165
|
+
* 4. Returns a configured GSuiteUser instance with proper permissions
|
|
166
|
+
*
|
|
167
|
+
* @param email - The user's email address
|
|
168
|
+
* @returns GSuiteUser instance configured for the specified user
|
|
169
|
+
* @throws Error if the user's domain is not found or user is not in directory
|
|
170
|
+
*/
|
|
171
|
+
user(email: string): GSuiteUser {
|
|
172
|
+
// Find the organization configuration based on email domain
|
|
173
|
+
const emailDomain = email.split("@")[1]!;
|
|
174
|
+
const orgConfig = Object.values(this.orgConfigs).find((orgConfig) =>
|
|
175
|
+
orgConfig.domains.some((domain) => domain.domainName === emailDomain)
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
if (!orgConfig) {
|
|
179
|
+
throw new Error(`Domain of ${email} not found in any organization`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Retrieve user directory data for authentication and permissions
|
|
183
|
+
const directoryData = this.usersDirectory[email];
|
|
184
|
+
if (!directoryData) {
|
|
185
|
+
throw new Error(`User ${email} not found in directory`);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Create and return configured user instance
|
|
189
|
+
return new GSuiteUser(
|
|
190
|
+
this.universe,
|
|
191
|
+
orgConfig.getAuth(email),
|
|
192
|
+
directoryData
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Checks the health of the GSuite service
|
|
198
|
+
* Verifies connectivity by attempting to fetch domains from the first organization
|
|
199
|
+
*
|
|
200
|
+
* @returns Promise<{ status: string; message: string; connected: boolean; organization?: string }>
|
|
201
|
+
*/
|
|
202
|
+
async getHealth(): Promise<{
|
|
203
|
+
status: string;
|
|
204
|
+
message: string;
|
|
205
|
+
connected: boolean;
|
|
206
|
+
organization?: string;
|
|
207
|
+
}> {
|
|
208
|
+
try {
|
|
209
|
+
if (!this.orgConfigs || Object.keys(this.orgConfigs).length === 0) {
|
|
210
|
+
return {
|
|
211
|
+
status: "error",
|
|
212
|
+
message: "No GSuite organizations configured",
|
|
213
|
+
connected: false,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const firstOrg = Object.keys(this.orgConfigs)[0];
|
|
218
|
+
const orgConfig = this.orgConfigs[firstOrg];
|
|
219
|
+
const gsuiteUser = this.user(orgConfig.adminUser);
|
|
220
|
+
const admin = gsuiteUser.admin();
|
|
221
|
+
await admin.getDomains();
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
status: "ok",
|
|
225
|
+
message: "Google APIs connection active",
|
|
226
|
+
connected: true,
|
|
227
|
+
organization: firstOrg,
|
|
228
|
+
};
|
|
229
|
+
} catch (error) {
|
|
230
|
+
return {
|
|
231
|
+
status: "error",
|
|
232
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
233
|
+
connected: false,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSuiteAdmin - Google Workspace Administrative Operations
|
|
3
|
+
*
|
|
4
|
+
* The GSuiteAdmin class provides administrative access to Google Workspace
|
|
5
|
+
* organizational settings, including domain management and user directory operations.
|
|
6
|
+
*
|
|
7
|
+
* This class handles:
|
|
8
|
+
* - Domain listing and validation for multi-tenant organizations
|
|
9
|
+
* - User directory queries for authentication and permissions
|
|
10
|
+
* - Administrative operations that require elevated privileges
|
|
11
|
+
*
|
|
12
|
+
* All operations are performed using the Google Admin SDK Directory API
|
|
13
|
+
* with the authenticated user's administrative credentials.
|
|
14
|
+
*
|
|
15
|
+
* @class GSuiteAdmin
|
|
16
|
+
* @version 1.0.0
|
|
17
|
+
* @author Divizend GmbH
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { google, admin_directory_v1 } from "googleapis";
|
|
21
|
+
import { JWT } from "google-auth-library";
|
|
22
|
+
import { Universe } from "../..";
|
|
23
|
+
|
|
24
|
+
export class GSuiteAdmin {
|
|
25
|
+
/** Google Admin SDK Directory API client instance */
|
|
26
|
+
private admin: admin_directory_v1.Admin;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates a new GSuiteAdmin instance
|
|
30
|
+
*
|
|
31
|
+
* @param universe - Reference to the central Universe instance
|
|
32
|
+
* @param auth - JWT authentication with administrative privileges
|
|
33
|
+
*/
|
|
34
|
+
constructor(private readonly universe: Universe, private auth: JWT) {
|
|
35
|
+
this.admin = google.admin({ version: "directory_v1", auth: this.auth });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Retrieves all domains associated with the organization
|
|
40
|
+
*
|
|
41
|
+
* This method queries the Google Admin SDK to list all domains
|
|
42
|
+
* that belong to the authenticated user's organization. This is
|
|
43
|
+
* essential for multi-domain organizations and user authentication.
|
|
44
|
+
*
|
|
45
|
+
* @returns Promise<admin_directory_v1.Schema$Domains[]> - Array of domain objects
|
|
46
|
+
* @throws Error if no domains are found or the API call fails
|
|
47
|
+
*/
|
|
48
|
+
async getDomains(): Promise<admin_directory_v1.Schema$Domains[]> {
|
|
49
|
+
const response = await this.admin.domains.list({
|
|
50
|
+
customer: "my_customer",
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
if (!response.data.domains || response.data.domains.length === 0) {
|
|
54
|
+
throw new Error("No domains found");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return response.data.domains;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Retrieves all users in the organization
|
|
62
|
+
*
|
|
63
|
+
* This method queries the Google Admin SDK to list all users
|
|
64
|
+
* that belong to the authenticated user's organization. The user
|
|
65
|
+
* list is used for authentication, permissions, and directory lookups.
|
|
66
|
+
*
|
|
67
|
+
* @returns Promise<admin_directory_v1.Schema$User[]> - Array of user objects
|
|
68
|
+
* @throws Error if no users are found or the API call fails
|
|
69
|
+
*/
|
|
70
|
+
async getUsers(): Promise<admin_directory_v1.Schema$User[]> {
|
|
71
|
+
const response = await this.admin.users.list({
|
|
72
|
+
customer: "my_customer",
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (!response.data.users || response.data.users.length === 0) {
|
|
76
|
+
throw new Error("No users found");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return response.data.users;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSuiteOrgConfig - Organization Configuration Container
|
|
3
|
+
*
|
|
4
|
+
* The GSuiteOrgConfig class holds configuration information for a specific
|
|
5
|
+
* Google Workspace organization, including authentication details, domain
|
|
6
|
+
* information, and administrative user settings.
|
|
7
|
+
*
|
|
8
|
+
* This class serves as a data container that encapsulates all the necessary
|
|
9
|
+
* information to authenticate and operate within a specific organization's
|
|
10
|
+
* Google Workspace environment.
|
|
11
|
+
*
|
|
12
|
+
* @class GSuiteOrgConfig
|
|
13
|
+
* @version 1.0.0
|
|
14
|
+
* @author Divizend GmbH
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { JWT } from "google-auth-library";
|
|
18
|
+
import { admin_directory_v1 } from "googleapis";
|
|
19
|
+
|
|
20
|
+
export class GSuiteOrgConfig {
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new GSuiteOrgConfig instance
|
|
23
|
+
*
|
|
24
|
+
* @param jwt - Function that creates JWT instances for organization users
|
|
25
|
+
* @param domains - Array of domains associated with the organization
|
|
26
|
+
* @param adminUser - Email address of the administrative user for the organization
|
|
27
|
+
*/
|
|
28
|
+
constructor(
|
|
29
|
+
public readonly jwt: (subject: string) => JWT,
|
|
30
|
+
public readonly domains: admin_directory_v1.Schema$Domains[],
|
|
31
|
+
public readonly adminUser: string
|
|
32
|
+
) {}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Creates a JWT authentication instance for a specific user
|
|
36
|
+
*
|
|
37
|
+
* This method uses the organization's service account credentials
|
|
38
|
+
* to create a JWT token that can impersonate the specified user
|
|
39
|
+
* within the organization's Google Workspace environment.
|
|
40
|
+
*
|
|
41
|
+
* @param subject - The email address of the user to authenticate as
|
|
42
|
+
* @returns JWT instance configured for the specified user
|
|
43
|
+
*/
|
|
44
|
+
getAuth(subject: string): JWT {
|
|
45
|
+
return this.jwt(subject);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSuiteUser - Google Workspace Service Facade
|
|
3
|
+
*
|
|
4
|
+
* The GSuiteUser class provides a unified interface for accessing all Google Workspace
|
|
5
|
+
* services on behalf of a specific user. It acts as a facade that simplifies access
|
|
6
|
+
* to Gmail, Google Drive, Google Sheets, Google Docs, and administrative functions.
|
|
7
|
+
*
|
|
8
|
+
* Each GSuiteUser instance is configured with:
|
|
9
|
+
* - JWT authentication for the specific user
|
|
10
|
+
* - User directory data for permissions and metadata
|
|
11
|
+
* - Access to all Google Workspace APIs through service-specific classes
|
|
12
|
+
*
|
|
13
|
+
* This class implements the Facade pattern, hiding the complexity of individual
|
|
14
|
+
* Google Workspace APIs behind a simple, consistent interface.
|
|
15
|
+
*
|
|
16
|
+
* @class GSuiteUser
|
|
17
|
+
* @version 1.0.0
|
|
18
|
+
* @author Divizend GmbH
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { JWT } from "google-auth-library";
|
|
22
|
+
import { admin_directory_v1 } from "googleapis";
|
|
23
|
+
import {
|
|
24
|
+
Documents,
|
|
25
|
+
Drive,
|
|
26
|
+
GSuiteAdmin,
|
|
27
|
+
Gmail,
|
|
28
|
+
Spreadsheets,
|
|
29
|
+
Universe,
|
|
30
|
+
} from "../..";
|
|
31
|
+
|
|
32
|
+
export class GSuiteUser {
|
|
33
|
+
/**
|
|
34
|
+
* Creates a new GSuiteUser instance
|
|
35
|
+
*
|
|
36
|
+
* @param universe - Reference to the central Universe instance
|
|
37
|
+
* @param auth - JWT authentication for the specific user
|
|
38
|
+
* @param directoryData - User directory information and metadata
|
|
39
|
+
*/
|
|
40
|
+
constructor(
|
|
41
|
+
private readonly universe: Universe,
|
|
42
|
+
public readonly auth: JWT,
|
|
43
|
+
public readonly directoryData: admin_directory_v1.Schema$User
|
|
44
|
+
) {}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Provides access to Google Workspace administrative functions
|
|
48
|
+
*
|
|
49
|
+
* Returns a GSuiteAdmin instance that can perform administrative
|
|
50
|
+
* operations like managing users, domains, and organizational settings.
|
|
51
|
+
*
|
|
52
|
+
* @returns GSuiteAdmin instance for administrative operations
|
|
53
|
+
*/
|
|
54
|
+
admin(): GSuiteAdmin {
|
|
55
|
+
return new GSuiteAdmin(this.universe, this.auth);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Provides access to Google Docs services
|
|
60
|
+
*
|
|
61
|
+
* Returns a Documents instance that can create, read, update,
|
|
62
|
+
* and delete Google Docs documents programmatically.
|
|
63
|
+
*
|
|
64
|
+
* @returns Documents instance for Google Docs operations
|
|
65
|
+
*/
|
|
66
|
+
documents(): Documents {
|
|
67
|
+
return new Documents(this.universe, this.auth);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Provides access to Google Drive services
|
|
72
|
+
*
|
|
73
|
+
* Returns a Drive instance that can manage files and folders,
|
|
74
|
+
* handle file uploads/downloads, and manage sharing permissions.
|
|
75
|
+
*
|
|
76
|
+
* @returns Drive instance for Google Drive operations
|
|
77
|
+
*/
|
|
78
|
+
drive(): Drive {
|
|
79
|
+
return new Drive(this.universe, this.auth);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Provides access to Gmail services
|
|
84
|
+
*
|
|
85
|
+
* Returns a Gmail instance that can read emails, send messages,
|
|
86
|
+
* manage labels, and handle email processing workflows.
|
|
87
|
+
*
|
|
88
|
+
* @returns Gmail instance for Gmail operations
|
|
89
|
+
*/
|
|
90
|
+
gmail(): Gmail {
|
|
91
|
+
return new Gmail(this.universe, this.auth);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Provides access to Google Sheets services
|
|
96
|
+
*
|
|
97
|
+
* Returns a Spreadsheets instance that can read/write spreadsheet
|
|
98
|
+
* data, manage sheets, and perform data analysis operations.
|
|
99
|
+
*
|
|
100
|
+
* @returns Spreadsheets instance for Google Sheets operations
|
|
101
|
+
*/
|
|
102
|
+
spreadsheets(): Spreadsheets {
|
|
103
|
+
return new Spreadsheets(this.universe, this.auth);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The email address of the authenticated user
|
|
108
|
+
*
|
|
109
|
+
* This property provides convenient access to the user's email
|
|
110
|
+
* address for use in API calls and logging.
|
|
111
|
+
*/
|
|
112
|
+
get email() {
|
|
113
|
+
return this.auth.subject;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSuite Core Module - Foundation Components
|
|
3
|
+
*
|
|
4
|
+
* This module contains the core building blocks for Google Workspace integration:
|
|
5
|
+
* - GSuite: Main integration manager for multi-organization setups
|
|
6
|
+
* - GSuiteUser: User-specific service access facade
|
|
7
|
+
* - GSuiteAdmin: Administrative operations and directory management
|
|
8
|
+
* - GSuiteOrgConfig: Organization configuration and authentication
|
|
9
|
+
*
|
|
10
|
+
* These components provide the foundation for all Google Workspace services
|
|
11
|
+
* including authentication, user management, and organizational structure.
|
|
12
|
+
*
|
|
13
|
+
* @module GSuiteCore
|
|
14
|
+
* @version 1.0.0
|
|
15
|
+
* @author Divizend GmbH
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export * from "./GSuite";
|
|
19
|
+
export * from "./GSuiteUser";
|
|
20
|
+
export * from "./GSuiteAdmin";
|
|
21
|
+
export * from "./GSuiteOrgConfig";
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Document - Individual Google Document Operations
|
|
3
|
+
*
|
|
4
|
+
* The Document class represents a single Google Docs document and provides
|
|
5
|
+
* methods for content manipulation, placeholder replacement, and document
|
|
6
|
+
* editing operations.
|
|
7
|
+
*
|
|
8
|
+
* Key Features:
|
|
9
|
+
* - Document metadata and properties access
|
|
10
|
+
* - Placeholder text replacement and customization
|
|
11
|
+
* - Batch update operations for efficiency
|
|
12
|
+
* - Integration with Google Docs API
|
|
13
|
+
*
|
|
14
|
+
* This class enables automated document generation workflows by providing
|
|
15
|
+
* programmatic access to document content and editing capabilities.
|
|
16
|
+
*
|
|
17
|
+
* @class Document
|
|
18
|
+
* @version 1.0.0
|
|
19
|
+
* @author Divizend GmbH
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { docs_v1 } from "googleapis";
|
|
23
|
+
import { Documents } from ".";
|
|
24
|
+
import TurndownService from "turndown";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Mapping of placeholder keys to replacement values
|
|
28
|
+
*
|
|
29
|
+
* This type defines the structure for placeholder replacement operations,
|
|
30
|
+
* where keys represent placeholder text (e.g., "{{DATE}}") and values
|
|
31
|
+
* represent the content to replace them with.
|
|
32
|
+
*/
|
|
33
|
+
export type DocumentPlaceholderReplacements = { [key: string]: string };
|
|
34
|
+
|
|
35
|
+
export class Document {
|
|
36
|
+
/**
|
|
37
|
+
* Creates a new Document instance
|
|
38
|
+
*
|
|
39
|
+
* @param docs - Reference to the Documents service instance
|
|
40
|
+
* @param document - Raw Google Docs API document data
|
|
41
|
+
*/
|
|
42
|
+
constructor(
|
|
43
|
+
private readonly docs: Documents,
|
|
44
|
+
public readonly document: docs_v1.Schema$Document
|
|
45
|
+
) {}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Constructs a Document instance from a document ID
|
|
49
|
+
*
|
|
50
|
+
* This factory method fetches the document content from Google Docs
|
|
51
|
+
* and creates a Document instance ready for operations.
|
|
52
|
+
*
|
|
53
|
+
* @param docs - Documents service instance
|
|
54
|
+
* @param documentId - Google Docs document ID
|
|
55
|
+
* @returns Promise<Document> - Initialized document instance
|
|
56
|
+
*/
|
|
57
|
+
static async construct(docs: Documents, documentId: string) {
|
|
58
|
+
const document = await docs.docs.documents.get({ documentId });
|
|
59
|
+
return new Document(docs, document.data);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Gets the unique identifier for this document
|
|
64
|
+
*
|
|
65
|
+
* The document ID is used for all Google Docs API operations
|
|
66
|
+
* and can be used to reference this document in other services.
|
|
67
|
+
*/
|
|
68
|
+
get id(): string {
|
|
69
|
+
return this.document.documentId!;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Replaces placeholder text in the document with specified values
|
|
74
|
+
*
|
|
75
|
+
* This method performs batch replacement of placeholder text (e.g., "{{DATE}}")
|
|
76
|
+
* with actual values. It's commonly used in template-based document
|
|
77
|
+
* generation workflows to customize document content automatically.
|
|
78
|
+
*
|
|
79
|
+
* The method uses the Google Docs batchUpdate API for efficiency,
|
|
80
|
+
* processing all replacements in a single API call.
|
|
81
|
+
*
|
|
82
|
+
* @param replacements - Object mapping placeholder keys to replacement values
|
|
83
|
+
* @returns Promise containing the batch update response
|
|
84
|
+
* @throws Error if the batch update operation fails
|
|
85
|
+
*/
|
|
86
|
+
async replacePlaceholders(replacements: DocumentPlaceholderReplacements) {
|
|
87
|
+
return this.docs.docs.documents.batchUpdate({
|
|
88
|
+
documentId: this.id,
|
|
89
|
+
requestBody: {
|
|
90
|
+
requests: Object.entries(replacements).map(([key, value]) => ({
|
|
91
|
+
replaceAllText: {
|
|
92
|
+
containsText: { text: `{{${key}}}`, matchCase: true },
|
|
93
|
+
replaceText: value,
|
|
94
|
+
},
|
|
95
|
+
})),
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Exports the document in the specified format
|
|
102
|
+
*
|
|
103
|
+
* This method uses the Google Drive API to export the document
|
|
104
|
+
* in the requested format, returning it exactly as exported by the API.
|
|
105
|
+
*
|
|
106
|
+
* @param mimeType - MIME type for export (e.g., "text/html", "text/plain")
|
|
107
|
+
* @returns Promise<string> - Document content in the requested format
|
|
108
|
+
* @throws Error if export fails
|
|
109
|
+
*/
|
|
110
|
+
async export(mimeType: string): Promise<string> {
|
|
111
|
+
// Get the Drive service from the Documents instance
|
|
112
|
+
const userEmail = this.docs.auth.subject!;
|
|
113
|
+
const gsuiteUser = this.docs.universe.gsuite.user(userEmail);
|
|
114
|
+
const drive = gsuiteUser.drive();
|
|
115
|
+
|
|
116
|
+
// Export via Drive API
|
|
117
|
+
const buffer = await drive.drive.files.export(
|
|
118
|
+
{
|
|
119
|
+
fileId: this.id,
|
|
120
|
+
mimeType,
|
|
121
|
+
},
|
|
122
|
+
{ responseType: "arraybuffer" }
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
const content = Buffer.from(buffer.data as any).toString("utf-8");
|
|
126
|
+
|
|
127
|
+
// Return the content exactly as exported by the API
|
|
128
|
+
return content;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Exports the document as HTML
|
|
133
|
+
*
|
|
134
|
+
* This method uses the Google Drive API to export the document
|
|
135
|
+
* as HTML directly, returning it exactly as exported by the API.
|
|
136
|
+
*
|
|
137
|
+
* @returns Promise<string> - Document content as HTML
|
|
138
|
+
* @throws Error if export fails
|
|
139
|
+
*/
|
|
140
|
+
async toHTML(): Promise<string> {
|
|
141
|
+
return this.export("text/html");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Exports the document as plain text
|
|
146
|
+
*
|
|
147
|
+
* This method uses the Google Drive API to export the document
|
|
148
|
+
* as plain text directly, returning it exactly as exported by the API.
|
|
149
|
+
*
|
|
150
|
+
* @returns Promise<string> - Document content as plain text
|
|
151
|
+
* @throws Error if export fails
|
|
152
|
+
*/
|
|
153
|
+
async toPlainText(): Promise<string> {
|
|
154
|
+
return this.export("text/plain");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Exports the document as Markdown
|
|
159
|
+
*
|
|
160
|
+
* This method exports the document as HTML first, then converts it
|
|
161
|
+
* to Markdown using Turndown. This provides a clean Markdown representation
|
|
162
|
+
* of the document content.
|
|
163
|
+
*
|
|
164
|
+
* @returns Promise<string> - Document content as Markdown
|
|
165
|
+
* @throws Error if export or conversion fails
|
|
166
|
+
*/
|
|
167
|
+
async toMarkdown(): Promise<string> {
|
|
168
|
+
const html = await this.toHTML();
|
|
169
|
+
const turndownService = new TurndownService();
|
|
170
|
+
turndownService.remove(["script", "style"]);
|
|
171
|
+
return turndownService.turndown(html).trim();
|
|
172
|
+
}
|
|
173
|
+
}
|