@braidhq/source-loader-gdrive 0.1.0 → 0.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 mroops0111
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # @braidhq/source-loader-gdrive
2
+
3
+ Braid keeps a product's intent and its code aligned in one knowledge graph, and lets plugins feed that graph from outside sources. `@braidhq/source-loader-gdrive` is the plugin that exports Google Docs from a Drive folder as markdown, so a team's design docs become a Braid source.
4
+
5
+ ## Role
6
+
7
+ The drive loader walks a Drive folder, exports every Google Doc it finds as markdown, and keeps a manifest so later syncs touch only what changed.
8
+
9
+ - **The Export**: Each doc is exported to `<destination>/<sanitised-title>/index.md`, and its inlined base64 images are decoded into sibling files, so the markdown stays readable for humans and models.
10
+ - **The Manifest**: A `.braid-gdrive-manifest.json` records each doc's id, title, and modified time, so sync can add, update, rename, or remove docs against the prior state instead of re-downloading everything.
11
+ - **The Auth**: A fresh OAuth access token is resolved per workspace and source through an injected callback, so credentials stay in the composition root, never in config.
12
+
13
+ ## Structure
14
+
15
+ ```
16
+ src/
17
+ ├── GoogleDriveSourceLoaderPlugin.ts the gdrive loader, config, walk, export, manifest-diff sync
18
+ ├── DriveClient.ts the Drive REST client, list children and export a doc
19
+ ├── Manifest.ts the on-disk sync-state manifest, read and write
20
+ └── index.ts re-exports the factory and its config type
21
+ ```
22
+
23
+ - **GoogleDriveSourceLoaderPlugin**: The `createGoogleDriveLoader` factory. It walks the folder, filters by title, exports each doc, extracts inline images, and diffs against the manifest on sync.
24
+ - **DriveClient**: The thin Drive REST wrapper, listing folder children and exporting a doc to a given mime type.
25
+ - **Manifest**: The read and write of `.braid-gdrive-manifest.json`, the record sync diffs against.
26
+
27
+ ## Export and Layout
28
+
29
+ Drive folder hierarchy is flattened. Every matched doc lands in its own directory directly under the destination, named from the sanitised Drive title, so two docs that sanitise to the same name collide and one must be renamed in Drive. Auto-created `Copy of` duplicates are skipped, and title `include` and `exclude` regexes narrow what is exported while subfolders are still traversed when `recursive` is set.
30
+
31
+ Only Google Docs are in scope. Sheets, Slides, Drawings, and Forms are left for a different plugin. The `folderId` alias `root` is rejected outright, since it would mirror an entire My Drive.
32
+
33
+ ## Boundaries
34
+
35
+ - **Owns Its Directory**: The destination and its manifest are the loader's to write. Provision wipes and rebuilds it, sync reconciles it against Drive.
36
+ - **No Credentials On Disk**: The access token is resolved at run time through the injected callback. Only exported markdown and images land in the destination.
37
+ - **A Plugin, Not A Service**: It implements core's `SourceLoader` port through the sdk factory, and depends on the host to supply OAuth token resolution.
38
+
39
+ ## Dependencies
40
+
41
+ - **Depends On**: `@braidhq/core` for the port, `@braidhq/schema` for shared types, `@braidhq/sdk` for the factory, and `zod`.
42
+ - **Consumed By**: The server composition root, where `composeFsApp` registers the gdrive loader and wires `resolveAccessToken` to its OAuth store.
@@ -3,7 +3,7 @@ import { Buffer } from 'node:buffer';
3
3
  * Tiny Google Drive v3 client wrapper. We only use a few endpoints and
4
4
  * don't need the full `googleapis` package (which ships > 1 MB of types).
5
5
  *
6
- * Inject `fetchFn` for tests; real callers use globalThis.fetch.
6
+ * Inject `fetchFn` for tests. Real callers use globalThis.fetch.
7
7
  */
8
8
  export type FetchFn = typeof globalThis.fetch;
9
9
  export interface DriveFileMetadata {
@@ -21,8 +21,8 @@ export declare class DriveClient {
21
21
  listChildren(folderId: string): Promise<readonly DriveFileMetadata[]>;
22
22
  /** Export a Google native doc (gdoc / gsheet / gslides) to a chosen format. */
23
23
  exportDoc(fileId: string, mimeType: string): Promise<Buffer>;
24
- /** Download a binary file (image, PDF, ) as-is. */
24
+ /** Download a binary file (image, PDF, and so on) as-is. */
25
25
  downloadFile(fileId: string): Promise<Buffer>;
26
26
  private authHeader;
27
27
  }
28
- //# sourceMappingURL=driveClient.d.ts.map
28
+ //# sourceMappingURL=DriveClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"driveClient.d.ts","sourceRoot":"","sources":["../src/driveClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAMpC;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,UAAU,CAAC,KAAK,CAAA;AAE7C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACrC;AAED,qBAAa,WAAW;IAEpB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,OAA0B;IAGtD,sDAAsD;IAChD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC;IAsB3E,+EAA+E;IACzE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQlE,oDAAoD;IAC9C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQnD,OAAO,CAAC,UAAU;CAGnB"}
1
+ {"version":3,"file":"DriveClient.d.ts","sourceRoot":"","sources":["../src/DriveClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAMpC;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,UAAU,CAAC,KAAK,CAAA;AAE7C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACrC;AAED,qBAAa,WAAW;IAEpB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,OAA0B;IAGtD,sDAAsD;IAChD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC;IAsB3E,+EAA+E;IACzE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQlE,4DAA4D;IACtD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQnD,OAAO,CAAC,UAAU;CAGnB"}
@@ -39,7 +39,7 @@ export class DriveClient {
39
39
  throw await driveError(response, `exportDoc(${fileId},${mimeType})`);
40
40
  return globalBuffer().from(await response.arrayBuffer());
41
41
  }
42
- /** Download a binary file (image, PDF, ) as-is. */
42
+ /** Download a binary file (image, PDF, and so on) as-is. */
43
43
  async downloadFile(fileId) {
44
44
  const url = `https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`;
45
45
  const response = await this.fetchFn(url, { headers: this.authHeader() });
@@ -55,4 +55,4 @@ async function driveError(response, op) {
55
55
  const text = await response.text().catch(() => '');
56
56
  return new Error(`Drive ${op} failed: ${response.status} ${response.statusText} ${text}`);
57
57
  }
58
- //# sourceMappingURL=driveClient.js.map
58
+ //# sourceMappingURL=DriveClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"driveClient.js","sourceRoot":"","sources":["../src/driveClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DriveClient.js","sourceRoot":"","sources":["../src/DriveClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { SourceLoaderContext, SourceLoaderPlugin } from '@braidhq/core';
2
+ import { z } from 'zod';
3
+ import { type DriveFileMetadata, type FetchFn } from './DriveClient.js';
4
+ export declare const GoogleDriveLoaderConfig: z.ZodObject<{
5
+ folderId: z.ZodString;
6
+ recursive: z.ZodDefault<z.ZodBoolean>;
7
+ include: z.ZodOptional<z.ZodString>;
8
+ exclude: z.ZodOptional<z.ZodString>;
9
+ }, z.core.$strip>;
10
+ export type GoogleDriveLoaderConfig = z.infer<typeof GoogleDriveLoaderConfig>;
11
+ export interface GoogleDriveLoaderDeps {
12
+ /**
13
+ * Resolve a fresh access token for a given `(workspaceId, sourceId)`.
14
+ * The composition root implements this against its OAuth refresh-token store.
15
+ * Tests can return a static token regardless of context.
16
+ */
17
+ resolveAccessToken: (context: SourceLoaderContext) => Promise<string>;
18
+ /** Inject for tests. Real callers use globalThis.fetch. */
19
+ fetchFn?: FetchFn;
20
+ }
21
+ /**
22
+ * Build a Google Drive source loader. Walks a Drive folder, exports every
23
+ * Google Doc inside as markdown, extracts inlined base64 images into
24
+ * sibling files, and lays everything out as:
25
+ *
26
+ * <destination>/
27
+ * <sanitised-doc-title>/
28
+ * index.md
29
+ * <image-label>.png (one per inlined image)
30
+ * <sanitised-doc-title-2>/
31
+ * index.md
32
+ * .braid-gdrive-manifest.json (sync state)
33
+ *
34
+ * Drive folder hierarchy is not preserved on disk.
35
+ * Every matched doc is flattened into a sibling directory under `destination/`.
36
+ * Two docs with the same sanitised title will collide,
37
+ * so rename one in Drive to disambiguate.
38
+ *
39
+ * Out of scope (intentional): Google Sheets, Slides, Drawings, Forms, and standalone binaries.
40
+ * Mirrors redoc's PRD-focused workflow.
41
+ * When you need spreadsheets or slide decks, provision them through a different source-loader plugin.
42
+ */
43
+ export declare function createGoogleDriveLoader(deps: GoogleDriveLoaderDeps): SourceLoaderPlugin;
44
+ /** Note: the helper used by DriveClient.exportDoc returns Buffer. */
45
+ export type { DriveFileMetadata, FetchFn };
46
+ //# sourceMappingURL=GoogleDriveSourceLoaderPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GoogleDriveSourceLoaderPlugin.d.ts","sourceRoot":"","sources":["../src/GoogleDriveSourceLoaderPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAK5E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAe,KAAK,iBAAiB,EAAE,KAAK,OAAO,EAAE,MAAM,kBAAkB,CAAA;AA4BpF,eAAO,MAAM,uBAAuB;;;;;iBAiClC,CAAA;AACF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAE7E,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,kBAAkB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IACrE,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAaD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,GAAG,kBAAkB,CAgHvF;AA+GD,qEAAqE;AACrE,YAAY,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAA"}
@@ -1,37 +1,39 @@
1
1
  import { Buffer } from 'node:buffer';
2
2
  import { mkdir, rm, writeFile } from 'node:fs/promises';
3
3
  import { join } from 'node:path';
4
- import { defineSourceLoader } from '@braidhq/sdk';
4
+ import { defineSourceLoaderPlugin } from '@braidhq/sdk';
5
5
  import { z } from 'zod';
6
- import { DriveClient } from './driveClient.js';
6
+ import { DriveClient } from './DriveClient.js';
7
7
  import { readManifest, writeManifest } from './Manifest.js';
8
8
  const FOLDER_MIME = 'application/vnd.google-apps.folder';
9
9
  const DOC_MIME = 'application/vnd.google-apps.document';
10
10
  /**
11
- * Drive auto-creates duplicates named "Copy of" (English) or "…的副本"
12
- * (Chinese) when users use the Make a Copy menu. They almost always carry
13
- * stale content that would conflict with the canonical doc, so we skip
14
- * them silently. Same rule as redoc.
11
+ * Drive auto-creates duplicates named "Copy of" (English) or ending in "的副本" (Chinese),
12
+ * when users use the Make a Copy menu.
13
+ * They almost always carry stale content that would conflict with the canonical doc,
14
+ * so we skip them silently. Same rule as redoc.
15
15
  */
16
16
  const COPY_PATTERNS = [/^Copy of /, /的副本$/];
17
17
  /**
18
- * Drive's `text/markdown` export inlines images as base64 data URIs in
19
- * reference-style link form:
18
+ * Drive's `text/markdown` export inlines images as base64 data URIs,
19
+ * in reference-style link form:
20
20
  *
21
- * [image0]: <data:image/png;base64,iVBORw0KG…>
21
+ * [image0]: <data:image/png;base64,iVBORw0KG...>
22
22
  *
23
- * Leaving those base64 blobs in the markdown bloats the file by ~33 % per
24
- * image and is unreadable for both humans and LLMs. This regex matches one
25
- * such reference line so we can extract the image to its own file and
26
- * rewrite the link to a relative path. Same approach as redoc.
23
+ * Leaving those base64 blobs in the markdown bloats the file by ~33 % per image,
24
+ * and is unreadable for both humans and LLMs.
25
+ * This regex matches one such reference line,
26
+ * so we can extract the image to its own file and rewrite the link to a relative path.
27
+ * Same approach as redoc.
27
28
  */
28
29
  const INLINE_IMAGE_RE = /^\[([^\]]+)\]:\s*<data:image\/([\w+]+);base64,([^>]+)>$/gm;
29
30
  export const GoogleDriveLoaderConfig = z.object({
30
31
  /**
31
- * Drive folder id (the long alphanumeric in the URL). Reject the alias
32
- * `root` outright: it expands to the user's entire My Drive and would
33
- * mirror every file they own, which is almost never what someone wants
34
- * from an "intent docs" source and easily costs gigabytes + minutes.
32
+ * Drive folder id (the long alphanumeric in the URL).
33
+ * Reject the alias `root` outright,
34
+ * since it expands to the user's entire My Drive and would mirror every file they own,
35
+ * which is almost never what someone wants from an "intent docs" source,
36
+ * and easily costs gigabytes and minutes.
35
37
  * Make people pick a specific subfolder.
36
38
  */
37
39
  folderId: z.string()
@@ -40,20 +42,22 @@ export const GoogleDriveLoaderConfig = z.object({
40
42
  message: 'folderId "root" refers to the entire My Drive and is rejected. Create a dedicated subfolder and use its id instead.',
41
43
  }),
42
44
  /**
43
- * Whether to traverse subfolders. Default true. Subfolder hierarchy
44
- * is NOT preserved on disk; every matching doc lives in its own dir
45
- * directly under `destination/`. Disable to limit to immediate
46
- * children of `folderId`.
45
+ * Whether to traverse subfolders. Default true.
46
+ * Subfolder hierarchy is not preserved on disk.
47
+ * Every matching doc lives in its own dir directly under `destination/`.
48
+ * Disable to limit to immediate children of `folderId`.
47
49
  */
48
50
  recursive: z.boolean().default(true),
49
51
  /**
50
- * Optional regex (string). When set, only docs whose *Drive title*
51
- * matches this pattern are downloaded. Subfolders are still traversed.
52
+ * Optional regex (string).
53
+ * When set, only docs whose *Drive title* matches this pattern are downloaded.
54
+ * Subfolders are still traversed.
52
55
  */
53
56
  include: z.string().optional(),
54
57
  /**
55
- * Optional regex (string). When set, docs whose title matches are
56
- * skipped. Evaluated after `include`, so exclude takes priority.
58
+ * Optional regex (string).
59
+ * When set, docs whose title matches are skipped.
60
+ * Evaluated after `include`, so exclude takes priority.
57
61
  */
58
62
  exclude: z.string().optional(),
59
63
  });
@@ -68,23 +72,22 @@ export const GoogleDriveLoaderConfig = z.object({
68
72
  * <image-label>.png (one per inlined image)
69
73
  * <sanitised-doc-title-2>/
70
74
  * index.md
71
- * .braid-manifest.json (sync state)
75
+ * .braid-gdrive-manifest.json (sync state)
72
76
  *
73
- * Drive folder hierarchy is NOT preserved on disk; every matched doc
74
- * is flattened into a sibling directory under `destination/`. Two docs
75
- * with the same sanitised title will collide; rename one in Drive to
76
- * disambiguate.
77
+ * Drive folder hierarchy is not preserved on disk.
78
+ * Every matched doc is flattened into a sibling directory under `destination/`.
79
+ * Two docs with the same sanitised title will collide,
80
+ * so rename one in Drive to disambiguate.
77
81
  *
78
- * Out of scope (intentional): Google Sheets, Slides, Drawings, Forms,
79
- * and standalone binaries. Mirrors redoc's PRD-focused workflow. If you
80
- * need spreadsheets / slide decks, ingest them through a different
81
- * source-loader plugin.
82
+ * Out of scope (intentional): Google Sheets, Slides, Drawings, Forms, and standalone binaries.
83
+ * Mirrors redoc's PRD-focused workflow.
84
+ * When you need spreadsheets or slide decks, provision them through a different source-loader plugin.
82
85
  */
83
86
  export function createGoogleDriveLoader(deps) {
84
- return defineSourceLoader({
87
+ return defineSourceLoaderPlugin({
85
88
  kind: 'gdrive',
86
89
  configSchema: GoogleDriveLoaderConfig,
87
- ingest: async (config, destination, context) => {
90
+ provision: async (config, destination, context) => {
88
91
  await rm(destination, { recursive: true, force: true });
89
92
  await mkdir(destination, { recursive: true });
90
93
  const client = await buildClient(deps, context);
@@ -109,8 +112,8 @@ export function createGoogleDriveLoader(deps) {
109
112
  sync: async (config, destination, context) => {
110
113
  const cached = await readManifest(destination);
111
114
  if (!cached) {
112
- // No manifest yet (first sync after upgrade / cache wiped). Fall
113
- // back to a clean ingest so we end up in a known-good state.
115
+ // No manifest yet (first sync after upgrade or cache wiped).
116
+ // Fall back to a clean provision so we end up in a known-good state.
114
117
  const client = await buildClient(deps, context);
115
118
  await rm(destination, { recursive: true, force: true });
116
119
  await mkdir(destination, { recursive: true });
@@ -156,8 +159,8 @@ export function createGoogleDriveLoader(deps) {
156
159
  added++;
157
160
  }
158
161
  else if (prior.localDir !== doc.localDir || prior.modifiedTime !== doc.modifiedTime) {
159
- // Either content updated or the doc was renamed in Drive. Both
160
- // cases: re-download to the new dir, then rm the old dir.
162
+ // Either content updated or the doc was renamed in Drive.
163
+ // Both cases re-download to the new dir, then rm the old dir.
161
164
  if (prior.localDir !== doc.localDir)
162
165
  await rm(join(destination, prior.localDir), { recursive: true, force: true });
163
166
  await downloadOne(client, doc, destination);
@@ -216,9 +219,10 @@ async function walk(client, config) {
216
219
  const localDir = sanitiseName(child.name);
217
220
  const collides = seenDirs.get(localDir);
218
221
  if (collides && collides !== child.id) {
219
- // Two distinct Drive docs sanitise to the same dir name. Keep
220
- // the first one we walked into; skipping the second is safer
221
- // than silently overwriting. User can rename in Drive.
222
+ // Two distinct Drive docs sanitise to the same dir name.
223
+ // Keep the first one we walked into.
224
+ // Skipping the second is safer than silently overwriting.
225
+ // User can rename in Drive.
222
226
  continue;
223
227
  }
224
228
  seenDirs.set(localDir, child.id);
@@ -244,10 +248,10 @@ async function downloadOne(client, doc, destination) {
244
248
  await writeFile(join(docDir, 'index.md'), rewritten, 'utf-8');
245
249
  }
246
250
  /**
247
- * Pull every `[label]: <data:image/ext;base64,...>` reference out of the
248
- * markdown, write the decoded bytes as `<label>.<ext>` in `docDir`, and
249
- * rewrite the reference to point at the new local file. Returns the
250
- * cleaned markdown. Matches redoc's behaviour.
251
+ * Pull every `[label]: <data:image/ext;base64,...>` reference out of the markdown,
252
+ * write the decoded bytes as `<label>.<ext>` in `docDir`,
253
+ * and rewrite the reference to point at the new local file.
254
+ * Returns the cleaned markdown. Matches redoc's behaviour.
251
255
  */
252
256
  async function extractInlineImages(markdown, docDir) {
253
257
  const writes = [];
@@ -277,9 +281,9 @@ function entryOf(doc) {
277
281
  };
278
282
  }
279
283
  function sanitiseName(name) {
280
- // Replace path separators, control chars, and common shell-hostile
281
- // characters with `_`. Spaces stay so human-readable titles survive
282
- // ("Roadmap Q3 2026" "Roadmap Q3 2026").
284
+ // Replace path separators, control chars, and common shell-hostile characters with `_`.
285
+ // Spaces stay so human-readable titles survive,
286
+ // for example "Roadmap Q3 2026" stays "Roadmap Q3 2026".
283
287
  return name.replace(/[/\\:*?"<>|]/g, '_');
284
288
  }
285
- //# sourceMappingURL=GoogleDriveLoader.js.map
289
+ //# sourceMappingURL=GoogleDriveSourceLoaderPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GoogleDriveSourceLoaderPlugin.js","sourceRoot":"","sources":["../src/GoogleDriveSourceLoaderPlugin.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /** Filename written inside `destination` to track per-file sync state. */
2
- export declare const MANIFEST_FILENAME = ".braid-manifest.json";
2
+ export declare const MANIFEST_FILENAME = ".braid-gdrive-manifest.json";
3
3
  export interface ManifestEntry {
4
- /** Posix relative dir under `destination`: the per-doc package. */
4
+ /** Posix relative dir under `destination`, the per-doc package. */
5
5
  localDir: string;
6
6
  modifiedTime: string;
7
7
  /** Drive title at the time of the last sync, for debugging only. */
@@ -14,9 +14,10 @@ export interface Manifest {
14
14
  files: Record<string, ManifestEntry>;
15
15
  }
16
16
  /**
17
- * Read the manifest file from `destination`. Returns `undefined` if the
18
- * file is missing or unparseable; callers should fall back to a clean
19
- * ingest in that case (no manifest = no incremental state to diff against).
17
+ * Read the manifest file from `destination`.
18
+ * Returns `undefined` when the file is missing or unparseable.
19
+ * Callers fall back to a clean provision in that case,
20
+ * since no manifest means no incremental state to diff against.
20
21
  */
21
22
  export declare function readManifest(destination: string): Promise<Manifest | undefined>;
22
23
  export declare function writeManifest(destination: string, manifest: Manifest): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"Manifest.d.ts","sourceRoot":"","sources":["../src/Manifest.ts"],"names":[],"mappings":"AAGA,0EAA0E;AAC1E,eAAO,MAAM,iBAAiB,yBAAyB,CAAA;AAEvD,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CACrC;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAQrF;AAED,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAM1F"}
1
+ {"version":3,"file":"Manifest.d.ts","sourceRoot":"","sources":["../src/Manifest.ts"],"names":[],"mappings":"AAGA,0EAA0E;AAC1E,eAAO,MAAM,iBAAiB,gCAAgC,CAAA;AAE9D,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CACrC;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAQrF;AAED,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAM1F"}
package/dist/Manifest.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import { readFile, writeFile } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
3
  /** Filename written inside `destination` to track per-file sync state. */
4
- export const MANIFEST_FILENAME = '.braid-manifest.json';
4
+ export const MANIFEST_FILENAME = '.braid-gdrive-manifest.json';
5
5
  /**
6
- * Read the manifest file from `destination`. Returns `undefined` if the
7
- * file is missing or unparseable; callers should fall back to a clean
8
- * ingest in that case (no manifest = no incremental state to diff against).
6
+ * Read the manifest file from `destination`.
7
+ * Returns `undefined` when the file is missing or unparseable.
8
+ * Callers fall back to a clean provision in that case,
9
+ * since no manifest means no incremental state to diff against.
9
10
  */
10
11
  export async function readManifest(destination) {
11
12
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"Manifest.js","sourceRoot":"","sources":["../src/Manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,iBAAiB,GAAG,sBAAsB,CAAA;AAiBvD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,WAAmB;IACpD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAAA;QACzE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;IACpC,CAAC;IACD,MAAM,CAAC;QACL,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAmB,EAAE,QAAkB;IACzE,MAAM,SAAS,CACb,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EACpC,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EACxC,OAAO,CACR,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"Manifest.js","sourceRoot":"","sources":["../src/Manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,iBAAiB,GAAG,6BAA6B,CAAA;AAiB9D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,WAAmB;IACpD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAAA;QACzE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;IACpC,CAAC;IACD,MAAM,CAAC;QACL,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAmB,EAAE,QAAkB;IACzE,MAAM,SAAS,CACb,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EACpC,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EACxC,OAAO,CACR,CAAA;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export * from './driveClient.js';
2
- export * from './GoogleDriveLoader.js';
1
+ export * from './DriveClient.js';
2
+ export * from './GoogleDriveSourceLoaderPlugin.js';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,oCAAoC,CAAA"}
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export * from './driveClient.js';
2
- export * from './GoogleDriveLoader.js';
1
+ export * from './DriveClient.js';
2
+ export * from './GoogleDriveSourceLoaderPlugin.js';
3
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,oCAAoC,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@braidhq/source-loader-gdrive",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.2.1",
5
5
  "description": "Google Drive source-loader plugin for Braid. Export docs from Google Drive, requires OAuth on first use.",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -10,40 +10,35 @@
10
10
  "directory": "packages/source-loader-gdrive"
11
11
  },
12
12
  "exports": {
13
- ".": "./src/index.ts"
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ }
14
17
  },
15
- "main": "./src/index.ts",
16
- "types": "./src/index.ts",
18
+ "main": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
17
20
  "files": [
18
21
  "README.md",
19
22
  "dist"
20
23
  ],
21
- "scripts": {
22
- "build": "tsc -p tsconfig.json",
23
- "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json",
24
- "test": "vitest run",
25
- "clean": "rm -rf dist .turbo *.tsbuildinfo coverage"
26
- },
27
24
  "dependencies": {
28
- "@braidhq/core": "workspace:*",
29
- "@braidhq/schema": "workspace:*",
30
- "@braidhq/sdk": "workspace:*",
31
- "zod": "^3.24.0"
25
+ "zod": "^4.2.1",
26
+ "@braidhq/core": "0.2.1",
27
+ "@braidhq/schema": "0.2.1",
28
+ "@braidhq/sdk": "0.2.1"
32
29
  },
33
30
  "devDependencies": {
34
- "@braidhq/test-utils": "workspace:*",
35
31
  "typescript": "^6.0.3",
36
- "vitest": "^4.1.0"
32
+ "vitest": "^4.1.10",
33
+ "@braidhq/test-utils": "0.2.1"
37
34
  },
38
35
  "publishConfig": {
39
- "access": "public",
40
- "main": "./dist/index.js",
41
- "types": "./dist/index.d.ts",
42
- "exports": {
43
- ".": {
44
- "types": "./dist/index.d.ts",
45
- "default": "./dist/index.js"
46
- }
47
- }
36
+ "access": "public"
37
+ },
38
+ "scripts": {
39
+ "build": "tsc -p tsconfig.json",
40
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json",
41
+ "test": "vitest run --coverage",
42
+ "clean": "rm -rf dist .turbo *.tsbuildinfo coverage"
48
43
  }
49
- }
44
+ }
@@ -1,78 +0,0 @@
1
- import type { SourceLoaderContext, SourceLoaderPlugin } from '@braidhq/core';
2
- import { z } from 'zod';
3
- import { type DriveFileMetadata, type FetchFn } from './driveClient.js';
4
- export declare const GoogleDriveLoaderConfig: z.ZodObject<{
5
- /**
6
- * Drive folder id (the long alphanumeric in the URL). Reject the alias
7
- * `root` outright: it expands to the user's entire My Drive and would
8
- * mirror every file they own, which is almost never what someone wants
9
- * from an "intent docs" source and easily costs gigabytes + minutes.
10
- * Make people pick a specific subfolder.
11
- */
12
- folderId: z.ZodEffects<z.ZodString, string, string>;
13
- /**
14
- * Whether to traverse subfolders. Default true. Subfolder hierarchy
15
- * is NOT preserved on disk; every matching doc lives in its own dir
16
- * directly under `destination/`. Disable to limit to immediate
17
- * children of `folderId`.
18
- */
19
- recursive: z.ZodDefault<z.ZodBoolean>;
20
- /**
21
- * Optional regex (string). When set, only docs whose *Drive title*
22
- * matches this pattern are downloaded. Subfolders are still traversed.
23
- */
24
- include: z.ZodOptional<z.ZodString>;
25
- /**
26
- * Optional regex (string). When set, docs whose title matches are
27
- * skipped. Evaluated after `include`, so exclude takes priority.
28
- */
29
- exclude: z.ZodOptional<z.ZodString>;
30
- }, "strip", z.ZodTypeAny, {
31
- folderId: string;
32
- recursive: boolean;
33
- exclude?: string | undefined;
34
- include?: string | undefined;
35
- }, {
36
- folderId: string;
37
- exclude?: string | undefined;
38
- recursive?: boolean | undefined;
39
- include?: string | undefined;
40
- }>;
41
- export type GoogleDriveLoaderConfig = z.infer<typeof GoogleDriveLoaderConfig>;
42
- export interface GoogleDriveLoaderDeps {
43
- /**
44
- * Resolve a fresh access token for a given `(workspaceId, sourceId)`.
45
- * The composition root implements this against its OAuth refresh-token
46
- * store; tests can return a static token regardless of context.
47
- */
48
- resolveAccessToken: (context: SourceLoaderContext) => Promise<string>;
49
- /** Inject for tests. Real callers use globalThis.fetch. */
50
- fetchFn?: FetchFn;
51
- }
52
- /**
53
- * Build a Google Drive source loader. Walks a Drive folder, exports every
54
- * Google Doc inside as markdown, extracts inlined base64 images into
55
- * sibling files, and lays everything out as:
56
- *
57
- * <destination>/
58
- * <sanitised-doc-title>/
59
- * index.md
60
- * <image-label>.png (one per inlined image)
61
- * <sanitised-doc-title-2>/
62
- * index.md
63
- * .braid-manifest.json (sync state)
64
- *
65
- * Drive folder hierarchy is NOT preserved on disk; every matched doc
66
- * is flattened into a sibling directory under `destination/`. Two docs
67
- * with the same sanitised title will collide; rename one in Drive to
68
- * disambiguate.
69
- *
70
- * Out of scope (intentional): Google Sheets, Slides, Drawings, Forms,
71
- * and standalone binaries. Mirrors redoc's PRD-focused workflow. If you
72
- * need spreadsheets / slide decks, ingest them through a different
73
- * source-loader plugin.
74
- */
75
- export declare function createGoogleDriveLoader(deps: GoogleDriveLoaderDeps): SourceLoaderPlugin;
76
- /** Note: the helper used by DriveClient.exportDoc returns Buffer. */
77
- export type { DriveFileMetadata, FetchFn };
78
- //# sourceMappingURL=GoogleDriveLoader.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"GoogleDriveLoader.d.ts","sourceRoot":"","sources":["../src/GoogleDriveLoader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAK5E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAe,KAAK,iBAAiB,EAAE,KAAK,OAAO,EAAE,MAAM,kBAAkB,CAAA;AA2BpF,eAAO,MAAM,uBAAuB;IAClC;;;;;;OAMG;;IAMH;;;;;OAKG;;IAEH;;;OAGG;;IAEH;;;OAGG;;;;;;;;;;;;EAEH,CAAA;AACF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAE7E,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,kBAAkB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IACrE,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAaD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,GAAG,kBAAkB,CAgHvF;AA8GD,qEAAqE;AACrE,YAAY,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"GoogleDriveLoader.js","sourceRoot":"","sources":["../src/GoogleDriveLoader.ts"],"names":[],"mappings":"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"}