gws-axi 0.6.2 → 0.8.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/src/cli.js +2 -4
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/drive/get.d.ts +2 -0
- package/dist/src/commands/drive/get.js +112 -0
- package/dist/src/commands/drive/get.js.map +1 -0
- package/dist/src/commands/drive/ls.d.ts +2 -0
- package/dist/src/commands/drive/ls.js +268 -0
- package/dist/src/commands/drive/ls.js.map +1 -0
- package/dist/src/commands/drive/permissions.d.ts +2 -0
- package/dist/src/commands/drive/permissions.js +117 -0
- package/dist/src/commands/drive/permissions.js.map +1 -0
- package/dist/src/commands/drive/search.d.ts +2 -0
- package/dist/src/commands/drive/search.js +169 -0
- package/dist/src/commands/drive/search.js.map +1 -0
- package/dist/src/commands/drive.d.ts +1 -1
- package/dist/src/commands/drive.js +134 -16
- package/dist/src/commands/drive.js.map +1 -1
- package/dist/src/commands/slides/get.d.ts +2 -0
- package/dist/src/commands/slides/get.js +95 -0
- package/dist/src/commands/slides/get.js.map +1 -0
- package/dist/src/commands/slides/page.d.ts +2 -0
- package/dist/src/commands/slides/page.js +100 -0
- package/dist/src/commands/slides/page.js.map +1 -0
- package/dist/src/commands/slides/summarize.d.ts +2 -0
- package/dist/src/commands/slides/summarize.js +159 -0
- package/dist/src/commands/slides/summarize.js.map +1 -0
- package/dist/src/commands/slides/text.d.ts +22 -0
- package/dist/src/commands/slides/text.js +103 -0
- package/dist/src/commands/slides/text.js.map +1 -0
- package/dist/src/commands/slides.d.ts +1 -1
- package/dist/src/commands/slides.js +93 -10
- package/dist/src/commands/slides.js.map +1 -1
- package/package.json +1 -1
package/dist/src/cli.js
CHANGED
|
@@ -8,8 +8,8 @@ import { doctorCommand, DOCTOR_HELP } from "./commands/doctor.js";
|
|
|
8
8
|
import { calendarCommand } from "./commands/calendar.js";
|
|
9
9
|
import { gmailCommand } from "./commands/gmail.js";
|
|
10
10
|
import { docsCommand } from "./commands/docs.js";
|
|
11
|
-
import { driveCommand
|
|
12
|
-
import { slidesCommand
|
|
11
|
+
import { driveCommand } from "./commands/drive.js";
|
|
12
|
+
import { slidesCommand } from "./commands/slides.js";
|
|
13
13
|
const DESCRIPTION = "Agent ergonomic CLI for Google Workspace. Unified interface for Gmail, Calendar, Docs, Drive, and Slides with agent-guided OAuth setup.";
|
|
14
14
|
const VERSION = readPackageVersion();
|
|
15
15
|
export const TOP_HELP = `usage: gws-axi [command] [args] [flags]
|
|
@@ -29,8 +29,6 @@ examples:
|
|
|
29
29
|
const COMMAND_HELP = {
|
|
30
30
|
auth: AUTH_HELP,
|
|
31
31
|
doctor: DOCTOR_HELP,
|
|
32
|
-
drive: DRIVE_HELP,
|
|
33
|
-
slides: SLIDES_HELP,
|
|
34
32
|
};
|
|
35
33
|
export async function main() {
|
|
36
34
|
await runAxiCli({
|
package/dist/src/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,WAAW,GACf,yIAAyI,CAAC;AAE5I,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;AAErC,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;CAUvB,CAAC;AAEF,0EAA0E;AAC1E,0EAA0E;AAC1E,iEAAiE;AACjE,MAAM,YAAY,GAA2B;IAC3C,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,WAAW;CACpB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,SAAS,CAAC;QACd,WAAW,EAAE,WAAW;QACxB,OAAO,EAAE,OAAO;QAChB,YAAY,EAAE,QAAQ;QACtB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,WAAW,EAAE;QAC/B,QAAQ,EAAE;YACR,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,aAAa;YACrB,QAAQ,EAAE,eAAe;YACzB,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,WAAW;YACjB,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,aAAa;SACtB;QACD,cAAc,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC;KACnD,CAAC,CAAC;AACL,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAErD,KAAK,MAAM,SAAS,IAAI;QACtB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;QAChC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;KACvC,EAAE,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAEzD,CAAC;QACF,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const GET_HELP = "usage: gws-axi drive get <file-id> [flags]\nargs[1]:\n <file-id> The Drive file ID (from the URL or `drive search` / ls output)\nflags[1]:\n --account <email> Account override when 2+ are configured\nexamples:\n gws-axi drive get 1AbC...\noutput:\n A `file{...}` object with name, mime_type, size, owners, parents,\n modified/created times, and view-link. For native Google files\n (Docs, Sheets, Slides) we include hints pointing at `docs read` /\n `docs download`; for other types, `drive download`.\n";
|
|
2
|
+
export declare function driveGetCommand(account: string, args: string[]): Promise<string>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { AxiError } from "axi-sdk-js";
|
|
2
|
+
import { driveClient, translateGoogleError } from "../../google/client.js";
|
|
3
|
+
import { joinBlocks, renderHelp, renderObject } from "../../output/index.js";
|
|
4
|
+
export const GET_HELP = `usage: gws-axi drive get <file-id> [flags]
|
|
5
|
+
args[1]:
|
|
6
|
+
<file-id> The Drive file ID (from the URL or \`drive search\` / ls output)
|
|
7
|
+
flags[1]:
|
|
8
|
+
--account <email> Account override when 2+ are configured
|
|
9
|
+
examples:
|
|
10
|
+
gws-axi drive get 1AbC...
|
|
11
|
+
output:
|
|
12
|
+
A \`file{...}\` object with name, mime_type, size, owners, parents,
|
|
13
|
+
modified/created times, and view-link. For native Google files
|
|
14
|
+
(Docs, Sheets, Slides) we include hints pointing at \`docs read\` /
|
|
15
|
+
\`docs download\`; for other types, \`drive download\`.
|
|
16
|
+
`;
|
|
17
|
+
function parseFlags(args) {
|
|
18
|
+
let fileId;
|
|
19
|
+
for (const arg of args) {
|
|
20
|
+
if (!arg.startsWith("--") && fileId === undefined) {
|
|
21
|
+
fileId = arg;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (!fileId) {
|
|
25
|
+
throw new AxiError("Missing file ID argument", "VALIDATION_ERROR", ["Usage: gws-axi drive get <file-id>"]);
|
|
26
|
+
}
|
|
27
|
+
return { fileId };
|
|
28
|
+
}
|
|
29
|
+
const GET_FIELDS = "id,name,mimeType,size,createdTime,modifiedTime,owners(emailAddress,displayName),parents,description,trashed,starred,shared,webViewLink,iconLink,sha256Checksum,fileExtension";
|
|
30
|
+
export async function driveGetCommand(account, args) {
|
|
31
|
+
const flags = parseFlags(args);
|
|
32
|
+
const api = await driveClient(account);
|
|
33
|
+
let file;
|
|
34
|
+
try {
|
|
35
|
+
const res = await api.files.get({
|
|
36
|
+
fileId: flags.fileId,
|
|
37
|
+
fields: GET_FIELDS,
|
|
38
|
+
supportsAllDrives: true,
|
|
39
|
+
});
|
|
40
|
+
file = res.data;
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
const translated = translateGoogleError(err, {
|
|
44
|
+
account,
|
|
45
|
+
operation: "drive.files.get",
|
|
46
|
+
});
|
|
47
|
+
if (translated.code === "NOT_FOUND") {
|
|
48
|
+
throw new AxiError(`File '${flags.fileId}' not found (or ${account} doesn't have access)`, "FILE_NOT_FOUND", [
|
|
49
|
+
`Verify the file ID is correct (from a Drive URL or \`drive search\`)`,
|
|
50
|
+
`Confirm ${account} has at least view access`,
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
53
|
+
throw translated;
|
|
54
|
+
}
|
|
55
|
+
const isNative = (file.mimeType ?? "").startsWith("application/vnd.google-apps.");
|
|
56
|
+
const isFolder = file.mimeType === "application/vnd.google-apps.folder";
|
|
57
|
+
const details = {
|
|
58
|
+
id: file.id ?? flags.fileId,
|
|
59
|
+
name: file.name ?? "",
|
|
60
|
+
mime_type: file.mimeType ?? "",
|
|
61
|
+
};
|
|
62
|
+
if (file.size)
|
|
63
|
+
details.size_bytes = parseInt(file.size, 10);
|
|
64
|
+
if (file.createdTime)
|
|
65
|
+
details.created = file.createdTime;
|
|
66
|
+
if (file.modifiedTime)
|
|
67
|
+
details.modified = file.modifiedTime;
|
|
68
|
+
if (file.owners?.length) {
|
|
69
|
+
details.owners = file.owners
|
|
70
|
+
.map((o) => o.emailAddress ?? o.displayName ?? "")
|
|
71
|
+
.filter(Boolean)
|
|
72
|
+
.join(", ");
|
|
73
|
+
}
|
|
74
|
+
if (file.parents?.length)
|
|
75
|
+
details.parents = file.parents.join(", ");
|
|
76
|
+
if (file.description)
|
|
77
|
+
details.description = file.description;
|
|
78
|
+
if (file.shared !== undefined)
|
|
79
|
+
details.shared = file.shared;
|
|
80
|
+
if (file.starred)
|
|
81
|
+
details.starred = true;
|
|
82
|
+
if (file.trashed)
|
|
83
|
+
details.trashed = true;
|
|
84
|
+
if (file.webViewLink)
|
|
85
|
+
details.web_view_link = file.webViewLink;
|
|
86
|
+
if (file.fileExtension)
|
|
87
|
+
details.file_extension = file.fileExtension;
|
|
88
|
+
const blocks = [];
|
|
89
|
+
blocks.push(renderObject({ account }));
|
|
90
|
+
blocks.push(renderObject({ file: details }));
|
|
91
|
+
const suggestions = [];
|
|
92
|
+
if (isFolder) {
|
|
93
|
+
suggestions.push(`Run \`gws-axi drive ls ${file.id} --recursive\` to walk this folder's contents`);
|
|
94
|
+
}
|
|
95
|
+
else if (file.mimeType === "application/vnd.google-apps.document") {
|
|
96
|
+
suggestions.push(`Run \`gws-axi docs read ${file.id}\` to read this Doc as markdown`);
|
|
97
|
+
suggestions.push(`Run \`gws-axi docs comments ${file.id}\` to see review comments`);
|
|
98
|
+
}
|
|
99
|
+
else if (isNative) {
|
|
100
|
+
suggestions.push(`Native Google file — run \`gws-axi docs download ${file.id} --as <mime>\` to export (e.g. application/pdf, text/csv)`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
suggestions.push(`Run \`gws-axi docs download ${file.id} --out <path>\` to fetch the raw file`);
|
|
104
|
+
}
|
|
105
|
+
suggestions.push(`Run \`gws-axi drive permissions ${file.id}\` to see who has access`);
|
|
106
|
+
if (file.webViewLink) {
|
|
107
|
+
suggestions.push(`Open in browser: ${file.webViewLink}`);
|
|
108
|
+
}
|
|
109
|
+
blocks.push(renderHelp(suggestions));
|
|
110
|
+
return joinBlocks(...blocks);
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../../../src/commands/drive/get.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const LS_HELP = "usage: gws-axi drive ls [<folder-id>] [flags]\nargs[1]:\n <folder-id> Folder ID to list (default: \"root\", aka My Drive).\n Pass \"shared-with-me\" to list files shared with you\n but not in any of your folders.\nflags[6]:\n --recursive, -r Walk the tree and emit a flat list with full paths\n relative to the queried folder. Off by default; for\n a quality overview of an entire client/project\n folder, pass --recursive.\n --depth <n> Cap recursion depth (default: unlimited \u2014 the\n --limit safety bound stops runaway walks). Only\n meaningful with --recursive; useful for \"give me\n a 2-level overview without diving into every\n subfolder.\"\n --limit <n> Max items to return (default: 500, max: 5000).\n For --recursive, this is the total file count\n across the walk; for non-recursive, it's the page\n size against the API.\n --page <token> Fetch next page (non-recursive only \u2014 recursive\n walks paginate internally).\n --include-trashed Include trashed files (default: trashed excluded)\n --account <email> Account override when 2+ are configured\nexamples:\n gws-axi drive ls # root contents\n gws-axi drive ls 1AbC...folder-id # one folder\n gws-axi drive ls 1AbC...folder-id --recursive # whole tree\n gws-axi drive ls 1AbC... --recursive --depth 3 --limit 1000 # constrained walk\noutput:\n A `files[N]{path,id,mime_type,size_bytes,modified}` table. `path` is\n the name for non-recursive listings; the relative path within the walk\n for recursive ones (`Subfolder/file.pdf`). Folders have an empty\n size_bytes. `mime_type` is the raw Google MIME (`application/vnd.google-apps.folder`,\n `application/vnd.google-apps.document`, etc.) \u2014 use it to filter.\nnotes:\n Recursive walks make one API call per folder (Drive doesn't support\n recursive list natively). A folder with 10 subfolders \u00D7 3 levels deep\n \u2248 1+10+100+1000 calls \u2014 bounded by --depth and --limit. Trashed and\n shortcut items are skipped unless --include-trashed.\n";
|
|
2
|
+
export declare function driveLsCommand(account: string, args: string[]): Promise<string>;
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { AxiError } from "axi-sdk-js";
|
|
2
|
+
import { driveClient, translateGoogleError } from "../../google/client.js";
|
|
3
|
+
import { field, renderListResponse, } from "../../output/index.js";
|
|
4
|
+
export const LS_HELP = `usage: gws-axi drive ls [<folder-id>] [flags]
|
|
5
|
+
args[1]:
|
|
6
|
+
<folder-id> Folder ID to list (default: "root", aka My Drive).
|
|
7
|
+
Pass "shared-with-me" to list files shared with you
|
|
8
|
+
but not in any of your folders.
|
|
9
|
+
flags[6]:
|
|
10
|
+
--recursive, -r Walk the tree and emit a flat list with full paths
|
|
11
|
+
relative to the queried folder. Off by default; for
|
|
12
|
+
a quality overview of an entire client/project
|
|
13
|
+
folder, pass --recursive.
|
|
14
|
+
--depth <n> Cap recursion depth (default: unlimited — the
|
|
15
|
+
--limit safety bound stops runaway walks). Only
|
|
16
|
+
meaningful with --recursive; useful for "give me
|
|
17
|
+
a 2-level overview without diving into every
|
|
18
|
+
subfolder."
|
|
19
|
+
--limit <n> Max items to return (default: 500, max: 5000).
|
|
20
|
+
For --recursive, this is the total file count
|
|
21
|
+
across the walk; for non-recursive, it's the page
|
|
22
|
+
size against the API.
|
|
23
|
+
--page <token> Fetch next page (non-recursive only — recursive
|
|
24
|
+
walks paginate internally).
|
|
25
|
+
--include-trashed Include trashed files (default: trashed excluded)
|
|
26
|
+
--account <email> Account override when 2+ are configured
|
|
27
|
+
examples:
|
|
28
|
+
gws-axi drive ls # root contents
|
|
29
|
+
gws-axi drive ls 1AbC...folder-id # one folder
|
|
30
|
+
gws-axi drive ls 1AbC...folder-id --recursive # whole tree
|
|
31
|
+
gws-axi drive ls 1AbC... --recursive --depth 3 --limit 1000 # constrained walk
|
|
32
|
+
output:
|
|
33
|
+
A \`files[N]{path,id,mime_type,size_bytes,modified}\` table. \`path\` is
|
|
34
|
+
the name for non-recursive listings; the relative path within the walk
|
|
35
|
+
for recursive ones (\`Subfolder/file.pdf\`). Folders have an empty
|
|
36
|
+
size_bytes. \`mime_type\` is the raw Google MIME (\`application/vnd.google-apps.folder\`,
|
|
37
|
+
\`application/vnd.google-apps.document\`, etc.) — use it to filter.
|
|
38
|
+
notes:
|
|
39
|
+
Recursive walks make one API call per folder (Drive doesn't support
|
|
40
|
+
recursive list natively). A folder with 10 subfolders × 3 levels deep
|
|
41
|
+
≈ 1+10+100+1000 calls — bounded by --depth and --limit. Trashed and
|
|
42
|
+
shortcut items are skipped unless --include-trashed.
|
|
43
|
+
`;
|
|
44
|
+
const DEFAULT_LIMIT = 500;
|
|
45
|
+
const MAX_LIMIT = 5000;
|
|
46
|
+
// Recursion defaults to unlimited depth; --limit (total file count)
|
|
47
|
+
// is the practical safety bound. Most folder trees aren't deeper
|
|
48
|
+
// than 5-6 levels anyway, so a depth cap rarely fires before --limit
|
|
49
|
+
// does. Callers who want a "shallow overview" pass --depth explicitly.
|
|
50
|
+
const DEFAULT_DEPTH = Number.POSITIVE_INFINITY;
|
|
51
|
+
const FOLDER_MIME = "application/vnd.google-apps.folder";
|
|
52
|
+
function parseFlags(args) {
|
|
53
|
+
let folderId;
|
|
54
|
+
let recursive = false;
|
|
55
|
+
let depth = DEFAULT_DEPTH;
|
|
56
|
+
let limit = DEFAULT_LIMIT;
|
|
57
|
+
let page;
|
|
58
|
+
let includeTrashed = false;
|
|
59
|
+
for (let i = 0; i < args.length; i++) {
|
|
60
|
+
const arg = args[i];
|
|
61
|
+
const next = args[i + 1];
|
|
62
|
+
switch (arg) {
|
|
63
|
+
case "--recursive":
|
|
64
|
+
case "-r":
|
|
65
|
+
recursive = true;
|
|
66
|
+
break;
|
|
67
|
+
case "--depth": {
|
|
68
|
+
const parsed = parseInt(next, 10);
|
|
69
|
+
depth = Number.isFinite(parsed) && parsed >= 0 ? parsed : DEFAULT_DEPTH;
|
|
70
|
+
i++;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
case "--limit":
|
|
74
|
+
limit = Math.max(1, Math.min(MAX_LIMIT, parseInt(next, 10) || DEFAULT_LIMIT));
|
|
75
|
+
i++;
|
|
76
|
+
break;
|
|
77
|
+
case "--page":
|
|
78
|
+
page = next;
|
|
79
|
+
i++;
|
|
80
|
+
break;
|
|
81
|
+
case "--include-trashed":
|
|
82
|
+
includeTrashed = true;
|
|
83
|
+
break;
|
|
84
|
+
default:
|
|
85
|
+
if (!arg.startsWith("--") && folderId === undefined) {
|
|
86
|
+
folderId = arg;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
folderId: folderId ?? "root",
|
|
92
|
+
recursive,
|
|
93
|
+
depth,
|
|
94
|
+
limit,
|
|
95
|
+
page,
|
|
96
|
+
includeTrashed,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const FILES_FIELDS = "id,name,mimeType,size,modifiedTime,trashed";
|
|
100
|
+
async function listOneFolder(api, folderId, pageToken, pageSize, includeTrashed) {
|
|
101
|
+
const q = includeTrashed
|
|
102
|
+
? `'${folderId}' in parents`
|
|
103
|
+
: `'${folderId}' in parents and trashed = false`;
|
|
104
|
+
const res = await api.files.list({
|
|
105
|
+
q,
|
|
106
|
+
fields: `nextPageToken, files(${FILES_FIELDS})`,
|
|
107
|
+
pageSize,
|
|
108
|
+
pageToken,
|
|
109
|
+
supportsAllDrives: true,
|
|
110
|
+
includeItemsFromAllDrives: true,
|
|
111
|
+
orderBy: "folder, name",
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
files: res.data.files ?? [],
|
|
115
|
+
nextPageToken: res.data.nextPageToken ?? undefined,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function toRow(file, path) {
|
|
119
|
+
return {
|
|
120
|
+
path,
|
|
121
|
+
id: file.id ?? "",
|
|
122
|
+
mime_type: file.mimeType ?? "",
|
|
123
|
+
size_bytes: file.size ? parseInt(file.size, 10) : "",
|
|
124
|
+
modified: file.modifiedTime ?? "",
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async function recursiveWalk(api, folderId, flags) {
|
|
128
|
+
const rows = [];
|
|
129
|
+
let foldersWalked = 0;
|
|
130
|
+
// BFS keyed by (folderId, prefixPath, depthFromRoot). Stable
|
|
131
|
+
// ordering means a folder's own row is emitted before its children's,
|
|
132
|
+
// which matches what humans expect from `ls -R`.
|
|
133
|
+
const queue = [
|
|
134
|
+
{ id: folderId, prefix: "", depth: 0 },
|
|
135
|
+
];
|
|
136
|
+
while (queue.length > 0 && rows.length < flags.limit) {
|
|
137
|
+
const { id, prefix, depth } = queue.shift();
|
|
138
|
+
foldersWalked += 1;
|
|
139
|
+
let pageToken;
|
|
140
|
+
do {
|
|
141
|
+
// 1000 is Drive's max pageSize and lets us drain a folder quickly.
|
|
142
|
+
const { files, nextPageToken } = await listOneFolder(api, id, pageToken, 1000, flags.includeTrashed);
|
|
143
|
+
for (const file of files) {
|
|
144
|
+
if (rows.length >= flags.limit)
|
|
145
|
+
break;
|
|
146
|
+
const path = prefix + (file.name ?? "");
|
|
147
|
+
rows.push(toRow(file, path));
|
|
148
|
+
if (file.mimeType === FOLDER_MIME && depth < flags.depth) {
|
|
149
|
+
queue.push({
|
|
150
|
+
id: file.id ?? "",
|
|
151
|
+
prefix: `${path}/`,
|
|
152
|
+
depth: depth + 1,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
pageToken = nextPageToken;
|
|
157
|
+
} while (pageToken && rows.length < flags.limit);
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
rows,
|
|
161
|
+
truncated: rows.length >= flags.limit && queue.length > 0,
|
|
162
|
+
foldersWalked,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function fileSchema() {
|
|
166
|
+
return [
|
|
167
|
+
field("path"),
|
|
168
|
+
field("id"),
|
|
169
|
+
field("mime_type"),
|
|
170
|
+
field("size_bytes"),
|
|
171
|
+
field("modified"),
|
|
172
|
+
];
|
|
173
|
+
}
|
|
174
|
+
export async function driveLsCommand(account, args) {
|
|
175
|
+
const flags = parseFlags(args);
|
|
176
|
+
const api = await driveClient(account);
|
|
177
|
+
let rows;
|
|
178
|
+
let nextPage;
|
|
179
|
+
let truncated = false;
|
|
180
|
+
let foldersWalked = 0;
|
|
181
|
+
if (flags.recursive) {
|
|
182
|
+
try {
|
|
183
|
+
const result = await recursiveWalk(api, flags.folderId, flags);
|
|
184
|
+
rows = result.rows;
|
|
185
|
+
truncated = result.truncated;
|
|
186
|
+
foldersWalked = result.foldersWalked;
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
const translated = translateGoogleError(err, {
|
|
190
|
+
account,
|
|
191
|
+
operation: "drive.files.list",
|
|
192
|
+
});
|
|
193
|
+
if (translated.code === "NOT_FOUND") {
|
|
194
|
+
throw new AxiError(`Folder '${flags.folderId}' not found (or ${account} doesn't have access)`, "FOLDER_NOT_FOUND", [
|
|
195
|
+
`Pass "root" or omit the argument to list My Drive root`,
|
|
196
|
+
`Verify the folder ID is correct (from a Drive URL or \`drive search\`)`,
|
|
197
|
+
]);
|
|
198
|
+
}
|
|
199
|
+
throw translated;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
try {
|
|
204
|
+
const result = await listOneFolder(api, flags.folderId, flags.page, flags.limit, flags.includeTrashed);
|
|
205
|
+
rows = result.files.map((f) => toRow(f, f.name ?? ""));
|
|
206
|
+
nextPage = result.nextPageToken;
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
const translated = translateGoogleError(err, {
|
|
210
|
+
account,
|
|
211
|
+
operation: "drive.files.list",
|
|
212
|
+
});
|
|
213
|
+
if (translated.code === "NOT_FOUND") {
|
|
214
|
+
throw new AxiError(`Folder '${flags.folderId}' not found (or ${account} doesn't have access)`, "FOLDER_NOT_FOUND", [
|
|
215
|
+
`Pass "root" or omit the argument to list My Drive root`,
|
|
216
|
+
`Verify the folder ID is correct (from a Drive URL or \`drive search\`)`,
|
|
217
|
+
]);
|
|
218
|
+
}
|
|
219
|
+
throw translated;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const header = {
|
|
223
|
+
account,
|
|
224
|
+
folder: flags.folderId,
|
|
225
|
+
mode: flags.recursive ? "recursive" : "shallow",
|
|
226
|
+
};
|
|
227
|
+
if (flags.recursive && foldersWalked > 0) {
|
|
228
|
+
header.folders_walked = foldersWalked;
|
|
229
|
+
}
|
|
230
|
+
if (nextPage)
|
|
231
|
+
header.next_page = nextPage;
|
|
232
|
+
const summary = { count: rows.length };
|
|
233
|
+
if (truncated) {
|
|
234
|
+
summary.truncated = true;
|
|
235
|
+
summary.note = `Hit --limit ${flags.limit} before walk completed — increase --limit or narrow --depth`;
|
|
236
|
+
}
|
|
237
|
+
const suggestions = [];
|
|
238
|
+
if (rows.length > 0) {
|
|
239
|
+
if (!flags.recursive) {
|
|
240
|
+
const folderCount = rows.filter((r) => r.mime_type === FOLDER_MIME).length;
|
|
241
|
+
if (folderCount > 0) {
|
|
242
|
+
suggestions.push(`${folderCount} folder${folderCount === 1 ? "" : "s"} in this listing — run \`gws-axi drive ls ${flags.folderId} --recursive\` for the full tree (or \`drive ls <subfolder-id>\` to dive into one)`);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
// Even with no folders to descend into, mention recursion exists for
|
|
246
|
+
// the case where this is a flat folder of files.
|
|
247
|
+
suggestions.push(`Run with --recursive for a deep listing (if subfolders exist this would expand them; this folder appears flat)`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
suggestions.push(`Run \`gws-axi drive get <id>\` for full file metadata (sharing, owners, descriptions)`);
|
|
251
|
+
suggestions.push(`Run \`gws-axi docs read <id>\` or \`drive download <id>\` to read file contents`);
|
|
252
|
+
if (nextPage) {
|
|
253
|
+
suggestions.push(`More items available — paginate with \`drive ls ${flags.folderId} --page ${nextPage}\``);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return renderListResponse({
|
|
257
|
+
header,
|
|
258
|
+
summary,
|
|
259
|
+
name: "files",
|
|
260
|
+
items: rows,
|
|
261
|
+
schema: fileSchema(),
|
|
262
|
+
suggestions,
|
|
263
|
+
emptyMessage: flags.recursive
|
|
264
|
+
? `no files in or under \`${flags.folderId}\``
|
|
265
|
+
: `no files in \`${flags.folderId}\` (try --recursive if you want subfolder contents, or --include-trashed)`,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=ls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ls.js","sourceRoot":"","sources":["../../../../src/commands/drive/ls.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const PERMISSIONS_HELP = "usage: gws-axi drive permissions <file-id> [flags]\nargs[1]:\n <file-id> The Drive file ID (from URL or `drive get` / `drive ls`)\nflags[1]:\n --account <email> Account override when 2+ are configured\nexamples:\n gws-axi drive permissions 1AbC...\noutput:\n A `file{id,name,shared}` header plus a `permissions[N]{role,type,\n email_or_domain,display_name,deleted}` table. `role` is owner/\n organizer/fileOrganizer/writer/commenter/reader; `type` is user/\n group/domain/anyone.\nnotes:\n Permissions only enumerate explicit grants \u2014 inherited folder\n permissions and shared-drive memberships aren't surfaced. Pass\n `supportsAllDrives: true` is automatic; shared-drive ACLs may\n include a longer chain than what shows here.\n";
|
|
2
|
+
export declare function drivePermissionsCommand(account: string, args: string[]): Promise<string>;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { AxiError } from "axi-sdk-js";
|
|
2
|
+
import { driveClient, translateGoogleError } from "../../google/client.js";
|
|
3
|
+
import { field, renderList, renderObject, joinBlocks, renderHelp, } from "../../output/index.js";
|
|
4
|
+
export const PERMISSIONS_HELP = `usage: gws-axi drive permissions <file-id> [flags]
|
|
5
|
+
args[1]:
|
|
6
|
+
<file-id> The Drive file ID (from URL or \`drive get\` / \`drive ls\`)
|
|
7
|
+
flags[1]:
|
|
8
|
+
--account <email> Account override when 2+ are configured
|
|
9
|
+
examples:
|
|
10
|
+
gws-axi drive permissions 1AbC...
|
|
11
|
+
output:
|
|
12
|
+
A \`file{id,name,shared}\` header plus a \`permissions[N]{role,type,
|
|
13
|
+
email_or_domain,display_name,deleted}\` table. \`role\` is owner/
|
|
14
|
+
organizer/fileOrganizer/writer/commenter/reader; \`type\` is user/
|
|
15
|
+
group/domain/anyone.
|
|
16
|
+
notes:
|
|
17
|
+
Permissions only enumerate explicit grants — inherited folder
|
|
18
|
+
permissions and shared-drive memberships aren't surfaced. Pass
|
|
19
|
+
\`supportsAllDrives: true\` is automatic; shared-drive ACLs may
|
|
20
|
+
include a longer chain than what shows here.
|
|
21
|
+
`;
|
|
22
|
+
function parseFlags(args) {
|
|
23
|
+
let fileId;
|
|
24
|
+
for (const arg of args) {
|
|
25
|
+
if (!arg.startsWith("--") && fileId === undefined)
|
|
26
|
+
fileId = arg;
|
|
27
|
+
}
|
|
28
|
+
if (!fileId) {
|
|
29
|
+
throw new AxiError("Missing file ID argument", "VALIDATION_ERROR", ["Usage: gws-axi drive permissions <file-id>"]);
|
|
30
|
+
}
|
|
31
|
+
return { fileId };
|
|
32
|
+
}
|
|
33
|
+
function permissionSchema() {
|
|
34
|
+
return [
|
|
35
|
+
field("role"),
|
|
36
|
+
field("type"),
|
|
37
|
+
field("email_or_domain"),
|
|
38
|
+
field("display_name"),
|
|
39
|
+
field("deleted"),
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
export async function drivePermissionsCommand(account, args) {
|
|
43
|
+
const flags = parseFlags(args);
|
|
44
|
+
const api = await driveClient(account);
|
|
45
|
+
// File metadata first so we can show name + shared flag alongside.
|
|
46
|
+
let file;
|
|
47
|
+
try {
|
|
48
|
+
const res = await api.files.get({
|
|
49
|
+
fileId: flags.fileId,
|
|
50
|
+
fields: "id,name,shared,owners(emailAddress)",
|
|
51
|
+
supportsAllDrives: true,
|
|
52
|
+
});
|
|
53
|
+
file = res.data;
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
const translated = translateGoogleError(err, {
|
|
57
|
+
account,
|
|
58
|
+
operation: "drive.files.get",
|
|
59
|
+
});
|
|
60
|
+
if (translated.code === "NOT_FOUND") {
|
|
61
|
+
throw new AxiError(`File '${flags.fileId}' not found (or ${account} doesn't have access)`, "FILE_NOT_FOUND", [`Verify the file ID is correct (from a Drive URL or \`drive search\`)`]);
|
|
62
|
+
}
|
|
63
|
+
throw translated;
|
|
64
|
+
}
|
|
65
|
+
let perms = [];
|
|
66
|
+
try {
|
|
67
|
+
const res = await api.permissions.list({
|
|
68
|
+
fileId: flags.fileId,
|
|
69
|
+
fields: "permissions(id,type,role,emailAddress,domain,displayName,deleted,pendingOwner)",
|
|
70
|
+
supportsAllDrives: true,
|
|
71
|
+
});
|
|
72
|
+
perms = res.data.permissions ?? [];
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
throw translateGoogleError(err, {
|
|
76
|
+
account,
|
|
77
|
+
operation: "drive.permissions.list",
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
const rows = perms.map((p) => ({
|
|
81
|
+
role: p.role ?? "",
|
|
82
|
+
type: p.type ?? "",
|
|
83
|
+
email_or_domain: p.emailAddress ?? p.domain ?? (p.type === "anyone" ? "anyone with link" : ""),
|
|
84
|
+
display_name: p.displayName ?? "",
|
|
85
|
+
deleted: p.deleted ? "✓" : "",
|
|
86
|
+
}));
|
|
87
|
+
const blocks = [];
|
|
88
|
+
blocks.push(renderObject({ account }));
|
|
89
|
+
blocks.push(renderObject({
|
|
90
|
+
file: {
|
|
91
|
+
id: file.id ?? flags.fileId,
|
|
92
|
+
name: file.name ?? "",
|
|
93
|
+
shared: file.shared ?? false,
|
|
94
|
+
},
|
|
95
|
+
}));
|
|
96
|
+
if (rows.length === 0) {
|
|
97
|
+
blocks.push(renderObject({ permissions: "no explicit permissions" }));
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
blocks.push(renderList("permissions", rows, permissionSchema()));
|
|
101
|
+
}
|
|
102
|
+
const suggestions = [];
|
|
103
|
+
const anyone = perms.find((p) => p.type === "anyone");
|
|
104
|
+
if (anyone) {
|
|
105
|
+
suggestions.push(`"anyone with link" (role: ${anyone.role}) — this file is accessible without sign-in`);
|
|
106
|
+
}
|
|
107
|
+
const externalUsers = perms.filter((p) => p.type === "user" &&
|
|
108
|
+
p.emailAddress &&
|
|
109
|
+
!p.emailAddress.endsWith(`@${account.split("@")[1] ?? ""}`));
|
|
110
|
+
if (externalUsers.length > 0) {
|
|
111
|
+
suggestions.push(`${externalUsers.length} external user${externalUsers.length === 1 ? "" : "s"} have access (not on ${account.split("@")[1] ?? "your"} domain)`);
|
|
112
|
+
}
|
|
113
|
+
if (suggestions.length > 0)
|
|
114
|
+
blocks.push(renderHelp(suggestions));
|
|
115
|
+
return joinBlocks(...blocks);
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../../../src/commands/drive/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EACL,KAAK,EACL,UAAU,EACV,YAAY,EACZ,UAAU,EACV,UAAU,GAEX,MAAM,uBAAuB,CAAC;AAE/B,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;CAiB/B,CAAC;AAMF,SAAS,UAAU,CAAC,IAAc;IAChC,IAAI,MAA0B,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM,GAAG,GAAG,CAAC;IAClE,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAChB,0BAA0B,EAC1B,kBAAkB,EAClB,CAAC,4CAA4C,CAAC,CAC/C,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO;QACL,KAAK,CAAC,MAAM,CAAC;QACb,KAAK,CAAC,MAAM,CAAC;QACb,KAAK,CAAC,iBAAiB,CAAC;QACxB,KAAK,CAAC,cAAc,CAAC;QACrB,KAAK,CAAC,SAAS,CAAC;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAe,EACf,IAAc;IAEd,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAEvC,mEAAmE;IACnE,IAAI,IAA0B,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;YAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,qCAAqC;YAC7C,iBAAiB,EAAE,IAAI;SACxB,CAAC,CAAC;QACH,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,EAAE;YAC3C,OAAO;YACP,SAAS,EAAE,iBAAiB;SAC7B,CAAC,CAAC;QACH,IAAI,UAAU,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACpC,MAAM,IAAI,QAAQ,CAChB,SAAS,KAAK,CAAC,MAAM,mBAAmB,OAAO,uBAAuB,EACtE,gBAAgB,EAChB,CAAC,sEAAsE,CAAC,CACzE,CAAC;QACJ,CAAC;QACD,MAAM,UAAU,CAAC;IACnB,CAAC;IAED,IAAI,KAAK,GAAiC,EAAE,CAAC;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC;YACrC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EACJ,gFAAgF;YAClF,iBAAiB,EAAE,IAAI;SACxB,CAAC,CAAC;QACH,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,oBAAoB,CAAC,GAAG,EAAE;YAC9B,OAAO;YACP,SAAS,EAAE,wBAAwB;SACpC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7B,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;QAClB,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;QAClB,eAAe,EAAE,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9F,YAAY,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;QACjC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;KAC9B,CAAC,CAAC,CAAC;IAEJ,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IACvC,MAAM,CAAC,IAAI,CACT,YAAY,CAAC;QACX,IAAI,EAAE;YACJ,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,KAAK,CAAC,MAAM;YAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;SAC7B;KACF,CAAC,CACH,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC,CAAC,CAAC;IACxE,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACtD,IAAI,MAAM,EAAE,CAAC;QACX,WAAW,CAAC,IAAI,CACd,6BAA6B,MAAM,CAAC,IAAI,6CAA6C,CACtF,CAAC;IACJ,CAAC;IACD,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAChC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,IAAI,KAAK,MAAM;QACjB,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAC9D,CAAC;IACF,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,WAAW,CAAC,IAAI,CACd,GAAG,aAAa,CAAC,MAAM,iBAAiB,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,wBAAwB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,UAAU,CAC/I,CAAC;IACJ,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IAEjE,OAAO,UAAU,CAAC,GAAG,MAAM,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const SEARCH_HELP = "usage: gws-axi drive search [flags]\nflags[5]:\n --query <text> Full-text search across file names AND content\n (Drive's fullText index). Quote multi-word\n phrases. Default when omitted: all files\n modified in the last 30 days.\n --mime <type> Filter by mime type (e.g.,\n \"application/vnd.google-apps.document\" for\n only Google Docs; \"application/pdf\" for PDFs).\n --limit <n> Max files to return (default: 100, max: 1000).\n --page <token> Fetch the next page (from prior `next_page`).\n --account <email> Account override when 2+ are configured.\nexamples:\n gws-axi drive search --query \"smart data hub\"\n gws-axi drive search --query \"tides\" --mime application/vnd.google-apps.document\n gws-axi drive search --query \"invoice\" --mime application/pdf --limit 25\noutput:\n A `files[N]{id,name,mime_type,size_bytes,modified,owners}` table.\n Pass any `id` to `drive get` for full metadata, `docs read` (for\n Docs), or `docs download` (any file). The `mime_type` lets agents\n filter for the file type they care about.\nnotes:\n fullText matching uses Drive's index, which lags edits by minutes.\n Recently-modified docs may not be indexed yet \u2014 for those, use\n `drive ls` on the parent folder instead.\n";
|
|
2
|
+
export declare function driveSearchCommand(account: string, args: string[]): Promise<string>;
|