@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,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sheet - Individual Sheet Operations and Data Management
|
|
3
|
+
*
|
|
4
|
+
* The Sheet class represents a single sheet within a Google Sheets
|
|
5
|
+
* spreadsheet and provides methods for data access, manipulation,
|
|
6
|
+
* and operations on sheet content.
|
|
7
|
+
*
|
|
8
|
+
* Key Features:
|
|
9
|
+
* - Sheet metadata and properties access
|
|
10
|
+
* - Range-based data retrieval
|
|
11
|
+
* - Column-specific operations
|
|
12
|
+
* - Row appending and data insertion
|
|
13
|
+
* - Integration with Google Sheets API
|
|
14
|
+
*
|
|
15
|
+
* This class enables fine-grained control over individual sheets,
|
|
16
|
+
* supporting complex data operations and workflow automation.
|
|
17
|
+
*
|
|
18
|
+
* @class Sheet
|
|
19
|
+
* @version 1.0.0
|
|
20
|
+
* @author Divizend GmbH
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { sheets_v4 } from "googleapis";
|
|
24
|
+
import {
|
|
25
|
+
Spreadsheet,
|
|
26
|
+
CellValue,
|
|
27
|
+
transformCellValueForSheets,
|
|
28
|
+
SheetValues,
|
|
29
|
+
} from "../..";
|
|
30
|
+
|
|
31
|
+
export class Sheet {
|
|
32
|
+
/**
|
|
33
|
+
* Creates a new Sheet instance
|
|
34
|
+
*
|
|
35
|
+
* @param spreadsheet - Reference to the parent Spreadsheet instance
|
|
36
|
+
* @param sheet - Raw Google Sheets API sheet data
|
|
37
|
+
*/
|
|
38
|
+
constructor(
|
|
39
|
+
private readonly spreadsheet: Spreadsheet,
|
|
40
|
+
public readonly sheet: sheets_v4.Schema$Sheet
|
|
41
|
+
) {}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Gets the display name of the sheet
|
|
45
|
+
*
|
|
46
|
+
* This is the name that appears on the sheet tab in Google Sheets
|
|
47
|
+
* and is used for range references and sheet identification.
|
|
48
|
+
*/
|
|
49
|
+
get name() {
|
|
50
|
+
return this.sheet.properties!.title!;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Gets the unique identifier for the sheet
|
|
55
|
+
*
|
|
56
|
+
* The sheet ID is used internally by Google Sheets for API operations
|
|
57
|
+
* and should not be displayed to users.
|
|
58
|
+
*/
|
|
59
|
+
get id() {
|
|
60
|
+
return this.sheet.properties!.sheetId!;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Retrieves values from a specified range in the sheet
|
|
65
|
+
*
|
|
66
|
+
* This method fetches data from the Google Sheets API for the
|
|
67
|
+
* specified range and returns it as a SheetValues instance for
|
|
68
|
+
* further processing and manipulation.
|
|
69
|
+
*
|
|
70
|
+
* @param range - A1 notation range (e.g., "A1:B10", "C:C")
|
|
71
|
+
* @returns Promise<SheetValues> - Values from the specified range
|
|
72
|
+
* @throws Error if no values are found for the range
|
|
73
|
+
*/
|
|
74
|
+
async getValues(range: string) {
|
|
75
|
+
const values = (
|
|
76
|
+
await this.spreadsheet.spreadsheets.sheets.spreadsheets.values.get({
|
|
77
|
+
spreadsheetId: this.spreadsheet.id,
|
|
78
|
+
range: `${this.name}!${range}`,
|
|
79
|
+
})
|
|
80
|
+
).data.values;
|
|
81
|
+
|
|
82
|
+
if (!values) {
|
|
83
|
+
throw new Error(`No values found for range ${range}`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return new SheetValues(this, values);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Retrieves all values from a specific column
|
|
91
|
+
*
|
|
92
|
+
* This method provides convenient access to column data by
|
|
93
|
+
* specifying just the column letter (e.g., "A", "B", "C").
|
|
94
|
+
*
|
|
95
|
+
* @param column - Column letter to retrieve
|
|
96
|
+
* @returns Promise<SheetValues> - All values from the specified column
|
|
97
|
+
*/
|
|
98
|
+
async getColumn(column: string) {
|
|
99
|
+
return this.getValues(`${column}:${column}`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Appends a new row of data to the sheet
|
|
104
|
+
*
|
|
105
|
+
* This method adds a new row at the bottom of the sheet with
|
|
106
|
+
* the specified values. The values are automatically formatted
|
|
107
|
+
* according to their CellValue specifications.
|
|
108
|
+
*
|
|
109
|
+
* @param values - Array of CellValue objects to append
|
|
110
|
+
* @throws Error if the append operation fails
|
|
111
|
+
*/
|
|
112
|
+
async appendRow(values: CellValue[]) {
|
|
113
|
+
await this.spreadsheet.spreadsheets.sheets.spreadsheets.batchUpdate({
|
|
114
|
+
spreadsheetId: this.spreadsheet.id,
|
|
115
|
+
requestBody: {
|
|
116
|
+
requests: [
|
|
117
|
+
{
|
|
118
|
+
appendCells: {
|
|
119
|
+
sheetId: this.id,
|
|
120
|
+
rows: [{ values: values.map(transformCellValueForSheets) }],
|
|
121
|
+
fields: "*",
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spreadsheet - Individual Spreadsheet Management
|
|
3
|
+
*
|
|
4
|
+
* The Spreadsheet class represents a single Google Sheets spreadsheet
|
|
5
|
+
* and provides access to its individual sheets and operations. It serves
|
|
6
|
+
* as the primary interface for working with spreadsheet content.
|
|
7
|
+
*
|
|
8
|
+
* Key Features:
|
|
9
|
+
* - Sheet access and management
|
|
10
|
+
* - Spreadsheet metadata and properties
|
|
11
|
+
* - Sheet-by-name lookup and access
|
|
12
|
+
* - Integration with Google Sheets API
|
|
13
|
+
*
|
|
14
|
+
* This class enables operations on individual spreadsheets, providing
|
|
15
|
+
* access to their sheets and data for processing and manipulation.
|
|
16
|
+
*
|
|
17
|
+
* @class Spreadsheet
|
|
18
|
+
* @version 1.0.0
|
|
19
|
+
* @author Divizend GmbH
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { sheets_v4 } from "googleapis";
|
|
23
|
+
import { Sheet, Spreadsheets } from "../..";
|
|
24
|
+
|
|
25
|
+
export class Spreadsheet {
|
|
26
|
+
/** Array of Sheet instances for all sheets in the spreadsheet */
|
|
27
|
+
public readonly sheets: Sheet[];
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Creates a new Spreadsheet instance
|
|
31
|
+
*
|
|
32
|
+
* @param spreadsheets - Reference to the Spreadsheets service
|
|
33
|
+
* @param id - Google Sheets spreadsheet ID
|
|
34
|
+
* @param sheetsRaw - Raw sheet data from the API
|
|
35
|
+
*/
|
|
36
|
+
constructor(
|
|
37
|
+
public readonly spreadsheets: Spreadsheets,
|
|
38
|
+
public readonly id: string,
|
|
39
|
+
sheetsRaw: sheets_v4.Schema$Sheet[]
|
|
40
|
+
) {
|
|
41
|
+
// Create Sheet instances for all sheets in the spreadsheet
|
|
42
|
+
this.sheets = sheetsRaw.map((s) => new Sheet(this, s));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Constructs a Spreadsheet instance from a spreadsheet ID
|
|
47
|
+
*
|
|
48
|
+
* This factory method fetches the spreadsheet metadata and creates
|
|
49
|
+
* Sheet instances for all sheets within the spreadsheet.
|
|
50
|
+
*
|
|
51
|
+
* @param spreadsheets - Spreadsheets service instance
|
|
52
|
+
* @param spreadsheetId - Google Sheets spreadsheet ID
|
|
53
|
+
* @returns Promise<Spreadsheet> - Initialized spreadsheet instance
|
|
54
|
+
*/
|
|
55
|
+
static async construct(spreadsheets: Spreadsheets, spreadsheetId: string) {
|
|
56
|
+
const sheetsRaw = await spreadsheets.sheets.spreadsheets.get({
|
|
57
|
+
spreadsheetId,
|
|
58
|
+
fields: "sheets.properties",
|
|
59
|
+
});
|
|
60
|
+
return new Spreadsheet(spreadsheets, spreadsheetId, sheetsRaw.data.sheets!);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Gets a sheet by name from the spreadsheet
|
|
65
|
+
*
|
|
66
|
+
* This method provides convenient access to individual sheets
|
|
67
|
+
* within the spreadsheet for data operations and manipulation.
|
|
68
|
+
*
|
|
69
|
+
* @param name - Name of the sheet to retrieve
|
|
70
|
+
* @returns Promise<Sheet> - Sheet instance for the specified name
|
|
71
|
+
* @throws Error if the sheet is not found
|
|
72
|
+
*/
|
|
73
|
+
async getSheet(name: string): Promise<Sheet> {
|
|
74
|
+
return this.sheets.find((s) => s.name === name)!;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spreadsheets - Google Sheets Service Integration
|
|
3
|
+
*
|
|
4
|
+
* The Spreadsheets class provides access to Google Sheets functionality
|
|
5
|
+
* through the Google Sheets API v4. It serves as the entry point for
|
|
6
|
+
* all spreadsheet operations within the system.
|
|
7
|
+
*
|
|
8
|
+
* Key Features:
|
|
9
|
+
* - Spreadsheet opening and access
|
|
10
|
+
* - API client management and authentication
|
|
11
|
+
* - Integration with other Google Workspace services
|
|
12
|
+
* - Support for complex spreadsheet operations
|
|
13
|
+
*
|
|
14
|
+
* This class enables automated workflows that require spreadsheet
|
|
15
|
+
* data processing, financial calculations, and data organization.
|
|
16
|
+
*
|
|
17
|
+
* @class Spreadsheets
|
|
18
|
+
* @version 1.0.0
|
|
19
|
+
* @author Divizend GmbH
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { google, sheets_v4 } from "googleapis";
|
|
23
|
+
import { JWT } from "google-auth-library";
|
|
24
|
+
import { Universe, Spreadsheet } from "../..";
|
|
25
|
+
|
|
26
|
+
export class Spreadsheets {
|
|
27
|
+
/** Google Sheets API v4 client instance */
|
|
28
|
+
public readonly sheets: sheets_v4.Sheets;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new Spreadsheets instance
|
|
32
|
+
*
|
|
33
|
+
* @param universe - Reference to the central Universe instance
|
|
34
|
+
* @param auth - JWT authentication for Sheets access
|
|
35
|
+
*/
|
|
36
|
+
constructor(private readonly universe: Universe, private auth: JWT) {
|
|
37
|
+
this.sheets = google.sheets({ version: "v4", auth: this.auth });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Opens a spreadsheet by ID for operations
|
|
42
|
+
*
|
|
43
|
+
* This method creates a Spreadsheet instance that provides access
|
|
44
|
+
* to the spreadsheet's sheets, data, and operations.
|
|
45
|
+
*
|
|
46
|
+
* @param spreadsheetId - Google Sheets spreadsheet ID
|
|
47
|
+
* @returns Promise<Spreadsheet> - Spreadsheet instance for operations
|
|
48
|
+
*/
|
|
49
|
+
async open(spreadsheetId: string): Promise<Spreadsheet> {
|
|
50
|
+
return Spreadsheet.construct(this, spreadsheetId);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google Sheets Module - Spreadsheet Management and Operations
|
|
3
|
+
*
|
|
4
|
+
* This module provides comprehensive Google Sheets integration including:
|
|
5
|
+
* - Spreadsheets: Main service for spreadsheet operations
|
|
6
|
+
* - Spreadsheet: Individual spreadsheet management
|
|
7
|
+
* - Sheet: Individual sheet operations and data access
|
|
8
|
+
* - CellValue: Cell data handling and formatting
|
|
9
|
+
* - SheetValues: Bulk data operations and column management
|
|
10
|
+
* - Utilities: Helper functions for common operations
|
|
11
|
+
*
|
|
12
|
+
* The Spreadsheets module enables automated data processing, financial
|
|
13
|
+
* record keeping, and complex spreadsheet operations within workflows.
|
|
14
|
+
*
|
|
15
|
+
* @module GoogleSheets
|
|
16
|
+
* @version 1.0.0
|
|
17
|
+
* @author Divizend GmbH
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export * from "./Spreadsheets";
|
|
21
|
+
export * from "./Spreadsheet";
|
|
22
|
+
export * from "./Sheet";
|
|
23
|
+
export * from "./CellValue";
|
|
24
|
+
export * from "./SheetValues";
|
|
25
|
+
export * from "./utils";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Google Sheets date serials:
|
|
2
|
+
// Day 0 = 1899-12-30 (UTC). Fractional part = time-of-day.
|
|
3
|
+
const SHEETS_EPOCH_UTC_MS = Date.UTC(1899, 11, 30);
|
|
4
|
+
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
5
|
+
|
|
6
|
+
export type YMD = readonly [year: number, month: number, day: number];
|
|
7
|
+
|
|
8
|
+
/** Returns the Google Sheets serial for a calendar DATE (no time). */
|
|
9
|
+
export function jsDateToSheetsSerial(input: Date | string | YMD): number {
|
|
10
|
+
let y: number, m: number, d: number;
|
|
11
|
+
|
|
12
|
+
if (input instanceof Date) {
|
|
13
|
+
// Use UTC parts so local timezone/DST can't shift the day.
|
|
14
|
+
y = input.getUTCFullYear();
|
|
15
|
+
m = input.getUTCMonth() + 1;
|
|
16
|
+
d = input.getUTCDate();
|
|
17
|
+
} else if (Array.isArray(input)) {
|
|
18
|
+
[y, m, d] = input;
|
|
19
|
+
} else if (typeof input === "string") {
|
|
20
|
+
// Accepts "YYYY_MM_DD" or "YYYY-MM-DD"
|
|
21
|
+
const m1 = /^(\d{4})[-_](\d{2})[-_](\d{2})$/.exec(input);
|
|
22
|
+
if (!m1) {
|
|
23
|
+
throw new RangeError(
|
|
24
|
+
`Unrecognized date string: "${input}". Use "YYYY-MM-DD".`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
y = Number(m1[1]);
|
|
28
|
+
m = Number(m1[2]);
|
|
29
|
+
d = Number(m1[3]);
|
|
30
|
+
} else {
|
|
31
|
+
// Should be unreachable due to the signature, but keeps TS happy in looser configs.
|
|
32
|
+
throw new TypeError("Unsupported input for jsDateToSheetsSerial()");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Build UTC midnight of the intended calendar date.
|
|
36
|
+
const utcMidnightMs = Date.UTC(y, m - 1, d);
|
|
37
|
+
|
|
38
|
+
// Validate (catches impossible dates like 1900-02-29).
|
|
39
|
+
const check = new Date(utcMidnightMs);
|
|
40
|
+
if (
|
|
41
|
+
check.getUTCFullYear() !== y ||
|
|
42
|
+
check.getUTCMonth() !== m - 1 ||
|
|
43
|
+
check.getUTCDate() !== d
|
|
44
|
+
) {
|
|
45
|
+
const pad = (n: number) => String(n).padStart(2, "0");
|
|
46
|
+
throw new RangeError(`Invalid calendar date: ${y}-${pad(m)}-${pad(d)}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Exact day count since 1899-12-30. Round to kill any FP dust.
|
|
50
|
+
const serial = (utcMidnightMs - SHEETS_EPOCH_UTC_MS) / MS_PER_DAY;
|
|
51
|
+
return Math.round(serial);
|
|
52
|
+
}
|
package/gsuite/utils.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSuite Utilities - Helper Functions
|
|
3
|
+
*
|
|
4
|
+
* Provides utility functions for Google Workspace operations.
|
|
5
|
+
*
|
|
6
|
+
* @module GSuiteUtils
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { GSuiteUser, Document, Spreadsheet, Sheet, Spreadsheets } from "..";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Extracts a Google Drive/Docs file ID from a URL or returns the input if it's already a file ID
|
|
14
|
+
*
|
|
15
|
+
* Supports various Google Drive/Docs URL formats:
|
|
16
|
+
* - https://drive.google.com/drive/folders/{folderId}
|
|
17
|
+
* - https://drive.google.com/drive/u/0/folders/{folderId}
|
|
18
|
+
* - https://docs.google.com/document/d/{fileId}/edit
|
|
19
|
+
* - https://docs.google.com/document/d/{fileId}
|
|
20
|
+
* - https://drive.google.com/file/d/{fileId}/view
|
|
21
|
+
* - https://drive.google.com/open?id={fileId}
|
|
22
|
+
* - Direct file ID or folder ID (returns as-is)
|
|
23
|
+
*
|
|
24
|
+
* @param urlOrId - Google Drive/Docs URL or file ID
|
|
25
|
+
* @returns The extracted file ID
|
|
26
|
+
* @throws Error if the URL format is not recognized
|
|
27
|
+
*/
|
|
28
|
+
export function extractFileId(urlOrId: string): string {
|
|
29
|
+
// If it's already a file ID (no slashes or special characters), return as-is
|
|
30
|
+
if (
|
|
31
|
+
!urlOrId.includes("/") &&
|
|
32
|
+
!urlOrId.includes("?") &&
|
|
33
|
+
!urlOrId.includes("&")
|
|
34
|
+
) {
|
|
35
|
+
return urlOrId;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Try to extract from various URL patterns
|
|
39
|
+
const patterns = [
|
|
40
|
+
// drive.google.com/drive/folders/{folderId}
|
|
41
|
+
// drive.google.com/drive/u/0/folders/{folderId}
|
|
42
|
+
/\/folders\/([a-zA-Z0-9_-]+)/,
|
|
43
|
+
// docs.google.com/document/d/{fileId}
|
|
44
|
+
/\/document\/d\/([a-zA-Z0-9_-]+)/,
|
|
45
|
+
// drive.google.com/file/d/{fileId}
|
|
46
|
+
/\/file\/d\/([a-zA-Z0-9_-]+)/,
|
|
47
|
+
// drive.google.com/open?id={fileId}
|
|
48
|
+
/[?&]id=([a-zA-Z0-9_-]+)/,
|
|
49
|
+
// Any URL with /d/{fileId} pattern
|
|
50
|
+
/\/d\/([a-zA-Z0-9_-]+)/,
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
for (const pattern of patterns) {
|
|
54
|
+
const match = urlOrId.match(pattern);
|
|
55
|
+
if (match && match[1]) {
|
|
56
|
+
return match[1];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// If no pattern matches, assume it's a file ID (might be invalid, but let the API handle it)
|
|
61
|
+
return urlOrId;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Opens a Google Doc by ID or URL
|
|
66
|
+
*
|
|
67
|
+
* @param gsuiteUser - GSuite user instance
|
|
68
|
+
* @param documentIdOrUrl - Document ID or URL
|
|
69
|
+
* @returns Promise<Document> - Opened document instance
|
|
70
|
+
*/
|
|
71
|
+
export async function openDocument(
|
|
72
|
+
gsuiteUser: GSuiteUser,
|
|
73
|
+
documentIdOrUrl: string
|
|
74
|
+
): Promise<Document> {
|
|
75
|
+
const extractedId = extractFileId(documentIdOrUrl);
|
|
76
|
+
const documents = gsuiteUser.documents();
|
|
77
|
+
return documents.open(extractedId);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Opens a spreadsheet and returns the first sheet
|
|
82
|
+
*
|
|
83
|
+
* @param gsuiteUser - GSuite user instance
|
|
84
|
+
* @param spreadsheetIdOrUrl - Spreadsheet ID or URL
|
|
85
|
+
* @returns Promise with spreadsheet and first sheet
|
|
86
|
+
* @throws Error if spreadsheet has no sheets
|
|
87
|
+
*/
|
|
88
|
+
export async function openSpreadsheetFirstSheet(
|
|
89
|
+
gsuiteUser: GSuiteUser,
|
|
90
|
+
spreadsheetIdOrUrl: string
|
|
91
|
+
): Promise<{
|
|
92
|
+
spreadsheet: Spreadsheet;
|
|
93
|
+
sheet: Sheet;
|
|
94
|
+
spreadsheets: Spreadsheets;
|
|
95
|
+
}> {
|
|
96
|
+
const extractedId = extractFileId(spreadsheetIdOrUrl);
|
|
97
|
+
const spreadsheets = gsuiteUser.spreadsheets();
|
|
98
|
+
const spreadsheet = await spreadsheets.open(extractedId);
|
|
99
|
+
const firstSheet = spreadsheet.sheets[0];
|
|
100
|
+
if (!firstSheet) {
|
|
101
|
+
throw new Error("Spreadsheet has no sheets");
|
|
102
|
+
}
|
|
103
|
+
return { spreadsheet, sheet: firstSheet, spreadsheets };
|
|
104
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HttpServer - Abstract HTTP server interface
|
|
3
|
+
*
|
|
4
|
+
* This interface defines the contract for HTTP server implementations.
|
|
5
|
+
* Currently, only NativeHttpServer is implemented using Node's native http module.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { ScratchEndpointDefinition, ScratchContext } from "../index";
|
|
9
|
+
|
|
10
|
+
export interface HttpServer {
|
|
11
|
+
/**
|
|
12
|
+
* Start the HTTP server
|
|
13
|
+
* @param port - Port to listen on
|
|
14
|
+
* @returns Promise that resolves when server is ready
|
|
15
|
+
*/
|
|
16
|
+
start(port: number): Promise<void>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Stop the HTTP server
|
|
20
|
+
* @returns Promise that resolves when server is stopped
|
|
21
|
+
*/
|
|
22
|
+
stop(): Promise<void>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get the fetch handler for the server (for Bun/Cloudflare Workers)
|
|
26
|
+
* @returns Fetch handler function
|
|
27
|
+
*/
|
|
28
|
+
getFetchHandler(): (request: Request) => Promise<Response>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Register static file serving
|
|
32
|
+
* @param rootPath - Root path for static files
|
|
33
|
+
*/
|
|
34
|
+
registerStaticFiles(rootPath: string): void;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Load endpoints from a directory
|
|
38
|
+
* @param directoryPath - Absolute path to directory containing endpoint files
|
|
39
|
+
*/
|
|
40
|
+
loadEndpointsFromDirectory(directoryPath: string): Promise<void>;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get all endpoint definitions
|
|
44
|
+
*/
|
|
45
|
+
getAllEndpoints(): ScratchEndpointDefinition[];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Register all Scratch endpoints
|
|
49
|
+
* @param endpoints - Array of endpoint definitions
|
|
50
|
+
*/
|
|
51
|
+
registerEndpoints(endpoints: ScratchEndpointDefinition[]): Promise<void>;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get all registered endpoints (for logging/debugging)
|
|
55
|
+
*/
|
|
56
|
+
getRegisteredEndpoints(): Promise<
|
|
57
|
+
Array<{
|
|
58
|
+
method: string;
|
|
59
|
+
endpoint: string;
|
|
60
|
+
blockType: string;
|
|
61
|
+
auth: string;
|
|
62
|
+
text: string;
|
|
63
|
+
}>
|
|
64
|
+
>;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get endpoint handlers as an object keyed by opcode
|
|
68
|
+
*/
|
|
69
|
+
getEndpointHandlers(): Promise<
|
|
70
|
+
Record<string, (context: any) => Promise<any>>
|
|
71
|
+
>;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get handler by opcode
|
|
75
|
+
*/
|
|
76
|
+
getHandler(
|
|
77
|
+
opcode: string
|
|
78
|
+
): Promise<
|
|
79
|
+
| ((
|
|
80
|
+
context: ScratchContext,
|
|
81
|
+
query?: Record<string, string>,
|
|
82
|
+
requestBody?: any,
|
|
83
|
+
authHeader?: string
|
|
84
|
+
) => Promise<any>)
|
|
85
|
+
| undefined
|
|
86
|
+
>;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Register an endpoint from TypeScript source code (PUT operation - always overwrites)
|
|
90
|
+
* @param source - TypeScript source code for the endpoint
|
|
91
|
+
* @returns Promise that resolves with registration result
|
|
92
|
+
*/
|
|
93
|
+
registerEndpoint(source: string): Promise<{
|
|
94
|
+
success: boolean;
|
|
95
|
+
opcode?: string;
|
|
96
|
+
message?: string;
|
|
97
|
+
error?: string;
|
|
98
|
+
}>;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Remove an endpoint by opcode (DELETE operation)
|
|
102
|
+
* @param opcode - The opcode of the endpoint to remove
|
|
103
|
+
* @returns Promise that resolves with removal result
|
|
104
|
+
*/
|
|
105
|
+
removeEndpoint(opcode: string): Promise<{
|
|
106
|
+
success: boolean;
|
|
107
|
+
message?: string;
|
|
108
|
+
error?: string;
|
|
109
|
+
}>;
|
|
110
|
+
}
|