@mastra/google-drive 0.0.0 → 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1 +1,43 @@
1
1
  # @mastra/google-drive
2
+
3
+ ## 0.1.0-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - GoogleDriveFilesystem tweaks: mkdir defaults to recursive, appendFile uses optimistic concurrency, rmdir skips redundant child listing, JSON body requests include Content-Type header, readFile uses consistent searchParams, and concurrent token refreshes are deduplicated. ([#16010](https://github.com/mastra-ai/mastra/pull/16010))
8
+
9
+ - Updated dependencies [[`e109607`](https://github.com/mastra-ai/mastra/commit/e10960749251e34d46b480a20648c490fd30381b)]:
10
+ - @mastra/core@1.31.0-alpha.1
11
+
12
+ ## 0.1.0-alpha.0
13
+
14
+ ### Minor Changes
15
+
16
+ - Add `@mastra/google-drive`, a new Google Drive `WorkspaceFilesystem` provider that mounts a single Drive folder as an agent workspace. Supports OAuth access tokens, async refresh callbacks, and service account (JWT) authentication. Implements the full `WorkspaceFilesystem` interface — read, write, list, copy, move, mkdir, rmdir, stat, exists — plus `expectedMtime` optimistic concurrency. ([#15756](https://github.com/mastra-ai/mastra/pull/15756))
17
+
18
+ ```typescript
19
+ import { Agent } from '@mastra/core/agent';
20
+ import { Workspace } from '@mastra/core/workspace';
21
+ import { GoogleDriveFilesystem } from '@mastra/google-drive';
22
+
23
+ const workspace = new Workspace({
24
+ filesystem: new GoogleDriveFilesystem({
25
+ folderId: process.env.GOOGLE_DRIVE_FOLDER_ID!,
26
+ accessToken: process.env.GOOGLE_DRIVE_ACCESS_TOKEN!,
27
+ }),
28
+ });
29
+
30
+ const agent = new Agent({
31
+ id: 'drive-agent',
32
+ name: 'Drive Agent',
33
+ model: 'openai/gpt-4o-mini',
34
+ workspace,
35
+ });
36
+ ```
37
+
38
+ A matching `googleDriveFilesystemProvider` descriptor is also exported for MastraEditor.
39
+
40
+ ### Patch Changes
41
+
42
+ - Updated dependencies [[`1723e09`](https://github.com/mastra-ai/mastra/commit/1723e099829892419ddbfe49287acfeac2522724), [`629f9e9`](https://github.com/mastra-ai/mastra/commit/629f9e9a7e56aa8f129515a3923c5813298790c7), [`25168fb`](https://github.com/mastra-ai/mastra/commit/25168fb9c1de9db7f8171df4f58ceb842c53aa29), [`ab34b5a`](https://github.com/mastra-ai/mastra/commit/ab34b5a2191b8e4353df1dbf7b9155e7d6628d79), [`5fb6c2a`](https://github.com/mastra-ai/mastra/commit/5fb6c2a95c1843cc231704b91354311fc1f34a71), [`394f0cf`](https://github.com/mastra-ai/mastra/commit/394f0cfc31e6b4d801219fdef2e9cc69e5bc8682), [`3d7f709`](https://github.com/mastra-ai/mastra/commit/3d7f709b615e588050bb6283c4ee5cfe2978cbde), [`48a42f1`](https://github.com/mastra-ai/mastra/commit/48a42f114a4006a95e0b7a1b5ad1a24815a175c2), [`2c83efc`](https://github.com/mastra-ai/mastra/commit/2c83efc4482b3efe50830e3b8b4ba9a8d219edff), [`282a10c`](https://github.com/mastra-ai/mastra/commit/282a10c9446e9922afe80e10e3770481c8ac8a28)]:
43
+ - @mastra/core@1.31.0-alpha.0
package/LICENSE.md ADDED
@@ -0,0 +1,30 @@
1
+ Portions of this software are licensed as follows:
2
+
3
+ - All content that resides under any directory named "ee/" within this
4
+ repository, including but not limited to:
5
+ - `packages/core/src/auth/ee/`
6
+ - `packages/server/src/server/auth/ee/`
7
+ is licensed under the license defined in `ee/LICENSE`.
8
+
9
+ - All third-party components incorporated into the Mastra Software are
10
+ licensed under the original license provided by the owner of the
11
+ applicable component.
12
+
13
+ - Content outside of the above-mentioned directories or restrictions is
14
+ available under the "Apache License 2.0" as defined below.
15
+
16
+ # Apache License 2.0
17
+
18
+ Copyright (c) 2025 Kepler Software, Inc.
19
+
20
+ Licensed under the Apache License, Version 2.0 (the "License");
21
+ you may not use this file except in compliance with the License.
22
+ You may obtain a copy of the License at
23
+
24
+ http://www.apache.org/licenses/LICENSE-2.0
25
+
26
+ Unless required by applicable law or agreed to in writing, software
27
+ distributed under the License is distributed on an "AS IS" BASIS,
28
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29
+ See the License for the specific language governing permissions and
30
+ limitations under the License.
@@ -1,6 +1,6 @@
1
+ import type { RequestContext } from '@mastra/core/request-context';
1
2
  import { MastraFilesystem } from '@mastra/core/workspace';
2
3
  import type { CopyOptions, FileContent, FileEntry, FileStat, FilesystemInfo, InstructionsOption, ListOptions, MastraFilesystemOptions, ProviderStatus, ReadOptions, RemoveOptions, WriteOptions } from '@mastra/core/workspace';
3
- import type { RequestContext } from '@mastra/core/request-context';
4
4
  export interface GoogleDriveServiceAccount {
5
5
  clientEmail: string;
6
6
  privateKey: string;
@@ -27,6 +27,7 @@ export declare class GoogleDriveFilesystem extends MastraFilesystem {
27
27
  status: ProviderStatus;
28
28
  private accessToken?;
29
29
  private tokenExpiresAt;
30
+ private tokenRefreshPromise?;
30
31
  private readonly folderId;
31
32
  private readonly getAccessToken?;
32
33
  private readonly serviceAccount?;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/filesystem/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/filesystem/index.ts"],"names":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -25,6 +25,7 @@ var GoogleDriveFilesystem = class extends workspace.MastraFilesystem {
25
25
  status = "pending";
26
26
  accessToken;
27
27
  tokenExpiresAt = 0;
28
+ tokenRefreshPromise;
28
29
  folderId;
29
30
  getAccessToken;
30
31
  serviceAccount;
@@ -82,7 +83,10 @@ var GoogleDriveFilesystem = class extends workspace.MastraFilesystem {
82
83
  await this.ensureReady();
83
84
  const file = await this.getFile(path);
84
85
  if (file.mimeType === FOLDER_MIME_TYPE) throw new workspace.IsDirectoryError(path);
85
- const response = await this.fetch(`${DRIVE_API}/files/${encodeURIComponent(file.id)}?alt=media`, { method: "GET" });
86
+ const response = await this.fetch(`${DRIVE_API}/files/${encodeURIComponent(file.id)}`, {
87
+ method: "GET",
88
+ searchParams: { alt: "media" }
89
+ });
86
90
  const buffer = Buffer.from(await response.arrayBuffer());
87
91
  return options?.encoding ? buffer.toString(options.encoding) : buffer;
88
92
  }
@@ -106,8 +110,19 @@ var GoogleDriveFilesystem = class extends workspace.MastraFilesystem {
106
110
  await this.upload(void 0, content, options?.mimeType, "POST", { name, parents: [parentId] });
107
111
  }
108
112
  async appendFile(path, content) {
109
- const current = await this.exists(path) ? await this.readFile(path) : Buffer.alloc(0);
110
- await this.writeFile(path, Buffer.concat([this.toBuffer(current), this.toBuffer(content)]), { recursive: true });
113
+ await this.ensureReady();
114
+ this.assertWritable("appendFile");
115
+ const existing = await this.findFile(path);
116
+ if (existing) {
117
+ if (existing.mimeType === FOLDER_MIME_TYPE) throw new workspace.IsDirectoryError(path);
118
+ const current = await this.readFile(path);
119
+ const expectedMtime = existing.modifiedTime ? new Date(existing.modifiedTime) : void 0;
120
+ await this.writeFile(path, Buffer.concat([this.toBuffer(current), this.toBuffer(content)]), {
121
+ expectedMtime
122
+ });
123
+ } else {
124
+ await this.writeFile(path, content, { recursive: true });
125
+ }
111
126
  }
112
127
  async deleteFile(path, options) {
113
128
  await this.ensureReady();
@@ -127,6 +142,7 @@ var GoogleDriveFilesystem = class extends workspace.MastraFilesystem {
127
142
  if (source.mimeType === FOLDER_MIME_TYPE) throw new workspace.IsDirectoryError(src);
128
143
  const existing = await this.findFile(dest);
129
144
  if (existing) {
145
+ if (existing.id === source.id) throw new workspace.FileExistsError(dest);
130
146
  if (existing.mimeType === FOLDER_MIME_TYPE || options?.overwrite === false) throw new workspace.FileExistsError(dest);
131
147
  await this.deleteAny(existing, dest, true);
132
148
  }
@@ -165,7 +181,7 @@ var GoogleDriveFilesystem = class extends workspace.MastraFilesystem {
165
181
  if (existing.mimeType !== FOLDER_MIME_TYPE) throw new workspace.FileExistsError(path);
166
182
  return;
167
183
  }
168
- const { parentId, name } = await this.resolveParent(path, options?.recursive ?? false);
184
+ const { parentId, name } = await this.resolveParent(path, options?.recursive ?? true);
169
185
  await this.createFolder(parentId, name);
170
186
  }
171
187
  async rmdir(path, options) {
@@ -177,8 +193,10 @@ var GoogleDriveFilesystem = class extends workspace.MastraFilesystem {
177
193
  throw new workspace.DirectoryNotFoundError(path);
178
194
  }
179
195
  if (dir.mimeType !== FOLDER_MIME_TYPE) throw new workspace.NotDirectoryError(path);
180
- const children = await this.listChildren(dir.id);
181
- if (children.length && !options?.recursive) throw new workspace.DirectoryNotEmptyError(path);
196
+ if (!options?.recursive) {
197
+ const children = await this.listChildren(dir.id);
198
+ if (children.length) throw new workspace.DirectoryNotEmptyError(path);
199
+ }
182
200
  await this.request(`${DRIVE_API}/files/${encodeURIComponent(dir.id)}`, { method: "DELETE" });
183
201
  }
184
202
  async readdir(path, options) {
@@ -368,9 +386,13 @@ Content-Type: ${mimeType}\r
368
386
  const token = await this.getToken();
369
387
  const target = new URL(url);
370
388
  for (const [key, value] of Object.entries(init.searchParams ?? {})) target.searchParams.set(key, value);
389
+ const headers = { Authorization: `Bearer ${token}` };
390
+ if (init.body && typeof init.body === "string" && !init.headers) {
391
+ headers["Content-Type"] = "application/json";
392
+ }
371
393
  const response = await globalThis.fetch(target, {
372
394
  ...init,
373
- headers: { Authorization: `Bearer ${token}`, ...init.headers }
395
+ headers: { ...headers, ...init.headers }
374
396
  });
375
397
  if (!response.ok) {
376
398
  const message = await response.text().catch(() => response.statusText);
@@ -381,7 +403,14 @@ Content-Type: ${mimeType}\r
381
403
  async getToken() {
382
404
  if (this.accessToken && Date.now() < this.tokenExpiresAt - 6e4) return this.accessToken;
383
405
  if (this.getAccessToken) return this.getAccessToken();
384
- if (this.serviceAccount) return this.getServiceAccountToken();
406
+ if (this.serviceAccount) {
407
+ if (!this.tokenRefreshPromise) {
408
+ this.tokenRefreshPromise = this.getServiceAccountToken().finally(() => {
409
+ this.tokenRefreshPromise = void 0;
410
+ });
411
+ }
412
+ return this.tokenRefreshPromise;
413
+ }
385
414
  if (this.accessToken) return this.accessToken;
386
415
  throw new Error("GoogleDriveFilesystem requires accessToken, getAccessToken, or serviceAccount authentication.");
387
416
  }
@@ -462,6 +491,22 @@ var googleDriveFilesystemProvider = {
462
491
  type: "string",
463
492
  description: "OAuth access token with the https://www.googleapis.com/auth/drive scope"
464
493
  },
494
+ serviceAccount: {
495
+ type: "object",
496
+ required: ["clientEmail", "privateKey"],
497
+ properties: {
498
+ clientEmail: { type: "string", description: "Google service account email" },
499
+ privateKey: { type: "string", description: "PEM-encoded private key" },
500
+ privateKeyId: { type: "string", description: "Optional private key ID" },
501
+ scopes: {
502
+ type: "array",
503
+ items: { type: "string" },
504
+ description: "Optional OAuth scopes override"
505
+ },
506
+ subject: { type: "string", description: "Optional delegated user email" }
507
+ },
508
+ description: "Service account credentials for server-to-server auth"
509
+ },
465
510
  readOnly: { type: "boolean", description: "Mount as read-only", default: false }
466
511
  }
467
512
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/filesystem/index.ts","../src/provider.ts"],"names":["MastraFilesystem","IsDirectoryError","FileExistsError","StaleFileError","FileNotFoundError","DirectoryNotFoundError","NotDirectoryError","DirectoryNotEmptyError","WorkspaceReadOnlyError","createSign"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createSign } from 'node:crypto';\nimport {\n DirectoryNotEmptyError,\n DirectoryNotFoundError,\n FileExistsError,\n FileNotFoundError,\n IsDirectoryError,\n MastraFilesystem,\n NotDirectoryError,\n StaleFileError,\n WorkspaceReadOnlyError,\n} from '@mastra/core/workspace';\nimport type {\n CopyOptions,\n FileContent,\n FileEntry,\n FileStat,\n FilesystemInfo,\n InstructionsOption,\n ListOptions,\n MastraFilesystemOptions,\n ProviderStatus,\n ReadOptions,\n RemoveOptions,\n WriteOptions,\n} from '@mastra/core/workspace';\nimport type { RequestContext } from '@mastra/core/request-context';\n\nconst DRIVE_API = 'https://www.googleapis.com/drive/v3';\nconst DRIVE_UPLOAD_API = 'https://www.googleapis.com/upload/drive/v3';\nconst OAUTH_TOKEN_URL = 'https://oauth2.googleapis.com/token';\nconst FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder';\n// Use the full `drive` scope by default — `drive.file` only exposes files the app created or\n// the user explicitly opened via a picker, so a folder shared with the service account would\n// be invisible and return 404 on access.\nconst DEFAULT_SCOPES = ['https://www.googleapis.com/auth/drive'];\n\n/**\n * Resolve an instructions override against default instructions.\n *\n * - `undefined` → return default\n * - `string` → return the string as-is\n * - `function` → call with { defaultInstructions, requestContext }\n */\nfunction resolveInstructions(\n override: InstructionsOption | undefined,\n getDefault: () => string,\n requestContext?: RequestContext,\n): string {\n if (typeof override === 'string') return override;\n const defaultInstructions = getDefault();\n if (override === undefined) return defaultInstructions;\n return override({ defaultInstructions, requestContext });\n}\n\nexport interface GoogleDriveServiceAccount {\n clientEmail: string;\n privateKey: string;\n privateKeyId?: string;\n scopes?: string[];\n subject?: string;\n}\n\nexport interface GoogleDriveFilesystemOptions extends MastraFilesystemOptions {\n id?: string;\n folderId: string;\n accessToken?: string;\n getAccessToken?: () => string | Promise<string>;\n serviceAccount?: GoogleDriveServiceAccount;\n readOnly?: boolean;\n instructions?: InstructionsOption;\n}\n\ninterface DriveFile {\n id: string;\n name: string;\n mimeType: string;\n size?: string;\n createdTime?: string;\n modifiedTime?: string;\n parents?: string[];\n trashed?: boolean;\n}\n\nexport class GoogleDriveFilesystem extends MastraFilesystem {\n readonly id: string;\n readonly name = 'GoogleDriveFilesystem';\n readonly provider = 'google-drive';\n readonly readOnly?: boolean;\n readonly icon = 'drive';\n readonly displayName = 'Google Drive';\n\n status: ProviderStatus = 'pending';\n\n private accessToken?: string;\n private tokenExpiresAt = 0;\n private readonly folderId: string;\n private readonly getAccessToken?: () => string | Promise<string>;\n private readonly serviceAccount?: GoogleDriveServiceAccount;\n private readonly instructionsOverride?: InstructionsOption;\n\n constructor(options: GoogleDriveFilesystemOptions) {\n super({ name: 'GoogleDriveFilesystem', ...options });\n this.id = options.id ?? `google-drive:${options.folderId}`;\n this.folderId = options.folderId;\n this.accessToken = options.accessToken;\n this.getAccessToken = options.getAccessToken;\n this.serviceAccount = options.serviceAccount;\n this.readOnly = options.readOnly;\n this.instructionsOverride = options.instructions;\n }\n\n async init(): Promise<void> {\n const driveFile = await this.request<DriveFile>(`${DRIVE_API}/files/${encodeURIComponent(this.folderId)}`, {\n searchParams: { fields: 'id,name,mimeType,trashed', supportsAllDrives: 'true' },\n });\n\n if (driveFile.trashed) {\n throw new Error(`Google Drive folder ${this.folderId} is trashed and cannot be used as a filesystem root.`);\n }\n\n if (driveFile.mimeType !== FOLDER_MIME_TYPE) {\n throw new Error(\n `Google Drive root ${this.folderId} must be a folder, but received mimeType ${driveFile.mimeType ?? 'unknown'}.`,\n );\n }\n }\n\n async destroy(): Promise<void> {}\n\n async isReady(): Promise<boolean> {\n return this.status === 'ready';\n }\n\n getInfo(): FilesystemInfo {\n return {\n id: this.id,\n name: this.name,\n provider: this.provider,\n status: this.status,\n error: this.error,\n readOnly: this.readOnly,\n icon: this.icon,\n metadata: { folderId: this.folderId },\n };\n }\n\n getInstructions(opts?: { requestContext?: RequestContext }): string {\n const defaultInstructions = [\n 'Google Drive filesystem mounted to a single folder.',\n 'Use POSIX-style paths relative to that folder, for example /notes/todo.txt.',\n 'Directories are Google Drive folders. File names must be unique within each folder for path-based operations.',\n this.readOnly\n ? 'This Google Drive filesystem is read-only.'\n : 'You can read, create, update, move, copy, and delete files in this folder.',\n ].join('\\n');\n return resolveInstructions(this.instructionsOverride, () => defaultInstructions, opts?.requestContext);\n }\n\n async readFile(path: string, options?: ReadOptions): Promise<string | Buffer> {\n await this.ensureReady();\n const file = await this.getFile(path);\n if (file.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n const response = await this.fetch(`${DRIVE_API}/files/${encodeURIComponent(file.id)}?alt=media`, { method: 'GET' });\n const buffer = Buffer.from(await response.arrayBuffer());\n return options?.encoding ? buffer.toString(options.encoding) : buffer;\n }\n\n async writeFile(path: string, content: FileContent, options?: WriteOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('writeFile');\n const existing = await this.findFile(path);\n if (existing) {\n if (existing.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n if (options?.overwrite === false) throw new FileExistsError(path);\n if (options?.expectedMtime) {\n if (!existing.modifiedTime) throw new StaleFileError(path, options.expectedMtime, new Date(0));\n\n const actual = new Date(existing.modifiedTime);\n if (actual.getTime() !== options.expectedMtime.getTime())\n throw new StaleFileError(path, options.expectedMtime, actual);\n }\n await this.upload(existing.id, content, options?.mimeType, 'PATCH');\n return;\n }\n\n const { parentId, name } = await this.resolveParent(path, options?.recursive ?? true);\n await this.upload(undefined, content, options?.mimeType, 'POST', { name, parents: [parentId] });\n }\n\n async appendFile(path: string, content: FileContent): Promise<void> {\n const current = (await this.exists(path)) ? await this.readFile(path) : Buffer.alloc(0);\n await this.writeFile(path, Buffer.concat([this.toBuffer(current), this.toBuffer(content)]), { recursive: true });\n }\n\n async deleteFile(path: string, options?: RemoveOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('deleteFile');\n const file = await this.findFile(path);\n if (!file) {\n if (options?.force) return;\n throw new FileNotFoundError(path);\n }\n if (file.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n await this.request<void>(`${DRIVE_API}/files/${encodeURIComponent(file.id)}`, { method: 'DELETE' });\n }\n\n async copyFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('copyFile');\n const source = await this.getFile(src);\n if (source.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(src);\n const existing = await this.findFile(dest);\n if (existing) {\n if (existing.mimeType === FOLDER_MIME_TYPE || options?.overwrite === false) throw new FileExistsError(dest);\n await this.deleteAny(existing, dest, true);\n }\n const { parentId, name } = await this.resolveParent(dest, options?.recursive ?? true);\n await this.request(`${DRIVE_API}/files/${encodeURIComponent(source.id)}/copy`, {\n method: 'POST',\n body: JSON.stringify({ name, parents: [parentId] }),\n });\n }\n\n async moveFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('moveFile');\n const source = await this.getFile(src);\n if (options?.overwrite === false && (await this.exists(dest))) throw new FileExistsError(dest);\n const existing = await this.findFile(dest);\n if (existing && existing.id !== source.id) {\n if (existing.mimeType === FOLDER_MIME_TYPE || options?.overwrite === false) throw new FileExistsError(dest);\n await this.deleteAny(existing, dest, true);\n }\n const { parentId, name } = await this.resolveParent(dest, options?.recursive ?? true);\n const searchParams: Record<string, string> = { addParents: parentId, fields: 'id', supportsAllDrives: 'true' };\n const oldParents = source.parents?.join(',');\n if (oldParents) searchParams.removeParents = oldParents;\n await this.request(`${DRIVE_API}/files/${encodeURIComponent(source.id)}`, {\n method: 'PATCH',\n searchParams,\n body: JSON.stringify({ name }),\n });\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await this.ensureReady();\n this.assertWritable('mkdir');\n if (this.normalize(path) === '/') return;\n const existing = await this.findFile(path);\n if (existing) {\n if (existing.mimeType !== FOLDER_MIME_TYPE) throw new FileExistsError(path);\n return;\n }\n const { parentId, name } = await this.resolveParent(path, options?.recursive ?? false);\n await this.createFolder(parentId, name);\n }\n\n async rmdir(path: string, options?: RemoveOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('rmdir');\n const dir = await this.findFile(path);\n if (!dir) {\n if (options?.force) return;\n throw new DirectoryNotFoundError(path);\n }\n if (dir.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(path);\n const children = await this.listChildren(dir.id);\n if (children.length && !options?.recursive) throw new DirectoryNotEmptyError(path);\n await this.request<void>(`${DRIVE_API}/files/${encodeURIComponent(dir.id)}`, { method: 'DELETE' });\n }\n\n async readdir(path: string, options?: ListOptions): Promise<FileEntry[]> {\n await this.ensureReady();\n const dir = await this.getFile(path);\n if (dir.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(path);\n const entries = await this.readdirRecursive(dir.id, options, 0);\n const extensions = Array.isArray(options?.extension)\n ? options.extension\n : options?.extension\n ? [options.extension]\n : undefined;\n return extensions\n ? entries.filter(entry => entry.type === 'directory' || extensions.some(ext => entry.name.endsWith(ext)))\n : entries;\n }\n\n async exists(path: string): Promise<boolean> {\n await this.ensureReady();\n return Boolean(await this.findFile(path));\n }\n\n async stat(path: string): Promise<FileStat> {\n await this.ensureReady();\n const file = await this.getFile(path);\n const isDirectory = file.mimeType === FOLDER_MIME_TYPE;\n return {\n name: file.name,\n path: this.normalize(path),\n type: isDirectory ? 'directory' : 'file',\n size: Number(file.size ?? 0),\n createdAt: file.createdTime ? new Date(file.createdTime) : new Date(0),\n modifiedAt: file.modifiedTime ? new Date(file.modifiedTime) : new Date(0),\n mimeType: isDirectory ? undefined : file.mimeType,\n };\n }\n\n async realpath(path: string): Promise<string> {\n return this.normalize(path);\n }\n\n private assertWritable(operation: string): void {\n if (this.readOnly) throw new WorkspaceReadOnlyError(operation);\n }\n\n private toBuffer(content: FileContent): Buffer {\n if (Buffer.isBuffer(content)) return content;\n if (content instanceof Uint8Array) return Buffer.from(content);\n return Buffer.from(content, 'utf-8');\n }\n\n private normalize(path: string): string {\n const parts = path.split('/').filter(Boolean);\n const stack: string[] = [];\n for (const part of parts) {\n if (part === '.') continue;\n if (part === '..') stack.pop();\n else stack.push(part);\n }\n return `/${stack.join('/')}`;\n }\n\n private async getFile(path: string): Promise<DriveFile> {\n const file = await this.findFile(path);\n if (!file) throw new FileNotFoundError(path);\n return file;\n }\n\n private async findFile(path: string): Promise<DriveFile | undefined> {\n const normalized = this.normalize(path);\n if (normalized === '/') return this.rootFile();\n const names = normalized.split('/').filter(Boolean);\n let parentId = this.folderId;\n let file: DriveFile | undefined;\n for (const name of names) {\n file = await this.findChild(parentId, name);\n if (!file) return undefined;\n parentId = file.id;\n }\n return file;\n }\n\n private async rootFile(): Promise<DriveFile> {\n return this.request<DriveFile>(`${DRIVE_API}/files/${encodeURIComponent(this.folderId)}`, {\n searchParams: { fields: 'id,name,mimeType,size,createdTime,modifiedTime,parents', supportsAllDrives: 'true' },\n });\n }\n\n private async resolveParent(path: string, recursive: boolean): Promise<{ parentId: string; name: string }> {\n const normalized = this.normalize(path);\n const parts = normalized.split('/').filter(Boolean);\n const name = parts.pop();\n if (!name) throw new IsDirectoryError(path);\n const parentPath = `/${parts.join('/')}`;\n const parent = recursive ? await this.resolveDir(parentPath, true) : await this.findFile(parentPath);\n if (!parent) throw new DirectoryNotFoundError(parentPath);\n if (parent.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(parentPath);\n return { parentId: parent.id, name };\n }\n\n private async resolveDir(path: string, recursive: boolean): Promise<DriveFile> {\n const normalized = this.normalize(path);\n if (normalized === '/') return this.rootFile();\n const names = normalized.split('/').filter(Boolean);\n let parentId = this.folderId;\n let current: DriveFile | undefined;\n for (const name of names) {\n current = await this.findChild(parentId, name);\n if (current) {\n if (current.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(name);\n parentId = current.id;\n continue;\n }\n if (!recursive) throw new DirectoryNotFoundError(normalized);\n current = await this.createFolder(parentId, name);\n parentId = current.id;\n }\n return current!;\n }\n\n private async createFolder(parentId: string, name: string): Promise<DriveFile> {\n return this.request<DriveFile>(`${DRIVE_API}/files`, {\n method: 'POST',\n searchParams: { fields: 'id,name,mimeType,size,createdTime,modifiedTime,parents', supportsAllDrives: 'true' },\n body: JSON.stringify({ name, mimeType: FOLDER_MIME_TYPE, parents: [parentId] }),\n });\n }\n\n private async findChild(parentId: string, name: string): Promise<DriveFile | undefined> {\n const files = await this.listChildren(parentId, `name = '${this.escapeQuery(name)}'`);\n return files[0];\n }\n\n private async listChildren(parentId: string, extraQuery?: string): Promise<DriveFile[]> {\n const query = [`'${this.escapeQuery(parentId)}' in parents`, 'trashed = false', extraQuery]\n .filter(Boolean)\n .join(' and ');\n const files: DriveFile[] = [];\n let pageToken: string | undefined;\n\n do {\n const result = await this.request<{ files: DriveFile[]; nextPageToken?: string }>(`${DRIVE_API}/files`, {\n searchParams: {\n q: query,\n fields: 'nextPageToken,files(id,name,mimeType,size,createdTime,modifiedTime,parents)',\n pageSize: '1000',\n supportsAllDrives: 'true',\n includeItemsFromAllDrives: 'true',\n ...(pageToken ? { pageToken } : {}),\n },\n });\n files.push(...(result.files ?? []));\n pageToken = result.nextPageToken;\n } while (pageToken);\n\n return files;\n }\n\n private async readdirRecursive(\n parentId: string,\n options: ListOptions | undefined,\n depth: number,\n ): Promise<FileEntry[]> {\n const children = await this.listChildren(parentId);\n const entries: FileEntry[] = [];\n for (const child of children) {\n const isDirectory = child.mimeType === FOLDER_MIME_TYPE;\n entries.push({ name: child.name, type: isDirectory ? 'directory' : 'file', size: Number(child.size ?? 0) });\n const shouldDescend =\n isDirectory && options?.recursive && (options.maxDepth === undefined || depth < options.maxDepth);\n if (shouldDescend) {\n const nested = await this.readdirRecursive(child.id, options, depth + 1);\n entries.push(...nested.map(entry => ({ ...entry, name: `${child.name}/${entry.name}` })));\n }\n }\n return entries;\n }\n\n private async deleteAny(file: DriveFile, path: string, recursive: boolean): Promise<void> {\n if (file.mimeType === FOLDER_MIME_TYPE) await this.rmdir(path, { recursive, force: true });\n else await this.deleteFile(path, { force: true });\n }\n\n private async upload(\n fileId: string | undefined,\n content: FileContent,\n mimeType = 'application/octet-stream',\n method: 'POST' | 'PATCH',\n metadata?: Record<string, unknown>,\n ): Promise<void> {\n const boundary = `mastra-${Date.now()}`;\n const body = Buffer.concat([\n Buffer.from(\n `--${boundary}\\r\\nContent-Type: application/json; charset=UTF-8\\r\\n\\r\\n${JSON.stringify(metadata ?? {})}\\r\\n`,\n ),\n Buffer.from(`--${boundary}\\r\\nContent-Type: ${mimeType}\\r\\n\\r\\n`),\n this.toBuffer(content),\n Buffer.from(`\\r\\n--${boundary}--`),\n ]);\n const url = fileId ? `${DRIVE_UPLOAD_API}/files/${encodeURIComponent(fileId)}` : `${DRIVE_UPLOAD_API}/files`;\n await this.request(url, {\n method,\n searchParams: { uploadType: 'multipart', fields: 'id', supportsAllDrives: 'true' },\n headers: { 'Content-Type': `multipart/related; boundary=${boundary}` },\n body,\n });\n }\n\n private escapeQuery(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n }\n\n private async request<T>(\n url: string,\n init: RequestInit & { searchParams?: Record<string, string> } = {},\n ): Promise<T> {\n const response = await this.fetch(url, init);\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n }\n\n private async fetch(\n url: string,\n init: RequestInit & { searchParams?: Record<string, string> } = {},\n ): Promise<Response> {\n const token = await this.getToken();\n const target = new URL(url);\n for (const [key, value] of Object.entries(init.searchParams ?? {})) target.searchParams.set(key, value);\n const response = await globalThis.fetch(target, {\n ...init,\n headers: { Authorization: `Bearer ${token}`, ...init.headers },\n });\n if (!response.ok) {\n const message = await response.text().catch(() => response.statusText);\n throw new Error(`Google Drive API request failed (${response.status}): ${message}`);\n }\n return response;\n }\n\n private async getToken(): Promise<string> {\n if (this.accessToken && Date.now() < this.tokenExpiresAt - 60_000) return this.accessToken;\n if (this.getAccessToken) return this.getAccessToken();\n if (this.serviceAccount) return this.getServiceAccountToken();\n if (this.accessToken) return this.accessToken;\n throw new Error('GoogleDriveFilesystem requires accessToken, getAccessToken, or serviceAccount authentication.');\n }\n\n private async getServiceAccountToken(): Promise<string> {\n const account = this.serviceAccount!;\n const now = Math.floor(Date.now() / 1000);\n const header = { alg: 'RS256', typ: 'JWT', ...(account.privateKeyId ? { kid: account.privateKeyId } : {}) };\n const claim = {\n iss: account.clientEmail,\n scope: (account.scopes ?? DEFAULT_SCOPES).join(' '),\n aud: OAUTH_TOKEN_URL,\n exp: now + 3600,\n iat: now,\n ...(account.subject ? { sub: account.subject } : {}),\n };\n const unsigned = `${this.base64Url(JSON.stringify(header))}.${this.base64Url(JSON.stringify(claim))}`;\n const privateKey = this.normalizePrivateKey(account.privateKey);\n let signature: string;\n try {\n signature = createSign('RSA-SHA256').update(unsigned).sign(privateKey, 'base64url');\n } catch (err) {\n const hasBegin = privateKey.includes('-----BEGIN');\n const hasEnd = privateKey.includes('-----END');\n throw new Error(\n `Google service account private key signing failed (${(err as Error).message}). ` +\n `Key has BEGIN marker: ${hasBegin}, END marker: ${hasEnd}. ` +\n `Ensure your .env value contains the raw PEM with \\\\n for newlines, without extra surrounding quotes or commas.`,\n );\n }\n const response = await globalThis.fetch(OAUTH_TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',\n assertion: `${unsigned}.${signature}`,\n }),\n });\n if (!response.ok)\n throw new Error(`Google service account token request failed (${response.status}): ${await response.text()}`);\n const json = (await response.json()) as { access_token: string; expires_in: number };\n this.accessToken = json.access_token;\n this.tokenExpiresAt = Date.now() + json.expires_in * 1000;\n return json.access_token;\n }\n\n private base64Url(value: string): string {\n return Buffer.from(value).toString('base64url');\n }\n\n private normalizePrivateKey(key: string): string {\n let out = key.trim();\n // Iteratively strip JSON-style wrapping that .env files tend to accumulate:\n // trailing commas, literal backslash-escaped quotes, and plain surrounding quotes.\n // Loop because values can be doubly wrapped (e.g. a JSON-encoded string pasted into\n // a .env file still wrapped in quotes by the dotenv loader).\n for (let i = 0; i < 5; i++) {\n const before = out;\n if (out.endsWith(',')) out = out.slice(0, -1).trim();\n if ((out.startsWith('\"') && out.endsWith('\"')) || (out.startsWith(\"'\") && out.endsWith(\"'\"))) {\n out = out.slice(1, -1);\n }\n if ((out.startsWith('\\\\\"') && out.endsWith('\\\\\"')) || (out.startsWith(\"\\\\'\") && out.endsWith(\"\\\\'\"))) {\n out = out.slice(2, -2);\n }\n if (out === before) break;\n }\n // Replace escaped newlines with real newlines (common when storing the key on one line in .env).\n out = out.replace(/\\\\n/g, '\\n');\n // Unescape any remaining escaped quotes that survived the unwrapping.\n out = out.replace(/\\\\\"/g, '\"').replace(/\\\\'/g, \"'\");\n // Normalize CRLF / CR to LF — OpenSSL's PEM decoder is strict about line endings.\n out = out.replace(/\\r\\n?/g, '\\n');\n // Ensure PEM ends with a trailing newline — required by some OpenSSL versions.\n if (!out.endsWith('\\n')) out += '\\n';\n return out;\n }\n}\n","/**\n * Google Drive filesystem provider descriptor for MastraEditor.\n *\n * @example\n * ```typescript\n * import { googleDriveFilesystemProvider } from '@mastra/google-drive';\n *\n * const editor = new MastraEditor({\n * filesystems: [googleDriveFilesystemProvider],\n * });\n * ```\n */\nimport type { FilesystemProvider } from '@mastra/core/editor';\nimport { GoogleDriveFilesystem } from './filesystem';\nimport type { GoogleDriveFilesystemOptions } from './filesystem';\n\nexport const googleDriveFilesystemProvider: FilesystemProvider<GoogleDriveFilesystemOptions> = {\n id: 'google-drive',\n name: 'Google Drive',\n description: 'Google Drive folder mounted as a filesystem',\n configSchema: {\n type: 'object',\n required: ['folderId'],\n properties: {\n folderId: { type: 'string', description: 'Google Drive folder ID to mount as the workspace root' },\n accessToken: {\n type: 'string',\n description: 'OAuth access token with the https://www.googleapis.com/auth/drive scope',\n },\n readOnly: { type: 'boolean', description: 'Mount as read-only', default: false },\n },\n },\n createFilesystem: config => new GoogleDriveFilesystem(config),\n};\n"]}
1
+ {"version":3,"sources":["../src/filesystem/index.ts","../src/provider.ts"],"names":["MastraFilesystem","IsDirectoryError","FileExistsError","StaleFileError","FileNotFoundError","DirectoryNotFoundError","NotDirectoryError","DirectoryNotEmptyError","WorkspaceReadOnlyError","createSign"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createSign } from 'node:crypto';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport {\n DirectoryNotEmptyError,\n DirectoryNotFoundError,\n FileExistsError,\n FileNotFoundError,\n IsDirectoryError,\n MastraFilesystem,\n NotDirectoryError,\n StaleFileError,\n WorkspaceReadOnlyError,\n} from '@mastra/core/workspace';\nimport type {\n CopyOptions,\n FileContent,\n FileEntry,\n FileStat,\n FilesystemInfo,\n InstructionsOption,\n ListOptions,\n MastraFilesystemOptions,\n ProviderStatus,\n ReadOptions,\n RemoveOptions,\n WriteOptions,\n} from '@mastra/core/workspace';\n\nconst DRIVE_API = 'https://www.googleapis.com/drive/v3';\nconst DRIVE_UPLOAD_API = 'https://www.googleapis.com/upload/drive/v3';\nconst OAUTH_TOKEN_URL = 'https://oauth2.googleapis.com/token';\nconst FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder';\n// Use the full `drive` scope by default — `drive.file` only exposes files the app created or\n// the user explicitly opened via a picker, so a folder shared with the service account would\n// be invisible and return 404 on access.\nconst DEFAULT_SCOPES = ['https://www.googleapis.com/auth/drive'];\n\n/**\n * Resolve an instructions override against default instructions.\n *\n * - `undefined` → return default\n * - `string` → return the string as-is\n * - `function` → call with { defaultInstructions, requestContext }\n */\nfunction resolveInstructions(\n override: InstructionsOption | undefined,\n getDefault: () => string,\n requestContext?: RequestContext,\n): string {\n if (typeof override === 'string') return override;\n const defaultInstructions = getDefault();\n if (override === undefined) return defaultInstructions;\n return override({ defaultInstructions, requestContext });\n}\n\nexport interface GoogleDriveServiceAccount {\n clientEmail: string;\n privateKey: string;\n privateKeyId?: string;\n scopes?: string[];\n subject?: string;\n}\n\nexport interface GoogleDriveFilesystemOptions extends MastraFilesystemOptions {\n id?: string;\n folderId: string;\n accessToken?: string;\n getAccessToken?: () => string | Promise<string>;\n serviceAccount?: GoogleDriveServiceAccount;\n readOnly?: boolean;\n instructions?: InstructionsOption;\n}\n\ninterface DriveFile {\n id: string;\n name: string;\n mimeType: string;\n size?: string;\n createdTime?: string;\n modifiedTime?: string;\n parents?: string[];\n trashed?: boolean;\n}\n\nexport class GoogleDriveFilesystem extends MastraFilesystem {\n readonly id: string;\n readonly name = 'GoogleDriveFilesystem';\n readonly provider = 'google-drive';\n readonly readOnly?: boolean;\n readonly icon = 'drive';\n readonly displayName = 'Google Drive';\n\n status: ProviderStatus = 'pending';\n\n private accessToken?: string;\n private tokenExpiresAt = 0;\n private tokenRefreshPromise?: Promise<string>;\n private readonly folderId: string;\n private readonly getAccessToken?: () => string | Promise<string>;\n private readonly serviceAccount?: GoogleDriveServiceAccount;\n private readonly instructionsOverride?: InstructionsOption;\n\n constructor(options: GoogleDriveFilesystemOptions) {\n super({ name: 'GoogleDriveFilesystem', ...options });\n this.id = options.id ?? `google-drive:${options.folderId}`;\n this.folderId = options.folderId;\n this.accessToken = options.accessToken;\n this.getAccessToken = options.getAccessToken;\n this.serviceAccount = options.serviceAccount;\n this.readOnly = options.readOnly;\n this.instructionsOverride = options.instructions;\n }\n\n async init(): Promise<void> {\n const driveFile = await this.request<DriveFile>(`${DRIVE_API}/files/${encodeURIComponent(this.folderId)}`, {\n searchParams: { fields: 'id,name,mimeType,trashed', supportsAllDrives: 'true' },\n });\n\n if (driveFile.trashed) {\n throw new Error(`Google Drive folder ${this.folderId} is trashed and cannot be used as a filesystem root.`);\n }\n\n if (driveFile.mimeType !== FOLDER_MIME_TYPE) {\n throw new Error(\n `Google Drive root ${this.folderId} must be a folder, but received mimeType ${driveFile.mimeType ?? 'unknown'}.`,\n );\n }\n }\n\n async destroy(): Promise<void> {}\n\n async isReady(): Promise<boolean> {\n return this.status === 'ready';\n }\n\n getInfo(): FilesystemInfo {\n return {\n id: this.id,\n name: this.name,\n provider: this.provider,\n status: this.status,\n error: this.error,\n readOnly: this.readOnly,\n icon: this.icon,\n metadata: { folderId: this.folderId },\n };\n }\n\n getInstructions(opts?: { requestContext?: RequestContext }): string {\n const defaultInstructions = [\n 'Google Drive filesystem mounted to a single folder.',\n 'Use POSIX-style paths relative to that folder, for example /notes/todo.txt.',\n 'Directories are Google Drive folders. File names must be unique within each folder for path-based operations.',\n this.readOnly\n ? 'This Google Drive filesystem is read-only.'\n : 'You can read, create, update, move, copy, and delete files in this folder.',\n ].join('\\n');\n return resolveInstructions(this.instructionsOverride, () => defaultInstructions, opts?.requestContext);\n }\n\n async readFile(path: string, options?: ReadOptions): Promise<string | Buffer> {\n await this.ensureReady();\n const file = await this.getFile(path);\n if (file.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n const response = await this.fetch(`${DRIVE_API}/files/${encodeURIComponent(file.id)}`, {\n method: 'GET',\n searchParams: { alt: 'media' },\n });\n const buffer = Buffer.from(await response.arrayBuffer());\n return options?.encoding ? buffer.toString(options.encoding) : buffer;\n }\n\n async writeFile(path: string, content: FileContent, options?: WriteOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('writeFile');\n const existing = await this.findFile(path);\n if (existing) {\n if (existing.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n if (options?.overwrite === false) throw new FileExistsError(path);\n if (options?.expectedMtime) {\n if (!existing.modifiedTime) throw new StaleFileError(path, options.expectedMtime, new Date(0));\n\n const actual = new Date(existing.modifiedTime);\n if (actual.getTime() !== options.expectedMtime.getTime())\n throw new StaleFileError(path, options.expectedMtime, actual);\n }\n await this.upload(existing.id, content, options?.mimeType, 'PATCH');\n return;\n }\n\n const { parentId, name } = await this.resolveParent(path, options?.recursive ?? true);\n await this.upload(undefined, content, options?.mimeType, 'POST', { name, parents: [parentId] });\n }\n\n async appendFile(path: string, content: FileContent): Promise<void> {\n await this.ensureReady();\n this.assertWritable('appendFile');\n const existing = await this.findFile(path);\n if (existing) {\n if (existing.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n const current = await this.readFile(path);\n const expectedMtime = existing.modifiedTime ? new Date(existing.modifiedTime) : undefined;\n await this.writeFile(path, Buffer.concat([this.toBuffer(current), this.toBuffer(content)]), {\n expectedMtime,\n });\n } else {\n await this.writeFile(path, content, { recursive: true });\n }\n }\n\n async deleteFile(path: string, options?: RemoveOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('deleteFile');\n const file = await this.findFile(path);\n if (!file) {\n if (options?.force) return;\n throw new FileNotFoundError(path);\n }\n if (file.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n await this.request<void>(`${DRIVE_API}/files/${encodeURIComponent(file.id)}`, { method: 'DELETE' });\n }\n\n async copyFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('copyFile');\n const source = await this.getFile(src);\n if (source.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(src);\n const existing = await this.findFile(dest);\n if (existing) {\n if (existing.id === source.id) throw new FileExistsError(dest);\n if (existing.mimeType === FOLDER_MIME_TYPE || options?.overwrite === false) throw new FileExistsError(dest);\n await this.deleteAny(existing, dest, true);\n }\n const { parentId, name } = await this.resolveParent(dest, options?.recursive ?? true);\n await this.request(`${DRIVE_API}/files/${encodeURIComponent(source.id)}/copy`, {\n method: 'POST',\n body: JSON.stringify({ name, parents: [parentId] }),\n });\n }\n\n async moveFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('moveFile');\n const source = await this.getFile(src);\n if (options?.overwrite === false && (await this.exists(dest))) throw new FileExistsError(dest);\n const existing = await this.findFile(dest);\n if (existing && existing.id !== source.id) {\n if (existing.mimeType === FOLDER_MIME_TYPE || options?.overwrite === false) throw new FileExistsError(dest);\n await this.deleteAny(existing, dest, true);\n }\n const { parentId, name } = await this.resolveParent(dest, options?.recursive ?? true);\n const searchParams: Record<string, string> = { addParents: parentId, fields: 'id', supportsAllDrives: 'true' };\n const oldParents = source.parents?.join(',');\n if (oldParents) searchParams.removeParents = oldParents;\n await this.request(`${DRIVE_API}/files/${encodeURIComponent(source.id)}`, {\n method: 'PATCH',\n searchParams,\n body: JSON.stringify({ name }),\n });\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await this.ensureReady();\n this.assertWritable('mkdir');\n if (this.normalize(path) === '/') return;\n const existing = await this.findFile(path);\n if (existing) {\n if (existing.mimeType !== FOLDER_MIME_TYPE) throw new FileExistsError(path);\n return;\n }\n const { parentId, name } = await this.resolveParent(path, options?.recursive ?? true);\n await this.createFolder(parentId, name);\n }\n\n async rmdir(path: string, options?: RemoveOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('rmdir');\n const dir = await this.findFile(path);\n if (!dir) {\n if (options?.force) return;\n throw new DirectoryNotFoundError(path);\n }\n if (dir.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(path);\n if (!options?.recursive) {\n const children = await this.listChildren(dir.id);\n if (children.length) throw new DirectoryNotEmptyError(path);\n }\n await this.request<void>(`${DRIVE_API}/files/${encodeURIComponent(dir.id)}`, { method: 'DELETE' });\n }\n\n async readdir(path: string, options?: ListOptions): Promise<FileEntry[]> {\n await this.ensureReady();\n const dir = await this.getFile(path);\n if (dir.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(path);\n const entries = await this.readdirRecursive(dir.id, options, 0);\n const extensions = Array.isArray(options?.extension)\n ? options.extension\n : options?.extension\n ? [options.extension]\n : undefined;\n return extensions\n ? entries.filter(entry => entry.type === 'directory' || extensions.some(ext => entry.name.endsWith(ext)))\n : entries;\n }\n\n async exists(path: string): Promise<boolean> {\n await this.ensureReady();\n return Boolean(await this.findFile(path));\n }\n\n async stat(path: string): Promise<FileStat> {\n await this.ensureReady();\n const file = await this.getFile(path);\n const isDirectory = file.mimeType === FOLDER_MIME_TYPE;\n return {\n name: file.name,\n path: this.normalize(path),\n type: isDirectory ? 'directory' : 'file',\n size: Number(file.size ?? 0),\n createdAt: file.createdTime ? new Date(file.createdTime) : new Date(0),\n modifiedAt: file.modifiedTime ? new Date(file.modifiedTime) : new Date(0),\n mimeType: isDirectory ? undefined : file.mimeType,\n };\n }\n\n async realpath(path: string): Promise<string> {\n return this.normalize(path);\n }\n\n private assertWritable(operation: string): void {\n if (this.readOnly) throw new WorkspaceReadOnlyError(operation);\n }\n\n private toBuffer(content: FileContent): Buffer {\n if (Buffer.isBuffer(content)) return content;\n if (content instanceof Uint8Array) return Buffer.from(content);\n return Buffer.from(content, 'utf-8');\n }\n\n private normalize(path: string): string {\n const parts = path.split('/').filter(Boolean);\n const stack: string[] = [];\n for (const part of parts) {\n if (part === '.') continue;\n if (part === '..') stack.pop();\n else stack.push(part);\n }\n return `/${stack.join('/')}`;\n }\n\n private async getFile(path: string): Promise<DriveFile> {\n const file = await this.findFile(path);\n if (!file) throw new FileNotFoundError(path);\n return file;\n }\n\n private async findFile(path: string): Promise<DriveFile | undefined> {\n const normalized = this.normalize(path);\n if (normalized === '/') return this.rootFile();\n const names = normalized.split('/').filter(Boolean);\n let parentId = this.folderId;\n let file: DriveFile | undefined;\n for (const name of names) {\n file = await this.findChild(parentId, name);\n if (!file) return undefined;\n parentId = file.id;\n }\n return file;\n }\n\n private async rootFile(): Promise<DriveFile> {\n return this.request<DriveFile>(`${DRIVE_API}/files/${encodeURIComponent(this.folderId)}`, {\n searchParams: { fields: 'id,name,mimeType,size,createdTime,modifiedTime,parents', supportsAllDrives: 'true' },\n });\n }\n\n private async resolveParent(path: string, recursive: boolean): Promise<{ parentId: string; name: string }> {\n const normalized = this.normalize(path);\n const parts = normalized.split('/').filter(Boolean);\n const name = parts.pop();\n if (!name) throw new IsDirectoryError(path);\n const parentPath = `/${parts.join('/')}`;\n const parent = recursive ? await this.resolveDir(parentPath, true) : await this.findFile(parentPath);\n if (!parent) throw new DirectoryNotFoundError(parentPath);\n if (parent.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(parentPath);\n return { parentId: parent.id, name };\n }\n\n private async resolveDir(path: string, recursive: boolean): Promise<DriveFile> {\n const normalized = this.normalize(path);\n if (normalized === '/') return this.rootFile();\n const names = normalized.split('/').filter(Boolean);\n let parentId = this.folderId;\n let current: DriveFile | undefined;\n for (const name of names) {\n current = await this.findChild(parentId, name);\n if (current) {\n if (current.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(name);\n parentId = current.id;\n continue;\n }\n if (!recursive) throw new DirectoryNotFoundError(normalized);\n current = await this.createFolder(parentId, name);\n parentId = current.id;\n }\n return current!;\n }\n\n private async createFolder(parentId: string, name: string): Promise<DriveFile> {\n return this.request<DriveFile>(`${DRIVE_API}/files`, {\n method: 'POST',\n searchParams: { fields: 'id,name,mimeType,size,createdTime,modifiedTime,parents', supportsAllDrives: 'true' },\n body: JSON.stringify({ name, mimeType: FOLDER_MIME_TYPE, parents: [parentId] }),\n });\n }\n\n private async findChild(parentId: string, name: string): Promise<DriveFile | undefined> {\n const files = await this.listChildren(parentId, `name = '${this.escapeQuery(name)}'`);\n return files[0];\n }\n\n private async listChildren(parentId: string, extraQuery?: string): Promise<DriveFile[]> {\n const query = [`'${this.escapeQuery(parentId)}' in parents`, 'trashed = false', extraQuery]\n .filter(Boolean)\n .join(' and ');\n const files: DriveFile[] = [];\n let pageToken: string | undefined;\n\n do {\n const result = await this.request<{ files: DriveFile[]; nextPageToken?: string }>(`${DRIVE_API}/files`, {\n searchParams: {\n q: query,\n fields: 'nextPageToken,files(id,name,mimeType,size,createdTime,modifiedTime,parents)',\n pageSize: '1000',\n supportsAllDrives: 'true',\n includeItemsFromAllDrives: 'true',\n ...(pageToken ? { pageToken } : {}),\n },\n });\n files.push(...(result.files ?? []));\n pageToken = result.nextPageToken;\n } while (pageToken);\n\n return files;\n }\n\n private async readdirRecursive(\n parentId: string,\n options: ListOptions | undefined,\n depth: number,\n ): Promise<FileEntry[]> {\n const children = await this.listChildren(parentId);\n const entries: FileEntry[] = [];\n for (const child of children) {\n const isDirectory = child.mimeType === FOLDER_MIME_TYPE;\n entries.push({ name: child.name, type: isDirectory ? 'directory' : 'file', size: Number(child.size ?? 0) });\n const shouldDescend =\n isDirectory && options?.recursive && (options.maxDepth === undefined || depth < options.maxDepth);\n if (shouldDescend) {\n const nested = await this.readdirRecursive(child.id, options, depth + 1);\n entries.push(...nested.map(entry => ({ ...entry, name: `${child.name}/${entry.name}` })));\n }\n }\n return entries;\n }\n\n private async deleteAny(file: DriveFile, path: string, recursive: boolean): Promise<void> {\n if (file.mimeType === FOLDER_MIME_TYPE) await this.rmdir(path, { recursive, force: true });\n else await this.deleteFile(path, { force: true });\n }\n\n private async upload(\n fileId: string | undefined,\n content: FileContent,\n mimeType = 'application/octet-stream',\n method: 'POST' | 'PATCH',\n metadata?: Record<string, unknown>,\n ): Promise<void> {\n const boundary = `mastra-${Date.now()}`;\n const body = Buffer.concat([\n Buffer.from(\n `--${boundary}\\r\\nContent-Type: application/json; charset=UTF-8\\r\\n\\r\\n${JSON.stringify(metadata ?? {})}\\r\\n`,\n ),\n Buffer.from(`--${boundary}\\r\\nContent-Type: ${mimeType}\\r\\n\\r\\n`),\n this.toBuffer(content),\n Buffer.from(`\\r\\n--${boundary}--`),\n ]);\n const url = fileId ? `${DRIVE_UPLOAD_API}/files/${encodeURIComponent(fileId)}` : `${DRIVE_UPLOAD_API}/files`;\n await this.request(url, {\n method,\n searchParams: { uploadType: 'multipart', fields: 'id', supportsAllDrives: 'true' },\n headers: { 'Content-Type': `multipart/related; boundary=${boundary}` },\n body,\n });\n }\n\n private escapeQuery(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n }\n\n private async request<T>(\n url: string,\n init: RequestInit & { searchParams?: Record<string, string> } = {},\n ): Promise<T> {\n const response = await this.fetch(url, init);\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n }\n\n private async fetch(\n url: string,\n init: RequestInit & { searchParams?: Record<string, string> } = {},\n ): Promise<Response> {\n const token = await this.getToken();\n const target = new URL(url);\n for (const [key, value] of Object.entries(init.searchParams ?? {})) target.searchParams.set(key, value);\n const headers: Record<string, string> = { Authorization: `Bearer ${token}` };\n // Auto-apply Content-Type for JSON bodies when not explicitly set (e.g. multipart uploads).\n if (init.body && typeof init.body === 'string' && !init.headers) {\n headers['Content-Type'] = 'application/json';\n }\n const response = await globalThis.fetch(target, {\n ...init,\n headers: { ...headers, ...(init.headers as Record<string, string>) },\n });\n if (!response.ok) {\n const message = await response.text().catch(() => response.statusText);\n throw new Error(`Google Drive API request failed (${response.status}): ${message}`);\n }\n return response;\n }\n\n private async getToken(): Promise<string> {\n if (this.accessToken && Date.now() < this.tokenExpiresAt - 60_000) return this.accessToken;\n if (this.getAccessToken) return this.getAccessToken();\n if (this.serviceAccount) {\n // Dedup concurrent refresh attempts — all callers share the same in-flight promise.\n if (!this.tokenRefreshPromise) {\n this.tokenRefreshPromise = this.getServiceAccountToken().finally(() => {\n this.tokenRefreshPromise = undefined;\n });\n }\n return this.tokenRefreshPromise;\n }\n if (this.accessToken) return this.accessToken;\n throw new Error('GoogleDriveFilesystem requires accessToken, getAccessToken, or serviceAccount authentication.');\n }\n\n private async getServiceAccountToken(): Promise<string> {\n const account = this.serviceAccount!;\n const now = Math.floor(Date.now() / 1000);\n const header = { alg: 'RS256', typ: 'JWT', ...(account.privateKeyId ? { kid: account.privateKeyId } : {}) };\n const claim = {\n iss: account.clientEmail,\n scope: (account.scopes ?? DEFAULT_SCOPES).join(' '),\n aud: OAUTH_TOKEN_URL,\n exp: now + 3600,\n iat: now,\n ...(account.subject ? { sub: account.subject } : {}),\n };\n const unsigned = `${this.base64Url(JSON.stringify(header))}.${this.base64Url(JSON.stringify(claim))}`;\n const privateKey = this.normalizePrivateKey(account.privateKey);\n let signature: string;\n try {\n signature = createSign('RSA-SHA256').update(unsigned).sign(privateKey, 'base64url');\n } catch (err) {\n const hasBegin = privateKey.includes('-----BEGIN');\n const hasEnd = privateKey.includes('-----END');\n throw new Error(\n `Google service account private key signing failed (${(err as Error).message}). ` +\n `Key has BEGIN marker: ${hasBegin}, END marker: ${hasEnd}. ` +\n `Ensure your .env value contains the raw PEM with \\\\n for newlines, without extra surrounding quotes or commas.`,\n );\n }\n const response = await globalThis.fetch(OAUTH_TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',\n assertion: `${unsigned}.${signature}`,\n }),\n });\n if (!response.ok)\n throw new Error(`Google service account token request failed (${response.status}): ${await response.text()}`);\n const json = (await response.json()) as { access_token: string; expires_in: number };\n this.accessToken = json.access_token;\n this.tokenExpiresAt = Date.now() + json.expires_in * 1000;\n return json.access_token;\n }\n\n private base64Url(value: string): string {\n return Buffer.from(value).toString('base64url');\n }\n\n private normalizePrivateKey(key: string): string {\n let out = key.trim();\n // Iteratively strip JSON-style wrapping that .env files tend to accumulate:\n // trailing commas, literal backslash-escaped quotes, and plain surrounding quotes.\n // Loop because values can be doubly wrapped (e.g. a JSON-encoded string pasted into\n // a .env file still wrapped in quotes by the dotenv loader).\n for (let i = 0; i < 5; i++) {\n const before = out;\n if (out.endsWith(',')) out = out.slice(0, -1).trim();\n if ((out.startsWith('\"') && out.endsWith('\"')) || (out.startsWith(\"'\") && out.endsWith(\"'\"))) {\n out = out.slice(1, -1);\n }\n if ((out.startsWith('\\\\\"') && out.endsWith('\\\\\"')) || (out.startsWith(\"\\\\'\") && out.endsWith(\"\\\\'\"))) {\n out = out.slice(2, -2);\n }\n if (out === before) break;\n }\n // Replace escaped newlines with real newlines (common when storing the key on one line in .env).\n out = out.replace(/\\\\n/g, '\\n');\n // Unescape any remaining escaped quotes that survived the unwrapping.\n out = out.replace(/\\\\\"/g, '\"').replace(/\\\\'/g, \"'\");\n // Normalize CRLF / CR to LF — OpenSSL's PEM decoder is strict about line endings.\n out = out.replace(/\\r\\n?/g, '\\n');\n // Ensure PEM ends with a trailing newline — required by some OpenSSL versions.\n if (!out.endsWith('\\n')) out += '\\n';\n return out;\n }\n}\n","/**\n * Google Drive filesystem provider descriptor for MastraEditor.\n *\n * @example\n * ```typescript\n * import { googleDriveFilesystemProvider } from '@mastra/google-drive';\n *\n * const editor = new MastraEditor({\n * filesystems: [googleDriveFilesystemProvider],\n * });\n * ```\n */\nimport type { FilesystemProvider } from '@mastra/core/editor';\nimport { GoogleDriveFilesystem } from './filesystem';\nimport type { GoogleDriveFilesystemOptions } from './filesystem';\n\nexport const googleDriveFilesystemProvider: FilesystemProvider<GoogleDriveFilesystemOptions> = {\n id: 'google-drive',\n name: 'Google Drive',\n description: 'Google Drive folder mounted as a filesystem',\n configSchema: {\n type: 'object',\n required: ['folderId'],\n properties: {\n folderId: { type: 'string', description: 'Google Drive folder ID to mount as the workspace root' },\n accessToken: {\n type: 'string',\n description: 'OAuth access token with the https://www.googleapis.com/auth/drive scope',\n },\n serviceAccount: {\n type: 'object',\n required: ['clientEmail', 'privateKey'],\n properties: {\n clientEmail: { type: 'string', description: 'Google service account email' },\n privateKey: { type: 'string', description: 'PEM-encoded private key' },\n privateKeyId: { type: 'string', description: 'Optional private key ID' },\n scopes: {\n type: 'array',\n items: { type: 'string' },\n description: 'Optional OAuth scopes override',\n },\n subject: { type: 'string', description: 'Optional delegated user email' },\n },\n description: 'Service account credentials for server-to-server auth',\n },\n readOnly: { type: 'boolean', description: 'Mount as read-only', default: false },\n },\n },\n createFilesystem: config => new GoogleDriveFilesystem(config),\n};\n"]}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,6 @@
3
3
  *
4
4
  * A filesystem implementation backed by a Google Drive folder.
5
5
  */
6
- export { GoogleDriveFilesystem, type GoogleDriveFilesystemOptions, type GoogleDriveServiceAccount, } from './filesystem/index.js';
6
+ export { GoogleDriveFilesystem, type GoogleDriveFilesystemOptions, type GoogleDriveServiceAccount } from './filesystem/index.js';
7
7
  export { googleDriveFilesystemProvider } from './provider.js';
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,qBAAqB,EACrB,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,GAC/B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,qBAAqB,EAAE,KAAK,4BAA4B,EAAE,KAAK,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACxH,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -23,6 +23,7 @@ var GoogleDriveFilesystem = class extends MastraFilesystem {
23
23
  status = "pending";
24
24
  accessToken;
25
25
  tokenExpiresAt = 0;
26
+ tokenRefreshPromise;
26
27
  folderId;
27
28
  getAccessToken;
28
29
  serviceAccount;
@@ -80,7 +81,10 @@ var GoogleDriveFilesystem = class extends MastraFilesystem {
80
81
  await this.ensureReady();
81
82
  const file = await this.getFile(path);
82
83
  if (file.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);
83
- const response = await this.fetch(`${DRIVE_API}/files/${encodeURIComponent(file.id)}?alt=media`, { method: "GET" });
84
+ const response = await this.fetch(`${DRIVE_API}/files/${encodeURIComponent(file.id)}`, {
85
+ method: "GET",
86
+ searchParams: { alt: "media" }
87
+ });
84
88
  const buffer = Buffer.from(await response.arrayBuffer());
85
89
  return options?.encoding ? buffer.toString(options.encoding) : buffer;
86
90
  }
@@ -104,8 +108,19 @@ var GoogleDriveFilesystem = class extends MastraFilesystem {
104
108
  await this.upload(void 0, content, options?.mimeType, "POST", { name, parents: [parentId] });
105
109
  }
106
110
  async appendFile(path, content) {
107
- const current = await this.exists(path) ? await this.readFile(path) : Buffer.alloc(0);
108
- await this.writeFile(path, Buffer.concat([this.toBuffer(current), this.toBuffer(content)]), { recursive: true });
111
+ await this.ensureReady();
112
+ this.assertWritable("appendFile");
113
+ const existing = await this.findFile(path);
114
+ if (existing) {
115
+ if (existing.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);
116
+ const current = await this.readFile(path);
117
+ const expectedMtime = existing.modifiedTime ? new Date(existing.modifiedTime) : void 0;
118
+ await this.writeFile(path, Buffer.concat([this.toBuffer(current), this.toBuffer(content)]), {
119
+ expectedMtime
120
+ });
121
+ } else {
122
+ await this.writeFile(path, content, { recursive: true });
123
+ }
109
124
  }
110
125
  async deleteFile(path, options) {
111
126
  await this.ensureReady();
@@ -125,6 +140,7 @@ var GoogleDriveFilesystem = class extends MastraFilesystem {
125
140
  if (source.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(src);
126
141
  const existing = await this.findFile(dest);
127
142
  if (existing) {
143
+ if (existing.id === source.id) throw new FileExistsError(dest);
128
144
  if (existing.mimeType === FOLDER_MIME_TYPE || options?.overwrite === false) throw new FileExistsError(dest);
129
145
  await this.deleteAny(existing, dest, true);
130
146
  }
@@ -163,7 +179,7 @@ var GoogleDriveFilesystem = class extends MastraFilesystem {
163
179
  if (existing.mimeType !== FOLDER_MIME_TYPE) throw new FileExistsError(path);
164
180
  return;
165
181
  }
166
- const { parentId, name } = await this.resolveParent(path, options?.recursive ?? false);
182
+ const { parentId, name } = await this.resolveParent(path, options?.recursive ?? true);
167
183
  await this.createFolder(parentId, name);
168
184
  }
169
185
  async rmdir(path, options) {
@@ -175,8 +191,10 @@ var GoogleDriveFilesystem = class extends MastraFilesystem {
175
191
  throw new DirectoryNotFoundError(path);
176
192
  }
177
193
  if (dir.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(path);
178
- const children = await this.listChildren(dir.id);
179
- if (children.length && !options?.recursive) throw new DirectoryNotEmptyError(path);
194
+ if (!options?.recursive) {
195
+ const children = await this.listChildren(dir.id);
196
+ if (children.length) throw new DirectoryNotEmptyError(path);
197
+ }
180
198
  await this.request(`${DRIVE_API}/files/${encodeURIComponent(dir.id)}`, { method: "DELETE" });
181
199
  }
182
200
  async readdir(path, options) {
@@ -366,9 +384,13 @@ Content-Type: ${mimeType}\r
366
384
  const token = await this.getToken();
367
385
  const target = new URL(url);
368
386
  for (const [key, value] of Object.entries(init.searchParams ?? {})) target.searchParams.set(key, value);
387
+ const headers = { Authorization: `Bearer ${token}` };
388
+ if (init.body && typeof init.body === "string" && !init.headers) {
389
+ headers["Content-Type"] = "application/json";
390
+ }
369
391
  const response = await globalThis.fetch(target, {
370
392
  ...init,
371
- headers: { Authorization: `Bearer ${token}`, ...init.headers }
393
+ headers: { ...headers, ...init.headers }
372
394
  });
373
395
  if (!response.ok) {
374
396
  const message = await response.text().catch(() => response.statusText);
@@ -379,7 +401,14 @@ Content-Type: ${mimeType}\r
379
401
  async getToken() {
380
402
  if (this.accessToken && Date.now() < this.tokenExpiresAt - 6e4) return this.accessToken;
381
403
  if (this.getAccessToken) return this.getAccessToken();
382
- if (this.serviceAccount) return this.getServiceAccountToken();
404
+ if (this.serviceAccount) {
405
+ if (!this.tokenRefreshPromise) {
406
+ this.tokenRefreshPromise = this.getServiceAccountToken().finally(() => {
407
+ this.tokenRefreshPromise = void 0;
408
+ });
409
+ }
410
+ return this.tokenRefreshPromise;
411
+ }
383
412
  if (this.accessToken) return this.accessToken;
384
413
  throw new Error("GoogleDriveFilesystem requires accessToken, getAccessToken, or serviceAccount authentication.");
385
414
  }
@@ -460,6 +489,22 @@ var googleDriveFilesystemProvider = {
460
489
  type: "string",
461
490
  description: "OAuth access token with the https://www.googleapis.com/auth/drive scope"
462
491
  },
492
+ serviceAccount: {
493
+ type: "object",
494
+ required: ["clientEmail", "privateKey"],
495
+ properties: {
496
+ clientEmail: { type: "string", description: "Google service account email" },
497
+ privateKey: { type: "string", description: "PEM-encoded private key" },
498
+ privateKeyId: { type: "string", description: "Optional private key ID" },
499
+ scopes: {
500
+ type: "array",
501
+ items: { type: "string" },
502
+ description: "Optional OAuth scopes override"
503
+ },
504
+ subject: { type: "string", description: "Optional delegated user email" }
505
+ },
506
+ description: "Service account credentials for server-to-server auth"
507
+ },
463
508
  readOnly: { type: "boolean", description: "Mount as read-only", default: false }
464
509
  }
465
510
  },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/filesystem/index.ts","../src/provider.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { createSign } from 'node:crypto';\nimport {\n DirectoryNotEmptyError,\n DirectoryNotFoundError,\n FileExistsError,\n FileNotFoundError,\n IsDirectoryError,\n MastraFilesystem,\n NotDirectoryError,\n StaleFileError,\n WorkspaceReadOnlyError,\n} from '@mastra/core/workspace';\nimport type {\n CopyOptions,\n FileContent,\n FileEntry,\n FileStat,\n FilesystemInfo,\n InstructionsOption,\n ListOptions,\n MastraFilesystemOptions,\n ProviderStatus,\n ReadOptions,\n RemoveOptions,\n WriteOptions,\n} from '@mastra/core/workspace';\nimport type { RequestContext } from '@mastra/core/request-context';\n\nconst DRIVE_API = 'https://www.googleapis.com/drive/v3';\nconst DRIVE_UPLOAD_API = 'https://www.googleapis.com/upload/drive/v3';\nconst OAUTH_TOKEN_URL = 'https://oauth2.googleapis.com/token';\nconst FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder';\n// Use the full `drive` scope by default — `drive.file` only exposes files the app created or\n// the user explicitly opened via a picker, so a folder shared with the service account would\n// be invisible and return 404 on access.\nconst DEFAULT_SCOPES = ['https://www.googleapis.com/auth/drive'];\n\n/**\n * Resolve an instructions override against default instructions.\n *\n * - `undefined` → return default\n * - `string` → return the string as-is\n * - `function` → call with { defaultInstructions, requestContext }\n */\nfunction resolveInstructions(\n override: InstructionsOption | undefined,\n getDefault: () => string,\n requestContext?: RequestContext,\n): string {\n if (typeof override === 'string') return override;\n const defaultInstructions = getDefault();\n if (override === undefined) return defaultInstructions;\n return override({ defaultInstructions, requestContext });\n}\n\nexport interface GoogleDriveServiceAccount {\n clientEmail: string;\n privateKey: string;\n privateKeyId?: string;\n scopes?: string[];\n subject?: string;\n}\n\nexport interface GoogleDriveFilesystemOptions extends MastraFilesystemOptions {\n id?: string;\n folderId: string;\n accessToken?: string;\n getAccessToken?: () => string | Promise<string>;\n serviceAccount?: GoogleDriveServiceAccount;\n readOnly?: boolean;\n instructions?: InstructionsOption;\n}\n\ninterface DriveFile {\n id: string;\n name: string;\n mimeType: string;\n size?: string;\n createdTime?: string;\n modifiedTime?: string;\n parents?: string[];\n trashed?: boolean;\n}\n\nexport class GoogleDriveFilesystem extends MastraFilesystem {\n readonly id: string;\n readonly name = 'GoogleDriveFilesystem';\n readonly provider = 'google-drive';\n readonly readOnly?: boolean;\n readonly icon = 'drive';\n readonly displayName = 'Google Drive';\n\n status: ProviderStatus = 'pending';\n\n private accessToken?: string;\n private tokenExpiresAt = 0;\n private readonly folderId: string;\n private readonly getAccessToken?: () => string | Promise<string>;\n private readonly serviceAccount?: GoogleDriveServiceAccount;\n private readonly instructionsOverride?: InstructionsOption;\n\n constructor(options: GoogleDriveFilesystemOptions) {\n super({ name: 'GoogleDriveFilesystem', ...options });\n this.id = options.id ?? `google-drive:${options.folderId}`;\n this.folderId = options.folderId;\n this.accessToken = options.accessToken;\n this.getAccessToken = options.getAccessToken;\n this.serviceAccount = options.serviceAccount;\n this.readOnly = options.readOnly;\n this.instructionsOverride = options.instructions;\n }\n\n async init(): Promise<void> {\n const driveFile = await this.request<DriveFile>(`${DRIVE_API}/files/${encodeURIComponent(this.folderId)}`, {\n searchParams: { fields: 'id,name,mimeType,trashed', supportsAllDrives: 'true' },\n });\n\n if (driveFile.trashed) {\n throw new Error(`Google Drive folder ${this.folderId} is trashed and cannot be used as a filesystem root.`);\n }\n\n if (driveFile.mimeType !== FOLDER_MIME_TYPE) {\n throw new Error(\n `Google Drive root ${this.folderId} must be a folder, but received mimeType ${driveFile.mimeType ?? 'unknown'}.`,\n );\n }\n }\n\n async destroy(): Promise<void> {}\n\n async isReady(): Promise<boolean> {\n return this.status === 'ready';\n }\n\n getInfo(): FilesystemInfo {\n return {\n id: this.id,\n name: this.name,\n provider: this.provider,\n status: this.status,\n error: this.error,\n readOnly: this.readOnly,\n icon: this.icon,\n metadata: { folderId: this.folderId },\n };\n }\n\n getInstructions(opts?: { requestContext?: RequestContext }): string {\n const defaultInstructions = [\n 'Google Drive filesystem mounted to a single folder.',\n 'Use POSIX-style paths relative to that folder, for example /notes/todo.txt.',\n 'Directories are Google Drive folders. File names must be unique within each folder for path-based operations.',\n this.readOnly\n ? 'This Google Drive filesystem is read-only.'\n : 'You can read, create, update, move, copy, and delete files in this folder.',\n ].join('\\n');\n return resolveInstructions(this.instructionsOverride, () => defaultInstructions, opts?.requestContext);\n }\n\n async readFile(path: string, options?: ReadOptions): Promise<string | Buffer> {\n await this.ensureReady();\n const file = await this.getFile(path);\n if (file.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n const response = await this.fetch(`${DRIVE_API}/files/${encodeURIComponent(file.id)}?alt=media`, { method: 'GET' });\n const buffer = Buffer.from(await response.arrayBuffer());\n return options?.encoding ? buffer.toString(options.encoding) : buffer;\n }\n\n async writeFile(path: string, content: FileContent, options?: WriteOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('writeFile');\n const existing = await this.findFile(path);\n if (existing) {\n if (existing.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n if (options?.overwrite === false) throw new FileExistsError(path);\n if (options?.expectedMtime) {\n if (!existing.modifiedTime) throw new StaleFileError(path, options.expectedMtime, new Date(0));\n\n const actual = new Date(existing.modifiedTime);\n if (actual.getTime() !== options.expectedMtime.getTime())\n throw new StaleFileError(path, options.expectedMtime, actual);\n }\n await this.upload(existing.id, content, options?.mimeType, 'PATCH');\n return;\n }\n\n const { parentId, name } = await this.resolveParent(path, options?.recursive ?? true);\n await this.upload(undefined, content, options?.mimeType, 'POST', { name, parents: [parentId] });\n }\n\n async appendFile(path: string, content: FileContent): Promise<void> {\n const current = (await this.exists(path)) ? await this.readFile(path) : Buffer.alloc(0);\n await this.writeFile(path, Buffer.concat([this.toBuffer(current), this.toBuffer(content)]), { recursive: true });\n }\n\n async deleteFile(path: string, options?: RemoveOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('deleteFile');\n const file = await this.findFile(path);\n if (!file) {\n if (options?.force) return;\n throw new FileNotFoundError(path);\n }\n if (file.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n await this.request<void>(`${DRIVE_API}/files/${encodeURIComponent(file.id)}`, { method: 'DELETE' });\n }\n\n async copyFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('copyFile');\n const source = await this.getFile(src);\n if (source.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(src);\n const existing = await this.findFile(dest);\n if (existing) {\n if (existing.mimeType === FOLDER_MIME_TYPE || options?.overwrite === false) throw new FileExistsError(dest);\n await this.deleteAny(existing, dest, true);\n }\n const { parentId, name } = await this.resolveParent(dest, options?.recursive ?? true);\n await this.request(`${DRIVE_API}/files/${encodeURIComponent(source.id)}/copy`, {\n method: 'POST',\n body: JSON.stringify({ name, parents: [parentId] }),\n });\n }\n\n async moveFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('moveFile');\n const source = await this.getFile(src);\n if (options?.overwrite === false && (await this.exists(dest))) throw new FileExistsError(dest);\n const existing = await this.findFile(dest);\n if (existing && existing.id !== source.id) {\n if (existing.mimeType === FOLDER_MIME_TYPE || options?.overwrite === false) throw new FileExistsError(dest);\n await this.deleteAny(existing, dest, true);\n }\n const { parentId, name } = await this.resolveParent(dest, options?.recursive ?? true);\n const searchParams: Record<string, string> = { addParents: parentId, fields: 'id', supportsAllDrives: 'true' };\n const oldParents = source.parents?.join(',');\n if (oldParents) searchParams.removeParents = oldParents;\n await this.request(`${DRIVE_API}/files/${encodeURIComponent(source.id)}`, {\n method: 'PATCH',\n searchParams,\n body: JSON.stringify({ name }),\n });\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await this.ensureReady();\n this.assertWritable('mkdir');\n if (this.normalize(path) === '/') return;\n const existing = await this.findFile(path);\n if (existing) {\n if (existing.mimeType !== FOLDER_MIME_TYPE) throw new FileExistsError(path);\n return;\n }\n const { parentId, name } = await this.resolveParent(path, options?.recursive ?? false);\n await this.createFolder(parentId, name);\n }\n\n async rmdir(path: string, options?: RemoveOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('rmdir');\n const dir = await this.findFile(path);\n if (!dir) {\n if (options?.force) return;\n throw new DirectoryNotFoundError(path);\n }\n if (dir.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(path);\n const children = await this.listChildren(dir.id);\n if (children.length && !options?.recursive) throw new DirectoryNotEmptyError(path);\n await this.request<void>(`${DRIVE_API}/files/${encodeURIComponent(dir.id)}`, { method: 'DELETE' });\n }\n\n async readdir(path: string, options?: ListOptions): Promise<FileEntry[]> {\n await this.ensureReady();\n const dir = await this.getFile(path);\n if (dir.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(path);\n const entries = await this.readdirRecursive(dir.id, options, 0);\n const extensions = Array.isArray(options?.extension)\n ? options.extension\n : options?.extension\n ? [options.extension]\n : undefined;\n return extensions\n ? entries.filter(entry => entry.type === 'directory' || extensions.some(ext => entry.name.endsWith(ext)))\n : entries;\n }\n\n async exists(path: string): Promise<boolean> {\n await this.ensureReady();\n return Boolean(await this.findFile(path));\n }\n\n async stat(path: string): Promise<FileStat> {\n await this.ensureReady();\n const file = await this.getFile(path);\n const isDirectory = file.mimeType === FOLDER_MIME_TYPE;\n return {\n name: file.name,\n path: this.normalize(path),\n type: isDirectory ? 'directory' : 'file',\n size: Number(file.size ?? 0),\n createdAt: file.createdTime ? new Date(file.createdTime) : new Date(0),\n modifiedAt: file.modifiedTime ? new Date(file.modifiedTime) : new Date(0),\n mimeType: isDirectory ? undefined : file.mimeType,\n };\n }\n\n async realpath(path: string): Promise<string> {\n return this.normalize(path);\n }\n\n private assertWritable(operation: string): void {\n if (this.readOnly) throw new WorkspaceReadOnlyError(operation);\n }\n\n private toBuffer(content: FileContent): Buffer {\n if (Buffer.isBuffer(content)) return content;\n if (content instanceof Uint8Array) return Buffer.from(content);\n return Buffer.from(content, 'utf-8');\n }\n\n private normalize(path: string): string {\n const parts = path.split('/').filter(Boolean);\n const stack: string[] = [];\n for (const part of parts) {\n if (part === '.') continue;\n if (part === '..') stack.pop();\n else stack.push(part);\n }\n return `/${stack.join('/')}`;\n }\n\n private async getFile(path: string): Promise<DriveFile> {\n const file = await this.findFile(path);\n if (!file) throw new FileNotFoundError(path);\n return file;\n }\n\n private async findFile(path: string): Promise<DriveFile | undefined> {\n const normalized = this.normalize(path);\n if (normalized === '/') return this.rootFile();\n const names = normalized.split('/').filter(Boolean);\n let parentId = this.folderId;\n let file: DriveFile | undefined;\n for (const name of names) {\n file = await this.findChild(parentId, name);\n if (!file) return undefined;\n parentId = file.id;\n }\n return file;\n }\n\n private async rootFile(): Promise<DriveFile> {\n return this.request<DriveFile>(`${DRIVE_API}/files/${encodeURIComponent(this.folderId)}`, {\n searchParams: { fields: 'id,name,mimeType,size,createdTime,modifiedTime,parents', supportsAllDrives: 'true' },\n });\n }\n\n private async resolveParent(path: string, recursive: boolean): Promise<{ parentId: string; name: string }> {\n const normalized = this.normalize(path);\n const parts = normalized.split('/').filter(Boolean);\n const name = parts.pop();\n if (!name) throw new IsDirectoryError(path);\n const parentPath = `/${parts.join('/')}`;\n const parent = recursive ? await this.resolveDir(parentPath, true) : await this.findFile(parentPath);\n if (!parent) throw new DirectoryNotFoundError(parentPath);\n if (parent.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(parentPath);\n return { parentId: parent.id, name };\n }\n\n private async resolveDir(path: string, recursive: boolean): Promise<DriveFile> {\n const normalized = this.normalize(path);\n if (normalized === '/') return this.rootFile();\n const names = normalized.split('/').filter(Boolean);\n let parentId = this.folderId;\n let current: DriveFile | undefined;\n for (const name of names) {\n current = await this.findChild(parentId, name);\n if (current) {\n if (current.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(name);\n parentId = current.id;\n continue;\n }\n if (!recursive) throw new DirectoryNotFoundError(normalized);\n current = await this.createFolder(parentId, name);\n parentId = current.id;\n }\n return current!;\n }\n\n private async createFolder(parentId: string, name: string): Promise<DriveFile> {\n return this.request<DriveFile>(`${DRIVE_API}/files`, {\n method: 'POST',\n searchParams: { fields: 'id,name,mimeType,size,createdTime,modifiedTime,parents', supportsAllDrives: 'true' },\n body: JSON.stringify({ name, mimeType: FOLDER_MIME_TYPE, parents: [parentId] }),\n });\n }\n\n private async findChild(parentId: string, name: string): Promise<DriveFile | undefined> {\n const files = await this.listChildren(parentId, `name = '${this.escapeQuery(name)}'`);\n return files[0];\n }\n\n private async listChildren(parentId: string, extraQuery?: string): Promise<DriveFile[]> {\n const query = [`'${this.escapeQuery(parentId)}' in parents`, 'trashed = false', extraQuery]\n .filter(Boolean)\n .join(' and ');\n const files: DriveFile[] = [];\n let pageToken: string | undefined;\n\n do {\n const result = await this.request<{ files: DriveFile[]; nextPageToken?: string }>(`${DRIVE_API}/files`, {\n searchParams: {\n q: query,\n fields: 'nextPageToken,files(id,name,mimeType,size,createdTime,modifiedTime,parents)',\n pageSize: '1000',\n supportsAllDrives: 'true',\n includeItemsFromAllDrives: 'true',\n ...(pageToken ? { pageToken } : {}),\n },\n });\n files.push(...(result.files ?? []));\n pageToken = result.nextPageToken;\n } while (pageToken);\n\n return files;\n }\n\n private async readdirRecursive(\n parentId: string,\n options: ListOptions | undefined,\n depth: number,\n ): Promise<FileEntry[]> {\n const children = await this.listChildren(parentId);\n const entries: FileEntry[] = [];\n for (const child of children) {\n const isDirectory = child.mimeType === FOLDER_MIME_TYPE;\n entries.push({ name: child.name, type: isDirectory ? 'directory' : 'file', size: Number(child.size ?? 0) });\n const shouldDescend =\n isDirectory && options?.recursive && (options.maxDepth === undefined || depth < options.maxDepth);\n if (shouldDescend) {\n const nested = await this.readdirRecursive(child.id, options, depth + 1);\n entries.push(...nested.map(entry => ({ ...entry, name: `${child.name}/${entry.name}` })));\n }\n }\n return entries;\n }\n\n private async deleteAny(file: DriveFile, path: string, recursive: boolean): Promise<void> {\n if (file.mimeType === FOLDER_MIME_TYPE) await this.rmdir(path, { recursive, force: true });\n else await this.deleteFile(path, { force: true });\n }\n\n private async upload(\n fileId: string | undefined,\n content: FileContent,\n mimeType = 'application/octet-stream',\n method: 'POST' | 'PATCH',\n metadata?: Record<string, unknown>,\n ): Promise<void> {\n const boundary = `mastra-${Date.now()}`;\n const body = Buffer.concat([\n Buffer.from(\n `--${boundary}\\r\\nContent-Type: application/json; charset=UTF-8\\r\\n\\r\\n${JSON.stringify(metadata ?? {})}\\r\\n`,\n ),\n Buffer.from(`--${boundary}\\r\\nContent-Type: ${mimeType}\\r\\n\\r\\n`),\n this.toBuffer(content),\n Buffer.from(`\\r\\n--${boundary}--`),\n ]);\n const url = fileId ? `${DRIVE_UPLOAD_API}/files/${encodeURIComponent(fileId)}` : `${DRIVE_UPLOAD_API}/files`;\n await this.request(url, {\n method,\n searchParams: { uploadType: 'multipart', fields: 'id', supportsAllDrives: 'true' },\n headers: { 'Content-Type': `multipart/related; boundary=${boundary}` },\n body,\n });\n }\n\n private escapeQuery(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n }\n\n private async request<T>(\n url: string,\n init: RequestInit & { searchParams?: Record<string, string> } = {},\n ): Promise<T> {\n const response = await this.fetch(url, init);\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n }\n\n private async fetch(\n url: string,\n init: RequestInit & { searchParams?: Record<string, string> } = {},\n ): Promise<Response> {\n const token = await this.getToken();\n const target = new URL(url);\n for (const [key, value] of Object.entries(init.searchParams ?? {})) target.searchParams.set(key, value);\n const response = await globalThis.fetch(target, {\n ...init,\n headers: { Authorization: `Bearer ${token}`, ...init.headers },\n });\n if (!response.ok) {\n const message = await response.text().catch(() => response.statusText);\n throw new Error(`Google Drive API request failed (${response.status}): ${message}`);\n }\n return response;\n }\n\n private async getToken(): Promise<string> {\n if (this.accessToken && Date.now() < this.tokenExpiresAt - 60_000) return this.accessToken;\n if (this.getAccessToken) return this.getAccessToken();\n if (this.serviceAccount) return this.getServiceAccountToken();\n if (this.accessToken) return this.accessToken;\n throw new Error('GoogleDriveFilesystem requires accessToken, getAccessToken, or serviceAccount authentication.');\n }\n\n private async getServiceAccountToken(): Promise<string> {\n const account = this.serviceAccount!;\n const now = Math.floor(Date.now() / 1000);\n const header = { alg: 'RS256', typ: 'JWT', ...(account.privateKeyId ? { kid: account.privateKeyId } : {}) };\n const claim = {\n iss: account.clientEmail,\n scope: (account.scopes ?? DEFAULT_SCOPES).join(' '),\n aud: OAUTH_TOKEN_URL,\n exp: now + 3600,\n iat: now,\n ...(account.subject ? { sub: account.subject } : {}),\n };\n const unsigned = `${this.base64Url(JSON.stringify(header))}.${this.base64Url(JSON.stringify(claim))}`;\n const privateKey = this.normalizePrivateKey(account.privateKey);\n let signature: string;\n try {\n signature = createSign('RSA-SHA256').update(unsigned).sign(privateKey, 'base64url');\n } catch (err) {\n const hasBegin = privateKey.includes('-----BEGIN');\n const hasEnd = privateKey.includes('-----END');\n throw new Error(\n `Google service account private key signing failed (${(err as Error).message}). ` +\n `Key has BEGIN marker: ${hasBegin}, END marker: ${hasEnd}. ` +\n `Ensure your .env value contains the raw PEM with \\\\n for newlines, without extra surrounding quotes or commas.`,\n );\n }\n const response = await globalThis.fetch(OAUTH_TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',\n assertion: `${unsigned}.${signature}`,\n }),\n });\n if (!response.ok)\n throw new Error(`Google service account token request failed (${response.status}): ${await response.text()}`);\n const json = (await response.json()) as { access_token: string; expires_in: number };\n this.accessToken = json.access_token;\n this.tokenExpiresAt = Date.now() + json.expires_in * 1000;\n return json.access_token;\n }\n\n private base64Url(value: string): string {\n return Buffer.from(value).toString('base64url');\n }\n\n private normalizePrivateKey(key: string): string {\n let out = key.trim();\n // Iteratively strip JSON-style wrapping that .env files tend to accumulate:\n // trailing commas, literal backslash-escaped quotes, and plain surrounding quotes.\n // Loop because values can be doubly wrapped (e.g. a JSON-encoded string pasted into\n // a .env file still wrapped in quotes by the dotenv loader).\n for (let i = 0; i < 5; i++) {\n const before = out;\n if (out.endsWith(',')) out = out.slice(0, -1).trim();\n if ((out.startsWith('\"') && out.endsWith('\"')) || (out.startsWith(\"'\") && out.endsWith(\"'\"))) {\n out = out.slice(1, -1);\n }\n if ((out.startsWith('\\\\\"') && out.endsWith('\\\\\"')) || (out.startsWith(\"\\\\'\") && out.endsWith(\"\\\\'\"))) {\n out = out.slice(2, -2);\n }\n if (out === before) break;\n }\n // Replace escaped newlines with real newlines (common when storing the key on one line in .env).\n out = out.replace(/\\\\n/g, '\\n');\n // Unescape any remaining escaped quotes that survived the unwrapping.\n out = out.replace(/\\\\\"/g, '\"').replace(/\\\\'/g, \"'\");\n // Normalize CRLF / CR to LF — OpenSSL's PEM decoder is strict about line endings.\n out = out.replace(/\\r\\n?/g, '\\n');\n // Ensure PEM ends with a trailing newline — required by some OpenSSL versions.\n if (!out.endsWith('\\n')) out += '\\n';\n return out;\n }\n}\n","/**\n * Google Drive filesystem provider descriptor for MastraEditor.\n *\n * @example\n * ```typescript\n * import { googleDriveFilesystemProvider } from '@mastra/google-drive';\n *\n * const editor = new MastraEditor({\n * filesystems: [googleDriveFilesystemProvider],\n * });\n * ```\n */\nimport type { FilesystemProvider } from '@mastra/core/editor';\nimport { GoogleDriveFilesystem } from './filesystem';\nimport type { GoogleDriveFilesystemOptions } from './filesystem';\n\nexport const googleDriveFilesystemProvider: FilesystemProvider<GoogleDriveFilesystemOptions> = {\n id: 'google-drive',\n name: 'Google Drive',\n description: 'Google Drive folder mounted as a filesystem',\n configSchema: {\n type: 'object',\n required: ['folderId'],\n properties: {\n folderId: { type: 'string', description: 'Google Drive folder ID to mount as the workspace root' },\n accessToken: {\n type: 'string',\n description: 'OAuth access token with the https://www.googleapis.com/auth/drive scope',\n },\n readOnly: { type: 'boolean', description: 'Mount as read-only', default: false },\n },\n },\n createFilesystem: config => new GoogleDriveFilesystem(config),\n};\n"]}
1
+ {"version":3,"sources":["../src/filesystem/index.ts","../src/provider.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { createSign } from 'node:crypto';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport {\n DirectoryNotEmptyError,\n DirectoryNotFoundError,\n FileExistsError,\n FileNotFoundError,\n IsDirectoryError,\n MastraFilesystem,\n NotDirectoryError,\n StaleFileError,\n WorkspaceReadOnlyError,\n} from '@mastra/core/workspace';\nimport type {\n CopyOptions,\n FileContent,\n FileEntry,\n FileStat,\n FilesystemInfo,\n InstructionsOption,\n ListOptions,\n MastraFilesystemOptions,\n ProviderStatus,\n ReadOptions,\n RemoveOptions,\n WriteOptions,\n} from '@mastra/core/workspace';\n\nconst DRIVE_API = 'https://www.googleapis.com/drive/v3';\nconst DRIVE_UPLOAD_API = 'https://www.googleapis.com/upload/drive/v3';\nconst OAUTH_TOKEN_URL = 'https://oauth2.googleapis.com/token';\nconst FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder';\n// Use the full `drive` scope by default — `drive.file` only exposes files the app created or\n// the user explicitly opened via a picker, so a folder shared with the service account would\n// be invisible and return 404 on access.\nconst DEFAULT_SCOPES = ['https://www.googleapis.com/auth/drive'];\n\n/**\n * Resolve an instructions override against default instructions.\n *\n * - `undefined` → return default\n * - `string` → return the string as-is\n * - `function` → call with { defaultInstructions, requestContext }\n */\nfunction resolveInstructions(\n override: InstructionsOption | undefined,\n getDefault: () => string,\n requestContext?: RequestContext,\n): string {\n if (typeof override === 'string') return override;\n const defaultInstructions = getDefault();\n if (override === undefined) return defaultInstructions;\n return override({ defaultInstructions, requestContext });\n}\n\nexport interface GoogleDriveServiceAccount {\n clientEmail: string;\n privateKey: string;\n privateKeyId?: string;\n scopes?: string[];\n subject?: string;\n}\n\nexport interface GoogleDriveFilesystemOptions extends MastraFilesystemOptions {\n id?: string;\n folderId: string;\n accessToken?: string;\n getAccessToken?: () => string | Promise<string>;\n serviceAccount?: GoogleDriveServiceAccount;\n readOnly?: boolean;\n instructions?: InstructionsOption;\n}\n\ninterface DriveFile {\n id: string;\n name: string;\n mimeType: string;\n size?: string;\n createdTime?: string;\n modifiedTime?: string;\n parents?: string[];\n trashed?: boolean;\n}\n\nexport class GoogleDriveFilesystem extends MastraFilesystem {\n readonly id: string;\n readonly name = 'GoogleDriveFilesystem';\n readonly provider = 'google-drive';\n readonly readOnly?: boolean;\n readonly icon = 'drive';\n readonly displayName = 'Google Drive';\n\n status: ProviderStatus = 'pending';\n\n private accessToken?: string;\n private tokenExpiresAt = 0;\n private tokenRefreshPromise?: Promise<string>;\n private readonly folderId: string;\n private readonly getAccessToken?: () => string | Promise<string>;\n private readonly serviceAccount?: GoogleDriveServiceAccount;\n private readonly instructionsOverride?: InstructionsOption;\n\n constructor(options: GoogleDriveFilesystemOptions) {\n super({ name: 'GoogleDriveFilesystem', ...options });\n this.id = options.id ?? `google-drive:${options.folderId}`;\n this.folderId = options.folderId;\n this.accessToken = options.accessToken;\n this.getAccessToken = options.getAccessToken;\n this.serviceAccount = options.serviceAccount;\n this.readOnly = options.readOnly;\n this.instructionsOverride = options.instructions;\n }\n\n async init(): Promise<void> {\n const driveFile = await this.request<DriveFile>(`${DRIVE_API}/files/${encodeURIComponent(this.folderId)}`, {\n searchParams: { fields: 'id,name,mimeType,trashed', supportsAllDrives: 'true' },\n });\n\n if (driveFile.trashed) {\n throw new Error(`Google Drive folder ${this.folderId} is trashed and cannot be used as a filesystem root.`);\n }\n\n if (driveFile.mimeType !== FOLDER_MIME_TYPE) {\n throw new Error(\n `Google Drive root ${this.folderId} must be a folder, but received mimeType ${driveFile.mimeType ?? 'unknown'}.`,\n );\n }\n }\n\n async destroy(): Promise<void> {}\n\n async isReady(): Promise<boolean> {\n return this.status === 'ready';\n }\n\n getInfo(): FilesystemInfo {\n return {\n id: this.id,\n name: this.name,\n provider: this.provider,\n status: this.status,\n error: this.error,\n readOnly: this.readOnly,\n icon: this.icon,\n metadata: { folderId: this.folderId },\n };\n }\n\n getInstructions(opts?: { requestContext?: RequestContext }): string {\n const defaultInstructions = [\n 'Google Drive filesystem mounted to a single folder.',\n 'Use POSIX-style paths relative to that folder, for example /notes/todo.txt.',\n 'Directories are Google Drive folders. File names must be unique within each folder for path-based operations.',\n this.readOnly\n ? 'This Google Drive filesystem is read-only.'\n : 'You can read, create, update, move, copy, and delete files in this folder.',\n ].join('\\n');\n return resolveInstructions(this.instructionsOverride, () => defaultInstructions, opts?.requestContext);\n }\n\n async readFile(path: string, options?: ReadOptions): Promise<string | Buffer> {\n await this.ensureReady();\n const file = await this.getFile(path);\n if (file.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n const response = await this.fetch(`${DRIVE_API}/files/${encodeURIComponent(file.id)}`, {\n method: 'GET',\n searchParams: { alt: 'media' },\n });\n const buffer = Buffer.from(await response.arrayBuffer());\n return options?.encoding ? buffer.toString(options.encoding) : buffer;\n }\n\n async writeFile(path: string, content: FileContent, options?: WriteOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('writeFile');\n const existing = await this.findFile(path);\n if (existing) {\n if (existing.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n if (options?.overwrite === false) throw new FileExistsError(path);\n if (options?.expectedMtime) {\n if (!existing.modifiedTime) throw new StaleFileError(path, options.expectedMtime, new Date(0));\n\n const actual = new Date(existing.modifiedTime);\n if (actual.getTime() !== options.expectedMtime.getTime())\n throw new StaleFileError(path, options.expectedMtime, actual);\n }\n await this.upload(existing.id, content, options?.mimeType, 'PATCH');\n return;\n }\n\n const { parentId, name } = await this.resolveParent(path, options?.recursive ?? true);\n await this.upload(undefined, content, options?.mimeType, 'POST', { name, parents: [parentId] });\n }\n\n async appendFile(path: string, content: FileContent): Promise<void> {\n await this.ensureReady();\n this.assertWritable('appendFile');\n const existing = await this.findFile(path);\n if (existing) {\n if (existing.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n const current = await this.readFile(path);\n const expectedMtime = existing.modifiedTime ? new Date(existing.modifiedTime) : undefined;\n await this.writeFile(path, Buffer.concat([this.toBuffer(current), this.toBuffer(content)]), {\n expectedMtime,\n });\n } else {\n await this.writeFile(path, content, { recursive: true });\n }\n }\n\n async deleteFile(path: string, options?: RemoveOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('deleteFile');\n const file = await this.findFile(path);\n if (!file) {\n if (options?.force) return;\n throw new FileNotFoundError(path);\n }\n if (file.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(path);\n await this.request<void>(`${DRIVE_API}/files/${encodeURIComponent(file.id)}`, { method: 'DELETE' });\n }\n\n async copyFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('copyFile');\n const source = await this.getFile(src);\n if (source.mimeType === FOLDER_MIME_TYPE) throw new IsDirectoryError(src);\n const existing = await this.findFile(dest);\n if (existing) {\n if (existing.id === source.id) throw new FileExistsError(dest);\n if (existing.mimeType === FOLDER_MIME_TYPE || options?.overwrite === false) throw new FileExistsError(dest);\n await this.deleteAny(existing, dest, true);\n }\n const { parentId, name } = await this.resolveParent(dest, options?.recursive ?? true);\n await this.request(`${DRIVE_API}/files/${encodeURIComponent(source.id)}/copy`, {\n method: 'POST',\n body: JSON.stringify({ name, parents: [parentId] }),\n });\n }\n\n async moveFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('moveFile');\n const source = await this.getFile(src);\n if (options?.overwrite === false && (await this.exists(dest))) throw new FileExistsError(dest);\n const existing = await this.findFile(dest);\n if (existing && existing.id !== source.id) {\n if (existing.mimeType === FOLDER_MIME_TYPE || options?.overwrite === false) throw new FileExistsError(dest);\n await this.deleteAny(existing, dest, true);\n }\n const { parentId, name } = await this.resolveParent(dest, options?.recursive ?? true);\n const searchParams: Record<string, string> = { addParents: parentId, fields: 'id', supportsAllDrives: 'true' };\n const oldParents = source.parents?.join(',');\n if (oldParents) searchParams.removeParents = oldParents;\n await this.request(`${DRIVE_API}/files/${encodeURIComponent(source.id)}`, {\n method: 'PATCH',\n searchParams,\n body: JSON.stringify({ name }),\n });\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await this.ensureReady();\n this.assertWritable('mkdir');\n if (this.normalize(path) === '/') return;\n const existing = await this.findFile(path);\n if (existing) {\n if (existing.mimeType !== FOLDER_MIME_TYPE) throw new FileExistsError(path);\n return;\n }\n const { parentId, name } = await this.resolveParent(path, options?.recursive ?? true);\n await this.createFolder(parentId, name);\n }\n\n async rmdir(path: string, options?: RemoveOptions): Promise<void> {\n await this.ensureReady();\n this.assertWritable('rmdir');\n const dir = await this.findFile(path);\n if (!dir) {\n if (options?.force) return;\n throw new DirectoryNotFoundError(path);\n }\n if (dir.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(path);\n if (!options?.recursive) {\n const children = await this.listChildren(dir.id);\n if (children.length) throw new DirectoryNotEmptyError(path);\n }\n await this.request<void>(`${DRIVE_API}/files/${encodeURIComponent(dir.id)}`, { method: 'DELETE' });\n }\n\n async readdir(path: string, options?: ListOptions): Promise<FileEntry[]> {\n await this.ensureReady();\n const dir = await this.getFile(path);\n if (dir.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(path);\n const entries = await this.readdirRecursive(dir.id, options, 0);\n const extensions = Array.isArray(options?.extension)\n ? options.extension\n : options?.extension\n ? [options.extension]\n : undefined;\n return extensions\n ? entries.filter(entry => entry.type === 'directory' || extensions.some(ext => entry.name.endsWith(ext)))\n : entries;\n }\n\n async exists(path: string): Promise<boolean> {\n await this.ensureReady();\n return Boolean(await this.findFile(path));\n }\n\n async stat(path: string): Promise<FileStat> {\n await this.ensureReady();\n const file = await this.getFile(path);\n const isDirectory = file.mimeType === FOLDER_MIME_TYPE;\n return {\n name: file.name,\n path: this.normalize(path),\n type: isDirectory ? 'directory' : 'file',\n size: Number(file.size ?? 0),\n createdAt: file.createdTime ? new Date(file.createdTime) : new Date(0),\n modifiedAt: file.modifiedTime ? new Date(file.modifiedTime) : new Date(0),\n mimeType: isDirectory ? undefined : file.mimeType,\n };\n }\n\n async realpath(path: string): Promise<string> {\n return this.normalize(path);\n }\n\n private assertWritable(operation: string): void {\n if (this.readOnly) throw new WorkspaceReadOnlyError(operation);\n }\n\n private toBuffer(content: FileContent): Buffer {\n if (Buffer.isBuffer(content)) return content;\n if (content instanceof Uint8Array) return Buffer.from(content);\n return Buffer.from(content, 'utf-8');\n }\n\n private normalize(path: string): string {\n const parts = path.split('/').filter(Boolean);\n const stack: string[] = [];\n for (const part of parts) {\n if (part === '.') continue;\n if (part === '..') stack.pop();\n else stack.push(part);\n }\n return `/${stack.join('/')}`;\n }\n\n private async getFile(path: string): Promise<DriveFile> {\n const file = await this.findFile(path);\n if (!file) throw new FileNotFoundError(path);\n return file;\n }\n\n private async findFile(path: string): Promise<DriveFile | undefined> {\n const normalized = this.normalize(path);\n if (normalized === '/') return this.rootFile();\n const names = normalized.split('/').filter(Boolean);\n let parentId = this.folderId;\n let file: DriveFile | undefined;\n for (const name of names) {\n file = await this.findChild(parentId, name);\n if (!file) return undefined;\n parentId = file.id;\n }\n return file;\n }\n\n private async rootFile(): Promise<DriveFile> {\n return this.request<DriveFile>(`${DRIVE_API}/files/${encodeURIComponent(this.folderId)}`, {\n searchParams: { fields: 'id,name,mimeType,size,createdTime,modifiedTime,parents', supportsAllDrives: 'true' },\n });\n }\n\n private async resolveParent(path: string, recursive: boolean): Promise<{ parentId: string; name: string }> {\n const normalized = this.normalize(path);\n const parts = normalized.split('/').filter(Boolean);\n const name = parts.pop();\n if (!name) throw new IsDirectoryError(path);\n const parentPath = `/${parts.join('/')}`;\n const parent = recursive ? await this.resolveDir(parentPath, true) : await this.findFile(parentPath);\n if (!parent) throw new DirectoryNotFoundError(parentPath);\n if (parent.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(parentPath);\n return { parentId: parent.id, name };\n }\n\n private async resolveDir(path: string, recursive: boolean): Promise<DriveFile> {\n const normalized = this.normalize(path);\n if (normalized === '/') return this.rootFile();\n const names = normalized.split('/').filter(Boolean);\n let parentId = this.folderId;\n let current: DriveFile | undefined;\n for (const name of names) {\n current = await this.findChild(parentId, name);\n if (current) {\n if (current.mimeType !== FOLDER_MIME_TYPE) throw new NotDirectoryError(name);\n parentId = current.id;\n continue;\n }\n if (!recursive) throw new DirectoryNotFoundError(normalized);\n current = await this.createFolder(parentId, name);\n parentId = current.id;\n }\n return current!;\n }\n\n private async createFolder(parentId: string, name: string): Promise<DriveFile> {\n return this.request<DriveFile>(`${DRIVE_API}/files`, {\n method: 'POST',\n searchParams: { fields: 'id,name,mimeType,size,createdTime,modifiedTime,parents', supportsAllDrives: 'true' },\n body: JSON.stringify({ name, mimeType: FOLDER_MIME_TYPE, parents: [parentId] }),\n });\n }\n\n private async findChild(parentId: string, name: string): Promise<DriveFile | undefined> {\n const files = await this.listChildren(parentId, `name = '${this.escapeQuery(name)}'`);\n return files[0];\n }\n\n private async listChildren(parentId: string, extraQuery?: string): Promise<DriveFile[]> {\n const query = [`'${this.escapeQuery(parentId)}' in parents`, 'trashed = false', extraQuery]\n .filter(Boolean)\n .join(' and ');\n const files: DriveFile[] = [];\n let pageToken: string | undefined;\n\n do {\n const result = await this.request<{ files: DriveFile[]; nextPageToken?: string }>(`${DRIVE_API}/files`, {\n searchParams: {\n q: query,\n fields: 'nextPageToken,files(id,name,mimeType,size,createdTime,modifiedTime,parents)',\n pageSize: '1000',\n supportsAllDrives: 'true',\n includeItemsFromAllDrives: 'true',\n ...(pageToken ? { pageToken } : {}),\n },\n });\n files.push(...(result.files ?? []));\n pageToken = result.nextPageToken;\n } while (pageToken);\n\n return files;\n }\n\n private async readdirRecursive(\n parentId: string,\n options: ListOptions | undefined,\n depth: number,\n ): Promise<FileEntry[]> {\n const children = await this.listChildren(parentId);\n const entries: FileEntry[] = [];\n for (const child of children) {\n const isDirectory = child.mimeType === FOLDER_MIME_TYPE;\n entries.push({ name: child.name, type: isDirectory ? 'directory' : 'file', size: Number(child.size ?? 0) });\n const shouldDescend =\n isDirectory && options?.recursive && (options.maxDepth === undefined || depth < options.maxDepth);\n if (shouldDescend) {\n const nested = await this.readdirRecursive(child.id, options, depth + 1);\n entries.push(...nested.map(entry => ({ ...entry, name: `${child.name}/${entry.name}` })));\n }\n }\n return entries;\n }\n\n private async deleteAny(file: DriveFile, path: string, recursive: boolean): Promise<void> {\n if (file.mimeType === FOLDER_MIME_TYPE) await this.rmdir(path, { recursive, force: true });\n else await this.deleteFile(path, { force: true });\n }\n\n private async upload(\n fileId: string | undefined,\n content: FileContent,\n mimeType = 'application/octet-stream',\n method: 'POST' | 'PATCH',\n metadata?: Record<string, unknown>,\n ): Promise<void> {\n const boundary = `mastra-${Date.now()}`;\n const body = Buffer.concat([\n Buffer.from(\n `--${boundary}\\r\\nContent-Type: application/json; charset=UTF-8\\r\\n\\r\\n${JSON.stringify(metadata ?? {})}\\r\\n`,\n ),\n Buffer.from(`--${boundary}\\r\\nContent-Type: ${mimeType}\\r\\n\\r\\n`),\n this.toBuffer(content),\n Buffer.from(`\\r\\n--${boundary}--`),\n ]);\n const url = fileId ? `${DRIVE_UPLOAD_API}/files/${encodeURIComponent(fileId)}` : `${DRIVE_UPLOAD_API}/files`;\n await this.request(url, {\n method,\n searchParams: { uploadType: 'multipart', fields: 'id', supportsAllDrives: 'true' },\n headers: { 'Content-Type': `multipart/related; boundary=${boundary}` },\n body,\n });\n }\n\n private escapeQuery(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n }\n\n private async request<T>(\n url: string,\n init: RequestInit & { searchParams?: Record<string, string> } = {},\n ): Promise<T> {\n const response = await this.fetch(url, init);\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n }\n\n private async fetch(\n url: string,\n init: RequestInit & { searchParams?: Record<string, string> } = {},\n ): Promise<Response> {\n const token = await this.getToken();\n const target = new URL(url);\n for (const [key, value] of Object.entries(init.searchParams ?? {})) target.searchParams.set(key, value);\n const headers: Record<string, string> = { Authorization: `Bearer ${token}` };\n // Auto-apply Content-Type for JSON bodies when not explicitly set (e.g. multipart uploads).\n if (init.body && typeof init.body === 'string' && !init.headers) {\n headers['Content-Type'] = 'application/json';\n }\n const response = await globalThis.fetch(target, {\n ...init,\n headers: { ...headers, ...(init.headers as Record<string, string>) },\n });\n if (!response.ok) {\n const message = await response.text().catch(() => response.statusText);\n throw new Error(`Google Drive API request failed (${response.status}): ${message}`);\n }\n return response;\n }\n\n private async getToken(): Promise<string> {\n if (this.accessToken && Date.now() < this.tokenExpiresAt - 60_000) return this.accessToken;\n if (this.getAccessToken) return this.getAccessToken();\n if (this.serviceAccount) {\n // Dedup concurrent refresh attempts — all callers share the same in-flight promise.\n if (!this.tokenRefreshPromise) {\n this.tokenRefreshPromise = this.getServiceAccountToken().finally(() => {\n this.tokenRefreshPromise = undefined;\n });\n }\n return this.tokenRefreshPromise;\n }\n if (this.accessToken) return this.accessToken;\n throw new Error('GoogleDriveFilesystem requires accessToken, getAccessToken, or serviceAccount authentication.');\n }\n\n private async getServiceAccountToken(): Promise<string> {\n const account = this.serviceAccount!;\n const now = Math.floor(Date.now() / 1000);\n const header = { alg: 'RS256', typ: 'JWT', ...(account.privateKeyId ? { kid: account.privateKeyId } : {}) };\n const claim = {\n iss: account.clientEmail,\n scope: (account.scopes ?? DEFAULT_SCOPES).join(' '),\n aud: OAUTH_TOKEN_URL,\n exp: now + 3600,\n iat: now,\n ...(account.subject ? { sub: account.subject } : {}),\n };\n const unsigned = `${this.base64Url(JSON.stringify(header))}.${this.base64Url(JSON.stringify(claim))}`;\n const privateKey = this.normalizePrivateKey(account.privateKey);\n let signature: string;\n try {\n signature = createSign('RSA-SHA256').update(unsigned).sign(privateKey, 'base64url');\n } catch (err) {\n const hasBegin = privateKey.includes('-----BEGIN');\n const hasEnd = privateKey.includes('-----END');\n throw new Error(\n `Google service account private key signing failed (${(err as Error).message}). ` +\n `Key has BEGIN marker: ${hasBegin}, END marker: ${hasEnd}. ` +\n `Ensure your .env value contains the raw PEM with \\\\n for newlines, without extra surrounding quotes or commas.`,\n );\n }\n const response = await globalThis.fetch(OAUTH_TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',\n assertion: `${unsigned}.${signature}`,\n }),\n });\n if (!response.ok)\n throw new Error(`Google service account token request failed (${response.status}): ${await response.text()}`);\n const json = (await response.json()) as { access_token: string; expires_in: number };\n this.accessToken = json.access_token;\n this.tokenExpiresAt = Date.now() + json.expires_in * 1000;\n return json.access_token;\n }\n\n private base64Url(value: string): string {\n return Buffer.from(value).toString('base64url');\n }\n\n private normalizePrivateKey(key: string): string {\n let out = key.trim();\n // Iteratively strip JSON-style wrapping that .env files tend to accumulate:\n // trailing commas, literal backslash-escaped quotes, and plain surrounding quotes.\n // Loop because values can be doubly wrapped (e.g. a JSON-encoded string pasted into\n // a .env file still wrapped in quotes by the dotenv loader).\n for (let i = 0; i < 5; i++) {\n const before = out;\n if (out.endsWith(',')) out = out.slice(0, -1).trim();\n if ((out.startsWith('\"') && out.endsWith('\"')) || (out.startsWith(\"'\") && out.endsWith(\"'\"))) {\n out = out.slice(1, -1);\n }\n if ((out.startsWith('\\\\\"') && out.endsWith('\\\\\"')) || (out.startsWith(\"\\\\'\") && out.endsWith(\"\\\\'\"))) {\n out = out.slice(2, -2);\n }\n if (out === before) break;\n }\n // Replace escaped newlines with real newlines (common when storing the key on one line in .env).\n out = out.replace(/\\\\n/g, '\\n');\n // Unescape any remaining escaped quotes that survived the unwrapping.\n out = out.replace(/\\\\\"/g, '\"').replace(/\\\\'/g, \"'\");\n // Normalize CRLF / CR to LF — OpenSSL's PEM decoder is strict about line endings.\n out = out.replace(/\\r\\n?/g, '\\n');\n // Ensure PEM ends with a trailing newline — required by some OpenSSL versions.\n if (!out.endsWith('\\n')) out += '\\n';\n return out;\n }\n}\n","/**\n * Google Drive filesystem provider descriptor for MastraEditor.\n *\n * @example\n * ```typescript\n * import { googleDriveFilesystemProvider } from '@mastra/google-drive';\n *\n * const editor = new MastraEditor({\n * filesystems: [googleDriveFilesystemProvider],\n * });\n * ```\n */\nimport type { FilesystemProvider } from '@mastra/core/editor';\nimport { GoogleDriveFilesystem } from './filesystem';\nimport type { GoogleDriveFilesystemOptions } from './filesystem';\n\nexport const googleDriveFilesystemProvider: FilesystemProvider<GoogleDriveFilesystemOptions> = {\n id: 'google-drive',\n name: 'Google Drive',\n description: 'Google Drive folder mounted as a filesystem',\n configSchema: {\n type: 'object',\n required: ['folderId'],\n properties: {\n folderId: { type: 'string', description: 'Google Drive folder ID to mount as the workspace root' },\n accessToken: {\n type: 'string',\n description: 'OAuth access token with the https://www.googleapis.com/auth/drive scope',\n },\n serviceAccount: {\n type: 'object',\n required: ['clientEmail', 'privateKey'],\n properties: {\n clientEmail: { type: 'string', description: 'Google service account email' },\n privateKey: { type: 'string', description: 'PEM-encoded private key' },\n privateKeyId: { type: 'string', description: 'Optional private key ID' },\n scopes: {\n type: 'array',\n items: { type: 'string' },\n description: 'Optional OAuth scopes override',\n },\n subject: { type: 'string', description: 'Optional delegated user email' },\n },\n description: 'Service account credentials for server-to-server auth',\n },\n readOnly: { type: 'boolean', description: 'Mount as read-only', default: false },\n },\n },\n createFilesystem: config => new GoogleDriveFilesystem(config),\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAEjE,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,CAAC,4BAA4B,CAiB1F,CAAC"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAEjE,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,CAAC,4BAA4B,CAiC1F,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/google-drive",
3
- "version": "0.0.0",
3
+ "version": "0.1.0-alpha.1",
4
4
  "description": "Google Drive filesystem provider for Mastra workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -18,28 +18,19 @@
18
18
  },
19
19
  "./package.json": "./package.json"
20
20
  },
21
- "scripts": {
22
- "build": "tsup --silent --config tsup.config.ts",
23
- "build:lib": "pnpm build",
24
- "build:watch": "pnpm build --watch",
25
- "test:unit": "vitest run",
26
- "test": "vitest run",
27
- "test:watch": "vitest watch",
28
- "lint": "eslint ."
29
- },
30
21
  "license": "Apache-2.0",
31
22
  "devDependencies": {
32
- "@internal/lint": "workspace:*",
33
- "@internal/types-builder": "workspace:*",
34
- "@mastra/core": "workspace:*",
35
23
  "@types/node": "22.19.15",
36
- "@vitest/coverage-v8": "catalog:",
37
- "@vitest/ui": "catalog:",
24
+ "@vitest/coverage-v8": "4.1.5",
25
+ "@vitest/ui": "4.1.5",
38
26
  "dotenv": "^17.3.1",
39
27
  "eslint": "^10.2.1",
40
28
  "tsup": "^8.5.1",
41
- "typescript": "catalog:",
42
- "vitest": "catalog:"
29
+ "typescript": "^6.0.3",
30
+ "vitest": "4.1.5",
31
+ "@internal/lint": "0.0.89",
32
+ "@internal/types-builder": "0.0.64",
33
+ "@mastra/core": "1.31.0-alpha.1"
43
34
  },
44
35
  "peerDependencies": {
45
36
  "@mastra/core": ">=1.4.0-0 <2.0.0-0"
@@ -59,5 +50,15 @@
59
50
  },
60
51
  "engines": {
61
52
  "node": ">=22.13.0"
53
+ },
54
+ "scripts": {
55
+ "build": "tsup --silent --config tsup.config.ts",
56
+ "build:lib": "pnpm build",
57
+ "build:watch": "pnpm build --watch",
58
+ "test:unit": "vitest run",
59
+ "test": "vitest run",
60
+ "test:cloud": "vitest run --passWithNoTests ./src/**/*.integration.test.ts",
61
+ "test:watch": "vitest watch",
62
+ "lint": "eslint ."
62
63
  }
63
- }
64
+ }