genjutsu-db 0.2.0 → 0.3.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/README.md +32 -1
- package/dist/drive.d.ts +23 -0
- package/dist/drive.d.ts.map +1 -0
- package/dist/drive.js +114 -0
- package/dist/drive.js.map +1 -0
- package/dist/errors.d.ts +2 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +3 -0
- package/dist/errors.js.map +1 -1
- package/dist/http.d.ts +15 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +95 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/managed.d.ts +9 -0
- package/dist/managed.d.ts.map +1 -0
- package/dist/managed.js +20 -0
- package/dist/managed.js.map +1 -0
- package/dist/transport.d.ts +2 -3
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +2 -78
- package/dist/transport.js.map +1 -1
- package/dist/types.d.ts +34 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/workspace.d.ts +7 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +48 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ Use Google Sheets as a structured database with typed models, full CRUD, relatio
|
|
|
14
14
|
- **Migrations** — Versioned schema changes tracked in a `_genjutsu_migrations` sheet
|
|
15
15
|
- **Formatting** — Header styles, number formats, alignment rules
|
|
16
16
|
- **Token provider** — Supports static tokens or async refresh functions with automatic 401 retry
|
|
17
|
+
- **Raw range access** — `db.raw.readRange()`, `writeRange()`, `clearRange()` for non-model sheets
|
|
17
18
|
- **Write mutex** — Serializes concurrent writes to prevent interleaved API calls
|
|
18
19
|
- **Read-only mode** — Use `apiKey` for public sheets (writes are blocked at the client level)
|
|
19
20
|
- **Zero dependencies** — Pure `fetch`-based, works in any JS runtime (browser, Node, Bun, Deno)
|
|
@@ -273,6 +274,36 @@ const sheetId = extractSpreadsheetId("https://docs.google.com/spreadsheets/d/abc
|
|
|
273
274
|
const { spreadsheetId, spreadsheetUrl } = await createSpreadsheet("Title", token);
|
|
274
275
|
```
|
|
275
276
|
|
|
277
|
+
### Raw Range Access
|
|
278
|
+
|
|
279
|
+
For sheets that don't fit a model (data blobs, summary tabs, etc.), use `db.raw` to read, write, and clear arbitrary ranges. Raw writes participate in the write mutex, so they're safe to use alongside model operations.
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
// Read raw cell values
|
|
283
|
+
const rows = await db.raw.readRange("Summary!A1:D10");
|
|
284
|
+
// rows: unknown[][] — e.g. [["Total", 1500], ["Average", 375]]
|
|
285
|
+
|
|
286
|
+
// Read with unformatted values (numbers instead of formatted strings)
|
|
287
|
+
const unformatted = await db.raw.readRange("Summary!A1:D10", "UNFORMATTED_VALUE");
|
|
288
|
+
|
|
289
|
+
// Write raw values (overwrites the range)
|
|
290
|
+
await db.raw.writeRange("Summary!A1:B2", [
|
|
291
|
+
["Total Expenses", 1500],
|
|
292
|
+
["Total Income", 3200],
|
|
293
|
+
]);
|
|
294
|
+
|
|
295
|
+
// Clear a range
|
|
296
|
+
await db.raw.clearRange("Summary!A1:D10");
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
| Method | Returns | Description |
|
|
300
|
+
|--------|---------|-------------|
|
|
301
|
+
| `readRange(range, valueRenderOption?)` | `Promise<unknown[][]>` | Read cell values from a range |
|
|
302
|
+
| `writeRange(range, values)` | `Promise<void>` | Overwrite a range with values |
|
|
303
|
+
| `clearRange(range)` | `Promise<void>` | Clear all values in a range |
|
|
304
|
+
|
|
305
|
+
> `readRange` works on both read-write and read-only clients. `writeRange` and `clearRange` throw `PERMISSION_ERROR` on read-only (`apiKey`) clients.
|
|
306
|
+
|
|
276
307
|
### Raw Schemas
|
|
277
308
|
|
|
278
309
|
For full control, skip `defineModel()` and provide a raw `SheetSchema<T>`:
|
|
@@ -336,7 +367,7 @@ GOOGLE_TOKEN="your-token" SHEET_ID="spreadsheet-id" bun run demo.ts
|
|
|
336
367
|
|
|
337
368
|
```bash
|
|
338
369
|
bun install # Install dependencies
|
|
339
|
-
bun test # Run tests (
|
|
370
|
+
bun test # Run tests (277 tests)
|
|
340
371
|
bun test --coverage # Coverage report (99.7% lines, 100% functions)
|
|
341
372
|
bun run build # TypeScript build to dist/
|
|
342
373
|
bun run lint # Type check
|
package/dist/drive.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level HTTP transport for Google Drive v3 REST API.
|
|
3
|
+
* Provides folder and spreadsheet management with appProperties-based identification.
|
|
4
|
+
*/
|
|
5
|
+
import type { DriveContext } from "./types";
|
|
6
|
+
export declare const DRIVE_API = "https://www.googleapis.com/drive/v3/files";
|
|
7
|
+
export declare function findAppFolder(ctx: DriveContext, appId: string): Promise<{
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
} | null>;
|
|
11
|
+
export declare function createAppFolder(ctx: DriveContext, appId: string, folderName: string): Promise<{
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
}>;
|
|
15
|
+
export declare function listSpreadsheetsInFolder(ctx: DriveContext, folderId: string): Promise<Array<{
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
}>>;
|
|
19
|
+
export declare function createSpreadsheetInFolder(ctx: DriveContext, folderId: string, title: string, appId: string): Promise<{
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
}>;
|
|
23
|
+
//# sourceMappingURL=drive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive.d.ts","sourceRoot":"","sources":["../src/drive.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,SAAS,8CAA8C,CAAC;AAMrE,wBAAsB,aAAa,CACjC,GAAG,EAAE,YAAY,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA0B9C;AAMD,wBAAsB,eAAe,CACnC,GAAG,EAAE,YAAY,EACjB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA6BvC;AAMD,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CA0B9C;AAMD,wBAAsB,yBAAyB,CAC7C,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA8BvC"}
|
package/dist/drive.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level HTTP transport for Google Drive v3 REST API.
|
|
3
|
+
* Provides folder and spreadsheet management with appProperties-based identification.
|
|
4
|
+
*/
|
|
5
|
+
import { fetchWithErrorHandling, buildAuthHeaders, } from "./http";
|
|
6
|
+
import { driveError } from "./errors";
|
|
7
|
+
export const DRIVE_API = "https://www.googleapis.com/drive/v3/files";
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Find App Folder
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
export async function findAppFolder(ctx, appId) {
|
|
12
|
+
const q = [
|
|
13
|
+
"mimeType='application/vnd.google-apps.folder'",
|
|
14
|
+
"trashed=false",
|
|
15
|
+
`appProperties has { key='genjutsuApp' and value='${appId}' }`,
|
|
16
|
+
].join(" and ");
|
|
17
|
+
const params = new URLSearchParams({
|
|
18
|
+
q,
|
|
19
|
+
fields: "files(id,name,modifiedTime)",
|
|
20
|
+
orderBy: "modifiedTime desc",
|
|
21
|
+
pageSize: "10",
|
|
22
|
+
supportsAllDrives: "true",
|
|
23
|
+
includeItemsFromAllDrives: "true",
|
|
24
|
+
});
|
|
25
|
+
const url = `${DRIVE_API}?${params.toString()}`;
|
|
26
|
+
const headers = await buildAuthHeaders(ctx);
|
|
27
|
+
const res = await fetchWithErrorHandling(url, { headers }, ctx);
|
|
28
|
+
const data = (await res.json());
|
|
29
|
+
const folder = data.files?.find((f) => f.id && f.name);
|
|
30
|
+
if (!folder?.id || !folder.name)
|
|
31
|
+
return null;
|
|
32
|
+
return { id: folder.id, name: folder.name };
|
|
33
|
+
}
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Create App Folder
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
export async function createAppFolder(ctx, appId, folderName) {
|
|
38
|
+
const url = `${DRIVE_API}?supportsAllDrives=true`;
|
|
39
|
+
const headers = {
|
|
40
|
+
...(await buildAuthHeaders(ctx)),
|
|
41
|
+
"Content-Type": "application/json",
|
|
42
|
+
};
|
|
43
|
+
const res = await fetchWithErrorHandling(url, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers,
|
|
46
|
+
body: JSON.stringify({
|
|
47
|
+
name: folderName,
|
|
48
|
+
mimeType: "application/vnd.google-apps.folder",
|
|
49
|
+
appProperties: {
|
|
50
|
+
genjutsuApp: appId,
|
|
51
|
+
genjutsuType: "appFolder",
|
|
52
|
+
},
|
|
53
|
+
}),
|
|
54
|
+
}, ctx);
|
|
55
|
+
const data = (await res.json());
|
|
56
|
+
if (!data.id || !data.name) {
|
|
57
|
+
throw driveError("Failed to create workspace folder: missing id or name in response");
|
|
58
|
+
}
|
|
59
|
+
return { id: data.id, name: data.name };
|
|
60
|
+
}
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// List Spreadsheets in Folder
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
export async function listSpreadsheetsInFolder(ctx, folderId) {
|
|
65
|
+
const q = [
|
|
66
|
+
`'${folderId}' in parents`,
|
|
67
|
+
"mimeType='application/vnd.google-apps.spreadsheet'",
|
|
68
|
+
"trashed=false",
|
|
69
|
+
].join(" and ");
|
|
70
|
+
const params = new URLSearchParams({
|
|
71
|
+
q,
|
|
72
|
+
fields: "files(id,name,modifiedTime)",
|
|
73
|
+
orderBy: "modifiedTime desc",
|
|
74
|
+
pageSize: "100",
|
|
75
|
+
supportsAllDrives: "true",
|
|
76
|
+
includeItemsFromAllDrives: "true",
|
|
77
|
+
});
|
|
78
|
+
const url = `${DRIVE_API}?${params.toString()}`;
|
|
79
|
+
const headers = await buildAuthHeaders(ctx);
|
|
80
|
+
const res = await fetchWithErrorHandling(url, { headers }, ctx);
|
|
81
|
+
const data = (await res.json());
|
|
82
|
+
return (data.files ?? [])
|
|
83
|
+
.filter((f) => Boolean(f.id && f.name))
|
|
84
|
+
.map((f) => ({ id: f.id, name: f.name }));
|
|
85
|
+
}
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// Create Spreadsheet in Folder
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
export async function createSpreadsheetInFolder(ctx, folderId, title, appId) {
|
|
90
|
+
const url = `${DRIVE_API}?supportsAllDrives=true`;
|
|
91
|
+
const headers = {
|
|
92
|
+
...(await buildAuthHeaders(ctx)),
|
|
93
|
+
"Content-Type": "application/json",
|
|
94
|
+
};
|
|
95
|
+
const res = await fetchWithErrorHandling(url, {
|
|
96
|
+
method: "POST",
|
|
97
|
+
headers,
|
|
98
|
+
body: JSON.stringify({
|
|
99
|
+
name: title,
|
|
100
|
+
mimeType: "application/vnd.google-apps.spreadsheet",
|
|
101
|
+
parents: [folderId],
|
|
102
|
+
appProperties: {
|
|
103
|
+
genjutsuApp: appId,
|
|
104
|
+
genjutsuType: "spreadsheet",
|
|
105
|
+
},
|
|
106
|
+
}),
|
|
107
|
+
}, ctx);
|
|
108
|
+
const data = (await res.json());
|
|
109
|
+
if (!data.id || !data.name) {
|
|
110
|
+
throw driveError("Failed to create workspace spreadsheet: missing id or name in response");
|
|
111
|
+
}
|
|
112
|
+
return { id: data.id, name: data.name };
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=drive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive.js","sourceRoot":"","sources":["../src/drive.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Typed error handling for the genjutsu-db library.
|
|
3
3
|
*/
|
|
4
|
-
export type GenjutsuErrorKind = "AUTH_ERROR" | "PERMISSION_ERROR" | "RATE_LIMIT" | "NETWORK_ERROR" | "VALIDATION_ERROR" | "SCHEMA_ERROR" | "MIGRATION_ERROR" | "API_ERROR";
|
|
4
|
+
export type GenjutsuErrorKind = "AUTH_ERROR" | "PERMISSION_ERROR" | "RATE_LIMIT" | "NETWORK_ERROR" | "VALIDATION_ERROR" | "SCHEMA_ERROR" | "MIGRATION_ERROR" | "API_ERROR" | "DRIVE_ERROR";
|
|
5
5
|
export interface ValidationIssue {
|
|
6
6
|
field: string;
|
|
7
7
|
message: string;
|
|
@@ -35,4 +35,5 @@ export declare function validationError(message: string, issues: ValidationIssue
|
|
|
35
35
|
export declare function schemaError(message: string, cause?: unknown): GenjutsuError;
|
|
36
36
|
export declare function migrationError(message: string, version: number, name: string, cause?: unknown): GenjutsuError;
|
|
37
37
|
export declare function apiError(message: string, cause?: unknown): GenjutsuError;
|
|
38
|
+
export declare function driveError(message: string, cause?: unknown): GenjutsuError;
|
|
38
39
|
//# sourceMappingURL=errors.d.ts.map
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,kBAAkB,GAClB,YAAY,GACZ,eAAe,GACf,kBAAkB,GAClB,cAAc,GACd,iBAAiB,GACjB,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,kBAAkB,GAClB,YAAY,GACZ,eAAe,GACf,kBAAkB,GAClB,cAAc,GACd,iBAAiB,GACjB,WAAW,GACX,aAAa,CAAC;AAElB,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;gBAG9B,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;QACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB;CAWJ;AAED,4CAA4C;AAC5C,eAAO,MAAM,aAAa,sBAAgB,CAAC;AAE3C,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,aAAa,CAElE;AAED,8CAA8C;AAC9C,eAAO,MAAM,eAAe,wBAAkB,CAAC;AAE/C,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,aAAa,CAEzE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,aAAa,CAE/E;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,OAAO,GACd,aAAa,CAEf;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,aAAa,CAE5E;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,eAAe,EAAE,GACxB,aAAa,CAIf;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,aAAa,CAE3E;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,OAAO,GACd,aAAa,CAMf;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,aAAa,CAExE;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,aAAa,CAE1E"}
|
package/dist/errors.js
CHANGED
|
@@ -56,4 +56,7 @@ export function migrationError(message, version, name, cause) {
|
|
|
56
56
|
export function apiError(message, cause) {
|
|
57
57
|
return new GenjutsuError("API_ERROR", message, { cause });
|
|
58
58
|
}
|
|
59
|
+
export function driveError(message, cause) {
|
|
60
|
+
return new GenjutsuError("DRIVE_ERROR", message, { cause });
|
|
61
|
+
}
|
|
59
62
|
//# sourceMappingURL=errors.js.map
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,IAAI,CAAoB;IACxB,KAAK,CAAW;IAChB,YAAY,CAAU;IACtB,gBAAgB,CAAqB;IACrC,gBAAgB,CAAU;IAC1B,aAAa,CAAU;IAEhC,YACE,IAAuB,EACvB,OAAe,EACf,OAMC;QAED,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,CAAC;QAC5B,IAAI,CAAC,YAAY,GAAG,OAAO,EAAE,YAAY,CAAC;QAC1C,IAAI,CAAC,gBAAgB,GAAG,OAAO,EAAE,gBAAgB,CAAC;QAClD,IAAI,CAAC,gBAAgB,GAAG,OAAO,EAAE,gBAAgB,CAAC;QAClD,IAAI,CAAC,aAAa,GAAG,OAAO,EAAE,aAAa,CAAC;IAC9C,CAAC;CACF;AAED,4CAA4C;AAC5C,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;AAE3C,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,OAAO,GAAG,YAAY,aAAa,CAAC;AACtC,CAAC;AAED,8CAA8C;AAC9C,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC;AAE/C,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,KAAe;IACxD,OAAO,IAAI,aAAa,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,KAAe;IAC9D,OAAO,IAAI,aAAa,CAAC,kBAAkB,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,OAAe,EACf,YAAqB,EACrB,KAAe;IAEf,OAAO,IAAI,aAAa,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,KAAe;IAC3D,OAAO,IAAI,aAAa,CAAC,eAAe,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,OAAe,EACf,MAAyB;IAEzB,OAAO,IAAI,aAAa,CAAC,kBAAkB,EAAE,OAAO,EAAE;QACpD,gBAAgB,EAAE,MAAM;KACzB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,KAAe;IAC1D,OAAO,IAAI,aAAa,CAAC,cAAc,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,OAAe,EACf,OAAe,EACf,IAAY,EACZ,KAAe;IAEf,OAAO,IAAI,aAAa,CAAC,iBAAiB,EAAE,OAAO,EAAE;QACnD,KAAK;QACL,gBAAgB,EAAE,OAAO;QACzB,aAAa,EAAE,IAAI;KACpB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,KAAe;IACvD,OAAO,IAAI,aAAa,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,KAAe;IACzD,OAAO,IAAI,aAAa,CAAC,aAAa,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AAC9D,CAAC"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared HTTP infrastructure for Google API transports (Sheets v4, Drive v3).
|
|
3
|
+
* Provides auth resolution, 401 retry, and structured error wrapping.
|
|
4
|
+
*/
|
|
5
|
+
export interface HttpContext {
|
|
6
|
+
auth?: string | (() => Promise<string>);
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function resolveToken(auth: string | (() => Promise<string>)): Promise<string>;
|
|
10
|
+
export declare function buildAuthHeaders(ctx: HttpContext): Promise<Record<string, string>>;
|
|
11
|
+
export declare function appendParams(url: string, extra: string): string;
|
|
12
|
+
export declare function parseRetryAfterMs(res: Response): number | undefined;
|
|
13
|
+
export declare function wrapHttpError(status: number, body: string, cause?: unknown): never;
|
|
14
|
+
export declare function fetchWithErrorHandling(url: string, init: RequestInit, ctx: HttpContext, retryOn401?: boolean): Promise<Response>;
|
|
15
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAMD,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GACrC,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAMjC;AAMD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG/D;AAMD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAKnE;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,OAAO,GACd,KAAK,CAWP;AAMD,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,WAAW,EAChB,UAAU,UAAO,GAChB,OAAO,CAAC,QAAQ,CAAC,CAwDnB"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared HTTP infrastructure for Google API transports (Sheets v4, Drive v3).
|
|
3
|
+
* Provides auth resolution, 401 retry, and structured error wrapping.
|
|
4
|
+
*/
|
|
5
|
+
import { authError, permissionError, rateLimitError, networkError, apiError, } from "./errors";
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Auth Helpers
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
export async function resolveToken(auth) {
|
|
10
|
+
return typeof auth === "function" ? auth() : auth;
|
|
11
|
+
}
|
|
12
|
+
export async function buildAuthHeaders(ctx) {
|
|
13
|
+
if (ctx.auth) {
|
|
14
|
+
const token = await resolveToken(ctx.auth);
|
|
15
|
+
return { Authorization: `Bearer ${token}` };
|
|
16
|
+
}
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// URL Helpers
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
export function appendParams(url, extra) {
|
|
23
|
+
if (!extra)
|
|
24
|
+
return url;
|
|
25
|
+
return url.includes("?") ? `${url}&${extra}` : `${url}?${extra}`;
|
|
26
|
+
}
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Error Helpers
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
export function parseRetryAfterMs(res) {
|
|
31
|
+
const header = res.headers.get("Retry-After");
|
|
32
|
+
if (!header)
|
|
33
|
+
return undefined;
|
|
34
|
+
const seconds = parseInt(header, 10);
|
|
35
|
+
return Number.isNaN(seconds) ? undefined : seconds * 1000;
|
|
36
|
+
}
|
|
37
|
+
export function wrapHttpError(status, body, cause) {
|
|
38
|
+
if (status === 401) {
|
|
39
|
+
throw authError(`Authentication failed: ${status} ${body}`, cause);
|
|
40
|
+
}
|
|
41
|
+
if (status === 403) {
|
|
42
|
+
throw permissionError(`Permission denied: ${status} ${body}`, cause);
|
|
43
|
+
}
|
|
44
|
+
if (status === 429) {
|
|
45
|
+
throw rateLimitError(`Rate limited: ${status} ${body}`, undefined, cause);
|
|
46
|
+
}
|
|
47
|
+
throw apiError(`Sheets API error: ${status} ${body}`, cause);
|
|
48
|
+
}
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Fetch with Error Handling + 401 Retry
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
export async function fetchWithErrorHandling(url, init, ctx, retryOn401 = true) {
|
|
53
|
+
let res;
|
|
54
|
+
try {
|
|
55
|
+
res = await fetch(url, init);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
throw networkError(`Network request failed: ${err instanceof Error ? err.message : String(err)}`, err);
|
|
59
|
+
}
|
|
60
|
+
// 401 retry: if auth is a function, call it again for a fresh token and retry once
|
|
61
|
+
if (res.status === 401 && retryOn401 && typeof ctx.auth === "function") {
|
|
62
|
+
const freshToken = await ctx.auth();
|
|
63
|
+
const retryInit = {
|
|
64
|
+
...init,
|
|
65
|
+
headers: {
|
|
66
|
+
...init.headers,
|
|
67
|
+
Authorization: `Bearer ${freshToken}`,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
let retryRes;
|
|
71
|
+
try {
|
|
72
|
+
retryRes = await fetch(url, retryInit);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
throw networkError(`Network request failed on retry: ${err instanceof Error ? err.message : String(err)}`, err);
|
|
76
|
+
}
|
|
77
|
+
if (!retryRes.ok) {
|
|
78
|
+
const body = await retryRes.text();
|
|
79
|
+
if (retryRes.status === 429) {
|
|
80
|
+
throw rateLimitError(`Rate limited: ${retryRes.status} ${body}`, parseRetryAfterMs(retryRes), retryRes);
|
|
81
|
+
}
|
|
82
|
+
wrapHttpError(retryRes.status, body, retryRes);
|
|
83
|
+
}
|
|
84
|
+
return retryRes;
|
|
85
|
+
}
|
|
86
|
+
if (!res.ok) {
|
|
87
|
+
const body = await res.text();
|
|
88
|
+
if (res.status === 429) {
|
|
89
|
+
throw rateLimitError(`Rate limited: ${res.status} ${body}`, parseRetryAfterMs(res), res);
|
|
90
|
+
}
|
|
91
|
+
wrapHttpError(res.status, body, res);
|
|
92
|
+
}
|
|
93
|
+
return res;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,9 +4,13 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { createClient } from "./client";
|
|
6
6
|
export { extractSpreadsheetId, createSpreadsheet } from "./transport";
|
|
7
|
-
export {
|
|
7
|
+
export type { HttpContext } from "./http";
|
|
8
|
+
export { findAppFolder, createAppFolder, listSpreadsheetsInFolder, createSpreadsheetInFolder, } from "./drive";
|
|
9
|
+
export { resolveWorkspace } from "./workspace";
|
|
10
|
+
export { createManagedClient } from "./managed";
|
|
11
|
+
export { GenjutsuError, SheetsDbError, isGenjutsuError, isSheetsDbError, authError, permissionError, rateLimitError, networkError, validationError, schemaError, migrationError, apiError, driveError, } from "./errors";
|
|
8
12
|
export type { GenjutsuErrorKind, ValidationIssue } from "./errors";
|
|
9
|
-
export type { SheetSchema, InferEntity, FormattingRule, HeaderFormat, FieldDefinition, RelationDefinition, Repository, ClientConfig, GenjutsuClient, RawRangeApi, FindOptions, ReadOptions, WriteOptions, Migration, MigrationContext, } from "./types";
|
|
13
|
+
export type { SheetSchema, InferEntity, FormattingRule, HeaderFormat, FieldDefinition, RelationDefinition, Repository, ClientConfig, GenjutsuClient, RawRangeApi, FindOptions, ReadOptions, WriteOptions, Migration, MigrationContext, DriveContext, WorkspaceConfig, ResolvedWorkspace, ManagedClientConfig, } from "./types";
|
|
10
14
|
export { defineModel, field } from "./model";
|
|
11
15
|
export type { FieldDef } from "./model";
|
|
12
16
|
export { generateId, isValidDate, normalizeDate, looksLikeIsoDate, parseAmount, hasIdColumn, findMissingHeaders, } from "./utils";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxC,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGtE,OAAO,EACL,aAAa,EACb,aAAa,EACb,eAAe,EACf,eAAe,EACf,SAAS,EACT,eAAe,EACf,cAAc,EACd,YAAY,EACZ,eAAe,EACf,WAAW,EACX,cAAc,EACd,QAAQ,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxC,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGtE,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAG1C,OAAO,EACL,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGhD,OAAO,EACL,aAAa,EACb,aAAa,EACb,eAAe,EACf,eAAe,EACf,SAAS,EACT,eAAe,EACf,cAAc,EACd,YAAY,EACZ,eAAe,EACf,WAAW,EACX,cAAc,EACd,QAAQ,EACR,UAAU,GACX,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAGnE,YAAY,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,cAAc,EACd,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAC7C,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,8 +6,12 @@
|
|
|
6
6
|
export { createClient } from "./client";
|
|
7
7
|
// Transport
|
|
8
8
|
export { extractSpreadsheetId, createSpreadsheet } from "./transport";
|
|
9
|
+
// Drive workspace
|
|
10
|
+
export { findAppFolder, createAppFolder, listSpreadsheetsInFolder, createSpreadsheetInFolder, } from "./drive";
|
|
11
|
+
export { resolveWorkspace } from "./workspace";
|
|
12
|
+
export { createManagedClient } from "./managed";
|
|
9
13
|
// Error types
|
|
10
|
-
export { GenjutsuError, SheetsDbError, isGenjutsuError, isSheetsDbError, authError, permissionError, rateLimitError, networkError, validationError, schemaError, migrationError, apiError, } from "./errors";
|
|
14
|
+
export { GenjutsuError, SheetsDbError, isGenjutsuError, isSheetsDbError, authError, permissionError, rateLimitError, networkError, validationError, schemaError, migrationError, apiError, driveError, } from "./errors";
|
|
11
15
|
// Model definition
|
|
12
16
|
export { defineModel, field } from "./model";
|
|
13
17
|
// Utilities
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,iBAAiB;AACjB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,YAAY;AACZ,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,iBAAiB;AACjB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,YAAY;AACZ,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKtE,kBAAkB;AAClB,OAAO,EACL,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,cAAc;AACd,OAAO,EACL,aAAa,EACb,aAAa,EACb,eAAe,EACf,eAAe,EACf,SAAS,EACT,eAAe,EACf,cAAc,EACd,YAAY,EACZ,eAAe,EACf,WAAW,EACX,cAAc,EACd,QAAQ,EACR,UAAU,GACX,MAAM,UAAU,CAAC;AA0BlB,mBAAmB;AACnB,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAG7C,YAAY;AACZ,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convenience factory that combines workspace resolution with client creation.
|
|
3
|
+
*/
|
|
4
|
+
import type { SheetSchema, GenjutsuClient, ManagedClientConfig, ResolvedWorkspace } from "./types";
|
|
5
|
+
export declare function createManagedClient<S extends Record<string, SheetSchema<any>>>(config: ManagedClientConfig<S>): Promise<{
|
|
6
|
+
client: GenjutsuClient<S>;
|
|
7
|
+
workspace: ResolvedWorkspace;
|
|
8
|
+
}>;
|
|
9
|
+
//# sourceMappingURL=managed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"managed.d.ts","sourceRoot":"","sources":["../src/managed.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB,wBAAsB,mBAAmB,CACvC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,EAE1C,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAC7B,OAAO,CAAC;IAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAAC,SAAS,EAAE,iBAAiB,CAAA;CAAE,CAAC,CAetE"}
|
package/dist/managed.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convenience factory that combines workspace resolution with client creation.
|
|
3
|
+
*/
|
|
4
|
+
import { resolveWorkspace } from "./workspace";
|
|
5
|
+
import { createClient } from "./client";
|
|
6
|
+
export async function createManagedClient(config) {
|
|
7
|
+
const workspace = await resolveWorkspace({
|
|
8
|
+
appId: config.appId,
|
|
9
|
+
folderName: config.folderName,
|
|
10
|
+
defaultSpreadsheetName: config.defaultSpreadsheetName,
|
|
11
|
+
auth: config.auth,
|
|
12
|
+
});
|
|
13
|
+
const client = createClient({
|
|
14
|
+
spreadsheetId: workspace.spreadsheetId,
|
|
15
|
+
auth: config.auth,
|
|
16
|
+
schemas: config.schemas,
|
|
17
|
+
});
|
|
18
|
+
return { client, workspace };
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=managed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"managed.js","sourceRoot":"","sources":["../src/managed.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAQxC,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAGvC,MAA8B;IAE9B,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC;QACvC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,sBAAsB,EAAE,MAAM,CAAC,sBAAsB;QACrD,IAAI,EAAE,MAAM,CAAC,IAAI;KAClB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,YAAY,CAAC;QAC1B,aAAa,EAAE,SAAS,CAAC,aAAa;QACtC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CAAC;IAEH,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC/B,CAAC"}
|
package/dist/transport.d.ts
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* Low-level HTTP transport for Google Sheets v4 REST API.
|
|
3
3
|
* Supports token provider pattern, 401 retry, 403→PERMISSION_ERROR, apiKey for public sheets.
|
|
4
4
|
*/
|
|
5
|
+
import { type HttpContext } from "./http";
|
|
5
6
|
export declare const SHEETS_API = "https://sheets.googleapis.com/v4/spreadsheets";
|
|
6
|
-
export interface TransportContext {
|
|
7
|
-
auth?: string | (() => Promise<string>);
|
|
8
|
-
apiKey?: string;
|
|
7
|
+
export interface TransportContext extends HttpContext {
|
|
9
8
|
spreadsheetId: string;
|
|
10
9
|
}
|
|
11
10
|
export declare function extractSpreadsheetId(urlOrId: string): string | null;
|
package/dist/transport.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,QAAQ,CAAC;AAGhB,eAAO,MAAM,UAAU,kDAAkD,CAAC;AAE1E,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMnE;AAaD,wBAAsB,cAAc,CAClC,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,MAAM,EACb,iBAAiB,GAAE,iBAAiB,GAAG,mBAAuC,GAC7E,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAUtB;AAED,wBAAsB,cAAc,CAClC,GAAG,EAAE,gBAAgB,EACrB,MAAM,EAAE,MAAM,EAAE,EAChB,iBAAiB,GAAE,iBAAiB,GAAG,mBAAuC,GAC7E,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAmBnC;AAMD,wBAAsB,WAAW,CAC/B,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EAAE,EAAE,EACnB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,UAAU,CAC9B,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAOf;AAMD,wBAAsB,UAAU,CAC9B,GAAG,EAAE,gBAAgB,EACrB,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAA;CAAE,EAAE,GAC7C,OAAO,CAAC,IAAI,CAAC,CAgBf;AAMD,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC;IAAE,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC,CAc3D;AAMD,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,gBAAgB,EACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAClC,OAAO,CAAC,IAAI,CAAC,CAWf;AAMD,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GACrC,OAAO,CAAC;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB5D"}
|
package/dist/transport.js
CHANGED
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
* Low-level HTTP transport for Google Sheets v4 REST API.
|
|
3
3
|
* Supports token provider pattern, 401 retry, 403→PERMISSION_ERROR, apiKey for public sheets.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { resolveToken, fetchWithErrorHandling, buildAuthHeaders, appendParams, } from "./http";
|
|
6
|
+
import { apiError } from "./errors";
|
|
6
7
|
export const SHEETS_API = "https://sheets.googleapis.com/v4/spreadsheets";
|
|
7
|
-
async function resolveToken(auth) {
|
|
8
|
-
return typeof auth === "function" ? auth() : auth;
|
|
9
|
-
}
|
|
10
8
|
export function extractSpreadsheetId(urlOrId) {
|
|
11
9
|
const match = urlOrId.match(/\/d\/([a-zA-Z0-9-_]+)/);
|
|
12
10
|
if (match)
|
|
@@ -16,86 +14,12 @@ export function extractSpreadsheetId(urlOrId) {
|
|
|
16
14
|
return urlOrId;
|
|
17
15
|
return null;
|
|
18
16
|
}
|
|
19
|
-
function parseRetryAfterMs(res) {
|
|
20
|
-
const header = res.headers.get("Retry-After");
|
|
21
|
-
if (!header)
|
|
22
|
-
return undefined;
|
|
23
|
-
const seconds = parseInt(header, 10);
|
|
24
|
-
return Number.isNaN(seconds) ? undefined : seconds * 1000;
|
|
25
|
-
}
|
|
26
|
-
function wrapHttpError(status, body, cause) {
|
|
27
|
-
if (status === 401) {
|
|
28
|
-
throw authError(`Authentication failed: ${status} ${body}`, cause);
|
|
29
|
-
}
|
|
30
|
-
if (status === 403) {
|
|
31
|
-
throw permissionError(`Permission denied: ${status} ${body}`, cause);
|
|
32
|
-
}
|
|
33
|
-
if (status === 429) {
|
|
34
|
-
throw rateLimitError(`Rate limited: ${status} ${body}`, undefined, cause);
|
|
35
|
-
}
|
|
36
|
-
throw apiError(`Sheets API error: ${status} ${body}`, cause);
|
|
37
|
-
}
|
|
38
|
-
async function buildAuthHeaders(ctx) {
|
|
39
|
-
if (ctx.auth) {
|
|
40
|
-
const token = await resolveToken(ctx.auth);
|
|
41
|
-
return { Authorization: `Bearer ${token}` };
|
|
42
|
-
}
|
|
43
|
-
return {};
|
|
44
|
-
}
|
|
45
17
|
function buildApiKeyParam(ctx) {
|
|
46
18
|
if (ctx.apiKey && !ctx.auth) {
|
|
47
19
|
return `key=${encodeURIComponent(ctx.apiKey)}`;
|
|
48
20
|
}
|
|
49
21
|
return "";
|
|
50
22
|
}
|
|
51
|
-
function appendParams(url, extra) {
|
|
52
|
-
if (!extra)
|
|
53
|
-
return url;
|
|
54
|
-
return url.includes("?") ? `${url}&${extra}` : `${url}?${extra}`;
|
|
55
|
-
}
|
|
56
|
-
async function fetchWithErrorHandling(url, init, ctx, retryOn401 = true) {
|
|
57
|
-
let res;
|
|
58
|
-
try {
|
|
59
|
-
res = await fetch(url, init);
|
|
60
|
-
}
|
|
61
|
-
catch (err) {
|
|
62
|
-
throw networkError(`Network request failed: ${err instanceof Error ? err.message : String(err)}`, err);
|
|
63
|
-
}
|
|
64
|
-
// 401 retry: if auth is a function, call it again for a fresh token and retry once
|
|
65
|
-
if (res.status === 401 && retryOn401 && typeof ctx.auth === "function") {
|
|
66
|
-
const freshToken = await ctx.auth();
|
|
67
|
-
const retryInit = {
|
|
68
|
-
...init,
|
|
69
|
-
headers: {
|
|
70
|
-
...init.headers,
|
|
71
|
-
Authorization: `Bearer ${freshToken}`,
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
let retryRes;
|
|
75
|
-
try {
|
|
76
|
-
retryRes = await fetch(url, retryInit);
|
|
77
|
-
}
|
|
78
|
-
catch (err) {
|
|
79
|
-
throw networkError(`Network request failed on retry: ${err instanceof Error ? err.message : String(err)}`, err);
|
|
80
|
-
}
|
|
81
|
-
if (!retryRes.ok) {
|
|
82
|
-
const body = await retryRes.text();
|
|
83
|
-
if (retryRes.status === 429) {
|
|
84
|
-
throw rateLimitError(`Rate limited: ${retryRes.status} ${body}`, parseRetryAfterMs(retryRes), retryRes);
|
|
85
|
-
}
|
|
86
|
-
wrapHttpError(retryRes.status, body, retryRes);
|
|
87
|
-
}
|
|
88
|
-
return retryRes;
|
|
89
|
-
}
|
|
90
|
-
if (!res.ok) {
|
|
91
|
-
const body = await res.text();
|
|
92
|
-
if (res.status === 429) {
|
|
93
|
-
throw rateLimitError(`Rate limited: ${res.status} ${body}`, parseRetryAfterMs(res), res);
|
|
94
|
-
}
|
|
95
|
-
wrapHttpError(res.status, body, res);
|
|
96
|
-
}
|
|
97
|
-
return res;
|
|
98
|
-
}
|
|
99
23
|
// ---------------------------------------------------------------------------
|
|
100
24
|
// Read Operations
|
|
101
25
|
// ---------------------------------------------------------------------------
|
package/dist/transport.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -107,4 +107,38 @@ export interface MigrationContext {
|
|
|
107
107
|
renameColumn(sheet: string, columnIndex: number, newName: string): Promise<void>;
|
|
108
108
|
renameSheet(oldName: string, newName: string): Promise<void>;
|
|
109
109
|
}
|
|
110
|
+
export interface DriveContext {
|
|
111
|
+
auth: string | (() => Promise<string>);
|
|
112
|
+
}
|
|
113
|
+
export interface DriveFile {
|
|
114
|
+
id: string;
|
|
115
|
+
name: string;
|
|
116
|
+
modifiedTime?: string;
|
|
117
|
+
}
|
|
118
|
+
export interface WorkspaceConfig {
|
|
119
|
+
/** Unique identifier for this app, stored in appProperties.genjutsuApp */
|
|
120
|
+
appId: string;
|
|
121
|
+
/** Human-readable folder name shown in Google Drive. Defaults to appId. */
|
|
122
|
+
folderName?: string;
|
|
123
|
+
/** Name for the default spreadsheet created on first run. */
|
|
124
|
+
defaultSpreadsheetName: string;
|
|
125
|
+
/** OAuth token or async provider. Required — Drive API needs user auth. */
|
|
126
|
+
auth: string | (() => Promise<string>);
|
|
127
|
+
}
|
|
128
|
+
export interface ResolvedWorkspace {
|
|
129
|
+
/** Google Drive folder ID. */
|
|
130
|
+
folderId: string;
|
|
131
|
+
/** Primary spreadsheet ID (most recently modified). */
|
|
132
|
+
spreadsheetId: string;
|
|
133
|
+
/** All spreadsheets in the workspace folder. */
|
|
134
|
+
spreadsheets: Array<{
|
|
135
|
+
id: string;
|
|
136
|
+
name: string;
|
|
137
|
+
}>;
|
|
138
|
+
/** True if folder and/or spreadsheet were created during this call. */
|
|
139
|
+
created: boolean;
|
|
140
|
+
}
|
|
141
|
+
export interface ManagedClientConfig<S extends Record<string, SheetSchema<any>>> extends WorkspaceConfig {
|
|
142
|
+
schemas: S;
|
|
143
|
+
}
|
|
110
144
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace orchestrator: finds or creates an app-specific folder and spreadsheet
|
|
3
|
+
* in the user's Google Drive using appProperties metadata for collision-proof identification.
|
|
4
|
+
*/
|
|
5
|
+
import type { WorkspaceConfig, ResolvedWorkspace } from "./types";
|
|
6
|
+
export declare function resolveWorkspace(config: WorkspaceConfig): Promise<ResolvedWorkspace>;
|
|
7
|
+
//# sourceMappingURL=workspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAElE,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,iBAAiB,CAAC,CAkD5B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace orchestrator: finds or creates an app-specific folder and spreadsheet
|
|
3
|
+
* in the user's Google Drive using appProperties metadata for collision-proof identification.
|
|
4
|
+
*/
|
|
5
|
+
import { findAppFolder, createAppFolder, listSpreadsheetsInFolder, createSpreadsheetInFolder, } from "./drive";
|
|
6
|
+
import { validationError } from "./errors";
|
|
7
|
+
export async function resolveWorkspace(config) {
|
|
8
|
+
// Validate config
|
|
9
|
+
if (!config.auth) {
|
|
10
|
+
throw validationError("resolveWorkspace requires OAuth auth", [
|
|
11
|
+
{ field: "auth", message: "auth is required (Drive API needs user authorization)" },
|
|
12
|
+
]);
|
|
13
|
+
}
|
|
14
|
+
if (!config.appId) {
|
|
15
|
+
throw validationError("appId must be a non-empty string", [
|
|
16
|
+
{ field: "appId", message: "appId is required" },
|
|
17
|
+
]);
|
|
18
|
+
}
|
|
19
|
+
if (!config.defaultSpreadsheetName) {
|
|
20
|
+
throw validationError("defaultSpreadsheetName must be a non-empty string", [
|
|
21
|
+
{ field: "defaultSpreadsheetName", message: "defaultSpreadsheetName is required" },
|
|
22
|
+
]);
|
|
23
|
+
}
|
|
24
|
+
const ctx = { auth: config.auth };
|
|
25
|
+
const folderName = config.folderName || config.appId;
|
|
26
|
+
let created = false;
|
|
27
|
+
// Step 1: Find or create the app folder
|
|
28
|
+
let folder = await findAppFolder(ctx, config.appId);
|
|
29
|
+
if (!folder) {
|
|
30
|
+
folder = await createAppFolder(ctx, config.appId, folderName);
|
|
31
|
+
created = true;
|
|
32
|
+
}
|
|
33
|
+
// Step 2: List spreadsheets in the folder
|
|
34
|
+
let spreadsheets = await listSpreadsheetsInFolder(ctx, folder.id);
|
|
35
|
+
// Step 3: Create default spreadsheet if none exist
|
|
36
|
+
if (spreadsheets.length === 0) {
|
|
37
|
+
const newSheet = await createSpreadsheetInFolder(ctx, folder.id, config.defaultSpreadsheetName, config.appId);
|
|
38
|
+
spreadsheets = [newSheet];
|
|
39
|
+
created = true;
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
folderId: folder.id,
|
|
43
|
+
spreadsheetId: spreadsheets[0].id,
|
|
44
|
+
spreadsheets,
|
|
45
|
+
created,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAG3C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAuB;IAEvB,kBAAkB;IAClB,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,eAAe,CAAC,sCAAsC,EAAE;YAC5D,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,uDAAuD,EAAE;SACpF,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,eAAe,CAAC,kCAAkC,EAAE;YACxD,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE;SACjD,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,sBAAsB,EAAE,CAAC;QACnC,MAAM,eAAe,CAAC,mDAAmD,EAAE;YACzE,EAAE,KAAK,EAAE,wBAAwB,EAAE,OAAO,EAAE,oCAAoC,EAAE;SACnF,CAAC,CAAC;IACL,CAAC;IAED,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAClC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,CAAC;IACrD,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,wCAAwC;IACxC,IAAI,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAC9D,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,0CAA0C;IAC1C,IAAI,YAAY,GAAG,MAAM,wBAAwB,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IAElE,mDAAmD;IACnD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAC9C,GAAG,EACH,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,sBAAsB,EAC7B,MAAM,CAAC,KAAK,CACb,CAAC;QACF,YAAY,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE;QACjC,YAAY;QACZ,OAAO;KACR,CAAC;AACJ,CAAC"}
|