runline 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugins/_shared/googleSchemas.js +23 -0
- package/dist/plugins/gmail/src/index.js +168 -184
- package/dist/plugins/googleAppsScript/src/index.js +88 -43
- package/dist/plugins/googleCalendar/src/index.js +307 -250
- package/dist/plugins/googleContacts/src/index.js +134 -145
- package/dist/plugins/googleDocs/src/documents.js +27 -38
- package/dist/plugins/googleDocs/src/formatting.js +49 -47
- package/dist/plugins/googleDocs/src/images.js +21 -26
- package/dist/plugins/googleDocs/src/shared.js +55 -0
- package/dist/plugins/googleDocs/src/structure.js +98 -123
- package/dist/plugins/googleDocs/src/tables.js +92 -154
- package/dist/plugins/googleDocs/src/tabs.js +24 -23
- package/dist/plugins/googleDocs/src/text.js +97 -136
- package/dist/plugins/googleDrive/src/index.js +414 -408
- package/dist/plugins/googleImage/src/index.js +13 -16
- package/dist/plugins/googleSheets/src/index.js +504 -339
- package/dist/plugins/googleSlides/src/index.js +85 -72
- package/dist/plugins/googleTasks/src/index.js +82 -92
- package/dist/plugins/shiftLabs/src/index.js +6 -0
- package/dist/plugins/shiftLabs/src/shared.js +2 -0
- package/dist/plugins/shiftLabs/src/transcription.js +203 -0
- package/package.json +1 -1
|
@@ -54,7 +54,37 @@
|
|
|
54
54
|
* (Buffer) vs a path (streamed).
|
|
55
55
|
*/
|
|
56
56
|
import { createReadStream, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
57
|
+
import * as t from "typebox";
|
|
57
58
|
import { googleAccessToken } from "../../_shared/googleAuth.js";
|
|
59
|
+
import { Id, NonEmptyString, RawGoogleObject, StringMap, StringOrStringArray, stringEnum, } from "../../_shared/googleSchemas.js";
|
|
60
|
+
const PermissionRole = stringEnum([
|
|
61
|
+
"owner",
|
|
62
|
+
"organizer",
|
|
63
|
+
"fileOrganizer",
|
|
64
|
+
"writer",
|
|
65
|
+
"commenter",
|
|
66
|
+
"reader",
|
|
67
|
+
]);
|
|
68
|
+
const PermissionType = stringEnum([
|
|
69
|
+
"user",
|
|
70
|
+
"group",
|
|
71
|
+
"domain",
|
|
72
|
+
"anyone",
|
|
73
|
+
]);
|
|
74
|
+
const AccessProposalRole = stringEnum([
|
|
75
|
+
"writer",
|
|
76
|
+
"commenter",
|
|
77
|
+
"reader",
|
|
78
|
+
]);
|
|
79
|
+
const PageSize100 = t.Integer({ minimum: 1, maximum: 100 });
|
|
80
|
+
const PageSize1000 = t.Integer({ minimum: 1, maximum: 1000 });
|
|
81
|
+
const Rfc3339Timestamp = t.String({
|
|
82
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$",
|
|
83
|
+
});
|
|
84
|
+
const QuotedFileContent = t.Object({
|
|
85
|
+
value: NonEmptyString,
|
|
86
|
+
mimeType: t.Optional(NonEmptyString),
|
|
87
|
+
}, { additionalProperties: false });
|
|
58
88
|
// ─── MIME constants ──────────────────────────────────────────────
|
|
59
89
|
const DRIVE = {
|
|
60
90
|
FOLDER: "application/vnd.google-apps.folder",
|
|
@@ -437,33 +467,28 @@ export default function googleDrive(rl) {
|
|
|
437
467
|
rl.registerAction("file.upload", {
|
|
438
468
|
access: "write",
|
|
439
469
|
description: "Upload a file to Drive. Supply one of contentBase64 / contentPath / content. Uses multipart for small files, resumable (2 MiB chunks) for large streamed paths.",
|
|
440
|
-
inputSchema: {
|
|
441
|
-
name:
|
|
442
|
-
folderId:
|
|
443
|
-
driveId:
|
|
444
|
-
mimeType:
|
|
445
|
-
contentBase64:
|
|
446
|
-
contentPath:
|
|
447
|
-
content:
|
|
448
|
-
properties:
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
type: "string",
|
|
463
|
-
required: false,
|
|
464
|
-
description: "Fields projection (default: '*' returns everything)",
|
|
465
|
-
},
|
|
466
|
-
},
|
|
470
|
+
inputSchema: t.Object({
|
|
471
|
+
name: t.Optional(NonEmptyString),
|
|
472
|
+
folderId: t.Optional(Id),
|
|
473
|
+
driveId: t.Optional(Id),
|
|
474
|
+
mimeType: t.Optional(NonEmptyString),
|
|
475
|
+
contentBase64: t.Optional(t.String()),
|
|
476
|
+
contentPath: t.Optional(NonEmptyString),
|
|
477
|
+
content: t.Optional(t.String()),
|
|
478
|
+
properties: t.Optional(StringMap),
|
|
479
|
+
appProperties: t.Optional(StringMap),
|
|
480
|
+
keepRevisionForever: t.Optional(t.Boolean()),
|
|
481
|
+
ocrLanguage: t.Optional(NonEmptyString),
|
|
482
|
+
useContentAsIndexableText: t.Optional(t.Boolean()),
|
|
483
|
+
fields: t.Optional(NonEmptyString),
|
|
484
|
+
}, {
|
|
485
|
+
additionalProperties: false,
|
|
486
|
+
oneOf: [
|
|
487
|
+
{ required: ["contentBase64"] },
|
|
488
|
+
{ required: ["contentPath"] },
|
|
489
|
+
{ required: ["content"] },
|
|
490
|
+
],
|
|
491
|
+
}),
|
|
467
492
|
async execute(input, ctx) {
|
|
468
493
|
const p = (input ?? {});
|
|
469
494
|
const content = resolveContent(p);
|
|
@@ -499,15 +524,15 @@ export default function googleDrive(rl) {
|
|
|
499
524
|
rl.registerAction("file.createFromText", {
|
|
500
525
|
access: "write",
|
|
501
526
|
description: "Create a text file from inline content. Set convertToGoogleDocument=true to convert to a Google Doc.",
|
|
502
|
-
inputSchema: {
|
|
503
|
-
name:
|
|
504
|
-
content:
|
|
505
|
-
folderId:
|
|
506
|
-
driveId:
|
|
507
|
-
convertToGoogleDocument:
|
|
508
|
-
properties:
|
|
509
|
-
appProperties:
|
|
510
|
-
},
|
|
527
|
+
inputSchema: t.Object({
|
|
528
|
+
name: t.Optional(NonEmptyString),
|
|
529
|
+
content: t.String(),
|
|
530
|
+
folderId: t.Optional(Id),
|
|
531
|
+
driveId: t.Optional(Id),
|
|
532
|
+
convertToGoogleDocument: t.Optional(t.Boolean()),
|
|
533
|
+
properties: t.Optional(StringMap),
|
|
534
|
+
appProperties: t.Optional(StringMap),
|
|
535
|
+
}, { additionalProperties: false }),
|
|
511
536
|
async execute(input, ctx) {
|
|
512
537
|
const p = (input ?? {});
|
|
513
538
|
const name = p.name || "Untitled";
|
|
@@ -573,19 +598,11 @@ export default function googleDrive(rl) {
|
|
|
573
598
|
rl.registerAction("file.download", {
|
|
574
599
|
access: "write",
|
|
575
600
|
description: "Download a file. Google-native docs are exported to the chosen format; regular files are downloaded as-is. Returns base64 by default, or writes to disk when savePath is set.",
|
|
576
|
-
inputSchema: {
|
|
577
|
-
fileId:
|
|
578
|
-
savePath:
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
description: "Write bytes to this filesystem path instead of returning base64",
|
|
582
|
-
},
|
|
583
|
-
googleDocFormat: {
|
|
584
|
-
type: "string",
|
|
585
|
-
required: false,
|
|
586
|
-
description: "Export MIME type for Google Docs (default: DOCX / PPTX / XLSX / image/jpeg by type)",
|
|
587
|
-
},
|
|
588
|
-
},
|
|
601
|
+
inputSchema: t.Object({
|
|
602
|
+
fileId: Id,
|
|
603
|
+
savePath: t.Optional(NonEmptyString),
|
|
604
|
+
googleDocFormat: t.Optional(NonEmptyString),
|
|
605
|
+
}, { additionalProperties: false }),
|
|
589
606
|
async execute(input, ctx) {
|
|
590
607
|
const p = (input ?? {});
|
|
591
608
|
const fileId = p.fileId;
|
|
@@ -638,18 +655,14 @@ export default function googleDrive(rl) {
|
|
|
638
655
|
rl.registerAction("file.copy", {
|
|
639
656
|
access: "write",
|
|
640
657
|
description: "Copy a file",
|
|
641
|
-
inputSchema: {
|
|
642
|
-
fileId:
|
|
643
|
-
name:
|
|
644
|
-
folderId:
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
driveId: { type: "string", required: false },
|
|
650
|
-
description: { type: "string", required: false },
|
|
651
|
-
copyRequiresWriterPermission: { type: "boolean", required: false },
|
|
652
|
-
},
|
|
658
|
+
inputSchema: t.Object({
|
|
659
|
+
fileId: Id,
|
|
660
|
+
name: t.Optional(NonEmptyString),
|
|
661
|
+
folderId: t.Optional(Id),
|
|
662
|
+
driveId: t.Optional(Id),
|
|
663
|
+
description: t.Optional(t.String()),
|
|
664
|
+
copyRequiresWriterPermission: t.Optional(t.Boolean()),
|
|
665
|
+
}, { additionalProperties: false }),
|
|
653
666
|
async execute(input, ctx) {
|
|
654
667
|
const p = (input ?? {});
|
|
655
668
|
const body = {};
|
|
@@ -669,11 +682,11 @@ export default function googleDrive(rl) {
|
|
|
669
682
|
rl.registerAction("file.move", {
|
|
670
683
|
access: "write",
|
|
671
684
|
description: "Move a file to another folder. Resolves current parents and swaps them in a single PATCH.",
|
|
672
|
-
inputSchema: {
|
|
673
|
-
fileId:
|
|
674
|
-
folderId:
|
|
675
|
-
driveId:
|
|
676
|
-
},
|
|
685
|
+
inputSchema: t.Object({
|
|
686
|
+
fileId: Id,
|
|
687
|
+
folderId: t.Optional(Id),
|
|
688
|
+
driveId: t.Optional(Id),
|
|
689
|
+
}, { additionalProperties: false }),
|
|
677
690
|
async execute(input, ctx) {
|
|
678
691
|
const p = (input ?? {});
|
|
679
692
|
const current = (await driveRequest(ctx, "GET", `/drive/v3/files/${p.fileId}`, undefined, { fields: "parents", supportsAllDrives: true }));
|
|
@@ -689,20 +702,49 @@ export default function googleDrive(rl) {
|
|
|
689
702
|
rl.registerAction("file.update", {
|
|
690
703
|
access: "write",
|
|
691
704
|
description: "Patch file metadata and/or replace its bytes. Supply content{Base64,Path} to update bytes.",
|
|
692
|
-
inputSchema: {
|
|
693
|
-
fileId:
|
|
694
|
-
name:
|
|
695
|
-
mimeType:
|
|
696
|
-
trashed:
|
|
697
|
-
properties:
|
|
698
|
-
appProperties:
|
|
699
|
-
contentBase64:
|
|
700
|
-
contentPath:
|
|
701
|
-
keepRevisionForever:
|
|
702
|
-
ocrLanguage:
|
|
703
|
-
useContentAsIndexableText:
|
|
704
|
-
fields:
|
|
705
|
-
},
|
|
705
|
+
inputSchema: t.Object({
|
|
706
|
+
fileId: Id,
|
|
707
|
+
name: t.Optional(NonEmptyString),
|
|
708
|
+
mimeType: t.Optional(NonEmptyString),
|
|
709
|
+
trashed: t.Optional(t.Boolean()),
|
|
710
|
+
properties: t.Optional(StringMap),
|
|
711
|
+
appProperties: t.Optional(StringMap),
|
|
712
|
+
contentBase64: t.Optional(t.String()),
|
|
713
|
+
contentPath: t.Optional(NonEmptyString),
|
|
714
|
+
keepRevisionForever: t.Optional(t.Boolean()),
|
|
715
|
+
ocrLanguage: t.Optional(NonEmptyString),
|
|
716
|
+
useContentAsIndexableText: t.Optional(t.Boolean()),
|
|
717
|
+
fields: t.Optional(NonEmptyString),
|
|
718
|
+
}, {
|
|
719
|
+
additionalProperties: false,
|
|
720
|
+
allOf: [
|
|
721
|
+
{ not: { required: ["contentBase64", "contentPath"] } },
|
|
722
|
+
...[
|
|
723
|
+
"keepRevisionForever",
|
|
724
|
+
"ocrLanguage",
|
|
725
|
+
"useContentAsIndexableText",
|
|
726
|
+
].map((field) => ({
|
|
727
|
+
anyOf: [
|
|
728
|
+
{ not: { required: [field] } },
|
|
729
|
+
{
|
|
730
|
+
anyOf: [
|
|
731
|
+
{ required: ["contentBase64"] },
|
|
732
|
+
{ required: ["contentPath"] },
|
|
733
|
+
],
|
|
734
|
+
},
|
|
735
|
+
],
|
|
736
|
+
})),
|
|
737
|
+
],
|
|
738
|
+
anyOf: [
|
|
739
|
+
{ required: ["name"] },
|
|
740
|
+
{ required: ["mimeType"] },
|
|
741
|
+
{ required: ["trashed"] },
|
|
742
|
+
{ required: ["properties"] },
|
|
743
|
+
{ required: ["appProperties"] },
|
|
744
|
+
{ required: ["contentBase64"] },
|
|
745
|
+
{ required: ["contentPath"] },
|
|
746
|
+
],
|
|
747
|
+
}),
|
|
706
748
|
async execute(input, ctx) {
|
|
707
749
|
const p = (input ?? {});
|
|
708
750
|
const fileId = p.fileId;
|
|
@@ -717,6 +759,15 @@ export default function googleDrive(rl) {
|
|
|
717
759
|
const url = new URL(`${API_BASE}/upload/drive/v3/files/${fileId}`);
|
|
718
760
|
url.searchParams.set("uploadType", "media");
|
|
719
761
|
url.searchParams.set("supportsAllDrives", "true");
|
|
762
|
+
for (const key of [
|
|
763
|
+
"keepRevisionForever",
|
|
764
|
+
"ocrLanguage",
|
|
765
|
+
"useContentAsIndexableText",
|
|
766
|
+
]) {
|
|
767
|
+
if (p[key] !== undefined) {
|
|
768
|
+
url.searchParams.set(key, String(p[key]));
|
|
769
|
+
}
|
|
770
|
+
}
|
|
720
771
|
const res = await fetch(url.toString(), {
|
|
721
772
|
method: "PATCH",
|
|
722
773
|
headers: {
|
|
@@ -735,6 +786,15 @@ export default function googleDrive(rl) {
|
|
|
735
786
|
const initUrl = new URL(`${API_BASE}/upload/drive/v3/files/${fileId}`);
|
|
736
787
|
initUrl.searchParams.set("uploadType", "resumable");
|
|
737
788
|
initUrl.searchParams.set("supportsAllDrives", "true");
|
|
789
|
+
for (const key of [
|
|
790
|
+
"keepRevisionForever",
|
|
791
|
+
"ocrLanguage",
|
|
792
|
+
"useContentAsIndexableText",
|
|
793
|
+
]) {
|
|
794
|
+
if (p[key] !== undefined) {
|
|
795
|
+
initUrl.searchParams.set(key, String(p[key]));
|
|
796
|
+
}
|
|
797
|
+
}
|
|
738
798
|
const initRes = await fetch(initUrl.toString(), {
|
|
739
799
|
method: "PATCH",
|
|
740
800
|
headers: {
|
|
@@ -785,34 +845,28 @@ export default function googleDrive(rl) {
|
|
|
785
845
|
body.name = p.name;
|
|
786
846
|
if (p.mimeType !== undefined)
|
|
787
847
|
body.mimeType = p.mimeType;
|
|
848
|
+
if (p.trashed !== undefined)
|
|
849
|
+
body.trashed = p.trashed;
|
|
788
850
|
if (p.properties !== undefined)
|
|
789
851
|
body.properties = p.properties;
|
|
790
852
|
if (p.appProperties !== undefined)
|
|
791
853
|
body.appProperties = p.appProperties;
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
qs.keepRevisionForever = p.keepRevisionForever;
|
|
797
|
-
if (p.ocrLanguage)
|
|
798
|
-
qs.ocrLanguage = p.ocrLanguage;
|
|
799
|
-
if (p.useContentAsIndexableText)
|
|
800
|
-
qs.useContentAsIndexableText = p.useContentAsIndexableText;
|
|
801
|
-
if (p.fields)
|
|
802
|
-
qs.fields = p.fields;
|
|
803
|
-
if (Object.keys(body).length === 0 && !p.trashed && !p.fields) {
|
|
854
|
+
if (Object.keys(body).length === 0) {
|
|
855
|
+
if (hasBytes && p.fields) {
|
|
856
|
+
return driveRequest(ctx, "GET", `/drive/v3/files/${fileId}`, undefined, { supportsAllDrives: true, fields: p.fields });
|
|
857
|
+
}
|
|
804
858
|
return { id: fileId, success: true };
|
|
805
859
|
}
|
|
806
|
-
return driveRequest(ctx, "PATCH", `/drive/v3/files/${fileId}`, body,
|
|
860
|
+
return driveRequest(ctx, "PATCH", `/drive/v3/files/${fileId}`, body, {
|
|
861
|
+
supportsAllDrives: true,
|
|
862
|
+
fields: p.fields,
|
|
863
|
+
});
|
|
807
864
|
},
|
|
808
865
|
});
|
|
809
866
|
rl.registerAction("file.delete", {
|
|
810
867
|
access: "write",
|
|
811
868
|
description: "Delete a file. Moves to trash by default; pass deletePermanently=true to erase.",
|
|
812
|
-
inputSchema: {
|
|
813
|
-
fileId: { type: "string", required: true },
|
|
814
|
-
deletePermanently: { type: "boolean", required: false },
|
|
815
|
-
},
|
|
869
|
+
inputSchema: t.Object({ fileId: Id, deletePermanently: t.Optional(t.Boolean()) }, { additionalProperties: false }),
|
|
816
870
|
async execute(input, ctx) {
|
|
817
871
|
const p = (input ?? {});
|
|
818
872
|
if (p.deletePermanently) {
|
|
@@ -829,10 +883,7 @@ export default function googleDrive(rl) {
|
|
|
829
883
|
rl.registerAction("file.get", {
|
|
830
884
|
access: "read",
|
|
831
885
|
description: "Get file metadata",
|
|
832
|
-
inputSchema: {
|
|
833
|
-
fileId: { type: "string", required: true },
|
|
834
|
-
fields: { type: "string", required: false, description: "Default: '*'" },
|
|
835
|
-
},
|
|
886
|
+
inputSchema: t.Object({ fileId: Id, fields: t.Optional(NonEmptyString) }, { additionalProperties: false }),
|
|
836
887
|
async execute(input, ctx) {
|
|
837
888
|
const p = (input ?? {});
|
|
838
889
|
return driveRequest(ctx, "GET", `/drive/v3/files/${p.fileId}`, undefined, { supportsAllDrives: true, fields: p.fields ?? "*" });
|
|
@@ -841,27 +892,44 @@ export default function googleDrive(rl) {
|
|
|
841
892
|
rl.registerAction("file.share", {
|
|
842
893
|
access: "write",
|
|
843
894
|
description: "Add a permission to a file. Create one permission per call; list the existing permissions via file.listPermissions.",
|
|
844
|
-
inputSchema: {
|
|
845
|
-
fileId:
|
|
846
|
-
role:
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
895
|
+
inputSchema: t.Object({
|
|
896
|
+
fileId: Id,
|
|
897
|
+
role: PermissionRole,
|
|
898
|
+
type: PermissionType,
|
|
899
|
+
emailAddress: t.Optional(NonEmptyString),
|
|
900
|
+
domain: t.Optional(NonEmptyString),
|
|
901
|
+
allowFileDiscovery: t.Optional(t.Boolean()),
|
|
902
|
+
emailMessage: t.Optional(t.String()),
|
|
903
|
+
sendNotificationEmail: t.Optional(t.Boolean()),
|
|
904
|
+
transferOwnership: t.Optional(t.Boolean()),
|
|
905
|
+
moveToNewOwnersRoot: t.Optional(t.Boolean()),
|
|
906
|
+
useDomainAdminAccess: t.Optional(t.Boolean()),
|
|
907
|
+
}, {
|
|
908
|
+
additionalProperties: false,
|
|
909
|
+
oneOf: [
|
|
910
|
+
{
|
|
911
|
+
properties: { type: { const: "user" } },
|
|
912
|
+
required: ["emailAddress"],
|
|
913
|
+
not: { required: ["domain"] },
|
|
914
|
+
},
|
|
915
|
+
{
|
|
916
|
+
properties: { type: { const: "group" } },
|
|
917
|
+
required: ["emailAddress"],
|
|
918
|
+
not: { required: ["domain"] },
|
|
919
|
+
},
|
|
920
|
+
{
|
|
921
|
+
properties: { type: { const: "domain" } },
|
|
922
|
+
required: ["domain"],
|
|
923
|
+
not: { required: ["emailAddress"] },
|
|
924
|
+
},
|
|
925
|
+
{
|
|
926
|
+
properties: { type: { const: "anyone" } },
|
|
927
|
+
not: {
|
|
928
|
+
anyOf: [{ required: ["emailAddress"] }, { required: ["domain"] }],
|
|
929
|
+
},
|
|
930
|
+
},
|
|
931
|
+
],
|
|
932
|
+
}),
|
|
865
933
|
async execute(input, ctx) {
|
|
866
934
|
const p = (input ?? {});
|
|
867
935
|
const body = {
|
|
@@ -891,10 +959,7 @@ export default function googleDrive(rl) {
|
|
|
891
959
|
rl.registerAction("file.listPermissions", {
|
|
892
960
|
access: "read",
|
|
893
961
|
description: "List permissions on a file",
|
|
894
|
-
inputSchema: {
|
|
895
|
-
fileId: { type: "string", required: true },
|
|
896
|
-
useDomainAdminAccess: { type: "boolean", required: false },
|
|
897
|
-
},
|
|
962
|
+
inputSchema: t.Object({ fileId: Id, useDomainAdminAccess: t.Optional(t.Boolean()) }, { additionalProperties: false }),
|
|
898
963
|
async execute(input, ctx) {
|
|
899
964
|
const p = (input ?? {});
|
|
900
965
|
return driveRequest(ctx, "GET", `/drive/v3/files/${p.fileId}/permissions`, undefined, {
|
|
@@ -907,10 +972,7 @@ export default function googleDrive(rl) {
|
|
|
907
972
|
rl.registerAction("file.deletePermission", {
|
|
908
973
|
access: "write",
|
|
909
974
|
description: "Revoke a permission on a file",
|
|
910
|
-
inputSchema: {
|
|
911
|
-
fileId: { type: "string", required: true },
|
|
912
|
-
permissionId: { type: "string", required: true },
|
|
913
|
-
},
|
|
975
|
+
inputSchema: t.Object({ fileId: Id, permissionId: Id }, { additionalProperties: false }),
|
|
914
976
|
async execute(input, ctx) {
|
|
915
977
|
const p = (input ?? {});
|
|
916
978
|
await driveRequest(ctx, "DELETE", `/drive/v3/files/${p.fileId}/permissions/${p.permissionId}`, undefined, { supportsAllDrives: true });
|
|
@@ -921,13 +983,13 @@ export default function googleDrive(rl) {
|
|
|
921
983
|
rl.registerAction("folder.create", {
|
|
922
984
|
access: "write",
|
|
923
985
|
description: "Create a folder",
|
|
924
|
-
inputSchema: {
|
|
925
|
-
name:
|
|
926
|
-
folderId:
|
|
927
|
-
driveId:
|
|
928
|
-
folderColorRgb: {
|
|
929
|
-
fields:
|
|
930
|
-
},
|
|
986
|
+
inputSchema: t.Object({
|
|
987
|
+
name: t.Optional(NonEmptyString),
|
|
988
|
+
folderId: t.Optional(Id),
|
|
989
|
+
driveId: t.Optional(Id),
|
|
990
|
+
folderColorRgb: t.Optional(t.String({ pattern: "^#?[0-9A-Fa-f]{6}$" })),
|
|
991
|
+
fields: t.Optional(NonEmptyString),
|
|
992
|
+
}, { additionalProperties: false }),
|
|
931
993
|
async execute(input, ctx) {
|
|
932
994
|
const p = (input ?? {});
|
|
933
995
|
const body = {
|
|
@@ -947,10 +1009,7 @@ export default function googleDrive(rl) {
|
|
|
947
1009
|
rl.registerAction("folder.delete", {
|
|
948
1010
|
access: "write",
|
|
949
1011
|
description: "Delete a folder. Moves to trash by default; pass deletePermanently=true to erase.",
|
|
950
|
-
inputSchema: {
|
|
951
|
-
folderId: { type: "string", required: true },
|
|
952
|
-
deletePermanently: { type: "boolean", required: false },
|
|
953
|
-
},
|
|
1012
|
+
inputSchema: t.Object({ folderId: Id, deletePermanently: t.Optional(t.Boolean()) }, { additionalProperties: false }),
|
|
954
1013
|
async execute(input, ctx) {
|
|
955
1014
|
const p = (input ?? {});
|
|
956
1015
|
if (p.deletePermanently) {
|
|
@@ -967,19 +1026,44 @@ export default function googleDrive(rl) {
|
|
|
967
1026
|
rl.registerAction("folder.share", {
|
|
968
1027
|
access: "write",
|
|
969
1028
|
description: "Add a permission to a folder (same shape as file.share)",
|
|
970
|
-
inputSchema: {
|
|
971
|
-
folderId:
|
|
972
|
-
role:
|
|
973
|
-
type:
|
|
974
|
-
emailAddress:
|
|
975
|
-
domain:
|
|
976
|
-
allowFileDiscovery:
|
|
977
|
-
emailMessage:
|
|
978
|
-
sendNotificationEmail:
|
|
979
|
-
transferOwnership:
|
|
980
|
-
moveToNewOwnersRoot:
|
|
981
|
-
useDomainAdminAccess:
|
|
982
|
-
},
|
|
1029
|
+
inputSchema: t.Object({
|
|
1030
|
+
folderId: Id,
|
|
1031
|
+
role: PermissionRole,
|
|
1032
|
+
type: PermissionType,
|
|
1033
|
+
emailAddress: t.Optional(NonEmptyString),
|
|
1034
|
+
domain: t.Optional(NonEmptyString),
|
|
1035
|
+
allowFileDiscovery: t.Optional(t.Boolean()),
|
|
1036
|
+
emailMessage: t.Optional(t.String()),
|
|
1037
|
+
sendNotificationEmail: t.Optional(t.Boolean()),
|
|
1038
|
+
transferOwnership: t.Optional(t.Boolean()),
|
|
1039
|
+
moveToNewOwnersRoot: t.Optional(t.Boolean()),
|
|
1040
|
+
useDomainAdminAccess: t.Optional(t.Boolean()),
|
|
1041
|
+
}, {
|
|
1042
|
+
additionalProperties: false,
|
|
1043
|
+
oneOf: [
|
|
1044
|
+
{
|
|
1045
|
+
properties: { type: { const: "user" } },
|
|
1046
|
+
required: ["emailAddress"],
|
|
1047
|
+
not: { required: ["domain"] },
|
|
1048
|
+
},
|
|
1049
|
+
{
|
|
1050
|
+
properties: { type: { const: "group" } },
|
|
1051
|
+
required: ["emailAddress"],
|
|
1052
|
+
not: { required: ["domain"] },
|
|
1053
|
+
},
|
|
1054
|
+
{
|
|
1055
|
+
properties: { type: { const: "domain" } },
|
|
1056
|
+
required: ["domain"],
|
|
1057
|
+
not: { required: ["emailAddress"] },
|
|
1058
|
+
},
|
|
1059
|
+
{
|
|
1060
|
+
properties: { type: { const: "anyone" } },
|
|
1061
|
+
not: {
|
|
1062
|
+
anyOf: [{ required: ["emailAddress"] }, { required: ["domain"] }],
|
|
1063
|
+
},
|
|
1064
|
+
},
|
|
1065
|
+
],
|
|
1066
|
+
}),
|
|
983
1067
|
async execute(input, ctx) {
|
|
984
1068
|
const p = (input ?? {});
|
|
985
1069
|
const body = { role: p.role, type: p.type };
|
|
@@ -1007,39 +1091,19 @@ export default function googleDrive(rl) {
|
|
|
1007
1091
|
rl.registerAction("fileFolder.search", {
|
|
1008
1092
|
access: "read",
|
|
1009
1093
|
description: "Search files and folders. `query` is passed directly; `name` wraps it as `name contains '…'`. Combine with folderId/driveId/whatToSearch/fileTypes filters.",
|
|
1010
|
-
inputSchema: {
|
|
1011
|
-
name:
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
whatToSearch: {
|
|
1024
|
-
type: "string",
|
|
1025
|
-
required: false,
|
|
1026
|
-
description: "all (default) | files | folders",
|
|
1027
|
-
},
|
|
1028
|
-
fileTypes: {
|
|
1029
|
-
type: "array",
|
|
1030
|
-
required: false,
|
|
1031
|
-
description: "MIME type filter (ignored when whatToSearch=folders)",
|
|
1032
|
-
},
|
|
1033
|
-
includeTrashed: { type: "boolean", required: false },
|
|
1034
|
-
fields: {
|
|
1035
|
-
type: "array",
|
|
1036
|
-
required: false,
|
|
1037
|
-
description: "Per-file fields to return (default: id,name)",
|
|
1038
|
-
},
|
|
1039
|
-
returnAll: { type: "boolean", required: false },
|
|
1040
|
-
maxResults: { type: "number", required: false },
|
|
1041
|
-
pageToken: { type: "string", required: false },
|
|
1042
|
-
},
|
|
1094
|
+
inputSchema: t.Object({
|
|
1095
|
+
name: t.Optional(t.String()),
|
|
1096
|
+
query: t.Optional(t.String()),
|
|
1097
|
+
folderId: t.Optional(Id),
|
|
1098
|
+
driveId: t.Optional(Id),
|
|
1099
|
+
whatToSearch: t.Optional(stringEnum(["all", "files", "folders"])),
|
|
1100
|
+
fileTypes: t.Optional(StringOrStringArray),
|
|
1101
|
+
includeTrashed: t.Optional(t.Boolean()),
|
|
1102
|
+
fields: t.Optional(StringOrStringArray),
|
|
1103
|
+
returnAll: t.Optional(t.Boolean()),
|
|
1104
|
+
maxResults: t.Optional(PageSize1000),
|
|
1105
|
+
pageToken: t.Optional(NonEmptyString),
|
|
1106
|
+
}, { additionalProperties: false }),
|
|
1043
1107
|
async execute(input, ctx) {
|
|
1044
1108
|
const p = (input ?? {});
|
|
1045
1109
|
const clauses = [];
|
|
@@ -1096,13 +1160,13 @@ export default function googleDrive(rl) {
|
|
|
1096
1160
|
rl.registerAction("drive.create", {
|
|
1097
1161
|
access: "write",
|
|
1098
1162
|
description: "Create a shared drive. requestId is generated automatically.",
|
|
1099
|
-
inputSchema: {
|
|
1100
|
-
name:
|
|
1101
|
-
colorRgb: {
|
|
1102
|
-
hidden:
|
|
1103
|
-
capabilities:
|
|
1104
|
-
restrictions:
|
|
1105
|
-
},
|
|
1163
|
+
inputSchema: t.Object({
|
|
1164
|
+
name: NonEmptyString,
|
|
1165
|
+
colorRgb: t.Optional(t.String({ pattern: "^#?[0-9A-Fa-f]{6}$" })),
|
|
1166
|
+
hidden: t.Optional(t.Boolean()),
|
|
1167
|
+
capabilities: t.Optional(RawGoogleObject),
|
|
1168
|
+
restrictions: t.Optional(RawGoogleObject),
|
|
1169
|
+
}, { additionalProperties: false }),
|
|
1106
1170
|
async execute(input, ctx) {
|
|
1107
1171
|
const p = (input ?? {});
|
|
1108
1172
|
const body = { name: p.name };
|
|
@@ -1116,10 +1180,7 @@ export default function googleDrive(rl) {
|
|
|
1116
1180
|
rl.registerAction("drive.get", {
|
|
1117
1181
|
access: "read",
|
|
1118
1182
|
description: "Get a shared drive",
|
|
1119
|
-
inputSchema: {
|
|
1120
|
-
driveId: { type: "string", required: true },
|
|
1121
|
-
useDomainAdminAccess: { type: "boolean", required: false },
|
|
1122
|
-
},
|
|
1183
|
+
inputSchema: t.Object({ driveId: Id, useDomainAdminAccess: t.Optional(t.Boolean()) }, { additionalProperties: false }),
|
|
1123
1184
|
async execute(input, ctx) {
|
|
1124
1185
|
const p = (input ?? {});
|
|
1125
1186
|
const qs = {};
|
|
@@ -1131,13 +1192,13 @@ export default function googleDrive(rl) {
|
|
|
1131
1192
|
rl.registerAction("drive.list", {
|
|
1132
1193
|
access: "read",
|
|
1133
1194
|
description: "List shared drives",
|
|
1134
|
-
inputSchema: {
|
|
1135
|
-
q:
|
|
1136
|
-
useDomainAdminAccess:
|
|
1137
|
-
returnAll:
|
|
1138
|
-
maxResults:
|
|
1139
|
-
pageToken:
|
|
1140
|
-
},
|
|
1195
|
+
inputSchema: t.Object({
|
|
1196
|
+
q: t.Optional(t.String()),
|
|
1197
|
+
useDomainAdminAccess: t.Optional(t.Boolean()),
|
|
1198
|
+
returnAll: t.Optional(t.Boolean()),
|
|
1199
|
+
maxResults: t.Optional(PageSize100),
|
|
1200
|
+
pageToken: t.Optional(NonEmptyString),
|
|
1201
|
+
}, { additionalProperties: false }),
|
|
1141
1202
|
async execute(input, ctx) {
|
|
1142
1203
|
const p = (input ?? {});
|
|
1143
1204
|
const qs = {};
|
|
@@ -1158,12 +1219,19 @@ export default function googleDrive(rl) {
|
|
|
1158
1219
|
rl.registerAction("drive.update", {
|
|
1159
1220
|
access: "write",
|
|
1160
1221
|
description: "Patch a shared drive",
|
|
1161
|
-
inputSchema: {
|
|
1162
|
-
driveId:
|
|
1163
|
-
name:
|
|
1164
|
-
colorRgb: {
|
|
1165
|
-
restrictions:
|
|
1166
|
-
},
|
|
1222
|
+
inputSchema: t.Object({
|
|
1223
|
+
driveId: Id,
|
|
1224
|
+
name: t.Optional(NonEmptyString),
|
|
1225
|
+
colorRgb: t.Optional(t.String({ pattern: "^#?[0-9A-Fa-f]{6}$" })),
|
|
1226
|
+
restrictions: t.Optional(RawGoogleObject),
|
|
1227
|
+
}, {
|
|
1228
|
+
additionalProperties: false,
|
|
1229
|
+
anyOf: [
|
|
1230
|
+
{ required: ["name"] },
|
|
1231
|
+
{ required: ["colorRgb"] },
|
|
1232
|
+
{ required: ["restrictions"] },
|
|
1233
|
+
],
|
|
1234
|
+
}),
|
|
1167
1235
|
async execute(input, ctx) {
|
|
1168
1236
|
const p = (input ?? {});
|
|
1169
1237
|
const body = {};
|
|
@@ -1177,7 +1245,7 @@ export default function googleDrive(rl) {
|
|
|
1177
1245
|
rl.registerAction("drive.delete", {
|
|
1178
1246
|
access: "write",
|
|
1179
1247
|
description: "Delete a shared drive",
|
|
1180
|
-
inputSchema: { driveId:
|
|
1248
|
+
inputSchema: t.Object({ driveId: Id }, { additionalProperties: false }),
|
|
1181
1249
|
async execute(input, ctx) {
|
|
1182
1250
|
const p = (input ?? {});
|
|
1183
1251
|
await driveRequest(ctx, "DELETE", `/drive/v3/drives/${p.driveId}`);
|
|
@@ -1202,24 +1270,12 @@ export default function googleDrive(rl) {
|
|
|
1202
1270
|
rl.registerAction("comment.list", {
|
|
1203
1271
|
access: "read",
|
|
1204
1272
|
description: "List all comments on a Drive file, including each comment's replies. Returns an array sorted by Drive's default (most recent first).",
|
|
1205
|
-
inputSchema: {
|
|
1206
|
-
fileId:
|
|
1207
|
-
includeDeleted:
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
},
|
|
1212
|
-
pageSize: {
|
|
1213
|
-
type: "number",
|
|
1214
|
-
required: false,
|
|
1215
|
-
description: "Max comments per page (Drive caps at 100).",
|
|
1216
|
-
},
|
|
1217
|
-
startModifiedTime: {
|
|
1218
|
-
type: "string",
|
|
1219
|
-
required: false,
|
|
1220
|
-
description: "RFC 3339 timestamp; only return comments modified at or after this time.",
|
|
1221
|
-
},
|
|
1222
|
-
},
|
|
1273
|
+
inputSchema: t.Object({
|
|
1274
|
+
fileId: Id,
|
|
1275
|
+
includeDeleted: t.Optional(t.Boolean()),
|
|
1276
|
+
pageSize: t.Optional(PageSize100),
|
|
1277
|
+
startModifiedTime: t.Optional(Rfc3339Timestamp),
|
|
1278
|
+
}, { additionalProperties: false }),
|
|
1223
1279
|
async execute(input, ctx) {
|
|
1224
1280
|
const p = (input ?? {});
|
|
1225
1281
|
const fileId = p.fileId;
|
|
@@ -1245,11 +1301,7 @@ export default function googleDrive(rl) {
|
|
|
1245
1301
|
rl.registerAction("comment.get", {
|
|
1246
1302
|
access: "read",
|
|
1247
1303
|
description: "Fetch a single comment (with its replies) by ID.",
|
|
1248
|
-
inputSchema: {
|
|
1249
|
-
fileId: { type: "string", required: true },
|
|
1250
|
-
commentId: { type: "string", required: true },
|
|
1251
|
-
includeDeleted: { type: "boolean", required: false },
|
|
1252
|
-
},
|
|
1304
|
+
inputSchema: t.Object({ fileId: Id, commentId: Id, includeDeleted: t.Optional(t.Boolean()) }, { additionalProperties: false }),
|
|
1253
1305
|
async execute(input, ctx) {
|
|
1254
1306
|
const p = (input ?? {});
|
|
1255
1307
|
return driveRequest(ctx, "GET", `/drive/v3/files/${p.fileId}/comments/${p.commentId}`, undefined, { fields: COMMENT_FIELDS, includeDeleted: p.includeDeleted ?? false });
|
|
@@ -1258,15 +1310,11 @@ export default function googleDrive(rl) {
|
|
|
1258
1310
|
rl.registerAction("comment.create", {
|
|
1259
1311
|
access: "write",
|
|
1260
1312
|
description: "Create a new top-level comment on a file. Pass quotedFileContent.value (and optionally mimeType) to anchor the comment to a specific snippet.",
|
|
1261
|
-
inputSchema: {
|
|
1262
|
-
fileId:
|
|
1263
|
-
content:
|
|
1264
|
-
quotedFileContent:
|
|
1265
|
-
|
|
1266
|
-
required: false,
|
|
1267
|
-
description: "{ value: string, mimeType?: string }",
|
|
1268
|
-
},
|
|
1269
|
-
},
|
|
1313
|
+
inputSchema: t.Object({
|
|
1314
|
+
fileId: Id,
|
|
1315
|
+
content: NonEmptyString,
|
|
1316
|
+
quotedFileContent: t.Optional(QuotedFileContent),
|
|
1317
|
+
}, { additionalProperties: false }),
|
|
1270
1318
|
async execute(input, ctx) {
|
|
1271
1319
|
const p = (input ?? {});
|
|
1272
1320
|
const body = { content: p.content };
|
|
@@ -1278,11 +1326,7 @@ export default function googleDrive(rl) {
|
|
|
1278
1326
|
rl.registerAction("comment.update", {
|
|
1279
1327
|
access: "write",
|
|
1280
1328
|
description: "Edit the content of an existing comment. Caller must be the author or have edit rights.",
|
|
1281
|
-
inputSchema: {
|
|
1282
|
-
fileId: { type: "string", required: true },
|
|
1283
|
-
commentId: { type: "string", required: true },
|
|
1284
|
-
content: { type: "string", required: true },
|
|
1285
|
-
},
|
|
1329
|
+
inputSchema: t.Object({ fileId: Id, commentId: Id, content: NonEmptyString }, { additionalProperties: false }),
|
|
1286
1330
|
async execute(input, ctx) {
|
|
1287
1331
|
const p = (input ?? {});
|
|
1288
1332
|
return driveRequest(ctx, "PATCH", `/drive/v3/files/${p.fileId}/comments/${p.commentId}`, { content: p.content }, { fields: COMMENT_FIELDS });
|
|
@@ -1291,10 +1335,7 @@ export default function googleDrive(rl) {
|
|
|
1291
1335
|
rl.registerAction("comment.delete", {
|
|
1292
1336
|
access: "write",
|
|
1293
1337
|
description: "Soft-delete a comment.",
|
|
1294
|
-
inputSchema: {
|
|
1295
|
-
fileId: { type: "string", required: true },
|
|
1296
|
-
commentId: { type: "string", required: true },
|
|
1297
|
-
},
|
|
1338
|
+
inputSchema: t.Object({ fileId: Id, commentId: Id }, { additionalProperties: false }),
|
|
1298
1339
|
async execute(input, ctx) {
|
|
1299
1340
|
const p = (input ?? {});
|
|
1300
1341
|
await driveRequest(ctx, "DELETE", `/drive/v3/files/${p.fileId}/comments/${p.commentId}`);
|
|
@@ -1304,15 +1345,7 @@ export default function googleDrive(rl) {
|
|
|
1304
1345
|
rl.registerAction("comment.resolve", {
|
|
1305
1346
|
access: "write",
|
|
1306
1347
|
description: "Resolve a comment thread by posting a resolution reply. `resolved` on a Comment is computed from replies; this is the canonical way to mark a thread done.",
|
|
1307
|
-
inputSchema: {
|
|
1308
|
-
fileId: { type: "string", required: true },
|
|
1309
|
-
commentId: { type: "string", required: true },
|
|
1310
|
-
content: {
|
|
1311
|
-
type: "string",
|
|
1312
|
-
required: false,
|
|
1313
|
-
description: "Optional reply body. Defaults to 'Resolved.'",
|
|
1314
|
-
},
|
|
1315
|
-
},
|
|
1348
|
+
inputSchema: t.Object({ fileId: Id, commentId: Id, content: t.Optional(NonEmptyString) }, { additionalProperties: false }),
|
|
1316
1349
|
async execute(input, ctx) {
|
|
1317
1350
|
const p = (input ?? {});
|
|
1318
1351
|
return driveRequest(ctx, "POST", `/drive/v3/files/${p.fileId}/comments/${p.commentId}/replies`, { action: "resolve", content: p.content ?? "Resolved." }, { fields: REPLY_FIELDS });
|
|
@@ -1321,11 +1354,7 @@ export default function googleDrive(rl) {
|
|
|
1321
1354
|
rl.registerAction("comment.reopen", {
|
|
1322
1355
|
access: "write",
|
|
1323
1356
|
description: "Re-open a previously resolved comment by posting a reopen reply.",
|
|
1324
|
-
inputSchema: {
|
|
1325
|
-
fileId: { type: "string", required: true },
|
|
1326
|
-
commentId: { type: "string", required: true },
|
|
1327
|
-
content: { type: "string", required: false },
|
|
1328
|
-
},
|
|
1357
|
+
inputSchema: t.Object({ fileId: Id, commentId: Id, content: t.Optional(NonEmptyString) }, { additionalProperties: false }),
|
|
1329
1358
|
async execute(input, ctx) {
|
|
1330
1359
|
const p = (input ?? {});
|
|
1331
1360
|
return driveRequest(ctx, "POST", `/drive/v3/files/${p.fileId}/comments/${p.commentId}/replies`, { action: "reopen", content: p.content ?? "Reopened." }, { fields: REPLY_FIELDS });
|
|
@@ -1334,12 +1363,12 @@ export default function googleDrive(rl) {
|
|
|
1334
1363
|
rl.registerAction("reply.list", {
|
|
1335
1364
|
access: "read",
|
|
1336
1365
|
description: "List replies on a specific comment.",
|
|
1337
|
-
inputSchema: {
|
|
1338
|
-
fileId:
|
|
1339
|
-
commentId:
|
|
1340
|
-
includeDeleted:
|
|
1341
|
-
pageSize:
|
|
1342
|
-
},
|
|
1366
|
+
inputSchema: t.Object({
|
|
1367
|
+
fileId: Id,
|
|
1368
|
+
commentId: Id,
|
|
1369
|
+
includeDeleted: t.Optional(t.Boolean()),
|
|
1370
|
+
pageSize: t.Optional(PageSize100),
|
|
1371
|
+
}, { additionalProperties: false }),
|
|
1343
1372
|
async execute(input, ctx) {
|
|
1344
1373
|
const p = (input ?? {});
|
|
1345
1374
|
const out = [];
|
|
@@ -1363,16 +1392,12 @@ export default function googleDrive(rl) {
|
|
|
1363
1392
|
rl.registerAction("reply.create", {
|
|
1364
1393
|
access: "write",
|
|
1365
1394
|
description: "Post a reply to a comment. Pass action: 'resolve' | 'reopen' to also flip the comment state.",
|
|
1366
|
-
inputSchema: {
|
|
1367
|
-
fileId:
|
|
1368
|
-
commentId:
|
|
1369
|
-
content:
|
|
1370
|
-
action:
|
|
1371
|
-
|
|
1372
|
-
required: false,
|
|
1373
|
-
description: "'resolve' | 'reopen'. Omit for a plain reply.",
|
|
1374
|
-
},
|
|
1375
|
-
},
|
|
1395
|
+
inputSchema: t.Object({
|
|
1396
|
+
fileId: Id,
|
|
1397
|
+
commentId: Id,
|
|
1398
|
+
content: NonEmptyString,
|
|
1399
|
+
action: t.Optional(stringEnum(["resolve", "reopen"])),
|
|
1400
|
+
}, { additionalProperties: false }),
|
|
1376
1401
|
async execute(input, ctx) {
|
|
1377
1402
|
const p = (input ?? {});
|
|
1378
1403
|
const body = { content: p.content };
|
|
@@ -1384,12 +1409,7 @@ export default function googleDrive(rl) {
|
|
|
1384
1409
|
rl.registerAction("reply.update", {
|
|
1385
1410
|
access: "write",
|
|
1386
1411
|
description: "Edit the content of a reply.",
|
|
1387
|
-
inputSchema: {
|
|
1388
|
-
fileId: { type: "string", required: true },
|
|
1389
|
-
commentId: { type: "string", required: true },
|
|
1390
|
-
replyId: { type: "string", required: true },
|
|
1391
|
-
content: { type: "string", required: true },
|
|
1392
|
-
},
|
|
1412
|
+
inputSchema: t.Object({ fileId: Id, commentId: Id, replyId: Id, content: NonEmptyString }, { additionalProperties: false }),
|
|
1393
1413
|
async execute(input, ctx) {
|
|
1394
1414
|
const p = (input ?? {});
|
|
1395
1415
|
return driveRequest(ctx, "PATCH", `/drive/v3/files/${p.fileId}/comments/${p.commentId}/replies/${p.replyId}`, { content: p.content }, { fields: REPLY_FIELDS });
|
|
@@ -1398,11 +1418,7 @@ export default function googleDrive(rl) {
|
|
|
1398
1418
|
rl.registerAction("reply.delete", {
|
|
1399
1419
|
access: "write",
|
|
1400
1420
|
description: "Soft-delete a reply.",
|
|
1401
|
-
inputSchema: {
|
|
1402
|
-
fileId: { type: "string", required: true },
|
|
1403
|
-
commentId: { type: "string", required: true },
|
|
1404
|
-
replyId: { type: "string", required: true },
|
|
1405
|
-
},
|
|
1421
|
+
inputSchema: t.Object({ fileId: Id, commentId: Id, replyId: Id }, { additionalProperties: false }),
|
|
1406
1422
|
async execute(input, ctx) {
|
|
1407
1423
|
const p = (input ?? {});
|
|
1408
1424
|
await driveRequest(ctx, "DELETE", `/drive/v3/files/${p.fileId}/comments/${p.commentId}/replies/${p.replyId}`);
|
|
@@ -1430,10 +1446,7 @@ export default function googleDrive(rl) {
|
|
|
1430
1446
|
rl.registerAction("revision.list", {
|
|
1431
1447
|
access: "read",
|
|
1432
1448
|
description: "List every revision Drive retains for a file, oldest first. For Office files the per-revision bytes are what `revision.download` returns.",
|
|
1433
|
-
inputSchema: {
|
|
1434
|
-
fileId: { type: "string", required: true },
|
|
1435
|
-
pageSize: { type: "number", required: false, description: "Default 200; Drive caps at 1000." },
|
|
1436
|
-
},
|
|
1449
|
+
inputSchema: t.Object({ fileId: Id, pageSize: t.Optional(PageSize1000) }, { additionalProperties: false }),
|
|
1437
1450
|
async execute(input, ctx) {
|
|
1438
1451
|
const p = (input ?? {});
|
|
1439
1452
|
const fileId = p.fileId;
|
|
@@ -1457,10 +1470,7 @@ export default function googleDrive(rl) {
|
|
|
1457
1470
|
rl.registerAction("revision.get", {
|
|
1458
1471
|
access: "read",
|
|
1459
1472
|
description: "Fetch metadata for a single revision.",
|
|
1460
|
-
inputSchema: {
|
|
1461
|
-
fileId: { type: "string", required: true },
|
|
1462
|
-
revisionId: { type: "string", required: true },
|
|
1463
|
-
},
|
|
1473
|
+
inputSchema: t.Object({ fileId: Id, revisionId: Id }, { additionalProperties: false }),
|
|
1464
1474
|
async execute(input, ctx) {
|
|
1465
1475
|
const p = (input ?? {});
|
|
1466
1476
|
return driveRequest(ctx, "GET", `/drive/v3/files/${p.fileId}/revisions/${p.revisionId}`, undefined, { fields: REVISION_FIELDS });
|
|
@@ -1469,15 +1479,7 @@ export default function googleDrive(rl) {
|
|
|
1469
1479
|
rl.registerAction("revision.download", {
|
|
1470
1480
|
access: "write",
|
|
1471
1481
|
description: "Download the bytes of a specific revision. Pass savePath to write to disk and get back the path; otherwise returns { contentBase64, mimeType, size }. This is the recovery path when an in-place file.update has overwritten in-document comments on an Office file.",
|
|
1472
|
-
inputSchema: {
|
|
1473
|
-
fileId: { type: "string", required: true },
|
|
1474
|
-
revisionId: { type: "string", required: true },
|
|
1475
|
-
savePath: {
|
|
1476
|
-
type: "string",
|
|
1477
|
-
required: false,
|
|
1478
|
-
description: "Filesystem path to write the bytes to. If omitted, returns base64.",
|
|
1479
|
-
},
|
|
1480
|
-
},
|
|
1482
|
+
inputSchema: t.Object({ fileId: Id, revisionId: Id, savePath: t.Optional(NonEmptyString) }, { additionalProperties: false }),
|
|
1481
1483
|
async execute(input, ctx) {
|
|
1482
1484
|
const p = (input ?? {});
|
|
1483
1485
|
const fileId = p.fileId;
|
|
@@ -1509,14 +1511,22 @@ export default function googleDrive(rl) {
|
|
|
1509
1511
|
rl.registerAction("revision.update", {
|
|
1510
1512
|
access: "write",
|
|
1511
1513
|
description: "Patch revision metadata. The most useful flag is keepForever — without it Drive can garbage-collect revisions after 30 days / 100 versions on Office files. Set keepForever=true on the head revision before any risky file.update so prior bytes are guaranteed recoverable.",
|
|
1512
|
-
inputSchema: {
|
|
1513
|
-
fileId:
|
|
1514
|
-
revisionId:
|
|
1515
|
-
keepForever:
|
|
1516
|
-
published:
|
|
1517
|
-
publishAuto:
|
|
1518
|
-
publishedOutsideDomain:
|
|
1519
|
-
},
|
|
1514
|
+
inputSchema: t.Object({
|
|
1515
|
+
fileId: Id,
|
|
1516
|
+
revisionId: Id,
|
|
1517
|
+
keepForever: t.Optional(t.Boolean()),
|
|
1518
|
+
published: t.Optional(t.Boolean()),
|
|
1519
|
+
publishAuto: t.Optional(t.Boolean()),
|
|
1520
|
+
publishedOutsideDomain: t.Optional(t.Boolean()),
|
|
1521
|
+
}, {
|
|
1522
|
+
additionalProperties: false,
|
|
1523
|
+
anyOf: [
|
|
1524
|
+
{ required: ["keepForever"] },
|
|
1525
|
+
{ required: ["published"] },
|
|
1526
|
+
{ required: ["publishAuto"] },
|
|
1527
|
+
{ required: ["publishedOutsideDomain"] },
|
|
1528
|
+
],
|
|
1529
|
+
}),
|
|
1520
1530
|
async execute(input, ctx) {
|
|
1521
1531
|
const p = (input ?? {});
|
|
1522
1532
|
const body = {};
|
|
@@ -1538,10 +1548,7 @@ export default function googleDrive(rl) {
|
|
|
1538
1548
|
rl.registerAction("revision.delete", {
|
|
1539
1549
|
access: "write",
|
|
1540
1550
|
description: "Permanently delete a revision (head revision cannot be deleted).",
|
|
1541
|
-
inputSchema: {
|
|
1542
|
-
fileId: { type: "string", required: true },
|
|
1543
|
-
revisionId: { type: "string", required: true },
|
|
1544
|
-
},
|
|
1551
|
+
inputSchema: t.Object({ fileId: Id, revisionId: Id }, { additionalProperties: false }),
|
|
1545
1552
|
async execute(input, ctx) {
|
|
1546
1553
|
const p = (input ?? {});
|
|
1547
1554
|
await driveRequest(ctx, "DELETE", `/drive/v3/files/${p.fileId}/revisions/${p.revisionId}`);
|
|
@@ -1551,15 +1558,7 @@ export default function googleDrive(rl) {
|
|
|
1551
1558
|
rl.registerAction("revision.restore", {
|
|
1552
1559
|
access: "write",
|
|
1553
1560
|
description: "Restore an older revision as the head of the file. Downloads the revision bytes and re-uploads them via multipart so the head moves to that content. Drive's REST API has no native restore endpoint for binary files; this performs the equivalent in two calls. Returns the new head file resource.",
|
|
1554
|
-
inputSchema: {
|
|
1555
|
-
fileId: { type: "string", required: true },
|
|
1556
|
-
revisionId: { type: "string", required: true, description: "Revision to restore as head." },
|
|
1557
|
-
mimeType: {
|
|
1558
|
-
type: "string",
|
|
1559
|
-
required: false,
|
|
1560
|
-
description: "Override mime type for the re-upload. Defaults to the revision's mime type.",
|
|
1561
|
-
},
|
|
1562
|
-
},
|
|
1561
|
+
inputSchema: t.Object({ fileId: Id, revisionId: Id, mimeType: t.Optional(NonEmptyString) }, { additionalProperties: false }),
|
|
1563
1562
|
async execute(input, ctx) {
|
|
1564
1563
|
const p = (input ?? {});
|
|
1565
1564
|
const fileId = p.fileId;
|
|
@@ -1604,10 +1603,10 @@ export default function googleDrive(rl) {
|
|
|
1604
1603
|
rl.registerAction("changes.getStartPageToken", {
|
|
1605
1604
|
access: "read",
|
|
1606
1605
|
description: "Get the current Drive change-feed start page token. Use as the seed `pageToken` for the first `changes.list` call.",
|
|
1607
|
-
inputSchema: {
|
|
1608
|
-
driveId:
|
|
1609
|
-
supportsAllDrives:
|
|
1610
|
-
},
|
|
1606
|
+
inputSchema: t.Object({
|
|
1607
|
+
driveId: t.Optional(Id),
|
|
1608
|
+
supportsAllDrives: t.Optional(t.Boolean()),
|
|
1609
|
+
}, { additionalProperties: false }),
|
|
1611
1610
|
async execute(input, ctx) {
|
|
1612
1611
|
const p = (input ?? {});
|
|
1613
1612
|
return driveRequest(ctx, "GET", `/drive/v3/changes/startPageToken`, undefined, {
|
|
@@ -1619,17 +1618,17 @@ export default function googleDrive(rl) {
|
|
|
1619
1618
|
rl.registerAction("changes.list", {
|
|
1620
1619
|
access: "read",
|
|
1621
1620
|
description: "List changes to files and Shared Drives since the given `pageToken`. Returns `{ changes, newStartPageToken, nextPageToken? }`. Drive does not surface comment-level changes here — use this for file metadata/content changes; pair with comments.list for review activity.",
|
|
1622
|
-
inputSchema: {
|
|
1623
|
-
pageToken:
|
|
1624
|
-
driveId:
|
|
1625
|
-
spaces:
|
|
1626
|
-
includeRemoved:
|
|
1627
|
-
includeItemsFromAllDrives:
|
|
1628
|
-
supportsAllDrives:
|
|
1629
|
-
restrictToMyDrive:
|
|
1630
|
-
pageSize:
|
|
1631
|
-
fields:
|
|
1632
|
-
},
|
|
1621
|
+
inputSchema: t.Object({
|
|
1622
|
+
pageToken: NonEmptyString,
|
|
1623
|
+
driveId: t.Optional(Id),
|
|
1624
|
+
spaces: t.Optional(NonEmptyString),
|
|
1625
|
+
includeRemoved: t.Optional(t.Boolean()),
|
|
1626
|
+
includeItemsFromAllDrives: t.Optional(t.Boolean()),
|
|
1627
|
+
supportsAllDrives: t.Optional(t.Boolean()),
|
|
1628
|
+
restrictToMyDrive: t.Optional(t.Boolean()),
|
|
1629
|
+
pageSize: t.Optional(PageSize1000),
|
|
1630
|
+
fields: t.Optional(NonEmptyString),
|
|
1631
|
+
}, { additionalProperties: false }),
|
|
1633
1632
|
async execute(input, ctx) {
|
|
1634
1633
|
const p = (input ?? {});
|
|
1635
1634
|
return driveRequest(ctx, "GET", `/drive/v3/changes`, undefined, {
|
|
@@ -1649,16 +1648,16 @@ export default function googleDrive(rl) {
|
|
|
1649
1648
|
rl.registerAction("changes.watch", {
|
|
1650
1649
|
access: "write",
|
|
1651
1650
|
description: "Subscribe to push notifications on the change feed. Drive will POST to `address` whenever a change in this corpus is recorded. Returns a channel resource; pair with `channels.stop` (`changes.stop`) when done.",
|
|
1652
|
-
inputSchema: {
|
|
1653
|
-
pageToken:
|
|
1654
|
-
address: {
|
|
1655
|
-
channelId:
|
|
1656
|
-
token:
|
|
1657
|
-
expiration: {
|
|
1658
|
-
driveId:
|
|
1659
|
-
supportsAllDrives:
|
|
1660
|
-
includeItemsFromAllDrives:
|
|
1661
|
-
},
|
|
1651
|
+
inputSchema: t.Object({
|
|
1652
|
+
pageToken: NonEmptyString,
|
|
1653
|
+
address: t.String({ pattern: "^https://" }),
|
|
1654
|
+
channelId: t.Optional(Id),
|
|
1655
|
+
token: t.Optional(t.String()),
|
|
1656
|
+
expiration: t.Optional(t.Integer({ minimum: 0 })),
|
|
1657
|
+
driveId: t.Optional(Id),
|
|
1658
|
+
supportsAllDrives: t.Optional(t.Boolean()),
|
|
1659
|
+
includeItemsFromAllDrives: t.Optional(t.Boolean()),
|
|
1660
|
+
}, { additionalProperties: false }),
|
|
1662
1661
|
async execute(input, ctx) {
|
|
1663
1662
|
const p = (input ?? {});
|
|
1664
1663
|
const body = {
|
|
@@ -1681,10 +1680,7 @@ export default function googleDrive(rl) {
|
|
|
1681
1680
|
rl.registerAction("changes.stop", {
|
|
1682
1681
|
access: "write",
|
|
1683
1682
|
description: "Stop a previously-subscribed change channel. Pass the same `channelId` and `resourceId` returned by `changes.watch`.",
|
|
1684
|
-
inputSchema: {
|
|
1685
|
-
channelId: { type: "string", required: true },
|
|
1686
|
-
resourceId: { type: "string", required: true },
|
|
1687
|
-
},
|
|
1683
|
+
inputSchema: t.Object({ channelId: Id, resourceId: Id }, { additionalProperties: false }),
|
|
1688
1684
|
async execute(input, ctx) {
|
|
1689
1685
|
const p = (input ?? {});
|
|
1690
1686
|
await driveRequest(ctx, "POST", `/drive/v3/channels/stop`, { id: p.channelId, resourceId: p.resourceId });
|
|
@@ -1700,16 +1696,26 @@ export default function googleDrive(rl) {
|
|
|
1700
1696
|
rl.registerAction("permission.update", {
|
|
1701
1697
|
access: "write",
|
|
1702
1698
|
description: "Patch an existing file/folder permission. Use to change the role on an existing share, set an expiration time, or transfer ownership.",
|
|
1703
|
-
inputSchema: {
|
|
1704
|
-
fileId:
|
|
1705
|
-
permissionId:
|
|
1706
|
-
role:
|
|
1707
|
-
expirationTime:
|
|
1708
|
-
transferOwnership:
|
|
1709
|
-
removeExpiration:
|
|
1710
|
-
useDomainAdminAccess:
|
|
1711
|
-
supportsAllDrives:
|
|
1712
|
-
},
|
|
1699
|
+
inputSchema: t.Object({
|
|
1700
|
+
fileId: Id,
|
|
1701
|
+
permissionId: Id,
|
|
1702
|
+
role: t.Optional(PermissionRole),
|
|
1703
|
+
expirationTime: t.Optional(Rfc3339Timestamp),
|
|
1704
|
+
transferOwnership: t.Optional(t.Boolean()),
|
|
1705
|
+
removeExpiration: t.Optional(t.Boolean()),
|
|
1706
|
+
useDomainAdminAccess: t.Optional(t.Boolean()),
|
|
1707
|
+
supportsAllDrives: t.Optional(t.Boolean()),
|
|
1708
|
+
}, {
|
|
1709
|
+
additionalProperties: false,
|
|
1710
|
+
anyOf: [
|
|
1711
|
+
{ required: ["role"] },
|
|
1712
|
+
{ required: ["expirationTime"] },
|
|
1713
|
+
{
|
|
1714
|
+
properties: { removeExpiration: { const: true } },
|
|
1715
|
+
required: ["removeExpiration"],
|
|
1716
|
+
},
|
|
1717
|
+
],
|
|
1718
|
+
}),
|
|
1713
1719
|
async execute(input, ctx) {
|
|
1714
1720
|
const p = (input ?? {});
|
|
1715
1721
|
const body = {};
|
|
@@ -1739,10 +1745,7 @@ export default function googleDrive(rl) {
|
|
|
1739
1745
|
rl.registerAction("accessProposal.list", {
|
|
1740
1746
|
access: "read",
|
|
1741
1747
|
description: "List access proposals (Request-access entries) on a file.",
|
|
1742
|
-
inputSchema: {
|
|
1743
|
-
fileId: { type: "string", required: true },
|
|
1744
|
-
pageSize: { type: "number", required: false },
|
|
1745
|
-
},
|
|
1748
|
+
inputSchema: t.Object({ fileId: Id, pageSize: t.Optional(PageSize100) }, { additionalProperties: false }),
|
|
1746
1749
|
async execute(input, ctx) {
|
|
1747
1750
|
const p = (input ?? {});
|
|
1748
1751
|
const out = [];
|
|
@@ -1759,14 +1762,23 @@ export default function googleDrive(rl) {
|
|
|
1759
1762
|
rl.registerAction("accessProposal.resolve", {
|
|
1760
1763
|
access: "write",
|
|
1761
1764
|
description: "Resolve an access proposal. `action` is one of 'ACCEPT' or 'DENY'. When accepting, pass `role` (default 'reader') to grant.",
|
|
1762
|
-
inputSchema: {
|
|
1763
|
-
fileId:
|
|
1764
|
-
proposalId:
|
|
1765
|
-
action:
|
|
1766
|
-
role:
|
|
1767
|
-
view:
|
|
1768
|
-
sendNotification:
|
|
1769
|
-
},
|
|
1765
|
+
inputSchema: t.Object({
|
|
1766
|
+
fileId: Id,
|
|
1767
|
+
proposalId: Id,
|
|
1768
|
+
action: stringEnum(["ACCEPT", "DENY"]),
|
|
1769
|
+
role: t.Optional(AccessProposalRole),
|
|
1770
|
+
view: t.Optional(NonEmptyString),
|
|
1771
|
+
sendNotification: t.Optional(t.Boolean()),
|
|
1772
|
+
}, {
|
|
1773
|
+
additionalProperties: false,
|
|
1774
|
+
oneOf: [
|
|
1775
|
+
{ properties: { action: { const: "ACCEPT" } } },
|
|
1776
|
+
{
|
|
1777
|
+
properties: { action: { const: "DENY" } },
|
|
1778
|
+
not: { anyOf: [{ required: ["role"] }, { required: ["view"] }] },
|
|
1779
|
+
},
|
|
1780
|
+
],
|
|
1781
|
+
}),
|
|
1770
1782
|
async execute(input, ctx) {
|
|
1771
1783
|
const p = (input ?? {});
|
|
1772
1784
|
const body = { action: p.action };
|
|
@@ -1784,9 +1796,7 @@ export default function googleDrive(rl) {
|
|
|
1784
1796
|
rl.registerAction("about.get", {
|
|
1785
1797
|
access: "read",
|
|
1786
1798
|
description: "Current user info: storage quota, export formats, max upload size, importable mime types. Useful for healthchecks and conversion planning.",
|
|
1787
|
-
inputSchema: {
|
|
1788
|
-
fields: { type: "string", required: false },
|
|
1789
|
-
},
|
|
1799
|
+
inputSchema: t.Object({ fields: t.Optional(NonEmptyString) }, { additionalProperties: false }),
|
|
1790
1800
|
async execute(input, ctx) {
|
|
1791
1801
|
const p = (input ?? {});
|
|
1792
1802
|
return driveRequest(ctx, "GET", `/drive/v3/about`, undefined, {
|
|
@@ -1799,15 +1809,11 @@ export default function googleDrive(rl) {
|
|
|
1799
1809
|
rl.registerAction("file.export", {
|
|
1800
1810
|
access: "write",
|
|
1801
1811
|
description: "Export a Google-native file (Doc/Sheet/Slide/Drawing/Form) to a non-native mimeType. Wrapper around the export endpoint; pass `savePath` to write to disk and get the path back, otherwise returns base64.",
|
|
1802
|
-
inputSchema: {
|
|
1803
|
-
fileId:
|
|
1804
|
-
mimeType:
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
description: "Target export mime, e.g. application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/pdf, text/plain, text/csv.",
|
|
1808
|
-
},
|
|
1809
|
-
savePath: { type: "string", required: false },
|
|
1810
|
-
},
|
|
1812
|
+
inputSchema: t.Object({
|
|
1813
|
+
fileId: Id,
|
|
1814
|
+
mimeType: NonEmptyString,
|
|
1815
|
+
savePath: t.Optional(NonEmptyString),
|
|
1816
|
+
}, { additionalProperties: false }),
|
|
1811
1817
|
async execute(input, ctx) {
|
|
1812
1818
|
const p = (input ?? {});
|
|
1813
1819
|
const token = await accessToken(ctx);
|
|
@@ -1830,19 +1836,19 @@ export default function googleDrive(rl) {
|
|
|
1830
1836
|
rl.registerAction("file.list", {
|
|
1831
1837
|
access: "read",
|
|
1832
1838
|
description: "Raw Drive `files.list`. Pass Drive search-syntax `q` and any combination of corpora / driveId / spaces / orderBy. `fileFolder.search` is the friendlier wrapper; reach for `file.list` only when you need the unwrapped surface.",
|
|
1833
|
-
inputSchema: {
|
|
1834
|
-
q:
|
|
1835
|
-
corpora:
|
|
1836
|
-
driveId:
|
|
1837
|
-
spaces:
|
|
1838
|
-
orderBy:
|
|
1839
|
-
pageSize:
|
|
1840
|
-
pageToken:
|
|
1841
|
-
includeItemsFromAllDrives:
|
|
1842
|
-
supportsAllDrives:
|
|
1843
|
-
fields:
|
|
1844
|
-
returnAll:
|
|
1845
|
-
},
|
|
1839
|
+
inputSchema: t.Object({
|
|
1840
|
+
q: t.Optional(t.String()),
|
|
1841
|
+
corpora: t.Optional(stringEnum(["user", "domain", "drive", "allDrives"])),
|
|
1842
|
+
driveId: t.Optional(Id),
|
|
1843
|
+
spaces: t.Optional(NonEmptyString),
|
|
1844
|
+
orderBy: t.Optional(NonEmptyString),
|
|
1845
|
+
pageSize: t.Optional(PageSize1000),
|
|
1846
|
+
pageToken: t.Optional(NonEmptyString),
|
|
1847
|
+
includeItemsFromAllDrives: t.Optional(t.Boolean()),
|
|
1848
|
+
supportsAllDrives: t.Optional(t.Boolean()),
|
|
1849
|
+
fields: t.Optional(NonEmptyString),
|
|
1850
|
+
returnAll: t.Optional(t.Boolean()),
|
|
1851
|
+
}, { additionalProperties: false }),
|
|
1846
1852
|
async execute(input, ctx) {
|
|
1847
1853
|
const p = (input ?? {});
|
|
1848
1854
|
const baseQs = {
|